diff --git a/fhem/CHANGED b/fhem/CHANGED
index 179ac36bf..4a1e0a16c 100644
--- a/fhem/CHANGED
+++ b/fhem/CHANGED
@@ -1,5 +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.
+ - feature: 10_SOMFY: new attr autoStoreRollingCode - store rc in uniqueID
- bugfix: OpenWeatherMapAPI: fix no visibility is available
- feature: 57_SSCal: set compatibility to Calendar package 2.3.4-0631,
some changes according to PBP
diff --git a/fhem/FHEM/10_SOMFY.pm b/fhem/FHEM/10_SOMFY.pm
index f9fb76de8..419defcbb 100644
--- a/fhem/FHEM/10_SOMFY.pm
+++ b/fhem/FHEM/10_SOMFY.pm
@@ -67,8 +67,16 @@
# - change log entries and remove debug in _Parse
# - added back parsestate temporarily - #msg743423
+# - new attributes disable/disabledForIntervals
#
#
+# - disabled will be honored - no updates/no sending/no received commands
+# - allow 20 characters messages for SOMFY (not just 14)
+#
+# - new attr autoStoreRollingCode - store rc in uniqueID
+# - store rolling code in uniqueid based on addr
+# - ensure largest rollingcode (either reading or unqieid is used)
+#
###############################################################################
#
#
@@ -194,7 +202,11 @@ sub SOMFY_CalcCurrentPos($$$$);
sub SOMFY_isSwitch($);
sub SOMFY_SendCommand($@);
+sub SOMFY_readRollCode($);
+sub SOMFY_storeRollCode($$);
+sub SOMFY_getRollCode($);
+#########################
######################################################
######################################################
@@ -239,7 +251,10 @@ sub SOMFY_Initialize($) {
. " fixed_enckey:1,0"
. " do_not_notify:1,0"
. " ignore:0,1"
- . " model:somfyblinds,somfyshutter,somfyremote,somfyswitch2,somfyswitch4"
+ . " disable:0,1"
+ . " disabledForIntervals "
+ . " autoStoreRollingCode:0,1 "
+ . " model:somfyblinds,somfyshutter,somfyremote,somfyswitch2,somfyswitch4"
. " loglevel:0,1,2,3,4,5,6"
. " rawDevice"
. " $readingFnAttributes";
@@ -306,6 +321,8 @@ sub SOMFY_Define($$) {
# store it, if old reading does not exist yet
# if(! defined( ReadingsVal($name, "rolling_code", undef) )) {
setReadingsVal($hash, "rolling_code", uc($a[4]), $tzero);
+ # store in uniqueID if requested
+ SOMFY_storeRollCode( $hash, uc($a[4]) ) if ( AttrVal( $name, "autoStoreRollingCode", 0 ) );
# }
}
}
@@ -334,6 +351,10 @@ sub SOMFY_Undef($$) {
}
}
}
+
+ # on delete - remove key
+ SOMFY_storeRollCode( $hash, undef );
+
return undef;
}
@@ -412,6 +433,15 @@ sub SOMFY_Attr(@) {
$attr{$name}{'drive-up-time-to-open'} = $aVal;
$attr{$name}{'drive-up-time-to-100'} = 0 if(!defined($attr{$name}{'drive-up-time-to-100'}) || ($attr{$name}{'drive-up-time-to-100'} > $aVal));
}
+
+
+ } elsif ($aName eq 'autoStoreRollingCode') {
+ if ($cmd eq "set") {
+ SOMFY_storeRollCode( $hash, undef ) if ( ! $aVal );
+ } elsif ($cmd eq "del") {
+ SOMFY_storeRollCode( $hash, undef );
+ }
+
}
return undef;
@@ -486,8 +516,8 @@ sub SOMFY_Parse($$) {
# preprocessing if IODev is SIGNALduino
if ($ioType eq "SIGNALduino") {
my $encData = substr($msg, 2);
- $ret = "Somfy RTS message format error (length)! :".$encData.":" if (length($encData) != 14);
- $ret = "Somfy RTS message format error! :".$encData.":" if ( ( ! $ret ) && ($encData !~ m/[0-9A-F]{14}/) );
+ $ret = "Somfy RTS message format error (length must be 14 or 20)! :".$encData.":" if ( (length($encData) != 14) && (length($encData) != 20));
+ $ret = "Somfy RTS message format error! :".$encData.":" if ( ( ! $ret ) && ($encData !~ m/^[0-9A-F]+$/) );
my ( $decData, $check );
if ( ! $ret ) {
@@ -541,6 +571,7 @@ sub SOMFY_Parse($$) {
$name = $lh->{NAME}; # It may be renamed
return "" if(IsIgnored($name));
+ return "" if(IsDisabled($name));
# update the state and log it
# Debug "SOMFY Parse: $name msg: $msg --> $cmd-$newstate";
@@ -615,7 +646,9 @@ sub SOMFY_InternalSet($@) {
return undef if ( IsIgnored($name) );
- ### Check Args
+ return undef if ( IsDisabled($name) );
+
+### Check Args
return "SOMFY_InternalSet: mode must be virtual or send: $mode " if ( $mode !~m/(virtual|send)/ );
my $numberOfArgs = int(@args);
@@ -973,7 +1006,6 @@ sub SOMFY_InternalSet($@) {
-
##############################################################################
##############################################################################
##
@@ -984,6 +1016,69 @@ sub SOMFY_InternalSet($@) {
+
+#####################################
+# stores ROllingcode // rcode empty means delete
+sub SOMFY_storeRollCode($$)
+{
+ my ($hash, $rcode) = @_;
+
+ my $index = "SOMFY_".$hash->{ADDRESS}."_rollingcode";
+#OLD my $index = "SOMFY_".$name."_rollingcode";
+
+
+ my $err = setKeyValue($index, $rcode);
+
+ return "error while saving the API token - $err" if(defined($err));
+ return "API token successfully saved";
+} # end SOMFY_storeRollCode
+
+#####################################
+# read the rolling code either from uniqueid
+sub SOMFY_readRollCode($)
+{
+ my ($hash ) = @_;
+
+ my $index = "SOMFY_".$hash->{ADDRESS}."_rollingcode";
+#OLD my $index = "SOMFY_" . $name . "_rollingcode";
+
+ my $rcode;
+ my $err;
+ ($err, $rcode) = getKeyValue($index);
+
+ if ( defined($err) ) {
+ Log3 $hash, 1, "SOMFY_readRollCode: Error: unable to read rolling code from file: $err";
+ return "0000";
+ }
+
+ return $rcode;
+} # end SOMFY_readRollCode
+
+
+#####################################
+# get the rolling code either from Reading or if empty consider stored from uniqueid
+sub SOMFY_getRollCode($)
+{
+ my ($hash) = @_;
+
+ my $name = $hash->{NAME};
+
+ my $rollingcode = uc(ReadingsVal($name, "rolling_code", "0000"));
+
+ if ( AttrVal( $name, "autoStoreRollingCode", 0 ) ) {
+ my $storeRC = uc( SOMFY_readRollCode( $hash ) );
+ $storeRC = "0000" if ( $storeRC !~ /[0-9a-f]{4}/ );
+ if ( $storeRC > $rollingcode ) {
+ $rollingcode = $storeRC;
+ }
+ }
+
+ return $rollingcode;
+} # end SOMFY_getRollCode
+
+
+
+
#############################
# 0 blinds / 2 or 4 for switches
sub SOMFY_isSwitch($) {
@@ -1031,7 +1126,7 @@ sub SOMFY_updateDef($;$$)
my $name = $hash->{NAME};
$ec = ReadingsVal($name, "enc_key", "A0") if ( ! defined( $ec ) );
- $rc = ReadingsVal($name, "rolling_code", "0000") if ( ! defined( $rc ) );
+ $rc = SOMFY_getRollCode( $hash ) if ( ! defined( $rc ) );
$hash->{DEF} = $hash->{ADDRESS}." ".uc($ec)." ".uc($rc);
}
@@ -1260,10 +1355,13 @@ sub SOMFY_UpdateStartTime($) {
###################################
sub SOMFY_TimedUpdate($) {
my ($hash) = @_;
-
+ my $name = $hash->{NAME};
+
Log3($hash->{NAME},4,"SOMFY_TimedUpdate");
- # get current infos
+ return if(IsDisabled($name));
+
+ # get current infos
my $pos = ReadingsVal($hash->{NAME},'exact',undef);
if ( AttrVal( $hash->{NAME}, "positionInverse", 0 ) ) {
@@ -1494,6 +1592,9 @@ sub SOMFY_SendCommand($@)
my $io = $hash->{IODev};
my $ioType = $io->{TYPE};
+ return $ret if(IsIgnored($name));
+ return $ret if(IsDisabled($name));
+
Log3($name,4,"SOMFY_sendCommand: $name -> cmd :$cmd: ");
# custom control needs 2 digit hex code
@@ -1553,7 +1654,7 @@ sub SOMFY_SendCommand($@)
# Ys ad 20 0ae3 a2 98 42
my $enckey = uc(ReadingsVal($name, "enc_key", "A0"));
- my $rollingcode = uc(ReadingsVal($name, "rolling_code", "0000"));
+ my $rollingcode = SOMFY_getRollCode( $hash );
if($command eq "XX") {
# use user-supplied custom command
@@ -1598,6 +1699,8 @@ sub SOMFY_SendCommand($@)
# update the readings, but do not generate an event
setReadingsVal($hash, "enc_key", $new_enc_key, $timestamp);
setReadingsVal($hash, "rolling_code", $new_rolling_code, $timestamp);
+ # store in uniqueID if requested
+ 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 );
@@ -1819,6 +1922,11 @@ sub SOMFY_SendCommand($@)
If set to 1 the enc-key is not changed after a command sent to the device. Default is value 0 meaning enc-key is changed normally for the RTS protocol.
+