This is my solution how to visualize the status (Online / Offline) of zigbee devices in OpenHAB Android / iOS app by integrating a webview element in my sitemap.
The Rule uses Rest API to query information about devices belonging to a specific zigbee coordinator. You do not need to specifiy your devices, everything is being collected automatically. You only need to insert the UID of your zigbee coordinator in the .rules file.
Annotations:
- This only works for zigbee binding, not for zigbee2mqtt!
- It can be useful to monitor devices that may periodically fail (e.g. Xiaomi sensors) or devices that might have range issues.
- This can also be a starting point to query other information about the devices (e.g. link quality, power level, …).
How the result will look like in OpenhHAB App:
How to set up
-
Create a .rules-File in your rules-directory and copy/paste the content below.
-
At the very beginning of the rule, adjust the string “Coordinator” to the UID of your zigbee coordinator. You can find this UID e.g. in Paper UI:
You may also want to adjust the trigger of the rule. It is configured to run every ten minutes, of course this can be changed. -
Include the ZigbeeStatus.html file in your sitemap by using a webview element:
Text label="Zigbee Status" icon="text" {
Webview url="static/ZigbeeStatus.html"
}
The url “static/ZigbeeStatus.html” without IP-adress/hostname works fine for me for the OpenHAB Android app (local access or remote access via OpenHAB cloud). You may need to adjust the URL to get it working in a browser.
Now here is the Rule:
rule "Zigbee Status"
when
//Rule will run every 10 minutes
Time cron "0 0/10 * 1/1 * ? *"
then
//Edit your coordiantor UID
var String Coordinator = "zigbee:coordinator_ember:013827EC"
//Process coordinator information
var String url = String::format("http://127.0.0.1:8080/rest/things/%s", Coordinator)
var String json = sendHttpGetRequest(url)
var String sLabelCoordinator = transform("JSONPATH", "$.label", json)
var String sStatusCoordinator = transform("JSONPATH", "$.statusInfo.status", json)
//Build coordinator HTML table rows
var String sTableCoordinator = "<tr><td>" + sLabelCoordinator + "</td><td>"
if (sStatusCoordinator == "ONLINE") {
sTableCoordinator += "<font color=\"green\">"
} else if (sStatusCoordinator == "OFFLINE") {
sTableCoordinator += "<font color=\"red\">"
} else {
sTableCoordinator += "<font color=\"grey\">"
}
sTableCoordinator += sStatusCoordinator + "</td></tr>"
//Process nodes / devices
url ="http://127.0.0.1:8080/rest/things"
json = sendHttpGetRequest(url)
var String sDevices = transform("JSONPATH", "$[?(@.bridgeUID == '" + Coordinator +"')].UID", json)
var Number nDevices = Integer::parseInt(transform("JSONPATH", "$.length()", sDevices))
//Only for debugging
//logInfo("Rules", "STemp: {}", sDevices)
//logInfo("Rules", "Length: {}", nDevices)
//Build node HTML table rows
var Number i = 0
var String sTable = ""
while (i < nDevices) {
var String sTemp = transform("JSONPATH", "$[" + i.toString +"]", sDevices)
var String sLabel = transform("JSONPATH", "$[?(@.UID == '" + sTemp + "')].label", json)
var String sStatus = transform("JSONPATH", "$[?(@.UID == '" + sTemp + "')].statusInfo.status", json)
sTable += "<tr><td>" + sLabel + "</td><td>"
if (sStatus == "ONLINE") {
sTable += "<font color=\"green\">"
} else if (sStatus == "OFFLINE") {
sTable += "<font color=\"red\">"
} else {
sTable += "<font color=\"grey\">"
}
sTable += sStatus + "</td></tr>"
//Only for debugging
//logInfo("Rules", "i: {}", i)
//logInfo("Rules", "sLabel: {}", sLabel)
//logInfo("Rules", "sStatus: {}", sStatus)
i += 1
}
//Create html content
var sHTML = "<html><body><table style=\"width:100%\"><tr><th style=\"text-align:left\">Coordinator</th><th style=\"text-align:left;width:80px\">Status</th></tr>" + sTableCoordinator + "</table><br><table style=\"width:100%\"><tr><th style=\"text-align:left\">Node</th><th style=\"text-align:left;width:80px\">Status</th></tr>" + sTable + "</table><br>Total Nodes: " + nDevices.toString + "</body></html>"
//Write file to disc
var sCommand = "/bin/sh@@-c@@(echo '"+ sHTML + "' > /etc/openhab2/html/ZigbeeStatus.html) >/dev/null 2>&1; echo $?"
var String sResult = executeCommandLine(sCommand, 5000)
//Only for debugging
//logInfo("Rules", "Exec Result: {}", sResult)
//Log write error
if (sResult != "0") {
logError("Rules", "Error writing Zigbee Status HTML-File. Please check permissions!")
}
end
The rule will create the file “ZigbeeStatus.html” in the folder “/etc/openhab2/html/”. If you adjust the path, just make sure the user “openhab” has write access to this folder.
Have fun!