Hello, I am wondering if it is possible to assign presence detection like AsusWRT to another zone as home.
I want to achieve following, I have remote router which is not home, and I would like to monitor connected devices , but logically if there is some device connected it is not home, so I would need to create zone for example work , and there would be asuswrt router assigned or nmap or anything. My goal is to monitor remote location presence without need to run separate HASS installation in every location.
I totally agree, this would be great. I would be happy to help if someone could point me in the right direction to modify the code. Is it the device tracker module, the actual device tracker platform or the homeassistant code somewhere I should begin?
I would like to test with ie TP-Link module configuration to accept:
Example configuration.yaml entry
device_tracker:
- platform: tplink
host: YOUR_ROUTER_IP
username: YOUR_ADMIN_USERNAME
password: YOUR_ADMIN_PASSWORD
zone: ZONE WHERE THE ROUTER IS LOCATED
or alternatively (if it will involve less modification of the code affected)
latitude: LATITUDE OF ROUTER
longitude: LONGITUDE OF ROUTER
Anybody have any thoughts on this?
from the device tracker code. any device that is seen gets assigned the router type and home gps cords.
https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/components/device_tracker/init.py#L712
We would need a way to pass the gps coordiniates from device tracker config platform into this code block.
Having similar issue. Two location with different zones but with persistent network connectivity and devices capable for device_tracking (SNMP). But unfortunately device_tracker can contribute to presence to “Home” location but not to any other.
in meantime I’ve solved this issue with creating device tracker system at nodered.
I can post more information if someone feels it can help.
Please do, this feature request has been re-requested for quite a number of years. It would be nice (and very handy) to see it come to light.
Allright, so basically it consists of 2 flows in NodeRED, it could be possibly merged into single flow but I like it separate.
First is flow which fetch data from SNMP device, parse it, write to json DB , and send message with GPS coordinates found in config.
Second flow handles leaving of device, if it is not seen, message with zero GPS coordinates is sent, and this information is also written to DB.
I tried to rename elements in flow but some of functions are in Slovak language and I am lazy to rename it, sorry for that.
Time after the device is marked as left can be configured in check time function in Device Tracker departer flow.
Configuration of SNMP devices to read from is in SNMP host.
And of course you need to edit MQTT broker settings.
Device tracker
[
{
"id": "d3c94d83.f0681",
"type": "tab",
"label": "SNMP Device tracker"
},
{
"id": "85e49032.dcb81",
"type": "debug",
"z": "d3c94d83.f0681",
"name": "Debug",
"active": false,
"console": false,
"complete": "true",
"x": 1110,
"y": 180,
"wires": []
},
{
"id": "d5ba4945.ec33a8",
"type": "snmp subtree",
"z": "d3c94d83.f0681",
"host": "",
"community": "",
"port": "",
"version": "1",
"oids": "",
"timeout": 5,
"name": "Get devices",
"x": 310,
"y": 180,
"wires": [
[
"654568.b8390a98"
]
]
},
{
"id": "6ef59a37.4b7294",
"type": "inject",
"z": "d3c94d83.f0681",
"name": "20 Sec",
"topic": "admin",
"payload": "",
"payloadType": "date",
"repeat": "20",
"crontab": "",
"once": true,
"x": 110,
"y": 60,
"wires": [
[
"2de66a2b.b12f06"
]
]
},
{
"id": "654568.b8390a98",
"type": "function",
"z": "d3c94d83.f0681",
"name": "Fetch devices",
"func": "var zariadenie = [];\nvar pocetZariadeni = msg.payload.length ;\nvar payloadOld = msg.payload; \nif(pocetZariadeni > 0){\n for(var i = 0; i < pocetZariadeni ; i++) {\n var topic = \"owntracks/nodered/\"+payloadOld[i].value.toString('hex');\n msg.payload = {};\n msg.payload.topic = topic; \n msg.payload._type = \"location\" ;\n msg.payload.alt = 0;\n msg.payload.acc = 10;\n msg.payload.lon = msg.zone.lon;\n msg.payload.lat = msg.zone.lat;\n if(payloadOld[i].value.toString('hex') !== \"\" || payloadOld[i].value.toString('hex') !== \"undefined\"){\n zariadenie.push({payload:msg.payload,mac:payloadOld[i].value.toString('hex')});\n }\n }\n}\nreturn [zariadenie];\n\n\n\n",
"outputs": 1,
"noerr": 0,
"x": 520,
"y": 180,
"wires": [
[
"584f443d.6fdbac",
"74865486.b521fc"
]
]
},
{
"id": "36ff90a8.cf67c",
"type": "json",
"z": "d3c94d83.f0681",
"name": "",
"x": 890,
"y": 180,
"wires": [
[
"6c08f278.a0928c",
"85e49032.dcb81"
]
]
},
{
"id": "2de66a2b.b12f06",
"type": "function",
"z": "d3c94d83.f0681",
"name": "SNMP host",
"func": "msg.host = \"address.or.ip.com\";\nmsg.community = \"public\";\nmsg.version = \"v1\";\nmsg.port = 162;\nmsg.oid = \"1.3.6.1.2.1.4.22.1.2\";\n//msg.oid = \"1.3.6.1.4.1.14988.1.1.1.2.1.1\";\nmsg.zone = {};\nmsg.zone.lon = 18.2212163;\nmsg.zone.lat = 48.9857362;\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 190,
"y": 120,
"wires": [
[
"d5ba4945.ec33a8"
]
]
},
{
"id": "584f443d.6fdbac",
"type": "function",
"z": "d3c94d83.f0681",
"name": "Set topic",
"func": "msg.topic = msg.payload.topic;\ndelete msg.payload.topic;\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 740,
"y": 180,
"wires": [
[
"36ff90a8.cf67c"
]
]
},
{
"id": "74865486.b521fc",
"type": "function",
"z": "d3c94d83.f0681",
"name": "Write to DB",
"func": "var mac = msg.mac;\n//delete msg.mac;\nmsg.datapath = \"/\" + mac;\nmsg.topic = msg.datapath;\n//msg.payload = \"{lastseen:\" + new Date() + \",sended: false }}\";\nmsg.payload = {};\nmsg.payload.lastseen = new Date().toString();\nmsg.payload.odideny = false;\nmac = mac.toUpperCase();\n// Remove all but alphanumeric characters\nmac = mac.replace(/\\W/ig, '');\n// Append a colon after every two characters\nmac = mac.replace(/(.{2})/g, \"$1:\").slice(0, -1);\nmsg.payload.mac = mac;\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 750,
"y": 440,
"wires": [
[
"9b08d2f4.aaa67",
"85e49032.dcb81"
]
]
},
{
"id": "9b08d2f4.aaa67",
"type": "DataIn",
"z": "d3c94d83.f0681",
"collection": "2af4cf4b.d50ec",
"name": "Write device",
"update": true,
"path": "/",
"x": 1100,
"y": 440,
"wires": []
},
{
"id": "6c08f278.a0928c",
"type": "mqtt out",
"z": "d3c94d83.f0681",
"name": "to MQTT",
"topic": "",
"qos": "1",
"retain": "false",
"broker": "b00d466c.6684a8",
"x": 1080,
"y": 240,
"wires": []
},
{
"id": "2af4cf4b.d50ec",
"type": "json-db-collection",
"z": "",
"name": "Gerety",
"collection": "Geretiky1",
"save": true
},
{
"id": "b00d466c.6684a8",
"type": "mqtt-broker",
"z": "",
"broker": "192.168.1.249",
"port": "1883",
"clientid": "Node-RED",
"usetls": false,
"compatmode": true,
"keepalive": "60",
"cleansession": true,
"birthTopic": "/stat/nodered/",
"birthQos": "0",
"birthRetain": "false",
"birthPayload": "Node-RED connected",
"willTopic": "/stat/nodered",
"willQos": "0",
"willRetain": "false",
"willPayload": "Node-RED disconnected"
}
]
Device tracker departer
[
{
"id": "2a331427.45465c",
"type": "tab",
"label": "Device Tracker departer"
},
{
"id": "14f16948.fb9b97",
"type": "DataOut",
"z": "2a331427.45465c",
"collection": "2af4cf4b.d50ec",
"name": "Load data",
"path": "/",
"error": true,
"x": 310,
"y": 100,
"wires": [
[
"cac6d2f8.80a78",
"9d35570f.f62c38"
]
]
},
{
"id": "22e3bb93.1c3684",
"type": "debug",
"z": "2a331427.45465c",
"name": "Debug",
"active": false,
"console": false,
"complete": "true",
"x": 1050,
"y": 100,
"wires": []
},
{
"id": "665388db.788de8",
"type": "inject",
"z": "2a331427.45465c",
"name": "30 secs",
"topic": "",
"payload": "",
"payloadType": "date",
"repeat": "30",
"crontab": "",
"once": true,
"x": 150,
"y": 100,
"wires": [
[
"14f16948.fb9b97"
]
]
},
{
"id": "70e03dd6.1f3f34",
"type": "function",
"z": "2a331427.45465c",
"name": "Check time",
"func": "var rozdiel = Math.abs((new Date().getTime() - new Date(msg.payload.lastseen).getTime()) / 1000);\nif (rozdiel >= 150 && msg.payload.odideny === false ) {\n msg.mac = msg.parts.key;\n delete msg.parts;\n return msg;\n}\n",
"outputs": 1,
"noerr": 0,
"x": 620,
"y": 100,
"wires": [
[
"4c15d179.f069e",
"bfe9c429.8e4fb8",
"22e3bb93.1c3684"
]
]
},
{
"id": "f00967ee.7c3328",
"type": "comment",
"z": "2a331427.45465c",
"name": "We left",
"info": "",
"x": 760,
"y": 160,
"wires": []
},
{
"id": "f6412108.3984e",
"type": "DataIn",
"z": "2a331427.45465c",
"collection": "2af4cf4b.d50ec",
"name": "Write device",
"update": true,
"x": 1060,
"y": 220,
"wires": []
},
{
"id": "4c15d179.f069e",
"type": "function",
"z": "2a331427.45465c",
"name": "Write to DB",
"func": "var mac = msg.mac;\ndelete msg.mac;\nmsg.datapath = \"/\" + mac + \"/odideny\";\nmsg.topic = msg.datapath;\n//msg.payload = {};\nmsg.payload = true;\nreturn msg;\n",
"outputs": 1,
"noerr": 0,
"x": 750,
"y": 220,
"wires": [
[
"f6412108.3984e",
"22e3bb93.1c3684"
]
]
},
{
"id": "9d35570f.f62c38",
"type": "debug",
"z": "2a331427.45465c",
"name": "Device list",
"active": false,
"console": false,
"complete": "true",
"x": 500,
"y": 40,
"wires": []
},
{
"id": "cac6d2f8.80a78",
"type": "split",
"z": "2a331427.45465c",
"name": "",
"splt": "\\n",
"spltType": "str",
"arraySplt": "1",
"arraySpltType": "len",
"stream": true,
"addname": "mac",
"x": 470,
"y": 100,
"wires": [
[
"70e03dd6.1f3f34"
]
]
},
{
"id": "97d638dc.6bcae8",
"type": "json",
"z": "2a331427.45465c",
"name": "",
"x": 910,
"y": 280,
"wires": [
[
"cffea1b3.4185e"
]
]
},
{
"id": "bfe9c429.8e4fb8",
"type": "function",
"z": "2a331427.45465c",
"name": "Leave device",
"func": "var payloadOld = msg.payload; \nvar topic = \"owntracks/nodered/\"+msg.mac;\nmsg.topic = topic; \nmsg.payload = {};\nmsg.payload._type = \"location\" ;\nmsg.payload.alt = 0;\nmsg.payload.acc = 10;\nmsg.payload.lon = 0;\nmsg.payload.lat = 0;\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 740,
"y": 280,
"wires": [
[
"97d638dc.6bcae8"
]
]
},
{
"id": "cffea1b3.4185e",
"type": "mqtt out",
"z": "2a331427.45465c",
"name": "to MQTT",
"topic": "",
"qos": "1",
"retain": "false",
"broker": "b00d466c.6684a8",
"x": 1040,
"y": 280,
"wires": []
},
{
"id": "2af4cf4b.d50ec",
"type": "json-db-collection",
"z": "",
"name": "Gerety",
"collection": "Geretiky1",
"save": true
},
{
"id": "b00d466c.6684a8",
"type": "mqtt-broker",
"z": "",
"broker": "192.168.1.249",
"port": "1883",
"clientid": "Node-RED",
"usetls": false,
"compatmode": true,
"keepalive": "60",
"cleansession": true,
"birthTopic": "/stat/nodered/",
"birthQos": "0",
"birthRetain": "false",
"birthPayload": "Node-RED connected",
"willTopic": "/stat/nodered",
"willQos": "0",
"willRetain": "false",
"willPayload": "Node-RED disconnected"
}
]
This flow parses data from Unifi Controller through API
[
{
"id": "8727f5df.79d828",
"type": "tab",
"label": "Unifi Controller API",
"disabled": false,
"info": ""
},
{
"id": "9fb79c79.d1d73",
"type": "Unifi",
"z": "8727f5df.79d828",
"name": "Get all sites",
"ip": "192.168.10.14",
"port": 8443,
"site": "",
"command": "1",
"x": 290,
"y": 80,
"wires": [
[
"2f18d9b.b509026"
]
]
},
{
"id": "fc55429b.ba245",
"type": "debug",
"z": "8727f5df.79d828",
"name": "Debug",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"x": 1130,
"y": 180,
"wires": []
},
{
"id": "364c2252.d3a5ce",
"type": "inject",
"z": "8727f5df.79d828",
"name": "1 minute",
"topic": "admin",
"payload": "",
"payloadType": "date",
"repeat": "60",
"crontab": "",
"once": true,
"onceDelay": 0.1,
"x": 120,
"y": 80,
"wires": [
[
"9fb79c79.d1d73"
]
]
},
{
"id": "2f18d9b.b509026",
"type": "function",
"z": "8727f5df.79d828",
"name": "Parse all sites",
"func": "var sajty = [];\n\nfor(var i = 0; i < msg.payload.length ; i++) {\n \n sajty.push({site:msg.payload[i].name, name: msg.payload[i].desc});\n \n}\nreturn [sajty];\n\n\n\n",
"outputs": 1,
"noerr": 0,
"x": 490,
"y": 80,
"wires": [
[
"a3a48cec.8ac8e"
]
]
},
{
"id": "5259fef9.da93f",
"type": "json",
"z": "8727f5df.79d828",
"name": "",
"property": "payload",
"action": "str",
"pretty": false,
"x": 930,
"y": 180,
"wires": [
[
"fc55429b.ba245",
"36110a7b.98f0f6"
]
]
},
{
"id": "9d33c273.72494",
"type": "function",
"z": "8727f5df.79d828",
"name": "Set topic",
"func": "msg.topic = msg.payload.topic;\ndelete msg.payload.topic;\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 780,
"y": 180,
"wires": [
[
"5259fef9.da93f"
]
]
},
{
"id": "79f0afdd.9ce99",
"type": "Unifi",
"z": "8727f5df.79d828",
"name": "Parse clients",
"ip": "192.168.10.14",
"port": 8443,
"site": "",
"command": "20",
"x": 380,
"y": 180,
"wires": [
[
"b5874d60.d458d"
]
]
},
{
"id": "4f14c4d.eec603c",
"type": "function",
"z": "8727f5df.79d828",
"name": "Set command and site",
"func": "if(msg.payload[0] && msg.payload[0][0] && msg.payload[0][0].y ) {\n msg.longitude = msg.payload[0][0].y;\n msg.latitude = msg.payload[0][0].x;\n}\nmsg.payload = { command: 'ClientDevices' , site: msg.site };\n//delete msg.site;\ndelete msg.command;\nreturn msg;\n",
"outputs": 1,
"noerr": 0,
"x": 160,
"y": 180,
"wires": [
[
"79f0afdd.9ce99"
]
]
},
{
"id": "1b69f2de.f08c8d",
"type": "Unifi",
"z": "8727f5df.79d828",
"name": "Fetch GPS of site",
"ip": "192.168.10.14",
"port": 8443,
"site": "",
"command": "70",
"x": 1120,
"y": 80,
"wires": [
[
"4f14c4d.eec603c"
]
]
},
{
"id": "3bebde31.5048f2",
"type": "function",
"z": "8727f5df.79d828",
"name": "Set command and site",
"func": "msg.payload = { command: \"AccessDevices\" , site: msg.site };\n//delete msg.site;\ndelete msg.command;\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 900,
"y": 80,
"wires": [
[
"1b69f2de.f08c8d"
]
]
},
{
"id": "a3a48cec.8ac8e",
"type": "delay",
"z": "8727f5df.79d828",
"name": "",
"pauseType": "rate",
"timeout": "5",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": false,
"x": 690,
"y": 80,
"wires": [
[
"3bebde31.5048f2"
]
]
},
{
"id": "b5874d60.d458d",
"type": "function",
"z": "8727f5df.79d828",
"name": "List devices",
"func": "var zariadenie = [];\nvar pocetZariadeni = msg.payload[0].length ;\nvar payloadOld = msg.payload; \nfor(var i = 0; i < pocetZariadeni ; i++) {\n var topic = \"owntracks/nodered/\"+payloadOld[0][i].mac.replace(/:/gi,\"\");\n msg.payload = {};\n msg.payload.topic = topic; \n msg.payload._type = \"location\" ;\n msg.payload.alt = 0;\n msg.payload.acc = 10;\n if(msg.longitude) {\n msg.payload.lon = msg.longitude;\n msg.payload.lat = msg.latitude;\n zariadenie.push({payload:msg.payload,mac:payloadOld[0][i].mac.replace(/:/gi,\"\")});\n }\n}\nreturn [zariadenie];\n\n\n\n",
"outputs": 1,
"noerr": 0,
"x": 580,
"y": 180,
"wires": [
[
"9d33c273.72494",
"5d42179.03215e8"
]
]
},
{
"id": "fcd60ed1.7daa6",
"type": "DataIn",
"z": "8727f5df.79d828",
"collection": "2af4cf4b.d50ec",
"name": "Zapis zariadenie",
"update": true,
"path": "/",
"x": 820,
"y": 280,
"wires": []
},
{
"id": "5d42179.03215e8",
"type": "function",
"z": "8727f5df.79d828",
"name": "Write to DB",
"func": "var mac = msg.mac;\ndelete msg.mac;\nmsg.datapath = \"/\" + mac;\n//msg.payload = \"{lastseen:\" + new Date() + \",sended: false }}\";\nmsg.payload = {};\nmsg.payload.lastseen = new Date().toString();\nmsg.payload.odideny = false;\nmac = mac.toUpperCase();\n// Remove all but alphanumeric characters\nmac = mac.replace(/\\W/ig, '');\n// Append a colon after every two characters\nmac = mac.replace(/(.{2})/g, \"$1:\").slice(0, -1);\nmsg.payload.mac = mac;\nreturn msg;\n ",
"outputs": 1,
"noerr": 0,
"x": 590,
"y": 280,
"wires": [
[
"fcd60ed1.7daa6"
]
]
},
{
"id": "36110a7b.98f0f6",
"type": "mqtt out",
"z": "8727f5df.79d828",
"name": "to MQTT",
"topic": "",
"qos": "1",
"retain": "false",
"broker": "b00d466c.6684a8",
"x": 1100,
"y": 280,
"wires": []
},
{
"id": "2af4cf4b.d50ec",
"type": "json-db-collection",
"z": "",
"name": "Gerety",
"collection": "Geretiky1",
"save": true
},
{
"id": "b00d466c.6684a8",
"type": "mqtt-broker",
"z": "",
"broker": "192.168.1.249",
"port": "1883",
"clientid": "Node-RED",
"usetls": false,
"compatmode": true,
"keepalive": "60",
"cleansession": true,
"birthTopic": "/stat/nodered/",
"birthQos": "0",
"birthRetain": "false",
"birthPayload": "Node-RED connected",
"willTopic": "/stat/nodered",
"willQos": "0",
"willRetain": "false",
"willPayload": "Node-RED disconnected"
}
]
Example HomeAssistant configuration
device_tracker 2:
- platform: owntracks
mqtt_topic: "owntracks/#"
consider_home: 180
track_new_devices: False
new_device_defaults:
track_new_devices: False
hide_if_away: False