The AVM Binding does receive updates from Fritz DECT 200/210 plugs only every 2min, although the interval in Thing configuration is 15sec by default. This interval is very long for power measuremnts.
I found an article that the measurement interval can be decreased down to 10sec, by connecting to the FritzBox UI and looking at the consumption data.
I tested this behavior on my network and can confirm that it works.
The binding received the power values from my dryer and washing machine every 2min.
As soon as I connected to my FritzBox and checked the consumption data on the Energy page, the interval changed and the binding was updated every 10sec instead of 2min.
I tried to used the HTTP binding to connect to the FritzBox in parallel, to trigger the 10sec refresh interval.
However I’m failing with the HTTP binding - I guess due to the authentication method using Session ID (SID), but maybe I did something else wrong
I also tried to create a script, as descripted in the article. However it is required to create a MD5 Hash - but I don’t know whether this is supported with JavaScript in OH4.1?
The best approach would be for sure, if the AVM FritzBox Binding could be updated with the “feature”
Maybe someone can support in either of the points:
how to use HTTP binding with Session ID?
how to generate a MD5 Hash?
could this feature be added to AVM FritzBox binding?
no problem - Its maybe not the best optimized code, but it works.
I refresh two devices - the ID was retrieved using the network monitor in Firefox tools.
I trigger the rule if either the Dryer or Washing machine gets started.
this.OPENHAB_CONF = (this.OPENHAB_CONF === undefined) ? java.lang.System.getenv("OPENHAB_CONF") : this.OPENHAB_CONF;
var log = Java.type("org.slf4j.LoggerFactory").getLogger("org.openhab.model.script.Rules.FritzRefresh_md5");
var MessageDigest = Java.type("java.security.MessageDigest");
var IP_ADDR = "FritzBox IP Address";
var TIMEOUT = 5000;
var USERNAME = "YourUsername";
var PASSWORD = "YourPassword";
var PostRequest = function (uri, contentType, content, timeout){
return actions.HTTP.sendHttpPostRequest(uri, contentType, content, timeout);
}
var GetRequest = function (uri){
return actions.HTTP.sendHttpGetRequest(uri);
}
var RefreshPage = function (SID){
// devices IDs I want to refresh
// ID value was retrieved using Browser Network Tools
// 16 = Washmaschine
// 17 = Dryer
var itemID = ["16", "17"];
for ( i = 0; i < itemID.length; i++){
var uri = "http://" + IP_ADDR + "/net/home_auto_query.lua?sid=" + SID +"&command=EnergyStats_10&id=" + itemID[i] + "&useajax=1&xhr=1&t=nocache";
var getResponse = GetRequest(uri);
log.debug("Refresh: getResponse ID: {} -- {}" ,itemID[i], getResponse);
}
return;
}
var GetSessionId = function(username, password) {
var getResponse = GetRequest("http://" + IP_ADDR + "/login_sid.lua");
var response = ReadResponse(getResponse);
if ( response.sid == "0000000000000000") {
var uri = "http://" + IP_ADDR + "/login_sid.lua?username=" + username ;
var contentType = "application/x-www-form-urlencoded";
var contentString = "response=" + GetHash(response.challenge, password);
var postResponse = PostRequest(uri, contentType, contentString, TIMEOUT);
var response = ReadResponse(postResponse);
if (response.sid == "0000000000000000") {
log.warn ("Wrong Username/Password!");
if (response.blocktime != 0){
log.warn ("Blocktime: {} sec.", response.blocktime);
}
}
else {
log.info ("Loging SUCCESS - Assigned SID: " + response.sid);
}
}
return response.sid;
}
var CleanPassword = function (password){
return password.replaceAll(/[^\x00-\xFF]/gi,".");
}
var GetHash = function (challenge, password) {
return challenge + "-" + GetMD5Hash(challenge + "-" + CleanPassword(password));
}
var ReadResponse = function (response){
return {"sid": parseXML(response, ".*<SID>(.*)<\/SID>.*"),
"challenge" : parseXML(response, ".*<Challenge>(.*)<\/Challenge>.*"),
"blocktime" : parseInt(parseXML(response, ".*<BlockTime>(.*)<\/BlockTime>.*"))};
}
var parseXML = function (value, RegEx) {
return actions.Transformation.transform("REGEX", RegEx , value);
}
var GetMD5Hash = function (string){
var md = MessageDigest.getInstance("MD5");
var string_bytes = string.getBytes("UTF-16LE");
md.update(string_bytes);
var md5bytes = md.digest();
var string = "";
for ( i = 0; i < md5bytes.length; i++) {
string += ( 0 + (md5bytes[i] & 0xFF).toString(16)).slice(-2);
}
return string;
}
var Logout = function (){
clearInterval(this.intervalId);
this.intervalId = undefined;
var getResponse = GetRequest("http://" + IP_ADDR + "/login_sid.lua?logout=1&sid=" + this.SID);
this.SID = ReadResponse(getResponse).sid;
log.info("Logout: {}", this.SID);
}
if (this.intervalId === undefined && event.itemState.toString() === "ON"){
this.SID = GetSessionId(USERNAME, PASSWORD);
this.intervalId = setInterval(function(){
if (this.SID != "0000000000000000") {
RefreshPage(this.SID);
}
else{
this.SID = GetSessionId(USERNAME, PASSWORD);
}
}, delay = 30000);
}
else if (event.itemState.toString() === "OFF"){
// only clear the interval if both devices are OFF
if (event.itemName == "item_AVM_Waschmaschine_Steckdose" && items.item_AVM_Trockner_Steckdose.state === "OFF"){
Logout();
}
else if (event.itemName == "item_AVM_Trockner_Steckdose" && items.item_AVM_Waschmaschine_Steckdose.state === "OFF"){
Logout();
}
}