From c4561f9050a0f48deafcded44afedf1b25e4a9da Mon Sep 17 00:00:00 2001
From: viegener <>
Date: Sat, 26 Sep 2020 20:45:19 +0000
Subject: [PATCH] 10_SOMFY: corrected autostore rolling code (esp. restart)
git-svn-id: https://svn.fhem.de/fhem/trunk@22861 2b470e98-0d58-463d-a4d8-8e2adae1ed80
---
fhem/CHANGED | 2 +-
fhem/FHEM/10_SOMFY.pm | 141 ++++++++++++++++++++++++++++--------------
2 files changed, 95 insertions(+), 48 deletions(-)
diff --git a/fhem/CHANGED b/fhem/CHANGED
index ae136d98e..3618babb7 100644
--- a/fhem/CHANGED
+++ b/fhem/CHANGED
@@ -1,6 +1,6 @@
# 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.
-
+ - bugfix: 10_SOMFY: corrected autostore rolling code (esp. restart)
- feature: 14_SD_WS: protocol 27 / new sensor EFS-3110A
- feature: 93_DbRep: sqlCmd supports PREPARE statement, Forum: #114293
- bugfix: 70_BOTVAC: fix processing of set for preferences
diff --git a/fhem/FHEM/10_SOMFY.pm b/fhem/FHEM/10_SOMFY.pm
index 807eeea4e..cc0d9ef42 100644
--- a/fhem/FHEM/10_SOMFY.pm
+++ b/fhem/FHEM/10_SOMFY.pm
@@ -78,8 +78,17 @@
# - ensure largest rollingcode (either reading or unqieid is used)
# - FIX: hex value warning for rollcode
# - FIX: allow empty ioTypes for testing
-#
-#
+# - finalPosReading as addtl attribute - specify name
+# - finalPosReading set at the end of a move with final position
+# - change all old log commands to log3
+# - log rolling code and enc key on sending verbose 5
+# - document rawdevice
+# - fix for finalposreading also reacting in virtual mode
+# - fix for finalposreading also reacting on stop
+
+# - store roll code on setting of attribute
+# - no update of DEF anymore with rolling code (roll code and enc key will be removed)
+# - FIX: corrected of autostore rolling code (esp. restart)
#
###############################################################################
#
@@ -101,8 +110,6 @@
# - Complete shutter / blind as different model
# - Make better distinction between different IoTypes - CUL+SCC / Signalduino
# - Known Issue - if timer is running and last command equals new command (only for open / close) - considered minor/but still relevant
-# -
-# - switch to standard 100 to 0 position
#
###############################################################################
#
@@ -208,7 +215,10 @@ sub SOMFY_SendCommand($@);
sub SOMFY_readRollCode($);
sub SOMFY_storeRollCode($$);
-sub SOMFY_getRollCode($);
+sub SOMFY_getRollCode($;$);
+
+sub SOMFY_UpdateState($$$$$$);
+
#########################
######################################################
@@ -247,6 +257,7 @@ sub SOMFY_Initialize($) {
. " drive-up-time-to-100"
. " drive-up-time-to-open "
. " additionalPosReading "
+ . " finalPosReading "
. " positionInverse:1,0 "
. " IODev"
. " symbol-length"
@@ -336,6 +347,10 @@ sub SOMFY_Define($$) {
$hash->{CODE}{ $ncode++ } = $code;
$modules{SOMFY}{defptr}{$code}{$name} = $hash;
$hash->{move} = 'stop';
+
+ # change 23.9.2020 - def will be modified to only include address
+ $hash->{DEF} = $hash->{ADDRESS}." ";
+
AssignIoPort($hash);
}
@@ -413,6 +428,19 @@ sub SOMFY_Attr(@) {
readingsEndUpdate($hash,1);
}
+ } elsif ($aName eq 'autoStoreRollingCode') {
+ if ($cmd eq "set") {
+ # change 23.9.2020 - store roll code on setting of attribute
+ if ( $aVal ) {
+ my $rollcode = SOMFY_getRollCode( $hash, 1 ); # ensure rollcode being read first during start specifically
+ SOMFY_storeRollCode( $hash, $rollcode );
+ } else {
+ SOMFY_storeRollCode( $hash, undef );
+ }
+ } elsif ($cmd eq "del") {
+ SOMFY_storeRollCode( $hash, undef );
+ }
+
} elsif ($cmd eq "set") {
if($aName eq 'drive-up-time-to-100') {
return "SOMFY_attr: value must be >=0 and <= 100" if($aVal < 0 || $aVal > 100);
@@ -439,13 +467,6 @@ sub SOMFY_Attr(@) {
}
- } elsif ($aName eq 'autoStoreRollingCode') {
- if ($cmd eq "set") {
- SOMFY_storeRollCode( $hash, undef ) if ( ! $aVal );
- } elsif ($cmd eq "del") {
- SOMFY_storeRollCode( $hash, undef );
- }
-
}
return undef;
@@ -734,6 +755,7 @@ sub SOMFY_InternalSet($@) {
my $move = $cmd;
my $newState;
my $updateState;
+
# translate state info to numbers - closed = 200 , open = 0 (correct missing values)
if ( !defined($pos) ) {
@@ -775,7 +797,6 @@ sub SOMFY_InternalSet($@) {
$newState = 'open';
} else {
}
-
} elsif(!defined($t1downclose) || !defined($t1down100) || !defined($t1upopen) || !defined($t1up100)) {
#if timings not set
@@ -954,10 +975,15 @@ sub SOMFY_InternalSet($@) {
} else {
Log3($name,5,"SOMFY_set: handled for drive/udpate: updateState :: drivet :$drivetime: updatet :$updatetime: ");
}
+
+ # check if finalPos or will be updated after time
+ my $isFinal = 0;
+ $isFinal = 1 if ( ( $updatetime != 0 ) || ( $drivetime != 0 ) || ( $move eq 'stop' ) );
+
# bulk update should do trigger if virtual mode
# SOMFY_UpdateState( $hash, $newState, $move, $updateState, ( $mode eq 'virtual' ) );
- SOMFY_UpdateState( $hash, $newState, $move, $updateState, 1 );
+ SOMFY_UpdateState( $hash, $newState, $move, $updateState, 1, $isFinal );
### send command
if ( $mode ne 'virtual' ) {
@@ -1061,23 +1087,28 @@ sub SOMFY_readRollCode($)
#####################################
# get the rolling code either from Reading or if empty consider stored from uniqueid
-sub SOMFY_getRollCode($)
+sub SOMFY_getRollCode($;$)
{
- my ($hash) = @_;
+ my ($hash, $doAutoStore) = @_;
my $name = $hash->{NAME};
my $rollingcode = uc(ReadingsVal($name, "rolling_code", "0000"));
-
- if ( AttrVal( $name, "autoStoreRollingCode", 0 ) ) {
+
+ $doAutoStore = AttrVal( $name, "autoStoreRollingCode", 0 ) if ( ! defined( $doAutoStore ) );
+
+ if ( $doAutoStore ) {
my $storeRC = uc( SOMFY_readRollCode( $hash ) );
- $storeRC = "0000" if ( $storeRC !~ /[0-9a-f]{4}/ );
+ $storeRC = "0000" if ( $storeRC !~ /[0-9A-F]{4}/ );
my $storeDec = hex( $storeRC );
my $rollDec = hex( $rollingcode );
+ Debug "Store hex: $storeRC dec: $storeDec";
+ Debug "RollC hex: $rollingcode dec: $rollDec";
if ( $storeDec > $rollDec ) {
$rollingcode = $storeRC;
}
+ Debug "Result Rolling code: $rollingcode";
}
return $rollingcode;
@@ -1126,17 +1157,18 @@ sub SOMFY_isRemote($) {
}
-#####################################
-sub SOMFY_updateDef($;$$)
-{
- my ($hash, $ec, $rc) = @_;
- my $name = $hash->{NAME};
+# 26.9.2020 - not used anymore - rc and ec removed from def on define
+# #####################################
+# sub SOMFY_updateDef($;$$)
+# {
+ # my ($hash, $ec, $rc) = @_;
+ # my $name = $hash->{NAME};
- $ec = ReadingsVal($name, "enc_key", "A0") if ( ! defined( $ec ) );
- $rc = SOMFY_getRollCode( $hash ) if ( ! defined( $rc ) );
+ # $ec = ReadingsVal($name, "enc_key", "A0") if ( ! defined( $ec ) );
+ # $rc = SOMFY_getRollCode( $hash ) if ( ! defined( $rc ) );
- $hash->{DEF} = $hash->{ADDRESS}." ".uc($ec)." ".uc($rc);
-}
+ # $hash->{DEF} = $hash->{ADDRESS}." ".uc($ec)." ".uc($rc);
+# }
######################################################
######################################################
@@ -1391,7 +1423,7 @@ sub SOMFY_TimedUpdate($) {
SOMFY_SendCommand($hash, $hash->{runningcmd});
}
# trigger update from timer
- SOMFY_UpdateState( $hash, $hash->{updateState}, 'stop', undef, 1 );
+ SOMFY_UpdateState( $hash, $hash->{updateState}, 'stop', undef, 1, 1 ); ## is final
delete $hash->{starttime};
delete $hash->{runningtime};
delete $hash->{runningcmd};
@@ -1400,7 +1432,7 @@ sub SOMFY_TimedUpdate($) {
if($utime > $somfy_updateFreq) {
$utime = $somfy_updateFreq;
}
- SOMFY_UpdateState( $hash, $pos, $hash->{move}, $hash->{updateState}, 1 );
+ SOMFY_UpdateState( $hash, $pos, $hash->{move}, $hash->{updateState}, 1, 0 ); ## not final yet
if ( defined( $hash->{runningcmd} )) {
Log3($hash->{NAME},4,"SOMFY_TimedUpdate: $hash->{NAME} -> stopping in $hash->{runningtime} sec");
} else {
@@ -1416,9 +1448,9 @@ sub SOMFY_TimedUpdate($) {
###################################
-# SOMFY_UpdateState( $hash, $newState, $move, $updateState );
-sub SOMFY_UpdateState($$$$$) {
- my ($hash, $newState, $move, $updateState, $doTrigger) = @_;
+# SOMFY_UpdateState( $hash, $newState, $move, $updateState, drotrigger, isFinal );
+sub SOMFY_UpdateState($$$$$$) {
+ my ($hash, $newState, $move, $updateState, $doTrigger, $isFinal) = @_;
my $name = $hash->{NAME};
my $addtlPosReading = AttrVal($hash->{NAME},'additionalPosReading',undef);
@@ -1426,6 +1458,12 @@ sub SOMFY_UpdateState($$$$$) {
$addtlPosReading = undef if ( ( $addtlPosReading eq "" ) or ( $addtlPosReading eq "state" ) or ( $addtlPosReading eq "position" ) or ( $addtlPosReading eq "exact" ) );
}
+ $isFinal = 0 if ( ! defined( $isFinal ) );
+ my $finalPosReading = AttrVal($hash->{NAME},'finalPosReading',undef);
+ if ( defined($finalPosReading )) {
+ $finalPosReading = undef if ( ( $finalPosReading eq "" ) or ( $finalPosReading eq "state" ) or ( $finalPosReading eq "position" ) or ( $finalPosReading eq "exact" ) );
+ }
+
my $newExact = $newState;
readingsBeginUpdate($hash);
@@ -1467,12 +1505,12 @@ sub SOMFY_UpdateState($$$$$) {
readingsBulkUpdate($hash,"position",$rounded);
- readingsBulkUpdate($hash,$addtlPosReading,$rounded) if ( defined($addtlPosReading) );
-
}
readingsBulkUpdate($hash,"exact",$newExact);
+ readingsBulkUpdate($hash,$finalPosReading,$newExact) if ( ( defined($finalPosReading) ) && ( $isFinal ) );
+
if ( defined( $updateState ) ) {
$hash->{updateState} = $updateState;
} else {
@@ -1638,8 +1676,7 @@ sub SOMFY_SendCommand($@)
{
$message = "t" . $attr{ $name }{"symbol-length"};
IOWrite( $hash, "Y", $message );
- Log GetLogLevel( $name, 4 ),
- "SOMFY set symbol-length: $message for $io->{NAME}";
+ Log3 $hash, 5, "SOMFY_send set symbol-length: $message for $io->{NAME}";
}
@@ -1649,8 +1686,7 @@ sub SOMFY_SendCommand($@)
{
$message = "r" . $attr{ $name }{"repetition"};
IOWrite( $hash, "Y", $message );
- Log GetLogLevel( $name, 4 ),
- "SOMFY set repetition: $message for $io->{NAME}";
+ Log3 $hash, 5, "SOMFY_send set repetition: $message for $io->{NAME}";
}
}
@@ -1686,7 +1722,8 @@ sub SOMFY_SendCommand($@)
. uc( $hash->{ADDRESS} );
## Log that we are going to switch Somfy
- Log GetLogLevel( $name, 4 ), "SOMFY set $name " . join(" ", @args) . ": $message";
+ Log3 $hash, 4, "SOMFY_send $name " . join(" ", @args) . ": $message";
+ Log3 $hash, 5, "SOMFY_send $name enc key : ". $new_enc_key." rolling code : ".$new_rolling_code;
## Send Message to IODev using IOWrite
if ($ioType eq "SIGNALduino") {
@@ -1700,7 +1737,7 @@ sub SOMFY_SendCommand($@)
#Log3 $hash, 4, "$hash->{IODev}->{NAME} SOMFY_sendCommand: $name -> message :$message: ";
IOWrite($hash, 'sendMsg', $message);
} else {
- Log3($name,5,"SOMFY_sendCommand: $name -> message :$message: ");
+ #Log3($name,5,"SOMFY_sendCommand: $name -> message :$message: ");
IOWrite( $hash, "Y", $message );
}
@@ -1711,7 +1748,8 @@ sub SOMFY_SendCommand($@)
SOMFY_storeRollCode( $hash, $new_rolling_code ) if ( AttrVal( $name, "autoStoreRollingCode", 0 ) );
# modify definition of device with actual enc/rc
- SOMFY_updateDef( $hash, $new_enc_key, $new_rolling_code );
+ # change 23.9.2020 - no update def anymore with rolling code (roll code and enc key will be removed)
+ # SOMFY_updateDef( $hash, $new_enc_key, $new_rolling_code );
# CUL specifics
if ($ioType ne "SIGNALduino") {
@@ -1721,8 +1759,7 @@ sub SOMFY_SendCommand($@)
{
$message = "t" . $somfy_defsymbolwidth;
IOWrite( $hash, "Y", $message );
- Log GetLogLevel( $name, 4 ),
- "SOMFY set symbol-length back: $message for $io->{NAME}";
+ Log3 $hash, 5, "SOMFY_send set symbol-length back: $message for $io->{NAME}";
}
## Do we need to change repetition back?
@@ -1731,8 +1768,7 @@ sub SOMFY_SendCommand($@)
{
$message = "r" . $somfy_defrepetition;
IOWrite( $hash, "Y", $message );
- Log GetLogLevel( $name, 4 ),
- "SOMFY set repetition back: $message for $io->{NAME}";
+ Log3 $hash, 5, "SOMFY_send set repetition back: $message for $io->{NAME}";
}
## Do we need to change RFMode back to HomeMatic??
@@ -1759,7 +1795,8 @@ sub SOMFY_SendCommand($@)
$lh->{READINGS}{enc_key}{VAL} = $new_enc_key;
$lh->{READINGS}{rolling_code}{TIME} = $tn;
$lh->{READINGS}{rolling_code}{VAL} = $new_rolling_code;
- SOMFY_updateDef( $lh, $new_enc_key, $new_rolling_code );
+ # change 23.9.2020 - no update def anymore with rolling code (roll code and enc key will be removed)
+ # SOMFY_updateDef( $lh, $new_enc_key, $new_rolling_code );
}
return $ret;
@@ -1926,6 +1963,11 @@ sub SOMFY_SendCommand($@)
Additionally this attribute might specify a name for an additional reading to be updated with the same value than the pos.
+