Node-RED integration: Give Docker container access to USB ports

Edit 20/02/2025 : Here is a PR that exposes the USB ports to the Node-RED Docker container. I moved this discussion to another thread for clarity.

I had to modify the unit tests, so I think that indeed your PR wasn’t changing the running container :smiley:

I started a build, which should complete in 50 minutes:

gladysassistant/gladys:node-red-usb-ports

Hello @pierre-gilles
I modified the command, check if it’s okay so I can test it in the morning.

docker run -d \
--log-driver json-file \
--log-opt max-size=10m \
--cgroupns=host \
--restart=always \
--privileged \
--network=host \
--name gladys \
-e NODE_ENV=production \
-e SERVER_PORT=80 \
-e TZ=Europe/Paris \
-e SQLITE_FILE_PATH=/var/lib/gladysassistant/gladys-production.db \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /var/lib/gladysassistant:/var/lib/gladysassistant \
-v /dev:/dev \
-v /run/udev:/run/udev:ro \
gladysassistant/gladys:node-red-usb-ports

That seems good to me :slight_smile:

I was able to test, but it still doesn’t work:
with dmesg -s 1024 I checked the port

Dmesg -s 1024 
62] usbcore: registered new interface driver usbserial_generic
[   12.602675] usbserial: USB Serial support registered for generic
[   12.614134] usbcore: registered new interface driver ch341
[   12.614354] usbserial: USB Serial support registered for ch341-uart
[   12.614551] ch341 1-1.3:1.0: ch341-uart converter detected
[   12.618019] usb 1-1.3: ch341-uart converter now attached to ttyUSB0

In Node-RED, I select the suggested port :

Configuration in Node-RED :

When deploying :

Node-RED logs

pi@raspberrypi:~ $ docker logs  nodered/node-red:3.1
27 Jan 10:40:44 - [info]

Welcome to Node-RED
===================

27 Jan 10:40:45 - [info] Node-RED version: v3.1.15
27 Jan 10:40:45 - [info] Node.js  version: v16.20.2
27 Jan 10:40:45 - [info] Linux 5.10.103-v8+ arm64 LE
27 Jan 10:40:50 - [info] Loading palette nodes
27 Jan 10:40:58 - [info] Settings file  : /data/settings.js
27 Jan 10:40:58 - [info] Context store  : 'default' [module=memory]
27 Jan 10:40:58 - [info] User directory : /data
27 Jan 10:40:58 - [warn] Projects disabled : editorTheme.projects.enabled=false
27 Jan 10:40:58 - [info] Flows file     : /data/flows.json
27 Jan 10:40:58 - [info] Creating new flow file
27 Jan 10:40:58 - [warn]

---------------------------------------------------------------------
Your flow credentials file is encrypted using a system-generated key.

If the system-generated key is lost for any reason, your credentials
file will not be recoverable, you will have to delete it and re-enter
your credentials.

You should set your own key using the 'credentialSecret' option in
your settings file. Node-RED will then re-encrypt your credentials
file using your chosen key the next time you deploy a change.
---------------------------------------------------------------------

