var cycle = 3 * 1000;
heater_pwm ("heater_1", 0, 1, "wb-gpio/A1_OUT");
heater_pwm ("heater_2", 1, 1, "wb-gpio/A2_OUT");
heater_pwm ("heater_3", 2, 1, "wb-gpio/A3_OUT");
startTicker("period", cycle); // основной цикл переключений
function heater_pwm (name, delay_sec, on_sec, relay){
var count = 0; // контроль непрерывности работы
var timer1Name = "timer1_" + name; // задаем уникальное текстовое значение имени таймера внутри каждого экземпляра функции
var timer2Name = "timer2_" + name; // задаем уникальное текстовое значение имени таймера внутри каждого экземпляра функции
defineRule("pwmCycle_" + name, { // правило для запуска таймера на окончание "положительной" полуволны
when: function () { return timers.period.firing; }, // начало отсчета основного цикла
then: function () {
log(count++);
startTimer(timer1Name, delay_sec * 1000); // запустили таймер на отключение "положительной" полуволны
timers[timer1Name].name = timer1Name; // присвоили уникальное имя таймеру, чтбы его окончание отследить
}
});
defineRule("pwmDelay_" + name, {
when: function () { return timers[timer1Name].firing; }, // отследили срабатывание таймера на задержку начала "положительной" полуволны
then: function () {
dev[relay] = 1; // включили "положительную" полуволну
startTimer(timer2Name, on_sec * 1000); // запустили таймер на отключение "положительной" полуволны
timers[timer2Name].name = timer2Name; // присвоили уникальное имя таймеру, чтбы его окончание отследить
}
});
defineRule("pwmOn_" + name, {
when: function () { return timers[timer2Name].firing; }, // отследили срабатывание таймера на окончание "положительной" полуволны
then: function () {
dev[relay] = 0; // закончили "положительную" полуволну
}
});
}
С такими параметрами можно использовать для “бегущих огней”
Обнаружил, что если частоту переключения поставить слишком большую (период 0,5 сек), то рано или поздно контроллер зависает.
Может быть посоветуете диагностический инструмент, чтобы отследить какой параметр достигает предельного? Пока подозреваю температуру процессора, так как она в этом режиме переваливает за 62 градуса.
Завешивание контроллера движком правил – неприятная проблема. Первое, что можно подозревать – это утечки памяти. Второе – перегрев. Я попробую воспроизвести проблему с вашим правилом, а вы можете смотреть в консоли за загрузкой процессора и потреблением памяти с помощью top, также интересно, появляется ли какая-то информация в отладочной консоли (USB Debug Console).
Я имел в виду то, что вы получите в терминале, подключившись к отладочной консоли USB/UART.
При падении иногда ядро успевает что-то интересное написать туда.
Такой вариант значительно изящнее.
Я его также использовал, только не догадался вызов функций осуществлять в периодическом цикле, а все-таки ловил его запуск.
Но все-равно правило “крутится” только определенное количество циклов от 50 до 100, а затем зависает.
К тому же, если во время работы программы поменять параметры, то одни таймеры накладываются на другие (оставшиеся от предыдущих параметров) и начинается хаос.
То есть не чистятся старые таймеры.
Это странно. С какими значениями параметров зависает?
Да. Как при изменении параметров останавливать запланированные setInterval и setTimeout идей нет. Тут похоже поможет только рестарт движка правил при изменении значений в скриптах, или делать на таймерах.
Лучше не менять значения в коде скриптов, а вынести это в виртуальные устройства и менять у них параметры через UI/MQTT, и в правилах при изменении этих значений останавливать старые таймеры и запускать новые с новыми значениями.
Да, не зная номер таймаута или интервала я не смог грохнуть прошлый экземпляр. Только ребут помогал. Решение “влоб”, к ни странно, помогло:
for (var i = 0;i<20;i++)
{
log("сбиваю интервал " + i);
clearInterval(i);
clearInterval(interval_id);
}
Присоединяюсь к вопросу. Есть ли возможность видеть наполнение памяти, например, или еще что-то, что позволит хотя бы таймеры отследить - появляются новые или нет? А то переполнят и завесят через месяц wb…
Ясно, буду изучать. Видите, мне не очень знакомы эти технологии, только собираю знания. Если у меня не получится самому, обращусь за уточнениями. Спасибо!
Какое свойство таймера можно проверить, чтобы понять запущен он уже или нет?
Чтобы избежать повторного его перезапуска при наступлении события еще раз.
Потому что clearTimeout попытался очистить таймер, которого не было.
Задумка понятная: если сейчас таймер, после которого свет выключится, запущен, а датчик показывает движение, то этот таймер нужно отключить, и потом пересоздать заново.
Но в самом правиле в примере действительно была допущена ошибка: запускать таймер нужно не в момент включения датчика движения, а в момент отключения. А вот удалять - действительно в момент включения.
Ещё одной проблемой было, что устройствам типа switch начиная со второй версии движка правил нельзя присваивать 0 или 1, а можно только true или false.
Сейчас исправил код в примере на верный: Примеры правил — Wiren Board