Connecting USB device via Serial Agent to OR 3.0

Hi,
I’m trying to connect a USB device to OR 3.0 by using the SerialAgent. I’ve got serialPort attribute set to /dev/ttyUSB0 as that’s where the device is attached to and baud rate set accordingly to 115200. However, in the OR terminal console I get:
otocol.io.AbstractNettyIOClient.PROTOCOL : Establishing connection: serial:///dev/ttyUSB0 manager_1 | java.lang.NoClassDefFoundError: Could not initialize class gnu.io.RXTXCommDriver thrown while loading gnu.io.RXTXCommDriver manager_1 | Failed to connect on port: /dev/ttyUSB0 exception: manager_1 | gnu.io.NoSuchPortException manager_1 | at gnu.io.CommPortIdentifier.getPortIdentifier(CommPortIdentifier.java:273) manager_1 | at gnu.io.NRSerialPort.connect(NRSerialPort.java:116) manager_1 | at org.openremote.agent.protocol.serial.NrJavaSerialChannel.doConnect(NrJavaSerialChannel.java:44) manager_1 | at io.netty.channel.rxtx.RxtxChannel$RxtxUnsafe.connect(RxtxChannel.java:163) manager_1 | at io.netty.channel.DefaultChannelPipeline$HeadContext.connect(DefaultChannelPipeline.java:1342) manager_1 | at io.netty.channel.AbstractChannelHandlerContext.invokeConnect(AbstractChannelHandlerContext.java:548) manager_1 | at io.netty.channel.AbstractChannelHandlerContext.connect(AbstractChannelHandlerContext.java:533) manager_1 | at io.netty.channel.AbstractChannelHandlerContext.connect(AbstractChannelHandlerContext.java:517) manager_1 | at io.netty.channel.DefaultChannelPipeline.connect(DefaultChannelPipeline.java:978) manager_1 | at io.netty.channel.AbstractChannel.connect(AbstractChannel.java:253) manager_1 | at io.netty.bootstrap.Bootstrap$3.run(Bootstrap.java:250) manager_1 | at io.netty.channel.ThreadPerChannelEventLoop.run(ThreadPerChannelEventLoop.java:69) manager_1 | at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) manager_1 | at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) manager_1 | at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) manager_1 | at java.lang.Thread.run(Thread.java:748) manager_1 | 2021-06-15 09:04:45.592 WARNING [oioEventLoopGroup-45-1 ] otocol.io.AbstractNettyIOClient.PROTOCOL : Connection error: serial:///dev/ttyUSB0 manager_1 | io.netty.channel.ConnectTimeoutException: Failed to establish connection to COM port: /dev/ttyUSB0

Also, the Agent Status is “CONNECTING” ratherunsurprisingly.

I can see the USB device (USB to serial converter) sends data when I send a character to it, so the device and the connection to it works in principle outside OR 3.0

All this is on RPi 4 running Ubuntu 20.4. Any suggestions what the matter is? It seems to me like some access issue on the USB port but I don’t seem to be able to put my finger on it. There are various references to similar issue out there but they don’t seem particularly relevant.
Or do I need to configure the port connection in some config file?

Thanks!
Pekka

Hi,

Have you mapped the device into the manager container? Seems it wasn’t mentioned in the SerialAgent wiki but I have added it now:

Hi @rich ,

I had come accross that somewhere but couldn’t implement it based on the info where I saw it. Thanks for adding it into the documentation. I have added it in now but it didn’t change anything - the error remains the same.

Could the issue be something related to this?
https://www.raspberrypi.org/forums/viewtopic.php?f=5&t=6011
I don’t know how I’d add that implementation in though.

I’m assuming that you put the correct device paths in your docker compose device mapping :slight_smile:

I would list docker containers:

docker ps

then:

docker exec -it <MANAGER_CONTAINER_ID> bash

Then check you can read/write to your serial device within the container and report back.

Yes, I put the relevant device path in the .yml file that matches the USB port where the device is connected to. :slight_smile:

Can it be that I don’t have containers…? None were listed:

$ sudo docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

You need to be running the stack and then list the running containers docker ps -a will list all containers including stopped ones.

Ah, doh.
I don’t seem to be getting back anything on my /dev/USB0 in the bash, apart from the character that triggers the device to send and assuming I’m doing it correctly. I’m not a SW developer of any sort really.

