Add port detection to enocean daemon
Currently enocean daemon uses hardcoded location of the serial port: /dev/ttyUSB0 This is not very flexible in terms of usb dongle may not be present or present under another name or several dongles added. Below is proposal on how to handle it for usb adapters. For non usb implementations of enocean modems we need another topic. May be even allow passing hardware location of modem as we do in GPIO daemon.
for usb dongles we need to handle detection of currently present devices as well as events of adapters being added/removed. Simplest way I found is to monitor d-bus signals of org.freedesktop.systemd1 interface and run org.freedesktop.systemd1.Manager.ListUnits method to get list of currently present devices.
When run RPi2 I see the following signals for enocean dongle added:
signal sender=:1.1 -> dest=(null destination) serial=995 path=/org/freedesktop/systemd1; interface=org.freedesktop.systemd1.Manager; member=UnitNew
string "sys-devices-platform-bcm2708_usb-usb1-1\x2d1-1\x2d1.4-1\x2d1.4:1.0-ttyUSB0-tty-ttyUSB0.device"
object path "/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dbcm2708_5fusb_2dusb1_2d1_5cx2d1_2d1_5cx2d1_2e4_2d1_5cx2d1_2e4_3a1_2e0_2dttyUSB0_2dtty_2dttyUSB0_2edevice"
signal sender=:1.1 -> dest=(null destination) serial=996 path=/org/freedesktop/systemd1; interface=org.freedesktop.systemd1.Manager; member=UnitNew
string "dev-ttyUSB0.device"
object path "/org/freedesktop/systemd1/unit/dev_2dttyUSB0_2edevice"
signal sender=:1.1 -> dest=(null destination) serial=997 path=/org/freedesktop/systemd1; interface=org.freedesktop.systemd1.Manager; member=UnitNew
string "dev-serial-by\x2did-usb\x2dEnOcean_GmbH_EnOcean_USB_300U_DA_FTWYT438\x2dif00\x2dport0.device"
object path "/org/freedesktop/systemd1/unit/dev_2dserial_2dby_5cx2did_2dusb_5cx2dEnOcean_5fGmbH_5fEnOcean_5fUSB_5f300U_5fDA_5fFTWYT438_5cx2dif00_5cx2dport0_2edevice"
signal sender=:1.1 -> dest=(null destination) serial=998 path=/org/freedesktop/systemd1; interface=org.freedesktop.systemd1.Manager; member=UnitNew
string "dev-serial-by\x2dpath-platform\x2dbcm2708_usb\x2dusb\x2d0:1.4:1.0\x2dport0.device"
object path "/org/freedesktop/systemd1/unit/dev_2dserial_2dby_5cx2dpath_2dplatform_5cx2dbcm2708_5fusb_5cx2dusb_5cx2d0_3a1_2e4_3a1_2e0_5cx2dport0_2edevice"
and removed:
signal sender=:1.1 -> dest=(null destination) serial=991 path=/org/freedesktop/systemd1; interface=org.freedesktop.systemd1.Manager; member=UnitRemoved
string "dev-serial-by\x2dpath-platform\x2dbcm2708_usb\x2dusb\x2d0:1.4:1.0\x2dport0.device"
object path "/org/freedesktop/systemd1/unit/dev_2dserial_2dby_5cx2dpath_2dplatform_5cx2dbcm2708_5fusb_5cx2dusb_5cx2d0_3a1_2e4_3a1_2e0_5cx2dport0_2edevice"
signal sender=:1.1 -> dest=(null destination) serial=992 path=/org/freedesktop/systemd1; interface=org.freedesktop.systemd1.Manager; member=UnitRemoved
string "dev-serial-by\x2did-usb\x2dEnOcean_GmbH_EnOcean_USB_300U_DA_FTWYT438\x2dif00\x2dport0.device"
object path "/org/freedesktop/systemd1/unit/dev_2dserial_2dby_5cx2did_2dusb_5cx2dEnOcean_5fGmbH_5fEnOcean_5fUSB_5f300U_5fDA_5fFTWYT438_5cx2dif00_5cx2dport0_2edevice"
signal sender=:1.1 -> dest=(null destination) serial=993 path=/org/freedesktop/systemd1; interface=org.freedesktop.systemd1.Manager; member=UnitRemoved
string "dev-ttyUSB0.device"
object path "/org/freedesktop/systemd1/unit/dev_2dttyUSB0_2edevice"
signal sender=:1.1 -> dest=(null destination) serial=994 path=/org/freedesktop/systemd1; interface=org.freedesktop.systemd1.Manager; member=UnitRemoved
string "sys-devices-platform-bcm2708_usb-usb1-1\x2d1-1\x2d1.4-1\x2d1.4:1.0-ttyUSB0-tty-ttyUSB0.device"
object path "/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dbcm2708_5fusb_2dusb1_2d1_5cx2d1_2d1_5cx2d1_2e4_2d1_5cx2d1_2e4_3a1_2e0_2dttyUSB0_2dtty_2dttyUSB0_2edevice"
Among all the listed units we can clearly detect one having EnOcean word in the path.
interface=org.freedesktop.systemd1.Manager; member=UnitNew
string "dev-serial-by\x2did-usb\x2dEnOcean_GmbH_EnOcean_USB_300U_DA_FTWYT438\x2dif00\x2dport0.device"
object path "/org/freedesktop/systemd1/unit/dev_2dserial_2dby_5cx2did_2dusb_5cx2dEnOcean_5fGmbH_5fEnOcean_5fUSB_5f300U_5fDA_5fFTWYT438_5cx2dif00_5cx2dport0_2edevice"
For that object we can run the following d-bus query:
(RaspberryPi2)ubuntu@localhost:~$ dbus-send --system --type=method_call --print-reply \
--dest=org.freedesktop.systemd1 \
/org/freedesktop/systemd1/unit/dev_2dserial_2dby_5cx2did_2dusb_5cx2dEnOcean_5fGmbH_5fEnOcean_5fUSB_5f300U_5fDA_5fFTWYT438_5cx2dif00_5cx2dport0_2edevice \
org.freedesktop.DBus.Properties.Get \
string:org.freedesktop.systemd1.Device \
string:SysFSPath
and get the mount point of the device:
method return sender=:1.1 -> dest=:1.42 reply_serial=2
variant string "/sys/devices/platform/bcm2708_usb/usb1/1-1/1-1.4/1-1.4:1.0/ttyUSB0/tty/ttyUSB0"
The d-bus manager handling usb device events is different on other linux and even ubuntu variants so making universal enocean daemon should consider that fact. For example on desktop ubuntu:
signal sender=:1.0 -> dest=(null destination) serial=6826 path=/com/ubuntu/Upstart; interface=com.ubuntu.Upstart0_6; member=EventEmitted
string "usb-device-removed"
array [
string "KERNEL=2-2.1"
string "DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:00.0/usb2/2-2/2-2.1"
string "DEVNAME=/dev/bus/usb/002/004"
string "SUBSYSTEM=usb"
string "ACTION=remove"
string "BUSNUM=002"
string "DEVNUM=004"
string "DEVTYPE=usb_device"
string "ID_BUS=usb"
string "ID_MM_DEVICE_IGNORE=1"
string "ID_MM_DEVICE_MANUAL_SCAN_ONLY=1"
string "ID_MODEL=EnOcean_USB_300U_DA"
string "ID_MODEL_ENC=EnOcean\x20USB\x20300U\x20DA"
string "ID_MODEL_FROM_DATABASE=FT232 USB-Serial (UART) IC"
string "ID_MODEL_ID=6001"
string "ID_REVISION=0600"
string "ID_SERIAL=EnOcean_GmbH_EnOcean_USB_300U_DA_FTWYT438"
string "ID_SERIAL_SHORT=FTWYT438"
string "ID_USB_INTERFACES=:ffffff:"
string "ID_VENDOR=EnOcean_GmbH"
string "ID_VENDOR_ENC=EnOcean\x20GmbH"
string "ID_VENDOR_FROM_DATABASE=Future Technology Devices International, Ltd"
string "ID_VENDOR_ID=0403"
string "MAJOR=189"
string "MINOR=131"
string "PRODUCT=403/6001/600"
string "SEQNUM=4404"
string "TYPE=0/0/0"
string "USEC_INITIALIZED=5535583031"
]