UPDATE
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
from sensor_catalog.models import SensorCatalog
|
||||
|
||||
|
||||
SENSOR_CATALOG_ITEMS = [
|
||||
{
|
||||
"code": "sensor_7_soil_moisture_sensor_v1_2",
|
||||
"name": "Sensor 7 - Soil Moisture Sensor v1.2",
|
||||
"description": (
|
||||
"This sensor is typically the YL-69 or FC-28 soil moisture sensor. "
|
||||
"It measures only soil moisture and provides analog and digital outputs. "
|
||||
"It does not report soil temperature, pH, or nutrients."
|
||||
),
|
||||
"customizable_fields": [],
|
||||
"supported_power_sources": ["solar", "direct_power"],
|
||||
"returned_data_fields": ["soil_moisture", "analog_output", "digital_output"],
|
||||
"sample_payload": {
|
||||
"soil_moisture": 42,
|
||||
"analog_output": 610,
|
||||
"digital_output": 1,
|
||||
},
|
||||
"is_active": True,
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
def seed_sensor_catalog():
|
||||
created_count = 0
|
||||
updated_count = 0
|
||||
results = []
|
||||
|
||||
for item in SENSOR_CATALOG_ITEMS:
|
||||
sensor, created = SensorCatalog.objects.update_or_create(
|
||||
code=item["code"],
|
||||
defaults={
|
||||
"name": item["name"],
|
||||
"description": item["description"],
|
||||
"customizable_fields": item["customizable_fields"],
|
||||
"supported_power_sources": item["supported_power_sources"],
|
||||
"returned_data_fields": item["returned_data_fields"],
|
||||
"sample_payload": item["sample_payload"],
|
||||
"is_active": item["is_active"],
|
||||
},
|
||||
)
|
||||
results.append((sensor, created))
|
||||
if created:
|
||||
created_count += 1
|
||||
else:
|
||||
updated_count += 1
|
||||
|
||||
return results, created_count, updated_count
|
||||
|
||||
@@ -1,53 +1,17 @@
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
from sensor_catalog.models import SensorCatalog
|
||||
|
||||
|
||||
SENSOR_CATALOG_ITEMS = [
|
||||
{
|
||||
"name": "Sensor 7 - Soil Moisture Sensor v1.2",
|
||||
"description": (
|
||||
"This sensor is typically the YL-69 or FC-28 soil moisture sensor. "
|
||||
"It measures only soil moisture and provides analog and digital outputs. "
|
||||
"It does not report soil temperature, pH, or nutrients."
|
||||
),
|
||||
"customizable_fields": [],
|
||||
"supported_power_sources": ["solar", "direct_power"],
|
||||
"returned_data_fields": ["soil_moisture", "analog_output", "digital_output"],
|
||||
"sample_payload": {
|
||||
"soil_moisture": 42,
|
||||
"analog_output": 610,
|
||||
"digital_output": 1,
|
||||
},
|
||||
"is_active": True,
|
||||
}
|
||||
]
|
||||
from sensor_catalog.management import seed_sensor_catalog
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Seed sensor catalog data."
|
||||
|
||||
def handle(self, *args, **options):
|
||||
created_count = 0
|
||||
updated_count = 0
|
||||
|
||||
for item in SENSOR_CATALOG_ITEMS:
|
||||
sensor, created = SensorCatalog.objects.update_or_create(
|
||||
name=item["name"],
|
||||
defaults={
|
||||
"description": item["description"],
|
||||
"customizable_fields": item["customizable_fields"],
|
||||
"supported_power_sources": item["supported_power_sources"],
|
||||
"returned_data_fields": item["returned_data_fields"],
|
||||
"sample_payload": item["sample_payload"],
|
||||
"is_active": item["is_active"],
|
||||
},
|
||||
)
|
||||
results, created_count, updated_count = seed_sensor_catalog()
|
||||
for sensor, created in results:
|
||||
if created:
|
||||
created_count += 1
|
||||
self.stdout.write(self.style.SUCCESS(f"Created sensor catalog item: {sensor.name}"))
|
||||
else:
|
||||
updated_count += 1
|
||||
self.stdout.write(self.style.WARNING(f"Updated sensor catalog item: {sensor.name}"))
|
||||
|
||||
self.stdout.write(
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import re
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
def _to_snake_case(value):
|
||||
normalized = re.sub(r"[^a-zA-Z0-9]+", "_", (value or "").strip()).strip("_").lower()
|
||||
return normalized or "sensor"
|
||||
|
||||
|
||||
def populate_sensor_codes(apps, schema_editor):
|
||||
SensorCatalog = apps.get_model("sensor_catalog", "SensorCatalog")
|
||||
|
||||
used_codes = set()
|
||||
for sensor in SensorCatalog.objects.all().order_by("id"):
|
||||
base_code = _to_snake_case(sensor.name)
|
||||
code = base_code
|
||||
suffix = 2
|
||||
while code in used_codes:
|
||||
code = f"{base_code}_{suffix}"
|
||||
suffix += 1
|
||||
sensor.code = code
|
||||
sensor.save(update_fields=["code"])
|
||||
used_codes.add(code)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("sensor_catalog", "0002_sensorcatalog_supported_power_sources"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="sensorcatalog",
|
||||
name="code",
|
||||
field=models.CharField(blank=True, db_index=True, default="", max_length=255),
|
||||
),
|
||||
migrations.RunPython(populate_sensor_codes, migrations.RunPython.noop),
|
||||
migrations.AlterField(
|
||||
model_name="sensorcatalog",
|
||||
name="code",
|
||||
field=models.CharField(db_index=True, max_length=255, unique=True),
|
||||
),
|
||||
]
|
||||
@@ -5,6 +5,7 @@ from django.db import models
|
||||
|
||||
class SensorCatalog(models.Model):
|
||||
uuid = models.UUIDField(default=uuid.uuid4, unique=True, editable=False, db_index=True)
|
||||
code = models.CharField(max_length=255, unique=True, db_index=True)
|
||||
name = models.CharField(max_length=255, unique=True, db_index=True)
|
||||
description = models.TextField(blank=True, default="")
|
||||
customizable_fields = models.JSONField(default=list, blank=True)
|
||||
@@ -17,7 +18,7 @@ class SensorCatalog(models.Model):
|
||||
|
||||
class Meta:
|
||||
db_table = "sensor_catalogs"
|
||||
ordering = ["name"]
|
||||
ordering = ["code"]
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
@@ -8,6 +8,7 @@ class SensorCatalogSerializer(serializers.ModelSerializer):
|
||||
model = SensorCatalog
|
||||
fields = [
|
||||
"uuid",
|
||||
"code",
|
||||
"name",
|
||||
"description",
|
||||
"customizable_fields",
|
||||
|
||||
@@ -16,6 +16,7 @@ class SensorCatalogListViewTests(TestCase):
|
||||
phone_number="09120000002",
|
||||
)
|
||||
SensorCatalog.objects.update_or_create(
|
||||
code="sensor_7_soil_moisture_sensor_v1_2",
|
||||
name="Sensor 7 - Soil Moisture Sensor v1.2",
|
||||
defaults={
|
||||
"description": (
|
||||
@@ -30,6 +31,7 @@ class SensorCatalogListViewTests(TestCase):
|
||||
},
|
||||
)
|
||||
SensorCatalog.objects.update_or_create(
|
||||
code="legacy_sensor",
|
||||
name="Legacy Sensor",
|
||||
defaults={
|
||||
"customizable_fields": [],
|
||||
@@ -50,6 +52,6 @@ class SensorCatalogListViewTests(TestCase):
|
||||
self.assertEqual(response.data["code"], 200)
|
||||
self.assertEqual(len(response.data["data"]), 2)
|
||||
self.assertEqual(
|
||||
{item["name"] for item in response.data["data"]},
|
||||
{"Sensor 7 - Soil Moisture Sensor v1.2", "Legacy Sensor"},
|
||||
{item["code"] for item in response.data["data"]},
|
||||
{"sensor_7_soil_moisture_sensor_v1_2", "legacy_sensor"},
|
||||
)
|
||||
|
||||
@@ -17,6 +17,6 @@ class SensorCatalogListView(APIView):
|
||||
responses={200: code_response("SensorCatalogListResponse", data=SensorCatalogSerializer(many=True))},
|
||||
)
|
||||
def get(self, request):
|
||||
sensors = SensorCatalog.objects.order_by("name")
|
||||
sensors = SensorCatalog.objects.order_by("code")
|
||||
data = SensorCatalogSerializer(sensors, many=True).data
|
||||
return Response({"code": 200, "msg": "success", "data": data}, status=status.HTTP_200_OK)
|
||||
|
||||
Reference in New Issue
Block a user