So you can see data on the serial device directly on the RPi OS but from inside the manager docker container you can’t? If this is the case then this suggests a problem with device mapping, double check naming and ownership permissions.

Yes, this seems to be the case, although I haven’t managed to convince myself 100% what the situation is when I run bash in the container. Data definitely comes in from the USB device when accessing the device from RPi OS directly.

The access rights should be in order, AFAIK as ls -l /dev/ttyUSB0 gives
crw-rw---- 1 root dialout 188, 0 Mar 17 21:36 /dev/ttyUSB0
and the user is part of dialout group.

Question: Why is there 3 forward slashes in the device path in the console output?
Connect to 'serial:///dev/ttyUSB0': scheduling retry in 134000 MILLISECONDS

Also, is the device meant to be mapped onto a serial port for the docker like this in the container .yml file? - /dev/ttyUSB0:/dev/ttyS0 Can you not map it to the USB0 port and point the serial agent to that directly?

Aside, sometimes when I start OR docker-compose, the manager volume is re-created. That is, the container ID changes. But I guess it doesn’t impact on this.

3 forward slashes:

Protocol instances are identified in logs using URIs and so are prefixed accordingly (i.e. tcp://, http://, etc.)

You see 3 slashes for serial on linux simply because the com port starts with a / on windows you’d see something like serial://COM3

I managed to configure the serial port in docker-compose.yml for a Z-Wave stick on a Ubuntu 20.10 host but haven’t tested it yet on a Raspberry Pi system.

It doesn’t matter which name is used for the serial port mapping in the container. All of the following examples should work:

devices:
- /dev/ttyUSB0:/dev/ttyS0

devices:
- /dev/ttyUSB0:/dev/ttyUSB0

devices:
- /dev/ttyUSB0

The second and third example have the same result.

I’ld suggest that you check that the serial port is working on your host with a simple test like the following:

cat /dev/ttyUSB0

In this example data that is read from the serial port is shown in the terminal. If you see gibberish all is Ok. Then try to do the same in the container.

1.) Start a container shell

docker exec -it openremote_manager_1 /bin/bash

(note that openremote_manager_1 is the container ID - this may be different on your system)

2.) Execute the serial port test

cat /dev/ttyS0

1 Like

Thank you for the suggestions @rainerhitz .
I have confirmed the device works with tio outside the container as I need to send “m” in order to get the device to send data. I don’t think I can send anything to the device with cat (inside or outside the container). Hence, I’m not getting anything from it when using cat.
Is there another way to test the device inside the container? Can I run a terminal client inside the container somehow?

I think I was able to reproduce the bug you reported. I’ve installed OpenRemote on the following system:

  • Raspberry Pi 4 B
  • Raspberry Pi OS 64 bit

I tried to configure a serial agent and got the following error in the log:

manager_1 | java.lang.UnsatisfiedLinkError: /tmp/libNRJavaSerial_root_0/libNRJavaSerial.so: /tmp/libNRJavaSerial_root_0/libNRJavaSerial.so: wrong ELF class: ELFCLASS32 (Possible cause: architecture word width mismatch)

This error is an indication that the serial library is missing binaries for the arm64 architecture.

Hi @rainerhitz ,

Sorry, I’m a bit off-and-on on this project.
However, your error doesn’t seem like exactly the issue I had but something like it. In any case, the end result is presumably the same.
I wiped my OR setup in my Ubuntu VM on PC and got the same USB device connected no problems.
I still have the problem of having to send a character to the USB device to trigger it to send something. I guess I cannot have a small program running in Ubuntu sending characters to the same port whilst OR being connected to that very port waiting for data. Any thoughts?

All in all, OR seems great! You guys are doing good job. Thank you!

@Pekka I’ve modified the serial port implementation (see https://github.com/openremote/openremote/commit/56a9cd9d5eaaab3127af56968ac2059180417c02) in order to add arm64 achitecture support. Serial ports should now work on the Raspberry Pi 4 with Raspberry Pi OS 64.

You could build the manager docker image on the Raspberry Pi in order to get the latest version. Let me know if you need help doing this.

1 Like

Shouldn’t need to build the manager image yourself our pipeline will build and push latest image to docker hub which supports aarch64.