Beispiel #1
0
 def get_reverse_verbose(self, prefix=', '):
     if self.reverse:
         if self.action:
             return prefix + t('иначе выключать')
         else:
             return prefix + t('иначе включать')
     else:
         return ''
Beispiel #2
0
class BotConfig(models.Model):
    ID_CHOICES = [('TELEGRAM_TOKEN', t('Токен телеграм-бота')),
                  ('ALLOWED_CLIENTS', t('Разрешенные id (через запятую)'))]
    id = models.CharField(max_length=40,
                          choices=ID_CHOICES,
                          verbose_name=t('Идентификатор'),
                          help_text=t('Идентификатор параметра'),
                          primary_key=True)
    value = models.CharField(max_length=400,
                             verbose_name=t('Значение'),
                             help_text=t('Значение параметра'))

    class Meta:
        ordering = ['id']
        verbose_name = t('Настройка телеграм-бота')
        verbose_name_plural = t('Настройки телеграм-бота')

    def __str__(self):
        return self.id

    @staticmethod
    def get_allowed_ids():
        try:
            bot_config = BotConfig.objects.get(id='ALLOWED_CLIENTS')
        except models.ObjectDoesNotExist:
            return []
        value = bot_config.value
        if ',' in value:
            allowed_clients = [s.strip() for s in value.split(',')]
        else:
            allowed_clients = [value.strip()]
        return allowed_clients
Beispiel #3
0
def get_context_extras():
    return {
        'title': t('Переключатели'),
        'no_switches': t('Здесь пока нет переключателей - настройте их'),
        'sensor_expired': t('Устаревшие данные датчика'),
        'updated': t('Обновлено'),
        'schedule_tasks_title': t('Плановые задачи'),
        'temper_tasks_title': t('Задачи по температуре и влажности')
    }
Beispiel #4
0
def validate_cron(cron_str):
    valid_chars = '-/,*0123456789 '
    e = t('Невалидная нотация. Строка должна содержать только знаки {0}'
          ', и четыре одинарных пробела. Удобно настроить и скопировать строку'
          ' можно здесь{1}')
    e = e.format(valid_chars, ' - https://crontab.guru/')
    try:
        pycron.is_now(cron_str)
        cron_descriptor.get_description(cron_str)
    except Exception:
        raise ValidationError(e)
    spaces_counter = 0
    for char in cron_str:
        if char == ' ':
            spaces_counter += 1
        if char not in valid_chars:
            raise ValidationError(e)
    if spaces_counter != 4:
        raise ValidationError(e)
    return cron_str
Beispiel #5
0
import pycron
import cron_descriptor
from django.core.exceptions import ValidationError
from main.translations import t


CRON_URL = '<a href="https://crontab.guru/" target="blank">' + \
                t('здесь') + '</a>'


def validate_cron(cron_str):
    valid_chars = '-/,*0123456789 '
    e = t('Невалидная нотация. Строка должна содержать только знаки {0}'
          ', и четыре одинарных пробела. Удобно настроить и скопировать строку'
          ' можно здесь{1}')
    e = e.format(valid_chars, ' - https://crontab.guru/')
    try:
        pycron.is_now(cron_str)
        cron_descriptor.get_description(cron_str)
    except Exception:
        raise ValidationError(e)
    spaces_counter = 0
    for char in cron_str:
        if char == ' ':
            spaces_counter += 1
        if char not in valid_chars:
            raise ValidationError(e)
    if spaces_counter != 4:
        raise ValidationError(e)
    return cron_str
Beispiel #6
0
class RelayAppConfig(AppConfig):
    name = 'relay_app'
    verbose_name = ' ' + t('Переключатели')
Beispiel #7
0
 class Meta:
     ordering = ['order_id']
     verbose_name = t('Настройка пина')
     verbose_name_plural = '    ' + t('Настройки пинов')
Beispiel #8
0
 class Meta:
     ordering = ['pin_data']
     verbose_name = t('Настройка задачи по датчику')
     verbose_name_plural = ' ' + t('Настройки задач по датчику')
