2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-02-26 10:34:52 +00:00

38_netatmo: home notification settings

git-svn-id: https://svn.fhem.de/fhem/trunk@14247 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
moises 2017-05-11 15:21:40 +00:00
parent 1a0d164edd
commit c859a43b46
2 changed files with 166 additions and 7 deletions

View File

@ -1,5 +1,6 @@
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
# Do not insert empty lines here, update check depends on it.
- feature: 38_netatmo: home notification settings
- feature: 98_alarmclock: New feature RepRoutine
- feature: 31_PLAYBULB: support for new Garden Model, move battery Reading to
powerLevel and add powerCharge Reading for Garden

View File

@ -361,12 +361,13 @@ netatmo_Define($$)
delete($hash->{refresh_token_app});
delete($hash->{expires_at});
delete($hash->{expires_at_app});
delete($hash->{csrf_token});
my $user = $a[@a-4];
my $pass = $a[@a-3];
my $username = netatmo_encrypt($user);
my $password = netatmo_encrypt($pass);
Log3 $name, 2, "$name: encrypt $user/$pass to $username/$password" if($user ne $username);
Log3 $name, 2, "$name: encrypt $user/$pass to $username/$password" if($user ne $username || $pass ne $password);
my $client_id = $a[@a-2];
my $client_secret = $a[@a-1];
@ -511,7 +512,7 @@ netatmo_Set($$@)
$list = "autocreate:noArg autocreate_homes:noArg autocreate_thermostats:noArg autocreate_homecoachs:noArg" if( $hash->{SUBTYPE} eq "ACCOUNT" );
#$list .= " unban:noArg" if( $hash->{SUBTYPE} eq "ACCOUNT" );
$list = "home:noArg away:noArg" if ($hash->{SUBTYPE} eq "PERSON");
$list = "empty:noArg" if ($hash->{SUBTYPE} eq "HOME");
$list = "empty:noArg notify_movements:never,empty,always notify_unknowns:empty,always record_movements:never,empty,always record_alarms:never,empty,always presence_record_humans:ignore,record,record_and_notify presence_record_vehicles:ignore,record,record_and_notify presence_record_animals:ignore,record,record_and_notify presence_record_movements:ignore,record,record_and_notify presence_record_alarms:ignore,record,record_and_notify gone_after presence_enable_notify_from_to:empty,always presence_notify_from presence_notify_to smart_notifs:on,off" if ($hash->{SUBTYPE} eq "HOME");
$list = "enable disable irmode:auto,always,never led_on_live:on,off mirror:off,on audio:on,off" if ($hash->{SUBTYPE} eq "CAMERA");
$list = "enable disable light_mode:auto,on,off floodlight intensity:slider,0,1,100 night_always:true,false night_person:true,false night_vehicle:true,false night_animal:true,false night_movement:true,false" if ($hash->{SUBTYPE} eq "CAMERA" && defined($hash->{model}) && $hash->{model} eq "NOC");
$list = "calibrate:noArg" if ($hash->{SUBTYPE} eq "TAG");
@ -552,6 +553,10 @@ netatmo_Set($$@)
return netatmo_setPresence($hash, "empty");
return undef;
}
elsif( $cmd =~ /^notify_/ || $cmd =~ /^record_/ || $cmd =~ /^presence_/ || $cmd eq "gone_after" || $cmd eq "smart_notifs" ) {
return netatmo_setNotifications($hash, $cmd, $parameters[0]);
return undef;
}
elsif( $cmd eq "enable" ) {
my $pin = $parameters[0];
$pin = "0000" if(!defined($pin) || length($pin) != 4);
@ -764,6 +769,7 @@ netatmo_refreshAppToken($;$)
return undef;
}
delete($hash->{csrf_token});
Log3 $name, 3, "$name: refreshing app token";
my $auth = "QXV0aG9yaXphdGlvbjogQmFzaWMgYm1GZlkyeHBaVzUwWDJsdmN6bzFObU5qTmpSaU56azBOak5oT1RrMU9HSTNOREF4TkRjeVpEbGxNREUxT0E9PQ==";
@ -851,7 +857,12 @@ netatmo_parseConnection($$$)
Log3 $name, 2, "$name: invalid json on connection check";
return undef;
}
my $json = JSON->new->utf8(0)->decode($data);
my $json = eval { JSON->new->utf8(0)->decode($data) };
if($@)
{
Log3 $name, 2, "$name: invalid json evaluation on connection check ".$@;
return undef;
}
$hash->{network} = "ok" if($json->{status} eq "ok");
}
return undef;
@ -1782,6 +1793,93 @@ netatmo_setPresence($$)
}
sub
netatmo_setNotifications($$$)
{
my ($hash,$setting,$value) = @_;
my $name = $hash->{NAME};
return undef if( !defined($hash->{IODev}) );
my $iohash = $hash->{IODev};
netatmo_refreshAppToken($iohash, defined($iohash->{access_token_app}));
return Log3 $name, 1, "$name: No access token was found! (setNotifications)" if(!defined($iohash->{access_token_app}));
if( !defined($iohash->{csrf_token}) )
{
my($err0,$data0) = HttpUtils_BlockingGet({
url => "https://auth.netatmo.com/access/checklogin",
timeout => 10,
noshutdown => 1,
});
if($err0 || !defined($data0))
{
Log3 $name, 1, "$name: csrf call failed! ".$err0;
return undef;
}
$data0 =~ /ci_csrf_netatmo" value="(.*)"/;
my $tmptoken = $1;
$iohash->{csrf_token} = $tmptoken;
if(!defined($iohash->{csrf_token})) {
Log3 $name, 1, "$name: CSRF ERROR ";
return undef;
}
Log3 $name, 4, "$name: csrf_token ".$iohash->{csrf_token};
}
my $homeid = $hash->{Home};
my %data;
if($setting eq "presence_notify_from" || $setting eq "presence_notify_to" || $setting eq "gone_after")
{
my @timevalue = split(":",$value);
if(defined($timevalue[1]))
{
$value = int($timevalue[0])*3600 + int($timevalue[1])*60;
}
else
{
$value *= 60;
}
$value = 0 if($value < 0);
$value = 86400 if($value > 86400 && $setting ne "gone_after");
}
elsif($setting eq "smart_notifs")
{
$value = (($value eq "on") ? "true" : "false");
}
if($setting eq "presence_enable_notify_from_to" || $setting =~ /^presence_record_/ || $setting =~ /^presence_notify_/ )
{
%data = (home_id => $homeid, 'presence_settings['.$setting.']' => $value, ci_csrf_netatmo => $iohash->{csrf_token});
}
else
{
%data = (home_id => $homeid, $setting => $value, ci_csrf_netatmo => $iohash->{csrf_token});
}
Log3 $name, 5, "$name: setNotifications ($setting $value)";
HttpUtils_NonblockingGet({
url => "https://my.netatmo.com/api/updatehome",
timeout => 20,
noshutdown => 1,
method => "POST",
header => "Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\nAuthorization: Bearer ".$iohash->{access_token_app},
data => \%data,
hash => $hash,
type => 'sethomesettings',
callback => \&netatmo_dispatch,
});
}
sub
netatmo_setCamera($$$)
{
@ -2263,8 +2361,12 @@ netatmo_dispatch($$$)
$hash->{network} = "ok" if($hash->{SUBTYPE} eq "ACCOUNT");
$hash->{IODev}->{network} = "ok" if($hash->{SUBTYPE} ne "ACCOUNT");
my $json;
$json = JSON->new->utf8(0)->decode($data);
my $json = eval { JSON->new->utf8(0)->decode($data) };
if($@)
{
Log3 $name, 2, "$name: invalid json evaluation on dispatch type ".$param->{type}." ".$@;
return undef;
}
Log3 "unknown", 2, "unknown (no name) ".Dumper($hash) if(!defined($name));
Log3 $name, 4, "$name: dispatch return: ".$param->{type};
@ -2334,6 +2436,8 @@ netatmo_dispatch($$$)
return netatmo_webhookStatus($hash,$json,"added");
} elsif( $param->{type} eq 'dropwebhook' ) {
return netatmo_webhookStatus($hash,$json,"dropped");
} elsif( $param->{type} eq 'sethomesettings' ) {
return netatmo_refreshHomeSettings($hash);
} else {
Log3 $name, 1, "$name: unknown '$param->{type}' ".Dumper($json);
}
@ -2960,10 +3064,19 @@ netatmo_parseReadings($$;$)
$hash->{helper}{NEXT_POLL} = $nextdata;
Log3 $name, 3, "$name: next dynamic update from device ($requested) at ".FmtDateTime($nextdata);
} else {
$nextdata += $step_time;
if($nextdata >= (gettimeofday()+155))
{
RemoveInternalTimer($hash, "netatmo_poll");
InternalTimer($nextdata, "netatmo_poll", $hash);
$hash->{helper}{NEXT_POLL} = $nextdata;
Log3 $name, 3, "$name: next extended dynamic update from device ($requested) at ".FmtDateTime($nextdata);
} else {
Log3 $name, 2, "$name: invalid time for dynamic update from device ($requested): ".FmtDateTime($nextdata);
}
}
}
}
elsif($nextdata >= (gettimeofday()+280))
{
RemoveInternalTimer($hash, "netatmo_poll");
@ -2971,9 +3084,18 @@ netatmo_parseReadings($$;$)
$hash->{helper}{NEXT_POLL} = $nextdata;
Log3 $name, 3, "$name: next dynamic update ($requested) at ".FmtDateTime($nextdata);
} else {
$nextdata += $step_time;
if($nextdata >= (gettimeofday()+280))
{
RemoveInternalTimer($hash, "netatmo_poll");
InternalTimer($nextdata, "netatmo_poll", $hash);
$hash->{helper}{NEXT_POLL} = $nextdata;
Log3 $name, 3, "$name: next extended dynamic update ($requested) at ".FmtDateTime($nextdata);
} else {
Log3 $name, 2, "$name: invalid time for dynamic update ($requested): ".FmtDateTime($nextdata);
}
}
}
}
}
@ -3478,6 +3600,25 @@ netatmo_parseHomeReadings($$;$)
readingsSingleUpdate($hash, "name", encode_utf8($homedata->{name}), 1) if(defined($homedata->{name}));
readingsSingleUpdate($hash, "presence_record_humans", $homedata->{presence_record_humans}, 1) if(defined($homedata->{presence_record_humans}));
readingsSingleUpdate($hash, "presence_record_vehicles", $homedata->{presence_record_vehicles}, 1) if(defined($homedata->{presence_record_vehicles}));
readingsSingleUpdate($hash, "presence_record_animals", $homedata->{presence_record_animals}, 1) if(defined($homedata->{presence_record_animals}));
readingsSingleUpdate($hash, "presence_record_movements", $homedata->{presence_record_movements}, 1) if(defined($homedata->{presence_record_movements}));
readingsSingleUpdate($hash, "presence_record_alarms", $homedata->{presence_record_alarms}, 1) if(defined($homedata->{presence_record_alarms}));
readingsSingleUpdate($hash, "gone_after", sprintf("%02d",(int($homedata->{gone_after}/60)/60)).":".sprintf("%02d",(int($homedata->{gone_after}/60)%60)), 1) if(defined($homedata->{gone_after}));
readingsSingleUpdate($hash, "smart_notifs", ($homedata->{smart_notifs} eq "1")?"on":"off", 1) if(defined($homedata->{smart_notifs}));
readingsSingleUpdate($hash, "presence_enable_notify_from_to", $homedata->{presence_enable_notify_from_to}, 1) if(defined($homedata->{presence_enable_notify_from_to}));
readingsSingleUpdate($hash, "presence_notify_from", sprintf("%02d",(int($homedata->{presence_notify_from}/60)/60)).":".sprintf("%02d",(int($homedata->{presence_notify_from}/60)%60)), 1) if(defined($homedata->{presence_notify_from}));
readingsSingleUpdate($hash, "presence_notify_to", sprintf("%02d",(int($homedata->{presence_notify_to}/60)/60)).":".sprintf("%02d",(int($homedata->{presence_notify_to}/60)%60)), 1) if(defined($homedata->{presence_notify_to}));
readingsSingleUpdate($hash, "notify_unknowns", $homedata->{notify_unknowns}, 1) if(defined($homedata->{notify_unknowns}));
readingsSingleUpdate($hash, "notify_movements", $homedata->{notify_movements}, 1) if(defined($homedata->{notify_movements}));
readingsSingleUpdate($hash, "record_alarms", $homedata->{record_alarms}, 1) if(defined($homedata->{record_alarms}));
readingsSingleUpdate($hash, "record_movements", $homedata->{record_movements}, 1) if(defined($homedata->{record_movements}));
if( $homedata->{place} ) {
$hash->{country} = encode_utf8($homedata->{place}{country}) if(defined($homedata->{place}{country}));
$hash->{bssid} = $homedata->{place}{bssid} if(defined($homedata->{place}{bssid}));
@ -3976,6 +4117,19 @@ netatmo_parseHomeReadings($$;$)
}
sub
netatmo_refreshHomeSettings($)
{
my($hash) = @_;
my $name = $hash->{NAME};
InternalTimer(gettimeofday()+5, "netatmo_poll", $hash);
return undef;
}
sub
netatmo_parseCameraPing($$;$)
{
@ -5520,8 +5674,12 @@ sub netatmo_Webhook() {
Log3 $name, 5, "Netatmo webhook JSON:\n".$data;
my $json = JSON->new->utf8(0)->decode($data);
my $json = eval { JSON->new->utf8(0)->decode($data) };
if($@)
{
Log3 $name, 2, "$name: invalid json evaluation for webhook ".$@;
return undef;
}
readingsBeginUpdate($hash);