mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-02-25 09:55:38 +00:00
74_AutomowerConnect: Common.pm, automowerconnect.js, handle userattr for API timeouts and logleveldevio, measure response time, prevent some warnings, update map via FW extension, reduce side effects while maually update mower data via polling
git-svn-id: https://svn.fhem.de/fhem/trunk@27684 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
f3eddb5d81
commit
5551c67305
@ -1,5 +1,9 @@
|
|||||||
# 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_AutomowerConnect: Common.pm, automowerconnect.js
|
||||||
|
handle userattr for API timeouts and logleveldevio, measure
|
||||||
|
response time, prevent some warnings, update map via FW extension,
|
||||||
|
reduce side effects while maually update mower data via polling
|
||||||
- feature: 72_FRITZBOX: Attribut: disableHostIPv4check
|
- feature: 72_FRITZBOX: Attribut: disableHostIPv4check
|
||||||
- bugfix: 72_FRITZBOX: Parameter Fehlerbehandlung: get fritzLog
|
- bugfix: 72_FRITZBOX: Parameter Fehlerbehandlung: get fritzLog
|
||||||
- change: 10_KNX: moved KNX_scan function to KNXIO-module, see Forum #122582
|
- change: 10_KNX: moved KNX_scan function to KNXIO-module, see Forum #122582
|
||||||
|
@ -378,11 +378,39 @@ __END__
|
|||||||
</code></li>
|
</code></li>
|
||||||
|
|
||||||
<li><a href="disable">disable</a></li>
|
<li><a href="disable">disable</a></li>
|
||||||
|
|
||||||
<li><a href="disabledForIntervals">disabledForIntervals</a></li>
|
<li><a href="disabledForIntervals">disabledForIntervals</a></li>
|
||||||
<br><br>
|
<br><br>
|
||||||
</ul>
|
</ul>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
|
||||||
|
<a id="AutomowerConnectUserAttr"></a>
|
||||||
|
<b>userattr</b><br>
|
||||||
|
<ul>
|
||||||
|
The following user attributes are taken into account.<br>
|
||||||
|
|
||||||
|
<li><a id='AutomowerConnect-attr-loglevelDevIo'>loglevelDevIo</a><br>
|
||||||
|
<code>attr <name> loglevelDevIo <[012345]></code><br>
|
||||||
|
Set internal deviologlevel, <a target="_blank" href="https://wiki.fhem.de/wiki/DevIo#Wichtige_Internals_zur_Konfiguration"> DevIo: Wichtige_Internals_zur_Konfiguration</a> </li>
|
||||||
|
|
||||||
|
<li><a id='AutomowerConnect-attr-timeoutGetMower'>timeoutGetMower</a><br>
|
||||||
|
<code>attr <name> timeoutGetMower <[6 to 60]></code><br>
|
||||||
|
Set timeout for API call, default 5 s. </li>
|
||||||
|
|
||||||
|
<li><a id='AutomowerConnect-attr-timeoutApiAuth'>ApiAuth</a><br>
|
||||||
|
<code>attr <name> timeoutApiAuth <[6 to 60]></code><br>
|
||||||
|
Set timeout for API call, default 5 s. </li>
|
||||||
|
|
||||||
|
<li><a id='AutomowerConnect-attr-timeoutCMD'>timeoutCMD</a><br>
|
||||||
|
<code>attr <name> timeoutCMD <[6 to 60]></code><br>
|
||||||
|
Set timeout for API call, default 5 s. </li><br>
|
||||||
|
The response time is meassured and logged if a timeout ist set to 60 s.
|
||||||
|
|
||||||
|
<br><br>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
<a id="AutomowerConnectReadings"></a>
|
<a id="AutomowerConnectReadings"></a>
|
||||||
<b>Readings</b>
|
<b>Readings</b>
|
||||||
<ul>
|
<ul>
|
||||||
@ -407,7 +435,7 @@ __END__
|
|||||||
<li>settings_cuttingHeight - actual cutting height from API</li>
|
<li>settings_cuttingHeight - actual cutting height from API</li>
|
||||||
<li>settings_headlight - actual headlight mode from API</li>
|
<li>settings_headlight - actual headlight mode from API</li>
|
||||||
<li>statistics_newGeoDataSets - number of new data sets between the last two different time stamps</li>
|
<li>statistics_newGeoDataSets - number of new data sets between the last two different time stamps</li>
|
||||||
<li>statistics_numberOfCollisions - Number of collisions (last day/all days)</li>
|
<li>statistics_numberOfCollisions - Number of collisions (current day/last day/all days)</li>
|
||||||
<li>status_connected - state of connetion between mower and Husqvarna Cloud.</li>
|
<li>status_connected - state of connetion between mower and Husqvarna Cloud.</li>
|
||||||
<li>status_statusTimestamp - local time of last status update</li>
|
<li>status_statusTimestamp - local time of last status update</li>
|
||||||
<li>status_statusTimestampDiff - time difference in seconds between the last and second last status update</li>
|
<li>status_statusTimestampDiff - time difference in seconds between the last and second last status update</li>
|
||||||
@ -708,11 +736,39 @@ __END__
|
|||||||
</code></li>
|
</code></li>
|
||||||
|
|
||||||
<li><a href="disable">disable</a></li>
|
<li><a href="disable">disable</a></li>
|
||||||
|
|
||||||
<li><a href="disabledForIntervals">disabledForIntervals</a></li>
|
<li><a href="disabledForIntervals">disabledForIntervals</a></li>
|
||||||
<br>
|
<br>
|
||||||
</ul>
|
</ul>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
|
||||||
|
<a id="AutomowerConnectUserAttr"></a>
|
||||||
|
<b>userattr</b><br>
|
||||||
|
<ul>
|
||||||
|
Die folgenden Benutzerattribute werden unterstützt.<br>
|
||||||
|
|
||||||
|
<li><a id='AutomowerConnect-attr-loglevelDevIo'>loglevelDevIo</a><br>
|
||||||
|
<code>attr <name> loglevelDevIo <[012345]></code><br>
|
||||||
|
Setzt das Internal deviologlevel, <a target="_blank" href="https://wiki.fhem.de/wiki/DevIo#Wichtige_Internals_zur_Konfiguration"> DevIo: Wichtige_Internals_zur_Konfiguration</a> </li>
|
||||||
|
|
||||||
|
<li><a id='AutomowerConnect-attr-timeoutGetMower'>timeoutGetMower</a><br>
|
||||||
|
<code>attr <name> timeoutGetMower <[6 to 60]></code><br>
|
||||||
|
Setzt den Timeout für das Lesen der Mäherdaten, default 5 s. </li>
|
||||||
|
|
||||||
|
<li><a id='AutomowerConnect-attr-timeoutApiAuth'>timeoutApiAuth</a><br>
|
||||||
|
<code>attr <name> timeoutApiAuth <[6 to 60]></code><br>
|
||||||
|
Setzt den Timeout für die Authentifikation, default 5 s. </li>
|
||||||
|
|
||||||
|
<li><a id='AutomowerConnect-attr-timeoutCMD'>timeoutCMD</a><br>
|
||||||
|
<code>attr <name> timeoutCMD <[6 to 60]></code><br>
|
||||||
|
Setzt den Timeout für Befehl senden, default 15 s. </li><br>
|
||||||
|
Wird ein Timeout auf 60 s gesetzt, wird die Antwortzeit gemessen und geloggt.
|
||||||
|
|
||||||
|
<br><br>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
<a id="AutomowerConnectReadings"></a>
|
<a id="AutomowerConnectReadings"></a>
|
||||||
<b>Readings</b>
|
<b>Readings</b>
|
||||||
<ul>
|
<ul>
|
||||||
@ -737,7 +793,7 @@ __END__
|
|||||||
<li>settings_cuttingHeight - aktuelle Schnitthöhe aus der API</li>
|
<li>settings_cuttingHeight - aktuelle Schnitthöhe aus der API</li>
|
||||||
<li>settings_headlight - aktueller Scheinwerfermode aus der API</li>
|
<li>settings_headlight - aktueller Scheinwerfermode aus der API</li>
|
||||||
<li>statistics_newGeoDataSets - Anzahl der neuen Datensätze zwischen den letzten zwei unterschiedlichen Zeitstempeln</li>
|
<li>statistics_newGeoDataSets - Anzahl der neuen Datensätze zwischen den letzten zwei unterschiedlichen Zeitstempeln</li>
|
||||||
<li>statistics_numberOfCollisions - Anzahl der Kollisionen (letzter Tag/alle Tage)</li>
|
<li>statistics_numberOfCollisions - Anzahl der Kollisionen (laufender Tag/letzter Tag/alle Tage)</li>
|
||||||
<li>status_connected - Status der Verbindung zwischen dem Automower und der Husqvarna Cloud.</li>
|
<li>status_connected - Status der Verbindung zwischen dem Automower und der Husqvarna Cloud.</li>
|
||||||
<li>status_statusTimestamp - Lokalzeit des letzten Statusupdates in der API</li>
|
<li>status_statusTimestamp - Lokalzeit des letzten Statusupdates in der API</li>
|
||||||
<li>status_statusTimestampDiff - Zeitdifferenz zwischen dem letzten und vorletzten Statusupdate.</li>
|
<li>status_statusTimestampDiff - Zeitdifferenz zwischen dem letzten und vorletzten Statusupdate.</li>
|
||||||
|
@ -47,6 +47,7 @@ BEGIN {
|
|||||||
CommandAttr
|
CommandAttr
|
||||||
CommandDeleteReading
|
CommandDeleteReading
|
||||||
FmtDateTime
|
FmtDateTime
|
||||||
|
FW_ME
|
||||||
getKeyValue
|
getKeyValue
|
||||||
InternalTimer
|
InternalTimer
|
||||||
InternalVal
|
InternalVal
|
||||||
@ -174,10 +175,14 @@ my $mapZonesTpl = '{
|
|||||||
interval_ping => 60,
|
interval_ping => 60,
|
||||||
retry_interval_apiauth => 840,
|
retry_interval_apiauth => 840,
|
||||||
retry_interval_getmower => 840,
|
retry_interval_getmower => 840,
|
||||||
|
timeout_apiauth => 5,
|
||||||
|
timeout_getmower => 5,
|
||||||
|
timeout_cmd => 15,
|
||||||
midnightCycle => 1,
|
midnightCycle => 1,
|
||||||
client_id => $client_id,
|
client_id => $client_id,
|
||||||
grant_type => 'client_credentials',
|
grant_type => 'client_credentials',
|
||||||
mowerNumber => $mowerNumber,
|
mowerNumber => $mowerNumber,
|
||||||
|
detailFnFirst => 0,
|
||||||
scaleToMeterLongitude => 67425,
|
scaleToMeterLongitude => 67425,
|
||||||
scaleToMeterLatitude => 108886,
|
scaleToMeterLatitude => 108886,
|
||||||
minLon => 180,
|
minLon => 180,
|
||||||
@ -187,7 +192,6 @@ my $mapZonesTpl = '{
|
|||||||
imageHeight => 650,
|
imageHeight => 650,
|
||||||
imageWidthHeight => '350 650',
|
imageWidthHeight => '350 650',
|
||||||
mapdesign => $mapAttr,
|
mapdesign => $mapAttr,
|
||||||
detailFnFirst => 0,
|
|
||||||
mapZonesTpl => $mapZonesTpl,
|
mapZonesTpl => $mapZonesTpl,
|
||||||
posMinMax => "-180 90\n180 -90",
|
posMinMax => "-180 90\n180 -90",
|
||||||
newdatasets => 0,
|
newdatasets => 0,
|
||||||
@ -201,7 +205,8 @@ my $mapZonesTpl = '{
|
|||||||
positions => [],
|
positions => [],
|
||||||
timestamp => 0,
|
timestamp => 0,
|
||||||
errordesc => '-',
|
errordesc => '-',
|
||||||
errordate => ''
|
errordate => '',
|
||||||
|
errorstate => ''
|
||||||
},
|
},
|
||||||
UNKNOWN => {
|
UNKNOWN => {
|
||||||
short => 'U',
|
short => 'U',
|
||||||
@ -289,7 +294,7 @@ my $mapZonesTpl = '{
|
|||||||
|
|
||||||
|
|
||||||
AddExtension( $name, \&GetMap, "$type/$name/map" );
|
AddExtension( $name, \&GetMap, "$type/$name/map" );
|
||||||
# AddExtension( $name, \&GetJson, "$type/$name/json" );
|
AddExtension( $name, \&GetJson, "$type/$name/json" );
|
||||||
|
|
||||||
if ( $::init_done ) {
|
if ( $::init_done ) {
|
||||||
|
|
||||||
@ -339,7 +344,9 @@ sub Undefine {
|
|||||||
my $type = $hash->{TYPE};
|
my $type = $hash->{TYPE};
|
||||||
|
|
||||||
RemoveInternalTimer( $hash );
|
RemoveInternalTimer( $hash );
|
||||||
RemoveExtension("$type/$name/map");
|
RemoveExtension( "$type/$name/map" );
|
||||||
|
RemoveExtension( "$type/$name/json" );
|
||||||
|
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,8 +370,10 @@ sub Rename {
|
|||||||
my $hash = $defs{$newname};
|
my $hash = $defs{$newname};
|
||||||
my $type = $hash->{TYPE};
|
my $type = $hash->{TYPE};
|
||||||
|
|
||||||
RemoveExtension("$type/$oldname/map");
|
RemoveExtension( "$type/$oldname/map" );
|
||||||
|
RemoveExtension( "$type/$oldname/json" );
|
||||||
AddExtension( $newname, \&GetMap, "$type/$newname/map" );
|
AddExtension( $newname, \&GetMap, "$type/$newname/map" );
|
||||||
|
AddExtension( $newname, \&GetJson, "$type/$newname/json" );
|
||||||
|
|
||||||
if ( $type eq 'AutomowerConnect' ) {
|
if ( $type eq 'AutomowerConnect' ) {
|
||||||
|
|
||||||
@ -436,7 +445,7 @@ sub FW_detailFn {
|
|||||||
|
|
||||||
if ( $hash->{helper} && $hash->{helper}{mower} && $hash->{helper}{mower}{attributes} && $hash->{helper}{mower}{attributes}{positions} && @{$hash->{helper}{mower}{attributes}{positions}} > 0 ) {
|
if ( $hash->{helper} && $hash->{helper}{mower} && $hash->{helper}{mower}{attributes} && $hash->{helper}{mower}{attributes}{positions} && @{$hash->{helper}{mower}{attributes}{positions}} > 0 ) {
|
||||||
|
|
||||||
my $img = "./fhem/$type/$name/map";
|
my $img = "$FW_ME/$type/$name/map";
|
||||||
my $zoom=AttrVal( $name,"mapImageZoom", 0.7 );
|
my $zoom=AttrVal( $name,"mapImageZoom", 0.7 );
|
||||||
my $backgroundcolor = AttrVal($name, 'mapBackgroundColor','');
|
my $backgroundcolor = AttrVal($name, 'mapBackgroundColor','');
|
||||||
my $bgstyle = $backgroundcolor ? " background-color:$backgroundcolor;" : '';
|
my $bgstyle = $backgroundcolor ? " background-color:$backgroundcolor;" : '';
|
||||||
@ -544,46 +553,96 @@ sub FW_detailFn_Update {
|
|||||||
my $mapy = $latlo-$latru;
|
my $mapy = $latlo-$latru;
|
||||||
|
|
||||||
# MOWING PATH
|
# MOWING PATH
|
||||||
my $posxy = '';
|
my @posxy = ();
|
||||||
|
|
||||||
if ( @pos > 0 ) {
|
if ( @pos > 0 ) {
|
||||||
|
my $k = 0;
|
||||||
|
for ( my $i = 0; $i < @pos; $i++ ){
|
||||||
|
|
||||||
$posxy = int( ( $lonlo-$pos[ 0 ]{longitude} ) * $picx / $mapx ).",".int( ( $latlo-$pos[ 0 ]{latitude} ) * $picy / $mapy ).",'".$pos[ 0 ]{act}."'";
|
$posxy[ $k++ ] = int( ( $lonlo - $pos[ $i ]{longitude} ) * $picx / $mapx );
|
||||||
|
$posxy[ $k++ ] = int( ( $latlo - $pos[ $i ]{latitude} ) * $picy / $mapy );
|
||||||
for ( my $i = 1; $i < @pos; $i++ ){
|
$posxy[ $k++ ] = $pos[ $i ]{act};
|
||||||
|
|
||||||
$posxy .= ",".int( ( $lonlo - $pos[ $i ]{longitude} ) * $picx / $mapx ).",".int( ( $latlo - $pos[ $i ]{latitude} ) * $picy / $mapy ).",'".$pos[ $i ]{act}."'";
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# MOWING PATH OLD
|
||||||
|
# my $posxy = '';
|
||||||
|
|
||||||
|
# if ( @pos > 0 ) {
|
||||||
|
|
||||||
|
# $posxy = int( ( $lonlo-$pos[ 0 ]{longitude} ) * $picx / $mapx ).",".int( ( $latlo-$pos[ 0 ]{latitude} ) * $picy / $mapy ).",'".$pos[ 0 ]{act}."'";
|
||||||
|
|
||||||
|
# for ( my $i = 1; $i < @pos; $i++ ){
|
||||||
|
|
||||||
|
# $posxy .= ",".int( ( $lonlo - $pos[ $i ]{longitude} ) * $picx / $mapx ).",".int( ( $latlo - $pos[ $i ]{latitude} ) * $picy / $mapy ).",'".$pos[ $i ]{act}."'";
|
||||||
|
|
||||||
|
# }
|
||||||
|
|
||||||
|
# }
|
||||||
|
|
||||||
# ERROR MESSAGE
|
# ERROR MESSAGE
|
||||||
my $errdesc = $hash->{helper}{lasterror}{errordesc};
|
my $errdesc = $hash->{helper}{lasterror}{errordesc};
|
||||||
my $errdate = $hash->{helper}{lasterror}{errordate};
|
my $errdate = $hash->{helper}{lasterror}{errordate};
|
||||||
|
my $errstate = $hash->{helper}{lasterror}{errorstate};
|
||||||
|
|
||||||
# ERROR PATH
|
# ERROR PATH
|
||||||
my $poserrxy = int( ( $lonru-$lonlo ) / 2 * $picx / $mapx ).",".int( ( $latlo - $latru ) / 2 * $picy / $mapy );;
|
|
||||||
|
my @poserrxy = ( int( ( $lonru-$lonlo ) / 2 * $picx / $mapx ), int( ( $latlo - $latru ) / 2 * $picy / $mapy ) );
|
||||||
|
|
||||||
if ( @poserr > 0 ) {
|
if ( @poserr > 0 ) {
|
||||||
|
my $k = 0;
|
||||||
|
for ( my $i = 0; $i < @poserr; $i++ ){
|
||||||
|
|
||||||
$poserrxy = int( ( $lonlo - $poserr[ 0 ]{longitude} ) * $picx / $mapx ) . "," . int( ( $latlo - $poserr[ 0 ]{latitude} ) * $picy / $mapy );
|
$poserrxy[ $k++ ] = int( ( $lonlo - $poserr[ $i ]{longitude} ) * $picx / $mapx );
|
||||||
|
$poserrxy[ $k++ ] = int( ( $latlo - $poserr[ $i ]{latitude} ) * $picy / $mapy );
|
||||||
|
|
||||||
for ( my $i = 1; $i < @poserr; $i++ ){
|
|
||||||
$poserrxy .= ",".int( ( $lonlo - $poserr[ $i ]{longitude} ) * $picx / $mapx) . "," . int( ( $latlo - $poserr[ $i ]{latitude} ) * $picy / $mapy );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ERROR PATH OLD
|
||||||
|
# my $poserrxy = int( ( $lonru-$lonlo ) / 2 * $picx / $mapx ).",".int( ( $latlo - $latru ) / 2 * $picy / $mapy );;
|
||||||
|
|
||||||
|
# if ( @poserr > 0 ) {
|
||||||
|
|
||||||
|
# $poserrxy = int( ( $lonlo - $poserr[ 0 ]{longitude} ) * $picx / $mapx ) . "," . int( ( $latlo - $poserr[ 0 ]{latitude} ) * $picy / $mapy );
|
||||||
|
|
||||||
|
# for ( my $i = 1; $i < @poserr; $i++ ){
|
||||||
|
# $poserrxy .= ",".int( ( $lonlo - $poserr[ $i ]{longitude} ) * $picx / $mapx) . "," . int( ( $latlo - $poserr[ $i ]{latitude} ) * $picy / $mapy );
|
||||||
|
# }
|
||||||
|
|
||||||
|
# }
|
||||||
|
|
||||||
# Log3 $name, 1, "AutomowerConnectUpdateDetail ( '$name', '$type', $detailFnFirst, $picx, $picy, $scalx, [ '$errdesc', '$errdate' ], [ $posxy ], [ $poserrxy ] )";
|
# Log3 $name, 1, "AutomowerConnectUpdateDetail ( '$name', '$type', $detailFnFirst, $picx, $picy, $scalx, [ '$errdesc', '$errdate' ], [ $posxy ], [ $poserrxy ] )";
|
||||||
my $detailFnFirst = $hash->{helper}{detailFnFirst};
|
|
||||||
|
# map {
|
||||||
|
# ::FW_directNotify("#FHEMWEB:$_", "AutomowerConnectUpdateDetail ( '$name', '$type', $detailFnFirst, $picx, $picy, $scalx, [ '$errdesc', '$errdate', '$errstate' ], [ $posxy ], [ $poserrxy ] )","");
|
||||||
|
# } devspec2array("TYPE=FHEMWEB");
|
||||||
|
|
||||||
|
# prepare hash for json map update
|
||||||
|
$hash->{helper}{mapupdate}{name} = $name;
|
||||||
|
$hash->{helper}{mapupdate}{type} = $type;
|
||||||
|
$hash->{helper}{mapupdate}{detailfnfirst} = $hash->{helper}{detailFnFirst};
|
||||||
|
$hash->{helper}{mapupdate}{lonlo} = $lonlo;
|
||||||
|
$hash->{helper}{mapupdate}{latlo} = $latlo;
|
||||||
|
$hash->{helper}{mapupdate}{mapx} = $mapx;
|
||||||
|
$hash->{helper}{mapupdate}{mapy} = $mapy;
|
||||||
|
$hash->{helper}{mapupdate}{picx} = $picx;
|
||||||
|
$hash->{helper}{mapupdate}{picy} = $picy;
|
||||||
|
$hash->{helper}{mapupdate}{scalx} = $scalx;
|
||||||
|
$hash->{helper}{mapupdate}{errdesc} = [ "$errdesc", "$errdate", "$errstate" ];
|
||||||
|
$hash->{helper}{mapupdate}{posxy} = \@posxy;
|
||||||
|
$hash->{helper}{mapupdate}{poserrxy} = \@poserrxy;
|
||||||
|
|
||||||
map {
|
map {
|
||||||
::FW_directNotify("#FHEMWEB:$_", "AutomowerConnectUpdateDetail ( '$name', '$type', $detailFnFirst, $picx, $picy, $scalx, [ '$errdesc', '$errdate' ], [ $posxy ], [ $poserrxy ] )","");
|
::FW_directNotify("#FHEMWEB:$_", "AutomowerConnectUpdateJson ( '$FW_ME/$type/$name/json' )","");
|
||||||
} devspec2array("TYPE=FHEMWEB");
|
} devspec2array("TYPE=FHEMWEB");
|
||||||
|
|
||||||
$hash->{helper}{detailFnFirst} = 0;
|
$hash->{helper}{detailFnFirst} = 0;
|
||||||
return undef;
|
|
||||||
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
##############################################################
|
##############################################################
|
||||||
@ -617,17 +676,19 @@ sub APIAuth {
|
|||||||
my $client_id = $hash->{helper}->{client_id};
|
my $client_id = $hash->{helper}->{client_id};
|
||||||
my $client_secret = $hash->{helper}->{passObj}->getReadPassword( $name );
|
my $client_secret = $hash->{helper}->{passObj}->getReadPassword( $name );
|
||||||
my $grant_type = $hash->{helper}->{grant_type};
|
my $grant_type = $hash->{helper}->{grant_type};
|
||||||
|
my $timeout = AttrVal( $name, 'timeoutApiAuth', $hash->{helper}->{timeout_apiauth} );
|
||||||
|
|
||||||
my $header = "Content-Type: application/x-www-form-urlencoded\r\nAccept: application/json";
|
my $header = "Content-Type: application/x-www-form-urlencoded\r\nAccept: application/json";
|
||||||
my $data = 'grant_type=' . $grant_type.'&client_id=' . $client_id . '&client_secret=' . $client_secret;
|
my $data = 'grant_type=' . $grant_type.'&client_id=' . $client_id . '&client_secret=' . $client_secret;
|
||||||
::HttpUtils_NonblockingGet( {
|
::HttpUtils_NonblockingGet( {
|
||||||
url => AUTHURL . '/oauth2/token',
|
url => AUTHURL . '/oauth2/token',
|
||||||
timeout => 5,
|
timeout => $timeout,
|
||||||
hash => $hash,
|
hash => $hash,
|
||||||
method => 'POST',
|
method => 'POST',
|
||||||
header => $header,
|
header => $header,
|
||||||
data => $data,
|
data => $data,
|
||||||
callback => \&APIAuthResponse,
|
callback => \&APIAuthResponse,
|
||||||
|
t_begin => scalar gettimeofday()
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -648,6 +709,7 @@ sub APIAuthResponse {
|
|||||||
my $statuscode = $param->{code} // '';
|
my $statuscode = $param->{code} // '';
|
||||||
my $iam = "$type $name APIAuthResponse:";
|
my $iam = "$type $name APIAuthResponse:";
|
||||||
|
|
||||||
|
Log3 $name, 1, "$iam response time ". sprintf( "%.2f", ( gettimeofday() - $param->{t_begin} ) ) . ' s' if ( $param->{timeout} == 60 );
|
||||||
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, 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) {
|
if( !$err && $statuscode == 200 && $data) {
|
||||||
@ -726,17 +788,19 @@ sub getMower {
|
|||||||
my $access_token = ReadingsVal($name,".access_token","");
|
my $access_token = ReadingsVal($name,".access_token","");
|
||||||
my $provider = ReadingsVal($name,".provider","");
|
my $provider = ReadingsVal($name,".provider","");
|
||||||
my $client_id = $hash->{helper}->{client_id};
|
my $client_id = $hash->{helper}->{client_id};
|
||||||
|
my $timeout = AttrVal( $name, 'timeoutGetMower', $hash->{helper}->{timeout_getmower} );
|
||||||
|
|
||||||
my $header = "Accept: application/vnd.api+json\r\nX-Api-Key: " . $client_id . "\r\nAuthorization: Bearer " . $access_token . "\r\nAuthorization-Provider: " . $provider;
|
my $header = "Accept: application/vnd.api+json\r\nX-Api-Key: " . $client_id . "\r\nAuthorization: Bearer " . $access_token . "\r\nAuthorization-Provider: " . $provider;
|
||||||
Log3 $name, 5, "$iam header [ $header ]";
|
Log3 $name, 5, "$iam header [ $header ]";
|
||||||
|
|
||||||
::HttpUtils_NonblockingGet({
|
::HttpUtils_NonblockingGet({
|
||||||
url => APIURL . "/mowers",
|
url => APIURL . "/mowers",
|
||||||
timeout => 5,
|
timeout => $timeout,
|
||||||
hash => $hash,
|
hash => $hash,
|
||||||
method => "GET",
|
method => "GET",
|
||||||
header => $header,
|
header => $header,
|
||||||
callback => \&getMowerResponse,
|
callback => \&getMowerResponse,
|
||||||
|
t_begin => scalar gettimeofday()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -750,10 +814,11 @@ 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 $statuscode = $param->{code} // '';
|
||||||
my $iam = "$type $name getMowerResponse:";
|
my $iam = "$type $name getMowerResponse:";
|
||||||
my $mowerNumber = $hash->{helper}{mowerNumber};
|
my $mowerNumber = $hash->{helper}{mowerNumber};
|
||||||
|
|
||||||
|
Log3 $name, 1, "$iam response time ". sprintf( "%.2f", ( gettimeofday() - $param->{t_begin} ) ) . ' s' if ( $param->{timeout} == 60 );
|
||||||
Log3 $name, 1, "debug $iam \$statuscode [$statuscode]\n\$err [$err],\n \$data [$data] \n\$param->url $param->{url}" if ( AttrVal($name, 'debug', '') );
|
Log3 $name, 1, "debug $iam \$statuscode [$statuscode]\n\$err [$err],\n \$data [$data] \n\$param->url $param->{url}" if ( AttrVal($name, 'debug', '') );
|
||||||
|
|
||||||
if( !$err && $statuscode == 200 && $data) {
|
if( !$err && $statuscode == 200 && $data) {
|
||||||
@ -789,7 +854,7 @@ sub getMowerResponse {
|
|||||||
}
|
}
|
||||||
Log3 $name, 5, "$iam found $foundMower ";
|
Log3 $name, 5, "$iam found $foundMower ";
|
||||||
|
|
||||||
if ( defined ($hash->{helper}{mower}{id}) && $hash->{helper}{midnightCycle} ) { # update dataset
|
if ( defined ( $hash->{helper}{mower}{id} ) && $hash->{helper}{midnightCycle} ) { # update dataset
|
||||||
|
|
||||||
$hash->{helper}{mowerold}{attributes}{metadata}{statusTimestamp} = $hash->{helper}{mower}{attributes}{metadata}{statusTimestamp};
|
$hash->{helper}{mowerold}{attributes}{metadata}{statusTimestamp} = $hash->{helper}{mower}{attributes}{metadata}{statusTimestamp};
|
||||||
$hash->{helper}{mowerold}{attributes}{mower}{activity} = $hash->{helper}{mower}{attributes}{mower}{activity};
|
$hash->{helper}{mowerold}{attributes}{mower}{activity} = $hash->{helper}{mower}{attributes}{mower}{activity};
|
||||||
@ -800,6 +865,7 @@ sub getMowerResponse {
|
|||||||
$hash->{helper}{mowerold}{attributes}{metadata}{statusTimestamp} = $hash->{helper}{mowers}[$mowerNumber]{attributes}{metadata}{statusTimestamp};
|
$hash->{helper}{mowerold}{attributes}{metadata}{statusTimestamp} = $hash->{helper}{mowers}[$mowerNumber]{attributes}{metadata}{statusTimestamp};
|
||||||
$hash->{helper}{mowerold}{attributes}{mower}{activity} = $hash->{helper}{mowers}[$mowerNumber]{attributes}{mower}{activity};
|
$hash->{helper}{mowerold}{attributes}{mower}{activity} = $hash->{helper}{mowers}[$mowerNumber]{attributes}{mower}{activity};
|
||||||
$hash->{helper}{mowerold}{attributes}{statistics}{numberOfCollisions} = $hash->{helper}{mowers}[$mowerNumber]{attributes}{statistics}{numberOfCollisions};
|
$hash->{helper}{mowerold}{attributes}{statistics}{numberOfCollisions} = $hash->{helper}{mowers}[$mowerNumber]{attributes}{statistics}{numberOfCollisions};
|
||||||
|
$hash->{helper}{statistics}{numberOfCollisionsOld} = $hash->{helper}{mowers}[$mowerNumber]{attributes}{statistics}{numberOfCollisions};
|
||||||
|
|
||||||
if ( AttrVal( $name, 'mapImageCoordinatesToRegister', '' ) eq '' ) {
|
if ( AttrVal( $name, 'mapImageCoordinatesToRegister', '' ) eq '' ) {
|
||||||
posMinMax( $hash, $hash->{helper}{mowers}[$mowerNumber]{attributes}{positions} );
|
posMinMax( $hash, $hash->{helper}{mowers}[$mowerNumber]{attributes}{positions} );
|
||||||
@ -814,7 +880,7 @@ sub getMowerResponse {
|
|||||||
|
|
||||||
$hash->{helper}{storediff} = $hash->{helper}{mower}{attributes}{metadata}{statusTimestamp} - $hash->{helper}{mowerold}{attributes}{metadata}{statusTimestamp};
|
$hash->{helper}{storediff} = $hash->{helper}{mower}{attributes}{metadata}{statusTimestamp} - $hash->{helper}{mowerold}{attributes}{metadata}{statusTimestamp};
|
||||||
|
|
||||||
calculateStatistics($hash) if ( $hash->{helper}{midnightCycle} );
|
calculateStatistics( $hash ) if ( $hash->{helper}{midnightCycle} );
|
||||||
|
|
||||||
# Update readings
|
# Update readings
|
||||||
readingsBeginUpdate($hash);
|
readingsBeginUpdate($hash);
|
||||||
@ -873,6 +939,7 @@ sub CMD {
|
|||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
my $type = $hash->{TYPE};
|
my $type = $hash->{TYPE};
|
||||||
my $iam = "$type $name CMD:";
|
my $iam = "$type $name CMD:";
|
||||||
|
my $timeout = AttrVal( $name, 'timeoutCMD', $hash->{helper}->{timeout_cmd} );
|
||||||
$hash->{helper}{mower_commandSend} = $cmd[ 0 ] . ' ' . ( $cmd[ 1 ] ? $cmd[ 1 ] : '' );
|
$hash->{helper}{mower_commandSend} = $cmd[ 0 ] . ' ' . ( $cmd[ 1 ] ? $cmd[ 1 ] : '' );
|
||||||
|
|
||||||
if ( IsDisabled( $name ) ) {
|
if ( IsDisabled( $name ) ) {
|
||||||
@ -920,12 +987,13 @@ my $header = "Accept: application/vnd.api+json\r\nX-Api-Key: ".$client_id."\r\nA
|
|||||||
|
|
||||||
::HttpUtils_NonblockingGet({
|
::HttpUtils_NonblockingGet({
|
||||||
url => APIURL . "/mowers/". $mower_id . "/".$post,
|
url => APIURL . "/mowers/". $mower_id . "/".$post,
|
||||||
timeout => 15,
|
timeout => $timeout,
|
||||||
hash => $hash,
|
hash => $hash,
|
||||||
method => "POST",
|
method => "POST",
|
||||||
header => $header,
|
header => $header,
|
||||||
data => $json,
|
data => $json,
|
||||||
callback => \&CMDResponse,
|
callback => \&CMDResponse,
|
||||||
|
t_begin => scalar gettimeofday()
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -939,6 +1007,7 @@ sub CMDResponse {
|
|||||||
my $statuscode = $param->{code};
|
my $statuscode = $param->{code};
|
||||||
my $iam = "$type $name CMDResponse:";
|
my $iam = "$type $name CMDResponse:";
|
||||||
|
|
||||||
|
Log3 $name, 1, "$iam response time ". sprintf( "%.2f", ( gettimeofday() - $param->{t_begin} ) ) . ' s' if ( $param->{timeout} == 60 );
|
||||||
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, 1, "\ndebug $iam \n\$statuscode [$statuscode]\n\$err [$err],\n \$data [$data] \n\$param->url $param->{url}" if ( AttrVal($name, 'debug', '') );
|
||||||
|
|
||||||
if( !$err && $statuscode == 202 && $data ) {
|
if( !$err && $statuscode == 202 && $data ) {
|
||||||
@ -1169,6 +1238,34 @@ sub Attr {
|
|||||||
|
|
||||||
}
|
}
|
||||||
##########
|
##########
|
||||||
|
} elsif( $attrName eq "loglevelDevIo" ) {
|
||||||
|
|
||||||
|
if( $cmd eq "set" ) {
|
||||||
|
|
||||||
|
return "$iam $attrName is invalid, select a number of [012345]" unless( $attrVal =~ /^[0-5]{1}$/ );
|
||||||
|
$hash->{devioLoglevel} = $attrVal;
|
||||||
|
Log3 $name, 4, "$iam $cmd $attrName $attrVal";
|
||||||
|
|
||||||
|
} elsif( $cmd eq "del" ) {
|
||||||
|
|
||||||
|
delete( $hash->{devioLoglevel} );
|
||||||
|
Log3 $name, 3, "$iam $cmd $attrName and set default.";
|
||||||
|
|
||||||
|
}
|
||||||
|
##########
|
||||||
|
} elsif( $attrName =~ /^(timeoutGetMower|timeoutApiAuth|timeoutCMD)$/ ) {
|
||||||
|
|
||||||
|
if( $cmd eq "set" ) {
|
||||||
|
|
||||||
|
return "$iam $attrVal is invalid, allowed time as integer between 5 and 61" unless( $attrVal =~ /^[\d]{1,2}$/ && $attrVal > 5 && $attrVal < 61 );
|
||||||
|
Log3 $name, 4, "$iam $cmd $attrName $attrVal";
|
||||||
|
|
||||||
|
} elsif( $cmd eq "del" ) {
|
||||||
|
|
||||||
|
Log3 $name, 3, "$iam $cmd $attrName and set default value.";
|
||||||
|
|
||||||
|
}
|
||||||
|
##########
|
||||||
} elsif ( $attrName eq 'numberOfWayPointsToDisplay' ) {
|
} elsif ( $attrName eq 'numberOfWayPointsToDisplay' ) {
|
||||||
|
|
||||||
my $icurr = scalar @{$hash->{helper}{areapos}};
|
my $icurr = scalar @{$hash->{helper}{areapos}};
|
||||||
@ -1179,7 +1276,7 @@ sub Attr {
|
|||||||
for ( my $i = $icurr; $i > $attrVal; $i-- ) {
|
for ( my $i = $icurr; $i > $attrVal; $i-- ) {
|
||||||
pop @{$hash->{helper}{areapos}};
|
pop @{$hash->{helper}{areapos}};
|
||||||
}
|
}
|
||||||
Log3 $name, 3, "$iam $cmd $attrName $attrVal";
|
Log3 $name, 4, "$iam $cmd $attrName $attrVal";
|
||||||
|
|
||||||
} elsif( $cmd eq "del" ) {
|
} elsif( $cmd eq "del" ) {
|
||||||
|
|
||||||
@ -1360,6 +1457,8 @@ sub AlignArray {
|
|||||||
|
|
||||||
@ar = reverse @ar if ( $cnt > 1 ); # positions seem to be in reversed order
|
@ar = reverse @ar if ( $cnt > 1 ); # positions seem to be in reversed order
|
||||||
|
|
||||||
|
# @ar = @ar if ( $cnt > 1 ); # positions seem to be not in reversed order
|
||||||
|
|
||||||
$tmp = dclone( \@ar );
|
$tmp = dclone( \@ar );
|
||||||
|
|
||||||
if ( @{ $hash->{helper}{areapos} } ) {
|
if ( @{ $hash->{helper}{areapos} } ) {
|
||||||
@ -1434,6 +1533,7 @@ sub isErrorThanPrepare {
|
|||||||
my $errc = $hash->{helper}{mower}{attributes}{mower}{errorCode};
|
my $errc = $hash->{helper}{mower}{attributes}{mower}{errorCode};
|
||||||
$hash->{helper}{lasterror}{errordesc} = $::FHEM::Devices::AMConnect::Common::errortable->{$errc};
|
$hash->{helper}{lasterror}{errordesc} = $::FHEM::Devices::AMConnect::Common::errortable->{$errc};
|
||||||
$hash->{helper}{lasterror}{errordate} = FmtDateTimeGMT( $ect / 1000 );
|
$hash->{helper}{lasterror}{errordate} = FmtDateTimeGMT( $ect / 1000 );
|
||||||
|
$hash->{helper}{lasterror}{errorstate} = $hash->{helper}{mower}{attributes}{mower}{state};
|
||||||
$hash->{helper}{lasterror}{errorzone} = $hash->{helper}{currentZone} if ( defined( $hash->{helper}{currentZone} ) );
|
$hash->{helper}{lasterror}{errorzone} = $hash->{helper}{currentZone} if ( defined( $hash->{helper}{currentZone} ) );
|
||||||
|
|
||||||
my $tmp = dclone( $hash->{helper}{lasterror} );
|
my $tmp = dclone( $hash->{helper}{lasterror} );
|
||||||
@ -1458,6 +1558,7 @@ sub resetLastErrorIfCorrected {
|
|||||||
$hash->{helper}{lasterror}{timestamp} = 0;
|
$hash->{helper}{lasterror}{timestamp} = 0;
|
||||||
$hash->{helper}{lasterror}{errordesc} = '-';
|
$hash->{helper}{lasterror}{errordesc} = '-';
|
||||||
$hash->{helper}{lasterror}{errordate} = '';
|
$hash->{helper}{lasterror}{errordate} = '';
|
||||||
|
$hash->{helper}{lasterror}{errorstate} = '';
|
||||||
::FHEM::Devices::AMConnect::Common::FW_detailFn_Update ($hash);
|
::FHEM::Devices::AMConnect::Common::FW_detailFn_Update ($hash);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1653,22 +1754,28 @@ sub GetMap() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#########################
|
#########################
|
||||||
# sub GetJson() {
|
sub GetJson() {
|
||||||
# my ($request) = @_;
|
my ($request) = @_;
|
||||||
|
|
||||||
# if ( $request =~ /^\/(AutomowerConnect)\/(\w+)\/json/ ) {
|
if ( $request =~ /^\/(AutomowerConnect)\/(\w+)\/json/ ) {
|
||||||
|
|
||||||
# my $type = $1;
|
my $type = $1;
|
||||||
# my $name = $2;
|
my $name = $2;
|
||||||
# my $hash = $::defs{$name};
|
my $hash = $::defs{$name};
|
||||||
# my $jsonMime = "application/json";
|
my $jsonMime = "application/json";
|
||||||
# my $jsonData = eval { encode_json ( $hash->{helper}{areapos} ) };
|
my $jsonData = eval { encode_json ( $hash->{helper}{mapupdate} ) };
|
||||||
# return ( $jsonMime, $jsonData );
|
if ($@) {
|
||||||
|
|
||||||
# }
|
Log3 $name, 2, "$type $name encode_json error: $@";
|
||||||
# return ( "text/plain; charset=utf-8", "No AutomowerConnect device for webhook $request" );
|
return ( "text/plain; charset=utf-8", "No AutomowerConnect device for webhook $request" );
|
||||||
|
|
||||||
# }
|
}
|
||||||
|
return ( $jsonMime, $jsonData );
|
||||||
|
|
||||||
|
}
|
||||||
|
return ( "text/plain; charset=utf-8", "No AutomowerConnect device for webhook $request" );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#########################
|
#########################
|
||||||
sub readMap {
|
sub readMap {
|
||||||
@ -1782,7 +1889,8 @@ sub fillReadings {
|
|||||||
readingsBulkUpdateIfChanged($hash, "planner_nextStart", $tstamp ? $timestamp : '-' );
|
readingsBulkUpdateIfChanged($hash, "planner_nextStart", $tstamp ? $timestamp : '-' );
|
||||||
|
|
||||||
$pref = 'statistics';
|
$pref = 'statistics';
|
||||||
readingsBulkUpdateIfChanged( $hash, $pref."_numberOfCollisions", '(' . $hash->{helper}{statistics}{lastDayCollisions} . '/' . $hash->{helper}{mower}{attributes}{$pref}{numberOfCollisions} . ')' );
|
my $noCol = $hash->{helper}{mower}{attributes}{$pref}{numberOfCollisions} - $hash->{helper}{mowerold}{attributes}{$pref}{numberOfCollisions};
|
||||||
|
readingsBulkUpdateIfChanged( $hash, $pref."_numberOfCollisions", '(' . $noCol . '/' . $hash->{helper}{statistics}{lastDayCollisions} . '/' . $hash->{helper}{mower}{attributes}{$pref}{numberOfCollisions} . ')' );
|
||||||
readingsBulkUpdateIfChanged( $hash, $pref."_newGeoDataSets", $hash->{helper}{newdatasets} );
|
readingsBulkUpdateIfChanged( $hash, $pref."_newGeoDataSets", $hash->{helper}{newdatasets} );
|
||||||
$pref = 'settings';
|
$pref = 'settings';
|
||||||
readingsBulkUpdateIfChanged( $hash, $pref."_headlight", $hash->{helper}{mower}{attributes}{$pref}{headlight}{mode} );
|
readingsBulkUpdateIfChanged( $hash, $pref."_headlight", $hash->{helper}{mower}{attributes}{$pref}{headlight}{mode} );
|
||||||
@ -1806,7 +1914,9 @@ sub calculateStatistics {
|
|||||||
$hash->{helper}{statistics}{lastDayTrack} = $hash->{helper}{statistics}{currentDayTrack};
|
$hash->{helper}{statistics}{lastDayTrack} = $hash->{helper}{statistics}{currentDayTrack};
|
||||||
$hash->{helper}{statistics}{lastDayArea} = $hash->{helper}{statistics}{currentDayArea};
|
$hash->{helper}{statistics}{lastDayArea} = $hash->{helper}{statistics}{currentDayArea};
|
||||||
$hash->{helper}{statistics}{lastDayTime} = $hash->{helper}{statistics}{currentDayTime};
|
$hash->{helper}{statistics}{lastDayTime} = $hash->{helper}{statistics}{currentDayTime};
|
||||||
$hash->{helper}{statistics}{lastDayCollisions} = $hash->{helper}{mower}{attributes}{statistics}{numberOfCollisions} - $hash->{helper}{mowerold}{attributes}{statistics}{numberOfCollisions};
|
$hash->{helper}{statistics}{lastDayCollisions} = $hash->{helper}{mower}{attributes}{statistics}{numberOfCollisions} - $hash->{helper}{statistics}{numberOfCollisionsOld};
|
||||||
|
$hash->{helper}{statistics}{numberOfCollisionsOld} = $hash->{helper}{mower}{attributes}{statistics}{numberOfCollisions};
|
||||||
|
|
||||||
$hash->{helper}{statistics}{currentWeekTrack} += $hash->{helper}{statistics}{currentDayTrack};
|
$hash->{helper}{statistics}{currentWeekTrack} += $hash->{helper}{statistics}{currentDayTrack};
|
||||||
$hash->{helper}{statistics}{currentWeekArea} += $hash->{helper}{statistics}{currentDayArea};
|
$hash->{helper}{statistics}{currentWeekArea} += $hash->{helper}{statistics}{currentDayArea};
|
||||||
$hash->{helper}{statistics}{currentWeekTime} += $hash->{helper}{statistics}{currentDayTime};
|
$hash->{helper}{statistics}{currentWeekTime} += $hash->{helper}{statistics}{currentDayTime};
|
||||||
@ -2056,7 +2166,7 @@ sub listErrorStack {
|
|||||||
|
|
||||||
for ( my $i = 0; $i < @{ $hash->{helper}{errorstack} }; $i++ ) {
|
for ( my $i = 0; $i < @{ $hash->{helper}{errorstack} }; $i++ ) {
|
||||||
|
|
||||||
$cnt++; $ret .= '<tr class="column '.( $cnt % 2 ? 'odd' : 'even' ).'"><td> ' . $hash->{helper}{errorstack}[$i]{errordate} . ' </td><td> ' . $hash->{helper}{errorstack}[$i]{errordesc} . ' </td><td> ' . $hash->{helper}{errorstack}[$i]{errorzone} . ' </td><td> ' . $hash->{helper}{errorstack}[$i]{positions}[0]{longitude} . ' / ' . $hash->{helper}{errorstack}[$i]{positions}[0]{latitude} . ' </td></tr>';
|
$cnt++; $ret .= '<tr class="column '.( $cnt % 2 ? 'odd' : 'even' ).'"><td> ' . $hash->{helper}{errorstack}[$i]{errordate} . ' </td><td> ' . $hash->{helper}{errorstack}[$i]{errorstate} . ' - ' . $hash->{helper}{errorstack}[$i]{errordesc} . ' </td><td> ' . $hash->{helper}{errorstack}[$i]{errorzone} . ' </td><td> ' . $hash->{helper}{errorstack}[$i]{positions}[0]{longitude} . ' / ' . $hash->{helper}{errorstack}[$i]{positions}[0]{latitude} . ' </td></tr>';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2299,17 +2409,17 @@ sub wsRead {
|
|||||||
|
|
||||||
AlignArray( $hash );
|
AlignArray( $hash );
|
||||||
|
|
||||||
my $deltaTime = $hash->{helper}{positionsTime} - $hash->{helper}{statusTime};
|
# my $deltaTime = $hash->{helper}{positionsTime} - $hash->{helper}{statusTime};
|
||||||
|
|
||||||
# if encounter positions shortly after status-event count it as error positions
|
# if encounter positions shortly after status-event count it as error positions
|
||||||
if ( $hash->{helper}{mower}{attributes}{mower}{errorCode} && $deltaTime > 0 && $deltaTime < 0.29 && @{ $result->{attributes}{positions} } < 3) {
|
# if ( $hash->{helper}{mower}{attributes}{mower}{errorCode} && $deltaTime > 0 && $deltaTime < 0.29 && @{ $result->{attributes}{positions} } < 3) {
|
||||||
|
|
||||||
$hash->{helper}{areapos}[ 0 ]{act} = 'N';
|
# $hash->{helper}{areapos}[ 0 ]{act} = 'N';
|
||||||
$hash->{helper}{areapos}[ 1 ]{act} = 'N';
|
# $hash->{helper}{areapos}[ 1 ]{act} = 'N';
|
||||||
$hash->{helper}{lasterror}{positions} = [dclone( $hash->{helper}{areapos}[ 0 ] ), dclone( $hash->{helper}{areapos}[ 1 ] ) ];
|
# $hash->{helper}{lasterror}{positions} = [dclone( $hash->{helper}{areapos}[ 0 ] ), dclone( $hash->{helper}{areapos}[ 1 ] ) ];
|
||||||
$hash->{helper}{errorstack}[0]{positions} = [dclone( $hash->{helper}{areapos}[ 0 ] ), dclone( $hash->{helper}{areapos}[ 1 ] ) ];
|
# $hash->{helper}{errorstack}[0]{positions} = [dclone( $hash->{helper}{areapos}[ 0 ] ), dclone( $hash->{helper}{areapos}[ 1 ] ) ];
|
||||||
|
|
||||||
}
|
# }
|
||||||
|
|
||||||
FW_detailFn_Update ($hash);
|
FW_detailFn_Update ($hash);
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ function AutomowerConnectShowError( ctx, div, dev, picx, picy, errdesc, erray )
|
|||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.fillStyle = div.getAttribute( 'data-errorBackgroundColor' );
|
ctx.fillStyle = div.getAttribute( 'data-errorBackgroundColor' );
|
||||||
ctx.font = div.getAttribute( 'data-errorFont' );
|
ctx.font = div.getAttribute( 'data-errorFont' );
|
||||||
var m = ctx.measureText( errdesc[ 1 ] + ', ' + dev + ': ' + errdesc[ 0 ] ).width > picy - 6;
|
var m = ctx.measureText( errdesc[ 1 ] + ', ' + dev + ': ' + errdesc[ 2 ] + ' - ' + errdesc[ 0 ] ).width > picx - 6;
|
||||||
|
|
||||||
if ( m ) {
|
if ( m ) {
|
||||||
|
|
||||||
@ -24,11 +24,11 @@ function AutomowerConnectShowError( ctx, div, dev, picx, picy, errdesc, erray )
|
|||||||
if ( m ) {
|
if ( m ) {
|
||||||
|
|
||||||
ctx.fillText( errdesc[ 1 ] + ', ' + dev + ':', 3, 15 );
|
ctx.fillText( errdesc[ 1 ] + ', ' + dev + ':', 3, 15 );
|
||||||
ctx.fillText( errdesc[ 0 ], 3, 30 );
|
ctx.fillText( errdesc[ 2 ] + ' - ' + errdesc[ 0 ], 3, 30 );
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
ctx.fillText( errdesc[ 1 ] + ', ' + dev + ': ' + errdesc[ 0 ], 3, 15 );
|
ctx.fillText( errdesc[ 1 ] + ', ' + dev + ': ' + errdesc[ 2 ] + ' - ' + errdesc[ 0 ], 3, 15 );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,11 +271,18 @@ function AutomowerConnectTor ( x0, y0, x1, y1 ) {
|
|||||||
//~ log ('ret: ' + ret);
|
//~ log ('ret: ' + ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function AutomowerConnectUpdateJson ( path ) {
|
||||||
|
$.getJSON( path, function( data, textStatus ) {
|
||||||
|
log( 'AutomowerConnectUpdateJson ( '+path+' ): status '+textStatus );
|
||||||
|
AutomowerConnectUpdateDetail ( data.name, data.type, data.detailfnfirst, data.picx, data.picy, data.scalx, data.errdesc, data.posxy, data.poserrxy );
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
//AutomowerConnectUpdateDetail (<devicename>, <type>, <detailfnfirst>, <imagesize x>, <imagesize y>,<scale x>, <error description>, <path array>, <error array>)
|
//AutomowerConnectUpdateDetail (<devicename>, <type>, <detailfnfirst>, <imagesize x>, <imagesize y>,<scale x>, <error description>, <path array>, <error array>)
|
||||||
function AutomowerConnectUpdateDetail (dev, type, detailfnfirst, picx, picy, scalx, errdesc, pos, erray) {
|
function AutomowerConnectUpdateDetail (dev, type, detailfnfirst, picx, picy, scalx, errdesc, pos, erray) {
|
||||||
//~ $.getJSON('./fhem/AutomowerConnect/am430x/json', function(data) {
|
|
||||||
//~ log(data[0].longitude+' '+data[0].latitude+' '+data[0].act);
|
|
||||||
//~ });
|
|
||||||
const colorat = {
|
const colorat = {
|
||||||
"U" : "otherActivityPath",
|
"U" : "otherActivityPath",
|
||||||
"N" : "errorPath",
|
"N" : "errorPath",
|
||||||
@ -286,7 +293,6 @@ function AutomowerConnectUpdateDetail (dev, type, detailfnfirst, picx, picy, sca
|
|||||||
"L" : "leavingPath",
|
"L" : "leavingPath",
|
||||||
"G" : "goingHomePath"
|
"G" : "goingHomePath"
|
||||||
};
|
};
|
||||||
// log('pos.length '+pos.length+' lixy.length '+lixy.length+', scalx '+scalx );
|
|
||||||
// log('loop: Start '+ type+' '+dev );
|
// log('loop: Start '+ type+' '+dev );
|
||||||
if (FW_urlParams.detail == dev || 1) {
|
if (FW_urlParams.detail == dev || 1) {
|
||||||
const canvas_0 = document.getElementById(type+'_'+dev+'_canvas_0');
|
const canvas_0 = document.getElementById(type+'_'+dev+'_canvas_0');
|
||||||
@ -295,7 +301,7 @@ function AutomowerConnectUpdateDetail (dev, type, detailfnfirst, picx, picy, sca
|
|||||||
|
|
||||||
if ( canvas && canvas_0 ) {
|
if ( canvas && canvas_0 ) {
|
||||||
|
|
||||||
// log('loop: canvas && canvas_0 true '+ type+' '+dev );
|
// log('loop: canvas && canvas_0 true '+ type+' '+dev + ' detailfnfirst '+detailfnfirst);
|
||||||
|
|
||||||
if ( detailfnfirst ) {
|
if ( detailfnfirst ) {
|
||||||
|
|
||||||
@ -306,6 +312,7 @@ function AutomowerConnectUpdateDetail (dev, type, detailfnfirst, picx, picy, sca
|
|||||||
// draw area limits
|
// draw area limits
|
||||||
const lixy = div.getAttribute( 'data-areaLimitsPath' ).split(",");
|
const lixy = div.getAttribute( 'data-areaLimitsPath' ).split(",");
|
||||||
if ( lixy.length > 0 ) AutomowerConnectLimits( ctx0, div, lixy, 'area' );
|
if ( lixy.length > 0 ) AutomowerConnectLimits( ctx0, div, lixy, 'area' );
|
||||||
|
// log('pos.length '+pos.length+' lixy.length '+lixy.length+', scalx '+scalx );
|
||||||
|
|
||||||
// draw property limits
|
// draw property limits
|
||||||
const plixy = div.getAttribute( 'data-propertyLimitsPath' ).split( "," );
|
const plixy = div.getAttribute( 'data-propertyLimitsPath' ).split( "," );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user