Mocht iemand het interessant vinden, ik ben al een tijdje op zoek naar een goede oplossing voor presence detection per kamer. Heb de esp32 ble beacon library geprobeerd op mijn esp bordjes maar dit werkte toch niet helemaal lekker; dikwijls 10 meter afstand volgens HA terwijl ik er naast stond, het was niet goed voor de batterij van onze telefoons en de updates kwamen laat binnen.
Het probleem wat ik namelijk nu heb, is dat de lampen uitgaan (na ongeveer 15 minuten) als de TV uitstaat en er geen beweging is in dat tijdsbestek. Dat is prima mogelijk als mijn vrouw een tijdschriftje leest op de bank bijvoorbeeld.
Toen bedacht ik me, waarom niet gewoon gebruik maken van de informatie van AIMesh van mijn 4 Asus routers/nodes. Op elke verdieping heb ik er 1 en op de begane grond 2. Helaas geeft de ASUSWRT integratie van HA geen info over welke apparaten verbonden zijn met welke nodes. Dus heb ik zelf iets in elkaar geklust in Python (ben Scala/Java developer dus verbeterpuntjes zijn welkom;)):
Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
| from flask import Flask
import json
app = Flask(__name__)
import os
routers = {'24:XX:XX:XX:XX': 'Bedroom', '24:XX:XX:XX:XX': 'Main', '24:XX:XX:XX:XX': 'Study', '24:XX:XX:XX:XX': 'Livingroom'}
map_to_floor = {'Bedroom': 'Second Floor', 'Study': 'First Floor', 'Main': 'Downstairs', 'Livingroom': 'Downstairs'}
types = ['2G', '5G']
def clients_by_identifier(identifier_fnc):
with open(os.environ.get('CLIENTFILE')) as file:
clients_by_id = {}
data = json.load(file)
for mac, location in routers.items():
for t in types:
if t in data[mac]:
if location in clients_by_id:
clients_by_id[location].extend(identifier_fnc(data[mac][t]))
else:
clients_by_id[location] = identifier_fnc(data[mac][t])
return clients_by_id
def find_location_of_client(identifier_fnc, client):
response = clients_by_identifier(identifier_fnc)
for router in response:
if client in response[router]:
return map_to_floor[router]
return 'Away'
@app.route('/')
def fetch_all():
return clients_by_identifier(lambda dict: [v['ip'] for _,v in dict.items()])
@app.route('/<mac>')
def fetch_by_mac(mac):
return find_location_of_client(lambda dict: list(dict.keys()), mac.replace('-', ':'))
@app.route('/ip/<ip>')
def fetch_by_ip(ip):
return find_location_of_client(lambda dict: [v['ip'] for _,v in dict.items()], ip) |
Op de router staat namelijk een bestandje in /tmp/ genaamd clientlist.json die elke x seconden wordt geupdate met info over welke apparaten met welke node zijn verbonden. Na het installeren van Python via opkg en het starten van de flask app via /jffs/scripts/services-start:
code:
1
2
| #!/bin/sh
CLIENTFILE=/tmp/clientlist.json FLASK_APP=/tmp/mnt/usbdrive/client-exporter/app.py nohup flask run --host=0.0.0.0 & |
Is het een kwestie van een nieuwe rest sensor toevoegen:
YAML:
1
2
3
4
| sensor:
- platform: rest
resource: http://192.168.2.1:5000/ip/192.168.2.69
name: "GJ Location Wifi" |
En een binary sensor aanmaken die aangeeft of er iemand beneden is:
YAML:
1
2
3
4
| - binary_sensor:
- name: Someone downstairs
state: >
{{ is_state('sensor.gj_location_wifi', 'Downstairs') or is_state('sensor.e****_location_wifi', 'Downstairs') }} |
Tot nu toe zeer tevreden met de resultaten, veel stabieler en betrouwbaarder dan de iBeacon oplossing.
[Voor 0% gewijzigd door septillion op 25-12-2022 14:38]