Beispiel #9
0
class TemperConfig(models.Model):
    ACT_CHOICES = [(1, t('Включать')), (0, t('Выключать'))]
    TEMP_CHOICES = [('t_greater', t('при температуре более чем')),
                    ('t_less', t('при температуре менее чем')),
                    ('h_greater', t('при влажности более чем')),
                    ('h_less', t('при влажности менее чем'))]
    pin_data = models.ForeignKey(PinData,
                                 on_delete=models.CASCADE,
                                 related_name='tempers',
                                 verbose_name=t('Переключатель'))
    compare_data = models.CharField(max_length=10,
                                    verbose_name=t('Сравнение'),
                                    help_text=t('Сравнение показателя'),
                                    choices=TEMP_CHOICES)
    num_data = models.SmallIntegerField(verbose_name=t('Значение'),
                                        help_text=t('Значение параметра (граду'
                                                    'сы цельсия или проценты '
                                                    'влажности)'))
    reverse = models.BooleanField(default=False,
                                  verbose_name=t('Иначе выполнять обратное'),
                                  help_text=t(
                                      'Для "Включать при температуре ме'
                                      'нее чем 18 градусов", при повы'
                                      'шении выше 18 градусов сразу '
                                      'выполнит обратное действие - '
                                      'выключит.'))
    action = models.PositiveSmallIntegerField(
        choices=ACT_CHOICES,
        verbose_name=t('Действие'),
        help_text=t('Действие над переключателем'))
    active = models.BooleanField(default=True,
                                 verbose_name=t('Активно'),
                                 help_text=t('Активна ли эта задача'))
    cron_time = models.CharField(
        max_length=100,
        default=None,
        null=True,
        blank=True,
        verbose_name=t('Время срабатывания'),
        help_text=t('Нотация Cron, удобно составлять') + ' ' + CRON_URL,
        validators=[validate_cron])
    describe_cron = models.CharField(
        max_length=200,
        default=None,
        null=True,
        blank=True,
        verbose_name=t('Описание времени выполнения'))

    class Meta:
        ordering = ['pin_data']
        verbose_name = t('Настройка задачи по датчику')
        verbose_name_plural = ' ' + t('Настройки задач по датчику')

    def __str__(self):
        return str(self.pin_data) + ' ' + str(self.action)

    @property
    def num_data_with_unit(self):
        return str(self.num_data) + self.get_unit()

    num_data_with_unit.fget.short_description = t('Значение')

    @property
    def pin_name(self):
        return self.pin_data.action_name

    pin_name.fget.short_description = t('Переключатель')

    def get_temp_choise_verbose(self):
        for c in TemperConfig.TEMP_CHOICES:
            if self.compare_data == c[0]:
                return c[1]

    def get_action_name(self):
        for value, verbose in TemperConfig.ACT_CHOICES:
            if self.action == value:
                return verbose

    def get_unit(self):
        if 't_' in self.compare_data:
            return '℃'
        else:
            return '%'

    def get_reverse_verbose(self, prefix=', '):
        if self.reverse:
            if self.action:
                return prefix + t('иначе выключать')
            else:
                return prefix + t('иначе включать')
        else:
            return ''

    def get_timer_description(self, prefix=', '):
        s = ''
        if self.cron_time and self.describe_cron:
            s = prefix + self.describe_cron.lower()
        return s

    def as_dict(self):
        return {
            'id': self.pk,
            'pin_board_num': self.pin_data.board_num,
            'pin_command': self.pin_name,
            'compare_data': self.compare_data,
            'compare_data_verbose': self.get_temp_choise_verbose(),
            'num_data': self.num_data,
            'reverse': self.reverse,
            'unit': self.get_unit(),
            'action': self.action,
            'action_name': self.get_action_name(),
            'active': int(self.active),
            'cron_time': self.cron_time,
            'cron_verbose': self.describe_cron,
            'full_report': self.get_full_report()
        }

    def get_full_report(self):
        return '{0} {1} {2} {3}'.format(self.get_action_name().capitalize(),
                                        self.pin_name.lower(),
                                        self.get_temp_choise_verbose(),
                                        self.num_data_with_unit) + \
                self.get_reverse_verbose() + self.get_timer_description()
