2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-01-31 06:39:11 +00:00

10_SOMFY: corrected autostore rolling code (esp. restart)

git-svn-id: https://svn.fhem.de/fhem/trunk@22861 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
viegener 2020-09-26 20:45:19 +00:00
parent d68b43809c
commit c4561f9050
2 changed files with 95 additions and 48 deletions

View File

@ -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

View File

@ -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;
@ -735,6 +756,7 @@ sub SOMFY_InternalSet($@) {
my $newState;
my $updateState;
# translate state info to numbers - closed = 200 , open = 0 (correct missing values)
if ( !defined($pos) ) {
if(exists($positions{$state})) {
@ -776,7 +798,6 @@ sub SOMFY_InternalSet($@) {
} else {
}
} elsif(!defined($t1downclose) || !defined($t1down100) || !defined($t1upopen) || !defined($t1up100)) {
#if timings not set
@ -955,9 +976,14 @@ sub SOMFY_InternalSet($@) {
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.
</li><br>
<li>finalPosReading<br>
This attribute can specify the name of an additional posReading that is only set at the end of a move. Meaning intermediate values are not set.
The name can not be any of the standard readings
</li><br>
<li>fixed_enckey 1|0<br>
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.
</li><br>
@ -1935,6 +1977,11 @@ sub SOMFY_SendCommand($@)
</li><br>
<li>rawDevice <somfy address - 6 digit hex> [ <list of further somfy addresses> ]<br>
If set this SOMFY device is representing a manual remote, that is used to control a somfy blind. The address of the blind (the physical blind) is specified in the rawdevice attribute to sync position changes in the blind when the remote is used. This requires an iodevice able to receive somfy commands (e.g. signalduino). Multiple physical blinds can be specified separated by space in the attribute.
</li><br>
<li>eventMap<br>
Replace event names and set arguments. The value of this attribute
consists of a list of space separated values, each value is a colon