Сценарии в intraHouse Cherry
-
Выложили шаблоны сценариев https://intrahouse.ru/scenes-examples_ru/
Их можно устанавливать двумя способами.
1. Загрузить zip файл со сценарием https://intrahouse.ru/work-scenes_ru/
2. Copy/Paste. Просто скопировать текст скрипта, добавить новый сценарий и вставить туда скопированный текст.
Также как в Berry, остается только привязать устройства к сценарию. При этом, при желании, можно корректировать сценарий.
Вариантов разных сценариев может быть много. Мы можем написать и опубликовать любые сценарии. Но желательно чтобы эти сценарии были востребованы и другими пользователями. Спрашивайте, обсуждайте функционал сценария, а мы реализуем.
Это не исключает самостоятельного написания сценариев. Если кто-то поделится своим скриптом, очень хорошо.
-
Спасибо большое!
Думаю, многим это будет интересно
Чтобы еще больше облегчить жизнь тем, кто захочет загрузить Ваш сценарий, сохраняйте его в zip как файл с расширением .js, а не .txt. А еще проще - сохраняйте прямо в Project Manager в списке сценариев командой "Выгрузить в файл".
Тогда командой "Загрузить из файла" сценарий сразу загрузится в проект.
-
А где задается заданная температура отопления?
-
Спасибо большое!
Думаю, многим это будет интересно
Чтобы еще больше облегчить жизнь тем, кто захочет загрузить Ваш сценарий, сохраняйте его в zip как файл с расширением .js, а не .txt. А еще проще - сохраняйте прямо в Project Manager в списке сценариев командой "Выгрузить в файл".
Intrahouse_scenes.png
Тогда командой "Загрузить из файла" сценарий сразу загрузится в проект.
Перевыгрузил. Предыдущий пост тогда лучше удалить, чтобы никого не смущать.
Управление светом
-
Управление вытяжкой\замком
-
А где задается заданная температура отопления?
В пользовательском интерфейсе при длинном нажатии на датчик температуры вызывается окно свойств датчика.
Там слайдером можно менять уставку температуры.
-
А можно для необразованных разжевать - как шаблонный сценарий привязать к устройствам? В Berry было все тривиально…тут затрудняюсь.
-
А можно для необразованных разжевать - как шаблонный сценарий привязать к устройствам? В Berry было все тривиально…тут затрудняюсь.
Вся настройка сценариев - в разделе Сценарии. Если сам сценарий уже есть (скачан или написан), то заполняются строчки в табличке "Запуск для устройств". Конечно, сделать это можно только для мультисценариев (шаблонных в терминологии Berry)
Просто выбираются устройства из списка устройств подходящего классаВозможно, затруднение связано с использованием списочного компонента. После того, как устройство выбрано, чтобы его поменять, нужно стирать строку, и будет появляться отфильтрованный список.
Как результат все рабочие сценарии, включая только что добавленный, можно увидеть в списке Рабочие сценарии.
Там есть информация об активных сценариях, времени последнего запуска и т д
Если сценарий имеет триггеры, то он запускается по событиям этих триггеров (Сценарии по событию в Berry)Если триггеров нет - это интерактивные сценарии, их можно вызывать с кнопки, по расписанию и тд
Наличие триггеров у сценария определяется неявно по функции check()
check() { return ((lamp.auto == 1) && ((lamp.dval == 0) && (motion.dval == 1) || (lamp.dval > 0))); },
Все устройства, включенные в check, являются триггерами - в данном случае lamp и motion
Если check возвращает true, то сценарий запускается (выполняется функция start) - примерно также как в Berry
Интерактивный сценарий не должен иметь check, если его запустили - он должен сработать, нужные проверки выполняются уже внутри запущенного сценария.
-
Добрый день!
Можно ли сделать так, что бы в процессе привязки датчика и устройства была строка для написания текста для отправки по e-mail с целью конкретного указания места, где сработал датчик. А то иметь на каждую группу устройств по индивидуальному сценарию не очень удобно.
Да, предложение хорошее - вместе с набором устройств добавлять дополнительные параметры при настройке в PM. Подумаем над реализацией.
Но в данном случае решение есть - можно в текст включить данные устройства в любой комбинации
sensor.name - название датчика
sensor.nameOf("place") - название уровня
sensor.nameOf("room") - название зоны
sensor.nameOf("subs") - название подсистемы
sensor.getPlaceDesc() - уровень и зона вместе, разделяются символом /: "1 этаж/Котельная"
Если уровня или зоны нет - выдается то что есть, без разделителя
Например:
this.info("email", "OWNER", "Тревога! "+ sensor.nameOf("place")+" "+sensor.nameOf("room")+". Сработал "+sensor.name)
Сформирует сообщение: "Тревога! 1 этаж Холл. Сработал Датчик движения"
Или
this.info("email", "OWNER", actor2.nameOf("place") + ": Включена сирена! Движение "+ sensor.getPlaceDesc())
Сформирует сообщение: "Гараж: Включена сирена! Движение 1 этаж/Коридор"
-
Добрый день!
Можно ли сделать так, что бы в процессе привязки датчика и устройства была строка для написания текста для отправки по e-mail с целью конкретного указания места, где сработал датчик. А то иметь на каждую группу устройств по индивидуальному сценарию не очень удобно.
Да, предложение хорошее - вместе с набором устройств добавлять дополнительные параметры при настройке в PM. Подумаем над реализацией.
Но в данном случае решение есть - можно в текст включить данные устройства в любой комбинации
sensor.name - название датчика
sensor.nameOf("place") - название уровня
sensor.nameOf("room") - название зоны
sensor.nameOf("subs") - название подсистемы
sensor.getPlaceDesc() - уровень и зона вместе, разделяются символом /: "1 этаж/Котельная"
Если уровня или зоны нет - выдается то что есть, без разделителя
Например:
> this.info("email", "OWNER", "Тревога! "+ sensor.nameOf("place")+" "+sensor.nameOf("room")+". Сработал "+sensor.name) > >
Сформирует сообщение: "Тревога! 1 этаж Холл. Сработал Датчик движения"
Или
> this.info("email", "OWNER", actor2.nameOf("place") + ": Включена сирена! Движение "+ sensor.getPlaceDesc()) > >
Сформирует сообщение: "Гараж: Включена сирена! Движение 1 этаж/Коридор"
А нет никакой инструкции вцелом по работе с плагином email? Задумка отправлять в заданный день месяца показания счётчиков на емэйл в УК и себе, но не представляю как это реализовать.
-
Недоступен для скачивания сценарий "Управление батареями отопления по датчикам температуры"…
Расскажите про добавление в сценарии пользовательских настроек. Например, делаю так:
const heater = Device("ActorD", "Нагреватель", [ {"name":"hist", "note":"Гистерезис включения/отключения актюатора, °C", "type":"number", "val":0.2} ]);
Но какое значение может быть в type чтобы hist можно было менять с точностью 0,05 градуса, например.
-
Недоступен для скачивания сценарий "Управление батареями отопления по датчикам температуры"…
Проверим
Расскажите про добавление в сценарии пользовательских настроек. Например, делаю так:
> const heater = Device("ActorD", "Нагреватель", [ > {"name":"hist", "note":"Гистерезис включения/отключения актюатора, °C", "type":"number", "val":0.2} > ]); >
Но какое значение может быть в type чтобы hist можно было менять с точностью 0,05 градуса, например.
Для "type":"number" в пользовательском интерфейсе можно ввести вручную любое число, в том числе с любым числом знаков после запятой.
- и - использовать не обязательно. Планируем шаг для +- также сделать настаиваемыми из сценария, но пока этого нет
Другие варианты:
"type":"cb" - checkbox,
"type":"time" - настройка времени - часы, минуты, секунды
-
Добрый день всем!!!
Реализовал в своем сценарии передачу сообщения на e-mail при работке датчика движения (this.info("email", "OWNER", "Тревога! "+ sensor.nameOf("place")+" "+sensor.nameOf("room")+". Сработал "+sensor.name)). Усложняем задачу!
В контроллере MegaD-2561 реализована возможность передачи и приема SMS сообщений https://ab-log.ru/page.php?Cat=110&ID=195&q=sim800.
Из темы:
Входящее SMS-сообщение передается на сервер следующим образом.
/script.php?sms_phone=+79000001234&sms_text=hello
Сервер также может через контроллер отправлять произвольные сообщения. Для этого необходимо отправить запрос следующего вида.
http://192.168.0.14/sec/?sms=Alarm!&phone=+79000000000
Подскажите пожалуйста как должна выглядеть строка в сценарии, что бы сообщение было продублировано на контроллер, а тот в свою очередь выслал бы это сообщение по SMS?
Добрый день!
Для этого есть функция сценария plugincommand(pluginID, obj), но пока плагин MegaD такую функцию не поддерживает
Добавим в ближайшее время.
Также, конечно, очень интересная тема по приему входящих sms через MegaD.
Планируем сделать модуль для обработки входящих сообщений (sms, telegram и др)
-
В скрипте требуется для работы оборудования только в ночное время сравнить текущее время с заданным пользователем. Как это записать? Я конечно понимаю что есть объект Date() c атрибутами getHours, getMinutes и можно условие записать как if( new Array(date.getHours(), date.getMinutes()) > new Array(21,00) ). Но проверка синтаксиса ругается на эту строчку в скрипте. Поэтому как это сделать в iH?
-
В скрипте требуется для работы оборудования только в ночное время сравнить текущее время с заданным пользователем. Как это записать? Я конечно понимаю что есть объект Date() c атрибутами getHours, getMinutes и можно условие записать как if( new Array(date.getHours(), date.getMinutes()) > new Array(21,00) ). Но проверка синтаксиса ругается на эту строчку в скрипте. Поэтому как это сделать в iH?
А для чего Array? Например, ночное время с 21 до 6.
if ((new Date().getHours() > 21) || (new Date().getHours() < 6)) ....
А лучше один раз считать, потом проверять
let dt = new Date(); if ((dt.getHours()>21) || (dt.getHours()<6))
-
В скрипте требуется для работы оборудования только в ночное время сравнить текущее время с заданным пользователем. Как это записать? Я конечно понимаю что есть объект Date() c атрибутами getHours, getMinutes и можно условие записать как if( new Array(date.getHours(), date.getMinutes()) > new Array(21,00) ). Но проверка синтаксиса ругается на эту строчку в скрипте. Поэтому как это сделать в iH?
А для чего Array? Например, ночное время с 21 до 6.
> if ((new Date().getHours() > 21) || (new Date().getHours() < 6)) .... > >
А лучше один раз считать, потом проверять
> let dt = new Date(); > if ((dt.getHours()>21) || (dt.getHours()<6)) > >
Array для того чтобы проверять часы и минуты. Иногда недостаточно только часов. У меня вот утром свет в 6.45 включается, а выключается в 7.20 когда уезжаю. Неужели проверка синтаксиса на Array ругается?
-
if( new Array(date.getHours(), date.getMinutes()) > new Array(21,00) ). Но проверка синтаксиса ругается на эту строчку в скрипте. ….
Иногда недостаточно только часов. У меня вот утром свет в 6.45 включается, а выключается в 7.20 когда уезжаю. Неужели проверка синтаксиса на Array ругается?
Скрипт не понимает, что такое date.getHours()
И в целом так не получится. В JS массивы так не сравнивают.
Могу предложить такой однострочный вариант (некрасивый, но рабочий)
if (new Date().getHours()*100+new Date().getMinutes() > 2100)
-
И в целом так не получится. В JS массивы так не сравнивают.
Я не стал особо заморачиваться минимизацией кода и написал, надеюсь, понятную пользователям функцию. "Настройка" простая, использование проще некуда.
getStatusTime() { let date = new Date(); let time = new Array(date.getHours(), date.getMinutes()); let timeMon = new Array(09,10); //Время начала работы let timeEve = new Array(21,30); //Время окончания работы if(time[0]*60 + time[1] >= timeMon[0]*60 + timeMon[1] && time[0]*60 + time[1] <= timeEve[0]*60 + timeEve[1]) return 1; //Текущее время совпадает с рабочим диапазоном времени else return 0; //Текущее время НЕ совпадает с рабочим диапазоном времени },
Применение:
if(this.getStatusTime()) this.speed1(); else this.speed2();
Вопросы:
1. Какой синтаксис чтобы в таймере исполнять не функцию, а сделать действие по окончании счета?
this.startTimer("T1", 20, "turnOffVent");
2. Как в функции в таймер передать значение времени из переменной? Чего-то догадаться не могу:( отладки такой как в Chrome нет…
-
1. Какой синтаксис чтобы в таймере исполнять не функцию, а сделать действие по окончании счета?
Действие все равно нужно оборачивать в анонимную callback-функцию.
Для удобства трассировки и контроля сценариев анонимные функции в сценариях не используются.
2. Как в функции в таймер передать значение времени из переменной?
Нужно объявить переменные на уровне объекта - сценария.
Дальше к ним обращение через this.
Эти переменные сохраняют значение пока сервер не перезагружен (т е запуск-останов сценария не приводит к сбросу значений).
Можно создавать сколько угодно переменных любых типов. В данном случае создаем три массива, первый - пустой.
Для отладки (и записи в журнал) можно использовать this.log():
const script = { curTime:[], timeMon:[9,10], timeEve:[21,30], start() { let date = new Date(); curTime[0] = date.getHours(); curTime[1] = date.getMinutes()); this.startTimer("T1", 20, "turnOffVent"); }, turnOffVent() { this.log('Current time='+this.curTime.join(':')); if(this.getStatusTime()) { .... } }, getStatusTime() { return ((this.curTime[0]*60 + this.curTime[1] >= this.timeMon[0]*60 +this.timeMon[1]) && (this.curTime[0]*60 + this.curTime[1] <= this.timeEve[0]*60 + this.timeEve[1])) ? 1 : 0; }, .... }
-
Для отладки (и записи в журнал) можно использовать this.log():
Пока не разобрался как же использовать log. Что он будет логировать? - работу функций или в его тело нужно вставлять какие-то комментарии?
В общем сделал автономный сценарий управления ПВУ. По задумке он должен работать когда мой SWITCH1 имеет режим AUTO (в другой теме отписался об этом) - это состояние 1 переключателя. Но я не до конца понимаю как работает check - он должен проверять какие-то свойства датчиков/актюаторов и если они true, то выполняется start??? В общем, в моем сценарии пока не работает то что надо.
Идея сценария такова - если включен хоть один приточный клапан в доме (их 3 штуки), то если не включены - включаем входной и выходной клапаны, а в зависимости от времени суток и количества включенных приточных клапанов выбираем скорость работы вентиляторов ПВУ.
Автоматическое управление приточными клапанами по датчикам влажности/СО2 скорее всего надо вынести в отдельные сценарии, а пока условия управления ими находится в start.
Подскажите что я делаю не так? Кодю немного не по правилам…но иначе теряю скобки.
Да, кстати, сценарий надо как-то принудительно вводить в эксплуатацию (Запустить сценарий)? В каком случае он останавливается (отладчик пишет "mRecuperatorBySensors Now is NOT active.")?
/** * @name Работа рекуператора по датчикам температуры/влажности/СО2 * @desc */ const sw = Device("SWITCH1"); const vent_s1 = Device("VENT_PVU1"); //Скорость 1 вентиляторов const vent_s2 = Device("VENT_PVU2"); //Скорость 2 вентиляторов const vent_s3 = Device("VENT_PVU3"); //Скорость 3 вентиляторов const valveIN = Device("VALVE_AIR1"); //Клапан на входе const valveOUT = Device("VALVE_AIR2"); //Клапан на выходе const valve1F = Device("VALVE_AIR3"); //Клапан первого этажа const valve2F = Device("VALVE_AIR4"); //Клапан второго этажа const valveLD = Device("VALVE_AIR5"); //Клапан прачечной const hum_guest = Device("SHUMIDITY1_01"); const hum_laundry = Device("SHUMIDITY1_07"); const hum_dressing_room = Device("SHUMIDITY1_08"); const hum_bedroom_SE = Device("SHUMIDITY2_01"); const hum_bedroom_NE = Device("SHUMIDITY2_02"); const hum_bedroom_SW = Device("SHUMIDITY2_03"); const co2_guest = Device("SENSORA1_01"); const co2_bedroom_SE = Device("SENSORA2_01"); const co2_bedroom_NE = Device("SENSORA2_02"); const co2_bedroom_SW = Device("SENSORA2_03"); const script = { //curTime:[], //timeMon:[9,10], //timeEve:[21,30], check() { return this.isAuto() && (valve1F.dval || valve2F.dval || valveLD.dval); }, start() { const humHST = 5; const CO2HST = 100; //let date = new Date(); //curTime[0] = date.getHours(); //curTime[1] = date.getMinutes(); //this.log('Current time='+this.curTime.join(':')); //Если ночное время суток, то работа на скорости 1 if(!this.getStatusTime()) { //Если включен хотя бы один клапан if(valve1F.dval || valve2F.dval || valveLD.dval) { //Включаем клапаны на входе и выходе if(!valveIN.dval || !valveOUT.dval) { this.valveOn(); //Задержка для открытия клапанов и включение скорости 1 this.startTimer("OnNight", 20, "speed1"); } else this.speed1(); } else { this.turnOff(); } } //Если дневное время, то работаем на скорости в зависимости от включенных клапанов else { //Если включен хотя бы один клапан if(valve1F.dval || valve2F.dval || valveLD.dval) { //Включаем клапаны на входе и выходе if(!valveIN.dval || !valveOUT.dval) { this.valveOn(); //Задержка для открытия клапанов и включение нужной скорости this.startTimer("OnDay", 20, "speedChange"); } else this.speedChange(); } else { this.turnOff(); } } //Условия открытия/закрытия клапана первого этажа if(hum_guest > 60+humHST || co2_guest > 800+CO2HST) { if(!valve1F.dval) this.do(valve1F, "on"); } else { if(hum_guest < 60-humHST || co2_guest < 800-CO2HST) { if(valve1F.dval) this.do(valve1F, "off"); } } //Условия открытия/закрытия клапана второго этажа if(hum_bedroom_SE > 60+humHST || hum_bedroom_NE > 60+humHST || hum_bedroom_SW > 60+humHST || co2_bedroom_SE > 800+CO2HST || co2_bedroom_NE > 800+CO2HST || co2_bedroom_SW > 800+CO2HST) { if(!valve2F.dval) this.do(valve2F, "on"); if(!this.getStatusTime()) this.startTimer("T1", 3600, "???"); } else { if(hum_bedroom_SE < 60-humHST || hum_bedroom_NE < 60-humHST || hum_bedroom_SW < 60-humHST || co2_bedroom_SE < 800-CO2HST || co2_bedroom_NE < 800-CO2HST || co2_bedroom_SW < 800-CO2HST) { if(valve2F.dval) this.do(valve2F, "off"); } } //Условия открытия/закрытия клапана прачечной и гардеробной if(hum_laundry > 60+humHST || hum_dressing_room > 60+humHST) { if(!valveLD.dval) this.do(valveLD, "on"); } else { if(hum_laundry < 60-humHST || hum_dressing_room < 60-humHST) { if(valveLD.dval) this.do(valveLD, "off"); } } }, isAuto() { return (sw.hasAuto&&sw.auto || !sw.hasAuto); }, onSw() { //Выключили другим способом или сбросили авто - просто выходим if (!sw.dval || !this.isAuto()) this.exit(); }, getStatusTime() { let date = new Date(); let time = new Array(date.getHours(), date.getMinutes()); let timeMon = new Array(07,30); //Время начала работы let timeEve = new Array(21,30); //Время окончания работы if(time[0]*60 + time[1] >= timeMon[0]*60 + timeMon[1] && time[0]*60 + time[1] <= timeEve[0]*60 + timeEve[1]) return 1; //Текущее время совпадает с рабочим диапазоном времени else return 0; //Текущее время НЕ совпадает с рабочим диапазоном времени }, valveOn() { if(!valveIN.dval) this.do(valveIN, "on"); if(!valveOUT.dval) this.do(valveOUT, "on"); }, valveOff() { if(valveIN.dval) this.do(valveIN, "off"); if(valveOUT.dval) this.do(valveOUT, "off"); }, speedChange() { //Переключение скоростей if(valve1F.dval && valve2F.dval || valve1F.dval && valveLD.dval || valve2F.dval && valveLD.dval) this.speed2(); //Включено два из всех клапанов else if(valve1F.dval && valve2F.dval && valveLD.dval) this.speed3(); //Включено три из всех клапанов else this.speed1(); //Включен один из всех клапанов }, speed1() { if(vent_s2.dval) this.do(vent_s2, "off"); if(vent_s3.dval) this.do(vent_s3, "off"); if(!vent_s1.dval) this.do(vent_s1, "on"); }, speed2() { if(vent_s1.dval) this.do(vent_s1, "off"); if(vent_s3.dval) this.do(vent_s3, "off"); if(!vent_s2.dval) this.do(vent_s2, "on"); }, speed3() { if(vent_s1.dval) this.do(vent_s1, "off"); if(vent_s2.dval) this.do(vent_s2, "off"); if(!vent_s3.dval) this.do(vent_s3, "on"); }, turnOffVent() { if(vent_s1.dval) this.do(vent_s1, "off"); if(vent_s2.dval) this.do(vent_s2, "off"); if(vent_s3.dval) this.do(vent_s3, "off"); }, turnOff() { this.valveOff(); this.startTimer("Off", 20, "turnOffVent"); } };
Еще компилятор ругается вот так:
UPD1: как я понял после сохранения скрипта его надо остановить и запустить. Тогда он работает по моим 3-м триггерам. Пока не понимаю почему:
1. Не включает 3-ю скорость когда включены все 3 приточных клапана.
2. Не выключает вентиляторы и входной/выходной клапаны, когда выключаю все приточные.