Benutzer-Werkzeuge

Webseiten-Werkzeuge


php:tado

Tado° ReST-API - Heizungssteuerung mit PHP

Die Firma tado GmbH produziert smarte Heizkörper-Thermostate, die sehr einfach gegen herkömmliche manuelle Thermostate ausgetauscht werden können. Neben den zahlreichen Features, welche die tado APP anbietet, besteht auch die Möglichkeit, die Thermostate über eine ReST-API anzusprechen. Mit der folgenden PHP-Klasse ist es möglich, die Thermostate per PHP auszulesen und zu steuern.

Um die Klasse benutzen zu können sind hier noch Benutzername und Passwort zu ergänzen, wobei der Benutzername der E-Mail-Adresse, mit der Ihr Konto bei Tado angelegt wurde, entspricht.

classTado.php
class Tado
{
    const PRESENCE_HOME = 'HOME';
    const PRESENCE_AWAY = 'AWAY';
 
    private $token      = '';
    private $homeId      = 0;
    private $zones      = [];
 
    private $endpoint   = '';
    private $username   = '';
    private $password   = '';
 
    public function __construct()
    {
        $content = file_get_contents( 'https://my.tado.com/webapp/env.js' );
 
        foreach( [ 'tgaRestApiV2Endpoint', 'apiEndpoint', 'clientId', 'clientSecret' ] as $var )
        {
            preg_match( sprintf( "/%s: '(.*)'/", $var ), $content, $matches );
 
            if( count( $matches ) === 2 )
            {
                $parameter[] = $matches[1];
            }
        }
 
        $this->endpoint = $parameter[0];
        $this->setBearerToken( $parameter );
        $this->setHomeId();
        $this->setZones();
    }
 
    private function setBearerToken( $parameter )
    {
        $data['client_id']      = $parameter[2];
        $data['client_secret']  = $parameter[3];
        $data['grant_type']     = 'password';
        $data['scope']          = 'home.user';
        $data['username']       = $this->username;
        $data['password']       = $this->password;
 
        $result = $this->curl( $parameter[1] . '/token', 'POST', $data );
 
        if( isset( $result->access_token ) )
        {
            $this->token = $result->access_token;
        }
    }
 
    private function setHomeId()
    {
        $result = $this->curl( $this->endpoint . '/me', 'GET' );
        $this->homeId = $result->homes[0]->id;
    }
 
    private function setZones()
    {
        $result = $this->curl( sprintf( $this->endpoint . '/homes/%s/zones', $this->homeId ), 'GET' );
        $this->zones = $result;
    }
 
    /**
     * @param $name
     * @return integer|false
     */
    private function getZoneId( $name )
    {
        foreach( $this->zones as $zone )
        {
            if( utf8_decode( $zone->name ) === $name )
            {
                return $zone->id;
            }
        }
 
        return false;
    }
 
    public function getSetting( $zone = null )
    {
        if( $zone === null )
        {
            $path = sprintf( $this->endpoint . '/homes/%s/state', $this->homeId, $zone );
            return $this->curl( $path, 'GET' );
        }
 
        $path = sprintf( $this->endpoint . '/homes/%s/zones/%d/state', $this->homeId, $zone );
        $result = $this->curl( $path, 'GET' );
        unset( $result->setting->temperature->fahrenheit );
        return $result->setting;
    }
 
    public function setPresence( $presence )
    {
        $data = new stdClass();
        $data->homePresence = $presence;
 
        $path = sprintf( $this->endpoint . '/homes/%s/presenceLock', $this->homeId );
        $this->curl( $path, 'PUT', $data );
    }
 
    /**
     * @param string $room
     * @param float $grad
     * @param integer $duration
     */
    public function updateTemperature( string $room, float $grad, $duration = 0 )
    {
        $zone = $this->getZoneId( $room );
 
        if( $zone === false )
        {
            return;
        }
 
        $setting = $this->getSetting( $zone );
        $setting->type = 'HEATING';
        $setting->temperature->celsius = $grad;
 
        $data = new stdClass();
        $data->setting = $setting;
        $data->termination = new stdClass();
 
        if( $duration === 0 )
        {
            $data->termination->type = 'MANUAL';
        }
        else
        {
            $data->termination->type = 'TIMER';
            $data->termination->durationInSeconds = $duration;
        }
 
        $this->curl( sprintf( $this->endpoint . '/homes/%s/zones/%d/overlay', $this->homeId, $zone ), 'PUT', $data );
    }
 
    /**
     * @param string $room
     */
    public function removeManualControl( $room )
    {
        $zone = $this->getZoneId( $room );
 
        if( $zone === false )
        {
            return;
        }
 
        $this->curl( sprintf( $this->endpoint . '/homes/%s/zones/%d/overlay', $this->homeId, $zone ), 'DELETE' );
    }
 
    public function curl( $path, $method, $data = '' )
    {
        $ch = curl_init( $path );
 
        if( ! empty( $this->token ) )
        {
            $header[] ='Authorization: Bearer ' . $this->token;
 
            if( $method === 'PUT' )
            {
                $header[] ='Content-Type:application/json;charset=UTF-8';
            }
 
            curl_setopt ($ch, CURLOPT_HTTPHEADER, $header );
        }
 
        curl_setopt( $ch, CURLOPT_URL, $path );
        curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
        curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, $method );
 
        if( ! empty( $data ) )
        {
            if( $method === 'PUT' )
            {
                curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode( $data ) );
            }
            else
            {
                curl_setopt( $ch, CURLOPT_POSTFIELDS, http_build_query( $data ) );
            }
        }
 
        $json = curl_exec( $ch );
        curl_close( $ch );
        return json_decode( $json );
    }
}

Beispiel 1: Temperatur im Büro dauerhaft auf 20 Grad stellen

$tado = new Tado;
$tado->updateTemperature( 'Büro', 20 );

Beispiel 2: Temperatur im Wohnzimmer für 90 Minuten auf 18 Grad stellen

Hinweis: Die Dauer wird in Sekunden übergeben (90 Minuten = 5400 Sekunden):

$tado = new Tado;
$tado->updateTemperature( 'Wohnzimmer', 18, 5400 );

Beispiel 3: Manuelle Steuerung im Wohnzimmer entfernen (intelligenter Zeitplan wird wieder aktiviert)

$tado = new Tado;
$tado->removeManualControl( 'Wohnzimmer' );

Beispiel 4: Status "HOME" setzen

$tado = new Tado;
$tado->setPresence( tado::PRESENCE_HOME );

Beispiel 5: Status "AWAY" setzen

$tado = new Tado;
$tado->setPresence( tado::PRESENCE_AWAY );
php/tado.txt · Zuletzt geändert: 2021/01/07 14:53 von webproducer