File Coverage

blib/lib/App/AquariumHive/Plugin/AqHive.pm
Criterion Covered Total %
statement 17 19 89.4
branch n/a
condition n/a
subroutine 7 7 100.0
pod n/a
total 24 26 92.3


line stmt bran cond sub pod time code
1             package App::AquariumHive::Plugin::AqHive;
2             BEGIN {
3 1     1   898 $App::AquariumHive::Plugin::AqHive::AUTHORITY = 'cpan:GETTY';
4             }
5             $App::AquariumHive::Plugin::AqHive::VERSION = '0.002';
6 1     1   5 use Moo;
  1         1  
  1         6  
7 1     1   287 use App::AquariumHive::Tile;
  1         2  
  1         21  
8 1     1   3 use JSON::MaybeXS;
  1         36  
  1         50  
9 1     1   538 use utf8;
  1         8  
  1         4  
10 1         6 use Digital qw(
11             AqHive::Temp
12             AqHive::ORP
13             AqHive::EC
14             AqHive::pH
15 1     1   30 );
  1         2  
16              
17             with qw(
18             App::AquariumHive::Role
19             );
20              
21 1     1   405 use AnyEvent::JSONRPC::TCP::Client;
  0            
  0            
22              
23             has kioskd_client => (
24             is => 'rw',
25             );
26              
27             sub new_kioskd_client {
28             my ( $self ) = @_;
29             return AnyEvent::JSONRPC::TCP::Client->new(
30             host => '127.0.0.1',
31             port => 24025,
32             on_error => sub {
33             $self->kioskd_client($self->new_kioskd_client);
34             },
35             );
36             }
37              
38             our @pwm_steps = qw(
39             0 1 1 2 2 2 2 2 3 3
40             3 4 4 5 5 6 6 7 8 9
41             10 11 12 13 15 17 19 21 23 26
42             29 32 36 40 44 49 55 61 68 76
43             85 94 105 117 131 146 162 181 202 225
44             250 279 311 346 386 430 479 534 595 663
45             739 824 918 1023
46             );
47              
48             our %sensor_names_and_units = (
49             ec => [ EC => yScm => 'yS/cm' ],
50             orp => [ ORP => mV => 'mV' ],
51             temp => [ Temp => C => '°C' ],
52             ph => [ pH => pH => 'pH' ],
53             );
54              
55             has pwm_step_state => (
56             is => 'rw',
57             default => sub {{
58             1 => '0',
59             2 => '0',
60             3 => '0',
61             4 => '0',
62             5 => '0',
63             6 => '0',
64             }},
65             );
66              
67             sub pwm_to_step {
68             my ( $self, $pwm ) = @_;
69             return 63 if $pwm >= 1023;
70             my $step;
71             for (0..62) {
72             $step = $_ if $pwm_steps[$_] <= $pwm;
73             }
74             return $step;
75             }
76              
77             sub BUILD {
78             my ( $self ) = @_;
79              
80             $self->kioskd_client($self->new_kioskd_client);
81              
82             if ($self->app->simulation) {
83             $self->web_mount( 'simulator', sub {
84             return [ 200, [ "Content-Type" => "application/json" ], [encode_json({
85             html => <<__HTML__,
86             <h1 class="text-center">AquariumHive 1 Simulationseinstellungen</h1>
87             <hr/>
88              
89             __HTML__
90             })] ];
91             });
92              
93             $self->add_tile( 'simulator' => App::AquariumHive::Tile->new(
94             id => 'simulator',
95             bgcolor => 'orange',
96             content => <<"__HTML__",
97              
98             <div class="large">
99             <div class="fattext">AqHive 1</div>
100             <div class="fattext">Simulator</div>
101             </div>
102              
103             __HTML__
104             js => <<"__JS__",
105              
106             \$('#simulator').click(function(){
107             call_app('simulator');
108             });
109              
110             __JS__
111             ));
112             }
113              
114             $self->on_data(sub {
115             my ( $app, $data ) = @_;
116             my %aqhive;
117             for my $d (@{$data}) {
118             my ( $key, $val ) = @{$d};
119             my ( $sensor, $no ) = $key =~ m/^([a-zA-Z]+)(\d+)$/;
120             if ($sensor_names_and_units{$sensor}) {
121             my ( $name, $func, $unit ) = @{$sensor_names_and_units{$sensor}};
122             $aqhive{$key} = sprintf('%.1f',input( 'aqhive_'.$sensor, $val )->$func);
123             } elsif ($sensor eq 'pwm') {
124             $self->pwm_step_state->{$no} = $self->pwm_to_step($val);
125             $aqhive{$key} = ( $self->pwm_step_state->{$no} == 63
126             ? 'MAX' : $self->pwm_step_state->{$no} );
127             }
128             }
129             $app->send( aqhive => \%aqhive );
130             for my $no (1..2) {
131             $self->kioskd_client->call( Update => {
132             name => 'values'.$no,
133             type => 'text',
134             text => join(' ',(
135             $aqhive{'ph'.$no},'ph',
136             $aqhive{'orp'.$no},'mV',
137             $aqhive{'temp'.$no},'C',
138             $aqhive{'ec'.$no},'yS/cm',
139             )),
140             x => ( 6 + ( 30 * ( $no - 1 ) ) ),
141             y => 6,
142             w => 1000,
143             h => 30,
144             font_path => '/opt/kioskd/fonts/din1451alt.ttf',
145             font_point_size => 24,
146             colour => [255, 255, 255, 255],
147             })->cb(sub {
148             eval { $_[0]->recv };
149             });
150             }
151             });
152              
153             $self->on_socketio( aqhive => sub {
154             my ( $app, $data ) = @_;
155             if ($data->{cmd}) {
156             $app->command_aqhive($data->{cmd});
157             }
158             });
159              
160             for my $no (1..2) {
161             my $app = 'aqhive_sensors'.$no;
162             $self->web_mount( $app, sub {
163             return [ 200, [ "Content-Type" => "application/json" ], [encode_json({
164             html => <<__HTML__,
165             <h1 class="text-center">AquariumHive 1 Sensors $no</h1>
166             <hr/>
167              
168             __HTML__
169             })] ];
170             });
171             for my $sensor (qw( temp ph orp ec )) {
172             my $id = 'aqhive_'.$sensor.$no;
173             my ( $name, $func, $unit ) = @{$sensor_names_and_units{$sensor}};
174             $self->add_tile( 'aqhive_'.$sensor.$no => App::AquariumHive::Tile->new(
175             id => $id,
176             bgcolor => 'lightTeal',
177             content => <<"__HTML__",
178              
179             <div class="large">
180             <div>AqHive 1</div>
181             <div>$name $no</div>
182             <div><span class="fattext" id="aqhive_val_$sensor$no"></span> $unit</div>
183             </div>
184              
185             __HTML__
186             js => <<"__JS__",
187              
188             socket.on('aqhive', function(aqhive){
189             \$('#aqhive_val_$sensor$no').text(aqhive.$sensor$no);
190             });
191              
192             \$('#$id').click(function(){
193             call_app('$app');
194             });
195              
196             __JS__
197             ));
198             }
199             }
200              
201             for my $pwm (1..6) {
202             $self->on_socketio ( 'pwm'.$pwm, sub {
203             my ( $app, $data ) = @_;
204             if ($data->{cmd}) {
205             my $cmd = $data->{cmd};
206             if ($cmd eq 'next') {
207             my $next = $self->pwm_step_state->{$pwm} + 1;
208             $next = 63 if $next > 63;
209             $app->command_aqhive( 'set_pwm', "".$pwm, "".$pwm_steps[$next]);
210             } elsif ($cmd eq 'prev') {
211             my $prev = $self->pwm_step_state->{$pwm} - 1;
212             $prev = 0 if $prev < 0;
213             $app->command_aqhive( 'set_pwm', "".$pwm, "".$pwm_steps[$prev]);
214             } elsif ($cmd eq 'first') {
215             $app->command_aqhive( 'set_pwm', "".$pwm, "0");
216             } elsif ($cmd eq 'last') {
217             $app->command_aqhive( 'set_pwm', "".$pwm, "1023");
218             }
219             }
220             });
221             $self->add_tile( 'aqhive_pwm'.$pwm, App::AquariumHive::Tile->new(
222             id => 'aqhive_pwm'.$pwm,
223             bgcolor => 'cyan',
224             class => 'pwm-tile',
225             content => <<"__HTML__",
226              
227             <a id="aqhive_first_pwm$pwm" class="button">
228             <i class="icon-first-2"></i>
229             </a>
230             <a id="aqhive_prev_pwm$pwm" class="button">
231             <i class="icon-previous"></i>
232             </a>
233             <div>AqHive 1</div>
234             <div>PWM $pwm</div>
235             <div id="aqhive_val_pwm$pwm">...</div>
236             <a id="aqhive_next_pwm$pwm" class="button">
237             <i class="icon-next"></i>
238             </a>
239             <a id="aqhive_last_pwm$pwm" class="button">
240             <i class="icon-last-2"></i>
241             </a>
242              
243             __HTML__
244             js => <<"__JS__",
245              
246             socket.on('aqhive', function(aqhive){
247             \$('#aqhive_val_pwm$pwm').text(aqhive.pwm$pwm);
248             });
249              
250             \$('#aqhive_prev_pwm$pwm').click(function(){
251             socket.emit('pwm$pwm',{ cmd: 'prev' });
252             });
253              
254             \$('#aqhive_next_pwm$pwm').click(function(){
255             socket.emit('pwm$pwm',{ cmd: 'next' });
256             });
257              
258             \$('#aqhive_first_pwm$pwm').click(function(){
259             socket.emit('pwm$pwm',{ cmd: 'first' });
260             });
261              
262             \$('#aqhive_last_pwm$pwm').click(function(){
263             socket.emit('pwm$pwm',{ cmd: 'last' });
264             });
265              
266             __JS__
267             ));
268             }
269              
270             }
271              
272             1;
273              
274             __END__
275              
276             =pod
277              
278             =head1 NAME
279              
280             App::AquariumHive::Plugin::AqHive
281              
282             =head1 VERSION
283              
284             version 0.002
285              
286             =head1 DESCRIPTION
287              
288             B<IN DEVELOPMENT, DO NOT USE YET>
289              
290             See L<http://aquariumhive.com/> for now.
291              
292             =head1 SUPPORT
293              
294             IRC
295              
296             Join #AquariumHive on irc.freenode.net. Highlight Getty for fast reaction :).
297              
298             Repository
299              
300             https://github.com/homehivelab/aquariumhive
301             Pull request and additional contributors are welcome
302              
303             Issue Tracker
304              
305             https://github.com/homehivelab/aquariumhive/issues
306              
307             =head1 AUTHOR
308              
309             Torsten Raudssus <torsten@raudss.us>
310              
311             =head1 COPYRIGHT AND LICENSE
312              
313             This software is copyright (c) 2014 by Torsten Raudssus.
314              
315             This is free software; you can redistribute it and/or modify it under
316             the same terms as the Perl 5 programming language system itself.
317              
318             =cut