Files
django-relay-controller/relaycontroller/relay/models.py
T
2026-03-10 13:10:32 +01:00

116 lines
4.1 KiB
Python

import json
from datetime import timedelta
from django.utils.translation import gettext_lazy as _
from django_resized import ResizedImageField
from django_celery_beat.models import PeriodicTask
from django.dispatch import receiver
from django.utils.text import slugify
from django.utils.safestring import mark_safe
from django.db.models.signals import post_save
from django.db import models
from modules import utils
class DeviceType(models.Model):
name = models.CharField(_("Nom du capteur"), max_length=64, null=True)
code = models.SlugField(_("Type de capteur"), help_text=_("Max 16 caractères"), unique=True, max_length=16, null=True, blank=True)
class Meta:
ordering = ['name']
verbose_name = _("Type de capteur")
verbose_name_plural = _("Types de capteurs")
def save(self, *args, **kwargs):
self.code = slugify(self.code)
super().save(*args, **kwargs)
def __str__(self):
return f'{self.name}'
class Device(models.Model):
label = models.CharField(_("Capteur"), max_length=100, null=True)
uuid = models.SlugField(_("Uuid"), help_text=_('Uuid iot clef unique'), unique=True, max_length=32, null=True, blank=True)
device_type = models.ForeignKey(DeviceType, verbose_name=_("Type de capteur"), on_delete=models.CASCADE, null=True, blank=True, )
index = models.SmallIntegerField(_("Index"), help_text=_("Numéro d'index"), default=0)
pin_active = models.BooleanField(_("Broche"), help_text=_("Broche active à l'initialisation"), default=True)
image = ResizedImageField(_("Image"), help_text=_("Image du capteur"), size=[320, 240], upload_to='devices/', null=True, blank=True, default = 'devices/vanne.png')
task = models.ForeignKey(
PeriodicTask,
verbose_name=_("Tâche périodique"),
help_text=_("Tâche de démarrage périodique de ce capteur (optionnel)"),
on_delete=models.CASCADE, null=True, blank=False
)
lifetime = models.DurationField(_("Durée"), help_text=_("Durée de l'évènement. Jours hh:mm:ss format"), blank=True, null=True, default=timedelta(hours=1, minutes=15))
heartbeat = models.IntegerField (_("Battement"), help_text=_("Interrogation du capteur en secondes"), default=1)
active = models.BooleanField(_("Actif"), default=True)
def image_tag(self):
return mark_safe(f'<img src="{self.image.url}" style="width: 45px; height:45px;">')
image_tag.short_description = _("Image")
image_tag.allow_tags = True
def to_register(self):
return dict(
dev_type=self.device_type.code if self.device_type else 'None',
index=self.index,
key=self.uuid,
label=self.label,
status=0,
active=1 if self.pin_active else 0,
)
class Meta:
ordering = ['index', ]
verbose_name = _("Capteur")
verbose_name_plural = _("Capteurs")
@classmethod
def all_devices(cls):
return Device.objects.filter(active=True).all().order_by('index')
@classmethod
def all_devices_json(cls):
devices = Device.objects.filter(active=True).all().order_by('index')
buf = []
for dev in devices:
buf.append({
"uuid": dev.uuid,
"index": dev.index,
})
return json.dumps(buf)
def save(self, *args, **kwargs):
if not self.uuid:
self.uuid = utils.get_device_uuid(12)
super().save(*args, **kwargs)
def __str__(self):
return f'{self.label}'
@receiver(post_save, sender=Device)
def create_device(sender, instance, created, **kwargs):
name = f'{instance.uuid}'
t = PeriodicTask.objects.filter(name__exact=name).first()
if not t:
p = PeriodicTask.objects.create(
name=name,
task='relay status',
description=_('Pas encore programmé'),
interval_id=1,
args=json.dumps([instance.uuid])
)
instance.task_id = p.id
instance.save()
else:
PeriodicTask.objects.filter(id=instance.task.id).update(
name=name,
args=json.dumps([instance.uuid])
)
instance.task.save()