WebThingsIO / gateway

WebThings Gateway - a self-hosted web application for monitoring and controlling a building over the web
http://webthings.io/gateway
Mozilla Public License 2.0
2.62k stars 339 forks source link

[Snap] Give add-ons access to serial ports #3152

Open benfrancis opened 3 months ago

benfrancis commented 3 months ago

May require the serial-port/raw-usb interface.

Currently the Zigbee add-on does not work...

STR:

Expected:

Actual:

Logs from /var/snap/webthings-gateway/current.webthings/log/run-app.log:

2024-08-20 19:06:03.296 INFO   : zigbee-adapter: Loading add-on zigbee-adapter from /root/snap/webthings-gateway/x1/.webthings/addons/zigbee-adapter
2024-08-20 19:06:03.879 INFO   : zigbee-adapter: DEBUG config = ''
2024-08-20 19:06:03.886 INFO   : zigbee-adapter: Probing serial ports
2024-08-20 19:06:04.081 INFO   : zigbee-adapter: Serial ports that were found:
2024-08-20 19:06:04.134 ERROR  : zigbee-adapter: Failed to start add-on zigbee-adapter: No Zigbee dongle found
benfrancis commented 3 months ago

The same will likely be true for the Z-Wave add-on too, since that also uses a serial connection.

In order to access serial ports, a snap needs access to the serial-port interface. We can request this interface in snapcraft.yaml, but it is usually not connected by default so would require a user to manually connect the interface on the command line. We can request an exception in the snap store but it may not be granted.

As I understand it on Ubuntu Core it also requires serial device paths to be hard coded in a gadget snap, unless using the experimental hotplug support, which is still marked as experimental and therefore can not be enabled by default. This may be a problem because the gateway supports multiple USB dongles.

As I understand it the existing Raspbian image supports hotplug USB devices.

ogra1 commented 4 weeks ago

as long as the zigbee devices are USB dongles (vs. actual sub-d attached serial devices) it should be possible to simply turn on hotplug support of the UbuntuCore image via a gadget.yaml setting (or simply tell the user to turn it on manually when used out of a pre-made image) ... could you try turning on hotplug on your test device and see if the dongle can be found or if we need to dig deeper here ... (perhaps hardware-observe or system-observe interfaces might be needed alongside and probably udevadm as a bundled binary, we'd need more logs here but i think this could be a viable way forward.)

benfrancis commented 3 weeks ago

@ogra1 Thank you for the advice.

I enabled hotplug with a Digi XStick (Zigbee dongle) and Aeotec Z-Stick (Z-Wave dongle) plugged in and saw the following:

$ snap connections system
...
serial-port              -                                      :aeotecz-stickgen5zw0     -
serial-port              -                                      :xstick                   -

So that's a good start.

Oddly, when I disconnected the Aeotec Z-Wave dongle and plugged a Z-Wave dongle from Sigma Designs in its place, it was detected as aeotecz-stickgen5zw0 - so that's not ideal...

But the obvious question is if a serial-port plug needs to be connected to a slot or slots which may be dynamically added and removed at runtime and whose name may not be known in advance, how is that interface connected? The connections can't just be statically defined in a snapcraft.yaml, or even a gadget snap. The nature of the gateway's extensible add-ons system also means we may not even know in advance the vendor IDs of all devices that may need to be connected in the future. For our non-technical users it's also not acceptable to require a user to run commands on the command line, all user interaction needs to be through the gateway's web interface.

Looking at the source code of the Zigbee adapter add-on as a starting point, it appears to use the serialport npm package (and home-grown serial-prober package which builds on serialport to probe a serial port for certain vendor and product IDs). I have no idea what magic serialport uses on the back end, but it seems to support a lot of different architectures.

Presumably to get USB dongles to connect dynamically at runtime on Ubuntu Core we would need some additional logic which automatically connects the serial-port plug to sockets as they appear. Is that even possible?

FYI I'm already adding a system-observe plug in #3168. What were you thinking the hardware-observe interface and udevadm binary might be used for?