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



  • @intrapro:

    @artem521:

    Здравствуйте. У меня другая проблема с датчиком освещенности. Сценарий такой: если значение равно 0 то лампа включается, если значение больше 100 то лампа выключается. Но проблема вот в чем, если я рукой прикрываю датчик чтобы он плавно менял значение стремясь к 0 и в итоге когда датчик увидел 0, то лапа не срабатывает, а если я резко делаю полную темноту датчику, то все отрабатывает. Подскажите, почему так? P.S. На устройстве.megad 2561 И еще не могу найти звуковое уведомление при событии устройства.

    Возможно, нужно добавить условие при выполнении команд:

    Включать, если значение < 100 AND лампа выключена (off)

    Выключать, если значение > 100 AND лампа включена (on)

    Спасибо, буду пробовать.



  • @intrapro:

    @artem521:

    Здравствуйте. У меня другая проблема с датчиком освещенности. Сценарий такой: если значение равно 0 то лампа включается, если значение больше 100 то лампа выключается. Но проблема вот в чем, если я рукой прикрываю датчик чтобы он плавно менял значение стремясь к 0 и в итоге когда датчик увидел 0, то лапа не срабатывает, а если я резко делаю полную темноту датчику, то все отрабатывает. Подскажите, почему так? P.S. На устройстве.megad 2561 И еще не могу найти звуковое уведомление при событии устройства.

    Возможно, нужно добавить условие при выполнении команд:

    Включать, если значение < 100 AND лампа выключена (off)

    Выключать, если значение > 100 AND лампа включена (on)

    Попробовал, не чего не поменялось.

    01.02 16:03:19.058 megad1:

    01.02 16:03:19.059 megad1: localhost => 192.168.0.16 HTTP GET /sec/?pt=30&cmd=get

    01.02 16:03:19.077 megad1: localhost <= 192.168.0.16 response: statusCode=200 contentType = text/html

    01.02 16:03:19.078 megad1: body: 13.05

    01.02 16:03:19.079 IH: get [{"id":"30","value":"13.05"}]

    01.02 16:03:19.080 IH: set {"SENSORA1":{"aval":"13.05","err":0}}

    01.02 16:03:19.860 megad1:

    01.02 16:03:19.861 megad1: localhost => 192.168.0.16 HTTP GET /sec/?cmd=all

    01.02 16:03:19.878 megad1: localhost <= 192.168.0.16 response: statusCode=200 contentType = text/html

    01.02 16:03:19.879 megad1: body: ON/1;OFF;ON;ON;ON;214;ON;ON;ON;ON;255;OFF;ON;OFF;ON;ON;OFF;ON;ON;ON;ON;ON;ON;ON;ON;ON;ON;ON;ON;ON;13.05;OFF;ON;ON;ON;ON;ON;ON

    01.02 16:03:19.881 IH: get [{"id":"1","value":"0"},{"id":"30","value":"13.05"}]

    01.02 16:03:19.882 IH: set {"VENT1":{"dval":"0","err":0},"SENSORA1":{"aval":"13.05","err":0}}

    01.02 16:03:20.262 megad1:

    01.02 16:03:20.263 megad1: localhost => 192.168.0.16 HTTP GET /sec/?pt=30&cmd=get

    01.02 16:03:20.284 megad1: localhost <= 192.168.0.16 response: statusCode=200 contentType = text/html

    01.02 16:03:20.285 megad1: body: 13.05

    01.02 16:03:20.287 IH: get [{"id":"30","value":"13.05"}]

    01.02 16:03:20.287 IH: set {"SENSORA1":{"aval":"13.05","err":0}}

    01.02 16:03:21.068 megad1:

    01.02 16:03:21.068 megad1: localhost => 192.168.0.16 HTTP GET /sec/?cmd=all

    01.02 16:03:21.090 megad1: localhost <= 192.168.0.16 response: statusCode=200 contentType = text/html

    01.02 16:03:21.091 megad1: body: ON/1;OFF;ON;ON;ON;208;ON;ON;ON;ON;255;OFF;ON;OFF;ON;ON;OFF;ON;ON;ON;ON;ON;ON;ON;ON;ON;ON;ON;ON;ON;13.05;OFF;ON;ON;ON;ON;ON;ON

    01.02 16:03:21.092 IH: get [{"id":"1","value":"0"},{"id":"30","value":"13.05"}]

    01.02 16:03:21.093 IH: set {"VENT1":{"dval":"0","err":0},"SENSORA1":{"aval":"13.05","err":0}}

    01.02 16:03:21.470 megad1:

    01.02 16:03:21.471 megad1: localhost => 192.168.0.16 HTTP GET /sec/?pt=30&cmd=get

    01.02 16:03:21.482 megad1: localhost <= 192.168.0.16 response: statusCode=200 contentType = text/html

    01.02 16:03:21.483 megad1: body: 13.05

    01.02 16:03:21.483 IH: get [{"id":"30","value":"13.05"}]

    01.02 16:03:21.484 IH: set {"SENSORA1":{"aval":"13.05","err":0}}

    01.02 16:03:22.274 megad1:

    01.02 16:03:22.275 megad1: localhost => 192.168.0.16 HTTP GET /sec/?cmd=all

    01.02 16:03:22.299 megad1: localhost <= 192.168.0.16 response: statusCode=200 contentType = text/html

    01.02 16:03:22.299 megad1: body: ON/1;OFF;ON;ON;ON;208;ON;ON;ON;ON;255;OFF;ON;OFF;ON;ON;OFF;ON;ON;ON;ON;ON;ON;ON;ON;ON;ON;ON;ON;ON;13.05;OFF;ON;ON;ON;ON;ON;ON

    01.02 16:03:22.300 IH: get [{"id":"1","value":"0"},{"id":"30","value":"13.05"}]

    01.02 16:03:22.301 IH: set {"VENT1":{"dval":"0","err":0},"SENSORA1":{"aval":"13.05","err":0}}
    0.png



  • @homa:

    Что-то не получается в блок-схемах накидать сценарий, никак не придумаю логику:

    Есть два блока питания (резервирование) я знаю нагрузку на них. на активном нагрузка > 0, на неактивном =0. Нужно присылать уведомление при изменении активного БП и текущую нагрузку на них.

    Все сценарии, которые написал оповещают о каждом изменении нагрузки на блок питания

    Вот пример для одного блока питания:
    scenbp1.jpg
    Таймер поставил для того чтобы в сообщении передавалось напряжение с учетом переходных процессов при включении блока питания.

    Само сообщение: БП1 - включен (напряжение ${BP1.value}В)

    ${x.value} - так можно передать значение value

    Суть сценария:

    Нам нужно чтобы при включении блока питания BP1 передать сообщение об этом событии один раз. При этом нужно передать еще и напряжение. При выключении просто сообщаем один раз о выключении.

    Для такого сценария нужна информация о предыдущем состоянии блока питания.

    Так как в блок-схемах нет возможности использовать глобальные переменные, воспользуемся параметром setpoint. Будем считать, если setpoint=0, блок питания выключен. Если setpoint=1, включен.

    В итоге получаем.

    Если блок питания был выключен (setpoint=0) и включается (value>0), то через 5 сек даем сообщение о включении и устанавливаем setpoint в единицу.

    Если блок питания был включен (setpoint=1) и выключается (value=0), даем сообщение об отключении блока питания и устанавливаем setpoint в ноль.

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

    Если посмотреть скрипт этой блок-схемы, там все намного короче:

    /** 
    * @name Контроль блоков питания  
    * @desc  
    * @version 4 
    */
    
    const BP1 = Device("BP1");
    
    startOnChange([BP1]);
    
    script({
      start() { 
        if ((BP1.value > 0) && (BP1.setpoint == 0)) {
          this.startTimer("T1",5,"onTimerT1");
        }
        if ((BP1.value == 0) && (BP1.setpoint == 1)) {
          BP1.setParam("setpoint",0);
          this.log(`БП1 - выключен`);
        }
      },
      onTimerT1() { 
         this.log(`БП1 - включен (напряжение ${BP1.value}В)`);
         BP1.setParam("setpoint",1);
      }
    })
    
    

    Прошу обновить систему до последней версии 4.4.17. Во время подготовки этого сценария найдена ошибка. Не передавалась константа в виде числа



  • @intrahouse:

    Попробовал, не чего не поменялось.

    Вы поставили элемент AND, и ничего к нему не привязали.

    Условие AND означает: если это=True и это=True то True, иначе False

    Попробуйте так:
    scenlamp1.jpg
    Если датчик освещенности больше 23 и лампа выключена, включить лампу.

    Если датчик освещенности меньше 1 (можно как у вас =0) и лампа включена, выключить лампу.

    Обновите систему до версии 4.4.17



  • Большое спасибо. Все работает корректно.



  • Добрый день!

    А все таки, есть ли способ запуска звукового файла из сценария? 😉



  • @sergeyygr:

    Добрый день!

    А все таки, есть ли способ запуска звукового файла из сценария? 😉

    Добрый день, уточните пожалуйста через звуковой выход сервера?



  • @dev:

    @sergeyygr:

    Добрый день!

    А все таки, есть ли способ запуска звукового файла из сценария? 😉

    Добрый день, уточните пожалуйста через звуковой выход сервера?

    Да, через звуковую карту сервера.



  • @sergeyygr:

    @dev:

    @sergeyygr:

    Добрый день!

    А все таки, есть ли способ запуска звукового файла из сценария? 😉

    Добрый день, уточните пожалуйста через звуковой выход сервера?

    Да, через звуковую карту сервера.

    В командной строке выполнения файла так:

    sever@sergey mplayer /home/sound/…sound1.mp3

    Вот бы эту команду из сценария передать.



  • Добрый день!

    Написал сценарий для тестирования выгоды перехода на трехтарифный расчет электроэнергии:

    /** 
    * @name ThreeTarif 
    * @desc  
    * @version 4 
    */
    
    const T1 = Device("METER18"); 
    const T2 = Device("METER17");
    const T3 = Device("METER19");
    const mmr = Device("METER20");
    const day = Device("METER6");
    const night = Device("METER5");
    const pulse3t = Device("SENSOR2");
    
    startOnChange(pulse3t); 
    
    script({
        Weight:0.0002, // вес импульса
        T1r:4.9, //свет T1
        T2r:1.6, //свет T2
        T3r:3.77, //свет T3
            start() {
            const dt = new Date();
        mmrbf = (t1.value-t1.getParam('uptoMonth'))*t1r+(t2.value-t2.getParam('uptoMonth'))*t2r+(t3.value-t3.getParam('uptoMonth'))*t3r;
        mmrbf.toFixed(2)
        this.assign(mmr, 'aval', mmrbf);
        //eesum.toFixed(2)
        //cwsum = (metercwv.value + metercwt.value - metercwv.getParam('uptoMonth') - metercwt.getParam('uptoMonth'))*this.cw
            if (dt.getHours() < 7 || dt.getHours()>=23) {  // c 23:00 - 7:00 ночной тариф T2 
              this.assign(T2, 'aval', T2.value+this.Weight);
              return false;
            } 
           if (dt.getHours() >= 7 || dt.getHours()<10) {  // c 7:00 - 10:00 тариф T1
              this.assign(T1, 'aval', T1.value+this.Weight);
            } 
            if (dt.getHours() >= 10 || dt.getHours()<17) {  // c 10:00 - 17:00 тариф T3
              this.assign(T3, 'aval', T3.value+this.Weight);
              return false;
            } 
            if (dt.getHours() >= 17 || dt.getHours()<21) {  // c 17:00 - 21:00 тариф T1
              this.assign(T1, 'aval', T1.value+this.Weight);
              return false;
            } 
            if (dt.getHours() >= 21 || dt.getHours()<23) {  // c 21:00 - 23:00 тариф T3
              this.assign(T3, 'aval', T3.value+this.Weight);
              return false;
            } 
    
        } 
    });
    
    

    Но он почему-то не срабатывает, отладчик пустой как будто не отрабатывает триггер "startOnChange(pulse3t)" хотя в соседнем сценарии по этому триггеру все работает



  • Добрый день!

    Есть простейшее расписание - включить на закате две лампочки, но включается только одна. Причем включается та, которая будет первой в списке)) Пересоздать задачу не помогает, но в журнале отображается запись "Команда on Расписание"
    2lamps.JPG



  • @homa:

    Добрый день!

    Написал сценарий для тестирования выгоды перехода на трехтарифный расчет электроэнергии:

    > /** 
    > * @name ThreeTarif 
    > * @desc  
    > * @version 4 
    > */
    > 
    > const T1 = Device("METER18"); 
    > const T2 = Device("METER17");
    > const T3 = Device("METER19");
    > const mmr = Device("METER20");
    > const day = Device("METER6");
    > const night = Device("METER5");
    > const pulse3t = Device("SENSOR2");
    > 
    > startOnChange(pulse3t); 
    > 
    > script({
    >     Weight:0.0002, // вес импульса
    >     T1r:4.9, //свет T1
    >     T2r:1.6, //свет T2
    >     T3r:3.77, //свет T3
    >         start() {
    >         const dt = new Date();
    >     mmrbf = (t1.value-t1.getParam('uptoMonth'))*t1r+(t2.value-t2.getParam('uptoMonth'))*t2r+(t3.value-t3.getParam('uptoMonth'))*t3r;
    >     mmrbf.toFixed(2)
    >     this.assign(mmr, 'aval', mmrbf);
    >     //eesum.toFixed(2)
    >     //cwsum = (metercwv.value + metercwt.value - metercwv.getParam('uptoMonth') - metercwt.getParam('uptoMonth'))*this.cw
    >         if (dt.getHours() < 7 || dt.getHours()>=23) {  // c 23:00 - 7:00 ночной тариф T2 
    >           this.assign(T2, 'aval', T2.value+this.Weight);
    >           return false;
    >         } 
    >        if (dt.getHours() >= 7 || dt.getHours()<10) {  // c 7:00 - 10:00 тариф T1
    >           this.assign(T1, 'aval', T1.value+this.Weight);
    >         } 
    >         if (dt.getHours() >= 10 || dt.getHours()<17) {  // c 10:00 - 17:00 тариф T3
    >           this.assign(T3, 'aval', T3.value+this.Weight);
    >           return false;
    >         } 
    >         if (dt.getHours() >= 17 || dt.getHours()<21) {  // c 17:00 - 21:00 тариф T1
    >           this.assign(T1, 'aval', T1.value+this.Weight);
    >           return false;
    >         } 
    >         if (dt.getHours() >= 21 || dt.getHours()<23) {  // c 21:00 - 23:00 тариф T3
    >           this.assign(T3, 'aval', T3.value+this.Weight);
    >           return false;
    >         } 
    > 
    >         
    >         
    >     } 
    > });
    > 
    

    Но он почему-то не срабатывает, отладчик пустой как будто не отрабатывает триггер "startOnChange(pulse3t)" хотя в соседнем сценарии по этому триггеру все работает

    PS разобрался, к числовым константам нужно обращаться как this.t1r



  • Подскажите по расписанию мультисценарий отработает по всем группам устройств?

    Кстати, обратил внимание, что если меняешь "Название" сценария, то его имя в Расписаниях остается старое. Вероятно поменяется только после перезагрузки iH?



  • @homa:

    Добрый день!

    Есть простейшее расписание - включить на закате две лампочки, но включается только одна. Причем включается та, которая будет первой в списке)) Пересоздать задачу не помогает, но в журнале отображается запись "Команда on Расписание"

    Спасибо. Проверим, пофиксим



  • @Alex_Jet:

    Подскажите по расписанию мультисценарий отработает по всем группам устройств?

    Нет, в списке же вы выбираете конкретный экземпляр сценария, в скобках набор устройств.

    @Alex_Jet:

    Кстати, обратил внимание, что если меняешь "Название" сценария, то его имя в Расписаниях остается старое. Вероятно поменяется только после перезагрузки iH?

    Да, после перезагрузки конечно поменяется. Проверим, постараемся исправить



  • @denis-000:

    Доброго времени суток. Пытаюсь изучить сценарии графические и у меня вопрос. Руководствуясь документацией, я маленько запутался ( фото прилагаю ) там указано, что " От датчика температуры (STEMP_1_1) поступает значение (VALUE) и сравнивается с уставкой (SETPOINT). Если температура меньше уставки, включаем батарею отопления (RADIATOR_1_1). Если больше, выключаем.

    Все работает. Температура в комнате регулируется " непонятно то, с чем сравнивается, если там не указана константа, а указано заданное значение ( setpoint ). Если смотреть эту картинку, откуда берется это заданное значение, как его задать?

    Отсюда: (см.скрин)

    В свойствах устройства должна стоять галка "есть уставка". Задать значение можно длительным нажатием на элемент
    ustavka.JPG



  • Здравствуйте.

    Решаю следующую задачу.

    Кнопки меняют значение виртуального актуатора.

    По факту изменения значения этого виртуального актуатора запускается скрипт, который присваивает измененное значение реальному актуатору, и тот передает значение по модбас физическуму устройству.

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

    Добавил таймеры.

    Задумка - записывать измененное значение в реальный актуатор спустя 2 сек. При этом, повторное нажатие кнопки до истечения срока останавливает таймер, и запускает его снова.

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

    Но ничего никуда не пишется.

    Пенял на одинарные ковычки. Те, которые указаны в описании стстема отвергла (не дала исполняемую функцию в this.startTimer('T1', 2.0, 'ActComf.setValue(newvalue)'); взять в те ковычни, которые у вас на сайте указаны).

    Поменял на другие - тоже нет результата.

    И без ковычек не работает 🙂

    const ActRz = Device("ActorA", "Режим отопления");
    const ActComf = Device("ActorA", "Уставка Комфорт");
    const ActDsp = Device("ActorA", "Отображение уставки текущего режима");
    
    startOnChange(ActDsp);
    
    script({
        start() {
          this.addTimer(T1);
          if (ActRz.value === 0) {
            let newvalue = ActDsp.value;
            this.stopTimer('T1');
            this.startTimer('T1', 2.0, 'ActComf.setValue(newvalue)');
            return;
          }  
        }
    });
    
    

    Что у меня не так?

    И так не работает

    start() {
         this.addTimer(T1);
          if (ActRz.value === 0) {
            let newvalue = ActDsp.value;
            if (this.timer.T1 == on) this.stopTimer.T1;
            this.startTimer(T1, 2.0, ActComf.setValue(newvalue));
            return;
          }  
    
    


  • Кажется нашел

    script ({
      start() {
        lamp.on();
        this.log('Hello, World!');
        this.startTimer('T1', 10, 'next'); 
        // Обратите внимание, здесь мы не определяем callback напрямую,
        // а просто сообщаем движку имя метода, который нужно будет запустить
      },
    
      next() {
         lamp.off();
      }  
    });
    
    


  • const ActRz = Device("ActorA", "Режим отопления");
    const ActComf = Device("ActorA", "Уставка Комфорт");
    const ActDsp = Device("ActorA", "Отображение уставки текущего режима");
    
    startOnChange(ActDsp);
    
    script({
        start() {
          this.addTimer(T1);
          if (ActRz.value === 0) {
            let newvalue = ActDsp.value;
            this.stopTimer('T1');
            this.startTimer('T1', 2.0, 'next');
            return;
          }  
        },
     next() {
        ActComf.setValue(newvalue);
      }     
    });
    
    

    не работает.



  • @Erik:

    > const ActRz = Device("ActorA", "Режим отопления");
    > const ActComf = Device("ActorA", "Уставка Комфорт");
    > const ActDsp = Device("ActorA", "Отображение уставки текущего режима");
    > 
    > startOnChange(ActDsp);
    > 
    > script({
    >     start() {
    >       this.addTimer(T1);
    >       if (ActRz.value === 0) {
    >         let newvalue = ActDsp.value;
    >         this.stopTimer('T1');
    >         this.startTimer('T1', 2.0, 'next');
    >         return;
    >       }  
    >     },
    >  next() {
    >     ActComf.setValue(newvalue);
    >   }     
    > });
    > 
    

    не работает.

    Добрый день!

    Здесь есть синтаксическая ошибка (объявление newvalue) и структурная

    Попробуйте написать так, чуть позже прокомментирую:

    const ActRz = Device("ActorA", "Режим отопления");
    const ActComf = Device("ActorA", "Уставка Комфорт");
    const ActDsp = Device("ActorA", "Отображение уставки текущего режима");
    
    startOnChange(ActDsp);
    
    script({
        newvalue:0,
    
        start() {
           if (ActRz.value === 0) {  // Не совсем понятно, что это. Но надо, так надо
            	this.newvalue = ActDsp.value;
            	this.log('start value ' + this.newvalue)
            	this.startTimer('T1', 2, 'next');
            	this.addListener(ActDsp, 'resetTimer');
           }
        },
    
       next() {
       	  this.log('SET '+this.newvalue)
        	  ActComf.setValue(this.newvalue);
              this.exit();
       },
    
      resetTimer() {
            if (this.newvalue != ActDsp.value) {      
             	 this.newvalue = ActDsp.value;
             	 this.log('new value '+this.newvalue)
             	 this.stopTimer('T1');
            	 this.startTimer('T1', 2, 'next');
            }  
      }
    });
    
    
    

    this.log вставлен, чтобы отследить работу алгоритма в отладчике или журнале


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