Dieser Beitrag wurde seit einem Jahr nicht mehr aktualisiert. Im Internet ist das manchmal eine halbe Ewigkeit. Es kann daher sein, dass die Informationen und Links nicht mehr aktuell sind.
Gäste-WLAN an- und ausschalten, eine Benachrichtigung über eingehende Anrufe oder eine Anwesenheitserkennung. Mit Node-RED und homee lässt sich eine FritzBox noch etwas smarter machen.
UPDATE:
Leider funktioniert das bisher verwendete Plugin node-red-contrib-fritzbox-presence
nicht mit FritzOS >= Version 7. Daher wurde die Anleitung mit einer Alternative aktualisiert. Gleichzeitig wurde der Flow zur Benachrichtigung von neuen Anrufern über eine Anrufer Erkennung ergänzt.
Installation
Für diese Funktionen benötigen wir NodeJS und Node-RED. Eine detaillierte Installationsanleitung findest Du im Post Virtuelle Geräte in homee. Außerdem sollte Dein homee mindestens Version 2.15 haben.
Zusätzlich benötigen wir ein Plugin für Node-RED welches wir mit folgenden Befehlen installieren:
cd ~/.node-red
npm install node-red-contrib-fritz
Damit das neue Plugins in Node-RED zur Verfügung steht, muss Node-RED neu gestartet werden. Das FritzBox Plugin nutzt zur Kommunikation die TR064 Schnittstelle die wir zuerst aktivieren müssen.
Aktivierung der TR064 API der FritzBox
Die Aktivierung kann über ein angeschlossenes Telefon erfolgen. Damit rufen wir die Ziffernfolge #96*5*
an. Zum Deaktivieren kann die Folge #96*4*
verwendet werden.
Weitere Informationen zur TR064 Schnittstelle gibt es hier von AVM.
Steuerung des Gäste-WLAN
Das Ein- und Ausschalten des Gäste-WLAN über die Oberfläche der FritzBox ist umständlich und lässt nur eine eingeschränkte Automation zu. Einfacher ist ein Schalten mit Hilfe eines virtuellen Geräts in homee. Der Schaltzustand des Gäste-WLAN kann dann auch als Auslöser für Homeegramme dienen. Genauso kann das Gäste-WLAN über ein Homeegramm ein und ausgeschaltet werden.
Für den Flow brauchen wir ein virtuelles WeMo Gerät, eine Funktion und den Fritz!Box Node. Das virtuelle WeMo Gerät konfigurieren wir mit den Payloads on
und off
.
Die Funktion sieht dann so aus
return {
payload: {
NewEnable: msg.payload === 'on' ? 1 : 0
}
};
Jetzt muss noch der Fritz Node konfiguriert werden. Mit einem Doppelklick auf den Node kommen wir in das Konfigurationsmenü und legen dort eine neue Fritz Box Konfiguration an.
Im Anschluss fragen wir die Services über den Button mit der Lupe ab. Je nach Modell der FritzBox kann das ein wenig dauern. Wenn nach einer Minute noch nichts im Dropdown Feld zu finden ist, einfach noch mal auf die Lupe klicken. Über die Liste wählen wir dann urn:dslforum-org:service:WLANConfiguration:3
aus.
Die gleiche Prozedur wiederholen wir beim Feld Actions. Dort wählen wir SetEnable
aus der Liste.
Jetzt kann der Schalter wie gewohnt in homee integriert oder mit einer anderen Software genutzt werden.
Gäste-WLAN Flow zum Download
[{"id":"986380e9.875368","type":"wemo-emulator","z":"5635fba3.2a0f44","name":"Guest Wifi","friendlyName":"Gäste WLAN","serial":"2938562","port":"41257","onTopic":"guest/wifi","onPayload":"on","offTopic":"guest/wifi","offPayload":"off","x":140,"y":280,"wires":[["db14626a.1d0d78"]]},{"id":"db14626a.1d0d78","type":"function","z":"5635fba3.2a0f44","name":"","func":"return {\n payload: {\n NewEnable: msg.payload === 'on' ? 1 : 0\n }\n};","outputs":1,"noerr":0,"x":290,"y":280,"wires":[["29bd9fc3.416"]]},{"id":"29bd9fc3.416","type":"fritzbox-in","z":"5635fba3.2a0f44","device":"61f053c7.62e594","name":"Gäste WLAN","service":"urn:dslforum-org:service:WLANConfiguration:3","action":"SetEnable","arguments":"{\"NewEnable\":\"value\"}","x":450,"y":280,"wires":[["97dece21.1bd53"]]},{"id":"97dece21.1bd53","type":"debug","z":"5635fba3.2a0f44","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":630,"y":280,"wires":[]},{"id":"61f053c7.62e594","type":"fritzbox-config","z":"","name":"FritzBox","host":"fritz.box","port":"49000","ssl":false}]
Benachrichtigung bei eingehenden Anrufen
Als nächstes erstellen wir einen Flow, der uns bei eingehenden Anrufen benachrichtigt und die anrufende Nummer im Telefonbuch der FritzBox nachschlägt. Wird ein Name gefunden, wird dieser zusätzlich mit ausgegeben. Die Benachrichtigung wird über Slack versandt; zusätzlich wird ein Webhook in Richtung von homee abgesandt. Natürlich sind auch andere Anbindungen, wie Telegram, Pushover oder E-Mail denkbar.
Der Callmonitor ist unser Ausgangspunkt. Im Konfigurationsmenü wählen wir unsere bereits erstellte FritzBox aus. Daran knüpfen wir den FritzBox-Lookup-Node. Hier ebenfalls wieder die zuvor eingerichtete FritzBox auswählen und im Feld Phonebook eine 0
erfassen. Letzteres wählt das Standardtelefonbuch.
Immer wenn ein Anruf eingeht, wird eine Nachricht erzeugt und an den nächsten Node weitergegeben. Der nächste Node sucht im Telefonbuch nach dem Anrufer und gibt diesen weiter. Neben eingehenden Anrufen werden auch nicht angenommene Anrufe gemeldet. Um nur eine Benachrichtigung bei eingehenden Anrufen und die Nachricht zu bauen, verwenden wir einen Funktions-Node.
// only incoming calls
if (msg.payload.type !== "INBOUND") return;
var response = 'Eingehender Anruf von: ';
if (msg.payload.caller_contacts.length) {
response += msg.payload.caller_contacts[0].person.realName + ' (' + msg.payload.caller + ')';
} else {
response += msg.payload.caller;
}
return { payload: response };
Die Funktion sorgt dafür, dass der Flow nur bei eingehenden Anrufen fortgesetzt und der Text “Eingehender Anruf von: [Name] ([Rufnummer])” bzw. “Eingehender Anruf von: [Rufnummer]” weitergegeben wird. Diese Nachricht wird an den Slack Node übermittelt.
Gleichzeitig wird ein Request Node dazu verwendet, einen Webhook in homee zu triggern.
Flow zum Download
[{"id":"32652d98.479a2a","type":"fritzbox-callmonitor","z":"2f1c2bc0.e5659c","device":"61f053c7.62e594","name":"","topic":"","x":180,"y":60,"wires":[["b7bdb240.1fd1b8"]]},{"id":"2c7d31b7.dddede","type":"slack","z":"2f1c2bc0.e5659c","name":"","channelURL":"https://hooks.slack.com/services/[...]","username":"MeinZuhause","emojiIcon":"","channel":"","x":670,"y":180,"wires":[]},{"id":"d05ebfc0.94bca8","type":"http request","z":"2f1c2bc0.e5659c","name":"","method":"GET","ret":"txt","url":"https://[homee-id].hom.ee/api/v2/webhook_trigger?webhooks_key=[webhook-key]&event=anruf","tls":"","x":590,"y":260,"wires":[["51d48672.1b2b7"]]},{"id":"b7bdb240.1fd1b8","type":"fritzbox-contact","z":"2f1c2bc0.e5659c","device":"61f053c7.62e594","name":"","topic":"","phonebook":"0","ccode":"DE","x":330,"y":120,"wires":[["78d007d6.44b8b"]]},{"id":"78d007d6.44b8b","type":"function","z":"2f1c2bc0.e5659c","name":"parse response","func":"// only incoming calls\nif (msg.payload.type !== \"INBOUND\") return;\n\nvar response = 'Eingehender Anruf von: ';\n\nif (msg.payload.caller_contacts.length) {\n response += msg.payload.caller_contacts[0].person.realName + ' (' + msg.payload.caller + ')';\n} else {\n response += msg.payload.caller;\n}\n\nreturn { payload: response };","outputs":1,"noerr":0,"x":460,"y":180,"wires":[["2c7d31b7.dddede","d05ebfc0.94bca8"]]},{"id":"51d48672.1b2b7","type":"debug","z":"2f1c2bc0.e5659c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":790,"y":260,"wires":[]},{"id":"61f053c7.62e594","type":"fritzbox-config","z":"","name":"FritzBox","host":"fritz.box","port":"49000","ssl":false}]
Anwesenheitserkennung für beliebig viele Personen
Last but not least wollen wir uns noch eine automatische Anwesenheitserkennung über die Anwesenheit des Smartphones bauen. Dazu fragen wir die an der FritzBox angemeldeten Geräte in einem definierten Intervall ab. Über einen Abgleich der eindeutigen MAC-Adresse der Geräte, kann der Anwesenheitsstatus ermittelt werden.
Den FritzBox-Node konfigurieren wir mit dem Service urn:dslforum-org:service:Hosts:1
und als Action wählen wir X_AVM-DE_GetHostListPath
. Der Node meldet uns bei der Ausführung einen Pfad samt Authentifizierungsschlüssel zurück, den wir für einen weiteren Request in Richtung FritzBox benötigen.
In der Konfiguration des Request Nodes geben wir die URL http://fritz.box:49000@{{{payload.NewX_AVM-DE_HostListPath}}}
wie im nächsten Screenshot gezeigt an. Bitte verwendet bei der URL unbedingt je drei geschweifte Klammern, sonst funktioniert die Übergabe der Variable nicht.
Die FritzBox antwortet dann mit einer Geräteliste im XML-Format, die unter anderem die Mac- und IP-Adressen sowie den Online-Status der angemeldeten Geräte enthält. Praktischerweise bringt Node-RED von Haus aus einen Node mit, der XML in JSON umwandeln kann.
Nach der Umwandlung mit Hilfe des XML Nodes enthält der Payload unseres Flows nun einen Array mit den Geräten, den wir in einer Funktion weiter verarbeiten können.
const devices = msg.payload.List.Item;
const macs = ['A1:B2:C3:D4:B5:F4', 'A1:B2:D7:49:AC:34'];
let state = false;
for (let i=0; i<devices.length; i++) {
if (macs.indexOf(devices[i].MACAddress[0]) > -1 && devices[i].Active[0] === "1") {
state = true;
}
}
if (state === context.get('oldState')) return;
context.set('oldState', state);
return state ? [msg, null] : [null, msg];
Die Funktion durchsucht den Array nach den festgelegten Mac-Adressen und prüft gleichzeitig den Online-Status des Gerätes. Dieser wird durch das Attribut Active
als String ("0"
oder "1"
) ausgewiesen. Sobald ein Gerät als Anwesend erkannt wurde, wird der Status auf true
gesetzt.
Um nur echte Statusänderungen weiterzuleiten, greifen wir auf eine Variable oldState
zu, die wir im Context des Nodes speichern und von dort wieder abrufen. Weicht der neue state
vom oldState
ab, wird eine Nachricht versendet. Mehr zum Speichern von Werten findet man in der offiziellen Node-RED Dokumentation.
Um einen Node einzusparen, bietet der Funktions-Node zwei Ausgänge. Einen für den Status Anwesend, einen für den Status Abwesend. Dabei wird der erste (obere) Ausgang für die Meldung der Anwesenheit und der zweite (untere) Ausgang für die Meldung der Abwesenheit verwendet.
Jetzt muss der Wert noch an homee übermittelt werden. Dazu gibt es zwei Möglichkeiten. Variante 1 ist das Auslösen eines Webhooks. Als Alternative kann auch mein Node-RED Plugin für homee genutzt werden. Ich werde hier nur die erste Variante beschreiben.
Wir erstellen zunächst zwei Homeegramme. Eins für den Status Anwesend, das zweite für den Status Abwesend. Als Auslöser verwenden wir jeweils einen Webhook und als Aktion verändern wir den Modus in Zuhause bzw. Abwesend. Damit der Modus Urlaub nicht durch den Status Abwesend verändert wird, legen wir im zweiten Homeegramm eine zusätzliche Bedingung an.
Für das Auslösen des Webhooks brauchen wir dann jeweils einen HTTP Request Node, den wir wie im Bild konfigurieren. Im Feld URL fügen wir unseren Webhook aus homee ein.
Nach dem Deployen des Flows wird nun alle 20 Sekunden der Anwesenheitsstatus überprüft und automatisch an homee übermittelt.
Flow für die Anwesenheitserkennung in Node-RED zum Download
[{"id":"8547a62b.261318","type":"function","z":"2f1c2bc0.e5659c","name":"parse response","func":"const devices = msg.payload.List.Item;\nconst macs = ['A1:B2:C3:D4:B5:F4', 'A1:B2:D7:49:AC:34'];\n\nlet state = false;\n\nfor (let i=0; i<devices.length; i++) {\n if (macs.indexOf(devices[i].MACAddress[0]) > -1 && devices[i].Active[0] === \"1\") {\n state = true;\n }\n}\n\nif (state === context.get('oldState')) return;\n\ncontext.set('oldState', state);\n\nreturn state ? [msg, null] : [null, msg];","outputs":2,"noerr":0,"x":440,"y":600,"wires":[["12b83e74.f3068a"],["fbbc4496.707ed8"]]},{"id":"96c4ff22.8fcf2","type":"xml","z":"2f1c2bc0.e5659c","name":"","property":"payload","attr":"","chr":"","x":350,"y":540,"wires":[["8547a62b.261318"]]},{"id":"12b83e74.f3068a","type":"http request","z":"2f1c2bc0.e5659c","name":"Anwesend","method":"GET","ret":"txt","url":"http://[homee-id]/api/v2/webhook_trigger?webhooks_key=[webhook-key]&event=zuhause","tls":"","x":633,"y":580,"wires":[["556d3d5d.9f2a1c"]]},{"id":"fbbc4496.707ed8","type":"http request","z":"2f1c2bc0.e5659c","name":"Abwesend","method":"GET","ret":"txt","url":"http://[homee-id]/api/v2/webhook_trigger?webhooks_key=[webhook-key]&event=Abwesend","tls":"","x":633,"y":620,"wires":[["556d3d5d.9f2a1c"]]},{"id":"9d3ded91.a8985","type":"http request","z":"2f1c2bc0.e5659c","name":"","method":"GET","ret":"txt","url":"http://fritz.box:49000@{{{payload.NewX_AVM-DE_HostListPath}}}","tls":"","x":270,"y":480,"wires":[["96c4ff22.8fcf2"]]},{"id":"556d3d5d.9f2a1c","type":"debug","z":"2f1c2bc0.e5659c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":810,"y":600,"wires":[]},{"id":"2cb8d0b3.406b88","type":"fritzbox-in","z":"2f1c2bc0.e5659c","device":"61f053c7.62e594","name":"","service":"urn:dslforum-org:service:Hosts:1","action":"X_AVM-DE_GetHostListPath","arguments":"{}","x":190,"y":420,"wires":[["9d3ded91.a8985"]]},{"id":"e3c594a3.28927","type":"inject","z":"2f1c2bc0.e5659c","name":"every 20s","topic":"","payload":"","payloadType":"date","repeat":"20","crontab":"","once":true,"onceDelay":0.1,"x":130,"y":360,"wires":[["2cb8d0b3.406b88"]]},{"id":"61f053c7.62e594","type":"fritzbox-config","z":"","name":"FritzBox","host":"fritz.box","port":"49000","ssl":false}]