27 Jan 10:40:58 - [info] Server now running at http://127.0.0.1:1880/
27 Jan 10:40:58 - [warn] Encrypted credentials not found
27 Jan 10:40:58 - [info] Starting flows
27 Jan 10:40:58 - [info] Started flows
27 Jan 10:41:42 - [info] Installing module: node-red-node-serialport, version: 2.0.3
27 Jan 10:42:21 - [info] Installed module: node-red-node-serialport
27 Jan 10:42:23 - [info] Added node types:
27 Jan 10:42:23 - [info]  - node-red-node-serialport:serial in
27 Jan 10:42:23 - [info]  - node-red-node-serialport:serial out
27 Jan 10:42:23 - [info]  - node-red-node-serialport:serial request
27 Jan 10:42:23 - [info]  - node-red-node-serialport:serial-port
27 Jan 10:42:23 - [info]  - node-red-node-serialport:serial control
27 Jan 10:46:16 - [info] Stopping flows
27 Jan 10:46:16 - [info] Stopped flows
27 Jan 10:46:16 - [info] Updated flows
27 Jan 10:46:16 - [info] Starting flows
27 Jan 10:46:16 - [info] Started flows
27 Jan 10:46:16 - [error] [serialconfig:b63b9d343f0c14e6] serial port /dev/ttyUSB0 error: Error: Error: Permission denied, cannot open /dev/ttyUSB0
27 Jan 10:46:44 - [info] Stopping flows
27 Jan 10:46:44 - [info] serial port /dev/ttyUSB0 closed
27 Jan 10:46:44 - [info] Stopped flows
27 Jan 10:46:44 - [info] Updated flows
27 Jan 10:46:44 - [info] Starting flows
27 Jan 10:46:44 - [info] Started flows
27 Jan 10:46:44 - [error] [serialconfig:b63b9d343f0c14e6] serial port /dev/ttyAMA0 error: Error: Error: Permission denied, cannot open /dev/ttyAMA0
27 Jan 10:48:20 - [info] Stopping flows
27 Jan 10:48:20 - [info] serial port /dev/ttyAMA0 closed
27 Jan 10:48:20 - [info] Stopped flows
27 Jan 10:48:20 - [info] Updated flows
27 Jan 10:48:20 - [info] Starting flows
27 Jan 10:48:21 - [info] Started flows
27 Jan 10:48:21 - [error] [serialconfig:b63b9d343f0c14e6] serial port /dev/ttyUSB0 error: Error: Error: Permission denied, cannot open /dev/ttyUSB0
27 Jan 10:48:29 - [info] Stopping flows
27 Jan 10:48:29 - [info] serial port /dev/ttyUSB0 closed
27 Jan 10:48:29 - [info] Stopped flows
27 Jan 10:48:29 - [info] Updated flows
27 Jan 10:48:29 - [info] Starting flows
27 Jan 10:48:29 - [info] Started flows
27 Jan 10:48:29 - [error] [serialconfig:b63b9d343f0c14e6] serial port /dev/ttyUSB0 error: Error: Error: Permission denied, cannot open /dev/ttyUSB0

port on the Raspberry

pi@raspberrypi:~ $ lsusb
Bus 001 Device 004: ID 1a86:7523 QinHeng Electronics CH340 serial converter
Bus 001 Device 003: ID 0424:ec00 Microchip Technology, Inc. (formerly SMSC) SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Microchip Technology, Inc. (formerly SMSC) SMC9514 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Let me know if you need more information.
Thanks.

Yes, I’d need you to run a:

docker inspect ID_DU_CONTAINER_NODE_RED

And post here what you see :slight_smile:

here you go


pi@raspberrypi:~ $ docker inspect ID_DU_CONTAINER_NODE_RED
[]
Error: No such object: ID_DU_CONTAINER_NODE_RED

ID_DU_CONTAINER_NODE_RED should be replaced with the ID of the Node-RED container :joy:

oups :roll_eyes:

en effet ça fait pas pareil :smile:

pi@raspberrypi:~ $ docker inspect 4bdf10801a20
[
    {
        "Id": "4bdf10801a2056713b1ea04d49e89a1f9b126ca041d89f6a56f2973c14354fd0",
        "Created": "2025-01-27T10:40:00.988429022Z",
        "Path": "./entrypoint.sh",
        "Args": [],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 2552,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2025-01-27T10:40:15.299175192Z",
            "FinishedAt": "0001-01-01T00:00:00Z",
            "Health": {
                "Status": "healthy",
                "FailingStreak": 0,
                "Log": [
                    {
                        "Start": "2025-01-27T14:32:45.468270734+01:00",
                        "End": "2025-01-27T14:32:46.089802444+01:00",
                        "ExitCode": 0,
                        "Output": ""
                    },
                    {
                        "Start": "2025-01-27T14:33:16.145544727+01:00",
                        "End": "2025-01-27T14:33:16.759836444+01:00",
                        "ExitCode": 0,
                        "Output": ""
                    },
                    {
                        "Start": "2025-01-27T14:33:46.827170575+01:00",
                        "End": "2025-01-27T14:33:47.459022894+01:00",
                        "ExitCode": 0,
                        "Output": ""
                    },
                    {
                        "Start": "2025-01-27T14:34:17.525029165+01:00",
                        "End": "2025-01-27T14:34:18.195952915+01:00",
                        "ExitCode": 0,
                        "Output": ""
                    },
                    {
                        "Start": "2025-01-27T14:34:48.342865391+01:00",
                        "End": "2025-01-27T14:34:49.004312549+01:00",
                        "ExitCode": 0,
                        "Output": ""
                    }
                ]
            }
        },
        "Image": "sha256:bf1dac2b1cbc77b96f0ef704281763f5cba01b59f36d3d16d231bab333dc4115",
        "ResolvConfPath": "/var/lib/docker/containers/4bdf10801a2056713b1ea04d49e89a1f9b126ca041d89f6a56f2973c14354fd0/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/4bdf10801a2056713b1ea04d49e89a1f9b126ca041d89f6a56f2973c14354fd0/hostname",
        "HostsPath": "/var/lib/docker/containers/4bdf10801a2056713b1ea04d49e89a1f9b126ca041d89f6a56f2973c14354fd0/hosts",
        "LogPath": "/var/lib/docker/containers/4bdf10801a2056713b1ea04d49e89a1f9b126ca041d89f6a56f2973c14354fd0/4bdf10801a2056713b1ea04d49e89a1f9b126ca041d89f6a56f2973c14354fd0-json.log",
        "Name": "/gladys-node-red",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": [
                "/var/lib/gladysassistant/node-red:/data",
                "/dev:/dev",
                "/run/udev:/run/udev:ro"
            ],
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {
                    "max-size": "10m"
                }
            },
            "NetworkMode": "default",
            "PortBindings": {
                "1880/tcp": [
                    {
                        "HostIp": "",
                        "HostPort": "1881"
                    }
                ]
            },
            "RestartPolicy": {
                "Name": "always",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "CgroupnsMode": "private",
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": true,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": [
                "label=disable"
            ],
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": null,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": null,
            "ReadonlyPaths": null
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/3bfbd36779fb2625e76ec7d8560e8d205ed75d33118a75db09e537794c454764-init/diff:/var/lib/docker/overlay2/5254fb1e94ecaad1ae06c3606a90da705ac47123e78697c7de02bdb355e24002/diff:/var/lib/docker/overlay2/2c0cf5446301fbfe977761e109d05d81c33aa068586cbf5bf8315da7521704ab/diff:/var/lib/docker/overlay2/b24091075e548c2bcbcd616e54ca72a5ff53b07bfd71061e05fef41f5fb6adee/diff:/var/lib/docker/overlay2/b8a6030c37237b02360c54260c2ad3ba7612b8da59d4d3eb97b9d2a8fac76c55/diff:/var/lib/docker/overlay2/afa66f72df5d76bbf043888f550d0368566273eec1a304edc679c38f7d4374f8/diff:/var/lib/docker/overlay2/ea57f7aff9e03e0ef6cf001967006f24e985f7f6d1ab249adda78c1e0a85e29c/diff:/var/lib/docker/overlay2/6583b1111613b61869c058a59fdc7ccf4f22e1cdd4e22ef3fefede0f530e7255/diff:/var/lib/docker/overlay2/b1e013593560d227c5f884021547e357bf131d66e9111d4aa055e5d0d4c91bee/diff:/var/lib/docker/overlay2/b57961199d2e32910e0c767f0f589cafab8ffe6c6124d91ad38154a893d59b34/diff:/var/lib/docker/overlay2/f318dcc1db476e645b3a58c11a01ecac48a8394560f714022ea13501dc06beb8/diff:/var/lib/docker/overlay2/9c5b0d92ed004650418f5a382adc499618b92140c3fac173fe0f24f3e480d469/diff:/var/lib/docker/overlay2/8104bd617585d550646386d8a342623040b89a155a6b89670fe1b096ffe47a9a/diff:/var/lib/docker/overlay2/71bbe4ab385219cd219eb357231e2ab340a4da222439327422f5ffe1ee66b7be/diff:/var/lib/docker/overlay2/c920da126c3090214760c81faeeb27c4ccb642e3efa51327d72dce89a801f35f/diff:/var/lib/docker/overlay2/3a0e8c6e90e5eea537307617a6586ec54e6689b817e22e32778cf74bb5236908/diff:/var/lib/docker/overlay2/c11fc90afb6e3e224589162178b7da33669ddf6510620671eec08fb0b8ac1732/diff:/var/lib/docker/overlay2/b61fc569233d18d75d56592e335fac15c022dffe9622e64fabe355a9012ba6f8/diff",
                "MergedDir": "/var/lib/docker/overlay2/3bfbd36779fb2625e76ec7d8560e8d205ed75d33118a75db09e537794c454764/merged",
                "UpperDir": "/var/lib/docker/overlay2/3bfbd36779fb2625e76ec7d8560e8d205ed75d33118a75db09e537794c454764/diff",
                "WorkDir": "/var/lib/docker/overlay2/3bfbd36779fb2625e76ec7d8560e8d205ed75d33118a75db09e537794c454764/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/var/lib/gladysassistant/node-red",
                "Destination": "/data",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Type": "bind",
                "Source": "/dev",
                "Destination": "/dev",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Type": "bind",
                "Source": "/run/udev",
                "Destination": "/run/udev",
                "Mode": "ro",
                "RW": false,
                "Propagation": "rprivate"
            }
        ],
        "Config": {
            "Hostname": "4bdf10801a20",
            "Domainname": "",
            "User": "node-red",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "1880/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/src/node-red/node_modules/.bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "NODE_VERSION=16.20.2",
                "YARN_VERSION=1.22.19",
                "NODE_RED_VERSION=v3.1.15",
                "NODE_PATH=/usr/src/node-red/node_modules:/data/node_modules",
                "FLOWS=flows.json"
            ],
            "Cmd": null,
            "Healthcheck": {
                "Test": [
                    "CMD-SHELL",
                    "node /healthcheck.js"
                ]
            },
            "Image": "nodered/node-red:3.1",
            "Volumes": null,
            "WorkingDir": "/usr/src/node-red",
            "Entrypoint": [
                "./entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {
                "authors": "Dave Conway-Jones, Nick O'Leary, James Thomas, Raymond Mouthaan",
                "org.label-schema.arch": "",
                "org.label-schema.build-date": "2024-12-17T09:46:41Z",
                "org.label-schema.description": "Low-code programming for event-driven applications.",
                "org.label-schema.docker.dockerfile": ".docker/Dockerfile.alpine",
                "org.label-schema.license": "Apache-2.0",
                "org.label-schema.name": "Node-RED",
                "org.label-schema.url": "https://nodered.org",
                "org.label-schema.vcs-ref": "",
                "org.label-schema.vcs-type": "Git",
                "org.label-schema.vcs-url": "https://github.com/node-red/node-red-docker",
                "org.label-schema.version": "3.1.15"
            }
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "24902baafb6717ff0342ee17e2c8ed2e809947ff30e9704acf3128dd5c5f3451",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "1880/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "1881"
                    },
                    {
                        "HostIp": "::",
                        "HostPort": "1881"
                    }
                ]
            },
            "SandboxKey": "/var/run/docker/netns/24902baafb67",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "cddbcedf3cd1d16eff4da4c215d9144946d26ae367673e542ef8179affd7418e",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.4",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:04",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "1d3b4c16fadcdd1917b86c97e0381ee4f056693bead5556046e45a6f43a01978",
                    "EndpointID": "cddbcedf3cd1d16eff4da4c215d9144946d26ae367673e542ef8179affd7418e",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.4",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:04",
                    "DriverOpts": null
                }
            }
        }
    }
]

