mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 18:59:33 +00:00
AutomowerConnect: improved error handling, fix missig password bug
git-svn-id: https://svn.fhem.de/fhem/trunk@27131 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
7974eefd1b
commit
1d22821d04
@ -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.
|
||||||
|
- bugfix: 74_AutomowerConnect: improved error handling, fix missig password bug
|
||||||
- feature: 74_AutomowerConnect: add disabledForIntervals, Internal MODEL
|
- feature: 74_AutomowerConnect: add disabledForIntervals, Internal MODEL
|
||||||
- feature: 75_AutomowerConnectDevice: add disabledForIntervals, Internal MODEL
|
- feature: 75_AutomowerConnectDevice: add disabledForIntervals, Internal MODEL
|
||||||
- bugfix: 98_WeekdayTimer: !$we handling
|
- bugfix: 98_WeekdayTimer: !$we handling
|
||||||
|
@ -97,6 +97,7 @@ sub Initialize() {
|
|||||||
$hash->{AttrFn} = \&Attr;
|
$hash->{AttrFn} = \&Attr;
|
||||||
$hash->{AttrList} = "interval " .
|
$hash->{AttrList} = "interval " .
|
||||||
"disable:1,0 " .
|
"disable:1,0 " .
|
||||||
|
"debug:1,0 " .
|
||||||
"disabledForIntervals " .
|
"disabledForIntervals " .
|
||||||
"mapImagePath " .
|
"mapImagePath " .
|
||||||
"mapImageWidthHeight " .
|
"mapImageWidthHeight " .
|
||||||
@ -217,12 +218,20 @@ EOF
|
|||||||
$hash->{VERSION}=$1;
|
$hash->{VERSION}=$1;
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoveInternalTimer($hash);
|
|
||||||
InternalTimer( gettimeofday() + 2, \&APIAuth, $hash, 1);
|
|
||||||
InternalTimer( gettimeofday() + 30, \&readMap, $hash, 0);
|
|
||||||
AddExtension( $name, \&GetMap, "$type/$name/map" );
|
AddExtension( $name, \&GetMap, "$type/$name/map" );
|
||||||
|
|
||||||
readingsSingleUpdate( $hash, 'state', 'defined', 1 );
|
if( $hash->{helper}->{passObj}->getReadPassword($name) ) {
|
||||||
|
|
||||||
|
RemoveInternalTimer($hash);
|
||||||
|
InternalTimer( gettimeofday() + 2, \&APIAuth, $hash, 1);
|
||||||
|
InternalTimer( gettimeofday() + 30, \&readMap, $hash, 0);
|
||||||
|
readingsSingleUpdate( $hash, 'state', 'defined', 1 );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
readingsSingleUpdate( $hash, 'state', 'defined - client_secret missing', 1 );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return undef;
|
return undef;
|
||||||
|
|
||||||
@ -278,6 +287,7 @@ sub APIAuth {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
RemoveInternalTimer( $hash, \&APIAuth);
|
RemoveInternalTimer( $hash, \&APIAuth);
|
||||||
InternalTimer(gettimeofday() + 20, \&APIAuth, $hash, 0);
|
InternalTimer(gettimeofday() + 20, \&APIAuth, $hash, 0);
|
||||||
|
|
||||||
@ -291,31 +301,24 @@ sub APIAuthResponse {
|
|||||||
my $hash = $param->{hash};
|
my $hash = $param->{hash};
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
my $type = $hash->{TYPE};
|
my $type = $hash->{TYPE};
|
||||||
|
my $statuscode = $param->{code};
|
||||||
|
my $interval = $hash->{helper}{interval};
|
||||||
my $iam = "$type $name APIAuthResponse:";
|
my $iam = "$type $name APIAuthResponse:";
|
||||||
|
|
||||||
if($err) {
|
Log3 $name, 1, "\ndebug $iam \n\$statuscode [$statuscode]\n\$err [$err],\n \$data [$data] \n\$param->url $param->{url}" if ( AttrVal($name, 'debug', '') );
|
||||||
|
|
||||||
Log3 $name, 2, "$iam error [$err], data [$data] for url $param->{url}";
|
|
||||||
readingsSingleUpdate( $hash, 'state', 'error', 1 );
|
|
||||||
|
|
||||||
} elsif( $data ) {
|
if( !$err && $statuscode == 200 && $data) {
|
||||||
|
|
||||||
my $result = eval { decode_json($data) };
|
my $result = eval { decode_json($data) };
|
||||||
if ($@) {
|
if ($@) {
|
||||||
Log3 $name, 2, "$iam JSON error [ $@ ]";
|
|
||||||
readingsSingleUpdate( $hash, 'state', 'error', 1 );
|
|
||||||
return undef;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($result->{errors} || $result->{message}) {
|
Log3 $name, 2, "$iam JSON error [ $@ ]";
|
||||||
Log3 $name, 2, "$iam error [ $data ]";
|
readingsSingleUpdate( $hash, 'state', 'error JSON', 1 );
|
||||||
readingsSingleUpdate( $hash, 'state', 'error', 1 );
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Log3 $name, 5, "$iam $data";
|
|
||||||
|
|
||||||
$hash->{helper}->{auth} = $result;
|
$hash->{helper}->{auth} = $result;
|
||||||
|
|
||||||
# Update readings
|
# Update readings
|
||||||
readingsBeginUpdate($hash);
|
readingsBeginUpdate($hash);
|
||||||
readingsBulkUpdateIfChanged($hash,'.access_token',$hash->{helper}{auth}{access_token},0 );
|
readingsBulkUpdateIfChanged($hash,'.access_token',$hash->{helper}{auth}{access_token},0 );
|
||||||
@ -338,9 +341,20 @@ sub APIAuthResponse {
|
|||||||
readingsEndUpdate($hash, 1);
|
readingsEndUpdate($hash, 1);
|
||||||
|
|
||||||
getMower( $hash );
|
getMower( $hash );
|
||||||
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
readingsSingleUpdate( $hash, 'state', "error statuscode $statuscode", 1 );
|
||||||
|
Log3 $name, 1, "\n$iam\n\$statuscode [$statuscode]\n\$err [$err],\n\$data [$data]\n\$param->url $param->{url}";
|
||||||
|
|
||||||
}
|
}
|
||||||
return undef;
|
|
||||||
|
RemoveInternalTimer( $hash, \&APIAuth );
|
||||||
|
InternalTimer( gettimeofday() + $interval, \&APIAuth, $hash, 0 );
|
||||||
|
return undef;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -382,155 +396,162 @@ sub getMowerResponse {
|
|||||||
my $hash = $param->{hash};
|
my $hash = $param->{hash};
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
my $type = $hash->{TYPE};
|
my $type = $hash->{TYPE};
|
||||||
|
my $statuscode = $param->{code};
|
||||||
|
my $interval = $hash->{helper}{interval};
|
||||||
my $iam = "$type $name getMowerResponse:";
|
my $iam = "$type $name getMowerResponse:";
|
||||||
my $mowerNumber = $hash->{helper}{mowerNumber};
|
my $mowerNumber = $hash->{helper}{mowerNumber};
|
||||||
|
|
||||||
if($err ne "") {
|
Log3 $name, 1, "\ndebug $iam \n\$statuscode [$statuscode]\n\$err [$err],\n \$data [$data] \n\$param->url $param->{url}" if ( AttrVal($name, 'debug', '') );
|
||||||
|
|
||||||
|
if( !$err && $statuscode == 200 && $data) {
|
||||||
|
|
||||||
Log3 $name, 2, "$iam request error ".$param->{url}." - $err";
|
|
||||||
|
|
||||||
} elsif ( $data ) {
|
|
||||||
if ( $data eq "[]" ) {
|
if ( $data eq "[]" ) {
|
||||||
|
|
||||||
Log3 $name, 2, "$iam Please register an automower first";
|
Log3 $name, 2, "$iam no mower data present";
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
#Log3 $name, 5, $data;
|
|
||||||
|
|
||||||
my $result = eval { decode_json($data) };
|
my $result = eval { decode_json($data) };
|
||||||
if ($@) {
|
if ($@) {
|
||||||
|
|
||||||
Log3( $name, 2, "$iam - JSON error while request: $@");
|
Log3( $name, 2, "$iam - JSON error while request: $@");
|
||||||
return undef;
|
|
||||||
}
|
|
||||||
if ($result->{message}) {
|
|
||||||
Log3( $name, 2, "$iam - API error while request: $data");
|
|
||||||
return undef;
|
|
||||||
}
|
|
||||||
$hash->{helper}{mowers} = $result->{data};
|
|
||||||
my $maxMower = @{$hash->{helper}{mowers}};
|
|
||||||
if ($maxMower <= $mowerNumber || $mowerNumber < 0 ) {
|
|
||||||
|
|
||||||
Log3 $name, 2, "$iam mower number $mowerNumber not available. Change definition of $name.";
|
|
||||||
return undef;
|
|
||||||
|
|
||||||
}
|
|
||||||
my $foundMower .= '0 => '.$hash->{helper}{mowers}[0]{attributes}{system}{name};
|
|
||||||
for (my $i = 1; $i < $maxMower; $i++) {
|
|
||||||
$foundMower .= ' | '.$i.' => '.$hash->{helper}{mowers}[$i]{attributes}{system}{name};
|
|
||||||
}
|
|
||||||
Log3 $name, 5, "$iam found $foundMower ";
|
|
||||||
|
|
||||||
if ( defined ($hash->{helper}{mower}{id}) ){
|
|
||||||
|
|
||||||
$hash->{helper}{mowerold} = dclone( $hash->{helper}{mower} );
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
$hash->{helper}{mowerold} = dclone( $hash->{helper}{mowers}[$mowerNumber] );
|
$hash->{helper}{mowers} = $result->{data};
|
||||||
|
my $maxMower = 0;
|
||||||
$hash->{helper}{searchpos} = [ dclone( $hash->{helper}{mowerold}{attributes}{positions}[0] ), dclone( $hash->{helper}{mowerold}{attributes}{positions}[1] ) ];
|
$maxMower = @{$hash->{helper}{mowers}} if ( ref ( $hash->{helper}{mowers} ) eq 'ARRAY' );
|
||||||
|
if ($maxMower <= $mowerNumber || $mowerNumber < 0 ) {
|
||||||
|
|
||||||
$hash->{helper}{areapos} = [ dclone( $hash->{helper}{mowerold}{attributes}{positions}[0] ), dclone( $hash->{helper}{mowerold}{attributes}{positions}[1] ) ];
|
Log3 $name, 2, "$iam wrong mower number $mowerNumber ($maxMower mower available). Change definition of $name.";
|
||||||
$hash->{helper}{areapos}[0]{statusTimestamp} = $hash->{helper}{mowerold}{attributes}{metadata}{statusTimestamp};
|
return undef;
|
||||||
$hash->{helper}{areapos}[1]{statusTimestamp} = $hash->{helper}{mowerold}{attributes}{metadata}{statusTimestamp} - 12000;
|
|
||||||
|
|
||||||
$hash->{helper}{cspos} = [ dclone( $hash->{helper}{mowerold}{attributes}{positions}[0] ), dclone( $hash->{helper}{mowerold}{attributes}{positions}[1] ) ];
|
|
||||||
$hash->{helper}{cspos}[0]{statusTimestamp} = $hash->{helper}{mowerold}{attributes}{metadata}{statusTimestamp};
|
|
||||||
$hash->{helper}{cspos}[1]{statusTimestamp} = $hash->{helper}{mowerold}{attributes}{metadata}{statusTimestamp} - 600000;
|
|
||||||
}
|
|
||||||
|
|
||||||
$hash->{helper}{mower} = dclone( $hash->{helper}{mowers}[$mowerNumber] );
|
|
||||||
my $storediff = $hash->{helper}{mower}{attributes}{metadata}{statusTimestamp} - $hash->{helper}{mowerold}{attributes}{metadata}{statusTimestamp};
|
|
||||||
if ($storediff) {
|
|
||||||
AlignArray( $hash );
|
|
||||||
FW_detailFn_Update ($hash) if (AttrVal($name,'showMap',1));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
# Update readings
|
|
||||||
readingsBeginUpdate($hash);
|
|
||||||
|
|
||||||
readingsBulkUpdateIfChanged($hash, "batteryPercent", $hash->{helper}{mower}{attributes}{battery}{batteryPercent} );
|
|
||||||
readingsBulkUpdateIfChanged($hash, 'api_MowerFound', $foundMower );
|
|
||||||
my $pref = 'mower';
|
|
||||||
readingsBulkUpdateIfChanged($hash, $pref.'_id', $hash->{helper}{mower}{id} );
|
|
||||||
readingsBulkUpdateIfChanged($hash, $pref.'_mode', $hash->{helper}{mower}{attributes}{$pref}{mode} );
|
|
||||||
readingsBulkUpdateIfChanged($hash, $pref.'_activity', $hash->{helper}{mower}{attributes}{$pref}{activity} );
|
|
||||||
readingsBulkUpdateIfChanged($hash, $pref.'_state', $hash->{helper}{mower}{attributes}{$pref}{state} );
|
|
||||||
readingsBulkUpdateIfChanged($hash, $pref.'_commandStatus', 'cleared' );
|
|
||||||
my $tstamp = $hash->{helper}{mower}{attributes}{$pref}{errorCodeTimestamp};
|
|
||||||
my $timestamp = FmtDateTime($tstamp/1000);
|
|
||||||
readingsBulkUpdateIfChanged($hash, $pref."_errorCodeTimestamp", $tstamp ? $timestamp : '-' );
|
|
||||||
my $errc = $hash->{helper}{mower}{attributes}{$pref}{errorCode};
|
|
||||||
readingsBulkUpdateIfChanged($hash, $pref.'_errorCode', $tstamp ? $errc : '-');
|
|
||||||
my $errd = $hash->{helper}{errortable}{$errc};
|
|
||||||
readingsBulkUpdateIfChanged($hash, $pref.'_errorDescription', $tstamp ? $errd : '-');
|
|
||||||
$pref = 'system';
|
|
||||||
readingsBulkUpdateIfChanged($hash, $pref."_name", $hash->{helper}{mower}{attributes}{$pref}{name} );
|
|
||||||
my $model = $hash->{helper}{mower}{attributes}{$pref}{model};
|
|
||||||
$model =~ s/AUTOMOWER./AUTOMOWER®/;
|
|
||||||
$hash->{MODEL} = $model if ( $model && $hash->{MODEL} ne $model );
|
|
||||||
# readingsBulkUpdateIfChanged($hash, $pref."_model", $model );
|
|
||||||
readingsBulkUpdateIfChanged($hash, $pref."_serialNumber", $hash->{helper}{mower}{attributes}{$pref}{serialNumber} );
|
|
||||||
$pref = 'planner';
|
|
||||||
readingsBulkUpdateIfChanged($hash, "planner_restrictedReason", $hash->{helper}{mower}{attributes}{$pref}{restrictedReason} );
|
|
||||||
readingsBulkUpdateIfChanged($hash, "planner_overrideAction", $hash->{helper}{mower}{attributes}{$pref}{override}{action} );
|
|
||||||
|
|
||||||
$tstamp = $hash->{helper}{mower}{attributes}{$pref}{nextStartTimestamp};
|
|
||||||
$timestamp = FmtDateTime($tstamp/1000);
|
|
||||||
readingsBulkUpdateIfChanged($hash, "planner_nextStart", $tstamp ? $timestamp : '-' );
|
|
||||||
$pref = 'statistics';
|
|
||||||
readingsBulkUpdateIfChanged($hash, $pref."_numberOfChargingCycles", $hash->{helper}->{mower}{attributes}{$pref}{numberOfChargingCycles} );
|
|
||||||
readingsBulkUpdateIfChanged($hash, $pref."_totalCuttingTime", $hash->{helper}->{mower}{attributes}{$pref}{totalCuttingTime} );
|
|
||||||
readingsBulkUpdateIfChanged($hash, $pref."_totalChargingTime", $hash->{helper}->{mower}{attributes}{$pref}{totalChargingTime} );
|
|
||||||
readingsBulkUpdateIfChanged($hash, $pref."_totalSearchingTime", $hash->{helper}->{mower}{attributes}{$pref}{totalSearchingTime} );
|
|
||||||
readingsBulkUpdateIfChanged($hash, $pref."_numberOfCollisions", $hash->{helper}->{mower}{attributes}{$pref}{numberOfCollisions} );
|
|
||||||
readingsBulkUpdateIfChanged($hash, $pref."_totalRunningTime", $hash->{helper}->{mower}{attributes}{$pref}{totalRunningTime} );
|
|
||||||
$pref = 'settings';
|
|
||||||
readingsBulkUpdateIfChanged($hash, $pref."_headlight", $hash->{helper}->{mower}{attributes}{$pref}{headlight}{mode} );
|
|
||||||
readingsBulkUpdateIfChanged($hash, $pref."_cuttingHeight", $hash->{helper}->{mower}{attributes}{$pref}{cuttingHeight} );
|
|
||||||
$pref = 'status';
|
|
||||||
readingsBulkUpdateIfChanged($hash, $pref."_connected", $hash->{helper}{mower}{attributes}{metadata}{connected} );
|
|
||||||
readingsBulkUpdateIfChanged($hash, $pref."_Timestamp", FmtDateTime( $hash->{helper}{mower}{attributes}{metadata}{statusTimestamp}/1000 ));
|
|
||||||
readingsBulkUpdateIfChanged($hash, $pref."_TimestampDiff", $storediff/1000 );
|
|
||||||
readingsBulkUpdateIfChanged($hash, $pref."_TimestampOld", FmtDateTime( $hash->{helper}{mowerold}{attributes}{metadata}{statusTimestamp}/1000 ));
|
|
||||||
$pref = 'positions';
|
|
||||||
readingsBulkUpdateIfChanged($hash, $pref."_lastLatitude", $hash->{helper}{mower}{attributes}{$pref}[0]{latitude} );
|
|
||||||
readingsBulkUpdateIfChanged($hash, $pref."_lastLongitude", $hash->{helper}{mower}{attributes}{$pref}[0]{longitude} );
|
|
||||||
readingsBulkUpdateIfChanged($hash, 'state', 'connected' );
|
|
||||||
|
|
||||||
my @time = localtime();
|
|
||||||
my $secs = ( $time[2] * 3600 ) + ( $time[1] * 60 ) + $time[0];
|
|
||||||
my $interval = $hash->{helper}->{interval};
|
|
||||||
# do at midnight
|
|
||||||
if ( $secs <= $interval ) {
|
|
||||||
|
|
||||||
readingsBulkUpdateIfChanged( $hash, 'statistics_lastDayTrack', ReadingsNum( $name, 'statistics_currentDayTrack', 0 ));
|
|
||||||
readingsBulkUpdateIfChanged( $hash, 'statistics_lastDayArea', ReadingsNum( $name, 'statistics_currentDayArea', 0 ));
|
|
||||||
readingsBulkUpdateIfChanged( $hash, 'statistics_currentWeekTrack', ReadingsNum( $name, 'statistics_currentWeekTrack', 0 ) + ReadingsNum( $name, 'statistics_currentDayTrack', 0 ));
|
|
||||||
readingsBulkUpdateIfChanged( $hash, 'statistics_currentWeekArea', ReadingsNum( $name, 'statistics_currentWeekArea', 0 ) + ReadingsNum( $name, 'statistics_currentDayArea', 0 ));
|
|
||||||
readingsBulkUpdateIfChanged( $hash, 'statistics_currentDayTrack', 0, 0);
|
|
||||||
readingsBulkUpdateIfChanged( $hash, 'statistics_currentDayArea', 0, 0);
|
|
||||||
# do on mondays
|
|
||||||
if ( $time[6] == 1 && $secs <= $interval ) {
|
|
||||||
|
|
||||||
readingsBulkUpdateIfChanged( $hash, 'statistics_lastWeekTrack', ReadingsNum( $name, 'statistics_currentWeekTrack', 0 ));
|
|
||||||
readingsBulkUpdateIfChanged( $hash, 'statistics_lastWeekArea', ReadingsNum( $name, 'statistics_currentWeekArea', 0 ));
|
|
||||||
readingsBulkUpdateIfChanged( $hash, 'statistics_currentWeekTrack', 0, 0);
|
|
||||||
readingsBulkUpdateIfChanged( $hash, 'statistics_currentWeekArea', 0, 0);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
readingsEndUpdate($hash, 1);
|
my $foundMower .= '0 => '.$hash->{helper}{mowers}[0]{attributes}{system}{name};
|
||||||
|
for (my $i = 1; $i < $maxMower; $i++) {
|
||||||
RemoveInternalTimer( $hash, \&APIAuth );
|
$foundMower .= ' | '.$i.' => '.$hash->{helper}{mowers}[$i]{attributes}{system}{name};
|
||||||
InternalTimer( gettimeofday() + $interval, \&APIAuth, $hash, 0 );
|
}
|
||||||
|
Log3 $name, 5, "$iam found $foundMower ";
|
||||||
|
|
||||||
|
if ( defined ($hash->{helper}{mower}{id}) ){
|
||||||
|
|
||||||
|
$hash->{helper}{mowerold} = dclone( $hash->{helper}{mower} );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
$hash->{helper}{mowerold} = dclone( $hash->{helper}{mowers}[$mowerNumber] );
|
||||||
|
|
||||||
|
$hash->{helper}{searchpos} = [ dclone( $hash->{helper}{mowerold}{attributes}{positions}[0] ), dclone( $hash->{helper}{mowerold}{attributes}{positions}[1] ) ];
|
||||||
|
|
||||||
|
$hash->{helper}{areapos} = [ dclone( $hash->{helper}{mowerold}{attributes}{positions}[0] ), dclone( $hash->{helper}{mowerold}{attributes}{positions}[1] ) ];
|
||||||
|
$hash->{helper}{areapos}[0]{statusTimestamp} = $hash->{helper}{mowerold}{attributes}{metadata}{statusTimestamp};
|
||||||
|
$hash->{helper}{areapos}[1]{statusTimestamp} = $hash->{helper}{mowerold}{attributes}{metadata}{statusTimestamp} - 12000;
|
||||||
|
|
||||||
|
$hash->{helper}{cspos} = [ dclone( $hash->{helper}{mowerold}{attributes}{positions}[0] ), dclone( $hash->{helper}{mowerold}{attributes}{positions}[1] ) ];
|
||||||
|
$hash->{helper}{cspos}[0]{statusTimestamp} = $hash->{helper}{mowerold}{attributes}{metadata}{statusTimestamp};
|
||||||
|
$hash->{helper}{cspos}[1]{statusTimestamp} = $hash->{helper}{mowerold}{attributes}{metadata}{statusTimestamp} - 600000;
|
||||||
|
}
|
||||||
|
|
||||||
|
$hash->{helper}{mower} = dclone( $hash->{helper}{mowers}[$mowerNumber] );
|
||||||
|
my $storediff = $hash->{helper}{mower}{attributes}{metadata}{statusTimestamp} - $hash->{helper}{mowerold}{attributes}{metadata}{statusTimestamp};
|
||||||
|
if ($storediff) {
|
||||||
|
|
||||||
|
AlignArray( $hash );
|
||||||
|
FW_detailFn_Update ($hash) if (AttrVal($name,'showMap',1));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# Update readings
|
||||||
|
readingsBeginUpdate($hash);
|
||||||
|
|
||||||
|
readingsBulkUpdateIfChanged($hash, "batteryPercent", $hash->{helper}{mower}{attributes}{battery}{batteryPercent} );
|
||||||
|
readingsBulkUpdateIfChanged($hash, 'api_MowerFound', $foundMower );
|
||||||
|
my $pref = 'mower';
|
||||||
|
readingsBulkUpdateIfChanged($hash, $pref.'_id', $hash->{helper}{mower}{id} );
|
||||||
|
readingsBulkUpdateIfChanged($hash, $pref.'_mode', $hash->{helper}{mower}{attributes}{$pref}{mode} );
|
||||||
|
readingsBulkUpdateIfChanged($hash, $pref.'_activity', $hash->{helper}{mower}{attributes}{$pref}{activity} );
|
||||||
|
readingsBulkUpdateIfChanged($hash, $pref.'_state', $hash->{helper}{mower}{attributes}{$pref}{state} );
|
||||||
|
readingsBulkUpdateIfChanged($hash, $pref.'_commandStatus', 'cleared' );
|
||||||
|
my $tstamp = $hash->{helper}{mower}{attributes}{$pref}{errorCodeTimestamp};
|
||||||
|
my $timestamp = FmtDateTime($tstamp/1000);
|
||||||
|
readingsBulkUpdateIfChanged($hash, $pref."_errorCodeTimestamp", $tstamp ? $timestamp : '-' );
|
||||||
|
my $errc = $hash->{helper}{mower}{attributes}{$pref}{errorCode};
|
||||||
|
readingsBulkUpdateIfChanged($hash, $pref.'_errorCode', $tstamp ? $errc : '-');
|
||||||
|
my $errd = $hash->{helper}{errortable}{$errc};
|
||||||
|
readingsBulkUpdateIfChanged($hash, $pref.'_errorDescription', $tstamp ? $errd : '-');
|
||||||
|
$pref = 'system';
|
||||||
|
readingsBulkUpdateIfChanged($hash, $pref."_name", $hash->{helper}{mower}{attributes}{$pref}{name} );
|
||||||
|
my $model = $hash->{helper}{mower}{attributes}{$pref}{model};
|
||||||
|
$model =~ s/AUTOMOWER./AUTOMOWER®/;
|
||||||
|
$hash->{MODEL} = $model if ( $model && $hash->{MODEL} ne $model );
|
||||||
|
# readingsBulkUpdateIfChanged($hash, $pref."_model", $model );
|
||||||
|
readingsBulkUpdateIfChanged($hash, $pref."_serialNumber", $hash->{helper}{mower}{attributes}{$pref}{serialNumber} );
|
||||||
|
$pref = 'planner';
|
||||||
|
readingsBulkUpdateIfChanged($hash, "planner_restrictedReason", $hash->{helper}{mower}{attributes}{$pref}{restrictedReason} );
|
||||||
|
readingsBulkUpdateIfChanged($hash, "planner_overrideAction", $hash->{helper}{mower}{attributes}{$pref}{override}{action} );
|
||||||
|
|
||||||
|
$tstamp = $hash->{helper}{mower}{attributes}{$pref}{nextStartTimestamp};
|
||||||
|
$timestamp = FmtDateTime($tstamp/1000);
|
||||||
|
readingsBulkUpdateIfChanged($hash, "planner_nextStart", $tstamp ? $timestamp : '-' );
|
||||||
|
$pref = 'statistics';
|
||||||
|
readingsBulkUpdateIfChanged($hash, $pref."_numberOfChargingCycles", $hash->{helper}->{mower}{attributes}{$pref}{numberOfChargingCycles} );
|
||||||
|
readingsBulkUpdateIfChanged($hash, $pref."_totalCuttingTime", $hash->{helper}->{mower}{attributes}{$pref}{totalCuttingTime} );
|
||||||
|
readingsBulkUpdateIfChanged($hash, $pref."_totalChargingTime", $hash->{helper}->{mower}{attributes}{$pref}{totalChargingTime} );
|
||||||
|
readingsBulkUpdateIfChanged($hash, $pref."_totalSearchingTime", $hash->{helper}->{mower}{attributes}{$pref}{totalSearchingTime} );
|
||||||
|
readingsBulkUpdateIfChanged($hash, $pref."_numberOfCollisions", $hash->{helper}->{mower}{attributes}{$pref}{numberOfCollisions} );
|
||||||
|
readingsBulkUpdateIfChanged($hash, $pref."_totalRunningTime", $hash->{helper}->{mower}{attributes}{$pref}{totalRunningTime} );
|
||||||
|
$pref = 'settings';
|
||||||
|
readingsBulkUpdateIfChanged($hash, $pref."_headlight", $hash->{helper}->{mower}{attributes}{$pref}{headlight}{mode} );
|
||||||
|
readingsBulkUpdateIfChanged($hash, $pref."_cuttingHeight", $hash->{helper}->{mower}{attributes}{$pref}{cuttingHeight} );
|
||||||
|
$pref = 'status';
|
||||||
|
readingsBulkUpdateIfChanged($hash, $pref."_connected", $hash->{helper}{mower}{attributes}{metadata}{connected} );
|
||||||
|
readingsBulkUpdateIfChanged($hash, $pref."_Timestamp", FmtDateTime( $hash->{helper}{mower}{attributes}{metadata}{statusTimestamp}/1000 ));
|
||||||
|
readingsBulkUpdateIfChanged($hash, $pref."_TimestampDiff", $storediff/1000 );
|
||||||
|
readingsBulkUpdateIfChanged($hash, $pref."_TimestampOld", FmtDateTime( $hash->{helper}{mowerold}{attributes}{metadata}{statusTimestamp}/1000 ));
|
||||||
|
$pref = 'positions';
|
||||||
|
readingsBulkUpdateIfChanged($hash, $pref."_lastLatitude", $hash->{helper}{mower}{attributes}{$pref}[0]{latitude} );
|
||||||
|
readingsBulkUpdateIfChanged($hash, $pref."_lastLongitude", $hash->{helper}{mower}{attributes}{$pref}[0]{longitude} );
|
||||||
|
readingsBulkUpdateIfChanged($hash, 'state', 'connected' );
|
||||||
|
|
||||||
|
my @time = localtime();
|
||||||
|
my $secs = ( $time[2] * 3600 ) + ( $time[1] * 60 ) + $time[0];
|
||||||
|
my $interval = $hash->{helper}->{interval};
|
||||||
|
# do at midnight
|
||||||
|
if ( $secs <= $interval ) {
|
||||||
|
|
||||||
|
readingsBulkUpdateIfChanged( $hash, 'statistics_lastDayTrack', ReadingsNum( $name, 'statistics_currentDayTrack', 0 ));
|
||||||
|
readingsBulkUpdateIfChanged( $hash, 'statistics_lastDayArea', ReadingsNum( $name, 'statistics_currentDayArea', 0 ));
|
||||||
|
readingsBulkUpdateIfChanged( $hash, 'statistics_currentWeekTrack', ReadingsNum( $name, 'statistics_currentWeekTrack', 0 ) + ReadingsNum( $name, 'statistics_currentDayTrack', 0 ));
|
||||||
|
readingsBulkUpdateIfChanged( $hash, 'statistics_currentWeekArea', ReadingsNum( $name, 'statistics_currentWeekArea', 0 ) + ReadingsNum( $name, 'statistics_currentDayArea', 0 ));
|
||||||
|
readingsBulkUpdateIfChanged( $hash, 'statistics_currentDayTrack', 0, 0);
|
||||||
|
readingsBulkUpdateIfChanged( $hash, 'statistics_currentDayArea', 0, 0);
|
||||||
|
# do on mondays
|
||||||
|
if ( $time[6] == 1 && $secs <= $interval ) {
|
||||||
|
|
||||||
|
readingsBulkUpdateIfChanged( $hash, 'statistics_lastWeekTrack', ReadingsNum( $name, 'statistics_currentWeekTrack', 0 ));
|
||||||
|
readingsBulkUpdateIfChanged( $hash, 'statistics_lastWeekArea', ReadingsNum( $name, 'statistics_currentWeekArea', 0 ));
|
||||||
|
readingsBulkUpdateIfChanged( $hash, 'statistics_currentWeekTrack', 0, 0);
|
||||||
|
readingsBulkUpdateIfChanged( $hash, 'statistics_currentWeekArea', 0, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
readingsEndUpdate($hash, 1);
|
||||||
|
|
||||||
|
RemoveInternalTimer( $hash, \&APIAuth );
|
||||||
|
InternalTimer( gettimeofday() + $interval, \&APIAuth, $hash, 0 );
|
||||||
|
return undef;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
readingsSingleUpdate( $hash, 'state', "error statuscode $statuscode", 1 );
|
||||||
|
Log3 $name, 1, "\ndebug $iam \n\$statuscode [$statuscode]\n\$err [$err],\n \$data [$data] \n\$param->url $param->{url}";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
RemoveInternalTimer( $hash, \&APIAuth );
|
||||||
|
InternalTimer( gettimeofday() + $interval, \&APIAuth, $hash, 0 );
|
||||||
return undef;
|
return undef;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -607,44 +628,47 @@ sub CMDResponse {
|
|||||||
my $hash = $param->{hash};
|
my $hash = $param->{hash};
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
my $type = $hash->{TYPE};
|
my $type = $hash->{TYPE};
|
||||||
|
my $statuscode = $param->{code};
|
||||||
|
my $interval = $hash->{helper}{interval};
|
||||||
my $iam = "$type $name CMDResponse:";
|
my $iam = "$type $name CMDResponse:";
|
||||||
|
|
||||||
if($err ne "") {
|
Log3 $name, 1, "\ndebug $iam \n\$statuscode [$statuscode]\n\$err [$err],\n \$data [$data] \n\$param->url $param->{url}" if ( AttrVal($name, 'debug', '') );
|
||||||
readingsSingleUpdate( $hash, 'state', 'error', 1 );
|
|
||||||
Log3 $name, 2, "$iam error while requesting ".$param->{url}." - $err";
|
if( !$err && $statuscode == 202 && $data ) {
|
||||||
|
|
||||||
} elsif($data ne "") {
|
|
||||||
|
|
||||||
my $result = eval { decode_json($data) };
|
my $result = eval { decode_json($data) };
|
||||||
if ($@) {
|
if ($@) {
|
||||||
|
|
||||||
Log3( $name, 2, "$iam - JSON error while request: $@");
|
Log3( $name, 2, "$iam - JSON error while request: $@");
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$hash->{helper}{CMDResponse} = $result;
|
|
||||||
if ($result->{message}) {
|
|
||||||
readingsSingleUpdate( $hash, 'state', 'error', 1 );
|
|
||||||
Log3 $name, 2, "$iam" . $data;
|
|
||||||
$hash->{helper}->{mower_commandStatus} = $result->{message};
|
|
||||||
|
|
||||||
} elsif ($result->{errors}) {
|
|
||||||
Log3 $name, 2, "$iam" . $data;
|
|
||||||
readingsSingleUpdate( $hash, 'state', 'error', 1 );
|
|
||||||
$hash->{helper}->{mower_commandStatus} = 'ERROR - '. $result->{errors}[0]{title};
|
|
||||||
} elsif ($result->{data}) {
|
|
||||||
Log3 $name, 5, $data;
|
|
||||||
if ( ref ($result->{data}) eq 'ARRAY') {
|
|
||||||
$hash->{helper}->{mower_commandStatus} = 'OK - '. $result->{data}[0]{type};
|
|
||||||
} else {
|
} else {
|
||||||
$hash->{helper}->{mower_commandStatus} = 'OK - '. $result->{data}{type};
|
|
||||||
}
|
$hash->{helper}{CMDResponse} = $result;
|
||||||
|
if ($result->{data}) {
|
||||||
|
|
||||||
|
Log3 $name, 5, $data;
|
||||||
|
if ( ref ($result->{data}) eq 'ARRAY') {
|
||||||
|
|
||||||
|
$hash->{helper}->{mower_commandStatus} = 'OK - '. $result->{data}[0]{type};
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
$hash->{helper}->{mower_commandStatus} = 'OK - '. $result->{data}{type};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
readingsSingleUpdate($hash, 'mower_commandStatus', $hash->{helper}->{mower_commandStatus} ,1);
|
||||||
|
return undef;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
readingsSingleUpdate($hash, 'mower_commandStatus', $hash->{helper}->{mower_commandStatus} ,1);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readingsSingleUpdate($hash, 'mower_commandStatus', "ERROR statuscode $statuscode" ,1);
|
||||||
|
Log3 $name, 2, "\n$iam \n\$statuscode [$statuscode]\n\$err [$err],\n\$data [$data]\n\$param->url $param->{url}";
|
||||||
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
#########################
|
#########################
|
||||||
@ -652,7 +676,7 @@ sub Get {
|
|||||||
my ($hash,@val) = @_;
|
my ($hash,@val) = @_;
|
||||||
my $type = $hash->{TYPE};
|
my $type = $hash->{TYPE};
|
||||||
|
|
||||||
return "$type $hash->{NAME} Get: needs at least an argument" if ( @val < 2 );
|
return "$type $hash->{NAME} Get: needs at least one argument" if ( @val < 2 );
|
||||||
|
|
||||||
my ($name,$setName,$setVal,$setVal2,$setVal3) = @val;
|
my ($name,$setName,$setVal,$setVal2,$setVal3) = @val;
|
||||||
my $iam = "$type $name Get:";
|
my $iam = "$type $name Get:";
|
||||||
@ -671,7 +695,7 @@ sub Set {
|
|||||||
my ($hash,@val) = @_;
|
my ($hash,@val) = @_;
|
||||||
my $type = $hash->{TYPE};
|
my $type = $hash->{TYPE};
|
||||||
|
|
||||||
return "$type $hash->{NAME} Set: needs at least an argument" if ( @val < 2 );
|
return "$type $hash->{NAME} Set: needs at least one argument" if ( @val < 2 );
|
||||||
|
|
||||||
my ($name,$setName,$setVal,$setVal2,$setVal3) = @val;
|
my ($name,$setName,$setVal,$setVal2,$setVal3) = @val;
|
||||||
my $iam = "$type $name Set:";
|
my $iam = "$type $name Set:";
|
||||||
@ -705,6 +729,8 @@ sub Set {
|
|||||||
my ($passResp, $passErr) = $hash->{helper}->{passObj}->setStorePassword($name, $setVal);
|
my ($passResp, $passErr) = $hash->{helper}->{passObj}->setStorePassword($name, $setVal);
|
||||||
Log3 $name, 1, "$iam error: $passErr" if ($passErr);
|
Log3 $name, 1, "$iam error: $passErr" if ($passErr);
|
||||||
return "$iam $passErr" if( $passErr );
|
return "$iam $passErr" if( $passErr );
|
||||||
|
RemoveInternalTimer($hash, \&APIAuth);
|
||||||
|
APIAuth($hash);
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -721,18 +747,16 @@ sub Set {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} elsif ( !IsDisabled($name) && $setName eq 'getNewAccessToken' ) {
|
} elsif ( !IsDisabled($name) && $setName eq 'getNewAccessToken' ) {
|
||||||
if ( $setVal ) {
|
|
||||||
|
|
||||||
readingsBeginUpdate($hash);
|
readingsBeginUpdate($hash);
|
||||||
readingsBulkUpdateIfChanged( $hash, '.access_token', '', 0 );
|
readingsBulkUpdateIfChanged( $hash, '.access_token', '', 0 );
|
||||||
readingsBulkUpdateIfChanged( $hash, 'state', 'initialized');
|
readingsBulkUpdateIfChanged( $hash, 'state', 'initialized');
|
||||||
readingsBulkUpdateIfChanged( $hash, 'mower_commandStatus', 'cleared');
|
readingsBulkUpdateIfChanged( $hash, 'mower_commandStatus', 'cleared');
|
||||||
readingsEndUpdate($hash, 1);
|
readingsEndUpdate($hash, 1);
|
||||||
|
|
||||||
RemoveInternalTimer($hash, \&APIAuth);
|
RemoveInternalTimer($hash, \&APIAuth);
|
||||||
APIAuth($hash);
|
APIAuth($hash);
|
||||||
return undef;
|
return undef;
|
||||||
}
|
|
||||||
|
|
||||||
} elsif (ReadingsVal( $name, 'state', 'defined' ) !~ /defined|initialized|authentification|authenticated|update/ && $setName =~ /ParkUntilFurtherNotice|ParkUntilNextSchedule|Pause|ResumeSchedule|sendScheduleFromAttributeToMower/) {
|
} elsif (ReadingsVal( $name, 'state', 'defined' ) !~ /defined|initialized|authentification|authenticated|update/ && $setName =~ /ParkUntilFurtherNotice|ParkUntilNextSchedule|Pause|ResumeSchedule|sendScheduleFromAttributeToMower/) {
|
||||||
sendCMD($hash,$setName);
|
sendCMD($hash,$setName);
|
||||||
|
Loading…
Reference in New Issue
Block a user