Сценарии пользователей
-
Добрый день! Подскажите пожалуйста каким образом можно реализовать счётчик моточасов? И как в сценарии при передаче сообщения о срабатывании датчика движения кроме передачи имени датчика, зоны срабатывания передать и время его срабатывания?
Первый вопрос реализовал сценарием (помогла идея по использованию плагина эмулятора). Вроде работает нормально (в эмуляторе устройство изменяет свое состояние 1 раз в 60 секунд).
А вот по второму вопросу все таки прошу помочь
Добрый день!
Отлично, что придумали реализацию, пока мы не сделали циклический запуск по расписанию
По второму вопросу - вы хотите передать время срабатывания датчика в сценарии, который вызван при сработке? То есть текущую дату и время?
let dt = new Date(); // это текущее время this.log('Время '+dt.toLocaleString()) ; // 'Время 2019-1-29 11:25:13',
-
Спасибо! Но надо только время, без даты.
Тогда можно так:
let dt = new Date(); this.log('Время '+dt.getHours()+":"+dt.getMinutes()+":"+dt.getSeconds() );
Или так:
let dt = new Date(); this.log('Время '+dt.toLocaleString().substr(10))
-
Задача - Если насос/котел/кран не менял свое состояние (не включался) больше некоторого времени, то включить его на 5 минут и затем выключить. Сам скрипт оказался не таким сложным. Но понадобилось время чтобы в json-конфигах сервера разыскать параметр устройства под названием "lastts" - это время последнего изменения состояния (ON/OFF/TOGGLE) устройства в мс. Параметры устройств нигде не опубликованы, о чем я сожалею. Однако если скрипт оставлять в таком виде, в котором я его привел, то нужно запускать его по расписанию в "cron". Может быть кто-нибудь подскажет - можно ли что-то сделать со StartOnChange или Listener - чтобы сценарий самостоятельно запускался каждую минуту/10 минут/час/день/неделю?
/** * @name Включение устройств на время * @desc Если прошло больше времени с момента последнего включения чем задано в сценарии, то включаем устройство на некоторое время * @version 4 */ const dev = Device("PUMP1"); script({ start() { let TurnOnDur = 300; //Длительность работы в секундах let timer = 4; //Таймер отсчета в часах let nowtime = Date.now(); // Текущее время в мс let lasttime = dev.getParam('lastts'); //Время изменения состояния в мс let diftime = nowtime - lasttime; //Разница в мс let dif = diftime/(1000*60*60); //Разница в часах let hours = Math.floor(dif); let minutes = Math.round((dif-hours)*60); //this.log(nowtime+ " - " +lasttime+ " = " +diftime); if(dev.isOff() && dif > timer) { this.log(dev.name+ " last ON = " +((hours < 10) ? "0" : "")+hours+ ":" +((minutes < 10) ? "0" : "")+minutes+ " ago > " +timer+ " -> TurnOn by " +TurnOnDur/60+ "min"); dev.on(); this.startTimer("T1", TurnOnDur, "TurnOffDev"); } else if(dev.isOn()) { this.log(dev.name+ " is ON ~ " +((hours < 10) ? "0" : "")+hours+ ":" +((minutes < 10) ? "0" : "")+minutes+ " -> exit"); } else { this.log(dev.name+ " last ON = " +((hours < 10) ? "0" : "")+hours+ ":" +((minutes < 10) ? "0" : "")+minutes+ " ago < " +timer+ " -> exit"); } }, TurnOffDev() { dev.off(); dev.setAuto('True'); } });
Если это будут читать разработчики iH, то ответьте на мои вопросы: тут и тут.
-
Задача - Если насос/котел/кран не менял свое состояние (не включался) больше некоторого времени, то включить его на 5 минут и затем выключить. Сам скрипт оказался не таким сложным. Но понадобилось время чтобы в json-конфигах сервера разыскать параметр устройства под названием "lastts" - это время последнего изменения состояния (ON/OFF/TOGGLE) устройства в мс. Параметры устройств нигде не опубликованы, о чем я сожалею. Однако если скрипт оставлять в таком виде, в котором я его привел, то нужно запускать его по расписанию в "cron". Может быть кто-нибудь подскажет - можно ли что-то сделать со StartOnChange или Listener - чтобы сценарий самостоятельно запускался каждую минуту/10 минут/час/день/неделю?
> /** > * @name Включение устройств на время > * @desc Если прошло больше времени с момента последнего включения чем задано в сценарии, то включаем устройство на некоторое время > * @version 4 > */ > > const dev = Device("PUMP1"); > > script({ > start() { > let TurnOnDur = 300; //Длительность работы в секундах > let timer = 4; //Таймер отсчета в часах > let nowtime = Date.now(); // Текущее время в мс > let lasttime = dev.getParam('lastts'); //Время изменения состояния в мс > let diftime = nowtime - lasttime; //Разница в мс > let dif = diftime/(1000*60*60); //Разница в часах > let hours = Math.floor(dif); > let minutes = Math.round((dif-hours)*60); > > //this.log(nowtime+ " - " +lasttime+ " = " +diftime); > > if(dev.isOff() && dif > timer) { > this.log(dev.name+ " last ON = " +((hours < 10) ? "0" : "")+hours+ ":" +((minutes < 10) ? "0" : "")+minutes+ " ago > " +timer+ " -> TurnOn by " +TurnOnDur/60+ "min"); > dev.on(); > this.startTimer("T1", TurnOnDur, "TurnOffDev"); > } > else if(dev.isOn()) { > this.log(dev.name+ " is ON ~ " +((hours < 10) ? "0" : "")+hours+ ":" +((minutes < 10) ? "0" : "")+minutes+ " -> exit"); > } > else { > this.log(dev.name+ " last ON = " +((hours < 10) ? "0" : "")+hours+ ":" +((minutes < 10) ? "0" : "")+minutes+ " ago < " +timer+ " -> exit"); > } > }, > > TurnOffDev() { > dev.off(); > dev.setAuto('True'); > } > }); > >
Если это будут читать разработчики iH, то ответьте на мои вопросы: тут и тут.
Это можно делать используя эмулятор сенсора. В настройках плагина задается период изменения, а сценарий выполняется по признаку startOnChange(sensor_name), либо это не чаще раза в день, то можно запускать сценарий в определенное время каждый день\день месяца\дни недели
-
Это можно делать используя эмулятор сенсора. В настройках плагина задается период изменения, а сценарий выполняется по признаку startOnChange(sensor_name), либо это не чаще раза в день, то можно запускать сценарий в определенное время каждый день\день месяца\дни недели
Про этот "костыль" я слышал, но не хочется в системе такого уровня использовать подобные вещи. Должно работать либо на основе методов сценария, либо штатным образом, как это делается везде - методом запуска сценариев через cron.
-
как это делается везде - методом запуска сценариев через cron.
Через Cron? Лично для меня это и есть костыль
-
Задача - Если насос/котел/кран не менял свое состояние (не включался) больше некоторого времени, то включить его на 5 минут и затем выключить. Сам скрипт оказался не таким сложным. Но понадобилось время чтобы в json-конфигах сервера разыскать параметр устройства под названием "lastts" - это время последнего изменения состояния (ON/OFF/TOGGLE) устройства в мс.
Не совсем так. lastts - это временная метка не ИЗМЕНЕНИЯ состояния, а получения данных от железа (даже если изменений нет)
Это время вы видите в меню устройства внизу
Почему - см ответ в другой теме: https://frm.intrahouse.ru/viewtopic.php?f=18&t=5446&p=8867#p8867
Для получения времени последнего изменения состояния (переключения) добавим новую функцию сценария в следующем релизе.
Параметры устройств нигде не опубликованы, о чем я сожалею.
Да, вы правы. Добавим в документацию
Однако если скрипт оставлять в таком виде, в котором я его привел, то нужно запускать его по расписанию в "cron". Может быть кто-нибудь подскажет - можно ли что-то сделать со StartOnChange или Listener - чтобы сценарий самостоятельно запускался каждую минуту/10 минут/час/день/неделю?
Нет, использовать cron мы не планируем.
Добавим либо циклический запуск из расписания, либо правило для запуска прямо в сценарии. Эта задача включена в план.
Если это будут читать разработчики iH, то ответьте на мои вопросы:
Постараемся не только ответить, но и реализовать. Но не все сразу
-
@intrahouse:
как это делается везде - методом запуска сценариев через 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: я часто сталкиваюсь с тем, что разработчики получат майл/пост на форуме и примут решение действительно что-то реализовать. А спустя день/неделю/месяц выкатывают свое решение (прошивка/новая версия ПО и т.д.). В итоге в это время живешь в условиях "вакуума" - то ли не прочитали, то ли забили, то ли что-то делают? Поэтому стараюсь задавать конкретные вопросы, чтобы получить на них конкретные ответы/комментарии.
-
Господа, дайте примеров сценариев с переключателями, не могу сообразить, просто примеры. Будут ли в "блоках" переключатели?
-
Господа, дайте примеров сценариев с переключателями, не могу сообразить, просто примеры. Будут ли в "блоках" переключатели?
Конкретизируйте что Вам необходимо реализовать?
-
Нужен переключатель на 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, или есть еще какие решения? Заранее спасибо!