Finally "location awareness" with multi-zone

This is a neat little idea I thought I’d share. I posted previously as to how I use an SNMP request to my router to determine if my mobile phone is present on the Wifi and use this to detect if I’m in the house.

Well a light bulb went off over my head at the weekend when I realised that today I have a mini pc in the living room, another in the bedroom and my main PC in the office.

So I extended the SNMP lookups to look for those three PCs and to set a flag denoting presence in that zone if those PCs are on.

There are obviously caveats. It only works if I switch those PCs on when I enter the room. However these PCs are the only source of TV or entertainment in those rooms, so they will nearly always be switched on if I enter the room for any period of time.

I also need to switch those PCs off when I leave the room or they will waste heating. That said, if I just get up and leave the room with the PC on, it will timeout and go to sleep after 15 minutes anyway.

As you know I don’t use HA, except as a UI, but I’m fairly sure it shouldn’t be that hard to write something similar to the below into an intergration which reports itself active when the SNMP condition is true.

from pysnmp.entity.rfc3413.oneliner import cmdgen

class SnmpPresence():
    def __init__(self, ip=ROUTER_IP, community='public', mib=(1,3,6,1,2,1,4,22,1,2,16)):
        self.ip=ip
        self.community=community
        self.mib=mib

    def isMacOnline(self, mac_address):
        generator = cmdgen.CommandGenerator()
        comm_data = cmdgen.CommunityData('server', self.community, 1) # 1 means version SNMP v2c
        transport = cmdgen.UdpTransportTarget((self.ip, 161))

        real_fun = getattr(generator, 'nextCmd')
        res = (errorIndication, errorStatus, errorIndex, varBinds)\
            = real_fun(comm_data, transport, self.mib)

        if not errorIndication is None  or errorStatus is True:
               print("Error: %s %s %s %s" % res)
               return False
        else:
               for varBind in varBinds:
                   name, valueT = varBind[0]
                   thisMac = valueT.prettyPrint()
                   if thisMac == mac_address:
                       return True

There’s no need to write an integration for this. Setup an SNMP sensor for each device (or any other means of tracking the device status, I use the Unifi Device tracker, which works perfectly fine for this). Then write 2-3 simple automations, done. Also SNMP isn’t really the best thing for tracking device status due to the timeout dou mentioned.

An integration only for this would be overkill and unnecessary.