Ok, that seems good to me then, my PR did what I had planned.

But I still have no idea why it’s

Good evening @pierre-gilles
I’m willing to test things, but getting involved with Docker is going to be complicated,

Gladys launches Node-RED with a simple docker run :slight_smile: So if you manage to get a Node-RED running, pass me your docker run and I’ll integrate it!

No worries, nothing urgent on my side!

I use what’s in the tutorial, but there may be things to adjust, notably the update by watchtower:

Installation de node red

1 - tapez la commande de @VonOx, il faudra avoir un systeme branché sur les ports USB0 et USB1, pour ma part j’ai un RFlink sur le port ttyUSB0 et la cle zigbbe Sonoff sur le port ttyUSB1. Donc il faudra peut etre adapter dans les lignes " --device=/dev/ttyUSB0 \ " le nom du port utilisé peut etre ttyACM0.

docker run -d \
--log-opt max-size=10m \
--restart=always \
--network=host \
--name node_red \
-u node-red:dialout \
--device=/dev/ttyUSB0 \
--device=/dev/ttyUSB1 \
--label com.centurylinklabs.watchtower.enable=false \
-v /var/lib/node-red:/data \
nodered/node-red

Attention , il faudra adapter la ligne :

--device=/dev/ttyUSB0 \
En fonction du port Usb où est branché le RFlink, certaines fois le Rflnk peut etre branché sur le port usb : /dev/ttyAMA0.
Dans mon cas le /devttyUSB0 correspond à ma clé zigbbe et le /dev/ttyUSB1 correspond a mon Rflink

Attention avec cette ligne de commande :

--label com.centurylinklabs.watchtower.enable=false \
Watchtower ne remet plus Node red à jour et quand on relance le PI , node red ne se lance plus tout seul comme Gladys. Il faudra relancer le container node red avec « docker restart node_red »

2 - puis celle-ci

sudo chown -R 1000:1000 /var/lib/node-red

I copy this command
docker run (and the rest…)

and above all
the command 2:

sudo chown -R 1000:1000 /var/lib/node-red

otherwise nothing works.

However « Node _red externe » is at version 4, and seems to have resolved the problems with the palette version of « node-red-node-serialport » (previously it was necessary to downgrade the version for it to work)

I just reread, but Node_Red version 3.1.15 also accepts the latest version of « node-red-node-serialport ».

One small bonus question about my mini PC
This Docker config wouldn’t prevent the

