NEWS

[Vorlage] Tado Heizung Skript



  • Moin Moin,

    ich geh man davon aus das nicht viele hier die Tado Thermostate nutzen, trotzdem möchte ich mein Skript hier vorstellen.

    Es ist noch in einem sehr frühen Stadium es geht noch nicht viel und es gibt auch noch Fehler !!

    Tado bietet noch immer keine Offizielle API, alles basiert auf dem Web-Interface

    Es Muss unter Authorisation der Username und das Passwort eingetragen werden

    Das Client_Secret sollte universell für die Web API sein, sollte dem nicht so sein, bitte um Rückmeldung

    createState('javascript.0.Tado.Authorization.Username','',{type: "string", role: "Username"});
    createState('javascript.0.Tado.Authorization.Password','',{type: "string", role: "Password"});
    createState('javascript.0.Tado.Authorization.Login','',{type: "boolean", role: "button"});
    createState('javascript.0.Tado.Authorization.Authorized',false,{type: "boolean", role: "Authorized",write:false});
    createState('javascript.0.Tado.GetZones','',{type: "boolean", role: "button"});  
    createState('javascript.0.Tado.GetZoneState','',{type: "boolean", role: "button"});
    var Application = {
        BaseURL:'https://my.tado.com/api/',
        Client_ID:'tado-web-app',
        Client_Secret:'wZaRN7rpjn3FoNyF5IFuxg9uMzYJcvOoQ8QWiIqS3hfk6gLhVlG57j5YNoZL2Rtc',
        Token:'', 
        refresh_token:'',
        HomeID:''
    };
    var ZoneIDs=[];
    function SendRequest(Endpoint,Method,Send_Body,callback){
    var options = {
        url: Application.BaseURL+Endpoint,
        method: Method,
        headers: {Authorization: 'Bearer '+Application.Token},
        form:Send_Body
    };
            request(options,function (error, response, body){
    
                    console.log(response.statusCode);
                    console.log(body);
    
                    switch (response.statusCode){
    
                        case 200: // OK
                                return callback(false,JSON.parse(body));
    
                        case 202: //Accepted, processing has not been completed.
    
                        break;
    
                        case 204: // OK, No Content
                                return callback(false,null);         
    
                        case 400: //Bad Request, message body will contain more information
                                return callback(true,null);
                         case 401: //Unauthorized 
    
                        RefreshToken(Application.refresh_token,function(err,access_token,refresh_token){
                            if(!err){
                                Application.Token=access_token;
                                Application.refresh_token=refresh_token;
                                console.log('Token erneuert !');
    
                                 SendRequest(Endpoint,Method,Send_Body,function(err,data){
    
                                     if(!err){return callback(false,data)}
                                     else{return callback(true,null)}
    
                                 });
                            }
                            else{return callback(true,null);}
    
                        });
                        break;
    
                         
                    default:
                            return callback(true,null);
                    }
    
            });
    }
     function GetToken(Password,Username,callback){
    var options = {
        url: 'https://auth.tado.com/oauth/token',
        method: 'POST',
        form: {grant_type:'password',password:Password,username:Username,scope:'home.user',client_id:Application.Client_ID,client_secret:Application.Client_Secret}
    };
         request(options, function (error, response, body){
            if (response.statusCode==200){
                P=JSON.parse(body);
                return callback(false,P.access_token,P.refresh_token);
            }
            else{ 
                console.warn(response.statusCode+' Login Error !');
                return callback(true,null,null);
            }
        });
     }//End of Function GetToken
     function RefreshToken(Refresh_Token,callback){
    var options = {
        url: 'https://auth.tado.com/oauth/token',
        method: 'POST',
        form: {grant_type:'refresh_token',scope:'home.user',client_id:Application.Client_ID,client_secret:Application.Client_Secret,refresh_token:Application.refresh_token}
    };
         request(options, function (error, response, body){
            if (response.statusCode==200){
                P=JSON.parse(body);
                return callback(false,P.access_token,P.refresh_token);
            }
            else{ 
                console.error(response.statusCode+' Fehler bei Refresh Token !');
                return callback(true,null,null);
            }
        });
     }//End of Function RefreshToken
     function GetZones(data,Pfad){
     for (var ObjName in data) {  
    
       var New_Pfad=Pfad+'.'+ObjName;
        console.log(ObjName)
    
        var Type=typeof data[ObjName];
    
        switch(Type){
    
            case 'object':
                console.log('ist Objekt')
                //console.log(ObjName)
                GetZones(data[ObjName],New_Pfad);
                break;
    
            case 'boolean':
            case 'string':
            case 'number':
            case 'none': 
    
                if (!getObject(New_Pfad)){
                                     createState(New_Pfad,     data[ObjName],    {type:Type,       role: ObjName});
                                 }
    
                                 else{setState(New_Pfad,data[ObjName],akt=true)}
                //console.log(ObjName)
            break;
    
            default:
    
            if (Array.isArray(data[ObjName])===true){
                console.log('ist Array')
                for (i = 0; i < data[ObjName].length; i++) {
    
                    GetZones(data[ObjName[i]]);
                }
            }
            else{console.log('is nix')}
            break;
        }
    } 
    }//End of Function 
     function GetZoneState(ZoneIDs){
        if ("undefined"== typeof  Intervall){
    
            Intervall = setInterval(function () {
    
                for (i = 0; i < ZoneIDs.length; i++) {
                    ZoneState(ZoneIDs[i]);
                }
              },10000);
    
        }
        else{clearInterval(Intervall)}
    
    }//End of Function    
     function ZoneState (id){
    SendRequest('v2/homes/'+Application.HomeID+'/zones/'+id+'/state','GET','',function(err,data){});    
    
    }
      on({id:'javascript.0.Tado.Authorization.Login'}, function (obj){ 
    
         var Username = getState('javascript.0.Tado.Authorization.Username').val;
         var Password = getState('javascript.0.Tado.Authorization.Password').val;
    
         GetToken(Password,Username,function(err,access_token,refresh_token){
    
        if(!err){
        //setState('javascript.0.Tado.Authorization.Username',val='',akt=true);
        //setState('javascript.0.Tado.Authorization.Password',val='',akt=true);
        setState('javascript.0.Tado.Authorization.Authorized',val=true,akt=true);
        Application.Token=access_token;
        Application.refresh_token=refresh_token;
    
        SendRequest('v1/me','GET','',function(err,data){
           if(!err){Application.HomeID=data.homeId}
        });
    
        }
        else{setState('javascript.0.Tado.Authorization.Authorized',val=false,akt=true);}
    
         });
    
      });
    
      on({id:'javascript.0.Tado.GetZones'}, function (obj){ 
    
                            SendRequest('v2/homes/'+Application.HomeID+'/zones','GET','',function(err,data){
           if(!err){GetZones(data,'javascript.0.Tado.Zones')}
        });
    
           
      });
       on({id:'javascript.0.Tado.GetZoneState'}, function (obj){ 
    
    GetZoneState([1,2,3]);
    
      });
    


  • danke für das script!!

    hatte mich die Tage auch mal an ein tado script gesetzt, aber dein script ist um einiges besser!

    Deshalb nehme ich nun auch deins 😉

    Wenn du schon eine neue Version hast wäre ich daran sehr interessiert!



  • Hallo Lucky,

    genau nach diesem Script habe ich gesucht.

    Wenn ich es jetzt aber ausführen, bekomme ich immer folgende Fehlermeldung:

    23:45:12.660 [error] javascript.0 script.js.Skript1: 401 Fehler bei Refresh Token !

    Könntest du mir erklären, woran das liegen könnte.

    Wünsche ein schönes Wochenende.



  • @senger1985:

    Hallo Lucky,

    genau nach diesem Script habe ich gesucht.

    Wenn ich es jetzt aber ausführen, bekomme ich immer folgende Fehlermeldung:

    23:45:12.660 [error] javascript.0 script.js.Skript1: 401 Fehler bei Refresh Token !

    Könntest du mir erklären, woran das liegen könnte.

    Wünsche ein schönes Wochenende. `

    Hast du deine Logindaten in die Datenpunkte die das Script erstellt eingetragen und dort über die buttons den Login gestartet?

    Ist der Datenpunkt 'javascript.0.Tado.Authorization.Authorized' auf true?

    Ich hatte auch mal ein kleines (nicht so umfangreiches wie das von Lucky) Script für tado zum auslesen der Werte geschrieben. schau mal hier, evtl hilft dir das auch weiter:

    http://forum.iobroker.net/viewtopic.php … 45#p112945



  • Hallo eXTreMe,

    Authorized ist bei mir auf "true", wie bekomme ich jetzt z. B. die aktuelle Temperatur im VIS angezeigt?



  • @senger1985:

    Hallo eXTreMe,

    Authorized ist bei mir auf "true", wie bekomme ich jetzt z. B. die aktuelle Temperatur im VIS angezeigt? `

    Habe mir das Script von Lucky (bzw die Datenpunkte die es erstellt) nun erstmal im Detail genau angeschaut…. es scheint alsob die Werte mit der aktuellen temperatur noch fehlen.

    In meinem Script habe ich das drin, da ist aber nur das problem, dass die werte nur aktualisiert werden, wenn das thermostat auch am heizen ist....

    bin leider auch kein script profi und habe auch nur wenig Ahnung von APIs. Ich hoffe dass Lucky demnächst eine neuere Version des Scripts mit uns teilt, in der auch die interessanten Datenpunkte wie Temperatur usw drin sind ;=) Er sagte ja, dass das Script noch in einem sehr frühen Stadium ist, vieles fehlt oder nicht richtig funktioniert.



  • @eXTreMe:

    @senger1985:

    Hallo eXTreMe,

    Authorized ist bei mir auf "true", wie bekomme ich jetzt z. B. die aktuelle Temperatur im VIS angezeigt? `

    Habe mir das Script von Lucky (bzw die Datenpunkte die es erstellt) nun erstmal im Detail genau angeschaut…. es scheint alsob die Werte mit der aktuellen temperatur noch fehlen.

    In meinem Script habe ich das drin, da ist aber nur das problem, dass die werte nur aktualisiert werden, wenn das thermostat auch am heizen ist....

    bin leider auch kein script profi und habe auch nur wenig Ahnung von APIs. Ich hoffe dass Lucky demnächst eine neuere Version des Scripts mit uns teilt, in der auch die interessanten Datenpunkte wie Temperatur usw drin sind ;=) Er sagte ja, dass das Script noch in einem sehr frühen Stadium ist, vieles fehlt oder nicht richtig funktioniert. `

    Eilt ja alles nicht.

    War/bin nur gerade dabei mir eine kleine "Schaltzentrale" zu basteln und habe halt nach eine Möglichkeit gesucht, die Werte von Tado auszulesen.

    Wünsche dir ein schönen Sonntag



  • Hallo,

    gibt es hier inzwischen eine Möglichkeit, auch die momentane Temperatur auszulesen?



  • @senger1985:

    Hallo,

    gibt es hier inzwischen eine Möglichkeit, auch die momentane Temperatur auszulesen? `

    Versuch mal mein Script, es liefert aber fehler wenn das Thermostat ausgeschaltet ist. Mir ist auch schonmal der Javascript Adapter dadurch abgeschmiert. Bin leider kein Script Profi.

    Das Skript ist auch etwas komplizierter einzurichten. Ich nutze es inzwischen auch selber garnicht mehr und warte darauf dass tado es endlich schafft eine öffentliche API rauszubringen.

    Zur Steuerung der Heizung habe ich einfach die tado login webseite in vis als iframe eingebunden. War das unkomplizierteste…

    Hier das Script, bitte die Hinweise in den Kommentaren im Code beachten!

    // tado Script für ioBroker
    // Version 0.1
    //
    // Anleitung:
    // 1\. Pro Thermostat muss ein Script erstellt und individuell konfiguriert werden!
    // 2\. Eindeutigen Raumname im Konfig-Bereich des Scripts für das Thermostat angeben. Bei mehreren Thermostaten in einem Raum bitte unterschiedliche Raumnamen verwenden.
    // 3\. Über folgende URL (Nutzername und Passwort in der URL angeben) per Webbrowser die HomeID ermitteln und in dem Konfigurations-Teil des Scripts eintragen:
    //    https://my.tado.com/api/v2/me?username=USERNAME&password=PASSWORT
    // 4\. Über folgende URL (HOME ID, Nutzername(E-Mail) und Passwort in der URL angeben, wenn das PW Sonderzeichen enthält dann müssen diese encodiert angegeben werden) per Webbrowser die ZoneID ermitteln und in dem Konfigurations-Teil des Scripts eintragen:
    //    https://my.tado.com/api/v2/homes/HOMEID/zones/2/state?username=USERNAME&password=PASSWORT
    //     - Die "2" im Link steht für ZoneID 2, in meinem Fall ist das das Thermostat im Wohnzimmer
    //     - am besten unterschiedliche Temperaturen in den Räumen per App einstellen und dann verschiedene Zahlen im Link durchprobieren)
    //
    //
    // Quellen die bei der Scripterstellung geholfen haben:
    // http://wirres.net/article/articleview/10326/1/6/
    // http://blog.scphillips.com/posts/2017/01/the-tado-api-v2/
     //Konfiguration:
    var Raumname = 'Wohnzimmer'; // Der hier angegebene Raumname dient zur Benennung des erzeugten Channel Objekts in ioBroker
    var ZoneID = "2"; // Zonennummer des Raums (muss über API URL ermittelt werden)
    var HomeID = "meine-home-id"; // HomeID aus API Abfrage
    var Username = "mein-nutzername"; // tado Username (E-Mail Adresse)
    var Password = "meinpasswort"; // tado Passwort (Sonderzeichen müssen encodiert eingetragen werden, z.B. # als %23 -> google hilft hier!)
     //Datenpunkterstellung:
    createState("tado." + Raumname + ".temperature", 0, false, {type: "number", name: "temperature", desc: "Eingestellte Temperatur", role: "value.temperature", unit: "°C", read: true, write: true});
    createState("tado." + Raumname + ".power", "OFF", false, {type: "string", name: "power", desc: "Aufheizen", read: true, write: true});
    createState("tado." + Raumname + ".inside_temperature", 0, false, {type: "number", name: "inside_temperature", desc: "Gemessene (Raum-)Temperatur", role: "value.temperature", unit: "°C", read: true, write: true});
    createState("tado." + Raumname + ".humidity", 0, false, {type: "number", name: "humidity", desc: "Luftfeuchtigkeit", role: "value.humidity", unit: "%", min: 0, max: 100, read: true, write: true});
    createState("tado." + Raumname + ".heatingpower", 0, false, {type: "number", name: "heatingpower", desc: "Heizkraft", unit: "%", min: 0, max: 100, read: true, write: true});
     // SCRIPTBEGINN - AB HIER NICHTS VERÄNDERN (außer den schedule zeitwert in der nächsten zeile der aktuell auf 10min gesetzt ist)!
    schedule("*/10 * * * *", function () { // Zeiteinstellung: Script aktualisiert alle 10 Min die Werte. Bei geringeren Abfrageintervallen kann es zu Verbindungsabbrüchen kommen und alle Geräte müssen neugestartet werden!
    
        //API URL mit Username und Passwort
    	var url = "https://my.tado.com/api/v2/homes/"+HomeID+"/zones/"+ZoneID+"/state?username="+Username+"&password="+Password;
       	//läd die Json herunter
      	var request = require("request");
        request(url, function (error, response, body) {
      	//parst die Json
        var json = JSON.parse(body);
    
        //Datenabfrage:
        //Temperatur:
      	setState("javascript.0.tado."+Raumname+".temperature", json.setting.temperature.celsius);
      	log('tado Temperatur '+Raumname+': ' + json.setting.temperature.celsius);
      	//Power:
      	setState("javascript.0.tado."+Raumname+".power", json.setting.power);
      	log('tado Power-Setting '+Raumname+': ' + json.setting.power);
      	//Humidity:
      	setState("javascript.0.tado."+Raumname+".humidity", json.sensorDataPoints.humidity.percentage);
      	log('tado Humidity '+Raumname+': ' + json.sensorDataPoints.humidity.percentage);
      	//Inside Temperature:
      	setState("javascript.0.tado."+Raumname+".inside_temperature", json.sensorDataPoints.insideTemperature.celsius);
      	log('tado Inside Temperature '+Raumname+': ' + json.sensorDataPoints.insideTemperature.celsius);
      	//Heating Power:
      	setState("javascript.0.tado."+Raumname+".heatingpower", json.activityDataPoints.heatingPower.percentage);
      	log('tado Heating Power '+Raumname+': ' + json.activityDataPoints.heatingPower.percentage);
      	});
    }); 
    


  • Hallo eXTreMe,

    dein Script habe ich versucht gehabt und er hat mir gar keine Werte ausgeworfen, leider.

    Aber super, dass du dich auch damit beschäftigst.



  • @senger1985:

    Hallo eXTreMe,

    dein Script habe ich versucht gehabt und er hat mir gar keine Werte ausgeworfen, leider.

    Aber super, dass du dich auch damit beschäftigst. `

    Hast du auch alle Anpassungen im Script vorgenommen?

    Username, Passwort, HomeID, usw. eingetragen?

    Du kannst auch über deinen Browser checken ob die von dir eingetragenen Daten korrekt sind indem du die API Links direkt aufrufst und deine Angaben dort reinsetzt.

    Link 1 zur ermittlung der HomeID (die HomeID dann im Link 2 einfügen):

    https://my.tado.com/api/v2/me?username=%5Bb%5DUSERNAME&password=PASSWORT

    Link 2 zur anzeige der Zone Nummer 2 (zahl kann geändert werden im link für andere räume)

    https://my.tado.com/api/v2/homes/%5Bb%5DHOMEID/zones/2/state?username=USERNAME&password=PASSWORT

    Wenn du alles richtig eingegeben hast sollten die Werte deines Thermostats in dem Raum mit der eingetragenen Zone ID angezeigt werden.

    bei mir sieht das z.B. so aus (damit es so geordnet angeziegt wird nutze ich das firefox addon "json viewer")
    2665_tado.png



  • ioBroker möchte mich einfach etwas ärgern und es mir komplizierter machen, als es eigentlich sein muss.

    Darum nutze ich inzwischen aber auch die "iframe"-Variante! 😉



  • Habe es mal in die Adapter Request Liste aufgenommen:

    https://github.com/ioBroker/AdapterRequests/issues/71



  • Heute kam ein Update der Tado-App(Android), welches jetzt auch die Luftqualität und den Pollenflug anzeigt.

    Weiß jemand, ob und wenn, wie ich diese Daten jetzt in den ioBroker bekomme?


  • Developer Most Active Administrators

    Ab jetzt auch als adapter verfügbar : https://forum.iobroker.net/topic/25723/aufruf-neuer-adaper-tado

    luftkwalitaet und Pollenflug hab ich in der API noch nicht gesehen aber schau es mir mal an.

    Bitte issue auf GitHub beim adapter anlegen damit es nicht vergessen wird



Suggested Topics

  • 2
  • 288
  • 5
  • 8
  • 7
  • 16
  • 5
  • 3

1.9k
Online

32.1k
Users

38.8k
Topics

526.1k
Posts