Чтение с modbus rtu текста в cp1251 и отображение на svg панели

Добрый день! Подскажите, где посмотреть решение, а лучше образец кода.

С modbus читаю 64 символа в кодировке 1251, команда 04. Как их конвертировать в читаемый вид?

Здравствуйте.

Вам нужно парсить получаемую последовательность символов и преобразовывать в соответствующие символы.

Обычно техподдержка не пишет код за пользователей, но с помощью местного AI бота за две итерации написал такой код:

defineVirtualDevice("cp1251convert", {
    title: "cp1251 convert",
    cells: {
        input: {
            type: "text",
            value: "input",  
            readonly: false
        },
        Convert: {
            type: "pushbutton",
            value: false
        },
        output: {
            type: "text",
            value: "Convert Text", 
            readonly: true
        },
    }
});// Таблица CP1251: индекс = байт (0..255), значение = Unicode-символ
// Для краткости: здесь только несколько примеров, НУЖНО заполнить всю таблицу.
// Я покажу структуру, а полный массив удобно взять готовый из справочника CP1251.
var cp1251 = [];
for (var i = 0; i < 256; i++) cp1251[i] = String.fromCharCode(i);

// Пример частичного переопределения для русских букв
// (фрагмент; полностью таблицу лучше скопировать из готового JS‑массива CP1251)
cp1251[0xC0] = "А"; cp1251[0xC1] = "Б"; cp1251[0xC2] = "В"; cp1251[0xC3] = "Г";
cp1251[0xC4] = "Д"; cp1251[0xC5] = "Е"; cp1251[0xC6] = "Ж"; cp1251[0xC7] = "З";
cp1251[0xC8] = "И"; cp1251[0xC9] = "Й"; cp1251[0xCA] = "К"; cp1251[0xCB] = "Л";
cp1251[0xCC] = "М"; cp1251[0xCD] = "Н"; cp1251[0xCE] = "О"; cp1251[0xCF] = "П";
cp1251[0xD0] = "Р"; cp1251[0xD1] = "С"; cp1251[0xD2] = "Т"; cp1251[0xD3] = "У";
cp1251[0xD4] = "Ф"; cp1251[0xD5] = "Х"; cp1251[0xD6] = "Ц"; cp1251[0xD7] = "Ч";
cp1251[0xD8] = "Ш"; cp1251[0xD9] = "Щ"; cp1251[0xDA] = "Ъ"; cp1251[0xDB] = "Ы";
cp1251[0xDC] = "Ь"; cp1251[0xDD] = "Э"; cp1251[0xDE] = "Ю"; cp1251[0xDF] = "Я";
cp1251[0xE0] = "а"; cp1251[0xE1] = "б"; cp1251[0xE2] = "в"; cp1251[0xE3] = "г";
cp1251[0xE4] = "д"; cp1251[0xE5] = "е"; cp1251[0xE6] = "ж"; cp1251[0xE7] = "з";
cp1251[0xE8] = "и"; cp1251[0xE9] = "й"; cp1251[0xEA] = "к"; cp1251[0xEB] = "л";
cp1251[0xEC] = "м"; cp1251[0xED] = "н"; cp1251[0xEE] = "о"; cp1251[0xEF] = "п";
cp1251[0xF0] = "р"; cp1251[0xF1] = "с"; cp1251[0xF2] = "т"; cp1251[0xF3] = "у";
cp1251[0xF4] = "ф"; cp1251[0xF5] = "х"; cp1251[0xF6] = "ц"; cp1251[0xF7] = "ч";
cp1251[0xF8] = "ш"; cp1251[0xF9] = "щ"; cp1251[0xFA] = "ъ"; cp1251[0xFB] = "ы";
cp1251[0xFC] = "ь"; cp1251[0xFD] = "э"; cp1251[0xFE] = "ю"; cp1251[0xFF] = "я";

// Функция: конвертация hex-строки (без пробелов) в строку по CP1251
function hexToCp1251String(hexStr) {
  // Оставляем только цифры и A-F
  hexStr = (hexStr || "").replace(/[^0-9a-fA-F]/g, "").toLowerCase();

  // Должно быть ровно 120 символов (60 байт) — при необходимости контролируйте
  if (hexStr.length < 120)
    log("WARN: hex string shorter than 120 chars: " + hexStr.length);

  var out = "";
  // Берём первые 60 байт (120 символов)
  var maxLen = Math.min(120, hexStr.length);
  for (var i = 0; i < maxLen; i += 2) {
    var byteHex = hexStr.substr(i, 2);
    var code = parseInt(byteHex, 16);
    if (isNaN(code)) continue;
    var ch = cp1251[code] || "?";
    out += ch;
  }
  return out;
}

defineRule("decode_cp1251_60bytes", {
  whenChanged: "cp1251convert/Convert",
  then: function (newValue, devName, cellName) {
    var hexRaw = dev["cp1251convert/input"];
    var decoded = hexToCp1251String(hexRaw);

     log("decoded = " +decoded);
    // Пишем результат в другой контрол
    dev["cp1251convert/output"] = decoded;
  }
});

Он создает виртуальное устройство, которое преобразует hex последовательность в кириллицу:


Мне удалось вам помочь? Есть ли еще какие-либо вопросы?

Спасибо за оперативный ответ, нужно время, чтобы разобраться.

Пока понятно, попробую реализовать.

1 лайк

Хорошо, если что-то будет не ясно - пишите, разберемся.

Закончил разработку и подключение платы к оборудованию, подключил к wirenboard по модбас.

По команде modbus_client_rpc --debug -mrtu -b19200 -pnone -s1 /dev/ttyRS485-1 -a0x5 -t0x04 -r0 -c64

успешно читаю все регистры, через echo -e $(modbus_client_rpc -mrtu -b19200 -pnone -s1 /dev/ttyRS485-1 -a5 -t0x04 -r0 -c64 | grep Data | sed -e ‘s/.*Data://’ -e ‘s/ 0x00/\x/g’) | iconv -f CP1251 -t UTF-8

получаю текст из регистров.

Настроил 485 интерфейс, создал модбас устройство. Подскажите, куда двигаться дальше, в каком направлении? Мне нужно на svg панели отобразить 4 строки по 16 символов и обновлять периодически.