diff --git a/FHEM/14_SD_RSL.pm b/FHEM/14_SD_RSL.pm index 9182178..d6ec558 100644 --- a/FHEM/14_SD_RSL.pm +++ b/FHEM/14_SD_RSL.pm @@ -23,43 +23,64 @@ my %sets = ( "off" => sub { return $_[0]->{OffCode}; } ); -my @RSLCodes; - - # Schiebeschalter/Kanal [I - IV] , Tastenpaar [1 - 4] , an-aus [1 - 0] - $RSLCodes[0][0][0] = 0xBE; # ? / ? off - $RSLCodes[0][0][1] = 0xB6; # ? / ? on - $RSLCodes[1][1][0] = 0x81; # I 1 / off - $RSLCodes[1][1][1] = 0x8E; # I 1 / on - $RSLCodes[1][2][0] = 0xAE; # I 2 / off - $RSLCodes[1][2][1] = 0xA6; # I 2 / on - $RSLCodes[1][3][0] = 0x9E; # I 3 / off - $RSLCodes[1][3][1] = 0x96; # I 3 / on - $RSLCodes[1][4][0] = 0xB5; # I 4 / off - nicht auf 12 Kanal FB - $RSLCodes[1][4][1] = 0xB9; # I 4 / on - nicht auf 12 Kanal FB - $RSLCodes[2][1][0] = 0x8D; # II 1 / off - $RSLCodes[2][1][1] = 0x85; # II 1 / on - $RSLCodes[2][2][0] = 0xA5; # II 2 / off - $RSLCodes[2][2][1] = 0xA9; # II 2 / on - $RSLCodes[2][3][0] = 0x95; # II 3 / off - $RSLCodes[2][3][1] = 0x99; # II 3 / on - $RSLCodes[2][4][0] = 0xB8; # II 4 / off - nicht auf 12 Kanal FB - $RSLCodes[2][4][1] = 0xB0; # II 4 / on - nicht auf 12 Kanal FB - $RSLCodes[3][1][0] = 0x84; # III 1 / off - $RSLCodes[3][1][1] = 0x88; # III 1 / on - $RSLCodes[3][2][0] = 0xA8; # III 2 / off - $RSLCodes[3][2][1] = 0xA0; # III 2 / on - $RSLCodes[3][3][0] = 0x98; # III 3 / off - $RSLCodes[3][3][1] = 0x90; # III 3 / on - $RSLCodes[3][4][0] = 0xB2; # III 4 / off - nicht auf 12 Kanal FB - $RSLCodes[3][4][1] = 0xBC; # III 4 / on - nicht auf 12 Kanal FB - $RSLCodes[4][1][0] = 0x8A; # IV 1 / off - $RSLCodes[4][1][1] = 0x82; # IV 1 / on - $RSLCodes[4][2][0] = 0xA2; # IV 2 / off - $RSLCodes[4][2][1] = 0xAC; # IV 2 / on - $RSLCodes[4][3][0] = 0x92; # IV 3 / off - $RSLCodes[4][3][1] = 0x9C; # IV 3 / on - $RSLCodes[4][4][0] = 0xA3; # IV 4 / off All - $RSLCodes[4][4][1] = 0x93; # IV 4 / on All +my %models = ( + "RSL" => { + # Kanal, Tastenpaar, Action + 0x81 => [1, 1, 0], # I 1 / off + 0x8E => [1, 1, 1], # I 1 / on + 0xAE => [1, 2, 0], # I 2 / off + 0xA6 => [1, 2, 1], # I 2 / on + 0x9E => [1, 3, 0], # I 3 / off + 0x96 => [1, 3, 1], # I 3 / on + 0xB5 => [1, 4, 0], # I 4 / off - nicht auf 12 Kanal FB + 0xB9 => [1, 4, 1], # I 4 / on - nicht auf 12 Kanal FB + + 0x8D => [2, 1, 0], # II 1 / off + 0x85 => [2, 1, 1], # II 1 / on + 0xA5 => [2, 2, 0], # II 2 / off + 0xA9 => [2, 2, 1], # II 2 / on + 0x95 => [2, 3, 0], # II 3 / off + 0x99 => [2, 3, 1], # II 3 / on + 0xB8 => [2, 4, 0], # II 4 / off - nicht auf 12 Kanal FB + 0xB0 => [2, 4, 1], # II 4 / on - nicht auf 12 Kanal FB + + 0x84 => [3, 1, 0], # III 1 / off + 0x88 => [3, 1, 1], # III 1 / on + 0xA8 => [3, 2, 0], # III 2 / off + 0xA0 => [3, 2, 1], # III 2 / on + 0x99 => [3, 3, 0], # III 3 / off + 0x90 => [3, 3, 1], # III 3 / on + 0xB2 => [3, 4, 0], # III 4 / off - nicht auf 12 Kanal FB + 0xBC => [3, 4, 1], # III 4 / on - nicht auf 12 Kanal FB + + 0x8A => [4, 1, 0], # IV 1 / off + 0x82 => [4, 1, 1], # IV 1 / on + 0xA2 => [4, 2, 0], # IV 2 / off + 0xAC => [4, 2, 1], # IV 2 / on + 0x92 => [4, 3, 0], # IV 3 / off + 0x9C => [4, 3, 1], # IV 3 / on + 0xA3 => [4, 4, 0], # IV 4 / off All + 0x93 => [4, 4, 1], # IV 4 / on All + }, + + "RSL866T" => { + # dummy, Tastenpaar, Action + 0x3E => [0, 1, 0], # 1 / off + 0x36 => [0, 1, 1], # 1 / on + + 0x01 => [0, 2, 0], # 2 / off + 0x0E => [0, 2, 1], # 2 / on + + 0x2E => [0, 3, 0], # 3 / off + 0x26 => [0, 3, 1], # 3 / on + + 0x1E => [0, 4, 0], # 4 / off + 0x16 => [0, 4, 1], # 4 / on + + 0x23 => [0, 5, 0], # G / off + 0x13 => [0, 5, 1] # G / on + } +); sub SD_RSL_Initialize { my ($hash) = @_; @@ -79,43 +100,72 @@ sub SD_RSL_Initialize { ##################################### -sub SD_RSL_Define($$) { - my ($hash, $def) = @_; +sub SD_RSL_Define($$) { + my ($hash, $def) = @_; - my @a = split("[ \t][ \t]*", $def); + my @a = split("[ \t][ \t]*", $def); - return "wrong syntax: define SD_RSL " if(int(@a) < 3 || int(@a) > 5); + return "wrong syntax: define SD_RSL " if (int(@a) < 3 || int(@a) > 4); - my $name = $a[0]; - my ($device,$channel,$button) = split("_",$a[2]); - if ($channel eq "ALL") { - $channel = 4; - $button = 4; - } + my $name = $a[0]; + my $modelName = undef; # Standard Wert für Backwards + my $device = ""; + my $channel = 0; + my $button = undef; - return "wrong syntax: use channel 1 - 4" if(($channel > 4)); # || ($channel < 1 )); - return "wrong syntax: use button 1 - 4" if(($button > 4)); # || ($button < 1)); - return "wrong syntax: use code 000000 - FFFFFF" if (length($device) != 6); - return "wrong Device Code $device , please use 000000 - FFFFFF" if ((hex($device) < 0) || (hex($device) > 16777215)); - - my $code = uc($a[2]); - $hash->{DEF} = $code; - - $modules{SD_RSL}{defptr}{$code} = $hash; - $modules{SD_RSL}{defptr}{$code}{$name} = $hash; - # code auf 32Bit umrechnen int 16777216 = 0x1000000 - #$hash->{OnCode} = ($RSLCodes[$channel][$button][1]*16777216) + hex($device); - #$hash->{OffCode} = ($RSLCodes[$channel][$button][0]*16777216) + hex($device); - $hash->{OnCode} = sprintf('%02X', ($RSLCodes[$channel][$button][1])); - $hash->{OffCode} = sprintf('%02X', ($RSLCodes[$channel][$button][0])); - - my $iodevice; - $iodevice = $a[3] if($a[3]); - $iodevice = $modules{SD_RSL}{defptr}{ioname} if (exists $modules{SD_RSL}{defptr}{ioname} && not $iodevice); - - AssignIoPort($hash, $iodevice); + my $numDeviceParts = $a[2] =~ tr/_//; + print "num: $numDeviceParts\n"; - return ; + if($numDeviceParts == 1) { + ($device, $button) = split("_", $a[2]); + + if ($button eq "ALL") { + $button = 5; + } + + return "wrong syntax: use button 1 - 5" if (($button > 5)); # || ($button < 1)); + + $modelName = "RSL866T"; + + } elsif($numDeviceParts == 2){ + ($device, $channel, $button) = split("_", $a[2]); + + if ($button eq "ALL") { + $channel = 4; + $button = 4; + } + + return "wrong syntax: use channel 1 - 4" if (($channel > 4)); # || ($channel < 1 )); + return "wrong syntax: use button 1 - 4" if (($button > 4)); # || ($button < 1)); + + $modelName = "RSL"; + + } else { + return "wrong syntax: use device XXXXXX_X_X for RSL or XXXXXX_X for RSL866T"; + } + + Log3 $hash, 4, "$name: SD_RSL_Define - Model: $modelName Device: $device Channel: $channel Button: $button"; + + return "wrong syntax: use code 000000 - FFFFFF" if (length($device) != 6); + return "wrong Device Code $device , please use 000000 - FFFFFF" if ((hex($device) < 0) || (hex($device) > 16777215)); + + my $code = uc($a[2]); + $hash->{DEF} = $code; + $hash->{Model} = $modelName; + + $modules{SD_RSL}{defptr}{$code} = $hash; + $modules{SD_RSL}{defptr}{$code}{$name} = $hash; + + $hash->{OnCode} = sprintf('%02X', RSL_getActionCode($modelName, $channel, $button, 1)); + $hash->{OffCode} = sprintf('%02X', RSL_getActionCode($modelName, $channel, $button, 0)); + + my $iodevice; + $iodevice = $a[3] if($a[3]); + $iodevice = $modules{SD_RSL}{defptr}{ioname} if (exists $modules{SD_RSL}{defptr}{ioname} && not $iodevice); + + AssignIoPort($hash, $iodevice); + + return; } ########################################################## @@ -142,99 +192,129 @@ sub SD_RSL_Set($@) { } ################################################################### -sub RSL_getButtonCode($$) { - - my ($hash,$msg) = @_; - - my $name = $hash->{NAME}; - my $DeviceCode = "undef"; - my $receivedButtonCode = "undef"; - my $receivedActionCode = "undef"; - my $parsedButtonCode = "undef"; - my $action = "undef"; - my $button = -1; - my $channel = -1; - - ## Groupcode - $DeviceCode = substr($msg,2,6); - $receivedButtonCode = substr($msg,0,2); - Log3 $hash, 4, "$name: SD_RSL_getButtonCode Message Devicecode: $DeviceCode Buttoncode: $receivedButtonCode"; - - if ((hex($receivedButtonCode) & 0xc0) != 0x80) { - Log3 $hash, 4, "$name: SD_RSL_getButtonCode Message Error: received Buttoncode $receivedButtonCode begins not with bin 10"; - return ""; - } - $parsedButtonCode = hex($receivedButtonCode); # & 63; # nur 6 Bit bitte - Log3 $hash, 5, "$name: SD_RSL_getButtonCode Message parsed Devicecode: $DeviceCode Buttoncode: $parsedButtonCode"; - - for (my $i=0; $i<5; $i++) { - for (my $j=0; $j<5; $j++) { - next if ($i == 0 && $j != 0); - next if ($i != 0 && $j == 0); - if ($RSLCodes[$i][$j][0] == $parsedButtonCode) {$action ="off"; $button = $j; $channel = $i;} - if ($RSLCodes[$i][$j][1] == $parsedButtonCode) {$action ="on"; $button = $j; $channel = $i;} +sub RSL_getActionCode($$) { + my ($modelName, $channel, $button, $action) = @_; + + foreach my $code (keys %{$models{$modelName}}){ + my @devData = $models{$modelName}{$code}; + + if($devData[0][0] == $channel + && $devData[0][1] == $button + && $devData[0][2] == $action + ) { + return $code; + } } - } +} - if (($button >-1) && ($channel > -1)) { - Log3 $hash, 4, "$name: SD_RSL_getButtonCode button return/result: ID: $DeviceCode $receivedButtonCode DEVICE: $DeviceCode $channel $button ACTION: $action"; - if ($channel == 4 && $button == 4) { - return $DeviceCode."_ALL ".$action; - } else { - return $DeviceCode."_".$channel."_".$button." ".$action; +sub RSL_getButtonCode($$) { + my ($hash, $msg) = @_; + + my $name = $hash->{NAME}; + my $DeviceCode = "undef"; + my $buttonCode = ""; + my $receivedButtonCode = "undef"; + my $parsedButtonCode = "undef"; + my $action = "undef"; + my $model = "unknown"; + my $button = -1; + my $channel = -1; + + ## Groupcode + $DeviceCode = substr($msg, 2, 6); + $receivedButtonCode = substr($msg, 0, 2); + Log3 $hash, 4, "$name: SD_RSL_getButtonCode Message Devicecode: $DeviceCode Buttoncode: $receivedButtonCode"; + + #if ((hex($receivedButtonCode) & 0xc0) != 0x80) { + # Log3 $hash, 4, "$name: SD_RSL_getButtonCode Message Error: received Buttoncode $receivedButtonCode begins not with bin 10"; + # return ""; + #} + + $parsedButtonCode = hex($receivedButtonCode); + Log3 $hash, 5, "$name: SD_RSL_getButtonCode Message parsed Devicecode: $DeviceCode Buttoncode: $parsedButtonCode"; + + foreach my $model_name (keys %models) { + Log3 $hash, 5, "$name: SD_RSL_getButtonCode test Model: $model_name"; + next if !$models{$model_name}{$parsedButtonCode}; + + my @tmp_button = $models{$model_name}{$parsedButtonCode}; + + $channel = $tmp_button[0][0]; + $button = $tmp_button[0][1]; + $action = $tmp_button[0][2]; + + Log3 $hash, 5, "$name: SD_RSL_getButtonCode Message parsed: Channel:$channel Button:$button Action:$action"; + + $buttonCode = $DeviceCode."_"; + + if($model_name eq 'RSL866T') { + if($button == 5) { + $buttonCode .= "ALL"; + } else { + $buttonCode .= $button; + } + + } else { + if($channel == 4 && $button == 4) { + $buttonCode .= "ALL"; + } else { + $buttonCode .= $channel."_".$button; + } + } + + $buttonCode .= " ".$action; + last; } - } - return ""; + Log3 $hash, 4, "$name: SD_RSL_getButtonCode button return/result: ID: $DeviceCode $receivedButtonCode DEVICE: $DeviceCode $channel $button ACTION: $action"; + + return $buttonCode; } ######################################################## -sub SD_RSL_Parse($$) { +sub SD_RSL_Parse($$) { + my ($hash, $msg) = @_; + my $name = $hash->{NAME}; + my (undef, $rawData) = split("#", $msg); - my ($hash,$msg) = @_; - my $name = $hash->{NAME}; - my (undef ,$rawData) = split("#",$msg); - - Log3 $hash, 4, "$name: SD_RSL_Parse - Message: $rawData"; + Log3 $hash, 4, "$name: SD_RSL_Parse - Message: $rawData"; - my $result = RSL_getButtonCode($hash,$rawData); + my $buttonCode = RSL_getButtonCode($hash, $rawData); - if ($result ne "") { - my ($deviceCode,$action) = split m/ /, $result, 2; + if ($buttonCode ne "") { + Log3 $hash, 4, "$name: SD_RSL_Parse - ButtonCode: $buttonCode"; - Log3 $hash, 4, "$name: SD_RSL_Parse - Device: $deviceCode Action: $action"; - - $modules{SD_RSL}{defptr}{ioname} = $name; - my $def = $modules{SD_RSL}{defptr}{$hash->{NAME} . "." . $deviceCode}; - $def = $modules{SD_RSL}{defptr}{$deviceCode} if(!$def); + my ($deviceCode, $action) = split m/ /, $buttonCode, 3; - if(!$def) { - Log3 $hash, 3, "$name: SD_RSL_Parse UNDEFINED Remotebutton send to define: $deviceCode"; - return "UNDEFINED RSL_$deviceCode SD_RSL $deviceCode"; - } - $hash = $def; + Log3 $hash, 4, "$name: SD_RSL_Parse - Device: $deviceCode Action: $action"; - my $name = $hash->{NAME}; - return "" if(IsIgnored($name)); + $modules{SD_RSL}{defptr}{ioname} = $name; + my $def = $modules{SD_RSL}{defptr}{$hash->{NAME}.".".$deviceCode}; - if(!$action) { - Log3 $name, 5, "$name: SD_RSL_Parse - can't decode $msg"; - return ""; - } + $def = $modules{SD_RSL}{defptr}{$deviceCode} if (!$def); - Log3 $name, 5, "$name: SD_RSL_Parse - actioncode: $action"; + if (!$def) { + Log3 $hash, 3, "$name: SD_RSL_Parse UNDEFINED Remotebutton send to define: $deviceCode"; + return "UNDEFINED RSL_$deviceCode SD_RSL $deviceCode"; + } - #if (($action eq "on") && ($hash->{STATE} eq "off")){$action = "stop";} - #if (($action eq "off") && ($hash->{STATE} eq "on")) {$action = "stop";} + $hash = $def; - #$hash->{CHANGED}[0] = $action; - #$hash->{STATE} = $action; - readingsSingleUpdate($hash,"state",$action,1); + my $name = $hash->{NAME}; + return "" if (IsIgnored($name)); - return $name; - } - return ""; + Log3 $name, 5, "$name: SD_RSL_Parse - actioncode: $action"; + + if($action == 1) { + readingsSingleUpdate($hash, "state", "on", 1); + } else { + readingsSingleUpdate($hash, "state", "off", 1); + } + + return $name; + } + return ""; } ######################################################## @@ -290,7 +370,21 @@ If autocreate is used, a device "<code>_ALL" like RSL_74A400_ALL

