diff --git a/fhem/CHANGED b/fhem/CHANGED
index 03730291f..c086f9774 100644
--- a/fhem/CHANGED
+++ b/fhem/CHANGED
@@ -1,5 +1,8 @@
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
# Do not insert empty lines here, update check depends on it.
+ - change: 74_AutomowerConnect: Common.pm try to reconnect if ws is open but
+ not ready, improve leaving path colorization if position polling is
+ on, some changes in automowerconnect.js, Cref update.
- new: 98_KNX_scan: implement FHEM-cmd: KNX_scan
- change: 00_KNXIO.pm: moved KNX_scan perl function to 10_KNX.pm
- change: 10_KNX.pm: moved KNX_scan perl function to 10_KNX.pm
diff --git a/fhem/FHEM/74_AutomowerConnect.pm b/fhem/FHEM/74_AutomowerConnect.pm
index a13d99b98..0f1033d7a 100644
--- a/fhem/FHEM/74_AutomowerConnect.pm
+++ b/fhem/FHEM/74_AutomowerConnect.pm
@@ -378,7 +378,7 @@ __END__
addPositionPolling
attr <name> addPositionPolling <[1|0]>
diff --git a/fhem/lib/FHEM/Devices/AMConnect/Common.pm b/fhem/lib/FHEM/Devices/AMConnect/Common.pm
index 9e7686f0e..7c0c4d06d 100644
--- a/fhem/lib/FHEM/Devices/AMConnect/Common.pm
+++ b/fhem/lib/FHEM/Devices/AMConnect/Common.pm
@@ -156,7 +156,9 @@ mowingPathLineColor="#ff0000"
mowingPathLineDash="6,2"
mowingPathLineWidth="1"
mowingPathDotWidth="2"
-mowingPathUseDots=""';
+mowingPathUseDots=""
+mowingPathShowCollisions=""
+';
my $mapZonesTpl = '{
"01_oben" : {
@@ -174,11 +176,13 @@ my $mapZonesTpl = '{
passObj => FHEM::Core::Authentication::Passwords->new($type),
interval => 840,
interval_ws => 7110,
- interval_ping => 60,
+ interval_ping => 570,
use_position_polling => 0,
additional_polling => 0,
+ reverse_positions_order => 1,
retry_interval_apiauth => 840,
retry_interval_getmower => 840,
+ retry_interval_wsreopen => 2,
timeout_apiauth => 5,
timeout_getmower => 5,
timeout_cmd => 10,
@@ -742,7 +746,6 @@ sub APIAuthResponse {
}
-
##############################################################
#
# GET MOWERS
@@ -818,7 +821,7 @@ sub getMowerResponseWs {
my $iam = "$type $name getMowerResponseWs:";
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, 4, "$iam response polling after status-event \$statuscode >$statuscode<, \$err >$err<, \$param->url $param->{url} \n \$data >$data<";
if( !$err && $statuscode == 200 && $data) {
@@ -848,13 +851,14 @@ sub getMowerResponseWs {
for ( $cnt = 0; $cnt < $poslen; $cnt++ ) {
if ( $hash->{helper}{searchpos}[ 0 ]{longitude} == $result->{data}{attributes}{positions}[ $cnt ]{longitude}
- && $hash->{helper}{searchpos}[ 0 ]{latitude} == $result->{data}{attributes}{positions}[ $cnt ]{latitude} ) {
+ && $hash->{helper}{searchpos}[ 0 ]{latitude} == $result->{data}{attributes}{positions}[ $cnt ]{latitude} || $cnt == $poslen -1) { # if nothing found take all
if ( $cnt > 0 ) {
my @ar;
push @ar, @{ $result->{data}{attributes}{positions} }[ 0 .. $cnt-1 ];
$hash->{helper}{mower}{attributes}{positions} = dclone( \@ar );
+
AlignArray( $hash );
FW_detailFn_Update ($hash);
@@ -915,7 +919,7 @@ sub getMowerResponse {
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, 4, "$iam response \$statuscode >$statuscode<, \$err >$err<, \$param->url $param->{url} \n\$data >$data<";
if( !$err && $statuscode == 200 && $data) {
@@ -1007,7 +1011,7 @@ sub getMowerResponse {
} else {
readingsSingleUpdate( $hash, 'device_state', "error statuscode $statuscode", 1 );
- Log3 $name, 1, "$iam \$statuscode [$statuscode]\n\$err [$err],\n \$data [$data] \n\$param->url $param->{url}";
+ Log3 $name, 1, "$iam \$statuscode >$statuscode<, \$err >$err<, \$param->url $param->{url} \n\$data >$data<";
}
@@ -1563,6 +1567,8 @@ sub AlignArray {
my ($hash) = @_;
my $name = $hash->{NAME};
my $use_position_polling = $hash->{helper}{use_position_polling};
+ my $reverse_positions_order = $hash->{helper}{reverse_positions_order};
+ my $additional_polling = $hash->{helper}{additional_polling};
my $act = $hash->{helper}{mower}{attributes}{mower}{activity};
my $actold = $hash->{helper}{mowerold}{attributes}{mower}{activity};
my $cnt = @{ $hash->{helper}{mower}{attributes}{positions} };
@@ -1573,8 +1579,9 @@ sub AlignArray {
my @ar = @{ $hash->{helper}{mower}{attributes}{positions} };
my $deltaTime = $hash->{helper}{positionsTime} - $hash->{helper}{statusTime};
- # if encounter positions shortly after status event old activity is assigned to positions
- if ( $cnt > 1 && $deltaTime > 0 && $deltaTime < 0.29 && !$use_position_polling) {
+ # if encounter positions shortly after status event old activity is assigned to positions
+ if ( $cnt > 1 && $deltaTime > 0 && $deltaTime < 0.29 && !$use_position_polling ||
+ $use_position_polling && ( $actold =~ /LEAVING/ && $act eq 'MOWING' || $act =~ /GOING_HOME/ && $actold eq 'MOWING' ) ) {
map { $_->{act} = $hash->{helper}{$actold}{short} } @ar;
@@ -1586,8 +1593,11 @@ sub AlignArray {
if ( !$use_position_polling ) {
- @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
+ if ( $reverse_positions_order ) {
+
+ @ar = reverse @ar if ( $cnt > 1 ); # positions seem to be in reversed order
+
+ }
}
@@ -1618,6 +1628,12 @@ sub AlignArray {
}
+ if ( $hash->{helper}{newcollisions} && $additional_polling && $act =~ /^(MOWING)$/ ) {
+
+ TagWayPointsAsCollision ( $hash, $cnt );
+
+ }
+
if ( AttrVal($name, 'mapZones', 0) && $act =~ /^(MOWING)$/ ) {
$tmp = dclone( \@ar );
@@ -1758,6 +1774,8 @@ sub ZoneHandling {
map { $hash->{helper}{mapZones}{$_}{currentDayCntPct} = ( $sumDayCnt ? sprintf( "%.0f", $hash->{helper}{mapZones}{$_}{zoneCnt} / $sumDayCnt * 100 ) : 0 );
$hash->{helper}{mapZones}{$_}{currentDayAreaPct} = ( $sumDayArea ? sprintf( "%.0f", $hash->{helper}{mapZones}{$_}{zoneLength} / $sumDayArea * 100 ) : 0 );
+ $hash->{helper}{mapZones}{$_}{currentDayTrack} = $hash->{helper}{mapZones}{$_}{zoneLength};
+ $hash->{helper}{mapZones}{$_}{currentDayTime} = $hash->{helper}{mapZones}{$_}{zoneCnt} * 30;
} @zonekeys;
$hash->{helper}{mapZones}{$hash->{helper}{currentZone}}{currentDayCollisions} += $hash->{helper}{newcollisions};
@@ -1818,6 +1836,19 @@ sub calcPathLength {
return $lsum;
}
+#########################
+sub TagWayPointsAsCollision {
+ my ( $hash, $i ) = @_;
+ my $name = $hash->{NAME};
+ for ( my $k = 1; $k < ($i-1); $k++) {
+
+ $hash->{helper}{areapos}[$k]{act} = 'K';
+
+ }
+ $hash->{helper}{areapos}[0]{act} = 'KE';
+ $hash->{helper}{areapos}[$i-1]{act} = 'KS' if ($i>1);
+}
+
#########################
sub AreaStatistics {
my ( $hash, $i ) = @_;
@@ -2056,9 +2087,11 @@ sub calculateStatistics {
$hash->{helper}{statistics}{currentWeekTrack} += $hash->{helper}{statistics}{currentDayTrack};
$hash->{helper}{statistics}{currentWeekArea} += $hash->{helper}{statistics}{currentDayArea};
$hash->{helper}{statistics}{currentWeekTime} += $hash->{helper}{statistics}{currentDayTime};
+ $hash->{helper}{statistics}{currentWeekCollisions} += $hash->{helper}{statistics}{lastDayCollisions};
$hash->{helper}{statistics}{currentDayTrack} = 0;
$hash->{helper}{statistics}{currentDayArea} = 0;
$hash->{helper}{statistics}{currentDayTime} = 0;
+ $hash->{helper}{statistics}{currentDayCollisions} = 0;
if ( AttrVal($name, 'mapZones', 0) && defined( $hash->{helper}{mapZones} ) ) {
@@ -2069,9 +2102,15 @@ sub calculateStatistics {
$hash->{helper}{mapZones}{$_}{currentWeekCnt} += $hash->{helper}{mapZones}{$_}{zoneCnt};
$sumCurrentWeekCnt += $hash->{helper}{mapZones}{$_}{currentWeekCnt};
$hash->{helper}{mapZones}{$_}{currentWeekArea} += $hash->{helper}{mapZones}{$_}{zoneLength};
- $sumCurrentWeekArea += $hash->{helper}{mapZones}{$_}{currentWeekArea};
+ $sumCurrentWeekArea += ( $hash->{helper}{mapZones}{$_}{currentWeekArea} ? $hash->{helper}{mapZones}{$_}{currentWeekArea} : 0 );
+ $hash->{helper}{mapZones}{$_}{lastDayTrack} = $hash->{helper}{mapZones}{$_}{currentDayTrack};
+ $hash->{helper}{mapZones}{$_}{currentWeekTrack} += ( $hash->{helper}{mapZones}{$_}{currentDayTrack} ? $hash->{helper}{mapZones}{$_}{currentDayTrack} : 0 );
+ $hash->{helper}{mapZones}{$_}{lastDayTime} = ( $hash->{helper}{mapZones}{$_}{currentDayTime} ? $hash->{helper}{mapZones}{$_}{currentDayTime} : 0 );
+ $hash->{helper}{mapZones}{$_}{currentWeekTime} += ( $hash->{helper}{mapZones}{$_}{currentDayTime} ? $hash->{helper}{mapZones}{$_}{currentDayTime} : 0 );
$hash->{helper}{mapZones}{$_}{zoneCnt} = 0;
$hash->{helper}{mapZones}{$_}{zoneLength} = 0;
+ $hash->{helper}{mapZones}{$_}{currentDayTrack} = 0;
+ $hash->{helper}{mapZones}{$_}{currentDayTime} = 0;
} @zonekeys;
map {
@@ -2081,6 +2120,11 @@ sub calculateStatistics {
$hash->{helper}{mapZones}{$_}{currentWeekAreaPct} = ( $sumCurrentWeekArea ? sprintf( "%.0f", $hash->{helper}{mapZones}{$_}{currentWeekArea} / $sumCurrentWeekArea * 100 ) : '' );
$hash->{helper}{mapZones}{$_}{currentDayCntPct} = '';
$hash->{helper}{mapZones}{$_}{currentDayAreaPct} = '';
+ if ( $hash->{helper}{additional_polling} ) {
+ $hash->{helper}{mapZones}{$_}{lastDayCollisions} = ( $hash->{helper}{mapZones}{$_}{currentDayCollisions} ? $hash->{helper}{mapZones}{$_}{currentDayCollisions} : 0 );
+ $hash->{helper}{mapZones}{$_}{currentWeekCollisions} += ( $hash->{helper}{mapZones}{$_}{currentDayCollisions} ? $hash->{helper}{mapZones}{$_}{currentDayCollisions} : 0 );
+ $hash->{helper}{mapZones}{$_}{currentDayCollisions} = 0;
+ }
} @zonekeys;
}
@@ -2090,9 +2134,11 @@ sub calculateStatistics {
$hash->{helper}{statistics}{lastWeekTrack} = $hash->{helper}{statistics}{currentWeekTrack};
$hash->{helper}{statistics}{lastWeekArea} = $hash->{helper}{statistics}{currentWeekArea};
$hash->{helper}{statistics}{lastWeekTime} = $hash->{helper}{statistics}{currentWeekTime};
+ $hash->{helper}{statistics}{lastWeekCollisions} = $hash->{helper}{statistics}{currentWeekCollisions};
$hash->{helper}{statistics}{currentWeekTrack} = 0;
$hash->{helper}{statistics}{currentWeekArea} = 0;
$hash->{helper}{statistics}{currentWeekTime} = 0;
+ $hash->{helper}{statistics}{currentWeekCollisions} = 0;
if ( AttrVal($name, 'mapZones', 0) && defined( $hash->{helper}{mapZones} ) ) {
@@ -2100,8 +2146,16 @@ sub calculateStatistics {
map {
$hash->{helper}{mapZones}{$_}{lastWeekCntPct} = $hash->{helper}{mapZones}{$_}{currentWeekCntPct};
$hash->{helper}{mapZones}{$_}{lastWeekAreaPct} = $hash->{helper}{mapZones}{$_}{currentWeekAreaPct};
+ $hash->{helper}{mapZones}{$_}{lastWeekTrack} = $hash->{helper}{mapZones}{$_}{currentWeekTrack};
+ $hash->{helper}{mapZones}{$_}{lastWeekTime} = $hash->{helper}{mapZones}{$_}{currentWeekTime};
$hash->{helper}{mapZones}{$_}{currentWeekCntPct} = '';
$hash->{helper}{mapZones}{$_}{currentWeekAreaPct} = '';
+ $hash->{helper}{mapZones}{$_}{currentWeekTrack} = 0;
+ $hash->{helper}{mapZones}{$_}{currentWeekTime} = 0;
+ if ( $hash->{helper}{additional_polling} ) {
+ $hash->{helper}{mapZones}{$_}{lastWeekCollisions} = $hash->{helper}{mapZones}{$_}{currentWeekCollisions};
+ $hash->{helper}{mapZones}{$_}{currentWeekCollisions} = 0;
+ }
} @zonekeys;
}
@@ -2125,6 +2179,16 @@ sub listStatisticsData {
my ( $hash ) = @_;
if ( $::init_done && $hash->{helper}{statistics} ) {
+ my %unit =(
+ Track => 'm',
+ Area => 'qm',
+ Time => 's',
+ Collisions => ' ',
+ CntPct => '%',
+ AreaPct => '%'
+ );
+ my @props = qw(Track Area Time Collisions);
+ my @items = qw(currentDay lastDay currentWeek lastWeek);
my $additional_polling = $hash->{helper}{additional_polling};
my $name = $hash->{NAME};
my $cnt = 0;
@@ -2140,95 +2204,48 @@ sub listStatisticsData {
$ret .= '| $hash->{helper}{mower}{attributes}{statistics}{totalRunningTime} | ' . sprintf( "%.0f", $hash->{helper}{mower}{attributes}{statistics}{totalRunningTime} / 3600 ) . '1 | h |
';
$ret .= '| $hash->{helper}{mower}{attributes}{statistics}{totalSearchingTime} | ' . sprintf( "%.0f", $hash->{helper}{mower}{attributes}{statistics}{totalSearchingTime} / 3600 ) . ' | h |
';
- $ret .= '| $hash->{helper}{statistics}{currentDayTrack} | ' . sprintf( "%.0f", $hash->{helper}{statistics}{currentDayTrack} ) . ' | m |
';
- $ret .= '| $hash->{helper}{statistics}{currentDayArea} | ' . sprintf( "%.0f", $hash->{helper}{statistics}{currentDayArea} ) . ' | qm |
';
- $ret .= '| $hash->{helper}{statistics}{currentDayTime} | ' . sprintf( "%.0f", $hash->{helper}{statistics}{currentDayTime} ) . ' | s |
';
- $ret .= '| $hash->{helper}{statistics}{currentDayCollisions} | ' . sprintf( "%.0f", $hash->{helper}{statistics}{currentDayCollisions} ) . ' | |
' if ( $additional_polling );
- $ret .= '| calculated speed | ' . sprintf( "%.2f", $hash->{helper}{statistics}{currentDayTrack} / $hash->{helper}{statistics}{currentDayTime} ) . ' | m/s |
' if ( $hash->{helper}{statistics}{currentDayTime} );
+ my $prop = '';
+ for my $item ( @items ) {
- $ret .= '| $hash->{helper}{statistics}{lastDayTrack} | ' . sprintf( "%.0f", $hash->{helper}{statistics}{lastDayTrack} ) . ' | m |
';
- $ret .= '| $hash->{helper}{statistics}{lastDayArea} | ' . sprintf( "%.0f", $hash->{helper}{statistics}{lastDayArea} ) . ' | qm |
';
- $ret .= '| $hash->{helper}{statistics}{lastDayTime} | ' . sprintf( "%.0f", $hash->{helper}{statistics}{lastDayTime} ) . ' | s |
';
- $ret .= '| $hash->{helper}{statistics}{lastDayCollisions} | ' . sprintf( "%.0f", $hash->{helper}{statistics}{lastDayCollisions} ) . ' | |
';
- $ret .= '| last day calculated speed | ' . sprintf( "%.2f", $hash->{helper}{statistics}{lastDayTrack} / $hash->{helper}{statistics}{lastDayTime} ) . ' | m/s |
' if ( $hash->{helper}{statistics}{lastDayTime} );
+ for $prop ( @props ) {
+
+ $ret .= '| $hash->{helper}{statistics}{'. $item . $prop . '} | ' . sprintf( "%.0f", ( $hash->{helper}{statistics}{$item.$prop} ? $hash->{helper}{statistics}{$item.$prop} : 0 ) ) . ' | ' . $unit{$prop} . ' |
' if ( $item.$prop ne 'currentDayCollision' or $additional_polling );
+
+ }
+
+ $ret .= '| '. $item . ' calculated speed | ' . sprintf( "%.2f", $hash->{helper}{statistics}{$item.'Track'} / $hash->{helper}{statistics}{$item.'Time'} ) . ' | m/s |
' if ( $hash->{helper}{statistics}{$item.'Time'} );
+
+ }
- $ret .= '| $hash->{helper}{statistics}{currentWeekTrack} | ' . sprintf( "%.0f", $hash->{helper}{statistics}{currentWeekTrack} ) . ' | m |
';
- $ret .= '| $hash->{helper}{statistics}{currentWeekArea} | ' . sprintf( "%.0f", $hash->{helper}{statistics}{currentWeekArea} ) . ' | qm |
';
- $ret .= '| $hash->{helper}{statistics}{currentWeekTime} | ' . sprintf( "%.0f", $hash->{helper}{statistics}{currentWeekTime} ) . ' | s |
';
- $ret .= '| $hash->{helper}{statistics}{lastWeekTrack} | ' . sprintf( "%.0f", $hash->{helper}{statistics}{lastWeekTrack} ) . ' | m |
';
- $ret .= '| $hash->{helper}{statistics}{lastWeekArea} | ' . sprintf( "%.0f", $hash->{helper}{statistics}{lastWeekArea} ) . ' | qm |
';
- $ret .= '| $hash->{helper}{statistics}{lastWeekTime} | ' . sprintf( "%.0f", $hash->{helper}{statistics}{lastWeekTime} ) . ' | s |
';
if ( AttrVal($name, 'mapZones', 0) && defined( $hash->{helper}{mapZones} ) ) {
my @zonekeys = sort (keys %{$hash->{helper}{mapZones}});
+ my @props = qw(Track CntPct AreaPct);
+ unshift @props, 'Collisions' if ( $additional_polling );
- if ( $additional_polling ) {
+ for my $prop ( @props ) {
- for ( @zonekeys ) {
+ for my $item ( @items ) {
- $ret .= '| $hash->{helper}{mapZones}{' . $_ . '}{currentDayCollisions} | ' . ( $hash->{helper}{mapZones}{$_}{currentDayCollisions} ? $hash->{helper}{mapZones}{$_}{currentDayCollisions} : '' ) . ' | |
';
+ for ( @zonekeys ) {
+
+ if ($prop eq 'Track') {
+
+ $ret .= '| '. $item . ' calculated speed for '. $_ . ' | ' . sprintf( "%.2f", $hash->{helper}{mapZones}{$_}{$item.'Track'} / $hash->{helper}{mapZones}{$_}{$item.'Time'} ) . ' | m/s |
' if ( $hash->{helper}{mapZones}{$_}{$item.'Time'} );
+
+ } else {
+
+ $ret .= '| $hash->{helper}{mapZones}{' . $_ . '}{'. $item . $prop . '} | ' . ( $hash->{helper}{mapZones}{$_}{$item.$prop} ? $hash->{helper}{mapZones}{$_}{$item.$prop} : '' ) . ' | ' . $unit{$prop} . ' |
';
+
+ }
+
+ }
}
}
- for ( @zonekeys ) {
-
-
- $ret .= '| $hash->{helper}{mapZones}{' . $_ . '}{currentDayCntPct} | ' . ( $hash->{helper}{mapZones}{$_}{currentDayCntPct} ? $hash->{helper}{mapZones}{$_}{currentDayCntPct} : '' ) . ' | % |
';
-
- }
-
- for ( @zonekeys ) {
-
-
- $ret .= '| $hash->{helper}{mapZones}{' . $_ . '}{lastDayCntPct} | ' . ( $hash->{helper}{mapZones}{$_}{lastDayCntPct} ? $hash->{helper}{mapZones}{$_}{lastDayCntPct} : '' ) . ' | % |
';
-
- }
-
- for ( @zonekeys ) {
-
-
- $ret .= '| $hash->{helper}{mapZones}{' . $_ . '}{currentWeekCntPct} | ' . ( $hash->{helper}{mapZones}{$_}{currentWeekCntPct} ? $hash->{helper}{mapZones}{$_}{currentWeekCntPct} : '' ) . ' | % |
';
-
- }
-
- for ( @zonekeys ) {
-
-
- $ret .= '| $hash->{helper}{mapZones}{' . $_ . '}{lastWeekCntPct} | ' . ( $hash->{helper}{mapZones}{$_}{lastWeekCntPct} ? $hash->{helper}{mapZones}{$_}{lastWeekCntPct} : '' ). ' | % |
';
-
- }
-
- for ( @zonekeys ) {
-
-
- $ret .= '| $hash->{helper}{mapZones}{' . $_ . '}{currentDayAreaPct} | ' . ( $hash->{helper}{mapZones}{$_}{currentDayAreaPct} ? $hash->{helper}{mapZones}{$_}{currentDayAreaPct} : '' ) . ' | % |
';
-
- }
-
- for ( @zonekeys ) {
-
-
- $ret .= '| $hash->{helper}{mapZones}{' . $_ . '}{lastDayAreaPct} | ' . ( $hash->{helper}{mapZones}{$_}{lastDayAreaPct} ? $hash->{helper}{mapZones}{$_}{lastDayAreaPct} : '' ) . ' | % |
';
-
- }
-
- for ( @zonekeys ) {
-
-
- $ret .= '| $hash->{helper}{mapZones}{' . $_ . '}{currentWeekAreaPct} | ' . ( $hash->{helper}{mapZones}{$_}{currentWeekAreaPct} ? $hash->{helper}{mapZones}{$_}{currentWeekAreaPct} : '' ) . ' | % |
';
-
- }
-
- for ( @zonekeys ) {
-
-
- $ret .= '| $hash->{helper}{mapZones}{' . $_ . '}{lastWeekAreaPct} | ' . ( $hash->{helper}{mapZones}{$_}{lastWeekAreaPct} ? $hash->{helper}{mapZones}{$_}{lastWeekAreaPct} : '' ). ' | % |
';
-
- }
-
}
$ret .= '';
@@ -2495,11 +2512,21 @@ sub wsReopen {
RemoveInternalTimer( $hash, \&wsReopen );
RemoveInternalTimer( $hash, \&wsKeepAlive );
DevIo_CloseDev( $hash ) if ( DevIo_IsOpen( $hash ) );
- $hash->{DeviceName} = WSDEVICENAME;
- DevIo_OpenDev( $hash, 0, \&wsInit, \&wsCb );
+ # $hash->{DeviceName} = WSDEVICENAME;
+ # DevIo_OpenDev( $hash, 0, \&wsInit, \&wsCb );
+ InternalTimer( gettimeofday() + $hash->{helper}{retry_interval_wsreopen}, \&wsAsyncDevIo_OpenDev, $hash, 0 );
}
+#########################
+sub wsAsyncDevIo_OpenDev {
+ my ( $hash ) = @_;
+ RemoveInternalTimer( $hash, \&wsAsyncDevIo_OpenDev );
+ $hash->{DeviceName} = WSDEVICENAME;
+ $hash->{helper}{retry_interval_wsreopen} = 2;
+ DevIo_OpenDev( $hash, 0, \&wsInit, \&wsCb );
+}
+
#########################
sub wsRead {
my ($hash) = @_;
@@ -2510,6 +2537,7 @@ sub wsRead {
my $use_position_polling = $hash->{helper}{use_position_polling};
my $buf = DevIo_SimpleRead( $hash );
return "" if ( !defined( $buf ) );
+ Log3 $name, 4, "$iam received websocket data: >$buf<";
if ( $buf ) {
@@ -2525,6 +2553,14 @@ sub wsRead {
$hash->{helper}{wsResult}{other} = dclone( $result );
+ if ( $result =~ /^{"ready":false/ ) {
+
+ readingsSingleUpdate( $hash, 'mower_wsEvent', 'not ready', 1);
+ $hash->{helper}{retry_interval_wsreopen} = 420;
+ wsReopen($hash);
+
+ }
+
}
if ( defined( $result->{type} ) && $result->{id} eq $hash->{helper}{mower_id} ) {
@@ -2551,13 +2587,12 @@ sub wsRead {
isErrorThanPrepare( $hash );
resetLastErrorIfCorrected( $hash );
- } elsif ( ( $additional_polling < $hash->{helper}{storesum} || $additional_polling && $act eq 'LEAVING' ) && !$hash->{helper}{midnightCycle} ) {
+ } elsif ( ( $additional_polling < $hash->{helper}{storesum} || $additional_polling && $act =~ /^(LEAVING|GOING_HOME)/ ) && !$hash->{helper}{midnightCycle} ) {
$hash->{helper}{storesum} = 0;
# RemoveInternalTimer( $hash, \&getMowerWs );
# InternalTimer(gettimeofday() + 2, \&getMowerWs, $hash, 0 );
getMowerWs( $hash );
- Log3 $name, 4, "$iam received websocket data, and polling is on: >$buf<";
$hash->{First_Read} = 0;
return;
@@ -2577,7 +2612,6 @@ sub wsRead {
} elsif ( $use_position_polling && $additional_polling ) {
- Log3 $name, 4, "$iam received websocket data, but position polling is on: >$buf<";
$hash->{First_Read} = 0;
return;
@@ -2607,7 +2641,6 @@ sub wsRead {
}
- Log3 $name, 4, "$iam received websocket data: >$buf<";
$hash->{First_Read} = 0;
return;
@@ -2616,6 +2649,7 @@ sub wsRead {
#########################
sub wsReady {
my ($hash ) = @_;
+ RemoveInternalTimer( $hash, \&wsAsyncDevIo_OpenDev);
RemoveInternalTimer( $hash, \&wsReopen);
RemoveInternalTimer( $hash, \&wsKeepAlive);
return DevIo_OpenDev( $hash, 1, \&wsInit, \&wsCb );
diff --git a/fhem/www/pgm2/automowerconnect.js b/fhem/www/pgm2/automowerconnect.js
index 859aeab77..2b8a13e5a 100644
--- a/fhem/www/pgm2/automowerconnect.js
+++ b/fhem/www/pgm2/automowerconnect.js
@@ -115,6 +115,44 @@ function AutomowerConnectScale( ctx, picx, picy, scalx ) {
ctx.stroke();
}
+function AutomowerConnectTag( ctx, pos, colorat ) {
+
+ for ( i = 0; i < pos.length ; i+=3 ){
+
+ if ( pos[ i + 2 ] == 'K' ){
+ ctx.beginPath();
+ ctx.setLineDash( [] );
+ ctx.lineWidth=1.5;
+ ctx.strokeStyle = 'white';
+ ctx.fillStyle= 'black';
+ ctx.arc( parseInt( pos[ i ] ), parseInt( pos[ i + 1 ] ), 2, 0, 2 * Math.PI, false );
+ ctx.fill();
+ ctx.stroke();
+ }
+ if ( pos[ i + 2 ] == 'KE' ){
+ ctx.beginPath();
+ ctx.setLineDash( [] );
+ ctx.lineWidth=3;
+ ctx.strokeStyle = 'white';
+ ctx.fillStyle= 'black';
+ ctx.arc( parseInt( pos[ i ] ), parseInt( pos[ i + 1 ] ), 4, 0, 2 * Math.PI, false );
+ ctx.fill();
+ ctx.stroke();
+ }
+ if ( pos[ i + 2 ] == 'KS' ){
+ ctx.beginPath();
+ ctx.setLineDash( [] );
+ ctx.lineWidth=3;
+ ctx.strokeStyle = 'red';
+ ctx.fillStyle= 'black';
+ ctx.arc( parseInt( pos[ i ] ), parseInt( pos[ i + 1 ] ), 4, 0, 2 * Math.PI, false );
+ ctx.fill();
+ ctx.stroke();
+ }
+
+ }
+
+}
function AutomowerConnectIcon( ctx, csx, csy, csrel, type ) {
if (parseInt(csx) > 0 && parseInt(csy) > 0) {
// draw icon
@@ -302,6 +340,9 @@ function AutomowerConnectUpdateDetail (dev, type, detailfnfirst, picx, picy, sca
"P" : "chargingStationPath",
"C" : "chargingStationPath",
"M" : "mowingPath",
+ "K" : "mowingPath",
+ "KE" : "mowingPath",
+ "KS" : "mowingPath",
"L" : "leavingPath",
"G" : "goingHomePath"
};
@@ -355,6 +396,10 @@ function AutomowerConnectUpdateDetail (dev, type, detailfnfirst, picx, picy, sca
}
+ // draw collision tag
+ if ( div.getAttribute( 'data-mowingPathShowCollisions' ) )
+ AutomowerConnectTag( ctx, pos, colorat );
+
// draw start
if ( div.getAttribute( 'data-mowingPathDisplayStart' ) ) {
ctx.beginPath();