2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-02-25 03:44:52 +00:00

00_TCM: eventCode 4: value list expanded, signal telegrams of the teach function changed

git-svn-id: https://svn.fhem.de/fhem/trunk@29647 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
klaus.schauer 2025-02-11 17:08:23 +00:00
parent 69b28ee6b2
commit 4b316b9d88

View File

@ -1,7 +1,6 @@
# $Id$ # $Id$
# This modules handles the communication with a TCM 120 or TCM 310 / TCM 400J / # This modules handles the communication with a TCM 120 or TCM 310 / TCM 400J / TCM 515 EnOcean transceiver chip.
# TCM 515 EnOcean transceiver chip. As the protocols are radically different, # As the protocols are radically different, this is actually 2 drivers in one.
# this is actually 2 drivers in one.
# See also: # See also:
# TCM_120_User_Manual_V1.53_02.pdf # TCM_120_User_Manual_V1.53_02.pdf
# EnOcean Serial Protocol 3 (ESP3) (for the TCM 310, TCM 400J, TCM 515) # EnOcean Serial Protocol 3 (ESP3) (for the TCM 310, TCM 400J, TCM 515)
@ -24,6 +23,20 @@ sub TCM_Parse310($$$);
sub TCM_CRC8($); sub TCM_CRC8($);
sub TCM_CSUM($); sub TCM_CSUM($);
# ESP3 response codes
my %esp3Rc = (
"00" => "OK",
"01" => "ERROR",
"02" => "NOT_SUPPORTED",
"03" => "WRONG_PARAM",
"04" => "OPERATION_DENIED",
"05" => "LOCK_SET",
"07" => "NO_FREE_BUFFER",
"82" => "FLASH_HW_ERROR",
"90" => "BASEID_OUT_OF_RANGE",
"91" => "BASEID_MAX_REACHED",
);
sub TCM_Initialize($) { sub TCM_Initialize($) {
my ($hash) = @_; my ($hash) = @_;
# Provider # Provider
@ -276,11 +289,8 @@ sub TCM_Write($$$$) {
my $bstring; my $bstring;
if ($hash->{MODEL} eq "ESP2") { if ($hash->{MODEL} eq "ESP2") {
# TCM 120 (ESP2) # TCM 120 (ESP2)
if (!$header) { if ($header) {
# command with ESP2 format # ESP3 packet
$bstring = $msg;
} else {
# command with ESP3 format
my $packetType = hex(substr($header, 6, 2)); my $packetType = hex(substr($header, 6, 2));
if ($packetType != 1) { if ($packetType != 1) {
Log3 $name, 1, "TCM $name Packet Type not supported."; Log3 $name, 1, "TCM $name Packet Type not supported.";
@ -296,7 +306,7 @@ sub TCM_Write($$$$) {
# translate the RORG to ORG # translate the RORG to ORG
my %rorgmap = ("F6"=>"05", my %rorgmap = ("F6"=>"05",
"D5"=>"06", "D5"=>"06",
"A5"=>"07", "A5"=>"07"
); );
if($rorgmap{$rorg}) { if($rorgmap{$rorg}) {
$rorg = $rorgmap{$rorg}; $rorg = $rorgmap{$rorg};
@ -308,6 +318,9 @@ sub TCM_Write($$$$) {
} else { } else {
$bstring = "6B" . $rorg . substr ($msg, 2); $bstring = "6B" . $rorg . substr ($msg, 2);
} }
} else {
# ESP2 packet
$bstring = $msg;
} }
$bstring = "A55A" . $bstring . TCM_CSUM($bstring); $bstring = "A55A" . $bstring . TCM_CSUM($bstring);
} else { } else {
@ -319,10 +332,11 @@ sub TCM_Write($$$$) {
} }
$hash->{helper}{telegramSentTimeLast} = gettimeofday(); $hash->{helper}{telegramSentTimeLast} = gettimeofday();
if (exists $hash->{helper}{SetAwaitCmdResp}) { if (exists $hash->{helper}{SetAwaitCmdResp}) {
push(@{$hash->{helper}{awaitCmdResp}}, 1); #push(@{$hash->{helper}{awaitCmdResp}}, 1);
push(@{$hash->{helper}{awaitCmdResp}}, $hash->{helper}{SetAwaitCmdResp});
delete $hash->{helper}{SetAwaitCmdResp}; delete $hash->{helper}{SetAwaitCmdResp};
} else { } else {
push(@{$hash->{helper}{awaitCmdResp}}, 0); push(@{$hash->{helper}{awaitCmdResp}}, undef);
} }
#Log3 $name, 5, "TCM $name awaitCmdResp: " . join(' ', @{$hash->{helper}{awaitCmdResp}}); #Log3 $name, 5, "TCM $name awaitCmdResp: " . join(' ', @{$hash->{helper}{awaitCmdResp}});
} }
@ -331,6 +345,7 @@ sub TCM_Write($$$$) {
DevIo_SimpleWrite($hash, $bstring, 1); DevIo_SimpleWrite($hash, $bstring, 1);
# next commands will be sent with a delay # next commands will be sent with a delay
usleep(int(AttrVal($name, "sendInterval", 100)) * 1000); usleep(int(AttrVal($name, "sendInterval", 100)) * 1000);
return undef;
} }
# ESP2 CRC # ESP2 CRC
@ -524,27 +539,20 @@ sub TCM_Read($) {
} elsif ($packetType == 2) { } elsif ($packetType == 2) {
# packet type RESPONSE # packet type RESPONSE
if (defined $hash->{helper}{awaitCmdResp}[0] && $hash->{helper}{awaitCmdResp}[0]) {
# do not execute if transceiver command answer is expected
$data .= $rest;
last;
}
shift(@{$hash->{helper}{awaitCmdResp}});
$mdata =~ m/^(..)(.*)$/; $mdata =~ m/^(..)(.*)$/;
my $rc = $1; my $rc = $1;
my %codes = ( my $rcTxt = exists($esp3Rc{$rc}) ? $esp3Rc{$rc} : $rc;
"00" => "OK", if (defined $hash->{helper}{awaitCmdResp}[0] && $hash->{helper}{awaitCmdResp}[0]) {
"01" => "ERROR", # received command response message
"02" => "NOT_SUPPORTED", TCM_Parse310($hash, $mdata, shift(@{$hash->{helper}{awaitCmdResp}}));
"03" => "WRONG_PARAM", # do not execute if transceiver command answer is expected
"04" => "OPERATION_DENIED", #$data .= $rest;
"05" => "LOCK_SET", #last;
"82" => "FLASH_HW_ERROR", } else {
"90" => "BASEID_OUT_OF_RANGE", # received sent data response messages
"91" => "BASEID_MAX_REACHED", shift(@{$hash->{helper}{awaitCmdResp}});
);
my $rcTxt = $codes{$rc} if($codes{$rc});
Log3 $name, $rc eq "00" ? 5 : 2, "TCM $name RESPONSE: $rcTxt"; Log3 $name, $rc eq "00" ? 5 : 2, "TCM $name RESPONSE: $rcTxt";
}
#$packetType = sprintf "%01X", $packetType; #$packetType = sprintf "%01X", $packetType;
#EnOcean:PacketType:ResposeCode:MessageData:OptionalData #EnOcean:PacketType:ResposeCode:MessageData:OptionalData
#Dispatch($hash, "EnOcean:$packetType:$1:$2:$odata", undef); #Dispatch($hash, "EnOcean:$packetType:$1:$2:$odata", undef);
@ -564,9 +572,9 @@ sub TCM_Read($) {
Dispatch($hash, "EnOcean:$packetType:$eventCode:$messageData", undef); Dispatch($hash, "EnOcean:$packetType:$eventCode:$messageData", undef);
} elsif (hex($eventCode) == 4) { } elsif (hex($eventCode) == 4) {
# CO_READY # CO_READY
my @resetCause = ('voltage_supply_drop', 'reset_pin', 'watchdog', 'flywheel', 'parity_error', 'hw_parity_error', 'memory_request_error', 'wake_up', 'wake_up', 'unknown'); my @resetCause = ('voltage_supply_drop', 'reset_pin', 'watchdog', 'flywheel', 'parity_error', 'hw_parity_error', 'memory_request_error', 'wake_up_pin_0', 'wake_up_pin_1', 'unknown', 'wake_up_uart', 'sw_reset');
my @secureMode = ('standard', 'extended'); my @secureMode = ('standard', 'extended');
$hash->{RESET_CAUSE} = $resetCause[hex($messageData)]; $hash->{RESET_CAUSE} = $resetCause[hex($messageData)] // $messageData;
$hash->{SECURE_MODE} = $secureMode[hex($odata)]; $hash->{SECURE_MODE} = $secureMode[hex($odata)];
DoTrigger($name, "EVENT: RESET_CAUSE: $hash->{RESET_CAUSE}"); DoTrigger($name, "EVENT: RESET_CAUSE: $hash->{RESET_CAUSE}");
DoTrigger($name, "EVENT: SECURE_MODE: $hash->{SECURE_MODE}"); DoTrigger($name, "EVENT: SECURE_MODE: $hash->{SECURE_MODE}");
@ -676,9 +684,7 @@ my %parsetbl120 = (
); );
# Parse TCM 120 # Parse TCM 120
sub sub TCM_Parse120($$$) {
TCM_Parse120($$$)
{
my ($hash,$rawmsg,$ret) = @_; my ($hash,$rawmsg,$ret) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
Log3 $name, 5, "TCM $name Parse $rawmsg"; Log3 $name, 5, "TCM $name Parse $rawmsg";
@ -702,19 +708,6 @@ TCM_Parse120($$$)
return $msg; return $msg;
} }
# Parse Table TCM 310
my %rc310 = (
"00" => "OK",
"01" => "ERROR",
"02" => "NOT_SUPPORTED",
"03" => "WRONG_PARAM",
"04" => "OPERATION_DENIED",
"05" => "LOCK_SET",
"82" => "FLASH_HW_ERROR",
"90" => "BASEID_OUT_OF_RANGE",
"91" => "BASEID_MAX_REACHED",
);
# Parse TCM 310 # Parse TCM 310
sub TCM_Parse310($$$) { sub TCM_Parse310($$$) {
my ($hash, $rawmsg, $ptr) = @_; my ($hash, $rawmsg, $ptr) = @_;
@ -723,7 +716,7 @@ sub TCM_Parse310($$$) {
my $rc = substr($rawmsg, 0, 2); my $rc = substr($rawmsg, 0, 2);
my $msg = ""; my $msg = "";
if ($rc ne "00") { if ($rc ne "00") {
$msg = $rc310{$rc}; $msg = $esp3Rc{$rc};
$msg = "Unknown return code $rc" if (!$msg); $msg = "Unknown return code $rc" if (!$msg);
} else { } else {
my @ans; my @ans;
@ -859,7 +852,7 @@ sub TCM_Get($@) {
my $cmdHex = $cmdhash->{cmd}; my $cmdHex = $cmdhash->{cmd};
my $oCmdHex = ''; my $oCmdHex = '';
$oCmdHex = $cmdhash->{oCmd} if (exists $cmdhash->{oCmd}); $oCmdHex = $cmdhash->{oCmd} if (exists $cmdhash->{oCmd});
$hash->{helper}{SetAwaitCmdResp} = 1; $hash->{helper}{SetAwaitCmdResp} = $cmdhash;
TCM_Write($hash, $hash, sprintf("%04X%02X%02X", length($cmdHex)/2, length($oCmdHex)/2, $cmdhash->{packetType}), $cmdHex . $oCmdHex); TCM_Write($hash, $hash, sprintf("%04X%02X%02X", length($cmdHex)/2, length($oCmdHex)/2, $cmdhash->{packetType}), $cmdHex . $oCmdHex);
($err, $msg) = TCM_ReadAnswer($hash, "get $cmd"); ($err, $msg) = TCM_ReadAnswer($hash, "get $cmd");
$msg = TCM_Parse310($hash, $msg, $cmdhash) if(!$err); $msg = TCM_Parse310($hash, $msg, $cmdhash) if(!$err);
@ -923,9 +916,9 @@ sub TCM_ClearTeach($) {
Log3 $hash->{NAME}, 3, "TCM $hash->{NAME} set teach 0"; Log3 $hash->{NAME}, 3, "TCM $hash->{NAME} set teach 0";
if($hash->{MODEL} ne 'ESP2') { if($hash->{MODEL} ne 'ESP2') {
# signal telegram learn mode status # signal telegram learn mode status
my $cmdhex = 'D011B' . 'F' x 17 . '0' x 10; my $cmdhex = 'D011B' . 'F' x 17 . $hash->{ChipID} . '0' x 2;
my ($err, $msg); my ($err, $msg);
$hash->{helper}{SetAwaitCmdResp} = 1; $hash->{helper}{SetAwaitCmdResp} = $sets310{'teach'};
TCM_Write($hash, $hash, sprintf("%04X00%02X", length($cmdhex)/2, 1), $cmdhex); TCM_Write($hash, $hash, sprintf("%04X00%02X", length($cmdhex)/2, 1), $cmdhex);
($err, $msg) = TCM_ReadAnswer($hash, "set teach"); ($err, $msg) = TCM_ReadAnswer($hash, "set teach");
if(!$err) { if(!$err) {
@ -1006,7 +999,7 @@ sub TCM_Set($@) {
delete $modules{"$hash->{TYPE}"}{Teach}; delete $modules{"$hash->{TYPE}"}{Teach};
return if ($hash->{MODEL} eq "ESP2"); return if ($hash->{MODEL} eq "ESP2");
# signal telegram learn mode status # signal telegram learn mode status
$cmdHex = 'D011B' . 'F' x 17 . '0' x 10; $cmdHex = 'D011B' . 'F' x 17 . $hash->{ChipID} . '0' x 2;
} else { } else {
while (my ($iDev, $iHash) = each (%{$modules{"$hash->{TYPE}"}{devHash}})) { while (my ($iDev, $iHash) = each (%{$modules{"$hash->{TYPE}"}{devHash}})) {
#Log3 $name, 2, "TCM $name clear Teach flag ioDev: $iDev ioHash: $iHash ioDevName: " . $defs{"$iHash->{NAME}"}->{NAME}; #Log3 $name, 2, "TCM $name clear Teach flag ioDev: $iDev ioHash: $iHash ioDevName: " . $defs{"$iHash->{NAME}"}->{NAME};
@ -1020,8 +1013,8 @@ sub TCM_Set($@) {
return if ($hash->{MODEL} eq "ESP2"); return if ($hash->{MODEL} eq "ESP2");
# signal telegram learn mode status # signal telegram learn mode status
my $remainTime = $arg < 10 ? 1 : int($arg / 10); my $remainTime = $arg < 10 ? 1 : int($arg / 10);
$remainTime = $remainTime > 254 ? $remainTime : 254; $remainTime = $remainTime < 254 ? $remainTime : 254;
$cmdHex = 'D0114F' . sprintf("%02X", $remainTime) . 'F' x 14 . '0' x 10; $cmdHex = 'D0114F' . sprintf("%02X", $remainTime) . 'F' x 14 . $hash->{ChipID} . '0' x 2;
} }
} }
@ -1049,7 +1042,7 @@ sub TCM_Set($@) {
delete $hash->{TRANSMIT_FAILED}; delete $hash->{TRANSMIT_FAILED};
return; return;
} }
$hash->{helper}{SetAwaitCmdResp} = 1; $hash->{helper}{SetAwaitCmdResp} = $cmdhash;
TCM_Write($hash, $hash, sprintf("%04X00%02X", length($cmdHex)/2, $cmdhash->{packetType}), $cmdHex); TCM_Write($hash, $hash, sprintf("%04X00%02X", length($cmdHex)/2, $cmdhash->{packetType}), $cmdHex);
($err, $msg) = TCM_ReadAnswer($hash, "set $cmd"); ($err, $msg) = TCM_ReadAnswer($hash, "set $cmd");
if(!$err) { if(!$err) {
@ -1238,18 +1231,7 @@ sub TCM_ReadAnswer($$) {
shift(@{$hash->{helper}{awaitCmdResp}}); shift(@{$hash->{helper}{awaitCmdResp}});
$mdata =~ m/^(..)(.*)$/; $mdata =~ m/^(..)(.*)$/;
my $rc = $1; my $rc = $1;
my %codes = ( my $rcTxt = $esp3Rc{$rc} if ($esp3Rc{$rc});
"00" => "OK",
"01" => "ERROR",
"02" => "NOT_SUPPORTED",
"03" => "WRONG_PARAM",
"04" => "OPERATION_DENIED",
"05" => "LOCK_SET",
"82" => "FLASH_HW_ERROR",
"90" => "BASEID_OUT_OF_RANGE",
"91" => "BASEID_MAX_REACHED",
);
my $rcTxt = $codes{$rc} if($codes{$rc});
Log3 $name, $rc eq "00" ? 5 : 2, "TCM $name RESPONSE: $rcTxt"; Log3 $name, $rc eq "00" ? 5 : 2, "TCM $name RESPONSE: $rcTxt";
#$packetType = sprintf "%01X", $packetType; #$packetType = sprintf "%01X", $packetType;
#EnOcean:PacketType:ResposeCode:MessageData:OptionalData #EnOcean:PacketType:ResposeCode:MessageData:OptionalData
@ -1269,7 +1251,7 @@ sub TCM_ReadAnswer($$) {
Dispatch($hash, "EnOcean:$packetTypeHex:$eventCode:$messageData", undef); Dispatch($hash, "EnOcean:$packetTypeHex:$eventCode:$messageData", undef);
} elsif (hex($eventCode) == 4) { } elsif (hex($eventCode) == 4) {
# CO_READY # CO_READY
my @resetCause = ('voltage_supply_drop', 'reset_pin', 'watchdog', 'flywheel', 'parity_error', 'hw_parity_error', 'memory_request_error', 'wake_up', 'wake_up', 'unknown'); my @resetCause = ('voltage_supply_drop', 'reset_pin', 'watchdog', 'flywheel', 'parity_error', 'hw_parity_error', 'memory_request_error', 'wake_up_pin_0', 'wake_up_pin_1', 'unknown', 'wake_up_uart', 'sw_reset');
my @secureMode = ('standard', 'extended'); my @secureMode = ('standard', 'extended');
$hash->{RESET_CAUSE} = $resetCause[hex($messageData)]; $hash->{RESET_CAUSE} = $resetCause[hex($messageData)];
$hash->{SECURE_MODE} = $secureMode[hex($odata)]; $hash->{SECURE_MODE} = $secureMode[hex($odata)];