feat / AEB-62 add additional DB schema for objects logic
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
from django.db import models
|
||||
from decimal import Decimal
|
||||
|
||||
from sitemanagement.constants.image_file_path import register_object_upload_path
|
||||
|
||||
class Multiplexor(models.Model):
|
||||
"""Устройство-мультиплексор"""
|
||||
@@ -61,9 +61,9 @@ class SensorType(models.Model):
|
||||
class SignalFormat(models.Model):
|
||||
"""Формат сигнала и правило преобразования"""
|
||||
sensor_type = models.ForeignKey(SensorType, on_delete=models.CASCADE, related_name="formats")
|
||||
code = models.CharField(max_length=50) # например "4-20мА", "VW f<1600Hz", "NTC R>250Ohm"
|
||||
unit = models.CharField(max_length=20, blank=True, null=True) # °C, мкм/м, мм и т.п.
|
||||
conversion_rule = models.CharField(max_length=255, blank=True, null=True)
|
||||
code = models.CharField(max_length=50, verbose_name="Код") # например "4-20мА", "VW f<1600Hz", "NTC R>250Ohm"
|
||||
unit = models.CharField(max_length=20, blank=True, null=True, verbose_name="Единица измерения") # °C, мкм/м, мм и т.п.
|
||||
conversion_rule = models.CharField(max_length=255, blank=True, null=True, verbose_name="Правило преобразования")
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
class Meta:
|
||||
@@ -79,13 +79,13 @@ class SignalFormat(models.Model):
|
||||
class Sensor(models.Model):
|
||||
"""Конкретный датчик, установленный в канале"""
|
||||
channel = models.ForeignKey(Channel, on_delete=models.CASCADE, related_name="sensors")
|
||||
sensor_type = models.ForeignKey(SensorType, on_delete=models.CASCADE)
|
||||
signal_format = models.ForeignKey(SignalFormat, on_delete=models.SET_NULL, null=True, blank=True)
|
||||
serial_number = models.CharField(max_length=50, blank=True, null=True) # CL 2106009
|
||||
name = models.CharField(max_length=50, blank=True, null=True) # GA-1, HLE-1 и т.п.
|
||||
sensor_type = models.ForeignKey(SensorType, on_delete=models.CASCADE, verbose_name="Тип сенсора")
|
||||
signal_format = models.ForeignKey(SignalFormat, on_delete=models.SET_NULL, null=True, blank=True, verbose_name="Формат сигнала")
|
||||
serial_number = models.CharField(max_length=50, blank=True, null=True, verbose_name="Серийный номер") # CL 2106009
|
||||
name = models.CharField(max_length=50, blank=True, null=True, verbose_name="Название") # GA-1, HLE-1 и т.п.
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
math_formula = models.CharField(null=True, blank=True, max_length=255)
|
||||
math_formula = models.CharField(null=True, blank=True, max_length=255, verbose_name="Математическая формула")
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Датчик"
|
||||
@@ -99,10 +99,10 @@ class Sensor(models.Model):
|
||||
class Metric(models.Model):
|
||||
"""Значения, которые приходят из CSV"""
|
||||
timestamp = models.DateTimeField()
|
||||
sensor = models.ForeignKey(Sensor, on_delete=models.CASCADE, related_name="metrics")
|
||||
raw_value = models.CharField(max_length=50) # исходное значение из файла (например "11.964 (A)")
|
||||
value = models.FloatField(null=True, blank=True) # преобразованное значение
|
||||
status = models.CharField(max_length=20, blank=True, null=True) # No Rx, Error, NotAv и т.д.
|
||||
sensor = models.ForeignKey(Sensor, on_delete=models.CASCADE, related_name="metrics", verbose_name="Датчик")
|
||||
raw_value = models.CharField(max_length=50, verbose_name="Исходное значение") # исходное значение из файла (например "11.964 (A)")
|
||||
value = models.FloatField(null=True, blank=True, verbose_name="Преобразованное значение") # преобразованное значение
|
||||
status = models.CharField(max_length=20, blank=True, null=True, verbose_name="Статус") # No Rx, Error, NotAv и т.д.
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
|
||||
@@ -121,21 +121,22 @@ class Metric(models.Model):
|
||||
|
||||
class Alert(models.Model):
|
||||
"""Тревоги по метрикам"""
|
||||
sensor = models.ForeignKey(Sensor, on_delete=models.CASCADE, related_name="alerts")
|
||||
metric = models.ForeignKey(Metric, on_delete=models.CASCADE, related_name="alerts")
|
||||
sensor_type = models.ForeignKey(SensorType, on_delete=models.CASCADE, related_name="alerts")
|
||||
message = models.CharField(max_length=255)
|
||||
sensor = models.ForeignKey(Sensor, on_delete=models.CASCADE, related_name="alerts", verbose_name="Датчик")
|
||||
metric = models.ForeignKey(Metric, on_delete=models.CASCADE, related_name="alerts", verbose_name="Метрика")
|
||||
sensor_type = models.ForeignKey(SensorType, on_delete=models.CASCADE, related_name="alerts", verbose_name="Тип сенсора")
|
||||
message = models.CharField(max_length=255, verbose_name="Сообщение")
|
||||
severity = models.CharField(
|
||||
max_length=20,
|
||||
choices=[
|
||||
("warning", "Warning"),
|
||||
("critical", "Critical"),
|
||||
],
|
||||
default="warning"
|
||||
default="warning",
|
||||
verbose_name="Уровень тревоги"
|
||||
)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
resolved = models.BooleanField(default=False)
|
||||
resolved = models.BooleanField(default=False, verbose_name="Статус обработки")
|
||||
|
||||
class Meta:
|
||||
indexes = [
|
||||
@@ -148,4 +149,40 @@ class Alert(models.Model):
|
||||
ordering = ["created_at", "sensor"]
|
||||
|
||||
def __str__(self):
|
||||
return f"ALERT {self.sensor} @ {self.metric.timestamp}: {self.message}"
|
||||
return f"ALERT {self.sensor} @ {self.metric.timestamp}: {self.message}"
|
||||
|
||||
class Object(models.Model):
|
||||
"""Объект"""
|
||||
title = models.CharField(max_length=255, verbose_name="Название")
|
||||
description = models.TextField(blank=True, null=True, verbose_name="Описание")
|
||||
image = models.ImageField(upload_to=register_object_upload_path, null=True, blank=True, verbose_name="Изображение")
|
||||
address = models.CharField(max_length=255, verbose_name="Адрес")
|
||||
floors = models.PositiveSmallIntegerField(verbose_name="Количество этажей")
|
||||
area = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="Площадь")
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Объект"
|
||||
verbose_name_plural = "Объекты"
|
||||
ordering = ["title"]
|
||||
|
||||
def __str__(self):
|
||||
return self.title
|
||||
|
||||
class Zone(models.Model):
|
||||
"""Зона"""
|
||||
object = models.ForeignKey(Object, on_delete=models.CASCADE, related_name="zones", verbose_name="Объект")
|
||||
name = models.CharField(max_length=255, verbose_name="Название")
|
||||
sensors = models.ManyToManyField(Sensor, related_name="zones", verbose_name="Датчики")
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Зона"
|
||||
verbose_name_plural = "Зоны"
|
||||
ordering = ["object", "name"]
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.object.title} - {self.name}"
|
||||
|
||||
Reference in New Issue
Block a user