<button> The button is 1-4

- + +Define (for RSL866T) +
    +

    define <name> SD_RSL <code>_<button> <optional IODEV> +
    +
    + <name> is any name assigned to the device. + + For a better overview it is recommended to use a name in the form "RSL_B1A800_2" +

    + <code> The code is 00000-FFFFFF +

    + <button> The button is 1-4 or ALL for the G Button +

    +

Set
    @@ -330,7 +424,7 @@ Beim Verwendung von Autocreate wird bei der Taste All anstatt channel und button Define
      -

      define <name> SD_RSL <code>_<channel>[_<button>] <optional IODEV> +

      define <name> SD_RSL <code>_<channel>_<button> <optional IODEV>

      <name> ist ein Name, der dem Gerät zugewiesen ist. @@ -343,6 +437,19 @@ Beim Verwendung von Autocreate wird bei der Taste All anstatt channel und button <button> Der Knopf ist 1-4

    +Define (for RSL866T) +
      +

      define <name> SD_RSL <code>_<button> <optional IODEV> +
      +
      + <name> ist ein Name, der dem Gerät zugewiesen ist. + Zur besseren Übersicht wird empfohlen, einen Namen in dieser Form zu verwenden "RSL_B1A800_2" +

      + <code> Der Code ist 00000-FFFFFF +

      + <button> Der Knopf ist 1-5 oder ALL +

      +

    Set