Skip to content

Instantly share code, notes, and snippets.

@x99percent
Created December 3, 2018 22:03
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save x99percent/a991cd7bdacf20a7d5be9d7712d25320 to your computer and use it in GitHub Desktop.
Save x99percent/a991cd7bdacf20a7d5be9d7712d25320 to your computer and use it in GitHub Desktop.
Node-RED flow for OwnTracks presence detection and remote config
[
{
"id": "c98e7d43.2a73f",
"type": "subflow",
"name": "Startup Delay",
"info": "",
"category": "",
"in": [
{
"x": 60,
"y": 120,
"wires": [
{
"id": "b777fc91.67f49"
}
]
}
],
"out": [
{
"x": 480,
"y": 120,
"wires": [
{
"id": "e18ed021.62aea",
"port": 0
}
]
}
]
},
{
"id": "e18ed021.62aea",
"type": "switch",
"z": "c98e7d43.2a73f",
"name": "",
"property": "StartupDelay",
"propertyType": "global",
"rules": [
{
"t": "false"
},
{
"t": "else"
}
],
"checkall": "true",
"repair": false,
"outputs": 2,
"x": 350,
"y": 120,
"wires": [
[],
[
"48947d36.db8c44"
]
]
},
{
"id": "48947d36.db8c44",
"type": "delay",
"z": "c98e7d43.2a73f",
"name": "",
"pauseType": "delay",
"timeout": "1",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": false,
"x": 360,
"y": 180,
"wires": [
[
"e18ed021.62aea"
]
]
},
{
"id": "b777fc91.67f49",
"type": "delay",
"z": "c98e7d43.2a73f",
"name": "",
"pauseType": "delay",
"timeout": "1",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": false,
"x": 180,
"y": 120,
"wires": [
[
"e18ed021.62aea"
]
]
},
{
"id": "e5c62b67.610eb8",
"type": "mqtt in",
"z": "5e0b1c4d.7d2ce4",
"name": "OwnTracks",
"topic": "owntracks/+/+",
"qos": "2",
"broker": "6f2f2627.f1e6d8",
"x": 100,
"y": 660,
"wires": [
[
"5d5cdefa.1230d"
]
]
},
{
"id": "f96eb4a7.982048",
"type": "json",
"z": "5e0b1c4d.7d2ce4",
"name": "",
"property": "payload",
"action": "",
"pretty": false,
"x": 410,
"y": 660,
"wires": [
[
"16805600.4b20ba"
]
]
},
{
"id": "16805600.4b20ba",
"type": "function",
"z": "5e0b1c4d.7d2ce4",
"name": "Parse",
"func": "if (msg.payload._type === \"location\")\n{\n// var date = new Date(parseInt(msg.payload.tst) * 1000);\n \n msg.payload.data = {\n \"battery\" : parseInt(msg.payload.batt),\n \"dev_id\" : msg.topic.replace(/\\/|-/g, \"_\").toLowerCase(),\n \"gps\" : [parseFloat(msg.payload.lat),parseFloat(msg.payload.lon)],\n \"gps_accuracy\" : msg.payload.acc\n };\n msg.timestamp = msg.payload.tst;\n}\nelse\n msg = null;\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 530,
"y": 660,
"wires": [
[
"d0af9d1d.6182a"
]
]
},
{
"id": "d0af9d1d.6182a",
"type": "geofence",
"z": "5e0b1c4d.7d2ce4",
"name": "Home",
"mode": "polyline",
"inside": "both",
"rad": 0,
"points": [
{
"latitude": 0.470799056043745,
"longitude": 40.95746326446533
},
{
"latitude": 0.47222352757142,
"longitude": 40.95632600784302
},
{
"latitude": 0.4736796205139,
"longitude": 40.95759201049805
},
{
"latitude": 0.4736796205139,
"longitude": 40.96282768249512
},
{
"latitude": 0.47220770028812,
"longitude": 40.96387910842896
},
{
"latitude": 0.47083071131877,
"longitude": 40.96278476715088
}
],
"centre": {},
"x": 650,
"y": 660,
"wires": [
[
"581e4bc0.708e94"
]
]
},
{
"id": "581e4bc0.708e94",
"type": "switch",
"z": "5e0b1c4d.7d2ce4",
"name": "At Home?",
"property": "location.inarea",
"propertyType": "msg",
"rules": [
{
"t": "false"
},
{
"t": "true"
}
],
"checkall": "true",
"repair": false,
"outputs": 2,
"x": 780,
"y": 660,
"wires": [
[
"7aff63c0.294d2c"
],
[
"71f4e44e.19026c",
"bc2ea88a.582b98"
]
]
},
{
"id": "71f4e44e.19026c",
"type": "change",
"z": "5e0b1c4d.7d2ce4",
"name": "Home",
"rules": [
{
"t": "set",
"p": "payload.data.location_name",
"pt": "msg",
"to": "home",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 930,
"y": 680,
"wires": [
[
"6646f347.b7900c",
"47636938.df44c8"
]
]
},
{
"id": "7aff63c0.294d2c",
"type": "change",
"z": "5e0b1c4d.7d2ce4",
"name": "Away",
"rules": [
{
"t": "set",
"p": "payload.data.location_name",
"pt": "msg",
"to": "not_home",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 930,
"y": 640,
"wires": [
[
"47636938.df44c8",
"6646f347.b7900c",
"485c774d.5c5468"
]
]
},
{
"id": "6646f347.b7900c",
"type": "debug",
"z": "5e0b1c4d.7d2ce4",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"x": 1070,
"y": 640,
"wires": []
},
{
"id": "47636938.df44c8",
"type": "api-call-service",
"z": "5e0b1c4d.7d2ce4",
"name": "Update device_tracker",
"server": "fce9a161.4cb4b",
"service_domain": "device_tracker",
"service": "see",
"data": "",
"mergecontext": "",
"x": 1120,
"y": 680,
"wires": [
[]
]
},
{
"id": "5d5cdefa.1230d",
"type": "subflow:c98e7d43.2a73f",
"z": "5e0b1c4d.7d2ce4",
"name": "",
"x": 260,
"y": 660,
"wires": [
[
"f96eb4a7.982048"
]
]
},
{
"id": "bc2ea88a.582b98",
"type": "api-current-state",
"z": "5e0b1c4d.7d2ce4",
"name": "Recent Door Activity?",
"server": "fce9a161.4cb4b",
"halt_if": "",
"override_topic": false,
"override_payload": true,
"override_data": true,
"entity_id": "input_boolean.door_activity",
"x": 940,
"y": 760,
"wires": [
[
"36955e21.ad5902",
"23f75f78.b25f5"
]
]
},
{
"id": "36955e21.ad5902",
"type": "switch",
"z": "5e0b1c4d.7d2ce4",
"name": "On / Off",
"property": "payload",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "on",
"vt": "str"
},
{
"t": "else"
}
],
"checkall": "false",
"repair": false,
"outputs": 2,
"x": 1140,
"y": 760,
"wires": [
[
"485c774d.5c5468"
],
[
"2efc09cb.d03296"
]
]
},
{
"id": "485c774d.5c5468",
"type": "function",
"z": "5e0b1c4d.7d2ce4",
"name": "OwnTracks variable",
"func": "distance = parseInt(msg.location.distances.Home);\ninterval = parseInt(0.000000000000475 * Math.pow(distance,4) - 0.00000000475 * Math.pow(distance,3) + 0.0000265 * Math.pow(distance,2) + 0.0037 * distance + 1.43);\ndev_id = msg.topic.replace(/\\/|-/g, \"_\").toLowerCase();\n\nif (interval < 3) interval = 3;\nif (interval > 300) interval = 300;\n\nlastInterval = flow.get(dev_id + '_last_owntracks_interval');\nlastTimestamp = flow.get(dev_id + '_last_owntracks_timestamp');\n\nvar temp = new Date(parseInt(msg.timestamp) * 1000);\nnode.status({fill: \"green\", shape: \"dot\", text: interval + \" at \" + temp.toLocaleString()});\n\nif (typeof(lastInterval) != \"undefined\")\n{\n\tif ((msg.timestamp - 3600) < lastTimestamp) // less than 1 hour since last update?\n\t{\n\t\tif (lastInterval > (interval / 1.05) && lastInterval < (interval * 1.05)) // within 5% of last update?\n {\n node.status({fill: \"red\", shape: \"ring\", text: interval + \" at \" + temp.toLocaleString()});\n msg = null;\n }\n else\n\t\t{\n node.status({fill: \"green\", shape: \"dot\", text: msg.timestamp + \" versus \" + lastTimestamp});\n flow.set('_last_owntracks_interval', interval);\n flow.set('_last_owntracks_timestamp', msg.timestamp);\n\n msg.topic = msg.topic + \"/cmd\";\n msg.payload = {\n \"_type\" : \"cmd\",\n \"action\" : \"setConfiguration\",\n \"configuration\" : {\n \"_type\" : \"configuration\",\n \"beaconMode\" : 2,\n \"locatorDisplacement\" : interval * 2,\n \"locatorInterval\" : interval,\n \"pub\" : \"true\",\n \"pubQos\" : 2\n }\n };\n }\n }\n else\n {\n flow.set(dev_id + '_last_owntracks_interval', interval);\n flow.set(dev_id + '_last_owntracks_timestamp', msg.timestamp);\n\n msg.topic = msg.topic + \"/cmd\";\n msg.payload = {\n \"_type\" : \"cmd\",\n \"action\" : \"setConfiguration\",\n \"configuration\" : {\n \"_type\" : \"configuration\",\n \"beaconMode\" : 2,\n \"locatorDisplacement\" : interval * 2,\n \"locatorInterval\" : interval,\n \"pub\" : \"true\",\n \"pubQos\" : 2\n }\n };\n }\n}\nelse\n{\n flow.set(dev_id + '_last_owntracks_interval', interval);\n flow.set(dev_id + '_last_owntracks_timestamp', msg.timestamp);\n\n msg.topic = msg.topic + \"/cmd\";\n msg.payload = {\n \"_type\" : \"cmd\",\n \"action\" : \"setConfiguration\",\n \"configuration\" : {\n \"_type\" : \"configuration\",\n \"beaconMode\" : 2,\n \"locatorDisplacement\" : interval * 2,\n \"locatorInterval\" : interval,\n \"pub\" : \"true\",\n \"pubQos\" : 2\n }\n };\n}\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 1330,
"y": 740,
"wires": [
[
"4fd086f6.3d86d8",
"f9e37b4f.ac0d38"
]
]
},
{
"id": "2efc09cb.d03296",
"type": "function",
"z": "5e0b1c4d.7d2ce4",
"name": "OwnTracks 120sec",
"func": "var timestamp = new Date(parseInt(msg.timestamp) * 1000);\nnode.status({fill: \"green\", shape: \"dot\", text: 120 + \" at \" + timestamp.toLocaleString()});\ndev_id = msg.topic.replace(/\\/|-/g, \"_\").toLowerCase();\n\nflow.set(dev_id + '_last_owntracks_timestamp', msg.timestamp);\nflow.set(dev_id + '_last_owntracks_interval', 120);\n\nmsg.topic = msg.topic + \"/cmd\";\nmsg.payload = {\n \"_type\" : \"cmd\",\n \"action\" : \"setConfiguration\",\n \"configuration\" : {\n \"_type\" : \"configuration\",\n \"beaconMode\" : 2,\n \"locatorDisplacement\" : 50,\n \"locatorInterval\" : 120,\n \"pub\" : \"true\",\n \"pubQos\" : 2\n }\n};\n// beaconMode was 0\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 1330,
"y": 800,
"wires": [
[
"f9e37b4f.ac0d38",
"4fd086f6.3d86d8"
]
]
},
{
"id": "4fd086f6.3d86d8",
"type": "mqtt out",
"z": "5e0b1c4d.7d2ce4",
"name": "",
"topic": "",
"qos": "2",
"retain": "false",
"broker": "6f2f2627.f1e6d8",
"x": 1510,
"y": 780,
"wires": []
},
{
"id": "f9e37b4f.ac0d38",
"type": "debug",
"z": "5e0b1c4d.7d2ce4",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"x": 1510,
"y": 740,
"wires": []
},
{
"id": "5bbec6b0.556958",
"type": "comment",
"z": "5e0b1c4d.7d2ce4",
"name": "Note: override topic is OFF",
"info": "",
"x": 930,
"y": 800,
"wires": []
},
{
"id": "23f75f78.b25f5",
"type": "debug",
"z": "5e0b1c4d.7d2ce4",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"x": 1130,
"y": 800,
"wires": []
},
{
"id": "6f2f2627.f1e6d8",
"type": "mqtt-broker",
"z": "",
"name": "Mosquitto",
"broker": "REDACTED_IP",
"port": "REDACTED_PORT",
"clientid": "Node-RED",
"usetls": false,
"compatmode": true,
"keepalive": "60",
"cleansession": true,
"birthTopic": "",
"birthQos": "0",
"birthPayload": "",
"closeTopic": "",
"closePayload": "",
"willTopic": "",
"willQos": "0",
"willPayload": ""
},
{
"id": "fce9a161.4cb4b",
"type": "server",
"z": "",
"name": "Home Assistant",
"legacy": false,
"hassio": false,
"rejectUnauthorizedCerts": true
}
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment