Есть группа освещения и кнопка, подключенные к wb-mr6c.
Есть датчик движения wb-msw-v4.
Настроено правило на автоматическое включение/отключение света по движению.
Подскажите, как в приавиле определить, за счёт чего включился свет, за счёт нажатия кнопки (wb-mr6c/Input 3 counter) или за счёт срабатывания правила на включение по движению?
Пробую улучшить работу правила, чтобы при отключении света кнопкой, включение/отключение света по датчику переставало срабатывать на какое-то время. Проблема в том, что если зашиться на регистр Input counter (whenChanged: “wb-mr6c/Input 3 counter”), то точно определить в какое состояние перешел регистр wb-mr6c/K3 не получается, выдаётся произвольное значение.
Правило одно.
Но если отслеживать изменения значения wb-mr6c/K3, то независимо от того, чем включается свет (кнопкой или правилом), значение devName = wb-mr6c и cellName = K3.
Т.е. с помощью этих параметров не удаётся определить кто включил свет.
Прикладываю текст правила.
Вопрос - как в правиле “СтопДвиж” однозначно определить, что при нажатии кнопки произошло именно отключение света?
//Тестовое правило
/*Суть правила:
- Свет автоматически включается при наличии движения
- Но если свет принудительно выключили кнопкой, то автоматически его снова включать не надо в течение одной минуты
*/
var long_timer_id = null; //ID таймера, который свидетельствует о том, что свет выключили кнопкой менее одной минут назад
defineRule("Движ", {
whenChanged: "wb-msw-v4_1/Max Motion",
then: function(newValue, devName, cellName) {
if (newValue > 40) {
//Если свет выключен и его недвно кнопкой не выключали, то включаем
if (dev["wb-mr6c_142/K3"] == false && long_timer_id == null) {
dev["wb-mr6c_142/K3"] = true;
log("Правило Движ: Включаю свет.");
};
}
}
});
//!!!!!!!! Это правило не всегда отпрабатывает, т.к. значение dev["wb-mr6c_142/K3"] выдаётся произвольное.
//!!!!!!!! Может быть true, хотя по факту свет кнопкой выключили, а не включили.
defineRule("СтопДвиж", {
whenChanged: "wb-mr6c_142/Input 3 counter",
then: function(newValue, devName, cellName) {
//Если после нажатия кнопки включения света, свет выключился, то устанавливаем таймер
if (dev["wb-mr6c_142/K3"] == false) {
long_timer_id = setTimeout(function () {
log("Правило СтопДвиж: Таймер {} закончился.",long_timer_id);
long_timer_id = null;
}, 1 * 60 * 1000);
log("Правило СтопДвиж: Устанавливаю таймер {}, т.к. кнопкой выключили свет.",long_timer_id);
}
}
});
Попробовал воспроизвести.
И да, ожидаемо: довольно часто состояние счетчика входа уже прочиталось (обновлено в топике) а состояние выхода - еще нет.
Что нормально для шины с конечной скоростью. я бы подошел с другой стороны - реагировал бы на изменение состояния выхода и проверял состояние счетчиков срабатывания.
Так не пробовал. Но, как понимаю, проблема останется, т.к. состояние входа уже поменялось, правило сработало, а состояние счётчика ещё не изменилось.
Как я понял, никакой чёткой связи между изменением состояния выхода и действием, которое вызвало это изменение - нету.
Буду пробовать предложенный вариант и вариант с таймаутом, чтобы дождаться изменения состояния выхода в регистре. Хотя оба эти варианта выглядят так, что могут в любой момент сработать не так как ожидалось. Хотелось, конечно, найти более однозначное решение.
Попробовал переписать правило как рекомендовали (реагировать на состояние выхода).
И оно заработало без ошибок. Правда иногда происходит двойное срабатывание правила.
Подскажите, хочу понять логику происходящего, почему так происходит? Ведь если состояние счетчика входа может обновиться позже состояния выхода (как периодически происходило в прошлом примере), то получается, что должны быть случаи, когда свет выключается кнопкой, состояние выхода обновляется, правило срабатывает, значение счётчика остаётся прежним и мы должны получить ошибочный результат работы правила.
И второй момент. Почему иногда происходит двойное срабатывание правила? Можно ли как-то от этого избавиться?
Попробую воспроизвести.
Но, совершенно одинаковые, в пределах той же миллисекунды записи в лог скорее всего говорят о двух экземплярах правила, запущенных параллельно. И да, для проверки - перезапустите сам движок правил, сервис wb-rules.