Сценарии пользователей



  • @Alex_Jet:

    Задача - Если насос/котел/кран не менял свое состояние (не включался) больше некоторого времени, то включить его на 5 минут и затем выключить. Сам скрипт оказался не таким сложным. Но понадобилось время чтобы в json-конфигах сервера разыскать параметр устройства под названием "lastts" - это время последнего изменения состояния (ON/OFF/TOGGLE) устройства в мс.

    Не совсем так. lastts - это временная метка не ИЗМЕНЕНИЯ состояния, а получения данных от железа (даже если изменений нет)

    Это время вы видите в меню устройства внизу

    Почему - см ответ в другой теме: https://frm.intrahouse.ru/viewtopic.php?f=18&t=5446&p=8867#p8867

    Для получения времени последнего изменения состояния (переключения) добавим новую функцию сценария в следующем релизе.

    @Alex_Jet:

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

    Да, вы правы. Добавим в документацию

    @Alex_Jet:

    Однако если скрипт оставлять в таком виде, в котором я его привел, то нужно запускать его по расписанию в "cron". Может быть кто-нибудь подскажет - можно ли что-то сделать со StartOnChange или Listener - чтобы сценарий самостоятельно запускался каждую минуту/10 минут/час/день/неделю?

    Нет, использовать cron мы не планируем.

    Добавим либо циклический запуск из расписания, либо правило для запуска прямо в сценарии. Эта задача включена в план.

    @Alex_Jet:

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

    Постараемся не только ответить, но и реализовать. Но не все сразу 🙂



  • @intrahouse:

    @Alex_Jet:

    как это делается везде - методом запуска сценариев через cron.

    Через Cron? Лично для меня это и есть костыль

    Ну это образно выражаясь. Cron - это прерогатива ОС, хотя я в своей СУиМ на php/js очень даже успешно использовал этого демона. Я больше к тому, что в движке iH должен быть свой аналог cron.
    @intrapro:

    Постараемся не только ответить, но и реализовать. Но не все сразу 🙂

    А можно тогда комментарии по 1,2,3,4 вопросам, которые озвучивал в посте https://frm.intrahouse.ru/viewtopic.php?f=18&t=5446&start=110#p8771 другой темы?

    PS: я часто сталкиваюсь с тем, что разработчики получат майл/пост на форуме и примут решение действительно что-то реализовать. А спустя день/неделю/месяц выкатывают свое решение (прошивка/новая версия ПО и т.д.). В итоге в это время живешь в условиях "вакуума" - то ли не прочитали, то ли забили, то ли что-то делают? Поэтому стараюсь задавать конкретные вопросы, чтобы получить на них конкретные ответы/комментарии.



  • Господа, дайте примеров сценариев с переключателями, не могу сообразить, просто примеры. Будут ли в "блоках" переключатели?



  • @thunder_d:

    Господа, дайте примеров сценариев с переключателями, не могу сообразить, просто примеры. Будут ли в "блоках" переключатели?

    Конкретизируйте что Вам необходимо реализовать?



  • Нужен переключатель на 10 положений (режимов), чтобы переключал 10 сценариев. 😉



  • Участник @thunder_d написал в Сценарии пользователей:

    Нужен переключатель на 10 положений (режимов), чтобы переключал 10 сценариев. 😉

    Делаете аналоговый актуатор с 10 фиксированными состояниями, и выводите его в интерфейс в виде переключателя.
    А в ваши скрипты добавляете проверку состояния этого актуатора. Если значение нужное - скрипт выполняется.



  • Переключатель уже давно готовый , мне надо пример сценария и только



  • @thunder_d написал в Сценарии пользователей:

    Переключатель уже давно готовый , мне надо пример сценария и только

    Извините за задержку с ответом
    Пример для стандартного переключателя на 3 состояния: Авто - Старт-Стоп
    Используется конструкция JavaScript-а switch
    Каждый вариант - это отдельный case, который должен заканчиваться break

    /** 
    * @name Отработка команд переключателя 
    * @desc  
    * @version 4 
    */
    
    const sw = DeviceT("SWITCH1"); 
    const vent = Device("VENT1"); 
    
    startOnChange(sw);
    
    const script = {
        start() {
          switch (Number(sw.value)) {
    
            case 0: 
                vent.setParam('auto',1);
                this.log('Вентилятор переведен в Авто с переключателя');
                break;
    
             case 1: 
                vent.on();
                this.log('Вентилятор включен с переключателя');
                break; 
    
             case 2: 
                vent.off();
                break; 
    
             // case 3:  ...  все остальные состояния 
          } 
        } 
    };
    

    Если действий много, для каждого варианта можно сделать отдельную функцию:

    /** 
    * @name Переключатель - своя функция для каждого случая
    * @desc  
    * @version 4 
    */
    
    const sw = DeviceT("SWITCH1"); 
    const vent = Device("LAMP1"); 
    
    startOnChange(sw);
    
    const script = {
        start() {
          switch (Number(sw.value)) {
    
            case 0: 
                this.press0();
                break;
    
             case 1: 
                this.press1();
                break; 
    
             case 2: 
                this.press2();
                break; 
          } 
        },
        
        press0() {
          vent.setParam('auto',1);
        },
        
        press1() {
          vent.on();
        },
        
        press2() {
          vent.off();
        }
    };
    

    Обратите внимание, что вызывать функции нужно через this: this.press2();

    Сценарий из сценария вызывать на данный момент нельзя 😞



  • Сенкью вэри мачь. Буду разбираться.



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


  • Подскажите, как работать со временем в сценариях? Очень простая задача - сделать будильник (включение/выключение), но время необходимо вводить/изменять в интерфейсе. Понятно, что это можно сделать и через расписание, но как-то тяжело объяснить пожилым людям как им настраивать и изменять расписание ☹
    Так же хотелось бы узнать, можно ли добавить в свойства устройств время? Не временной интервал, а именно время?



  • @gis
    Если с расписанием не хочется работать, то можно сделать например, так:

    /** 
    * @name Управление будильником 
    * @desc  
    * @version 4 
    */
    const clock = Device("alarmClock",  [{"name":"wakeUpTime", "note":"Время будильника", "type":"time", "val":0}]); 
    
    script({
        boot() {
          return true;
        },
        
        start() {
          // Вывести планируемое время при старте - только для отладки. Реально оно будет динамически пересчитываться
          this.log('Планируемое время: '+ this.showWakeUpTime());
            
          // Сразу проверить время, затем проверять каждые 30 сек
          this.manageClock();
          this.startTimer("T1", 30, "onTimer");
        },
        
        onTimer() {
          this.manageClock();
          this.startTimer("T1", 30, "onTimer");
        },
        
        manageClock() {
          const itsTimeToWakeUp = this.checkWakeUpTime();
          if (itsTimeToWakeUp) {
            
            this.log('Будильник: '+ this.showWakeUpTime());
            clock.on(); 
          } else if (clock.isOn()) {
            // В следующем цикле сбросить
            clock.off();
          }
        },
        
        calcWakeUpTime() {
           // К времени от полуночи прибавить временной интервал устройства. Умножить на 1000, так как дате нужны милисекунды  
           return new Date().setHours(0,0,0,0) + clock.getParam('wakeUpTime')*1000;
        },
        
        checkWakeUpTime() {
          // Будильник должен сработать, если текущее время попадает в 30 сек интервал
          return (clock.getParam('wakeUpTime') && Math.abs(Date.now() - this.calcWakeUpTime() ) < 30000);
        },
        
        showWakeUpTime() {
           return new Date(this.calcWakeUpTime()).toLocaleString();
        }
    });
    

    Здесь alarmClock - дискретный актуатор, для которого задаем время сработки будильника как параметр. Используется компонент типа "time", он дает количество секунд. Прибавляем к полуночи и получаем время.

    Сценарий запускается на старте сервера (boot - true) и постоянно активен. Постоянно взводит таймер и проверяет, не пришло ли время звонить. Точность будет зависеть от интервала таймера, здесь - 30 сек, можно сделать и чаще.
    Так как никакого другого события запуска кроме старта сервера нет, при первом запуске или после редактирования сценарий автоматически не запустится, его надо запустить вручную. Штатно он всегда должен быть активен, в Рабочих сценариях должна быть зеленая галочка.

    Дальше можно доработать сценарий с учетом дня недели - задать для каждого дня время или просто checkbox-ы - должен сработать или нет в конкретный день. Также можно использовать механизм auto или дополнительные флаги для включения - отключения функции.
    Для самого устройства (его ведь придется вынести на интерфейс, чтобы устанавливать время) вероятно нужно настроить Действие при нажатии - off или даже none.



  • Спасибо большое! Попробую реализовать.



  • Добрый вечер! Есть связка RPi4 + Mega (пока по USB). Подскажите, как работать с Serial для выдачи команды в канал от IHS к устройству, подключенному к Ардуино, и приема из канала ответа устройства, подключенного к Ардуино? Только по Modbus, или есть еще какие решения? Заранее спасибо!



  • Участник @kostinanton написал в Сценарии пользователей:

    Добрый вечер! Есть связка RPi4 + Mega (пока по USB). Подскажите, как работать с Serial для выдачи команды в канал от IHS к устройству, подключенному к Ардуино, и приема из канала ответа устройства, подключенного к Ардуино? Только по Modbus, или есть еще какие решения? Заранее спасибо!

    Только по Modbus. Других вариантов сейчас нет



  • @intrahouse в есть наработки по МЭК-61850?



  • @intrapro а подскажите, как из свойства time получить значения минут и секунд? Устанавливаю на 00:00:00, в логе вижу значение:
    03.03 16:49:47.867 log: 4492800
    как преобразовать?



  • @homa, если Вы имеете в виду параметр сценария type:"time", там банальные секунды 🙂
    Вот например сценарий определяет параметры auto_afterOn, auto_afterOff

    const kev_speed_status = Device("SensorD","Состояние скоростей", [
      {"name":"auto_afterOn", "note":"После ручного включения", "type":"time", "val":0},
      {"name":"auto_afterOff", "note":"После ручного выключения", "type":"time", "val":0}
      ]);
    
    script({
        start() {
         .....
          this.log("auto_afterOn="+kev.getParam('auto_afterOn'))
         ......
        } 
    });
    

    Задаем 1 час
    timeParam.png

    Результат:
    03.03 17:55:42.230 log: auto_afterOn=3600

    Если поставить 00:00:00
    03.03 17:55:04.036 log: auto_afterOn=0

    Или что-то другое имелось в виду?



  • @intrapro я и ожидал секунды... но почему-то значение в 52 дня лежит, хотя выставлено 0



  • @homa да странно 😞 А если изменить?


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