Skip to content

Commit

Permalink
139 label code generieren und im device detail anzeigen (#141)
Browse files Browse the repository at this point in the history
* added ModelCounter

* changed post url back to datahub

* changed model filed type to int

* added QR-Code Text field

* added get_device_name to Device model

* format qr-code in device detail

* add dev api device initial station info test

* create change log for device and user

* #84 display logs for Organization, room and user

* #143 save when device is saved assign name if model is set

* #144

---------

Co-authored-by: Nik Sauer <[email protected]>
Co-authored-by: Silvio Heinze <[email protected]>
  • Loading branch information
3 people authored Jan 31, 2025
1 parent 33151b7 commit 1206955
Show file tree
Hide file tree
Showing 9 changed files with 342 additions and 98 deletions.
26 changes: 26 additions & 0 deletions app/devices/migrations/0017_modelcounter_device_auto_number.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Generated by Django 5.1.5 on 2025-01-30 10:12

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('devices', '0016_alter_device_current_campaign_and_more'),
]

operations = [
migrations.CreateModel(
name='ModelCounter',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('model', models.CharField(max_length=255, unique=True)),
('last_auto_number', models.IntegerField(default=0)),
],
),
migrations.AddField(
model_name='device',
name='auto_number',
field=models.IntegerField(blank=True, null=True),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Generated by Django 5.1.5 on 2025-01-30 10:22

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('devices', '0017_modelcounter_device_auto_number'),
]

