Search for examples for serial request node usage (/dev/ttyUSB0)

Hello everyone,

I hope you all had a wonderful Christmas!

I am looking for help with the following ‘problem’:

My gas heating is connected to my Rpi4B (USB Interface) and I can read data using the following Python script:

import serial
import time

SERIAL_PORT = '/dev/ttyUSB0'


def main():
    ser = None
    try:
        ser = serial.Serial(SERIAL_PORT,
                    baudrate=4800,
                    parity=serial.PARITY_EVEN,
                    stopbits=serial.STOPBITS_TWO,
                    bytesize=serial.EIGHTBITS,
                    exclusive=True,
                    timeout=0)
        # send reset
        ser.write(bytes([0x04]))
        print("tx 0x04")
        if(wait_for_05(ser)):
            # now read F8 4 bytes
            #outbuff = bytes([0xC7,0xF8,0x04])
            outbuff = bytes([0x01,0xC7,0xF8,0x04])
            ser.reset_input_buffer()
            ser.write(outbuff)
            print("tx", bbbstr(outbuff))
            receive_resp_telegr(4,0xF8,ser)
    except Exception as e:
        print(e)
    finally:
        if ser:
            ser.close()
        print("done. bye!")




def wait_for_05(ser:serial.Serial) -> bool:
    # and for 30x100ms waited for an ENQ (0x05) - we do 50x100ms (1 byte @4800 ca. 0.002s)
    for _ in range(50):
        time.sleep(0.1)
        try:
            buff = ser.read(1)
            print(buff)
        except Exception as e:
            print(e) 
            return False
        #print(buff)
        if(len(buff) > 0) and (int(buff[0]) == 0x05):
            return True
    print("Timeout waiting for 0x05")
    return False


def receive_resp_telegr(rlen:int, addr:int, ser:serial.Serial):
    inbuff = bytearray()

    # for up 20x50ms serial data is read. (we do 20x100ms)
    for _ in range(20):
        time.sleep(0.1)
        try:
            inbytes = ser.read_all()
            if(inbytes):
                inbuff += inbytes
                print("rx", bbbstr(inbuff))
        except Exception as e:
            print(e) 
         
        # 'evaluate'
        if(len(inbuff) >= rlen):
            print("f8 received", bbbstr(inbuff))
            return

    # timout
    print("rx telegr timeout")


def bbbstr(data):
    try:
        return ' '.join([format(byte, '02x') for byte in data])
    except:
        return data


if __name__ == "__main__":
    main()

The heating system then provides the following data, for example:

(myvenv) pi@rpi4B:~/optolink-splitter $ python3 readf8gwg_outbuff_0x01_0xC7_0xF8_0x04.py
tx 0x04
b'\x05'
tx 01 c7 f8 04
rx 20 53 01 1e
f8 received 20 53 01 1e

I assume that what works with the Python script can also be implemented directly in Node-RED with the serial request node.

Could someone assist me with this and tell me which values need to be entered in the yellow marked areas and show me how the Inject??? node needs to be structured so that exactly the same data can be sent and received as shown above?

Many thanks in advance!!!

Best regards,
Thomas

Yes.

A couple of initial things.

Firstly, Serial ports are often exclusive. So if you have something already opening the port, you generally won't be able to have another process also opening it. There are ways around that but that is more complex and best avoided if possible.

The second point of note is that USB serial ports have a nasty habit of occasionally changing position. So on Linux, it is often best to use one of the more explicit dev locations that the udev service provides:

Using these will save you heartache in the future. :smiley:

So noting those things, make sure your Python code isn't running before trying to connect Node-RED to the port.

As for the rest, I generally don't directly use a serial port and don't have the node installed. However, I would have thought that simply leaving those fields blank and dumping the output to debug would give you the clues you need?

1 Like

If you leave those blank then it will use the timeout, so as you show it, it will give you the data after 10 seconds, so you might want to reduce that a bit. Once you see what comes back you will be better able to work out the best strategy.

Looking at the python code it looks like you may need to do two inject nodes...
one with a buffer of ["0x04"] then it should reply with "0x05" - then send a buffer with ["0x01, 0xc7, 0xf8, 0x04"] and you should get 4 bytes back...

Screenshot 2025-12-27 at 22.12.19

To start with I would leave the wait for start char blank (IE don't wait for anything special - just dump anything - also set the split to be a timeout of say 20mS - (do experiment) - and deliver a binary buffer.

Then try each inject in turn - the first seems to say it is a reset - so maybe you only need to do that one - so that could be set to fire on deploy then the other any time you want to read.

Good Morning!

Firstly, Serial ports are often exclusive. So if you have something already opening the port, you generally won't be able to have another process also opening it. There are ways around that but that is more complex and best avoided if possible.

Thank you very much for this hint!

The second point of note is that USB serial ports have a nasty habit of occasionally changing position. So on Linux, it is often best to use one of the more explicit dev locations that the udev service provides:

I have read this somewhere before and have taken it into account by ensuring that only one USB port on my Rpi4B was in use during the “tests” listed above.

Thank you very much for that as well!

So noting those things, make sure your Python code isn't running before trying to connect Node-RED to the port.

Same!

And now I will try to understand and work on the other useful answers below.

That is not sufficient. If, during use, the USB port (not the serial connection but the USB itself) disconnects and then reconnects (which is not unusual) then it may well reconnect as a different port number. As suggested it is better to use /dev/serial/by-id/xxx as that will not change. Unless you change the serial/usb interface at least.

Understood, thank you!
:grinning_face:

@Colin
I'm afraid I didn't quite understand.

My device shows:

pi@rpi4B:~ $ ls -l /dev/serial/by-id
insgesamt 0
lrwxrwxrwx 1 root root 13 27. Dez 19:03 usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0001-if00-port0 -> ../../ttyUSB0

But how can I use (select) this in the serial request node?
Only /dev/ttyUSB0 is shown there…

Thx!

/dev/serial/by-id/usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0001-if00-port0

You use that instead of what you have.

Can't you just paste it in?

One other thing you could do is use mqtt to publish the data and have NR subscribe to it.
If you want an example, you could take a look at this:

I’ve been using it since 2023.