Добрый день!
Написал скрипт управления теплым полом и отоплением кухни, но он не работает, скрипт во вложении. Не могу понять где ошибка, может кто-то подскажет.
Задача: есть кухня, где есть водяное отопление со своим контуром (датчик WB-MSW v3) и теплый электрический пол (датчик 1-Wire).
Хотелось бы включать электрический пол с 23.00-7.00 ежедневно,
а отопление в будни с 18.00-23.30 и в выходные с 9.00-23.30.
Конечно есть два гистерезиса по температурам, то есть когда реле М6С отключает теплый пол и когда поступает 24В от wb-gpio/EXT1_K1 на нормально-открытые сервопривода контура отопления.
Также есть:
- три ползунка: первый активирует правило теплого пола, второй: активирует правило отопления, третий активирует режим отопления: выходной и будни;
- два выключателя: один повешен на реле М6С (канал 5), второй повешен на клему контроллера А1_IN, на которую подано 5В.
В приоритете над правилом являются выключатели и если они нажаты, то пол или отопление работают.
Кухня-теплый пол и отопление.txt (16,5 КБ)

Доброго дня.
В первую очередь, я рекомендую все значения дат обновлять внутри whenChanged, в данном виде у вас значения фиксируются при сохранении скрипта и больше не меняются.
Во-вторых, пользуйтесь промежуточным выводом значений в консоль при помощи функции log(), проблему с датами вы бы давно таким образом заметили.
В коде есть небольшая ошибка в определении выходных дней. Дни недели в JavaScript начинаются с воскресенья (0), поэтому суббота будет 6, а воскресенье - 0.
Исправление: var isWeekend = (day == 6) || (day == 0);
Сравнение с true
и false
: В JavaScript прямое сравнение с true
или false
часто является излишним. Например, if (dev["wb-mr6c_149/Input 5"] == true)
можно заменить на if (dev["wb-mr6c_149/Input 5"])
. Это не ошибка, просто рекомендация для упрощения кода.
Повторяющиеся действия: В вашем коде есть множество условий, которые устанавливают одно и то же значение для dev["wb-gpio/EXT1_K1"]
или dev["wb-mr6c_149/K5"]
. Это может быть упрощено путем группировки условий.
Проверка условий времени: Вы используете date > date_start_floor
и date < date_end_floor
для проверки времени. Убедитесь, что это корректно отражает вашу логику, так как это будет сравнивать даты, включая день, месяц и год. Уточнение: Если вам нужно сравнивать только время, а не даты, вам придется преобразовать эти значения в формат, который сравнивает только часы и минуты.
Добрый день!
А что значит обнулять значения дат внутри whenchanged?
Для примера, оборачиваем запрос актуальных дат в отдельную функцию (привожу только часть кода):
function updateDateVariables() {
var now = new Date();
var date_start_floor = new Date(now);
var date_end_floor = new Date(now);
date_start_floor.setHours(23, 2, 0, 0); // Устанавливаем время начала работы теплого пола
date_end_floor.setHours(6, 58, 0, 0); // Устанавливаем время окончания работы теплого пола
// Возвращаем объект с обновленными временными переменными
return {
startFloor: date_start_floor,
endFloor: date_end_floor
};
}
и далее уже при каждом изменении значения температуры, запрашиваем актуальные даты.
defineRule("Heat_Floor_Kitchen", {
whenChanged: "wb-w1/28-00000c19588c",
then: function (newValue, devName, cellName) {
// Код пропущен
// Получаем обновленные временные переменные
var dates = updateDateVariables();
var now = new Date();
if ((dev["wb-mr6c_149/Input 5"] == false) && (dev["Kitchen/RuleTempFloor"] == true)) {
if (now > dates.startFloor && now < dates.endFloor && newValue < (dev["Kitchen/temp2"] - hysteresis_floor)) {
dev["wb-mr6c_149/K5"] = true; // теплый пол работает
} else {
dev["wb-mr6c_149/K5"] = false; // теплый пол не работает
}
}
// ... продолжение вашего кода
}
});
Но лучше самостоятельно разобраться в коде и понять где что менять, я особо не углублялся в логику работы вашего скрипта.
Добрый день!
“Повторяющиеся действия: В вашем коде есть множество условий, которые устанавливают одно и то же значение…”
Напишите пожалуйста пример группировки условий.
Спасибо.
Добрый день! С ветвлениями и виртуальными устройствами разобрался, спасибо, но с датами и временем Ваш алгоритм мне не подошел.
Ваш пример работает для интервалов в рамках одних суток (например с 7.00 до 23.00), а если интервал в котором нужно работать устройству начинается в одних сутках и заканчивается в других, то получается в текущих сутках в логах такой результат:
INFO: [rule info] 2024-02-05 23:01:00.000+03:00 2024-02-06 06:58:00.000+03:00.
А как начнутся следующие сутки (после 00.00):
INFO: [rule info] 2024-02-06 23:01:00.000+03:00 2024-02-07 06:58:00.000+03:00.
То есть задача, чтобы теплый пол работал с 23.01 до 6.58. А по факту пол по примеру выше работает у меня с 23.01 до 00.00 и как начинаются новые сутки, даты в коде меняются (см. значение выше в логах).
Вместо 6.58 ставил 30.58, то есть 24+6, но это ничего не меняет.
Не подскажите как решить эту проблему?
Добрый день.
Мы не занимаемся написанием кода, к сожалению.
Но давайте натолкну на верный путь.
Надеюсь что у вас получится разобраться и адаптировать под свои задачи.
function isTimeBetween(startTime, endTime, now) {
if (endTime < startTime) {
// Переход через полночь
return now >= startTime || now <= endTime;
}
return now >= startTime && now <= endTime;
}
defineRule("Heat_Floor_Kitchen", {
whenChanged: "wb-w1/28-00000c19588c",
then: function (newValue, devName, cellName) {
var now = new Date();
var todayStart = new Date(now);
var todayEnd = new Date(now);
var tomorrowStart = new Date(now);
var tomorrowEnd = new Date(now);
todayStart.setHours(23, 0, 0, 0); // Время начала работы теплого пола сегодня
todayEnd.setHours(23, 59, 59, 999); // Конец сегодняшнего дня
tomorrowStart.setHours(0, 0, 0, 0); // Начало следующего дня
tomorrowEnd.setHours(7, 0, 0, 0); // Время окончания работы теплого пола завтра
var isWorkingTimeToday = isTimeBetween(todayStart, todayEnd, now);
var isWorkingTimeTomorrow = isTimeBetween(tomorrowStart, tomorrowEnd, now);
var shouldHeat = (isWorkingTimeToday || isWorkingTimeTomorrow) && newValue < (dev["Kitchen/temp2"] - hysteresis_floor);
dev["wb-mr6c_149/K5"] = shouldHeat;
}
});
Для удобства обновление дат можно вынести в отдельную функцию, как мы делали ранее.
Я, к сожалению, не тестировал этот код в реальных условиях, но должно работать.