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



  • @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 вставлен, чтобы отследить работу алгоритма в отладчике или журнале



  • "Не совсем понятно …" - эта часть скрипта должна выполняться, если режим отопления комфортный (ActRz.value = 0)

    Полная версия для 3-х разных режимов присваивает значения разным актуаторам.

    А в 4-и режиме ничего не присваивает.

    const ActRz = Device("ActorA", "Режим отопления");
    const ActComf = Device("ActorA", "Уставка Комфорт");
    const ActEco = Device("ActorA", "Уставка Эконом");
    const ActOff = 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, 'next1');
            	this.addListener(ActDsp, 'resetTimer');
           }
            if (ActRz.value == 1) {  // Не совсем понятно, что это. Но надо, так надо
            	this.newvalue = ActDsp.value;
            	this.log('start value ' + this.newvalue)
            	this.startTimer('T1', 2, 'next2');
            	this.addListener(ActDsp, 'resetTimer');
           }
            if (ActRz.value == 3) {  // Не совсем понятно, что это. Но надо, так надо
            	this.newvalue = ActDsp.value;
            	this.log('start value ' + this.newvalue)
            	this.startTimer('T1', 2, 'next3');
            	this.addListener(ActDsp, 'resetTimer');
           }
        },
    
       next1() {
       	  this.log('SET '+this.newvalue)
        	  ActComf.setValue(this.newvalue);
              this.exit();
       },
        next2() {
       	  this.log('SET '+this.newvalue)
        	  ActEco.setValue(this.newvalue);
              this.exit();
        },       
      next3() {
       	  this.log('SET '+this.newvalue)
        	  ActOff.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');
            }  
      }
    });
    
    

    А что будет, если второе нажатие случится ДО истечения таймера от первого нажатия? Таймер сам перезапускается, ему команды старт/стоп давать не нужно?



  • Этот скрипт (без таймеров) у меня работает

    const ActRz = Device("ActorA", "Режим отопления");
    const ActComf = Device("ActorA", "Уставка Комфорт");
    const ActEco = Device("ActorA", "Уставка Эконом");
    const ActOff = Device("ActorA", "Уставка Выключено");
    const ActDsp = Device("ActorA", "Отображение уставки текущего режима");
    
    startOnChange(ActDsp);
    
    script({
        start() {
          if (ActRz.value === 0) {
            let newvalue = ActDsp.value;
            ActComf.setValue(newvalue);
            return;
          }  
    
          if (ActRz.value == 1) {
            let newvalue = ActDsp.value;
            ActEco.setValue(newvalue);
            return;
          }
          if (ActRz.value == 3) {
            let newvalue = ActDsp.value;
            ActOff.setValue(newvalue);
            return;
          }
        }
    });
    
    

    Если добавляю таймер только в экономичный режим, все работает (в экономичном режиме переключает тоже)

    const ActRz = Device("ActorA", "Режим отопления");
    const ActComf = Device("ActorA", "Уставка Комфорт");
    const ActEco = Device("ActorA", "Уставка Эконом");
    const ActOff = Device("ActorA", "Уставка Выключено");
    const ActDsp = Device("ActorA", "Отображение уставки текущего режима");
    
    startOnChange(ActDsp);
    
    script({
       newvalue:0,
        start() {
          if (ActRz.value === 0) {
            let newvalue = ActDsp.value;
            ActComf.setValue(newvalue);
            return;
          }  
    
          if (ActRz.value == 1) {
            this.newvalue = ActDsp.value;
            	this.log('start value ' + this.newvalue)
            	this.startTimer('T1', 2, 'next');
            	this.addListener(ActDsp, 'resetTimer');
           }
    
          if (ActRz.value == 3) {
            let newvalue = ActDsp.value;
            ActOff.setValue(newvalue);
            return;
          }
        },
    
       next() {
       	  this.log('SET '+this.newvalue)
        	  ActEco.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');
            }  
      }
    });
    
    

    А если по аналогии делаю все режимы - ничего не работает

    const ActRz = Device("ActorA", "Режим отопления");
    const ActComf = Device("ActorA", "Уставка Комфорт");
    const ActEco = Device("ActorA", "Уставка Эконом");
    const ActOff = Device("ActorA", "Уставка Выключено");
    const ActDsp = Device("ActorA", "Отображение уставки текущего режима");
    
    startOnChange(ActDsp);
    
    script({
       newvalue:0,
        start() {
          if (ActRz.value === 0) {
            this.log('start value ' + this.newvalue)
            	this.startTimer('T1', 2, 'next1');
            	this.addListener(ActDsp, 'resetTimer');
          }  
    
          if (ActRz.value == 1) {
            this.newvalue = ActDsp.value;
            	this.log('start value ' + this.newvalue)
            	this.startTimer('T1', 2, 'next2');
            	this.addListener(ActDsp, 'resetTimer');
           }
    
          if (ActRz.value == 3) {
            this.log('start value ' + this.newvalue)
            	this.startTimer('T1', 2, 'next3');
            	this.addListener(ActDsp, 'resetTimer');
          }
        },
       next1() {
       	  this.log('SET '+this.newvalue)
        	  ActComf.setValue(this.newvalue);
              this.exit();
       },
       next2() {
       	  this.log('SET '+this.newvalue)
        	  ActEco.setValue(this.newvalue);
              this.exit();
       },
       next3() {
       	  this.log('SET '+this.newvalue)
        	  ActOff.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');
            }  
      }
    });
    
    


  • @Erik:

    А что будет, если второе нажатие случится ДО истечения таймера от первого нажатия? Таймер сам перезапускается, ему команды старт/стоп давать не нужно?

    Для этого добавлен слушатель : this.addListener(ActDsp, 'resetTimer');

    В целом, механизм такой:

    Если сценарий запустился и взвел таймеры, он второй раз по триггерам не запустится. Он ведь уже работает!

    И если нужно следить за событиями устройств изнутри сценария, нужно добавить слушателя

     this.addListener(ActDsp, 'resetTimer');
    
    

    Слушатель срабатывает по событиям устройства ActDsp, то есть при втором … n-ном нажатии. По событию выполнится resetTimer

    В нем смотрим - изменилось значение - тогда перевзводим таймер

    Если же таймер досчитал и обновил значение - нужно завершить сценарий

    this.exit();. 
    
    

    Тогда следующее нажатие уже пройдет через старт.

    Если сценарий со слушателем не завершить - он останется активным



  • @Erik:

    Этот скрипт (без таймеров) у меня работает

    А если по аналогии делаю все режимы - ничего не работает

    Вы значение this.newvalue присваиваете только в одном из IF.

     if (ActRz.value === 0) {
          // ЗДЕСЬ НЕТ
            this.log('start value ' + this.newvalue)
            	this.startTimer('T1', 2, 'next1');
            	this.addListener(ActDsp, 'resetTimer');
          }  
    
          if (ActRz.value == 1) {
            this.newvalue = ActDsp.value;
            	this.log('start value ' + this.newvalue)
            	this.startTimer('T1', 2, 'next2');
            	this.addListener(ActDsp, 'resetTimer');
           }
    
          if (ActRz.value == 3) {
          // ЗДЕСЬ НЕТ
            this.log('start value ' + this.newvalue)
            	this.startTimer('T1', 2, 'next3');
            	this.addListener(ActDsp, 'resetTimer');
          }
        }
    
    

    Можно вынести в начало

    start() {
          this.newvalue = ActDsp.value;
          if (ActRz.value === 0) {
         ...
    
    
    


  • Заработало так

    const ActRz = Device("ActorA", "Режим отопления");
    const ActComf = Device("ActorA", "Уставка Комфорт");
    const ActEco = Device("ActorA", "Уставка Эконом");
    const ActOff = Device("ActorA", "Уставка Выключено");
    const ActDsp = Device("ActorA", "Отображение уставки текущего режима");
    
    startOnChange(ActDsp);
    
    script({
       newvalue:0,
        start() {
          if (ActRz.value === 0) {
            this.newvalue = ActDsp.value;
            	this.startTimer('T1', 2, 'next1');
            	this.addListener(ActDsp, 'resetTimer1');
          }  
    
          if (ActRz.value == 1) {
            this.newvalue = ActDsp.value;
            	this.startTimer('T2', 2, 'next2');
            	this.addListener(ActDsp, 'resetTimer2');
           }
    
          if (ActRz.value == 3) {
            	this.newvalue = ActDsp.value;
            	this.startTimer('T3', 2, 'next3');
            	this.addListener(ActDsp, 'resetTimer3');
          }
        },
       next1() {
       	  this.log('SET '+this.newvalue)
        	  ActComf.setValue(this.newvalue);
              this.exit();
       },
       next2() {
       	  this.log('SET '+this.newvalue)
        	  ActEco.setValue(this.newvalue);
              this.exit();
       },
       next3() {
       	  this.log('SET '+this.newvalue)
        	  ActOff.setValue(this.newvalue);
              this.exit();
       },
    
      resetTimer1() {
            if (this.newvalue != ActDsp.value) {      
             	 this.newvalue = ActDsp.value;
             	 this.log('new value '+this.newvalue)
             	 this.stopTimer('T1');
            	 this.startTimer('T1', 2, 'next1');
            }
      },
      resetTimer2() {
            if (this.newvalue != ActDsp.value) {      
             	 this.newvalue = ActDsp.value;
             	 this.log('new value '+this.newvalue)
             	 this.stopTimer('T2');
            	 this.startTimer('T2', 2, 'next2');
            }
      },
      resetTimer3() {
            if (this.newvalue != ActDsp.value) {      
             	 this.newvalue = ActDsp.value;
             	 this.log('new value '+this.newvalue)
             	 this.stopTimer('T3');
            	 this.startTimer('T3', 2, 'next3');
            }  
      }
    });
    
    

    Посоветуйте учебник.

    Хаотические манипуляции с непонятным текстом интересны только первые 20 минут 🙂



  • @Erik:

    Заработало так

    Посоветуйте учебник.

    Хаотические манипуляции с непонятным текстом интересны только первые 20 минут 🙂

    Вы оказывается и таймеры разные взводили 🙂 Но получилось же :!:

    Можно значительно короче - один и тот же таймер и один resetTimer - за один раз сработает только один вариант

    По учебнику - любой по JavaScript, основы, можно в комбинации: JavaScript+Node.js, серверный JavaScript

    Нужно еще привыкнуть, что сценарии выполняются не напрямую, а движком сценариев IH

    И все происходит не линейно, а асинхронно

    Здесь описан механизм сценариев с примерами: https://ih-systems.com/ru/about-scenes/

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

    В нем используются все основные концепции

    И советую применять отладчик в рабочих сценариях, там виден ход выполнения

    Вот результат выполнения одного из вариантов вашего скрипта

    06.02 16:50:53.228 S9(ACTORA1,,ACTORA2,ACTORA3) Trigger ACTORA3
    06.02 16:50:53.229 S9(ACTORA1,,ACTORA2,ACTORA3) Started
    06.02 16:50:53.230 S9(ACTORA1,,ACTORA2,ACTORA3) log: start value 28
    06.02 16:50:53.357 S9(ACTORA1,,ACTORA2,ACTORA3) start timer T1 for 2 sek
    06.02 16:50:55.795 S9(ACTORA1,,ACTORA2,ACTORA3) listener on event ACTORA3: resetTimer
    06.02 16:50:55.796 S9(ACTORA1,,ACTORA2,ACTORA3) exec function resetTimer
    06.02 16:50:55.797 S9(ACTORA1,,ACTORA2,ACTORA3) log: new value 35
    06.02 16:50:55.818 S9(ACTORA1,,ACTORA2,ACTORA3) stop timer T1
    06.02 16:50:55.819 S9(ACTORA1,,ACTORA2,ACTORA3) start timer T1 for 2 sek
    06.02 16:51:00.872 S9(ACTORA1,,ACTORA2,ACTORA3) Done timer T1
    06.02 16:51:00.873 S9(ACTORA1,,ACTORA2,ACTORA3) exec function next
    06.02 16:51:00.874 S9(ACTORA1,,ACTORA2,ACTORA3) log: SET 35
    06.02 16:51:00.895 S9(ACTORA1,,ACTORA2,ACTORA3) do ACTORA2 set 35
    06.02 16:51:00.897 S9(ACTORA1,,ACTORA2,ACTORA3) exit
    
    


  • Пока все по углам не развел - не работало. 🙂



  • Подскажите, а сейчас есть возможность в сценариях сделать что-то такое:

    act.on(onResponse:[this.flag = 1])
    
    

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

    Конечно можно взвести таймер и проверить включился ли актюатор (act.isOn()), но это будет плохим решением когда одна железка отрабатывает за несколько мс (виртуальный актюатор, не подключенный к каналам), другой за 1-2 секунды (MegaD с дисплеями особенно), третий за 30-180 секунд (приводы заслонок с обратной связью).



  • @Alex_Jet:

    Подскажите, а сейчас есть возможность в сценариях сделать что-то такое:

    > act.on(onResponse:[this.flag = 1])
    > 
    

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

    Конечно можно взвести таймер и проверить включился ли актюатор (act.isOn()), но это будет плохим решением когда одна железка отрабатывает за несколько мс (виртуальный актюатор, не подключенный к каналам), другой за 1-2 секунды (MegaD с дисплеями особенно), третий за 30-180 секунд (приводы заслонок с обратной связью).

    Можно, конечно

    Нужно установить слушателя событий this.addListener(device, 'funname')

    Пример 4 из документации https://ih-systems.com/ru/about-scenes/

    /**
    * @name Hello World and Blinking and Manual
    * @desc Тестовый сценарий
    * @version 4 
    */
    
    const lamp = Device("LAMP1");
    
    script ({
      lampState:0, // Просто добавляем объекту свойства - переменные             
      count:0,  // Внутри методов обращаться к ним нужно через this
    
      start() {
        this.count = 0; // В таких переменных данные сохраняются и между запусками.
                        // Иногда это нужно, в данном случае считаем с нуля 
        this.lampState = lamp.value; // фиксируем, в каком состоянии находится лампа
                                    // при запуске
        this.log('Hello, World!');
        this.addListener(lamp, 'onLamp'); // Слушаем переключения состояния лампы
        this.next(); // Запускаем функцию, которая также будет работать по таймеру
      },
    
      next() { 
        if (this.lampState) {
           this.lampState = 0; // Здесь ставим ожидаемое состояние     
           lamp.off(); // Даем команду на выключение.
                       // В следующей строке лампа возможно еще не выключится,
                       // если мы работаем с физическим устр-вом
                       // Когда  выключится и пришлет новое состояние - зависит от железа 
                       // и от плагина. При переключении сработает onLamp  
    
           if (this.count <= 10) {
             this.startTimer('T1', 0.4, 'next'); 
           } else { 
             // Выходим после выключения, 10 раз уже мигнули
            this.exit();
           }    
         } else {
            this.lampState = 1;     
            lamp.on();
            this.count += 1; // считаем включения
            this.startTimer('T1', 3, 'next'); 
         }
      },
    
      onLamp() {
        if (this.lampState != lamp.value) {
          // Было внешнее переключение - завершим сценарий
          this.exit();
        }
      }
    });
    
    
    


  • А можно без слушателя и таймеров.

    Запускать сценарий по факту любого изменения актуатора ( startOnChange(Act); ).

    А внутри сценария проверять какое значение от принял, перепроверять (получать подтверждения), и присваивать/изменять значение глобальной переменной.



  • @intrapro:

    Можно значительно короче - один и тот же таймер и один resetTimer - за один раз сработает только один вариант

    Там каждый "nextХ" работает с конкретным актуатором, а каждый "resetX" отсылает к конкретному "nextX".

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

    Это как сделать?



  • @Erik:

    @intrapro:

    Можно значительно короче - один и тот же таймер и один resetTimer - за один раз сработает только один вариант

    Там каждый "nextХ" работает с конкретным актуатором, а каждый "resetX" отсылает к конкретному "nextX".

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

    Это как сделать?

    Имя строкой не передается. Возможно, добавим этот функционал

    Но думаю вам это и не надо. Вы к разным актуаторам только в next обращаетесь. Нужно запомнить на входе значение ActRz.

    Хотя можно и не запоминать. Просто проверятьActRz в next

    Вариант с запоминанием:

    startOnChange(ActDsp);
    
    script({
       newvalue:0,
       regim:0,
    
        start() {
          if (ActRz.value < 4) {
                   this.newvalue = ActDsp.value;
                   this.regim = ActRz.value;
                   this.startTimer('T1', 2, 'next');
                   this.addListener(ActDsp, 'resetTimer');
          }  
        },
    
       next() {
       	  this.log('SET '+this.newvalue+' regim='+ this.regim);
              if (this.regim == 0)  ActComf.setValue(this.newvalue);
              if (this.regim == 1)  ActEco.setValue(this.newvalue);
              if (this.regim == 2)  ActOff.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');
            }
      }
    });
    
    


  • @intrapro:

    Вариант с запоминанием:

    Да, красиво!

    Спасибо.



  • Доброго времени суток Всем !

    Помогите разобраться с информированием telegramm.

    Создал простейшую блок-схему включения отопителя по условию достижения определённой температуры DHT22_t с последующей отправкой сообщения в telegramm. Все отрабатывает как нужно, но но сообщения в бот валятся при каждом опросе датчика DHT22_t.

    Что я делаю не так ?
    1_3.png
    1_2.png
    1_1.png



  • перед "Action" нужна проверка состояния.

    Если и так все как надо присвоено - ничего не делать.

    Если нет - тогда присвоить и отправить в телеграмм.

    Иначе он каждый раз присваивает и отправляет.


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