2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-01-31 06:39:11 +00:00

AutomowerConnectFamily: 75_AutomowerConnectDevice: last revision, declared deprecated,will be removed soon, change definition to AutomowerConnect, use different application key, 74_AutomowerConnect: Common.pm remove attr mowerActivityToHighLight, extend design attributes, automowerconnect.js enhanced highlighting

git-svn-id: https://svn.fhem.de/fhem/trunk@27585 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
Ellert 2023-05-17 12:42:21 +00:00
parent a06c1f1fc3
commit c87a771b34
5 changed files with 124 additions and 292 deletions

View File

@ -1,5 +1,10 @@
# 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: 75_AutomowerConnectDevice: last revision, declared deprecated
will be removed soon, change definition to AutomowerConnect
use different application key
- change: 74_AutomowerConnect: Common.pm remove attr mowerActivityToHighLight
extend design attributes, automowerconnect.js enhanced highlighting
- change: 93_DbRep: attr executeBeforeProc, executeAfterProc can execute
FHEM commands as well as PERL code
- bugfix: 82_LGTV_WebOS: fix little typos and change version

View File

@ -113,7 +113,6 @@ sub Initialize() {
"mapBackgroundColor " .
"mapDesignAttributes:textField-long " .
"mapZones:textField-long " .
"mowerActivityToHighLight:textField-long " .
"showMap:1,0 " .
"chargingStationCoordinates " .
"chargingStationImagePosition:left,top,right,bottom,center " .
@ -329,16 +328,17 @@ sub getMowerResponse {
if ( defined ($hash->{helper}{mower}{id}) ){ # update dataset
$hash->{helper}{mowerold} = dclone( $hash->{helper}{mower} );
$hash->{helper}{mowerold}{attributes}{metadata}{statusTimestamp} = $hash->{helper}{mower}{attributes}{metadata}{statusTimestamp};
$hash->{helper}{mowerold}{attributes}{mower}{activity} = $hash->{helper}{mower}{attributes}{mower}{activity};
} else { # first data set
$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}{timestamps}[ 0 ] = $hash->{helper}{mowerold}{attributes}{metadata}{statusTimestamp};
$hash->{helper}{searchpos} = [ dclone( $hash->{helper}{mowers}[$mowerNumber]{attributes}{positions}[0] ), dclone( $hash->{helper}{mowers}[$mowerNumber]{attributes}{positions}[1] ) ];
$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};
if ( AttrVal( $name, 'mapImageCoordinatesToRegister', '' ) eq '' ) {
::FHEM::Devices::AMConnect::Common::posMinMax( $hash, $hash->{helper}{mowerold}{attributes}{positions} );
::FHEM::Devices::AMConnect::Common::posMinMax( $hash, $hash->{helper}{mowers}[$mowerNumber]{attributes}{positions} );
}
}
@ -348,8 +348,8 @@ sub getMowerResponse {
push( @{ $hash->{helper}{mower}{attributes}{positions} }, @{ dclone( $hash->{helper}{searchpos} ) } );
$hash->{helper}{newdatasets} = 0;
my $storediff = $hash->{helper}{mower}{attributes}{metadata}{statusTimestamp} - $hash->{helper}{mowerold}{attributes}{metadata}{statusTimestamp};
if ($storediff) {
$hash->{helper}{storediff} = $hash->{helper}{mower}{attributes}{metadata}{statusTimestamp} - $hash->{helper}{mowerold}{attributes}{metadata}{statusTimestamp};
if ($hash->{helper}{storediff}) {
::FHEM::Devices::AMConnect::Common::AlignArray( $hash );
::FHEM::Devices::AMConnect::Common::FW_detailFn_Update ($hash) if (AttrVal($name,'showMap',1));
@ -710,24 +710,6 @@ sub Attr {
CommandDeleteReading( $hash, "$name mower_currentZone" );
Log3 $name, 3, "$iam $cmd $attrName";
}
##########
} elsif( $attrName eq "mowerActivityToHighLight" ) {
if( $cmd eq "set" ) {
my $act = 'LEAVING';
my $actold = 'LEAVING';
my $perl = eval "($attrVal)";
if ($@) {
return "$iam $cmd $attrName syntax error in condition: $@ \n $attrVal";
}
Log3 $name, 4, "$iam $cmd $attrName";
} elsif( $cmd eq "del" ) {
Log3 $name, 3, "$iam $cmd $attrName";
}
}
return undef;
@ -751,22 +733,21 @@ __END__
<a id="AutomowerConnect" ></a>
<h3>AutomowerConnect</h3>
<ul>
<u><b>FHEM-FORUM:</b></u> <a target="_blank" href="https://forum.fhem.de/index.php/topic,131661.0.html"> AutomowerConnect und AutomowerConnectDevice</a><br>
<u><b>FHEM-Wiki:</b></u> <a target="_blank" href="https://wiki.fhem.de/wiki/AutomowerConnect"> AutomowerConnect und AutomowerConnectDevice: Wie erstellt man eine Karte des Mähbereiches?</a>
<u><b>FHEM-FORUM:</b></u> <a target="_blank" href="https://forum.fhem.de/index.php/topic,131661.0.html"> AutomowerConnect</a><br>
<u><b>FHEM-Wiki:</b></u> <a target="_blank" href="https://wiki.fhem.de/wiki/AutomowerConnect"> AutomowerConnect: Wie erstellt man eine Karte des Mähbereiches?</a>
<br><br>
<u><b>Introduction</b></u>
<br><br>
<ul>
<li>This module allows the communication between the Husqvarna Cloud and FHEM to control Husqvarna Automower equipped with a Connect Module (SIM).</li>
<li>It acts as Device for one mower and it acts as host for aditional mower registered in the API.</li>
<li>Additional mower have to be defined with the modul AutomowerConnectDevice.</li>
<li>It acts as Device for one mower. Use this Module for aditional mower registered in the API. Provide a different application key and application secret each mower</li>
<li>The mower path is shown in the detail view.</li>
<li>An arbitrary map can be used as background for the mower path.</li>
<li>The map has to be a raster image in webp, png or jpg format.</li>
<li>It's possible to control everything the API offers, e.g. schedule, headlight, cutting height and actions like start, pause, park etc. </li>
<li>Zones are definable. </li>
<li>Cutting height can be set for each zone differently. </li>
<li>All API data is stored in the device hash, the last and the second last one. Use <code>{Dumper $defs{&lt;name&gt;}}</code> in the commandline to find the data and build userReadings out of it.</li><br>
<li>All API data is stored in the device hash. Use <code>{Dumper $defs{&lt;name&gt;}}</code> in the commandline to find the data and build userReadings out of it.</li><br>
</ul>
<u><b>Limits for the Automower Connect API</b></u>
<br><br>
@ -780,7 +761,7 @@ __END__
<br><br>
<ul>
<li>To get access to the API an application has to be created in the <a target="_blank" href="https://developer.husqvarnagroup.cloud/docs/get-started">Husqvarna Developer Portal</a>.</li>
<li>During registration an application key (client_id) and an application secret (client secret) is provided. Use these for for the module. The module uses client credentials as grant type for authorization.</li>
<li>During registration an application key (client_id) and an application secret (client secret) is provided. Use these for for the module.</li>
<li>The module uses client credentials as grant type for authorization.</li>
</ul>
<br>
@ -793,11 +774,6 @@ __END__
It has to be set a <b>client_secret</b>. It's the application secret from the <a target="_blank" href="https://developer.husqvarnagroup.cloud/docs/get-started">Husqvarna Developer Portal</a>.<br>
<code>set myMower &lt;client secret&gt;</code>
<br><br>
Additional mower devices<br>
<code>define &lt;device name&gt; AutomowerConnectDevice &lt;host name&gt; &lt;mower number&gt;</code><br>
Example:<br>
<code>define myAdditionalMower AutomowerConnectDevice MyMower 1</code> Second device with host name <i>myMower</i> and mower number <i>1</i>
<br><br>
</ul>
<br>
@ -1033,16 +1009,6 @@ __END__
}'<br>
</code></li>
<li><a id='AutomowerConnect-attr-mowerActivityToHighLight'>mowerActivityToHighLight</a><br>
<code>attr &lt;name&gt; mowerActivityToHighLight &lt;perl condition to determine a path section&gt;</code><br>
A perl condition to highlight a path section by mower activities.<br>
The current interval activity is accessible by $act. The last intervall activity is accessible by $actold.<br>
LineColor, LineDash and LineWidth are adjustable by the attribut <i>mapDesignAttributes</i> under otherActivityPath...<br>
Example: Highlight path when leaving charging station.<br>
<code>attr &lt;name&gt; mowerActivityToHighLight $act =~ /MOWING|LEAVING/ && $actold =~ /LEAVING|PARKED_IN_CS|CHARGING/</code><br>
Example: Highlight path when returning to charging station.<br>
<code>attr &lt;name&gt; mowerActivityToHighLight $act =~ /PARKED_IN_CS|CHARGING|GOING_HOME/ && $actold =~ /MOWING|GOING_HOME/</code><br></li>
<li><a href="disable">disable</a></li>
<li><a href="disabledForIntervals">disabledForIntervals</a></li>
@ -1078,7 +1044,6 @@ __END__
<li>status_connected - state of connetion between mower and Husqvarna Cloud, (1 => CONNECTED, 0 => OFFLINE)</li>
<li>status_statusTimestamp - local time of last change of the API content</li>
<li>status_statusTimestampDiff - time difference in seconds between the last and second last change of the API content</li>
<li>status_statusTimestampOld - local time of second last change of the API content</li>
<li>system_name - name of the mower</li>
</ul>
@ -1093,22 +1058,21 @@ __END__
<a id="AutomowerConnect"></a>
<h3>AutomowerConnect</h3>
<ul>
<u><b>FHEM-FORUM:</b></u> <a target="_blank" href="https://forum.fhem.de/index.php/topic,131661.0.html"> AutomowerConnect und AutomowerConnectDevice</a><br>
<u><b>FHEM-Wiki:</b></u> <a target="_blank" href="https://wiki.fhem.de/wiki/AutomowerConnect"> AutomowerConnect und AutomowerConnectDevice: Wie erstellt man eine Karte des Mähbereiches?</a>
<u><b>FHEM-FORUM:</b></u> <a target="_blank" href="https://forum.fhem.de/index.php/topic,131661.0.html"> AutomowerConnect</a><br>
<u><b>FHEM-Wiki:</b></u> <a target="_blank" href="https://wiki.fhem.de/wiki/AutomowerConnect"> AutomowerConnect : Wie erstellt man eine Karte des Mähbereiches?</a>
<br><br>
<u><b>Einleitung</b></u>
<br><br>
<ul>
<li>Dieses Modul etabliert eine Kommunikation zwischen der Husqvarna Cloud and FHEM, um einen Husqvarna Automower zu steuern, der mit einem Connect Modul (SIM) ausgerüstet ist.</li>
<li>Es arbeitet als Device für einen Mähroboter und übernimmt die Rolle als Host für zusätzliche in der API registrierte Mähroboter.</li>
<li>Zusätzliche Mähroboter sollten mit dem Modul AutomowerConnectDevice definiert werden..</li>
<li>Es arbeitet als Device für einen Mähroboter. Für zusätzliche in der API registrierte Mähroboter ist für jeden Mäher ein extra Appilcation Key mit Application Secret zu verwenden.</li>
<li>Der Pfad des Mähroboters wird in der Detailansicht des FHEMWEB Frontends angezeigt.</li>
<li>Der Pfad kann mit einer beliebigen Karte hinterlegt werden.</li>
<li>Die Karte muss als Rasterbild im webp, png oder jpg Format vorliegen.</li>
<li>Es ist möglich alles was die API anbietet zu steuern, z.B. Mähplan,Scheinwerfer, Schnitthöhe und Aktionen wie, Start, Pause, Parken usw. </li>
<li>Zonen können selbst definiert werden. </li>
<li>Die Schnitthöhe kann je selbstdefinierter Zone eingestellt werden. </li>
<li>Die letzten und vorletzten Daten aus der API sind im Gerätehash gespeichert, Mit <code>{Dumper $defs{&lt;device name&gt;}}</code> in der Befehlezeile können die Daten angezeigt werden und daraus userReadings erstellt werden.</li><br>
<li>Die Daten aus der API sind im Gerätehash gespeichert, Mit <code>{Dumper $defs{&lt;device name&gt;}}</code> in der Befehlezeile können die Daten angezeigt werden und daraus userReadings erstellt werden.</li><br>
</ul>
<u><b>Limit Automower Connect API</b></u>
<br><br>
@ -1134,11 +1098,6 @@ __END__
<code>define myMower AutomowerConnect 123456789012345678901234567890123456</code> Erstes Gerät: die Defaultmähernummer ist 0.<br>
Es muss ein <b>client_secret</b> gesetzt werden. Es ist das Application Secret vom <a target="_blank" href="https://developer.husqvarnagroup.cloud/docs/get-started">Husqvarna Developer Portal</a>.<br>
<code>set myMower &lt;client secret&gt;</code><br>
<br>
Zusätzlicher Mähroboter<br>
<code>define &lt;device name&gt; AutomowerConnectDevice &lt;host name&gt; &lt;mower number&gt;</code><br>
Beispiel:<br>
<code>define myAdditionalMower AutomowerConnectDevice MyMower 1</code> Zweites Gerät mit Hostname <i>myMower</i> und Mähernummer <i>1</i>
<br><br>
</ul>
<br>
@ -1377,17 +1336,6 @@ __END__
}'<br>
</code></li>
<li><a id='AutomowerConnect-attr-mowerActivityToHighLight'>mowerActivityToHighLight</a><br>
<code>attr &lt;name&gt; mowerActivityToHighLight &lt;perl condition to determine a path section&gt;</code><br>
Eine Perl Bedingung, die Aktivitäten verknüpft, um einen Pfadabschnitt festzulegen, der hervorgehoben wird.<br>
Die Aktivität im aktuellen Intervall steht über die Perlvariable $act und die Aktivität im letzten Intervall über $actold zur Verfügung.<br>
Die Farbe, Strichstärke und Muster können über das Attribut <i>mapDesignAttributes</i> unter otherActivityPath... eingestellt werden.<br>
Beispiel: Pfad beim Verlassen der Ladestation hervorheben.<br>
<code>attr &lt;name&gt; mowerActivityToHighLight $act =~ /MOWING|LEAVING/ && $actold =~ /LEAVING|PARKED_IN_CS|CHARGING/</code><br>
Beispiel: Pfad beim Zurückkehren zur Ladestation hervorheben.<br>
<code>attr &lt;name&gt; mowerActivityToHighLight $act =~ /PARKED_IN_CS|CHARGING|GOING_HOME/ && $actold =~ /MOWING|GOING_HOME/</code><br>
</li>
<li><a href="disable">disable</a></li>
<li><a href="disabledForIntervals">disabledForIntervals</a></li>
@ -1424,7 +1372,6 @@ __END__
<li>status_connected - Status der Verbindung zwischen dem Automower und der Husqvarna Cloud, (1 => CONNECTED, 0 => OFFLINE)</li>
<li>status_statusTimestamp - Lokalzeit der letzten Änderung der Daten in der API</li>
<li>status_statusTimestampDiff - Zeitdifferenz zwischen den beiden letzten Änderungen im Inhalt der Daten aus der API</li>
<li>status_statusTimestampOld - Lokalzeit der vorletzten Änderung der Daten in der API</li>
<li>system_name - Name des Automowers</li>
</ul>
</ul>

