AVM Fritz Binding DECT 200/210 - update interval

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.

curl -d 'sid=123456790&c=smarthome&a=getData' http://fritz.box/myfritz/api/data.lua

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 :frowning:

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” :slight_smile:

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?

Many thanks.

Have you tried to use executecommandline and a shell script? md5sum is command that is available using a shell.

Sorry for the late reply. I didn’t test this yet.
Was just wondering whether to install the Java MD5 library.

I found a solution using JavaScript :slight_smile:
I can share the approach, in case someone is interested.

1 Like

Why not without that anyone is showing interest ?

1 Like

Hello Wolfgang,

no problem - Its maybe not the best optimized code, but it works. :slight_smile:

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();
  }  
  
}





 
3 Likes