RPI USB allocation

What happens if you attach an inject node to the exec node and run it?

I receive this from the third output {"code":2}

What does that mean?

It means you have a problem.

Did you get anything from the other debug nodes? Also set them to display the 'complete msg object'

I receive this with all three debug nodes set to complete msg object.
image

There is no output from the debug on output 1.

So look at the output from debug TWO. Click on the triangle next to the open bracket to expand the information.

What does that tell you?

image

Sorry, I'm none the wiser at this moment by this "Unterminated quoted string" .

Does the newline at the end of it cause a problem?

The exec node doesn't seem to like that command. I don't think you need the sh -c ' on the front or the ' on the end.

Colin, with:

udevadm info -a -p $(udevadm info -q path -n /dev/ttyUSB0) | fgrep "ATTRS{serial}"

I get:

image

Yes, you are right, that is no good. I don't know why the exec node won't accept the original command. Anyone else know?

But with "when the command is complete exec mode"

the original reply in terminal was:

sh -c 'udevadm info -a -p $(udevadm info -q path -n /dev/ttyUSB0) | fgrep "ATTRS{serial}"'
ATTRS{serial}=="20980000.usb"

I wonder whether, with the original mode it tries to run the first part of the command first, so you get the unterminated string.
Anyway, when complete is actually what you want I think.

Thinking out load, in this command I address a particular USB port, at this time it's USB0 and USB1 but next time it boots could it assign USB2 and USB4 which I'm not interrogating!

Should I be trying to first find out which USB ports have devices connected (is that possible?) and then ask these which serial numbers are connected!?

Also I have a GPS device which runs at 9600 baud, different to the Victron devices!

I thought you had a solution by interrogating the data to determine the source, or does that not work for some reason?

Colin,

I do but I don't know what the RPi does with USB. My Linux PC's seem to swap USB numbers when programming Arduino's.

I guess time will tell.

Regards the reply from the exec node, do I split the reply at the "/"s and use the serial number OR is there a better way?

Not sure what you mean by that. You cannot guarantee that the same device will get the same USB number each time, and even worse if there is a USB glitch and it disconnects then reconnects (which is not uncommon) then it will change USB number on the fly. The only really safe way is to use udev rules.

Does this work ?

[{"id":"81f148f5.be0bc8","type":"inject","z":"35d94b44.b5fd94","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":300,"y":300,"wires":[["be050931.11e6d8"]]},{"id":"be050931.11e6d8","type":"exec","z":"35d94b44.b5fd94","command":"udevadm","addpay":false,"append":" info -a --name /dev/ttyUSB0 | grep ATTRS{serial}","useSpawn":"false","timer":"","oldrc":false,"name":"","x":160,"y":420,"wires":[["f2659586.1d1598"],["3df3eee3.e8b4c2"],["bae5e0eb.2d12b"]]},{"id":"f2659586.1d1598","type":"debug","z":"35d94b44.b5fd94","name":"ONE","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":610,"y":400,"wires":[]},{"id":"3df3eee3.e8b4c2","type":"debug","z":"35d94b44.b5fd94","name":"TWO","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":610,"y":460,"wires":[]},{"id":"bae5e0eb.2d12b","type":"debug","z":"35d94b44.b5fd94","name":"THREE","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":600,"y":520,"wires":[]}]

I get a short and simple reply:

image

Should I use a function containing this if(msg.payload.includes('20980000.usb')) ?

It depends what you want to do. You could do it in a Function node or a Switch node.

1 Like

You probably don't need udev rules. For usb-serial adapters (and in recent enough linux kernels), you can address them by their hardware path on /dev/serial/by-path/** instead of /dev/ttyUSB**. This is what my computer shows with two identical serial adapters:

image

The link's name is directly tied to the USB port you've connected the adapter to. Note that there's no way then to detect if you swap the adapter between two ports. That said, there's the /dev/serial/by-id/** path, but cheaper adapters usually don't have unique IDs to differentiate them.

Found this out by casually looking around the /dev folder.

P.S.: You can then just use this /dev/serial/by-path/pci-0000:00:14.0-usb-0:2:1.0-port0 (adapt the path to yours) in the serial node instead of the traditional /dev/ttyUSB0 and it should work normally

2 Likes

There's also the directory /dev/serial/by-id/ that might have symlinks with the serial number in it. It is generated automatically by /lib/udev/rules.d/60-serial.rules in Raspbian Buster.

Here the output of ls -Al /dev/serial/by-id looks like that ("Oibadrischl" is the serial number here):

insgesamt 0
lrwxrwxrwx 1 root root 13 Feb 23 13:06 usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_Oibadrischl-if00-port0 -> ../../ttyUSB0

node-red-contrib-readdir can list the directory, but alas I couldn't find a node that can read the target of the symlink.

Maybe you could use an exec node with ls -Al /dev/serial/by-id/ as the command, split the lines and search for the possible serial numbers, then use the part after the last / to get the device name.

1 Like