Draytek Vigor Presence Detection

Hi All,

Sharing something that I have created to enable presence detection using a Draytek Vigor 2927 router; I expect that this will work for most other DrayOS based routers that have the ability to check the ARP table via the telnet admin interface.

Problem: ‘to my knowledge’ Draytek routers are not a supported platform for HA presence detection with no out of the box integrations.

Solution: Using a second RPI that executes two scripts to check the ARP table of the router to see of certain mac addresses are present; the output then updates MQTT location topics set in HA.

Pre reqs: install the following packages on the RPI - telnet (i know dont judge), expect and mosquitto-clients

Script #1 (check_arp) - Login to the router via telnet and check the arp table

#!/bin/bash
expect <<END
            spawn telnet 192.168.x.x
            expect "Account"
            send "username\r"
            expect "Password:"
            send "password"
            send "\r"
            expect "your_router_name>"
            send "ip arp status \r"
            sleep 0.2
            send " "
            send "exit \r"
            expect eof
END

Script #2 (presence_check) - Grep the output for mac values and set the relevant MQTT status

#!/bin/bash

if /home/pi/path_to_script/check_arp|grep -q  mac_address1;
        then mosquitto_pub -h 192.168.x.x -t location/name1 -m 'home' -u username -P password
        else mosquitto_pub -h 192.168.x.x -t location/name1 -m 'not_home' -u username -P password
fi

if /home/pi/path_to_script/check_arp|grep -q  mac_address2;
        then mosquitto_pub -h 192.168.x.x -t location/name2 -m 'home' -u username -P password
        else mosquitto_pub -h 192.168.x.x -t location/name2 -m 'not_home' -u username -P password
fi

if /home/pi/path_to_script/check_arp|grep -q  mac_address3;
        then mosquitto_pub -h 192.168.x.x -t location/name3 -m 'home' -u username -P password
        else mosquitto_pub -h 192.168.x.x -t location/name3 -m 'not_home' --u username -P password
fi

if /home/pi/path_to_script/check_arp|grep -q  mac_address4;
        then mosquitto_pub -h 192.168.x.x -t location/name4 -m 'home' -u username -P password
        else mosquitto_pub -h 192.168.x.x -t location/name4 -m 'not_home' -u username -P password
fi

Save the above two scripts onto your RPI box (not home assistant) , modify the path_to_script so it matches your script locations and set the scripts to execute (sudo chmod +x filename).

Update the mac_addresses, username, passwords to match your environment - and lastly setup your crontab to run the presence_check script as often as you like.

I am sure that this could be done easier and likley direct on the HA RPI, but given my limited knowledge/ time this is the best I could figure out - hope it helps someone

Improvements welcomed!!!

I can see how it works for detection of new connection (device joining network), as new entry is added to ARP table. But what about leaving network? I think Draytek routers are caching ARP table, so disconnection won’t be quickly/reliably discovered… or am I wrong?

Actually Works really well.

On the router it takes about a minute for the arp table to clear disconnected devices unless you have set it to cache for a longer period for some reason.

I think I know where the problem is… I have 90% of my devices configured with IP reservations on router (Bind IP to MAC). These are always showing in ARP table. Then the difference is in the last 2 columns of the ‘ip arp status \r’ command - VLAN status and Port: it is showing dash for offline devices and VLAN assignment and connection port for devices that are active… but only refreshes after router restart or clearing of the cache manually. I have cache life set to 10 seconds and despite this once static IP device comes to on-line status it is never cleared… or I did not wait long enough (~10 minutes).

I have a Draytek Router but have always used the NMAP Integration for tracking devices that do not support the Companion App, another option is a Ping Sensor.

Could someone enlighten me as to why you would want to use this instead of NMAP?

Mirek - the grep statement in my script is really basic if you know what the exact output is in the arp table, you suggested a dash?, when the device is on/ offline then you could modify and expand the query to match the exact line?

Jonah, I used to use nmap and ping sensors myself but when you have apple phones, the WiFi sleeps after a small period of time to save battery and does not respond to ping or other layer 3 probes this results in the sensors reporting you being away when your not if your tracking people via there apple device. That said they work really well for other devices that have an active always on network connection, just not apple.

Fred, what I observe is in following sample of router output:

HOME-ROUTER> ip arp status
[ARP Table]
 Index IP Address     MAC Address         HOST ID                 Interface  VLAN   Port
   1   192.168.52.100 70-EE-50-01-B3-6A                            LAN1       VLAN0   P1
   2   192.168.52.101 00-04-20-E7-F2-E8                            LAN1       VLAN0   P1
   3   192.168.52.102 C8-DB-26-09-D3-CF                            LAN1       VLAN0   P1
   4   192.168.52.103 44-07-0B-51-21-6E                            LAN1       VLAN0   P1
   5   192.168.52.104 B8-27-EB-5B-F6-BA                            LAN1        ---    --
   6   192.168.52.105 50-14-79-1A-AC-5E                            LAN1       VLAN0   P1
   7   192.168.52.106 30-AE-A4-E2-0A-94                            LAN1        ---    --
   8   192.168.52.107 10-5B-AD-5C-CE-7B                            LAN1        ---    --
   9   192.168.52.108 F8-0D-AC-8C-E1-2A                            LAN1       VLAN0   P1
  10   192.168.52.110 68-DB-CA-0B-89-6A                            LAN1       VLAN0   P1
  11   192.168.52.111 88-E9-FE-C1-C1-69                            LAN1        ---    --
  12   192.168.52.112 90-68-C3-DB-45-C8                            LAN1        ---    --
  13   192.168.52.113 44-90-BB-58-14-65                            LAN1       VLAN0   P1
  14   192.168.52.114 40-C7-11-14-AE-2B                            LAN1       VLAN0   P1
  15   192.168.52.115 FC-A1-83-21-BC-16                            LAN1       VLAN0   P1
  16   192.168.52.116 50-DC-E7-55-7A-8A                            LAN1       VLAN0   P1
  17   192.168.52.117 68-FE-F7-44-12-F3                            LAN1        ---    --
  18   192.168.52.118 B8-41-A4-0C-4C-AD                            LAN1       VLAN0   P1
  19   192.168.52.119 00-26-82-51-5D-7F                            LAN1        ---    --
  20   192.168.52.120 18-AF-61-B8-CC-6C                            LAN1        ---    --

All the devices in this log are configured with static IP on myrouter (not real static IP configured on the device, but IP address reservation in router DHCP server). I’m not grep specialist, but I think in your script you are looking for occurence of MAC address. This will work for dynnamic IPs that will be cleared from the output as soon as cache is cleared. But preconfigured IPs are already known to router and it is showing them even if off-line. The distinction for these is dat ain last 2 columns (VLAN and PORT), that shows data if devices are online or dashes if offline. So if grep can somehow capture combination of these two (MAC address presence and status of last columns) this would really give reliable presence detection! Possible conditions are for single line would be:

  • MAC and “VLAN”
  • MAC and NOT “–” (double dash)

This would give reliable detection, I think :slight_smile:

You could try this…

if /home/pi/path_to_script/check_arp|grep -q  '70-EE-50-01-B3-6A                            LAN1       VLAN0   P1';
        then mosquitto_pub -h 192.168.x.x -t location/name3 -m 'home' -u username -P password
        else mosquitto_pub -h 192.168.x.x -t location/name3 -m 'not_home' --u username -P password
fi

I tried it on my setup with the arp table output copied straight into the script - seems to work ok. The only thing I added where the ’ ’ to ensure that grep searches for the exact string. The logic of the script is still the same match the string your home anything else your not :slight_smile: