From d30341ff545e7c35ae3defb6a43c1ac617ddcf8e Mon Sep 17 00:00:00 2001 From: FranciscoLozCoding Date: Mon, 11 Dec 2023 15:23:12 -0600 Subject: [PATCH 1/3] switched lorawan device to use abstract sensor --- manifests/admin.py | 4 +- ...device_name_lorawandevice_name_and_more.py | 44 +++++++++++++++++++ manifests/models.py | 6 +-- manifests/serializers.py | 2 +- 4 files changed, 50 insertions(+), 6 deletions(-) create mode 100644 manifests/migrations/0037_rename_device_name_lorawandevice_name_and_more.py diff --git a/manifests/admin.py b/manifests/admin.py index e7df491..6a26478 100644 --- a/manifests/admin.py +++ b/manifests/admin.py @@ -401,8 +401,8 @@ def get_sensors(self, obj): @admin.register(LorawanDevice) class LorawanDeviceAdmin(admin.ModelAdmin): - list_display = ["device_name", "deveui", "battery_level"] - search_fields = ["device_name", "deveui"] + list_display = ["name", "deveui", "battery_level"] + search_fields = ["name", "deveui"] @admin.register(LorawanConnection) diff --git a/manifests/migrations/0037_rename_device_name_lorawandevice_name_and_more.py b/manifests/migrations/0037_rename_device_name_lorawandevice_name_and_more.py new file mode 100644 index 0000000..e07c3cb --- /dev/null +++ b/manifests/migrations/0037_rename_device_name_lorawandevice_name_and_more.py @@ -0,0 +1,44 @@ +# Generated by Django 4.2.5 on 2023-12-11 21:09 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + ("manifests", "0036_nodedata_project"), + ] + + operations = [ + migrations.RenameField( + model_name="lorawandevice", + old_name="device_name", + new_name="name", + ), + migrations.AddField( + model_name="lorawandevice", + name="hardware", + field=models.ForeignKey( + blank=True, + default=1, + on_delete=django.db.models.deletion.CASCADE, + to="manifests.sensorhardware", + ), + preserve_default=False, + ), + migrations.AddField( + model_name="lorawandevice", + name="labels", + field=models.ManyToManyField(blank=True, to="manifests.label"), + ), + migrations.AddField( + model_name="lorawandevice", + name="serial_no", + field=models.CharField(blank=True, default="", max_length=30), + ), + migrations.AddField( + model_name="lorawandevice", + name="uri", + field=models.CharField(blank=True, default="", max_length=256), + ), + ] diff --git a/manifests/models.py b/manifests/models.py index eb020a8..3af964b 100644 --- a/manifests/models.py +++ b/manifests/models.py @@ -327,11 +327,11 @@ def clean(self): ) -class LorawanDevice(models.Model): +class LorawanDevice(AbstractSensor): deveui = models.CharField( max_length=16, primary_key=True, unique=True, null=False, blank=False ) - device_name = models.CharField(max_length=100, null=True, blank=True) + name = models.CharField(max_length=100, null=True, blank=True) battery_level = models.DecimalField( max_digits=5, decimal_places=2, null=True, blank=True ) @@ -342,7 +342,7 @@ class Meta: verbose_name_plural = "Lorawan Devices" def __str__(self): - return str(self.device_name) + "-" + str(self.deveui) + return str(self.name) + "-" + str(self.deveui) def natural_key(self): return self.deveui diff --git a/manifests/serializers.py b/manifests/serializers.py index b03ed71..147137c 100644 --- a/manifests/serializers.py +++ b/manifests/serializers.py @@ -179,7 +179,7 @@ def serialize_compute_hardware(h): def serialize_lorawan_devices(l): return { "deveui": l.deveui, - "device_name": l.device_name, + "name": l.name, "battery_level": l.battery_level, } From 3cceefba987fcfdfd66605c55325dff36efa3143 Mon Sep 17 00:00:00 2001 From: FranciscoLozCoding Date: Tue, 12 Dec 2023 13:06:18 -0600 Subject: [PATCH 2/3] added lorawan sensors to SensorHardwareViewSet --- manifests/serializers.py | 4 +++- manifests/views.py | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/manifests/serializers.py b/manifests/serializers.py index 147137c..5dfce7b 100644 --- a/manifests/serializers.py +++ b/manifests/serializers.py @@ -12,7 +12,9 @@ class SensorViewSerializer(serializers.ModelSerializer): def get_vsns(self, obj): compute_sensors = obj.computesensor_set.all() node_sensors = obj.nodesensor_set.all() - nodes = [s.scope.node for s in compute_sensors] + [s.node for s in node_sensors] + lorawan_sensors = obj.lorawandevice_set.all() + lorawan_connections = [ld.lorawanconnections.all() for ld in lorawan_sensors] + nodes = [s.scope.node for s in compute_sensors] + [s.node for s in node_sensors] + [lc[0].node for lc in lorawan_connections] project = self.context['request'].query_params.get("project") if project: diff --git a/manifests/views.py b/manifests/views.py index 335702c..27b3991 100644 --- a/manifests/views.py +++ b/manifests/views.py @@ -64,7 +64,9 @@ class SensorHardwareViewSet(ReadOnlyModelViewSet): "nodesensor_set__node", "computesensor_set", "computesensor_set__scope", - "computesensor_set__scope__node" + "computesensor_set__scope__node", + "lorawandevice_set", + "lorawandevice_set__lorawanconnections" ) .order_by("hardware") ) From 9d62a1d58bffe6eee427c3c586a36a310b49b85c Mon Sep 17 00:00:00 2001 From: FranciscoLozCoding Date: Tue, 12 Dec 2023 13:06:34 -0600 Subject: [PATCH 3/3] edited test to include lorawan sensors --- manifests/tests.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/manifests/tests.py b/manifests/tests.py index 5e9a995..f7065aa 100644 --- a/manifests/tests.py +++ b/manifests/tests.py @@ -207,9 +207,12 @@ def test_list_view(self): node_b = NodeData.objects.create(vsn="B123", name="B_name", project=project_b, phase='Awaiting Shipment') sensor_a = SensorHardware.objects.create(hardware="top_camera", hw_model="fe-8010") sensor_b = SensorHardware.objects.create(hardware="bottom_camera", hw_model="ptz-8081") + sensor_c = SensorHardware.objects.create(hardware="lorawan_temp", hw_model="temp") + ld = LorawanDevice.objects.create(deveui="234",hardware=sensor_c,name="test") NodeSensor.objects.create(node=node_a, hardware=sensor_a) NodeSensor.objects.create(node=node_b, hardware=sensor_a) NodeSensor.objects.create(node=node_b, hardware=sensor_b) + LorawanConnection.objects.create(node=node_a,connection_type="OTAA",lorawan_device=ld) # request without filters r = self.client.get("/sensors/") @@ -228,6 +231,12 @@ def test_list_view(self): vsns = sensors[0]["vsns"] self.assertCountEqual(vsns, ['B123']) + # check for lorawan temp sensor + sensors = list(filter(lambda o: o["hardware"] == "lorawan_temp", items)) + self.assertEqual(len(sensors), 1) + vsns = sensors[0]["vsns"] + self.assertCountEqual(vsns, ['A123']) + # # test requests with filters # @@ -235,8 +244,8 @@ def test_list_view(self): self.assertEqual(r.status_code, 200) items = r.json() - # check only 1 sensor is listed (for ProjA) - self.assertEqual(len(items), 1) + # check 2 sensor is listed (for ProjA) + self.assertEqual(len(items), 2) self.assertCountEqual(items[0]["vsns"], ["A123"]) # 0 queries @@ -259,7 +268,7 @@ def test_list_view(self): # multi filtering r = self.client.get("/sensors/?phase=deployed,awaiting shipment") items = r.json() - self.assertEqual(len(items), 2) + self.assertEqual(len(items), 3) sensors = list(filter(lambda o: o["hardware"] == "bottom_camera", items)) self.assertEqual(len(sensors), 1) @@ -271,7 +280,7 @@ def test_list_view(self): r = self.client.get("/sensors/?project=proja&phase=deployed,awaiting shipment") items = r.json() - self.assertEqual(len(items), 1) + self.assertEqual(len(items), 2) self.assertCountEqual(items[0]["vsns"], ["A123"]) r = self.client.get("/sensors/?project=proja&phase=awaiting shipment")