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



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

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

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



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

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

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



  • Коллеги, старую версию сценариев уже забыл...как в сценарии проверить включен ли RGB-светильник? По isChanged в отладчике вижу вот это:

    isChanged(RGBLAMP4_01,aval)=true Changed: {"RGBLAMP4_01":{"aval":[255,255,255],"dval":1,"stval":1}}
    


  • Добрый день.
    this.isChanged(device1) проверяет свойство Error устройства device1 ?
    В сценарии есть команда
    if(this.isChanged(TERMOREG_1)) {
    //
    }

    Сценарий запускается по изменению, но при этом результат проверки условия false.
    02.12 16:10:27.687 Check(TERMOREG_1) => true
    02.12 16:10:27.688 Started
    02.12 16:10:27.689 isChanged(TERMOREG_1,aval)=false Changed: {"TERMOREG_1":{"err":"Device timeout error!"}}
    02.12 16:10:27.689 isChanged(LAMP_32,dval)=false Changed: {"TERMOREG_1":{"err":"Device timeout error!"}}
    02.12 16:10:27.689 isChanged(TERMOREG_3_1,aval)=false Changed: {"TERMOREG_1":{"err":"Device timeout error!"}}
    02.12 16:10:27.689 Stopped

    Тип устройства: аналоговый датчик.



  • @fanagor, добрый день.

    Метод this.isChanged позволяет узнать, какое событие стало причиной запуска сценария:
    this.isChanged(device, 'setpoint') - изменили уставку
    this.isChanged(device, 'auto') - изменился флаг auto
    this.isChanged(device, 'value') - изменилось основное значение

    this.isChanged(device) сокращенная форма для this.isChanged(device, 'value'), то есть =true, если сценарий запущен при изменении основного свойства устройства (aval для аналогового, dval для дискретного устройства)

    isChanged(TERMOREG_1,aval)=false Changed: {"TERMOREG_1":{"err":"Device timeout error!"}} означает:
    Сценарий запустился при изменении основного значения TERMOREG_1?
    Нет, изменился флаг ошибки "err", так как сработал таймаут
    Истинным в данном случае будет
    this.isChanged(TERMOREG_1, 'error') или this.isChanged(TERMOREG_1, 'err')



  • Это сообщение удалено!


  • Добрый день!
    При использовании функции boot() сценарий запускается при старте сервера и остается постоянно активным хотя в нем никаких таймеров и слушателей нет. Так и должно быть?



  • @Lost, добрый день!
    Нет, так быть не должно.
    Функция boot должна проверить условие, и если истина, запускается функция start(). Дальше работает как обычно. Этот же сценарий может запускаться дальше по startOnChange() или интерактивно

    script({
      boot() { 
         return lamp.isOn();  // Запустит на старте функцию  start, если выполнено условие
        // return true; // Будет всегда запускать на старте  функцию start
      },
      start() { 
      	.....
      },
    

    В самой boot никаких действий делать не надо!



  • Я и не делал. Сделано пока вот так для пробы:
    script({
    boot() {
    return true;
    },
    start() {
    global.set(‘Armed’, 1);
    },
    Скрипт после перезагрузки сервера запускается и висит активным в рабочих сценариях (есть зеленая галочка). Вручную останавливается. Если вручную запустить то он после отработки останавливается (увеличивается счетчик количества запусков). Что не так?



  • @Lost, Вы правы, это баг 😞
    Сценарий с boot, не имеющий асинхронных механизмов, остается в состоянии активный (зеленая галочка)
    Исправим в версии 4.7.7, выйдет на следующей неделе



  • Здравствуйте, уважаемые разработчики и форумчане! Поздравляю всех с наступившим Новым 2021 годом!
    Желаю всем творческих успехов.
    А теперь о проблеме. Пишу сценарий для управления новогодней гирляндой. У нее есть http API. При управлении используются данные из предыдущих ответов на запрос. Проблема в том, что не получается распарсить ответ и присвоить его разным переменным. Вот, собственно, сценарий

    /** 
    * @name twinkly_http 
    * @desc  
    * @version 4  
    */
    
    script({
        host: '192.168.144.68',
        port: 80,
        method: '',
        path: '',
        myObj: '',
    
        start() {
          // login
          this.path = '/xled/v1/login';
          this.method = 'POST';
          this.send_http();
    
          // verify
          
          // Действие
          
        },  
        
        send_http() {
          const http = require('http');
          const querystring = require('querystring');
          const postData = JSON.stringify({
            challenge: 'AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8='
          });
          this.log('postData: '+postData);
          
          var options = {
            hostname: this.host,
    	      port: this.port,
    	      path: this.path,
    	      method: this.method,
    	      headers: {
    	        'Host': '192.168.144.68',
    		      'Content-Type': 'application/json',
    		      'Content-Length': postData.length //Buffer.byteLength(postData)
    	      }
          };
    
          var req = http.request(options, (res) => {
    	      this.log('STATUS: '+res.statusCode);
    	      this.log('HEADERS:' +JSON.stringify(res.headers));
    	      res.setEncoding('utf8');
    	      res.on('data', (chunk) => this.myObj += chunk);
    
    	      res.on('end', () => {
    		      this.log('Data:' +this.myObj);
    		      const data = JSON.parse(this.myObj);
    		      this.log('Code:' +data);
    		      this.log(typeof this.myObj === 'string');
    		      this.log('No more data in response.');
    	      });
          });
    
          req.on('error', (e) => {
    	      this.log('problem with request: ' +e.message);
          });
    
          // write data to request body
          req.write(postData);
          req.end();
        }
    });
    

    А вот сообщение в отладчике

    03.01 13:15:08.970 Started
    03.01 13:15:08.971 log: postData: {"challenge":"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8="}
    03.01 13:15:08.994 Stopped
    03.01 13:15:09.013 log: STATUS: 200
    03.01 13:15:09.017 log: HEADERS:{"connection":"close","content-length":"155","content-type":"application/json"}
    03.01 13:15:09.021 log: Data:{"authentication_token":"4Be8Ix3sQBQ=","authentication_token_expires_in":14400,"challenge-response":"7ef99322220ff8a9c45aa1efa26ba01d2320aecc","code":1000}
    03.01 13:15:09.024 log: Code:[object Object]
    03.01 13:15:09.026 log: true
    03.01 13:15:09.028 log: No more data in response.

    Данные из строки Data не могу получить по отдельности. Перечитал разные доки, форумы. Ничего не получается. Что я делаю не так?



  • @int144, добрый день! Удачи в Новом году!!!

    Данные из строки Data не могу получить по отдельности.

    Если только в этом проблема, то здесь у вас уже все есть, нужно брать свойства data через точку:

    const data = JSON.parse(this.myObj); // из строки получился прекрасный объект, дальше присваиваете свойствам сценария или локально:

    this.authentication_token = data.authentication_token;
    const challenge-response = data.challenge-response;



  • @intrapro, спасибо за быстрый ответ.
    Заработало, хотя вроде пробовал так, но может не совсем так. Но!
    Значения выводятся в лог, только если я их присвоил в разделе res.on('end'..., а если я пытаюсь вывести в лог присвоенные значения из start после вызова this.send_http, то получаю пустые значения



  • @int144, все верно, start работает синхронно, он просто запускает запрос в this.send_http и идет дальше. Не ждет, когда придет ответ на запрос.

    03.01 13:15:08.994 Stopped - здесь start уже работу свою закончил

    Можно взвести таймер (на 1 сек или меньше, 0.1 даже достаточно). И в этой функции значения уже должны быть



  • @intrapro, а таймер взводить в start?



  • @int144, да



  • @intrapro, спасибо, буду пробовать



  • Добрый день!
    Не работает команда операционной системы
    Вот сценарий

    const mon = Device("POWER_MIRROR");
    
    // Запускаем сценарий при изменении состояния выключателя зеркала
    startOnChange(mon);
    
    script({
        start() {
          if (mon.isOff()) // Если он выключен
            this.execOS(`/home/pi/mirror_off.sh`); // Даем команду на выключение монитора
          else
            this.execOS(`/home/pi/mirror_on.sh`); // Иначе - на включение
        }
    });
    

    В отладчике пишет

    04.01 15:56:49.463 Trigger POWER_MIRROR
    04.01 15:56:49.464 Started
    04.01 15:56:49.465 execOS: /home/pi/mirror_off.sh
    04.01 15:56:49.492 Stopped
    04.01 15:56:49.522 execOS error: Error: Command failed: /home/pi/mirror_off.sh
    No protocol specified
    xset: unable to open display ":0.0"

    04.01 15:56:49.523 stdout:
    04.01 15:56:49.524 stderr: No protocol specified
    xset: unable to open display ":0.0"

    Хотя из терминала все прекрасно срабатывает. Может кто-то подсказать куда копать?



  • Подскажите как можно вывести среднюю температуру с 3 датчиков температури в сценарии? Хочу чтобы рекуператор менял уставку в зависимости от температуры в помещении.



  • @amgstone, ну а в чем проблема? Подтягиваете в сценарий своих 3 датчика температуры, в переменную заносите среднюю температуру от них и присваиваете 4-му датчику усредненное значение, по которому будет работать рекуператор.


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