Fritzbox
A router can be used to detect if somebody is present at a location with a WIFI network. The Fritzbox integration connects to the router and retreives a list of devices that are connected. You can use this integration to show a screen at the office that automatically shows who is present based on the WIFI connection of their phone. This may help to comply to legal requirements in some buildings that mandate that at all times a list of all persons in the building should be maintained. The information about presence can also be used to automatically turn on heating, cooling, lights and other devices based on current building occupancy.
Script
Create a new script with name Fritzbox
. The script shows how you can implement a more complex multi pass authentication for accessing the device information. The script first connects to the router with the username to request a token called Challenge
. This token is combined with the password and encoded to a UTF-16LE string. This is used to request a token and the response is an XML file. The XML is converted to JSON and the session is SID
is obtained. In a third call the state of the router is requested via an HTTP request. If the object passed to the get
functions is found in the net.devices
JSON array the value is set to 1
, or else 0
.
const get = async (object, context) => {
let connections = await devices(context)
let connected = connections.find(item => item.name === object) ? 1: 0
return {object, connected}
}
const devices = async (context) => {
let sid = await SID(context);
let res = await http.get(context.host + '/data.lua?sid=' + sid, "1 minute")
let devices = res.data.net.devices;
return devices
}
const SID = async (context) => {
let response = await http.get(context.host + '/login_sid.lua?username=' + context.username, "1 minute");
let json = await xml.toJson(response).then(result => {return(result)}).catch(err=>error(err));
let challenge = json.SessionInfo.Challenge;
let token = encryption.encode(challenge + '-' + context.password, "UTF-16LE");
token = encryption.md5(token)
response = await http.get(context.host + '/login_sid.lua?username=' + context.username + '&response='+challenge+'-'+token, "1 minute");
json = await xml.toJson(response).then(result => {return(result)}).catch(err=>error(err));
return json.SessionInfo.SID
}
Note that you can test the script before running the importer. To paste the code below in the test
field of the script and click Run
.
let context = await encryption.secret('Fritzbox');
let home = await get('iPhoneGary', context)
print(JSON.stringify(home))
Datasource
Create a new secret with a type
set to script
and fields for the host
, username
and password
. The host
should be the URL to the admin port of the router, such as https://fritzbox.mydomain.com:1443
.
Importer
Create a new importer and set the Datasource
to the secret that defines the Fritzbox connection. Add one or more objects for which the script should be called. The field Object
should contain the name of the device as it is registed with the router, typically the name of the smartphone.
Form
Create a new form with the definition below. The form has three 'led' like symbols that turn green if the person is home and grey if not. The form has tree items where the <
symbol is used to define an input formula for displaying the value. The [led]
field indicates that the form control should be a led and the |4
means that each control should take 4 of 12 columns in a row.
Presence
Alice Wood
<alice.present
[led]
|4
Bob Smith
<bob.present
[led]
|4
Charlie Green
<charlie.present
[led]
|4
After running the connector go to items
and search for the item home.presence
. If you open the item the newly created form with be used