Beispiel #10
0
class PinData(models.Model):
    BOARD_CHOICES = [(i, 'BOARD-' + str(i)) for i in settings.BOARD_NUMS]

    objects = PinDataQuerySet.as_manager()

    order_id = models.PositiveIntegerField(
        verbose_name=t('Порядковый номер'),
        help_text=t('Для отображения в списке'),
        unique=True)
    board_num = models.IntegerField(verbose_name=t('Номер пина (BOARD)'),
                                    help_text=t('Нумерация GPIO BOARD'),
                                    unique=True,
                                    choices=BOARD_CHOICES)
    command = models.CharField(max_length=30,
                               unique=True,
                               verbose_name=t('Назначение переключателя'),
                               help_text=t('Например "Свет на кухне"'))
    comment = models.CharField(max_length=250,
                               verbose_name=t('Комментарий'),
                               help_text=t('Необязательное поле'),
                               blank=True,
                               null=True)
    state = models.BooleanField(default=False,
                                verbose_name=t('Текущее состояние'),
                                help_text=t('Включен или выключен'))
    invert_state = models.BooleanField(
        default=False,
        verbose_name=t('Инвертировать состояние'),
        help_text=t('Инвертировать состояние пинов'
                    ' на уровне GPIO (т.е. "Включ'
                    'енный пин" = GPIO.LOW (gnd))'))
    visible = models.BooleanField(default=True,
                                  verbose_name=t('Активен'),
                                  help_text=t('Отображать ли в интерфейсах?'))

    class Meta:
        ordering = ['order_id']
        verbose_name = t('Настройка пина')
        verbose_name_plural = '    ' + t('Настройки пинов')

    def __str__(self):
        return self.command

    @property
    def action_name(self):
        return '"' + self.command + '"'

    def as_dict(self):
        return {
            'order_id': self.order_id,
            'board_num': self.board_num,
            'name': self.command,
            'comment': self.comment,
            'state': self.state,
            'command_verbose': self.action_name,
            'invert_state': self.invert_state
        }

    def save(self, *args, **kwargs):
        ret_code = switch_gpio(self.board_num, self.state, self.invert_state)
        if ret_code:  # assume error here
            return
        if not self.visible:
            self.state = False
        super(PinData, self).save(*args, **kwargs)

    def delete(self, *args, **kwargs):
        ret_code = switch_gpio(self.board_num, False, self.invert_state)
        if ret_code:  # assume error here
            return
        super(PinData, self).delete(*args, **kwargs)
Beispiel #11
0
class ScheduleConfig(models.Model):
    ACT_CHOICES = [(1, t('Включать')), (0, t('Выключать')),
                   (2, t('Переключать'))]
    pin_data = models.ForeignKey(PinData,
                                 on_delete=models.CASCADE,
                                 related_name='schedules',
                                 verbose_name=t('Переключатель'))
    cron_time = models.CharField(
        max_length=100,
        default='* * * * *',
        verbose_name=t('Время срабатывания'),
        help_text=t('Нотация Cron, удобно составлять') + ' ' + CRON_URL,
        validators=[validate_cron])
    describe_cron = models.CharField(
        max_length=200,
        default=t('Каждую минуту'),
        verbose_name=t('Описание времени выполнения'))
    action = models.PositiveSmallIntegerField(
        choices=ACT_CHOICES,
        verbose_name=t('Действие'),
        help_text=t('Действие над переключателем'))
    active = models.BooleanField(default=True,
                                 verbose_name=t('Активно'),
                                 help_text=t('Активна ли эта задача'))
    comment = models.CharField(max_length=200,
                               verbose_name=t('Комментарий'),
                               blank=True,
                               null=True)

    class Meta:
        ordering = ['pin_data']
        verbose_name = t('Настройка задачи по таймеру')
        verbose_name_plural = '  ' + t('Настройки задач по таймеру')

    def __str__(self):
        return str(self.pin_data) + ' ' + str(self.action)

    @property
    def pin_name(self):
        return self.pin_data.action_name

    pin_name.fget.short_description = t('Переключатель')

    def as_dict(self):
        return {
            'id': self.pk,
            'pin_board_num': self.pin_data.board_num,
            'pin_command': self.pin_name,
            'cron_time': self.cron_time,
            'cron_verbose': self.describe_cron.lower(),
            'action': self.action,
            'action_name': self.get_action_name(),
            'active': int(self.active),
            'full_report': self.get_full_report()
        }

    def get_action_name(self):
        for value, verbose in ScheduleConfig.ACT_CHOICES:
            if self.action == value:
                return verbose

    def get_full_report(self):
        return '{0} {1} {2}'.format(self.get_action_name().capitalize(),
                                    self.pin_name.lower(),
                                    self.describe_cron.lower())
Beispiel #12
0
 class Meta:
     ordering = ['id']
     verbose_name = t('Настройка телеграм-бота')
     verbose_name_plural = t('Настройки телеграм-бота')