mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-08 07:24:21 +00:00
new protocols added: AC, HomeEasy EU and ANSLUT
git-svn-id: https://svn.fhem.de/fhem/trunk@1427 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
26289a6dac
commit
3def3d4c65
@ -8,6 +8,10 @@
|
|||||||
# "WAVEMAN" -> Waveman
|
# "WAVEMAN" -> Waveman
|
||||||
# "EMW200" -> Chacon EMW200
|
# "EMW200" -> Chacon EMW200
|
||||||
# "IMPULS" -> IMPULS
|
# "IMPULS" -> IMPULS
|
||||||
|
# "AC" -> KlikAanKlikUit, NEXA, CHACON, HomeEasy UK
|
||||||
|
# "HOMEEASY" -> HomeEasy EU
|
||||||
|
# "ANSLUT" -> ANSLUT
|
||||||
|
# "KOPPLA" -> Ikea Koppla
|
||||||
#
|
#
|
||||||
# - ms14a: motion sensor
|
# - ms14a: motion sensor
|
||||||
# - x10: generic X10 sensor
|
# - x10: generic X10 sensor
|
||||||
@ -40,34 +44,40 @@ my $TRX_LIGHT_X10_type_default = "x10";
|
|||||||
my $DOT = q{_};
|
my $DOT = q{_};
|
||||||
|
|
||||||
my %light_device_codes = ( # HEXSTRING => "NAME", "name of reading",
|
my %light_device_codes = ( # HEXSTRING => "NAME", "name of reading",
|
||||||
0x00 => [ "X10", "light" ],
|
# 0x10: Lighting1
|
||||||
0x01 => [ "ARC", "light" ],
|
0x1000 => [ "X10", "light" ],
|
||||||
0x02 => [ "AB400D", "light" ],
|
0x1001 => [ "ARC", "light" ],
|
||||||
0x03 => [ "WAVEMAN", "light" ],
|
0x1002 => [ "AB400D", "light" ],
|
||||||
0x04 => [ "EMW200", "light"],
|
0x1003 => [ "WAVEMAN", "light" ],
|
||||||
0x05 => [ "IMPULS", "light"],
|
0x1004 => [ "EMW200", "light"],
|
||||||
|
0x1005 => [ "IMPULS", "light"],
|
||||||
|
# 0x11: Lighting2
|
||||||
|
0x1100 => [ "AC", "light"],
|
||||||
|
0x1101 => [ "HOMEEASY", "light"],
|
||||||
|
0x1102 => [ "ANSLUT", "light"],
|
||||||
|
# 0x12: Lighting3
|
||||||
|
0x1200 => [ "KOPPLA", "light"], # IKEA Koppla
|
||||||
);
|
);
|
||||||
|
|
||||||
my %light_device_commands = ( # HEXSTRING => commands
|
my %light_device_commands = ( # HEXSTRING => commands
|
||||||
0x00 => [ "off", "on", "dim", "bright", "all_off", "all_on", ""],
|
# 0x10: Lighting1
|
||||||
0x01 => [ "off", "on", "", "", "all_off", "all_on", "chime"],
|
0x1000 => [ "off", "on", "dim", "bright", "all_off", "all_on", ""], # X10
|
||||||
0x02 => [ "off", "on", "", "", "", "", ""],
|
0x1001 => [ "off", "on", "", "", "all_off", "all_on", "chime"], # ARC
|
||||||
0x03 => [ "off", "on", "", "", "", "", ""],
|
0x1002 => [ "off", "on", "", "", "", "", ""], # AB400D
|
||||||
0x04 => [ "off", "on", "", "", "all_off", "all_on", ""],
|
0x1003 => [ "off", "on", "", "", "", "", ""], # WAVEMAN
|
||||||
0x05 => [ "off", "on", "", "", "", "", ""],
|
0x1004 => [ "off", "on", "", "", "all_off", "all_on", ""], # EMW200
|
||||||
|
0x1005 => [ "off", "on", "", "", "", "", ""], # IMPULS
|
||||||
|
# 0x11: Lighting2
|
||||||
|
0x1100 => [ "off", "on", "level", "all_off", "all_on", "all_level"], # AC
|
||||||
|
0x1101 => [ "off", "on", "level", "all_off", "all_on", "all_level"], # HOMEEASY
|
||||||
|
0x1102 => [ "off", "on", "level", "all_off", "all_on", "all_level"], # ANSLUT
|
||||||
|
# 0x12: Lighting3
|
||||||
|
0x1200 => [ "bright", "", "", "", "", "", "", "dim", "", "", "", "", "", "", "", "", "",
|
||||||
|
"on", "level1", "level2", "level3", "level4", "level5", "level6", "level7", "level8", "level9", "off", "", "program", "", "", "", "",], # Koppla
|
||||||
);
|
);
|
||||||
|
|
||||||
my %light_device_c2b; # DEVICE_TYPE->hash (reverse of light_device_codes)
|
my %light_device_c2b; # DEVICE_TYPE->hash (reverse of light_device_codes)
|
||||||
|
|
||||||
# Get the binary value for a command
|
|
||||||
# return -1 if command not valid dor dev_type
|
|
||||||
sub TRX_LIGHT_cmd_to_binary {
|
|
||||||
my ($dev_type, $command) = @_;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub
|
sub
|
||||||
TRX_LIGHT_Initialize($)
|
TRX_LIGHT_Initialize($)
|
||||||
{
|
{
|
||||||
@ -107,34 +117,27 @@ TRX_LIGHT_Set($@)
|
|||||||
my $ret = undef;
|
my $ret = undef;
|
||||||
my $na = int(@a);
|
my $na = int(@a);
|
||||||
|
|
||||||
return "no set value specified" if($na < 2 || $na > 3);
|
return "no set value specified" if($na < 2 || $na > 4);
|
||||||
|
|
||||||
# look for device_type
|
# look for device_type
|
||||||
|
|
||||||
my $name = $a[0];
|
my $name = $a[0];
|
||||||
my $command = $a[1];
|
my $command = $a[1];
|
||||||
|
my $level = $a[2];
|
||||||
|
|
||||||
my $device_type = $hash->{TRX_LIGHT_type};
|
my $device_type = $hash->{TRX_LIGHT_type};
|
||||||
my $deviceid = $hash->{TRX_LIGHT_deviceid};
|
my $deviceid = $hash->{TRX_LIGHT_deviceid};
|
||||||
|
|
||||||
my $house;
|
|
||||||
my $unit;
|
|
||||||
if ($deviceid =~ /(.)(.*)/ ) {
|
|
||||||
$house = ord("$1");
|
|
||||||
$unit = $2;
|
|
||||||
} else {
|
|
||||||
Log 4,"TRX_LIGHT_Set wrong deviceid: name=$name device_type=$device_type, deviceid=$deviceid";
|
|
||||||
return "error set name=$name deviveid=$deviceid";
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($device_type eq "MS14A") {
|
if ($device_type eq "MS14A") {
|
||||||
return "No set implemented for $device_type";
|
return "No set implemented for $device_type";
|
||||||
}
|
}
|
||||||
|
|
||||||
my $device_type_num = $light_device_c2b{$device_type};
|
my $device_type_num = $light_device_c2b{$device_type};
|
||||||
if(!defined($device_type_num)) {
|
if(!defined($device_type_num)) {
|
||||||
return "Unknown device_type, choose one of " .
|
return "Unknown device_type, choose one of " .
|
||||||
join(" ", sort keys %light_device_c2b);
|
join(" ", sort keys %light_device_c2b);
|
||||||
}
|
}
|
||||||
|
my $protocol_type = $device_type_num >> 8; # high bytes
|
||||||
|
|
||||||
# Now check if the command is valid and retrieve the command id:
|
# Now check if the command is valid and retrieve the command id:
|
||||||
my $rec = $light_device_commands{$device_type_num};
|
my $rec = $light_device_commands{$device_type_num};
|
||||||
@ -147,14 +150,49 @@ TRX_LIGHT_Set($@)
|
|||||||
return $error;
|
return $error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($na == 4 && $command ne "level") {
|
||||||
|
my $error = "Error: level not possible for command $command";
|
||||||
|
}
|
||||||
|
|
||||||
my $seqnr = 0;
|
my $seqnr = 0;
|
||||||
my $cmnd = $i;
|
my $cmnd = $i;
|
||||||
|
|
||||||
my $hex_prefix = sprintf "0710";
|
my $hex_prefix;
|
||||||
my $hex_command = sprintf "%02x%02x%02x%02x%02x00", $device_type_num, $seqnr, $house, $unit, $cmnd;
|
my $hex_command;
|
||||||
|
if ($protocol_type == 0x10) {
|
||||||
|
my $house;
|
||||||
|
my $unit;
|
||||||
|
if ($deviceid =~ /(.)(.*)/ ) {
|
||||||
|
$house = ord("$1");
|
||||||
|
$unit = $2;
|
||||||
|
} else {
|
||||||
|
Log 4,"TRX_LIGHT_Set lightning1 wrong deviceid: name=$name device_type=$device_type, deviceid=$deviceid";
|
||||||
|
return "error set name=$name deviveid=$deviceid";
|
||||||
|
}
|
||||||
|
|
||||||
|
# lightning1
|
||||||
|
$hex_prefix = sprintf "0710";
|
||||||
|
$hex_command = sprintf "%02x%02x%02x%02x%02x00", $device_type_num, $seqnr, $house, $unit, $cmnd;
|
||||||
Log 1,"TRX_LIGHT_Set name=$name device_type=$device_type, deviceid=$deviceid house=$house, unit=$unit command=$command" if ($TRX_LIGHT_debug == 1);
|
Log 1,"TRX_LIGHT_Set name=$name device_type=$device_type, deviceid=$deviceid house=$house, unit=$unit command=$command" if ($TRX_LIGHT_debug == 1);
|
||||||
Log 1,"TRX_LIGHT_Set hexline=$hex_command" if ($TRX_LIGHT_debug == 1);
|
Log 1,"TRX_LIGHT_Set hexline=$hex_command" if ($TRX_LIGHT_debug == 1);
|
||||||
|
} elsif ($protocol_type == 0x11) {
|
||||||
|
# lightning2
|
||||||
|
if (uc($deviceid) =~ /^[0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F]$/ ) {
|
||||||
|
;
|
||||||
|
} else {
|
||||||
|
Log 4,"TRX_LIGHT_Set lightning2 wrong deviceid: name=$name device_type=$device_type, deviceid=$deviceid";
|
||||||
|
return "error set name=$name deviveid=$deviceid";
|
||||||
|
}
|
||||||
|
$hex_prefix = sprintf "0711";
|
||||||
|
$hex_command = sprintf "%02x%02x%s%02x%02x00", $device_type_num, $seqnr, $deviceid, $cmnd, $level;
|
||||||
|
if ($command eq "level") {
|
||||||
|
$command .= sprintf " %d", $level;
|
||||||
|
}
|
||||||
|
Log 1,"TRX_LIGHT_Set name=$name device_type=$device_type, deviceid=$deviceid command=$command" if ($TRX_LIGHT_debug == 1);
|
||||||
|
Log 1,"TRX_LIGHT_Set hexline=$hex_command" if ($TRX_LIGHT_debug == 1);
|
||||||
|
} else {
|
||||||
|
return "No set implemented for $device_type . Unknown protocol type";
|
||||||
|
}
|
||||||
|
|
||||||
IOWrite($hash, $hex_prefix, $hex_command);
|
IOWrite($hash, $hex_prefix, $hex_command);
|
||||||
|
|
||||||
@ -192,7 +230,7 @@ TRX_LIGHT_Define($$)
|
|||||||
|
|
||||||
$type = uc($type);
|
$type = uc($type);
|
||||||
|
|
||||||
if ($type ne "X10" && $type ne "ARC" && $type ne "MS14A" && $type ne "AB400D" && $type ne "WAVEMAN" && $type ne "EMW200" && $type ne "IMPULS") {
|
if ($type ne "X10" && $type ne "ARC" && $type ne "MS14A" && $type ne "AB400D" && $type ne "WAVEMAN" && $type ne "EMW200" && $type ne "IMPULS" && $type ne "AC" && $type ne "HOMEEASY" && $type ne "ANSLUT" && $type ne "KOPPLA") {
|
||||||
Log 1,"TRX_LIGHT define: wrong type: $type";
|
Log 1,"TRX_LIGHT define: wrong type: $type";
|
||||||
return "TRX_LIGHT: wrong type: $type";
|
return "TRX_LIGHT: wrong type: $type";
|
||||||
}
|
}
|
||||||
@ -246,24 +284,32 @@ TRX_LIGHT_Undef($$)
|
|||||||
sub TRX_LIGHT_parse_X10 {
|
sub TRX_LIGHT_parse_X10 {
|
||||||
my $bytes = shift;
|
my $bytes = shift;
|
||||||
|
|
||||||
my $error;
|
my $error = "";
|
||||||
|
|
||||||
|
|
||||||
#my $device;
|
#my $device;
|
||||||
|
|
||||||
|
my $type = $bytes->[0];
|
||||||
my $subtype = $bytes->[1];
|
my $subtype = $bytes->[1];
|
||||||
my $dev_type;
|
my $dev_type;
|
||||||
my $dev_reading;
|
my $dev_reading;
|
||||||
my $rest;
|
my $rest;
|
||||||
if (exists $light_device_codes{$subtype}) {
|
|
||||||
my $rec = $light_device_codes{$subtype};
|
my $type_subtype = ($type << 8) + $subtype;
|
||||||
|
|
||||||
|
if (exists $light_device_codes{$type_subtype}) {
|
||||||
|
my $rec = $light_device_codes{$type_subtype};
|
||||||
($dev_type, $dev_reading) = @$rec;
|
($dev_type, $dev_reading) = @$rec;
|
||||||
} else {
|
} else {
|
||||||
$error = sprintf "TRX_LIGHT: error undefined subtype=%02x", $subtype;
|
$error = sprintf "TRX_LIGHT: error undefined type=%02x, subtype=%02x", $type, $subtype;
|
||||||
Log 1, $error;
|
Log 1, $error;
|
||||||
return $error;
|
return $error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
my $device;
|
||||||
|
my $data;
|
||||||
|
if ($type == 0x10) {
|
||||||
my $dev_first = "?";
|
my $dev_first = "?";
|
||||||
|
|
||||||
my %x10_housecode =
|
my %x10_housecode =
|
||||||
@ -289,33 +335,39 @@ sub TRX_LIGHT_parse_X10 {
|
|||||||
if (exists $x10_housecode{$devnr}) {
|
if (exists $x10_housecode{$devnr}) {
|
||||||
$dev_first = $x10_housecode{$devnr};
|
$dev_first = $x10_housecode{$devnr};
|
||||||
} else {
|
} else {
|
||||||
$error = sprintf "TRX_SECURITY: x10_housecode wrong housecode=%02x", $devnr;
|
$error = sprintf "TRX_LIGHT: x10_housecode wrong housecode=%02x", $devnr;
|
||||||
Log 1, $error;
|
Log 1, $error;
|
||||||
return $error;
|
return $error;
|
||||||
}
|
}
|
||||||
|
|
||||||
my $unit = $bytes->[4]; # unitcode
|
my $unit = $bytes->[4]; # unitcode
|
||||||
|
$device = sprintf '%s%0d', $dev_first, $unit;
|
||||||
|
$data = $bytes->[5];
|
||||||
|
|
||||||
my $device = sprintf '%s%0d', $dev_first, $unit;
|
} elsif ($type == 0x11) {
|
||||||
|
$device = sprintf '%02x%02x%02x%02x%02x', $bytes->[3], $bytes->[4], $bytes->[5], $bytes->[6], $bytes->[7];
|
||||||
my $data = $bytes->[5];
|
$data = $bytes->[8];
|
||||||
|
} else {
|
||||||
|
$error = sprintf "TRX_LIGHT: wrong type=%02x", $type;
|
||||||
|
Log 1, $error;
|
||||||
|
return $error;
|
||||||
|
}
|
||||||
my $hexdata = sprintf '%02x', $data;
|
my $hexdata = sprintf '%02x', $data;
|
||||||
|
|
||||||
|
|
||||||
my $command = "";
|
my $command = "";
|
||||||
if ($data == 0xff) {
|
if (exists $light_device_commands{$type_subtype}) {
|
||||||
$command = "illegal_cmd";
|
my $code = $light_device_commands{$type_subtype};
|
||||||
} else {
|
|
||||||
if (exists $light_device_commands{$subtype}) {
|
|
||||||
my $code = $light_device_commands{$subtype};
|
|
||||||
if (exists $code->[$data]) {
|
if (exists $code->[$data]) {
|
||||||
$command = $code->[$data];
|
$command = $code->[$data];
|
||||||
} else {
|
} else {
|
||||||
$error = sprintf "TRX_LIGHT: out of range for subtype=%02x data=%02x", $subtype, $data;
|
$error = sprintf "TRX_LIGHT: unknown cmd type_subtype=%02x cmd=%02x", $type_subtype, $data;
|
||||||
Log 1, $error;
|
Log 1, $error;
|
||||||
return $error;
|
return $error;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
$error = sprintf "TRX_LIGHT: unknown type_subtype %02x data=%02x", $type_subtype, $data;
|
||||||
|
Log 1, $error;
|
||||||
|
return $error;
|
||||||
}
|
}
|
||||||
|
|
||||||
#my @res;
|
#my @res;
|
||||||
@ -331,7 +383,7 @@ sub TRX_LIGHT_parse_X10 {
|
|||||||
$firstdevice = 0;
|
$firstdevice = 0;
|
||||||
$def = $modules{TRX_LIGHT}{defptr2}{$device_name};
|
$def = $modules{TRX_LIGHT}{defptr2}{$device_name};
|
||||||
if (!$def) {
|
if (!$def) {
|
||||||
Log 1, "UNDEFINED $device_name TRX_SECURITY $dev_type $device $dev_reading" if ($TRX_LIGHT_debug == 1);
|
Log 1, "UNDEFINED $device_name TRX_LIGHT $dev_type $device $dev_reading" if ($TRX_LIGHT_debug == 1);
|
||||||
Log 3, "TRX_LIGHT: TRX_LIGHT Unknown device $device_name, please define it";
|
Log 3, "TRX_LIGHT: TRX_LIGHT Unknown device $device_name, please define it";
|
||||||
return "UNDEFINED $device_name TRX_LIGHT $dev_type $device $dev_reading";
|
return "UNDEFINED $device_name TRX_LIGHT $dev_type $device $dev_reading";
|
||||||
|
|
||||||
@ -361,10 +413,14 @@ sub TRX_LIGHT_parse_X10 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ($device_type eq "X10") {
|
if ($type == 0x10 || $type == 0x11) {
|
||||||
if (1) {
|
|
||||||
# try to use it for all types:
|
# try to use it for all types:
|
||||||
$current = $command;
|
$current = $command;
|
||||||
|
if ($type == 0x11 && $command eq "level") {
|
||||||
|
# append level number
|
||||||
|
my $level = $bytes->[9];
|
||||||
|
$current .= sprintf " %d", $level;
|
||||||
|
}
|
||||||
|
|
||||||
$sensor = $firstdevice == 1 ? $def->{TRX_LIGHT_devicelog} : $def->{TRX_LIGHT_devicelog2};
|
$sensor = $firstdevice == 1 ? $def->{TRX_LIGHT_devicelog} : $def->{TRX_LIGHT_devicelog2};
|
||||||
$val .= $current;
|
$val .= $current;
|
||||||
@ -372,8 +428,9 @@ sub TRX_LIGHT_parse_X10 {
|
|||||||
$def->{READINGS}{$sensor}{VAL} = $current;
|
$def->{READINGS}{$sensor}{VAL} = $current;
|
||||||
$def->{CHANGED}[$n++] = $sensor . ": " . $current;
|
$def->{CHANGED}[$n++] = $sensor . ": " . $current;
|
||||||
} else {
|
} else {
|
||||||
Log 1, "TRX_LIGHT: X10 error unknown sensor type=$device_type $name devn=$device_name first=$firstdevice type=$command, user=$device (hex $hexdata)";
|
$error = sprintf "TRX_LIGHT: error unknown sensor type=%x device_type=%s devn=%s first=%d command=%s", $type, $device_type, $device_name, $firstdevice, $command;
|
||||||
return "TRX_LIGHT X10 error unknown sensor type=$device_type for $device_name device=$device";
|
Log 1, $error;
|
||||||
|
return $error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (($firstdevice == 1) && $val) {
|
if (($firstdevice == 1) && $val) {
|
||||||
@ -420,7 +477,7 @@ TRX_LIGHT_Parse($$)
|
|||||||
|
|
||||||
#Log 1, "TRX_LIGHT: num_bytes=$num_bytes hex=$hexline type=$type" if ($TRX_LIGHT_debug == 1);
|
#Log 1, "TRX_LIGHT: num_bytes=$num_bytes hex=$hexline type=$type" if ($TRX_LIGHT_debug == 1);
|
||||||
my $res = "";
|
my $res = "";
|
||||||
if ($type == 0x10) {
|
if ($type == 0x10 || $type == 0x11 || $type == 0x12) {
|
||||||
Log 1, "TRX_LIGHT: X10 num_bytes=$num_bytes hex=$hexline" if ($TRX_LIGHT_debug == 1);
|
Log 1, "TRX_LIGHT: X10 num_bytes=$num_bytes hex=$hexline" if ($TRX_LIGHT_debug == 1);
|
||||||
$res = TRX_LIGHT_parse_X10(\@rfxcom_data_array);
|
$res = TRX_LIGHT_parse_X10(\@rfxcom_data_array);
|
||||||
Log 1, "TRX_LIGHT: unsupported hex=$hexline" if ($res ne "" && $res !~ /^UNDEFINED.*/);
|
Log 1, "TRX_LIGHT: unsupported hex=$hexline" if ($res ne "" && $res !~ /^UNDEFINED.*/);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user