Здравствуйте. Подскажите как прописать расчёт контрольной суммы в wb-rules. Задача -отправлять широковещательную команду в порт rs-485 для управления внутрипольными конвекторами. В документации производителя указано следующее:
-Контрольная сумма (CS):
Результат операции XOR над всеми байтами пакета, кроме преамбулы.
Примеры пакетов
55 FF 03 01 01 01 FD включить клапан
55 FF 03 01 00 AA 00 57 вентилятор на 170 (67%)
Сейчас создал нехитрое правило, по образцу в вашей документации:
defineVirtualDevice(“rs485_cmd”, {
title: “Send custom command to RS-485 port”,
cells: {
enabled: {
type: “switch”,
value: false
},
}
});
defineRule(“_rs485_switch_on”, {
asSoonAs: function () {
return dev.rs485_cmd.enabled;
},
then: function() {
runShellCommand(“/usr/bin/printf ‘\x55\xff\x03\x01\x00\xAA\x00\x57’ > /dev/ttyMOD1”);
}
});
defineRule(“_rs485_switch_off”, {
asSoonAs: function () {
return !dev.rs485_cmd.enabled;
},
then: function() {
runShellCommand(“/usr/bin/printf ‘\x55\xff\x03\x01\x00\x0A\xF7’ >/dev/ttyMOD1”);
}
});
Но, по этому правилу могу только включать конвектор на определённые обороты, и выключать его. А хотелось бы регулировать обороты (я так понимаю нужно поменять type: “switch” в правиле на type:“range”, но придётся подсчитывать контрольную сумму в правиле).
Мне в таких случаях помогает Sunshine's Homepage - Online CRC Calculator Javascript . Нахожу алгоритм расчета CRC, а дальше гугл, может и для JS пример кода будет
Добрый день.
Для примера: Dooya DT82 (Onviz MR-2234F) - #15 от пользователя BrainRoot функция “crc16modbus”
А зачем используете “runShellCommand”? Есть же удобный RPC.
Реализацию на runShellCommand скопировал из документации wirenboard. Был бы очень рад увидеть реализацию этого скрипта на удобнейшем RPC! Думаю, для специалиста подправить скрипт-дело двух минут…
И для RPC: Примеры правил — Wiren Board
Да, у нас есть партнеры-интеграторы которые вполне могут сделать такое.
Как хорошо ,что можно вот так обратиться в тех поддержу, и мило поболтать! Спасибо большое!
Не забудьте отметить мой вопрос как решённый , вы мне очень помогли! Обязательно обращусь к вашим партнёрам-интеграторам!
Техподддержка - не занимается написанием скриптов. Подсказать - да, но не реализовывать.
// Виртуальное устройство для управления
defineVirtualDevice(“rs485_control”, {
title: “RS-485 Controller (ES5)”,
cells: {
level: {
type: “range”,
value: 0,
min: 0,
max: 255,
step: 1
},
last_command: {
type: “text”,
value: “”,
readonly: true
},
status: {
type: “text”,
value: “OK”,
readonly: true
}
}
});
// Функция для расчета контрольной суммы (XOR)
function calculateCS(packet) {
var cs = 0;
for (var i = 1; i < packet.length; i++) {
cs ^= packet[i];
}
return cs;
}
// Функция для отправки команды
function sendCommand(value) {
try {
// Формируем пакет
var packet = [0x55, 0xFF, 0x03, 0x01, 0x00, value,];
packet.push(calculateCS(packet));
// Преобразуем в HEX-строку
var hexString = packet.map(function(byte) {
return '\\x' + ('0' + byte.toString(16)).slice(-2);
}).join('');
// Логируем команду
log("Отправляемая команда: " + hexString);
// Отправляем команду
runShellCommand('/usr/bin/printf "' + hexString + '" > /dev/ttyMOD1');
// Обновляем статус
dev.rs485_control.last_command = hexString;
dev.rs485_control.status = "OK: " + new Date().toLocaleTimeString();
} catch (e) {
dev.rs485_control.status = "Error: " + e.message;
log("Ошибка: " + e);
}
}
// Правило для обработки изменений уровня
defineRule(“rs485_level_rule”, {
whenChanged: “rs485_control/level”,
then: function (newValue) {
if (newValue >= 0 && newValue <= 255) {
sendCommand(newValue);
} else {
dev.rs485_control.status = “Error: Invalid value (” + newValue + “)”;
}
}
});
1 лайк
Вот рабочий скрипт для конвекторов KZTO. Может кому-то пригодится. Чтобы лишний раз не тратится на партнёров-интеграторов!