Generic zigbee gateway serial discovery

Hey all,

I am curious, right now, HA detects zigbee gateways via zeroconf if it matches the type and name. This is a fine mechanism, but also ‘Forces’ each manufacturer to come up with a pull-request.

Is it not feasible to introduce a ‘common’ entry here?

I saw some devices are based on esphome with serial-stream, which is pretty cool for a solution, but won’t work exactly like that for example for openwrt, or a linux server (well we can still use _esphome_lib.local of course).

Naming things of course is hard, things that crossed my mind is:

diff --git a/homeassistant/components/zha/manifest.json b/homeassistant/components/zha/manifest.json
index 7087ff0b2f..a31fb37d2b 100644
--- a/homeassistant/components/zha/manifest.json
+++ b/homeassistant/components/zha/manifest.json
@@ -113,6 +113,10 @@
     }
   ],
   "zeroconf": [
+    {
+      "type": "_ser2net_zigbee-gateway._tcp.local.",
+      "name": "*"
+    },
     {
       "type": "_esphomelib._tcp.local.",
       "name": "tube*"

but I’m sure there’s tons of useful names that are generic enough, without tying it to a brand.

In addition maybe, what about storing configurations in attributes? E.g. baudrate, modem type (znp, ezp), flow-control etc. This would make autodiscovery even more ‘automatic’ and nice for the end user.

This would also set the standard for others to follow of course, where vendor type/names would indicate deviations and ‘custom code’.

An example I’m using with ser2net to test things, looks like this. Obviously the settings are not honored, but just comming up with some specs here.

<service-group>

  <name replace-wildcards="yes">%h (not zigate)</name>

  <service>
    <type>_zigate-zigbee-gateway._tcp</type>
    <port>8888</port>
    <txt-record>baudrate=115200</txt-record>
    <txt-record>flow-control=software</txt-record>
    <txt-record>radio=znp</txt-record>
  </service>    
                
</service-group>

wdyt?

I just wrote a openwrt hotplug script that would do this for, well openwrt :stuck_out_tongue:

cat << "EOF" > /etc/hotplug.d/usb/20-cp210x-ser2net
CP210_PRODID='10c4/ea60/100'                                                                                                                                                          
SER2NET_PID='/var/run/ser2net.pid'                                                                                                                                                    
SER2NET_PORT=18888                                                                                                                                                                    
SER2NET_BAUDRATE=115200                                                                                                                                                               
SER2NET_FLOWRATE='software'                                                                                                                                                           
SER2NET_RADIO='znp'                                                                                                                                                                   
SER2NET_OPTS="${SER2NET_BAUDRATE} NONE 1STOPBIT 8DATABITS -RTSCTS -LOCAL NOBREAK"                                                                                                     
 
set -eu                                                                                                                                                                               
 
if [ "${DEVTYPE:-}" = 'usb_interface' ] && \                                                                                                                                          
   [ "${PRODUCT:-}" = "${CP210_PRODID}" ]; then                                                                                                                                       
        if [ "${ACTION:-}" = 'bind' ]; then                                                                                                                                           
                if [ -s "${SER2NET_PID}" ]; then                                                                                                                                      
                        logger -t hotplug "Warning: ser2net already running as pid: $(cat "${SER2NET_PID}") via ${SER2NET_PID}"                                                       
                        exit 0                                                                                                                                                        
                fi                                                                                                                                                                    
 
                DEVICE_NAME="$(find "/sys${DEVPATH:-}" -maxdepth 1 -type d -iname 'ttyUSB*' -exec basename {} \;)"                                                                    
                if [ -z "${DEVICE_NAME}" ]; then                                                                                                                                      
                        logger -t hotplug 'Warning: DEVICE_NAME is empty'                                                                                                             
                        exit 0                                                                                                                                                        
                fi                                                                                                                                                                    
                logger -t hotplug "Device name of cp210 is '${DEVICE_NAME}'"                                                                                                          
 
                ser2net -C "${SER2NET_PORT}:raw:100:/dev/${DEVICE_NAME}:${SER2NET_OPTS}" -P "${SER2NET_PID}"                                                                          
                if [ -d '/etc/avahi/services' ]; then                                                                                                                                 
                        {                                                                                                                                                             
                                printf '<service-group>\n\n'                                                                                                                          
                                printf '  <name replace-wildcards="yes">%%h</name>\n\n'                                                                                  
                                printf '  <service>\n'                                                                                                                                
                                printf '    <type>_ser2net_zigbee-gateway._tcp</type>\n'                                                                                               
                                printf '    <port>%d</port>\n' "${SER2NET_PORT}"                                                                                                      
                                printf '    <txt-record>baudrate=%d</txt-record>\n' "${SER2NET_BAUDRATE:-115200}"                                                                     
                                printf '    <txt-record>flow-control=%s</txt-record>\n' "${SER2NET_FLOWRATE:-software}"                                                               
                                printf '    <txt-record>radio=%s</txt-record>\n' "${SER2NET_RADIO:-znp}"                                                                              
                                printf '  </service>\n\n'                                                                                                                             
                                printf '</service-group>\n'                                                                                                                           
                        } > '/etc/avahi/services/ser2net.service'                                                                                                                     
                fi                                                                                                                                                                    
 
                logger -t hotplug "Started ser2net on '/dev/${DEVICE_NAME}'"                                                                                                          
        fi                                                                                                                                                                            
 
        if [ "${ACTION:-}" = 'unbind' ]; then                                                                                                                                         
                logger -t hotplug "Attempting to stop ser2net with pid: $(cat "${SER2NET_PID}")"                                                                                      
                kill -3 "$(cat "${SER2NET_PID}")"                                                                                                                                     
                if [ -s '/etc/avahi/services/ser2net.service' ]; then                                                                                                                 
                        rm '/etc/avahi/services/ser2net.service'                                                                                                                      
                fi                                                                                                                                                                    
                if [ ! -s "${SER2NET_PID}" ]; then                                                                                                                                    
                        logger -t hotplug 'Failed'                                                                                                                                    
                        exit 0                                                                                                                                                        
                fi                                                                                                                                                                    
        fi                                                                                                                                                                            
fi     
EOF