From 0bb50844f954f84fd8e0354a6263fa5f050ee4d2 Mon Sep 17 00:00:00 2001 From: LeonGaultier Date: Fri, 16 Apr 2021 05:19:43 +0000 Subject: [PATCH] 74_GardenaDevice: add new API for mower git-svn-id: https://svn.fhem.de/fhem/trunk@24255 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 1 + fhem/FHEM/73_GardenaSmartBridge.pm | 82 ++++++++++++++++++++++++------ fhem/FHEM/74_GardenaSmartDevice.pm | 80 ++++++++++++++++++++++------- 3 files changed, 129 insertions(+), 34 deletions(-) diff --git a/fhem/CHANGED b/fhem/CHANGED index 54c341479..9ee9a4067 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -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. + - change: 74_GardenaDevice: add new API for mower - bugfix: 70_BOTVAC: transient map cache - bugfix: 73_DoorBird: Event Video Routine - bugfix: 73_ElectricityCalculator: Bugfix - Midnight-Crash diff --git a/fhem/FHEM/73_GardenaSmartBridge.pm b/fhem/FHEM/73_GardenaSmartBridge.pm index 9351878cb..7517fd680 100644 --- a/fhem/FHEM/73_GardenaSmartBridge.pm +++ b/fhem/FHEM/73_GardenaSmartBridge.pm @@ -57,7 +57,7 @@ package FHEM::GardenaSmartBridge; use GPUtils qw(GP_Import GP_Export); -# use Data::Dumper; #only for Debugging +#use Data::Dumper; #only for Debugging use strict; use warnings; @@ -194,6 +194,7 @@ sub Initialize { # Consumer $hash->{SetFn} = \&Set; + $hash->{GetFn} = \&Get; $hash->{DefFn} = \&Define; $hash->{UndefFn} = \&Undef; $hash->{DeleteFn} = \&Delete; @@ -300,9 +301,9 @@ sub Attr { } elsif ( $attrName eq 'interval' ) { if ( $cmd eq 'set' ) { - RemoveInternalTimer($hash); return 'Interval must be greater than 0' if ( $attrVal == 0 ); + RemoveInternalTimer($hash); $hash->{INTERVAL} = $attrVal; Log3 $name, 3, "GardenaSmartBridge ($name) - set interval: $attrVal"; @@ -394,6 +395,29 @@ sub Notify { 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 { my $hash = shift // return; @@ -445,13 +469,13 @@ sub Set { } sub Write { - my ( $hash, $payload, $deviceId, $abilities ) = @_; + my ( $hash, $payload, $deviceId, $abilities, $service_id ) = @_; my $name = $hash->{NAME}; my ( $session_id, $header, $uri, $method ); - ( $payload, $session_id, $header, $uri, $method, $deviceId, $abilities ) = - createHttpValueStrings( $hash, $payload, $deviceId, $abilities ); + ( $payload, $session_id, $header, $uri, $method, $deviceId, $service_id ) = + createHttpValueStrings( $hash, $payload, $deviceId, $abilities, $service_id ); HttpUtils_NonblockingGet( { @@ -491,7 +515,7 @@ sub ErrorHandling { 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) }; if ($@) { @@ -749,6 +773,19 @@ sub ResponseProcessing { 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} ) && ref( $decode_json->{devices} ) eq 'ARRAY' && scalar( @{ $decode_json->{devices} } ) > 0 ) @@ -855,9 +892,8 @@ sub WriteReadings { $decode_json->{abilities}[0]{properties}[$properties] {name} . '-' . $t, $v - ) + ) if ($decode_json->{abilities}[0]{properties}[$properties]{name} !~ /ethernet_status|wifi_status/ ); - if ( ( $decode_json->{abilities}[0]{properties} @@ -885,7 +921,7 @@ sub WriteReadings { { #TODO: read valies if bridge connected to wifi readingsBulkUpdateIfChanged( $hash, - 'wifi_status-ssid', $v->{ssid} ) + 'wifi_status-ssid', $v->{ssid} ) if (ref($v->{ssid}) ne 'HASH'); readingsBulkUpdateIfChanged( $hash, 'wifi_status-mac', $v->{mac} ); @@ -1129,7 +1165,7 @@ sub ParseJSON { } sub createHttpValueStrings { - my ( $hash, $payload, $deviceId, $abilities ) = @_; + my ( $hash, $payload, $deviceId, $abilities, $service_id ) = @_; my $session_id = $hash->{helper}{session_id}; my $header = "Content-Type: application/json"; @@ -1148,7 +1184,7 @@ sub createHttpValueStrings { if ( $payload eq '{}' ) { $method = 'GET'; $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} ) && !defined( $hash->{helper}{locations_id} ) ); readingsSingleUpdate( $hash, 'state', 'fetch locationId', 1 ) @@ -1159,22 +1195,38 @@ sub createHttpValueStrings { && 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($abilities) && $abilities eq 'mower_settings' ) { $method = 'PUT'; my $dhash = $modules{GardenaSmartDevice}{defptr}{$deviceId}; + $uri .= '/devices/' . $deviceId . '/settings/' - . $dhash->{helper}{STARTINGPOINTID} + . $service_id if ( defined($abilities) && defined($payload) && $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) && defined($payload) @@ -1291,7 +1343,7 @@ sub DeletePassword {
  • longitude - Längengrad des Grundstücks
  • name - Name of your Garden – Default „My Garden“
  • state - State of the Bridge
  • -
  • token - SessionID
  • +
  • token - SessionID


  • @@ -1393,7 +1445,7 @@ sub DeletePassword { ], "release_status": "stable", "license": "GPL_2", - "version": "v2.2.1", + "version": "v2.2.2", "author": [ "Marko Oldenburg " ], diff --git a/fhem/FHEM/74_GardenaSmartDevice.pm b/fhem/FHEM/74_GardenaSmartDevice.pm index 5412ee398..bdd4e004c 100644 --- a/fhem/FHEM/74_GardenaSmartDevice.pm +++ b/fhem/FHEM/74_GardenaSmartDevice.pm @@ -10,6 +10,7 @@ # - Matthias (Kenneth) Thanks for Wiki entry # - BioS Thanks for predefined start points Code # - 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 @@ -63,7 +64,7 @@ use POSIX; use FHEM::Meta; use Time::Local; -use Data::Dumper; # only for debugging +#use Data::Dumper; # only for debugging # try to use JSON::MaybeXS wrapper # for chance of better performance + open code @@ -203,9 +204,11 @@ sub Define { my $deviceId = $aArg->[2]; my $category = $aArg->[3]; - $hash->{DEVICEID} = $deviceId; - $hash->{VERSION} = version->parse($VERSION)->normal; - $hash->{helper}{STARTINGPOINTID} = ''; + $hash->{DEVICEID} = $deviceId; + $hash->{VERSION} = version->parse($VERSION)->normal; + $hash->{helper}{STARTINGPOINTID} = ''; + $hash->{helper}{schedules_paused_until_id} = ''; + $hash->{helper}{eco_mode_id} = ''; CommandAttr( undef, "$name IODev $modules{GardenaSmartBridge}{defptr}{BRIDGE}->{NAME}" ) @@ -269,38 +272,62 @@ sub Attr { } sub Set { - my $hash = shift // return; - my $aArg = shift // return; + my $hash = shift // return; + my $aArg = shift // return; - my $name = shift @$aArg; - my $cmd = shift @$aArg // return qq{"set $name" needs at least one argument}; + my $name = shift @$aArg; + my $cmd = shift @$aArg // return qq{"set $name" needs at least one argument}; my $payload; - my $abilities = ''; - - ### mower + my $abilities; + my $service_id; + my $mainboard_version = ReadingsVal( $name, 'mower_type-mainboard_version', 0.0 ); + ### mower + # service_id (eco, parkuntilfurhternotice, startpoints) if ( lc $cmd eq 'parkuntilfurthernotice' ) { $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"'; - + if ( $mainboard_version > 10.30 ){ + $payload = '"properties":{"name":"mower_timer","value":0}' ; + $abilities = 'mower_timer'; + } } elsif ( lc $cmd eq 'startresumeschedule' ) { $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' ) { $payload = '"name":"start_override_timer","parameters":{"duration":' . $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' ) { my $err; - ( $err, $payload, $abilities ) = SetPredefinedStartPoints( $hash, $aArg ); + $service_id = $hash->{helper}{STARTINGPOINTID}; 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 elsif ( lc $cmd eq 'pumptimer' ) { $payload = @@ -399,10 +426,10 @@ sub Set { return "Unknown argument $cmd, choose one of $list"; } - + $abilities = 'mower' if ( AttrVal( $name, 'model', 'unknown' ) eq 'mower' ) - && $abilities ne 'mower_settings'; + && ($abilities !~ /mower_settings|mower_timer/); $abilities = 'watering' if ( AttrVal( $name, 'model', 'unknown' ) eq 'ic24' || AttrVal( $name, 'model', 'unknown' ) eq 'watering_computer' ); @@ -414,7 +441,7 @@ sub Set { $hash->{helper}{deviceAction} = $payload; 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, "GardenaSmartBridge ($name) - IOWrite: $payload $hash->{DEVICEID} $abilities IODevHash=$hash->{IODev}"; @@ -573,7 +600,21 @@ sub WriteReadings { } while ( $abilities >= 0 ); 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" && $decode_json->{settings}[$settings]{name} eq 'starting_points' ) { @@ -883,6 +924,7 @@ sub SetPredefinedStartPoints { $payload = '"settings": ' . encode_json($decode_json_settings); $abilities = 'mower_settings'; + #$abilities['service_id'] = $hash->{helper}{STARTINGPOINTID}; } else { return @@ -1213,7 +1255,7 @@ sub SetPredefinedStartPoints { ], "release_status": "stable", "license": "GPL_2", - "version": "v2.0.3", + "version": "v2.2.2", "author": [ "Marko Oldenburg " ],