File Coverage

blib/lib/Device/RFXCOM/Encoder/HomeEasy.pm
Criterion Covered Total %
statement 55 59 93.2
branch 12 14 85.7
condition 2 6 33.3
subroutine 9 9 100.0
pod 2 2 100.0
total 80 90 88.8


line stmt bran cond sub pod time code
1 1     1   1432 use strict;
  1         2  
  1         35  
2 1     1   6 use warnings;
  1         1  
  1         53  
3             package Device::RFXCOM::Encoder::HomeEasy;
4             $Device::RFXCOM::Encoder::HomeEasy::VERSION = '1.142010';
5             # ABSTRACT: Device::RFXCOM::Encoder::HomeEasy encode HomeEasy RF messages
6              
7              
8 1     1   26 use 5.006;
  1         3  
  1         55  
9 1     1   5 use constant DEBUG => $ENV{DEVICE_RFXCOM_ENCODER_HOMEEASY_DEBUG};
  1         1  
  1         66  
10 1     1   4 use Carp qw/croak carp/;
  1         2  
  1         47  
11 1     1   5 use base 'Device::RFXCOM::Encoder';
  1         2  
  1         556  
12 1     1   584 use Device::RFXCOM::Response::HomeEasy;
  1         4  
  1         455  
13              
14              
15             sub encode {
16 4     4 1 6 my ($self, $parent, $p) = @_;
17 4         11 my @bytes = ( 0, 0, 0, 0, 0 );
18 4         4 my $length = 33;
19 4         8 my $command;
20              
21 4 50 33     31 unless (exists $p->{command} && exists $p->{unit} && exists $p->{address}) {
      33        
22 0         0 carp $self.'->encode: Invalid homeeasy message';
23 0         0 return [];
24             }
25 4 100       11 if ($p->{command} eq 'preset') {
26 1 50       4 unless (exists $p->{level}) {
27 0         0 carp $self.'->encode: Invalid homeeasy message';
28 0         0 return [];
29             }
30 1         2 $length = 36;
31 1         3 $bytes[4] = $p->{level} << 4;
32 1         1 $command = 0;
33             } else {
34 3 100       10 $command = $p->{command} eq 'on' ? 1 : 0;
35             }
36 4 100       14 if ($p->{unit} eq 'group') {
37 1         3 $p->{unit} = 0;
38 1         3 $command |= 0x2;
39             }
40 4         11 my $addr = encode_address($p->{address});
41 4         6 $bytes[0] = $addr >> 18;
42 4         6 $bytes[1] = ($addr >> 10) & 0xff;
43 4         6 $bytes[2] = ($addr >> 2) & 0xff;
44 4         5 $bytes[3] = (($addr & 0x3) << 6);
45 4         6 $bytes[3] |= $p->{unit};
46 4         3 $bytes[3] |= ($command << 4);
47             return {
48 12         45 raw => (pack 'C6', $length, @bytes),
49             desc =>
50             'homeeasy: '.(join '/',
51 4         7 grep { defined $_
52 4         14 } @{$p}{qw/command address unit/})
53             },
54             }
55              
56              
57             sub encode_address {
58 4     4 1 5 my $addr = shift;
59 4 100       20 return hex($addr) & 0x3ffffff if ($addr =~ /^0x[0-9a-f]{1,8}$/i);
60 3         5 my $val = 0;
61 3         3 my $offset = 0;
62 3         8 foreach my $b (map { ord $_ } split //, $addr) {
  15         21  
63 15         20 $val ^= ($b&0x7f) << $offset;
64 15         40 $offset += 4;
65 15 100       28 $offset = 0 if ($offset > 20);
66             }
67 3         9 return $val & 0x3ffffff;
68             }
69              
70             1;
71              
72             __END__