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.
+
  • autoStoreRollingCode 1|0
    + If set to 1 the rolling code is stored automatically in the FHEM uniqueID file (Default is 0 - off). After setting the attribute, the code is first saved after the next change of the rolling code. +

  • + +
  • eventMap
    Replace event names and set arguments. The value of this attribute consists of a list of space separated values, each value is a colon