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



  • @int144, никак! Я пробовал по разному, но пробел, отсутствие символа и т.д. актуатору аналоговому присвоить нельзя. В своем "событийном" виджете при отсутствии событий просто отображаю "Нет событий".



  • @Alex_Jet, спасибо, понял. Жаль, конечно. А как выяснить, что пустой параметр - if(obj.artist === undefined)?



  • @int144, да, именно так.



  • @Alex_Jet, я так сделал, а в отладчике
    01.06 19:57:45.696 assign PIHALL_TRACK5_5.value= Радио 7
    01.06 19:57:45.696 assign PIHALL_ALBUM4_5.value=
    01.06 19:57:45.696 assign PIHALL_ARTIST3_5.value=
    undefined почему-то не срабатывает



  • @Alex_Jet, сработало только на if(obj.artist === "")



  • Добрый день! Поскажите, в чем может быть проблема:
    Команда включает порт 5 (pin=5) на 5 сек (click=5) на ESP 8266/

    http://192.168.0.41/gpio?st=1&pin=5&click=5
    

    Если посылать эту команду через Chrome, то все отрабытывает пормально (порт включается и выключается через 5 сек), но если вызывать из сценария

    require ("http").get(`http://192.168.0.41/gpio?st=1&pin=5&click=5 `);
    

    то порт остается включенным. Такое впечатление, что click=5 не отсылается. Как посмотреть в отлатчике, что там отсылается? У меня не видно отправляемую команду.



  • @gis Добрый день.
    Попробуйте убрать последний пробел

    require ("http").get(`http://192.168.0.41/gpio?st=1&pin=5&click=5 `); // После 5 есть пробел
    require ("http").get(`http://192.168.0.41/gpio?st=1&pin=5&click=5`); 
    


  • @intrapro спасибо, но я уже пробовал и сним и без него - разницы нет. Поставил пробел, думал последний символ не передается.



  • Подскажите пожалуйста как установить значение даты замены фильтра в рекуператоре. Нужно чтобы не забивать когда был поменян фильтр и когда следующий раз менять чтобы IH сам сообщал что нужно заменить фильтр. Актуально для фильтров рекуператора, фильтра воды.....



  • Коллеги, вероятно где-то туплю. Переписал работающий сценарий, вынеся гистерезис в дополнительные параметры устройства чтобы можно было из вебки изменять все уставки. Однако система жалуется (co2_guest Device params: Unexpected token / in JSON at position 4), что в сценарии есть ошибка. Не могу понять в чем дело!

    const valve1F   = Device("VALVE_AIR3");     //Клапан первого этажа
    const hum_guest = Device("SHUMIDITY1_01", [ //Датчик влажности гостевой
      {"name":"hst", "note":"Гистерезис, %", "type":"number", "val":5}
      ]);
    const co2_guest = Device("SENSORA1_01", [   //Датчик CO2 гостевой
      {"name":"hst", "note":"Гистерезис, ppm", "type":"number", "val":100}
      ]);
    
    script({
        check() {
          return(   (hum_guest.value > hum_guest.setpoint + hum_guest.getParam("hst") || co2_guest.value > co2_guest.setpoint + co2_guest.getParam("hst"))&&(valve1F.isOff()) ||
                    (hum_guest.value < hum_guest.setpoint - hum_guest.getParam("hst") && co2_guest.value < co2_guest.setpoint - co2_guest.getParam("hst"))&&(valve1F.isOn()) );
        },
        
        start() {
          if(valve1F.isOff()) valve1F.on();
          else valve1F.off();
        }
    });
    


  • Пользователь @Alex_Jet написал в Сценарии - новая версия API:

    Коллеги, вероятно где-то туплю.

    Такое ощущение, что виновными оказались комментарии внутри []...

    Ну а что не так с этим???

    const sensor_hum  = Device("SensorA", "Датчик влажности", [
      {"name":"hst", "note":"Гистерезис (для управления), %", "type":"number", "val":"5"}
      ]);
    

    В ошибке - sensor_hum Device params: Unexpected end of JSON input



  • @Alex_Jet, да, Вы правы, проблема именно в комментариях.
    В декларативной части сценария (выше script) код не выполняется движком JS, а парсится системой.
    Массив дополнительных параметров рассматривается как единый JSON объект. А внутри JSON-а комментарии не разрешены 😞



  • @intrapro, а что не так тут:???

    const sensor_hum  = Device("SensorA", "Датчик влажности", [
      {"name":"hist", "note":"Гистерезис (для управления), %", "type":"number", "val":5}
      ]);
    

    В ошибке - Unexpected end of JSON input
    Я уже перепробовал кучу всего и не могу понять где есть загвоздка!!!
    Вот на такое же ведь не ругается!!!:

    const dt          = Device("SensorA", "Датчик температуры в зоне актюатора ТП", [
      {"name":"hist", "note":"Гистерезис включения/отключения актюатора, °C", "type":"number", "val":2}
      ]);
    


  • @Alex_Jet, скобочки в значениях ломают парсинг.
    Так будет работать:

     "note":"Гистерезис для управления, %"
    


  • @intrapro, вопрос на 100$))). Вопрос методом гугления отпал сам собой... Только если ответите по поводу оптимальности такого кода)
    В сценарий забил свойства своих камеры в виде литералов чтобы при постановке дома на охрану перебрать их в цикле и сформировать для каждой команду включения motion_detection. Получилось так:

      //Функция включения/выключения режима охраны у камер видеонаблюдения
          CamerasSecurity(md_state) {
            //Список IP камер
            const camera1 = {ip:"192.168.11.11", login:"admin", password:"admin"};
            const camera2 = {ip:"192.168.11.12", login:"admin", password:"admin"};
            let obj = Object.assign([], [camera1, camera2]);
            
            //Преобразование On/Off -> 0/1
            if(md_state == "On") md_state = 1;
            else if(md_state == "Off") md_state = 0;
            
            //Цикл для перебора всех камер
            for(var i = 0; i < obj.length; i++) {
              let command = "http://" +obj[i].login+ ":" +obj[i].password+ "@" +obj[i].ip;
              
              //enable = 0/1 (Disable/Enable Motion Detection of Zone 1: "name=1")
              command += "/web/cgi-bin/hi3510/param.cgi?cmd=setmdattr&-name=1&-enable=" +md_state;
              
              //Отправка команды плагину HTTP
              this.SendCommandToHTTP(command);
            }
          },
        }
    

    PS: А можно в сценарии каким-нибудь образом брать данные по камерам из плагина? И да - у плагина CCTV будет древовидная структура в 5-й версии iH?



  • Пользователь @Alex_Jet написал в Сценарии - новая версия API:

    Только если ответите по поводу оптимальности такого кода)

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

    Если по синтаксису - массив можно заполнить проще:

       const obj = []; // Объявляем пустой массив obj. push добавляет элементы-объекты
       obj.push({ip:"192.168.11.11", login:"admin", password:"admin"});
       obj.push({ip:"192.168.11.12", login:"admin", password:"admin"});
    

    А можно в сценарии каким-нибудь образом брать данные по камерам из плагина?

    Нет, в Cherry такой возможности нет

    И да - у плагина CCTV будет древовидная структура в 5-й версии iH?

    Да, в V5 деревья будут почти везде 🙂



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

    /** 
    * @name Жалюзі автоматика  
    * @desc  
    * @version 4  
    */
    
    const switch_1 = Device("ActorE","Switch");
    const jalusi = Device("ActorD","Actor",[
        {"name":"point_open", "note":"Пін відкриття", "type":"number", "val":15},
        {"name":"point_close", "note":"Пін закриття", "type":"number", "val":16}
      ]);
    
    startOnChange([switch_1,jalusi]); 
    
    script({
        start() {
          if(this.isChanged(switch_1)){
            this.onSwitch();
          }
          if(this.isChanged(jalusi)){
            if(switch_1.value===1){
              this.onJalusi();
            }
          }
        },
        onSwitch(){
          switch(switch_1.value){
              case 0:
                if(jalusi.isOff()){
                  if(global.get('jalusi_work')){
                    global.set('jalusi_count',global.get('jalusi_count')+1);
                    this.log('Жалюзі статус : jalusi_count : '+global.get('jalusi_count'));
                    this.startTimer("T1"+global.get('jalusi_count'), global.get('jalusi_time'), "Start_Jalusi_up");
                    global.set('jalusi_time',(global.get('jalusi_time')+28));
                  }else{
                    global.set('jalusi_work',true);
                    this.log('Жалюзі статус : '+jalusi.id);
                    global.set('jalusi_count',1);
                    global.set('jalusi_time',28);
                    this.startTimer("T11", 0.100, "Start_Jalusi_up");
                  }
                }
              break;
              case 1:
                  global.remove('jalusi_work');
                  global.remove('jalusi_count');
              break;
              case 2:
                if(jalusi.isOn()){
                  if(global.get('jalusi_work')){
                    global.set('jalusi_count',global.get('jalusi_count')+1);
                    this.log('Жалюзі статус : jalusi_count : '+global.get('jalusi_count'));
                    this.startTimer("T1"+global.get('jalusi_count'), global.get('jalusi_time'), "Start_Jalusi_down");
                    global.set('jalusi_time',(global.get('jalusi_time')+28));
                  }else{
                    global.set('jalusi_work',true);
                    this.log('Жалюзі статус : '+jalusi.id);
                    global.set('jalusi_count',1);
                    global.set('jalusi_time',28);
                    this.startTimer("T11", 0.100, "Start_Jalusi_down");
                  }
                }
              break;
            }
        },
        onJalusi(){
          if(switch_1.value===1){
            if(jalusi.isOn()){
              if(global.get('jalusi_work')){
                global.set('jalusi_count',global.get('jalusi_count')+1);
                this.log('Жалюзі статус : jalusi_count : '+global.get('jalusi_count'));
                this.startTimer("T1"+global.get('jalusi_count'), global.get('jalusi_time'), "Start_Jalusi_up");
                global.set('jalusi_time',(global.get('jalusi_time')+28));
              }else{
                global.set('jalusi_work',true);
                this.log('Жалюзі статус : '+jalusi.id);
                global.set('jalusi_count',1);
                global.set('jalusi_time',28);
                this.startTimer("T11", 0.100, "Start_Jalusi_up");
              }
            }else{
              if(global.get('jalusi_work')){
                global.set('jalusi_count',global.get('jalusi_count')+1);
                this.log('Жалюзі статус : jalusi_count : '+global.get('jalusi_count'));
                this.startTimer("T1"+global.get('jalusi_count'), global.get('jalusi_time'), "Start_Jalusi_down");
                global.set('jalusi_time',(global.get('jalusi_time')+28));
              }else{
                global.set('jalusi_work',true);
                this.log('Жалюзі статус : '+jalusi.id);
                global.set('jalusi_count',1);
                global.set('jalusi_time',28);
                this.startTimer("T11", 0.100, "Start_Jalusi_down");
              }
            }
          }
        },
        Start_Jalusi_up(){
          jalusi.on();
          jalusi.setBlk(1);
          this.log('Жалюзі статус : Start_Jalusi_up '+jalusi.id);
          switch(jalusi.id){
            case "ACTOR7":
              this.pluginCommand({unit:'megad3', command:'/258/?cmd='+jalusi.getParam('point_open')+':1;'});
            break;
            case "ACTOR8":
              this.pluginCommand({unit:'megad2', command:'/258/?cmd='+jalusi.getParam('point_open')+':1;'});
            break;
            case "ACTOR9":
              this.pluginCommand({unit:'megad2', command:'/258/?cmd='+jalusi.getParam('point_open')+':1;'});
            break;
            case "ACTOR10":
              this.pluginCommand({unit:'megad2', command:'/258/?cmd='+jalusi.getParam('point_open')+':1;'});
            break;
          }
          this.startTimer("T2", 25, "Stop_Jalusi_up");
        },
        Start_Jalusi_down(){
          jalusi.off();
          jalusi.setBlk(1);
          this.log('Жалюзі статус : Start_Jalusi_down '+jalusi.id);
          switch(jalusi.id){
            case "ACTOR7":
              this.pluginCommand({unit:'megad3', command:'/258/?cmd='+jalusi.getParam('point_close')+':1;'});
            break;
            case "ACTOR8":
              this.pluginCommand({unit:'megad2', command:'/258/?cmd='+jalusi.getParam('point_close')+':1;'});
            break;
            case "ACTOR9":
              this.pluginCommand({unit:'megad2', command:'/258/?cmd='+jalusi.getParam('point_close')+':1;'});
            break;
            case "ACTOR10":
              this.pluginCommand({unit:'megad2', command:'/258/?cmd='+jalusi.getParam('point_close')+':1;'});
            break;
          }
          this.startTimer("T2", 25, "Stop_Jalusi_down");
        },
        Stop_Jalusi_up() {
          global.set('jalusi_count',global.get('jalusi_count')-1);
          this.log('Жалюзі статус : Stop_Jalusi_up '+jalusi.id+' jalusi_count : '+global.get('jalusi_count'));
          switch(jalusi.id){
            case "ACTOR7":
              this.pluginCommand({unit:'megad3', command:'/258/?cmd='+jalusi.getParam('point_open')+':0;'});
            break;
            case "ACTOR8":
              this.pluginCommand({unit:'megad2', command:'/258/?cmd='+jalusi.getParam('point_open')+':0;'});
            break;
            case "ACTOR9":
              this.pluginCommand({unit:'megad2', command:'/258/?cmd='+jalusi.getParam('point_open')+':0;'});
            break;
            case "ACTOR10":
              this.pluginCommand({unit:'megad2', command:'/258/?cmd='+jalusi.getParam('point_open')+':0;'});
            break;
          }
          global.set('jalusi_work',false);
          jalusi.setBlk(0);
          if(global.get('jalusi_count')===0){
            switch_1.setValue(1);
          }
          this.log('End Jalusi Up');
        },
        Stop_Jalusi_down() {
          global.set('jalusi_count',global.get('jalusi_count')-1);
          this.log('Жалюзі статус : Stop_Jalusi_down '+jalusi.id+' jalusi_count : '+global.get('jalusi_count'));
          switch(jalusi.id){
            case "ACTOR7":
              this.pluginCommand({unit:'megad3', command:'/258/?cmd='+jalusi.getParam('point_close')+':0;'});
            break;
            case "ACTOR8":
              this.pluginCommand({unit:'megad2', command:'/258/?cmd='+jalusi.getParam('point_close')+':0;'});
            break;
            case "ACTOR9":
              this.pluginCommand({unit:'megad2', command:'/258/?cmd='+jalusi.getParam('point_close')+':0;'});
            break;
            case "ACTOR10":
              this.pluginCommand({unit:'megad2', command:'/258/?cmd='+jalusi.getParam('point_close')+':0;'});
            break;
          }
          global.set('jalusi_work',false);
          jalusi.setBlk(0);
          if(global.get('jalusi_count')===0){
            switch_1.setValue(1);
          }
          this.log('End Jalusi Down');
        }
    });
    
    
    /** 
    * @name Жалюзі закрити 
    * @desc  
    * @version 4  
    */
    const mid = Device("ACTORA1");
    const jalusi_1 = Device("ACTOR7");
    const jalusi_2 = Device("ACTOR8");
    const jalusi_3 = Device("ACTOR9");
    const jalusi_4 = Device("ACTOR10");
    const switch_jalusi = Device("SWITCH_windows");
    
    script({
        start() {
            if(jalusi_1.isOn() || jalusi_2.isOn() || jalusi_3.isOn() || jalusi_4.isOn()){
              this.assign( switch_jalusi, "value", 2);
              mid.setValue([10016, 20]);
            }
        } 
    });
    
    


  • @amgstone, вроде как в сченарии для управления освещением по датчику движения тут было опубликовано уже. Вот модификация моя:

    const lamp = Device("ActorD", "Светильник", [
      {"name":"timeOff", "note":"Светильник горит без движения, мин", "type":"number", "val":1}
      ]);
    
            if(motion.isOn()) {
              lamp.turnOnSaveAuto();  // Если просто дать команду on - АВТО будет сброшен.
                                      // Сейчас мы хотим сохранить АВТО  
            }
            else {
              // движения нет - взводим таймер, чтобы отключить 
              this.startTimer("T1", lamp.getParam("timeOff")*60, "turnOff");       
            }
    
        // Функция, которая сработает, когда таймер досчитает (нет движения в течение
        // заданного времени) - отключаем и выходим
        turnOff() {
          lamp.turnOffSaveAuto();
          this.exit();
        }
    

    По вашей роллете нужно делать аналогично.



  • @Alex_Jet нет, у меня там не все так просто, за закрытие ролокасет отвечает switch, надо какое то условие, что когда срабатывает switch на закрытие ролокасет опрашивался датчик движение и запретил закрывать ролокасету (двери-actor), и когда движение небудет установленое время то закрить отрытую ролокасету.



  • @amgstone, ну вы же сами описываете свой алгоритм! Значит надо для switch сделать слушателя, который будет выполнять функцию, в которой будет проверяться состояние датчика движения и взводить соответствующий таймер.


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