Actually, we can’t do that, because the USB port here is fixed.

Here, we want Node-RED to have access to all USB ports, hence mounting /dev:/dev as a volume and using the container’s --privileged mode.

Good evening @pierre-gilles and everyone
I’m back on Node-RED and RFLink, I run this command :ls /dev/tty*

pi@rasp3b:// $ ls /dev/tty*
/dev/tty    /dev/tty14  /dev/tty20  /dev/tty27  /dev/tty33  /dev/tty4   /dev/tty46  /dev/tty52  /dev/tty59  /dev/tty8
/dev/tty0   /dev/tty15  /dev/tty21  /dev/tty28  /dev/tty34  /dev/tty40  /dev/tty47  /dev/tty53  /dev/tty6   /dev/tty9
/dev/tty1   /dev/tty16  /dev/tty22  /dev/tty29  /dev/tty35  /dev/tty41  /dev/tty48  /dev/tty54  /dev/tty60  /dev/ttyAMA0
/dev/tty10  /dev/tty17  /dev/tty23  /dev/tty3   /dev/tty36  /dev/tty42  /dev/tty49  /dev/tty55  /dev/tty61  /dev/ttyprintk
/dev/tty11  /dev/tty18  /dev/tty24  /dev/tty30  /dev/tty37  /dev/tty43  /dev/tty5   /dev/tty56  /dev/tty62  /dev/ttyUSB0
/dev/tty12  /dev/tty19  /dev/tty25  /dev/tty31  /dev/tty38  /dev/tty44  /dev/tty50  /dev/tty57  /dev/tty63  /dev/tty-usb-arduino-nano
/dev/tty13  /dev/tty2   /dev/tty26  /dev/tty32  /dev/tty39  /dev/tty45  /dev/tty51  /dev/tty58  /dev/tty7

For the last USB ports, I see the port /dev/tty/USB0 and then there is this port /dev/tty-usb-arduino-nano.
They are the same ports because when I unplug the RFLink both ports disappear.
However on the miniPC, I do see the port /devttyUSB1 (when I plug in the RFLink) but not the renaming to « /dev/tty-usb-arduino-nano », knowing that on the miniPC, I’m on external Node-RED.
Is this normal? Is the USB port renamed in the internal Node-RED and is that why we don’t see it?
Thanks for your help

You must have created a udev rule that is valid on the host but not available in the container!

Hello @pierre-gilles
I didn’t create anything, if there are udev rules, they come from the installation of Node-RED by Gladys :thinking:

udev rules don’t appear by magic :stuck_out_tongue:

Hello @pierre-gilles
I didn’t create any udev rule, however /dev/tty-usb-arduino-nano is a symbolic link that is created, I think when the RFLink is plugged in. I saw a table that creates the mappings when an Arduino Uno or an Arduino Mega is plugged in,
rasp3b:/etc/udev/rules.d $ sudo nano 99-gladys-tty.rules

So according to my research, I found that this symbolic link (as Gemini said) has permissions like this :

pi@rasp3b:~ $  ls -l /dev/tty-usb-arduino-nano
lrwxrwxrwx 1 root root 7 Feb 19 10:02 /dev/tty-usb-arduino-nano -> ttyUSB0

and the Usb0 port to which /dev/tty-usb-arduino-nano is linked has the following permissions :

pi@rasp3b:~ $ ls -l /dev/ttyUSB0
crw-rw---- 1 root dialout 188, 0 Feb 19 10:02 /dev/ttyUSB0

So I did a sudo chmod a+rw /dev/ttyUSB0, to give permissions to « OTHERS »:

pi@rasp3b:~ $ ls -l /dev/ttyUSB0
crw-rw-rw- 1 root dialout 188, 0 Feb 19 11:50 /dev/ttyUSB0

and now my « node serial » connects:

  • I don’t know what that is worth in terms of security?
  • the problem is that every time the RFLink disconnects the USB0 port permissions reset to

crw-rw---- 1 root dialout 188, 0 Feb 19 10:02 /dev/ttyUSB0`

and so we lose the Node Serial connection.
These permissions should be fixed so that they are initialized correctly when the RFLink is plugged in. And maybe even for other ports, if multiple devices are connected (Xiaomi gateway, or Arduino Uno board, …)

So if you can do that when you have some time, I’d be happy to test the new image
Thanks

@Psoy I’m surprised by what you’re telling me because normally Node-RED is started in « priviledged » mode, with all permissions.

So are you sure you properly started your Gladys, which itself properly started Node-RED?

Here’s the Docker image:

gladysassistant/gladys:node-red-usb-ports