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



  • @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 сделать слушателя, который будет выполнять функцию, в которой будет проверяться состояние датчика движения и взводить соответствующий таймер.



  • @Алексей, во-первых, не понятно о чем вы говорите, во-вторых, может вы ошиблись форумом?



  • @intrapro, помогите свежим взглядом разобраться. Выявил, что почему-то иногда сценарий передает "не контроллируемые" данные - передачу громкости 58 и 100 единиц:
    Сам сценарий запускается по входящему от терминала:

    12.10 12:39:55.773 voiceterminal1: 192.168.11.51 => localhost:11051 HTTP GET /api/method/name.method?terminal=VT1&volume=58&uptime=92530&username=voiceterminal
    12.10 12:39:55.774 voiceterminal1: 192.168.11.51 <= localhost:11051 
    12.10 12:39:55.774 voiceterminal1: { type: 'startscene',
      id: 'VoiceTerminal_Status',
      arg: '{"terminal":"VT1","volume":"58","uptime":"92530","username":"voiceterminal"}' }
    12.10 12:39:55.776 IH: plugin command { unit: 'voiceterminal1', command: 'volume:58', type: 'command' }
    12.10 12:39:55.778 IH: startscene VoiceTerminal_Status
    12.10 12:39:55.779 voiceterminal1: send command to terminal - 'volume:58'
    12.10 12:39:55.779 voiceterminal1: connection by socket to the 192.168.11.51:7999 successfull!
    12.10 12:39:55.779 voiceterminal1: send data by socket - 'volume:58'
    12.10 12:39:55.780 voiceterminal1: connection by socket to the 192.168.11.51:7999 is end!
    12.10 12:39:55.833 voiceterminal1: 192.168.11.51 => localhost:11051 HTTP GET /api/method/name.method?terminal=VT1&volume=100&uptime=92530&username=voiceterminal
    12.10 12:39:55.834 voiceterminal1: 192.168.11.51 <= localhost:11051 
    12.10 12:39:55.834 voiceterminal1: { type: 'startscene',
      id: 'VoiceTerminal_Status',
      arg: '{"terminal":"VT1","volume":"100","uptime":"92530","username":"voiceterminal"}' }
    12.10 12:39:55.835 IH: plugin command { unit: 'voiceterminal1',
      command: 'volume:100',
      type: 'command' }
    12.10 12:39:55.838 IH: startscene VoiceTerminal_Status
    12.10 12:39:55.838 voiceterminal1: send command to terminal - 'volume:100'
    12.10 12:39:55.839 voiceterminal1: connection by socket to the 192.168.11.51:7999 successfull!
    12.10 12:39:55.839 voiceterminal1: send data by socket - 'volume:100'
    12.10 12:39:55.839 voiceterminal1: connection by socket to the 192.168.11.51:7999 is end!
    12.10 12:39:55.893 voiceterminal1: 192.168.11.51 => localhost:11051 HTTP GET /api/method/name.method?terminal=VT1&volume=58&uptime=92530&username=voiceterminal
    12.10 12:39:55.893 voiceterminal1: 192.168.11.51 <= localhost:11051 
    12.10 12:39:55.894 voiceterminal1: { type: 'startscene',
      id: 'VoiceTerminal_Status',
      arg: '{"terminal":"VT1","volume":"58","uptime":"92530","username":"voiceterminal"}' }
    12.10 12:39:55.895 IH: plugin command { unit: 'voiceterminal1', command: 'volume:58', type: 'command' }
    12.10 12:39:55.898 IH: startscene VoiceTerminal_Status
    12.10 12:39:55.898 voiceterminal1: send command to terminal - 'volume:58'
    12.10 12:39:55.899 voiceterminal1: connection by socket to the 192.168.11.51:7999 successfull!
    12.10 12:39:55.899 voiceterminal1: send data by socket - 'volume:58'
    12.10 12:39:55.899 voiceterminal1: connection by socket to the 192.168.11.51:7999 is end!
    12.10 12:39:55.950 voiceterminal1: 192.168.11.51 => localhost:11051 HTTP GET /api/method/name.method?terminal=VT1&volume=100&uptime=92530&username=voiceterminal
    12.10 12:39:55.950 voiceterminal1: 192.168.11.51 <= localhost:11051 
    12.10 12:39:55.951 voiceterminal1: { type: 'startscene',
      id: 'VoiceTerminal_Status',
      arg: '{"terminal":"VT1","volume":"100","uptime":"92530","username":"voiceterminal"}' }
    12.10 12:39:55.952 IH: plugin command { unit: 'voiceterminal1',
      command: 'volume:100',
      type: 'command' }
    12.10 12:39:55.955 IH: startscene VoiceTerminal_Status
    12.10 12:39:55.956 voiceterminal1: send command to terminal - 'volume:100'
    12.10 12:39:55.956 voiceterminal1: connection by socket to the 192.168.11.51:7999 successfull!
    12.10 12:39:55.957 voiceterminal1: send data by socket - 'volume:100'
    12.10 12:39:55.957 voiceterminal1: connection by socket to the 192.168.11.51:7999 is end!
    12.10 12:39:56.006 voiceterminal1: 192.168.11.51 => localhost:11051 HTTP GET /api/method/name.method?terminal=VT1&volume=58&uptime=92531&username=voiceterminal
    12.10 12:39:56.006 voiceterminal1: 192.168.11.51 <= localhost:11051 
    12.10 12:39:56.007 voiceterminal1: { type: 'startscene',
      id: 'VoiceTerminal_Status',
      arg: '{"terminal":"VT1","volume":"58","uptime":"92531","username":"voiceterminal"}' }
    12.10 12:39:56.008 IH: plugin command { unit: 'voiceterminal1', command: 'volume:58', type: 'command' }
    12.10 12:39:56.011 IH: startscene VoiceTerminal_Status
    12.10 12:39:56.012 voiceterminal1: send command to terminal - 'volume:58'
    12.10 12:39:56.012 voiceterminal1: connection by socket to the 192.168.11.51:7999 successfull!
    12.10 12:39:56.012 voiceterminal1: send data by socket - 'volume:58'
    12.10 12:39:56.012 voiceterminal1: connection by socket to the 192.168.11.51:7999 is end!
    12.10 12:39:56.044 voiceterminal1: 192.168.11.51 => localhost:11051 HTTP GET /api/method/name.method?terminal=VT1&volume=100&uptime=92531&username=voiceterminal
    12.10 12:39:56.044 voiceterminal1: 192.168.11.51 <= localhost:11051 
    12.10 12:39:56.045 voiceterminal1: { type: 'startscene',
      id: 'VoiceTerminal_Status',
      arg: '{"terminal":"VT1","volume":"100","uptime":"92531","username":"voiceterminal"}' }
    12.10 12:39:56.046 IH: plugin command { unit: 'voiceterminal1',
      command: 'volume:100',
      type: 'command' }
    12.10 12:39:56.048 IH: startscene VoiceTerminal_Status
    12.10 12:39:56.049 voiceterminal1: send command to terminal - 'volume:100'
    12.10 12:39:56.049 voiceterminal1: connection by socket to the 192.168.11.51:7999 successfull!
    12.10 12:39:56.049 voiceterminal1: send data by socket - 'volume:100'
    12.10 12:39:56.050 voiceterminal1: connection by socket to the 192.168.11.51:7999 is end!
    12.10 12:39:56.366 voiceterminal1: 192.168.11.51 => localhost:11051 HTTP GET /api/method/name.method?terminal=VT1&volume=58&uptime=92531&username=voiceterminal
    12.10 12:39:56.366 voiceterminal1: 192.168.11.51 <= localhost:11051 
    12.10 12:39:56.367 voiceterminal1: { type: 'startscene',
      id: 'VoiceTerminal_Status',
      arg: '{"terminal":"VT1","volume":"58","uptime":"92531","username":"voiceterminal"}' }
    12.10 12:39:56.368 IH: plugin command { unit: 'voiceterminal1', command: 'volume:58', type: 'command' }
    12.10 12:39:56.370 IH: startscene VoiceTerminal_Status
    12.10 12:39:56.371 voiceterminal1: send command to terminal - 'volume:58'
    12.10 12:39:56.371 voiceterminal1: connection by socket to the 192.168.11.51:7999 successfull!
    12.10 12:39:56.372 voiceterminal1: send data by socket - 'volume:58'
    12.10 12:39:56.372 voiceterminal1: connection by socket to the 192.168.11.51:7999 is end!
    12.10 12:39:56.403 voiceterminal1: 192.168.11.51 => localhost:11051 HTTP GET /api/method/name.method?terminal=VT1&volume=100&uptime=92531&username=voiceterminal
    12.10 12:39:56.403 voiceterminal1: 192.168.11.51 <= localhost:11051 
    12.10 12:39:56.403 voiceterminal1: { type: 'startscene',
      id: 'VoiceTerminal_Status',
      arg: '{"terminal":"VT1","volume":"100","uptime":"92531","username":"voiceterminal"}' }
    12.10 12:39:56.405 IH: plugin command { unit: 'voiceterminal1',
      command: 'volume:100',
      type: 'command' }
    12.10 12:39:56.408 IH: startscene VoiceTerminal_Status
    12.10 12:39:56.408 voiceterminal1: send command to terminal - 'volume:100'
    12.10 12:39:56.408 voiceterminal1: connection by socket to the 192.168.11.51:7999 successfull!
    12.10 12:39:56.409 voiceterminal1: send data by socket - 'volume:100'
    12.10 12:39:56.409 voiceterminal1: connection by socket to the 192.168.11.51:7999 is end!
    12.10 12:39:56.632 voiceterminal1: 192.168.11.51 => localhost:11051 HTTP GET /api/method/name.method?terminal=VT1&status=start_record&uptime=92531&username=voiceterminal
    12.10 12:39:56.632 voiceterminal1: 192.168.11.51 <= localhost:11051 
    12.10 12:39:56.633 voiceterminal1: { type: 'startscene',
      id: 'VoiceTerminal_Status',
      arg: '{"terminal":"VT1","status":"start_record","uptime":"92531","username":"voiceterminal"}' }
    12.10 12:39:56.636 IH: startscene VoiceTerminal_Status
    

    Сценарий создавался для того, чтобы:

    1. На вкладке параметры устройства отображать состояние терминала
    2. Со вкладки параемтры регулировать громкость терминала и плеера.
    const dev1 = Device("_UNIT_voiceterminal1", [
      {"name":"uptime", "note":"Времы работы", "type":"string", "val":""},
      {"name":"status", "note":"Состояние", "type":"string", "val":""},
      {"name":"updater", "note":"Обновления", "type":"string", "val":""},
      {"name":"set_volume", "note":"Громкость терминала", "type":"number", "val":50},
      {"name":"set_music_volume", "note":"Громкость плеера", "type":"number", "val":50},
      {"name":"last_update", "note":"Update", "type":"string", "val":""}
      ]);
    
    const dev2 = Device("_UNIT_voiceterminal2", [
      {"name":"uptime", "note":"Времы работы", "type":"string", "val":""},
      {"name":"status", "note":"Состояние", "type":"string", "val":""},
      {"name":"updater", "note":"Обновление", "type":"string", "val":""},
      {"name":"set_volume", "note":"Громкость терминала", "type":"number", "val":50},
      {"name":"set_music_volume", "note":"Громкость плеера", "type":"number", "val":50},
      {"name":"last_update", "note":"Last update", "type":"string", "val":""}
      ]);
    
    script({
      start(param) {
        let device = '';
    
        //Скрипт запускается плагином с параметрами
        if(param !== undefined) {
          
          const obj = this.ParseJSON(param);
          
          //Выбор устройства
          if(obj.terminal == "VT1") {
            device = dev1;
          }
          else if(obj.terminal == "VT2") {
            device = dev2;
          }
        
          //Конвертация времени из секунд в часы
          let days = Math.floor(obj.uptime/86400);
          let hours = Math.floor((obj.uptime % 86400)/3600);
          let minutes = Math.floor((obj.uptime % 3600)/60);
          let seconds = obj.uptime % 60;
          let time = days+ "d " +((hours < 10) ? "0" : "")+hours+ ":" +((minutes < 10) ? "0" : "")+minutes+ ":" +((seconds < 10) ? "0" : "")+seconds;
          
          //Обновление параметров устройства
          if(obj.uptime !== undefined)
          device.setParam("uptime", time);
          
          if(obj.status !== undefined)
          device.setParam("status", obj.status);
          
          if(obj.updater !== undefined)
          device.setParam("updater", obj.updater);
          
          if(obj.volume !== undefined)
          device.setParam("set_volume", obj.volume);
          
          if(obj.music_volume !== undefined)
          device.setParam("set_music_volume", obj.music_volume);
          
          device.setParam("last_update", this.GetDate());
        }
      },
      
      ParseJSON(param) {
          try {
            return JSON.parse(param);
          }
          catch (e) {
            let text = e instanceof SyntaxError;
            this.log("SyntaxError - " +text+ "; param - " +param);
          }
      },
      
      GetDate() {
        return new Date().toLocaleString('ru-RU');
      }
    });
    

    В отладчике сценария:

    12.10 12:39:37.115 Started
    12.10 12:39:37.116 do _UNIT_voiceterminal1 uptime 1d 01:41:52
    12.10 12:39:37.117 do _UNIT_voiceterminal1 set_volume 58
    12.10 12:39:37.121 do _UNIT_voiceterminal1 last_update 2020-10-12 12:39:37
    12.10 12:39:37.122 Stopped
    12.10 12:39:37.148 Started
    12.10 12:39:37.149 do _UNIT_voiceterminal1 uptime 1d 01:41:52
    12.10 12:39:37.150 do _UNIT_voiceterminal1 set_volume 100
    12.10 12:39:37.152 do _UNIT_voiceterminal1 last_update 2020-10-12 12:39:37
    12.10 12:39:37.153 Stopped
    12.10 12:39:37.427 Started
    12.10 12:39:37.428 do _UNIT_voiceterminal1 uptime 1d 01:41:52
    12.10 12:39:37.428 do _UNIT_voiceterminal1 set_volume 58
    12.10 12:39:37.432 do _UNIT_voiceterminal1 last_update 2020-10-12 12:39:37
    12.10 12:39:37.432 Stopped
    12.10 12:39:37.464 Started
    12.10 12:39:37.464 do _UNIT_voiceterminal1 uptime 1d 01:41:52
    12.10 12:39:37.465 do _UNIT_voiceterminal1 set_volume 100
    12.10 12:39:37.467 do _UNIT_voiceterminal1 last_update 2020-10-12 12:39:37
    12.10 12:39:37.468 Stopped
    12.10 12:39:37.676 Started
    12.10 12:39:37.676 do _UNIT_voiceterminal1 uptime 1d 01:41:52
    12.10 12:39:37.677 do _UNIT_voiceterminal1 status start_record
    12.10 12:39:37.680 do _UNIT_voiceterminal1 last_update 2020-10-12 12:39:37
    12.10 12:39:37.681 Stopped
    

    Хм...этот сценарий причем лишь косвенно. Отрабатывает другой - вот этот!!!

    const dev1 = Device("_UNIT_voiceterminal1");
    const dev2 = Device("_UNIT_voiceterminal2");
    
    startOnChange([dev1,dev2]);
    
    script({
      start() {
        let device = '';
        let flag_volume = 0;
        
        //Проверка с какого устройства поступила команда
        if(this.isChanged(dev1, "set_volume")) {
          device = dev1;
          flag_volume = 1;
        }
        else if(this.isChanged(dev2, "set_volume")) {
          device = dev2;
          flag_volume = 1;
        }
        else if(this.isChanged(dev1, "set_music_volume")) {
          device = dev1;
          flag_volume = 2;
        }
        else if(this.isChanged(dev2, "set_music_volume")) {
          device = dev2;
          flag_volume = 2;
        }
        
        //Установка громкости на нужном терминале
        if(flag_volume == 1) this.SetVolumeTerminal(device);
        else if(flag_volume == 2) this.SetVolumeMusic(device);
      },
      
      SetVolumeTerminal(device) {
        let unit = device.id.replace('_UNIT_', '');
        let command = device.getParam('set_volume');
        this.pluginCommand({unit: unit, command:"volume:" +command});
      },
      
      SetVolumeMusic(device) {
        let unit = device.id.replace('_UNIT_', '');
        let command = device.getParam('set_music_volume');
        this.pluginCommand({unit: unit, command:"mvolume:" +command});
      }
    });
    

    Его лог:

    12.10 12:52:43.246 Trigger _UNIT_voiceterminal1
    12.10 12:52:43.247 Started
    12.10 12:52:43.247 isChanged(_UNIT_voiceterminal1,set_volume)=true Changed: {"_UNIT_voiceterminal1":{"set_volume":"58"}}
    12.10 12:52:43.247 plugincCommand { unit: 'voiceterminal1', command: 'volume:58' }
    12.10 12:52:43.248 Stopped
    12.10 12:52:43.285 Trigger _UNIT_voiceterminal1
    12.10 12:52:43.285 Started
    12.10 12:52:43.286 isChanged(_UNIT_voiceterminal1,set_volume)=true Changed: {"_UNIT_voiceterminal1":{"set_volume":"100"}}
    12.10 12:52:43.286 plugincCommand { unit: 'voiceterminal1', command: 'volume:100' }
    12.10 12:52:43.287 Stopped
    12.10 12:52:43.602 Trigger _UNIT_voiceterminal1
    12.10 12:52:43.603 Started
    12.10 12:52:43.603 isChanged(_UNIT_voiceterminal1,set_volume)=true Changed: {"_UNIT_voiceterminal1":{"set_volume":"58"}}
    12.10 12:52:43.604 plugincCommand { unit: 'voiceterminal1', command: 'volume:58' }
    12.10 12:52:43.604 Stopped
    12.10 12:52:43.661 Trigger _UNIT_voiceterminal1
    12.10 12:52:43.661 Started
    12.10 12:52:43.662 isChanged(_UNIT_voiceterminal1,set_volume)=true Changed: {"_UNIT_voiceterminal1":{"set_volume":"100"}}
    12.10 12:52:43.662 plugincCommand { unit: 'voiceterminal1', command: 'volume:100' }
    12.10 12:52:43.663 Stopped
    12.10 12:52:43.698 Trigger _UNIT_voiceterminal1
    12.10 12:52:43.698 Started
    12.10 12:52:43.699 isChanged(_UNIT_voiceterminal1,set_volume)=true Changed: {"_UNIT_voiceterminal1":{"set_volume":"58"}}
    12.10 12:52:43.699 plugincCommand { unit: 'voiceterminal1', command: 'volume:58' }
    12.10 12:52:43.700 Stopped
    12.10 12:52:43.931 Trigger _UNIT_voiceterminal1
    

    Заблокировал сценарий - все пропало. Разблокировал сценарий - тоже все нормально. В какой-то момент что-то происходит, что на каждый "чих" голосового терминала последний сценарий шлет ему громкость 58 и 100 попеременно (вероятно эти значения были заданы на вкладке "Параметры").
    Пока не могу предположить почему так происходит...



  • Подсжите как сделать сценарий: обратный отсчет времени для замены фильтра воды.



  • @amgstone создал сценарий:

    /** 
    * @name Заміна фільтра води 
    * @desc  
    * @version 4 
    */
    const meter = Device("Meter","час заміни фільтра"); 
    
    script({
        start() {
        meter.setParam("aval",meter.getParam("aval")+1);
        if(meter.getParam("aval")===90){
        this.info('telegram', 'OWNER', 'Заміна фільтра води');
        this.info('pushnotification', 'OWNER', 'Заміна фільтра води'); 
        
        }
        } 
    });
    
    

    но в IH не смог создать дату, чтобы визуализировало дату когда надо заменить фильтр, возможно добавите устройство?



  • Готовлюсь к новому году) в проем гаражных ворот смонтировал RGB-ленту на базе WS2818. Хочется реализовать эффект бегущего огня с плавно изменяемой яркостью (вот пример - смотреть на 2:52-3:02). Я конечно понимаю, что iH - это не RGB-контроллер, но все же есть ли какая-то возможность сделать подобный эффект?? Сам сделал "длинный" бегущий огонь, но код очень топорный...

        TronEffect() {
          this.addListener(sw, "ChangeStateSw");
          
          let blue = 'FF00FF';
          let dark = '000000';
          let color = [blue+blue+blue+dark+dark+dark,dark+blue+blue+blue+dark+dark, dark+dark+blue+blue+blue+dark, dark+dark+dark+blue+blue+blue, blue+dark+dark+dark+blue+blue, blue+blue+dark+dark+dark+blue];
          
          if(++this.i > color.length-1) this.i = 0;
          this.cmd = color[this.i];
          
          this.SendDataToWS2818(this.plugin, this.channel, this.cmd, this.chip);
          
          this.startTimer("T1", this.period, "TronEffect");
        },
    

    Причем это просто бегущий огонь из 6 "пикселей". Как сделать уменьшающийся по яркости хвост огня и увеличить его скорость - это большой вопрос!!



  • @Alex_Jet Добрый день, судя по коду, огонь у вас бегает в переделах 6-ти пикселей ? какая длина ленты у вас ? есть фризы ?



  • @dev, огонь смещается по 6 пикселям. Но поскольку megad повторяет всю эту посылку N-количество раз (ключ "chip" - тут описание), то выглядит это вот так:
    видео. Лента состоит из двух логических запараллеленых кусков длиной 39 чипов)). Ну а вообще длина - 2,4+3+2,4 м. Что такое фризы?



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

    @homa, пока такой возможности нет 😞

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



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

    И есть ли возможность после перезагрузки системы возобновлять работу активных сценариев ?

    А так не получается - функция boot()?
    @intrahouse, @dev, я бы всякие такие возможности (startOnChange, check, boot и прочее) добавил бы на страницу "Система команд".



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

    А так не получается - функция boot()?

    Если сценарий инициирует перезагрузку системы, думаю как сделать, чтобы после перезагрузки он продолжил свое выполнение дальше.
    boot() инициирует новый запуск, вопрос как возобновить исполнение с нужной точки.



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

    boot() инициирует новый запуск, вопрос как возобновить исполнение с нужной точки.

    Может быть запоминать состояние в переменной сценария или вообще в глобальной переменной?



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

    Может быть запоминать состояние в переменной сценария или вообще в глобальной переменной?

    Да, видимо так и сделаю.
    Есть сценарии которые выполняются циклически через заданный промежуток времени, если он выполнил перезагрузку системы, то нужно ждать пока он не запустится заново.
    Видимо перед перезагрузкой нужно присвоить значение нужной переменной, продублировать сценарий но уже с функцией boot() и проверкой этой переменной.
    Думал обойтись без дублирования сценария, может есть механизм ? Было бы удобно.


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