operations = [
migrations.RemoveField(
model_name='modelcounter',
name='id',
),
migrations.AlterField(
model_name='modelcounter',
name='model',
field=models.CharField(max_length=255, primary_key=True, serialize=False),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 5.1.5 on 2025-01-30 10:47

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('devices', '0018_remove_modelcounter_id_alter_modelcounter_model'),
]

operations = [
migrations.AlterField(
model_name='device',
name='model',
field=models.IntegerField(blank=True, null=True),
),
migrations.AlterField(
model_name='modelcounter',
name='model',
field=models.IntegerField(primary_key=True, serialize=False),
),
]
53 changes: 49 additions & 4 deletions app/devices/models.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from django.db import models
from django.db import models, transaction
from django.utils import timezone
from organizations.models import Organization
from campaign.models import Room
Expand All @@ -7,30 +7,75 @@
from auditlog.registry import auditlog
from auditlog.models import AuditlogHistoryField

from main.enums import LdProduct


class Device(models.Model):
"""
Device model.
"""
id = models.CharField(max_length=255, primary_key=True)
device_name = models.CharField(max_length=255, blank=True, null=True)
model = models.CharField(max_length=255, blank=True, null=True)
model = models.IntegerField(null=True, blank=True)
firmware = models.CharField(max_length=255, blank=True)
btmac_address = models.CharField(max_length=12, null=True, blank=True)
last_update = models.DateTimeField(null=True, blank=True)
notes = models.TextField(null=True, blank=True)
api_key = models.CharField(max_length=64, null=True)
auto_number = models.IntegerField(null=True, blank=True)

current_room = models.ForeignKey(Room, related_name='current_devices', null=True, on_delete=models.SET_NULL, blank=True)
current_organization = models.ForeignKey(Organization, related_name='current_devices', null=True, on_delete=models.SET_NULL, blank=True)
current_user = models.ForeignKey(CustomUser, null=True, related_name='current_devices', on_delete=models.SET_NULL, blank=True)
current_campaign = models.ForeignKey(Campaign, null=True, related_name='current_devices', on_delete=models.SET_NULL, blank=True)

history = AuditlogHistoryField()
history = AuditlogHistoryField(pk_indexable=False)

def save(self, *args, **kwargs):
# if the model id is not set or the auto_number is already set we don't
# need to update the auto_number
if self.model is None:
super().save(*args, **kwargs)
return

if self.auto_number:
# assign name to update existing devices
# TODO could be removed
self.device_name = f'{self.get_model_name()} {self.auto_number:04d}'
super().save(*args, **kwargs)
return

# update auto_number for the first time
with transaction.atomic():
counter, _ = ModelCounter.objects.get_or_create(model=self.model)
counter.last_auto_number += 1
counter.save()

self.auto_number = counter.last_auto_number
'''
assigns a unique name for this device in this format: "{model name}{auto_number}"
for example "Air Cube 0001"
'''
self.device_name = f'{self.get_model_name()} {self.auto_number:04d}'

super().save(*args, **kwargs)

def get_ble_id(self):
# cuts of the 3 last characters that are use for board identification
return self.id[:-3]

def get_model_name(self):
'''returns the corresponding LdProduct name'''
return LdProduct._names.get(self.model, 'Unknown Model')

def __str__(self):
return self.id or "Undefined Device" # Added fallback for undefined IDs



class ModelCounter(models.Model):
model = models.IntegerField(primary_key=True)
last_auto_number = models.IntegerField(default=0)


class Sensor(models.Model):
"""
Expand Down
43 changes: 42 additions & 1 deletion app/devices/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@
from django.db import transaction

from .models import Device, DeviceStatus, DeviceLogs, Measurement
from accounts.models import CustomUser
from .forms import DeviceForm, DeviceNotesForm
from main.enums import SensorModel, Dimension
from organizations.models import Organization
from campaign.models import Room

class DeviceListView(LoginRequiredMixin, UserPassesTestMixin, ListView):
model = Device
Expand Down Expand Up @@ -64,6 +67,45 @@ def get_context_data(self, **kwargs):
if status.battery_soc is not None and status.battery_voltage is not None
]

# query changes
organization_changes = device.history.filter(changes__icontains = '"current_organization"').all().order_by('-timestamp')
room_changes = device.history.filter(changes__icontains = '"current_room"').all().order_by('-timestamp')
user_changes = device.history.filter(changes__icontains = '"current_user"').all().order_by('-timestamp')

organization_change_log = []
room_change_log = []
user_change_log = []

# prepare changes
for h in organization_changes:
prev = h.changes['current_organization'][0]
next = h.changes['current_organization'][1]
organization_change_log.append({
'timestamp': h.timestamp,
'prev': None if prev == 'None' else Organization.objects.filter(id=prev).first(),
'next': None if next == 'None' else Organization.objects.filter(id=next).first(),
})
for h in room_changes:
prev = h.changes['current_room'][0]
next = h.changes['current_room'][1]
room_change_log.append({
'timestamp': h.timestamp,
'prev': None if prev == 'None' else Room.objects.filter(id=prev).first(),
'next': None if next == 'None' else Room.objects.filter(id=next).first(),
})
for h in user_changes:
prev = h.changes['current_user'][0]
next = h.changes['current_user'][1]
user_change_log.append({
'timestamp': h.timestamp,
'prev': None if prev == 'None' else CustomUser.objects.filter(id=prev).first(),
'next': None if next == 'None' else CustomUser.objects.filter(id=next).first(),
})

context['organization_change_log'] = organization_change_log
context['room_change_log'] = room_change_log
context['user_change_log'] = user_change_log

# Serialize data to JSON format
context['battery_times'] = json.dumps(battery_times, cls=DjangoJSONEncoder)
context['battery_charges'] = json.dumps(battery_charges, cls=DjangoJSONEncoder)
Expand Down Expand Up @@ -101,7 +143,6 @@ def get_context_data(self, **kwargs):
sensors = defaultdict(list)
# add available sensors
for measurement in Measurement.objects.filter(device=device, time_measured=device.last_update).all():
print(measurement.sensor_model)
for value in measurement.values.all():
sensors[SensorModel.get_sensor_name(measurement.sensor_model)].append(Dimension.get_name(value.dimension))

Expand Down
1 change: 0 additions & 1 deletion app/main/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ def get_or_create_station(station_info: dict):
id = station_info['device']
)
if created:
station.device_name = station_info['device']
station.model = station_info['model']
station.firmware = station_info['firmware']
station.api_key = station_info['apikey']
Expand Down
Loading

0 comments on commit 1206955

Please sign in to comment.