File Coverage

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


line stmt bran cond sub pod time code
1 1     1   1068 use strict;
  1         2  
  1         32  
2 1     1   4 use warnings;
  1         2  
  1         49  
3             package Device::RFXCOM::Encoder::X10;
4             $Device::RFXCOM::Encoder::X10::VERSION = '1.142010';
5             # ABSTRACT: Device::RFXCOM::Encoder::X10 encode X10 RF messages
6              
7              
8 1     1   19 use 5.006;
  1         4  
  1         54  
9 1     1   6 use constant DEBUG => $ENV{DEVICE_RFXCOM_ENCODER_X10_DEBUG};
  1         2  
  1         60  
10 1     1   4 use Carp qw/croak carp/;
  1         2  
  1         58  
11 1     1   4 use base 'Device::RFXCOM::Encoder';
  1         2  
  1         65  
12 1     1   556 use Device::RFXCOM::Response::X10;
  1         2  
  1         613  
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 7 my ($self, $parent, $p) = @_;
36 4         7 my @res = ();
37 4 100       14 if ($p->{house}) {
    100          
38 1         5 foreach (split //, $p->{house}) {
39 1         5 push @res, $self->_encode_x10({
40             command => $p->{command},
41             house => $p->{house},
42             });
43             }
44             } elsif ($p->{device}) {
45 2         8 foreach (split /,/, $p->{device}) {
46 4 100       21 my ($house, $unit) = /^([a-p])(\d+)$/i or next;
47 3         14 push @res, $self->_encode_x10({
48             command => $p->{command},
49             house => $house,
50             unit => $unit,
51             });
52             }
53             } else {
54 1         201 carp $self.'->encode: Invalid x10 message';
55             }
56 4         119 return \@res;
57             }
58              
59             sub _encode_x10 {
60 4     4   5 my ($self, $p) = @_;
61 4         12 my @bytes = ( 0, 0, 0, 0 );
62 4         10 $bytes[2] |= $command_to_byte{lc $p->{command}};
63 4         10 $bytes[0] |= ($house_to_byte{lc $p->{house}})<<4;
64 4         6 my $unit = $p->{unit};
65 4 100       10 unless ($bytes[2]&0x80) {
66 3 100       8 if ($unit > 8) {
67 1         2 $unit -= 8;
68 1         2 $bytes[0] |= 0x4;
69             }
70 3         7 $bytes[2] |= $unit_to_bytes{$unit};
71             }
72 4         6 $bytes[1] = $bytes[0]^0xff;
73 4         5 $bytes[3] = $bytes[2]^0xff;
74 12         38 return { raw => (pack 'C5', 32, @bytes),
75             desc =>
76             'x10: '.(join '/',
77 4         10 grep { defined $_
78 4         11 } @{$p}{qw/command house unit/})
79             };
80             }
81              
82             1;
83              
84             __END__