File Coverage

blib/lib/AquariumHive/Simulator.pm
Criterion Covered Total %
statement 19 92 20.6
branch 0 24 0.0
condition 0 12 0.0
subroutine 7 23 30.4
pod 0 9 0.0
total 26 160 16.2


line stmt bran cond sub pod time code
1             package AquariumHive::Simulator;
2             BEGIN {
3 1     1   629 $AquariumHive::Simulator::AUTHORITY = 'cpan:GETTY';
4             }
5             $AquariumHive::Simulator::VERSION = '0.002';
6 1     1   4 use Moo;
  1         1  
  1         4  
7 1     1   7222 use AnyEvent::Handle;
  1         23343  
  1         30  
8 1     1   6 use AnyEvent::Util 'portable_socketpair';
  1         1  
  1         38  
9 1     1   515 use HiveJSO;
  1         16531  
  1         41  
10 1     1   1235 use DDP;
  1         28435  
  1         9  
11 1     1   380 use AquariumHive::State;
  1         3  
  1         892  
12              
13             sub BUILD {
14 0     0 0   my ( $self ) = @_;
15 0           $self->handle;
16 0           $self->pulse;
17             }
18              
19             has _portable_socketpair => (
20             is => 'lazy',
21             init_arg => undef,
22             );
23              
24             sub _build__portable_socketpair {
25 0     0     my ($fh1, $fh2) = portable_socketpair;
26 0           return [ $fh1, $fh2 ];
27             }
28              
29             has handle => (
30             is => 'lazy',
31             init_arg => undef,
32             );
33              
34             sub _build_handle {
35 0     0     my ( $self ) = @_;
36 0           my $handle = AnyEvent::Handle->new(
37             fh => $self->_portable_socketpair->[1],
38             );
39             $handle->on_read(sub {
40             $_[0]->push_read( hivejso => sub {
41 0           my ( $handle, $data ) = @_;
42 0 0         if (ref $data eq 'HiveJSO::Error') {
43 0           p($data->error); p($data->garbage);
  0            
44 0           return;
45             }
46 0           $self->on_hivejso($data);
47 0     0     });
48 0           });
49 0           return $handle;
50             }
51              
52             has fh => (
53             is => 'lazy',
54             init_arg => undef,
55             );
56              
57             sub _build_fh {
58 0     0     my ( $self ) = @_;
59 0           return $self->_portable_socketpair->[0];
60             }
61              
62             has pulse => (
63             is => 'lazy',
64             );
65              
66             sub _build_pulse {
67 0     0     my ( $self ) = @_;
68             return AE::timer 0, 60, sub {
69 0     0     for my $no (1..2) {
70 0           for my $sensor (qw( ph orp ec temp )) {
71 0           my $attr = $sensor.$no;
72 0           my $next = 'next_'.$sensor;
73 0           my $current = $self->state->$attr;
74 0           my $new = $self->$next($current);
75 0           $self->state->$attr($new);
76             }
77             }
78 0           };
79             }
80              
81             has state => (
82             is => 'lazy',
83             init_arg => undef,
84             );
85              
86             sub _build_state {
87 0     0     my ( $self ) = @_;
88 0           return AquariumHive::State->new(
89 0           (map { 'pwm'.$_, 0 } (1..6)),
90 0           (map { 'ph'.$_, $self->next_ph } (1..2)),
91 0           (map { 'orp'.$_, $self->next_orp } (1..2)),
92 0           (map { 'ec'.$_, $self->next_ec } (1..2)),
93 0           (map { 'temp'.$_, $self->next_temp } (1..2)),
94             );
95             }
96              
97             sub hivejso_base {
98 0     0 0   return unit => 'aqhive';
99             }
100              
101             sub state_to_hivejso {
102 0     0 0   my ( $self ) = @_;
103 0           my %state = %{$self->state->data};
  0            
104 0           my @data;
105 0           for my $key (@AquariumHive::State::attributes) {
106 0           push @data, [$key, $state{$key}];
107             }
108 0           return HiveJSO->new( $self->hivejso_base, data => \@data );
109             }
110              
111             sub on_hivejso {
112 0     0 0   my ( $self, $hivejso ) = @_;
113 0 0         if ($hivejso->has_command) {
114             # "o":"data"
115 0 0         if ($hivejso->command_cmd eq 'data') {
116 0           $self->send_state;
117             }
118             # "o":["set_pwm1",100]
119 0 0         if ($hivejso->command_cmd eq 'set_pwm') {
120 0           my ( $no, $value ) = $hivejso->command_args;
121 0           my $func = 'pwm'.$no;
122 0           $self->state->$func($value);
123 0           $self->send_state;
124             }
125             }
126             }
127              
128             sub send_state {
129 0     0 0   my ( $self ) = @_;
130 0           $self->handle->push_write($self->state_to_hivejso->hivejso_short);
131             }
132              
133             sub next_temp {
134 0     0 0   my ( $self, $current ) = @_;
135 0 0         return 615 unless defined $current;
136 0           my $new = $current + (int(rand(3)) - 2);
137 0 0 0       return $self->next_temp($current) if $new > 619 || $new < 610;
138 0           return $new;
139             }
140              
141             sub next_ph {
142 0     0 0   my ( $self, $current ) = @_;
143 0 0         return 512 unless defined $current;
144 0           my $new = $current + (int(rand(5)) - 3);
145 0 0 0       return $self->next_ph($current) if $new > 525 || $new < 500;
146 0           return $new;
147             }
148              
149             sub next_orp {
150 0     0 0   my ( $self, $current ) = @_;
151 0 0         return 458 unless defined $current;
152 0           my $new = $current + (int(rand(5)) - 3);
153 0 0 0       return $self->next_orp($current) if $new > 475 || $new < 425;
154 0           return $new;
155             }
156              
157             sub next_ec {
158 0     0 0   my ( $self, $current ) = @_;
159 0 0         return 120 unless defined $current;
160 0           my $new = $current + (int(rand(5)) - 3);
161 0 0 0       return $self->next_ec($current) if $new > 140 || $new < 100;
162 0           return $new;
163             }
164              
165             1;
166              
167             __END__
168              
169             =pod
170              
171             =head1 NAME
172              
173             AquariumHive::Simulator
174              
175             =head1 VERSION
176              
177             version 0.002
178              
179             =head1 DESCRIPTION
180              
181             B<IN DEVELOPMENT, DO NOT USE YET>
182              
183             See L<http://aquariumhive.com/> for now.
184              
185             =head1 SUPPORT
186              
187             IRC
188              
189             Join #AquariumHive on irc.freenode.net. Highlight Getty for fast reaction :).
190              
191             Repository
192              
193             https://github.com/homehivelab/aquariumhive
194             Pull request and additional contributors are welcome
195              
196             Issue Tracker
197              
198             https://github.com/homehivelab/aquariumhive/issues
199              
200             =head1 AUTHOR
201              
202             Torsten Raudssus <torsten@raudss.us>
203              
204             =head1 COPYRIGHT AND LICENSE
205              
206             This software is copyright (c) 2014 by Torsten Raudssus.
207              
208             This is free software; you can redistribute it and/or modify it under
209             the same terms as the Perl 5 programming language system itself.
210              
211             =cut