View File

@ -107,7 +107,6 @@ sub Initialize() {
"mapBackgroundColor " .
"mapDesignAttributes:textField-long " .
"mapZones:textField-long " .
"mowerActivityToHighLight:textField-long " .
"showMap:1,0 " .
"chargingStationCoordinates " .
"chargingStationImagePosition:left,top,right,bottom,center " .
@ -160,16 +159,17 @@ sub Notify {
my $myMower = dclone( $mowerhash );
if ( defined ($hash->{helper}{mower}{id}) ){ # update dataset
$hash->{helper}{mowerold} = dclone( $hash->{helper}{mower} );
$hash->{helper}{mowerold}{attributes}{metadata}{statusTimestamp} = $hash->{helper}{mower}{attributes}{metadata}{statusTimestamp};
$hash->{helper}{mowerold}{attributes}{mower}{activity} = $hash->{helper}{mower}{attributes}{mower}{activity};
} else { # first data set
$hash->{helper}{mowerold} = $myMower;
$hash->{helper}{searchpos} = [ dclone( $hash->{helper}{mowerold}{attributes}{positions}[0] ), dclone( $hash->{helper}{mowerold}{attributes}{positions}[1] ) ];
$hash->{helper}{timestamps}[ 0 ] = $hash->{helper}{mowerold}{attributes}{metadata}{statusTimestamp};
$hash->{helper}{searchpos} = [ dclone( $myMower->{attributes}{positions}[0] ), dclone( $myMower->{attributes}{positions}[1] ) ];
$hash->{helper}{mowerold}{attributes}{metadata}{statusTimestamp} = $myMower->{attributes}{metadata}{statusTimestamp};
$hash->{helper}{mowerold}{attributes}{mower}{activity} = $myMower->{attributes}{mower}{activity};
if ( AttrVal( $name, 'mapImageCoordinatesToRegister', '' ) eq '' ) {
::FHEM::Devices::AMConnect::Common::posMinMax( $hash, $hash->{helper}{mowerold}{attributes}{positions} );
::FHEM::Devices::AMConnect::Common::posMinMax( $hash, $myMower->{attributes}{positions} );
}
}
@ -179,8 +179,8 @@ sub Notify {
push( @{ $hash->{helper}{mower}{attributes}{positions} }, @{ dclone( $hash->{helper}{searchpos} ) } );
$hash->{helper}{newdatasets} = 0;
my $storediff = $hash->{helper}{mower}{attributes}{metadata}{statusTimestamp} - $hash->{helper}{mowerold}{attributes}{metadata}{statusTimestamp};
if ($storediff) {
$hash->{helper}{storediff} = $hash->{helper}{mower}{attributes}{metadata}{statusTimestamp} - $hash->{helper}{mowerold}{attributes}{metadata}{statusTimestamp};
if ($hash->{helper}{storediff}) {
::FHEM::Devices::AMConnect::Common::AlignArray( $hash );
::FHEM::Devices::AMConnect::Common::FW_detailFn_Update ($hash) if (AttrVal($name,'showMap',1));
@ -494,24 +494,6 @@ sub Attr {
CommandDeleteReading( $hash, "$name mower_currentZone" );
Log3 $name, 3, "$iam $cmd $attrName";
}
##########
} elsif( $attrName eq "mowerActivityToHighLight" ) {
if( $cmd eq "set" ) {
my $act = 'LEAVING';
my $actold = 'LEAVING';
my $perl = eval "($attrVal)";
if ($@) {
return "$iam $cmd $attrName syntax error in condition: $@ \n $attrVal";
}
Log3 $name, 4, "$iam $cmd $attrName";
} elsif( $cmd eq "del" ) {
Log3 $name, 3, "$iam $cmd $attrName";
}
}
return undef;
@ -526,8 +508,8 @@ __END__
=pod
=item device
=item summary Module to control Husqvarnas robotic lawn mowers with Connect Module (SIM)
=item summary_DE Modul zur Steuerung von Husqvarnas Mähroboter mit Connect Modul (SIM)
=item summary This Module is deprecated. Please don't use it.
=item summary_DE Das Modul ist veraltet. Bitte, nicht mehr benutzen.
=begin html
@ -535,23 +517,13 @@ __END__
<h3>AutomowerConnectDevice</h3>
<ul>
<u><b>FHEM-FORUM:</b></u> <a target="_blank" href="https://forum.fhem.de/index.php/topic,131661.0.html"> AutomowerConnect und AutomowerConnectDevice</a><br>
<u><b>FHEM-Wiki:</b></u> <a target="_blank" href="https://wiki.fhem.de/wiki/AutomowerConnect"> AutomowerConnect und AutomowerConnectDevice: Wie erstellt man eine Karte des Mähbereiches?</a>
<br><br>
<u><b>Introduction</b></u>
<br><br>
<ul>
<li>This module uses an entity of the AutomowerConnect Module as host, to control additional Husqvarna Automower equipped with Connect Module (SIM) and if their data hosted there.</li>
<li>The entities of this module are FHEM devices of additional mowers.</li>
<li>This module is nessesary only when additional mowers registered under the same application key.</li>
<li>The mower path is shown in the detail view.</li>
<li>The number of way points to display is customizable.</li>
<li>An arbitrary map can be used as background for the mower path.</li>
<li>The map has to be a raster image in webp, png or jpg format.</li>
<li>It's possible to control everything the API offers, e.g. schedule, headlight, cutting height and actions like start, pause, park etc. </li>
<li>Zones are definable. </li>
<li>Cutting height can be set for each zone differently. </li>
<li>All API data is stored in the device hash, the last and the second last one. Use <code>{Dumper $defs{&lt;name&gt;}}</code> in the commandline to find the data and build userReadings out of it.</li><br>
</ul>
<li><h1>This Module is deprecated. Please don't use it.</h1></li>
<li>Use the AutomowerConnect Modul for additional Mowers. You should use an extra application-key and application-secret</li><br>
</ul>
<u><b>Requirements</b></u>
<br><br>
<ul>
@ -785,16 +757,6 @@ __END__
}'<br>
</code></li>
<li><a id='AutomowerConnectDevice-attr-mowerActivityToHighLight'>mowerActivityToHighLight</a><br>
<code>attr &lt;name&gt; mowerActivityToHighLight &lt;perl condition to determine a path section&gt;</code><br>
A perl condition to highlight a path section by mower activities.<br>
The current interval activity is accessible by $act. The last intervall activity is accessible by $actold.<br>
LineColor, LineDash and LineWidth are adjustable by the attribut <i>mapDesignAttributes</i> under otherActivityPath...<br>
Example: Highlight path when leaving charging station.<br>
<code>attr &lt;name&gt; mowerActivityToHighLight $act =~ /MOWING|LEAVING/ && $actold =~ /LEAVING|PARKED_IN_CS|CHARGING/</code><br>
Example: Highlight path when returning to charging station.<br>
<code>attr &lt;name&gt; mowerActivityToHighLight $act =~ /PARKED_IN_CS|CHARGING|GOING_HOME/ && $actold =~ /MOWING|GOING_HOME/</code><br></li>
<li><a href="disable">disable</a></li>
<li><a href="disabledForIntervals">disabledForIntervals</a></li>
@ -829,7 +791,6 @@ __END__
<li>status_connected - state of connetion between mower and Husqvarna Cloud, (1 => CONNECTED, 0 => OFFLINE)</li>
<li>status_statusTimestamp - local time of last change of the API content</li>
<li>status_statusTimestampDiff - time difference in seconds between the last and second last change of the API content</li>
<li>status_statusTimestampOld - local time of second last change of the API content</li>
<li>system_name - name of the mower</li>
</ul>
@ -845,23 +806,13 @@ __END__
<h3>AutomowerConnectDevice</h3>
<ul>
<u><b>FHEM-FORUM:</b></u> <a target="_blank" href="https://forum.fhem.de/index.php/topic,131661.0.html"> AutomowerConnect und AutomowerConnectDevice</a><br>
<u><b>FHEM-Wiki:</b></u> <a target="_blank" href="https://wiki.fhem.de/wiki/AutomowerConnect"> AutomowerConnect und AutomowerConnectDevice: Wie erstellt man eine Karte des Mähbereiches?</a>
<br><br>
<u><b>Einleitung</b></u>
<br><br>
<ul>
<li>Dieses Modul nutzt eine Istanz des AutomowerConnect Moduls als Host, um einen weiteren Husqvarna Automower, dessen Daten dort gehostet werden und der mit einem Connect Modul (SIM) ausgerüstet ist, zu steuern.</li>
<li>Die Instanzen dieses Moduls bilden die FHEM-Geräte weiterer Mähroboter.</li>
<li>Dieses Modul wird also erst benötigt, wenn mehrere Mähroboter unter einem Application Key registriert sind.</li>
<li>Der Pfad des Mähroboters wird in der Detailansicht des FHEMWEB Frontends angezeigt.</li>
<li>Die Zahl der anzuzeigenden Wegpunkte des Pfades kann frei gewählt werden.</li>
<li>Der Pfad kann mit einer beliebigen Karte hinterlegt werden.</li>
<li>Die Karte muss als Rasterbild im webp, png oder jpg Format vorliegen.</li>
<li>Es ist möglich alles was Die API anbietet zu steuern, z.B. Mähplan,Scheinwerfer, Schnitthöhe und Aktionen wie, Start, Pause, Parken usw. </li>
<li>Zonen können selbst definiert werden. </li>
<li>Die Schnitthöhe kann je selbstdefinierter Zone eingestellt werden. </li>
<li>Die letzten und vorletzten Daten aus dem Host sind im Gerätehash gespeichert, Mit <code>{Dumper $defs{&lt;device name&gt;}}</code> in der Befehlszeile können die Daten angezeigt werden und daraus userReadings erstellt werden.</li><br>
<li>Das Modul ist veraltet. Bitte, nicht mehr benutzen.</li>
<li>Für weitere Mähroboter das Modul AutomowerConnect benutzen. Je Mähroboter sollte ein extra Application Key mit Application Secret verwendet werden.</li><br>
</ul>
<u><b>Anforderungen</b></u>
<br><br>
@ -1098,17 +1049,6 @@ __END__
}'<br>
</code></li>
<li><a id='AutomowerConnectDevice-attr-mowerActivityToHighLight'>mowerActivityToHighLight</a><br>
<code>attr &lt;name&gt; mowerActivityToHighLight &lt;perl condition to determine a path section&gt;</code><br>
Eine Perl Bedingung, die Aktivitäten verknüpft, um einen Pfadabschnitt festzulegen, der hervorgehoben wird.<br>
Die Aktivität im aktuellen Interval steht über die Perlvariable $act und die Aktivität im letzten Intervall über $actold zur Verfügung.<br>
Die Farbe, Strichstärke und Muster können über das Attribut <i>mapDesignAttributes</i> unter otherActivityPath... eingestellt werden.<br>
Beispiel: Pfad beim Verlassen der Ladestation hervorheben.<br>
<code>attr &lt;name&gt; mowerActivityToHighLight $act =~ /MOWING|LEAVING/ && $actold =~ /LEAVING|PARKED_IN_CS|CHARGING/</code><br>
Beispiel: Pfad beim Zurückkehren zur Ladestation hervorheben.<br>
<code>attr &lt;name&gt; mowerActivityToHighLight $act =~ /PARKED_IN_CS|CHARGING|GOING_HOME/ && $actold =~ /MOWING|GOING_HOME/</code><br>
</li>
<li><a href="disable">disable</a></li>
<li><a href="disabledForIntervals">disabledForIntervals</a></li>
@ -1143,7 +1083,6 @@ __END__
<li>status_connected - Status der Verbindung zwischen dem Automower und der Husqvarna Cloud, (1 => CONNECTED, 0 => OFFLINE)</li>
<li>status_statusTimestamp - Lokalzeit der letzten Änderung der Daten in der API</li>
<li>status_statusTimestampDiff - Zeitdifferenz zwichen den beiden letzten Änderungen im Inhalt der Daten aus der API</li>
<li>status_statusTimestampOld - Lokalzeit der vorletzten Änderung der Daten in der API</li>
<li>system_name - Name des Automowers</li>
</ul>
</ul>

View File

@ -137,10 +137,16 @@ errorPathLineDash=""
errorPathLineWidth="2"
chargingStationPathLineColor="#999999"
chargingStationPathLineDash="6,2"
chargingStationPathLineWidth="3"
otherActivityPathLineColor="#33cc33"
chargingStationPathLineWidth="1"
otherActivityPathLineColor="#999999"
otherActivityPathLineDash="6,2"
otherActivityPathLineWidth="2"
otherActivityPathLineWidth="1"
leavingPathLineColor="#33cc33"
leavingPathLineDash="6,2"
leavingPathLineWidth="2"
goingHomePathLineColor="#0099ff"
goingHomePathLineDash="6,2"
goingHomePathLineWidth="2"
mowingPathDisplayStart=""
mowingPathLineColor="#ff0000"
mowingPathLineDash="6,2"
@ -195,7 +201,6 @@ my $mapZonesTpl = '{
MAP_MIME => '',
MAP_CACHE => '',
cspos => [],
otherpos => [],
areapos => [],
searchpos => [],
timestamps => [],
@ -210,18 +215,21 @@ my $mapZonesTpl = '{
olLat => 0
},
UNKNOWN => {
arrayName => 'otherpos',
short => 'U',
arrayName => '',
maxLength => 100,
cnt => 0,
callFn => ''
},
NOT_APPLICABLE => {
arrayName => 'otherpos',
short => 'N',
arrayName => '',
maxLength => 50,
cnt => 0,
callFn => ''
},
MOWING => {
short => 'M',
arrayName => 'areapos',
maxLength => 5000,
maxLengthDefault => 5000,
@ -229,30 +237,35 @@ my $mapZonesTpl = '{
callFn => \&FHEM::Devices::AMConnect::Common::AreaStatistics
},
GOING_HOME => {
arrayName => 'otherpos',
short => 'G',
arrayName => '',
maxLength => 50,
cnt => 0,
callFn => ''
},
CHARGING => {
short => 'C',
arrayName => 'cspos',
maxLength => 100,
cnt => 0,
callFn => \&FHEM::Devices::AMConnect::Common::ChargingStationPosition
},
LEAVING => {
arrayName => 'otherpos',
short => 'L',
arrayName => '',
maxLength => 50,
cnt => 0,
callFn => ''
},
PARKED_IN_CS => {
short => 'P',
arrayName => 'cspos',
maxLength => 100,
cnt => 0,
callFn => \&FHEM::Devices::AMConnect::Common::ChargingStationPosition
},
STOPPED_IN_GARDEN => {
short => 'S',
arrayName => 'otherpos',
maxLength => 50,
cnt => 0,
@ -298,6 +311,10 @@ my $mapZonesTpl = '{
} elsif ( $type eq 'AutomowerConnectDevice' ) {
$hash->{HINWEIS1} = 'Dieses Modul nicht mehr verwenden, die Entwicklung ist eingestellt.';
$hash->{HINWEIS2} = 'Bestehende Instanzen muessen umgehend auf AutomowerConnect umgestellt werden.';
$hash->{HINWEIS3} = 'Für jedes Geraet ist ein extra Application Key zu verwenden.';
RemoveInternalTimer($hash);
InternalTimer( gettimeofday() + 25, \&readMap, $hash, 0);
@ -438,7 +455,6 @@ sub FW_detailFn_Update {
my @pos = @{ $hash->{helper}{areapos} };
my @posc = @{ $hash->{helper}{cspos} };
my @posother = @{ $hash->{helper}{otherpos} };
my @poserr = @{ $hash->{helper}{lasterror}{positions} };
my $img = "./fhem/$type/$name/map";
@ -474,23 +490,12 @@ sub FW_detailFn_Update {
my $cslat = int(($latlo-$csla) * $picy / $mapy);
# MOWING PATH
my $posxy = int($lonlo * $picx / $mapx).",".int($latlo * $picy / $mapy);
my $posxy = int( $lonlo * $picx / $mapx ).",".int( $latlo * $picy / $mapy );
if ( @pos > 1 ) {
$posxy = int(($lonlo-$pos[0]{longitude}) * $picx / $mapx).",".int(($latlo-$pos[0]{latitude}) * $picy / $mapy);
$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);
}
}
# OTHER PATH
my $posoxy = int($lonlo * $picx / $mapx).",".int($latlo * $picy / $mapy);
if ( @posother > 1 ) {
$posoxy = int(($lonlo-$posother[0]{longitude}) * $picx / $mapx).",".int(($latlo-$posother[0]{latitude}) * $picy / $mapy);
for (my $i=1;$i<@posother;$i++){
$posoxy .= ",".int(($lonlo-$posother[$i]{longitude}) * $picx / $mapx).",".int(($latlo-$posother[$i]{latitude}) * $picy / $mapy);
$posxy .= ",".int( ( $lonlo - $pos[ $i ]{longitude} ) * $picx / $mapx ).",".int( ( $latlo - $pos[ $i ]{latitude} ) * $picy / $mapy ).",'".$pos[ $i ]{act}."'";
}
}
@ -551,10 +556,10 @@ sub FW_detailFn_Update {
my $erray = "$errlon,$errlat,$errx,$erry,$poserrxy";
# Log3 $name, 1, "AutomowerConnectUpdateDetail ( '$name', '$type', '$img', $picx, $picy, $cslon, $cslat, '$csimgpos', $scalx, '$errdesc', [ $posxy ], [ $limi ], [ $propli ], [ $poscxy ], [ $erray ] )";
# Log3 $name, 1, "AutomowerConnectUpdateDetail ( '$name', '$type', '$img', $picx, $picy, $cslon, $cslat, '$csimgpos', $scalx, '$errdesc', [ $posxy ], [ $limi ], [ $propli ], [ $erray ] )";
map {
::FW_directNotify("#FHEMWEB:$_", "AutomowerConnectUpdateDetail ( '$name', '$type', '$img', $picx, $picy, $cslon, $cslat, '$csimgpos', $scalx, [ '$errdesc', '$errdate' ], [ $posxy ], [ $limi ], [ $propli ], [ $poscxy ], [ $erray ], [ $posoxy ] )","");
::FW_directNotify("#FHEMWEB:$_", "AutomowerConnectUpdateDetail ( '$name', '$type', '$img', $picx, $picy, $cslon, $cslat, '$csimgpos', $scalx, [ '$errdesc', '$errdate' ], [ $posxy ], [ $limi ], [ $propli ], [ $erray ] )","");
} devspec2array("TYPE=FHEMWEB");
}
return undef;
@ -707,6 +712,9 @@ sub AlignArray {
if ( $cnt > 0 ) {
my @ar = @{ $hash->{helper}{mower}{attributes}{positions} }[ 0 .. $cnt-1 ];
map { $_->{act} = $hash->{helper}{$act}{short} } @ar;
$tmp = dclone( \@ar );
if ( @{ $hash->{helper}{areapos} } ) {
@ -756,15 +764,6 @@ sub AlignArray {
}
my $val = AttrVal($name, 'mowerActivityToHighLight', 0);
if ( $val && eval( "$val" ) ) {
$tmp = dclone( \@ar );
HighlightPath ( $hash, $tmp, $cnt );
}
} else {
$cnt = 0;
@ -909,71 +908,6 @@ sub ZoneHandling {
}
#########################
sub setCuttingHeight {
my ( $hash, $poshash, $cnt ) = @_;
my $name = $hash->{NAME};
my $zone = '';
my $nextzone = '';
my @pos = @$poshash;
my $longitude = 0;
my $latitude = 0;
my @zonekeys = sort (keys %{$hash->{helper}{mapZones}});
my $i = 0;
my $k = 0;
map{ $hash->{helper}{mapZones}{$_}{curZoneCnt} = 0 } @zonekeys;
for ( $i = 0; $i < $cnt; $i++){
$longitude = $pos[$i]{longitude};
$latitude = $pos[$i]{latitude};
for ( $k = 0; $k < @zonekeys-1; $k++){
if ( eval ("$hash->{helper}{mapZones}{$zonekeys[$k]}{condition}") ) {
if ( $hash->{helper}{mapZones}{$zonekeys[$k]}{curZoneCnt} == $i) { # find current zone and count consecutive way points
$hash->{helper}{mapZones}{$zonekeys[$k]}{curZoneCnt}++;
$hash->{helper}{currentZone} = $zonekeys[$k];
}
$hash->{helper}{mapZones}{$zonekeys[$k]}{zoneCnt}++;
$hash->{helper}{mapZones}{$zonekeys[$k]}{zoneLength} += calcPathLength( $hash, $i, $i + 1 );
last;
} elsif ( $k == @zonekeys-2 ) { # last zone
if ( $hash->{helper}{mapZones}{$zonekeys[$k+1]}{curZoneCnt} == $i) { # find current zone and count consecutive way points
$hash->{helper}{mapZones}{$zonekeys[$k+1]}{curZoneCnt}++;
$hash->{helper}{currentZone} = $zonekeys[$k+1];
}
$hash->{helper}{mapZones}{$zonekeys[$k+1]}{zoneCnt}++;
$hash->{helper}{mapZones}{$zonekeys[$k+1]}{zoneLength} += calcPathLength( $hash, $i, $i + 1 );
}
}
}
my $sumDayCnt=0;
my $sumDayArea=0;
map { $sumDayCnt += $hash->{helper}{mapZones}{$_}{zoneCnt};
$hash->{helper}{mapZones}{$_}{currentDayCntPct} = ( $sumDayCnt ? sprintf( "%.0f", $hash->{helper}{mapZones}{$_}{zoneCnt} / $sumDayCnt * 100 ) : 0 );
$sumDayArea += $hash->{helper}{mapZones}{$_}{zoneLength};
$hash->{helper}{mapZones}{$_}{currentDayAreaPct} = ( $sumDayArea ? sprintf( "%.0f", $hash->{helper}{mapZones}{$_}{zoneLength} / $sumDayArea * 100 ) : 0 );
} @zonekeys;
$hash->{helper}{newzonedatasets} = $cnt;
}
#########################
sub ChargingStationPosition {
my ( $hash, $poshash, $cnt ) = @_;
@ -1009,27 +943,6 @@ sub ChargingStationPosition {
}
#########################
sub HighlightPath {
my ( $hash, $poshash, $cnt ) = @_;
if ( $cnt && @{ $hash->{helper}{otherpos} } ) {
unshift ( @{ $hash->{helper}{otherpos} }, @$poshash );
} elsif ( $cnt ) {
$hash->{helper}{otherpos} = $poshash;
}
while ( @{ $hash->{helper}{otherpos} } > $hash->{helper}{UNKNOWN}{maxLength} ) {
pop ( @{ $hash->{helper}{otherpos}} ); # reduce to max allowed length
}
return undef;
}
#########################
sub calcPathLength {
my ( $hash, $istart, $i ) = @_;
@ -1213,10 +1126,8 @@ sub fillReadings {
my $connected = $hash->{helper}{mower}{attributes}{metadata}{connected};
readingsBulkUpdateIfChanged($hash, $pref."_connected", ( $connected ? "CONNECTED($connected)" : "OFFLINE($connected)") );
my $storediff = $hash->{helper}{mower}{attributes}{metadata}{statusTimestamp} - $hash->{helper}{mowerold}{attributes}{metadata}{statusTimestamp};
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 ));
readingsBulkUpdateIfChanged($hash, $pref."_TimestampDiff", $hash->{helper}{storediff}/1000 );
return undef;
}
@ -1474,9 +1385,6 @@ sub listInternalData {
$arnr = scalar @{ $hash->{helper}{areapos} } if( scalar @{ $hash->{helper}{areapos} } > 2 );
my $arnrmax = $hash->{helper}{MOWING}{maxLength};
my $ornr = scalar @{ $hash->{helper}{otherpos} };
my $ornrmax = $hash->{helper}{UNKNOWN}{maxLength};
my $ernr = scalar @{ $hash->{helper}{lasterror}{positions} };
$hash->{helper}{posMinMax} =~ /(-?\d*\.?\d+)\s(-?\d*\.?\d+)(\R|\s)(-?\d*\.?\d+)\s(-?\d*\.?\d+)/;
@ -1484,7 +1392,7 @@ sub listInternalData {
if ( $::init_done && $1 && $2 && $4 && $5 ) {
$ret .= '<tr class="col_header"><td> Data Sets ( max )&emsp;</td><td> Corner </td><td> Longitude </td><td> Latitude </td></tr>';
$ret .= '<tr class="column odd"><td rowspan="2" style="vertical-align:middle;" > ' . ($csnr + $arnr) . ' ( ' . ($csnrmax + $arnrmax) . ' )&emsp;</td><td> Upper Left </td><td> ' . $1 . ' </td><td> ' . $2 . ' </td></tr>';
$ret .= '<tr class="column odd"><td rowspan="2" style="vertical-align:middle;" > ' . $arnr . ' ( ' . $arnrmax . ' )&emsp;</td><td> Upper Left </td><td> ' . $1 . ' </td><td> ' . $2 . ' </td></tr>';
$ret .= '<tr class="column even"><td> Lower Right </td><td> ' . $4 . ' </td><td> ' . $5 . ' </td></tr>';
$ret .= '</tbody></table><p>';
@ -1498,12 +1406,9 @@ sub listInternalData {
$ret .= '<table class="block wide">';
$ret .= '<caption><b>Way Point Stacks</b></caption><tbody>';
$ret .= '<tr class="col_header"><td> Used For Action&emsp;</td><td> Stack Name&emsp;</td><td> Current Size&emsp;</td><td> Max Size&emsp;</td></tr>';
$ret .= '<tr class="col_header"><td> Used For Activities&emsp;</td><td> Stack Name&emsp;</td><td> Current Size&emsp;</td><td> Max Size&emsp;</td></tr>';
$ret .= '<tr class="column odd"><td>PARKED_IN_CS, CHARGING&emsp;</td><td> cspos&emsp;</td><td> ' . $csnr . ' </td><td> ' . $csnrmax . '&emsp;</td></tr>';
$ret .= '<tr class="column even"><td>MOWING&emsp;</td><td> areapos&emsp;</td><td> ' . $arnr . ' </td><td> ' . $arnrmax . '&emsp;</td></tr>';
$ret .= '<tr class="column odd"><td>User defined activities&emsp;</td>
<td style="vertical-align:middle;" > otherpos&emsp;</td><td style="vertical-align:middle;" > ' . $ornr . ' </td>
<td style="vertical-align:middle;" > ' . $ornrmax . '&emsp;</td></tr>';
$ret .= '<tr class="column even"><td>ALL&emsp;</td><td> areapos&emsp;</td><td> ' . $arnr . ' </td><td> ' . $arnrmax . '&emsp;</td></tr>';
$ret .= '<tr class="column even"><td>NOT_APPLICABLE with error time stamp&emsp;</td><td> lasterror/positions&emsp;</td><td> ' . $ernr . ' </td><td> -&emsp;</td></tr>';
$ret .= '</tbody></table>';

View File

@ -175,8 +175,47 @@ function AutomowerConnectDrawPath ( ctx, div, pos, type ) {
}
//AutomowerConnectUpdateDetail (<devicename>, <type> <background-image path>, <imagesize x>, <imagesize y>, <relative positio of CS marker>,<scale x>, <error description>, <path array>, <area limits array>, <property limits array>, <error array>, <other positions>)
function AutomowerConnectUpdateDetail (dev, type, imgsrc, picx, picy, csx, csy, csrel, scalx, errdesc, pos, lixy, plixy, posc, erray, poso) {
function AutomowerConnectDrawPathColor ( ctx, div, pos, colorat ) {
// draw path
var type = colorat[ pos[ 2 ] ];
ctx.beginPath();
ctx.strokeStyle = div.getAttribute( 'data-'+ type + 'LineColor' );
ctx.lineWidth=div.getAttribute( 'data-'+ type + 'LineWidth' );
ctx.setLineDash( div.getAttribute( 'data-'+ type + 'LineDash' ).split(",") );
ctx.moveTo( parseInt( pos[0] ), parseInt( pos[ 1 ] ) );
for (var i=3;i<pos.length;i+=3){
ctx.lineTo( parseInt( pos[ i ] ),parseInt( pos[ i+1 ] ) );
if ( colorat[ pos[ i+2 ] ] != type ){
ctx.stroke();
var type = colorat[ pos[ i + 2 ] ];
ctx.beginPath();
ctx.strokeStyle = div.getAttribute( 'data-'+ type + 'LineColor' );
ctx.lineWidth=div.getAttribute( 'data-'+ type + 'LineWidth' );
ctx.setLineDash( div.getAttribute( 'data-'+ type + 'LineDash' ).split(",") );
}
}
ctx.stroke();
}
//AutomowerConnectUpdateDetail (<devicename>, <type> <background-image path>, <imagesize x>, <imagesize y>, <relative position of CS marker>,<scale x>, <error description>, <path array>, <area limits array>, <property limits array>, <error array>)
function AutomowerConnectUpdateDetail (dev, type, imgsrc, picx, picy, csx, csy, csrel, scalx, errdesc, pos, lixy, plixy, erray) {
const colorat = {
"U" : "otherActivityPath",
"N" : "otherActivityPath",
"S" : "otherActivityPath",
"P" : "chargingStationPath",
"C" : "chargingStationPath",
"M" : "mowingPath",
"L" : "leavingPath",
"G" : "goingHomePath"
};
// log('pos.length '+pos.length+' lixy.length '+lixy.length+', scalx '+scalx );
// log('loop: Start '+ type+' '+dev );
if (FW_urlParams.detail == dev || 1) {
@ -194,13 +233,10 @@ function AutomowerConnectUpdateDetail (dev, type, imgsrc, picx, picy, csx, csy,
if ( plixy.length > 0 ) AutomowerConnectLimits( ctx, div, plixy, 'property' );
// draw scale
AutomowerConnectScale( ctx, picx, picy, scalx );
// draw charging station path
AutomowerConnectDrawPath ( ctx, div, posc, 'chargingStationPath' );
if ( pos.length > 2 ) {
// draw mowing path
AutomowerConnectDrawPath ( ctx, div, pos, 'mowingPath' );
// draw path for other activity
if ( poso.length > 1 ) AutomowerConnectDrawPath ( ctx, div, poso, 'otherActivityPath' );
if ( pos.length > 3 ) {
// draw mowing path color
AutomowerConnectDrawPathColor ( ctx, div, pos, colorat );
// draw start
if ( div.getAttribute( 'data-mowingPathDisplayStart' ) ) {
@ -209,7 +245,7 @@ function AutomowerConnectUpdateDetail (dev, type, imgsrc, picx, picy, csx, csy,
ctx.lineWidth=3;
ctx.strokeStyle = 'white';
ctx.fillStyle= 'black';
ctx.arc(parseInt(pos[pos.length-2]), parseInt(pos[pos.length-1]), 4, 0, 2 * Math.PI, false);
ctx.arc(parseInt(pos[pos.length-3]), parseInt(pos[pos.length-2]), 4, 0, 2 * Math.PI, false);
ctx.fill();
ctx.stroke();
}
@ -228,13 +264,13 @@ function AutomowerConnectUpdateDetail (dev, type, imgsrc, picx, picy, csx, csy,
} else {
setTimeout(()=>{
// log('loop: canvas false '+ type+' '+dev );
AutomowerConnectUpdateDetail (dev, type, imgsrc, picx, picy, csx, csy, csrel, scalx, errdesc, pos, lixy, plixy, posc, erray, poso);
AutomowerConnectUpdateDetail (dev, type, imgsrc, picx, picy, csx, csy, csrel, scalx, errdesc, pos, lixy, plixy, erray);
}, 100);
}
} else {
setTimeout(()=>{
// log('loop: detail false '+ type+' '+dev );
AutomowerConnectUpdateDetail (dev, type, imgsrc, picx, picy, csx, csy, csrel, scalx, errdesc, pos, lixy, plixy, posc, erray, poso);
AutomowerConnectUpdateDetail (dev, type, imgsrc, picx, picy, csx, csy, csrel, scalx, errdesc, pos, lixy, plixy, erray);
}, 100);
}
}