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



  • @homa, вот так все работает:

    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":""}
      ]);
    


  • @homa, в принципе корректно. У устройства будут свойства с одинаковым названием, но отнесенные к разным сценариям:
    Устройство_Дополнительные_Параметры.png



  • @Alex_Jet идея в том, чтобы изменять из разных сценариев одно свойство... выходит не выходит)



  • @intrapro, this.exit() действительно есть в функции сценария, но перед этим переменной сценария flag_com присваивается 1, что указывает на то что не надо выполнять основное ветвление if, а надо выполнить else. Типа вот такого:

    if(!this.flag_com) {
      //Парсим входные данные и в соответствии с ними выполняем команды..
    }
    else {
     //Повторно заходим в функцию чтобы выполнить действие с уточненным названием помещения
     this.Lamp_Control();
    }
    

    Если функция отработала успешно, то присваиваем flag_com=0, чтобы сценарий работал по основному ветвлению if. В общем, попробую добавить логирование в сценарий...просто не хотелось журнал забивать не нужной информацией:(



  • @homa, тогда нужно использовать глобальные переменные. Функционал есть, API описан, но я его еще не пробовал. Приведите для примера задачу) может и мне понадобится😀



  • @Alex_Jet У меня управление одним устройством с разных сценариев) я думал о глобальных переменных, чтобы там хранить значение свойства, но при выполнении сценария его придется каждый раз перепроверять. Думал может есть простой способ обращения)



  • @homa, ну а какая разница? Это же не искать какое-то определенное значение в раздутой БД! Все довольно просто и быстро).
    А вообще интересная задача - управление одним устройством разными сценариями...я не могу придумать никакого практического применения(((. Просвятите что вы хотите сделать!
    У меня единственный навороченный сценарий/немного поверх другого - это отключение авто-режима актюатора если вдруг кто-то открыл окно для проветривания, например. Правда после открытия окна проверяется - включен ли актюатор (то есть холодно и помещение уже греется), если да то просто выходим, если нет, то отключаем у него авто режим))) При этом если в комнате стало холоднее уставки "эконом", то возвращаем актюатору авто-режим (чтобы отопление принудительно включилось).



  • @Alex_Jet у меня скорее просто неоптимальная реализация для управления мотором)
    у меня есть три актуатора = 3 положения кнопки вытяжки, три сенсора = три положения физического переключателя. один сценарий синхронизирует состояния физики и логики, второй делает правильное переключение, чтобы не включить две "кнопки" сразу, а третий регулирует скорость в зависимости от разницы температур и электропотребления



  • @homa, как-то все сложно. А не проще сделать переключатель? У меня рекуператор (3 скорости) управляется переключателем (выключен, авто, скорость 1, скорость 2, скорость 3). Есть 2 сценария - один "чувствует" переключение переключателя и отрабатывает нужные действия, другой - активируется только когда переключатель в состоянии "Авто".
    А!!! Еще не пойму - зачем нужен физический переключатель? У нас же умный дом! Я конечно тоже установил двухклавишный переключатель (висит на MegaD и MegaD управляет рекуператором, причем 3 выхода MegaD связаны в sw link чтобы всегда включалось одно из трех реле), но это для экстренного режима управления рекуператором (включить/выключить рекуператор, выбрать скорость 1 или 2) когда все сдохло/умер сервер/смартфон/роутер/коммутатор и т.п.



  • @Alex_Jet Физические переключатели всегда должны дублировать основной функционал. А если переделываешь что-то совсем аналоговое, то приходится привязываться к старым органам управления



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

    /** 
    * @name Світло коридор 1 поверх 
    * @desc Включает светильник по датчику движения, отключает при отсутствии движения в течение заданного времени.  
    * @version 4  
    */
    
    
    const lamp = Device("ActorD", "Светильник", [
      {"name":"timeOff", "note":"Светильник горит без движения, сек", "type":"number", "val":5},
      {"name":"light_threshold", "note":"Порог освещенности для включения", "type":"number", "val":20}
      ]); 
    
    const lamp2 = Device("ActorD", "Освітлення Led коридор 1 поверх Коридор");  
      
    const motion = Device("SensorD", "Датчик движения");  
    const lightSensor = Device("SensorA", "Датчик освещенности (аналоговый)"); 
    
    // Запустим сценарий при сработке датчика движения, если светильник не горит и освещенность ниже порога
    // ИЛИ если движение прекратилось, а светильник горит 
    startOnChange([motion,lamp2], motion.isOn() && lamp.isOff() && lightSensor.value <= lamp.getParam("light_threshold") || motion.isOff() && lamp.isOn());
    
    script ({    
        start() {
          if(lamp2.isOff()){
              this.addTimer("T1");  
               
              if (motion.isOn()) {
                lamp.on();
              } else {
                // движения нет - взводим таймер, чтобы отключить 
                this.startTimer("T1", lamp.getParam("timeOff"), "turnOff");       
              }
              // В любом случае следим за датчиком движения и светильником
              this.addListener(motion, "onMotion");
              this.addListener(lamp, "onLamp");
          }else{
            lamp.off();
            this.exit();
          }
        },
        
        onMotion() {
           // Если движение прекратилось - взводим таймер
          if (motion.isOff() && this.timer.T1 == "off")  {
            this.startTimer("T1", lamp.getParam("timeOff"), "turnOff");
          }  
            
           // Если движение возобновилось - сбрасываем таймер
          if (motion.isOn())  {
            this.stopTimer('T1');
          }  
        },
        
        onLamp() {
          // Светильник выключили другим способом - выходим
           if (lamp.isOff()) this.exit();
         },
         
        // Функция, которая сработает, когда таймер досчитает (нет движения в течение заданного 
        // времени) - отключаем и выходим
        turnOff() {
          lamp.off();
          this.exit();
        }
    });
    


  • @homa, не согласен - по мне физика отмирает. Даже в современных авто уже нет физических кнопок. Кстати, у моего рекуператора есть свой контроллер с дисплеем и т.д., но я его просто выкинул, подключив все к MegaD.
    Тренд в управлении - автоматика, мобильные приложения и голосовые ассистенты. Тот же рекуператор у меня всегда в режиме авто, "ручные" режимы сделаны скорее для того чтобы были.



  • Участник @homa написал

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

    идея в том, чтобы изменять из разных сценариев одно свойство... выходит не выходит)

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



  • Добрый день! А можно добавить возможность писать значение устройства из плагина не в value, а в созданный в скрипте дополнительный параметр?
    76bb8199-889e-4bc4-8445-31ebbfce4727-image.png
    чтобы в value писать уже значение после обработки



  • подскажите пожалуйста решение задачи. требуется присвоить значение виртуальному счетчику от физического
    по простому продублировать значение одного другому



  • @m_n61rus Сделайте сценарий

    /** 
    * @name xx 
    * @desc  
    * @version 4 
    */
    const meter6 = Device("METER6"); //оригинал
    const meter7 = Device("METER7"); //копия
    
    startOnChange(meter6); 
    
    script({
        start() {
           this.assign(meter7, 'aval', meter6.value);
        } 
    });
    


  • @homa спасибо попробую



  • @intrapro, расскажите как сделать скрипт, который можно запустить кнопкой и остановить. При этом запущенный скрипт должен работать в бесконечном цикле. Задача - работа гирлянды на базе WS2818 с включением вручную, по расписанию, по датчикам.
    Пример скрипта на php для бесконечной работы гирлянды:

    $cmd_list = array("FF0000", "00FF00", "0000FF", "FFFFFF", "000000");
    $color = 0;
    
    while(true)
    {
        $cmd = "";
        for ( $i = 0; $i < 9; $i++ )
        {
            $color = dechex(rand(0,100));
            if ( strlen($color) == 1 )
            $color = "0".$color;
            $cmd .= $color;
        }
        file_get_contents("http://192.168.0.14/sec/?pt=35&ws=$cmd");
        sleep(1);
    }
    


  • @Alex_Jet
    Примерно так.

    Если нужно 4 состояния ленты менять по кругу бесконечно, то скрипт такой.

    По нажатию кнопки включаете ленту в состояние 1, запускаете таймер с переходом на "stage2", запускаете слушателя кнопки c переходом на "turnOff".
    stage2 - переключаете ленту в состояние 2, запускаете таймер с переходом на "stage3"
    stage3 - переключаете ленту в состояние 3, запускаете таймер с переходом на "stage4"
    stage4 - переключаете ленту в состояние 4, запускаете таймер с переходом на "stage5"
    stage5 - переключаете ленту в состояние 1, запускаете таймер с переходом на "stage2"
    turnOff - останавливаете таймер, выходите из скрипта.

    Если нужно не по кнопке, а из другого скрипта, сделайте актуатор, состояние которого меняете из другого скрипта или той же кнопкой, а скрипт ленты запускайте по изменению этого актуатора, и слушатель в нем на изменения этого актуатора, а не кнопки.



  • @Alex_Jet, Добрый день! @Erik прав - нужен актуатор, который можно переключать как угодно - интерактивно, сценарием, по расписанию...

    Сценарий гирлянды запускается при включении этого актуатора.

    Состояния в php скрипте меняются случайным образом, поэтому логика еще проще:

    1. Добавить слушателя для актуатора-триггера
    2. Генерировать строку цветов случайным образом
    3. Передать команду на MegaD
    4. Взвести таймер 1 сек

    По таймеру - повторить пункты 1-3
    При выключении триггера - завершить сценарий


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