Нужна помощь с получением и обработкой обратки из RS-232

Приветствую, коллеги,
я новичок в работе с Wirenboard.

Есть небольшая учебная задача, необходимо научиться получать обратку от устройства и разбирать её, управляю дисплеем LG через интерфейс 232.
В базе установлена плата WBE2-I-RS232 в MOD1.

Включить и выключить дисплей могу через раздел с устройствами. Но как получить обратку и разобрать её пока не могу понять, точнее небольшое понимание есть, но не работает).

Во вложении файлы с правилом, bash и диаг. лог.
screen.sh (601 байт)
screen.js (738 байтов)

Что уже сделал:

  1. Нашёл и адаптировал под свою задачу bash скрипт, положил в корень.
  2. #!/bin/bash 
    #Инициализируем порт /dev/ttyWBE0
    stty -F /dev/ttyWBE0 ospeed 9600 ispeed 9600 raw clocal -parenb -echo cs8 
    CR="$(echo -e '\r')"
    exec 4<> /dev/ttyWBE0
    cat <&4 | while :
    do
        IFS="$CR" read -r line 
        case "$line" in
        quit*)
            break
            ;;
        *)
    
    	if [[ -n "$line"  ]]; then
    	    echo $line
                    #Полученные строки шлём в MQTT
       		mosquitto_pub -t /devices/screen/controls/raw/meta/type  -r  -m text
    		mosquitto_pub -t /devices/screen/controls/raw/on  -r  -m "$line"
    	fi
    
            ;;
        esac
    done
    
    1. Создал правило wb-rules:
    2. defineVirtualDevice("screen", { // создаем виртуальный девайс
          title: "nextion screen",
          cells: {
              raw: {
                  type: "text",
                  value: ""
              },
              enabled: {
          	    type: "switch",
          	    value: false
          	},
          }
      });
      
      
      //ka 01 01\r
      defineRule("_rs485_switch_on", {
        asSoonAs: function () {
          return dev.screen.enabled;
        },
        then: function() {
          runShellCommand("/usr/bin/printf 'ka 01 01\\x0d' > /dev/ttyWBE0");
        }
      });
      
      //ka 01 00\r
      defineRule("_rs485_switch_off", {
        asSoonAs: function () {
          return !dev.screen.enabled;
        },
        then: function() {
          runShellCommand("/usr/bin/printf 'ka 01 00\\x0d' >/dev/ttyWBE0");
        }
      });
      

      приложен диагностический архив, доступен только сотрудникам поддержки
      (243,2 КБ)

      Данные по контроллеру:
      WB 8.5
      Номер партии 8.5.3A/4G1 1.3.3C-4G
      Версия DTS 851
      Версия контроллера 8.5.3
      Название релиза wb-2507
      Тип релиза stable

Я Вам советую использовать RPC. Небольшая история с примерами и ссылками на документацию: Создание своего протокола - #8 от пользователя maks0508

1 лайк

Спасибо, изучу информацию.
Но насколько я понял, данная реализация не позволяет читать информацию от устройства без запроса, т.е. устройство само не сможет что-то отправить в порт?
А мне такая возможность нужна.

Два варианта: или писать свой драйвер или обойтись скриптами. Для примера: Аппарат для выдачи печенья «Кукинатор 3000» / Хабр

Пытаюсь разобраться во всех вариантах.
Со скриптами у меня как раз затык, не получается вывести обратку в MQTT топик. Скрипты приложил, если можно ткните меня где ошибка).
А что за способ с драйверами, можете навести, куда копать?

Мне вот это непонятно:

function () {
    return dev.screen.enabled;
  },

Что такое “dev.screen.enabled”?

Это отрабатывает?

Драйвер - например на C. Ну или питон, если он ближе.

“dev.screen.enabled” - это конструкция, взятая из wiki.wirenboard с примером для переключателя, соответственно в зависимости от стейта переключателя в веб-интерфейсе устройству улетает та или иная команда. Этот кусок скрипта работает, устройство попеременно вкл. и выкл.

Отправка полученных строк в MQTT не работает, значения топиков не изменяются, но не факт, что я корректно принимаю обратку.

Такой ответ ожидаю от устройства: a 01 OK00x, общепринятого символа конца строки \r там нет, а есть x в ascii. Пробовал заменять в bash-скрипте ‘\r’ на ‘x’, всё равно не работает.
Если в целом скрипты верные, то наверное надо копать в сторону того, что я неправильно обозначаю ожидаемый конец строки.

По варианту с драйвером спасибо, параллельно буду прорабатывать разработку на питоне, т.к. на нём пишу и скорее всего такая возможность пригодится.

Что именно (какие байты) приходят в порт? Я бы вывел каждый в лог и посмотрел…

Упростил задачу, по кнопке из wb-rules отправляю попеременно то вкл, то выкл в устройство. Устройство отрабатывает корректно.

Bash скрипт удалён.

Добавил вывод в лог обратки, как я уже начинаю понимать, так можно, но туда от устройства ничего не приходит:

2025-10-07 10:55:47Result output:
2025-10-07 10:55:47cmd Erroroutput:

Текущее правило:

defineVirtualDevice("screen", { // создаем виртуальный девайс
    title: "nextion screen",
    cells: {
        raw: {
            type: "text",
            value: ""
        },
        enabled: {
    	    type: "switch",
    	    value: false
    	},
    }
});


//ka 01 01\r
defineRule("_rs485_switch_on", {
  asSoonAs: function () {
    return dev.screen.enabled;
  },
  then: function() {
    runShellCommand("/usr/bin/printf 'ka 01 01\\x0d' > /dev/ttyWBE0",{
      captureOutput: true, 
      captureErrorOutput: false, 
      exitCallback: function (exitCode, capturedOutput, capturedErrorOutput) //Функция, в которую попадает вывод
      {            
        var result = capturedOutput;
        log("Result output: " + capturedOutput); //строка полностью
        //dev.screen.raw = capturedOutput.toString();
        log("cmd Erroroutput: " + capturedErrorOutput);
        if (exitCode){
          log.error("Ошибка: " + capturedErrorOutput);
        }
      }
    });
  }
});

//ka 01 00\r
defineRule("_rs485_switch_off", {
  asSoonAs: function () {
    return !dev.screen.enabled;
  },
  then: function() {
    runShellCommand("/usr/bin/printf 'ka 01 00\\x0d' >/dev/ttyWBE0");
  }
});

Update:
Данную команду отправил из командной строки и данные записались в топик:

cat /dev/ttyWBE0 | mosquitto_pub -t /devices/screen/controls/raw -l

screen/raw text /devices/screen/controls/raw
a 01 OK03xa 01 OKx
OK

А что ожидаете в выводе printf? если посмотреть в документацию printf возвращает только ошибку в случае ее возникновения.

Если хотите принимать данные приходящие в порт - то это не получится совместить с отправкой. Или я идею не понял?

Удалось всё-таки коллективным разумом решить задачу.

Решение оказалось наипростейшее).

  1. Отправляю в устройство данные:
runShellCommand("echo 'ka 01 01\r' > /dev/ttyWBE0")
  1. Через startTicker циклически читаю буфер последовательного порта /dev/ttyWBE0. Там лежат все данные, полученные из порта.
runShellCommand("cat /dev/ttyWBE0")
Вывод из буфера:

a 01 OKxa 01 OK0▒▒▒▒a 01 OK01xa 01 OK01xa 01 OK01xa 01 OK01xa 01 OK01xa 01 OK01xa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKxa 01 OKx

Всем спасибо огромное за помощь!

1 лайк

Ну отлично, рад.