Сценарии - новая версия API



  • @filippovsky:

    Скажите, пожалуйста, как можно привязать запуск сценария к моменту запуска сервера?

    Условный пример:

    Есть дискретный актуатор "Солнце".

    По расписанию "На рассвете" оно включается.

    По расписанию "На закате" оно выключается.

    Но если сервер включен между этими событиями посреди дня - то Солнце будет выключено, пока не наступит ближайший рассвет.

    Можно написать сценарий, в котором явно установить состояние Солнца в зависимости от текущего времени, времени рассвета и заката.

    Но как заставить этот сценарий запуститься в момент запуска сервера, чтобы инициализировать Солнце?

    Нужно в сценарий включить функцию boot, которая должна вернуть результат true, чтобы сценарий запустился при старте сервера. Выполнение, как обычно, начнется с функции start()

    boot() {
        return true; // Всегда запускать при старте сервера
    },
    
    start() {
       //  
    } 
    
    

    Эта возможность не документирована. Возможно, синтаксис изменится при доработке API сценариев.



  • @intrapro:

    Нужно в сценарий включить функцию boot, которая должна вернуть результат true, чтобы сценарий запустился при старте сервера.

    Эта возможность не документирована. Возможно, синтаксис изменится при доработке API сценариев.

    Спасибо большое



  • Можно попросить добавить в окно отладчика сценариев кнопку "Пробный запуск сценария"?

    Сейчас "Пробный запуск" можно сделать из меню по кнопке в верхней части экрана, но при открытом отладчике эта кнопка становится disabled.

    В итоге невозможно сделать РУЧНОЙ пробный запуск сценария с просмотром в отладчике.
    ih02.jpg



  • @filippovsky:

    Можно попросить добавить в окно отладчика сценариев кнопку "Пробный запуск сценария"?

    Сейчас "Пробный запуск" можно сделать из меню по кнопке в верхней части экрана, но при открытом отладчике эта кнопка становится disabled.

    В итоге невозможно сделать РУЧНОЙ пробный запуск сценария с просмотром в отладчике.

    Тоже соглашусь с этим. Очень неудобно держать открытыми 4-5 (2 для сценариев, 2 для плагинов и 1 для изменения разных настроек) окон PM для отладки!

    Кстати, по поводу:

    1. Реализации "cron" для сценариев (запуск сценариев для проверки состояния устройств)

    2. Доступности из сценариев "журнал устройств" (для принудительного запуска насосов/котлов/кранов/клапанов если их период простоя велик)

    3. Доступности из сценариев данных по устройству из БД (для составления и отправки месячной сводки в управляющие компании)

    4. Доступности из сценариев пользовательских журналов (создавать журналы можно, но писать в них логи пока никак)

    Какие-нибудь комментарии будут? Даже не комментарии, а возможная реализация и ее примерный срок.

    По столбцам ID у объектов/зон/систем/устройств уже сообщал свое пожелание выше… хотя тут обнаружил, что система теперь запоминает расположение столбцов. То есть если столбцы перенести как нужно администратору системы, то они в таком виде и останутся при следующим заходе в pm?



  • Доброго времени суток. Помогите пожалуйста сообразить сценарий. Смысл такой: Имеются 2 датчика E18-D80NK которые будут вести подсчет людей зашедших/вышедших из комнаты. Допустим зашло 2 человека, один человек вышел- свет горит, вышел второй человек- свет погас. Также дополнить все это дело датчиком освещенности, что это все работает с условием что если допустим выше 200 lux свет не горит, 100 lux горит.



  • @filippovsky:

    Можно попросить добавить в окно отладчика сценариев кнопку "Пробный запуск сценария"?

    Сейчас "Пробный запуск" можно сделать из меню по кнопке в верхней части экрана, но при открытом отладчике эта кнопка становится disabled.

    В итоге невозможно сделать РУЧНОЙ пробный запуск сценария с просмотром в отладчике.

    Да, Вы правы, постараемся добавить в одной из ближайших версий



  • @Alex_Jet:

    Кстати, по поводу:

    1. Реализации "cron" для сценариев (запуск сценариев для проверки состояния устройств)

    Будет в конце месяца для простых и мультисценариев (пока без блок-схем)

    @Alex_Jet:

    2. Доступности из сценариев "журнал устройств" (для принудительного запуска насосов/котлов/кранов/клапанов если их период простоя велик)

    Эта возможность уже добавлена в последней версии 4.5.3 как функция устройства device.getLog(<count>)

    Опциональный параметр count - количество записей.

    Возвращаются последние записи по возрастанию времени в виде массива с полями: значение, флаг ошибки, метка времени

    {val:"23.5", err:0, ts:1554076800000}
    
    

    Получить последние 10 записей:

    const logArr = dn.getLog(10);
    logArr.forEach(item => {
             this.log(JSON.stringify(item));
    });
    
    
    

    @Alex_Jet:

    4. Доступности из сценариев пользовательских журналов (создавать журналы можно, но писать в них логи пока никак)

    Концепция журналов будет пересматриваться, пока по срокам не ясно

    @Alex_Jet:

    По столбцам ID у объектов/зон/систем/устройств уже сообщал свое пожелание выше… хотя тут обнаружил, что система теперь запоминает расположение столбцов. То есть если столбцы перенести как нужно администратору системы, то они в таком виде и останутся при следующим заходе в pm?

    Да, это работает довольно давно.

    Запоминаются ширина и порядок столбцов. Настройки хранятся на сервере, для нового сеанса всегда используется последняя настройка.</count>



  • @Alex_Jet:

    3. Доступности из сценариев данных по устройству из БД (для составления и отправки месячной сводки в управляющие компании)

    Эта возможность добавлена в последней версии 4.5.3 в тестовом режиме.

    this.dbread({table:'consumption',dn:'METER1,METER2', start:'2019-04-01', end:'2019-04-01 23:59'}, 'onReady');
    
    

    Здесь результат сразу не возвращается, так как чтение происходит асинхронно. При получении данных будет вызвана функция сценария (здесь она называется onReady), в которой данные нужно обработать.

    onReady(result) {
      this.log('Получено записей: '+result.length);
       result.forEach(item => {
             this.log(JSON.stringify(item));
       });
    }
    
    
    

    Первый аргумент this.dbread - объект, содержащий критерии отбора данных:
    <list>* table - имя таблицы. Показания счетчиков хранятся в таблице consumption

    dn: ID устройства или список через запятую
    
    start: метка времени или строка, определяющая начало диапазона
    
    end: метка времени или строка, определяющая конец диапазона</list>
    

    То есть можно задавать временные точки по разному

      start:1554076800000 // timestamp
      start:Date.now()-3600000 // timestamp
      start:'2019-04-01'   // string дата 0 часов
      start:'2019-04-01 22:00' // string дата время
    
    
    

    Данные возвращаются в массиве, каждая запись содержит метку времени, ID устройства, значение:

    03.04 18:16:00.910 log: {"id":723,"ts":1554289199000,"dn":"METER1","val":"970.8578"}
    
    
    

    Надо иметь в виду, что запрашивание больших массивов информации и их длительная обработка внутри сценария может приводить к замедлению работы сервера в целом, так как сценарии выполняются в главном потоке сервера.

    Конечно, с получением показаний счетчиков на текущую дату никакой проблемы не будет. Но аппетит, как водится, приходит 🙂

    И почему бы не получить данные за год и посчитать что-нибудь этакое средневзвешенное…

    Если стоит задача обработки больших массивов, целесообразно будет применение сервисных плагинов (аддонов), механизм и API которых в данный момент разрабатывается. По сути это объединение функциональности плагина (независимый модуль, выполняемый в отдельном потоке) и сценария (доступ к данным ядра на уровне устройств и таблиц, подписка на события)

    Планируется в мае выпустить версию и опубликовать новое API плагинов.

    Цель - дать возможность пользователям разрабатывать свои плагины для решения прикладных задач, когда функционала сценариев недостаточно. Есть также идея делать это интерактивно, по аналогии со сценариями, чтобы порог вхождения был пониже.



  • Ну прям все круто! "Respect и уважуха" к вашей компании! И просто спасибо:)



  • @sergeyygr:

    Показания нужно передавать 17 числа каждого месяца. Как сформировать отчёт и выслать в УК?

    Не понятно. Про какой отчет идет речь?

    Нужно ведь отправлять показания счетчиков?



  • @Alex_Jet:

    Ну прям все круто! "Respect и уважуха" к вашей компании! И просто спасибо:)

    @sergeyygr:

    Присоединяюсь! Тоже с восхищением отношусь к вашей работе и мгновенной обратной связи!

    Коллеги, большое спасибо!

    Ваша поддержка придает уверенность и силы в дальнейшей работе



  • На сайте в блоге опубликовали статью по отправке показаний счетчиков https://ih-systems.com/ru/send_meter/

    Надеюсь, будет полезна.



  • @sergeyygr:

    Спасибо! Все отлично работает! Только в показаниях счетчиков электроэнергии, после запятой, число длинной с… километр :lol: А в настройках стоит 2 знака.

    Надо использовать функции js:

    const meter = Device("METER1_01");
    
    script({
        start() {
          //Сводка по газу
          let account = xxxxxx;
          let name = meter.name;
          let value = meter.value.toFixed(0);
    
          this.info("email", "GAS_SERVICE", account+ "*" +value);
          this.info("telegram", "OWNER", "Текущее показание '"+name+ "' - " +value+ " куб.м");
    
        }
    });
    
    


  • Интересный вопрос - если нужно временно отключить выполнение скрипта по расписанию, то как это можно сделать? Если убрать все дни недели, то он запуститься в уже назначенное время? Предусмотрите, пожалуйста, возможность блокировки задания в расписании. Конечно кто-то скажет что можно удалить и т.д., но если это надо временно, то почему бы не иметь возможность просто блокировать выполнение?

    То же, например, с блокировкой мультисценариев и блокировкой канала плагина Ping.



  • Вопрос правильный. Надо сделать.



  • @intrahouse:

    Вопрос правильный. Надо сделать.

    Отвечу сам на свой вопрос - если в сценарии не указать ни один день недели, то расписание срабатывает ежедневно в назначенное время.



  • Я имел ввиду то, что надо дать возможность временной блокировки пунктов расписания



  • @intrahouse:

    Я имел ввиду то, что надо дать возможность временной блокировки пунктов расписания

    Понятно! Я с этим тоже согласен.

    Просто проверил - можно ли таким способом не запускать расписание? - ответ нет, нельзя.



  • Есть сценарий, вкл. полотенцесушитель, взводим таймер на определенное время:

    /**

    • @name Вкл. полотенцесушителя на время

    • @desc Включает сушилку на заданное время

    • @version 4

    */

    const lamp = Device("SOCKET1_4",[

    {"name":"timeOff", "note":"Время работы, сек", "type":"number", "val":1800}

    ]);

    startOnChange([lamp]);

    script({

    start() {

    if (lamp.isOn()) {

    this.startTimer("T1",lamp.getParam("timeOff"),"onTimerT1");

    this.addListener(lamp, "onLamp");

    }

    },

    onTimerT1() {

    lamp.off();

    this.exit();

    },

    onLamp() {

    if (lamp.isOff()) {

    this.stopTimer("T1");

    this.exit();

    }

    }

    });

    Вроде всё работает, но обнаружил : при перезагрузке системы если таймер был взведен, устройство так и останется включенным. Как в этом случае поступить ?, может где-то прописать что должно быть вкл или выкл при перезагрузке ? или в сценарии как прописать что если после перезагрузки вкл, то снова взести таймер ?



  • @Anatol:

    Есть сценарий, вкл. полотенцесушитель, взводим таймер на определенное время:

    Вроде всё работает, но обнаружил : при перезагрузке системы если таймер был взведен, устройство так и останется включенным. Как в этом случае поступить ?, может где-то прописать что должно быть вкл или выкл при перезагрузке ? или в сценарии как прописать что если после перезагрузки вкл, то снова взести таймер ?

    Чтобы сценарий срабатывал при загрузке, нужно добавить функцию boot.

    Эта функция на старте проверяет, нужно ли запустить сценарий

    Если вернется true, то будет запущена функция start

    Сценарий всегда будет срабатывать при перезагрузке

    ....
    script({
      boot() { 
         return true;
      },
      start() { 
      	.....
      },
    ...
    
    
    

    Cработает только если устройство включено:

    ....
    script({
      boot() { 
         return lamp.isOn();
      },
      start() { 
      	.....
      },
    ...
    
    
    

Авторизуйтесь, чтобы ответить