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



  • @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 и уважуха" к вашей компании! И просто спасибо:)



  • @Alex_Jet:

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

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



  • @intrapro:

    @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 плагинов.

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

    Вот бы пример сценария где эти «пазлы» упорядоченно сложены! У меня в голове не укладывается). Есть 4 Счетчика воды, счётчик электроэнергии ( день/ ночь), Показания нужно передавать 17 числа каждого месяца. Как сформировать отчёт и выслать в УК?



  • @sergeyygr:

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

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

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



  • @Alex_Jet:

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

    @sergeyygr:

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

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

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



  • @intrahouse:

    @sergeyygr:

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

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

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

    Совершенно верно. Показания счетчиков на 17 число каждого месяца.



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

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



  • @intrahouse:

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

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

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



  • @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+ " куб.м");
    
        }
    });
    
    


  • @Alex_Jet:

    @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+ " куб.м");
    >       
    >     }
    > });
    > 
    

    Спасибо за подсказку! Все работает 😄 Сделал так:

    this.info("email","OWNER",`Электроэнергия Т1: ${meter6.value.toFixed(0)} \n Электроэнергия Т2: ${meter7.value.toFixed(0)}



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

    То же, например, с блокировкой мультисценариев и блокировкой канала плагина 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() { 
      	.....
      },
    ...
    
    
    


  • Есть блок-схема: лог, таймер, присваивание значения, но почему-то создается 4 таймера и значение присваивается только в одном случае. Не верно строится скрипт из блоксхемы. Причем блок "лог" пришлось добавить потому что нельзя завести 4 входящие линии в таймер. Можно это тоже поправить?

    /** 
    * @name TelegramControl  
    * @desc  
    * @version 4 
    */
    
    const SENSORA15 = Device("SENSORA15");
    const ACTOR5 = Device("ACTOR5");
    const SWITCH1 = Device("SWITCH1");
    
    startOnChange([SENSORA15]);
    
    script({
      start() { 
        if (SENSORA15.value == "/lightoff") {
          this.doAll({ type: '510' },"off");
          this.log(``);
          this.startTimer("T1",1,"onTimerT1");
        }
        if (SENSORA15.value == "/securityon") {
          ACTOR5.on();
          this.log(``);
          this.startTimer("T2",1,"onTimerT2");
        }
        if (SENSORA15.value == "/securityoff") {
          ACTOR5.off();
          this.log(``);
          this.startTimer("T3",1,"onTimerT3");
        }
        if (SENSORA15.value == "/openhalldoor") {
          SWITCH1.on();
          this.log(``);
          this.startTimer("T4",1,"onTimerT4");
        }
      },
      onTimerT1() { 
         SENSORA15.setParam("value",100);
      },
      onTimerT2() { 
      },
      onTimerT3() { 
      },
      onTimerT4() { 
      }
    })
    
    
    

    sc1.JPG



  • Есть тригер : датчик температуры, значения до десятой, н.р 5.3 град. Сейчас тригер срабатывает при каждом изменении на 0.1 град. Как сделать чтобы он срабатывал по целым числам, т.е при изменении на один градус ? Можно загрубить значение при выводе с датчика, но это нежелательно.


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