Сценарии в intraHouse Cherry
-
У меня актюаторы НО. Чтобы когнитивный диссонанс не устраивать в скриптах, я так понимаю, в соответствующих каналах плагина MegaD нужно активировать чек-бокс "Ивертировать выходное значение"?
Да, должно работать (примерно как было в Berry)
-
Можно еще проще - привязать бинарный актуатор, а интерактивные операции для него отключить
В принципе эта идея сработала. При поднесении нужного ключа к считывателю актуатор меняет свое состояние. Отталкиваясь от его состояния можно написать сценарий установки/снятия с охраны. Единственный неопределенный момент в том, что когда MegaD опрашиваем командой cmd=all, то канал, соответствующий считывателю находится в неопределенном состоянии (ранее писал, что не верно под неопределенным состоянием считать 0). Возникает вопрос - после перезагрузки MegaD в каком состоянии окажется привязанный к этому каналу актуатор (ну или сенсор, если добавите ему обработку toggle). Или все же это правильно - считать за 0/OFF неопределенное состояние порта?
Написал сценарий постановки дома на охрану. Button - это актюатор, который привязан ко входу MegaD, к которому подключен считыватель. Кроме этого, из этого устройства сделан индикатор постановки на охрану в строке состояния и две кнопки "Постановка/Снятие с охраны" (для одной в свойствах выбрано on, для другой - off). Lamp - это сигнальная лампа (загорается при постановке), Ring - это сирена.
const Button = DeviceT("ACTOR_SECURITY_SYS01"); const Lamp = Device("ACTOR_SECURITY_SYS02"); const Ring = Device("ACTOR_SECURITY_SYS03"); const script = { start() { this.log(Button.name+ "=" +Button.dval); if(Button.dval) { this.do(Lamp, "on"); //Включаем лампу this.do(Ring, "on"); //На секунду срабатывает сирена this.startTimer("T1", 0.1, "ringOff"); } else { this.do(Lamp, "off"); //Выключаем лампу this.do(Ring, "on"); //На секунду срабатывает сирена this.startTimer("T1", 0.1, "ringOff"); } }, // Функция, которая сработает, когда таймер досчитает - отключаем и выходим ringOff() { this.do(Ring, "off"); this.exit(); } };
Суть в том, что при сработке считывателя все работает хорошо (актюатор меняет свое состояние и скрипт все верно отрабатывает). А вот при нажатии кнопок работает не верно - нажимаю кнопку "Поставить на охрану" (on) индикатор охраны становится активным, но реле сигнальном лампы не срабатывает, а в отладчике скрипта видно, что актюатор почему-то не "встал":
27.10 23:52:44.905 Trigger ACTOR_SECURITY_SYS01 27.10 23:52:44.905 Started 27.10 23:52:44.906 log: Актуатор постановки на охрану=0 27.10 23:52:44.912 do ACTOR_SECURITY_SYS02 off 27.10 23:52:44.916 do ACTOR_SECURITY_SYS03 on 27.10 23:52:44.918 start timer T1 for 0.1 sek 27.10 23:52:45.026 Done timer T1 27.10 23:52:45.026 exec function ringOff 27.10 23:52:45.027 do ACTOR_SECURITY_SYS03 off 27.10 23:52:45.029 exit 27.10 23:52:45.029 Stopped
Не могу понять почему так происходит? Надо таймер взводить перед проверкой состояния актюатора?
Up1: методом итераций (сначало сделал таймер на 0,1 секунду с переходом в main), потом чтобы при повторном нажатии той же кнопки (когда взято под охрану, но еще раз нажимают кнопку "Взять под охрану") не срабатывала сирена решил проверять совпадает текущее значение актуатора с предыдущем, потом судя по логам работы решил убрать таймер. И получилось вот что:
const Button = DeviceT("ACTOR_SECURITY_SYS01"); //Актуатор постановки на охрану const Lamp = Device("ACTOR_SECURITY_SYS02"); //Сигнальная лампа const Ring = Device("ACTOR_SECURITY_SYS03"); //Сирена var Status; const script = { start() { //this.log(Button.name+ " = " +Button.dval); this.main(); Status = Button.dval; }, // Основная функция постановки на охрану main() { //this.log(Button.name+ " = " +Button.dval); //Если предыдущее состояние актуатора совпадает с текущим, то выходим. if(Status != Button.dval) { if(Button.dval) this.do(Lamp, "on"); //Включаем лампу else this.do(Lamp, "off"); //Выключаем лампу this.do(Ring, "on"); //Срабатывает сирена this.startTimer("T1", 0.1, "ringOff"); } }, // Функция отключения сирены с выходом из скрипта ringOff() { this.do(Ring, "off"); this.exit(); } };
Парадокс в том, что если исключить Status = Button.dval; или перенести до this.main(); то ничего не работает. А именно в такой последовательности - работает. Однако моя логика не понимает в чем суть…
-
Написал сценарий постановки дома на охрану. Button - это актюатор, который привязан ко входу MegaD, к которому подключен считыватель. Кроме этого, из этого устройства сделан индикатор постановки на охрану в строке состояния и две кнопки "Постановка/Снятие с охраны" (для одной в свойствах выбрано on, для другой - off)…..
А канал считывателя MegaD отрабатывается как toggle?
Думаю, проблема в том, что у вас устройство Button, с одной стороны - псевдоактуатор с привязкой к считывателю, с другой - его же вы используете как виртуальный актуатор для постановки/снятия. Но фактически у вас выход не переключается, поэтому состояние может не совпадать с ожидаемым.
Можете посмотреть журнал устройства (при длинном нажатии).
Если отключить Button от канала, то виртуальное устройство будет правильно отрабатывать кнопки по первому варианту.
Выход - создать отдельный виртуальный актуатор Постановка/Снятие (Guard, например).
Он выводится на индикацию, он переключается кнопками. По его событиям включается сигнальная лампа и вообще все, что нужно сделать при постановке (снятии). Его состояние вы можете учитывать в других сценариях (датчики, герконы на охране и т д, ну вы знаете
Дополнительно, как я понимаю, вы хотите реализовать Постановку (и Снятие?) при сработке считывателя. Т е это триггер, который должен переключить Guard . Так это и надо реализовать - отдельный сценарий, который просто переключает Guard по считывателю (по сути, как кнопка)
-
Написал сценарий постановки дома на охрану. Button - это актюатор, который привязан ко входу MegaD, к которому подключен считыватель. Кроме этого, из этого устройства сделан индикатор постановки на охрану в строке состояния и две кнопки "Постановка/Снятие с охраны" (для одной в свойствах выбрано on, для другой - off)…..
А канал считывателя MegaD отрабатывается как toggle?
Думаю, проблема в том, что у вас устройство Button, с одной стороны - псевдоактуатор с привязкой к считывателю, с другой - его же вы используете как виртуальный актуатор для постановки/снятия. Но фактически у вас выход не переключается, поэтому состояние может не совпадать с ожидаемым.
Можете посмотреть журнал устройства (при длинном нажатии).
Если отключить Button от канала, то виртуальное устройство будет правильно отрабатывать кнопки по первому варианту.
Выход - создать отдельный виртуальный актуатор Постановка/Снятие (Guard, например).
Он выводится на индикацию, он переключается кнопками. По его событиям включается сигнальная лампа и вообще все, что нужно сделать при постановке (снятии). Его состояние вы можете учитывать в других сценариях (датчики, герконы на охране и т д, ну вы знаете
Дополнительно, как я понимаю, вы хотите реализовать Постановку (и Снятие?) при сработке считывателя. Т е это триггер, который должен переключить Guard . Так это и надо реализовать - отдельный сценарий, который просто переключает Guard по считывателю (по сути, как кнопка)
Да, канал считывателя отрабатывается как toggle.
Вообще я замечал, что если актуатор привязан к каналу и канал недоступен (плагин не включен, MegaD недоступна), то при переключении актуатора в вебе его состояние не меняется. Тут же канал доступен, актуатор свое состояние в вебе меняет, а логическое состояние изменяется только после повторного нажатия кнопки. Парадокс в том, что мой последний скрипт работает так как задумано (и от устройств-кнопок и от считывателя), но при этом сам скрипт вообще не логичен…
По поводу дополнительного сценария - у меня сейчас уже порядка 30 различных скриптов, поэтому дополнительных плодить не хотел. И именно поэтому ранее вносил предложение - добавить в скриптах признак системы.
В общем попробую ваше предложение осуществить.
-
Сделал новый актуатор не привязанный к каналам, переделал скрипт - вечером посмотрю как работает со считывателем (с "виртуальным" актуатором, судя по отладчикам, проблем нет). Вопрос - чтобы состояние "виртуального" актуатора оставалось актуальным даже после выключения/включения сервера надо изменение его состояния записывать в БД? Или его последнее состояние храниться в json и даже после жесткого ребута будет актуальным?
PS: для входов состояние toggle будете определять?
-
Вопрос - чтобы состояние "виртуального" актуатора оставалось актуальным даже после выключения/включения сервера надо изменение его состояния записывать в БД? Или его последнее состояние храниться в json и даже после жесткого ребута будет актуальным?
Нет, в БД писать не надо. Да, будет сохраняться.
Гарантированный интервал сохранения на диск 10 сек (при жестком ребуте есть вероятность потери состояний, изменившихся за последние 10 сек)
PS: для входов состояние toggle будете определять?
Не совсем понятен вопрос. toggle - это операция. Состояние - результат выполнения, зависит от предыдущего состояния.
Поэтому для входов определять toggle считают неверным. Мы же реальное состояние с входа только получаем, повлиять на него не можем, но можем сильно запутаться
Для канала считывателя, если считаете, что вам удобнее toggle - определите его как выход
-
Для канала считывателя, если считаете, что вам удобнее toggle - определите его как выход
ОК, понятно. А как в скрипте сделать toggle для актуатора состояния сигнализации? То есть при любом изменении reader изменить состояние Button на противоположное? Что-то не могу догадаться…
-
А как в скрипте сделать toggle для актуатора состояния сигнализации? То есть при любом изменении reader изменить состояние Button на противоположное? Что-то не могу догадаться…
Вы же все уже сделали - канал привязали к актуатору Button c операцией toggle. Он сам меняет состояние по считывателю.
Что вам осталось сделать - по триггеру Button переключать Guard
-
Вы же все уже сделали - канал привязали к актуатору Button c операцией toggle. Он сам меняет состояние по считывателю.
Что вам осталось сделать - по триггеру Button переключать Guard
Извините. Я просто все немного переименовал. Button - это у меня виртуальный актуатор, который вынесен на веб-интерфейс в том числе в виде кнопок. А Reader - тот который привязан к каналу считывателя.
В одном скрипте у меня если изменяется состояние Button (кнопки на веб-морде), то я ставлю/снимаю сигнализацию.
В другом скрипте у меня должно быть по любому изменению Reader состояние Button меняться на противоположное - я не знаю как это сделать…догадался сам пока писал:
const script = { start() { //При успешном считывании Reader меняем состояние Button на противоположное this.assign(Button, "dval", !Button.dval); } };
-
Подскажите как сделать нечто подобное чтобы оно работало как задумано:
/** * @name Сообщение в Telegram о недоступности * @desc Уведомление пользователя по Telegram о недоступности оборудования */ //const Device1 = DeviceT("SENSOR0"); const script = { check() { let i; for(i = 0; i < 10; i++) { dev = Device("SENSOR" +i); if(!dev.dval) this.info("telegram", "OWNER", "Внимание! Недоступно устройство '" +dev.name+ "'"); else this.info("telegram", "OWNER", "Связь с устройством '" +dev.name+ "' восстановлена"); this.log(dev.name+ "=" +dev.dval); } }, start() { } };
Если подробнее, то не объявлять в виде констант 100500 устройств (как DeviceT или проверять "вручную" изменение каждого в check), а с помощью цикла в check проверить состояние каждого. Если добавится еще 10 устройств, то заменить в скрипте только одно значение.
-
Подскажите как сделать нечто подобное чтобы оно работало как задумано:
> /** > * @name Сообщение в Telegram о недоступности > * @desc Уведомление пользователя по Telegram о недоступности оборудования > */ > //const Device1 = DeviceT("SENSOR0"); > > const script = { > check() { > let i; > for(i = 0; i < 10; i++) { > dev = Device("SENSOR" +i); > if(!dev.dval) this.info("telegram", "OWNER", "Внимание! Недоступно устройство '" +dev.name+ "'"); > else this.info("telegram", "OWNER", "Связь с устройством '" +dev.name+ "' восстановлена"); > > this.log(dev.name+ "=" +dev.dval); > } > }, > > start() { > > } > }; >
Если подробнее, то не объявлять в виде констант 100500 устройств (как DeviceT или проверять "вручную" изменение каждого в check), а с помощью цикла в check проверить состояние каждого. Если добавится еще 10 устройств, то заменить в скрипте только одно значение.
Зато будете получать 100500 телеграм-сообщений - при каждой сработке любого устройства такой скрипт выдавал бы сообщение о каждом устройстве, это наверное все же не совсем то, о чем мечтается
Главная цель определения триггера - запуск сценария именно в тот момент, когда с устройством что-то происходит
Можно же один раз сделать один-единственный мультисценарий
/** * @name Сообщение в Telegram о недоступности * @desc Уведомление пользователя по Telegram о недоступности оборудования */ const dev = DeviceT("SensorD"); const script = { start() { if(!dev.dval) this.info("telegram", "OWNER", "Внимание! Недоступно устройство '" +dev.name+ "'"); else this.info("telegram", "OWNER", "Связь с устройством '" +dev.name+ "' восстановлена"); this.log(dev.name+ "=" +dev.dval); } };
И привязывать устройства через Запуск для сценария
-
Можно же один раз сделать один-единственный мультисценарий
Да, вы правы. Как-то я увлекся скриптами…забыв что можно сделать "мультисценарий".
А как убрать из журнала "отладочные" сообщения telegram??? Типа "telegram send: xxx". Ну или сделать как в Berry для GSM-шлюза было:
"SMS +799999 Сообщение отправлено: текст сообщения"
-
@Alexulik:
const script = {
start() {
const temp = 25;
this.assign(dt, "defval", temp);
Видимо так?
Да, все верно, можно так.
Этот сценарий можно привязать к кнопке либо запускать по расписанию.
Если хочется более универсального решения, можно добавить виртуальное устройство Режим (как было в Berry):
1. Добавить устройство с типом Переключатель, назовем его MODE
2. Этому устройству в нижней табличке Состояния сделать: 0 - День 1 - Ночь 2 - Эконом и соотв. картинки
3. Теперь это устройство можно вытащить на интерфейс. Шаблон представления - Переключатель состояния.
Плюс по сравнению с кнопками - отображение текущего состояния.
Его же можно вытащить в виде иконки как индикатор ( то что было в Berry)
4. Сделать сценарий, для которого MODE является триггером и в нем уже менять уставки.
Например, сделаем сценарий, который будет переключать уставки датчику. А сами уставки доступны через интерфейс пользователя.
/** * @name При изменении режима - изменить уставку * @desc * @version */ const mode = DeviceT("ActorE", "Переключатель режима"); const dt = Device("SensorA", "Датчик температуры", [ {"name":"dayTemp", "note": "Целевая днем, С", "type":"number", "val":23}, {"name":"nightTemp", "note": "Целевая ночью, С", "type":"number", "val":21}, {"name":"ecoTemp", "note": "Целевая в режиме эконом, С", "type":"number", "val":19} ]); const script = { start() { if (mode.dval == 0) this.assign(dt, "defval", dt.dayTemp); if (mode.dval == 1) this.assign(dt, "defval", dt.nightTemp); if (mode.dval == 2) this.assign(dt, "defval", dt.ecoTemp); } }
Сделать для нужных датчиков привязку - Запуск для сценария
А можно параметры уставки перенести в Переключатель - тогда для всех будет один температурный режим.
И масса других вариантов …
Естественно, MODE можно переключать сценарием по расписанию
-
Да, все верно, можно так.
Наконец-то опубликовали частичное решение моего давнишнего вопроса А если датчиков температуры 100500? Как у меня - 7 зон на первом этаже и 7 зон на втором этаже!
Я пытался сделать 3 мультисценария (День/Ночь/Эконом) в которые добавлял нужные датчики температуры. А в самом сценарии прописывал const temp = 24/25/23, которую ассигновал соответствующим датчикам температуры. Однако поскольку могу управлять всеми 14-тью зонами, то хотелось бы в каждой зоне индивидуально настраивать температуру. Например, в котельной/гардеробной пусть будет всегда 23, а в прачечной - всегда 25. Кому-то из детей захочется сделать 24,5 в своей комнате или 25,5. В общем чтобы была возможность управления зонами.
PS: ответьте, пожалуйста, по вопросам в предыдущем моем сообщении.
-
Наконец-то опубликовали частичное решение моего давнишнего вопроса
А почему частичное? Вроде задача решается - один мультсценарий, к которому привязываете датчики, которые должны по режимам переключаться - 14 штук :), а уставки - у каждого свои
Да, вы правы, мало у нас опубликовано т н кейсов, где расписано решение конкретной задачи
Дело в том, что сейчас идет переработка API сценариев.
Действия устройства будет выполнять само устройство - lamp.on(), vent.toggle(), temp.setSetpoint()
Через this будут только функции скрипта (таймеры и т д) и ядра (информирование, запись в журнал..)
Одновременно будут работать и старые сценарии.
Но в одном сценарии старый и новый синтаксис, естественно, смешивать нельзя. Как только запустим новый вариант - будем публиковать решения.
А как убрать из журнала "отладочные" сообщения telegram??? Типа "telegram send: xxx". Ну или сделать как в Berry для GSM-шлюза было:
"SMS +799999 Сообщение отправлено: текст сообщения"
В новом API сценариев сохранением в журнал можно будет управлять. Либо сделаем как в Berry - на галочках, не решили еще.
-
@Alexulik:
Подскажите, как запустить сценарий из сценария?
В настоящий момент это не реализовано.
@intrapro:сейчас идет переработка API сценариев
Там будет возможность запускать сценарии из сценариев.
-
А почему частичное? Вроде задача решается - один мультсценарий, к которому привязываете датчики, которые должны по режимам переключаться - 14 штук :), а уставки - у каждого свои
Да, Вы правы - с таким мультисценарием логика работает как надо - по всем 14 зонам. Осталось подключить железо к iH и проверить как работает в реальности.
-
Всем Доброе утро!
Подскажите пожалуйста как решить одну проблемку!
Имеется система отопления, прекрасно управляемая IH. Котел, обогрев трубы ввода воды получают информацию от датчиков, подключенных по шине 1W через контроллер MegaD 2560. Ну и все остальное тоже управляется данными контроллерами. В общем я просто решил активировать режим "авто" и доверить автоматике управлять температурой в комнатах раздельно. Ранее все было нормально, а неделю назад при включении этого режима начали мигать иконки переключаясь с вкл на выкл и так далее в цикле. Реле также отрабатывает эти команды. Неделю пытался экспериментальным путем найти причину, остановился на том, что команду эту все таки дает именно сценарий. Хотя подогрев ввода и Котел работают отлично, в автоматическом режиме.
Похоже, проблема с инверсными выходами в автоматическом режиме. Проверим.
У вас в сценарии используются команды aon-aoff?
Можно текст сценария?
-
Ммм… Только обогрев ввода тоже с инверсией и глюка такого не наблюдается. Правда сценарий там немного другой. Сейчас попробовал, актуатор отопления переподключил на "работающий" сценарий и результат тот же. Правда заметил то, что произвольное переключение актуатора прекращается при достижении показания датчика более 10 ти градусов (radiator100_1 переключаться прекратил. Подожду пока температура поднимется в другой комнате и проверю.
А случайно для датчика температуры не выставлен диапазон от 10 градусов?
С установкой флага ошибки меньше 10?
Можно посмотреть в журнале датчика температуры
-
Если ошибки нет, тогда зацикливание с датчиком температуры скорее всего не связано.
Попробуйте так:
check() { return bat.auto && ( (bat.dval == 0)&&(Number(dt.aval) <= Number(dt.defval)-0.5) || (bat.dval == 1)&&(Number(dt.aval) >= Number(dt.defval) ) ); }, start() { if (bat.dval == 0) { this.do(bat, "aon"); } else { this.do(bat, "aoff"); } }
И еще интервалы показаний датчиков не получается задать в плагине. Датчики передают показания как вздумается. По шине I2C может меняться 2 раза в секунду при установке интервала опроса 15 секунд. По шине 1W - один раз в 25-30 секунд при установке 5 секунд. И изменить не получается. Может плагин виноват? (или мои кривые руки))))
Руки вероятно не виноваты
По 1W через MegaD помнится есть минимальное время отклика как раз порядка 20-25 сек. Там же последовательный опрос цепочки датчиков
По шине I2C - нужно посмотреть лог, скиньте, пригодится, когда будем плагин переделывать