From 597f8d4e4ceb8b293c2b04ae66807808f0ce4418 Mon Sep 17 00:00:00 2001 From: KernSani Date: Wed, 26 Dec 2018 16:21:40 +0000 Subject: [PATCH] 45_TRX.pm: New protocols set command git-svn-id: https://svn.fhem.de/fhem/trunk@18060 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/45_TRX.pm | 376 ++++++++++++++++++++++++++++++++------------ 1 file changed, 276 insertions(+), 100 deletions(-) diff --git a/fhem/FHEM/45_TRX.pm b/fhem/FHEM/45_TRX.pm index 9e9627478..dc3b690dd 100755 --- a/fhem/FHEM/45_TRX.pm +++ b/fhem/FHEM/45_TRX.pm @@ -28,7 +28,10 @@ ############################################################################## # # CHANGELOG -# +# +# 26.12.2018 RfxMgr-like functionality to enable/disable protocols +# Support for Cuveo devices +# 15.12.2018 added more readings and additional RFX-models # 23.04.2018 added readings for Settings (firmware, frequency, protocols) # 02.04.2018 support for vair CO2 sensors (forum #67734) -Thanks to vbs # 29.03.2018 Summary for Commandref @@ -51,7 +54,48 @@ sub TRX_Read($@); sub TRX_Ready($); sub TRX_Parse($$$$); -my %sets = ( "reopen" => "" ); +my %m3 = ( + 0x01 => "AE/Blyss/Cuveo", + 0x02 => "Rubicson", + 0x04 => "FineOffset/Viking", + 0x08 => "Lighting4", + 0x10 => "RSL", + 0x20 => "ByronSX", + 0x40 => "Imagintronix/Opus", + 0x80 => "undecoded" +); +my %m4 = ( + 0x01 => "Mertik", + 0x02 => "AD/LightwaveRF", + 0x04 => "Hideki/TFA/Cresta/UPM", + 0x08 => "LaCrosse", + 0x10 => "Legrand/CAD", + 0x40 => "BlindsT0", + 0x80 => "BlindsT1/T2/T3/T4" +); +my %m5 = ( + 0x01 => "X10", + 0x02 => "ARC", + 0x04 => "AC", + 0x08 => "HomeEasyEU", + 0x10 => "Meiantech/Atlantic", + 0x20 => "Oregon", + 0x40 => "ATI/cartelectronic", + 0x80 => "Visonic" +); +my %m6 = ( + 0x01 => "Keeloq", + 0x02 => "HomeConfort", + 0x40 => "MCZ", + 0x80 => "FunkBus" +); + +my $modes = join( ",", values %m3 ); +$modes .= "," . join( ",", values %m4 ); +$modes .= "," . join( ",", values %m5 ); +$modes .= "," . join( ",", values %m6 ); + +my $sets = "reopen:noArg protocols:multiple-strict," . $modes . " save:noArg"; sub TRX_Initialize($) { my ($hash) = @_; @@ -189,8 +233,7 @@ sub TRX_Set($@) { my ( $hash, @a ) = @_; return "\"set TRX\" needs at least one parameter" if ( @a < 1 ); - return "Unknown argument $a[1], choose one of " . join( " ", sort keys %sets ) - if ( !defined( $sets{ $a[1] } ) ); + my $usage = "Unknown argument $a[1], choose one of " . $sets; my $name = shift @a; my $type = shift @a; @@ -198,8 +241,64 @@ sub TRX_Set($@) { if ( $type eq "reopen" ) { #################################### TRX_Reopen($hash); } + elsif ( $type eq "protocols" ) { + return TRX_SetModes( $hash, @a ); + } + elsif ( $type eq "save" ) { + return TRX_Save($hash); + } + else { + return $usage; + } +} +##################################### +sub TRX_Save($) { + my ($hash) = @_; + my $cmd = "0D0000000600000000000000"; + DevIo_SimpleWrite( $hash, $cmd, 1 ); +} + +##################################### +sub TRX_SetModes($@) { + my ( $hash, $values ) = @_; + my $name = $hash->{NAME}; + my @vals = split( ",", $values ); + my $ret = undef; + my $protocols = ""; + + my ( $b3, $b4, $b5, $b6 ) = "00"; + + Log3 $name, 5, "[$name] Setting protocols " . Dumper(@vals); + foreach my $key ( keys %m3 ) { + if ( grep ( /$m3{$key}/, @vals ) ) { + $b3 += $key; + $protocols .= $m3{$key} . ","; + } + } + foreach my $key ( keys %m4 ) { + if ( grep ( /$m4{$key}/, @vals ) ) { + $b4 += $key; + $protocols .= $m4{$key} . ","; + } + } + foreach my $key ( keys %m5 ) { + if ( grep ( /$m5{$key}/, @vals ) ) { + $b5 += $key; + $protocols .= $m5{$key} . ","; + } + } + foreach my $key ( keys %m6 ) { + if ( grep ( /$m6{$key}/, @vals ) ) { + $b6 += $key; + $protocols .= $m6{$key} . ","; + } + } + my $hex = sprintf( "0D000000035308%02x%02x%02x%02x000000", $b3, $b4, $b5, $b6 ); + DevIo_SimpleWrite( $hash, $hex, 1 ); + return undef; + } ##################################### @@ -237,8 +336,10 @@ sub TRX_DoInit($) { else { # Reset my $init = pack( 'H*', "0D00000000000000000000000000" ); - DevIo_SimpleWrite( $hash, $init, 0 ); - DevIo_TimeoutRead( $hash, 0.5 ); + + #DevIo_SimpleWrite( $hash, $init, 0 ); + #DevIo_TimeoutRead( $hash, 0.5 ); + DevIo_Expect( $hash, $init, 0.5 ); sleep(1); TRX_Clear($hash); @@ -262,93 +363,7 @@ sub TRX_DoInit($) { } else { Log3 $name, 1, "TRX: Init OK"; - - my $fw = undef; - if ( $buf =~ m/0d0100(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)/ ) { - $fw = 1; - } - elsif ( $buf =~ m/140100(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)/ ) { - $fw = 2; - } - if ($fw) { - - # Analyse result and display it: - my $status = ""; - - my $seqnbr = $1; - my $cmnd = $2; - my $msg1 = $3; - my $msg2 = ord( pack( 'H*', $4 ) ); - my $msg3 = ord( pack( 'H*', $5 ) ); - my $msg4 = ord( pack( 'H*', $6 ) ); - my $msg5 = ord( pack( 'H*', $7 ) ); - my $msg6 = ""; - $msg6 = ord( pack( 'H*', $8 ) ) if $fw == 2; - my $freq = { - '50' => '310MHz', - '51' => '315MHz', - '52' => '433.92MHz receiver only', - '53' => '433.92MHz transceiver', - '55' => '868.00MHz', - '56' => '868.00MHz FSK', - '57' => '868.30MHz', - '58' => '868.30MHz FSK', - '59' => '868.35MHz', - '5a' => '868.35MHz FSK', - '5b' => '868.95MHz' - }->{$msg1} - || 'unknown Mhz'; - $status .= $freq; - my $firmware = ""; - - if ( $fw == 2 ) { - $firmware = $msg2 + 1000; - } - else { - $firmware = $msg2; - } - - $status .= ", " . sprintf "firmware=%d", $firmware; - my $protocols = ""; - $status .= ", protocols enabled: "; - $protocols .= "undecoded " if ( $msg3 & 0x80 ); - $protocols .= "RFU " if ( $msg3 & 0x40 ); - $protocols .= "ByronSX " if ( $msg3 & 0x20 ); - $protocols .= "RSL " if ( $msg3 & 0x10 ); - $protocols .= "Lighting4 " if ( $msg3 & 0x08 ); - $protocols .= "FineOffset/Viking " if ( $msg3 & 0x04 ); - $protocols .= "Rubicson " if ( $msg3 & 0x02 ); - $protocols .= "AE/Blyss " if ( $msg3 & 0x01 ); - $protocols .= "BlindsT1/T2/T3/T4 " if ( $msg4 & 0x80 ); - $protocols .= "BlindsT0 " if ( $msg4 & 0x40 ); - $protocols .= "ProGuard " if ( $msg4 & 0x20 ); - $protocols .= "FS20 " if ( $msg4 & 0x10 ); - $protocols .= "LaCrosse " if ( $msg4 & 0x08 ); - $protocols .= "Hideki " if ( $msg4 & 0x04 ); - $protocols .= "LightwaveRF " if ( $msg4 & 0x02 ); - $protocols .= "Mertik " if ( $msg4 & 0x01 ); - $protocols .= "Visonic " if ( $msg5 & 0x80 ); - $protocols .= "ATI " if ( $msg5 & 0x40 ); - $protocols .= "OREGON " if ( $msg5 & 0x20 ); - $protocols .= "KOPPLA " if ( $msg5 & 0x10 ); - $protocols .= "HOMEEASY " if ( $msg5 & 0x08 ); - $protocols .= "AC " if ( $msg5 & 0x04 ); - $protocols .= "ARC " if ( $msg5 & 0x02 ); - $protocols .= "X10 " if ( $msg5 & 0x01 ); - $protocols .= "HomeComfort " if ( $msg6 & 0x02 and $fw == 2 ); - $protocols .= "KEELOQ " if ( $msg6 & 0x01 and $fw == 2 ); - $status .= $protocols; - my $hexline = unpack( 'H*', $buf ); - Log3 $name, 4, "TRX: Init status hexline='$hexline'"; - Log3 $name, 1, "TRX: Init status: '$status'"; - readingsBeginUpdate($hash); - readingsBulkUpdate( $hash, "frequency", $freq ); - readingsBulkUpdate( $hash, "firmware", $firmware ); - readingsBulkUpdate( $hash, "protocols", $protocols ); - readingsEndUpdate( $hash, 1 ); - - } - + TRX_evaluateResponse( $hash, $buf ); } } @@ -361,6 +376,151 @@ sub TRX_DoInit($) { return undef; } +sub TRX_evaluateResponse($$) { + my ($hash, $buf ) = @_; + my $name = $hash->{NAME}; + + my $fw = undef; + if ( $buf =~ m/0d0100(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)/ ) { + $fw = 1; + } + + # 140100 04 03 53 21 00 00 27 00 01 03 1C 05 5F 46 58 43 4F 4D + elsif ( $buf =~ m/140100(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)/ ) { + $fw = 2; + } + if ($fw) { + + # Analyse result and display it: + my $status = ""; + + my $seqnbr = $1; + my $cmnd = $2; + my $msg1 = $3; + my $msg2 = ord( pack( 'H*', $4 ) ); + my $msg3 = ord( pack( 'H*', $5 ) ); + my $msg4 = ord( pack( 'H*', $6 ) ); + my $msg5 = ord( pack( 'H*', $7 ) ); + my $msg6 = ""; + + $msg6 = ord( pack( 'H*', $8 ) ) if $fw == 2; + my $freq = { + '50' => 'RFXtrx315 310MHz', + '51' => 'RFXtrx315 315MHz', + '52' => 'RFXrec433 433.92MHz receiver only', + '53' => 'RFXrec433 433.92MHz transceiver', + '54' => 'RFXrec433 433.42MHz transceiver', + '55' => 'RFXtrx868X 868.00MHz', + '56' => 'RFXtrx868X 868.00MHz FSK', + '57' => 'RFXtrx868X 868.30MHz', + '58' => 'RFXtrx868X 868.30MHz FSK', + '59' => 'RFXtrx868X 868.35MHz', + '5a' => 'RFXtrx868X 868.35MHz FSK', + '5b' => 'RFXtrx868X 868.95MHz', + '5c' => 'RFXtrxIOT 433.92MHz', + '5d' => 'RFXtrxIOT 868MHz', + '5f' => 'RFXtrx433 434.50MHz' + }->{$msg1} + || 'unknown Mhz'; + $status .= $freq; + + #Firmware Type + my $msg10 = ord( pack( 'H*', $12 ) ); + my $fwt = { + '0' => 'Type1 RFXrec receive only firmware', + '1' => 'Type1', + '2' => 'Type2', + '3' => 'Ext', + '4' => 'Ext2', + '5' => 'Pro1', + '6' => 'Pro2', + '10' => 'ProXL1', + }->{$msg10} + || 'unknown FW Type ' . $msg10; + + #Firmware + my $firmware = ""; + + if ( $fw == 2 ) { + $firmware = $msg2 + 1000; + } + else { + $firmware = $msg2; + } + + #Hardware version + my $hw_major = ord( pack( 'H*', $9 ) ); + my $hw_minor = ord( pack( 'H*', $10 ) ); + my $hw = $hw_major . "." . $hw_minor; + $status .= ", " . "hardware=$hw"; + + #Output Power + my $output = ( ord( pack( 'H*', $11 ) ) - 18 ) . "dBm"; + $status .= ", " . "output power=$output"; + + $status .= ", " . sprintf "firmware=%d", $firmware; + my $protocols = ""; + $status .= ", protocols enabled: "; + foreach my $key ( keys %m3 ) { + $protocols .= $m3{$key} . "," if ( $msg3 & $key ); + } + foreach my $key ( keys %m4 ) { + $protocols .= $m4{$key} . "," if ( $msg4 & $key ); + } + foreach my $key ( keys %m5 ) { + $protocols .= $m5{$key} . "," if ( $msg5 & $key ); + } + foreach my $key ( keys %m6 ) { + $protocols .= $m6{$key} . "," if ( $msg6 & $key ); + } + + #$protocols .= "undecoded " if ( $msg3 & 0x80 ); + #$protocols .= "Imagintronix/Opus " if ( $msg3 & 0x40 ); + #$protocols .= "ByronSX " if ( $msg3 & 0x20 ); + #$protocols .= "RSL " if ( $msg3 & 0x10 ); + #$protocols .= "Lighting4 " if ( $msg3 & 0x08 ); + #$protocols .= "FineOffset/Viking " if ( $msg3 & 0x04 ); + #$protocols .= "Rubicson " if ( $msg3 & 0x02 ); + #$protocols .= "AE/Blyss " if ( $msg3 & 0x01 ); + #$protocols .= "BlindsT1/T2/T3/T4 " if ( $msg4 & 0x80 ); + #$protocols .= "BlindsT0 " if ( $msg4 & 0x40 ); + #$protocols .= "ProGuard " if ( $msg4 & 0x20 ); + #$protocols .= "FS20 " if ( $msg4 & 0x10 ); + #$protocols .= "LaCrosse " if ( $msg4 & 0x08 ); + #$protocols .= "Hideki " if ( $msg4 & 0x04 ); + #$protocols .= "LightwaveRF " if ( $msg4 & 0x02 ); + #$protocols .= "Mertik " if ( $msg4 & 0x01 ); + #$protocols .= "Visonic " if ( $msg5 & 0x80 ); + #$protocols .= "ATI " if ( $msg5 & 0x40 ); + #$protocols .= "OREGON " if ( $msg5 & 0x20 ); + #$protocols .= "Meiantech/Atlantic " if ( $msg5 & 0x10 ); + #$protocols .= "HOMEEASY " if ( $msg5 & 0x08 ); + #$protocols .= "AC " if ( $msg5 & 0x04 ); + #$protocols .= "ARC " if ( $msg5 & 0x02 ); + #$protocols .= "X10 " if ( $msg5 & 0x01 ); + #$protocols .= "HomeComfort " if ( $msg6 & 0x02 and $fw == 2 ); + #$protocols .= "KEELOQ " if ( $msg6 & 0x01 and $fw == 2 ); + #$protocols .= "FunkBus " if ( $msg6 & 0x80 ); + #$protocols .= "MCZ " if ( $msg6 & 0x40 ); + + $status .= $protocols; + + my $hexline = unpack( 'H*', $buf ); + Log3 $name, 4, "TRX: Init status hexline='$hexline'"; + Log3 $name, 1, "TRX: Init status: '$status'"; + readingsBeginUpdate($hash); + readingsBulkUpdate( $hash, "frequency", $freq ); + readingsBulkUpdate( $hash, "firmware", $firmware ); + readingsBulkUpdate( $hash, "protocols", $protocols ); + readingsBulkUpdate( $hash, "output_power", $output ); + readingsBulkUpdate( $hash, "firmware_type", $fwt ); + readingsBulkUpdate( $hash, "hardware", $hw ); + readingsEndUpdate( $hash, 1 ); + + } + +} + ##################################### # This is a direct read for commands like get sub TRX_ReadAnswer($$) { @@ -419,7 +579,7 @@ sub TRX_ReadAnswer($$) { } } } - + ##################################### # called from the global loop, when the select for hash->{FD} reports data sub TRX_Read($@) { @@ -476,12 +636,18 @@ sub TRX_Parse($$$$) { # (some Oregon sensors always sends the message twice, X10 security sensors even sends the message five times) if ( ( "$last_rmsg" ne "$rmsg" ) || ( time() - $last_time ) > 1 ) { Log3 $hash, 5, "TRX_Parse() '$rmsg'"; - %addvals = ( RAWMSG => $rmsg ); - Dispatch( $hash, $rmsg, \%addvals ); - $hash->{"${name}_MSGCNT"}++; - $hash->{"${name}_TIME"} = TimeNow(); - $hash->{RAWMSG} = $rmsg; - readingsSingleUpdate( $hash, "state", $hash->{READINGS}{state}{VAL}, 0 ); + if ( $rmsg =~ m/0d0100....................../ || $rmsg =~ m/140100..................................../ ) { + Log3 $hash, 5, "TRX_Parse() retrieved a command response - no dispatch"; + TRX_evaluateResponse( $hash, $rmsg ); + } + else { + %addvals = ( RAWMSG => $rmsg ); + Dispatch( $hash, $rmsg, \%addvals ); + $hash->{"${name}_MSGCNT"}++; + $hash->{"${name}_TIME"} = TimeNow(); + $hash->{RAWMSG} = $rmsg; + readingsSingleUpdate( $hash, "state", $hash->{READINGS}{state}{VAL}, 0 ); + } } else { Log3 $hash, 5, "TRX_Parse() '$rmsg' dup"; @@ -572,6 +738,16 @@ KlikAanKlikUit, NEXA, CHACON, HomeEasy UK.
+ + Set + + Readings