reduced API requests, all readings dynamic (zone and device independent)
This commit is contained in:
parent
9308d1f50f
commit
6d3ddb4bae
677
98_TadoAPI.pm
677
98_TadoAPI.pm
@ -60,14 +60,17 @@ my %sets = (
|
||||
"getTemperature" => "",
|
||||
"refreshToken" => "noArg",
|
||||
"password" => "",
|
||||
"setGeo" => "on,off",
|
||||
"setOverlay" => "20,21,22,off"
|
||||
"update" => "noArg",
|
||||
"setGeo" => "",
|
||||
"setOverlay" => ""
|
||||
);
|
||||
|
||||
my %gets = (
|
||||
"getHomeMode" => "noArg",
|
||||
"getZoneDevices" => "",
|
||||
"getZoneInfo" => "noArg",
|
||||
"getGeo" => "noArg"
|
||||
"getGeo" => "",
|
||||
#"getXTest" => "noArg",
|
||||
"getMobileDevices" => "noArg"
|
||||
);
|
||||
|
||||
|
||||
@ -158,22 +161,24 @@ sub TadoAPI_Set(@) {
|
||||
}
|
||||
|
||||
if( $cmd eq 'setGeo' ) {
|
||||
if( $value eq "on" ) {
|
||||
return "Need at least two parameters (mobileID, Setting)" if(@a < 4);
|
||||
if( $a[3] eq "on" ) {
|
||||
Log3 $name, 3, "TadoAPI: set $name: processing ($cmd)";
|
||||
TadoAPI_SetGeo($hash, 1);
|
||||
TadoAPI_SetGeoById($hash, $value, 1);
|
||||
} else {
|
||||
Log3 $name, 3, "TadoAPI: set $name: processing ($cmd)";
|
||||
TadoAPI_SetGeo($hash, 0);
|
||||
TadoAPI_SetGeoById($hash, $value, 0);
|
||||
}
|
||||
TadoAPI_GetGeo($hash);
|
||||
TadoAPI_GetGeoById($hash, $value);
|
||||
return undef;
|
||||
|
||||
} elsif( $cmd eq 'setOverlay' ) {
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "processing ($cmd)" if $debug;
|
||||
if( $value > 10 ) {
|
||||
TadoAPI_SetOverlay($hash, $value);
|
||||
return "Need at least two parameters (ID, Setting)" if(@a < 4);
|
||||
if( $a[3] > 10 ) {
|
||||
TadoAPI_SetOverlay($hash, $value, $a[3]);
|
||||
} else {
|
||||
TadoAPI_SetOverlay($hash, "off");
|
||||
TadoAPI_SetOverlay($hash, $value, "off");
|
||||
}
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "$cmd finished\n";
|
||||
return undef;
|
||||
@ -185,6 +190,11 @@ sub TadoAPI_Set(@) {
|
||||
TadoAPI_Connect($hash);
|
||||
return undef;
|
||||
|
||||
} elsif( $cmd eq 'update' ) {
|
||||
Log3 $name, 3, "TadoAPI: set $name: processing ($cmd)";
|
||||
TadoAPI_UpdateFn($hash);
|
||||
return undef;
|
||||
|
||||
} elsif( $cmd eq 'getTemperature' ) {
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "processing ($cmd)" if $debug;
|
||||
return "ZoneID as parameter needed" if (!$value);
|
||||
@ -233,19 +243,46 @@ sub TadoAPI_Get(@) {
|
||||
}
|
||||
|
||||
if($cmd =~ /\Qget\E/) {
|
||||
eval {
|
||||
|
||||
COMMAND_HANDLER: {
|
||||
|
||||
$cmd eq "getGeo" and do {
|
||||
return "Need at least one parameter (mobileID)" if(@a < 3);
|
||||
return "Wrong MobileID" if (length($value) < 6);
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "processing ($cmd)" if $debug;
|
||||
TadoAPI_GetGeo($hash);
|
||||
TadoAPI_GetGeoById($hash, $value);
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "$cmd finished\n";
|
||||
last;
|
||||
};
|
||||
|
||||
$cmd eq "getHomeMode" and do {
|
||||
$cmd eq "getMobileDevices" and do {
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "processing ($cmd)" if $debug;
|
||||
TadoAPI_GetHomeMode($hash);
|
||||
my @data = TadoAPI_RequestMobileDevices($hash);
|
||||
$message = "Device List:\n";
|
||||
foreach my $item ( @data ){
|
||||
print "\n";
|
||||
$message =+ $message . $item->{'name'} . ": " . $item->{'id'} . "\n";
|
||||
};
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "$cmd finished\n";
|
||||
last;
|
||||
};
|
||||
|
||||
$cmd eq "getXTest" and do {
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "processing ($cmd)" if $debug;
|
||||
TadoAPI_UpdateFn($hash);
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "$cmd finished\n";
|
||||
last;
|
||||
};
|
||||
|
||||
$cmd eq "getZoneDevices" and do {
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "processing ($cmd)" if $debug;
|
||||
return "ID parameter missing (set getZoneDevices zoneID)" if(@a < 3);
|
||||
TadoAPI_Connect($hash);
|
||||
my ($devcount, $deviceList) = TadoAPI_GetZoneDevicesById($hash, $value);
|
||||
$message= "There are " . $devcount . " Tado-Device(s) in this Zone.\n";
|
||||
foreach my $item ( @$deviceList ){
|
||||
$message =+ $message . $item->{'serialNo'} . " Battery: " . $item->{'batteryState'} . "\n";
|
||||
}
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "$cmd finished\n";
|
||||
last;
|
||||
};
|
||||
@ -263,7 +300,7 @@ sub TadoAPI_Get(@) {
|
||||
last;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return $message if $message;
|
||||
return TadoAPI_Catch($@) if $@;
|
||||
return undef;
|
||||
@ -289,75 +326,7 @@ sub TadoAPI_Undefine($$) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
######################################################
|
||||
# storePW & readPW Code geklaut aus 96_SIP.pm :)
|
||||
######################################################
|
||||
sub TadoAPI_storePassword($$)
|
||||
{
|
||||
my ($name, $password) = @_;
|
||||
my $index = "TadoAPI_".$name."_passwd";
|
||||
my $key = getUniqueId().$index;
|
||||
my $e_pwd = "";
|
||||
|
||||
if (eval "use Digest::MD5;1")
|
||||
{
|
||||
$key = Digest::MD5::md5_hex(unpack "H*", $key);
|
||||
$key .= Digest::MD5::md5_hex($key);
|
||||
}
|
||||
|
||||
for my $char (split //, $password)
|
||||
{
|
||||
my $encode=chop($key);
|
||||
$e_pwd.=sprintf("%.2x",ord($char)^ord($encode));
|
||||
$key=$encode.$key;
|
||||
}
|
||||
|
||||
my $error = setKeyValue($index, $e_pwd);
|
||||
return "error while saving TadoAPI password : $error" if(defined($error));
|
||||
return "TadoAPI password successfully saved in FhemUtils/uniqueID Key $index";
|
||||
}
|
||||
|
||||
sub TadoAPI_readPassword($)
|
||||
{
|
||||
my ($name) = @_;
|
||||
my $index = "TadoAPI_".$name."_passwd";
|
||||
my $key = getUniqueId().$index;
|
||||
|
||||
my ($password, $error);
|
||||
|
||||
#Log3 $name,5,"$name, read user password from FhemUtils/uniqueID Key $key";
|
||||
($error, $password) = getKeyValue($index);
|
||||
|
||||
if ( defined($error) )
|
||||
{
|
||||
Log3 $name,3, "$name, cant't read Tado password from FhemUtils/uniqueID: $error";
|
||||
return undef;
|
||||
}
|
||||
|
||||
if ( defined($password) )
|
||||
{
|
||||
if (eval "use Digest::MD5;1")
|
||||
{
|
||||
$key = Digest::MD5::md5_hex(unpack "H*", $key);
|
||||
$key .= Digest::MD5::md5_hex($key);
|
||||
}
|
||||
|
||||
my $dec_pwd = '';
|
||||
|
||||
for my $char (map { pack('C', hex($_)) } ($password =~ /(..)/g))
|
||||
{
|
||||
my $decode=chop($key);
|
||||
$dec_pwd.=chr(ord($char)^ord($decode));
|
||||
$key=$decode.$key;
|
||||
}
|
||||
return $dec_pwd;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log3 $name,3,"$name, no Tado password found in FhemUtils/uniqueID";
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
|
||||
sub TadoAPI_callback($$$){
|
||||
my ($param, $err, $data) = @_;
|
||||
@ -551,7 +520,7 @@ sub TadoAPI_Update(@){
|
||||
InternalTimer( $nextTimer, "TadoAPI_Update", $hash, 0 );
|
||||
|
||||
# update subs
|
||||
TadoAPI_GetUpdate($hash);
|
||||
TadoAPI_UpdateFn($hash);
|
||||
|
||||
return undef;
|
||||
}
|
||||
@ -559,16 +528,12 @@ sub TadoAPI_Update(@){
|
||||
######################## tado methods ########################
|
||||
##############################################################
|
||||
sub TadoAPI_SetOverlay(@){
|
||||
my ($hash, $setting) = @_;
|
||||
my ($hash, $zoneID, $setting) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $homeID = $attr{$name}{homeID};
|
||||
my $URL = $QueryURL . qq{/$homeID/zones/1/overlay};
|
||||
|
||||
# todo make dynamic
|
||||
my $zoneID = 1;
|
||||
|
||||
my $URL = $QueryURL . qq{/$homeID/zones/$zoneID/overlay};
|
||||
|
||||
Log3 $name, 3, "TadoAPI $name" . ": SetOverlay (Setting: " . $setting . ") - " . "query-URL: $URL" if $debug;
|
||||
Log3 $name, 3, "TadoAPI $name" . ": SetOverlay for Zone $zoneID (Setting: " . $setting . ") - " . "query-URL: $URL" if $debug;
|
||||
|
||||
if($apiStatus == 1){
|
||||
TadoAPI_Connect($hash);
|
||||
@ -616,7 +581,7 @@ sub TadoAPI_SetOverlay(@){
|
||||
if($res->is_success){
|
||||
print "\n Retriving State:\n" if $debug;
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "Retriving state:\n" . $res->content if $debug;
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "Set Overlay setting to: $setting";
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "Set Overlay for Zone $zoneID to: $setting";
|
||||
|
||||
# write readings
|
||||
readingsBeginUpdate($hash);
|
||||
@ -631,109 +596,92 @@ sub TadoAPI_SetOverlay(@){
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub TadoAPI_GetUpdate(@){
|
||||
sub TadoAPI_UpdateFn(@){
|
||||
my ($hash) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $homeID = $attr{$name}{homeID};
|
||||
my $mobileID = $attr{$name}{mobileID};
|
||||
my $URL=$QueryURL.qq{/$homeID/zones/1/state};
|
||||
my $deviceURL=$QueryURL.qq{/$homeID/mobileDevices/$mobileID/settings};
|
||||
my $setting = 0;
|
||||
my $tadoMode = 0;
|
||||
my $success = 0;
|
||||
|
||||
TadoAPI_Connect($hash);
|
||||
|
||||
my $zonecount = TadoAPI_GetZoneCount($hash);
|
||||
|
||||
# zone specific updates
|
||||
if($apiStatus == 1){
|
||||
$header = HTTP::Headers->new("Content-Type"=>"application/json;charset=UTF-8","Authorization" => "$TokenData->{'token_type'} $TokenData->{'access_token'}");
|
||||
$UserAgent = LWP::UserAgent::Paranoid->new(ssl_opts => { verify_hostname => 1 },protocols_allowed => ['https','http'],request_timeout => 5,);
|
||||
$UserAgent->default_headers($header);
|
||||
|
||||
$Request = GET($URL);
|
||||
$Response = $UserAgent->request($Request);
|
||||
|
||||
if($Response->is_success){
|
||||
my $ResponseData = decode_json($Response->content);
|
||||
$tadoMode = $ResponseData->{'tadoMode'};
|
||||
$success = 1;
|
||||
}else{
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "UpdateFn: [Authentication Error]". $Response->status_line;
|
||||
$success = 0;
|
||||
my @zones = TadoAPI_RequestZones($hash);
|
||||
my @devices = TadoAPI_RequestTadoDevices($hash);
|
||||
my $zonecount = @zones;
|
||||
|
||||
for (my $i=0; $i < $zonecount; $i++) {
|
||||
print "HomeMode_" . encode("UTF-8", $devices[$i]->{'name'}) . $zones[$i]->{'tadoMode'} . "\n" if $debug;
|
||||
my $overlay = $zones[$i]->{'overlayType'};
|
||||
if (!defined $overlay) {$overlay = "no overlay"};
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
readingsBulkUpdate($hash, "HomeMode_" . encode("UTF-8", $devices[$i]->{'name'}), $zones[$i]->{'tadoMode'});
|
||||
readingsBulkUpdate($hash, "Temperatur_" . encode("UTF-8", $devices[$i]->{'name'}), $zones[$i]->{'sensorDataPoints'}->{'insideTemperature'}->{'celsius'});
|
||||
readingsBulkUpdate($hash, "Luftfeuchtigkeit_" . encode("UTF-8", $devices[$i]->{'name'}), $zones[$i]->{'sensorDataPoints'}->{'humidity'}->{'percentage'});
|
||||
readingsBulkUpdate($hash, "Heizleistung_" . encode("UTF-8", $devices[$i]->{'name'}), $zones[$i]->{'activityDataPoints'}->{'heatingPower'}->{'percentage'});
|
||||
readingsBulkUpdate($hash, "OverlayType_" . encode("UTF-8", $devices[$i]->{'name'}), $overlay);
|
||||
readingsBulkUpdate($hash, "DesiredTemp_" . encode("UTF-8", $devices[$i]->{'name'}), $zones[$i]->{'setting'}->{'temperature'}->{'celsius'});
|
||||
readingsEndUpdate( $hash, 1 );
|
||||
}
|
||||
|
||||
# device specific updates
|
||||
$Request = GET($deviceURL);
|
||||
$Response = $UserAgent->request($Request);
|
||||
# mobile devices
|
||||
my @mobDev = TadoAPI_RequestMobileDevices($hash);
|
||||
my $mobDevCount = @mobDev;
|
||||
|
||||
if($Response->is_success && $success){
|
||||
my $ResponseData = decode_json($Response->content);
|
||||
$setting = $ResponseData->{'geoTrackingEnabled'};
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "UpdateFn: Actual geo setting for $mobileID is: $setting" if $debug;
|
||||
$success = 1;
|
||||
}else{
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "UpdateFn: [Authentication Error]";
|
||||
$success = 0;
|
||||
for (my $i=0; $i < $mobDevCount; $i++) {
|
||||
print "Geolocation_" . encode("UTF-8", $mobDev[$i]->{'name'}) . $mobDev[$i]->{'settings'}->{'geoTrackingEnabled'} . "\n" if $debug;
|
||||
readingsBeginUpdate($hash);
|
||||
readingsBulkUpdate($hash, "Geolocation_" . encode("UTF-8", $mobDev[$i]->{'id'}), $mobDev[$i]->{'settings'}->{'geoTrackingEnabled'});
|
||||
readingsEndUpdate( $hash, 1 );
|
||||
}
|
||||
|
||||
if ($success){
|
||||
# readings update
|
||||
for (my $i=1; $i <= TadoAPI_GetZoneCount($hash); $i++) {
|
||||
TadoAPI_GetZoneReadingsById($hash, $i);
|
||||
}
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
readingsBulkUpdate($hash, "Geolocation", $setting);
|
||||
readingsBulkUpdate($hash, "HomeMode", $tadoMode);
|
||||
readingsBulkUpdate($hash, "ActiveZones", $zonecount);
|
||||
# tado devices
|
||||
for (my $i=0; $i < $zonecount; $i++) {
|
||||
my $deviceList = $devices[$i]->{'devices'};
|
||||
foreach my $dev ( @$deviceList ){
|
||||
print "Battery_" . encode("UTF-8", $dev->{'serialNo'}) . $dev->{'batteryState'} . "\n" if $debug;
|
||||
readingsBeginUpdate($hash);
|
||||
readingsBulkUpdate($hash, "Battery_" . $dev->{'serialNo'}, $dev->{'batteryState'});
|
||||
readingsEndUpdate( $hash, 1 );
|
||||
}
|
||||
}
|
||||
$success = 0;
|
||||
readingsBeginUpdate($hash);
|
||||
readingsBulkUpdate($hash, "ActiveZones", $zonecount);
|
||||
readingsEndUpdate( $hash, 1 );
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub TadoAPI_GetGeo(@){
|
||||
my ($hash) = @_;
|
||||
sub TadoAPI_GetGeoById(@){
|
||||
my ($hash, $mobileID) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
my $homeID = $attr{$name}{homeID};
|
||||
my $mobileID = $attr{$name}{mobileID};
|
||||
|
||||
my $URL=$QueryURL.qq{/$homeID/mobileDevices/$mobileID/settings};
|
||||
my $setting = 0;
|
||||
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "homeID: $homeID" if $debug;
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "mobID: $mobileID" if $debug;
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "query-URL: $URL" if $debug;
|
||||
|
||||
if($apiStatus == 1){
|
||||
TadoAPI_Connect($hash);
|
||||
og3 $name, 3, "TadoAPI $name" . ": " . "query-URL: $URL" if $debug;
|
||||
TadoAPI_Connect($hash);
|
||||
|
||||
$header = HTTP::Headers->new("Content-Type"=>"application/json;charset=UTF-8","Authorization" => "$TokenData->{'token_type'} $TokenData->{'access_token'}");
|
||||
$UserAgent = LWP::UserAgent::Paranoid->new(ssl_opts => { verify_hostname => 1 },protocols_allowed => ['https','http'],request_timeout => 5,);
|
||||
$UserAgent->default_headers($header);
|
||||
if($apiStatus == 1){
|
||||
my $header = HTTP::Headers->new("Content-Type"=>"application/json;charset=UTF-8","Authorization" => "$TokenData->{'token_type'} $TokenData->{'access_token'}");
|
||||
my $ua = LWP::UserAgent::Paranoid->new(ssl_opts => { verify_hostname => 1 },protocols_allowed => ['https','http'],request_timeout => 5,);
|
||||
$ua->default_headers($header);
|
||||
|
||||
$Request = GET($URL);
|
||||
$Response = $UserAgent->request($Request);
|
||||
my $req = GET($URL);
|
||||
my $res = $ua->request($req);
|
||||
|
||||
if($Response->is_success){
|
||||
my $ResponseData = decode_json($Response->content);
|
||||
if($res->is_success){
|
||||
my $ResponseData = decode_json($res->content);
|
||||
$setting = $ResponseData->{'geoTrackingEnabled'};
|
||||
#print "\n Retriving State:\n" if $debug;
|
||||
#print $Response->content."\n\n" if $debug;
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "Actual geo setting for $mobileID is: $setting" if $debug;
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
readingsBulkUpdate($hash, "Geolocation", $setting);
|
||||
readingsBulkUpdate($hash, "Geolocation_" . $mobileID, $setting);
|
||||
readingsEndUpdate( $hash, 1 );
|
||||
return $setting;
|
||||
}else{
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "[Authentication Error in TadoAPI_GetGeo()]";
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "Error: ". $Response->status_line if $debug;
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "[Authentication Error in TadoAPI_GetGeoById( $mobileID )]";
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "Error: ". $res->status_line if $debug;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -760,7 +708,7 @@ sub TadoAPI_GetZoneInfo(@) {
|
||||
if($res->is_success){
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "Home Info:\n" . $res->content . "\n";
|
||||
}else{
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "[Authentication Error]". $res->status_line;
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "GetZoneInfo: [Authentication Error]". $res->status_line;
|
||||
}
|
||||
# TadoDevicesInfo
|
||||
$URL = $QueryURL.qq{/$homeID/zones};
|
||||
@ -772,7 +720,7 @@ sub TadoAPI_GetZoneInfo(@) {
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "Tado Devices:\n" . $res->content . "\n";
|
||||
|
||||
}else{
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "[Authentication Error]". $res->status_line;
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "GetZoneInfo: [Authentication Error]". $res->status_line;
|
||||
}
|
||||
# Mobileinfo
|
||||
$URL = $QueryURL . qq{/$homeID/mobileDevices};
|
||||
@ -783,10 +731,22 @@ sub TadoAPI_GetZoneInfo(@) {
|
||||
if($res->is_success){
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "Mobile Devices:\n" . $res->content . "\n";
|
||||
}else{
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "[Authentication Error]". $res->status_line;
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "GetZoneInfo: [Authentication Error]". $res->status_line;
|
||||
}
|
||||
|
||||
my $mobileID = $attr{$name}{mobileID};
|
||||
$URL=$QueryURL.qq{/$homeID/mobileDevices/$mobileID/settings};
|
||||
|
||||
$req = GET($URL);
|
||||
$res = $UserAgent->request($req);
|
||||
|
||||
if($res->is_success){
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "Mobile Device $mobileID :\n" . $res->content . "\n";
|
||||
}else{
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "GetZoneInfo: [Authentication Error]". $res->status_line;
|
||||
}
|
||||
|
||||
# zones
|
||||
for (my $i=1; $i <= TadoAPI_GetZoneCount($hash); $i++) {
|
||||
$URL=$QueryURL.qq{/$homeID/zones/$i/state};
|
||||
|
||||
@ -798,47 +758,13 @@ sub TadoAPI_GetZoneInfo(@) {
|
||||
my $zoneName = TadoAPI_GetZoneNameById($hash, $i);
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "Zone $i ($zoneName) Status:\n" . $res->content;
|
||||
}else{
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "[Authentication Error]". $res->status_line;
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "GetZoneInfo [Authentication Error]". $res->status_line;
|
||||
}
|
||||
}
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub TadoAPI_GetHomeMode(@) {
|
||||
my ($hash) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $homeID = $attr{$name}{homeID};
|
||||
my $URL=$QueryURL.qq{/$homeID/zones/1/state};
|
||||
my $tadoMode = 0;
|
||||
|
||||
if($apiStatus == 1){
|
||||
TadoAPI_Connect($hash);
|
||||
|
||||
$header = HTTP::Headers->new("Content-Type"=>"application/json;charset=UTF-8","Authorization" => "$TokenData->{'token_type'} $TokenData->{'access_token'}");
|
||||
$UserAgent = LWP::UserAgent::Paranoid->new(ssl_opts => { verify_hostname => 1 },protocols_allowed => ['https','http'],request_timeout => 5,);
|
||||
$UserAgent->default_headers($header);
|
||||
|
||||
$Request = GET($URL);
|
||||
$Response = $UserAgent->request($Request);
|
||||
|
||||
if($Response->is_success){
|
||||
my $ResponseData = decode_json($Response->content);
|
||||
$tadoMode = $ResponseData->{'tadoMode'};
|
||||
#debug
|
||||
#{Log 3, ("Retriving Zone 1 State:") if $verbose};
|
||||
#print $Response->content."\n\n" if $verbose;
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "Actual tado mode is: $tadoMode" if $debug;
|
||||
readingsBeginUpdate($hash);
|
||||
readingsBulkUpdate($hash, "HomeMode", $tadoMode);
|
||||
readingsEndUpdate( $hash, 1 );
|
||||
}else{
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "[Authentication Error]: " . $Response->status_line if $debug;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub TadoAPI_SetGeo(@){
|
||||
my ($hash, $geo) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
@ -881,6 +807,200 @@ sub TadoAPI_SetGeo(@){
|
||||
}
|
||||
}
|
||||
|
||||
sub TadoAPI_SetGeoById(@){
|
||||
my ($hash, $mobID, $geo) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $homeID = $attr{$name}{homeID};
|
||||
my $URL=$QueryURL.qq{/$homeID/mobileDevices/$mobID/settings};
|
||||
|
||||
TadoAPI_Connect($hash);
|
||||
|
||||
if($apiStatus == 1){
|
||||
|
||||
my $header = HTTP::Headers->new("Content-Type"=>"application/json;charset=UTF-8","Authorization" => "$TokenData->{'token_type'} $TokenData->{'access_token'}");
|
||||
my $ua = LWP::UserAgent::Paranoid->new(ssl_opts => { verify_hostname => 1 },protocols_allowed => ['https','http'],request_timeout => 5,);
|
||||
$ua->default_headers($header);
|
||||
|
||||
my $req = HTTP::Request->new('PUT',$URL);
|
||||
$req->content_type('application/json');
|
||||
|
||||
if($geo){
|
||||
$req->content('{"geoTrackingEnabled":"true"}');
|
||||
}else{
|
||||
$req->content('{"geoTrackingEnabled":"false"}');
|
||||
}
|
||||
|
||||
my $res = $ua->request($req);
|
||||
|
||||
if($res->is_success){
|
||||
print "\n Retriving State:\n" if $debug;
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "Retriving state:\n" . $res->content if $debug;
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "Set geo setting for $mobID to: $geo";
|
||||
}else{
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "Error in setGeo()";
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "Status: " . $res->status_line if $debug;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#######################################################################################################
|
||||
# API Subs
|
||||
###########
|
||||
|
||||
sub TadoAPI_RequestHome(@) {
|
||||
my ($hash) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $URL=qq{https://my.tado.com/api/v2/me};
|
||||
|
||||
if($apiStatus == 1){
|
||||
TadoAPI_Connect($hash);
|
||||
|
||||
my $header = HTTP::Headers->new("Content-Type"=>"application/json;charset=UTF-8","Authorization" => "$TokenData->{'token_type'} $TokenData->{'access_token'}");
|
||||
my $ua = LWP::UserAgent::Paranoid->new(ssl_opts => { verify_hostname => 1 },protocols_allowed => ['https','http'],request_timeout => 5,);
|
||||
$ua->default_headers($header);
|
||||
|
||||
my $req = GET($URL);
|
||||
my $res = $ua->request($req);
|
||||
|
||||
if($res->is_success){
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "TadoAPI_RequestHome:\n" . $res->content . "\n" if $debug;
|
||||
my $data = $res->content;
|
||||
# validate response from api
|
||||
eval { decode_json($data) };
|
||||
if ($@)
|
||||
{
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "TadoAPI_RequestHome: decode_json failed, invalid json. error:$@\n";
|
||||
}else{
|
||||
# returns json
|
||||
return $data;
|
||||
}
|
||||
}else{
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "TadoAPI_RequestHome: [Authentication Error]". $res->status_line;
|
||||
}
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
||||
sub TadoAPI_RequestTadoDevices(@) {
|
||||
# returns array with zonenames and zone devices
|
||||
my ($hash) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $homeID = $attr{$name}{homeID};
|
||||
my $URL=$QueryURL.qq{/$homeID/zones};
|
||||
|
||||
if($apiStatus == 1){
|
||||
TadoAPI_Connect($hash);
|
||||
|
||||
my $header = HTTP::Headers->new("Content-Type"=>"application/json;charset=UTF-8","Authorization" => "$TokenData->{'token_type'} $TokenData->{'access_token'}");
|
||||
my $ua = LWP::UserAgent::Paranoid->new(ssl_opts => { verify_hostname => 1 },protocols_allowed => ['https','http'],request_timeout => 5,);
|
||||
$ua->default_headers($header);
|
||||
|
||||
my $req = GET($URL);
|
||||
my $res = $ua->request($req);
|
||||
|
||||
if($res->is_success){
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "RequestTadoDevices:\n" . $res->content . "\n" if $debug;
|
||||
my $data = $res->content;
|
||||
# validate response from api
|
||||
my $decoded_data = eval { decode_json($data) };
|
||||
if ($@)
|
||||
{
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "RequestTadoDevices: decode_json failed, invalid json. error:$@\n";
|
||||
}else{
|
||||
my @devices = ();
|
||||
foreach my $dev (@$decoded_data){
|
||||
push @devices, $dev;
|
||||
}
|
||||
return @devices;
|
||||
}
|
||||
}else{
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "RequestTadoDevices: [Authentication Error]". $res->status_line;
|
||||
}
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub TadoAPI_RequestZones(@) {
|
||||
# returns array with state of all zones
|
||||
my ($hash) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $homeID = $attr{$name}{homeID};
|
||||
|
||||
if($apiStatus == 1){
|
||||
TadoAPI_Connect($hash);
|
||||
|
||||
my $header = HTTP::Headers->new("Content-Type"=>"application/json;charset=UTF-8","Authorization" => "$TokenData->{'token_type'} $TokenData->{'access_token'}");
|
||||
my $ua = LWP::UserAgent::Paranoid->new(ssl_opts => { verify_hostname => 1 },protocols_allowed => ['https','http'],request_timeout => 5,);
|
||||
$ua->default_headers($header);
|
||||
|
||||
my @zones = ();
|
||||
|
||||
for (my $i=1; $i <= TadoAPI_GetZoneCount($hash); $i++) {
|
||||
my $URL=$QueryURL.qq{/$homeID/zones/$i/state};
|
||||
|
||||
my $req = GET($URL);
|
||||
my $res = $UserAgent->request($req);
|
||||
|
||||
if($res->is_success){
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "RequestZones: Zone $i Status:\n" . $res->content if $debug;
|
||||
my $data = $res->content;
|
||||
# validate response from api
|
||||
my $decoded_data = eval { decode_json($data) };
|
||||
if ($@)
|
||||
{
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "RequestZones: Zone $i decode_json failed, invalid json. error:$@\n";
|
||||
}else{
|
||||
# returns a json object with zone i
|
||||
push @zones, $decoded_data;
|
||||
}
|
||||
}else{
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "RequestZones: [Authentication Error]". $res->status_line;
|
||||
}
|
||||
}
|
||||
return @zones;
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub TadoAPI_RequestMobileDevices(@) {
|
||||
my ($hash) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $homeID = $attr{$name}{homeID};
|
||||
my $URL=$QueryURL . qq{/$homeID/mobileDevices};
|
||||
|
||||
if($apiStatus == 1){
|
||||
TadoAPI_Connect($hash);
|
||||
my @devices = ();
|
||||
|
||||
my $header = HTTP::Headers->new("Content-Type"=>"application/json;charset=UTF-8","Authorization" => "$TokenData->{'token_type'} $TokenData->{'access_token'}");
|
||||
my $ua = LWP::UserAgent::Paranoid->new(ssl_opts => { verify_hostname => 1 },protocols_allowed => ['https','http'],request_timeout => 5,);
|
||||
$ua->default_headers($header);
|
||||
|
||||
my $req = GET($URL);
|
||||
my $res = $ua->request($req);
|
||||
|
||||
if($res->is_success){
|
||||
my $data = $res->content;
|
||||
# validate response from api
|
||||
my $decoded_data = eval { decode_json($data) };
|
||||
if ($@)
|
||||
{
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "RequestMobileDevice: decode_json failed, invalid json. error:$@\n";
|
||||
}else{
|
||||
foreach my $item( @$decoded_data ) {
|
||||
push @devices, $item;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "RequestMobileDevices: [Authentication Error]". $res->status_line;
|
||||
}
|
||||
return @devices;
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
||||
######################################
|
||||
############ Helpers #################
|
||||
######################################
|
||||
@ -905,7 +1025,7 @@ sub TadoAPI_GetZoneCount(@) {
|
||||
}
|
||||
return $zonecount;
|
||||
}else{
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "[Authentication Error]". $Response->status_line;
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "GetZoneCount: [Authentication Error]". $Response->status_line;
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
@ -925,10 +1045,39 @@ sub TadoAPI_GetZoneNameById(@) {
|
||||
|
||||
if($Response->is_success){
|
||||
my $ResponseData = decode_json($Response->content);
|
||||
my $zoneName = @$ResponseData[$zoneID - 1]->{'name'};
|
||||
my $zoneName = encode("UTF-8", @$ResponseData[$zoneID - 1]->{'name'});
|
||||
return $zoneName;
|
||||
}else{
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "[Authentication Error]". $Response->status_line;
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "GetZoneNameById: [Authentication Error]". $Response->status_line;
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
# todo delete this
|
||||
sub TadoAPI_GetZoneDevicesById(@) {
|
||||
my ($hash, $zoneID) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $homeID = $attr{$name}{homeID};
|
||||
my $URL=$QueryURL.qq{/$homeID/zones};
|
||||
|
||||
$header = HTTP::Headers->new("Content-Type"=>"application/json;charset=UTF-8","Authorization" => "$TokenData->{'token_type'} $TokenData->{'access_token'}");
|
||||
$UserAgent = LWP::UserAgent::Paranoid->new(ssl_opts => { verify_hostname => 1 },protocols_allowed => ['https','http'],request_timeout => 5,);
|
||||
$UserAgent->default_headers($header);
|
||||
|
||||
$Request = GET($URL);
|
||||
$Response = $UserAgent->request($Request);
|
||||
|
||||
if($Response->is_success){
|
||||
my $devcount = 0;
|
||||
my $ResponseData = decode_json($Response->content);
|
||||
my $zoneDeviceList = @$ResponseData[$zoneID - 1]->{'devices'};
|
||||
|
||||
foreach my $item( @$zoneDeviceList ) {
|
||||
$devcount++;
|
||||
}
|
||||
return ($devcount, $zoneDeviceList);
|
||||
}else{
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "GetZoneDevicesById: [Authentication Error]". $Response->status_line;
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
@ -955,7 +1104,7 @@ sub TadoAPI_GetZoneTemperatureById(@){
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "Temperature: $temperature Humidity: $humidity\n" if $debug;
|
||||
return ($temperature, $humidity);
|
||||
}else{
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "[Authentication Error]". $Response->status_line;
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "GetZoneTemperatureById: [Authentication Error]". $Response->status_line;
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
@ -971,39 +1120,109 @@ sub TadoAPI_GetZoneReadingsById(@){
|
||||
my $currentHeatingPower = 0;
|
||||
my $overlay = 0;
|
||||
|
||||
$header = HTTP::Headers->new("Content-Type"=>"application/json;charset=UTF-8","Authorization" => "$TokenData->{'token_type'} $TokenData->{'access_token'}");
|
||||
$UserAgent = LWP::UserAgent::Paranoid->new(ssl_opts => { verify_hostname => 1 },protocols_allowed => ['https','http'],request_timeout => 5,);
|
||||
$UserAgent->default_headers($header);
|
||||
my $header = HTTP::Headers->new("Content-Type"=>"application/json;charset=UTF-8","Authorization" => "$TokenData->{'token_type'} $TokenData->{'access_token'}");
|
||||
my $ua = LWP::UserAgent::Paranoid->new(ssl_opts => { verify_hostname => 1 },protocols_allowed => ['https','http'],request_timeout => 5,);
|
||||
$ua->default_headers($header);
|
||||
|
||||
$Request = GET($URL);
|
||||
$Response = $UserAgent->request($Request);
|
||||
my $req = GET($URL);
|
||||
my $res = $ua->request($req);
|
||||
|
||||
if($Response->is_success){
|
||||
my $ResponseData = decode_json($Response->content);
|
||||
$temperature = $ResponseData->{'sensorDataPoints'}->{'insideTemperature'}->{'celsius'};
|
||||
$humidity = $ResponseData->{'sensorDataPoints'}->{'humidity'}->{'percentage'};
|
||||
$desiredTemp = $ResponseData->{'setting'}->{'temperature'}->{'celsius'};
|
||||
$currentHeatingPower = $ResponseData->{'activityDataPoints'}->{'heatingPower'}->{'percentage'};
|
||||
$overlay = $ResponseData->{'overlayType'};
|
||||
if (!defined $overlay) {$overlay = "no overlay"};
|
||||
if($res->is_success){
|
||||
my $ResponseData = decode_json($res->content);
|
||||
$temperature = $ResponseData->{'sensorDataPoints'}->{'insideTemperature'}->{'celsius'};
|
||||
$humidity = $ResponseData->{'sensorDataPoints'}->{'humidity'}->{'percentage'};
|
||||
$desiredTemp = $ResponseData->{'setting'}->{'temperature'}->{'celsius'};
|
||||
$currentHeatingPower = $ResponseData->{'activityDataPoints'}->{'heatingPower'}->{'percentage'};
|
||||
$overlay = $ResponseData->{'overlayType'};
|
||||
if (!defined $overlay) {$overlay = "no overlay"};
|
||||
|
||||
my $zoneName = TadoAPI_GetZoneNameById($hash, $zoneID);
|
||||
my $zoneName = TadoAPI_GetZoneNameById($hash, $zoneID);
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
readingsBulkUpdate($hash, "Temperatur_" . $zoneName, $temperature);
|
||||
readingsBulkUpdate($hash, "Luftfeuchtigkeit_" . $zoneName, $humidity);
|
||||
readingsBulkUpdate($hash, "Heizleistung_" . $zoneName, $currentHeatingPower);
|
||||
readingsBulkUpdate($hash, "OverlayType_" . $zoneName, $overlay);
|
||||
readingsBulkUpdate($hash, "DesiredTemp_" . $zoneName, $desiredTemp);
|
||||
readingsEndUpdate( $hash, 1 );
|
||||
readingsBeginUpdate($hash);
|
||||
readingsBulkUpdate($hash, "Temperatur_" . $zoneName, $temperature);
|
||||
readingsBulkUpdate($hash, "Luftfeuchtigkeit_" . $zoneName, $humidity);
|
||||
readingsBulkUpdate($hash, "Heizleistung_" . $zoneName, $currentHeatingPower);
|
||||
readingsBulkUpdate($hash, "OverlayType_" . $zoneName, $overlay);
|
||||
readingsBulkUpdate($hash, "DesiredTemp_" . $zoneName, $desiredTemp);
|
||||
readingsEndUpdate( $hash, 1 );
|
||||
|
||||
return ($temperature, $humidity, $desiredTemp, $currentHeatingPower, $overlay );
|
||||
}else{
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "[Authentication Error]". $Response->status_line;
|
||||
}
|
||||
return ($temperature, $humidity, $desiredTemp, $currentHeatingPower, $overlay );
|
||||
}else{
|
||||
Log3 $name, 3, "TadoAPI $name" . ": " . "GetZoneReadingsById: [Authentication Error]". $Response->status_line;
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
######################################################
|
||||
# storePW & readPW Code geklaut aus 96_SIP.pm :)
|
||||
######################################################
|
||||
sub TadoAPI_storePassword($$)
|
||||
{
|
||||
my ($name, $password) = @_;
|
||||
my $index = "TadoAPI_".$name."_passwd";
|
||||
my $key = getUniqueId().$index;
|
||||
my $e_pwd = "";
|
||||
|
||||
if (eval "use Digest::MD5;1")
|
||||
{
|
||||
$key = Digest::MD5::md5_hex(unpack "H*", $key);
|
||||
$key .= Digest::MD5::md5_hex($key);
|
||||
}
|
||||
|
||||
for my $char (split //, $password)
|
||||
{
|
||||
my $encode=chop($key);
|
||||
$e_pwd.=sprintf("%.2x",ord($char)^ord($encode));
|
||||
$key=$encode.$key;
|
||||
}
|
||||
|
||||
my $error = setKeyValue($index, $e_pwd);
|
||||
return "error while saving TadoAPI password : $error" if(defined($error));
|
||||
return "TadoAPI password successfully saved in FhemUtils/uniqueID Key $index";
|
||||
}
|
||||
|
||||
sub TadoAPI_readPassword($)
|
||||
{
|
||||
my ($name) = @_;
|
||||
my $index = "TadoAPI_".$name."_passwd";
|
||||
my $key = getUniqueId().$index;
|
||||
|
||||
my ($password, $error);
|
||||
|
||||
#Log3 $name,5,"$name, read user password from FhemUtils/uniqueID Key $key";
|
||||
($error, $password) = getKeyValue($index);
|
||||
|
||||
if ( defined($error) )
|
||||
{
|
||||
Log3 $name,3, "$name, cant't read Tado password from FhemUtils/uniqueID: $error";
|
||||
return undef;
|
||||
}
|
||||
|
||||
if ( defined($password) )
|
||||
{
|
||||
if (eval "use Digest::MD5;1")
|
||||
{
|
||||
$key = Digest::MD5::md5_hex(unpack "H*", $key);
|
||||
$key .= Digest::MD5::md5_hex($key);
|
||||
}
|
||||
|
||||
my $dec_pwd = '';
|
||||
|
||||
for my $char (map { pack('C', hex($_)) } ($password =~ /(..)/g))
|
||||
{
|
||||
my $decode=chop($key);
|
||||
$dec_pwd.=chr(ord($char)^ord($decode));
|
||||
$key=$decode.$key;
|
||||
}
|
||||
return $dec_pwd;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log3 $name,3,"$name, no Tado password found in FhemUtils/uniqueID";
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
# Beginn der Commandref
|
||||
|
Loading…
x
Reference in New Issue
Block a user