NEWS
MQTT Bluetooth BLE Anwesenheitserkennung mit ESP32
-
@spezialtrick
Wichtig ist, dass der Fehler jetzt gefunden wurde.
Habe gestern an einem größeren Skript im Kreis gewerkelt, weil ich wissen Fehler nicht finden konnte. Letztendlich war es ein flüchtiger Fehler, der mich eine Stunde gekostet hatte. PassiertAktuell habe ich unter meinem Bett einen Scanner, somit wird gut erkannt, ob ich im Schlafzimmer bin. Damit steuere ich meine "Guten Morgen" Routine. Rollläden fahren hoch, Lichter gehen nicht mehr gedimmt an.
Eigentlich habe ich eine Funktion geschrieben, mit der Trianguliert werden kann. In 2D kann über drei Scanner die Position halbwegs genau ermittelt werden. Aber ich habe bisher keine weiteren Scanner daheim verbaut, weil ich meine Hoffnung ein wenig auf uwb setze.
UWB Smartwatch mit passenden UWB Scanner könnte die Position sehr viel genauer ermitteln. Daher bin ich selbst gerade noch im "Schwebezustand".
Ansonsten würde ich Lichtsteuerung mit diesen ble scanner erweitern:
Licht geht über Bewegungsmelder an und geht erst aus wenn über ble der Bereich verlassen wird. Das wäre eine gute Ergänzung. Bewegungsmelder reagieren meist nicht schnell hintereinander. Außerdem werden kleinere Bewegungen nicht erkannt. Somit eine passende Ergänzung.
Muss jetzt nur noch meine bessere Hälfte dazu bringen, auch eine Smartwatch mit ble zu verwenden -
@spezialtrick
Übrigens verwende ich nur den gemittelten Wert weiter, der andere kann schonmal Sprünge aufweisen.
Anhand der Länge des Array für den gleitenden Mittelwert, kann zwischen Schnelligkeit und Genauigkeit variiert werden. -
@giuseppes said in MQTT Bluetooth BLE Anwesenheitserkennung mit ESP32:
Wichtig ist, dass der Fehler jetzt gefunden wurde.
Aber extrem ärgerlich... -.-
Aktuell habe ich unter meinem Bett einen Scanner, somit wird gut erkannt, ob ich im Schlafzimmer bin. Damit steuere ich meine "Guten Morgen" Routine. Rollläden fahren hoch, Lichter gehen nicht mehr gedimmt an.
Könntest du mir dieses Skript bereitstellen? Mir fehlt aktuell ein wenig die Idee, ab welchen RSSI Wert ein Gerät abwesend ist.
Eigentlich habe ich eine Funktion geschrieben, mit der Trianguliert werden kann. In 2D kann über drei Scanner die Position halbwegs genau ermittelt werden. Aber ich habe bisher keine weiteren Scanner daheim verbaut, weil ich meine Hoffnung ein wenig auf uwb setze.
Magst du mir die Funktion zum Testen geben? Ich hätte vier ESP32 hier, die ich nur dafür gekauft hatte.
-
@spezialtrick
Ich sende es dir sobald ich wieder am privaten PC bin. Ich habe im Skript mit triangulation auch die Erstellung von HTML Objekten, um die Position darzustellen.
Triangulation funktioniert zwar, aber natürlich musst du die Positionen der esp32 im 2D System darin eintragen.Übrigens warte ich aktuell auch darauf, dass Shelly seine Variante 2.5 mit esp32 rausbringt. Dann könnte mit alternativer Firmware der Rollladen normal gesteuert und der esp32 als Scanner verwendet werden. Dann wäre triangulation echt sehr gut möglich.
-
@giuseppes sagte in MQTT Bluetooth BLE Anwesenheitserkennung mit ESP32:
Ich sende es dir sobald ich wieder am privaten PC bin. Ich habe im Skript mit triangulation auch die Erstellung von HTML Objekten, um die Position darzustellen.
Perfekt. Soll ich mit vier oder erstmal drei ESP32 testen?
Triangulation funktioniert zwar, aber natürlich musst du die Positionen der esp32 im 2D System darin eintragen.
Macht Sinn. Ansonsten dürfte es mit den Berechnungen schwierig werden.
Übrigens warte ich aktuell auch darauf, dass Shelly seine Variante 2.5 mit esp32 rausbringt. Dann könnte mit alternativer Firmware der Rollladen normal gesteuert und der esp32 als Scanner verwendet werden. Dann wäre triangulation echt sehr gut möglich.
Mit Shelly habe ich mich tatsächlich noch nie beschäftigt. Klingt aber spannend.
-
@spezialtrick
Nach aktuellem Stand, funktioniert die Triangulation nur mit drei Werten.
Am besten fütterst du das Skript mit den drei ESP32, die die kleinsten Werte aufweisen.
Als Ergebnis bekommt man einen Kreis, der, je nach Abweichung, größer oder kleiner ausfällt.
Hintergrund: mathematisch wird die Rechnung nie perfekt aufgehen, wenn grobe rssi Werte genommen werden. Man muss sich das so vorstellen, dass u.U. diese drei Entfernungen sich nie berühren. Aber es wird dann ein Kreis gebildet, der auf seinem Umfang, diese drei Entfernungspunkte berührt. -
Dann setze ich erstmal drei ESP auf und warte auf dein Skript.
-
Anbei das Skript für Triangulation:
const mathjs = require("mathjs"); /** * Berechnet triangulierten Punkt inkl. Unschärfe-Radius * * Basis-Gleichung lautet: * (x - x_i)² + (y - y_i)² = (r_i + ur)², * mit i = 1,2,3 und ur = Unschärferadius * -> x² + x_i² - 2x_i*x + y² + y_i² - 2y_i*y = r_i² + u² + 2r_i*u * * Angelehnt an Lösungsweg: https://stackoverflow.com/a/56294794 * Änderung: statt "= (r_i * k)² wird "= (r_i + ur)²" verwendet! * * @param {Object} p1 First point and radius: [ x, y, r ] * @param {Object} p2 Second point and radius: [ x, y, r ] * @param {Object} p3 Third point and radius: [ x, y, r ] * @return {Object} tril. Point and error-radius { x, y, ur } */ function trilaterate (p1, p2, p3) { function sqr (a) {return a*a}; function sqrt (a) {return mathjs.sqrt(a)}; function solvePQ (p,q) { let d = sqr(p)/4 - q; if (d >= 0){ let x1 = -p/2 + sqrt(d); let x2 = -p/2 - sqrt(d); return [x1, x2] } else { return [] } } let x1 = p1[0], y1 = p1[1], r1 = p1[2], x2 = p2[0], y2 = p2[1], r2 = p2[2], x3 = p3[0], y3 = p3[1], r3 = p3[2]; // Gl. a_i: x² + x_i² - 2x_i*x + y² + y_i² - 2y_i*y = r_i² + u² + 2r_i*u // Gl. a_1 - Gl. a_2 und Gl. a_1 - Gl.a_3 eliminiert x²/y² und ergibt ein LGS // A * X = C + B * u >>> X = A^-1 * C + A^-1 * B * u let A = [ [ 2*(x2 - x1), 2*(y2 - y1) ], [ 2*(x3 - x1), 2*(y3 - y1) ] ]; let C = [ sqr(r1) - sqr(r2) - sqr(x1) + sqr(x2) - sqr(y1) + sqr(y2), sqr(r1) - sqr(r3) - sqr(x1) + sqr(x3) - sqr(y1) + sqr(y3) ]; let B = [ 2*(r1 - r2), 2*(r1 - r3) ]; let A_inv = mathjs.inv(A); let A_invC = mathjs.multiply(A_inv, C); let A_invB = mathjs.multiply(A_inv, B); // x = A_invC[0] + A_invB[0] * u, und y = A_invC[1] + A_invB[1] * u // x = c1 + c2 * u, und y = c3 + c4 * u in Gl. a_1 let c1 = A_invC[0]; let c2 = A_invB[0]; let c3 = A_invC[1]; let c4 = A_invB[1]; let quot = sqr(c2) + sqr(c4) - 1; let p = (2*c1*c2 - 2*x1*c2 + 2*c3*c4 - 2*y1*c4 - 2*r1) / quot; let q = (sqr(c1) + sqr(x1) - 2*x1*c1 + sqr(c3) + sqr(y1) - 2*y1*c3 - sqr(r1)) / quot; let arrU = solvePQ(p,q); if (arrU == []) return "ur konnte nicht berechnet werden!"; let u = arrU[0]; // Bisherige Tests: arrU[0] scheint immer zu passen? let x = c1 + c2 * u; let y = c3 + c4 * u; return { x: x.toFixed(2), y: y.toFixed(2), ur: u.toFixed(2) } } console.log(trilaterate( [0,0,7], [10,0,7], [5,8.66,7] ))
Übergabe in die Funktion "trilaterate()" sind die drei Punkte mit X, Y und Radius. Radius ist der in cm oder m umgerechnete RSSI Wert. Die Umrechnung findest Du im unteren Skript mit "getDist()". Wichtig ist natürlich, dass immer dieselben Einheiten verwendet werden
Übrigens musst Du innerhalb der Javascript Instanz das Modul mathjs eingeben. Das wird hier für vereinfachte Matrizen-Rechnungen verwendet.Womit ich zuletzt experimentiert hatte, war das Anzeigen der RSSI Werte (umgerechnet in cm) über html. Weil ich nur ein esp32 hatte (+ BLE vom PC), habe ich so nutzbare Filtermöglichkeiten getestet.
Für das bessere Verständnis:
"rssiComp" = RSSI Wert meines PCs = Sensor 1
"rssiWemos" = RSSI Wert meines ESP32 = Sensor 2Im folgenden Skript werden die Positionen der beiden Sensoren + deren RSSI-in-cm Werten zu meiner BLE Uhr angezeigt
createState("VIS.bleScan.Drawing"); let idType = "Avg"; // Kf oder Raw // return in cm function getDist(rssi, txPower){ let n = 2; let exponent = (txPower - rssi) / (10 * n); return Math.pow(10, exponent)*100; } let rssiComp, rssiWemos; on({id: new RegExp('javascript\.1\.VIS\.bleScan.\Pino\..*'), change: "any"}, function (obj) { let value = obj.state.val; let id = obj.id.split(".").pop(); if (id == idType + "Wemos") rssiWemos = value; if (id == idType + "Comp") rssiComp = value; let html = '<svg width="410" height="900"> ' + '<rect x="10" y="10" width="225" height="500" style="fill:none;stroke:white;stroke-width:5" />' + '<circle cx="220" cy="70" r="5" stroke="white" stroke-width="5" fill=white />' /*Comp*/ + '<text x="200" y="100" fill="red">' + rssiComp + '</text>' /*Comp*/ + '<circle cx="220" cy="70" r="' + getDist(rssiComp, -69)/2 + '" stroke="green" stroke-width="4" fill=none />' /*Comp*/ + '<circle cx="100" cy="410" r="5" stroke="white" stroke-width="5" fill=white />' /*Wemos*/ + '<text x="80" y="440" fill="red">' + rssiWemos + '</text>' /*Wemos*/ + '<circle cx="100" cy="410" r="' + getDist(rssiWemos, -69)/2 + '" stroke="green" stroke-width="4" fill=none />' /*Wemos*/ + '</svg>' setState("javascript." + instance + ".VIS.bleScan.Drawing", html); });
So sahen meine Test-States aus:
-
@spezialtrick
Natürlich kannst Du beide Skripte in ein einziges Skript zusammnführen. Ich hatte zu dem Zeitpunkt die beiden Tests unabhängig voneinander durchgeführt, daher getrennt aufgeführt... -
Hallo klappt es auch mit iphone kann ich das Bluetooth signal vom iphone auch dafür benutzen???
-
@exitus
Sowie ich das beim iPhone meiner Freundin erkennen konnte, sendete das iPhone nur ble Advertisements während es entsperrt war. Nicht dauerhaft. Bei Androiden gibt es Apps, um es dauerhaft zu aktivieren. -
@giuseppes warum es hier klappt ???
https://www.youtube.com/watch?v=ShyqG8DjkrU&t=65s -
@exitus
Habe mir gerade die Zeit genommen und in Video reingeschaut. Im Video geht es Bluetooth allgemein und nicht ble. So löse ich übrigens auch daheim das allgemeine Thema Anwesenheit. Mit dem Bluetooth vom PC, das funktioniert auch mit iPhones.
In diesem Thread geht es um BLE, hierfür werden Geräte benötigt, die dauerhaft BLE Advertisements senden. Und soweit ich weiß, senden iPhones nur bis die ihren Funk allgemein schlafen legen. Deshalb ist beim iPhones auch die Anwesenheit per WLAN ping nur eingeschränkt möglich. -
Ich denke, dass dieses Projekt die richtige Adresse für alle Interessenten ist:
Hier wird anscheinend alles geboten, um mehrere esp32 zu verwenden und daraus die eigene Position zu ermitteln.
EDIT:
Anscheinend ist espresense nur eine angenehme Art die ESPs zu flashen. Natürlich inkl einiger Vorteile dieser Firmware: statt MAC wird ein Fingerprint gesendet. Unkomplizierte Art der Konfiguration über Weboberfläche. Trilateration und Darstellung ist trotzdem zu erledigen. Wenn ich mit meinem FireTV Projekt durch bin, werde ich hier was versuchen... -
@giuseppes Bist du schon zum Testen gekommen?
-
@spezialtrick
Ja, allerdings mit der Erkenntnis, dass die esp32 ab ca. 4-6 absolut ungenau sind. Kann später mein Skript hochladen. Hatte es schon ziemlich generisch programmiert. Hatte zu Testzwecken folgendes umgesetzt:- Erstellen von Räumen in svg
- Darstellung der Radien der esp32
Es wird ein Datenpunkt erstellt und aktualisiert. So kann man sich ein Bild davon machen, wie genau die esp32 einen orten können.
Wollte schauen wie die Genauigkeit ist, bevor ich bzgl Trilateration etc weiter mach. Habe dann abgebrochen, d.h. Trilateration habe ich nicht integriert.
-
@giuseppes Danke für die kurzfristige Antwort!
War deine Erkenntnis, dass esp32 ab ca. 4-6m Entfernung ungenau werden oder wenn man 4-6 ESPs nutzt, Ungenauigkeiten auftreten?
-
Hat schon jemand das Appdaemon app eingesetzt?
https://github.com/ESPresense/ad-espresense-ips -
@spezialtrick
Ab ca 3m wird es immer ungenauer, sodass das Signal ab gut 4m eigentlich nicht mehr brauchbar ist. Dann würde die räumliche Zuordnung nicht mehr funktionieren. Alternativ müsste man entsprechend viele esp32 verteilen. Aber in meinen 90qm müssten es dann schon mindestens 7 Stück sein.@Muchul
Diese sogenannte App ist ein python script zugeschnitten auf Homeassistant. Die Triangulation ist zwar in einer separaten Unterfunktion, aber die Berechnung wird mit Hilfe weniger mathematischer Aufrufe aus python Bibliotheken durchgeführt. Ich habe nach Alternativen für JS gesucht aber bin nicht fündig geworden.
Grundsätzlich halte ich es aber eh für genauer, nur die nächstgelegenen 3 esp32 zu verwenden statt alle und ein best-fit zu berechnen. Schließlich nahm in meinem Test mit zunehmender Distanz die Genauigkeit massiv ab. Triangulation mit nur drei Punkten auf der Ebene habe ich schon. -
@giuseppes
Ich suche noch nach einer Möglichkeit, auf einer Karte anzuzeigen, wo der BLE Tag liegt.
Ich habe 100qm und 6 Räume. Ich wäre auch geneigt bis zu 10 esp32 Laufen zu lassen, aber Mangels Programmierkenntnisse wird es wohl schwierig.