diff --git a/fhem/CHANGED b/fhem/CHANGED
index 7fe42fd8c..331abda99 100644
--- a/fhem/CHANGED
+++ b/fhem/CHANGED
@@ -1,5 +1,7 @@
# 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
+ - feature: 74_AutomowerConnect: attribute controlled automatic syncronizing
+ the mower time if DST changes
- feature: 76_SolarForecast: new attr affectConsForecastLastDays and more
features, changes in Flowgraphic
- change: 74_XiaomiBTLESens: remove experimental switch
diff --git a/fhem/FHEM/74_AutomowerConnect.pm b/fhem/FHEM/74_AutomowerConnect.pm
index 042793ce8..4b5f0c07a 100644
--- a/fhem/FHEM/74_AutomowerConnect.pm
+++ b/fhem/FHEM/74_AutomowerConnect.pm
@@ -67,16 +67,17 @@ sub Initialize() {
"mapBackgroundColor " .
"mapDesignAttributes:textField-long " .
"mapZones:textField-long " .
- "showMap:1,0 " .
"chargingStationCoordinates " .
"chargingStationImagePosition:left,top,right,bottom,center " .
- "scaleToMeterXY " .
"mowerCuttingWidth " .
"mowerPanel:textField-long,85 " .
"mowerSchedule:textField-long " .
"mowingAreaLimits:textField-long " .
"mowingAreaHull:textField-long " .
+ "mowerAutoSyncTime:1,0 " .
"propertyLimits:textField-long " .
+ "scaleToMeterXY " .
+ "showMap:1,0 " .
"weekdaysToResetWayPoints " .
"numberOfWayPointsToDisplay " .
"addPollingMinInterval " .
@@ -192,8 +193,8 @@ __END__
Starts immediately for <number of minutes>
dateTime
- set <name> dateTime <RTC and DST time corretion / h >
- Syncronize the mower time. The proposal is for RTC = UTC and DST for CET(MEZ)
+ set <name> dateTime <timestamp / s>
+ Syncronize the mower time to timestamp. The default (empty Input field) timestamp is for local time of the machine the mower is defined.
confirmError
set <name> confirmError
@@ -377,6 +378,10 @@ __END__
attr <name> showMap <1,0>
Shows Map on (1 default) or not (0).
+ mowerAutoSyncTime
+ attr <name> mowerAutoSyncTime <0,1>
+ Synchronizes mower time if DST changes, on (1) or not (0 default).
+
chargingStationCoordinates
attr <name> chargingStationCoordinates <longitude><separator><latitude>
Longitude and latitude of the charging station. Use WGS84 (GPS) coordinates in decimal degree notation. <separator> is one space character
@@ -720,8 +725,9 @@ __END__
Der Zonenname darf keine Leerzeichen beinhalten und muss mindestens einen Buchstaben enthalten.
dateTime
- set <name> dateTime <RTC and DST time corretion / h >
- Synchronisiert die Zeit im Mäher. Der im Auswahlfeld vorgeschlagene Korrekturwert geht davon aus, dass die RTC auf UTC eingestellt ist und berücksichtigt DST für CET(MEZ).
+ set <name> dateTime <timestamp / s>
+ Synchronisiert die Zeit im Mäher. Timestamp, ist die Zeit in Sekunden seit 1. Januar 1970, 00:00 Uhr UTC unter Berücksichtigung der Zeitzone und DST.
+ Der Standardwert (leeres Eingabefeld) verwendet die lokale Zeit des Rechners auf dem der Mäher definiert ist, siehe auch mowerAutoSyncTime
confirmError
set <name> confirmError
@@ -890,6 +896,10 @@ __END__
attr <name> chargingStationImagePosition <right, bottom, left, top, center>
Position der Ladestation relativ zu ihren Koordinaten.
+ mowerAutoSyncTime
+ attr <name> mowerAutoSyncTime <0,1>
+ Synchronisiert die Zeit im Mäher, bei einer Zeitumstellung, ein (1) aus (0 Standard).
+
mowerCuttingWidth
attr <name> mowerCuttingWidth <cutting width>
Schnittbreite in Meter zur Berechnung der gemähten Fläche. default: 0.24
diff --git a/fhem/lib/FHEM/Devices/AMConnect/Common.pm b/fhem/lib/FHEM/Devices/AMConnect/Common.pm
index 2838c341c..2f647a5b8 100644
--- a/fhem/lib/FHEM/Devices/AMConnect/Common.pm
+++ b/fhem/lib/FHEM/Devices/AMConnect/Common.pm
@@ -48,6 +48,7 @@ BEGIN {
CommandDeleteReading
DoTrigger
FmtDateTime
+ fhemTimeGm
FW_ME
FW_dir
FW_wname
@@ -199,6 +200,7 @@ hideSchedulerButton=""
url => 'https://raw.githubusercontent.com/AndriiHeonia/hull/master/dist/hull.js'
},
interval => 840,
+ isDst => -1,
no_position_attr => $noPositionAttr,
interval_ws => 7110,
interval_ping => 570,
@@ -211,7 +213,7 @@ hideSchedulerButton=""
retry_interval_wsreopen => 2,
timeout_apiauth => 5,
timeout_getmower => 5,
- timeout_cmd => 10,
+ timeout_cmd => 15,
midnightCycle => 1,
client_id => $client_id,
grant_type => 'client_credentials',
@@ -1170,8 +1172,6 @@ sub Set {
my $type = $hash->{TYPE};
my $name = $hash->{NAME};
my $iam = "$type $name Set:";
- my @ti = localtime();
- my $tcorr = ($ti[8] ? '2,1,0' : '1,2,0 ');
return "$iam: needs at least one argument" if ( @val < 2 );
return "Unknown argument, $iam is disabled, choose one of none:noArg" if ( IsDisabled( $name ) );
@@ -1355,7 +1355,7 @@ sub Set {
}
##########
- my $ret = " getNewAccessToken:noArg ParkUntilFurtherNotice:noArg ParkUntilNextSchedule:noArg Pause:noArg Start:selectnumbers,30,30,600,0,lin Park:selectnumbers,30,30,600,0,lin ResumeSchedule:noArg getUpdate:noArg client_secret dateTime:$tcorr ";
+ my $ret = " getNewAccessToken:noArg ParkUntilFurtherNotice:noArg ParkUntilNextSchedule:noArg Pause:noArg Start:selectnumbers,30,30,600,0,lin Park:selectnumbers,30,30,600,0,lin ResumeSchedule:noArg getUpdate:noArg client_secret dateTime ";
$ret .= "mowerScheduleToAttribute:noArg sendScheduleFromAttributeToMower:noArg ";
$ret .= "cuttingHeight:1,2,3,4,5,6,7,8,9 " if ( defined $hash->{helper}{mower}{attributes}{settings}{cuttingHeight} );
$ret .= "defaultDesignAttributesToAttribute:noArg mapZonesTemplateToAttribute:noArg chargingStationPositionToAttribute:noArg " if ( $hash->{helper}{mower}{attributes}{capabilities}{position} );
@@ -1398,6 +1398,7 @@ sub CMD {
my $iam = "$type $name CMD:";
my $timeout = AttrVal( $name, 'timeoutCMD', $hash->{helper}->{timeout_cmd} );
my $method = 'POST';
+ my $ts = TimeLocal();
$hash->{helper}{mower_commandSend} = $cmd[ 0 ] . ( $cmd[ 1 ] ? ' '.$cmd[ 1 ] : '' ) . ( $cmd[ 2 ] ? ' '.$cmd[ 2 ] : '' );
if ( IsDisabled( $name ) ) {
@@ -1430,7 +1431,7 @@ my $header = "Accept: application/vnd.api+json\r\nX-Api-Key: ".$client_id."\r\nA
elsif ($cmd[0] eq "StartInWorkArea" && !$cmd[2])
{ $json = '{"data": {"type":"'.$cmd[0].'","attributes":{"workAreaId":'.$cmd[1].'}}}'; $post = 'actions' }
elsif ($cmd[0] eq "headlight") { $json = '{"data": {"type":"settings","attributes":{"'.$cmd[0].'": {"mode": "'.$cmd[1].'"}}}}'; $post = 'settings' }
- elsif ($cmd[0] eq "dateTime") { $json = '{"data": {"type":"settings","attributes":{"'.$cmd[0].'": '.int(time + $cmd[1] * 3600).'}}}'; $post = 'settings' }
+ elsif ($cmd[0] eq "dateTime") { $json = '{"data": {"type":"settings","attributes":{"'.$cmd[0].'": '.( $cmd[1] ? $cmd[1] : $ts ).'}}}'; $post = 'settings';$hash->{helper}{mower_commandSend} .= ( $cmd[1] ? '' : ' '.$ts ) }
elsif ($cmd[0] eq "cuttingHeight") { $json = '{"data": {"type":"settings","attributes":{"'.$cmd[0].'": '.$cmd[1].'}}}'; $post = 'settings' }
elsif ($cmd[0] eq "stayOutZone") { $json = '{"data": {"type":"stayOutZone","id":"'.$cmd[1].'","attributes":{"enable": '.$cmd[2].'}}}'; $post = 'stayOutZones/' . $cmd[1]; $method = 'PATCH' }
elsif ($cmd[0] eq "confirmError") { $json = '{}'; $post = 'errors/confirm' }
@@ -2865,10 +2866,40 @@ sub listErrorCodes {
}
#########################
-# Format mower timestamp assuming mower time is always set to daylight saving time, because it is the mowing period.
sub FmtDateTimeGMT {
- my $ti = shift // 0;
- my $ret = POSIX::strftime( "%F %H:%M:%S", gmtime( $ti ) );
+ # Returns a yyyy-mm-dd HH:MM:SS formated string for a UNIX like timestamp for local time (seconds since EPOCH)
+ my $ret = POSIX::strftime( "%F %H:%M:%S", gmtime( shift // 0 ) );
+}
+
+#########################
+# Calculate time timestamp in seconds regarding RTC time and DST
+sub TimeLocal {
+ # Creates a UNIX like timestamp for local time (seconds since EPOCH)
+ my @ti = localtime();
+ return ceil( fhemTimeGm( $ti[0], $ti[1], $ti[2], $ti[3], $ti[4], $ti[5] ) );
+}
+
+#########################
+sub autoDstSync {
+ my ( $hash ) = @_;
+ my @ti = localtime();
+ my $isDstOld = $hash->{helper}{isDst};
+ if ( $ti[8] ne $isDstOld && ( $ti[2] == 4 || $isDstOld eq -1 ) ) {
+
+ $hash->{helper}{isDst} = $ti[8];
+ InternalTimer( gettimeofday() + 7, \&CMDdateTime, $hash, 0 );
+
+ }
+ return
+}
+
+#########################
+sub CMDdateTime {
+ my ( $hash ) = @_;
+ my $name = $hash->{NAME};
+ RemoveInternalTimer( $hash, \&CMDdateTime );
+ CMD( $hash, 'dateTime' );
+ return
}
#########################
@@ -3141,6 +3172,8 @@ sub wsRead {
}
+ autoDstSync( $hash ) if ( AttrVal( $name, "mowerAutoSyncTime", 0 ) );
+
}
}