2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-10 09:16:53 +00:00

74_GardenaDevice: add new API for mower

git-svn-id: https://svn.fhem.de/fhem/trunk@24255 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
LeonGaultier 2021-04-16 05:19:43 +00:00
parent cd73dcf235
commit 0bb50844f9
3 changed files with 129 additions and 34 deletions

View File

@ -1,5 +1,6 @@
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # 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. # Do not insert empty lines here, update check depends on it.
- change: 74_GardenaDevice: add new API for mower
- bugfix: 70_BOTVAC: transient map cache - bugfix: 70_BOTVAC: transient map cache
- bugfix: 73_DoorBird: Event Video Routine - bugfix: 73_DoorBird: Event Video Routine
- bugfix: 73_ElectricityCalculator: Bugfix - Midnight-Crash - bugfix: 73_ElectricityCalculator: Bugfix - Midnight-Crash

View File

@ -57,7 +57,7 @@
package FHEM::GardenaSmartBridge; package FHEM::GardenaSmartBridge;
use GPUtils qw(GP_Import GP_Export); use GPUtils qw(GP_Import GP_Export);
# use Data::Dumper; #only for Debugging #use Data::Dumper; #only for Debugging
use strict; use strict;
use warnings; use warnings;
@ -194,6 +194,7 @@ sub Initialize {
# Consumer # Consumer
$hash->{SetFn} = \&Set; $hash->{SetFn} = \&Set;
$hash->{GetFn} = \&Get;
$hash->{DefFn} = \&Define; $hash->{DefFn} = \&Define;
$hash->{UndefFn} = \&Undef; $hash->{UndefFn} = \&Undef;
$hash->{DeleteFn} = \&Delete; $hash->{DeleteFn} = \&Delete;
@ -300,9 +301,9 @@ sub Attr {
} }
elsif ( $attrName eq 'interval' ) { elsif ( $attrName eq 'interval' ) {
if ( $cmd eq 'set' ) { if ( $cmd eq 'set' ) {
RemoveInternalTimer($hash);
return 'Interval must be greater than 0' return 'Interval must be greater than 0'
if ( $attrVal == 0 ); if ( $attrVal == 0 );
RemoveInternalTimer($hash);
$hash->{INTERVAL} = $attrVal; $hash->{INTERVAL} = $attrVal;
Log3 $name, 3, Log3 $name, 3,
"GardenaSmartBridge ($name) - set interval: $attrVal"; "GardenaSmartBridge ($name) - set interval: $attrVal";
@ -394,6 +395,29 @@ sub Notify {
return; return;
} }
sub Get {
my $hash = shift // return;
my $aArg = shift // return;
my $name = shift @$aArg // return;
my $cmd = shift @$aArg
// return qq{"get $name" needs at least one argument};
if ( lc $cmd eq 'debug_devices_list' ) {
$hash->{helper}{debug_device_list} = 'get';
#Log3 $name, 2, Dumper($hash->{helper});
#Write($hash, undef, undef, undef, undef);
return 'coming soon';
} else {
my $list = "";
$list .= " debug_devices_list:noArg"
if ( AttrVal( $name, "debugJSON", "none") ne "none" );
return "Unknown argument $cmd,choose one of $list";
}
}
sub Set { sub Set {
my $hash = shift // return; my $hash = shift // return;
@ -445,13 +469,13 @@ sub Set {
} }
sub Write { sub Write {
my ( $hash, $payload, $deviceId, $abilities ) = @_; my ( $hash, $payload, $deviceId, $abilities, $service_id ) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my ( $session_id, $header, $uri, $method ); my ( $session_id, $header, $uri, $method );
( $payload, $session_id, $header, $uri, $method, $deviceId, $abilities ) = ( $payload, $session_id, $header, $uri, $method, $deviceId, $service_id ) =
createHttpValueStrings( $hash, $payload, $deviceId, $abilities ); createHttpValueStrings( $hash, $payload, $deviceId, $abilities, $service_id );
HttpUtils_NonblockingGet( HttpUtils_NonblockingGet(
{ {
@ -491,7 +515,7 @@ sub ErrorHandling {
my $dname = $dhash->{NAME}; my $dname = $dhash->{NAME};
Log3 $name, 2, "GardenaSmartBridge ($name) - Request: $data"; Log3 $name, 4, "GardenaSmartBridge ($name) - Request: $data";
my $decode_json = eval { decode_json($data) }; my $decode_json = eval { decode_json($data) };
if ($@) { if ($@) {
@ -749,6 +773,19 @@ sub ResponseProcessing {
return; return;
} }
elsif ( exists($hash->{helper}{debug_device_list}) ) {
Log3 $name, 4, "Debug Devices List";
my $msg;
$msg = "test krams";
my @buffer = split( '"devices":\[', $json );
my ( $json, $tail ) = ParseJSON( $hash, $buffer[1] );
$decode_json = eval { decode_json($json) };
delete $hash->{helper}{debug_device_list};
return $msg;
}
elsif (defined( $decode_json->{devices} ) elsif (defined( $decode_json->{devices} )
&& ref( $decode_json->{devices} ) eq 'ARRAY' && ref( $decode_json->{devices} ) eq 'ARRAY'
&& scalar( @{ $decode_json->{devices} } ) > 0 ) && scalar( @{ $decode_json->{devices} } ) > 0 )
@ -857,7 +894,6 @@ sub WriteReadings {
$v $v
) )
if ($decode_json->{abilities}[0]{properties}[$properties]{name} !~ /ethernet_status|wifi_status/ ); if ($decode_json->{abilities}[0]{properties}[$properties]{name} !~ /ethernet_status|wifi_status/ );
if ( if (
( (
$decode_json->{abilities}[0]{properties} $decode_json->{abilities}[0]{properties}
@ -1129,7 +1165,7 @@ sub ParseJSON {
} }
sub createHttpValueStrings { sub createHttpValueStrings {
my ( $hash, $payload, $deviceId, $abilities ) = @_; my ( $hash, $payload, $deviceId, $abilities, $service_id ) = @_;
my $session_id = $hash->{helper}{session_id}; my $session_id = $hash->{helper}{session_id};
my $header = "Content-Type: application/json"; my $header = "Content-Type: application/json";
@ -1148,7 +1184,7 @@ sub createHttpValueStrings {
if ( $payload eq '{}' ) { if ( $payload eq '{}' ) {
$method = 'GET'; $method = 'GET';
$payload = ''; $payload = '';
$uri .= '/locations/?locatioId=null&user_id=' . $hash->{helper}{user_id} $uri .= '/locations?locatioId=null&user_id=' . $hash->{helper}{user_id}
if ( exists( $hash->{helper}{user_id} ) if ( exists( $hash->{helper}{user_id} )
&& !defined( $hash->{helper}{locations_id} ) ); && !defined( $hash->{helper}{locations_id} ) );
readingsSingleUpdate( $hash, 'state', 'fetch locationId', 1 ) readingsSingleUpdate( $hash, 'state', 'fetch locationId', 1 )
@ -1159,22 +1195,38 @@ sub createHttpValueStrings {
&& defined( $hash->{helper}{locations_id} ) ); && defined( $hash->{helper}{locations_id} ) );
} }
$uri .= '/auth/token' if ( !defined( $hash->{helper}{session_id} ) ); $uri = '/auth/token' if ( !defined( $hash->{helper}{session_id} ) );
if ( defined( $hash->{helper}{locations_id} ) ) { if ( defined( $hash->{helper}{locations_id} ) ) {
if ( defined($abilities) && $abilities eq 'mower_settings' ) { if ( defined($abilities) && $abilities eq 'mower_settings' ) {
$method = 'PUT'; $method = 'PUT';
my $dhash = $modules{GardenaSmartDevice}{defptr}{$deviceId}; my $dhash = $modules{GardenaSmartDevice}{defptr}{$deviceId};
$uri .= $uri .=
'/devices/' '/devices/'
. $deviceId . $deviceId
. '/settings/' . '/settings/'
. $dhash->{helper}{STARTINGPOINTID} . $service_id
if ( defined($abilities) if ( defined($abilities)
&& defined($payload) && defined($payload)
&& $abilities eq 'mower_settings' ); && $abilities eq 'mower_settings' );
} # park until next schedules or override
elsif (defined($abilities)
&& defined($payload)
&& $abilities eq 'mower_timer' )
{
my $valve_id;
$method = 'PUT';
$uri .=
'/devices/'
. $deviceId
. '/abilities/'
. $abilities
. '/properties/mower_timer';
} }
elsif (defined($abilities) elsif (defined($abilities)
&& defined($payload) && defined($payload)
@ -1393,7 +1445,7 @@ sub DeletePassword {
], ],
"release_status": "stable", "release_status": "stable",
"license": "GPL_2", "license": "GPL_2",
"version": "v2.2.1", "version": "v2.2.2",
"author": [ "author": [
"Marko Oldenburg <leongaultier@gmail.com>" "Marko Oldenburg <leongaultier@gmail.com>"
], ],

View File

@ -10,6 +10,7 @@
# - Matthias (Kenneth) Thanks for Wiki entry # - Matthias (Kenneth) Thanks for Wiki entry
# - BioS Thanks for predefined start points Code # - BioS Thanks for predefined start points Code
# - fettgu Thanks for Debugging Irrigation Control data flow # - fettgu Thanks for Debugging Irrigation Control data flow
# - Sebastian (BOFH) Thanks for new Auth Code after API Change
# #
# #
# This script is free software; you can redistribute it and/or modify # This script is free software; you can redistribute it and/or modify
@ -63,7 +64,7 @@ use POSIX;
use FHEM::Meta; use FHEM::Meta;
use Time::Local; use Time::Local;
use Data::Dumper; # only for debugging #use Data::Dumper; # only for debugging
# try to use JSON::MaybeXS wrapper # try to use JSON::MaybeXS wrapper
# for chance of better performance + open code # for chance of better performance + open code
@ -206,6 +207,8 @@ sub Define {
$hash->{DEVICEID} = $deviceId; $hash->{DEVICEID} = $deviceId;
$hash->{VERSION} = version->parse($VERSION)->normal; $hash->{VERSION} = version->parse($VERSION)->normal;
$hash->{helper}{STARTINGPOINTID} = ''; $hash->{helper}{STARTINGPOINTID} = '';
$hash->{helper}{schedules_paused_until_id} = '';
$hash->{helper}{eco_mode_id} = '';
CommandAttr( undef, CommandAttr( undef,
"$name IODev $modules{GardenaSmartBridge}{defptr}{BRIDGE}->{NAME}" ) "$name IODev $modules{GardenaSmartBridge}{defptr}{BRIDGE}->{NAME}" )
@ -276,31 +279,55 @@ sub Set {
my $cmd = shift @$aArg // return qq{"set $name" needs at least one argument}; my $cmd = shift @$aArg // return qq{"set $name" needs at least one argument};
my $payload; my $payload;
my $abilities = ''; my $abilities;
my $service_id;
my $mainboard_version = ReadingsVal( $name, 'mower_type-mainboard_version', 0.0 );
### mower ### mower
# service_id (eco, parkuntilfurhternotice, startpoints)
if ( lc $cmd eq 'parkuntilfurthernotice' ) { if ( lc $cmd eq 'parkuntilfurthernotice' ) {
$payload = '"name":"park_until_further_notice"'; $payload = '"name":"park_until_further_notice"';
if ( $mainboard_version > 10.30 ) {
$payload = ' "settings":{"name":"schedules_paused_until","value":"2040-12-31T22:00:00.000Z","device":"'.$hash->{DEVICEID}.'"}';
$abilities = 'mower_settings' ;
$service_id = $hash->{helper}{schedules_paused_until_id};
}
} }
elsif ( lc $cmd eq 'parkuntilnexttimer' ) { elsif ( lc $cmd eq 'parkuntilnexttimer' ) {
$payload = '"name":"park_until_next_timer"'; $payload = '"name":"park_until_next_timer"';
if ( $mainboard_version > 10.30 ){
$payload = '"properties":{"name":"mower_timer","value":0}' ;
$abilities = 'mower_timer';
}
} }
elsif ( lc $cmd eq 'startresumeschedule' ) { elsif ( lc $cmd eq 'startresumeschedule' ) {
$payload = '"name":"start_resume_schedule"'; $payload = '"name":"start_resume_schedule"';
if ( $mainboard_version > 10.30 ) {
$payload = ' "settings":{"name":"schedules_paused_until","value":"","device":"'.$hash->{DEVICEID}.'"}';
$abilities = 'mower_settings' ;
$service_id = $hash->{helper}{schedules_paused_until_id};
}
} }
elsif ( lc $cmd eq 'startoverridetimer' ) { elsif ( lc $cmd eq 'startoverridetimer' ) {
$payload = '"name":"start_override_timer","parameters":{"duration":' $payload = '"name":"start_override_timer","parameters":{"duration":'
. $aArg->[0] * 60 . '}'; . $aArg->[0] * 60 . '}';
if ( $mainboard_version > 10.30 ){
$payload = '"properties":{"name":"mower_timer","value":'.$aArg->[0] * 60 .'}';
$abilities = 'mower_timer';
}
} }
elsif ( lc $cmd eq 'startpoint' ) { elsif ( lc $cmd eq 'startpoint' ) {
my $err; my $err;
( $err, $payload, $abilities ) = SetPredefinedStartPoints( $hash, $aArg ); ( $err, $payload, $abilities ) = SetPredefinedStartPoints( $hash, $aArg );
$service_id = $hash->{helper}{STARTINGPOINTID};
return $err if ( defined($err) ); return $err if ( defined($err) );
} }
elsif ( lc $cmd eq 'eco' ) {
$payload = '"settings": {"name": "eco_mode", "value": '.$aArg->[0].', "device": "'.$hash->{DEVICEID}.'"}';
$abilities = 'mower_settings' if ( $mainboard_version > 10.30 );
$service_id = $hash->{helper}{eco_mode_id};
#$abilities['service_id'] = $hash->{helper}{SCHEDULESID} if ( $mainboard_version > 10.30 );
}
### electronic_pressure_pump ### electronic_pressure_pump
elsif ( lc $cmd eq 'pumptimer' ) { elsif ( lc $cmd eq 'pumptimer' ) {
$payload = $payload =
@ -402,7 +429,7 @@ sub Set {
$abilities = 'mower' $abilities = 'mower'
if ( AttrVal( $name, 'model', 'unknown' ) eq 'mower' ) if ( AttrVal( $name, 'model', 'unknown' ) eq 'mower' )
&& $abilities ne 'mower_settings'; && ($abilities !~ /mower_settings|mower_timer/);
$abilities = 'watering' $abilities = 'watering'
if ( AttrVal( $name, 'model', 'unknown' ) eq 'ic24' if ( AttrVal( $name, 'model', 'unknown' ) eq 'ic24'
|| AttrVal( $name, 'model', 'unknown' ) eq 'watering_computer' ); || AttrVal( $name, 'model', 'unknown' ) eq 'watering_computer' );
@ -414,7 +441,7 @@ sub Set {
$hash->{helper}{deviceAction} = $payload; $hash->{helper}{deviceAction} = $payload;
readingsSingleUpdate( $hash, "state", "send command to gardena cloud", 1 ); readingsSingleUpdate( $hash, "state", "send command to gardena cloud", 1 );
IOWrite( $hash, $payload, $hash->{DEVICEID}, $abilities ); IOWrite( $hash, $payload, $hash->{DEVICEID}, $abilities, $service_id );
Log3 $name, 4, Log3 $name, 4,
"GardenaSmartBridge ($name) - IOWrite: $payload $hash->{DEVICEID} $abilities IODevHash=$hash->{IODev}"; "GardenaSmartBridge ($name) - IOWrite: $payload $hash->{DEVICEID} $abilities IODevHash=$hash->{IODev}";
@ -573,7 +600,21 @@ sub WriteReadings {
} while ( $abilities >= 0 ); } while ( $abilities >= 0 );
do { do {
#Log3 $name, 1, "Settings pro Device : ".$decode_json->{settings}[$settings]{name};
#Log3 $name, 1, " - KEIN ARRAY" if ( ref( $decode_json->{settings}[$settings]{value} ) ne "ARRAY");
#Log3 $name, 1, " - IST ARRAY" if ( ref( $decode_json->{settings}[$settings]{value} ) eq "ARRAY");
if ( $decode_json->{settings}[$settings]{name} eq 'schedules_paused_until'
|| $decode_json->{settings}[$settings]{name} eq 'eco_mode'
)
{
if ( $hash->{helper}{$decode_json->{settings}[$settings]{name}.'_id'} ne
$decode_json->{settings}[$settings]{id} )
{
$hash->{helper}{$decode_json->{settings}[$settings]{name}.'_id'} =
$decode_json->{settings}[$settings]{id};
}
}
if ( ref( $decode_json->{settings}[$settings]{value} ) eq "ARRAY" if ( ref( $decode_json->{settings}[$settings]{value} ) eq "ARRAY"
&& $decode_json->{settings}[$settings]{name} eq 'starting_points' ) && $decode_json->{settings}[$settings]{name} eq 'starting_points' )
{ {
@ -883,6 +924,7 @@ sub SetPredefinedStartPoints {
$payload = '"settings": ' . encode_json($decode_json_settings); $payload = '"settings": ' . encode_json($decode_json_settings);
$abilities = 'mower_settings'; $abilities = 'mower_settings';
#$abilities['service_id'] = $hash->{helper}{STARTINGPOINTID};
} }
else { else {
return return
@ -1213,7 +1255,7 @@ sub SetPredefinedStartPoints {
], ],
"release_status": "stable", "release_status": "stable",
"license": "GPL_2", "license": "GPL_2",
"version": "v2.0.3", "version": "v2.2.2",
"author": [ "author": [
"Marko Oldenburg <leongaultier@gmail.com>" "Marko Oldenburg <leongaultier@gmail.com>"
], ],