Сценарии - новая версия API
-
@Lost, смысл в том что JS-многопоточный! Вы запускаете T1 на 0,5 секунды и параллельно тот же T1 запускается на 55 секунд (по идее его сработка на 0,5 секунд должна отмениться). Не знаю как движок системы в этом случае себя должен вести, но по мне - случайным образом... поэтому если нужно взводить несколько таймеров, то называйте их по разному.
-
Добрый вечер!
Заметил, что если после команды this.exit() есть еще какой либо код, то он вполне себе исполняется. Вот пример:
start() {
this.off();
},
off() {
this.log('сценарий запущен');
this.exit();
this.log('1');
this.log('2');
this.log('3');
this.log('4');
this.log('5');
this.log('6');
this.log(6 + 10);
}
});
Лог отладчика:
07.02 20:01:55.351 Started
07.02 20:01:55.352 log: сценарий запущен
07.02 20:01:55.369 exit
07.02 20:01:55.370 Stopped
07.02 20:01:55.371 log: 1
07.02 20:01:55.375 log: 2
07.02 20:01:55.377 log: 3
07.02 20:01:55.380 log: 4
07.02 20:01:55.383 log: 5
07.02 20:01:55.385 log: 6
07.02 20:01:55.388 log: 16
Разве так и должно быть? Ранее в этой теме писалось, что по этой команде все таймеры и слушатели сценария удаляются и сценарий станет не активным. Я так понимаю, что после this.exit() сценарий должен сразу завершиться..
-
@intrapro, в продолжении вот этого топика...
Все работало хорошо при существующем startOnChange и check(). Перенес все настройки системы вентиляции в свойства sw_pvu и чтобы при любом "чихе" не происходило сработки системы добавил в check() и ValveControl() дополнительные условия this.isChanged().
Однако в связи с определенными обстоятельствами понадобилось чтобы в зимних условиях установка отключалась когда tempOut < уставки1 и включалась снова при tempOut > уставка2, поэтому сделал функцию CheckTempOut(), которую запускает this.addListener(tempOut, "CheckTempOut") когда система вентиляции включиться. В таком случае сценарий всегда в работе и по сути ни startOnChange, ни check() не принимают участия в работе сценария. Пока установка выключена по температуре, клапаны вентиляции могут отключиться. Значит и для них нужны тоже слушатели. Столкнулся с тем что из CheckTempOut() не могу дернуть ValveControl() как раз из-за this.isChanged()... в итоге добавил новый "флаг" - start_pvu, если он установлен то ValveControl() запустится, иначе нет. Сценарий по моему получился очень сложным. Как профессионал подскажите - может можно было все сделать легче?//Переключатель работы ПВУ и настройка опций const sw_pvu = Device("SWITCH_PVU", [ {"name":"timeOpenValves", "note":"Время открытия клапанов, сек.:", "type":"number", "val":20}, {"name":"timeCloseValves", "note":"Время закрытия клапанов, сек.:", "type":"number", "val":10}, {"name":"startTimeWork", "note":"Время начала работы 'Full speed':", "type":"time", "val":0}, {"name":"endTimeWork", "note":"Время окончания работы 'Full speed':", "type":"time", "val":0}, {"name":"tempOutMin", "note":"Минимальная температура на выходе:", "type":"number", "val":1}, {"name":"tempOutNorm", "note":"Нормальная температура на выходе:", "type":"number", "val":15}, {"name":"logcb", "note":"Уведомление в журнале", "type":"cb", "val":1} ]); //Актуаторы включения скорости 1-3 у вентиляторов ПВУ const vent_s1 = Device("VENT_PVU1"); const vent_s2 = Device("VENT_PVU2"); const vent_s3 = Device("VENT_PVU3"); //Клапаны системы вентиляции 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 tempIn = Device("STEMP_PVU1"); //Температура на входе ПВУ const tempOut = Device("STEMP_PVU2"); //Температура на выходе ПВУ const tempAirFlow = Device("STEMP_PVU3"); //Температура на притоке ПВУ const heaterAir = Device("PUMP5"); //Насос жидкостного нагревателя startOnChange([sw_pvu,valve1F,valve2F,valveLD]); script({ state_pvu: 0, //0-выключена, 1-выключена по температуре, 2-включена start_pvu: 0, //Флаг запуска системы (после остановки по температуре) message: '', check() { let auto = valveIn.auto && valveOut.auto && (sw_pvu.value == 1); //Проверка основных условий return auto && ( this.isChanged(sw_pvu, "value") || this.isChanged(valve1F, "value") || this.isChanged(valve2F, "value") || this.isChanged(valveLD, "value") ); }, start() { this.ValveControl(); this.startTimer("Add_Listener", 5, "AddListener"); }, AddListener() { //this.addListener(sw_pvu, "OnSw"); this.addListener(tempOut, "CheckTempOut"); this.addListener(valve1F, "ValveControl"); this.addListener(valve2F, "ValveControl"); this.addListener(valveLD, "ValveControl"); }, //Реализация автоматической работы системы вентиляции ValveControl() { //Если состояние системы "Выключено" или "Включено" и производится старт системы или изменено состояние расходных клапанов if(this.state_pvu != 1 && (this.start_pvu || this.isChanged(valve1F, "value") || this.isChanged(valve2F, "value") || this.isChanged(valveLD, "value"))) { //Включение системы если открыт хотя бы один клапан вентиляции if(this.SumOpenValves()) { //Если входной и выходной клапан закрыты, то включаем систему if(valveIn.isOff() || valveOut.isOff()) this.TurnOn(); //Иначе управляем только скоростью else this.SpeedControl(); this.SendMessage(2); } //Выключение системы если все клапаны закрыты else { this.TurnOff(); this.SendMessage(0); } } }, //Реализация защиты от перемерзания рекуператора CheckTempOut() { if(this.isChanged(tempOut, "value")) { //Определение уставок let ust_min = sw_pvu.getParam("tempOutMin"); let ust_max = sw_pvu.getParam("tempOutNorm"); //Если температура минимум и система включена if((tempOut.value <= ust_min) && this.state_pvu == 2) { this.start_pvu = 0; //Флаг запуска системы обнулен this.TurnOffTemp(); //Отключение системы по температуре this.SendMessage(1); } //Если температура нормальная и система выключена по температуре else if((tempOut.value >= ust_max) && this.state_pvu == 1) { this.start_pvu = 1; //Флаг запуска системы установлен this.state_pvu = 2; //Состояние ПВУ - "Включена" this.ValveControl(); } } }, //Вывод информации о работе в журнал SendMessage(variant) { //Если установлен соответствующий чек-бокс if(sw_pvu.getParam("logcb")) { let message = "Вентиляция. "; if(variant === 0) { message += "Все клапаны закрыты, ПВУ выключена"; } else if(variant == 1) { message += "ПВУ выключена из-за низкой температуры!"; } else if(variant == 2) { if(this.SumOpenValves() == 1) message += "Открыт - "; else if(this.SumOpenValves() > 1) message += "Открыты - "; if(valve1F.value) message += "'" +valve1F.name+ "', "; if(valve2F.value) message += "'" +valve2F.name+ "', "; if(valveLD.value) message += "'" +valveLD.name+ "', "; if(!this.GetStatusTime()) message += "установлена скорость 1"; else message += "установлена скорость " +this.SumOpenValves(); } this.log(message); } }, //Функция определения количества включенных клапанов SumOpenValves() { return valve1F.value + valve2F.value + valveLD.value; }, //Функция контроля скорости вентиляторов SpeedControl() { if(!this.GetStatusTime()) this.Speed1(); else this.SpeedChange(); }, //Функция изменения скорости вентиляторов SpeedChange() { switch(this.SumOpenValves()) { case 1: this.Speed1(); break; case 2: this.Speed2(); break; case 3: this.Speed3(); break; } }, //Функция выключения системы TurnOff() { this.state_pvu = 0; //Состояние ПВУ - "Выключена" this.ValvesOff(); //Закрытие клапанов с задержкой выключения вентиляторов this.startTimer("Close_Valves", sw_pvu.getParam("timeCloseValves"), "TurnOffVent"); }, //Функция выключения системы по тмпературе TurnOffTemp() { this.state_pvu = 1; //Состояние ПВУ - "Выключена по температуре" this.ValvesOff(); //Закрытие клапанов с задержкой выключения вентиляторов this.startTimer("Close_Valves_ByTemp", sw_pvu.getParam("timeCloseValves"), "TurnOffVentByTemp"); }, //Функция включения системы TurnOn() { this.state_pvu = 2; //Состояние ПВУ - "Включена" this.ValvesOn(); //Открытие клапанов с задержкой включения вентиляторов this.startTimer("Open_Valves", sw_pvu.getParam("timeOpenValves"), "SpeedControl"); }, //Функция получения статуса работы по времени GetStatusTime() { let date = new Date(); let time = 3600*date.getHours() + 60*date.getMinutes() + date.getSeconds(); let startTimeWork = sw_pvu.getParam("startTimeWork"); let endTimeWork = sw_pvu.getParam("endTimeWork"); if(time > startTimeWork && time < endTimeWork) return 1; //Текущее время совпадает с рабочим диапазоном времени else return 0; //Текущее время НЕ совпадает с рабочим диапазоном времени }, ValvesOn() { valveIn.turnOnSaveAuto(); valveOut.turnOnSaveAuto(); }, ValvesOff() { valveIn.turnOffSaveAuto(); valveOut.turnOffSaveAuto(); }, Speed1() { vent_s2.off(); vent_s3.off(); vent_s1.on(); }, Speed2() { vent_s1.off(); vent_s3.off(); vent_s2.on(); }, Speed3() { vent_s1.off(); vent_s2.off(); vent_s3.on(); }, TurnOffVentByTemp() { vent_s1.off(); vent_s2.off(); vent_s3.off(); }, TurnOffVent() { vent_s1.off(); vent_s2.off(); vent_s3.off(); this.exit(); } });
И да - очень долго не мог понять как правильно выйти из сценария чтобы завершилась работа всех слушателей. this.exit(), как понял останавливает и слушателей, и таймеры. Но главным образом смущал такой лог:
18.02 17:57:17.536 listener on event VALVE_AIR5: ValveControl 18.02 17:57:17.536 exec function ValveControl 18.02 17:57:17.537 do VALVE_AIR1 aoff 18.02 17:57:17.538 do VALVE_AIR2 aoff 18.02 17:57:17.593 start timer Close_Valves for 10 sek 18.02 17:57:17.594 log: Вентиляция. Все клапаны закрыты, ПВУ выключена 18.02 17:57:27.608 Done timer Close_Valves 18.02 17:57:27.609 exec function TurnOffVent 18.02 17:57:27.609 do VENT_PVU1 off 18.02 17:57:27.611 do VENT_PVU2 off 18.02 17:57:27.620 do VENT_PVU3 off 18.02 17:57:27.622 exit 18.02 17:57:27.623 Stopped 18.02 17:57:48.262 isChanged(SWITCH_PVU,dval)=false Changed: {"VALVE_AIR5":{"auto":1}} 18.02 17:57:48.263 isChanged(VALVE_AIR3,dval)=false Changed: {"VALVE_AIR5":{"auto":1}} 18.02 17:57:48.263 isChanged(VALVE_AIR4,dval)=false Changed: {"VALVE_AIR5":{"auto":1}} 18.02 17:57:48.263 isChanged(VALVE_AIR5,dval)=false Changed: {"VALVE_AIR5":{"auto":1}} 18.02 17:57:48.264 Check(VALVE_AIR5) => false
Вроде произошел exit, но все равно появились 5 последних строчек...
-
Здравствуйте! Можно ли сделать сценарий, чтобы он отображался в виде кнопки в боковом меню устройства!
или
Кнопка с ссылкой, при нажатии которой происходит переход по адресу в браузер.
-
@konia74 выбрать мнемосхему где хотите что бы она визуализировалась, нажать на "+", примитивы и выбрать кнопка, а потом на ету кнопку назначить выполнение сценария.
-
@amgstone Кнопка должна находится именно в боковом меню устройства, которое открывается после долгого нажатия на устройство. Чтобы было понятнее кратко опишу идею: устройство с прошивкой для ws2812 WLED имеет очень широкий функционал но реализовать его (кроме вкл/выкл и изменения цветов) в IH нет возможности и смысла. Поэтому хочу сделать дополнительную кнопку в боковом меню выключателя, по нажатию на которую будет переход в браузер на адрес ip устройства, где уже будут все настройки устройства
Проблема в написании сценария, я не знаком с языками программирования.
-
подскажите как в этом сценарии передавать на виртуальное устройство температуру каждых 5 минут а не при каджом изменении температуры?
/** * @name Середня температура будинку * @desc * @version 4 */ const temp_bedroom = Device("STEMP1"); const temp_korudor = Device("STEMP11"); const temp_vana = Device("STEMP12"); const temp_hall = Device("STEMP5"); const temp_danulo = Device("STEMP6"); const temp_sofija = Device("STEMP7"); const temp_kamina = Device("STEMP8"); const temp_kitchen = Device("STEMP9"); const temp_house = Device("Stemp_house"); startOnChange([temp_bedroom,temp_korudor,temp_vana,temp_hall,temp_danulo,temp_sofija,temp_kamina,temp_kitchen]); script({ start() { let temp_house_t= (temp_bedroom.value+temp_korudor.value+temp_vana.value+temp_hall.value+temp_danulo.value+temp_sofija.value+temp_kamina.value+temp_kitchen.value)/7; this.assign(temp_house, "value", temp_house_t.toFixed(2)); } });
-
@amgstone при первом изменении температуры вы можете запустить таймер и записать среднюю температуру через 5 минут, и снова вызвать таймер и так бесконечно. Или вызывать сценарий периодически в расписании, только удалите функцию StartOnChange.
-
Добрый вечер! Подскажите где найти сценарий Управление поливом, смотрел видео с версией Berry и там использовался такой сценарий, планирую использовать в версии Cherry на MegaD.
-
Такой сценарий создать просто. Вам нужно создать два сценария, которые включают и выключают полив и настроить вызов этих сценариев через расписание. Это если по простому, но у вас может свой алгоритм работы.
-
@goodspeed1986 спасибо, но чтобы его создать нужно оттолкнуться хотьб от маломальского похожего сценария, в котором я бы смог что-то менять и экспериментировать, так как мне это ещё сложно.
-
Имеется:
- 3 зоны полива по разным сторонам света
- Отдельно в зонах:
• В 1-й зоне 5 направлений
• В 2-й зоне 3 направления
• В 3-й зоне 4 направления - В 3-х зонах по одному датчику влажности
Хочется такое: - Включение и отключение авто полива.
- Выставлять значение влажности в каждой зоне отдельно при котором значении включается полив
- В каждой зоне может включиться только одно направление полива и переключатся по очерёдно по расписанию, как пример ( 1-е направление – 15 минут, потом 2-е направление – 10 минут, потом 3-е направление - 7 минут и т.д.)
Может кто писал какой-то похожий сценарий, от которого оттолкнуться.
-
Это достаточно сложный сценарий. Сразу у вас такой сделать не получится. Начните с включения/выключения полива по влажности, потом переключайтесь на зоны. Включение по влажности очень похоже на отопление. Если все таки сами не сможете, может кто-то согласиться вам помочь за вознаграждение.
-
Друзья, изучайте JS - он не так сложен, особенно если вы не знаете ни одного языка программирования). Только со знанием JS получится создать сценарий, который будет удовлетворять всем вашим критериям. Нативные блок-схемы - все это балоство.. .лучше начните баловаться с простыми выражениями типа...простых не нашел...все мои сценарии уже очень сложны, поскольку учитывают множество факторов. Все же умный дом):
//Проверка основных условий (авто-режим клапана и дом снят с охраны) if(valve.auto && guard.isOff()) { //Если давление воды на вводе в норме if(pressure.value > pressure.setpoint) { //И если емкость не заполнена (показания датчика меньше 900) if(level.value < 900) { //Включаем клапан подачи воды в емкость if(valve.isOff()) valve.turnOnSaveAuto(); this.message += valve.name+ " включен"; //Взвод таймеров для установки "слушателя" и защитного отключения клапана this.startTimer("Timer_AddListener", 3, "AddListener"); this.startTimer("Timer_OffValve", valve.getParam("timeOff")*60, "OffValve"); } else { this.message += "Емкость заполнена"; } } else { this.message += pressure.name+ " низкое!"; } } else { this.message +
-
Коллеги, в мультисценарий потребовалось добавить переключатель режимов ПВУ (вдруг если где-то задымление, то отключаем систему вентиляции). Как это сделать?
-
@Alex_Jet, добрый день. Не совсем понятна проблема. Нужно добавить переключатель как устройство сценария, а потом в каждый экземпляр его добавить. Другой вариант - сделать виртуальное устройство как индикатор задымления, включить в мультисценарий его. По этому индикатору выключать вытяжку - мульти здесь уже не нужен.
-
@intrapro, первый вариант предпочтительней, поскольку в сценарии работы системы вентиляции уже наворочено сверх возможного. Однако как добавить переключатель как устройство сценария? Если как ActorD, то не могу выбрать переключатель в экземпляре мультисценария.
-
Добрый день!
Подскажите, пожалуйста, где и как можно узнать свойства устройств и что они значат?
-
Пользователь @laronov написал в Сценарии - новая версия API:
Добрый день!
Подскажите, пожалуйста, где и как можно узнать свойства устройств и что они значат?В 4 версии все свойства устройства были определены в системе жестко. State - бинарные значения, Value - аналоговые, Blk.
В 5 версии все свойства устройства можно настраивать. К примеру, есть датчик температуры и влажности. Сейчас нет необходимости делать два устройства. Можно одно устройство со свойствами temperature (температура) и humidity (влажность). Если понадобится еще давление, то просто добавить еще свойство pressure (давление). Благодаря такому механизму вы можете создать свои устройства.
В комплекте с системой уже есть некоторые типовые устройства в папке "Типы устройств". Можно посмотреть как они сделаны.
Подробнее можно почитать в документации
-
Пользователь @IntraVM написал в Сценарии - новая версия API:
Blk
что значит данное свойство?