Добрый день!
Настроил получение команд и отправку сообщений в Телеграм с помощью GitHub - aadegtyarev/telegram2wb: Телеграм-бот на wb-rules. Скрипт взял оттуда же из примеров, просто добавил туда свои команды и оповещения. Все прекрасно работает, но только до перезагрузки контроллера. После перезагрузки бот никак не откликается до тех пор, пока не зайти в правило из веб-интерфейса и не пересохранить его. После этого оно выполняется, приходят все команды, что были отправлены пока бот “молчал” и далее уже все работает как обычно. Возможно, я что-то упустил в документации и чтобы правило выполнилось после перезапуска контроллера, надо как-то его триггернуть? Инициализация бота там написана как и в примере вне каких-либо коллбэков.
Добрый день.
После инициализации рекомендую явно чистить “топик команд”, добавив
dev[cmdTopic] = ""
А где это нужно написать? Если просто после bot.init(token, allowUsers, deviceName); это написать следующей строчкой, то он ругается на такое. Видимо, внутри функции только можно так писать.
Как ругается?
После определения всего, в конце, например.
К сожалению, после экспериментов с этой строчкой скрипт совсем сломался и теперь даже будучи возвращенным в прежнее состояние и после перезагрузки контроллера постоянно сыпет ошибку:
2025-10-27 14:13:29ECMAScript error: TypeError: invalid base value
duk_hobject_props.c:2000
writeMqttCmd telegram2wb:529
anon telegram2wb:101 preventsyield
call native strict preventsyield
anon /usr/share/wb-rules-system/scripts/lib.js:240 preventsyield
Боюсь информации которую представляете недостаточно для диагностики;
В общем после инициализации явно обнулите топик команд.
Ну получается так, что при вызове dev[cmdTopic] = “”; триггерится правило “bot_cmd_controller”, при этом его аргументы получаются пустыми (newValue, например). Соотв. там получается ошибка. Если проверить newValue на null и выйти из правила, то потом начинает сыпать указанную выше ошибку до тех пор, пока в скрипте не поменяешь название устройства deviceName, видимо что-то в топике устройства оказывается испорчено…
Нет ошибки, если писать dev[cmdTopic] = “{}”;
Но, к сожалению, это ничего не меняет - все равно после перезагрузки бот не отзывается, пока не зайдешь в правило и не пересохранишь его, либо не выполнишь команду перезагрузки wb-rules, что тоже заставляет правило начать работать.
Да, ожидаемо.
Проверяю:
dev[cmdTopic] = "1"
dev[cmdTopic] = ""
В логе, с включенным debug
Oct 27 12:52:00 wirenboard-AQASN7R6 wb-rules[26838]: ERROR: [rule error] ECMAScript error: TypeError: unexpected type
duk_api_stack.c:1266
keys native strict preventsyield
isEmptyJson /etc/wb-rules/telegram2wb.js:232
anon /etc/wb-rules/telegram2wb.js:23 preventsyield
call native strict preventsyield
anon /usr/share/wb-rules-system/scripts/lib.js:238 preventsyield
Oct 27 12:52:00 wirenboard-AQASN7R6 wb-rules[26838]: ERROR: [rule error] ECMAScript error: TypeError: invalid base value
duk_hobject_props.c:2000
anon /etc/wb-rules/telegram2wb.js:22 preventsyield
call native strict preventsyield
anon /usr/share/wb-rules-system/scripts/lib.js:238 preventsyield
Oct 27 12:52:01 wirenboard-AQASN7R6 wb-rules[26838]: INFO: reloading file: /etc/wb-rules/rules.js
Oct 27 12:52:03 wirenboard-AQASN7R6 wb-rules[26838]: INFO: [rule info] telegram2wb: [GO TO parseUpdates]
|→ undefined
Oct 27 12:52:03 wirenboard-AQASN7R6 wb-rules[26838]: INFO: [rule info] telegram2wb: [IN parseUpdates 1 JSON:]
|→ {"ok":true,"result":[]}
Oct 27 12:52:03 wirenboard-AQASN7R6 wb-rules[26838]: INFO: [rule info] telegram2wb: [IN parseUpdates 1.0]
|→ []
Oct 27 12:52:03 wirenboard-AQASN7R6 wb-rules[26838]: INFO: [rule info] telegram2wb: [IN parseUpdates 1.1]
|→
У меня cmd обрабатывается так (начало)
defineRule("bot_cmd_controller", {
whenChanged: cmdTopic,
then: function (newValue, devName, cellName) {
cmd = JSON.parse(newValue);
dev[devName][cellName] = "{}";
log.info("cmd.common",cmd.common)
if (!isEmptyJson(cmd)) { // Проверяем, что команда не пустая
То есть сам скрипт вполне продолжает работать.
При этом, что интересно, бот посылает сообщения, которые триггерятся правилами (например, что изменилась температура). Он только не отзывается на команды. В дебаге видно, что там должна периодически вызываться функция getMessages - вот этого и не происходит до сохранения скрипта/перезагрузки wb-rules.
Вот в документации про это:
Команды, как понятно из архитектуры - обрабатываются пользовательским скриптом.
Но вот в Cmd публикуется, при приеме, например:
/devices/telegram2wb/controls/Cmd {"chatId":***********,"chatType":"private","mentions":[],"messageId":1109,"command":"/help","args":""}
Интересно, но не воспроизводится.
А сам бот включен?

А если его выключить-включить?
Предполагаю что не работает telegram2wb/src/telegram2wb.js at 860bb4ef40d33162bc3c39a2bd1ed131f6b4763f · aadegtyarev/telegram2wb · GitHub
Да, включен, конечно. Вижу в логах, что после перезагрузки контроллера много раз (несколько десятков, но не бесконечно) повторяется ошибка:
INFO: [rule info] tg_bot: [sendMessage/runShellCommand] exitCode: 6 | capturedOutput: | capturedErrorOutput:
|→ command: curl -s --connect-timeout 60 --max-time 30 -X POST https://api.telegram.org/bot_token/sendMessage -d chat_id=undefined -d text=‘Could not send the result of the command execution.
ExitCode: 6
See details in the controller console.’ -d parse_mode=Markdown
Также несколько раз повторяется ошибка:
ERROR: [rule error] Error in getting device: Device with given ID doesn’t exist
Но непонятно к какому скрипту она относится - нет указания в логе.
tg_bot достаточно идентифицирует, думаю.
А точно ресурс (сеть) на момент запуска скрипта уже доступен?
Я имею в виду вторую ошибку, первая-то да, точно от бота. Возможно, что сеть может быть еще недоступна - не знаю, как это можно проверить из скрипта, например? Контроллер подключен по Wi-Fi к сети, вполне возможно что на момент выполнения скрипта там еще не установилось соединение, но я не знаю как этот процесс контролировать с моей стороны, он же автоматически после рестарта соединяется.
Ping выполнить - пожалуй проще всего. Ну или тот же wget выполнить. Или посмотреть текущий локальный адрес (состояние интерфейса, косвенно).
Ну или просто запустить модуль через ХХ секунд после запуска движка. Варантов, на самом деле полно. Но - я б проверил что функция, ссылку на которую дал работает.
Да, но сам факт (установки) соединения - можно использовать. Да хотя б адрес из штатного устройства “network/Ethernet IP”.
А вот, кстати, да. Напишу разработчикам - надо вывести что за контрол указан.
Ну и проверьте telegram2wb/src/telegram2wb.js at 860bb4ef40d33162bc3c39a2bd1ed131f6b4763f · aadegtyarev/telegram2wb · GitHub значение. Также - как уже писал: что происходит при выключении и снова вклюючении переключателя? Отрабатывает ли таймер?
Надо сказать что предлагаемый скрипт не относится к штатному ПО. То есть помочь смогу - но если только воспроизведу подобное у себя.
Проверил такой функцией:
runShellCommand("wget -q -O - http://network-test.debian.org/nm", {
captureOutput: true,
exitCallback: function (exitCode, capturedOutput) {
log("INET STATUS!!! " + capturedOutput);
}
});
При автоматическом выполнении скрипта после запуска контроллера capturedOutput пустой, а когда я сохраняют скрипт из UI, то он уже содержит значение NetworkManager is online. Ну и IP адреса в момент автозапуска все равны null. Так что, действительно, дело наверное в этом.
Таймер начинает работать после того, как скрипт пересохранен/перезагружен wb-rules. Если отключить бота, то таймер останавливается, если включить - продолжает тикать. Вроде бы выглядит в этом плане все корректно, когда скрипт уже работает. pollInterval = 1000 с самого начала.
В итоге, кажется, победил такой штукой:
var intervalId = setInterval(initBot, 1000);
function initBot()
{
log("Checking WIFI IP: " + dev["network/Wi-Fi IP"]);
log("Checking GPRS IP: " + dev["network/GPRS IP"]);
if (dev["network/Wi-Fi IP"] != null || dev["network/GPRS IP"] != null)
{
bot.init(token, allowUsers, deviceName);
clearInterval(intervalId);
log("Telegram Bot initilized");
}
}
Большое спасибо за помощь!
PS. А вот ошибка ERROR: [rule error] Error in getting device: Device with given ID doesn’t exist осталась. Видимо, другой скрипт какой-то, придется искать методом исключения.
Ну - отлично.
Но вот тут с практической точки зрения более интересно как будет отрабатывать не отсутствие (ожидаемое) связи при запуске а прерывание в процессе работы.
То есть - все работает, интернет пропал и потом (через минуты или часы) появился.
Тут, кажется, все как раз проще. Как только таймер бота стартовал, он уже опрашивает регулярно источник сообщений; если сети нет, то просто опросы ничего не возвращают. А когда сеть появляется, то прилетают все команды, что были посланы, пока сеть лежала. То есть бот уже штатно тут работает, нет этой проблемы с битой инициализацией из-за отсутствия даже не Интернета, а скорее поднятого сетевого интерфейса.
