File Coverage

blib/lib/Device/RFXCOM/Encoder/X10.pm
Criterion Covered Total %
statement 45 45 100.0
branch 10 10 100.0
condition n/a
subroutine 9 9 100.0
pod 1 1 100.0
total 65 65 100.0


line stmt bran cond sub pod time code
1 1     1   1252 use strict;
  1         3  
  1         46  
2 1     1   7 use warnings;
  1         3  
  1         80  
3             package Device::RFXCOM::Encoder::X10;
4             $Device::RFXCOM::Encoder::X10::VERSION = '1.163170';
5             # ABSTRACT: Device::RFXCOM::Encoder::X10 encode X10 RF messages
6              
7              
8 1     1   30 use 5.006;
  1         3  
9 1     1   6 use constant DEBUG => $ENV{DEVICE_RFXCOM_ENCODER_X10_DEBUG};
  1         1  
  1         97  
10 1     1   7 use Carp qw/croak carp/;
  1         3  
  1         88  
11 1     1   7 use base 'Device::RFXCOM::Encoder';
  1         2  
  1         122  
12 1     1   702 use Device::RFXCOM::Response::X10;
  1         4  
  1         764  
13              
14             my %command_to_byte =
15             (
16             'dim' => 0x98,
17             'bright' => 0x88,
18             'all_lights_on' => 0x90,
19             'all_lights_off' => 0x80,
20             'on' => 0x0,
21             'off' => 0x20,
22             );
23             my $i = 0;
24             my %house_to_byte =
25             map { $_ => $i++ } ('m', 'n', 'o', 'p', 'c', 'd', 'a', 'b',
26             'e', 'f', 'g', 'h', 'k', 'l', 'i', 'j');
27              
28             $i = 1;
29             my %bytes_to_unit =
30             map { $_ => $i++ } ( 0x00, 0x10, 0x08, 0x18, 0x40, 0x50, 0x48, 0x58 );
31             my %unit_to_bytes = reverse %bytes_to_unit;
32              
33              
34             sub encode {
35 4     4 1 10 my ($self, $parent, $p) = @_;
36 4         9 my @res = ();
37 4 100       21 if ($p->{house}) {
    100          
38 1         8 foreach (split //, $p->{house}) {
39             push @res, $self->_encode_x10({
40             command => $p->{command},
41             house => $p->{house},
42 1         9 });
43             }
44             } elsif ($p->{device}) {
45 2         20 foreach (split /,/, $p->{device}) {
46 4 100       31 my ($house, $unit) = /^([a-p])(\d+)$/i or next;
47             push @res, $self->_encode_x10({
48             command => $p->{command},
49 3         20 house => $house,
50             unit => $unit,
51             });
52             }
53             } else {
54 1         270 carp $self.'->encode: Invalid x10 message';
55             }
56 4         146 return \@res;
57             }
58              
59             sub _encode_x10 {
60 4     4   10 my ($self, $p) = @_;
61 4         10 my @bytes = ( 0, 0, 0, 0 );
62 4         14 $bytes[2] |= $command_to_byte{lc $p->{command}};
63 4         12 $bytes[0] |= ($house_to_byte{lc $p->{house}})<<4;
64 4         9 my $unit = $p->{unit};
65 4 100       13 unless ($bytes[2]&0x80) {
66 3 100       12 if ($unit > 8) {
67 1         2 $unit -= 8;
68 1         3 $bytes[0] |= 0x4;
69             }
70 3         9 $bytes[2] |= $unit_to_bytes{$unit};
71             }
72 4         7 $bytes[1] = $bytes[0]^0xff;
73 4         9 $bytes[3] = $bytes[2]^0xff;
74             return { raw => (pack 'C5', 32, @bytes),
75             desc =>
76             'x10: '.(join '/',
77 12         49 grep { defined $_
78 4         18 } @{$p}{qw/command house unit/})
  4         11  
79             };
80             }
81              
82             1;
83              
84             __END__