File Coverage

blib/lib/Device/Neurio.pm
Criterion Covered Total %
statement 40 293 13.6
branch 1 142 0.7
condition 0 33 0.0
subroutine 14 30 46.6
pod 1 15 6.6
total 56 513 10.9


line stmt bran cond sub pod time code
1             package Device::Neurio;
2              
3 1     1   579 use warnings;
  1         1  
  1         35  
4 1     1   3 use strict;
  1         1  
  1         25  
5 1     1   20 use 5.006_001;
  1         11  
  1         135  
6              
7             require Exporter;
8              
9             our @ISA = qw(Exporter);
10              
11             # Items to export into callers namespace by default. Note: do not export
12             # names by default without a very good reason. Use EXPORT_OK instead.
13             # Do not simply export all your public functions/methods/constants.
14              
15             # This allows declaration use Device::NeurioTools ':all';
16             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
17             # will save memory.
18              
19             our %EXPORT_TAGS = ( 'all' => [ qw(
20             new connect fetch_Samples_Recent_Live fetch_Samples_Last_Live fetch_Samples
21             fetch_Samples_Full fetch_Stats_Energy
22             ) ] );
23              
24             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
25             our @EXPORT = qw( $EXPORT_TAGS{'all'});
26              
27             BEGIN
28             {
29 1 50   1   2866 if ($^O eq "MSWin32"){
30 1     1   2587 use LWP::UserAgent;
  1         41691  
  1         50  
31 1     1   13 use Time::Local;
  1         2  
  1         82  
32 1     1   5 use JSON qw(decode_json encode_json);
  1         2  
  1         9  
33 1     1   746 use MIME::Base64 (qw(encode_base64));
  1         692  
  1         60  
34 1     1   1607 use Data::Dumper;
  1         6351  
  1         78  
35             } else {
36 1     1   7 use LWP::UserAgent;
  1         1  
  1         17  
37 1     1   4 use Time::Local;
  1         1  
  1         43  
38 1     1   4 use JSON qw(decode_json encode_json);
  1         1  
  1         7  
39 1     1   121 use MIME::Base64 (qw(encode_base64));
  1         1  
  1         36  
40 1     1   4 use Data::Dumper;
  1         1  
  1         28  
41             }
42             }
43              
44              
45             =head1 NAME
46              
47             Device::Neurio - Methods for wrapping the Neurio API calls so that they are
48             accessible via Perl
49              
50             =head1 VERSION
51              
52             Version 0.14
53              
54             =cut
55              
56             our $VERSION = '0.14';
57              
58             #******************************************************************************
59             =head1 SYNOPSIS
60              
61             This module provides a Perl interface to a Neurio sensor via the following
62             methods:
63             - new
64             - connect
65             - fetch_Samples
66             - fetch_Samples_Full
67             - fetch_Samples_Last_Live
68             - fetch_Samples_Recent_Live
69             - fetch_Stats_Energy
70             - fetch_Appliances
71             - fetch_Appliances_Events
72             - fetch_Appliances_Specific
73             - fetch_Appliances_Stats
74              
75             Please note that in order to use the 'Samples' methods in this module you will
76             require three parameters (key, secret, sensor_id) as well as an Energy Aware
77             Neurio sensor installed in your house. In order to use the 'Appliances'
78             methods, you will also require another parameter (location_id). This information
79             can be obtained from the Neurio developpers website.
80              
81             The module is written entirely in Perl and was developped on Raspbian Linux.
82              
83             All date/time values are specified using ISO8601 format (yyyy-mm-ddThh:mm:ssZ)
84              
85             =head1 SAMPLE CODE
86              
87             use Device::Neurio;
88              
89             $my_Neurio = Device::Neurio->new($key,$secret,$sensor_id,$debug);
90              
91             $my_Neurio->connect();
92            
93             $data = $my_Neurio->fetch_Samples_Last_Live();
94             print $data->{'consumptionPower'}
95              
96             $data = $my_Neurio->fetch_Samples_Recent_Live("2014-06-18T19:20:21Z");
97             print $data->[0]->{'consumptionPower'}
98              
99             undef $my_Neurio;
100              
101              
102             =head2 EXPORT
103              
104             All by default.
105              
106              
107             =head1 SUBROUTINES/METHODS
108              
109             =head2 new - the constructor for a Neurio object
110              
111             Creates a new instance which will be able to fetch data from a unique Neurio
112             sensor. All three parameters are required and can be obtained from the
113             Neurio developpers website.
114              
115             my $Neurio = Device::Neurio->new($key, $secret, $sensor_id, $debug);
116              
117             This method accepts the following parameters:
118             - $key : unique key for the account - Required
119             - $secret : secret key for the account - Required
120             - $sensor_id : sensor ID connected to the account - Required
121             - $debug : turn on debug messages - Optional
122              
123             Returns a Neurio object if successful.
124             Returns 0 on failure
125            
126             =cut
127              
128             sub new {
129 0     0 1   my $class = shift;
130 0           my $self;
131            
132 0           $self->{'ua'} = LWP::UserAgent->new();
133 0           $self->{'key'} = shift;
134 0           $self->{'secret'} = shift;
135 0           $self->{'sensor_id'} = shift;
136 0           $self->{'debug'} = shift;
137 0           $self->{'base64'} = encode_base64($self->{'key'}.":".$self->{'secret'});
138 0           chomp($self->{'base64'});
139            
140 0 0         if (!defined $self->{'debug'}) {
141 0           $self->{'debug'} = 0;
142             }
143            
144 0 0 0       if ((!defined $self->{'key'}) || (!defined $self->{'secret'}) || (!defined $self->{'sensor_id'})) {
      0        
145 0 0         print "\nNeurio->new(): Key, Secret and Sensor_ID are REQUIRED parameters\n" if ($self->{'debug'});
146 0           $self->{'last_code'} = '0';
147 0           $self->{'last_reason'} = 'Neurio->new(): Key, Secret and Sensor_ID are REQUIRED parameters';
148 0           return 0;
149             }
150            
151             # $self->{'base_url'} = "https://api-staging.neur.io/v1";
152 0           $self->{'base_url'} = "https://api.neur.io/v1";
153 0           $self->{'Samples_Recent_Live_url'} = $self->{'base_url'}."/samples/live?sensorId=".$self->{'sensor_id'};
154 0           $self->{'Samples_Last_Live_url'} = $self->{'base_url'}."/samples/live/last?sensorId=".$self->{'sensor_id'};
155 0           $self->{'Samples_url'} = $self->{'base_url'}."/samples?sensorId=".$self->{'sensor_id'};
156 0           $self->{'Samples_Full_url'} = $self->{'base_url'}."/samples/full?sensorId=".$self->{'sensor_id'};
157 0           $self->{'Stats_Energy_url'} = $self->{'base_url'}."/samples/stats?sensorId=".$self->{'sensor_id'};
158 0           $self->{'Appliances_url'} = $self->{'base_url'}."/appliances";
159 0           $self->{'Appliances_Specific_url'} = $self->{'base_url'}."/appliances/";
160 0           $self->{'Appliances_Stats_url'} = $self->{'base_url'}."/appliances/stats";
161 0           $self->{'Appliances_Events_url'} = $self->{'base_url'}."/appliances/events";
162 0           $self->{'last_code'} = '';
163 0           $self->{'last_reason'} = '';
164            
165 0           bless $self, $class;
166            
167 0           return $self;
168             }
169              
170              
171             #******************************************************************************
172             =head2 connect - open a secure connection to the Neurio server
173              
174             Opens a secure connection via HTTPS to the Neurio server which provides
175             access to a set of API commands to access the sensor data.
176            
177             An optional location ID can be given. This is only required if calls
178             will be made to the 'Appliance' methods. Calls to the 'Samples'
179             methods do not require that a location ID be set. If a location_id is not
180             specified at connection, then it must be specified when using the 'Appliance'
181             methods.
182            
183             A location ID can be acquired from the Neurio developpers web site
184              
185             $Neurio->connect($location_id);
186            
187             This method accepts the following parameter:
188             - $location_id : unique location id - Optional
189            
190             Returns 1 on success
191             Returns 0 on failure
192            
193             =cut
194              
195             sub connect {
196 0     0 0   my ($self,$location_id) = @_;
197 0           my $access_token = '';
198            
199 0 0         if (defined $location_id) {
200 0           $self->{'location_id'} = $location_id;
201             } else {
202 0           $self->{'location_id'} = '';
203             }
204              
205             # Submit request for authentiaction token.
206 0           my $response = $self->{'ua'}->post('https://api-staging.neur.io/v1/oauth2/token',
207             { basic_authentication => $self->{'base64'},
208             Content_Type => 'application/x-www-form-urlencoded',
209             grant_type => 'client_credentials',
210             client_id => $self->{'key'},
211             client_secret => $self->{'secret'},
212             }
213             );
214            
215 0 0         if($response->is_success) {
216 0           my $return = $response->content;
217 0           $return =~ /\"access_token\":\"(.*)\"\,\"token_type\"/;
218 0           $self->{'access_token'} = $1;
219 0           return 1;
220             } else {
221 0 0         print "\nDevice::Neurio->connect(): Failed to connect.\n" if ($self->{'debug'});
222 0 0         print $response->content."\n\n" if ($self->{'debug'});
223 0           $self->{'last_code'} = '0';
224 0           $self->{'last_reason'} = 'Neurio->new(): Device::Neurio->connect(): Failed to connect';
225 0           return 0;
226             }
227             }
228              
229              
230             #******************************************************************************
231             =head2 fetch_Samples_Recent_Live - Fetch recent sensor samples
232              
233             Retrieves recent sensor readings from the Neurio server.
234             The values represent the sum of all phases.
235              
236             $Neurio->fetch_Samples_Recent_Live($last);
237            
238             This method accepts the following parameters:
239             $last - time of last sample received specified using ISO8601
240             format (yyyy-mm-ddThh:mm:ssZ) - Optional
241            
242             If no value is specified for $last, a default of 2 minutes is used.
243            
244             Returns an array of Perl data structures on success
245             $VAR1 = [
246             {
247             'generationEnergy' => 3716166644,
248             'timestamp' => '2014-06-24T11:08:00.000Z',
249             'consumptionEnergy' => 6762651207,
250             'generationPower' => 564,
251             'consumptionPower' => 821
252             },
253             ...
254             ]
255             Returns 0 on failure
256            
257             =cut
258              
259             sub fetch_Samples_Recent_Live {
260 0     0 0   my ($self,$last) = @_;
261 0           my $url;
262              
263             # if optional parameter is defined, add it
264 0 0         if (defined $last) {
265 0           $url = $self->{'Samples_Recent_Live_url'}."&last=$last";
266             } else {
267 0           $url = $self->{'Samples_Recent_Live_url'};
268             }
269 0           return $self->__process_get($url);
270             }
271              
272              
273             #******************************************************************************
274             =head2 fetch_Samples_Last_Live - Fetch the last live sensor sample
275              
276             Retrieves the last live sensor reading from the Neurio server.
277             The values represent the sum of all phases.
278              
279             $Neurio->fetch_Samples_Last_Live();
280              
281             This method accepts no parameters
282            
283             Returns a Perl data structure on success:
284             $VAR1 = {
285             'generationEnergy' => 3716027450,
286             'timestamp' => '2014-06-24T11:03:43.000Z',
287             'consumptionEnergy' => 6762445671,
288             'generationPower' => 542,
289             'consumptionPower' => 800
290             };
291             Returns 0 on failure
292            
293             =cut
294              
295             sub fetch_Samples_Last_Live {
296 0     0 0   my $self = shift;
297 0           my $url = $self->{'Samples_Last_Live_url'};
298 0           return $self->__process_get($url);
299             }
300              
301              
302             #******************************************************************************
303             =head2 fetch_Samples - Fetch sensor samples from the Neurio server
304              
305             Retrieves sensor readings within the parameters specified.
306             The values represent the sum of all phases.
307              
308             $Neurio->fetch_Samples($start,$granularity,$end,$frequency,$perPage,$page);
309              
310             This method accepts the following parameters:
311             - $start : yyyy-mm-ddThh:mm:ssZ - Required
312             specified using ISO8601 format
313             - $granularity : seconds|minutes|hours|days - Required
314             - $end : yyyy-mm-ddThh:mm:ssZ - Optional
315             specified using ISO8601 format
316             - $frequency : if the granularity is specified as 'minutes', then the
317             frequency must be a multiple of 5 - Optional
318             - $perPage : number of results per page - Optional
319             - $page : page number to return - Optional
320            
321             Returns an array of Perl data structures on success
322             $VAR1 = [
323             {
324             'generationEnergy' => 3568948578,
325             'timestamp' => '2014-06-21T19:00:00.000Z',
326             'consumptionEnergy' => 6487889194,
327             'generationPower' => 98,
328             'consumptionPower' => 240
329             },
330             ...
331             ]
332             Returns 0 on failure
333            
334             =cut
335              
336             sub fetch_Samples {
337 0     0 0   my ($self,$start,$granularity,$end,$frequency,$perPage,$page) = @_;
338            
339             # make sure $start and $granularity are defined
340 0 0 0       if ((!defined $start) || (!defined $granularity)) {
341 0 0         print "\nNeurio->fetch_Samples_Full(): \$start and \$granularity are required parameters\n\n" if ($self->{'debug'});
342 0           $self->{'last_code'} = '0';
343 0           $self->{'last_reason'} = 'Neurio->fetch_Samples_Full(): \$start and \$granularity are required parameters';
344 0           return 0;
345             }
346             # make sure that frequqncy is a multiple of 5 if $granularity is in minutes
347 0 0 0       if (($granularity eq 'minutes') and defined $frequency) {
348 0 0         if (eval($frequency%5) != 0) {
349 0 0         print "\nNeurio->fetch_Samples(): Only multiples of 5 are supported for \$frequency when \$granularity is in minutes\n\n" if ($self->{'debug'});
350 0           $self->{'last_code'} = '0';
351 0           $self->{'last_reason'} = 'Neurio->fetch_Samples(): Only multiples of 5 are supported for \$frequency when \$granularity is in minutes';
352 0           return 0;
353             }
354             }
355             # make sure $granularity is one of the correct values
356 0 0         if (!($granularity =~ /[seconds|minutes|hours|days]/)) {
357 0 0         print "\nNeurio->fetch_Samples_Full(): Only values of 'seconds, minutes, hours or days' are supported for \$granularity\n\n" if ($self->{'debug'});
358 0           $self->{'last_code'} = '0';
359 0           $self->{'last_reason'} = 'Neurio->fetch_Samples_Full(): Only values of "seconds, minutes, hours or days" are supported for \$granularity';
360 0           return 0;
361             }
362            
363 0           my $url = $self->{'Samples_url'}."&start=$start&granularity=$granularity";
364            
365             # if optional parameter is defined, add it
366 0 0         if (defined $end) {
367 0           $url = $url . "&end=$end";
368             }
369             # if optional parameter is defined, add it
370 0 0         if (defined $frequency) {
371 0           $url = $url . "&frequency=$frequency";
372             }
373             # if optional parameter is defined, add it
374 0 0         if (defined $perPage) {
375 0           $url = $url . "&perPage=$perPage";
376             }
377             # if optional parameter is defined, add it
378 0 0         if (defined $page) {
379 0           $url = $url . "&page=$page";
380             }
381            
382 0           return $self->__process_get($url);
383             }
384              
385              
386             #******************************************************************************
387             =head2 fetch_Samples_Full - Fetches full samples for all phases
388              
389             Retrieves full sensor readings including data for each individual phase within
390             the parameters specified.
391              
392             $Neurio->fetch_Samples_Full($start,$granularity,$end,$frequency,$perPage,$page);
393              
394             This method accepts the following parameters:
395             - $start : yyyy-mm-ddThh:mm:ssZ - Required
396             specified using ISO8601 format
397             - $granularity : seconds|minutes|hours|days - Required
398             - $end : yyyy-mm-ddThh:mm:ssZ - Optional
399             specified using ISO8601 format
400             - $frequency : an integer - Optional
401             - $perPage : number of results per page - Optional
402             - $page : page number to return - Optional
403            
404             Returns an array of Perl data structures on success
405             [
406             {
407             'timestamp' => '2014-06-16T19:20:21.000Z',
408             'channelSamples' => [
409             {
410             'voltage' => '123.19',
411             'power' => 129,
412             'name' => '1',
413             'energyExported' => 27,
414             'channelType' => 'phase_a',
415             'energyImported' => 2682910899,
416             'reactivePower' => 41
417             },
418             {
419             'voltage' => '123.94',
420             'power' => 199,
421             'name' => '2',
422             'energyExported' => 6,
423             'channelType' => 'phase_b',
424             'energyImported' => 3296564362,
425             'reactivePower' => -45
426             },
427             {
428             'voltage' => '123.57',
429             'power' => 327,
430             'name' => '3',
431             'energyExported' => 10,
432             'channelType' => 'consumption',
433             'energyImported' => 5979475235,
434             'reactivePower' => -4
435             }
436             ]
437             },
438             ...
439             ]
440             Returns 0 on failure
441            
442             =cut
443              
444             sub fetch_Samples_Full {
445 0     0 0   my ($self,$start,$granularity,$end,$frequency,$perPage,$page) = @_;
446            
447             # make sure $start and $granularity are defined
448 0 0 0       if ((!defined $start) || (!defined $granularity)) {
449 0 0         print "\nNeurio->fetch_Samples_Full(): \$start and \$granularity are required parameters\n\n" if ($self->{'debug'});
450 0           $self->{'last_code'} = '0';
451 0           $self->{'last_reason'} = 'Neurio->fetch_Samples_Full(): \$start and \$granularity are required parameters';
452 0           return 0;
453             }
454             # make sure $granularity is one of the correct values
455 0 0         if (!($granularity =~ /[seconds|minutes|hours|days]/)) {
456 0 0         print "\nNeurio->fetch_Samples_Full(): Found \$granularity of $granularity\nOnly values of 'seconds, minutes, hours or days' are supported for \$granularity\n\n" if ($self->{'debug'});
457 0           $self->{'last_code'} = '0';
458 0           $self->{'last_reason'} = 'Neurio->fetch_Samples_Full(): Only values of "seconds, minutes, hours or days" are supported for \$granularity';
459 0           return 0;
460             }
461            
462 0           my $url = $self->{'Samples_Full_url'}."&start=$start&granularity=$granularity";
463            
464             # if optional parameter is defined, add it
465 0 0         if (defined $end) {
466 0           $url = $url . "&end=$end";
467             }
468             # if optional parameter is defined, add it
469 0 0         if (defined $frequency) {
470 0           $url = $url . "&frequency=$frequency";
471             }
472             # if optional parameter is defined, add it
473 0 0         if (defined $perPage) {
474 0           $url = $url . "&perPage=$perPage";
475             }
476             # if optional parameter is defined, add it
477 0 0         if (defined $page) {
478 0           $url = $url . "&page=$page";
479             }
480            
481 0           return $self->__process_get($url);
482             }
483              
484              
485             #******************************************************************************
486             =head2 fetch_Stats_Energy - Fetches energy statistics
487              
488             Retrieves energy statistics within the parameters specified.
489             The values represent the sum of all phases.
490              
491             $Neurio->fetch_Stats_Energy($start,$granularity,$end,$frequency,$perPage,$page);
492              
493             This method accepts the following parameters:
494             - $start : yyyy-mm-ddThh:mm:ssZ - Required
495             specified using ISO8601 format
496             - $granularity : minutes|hours|days|months - Required
497             - $end : yyyy-mm-ddThh:mm:ssZ - Optional
498             specified using ISO8601 format
499             - $frequency : if the granularity is specified as 'minutes', then the
500             frequency must be a multiple of 5 - Optional
501             - $perPage : number of results per page - Optional
502             - $page : page number to return - Optional
503            
504             Returns a Perl data structure containing all the raw data
505             Returns 0 on failure
506            
507             =cut
508              
509             sub fetch_Stats_Energy {
510 0     0 0   my ($self,$start,$granularity,$end,$frequency,$perPage,$page) = @_;
511              
512             # make sure $start and $granularity are defined
513 0 0 0       if ((!defined $start) || (!defined $granularity)) {
514 0 0         print "\nNeurio->fetch_Stats_Energy(): \$start and \$granularity are required parameters\n\n" if ($self->{'debug'});
515 0           $self->{'last_code'} = '0';
516 0           $self->{'last_reason'} = 'Neurio->fetch_Stats_Energy(): \$start and \$granularity are required parameters';
517 0           return 0;
518             }
519             # make sure that frequqncy is a multiple of 5 if $granularity is in minutes
520 0 0 0       if (($granularity eq 'minutes') and defined $frequency) {
521 0 0         if (eval($frequency%5) != 0) {
522 0 0         print "\nNeurio->fetch_Stats_Energy(): Only multiples of 5 are supported for \$frequency when \$granularity is in minutes\n\n" if ($self->{'debug'});
523 0           $self->{'last_code'} = '0';
524 0           $self->{'last_reason'} = 'Neurio->fetch_Stats_Energy(): Only multiples of 5 are supported for \$frequency when \$granularity is in minutes';
525 0           return 0;
526             }
527             }
528             # make sure $granularity is one of the correct values
529 0 0         if (!($granularity ~~ ['minutes','hours','days','months'])) {
530 0 0         print "\nNeurio->fetch_Stats_Energy(): Only values of 'minutes, hours, days or months' are supported for \$granularity\n\n" if ($self->{'debug'});
531 0           $self->{'last_code'} = '0';
532 0           $self->{'last_reason'} = 'Neurio->fetch_Stats_Energy(): Only values of "minutes, hours, days or months" are supported for \$granularity';
533 0           return 0;
534             }
535            
536 0           my $url = $self->{'Stats_Energy_url'}."&start=$start&granularity=$granularity";
537            
538             # if optional parameter is defined, add it
539 0 0         if (defined $end) {
540 0           $url = $url . "&end=$end";
541             }
542             # if optional parameter is defined, add it
543 0 0         if (defined $frequency) {
544 0           $url = $url . "&frequency=$frequency";
545             }
546             # if optional parameter is defined, add it
547 0 0         if (defined $perPage) {
548 0           $url = $url . "&perPage=$perPage";
549             }
550             # if optional parameter is defined, add it
551 0 0         if (defined $page) {
552 0           $url = $url . "&page=$page";
553             }
554            
555 0           return $self->__process_get($url);
556             }
557              
558              
559             #******************************************************************************
560             =head2 fetch_Appliances - Fetch the appliances for a specific location
561              
562             Retrieves the appliances added for a specific location.
563            
564             The location_id is an optional parameter because it can be specified when
565             connecting. If it is specified below, then this will over-ride the location
566             ID set when connecting, but for this function call only.
567              
568             $Neurio->fetch_Appliances($location_id);
569              
570             This method accepts the following parameters:
571             - $location_id : id of a location - Optional
572            
573             Returns an array of Perl data structures on success
574             $VAR1 = [
575             {
576             'locationId' => 'xxxxxxxxxxxxxxx',
577             'name' => 'lighting_appliance',
578             'id' => 'yyyyyyyyyyyyyyyyy',
579             'label' => 'Range Light on Medium',
580             'tags' => []
581             },
582             {
583             'locationId' => 'xxxxxxxxxxxxxxx-3',
584             'name' => 'refrigerator',
585             'id' => 'zzzzzzzzzzzzzzzz',
586             'label' => '',
587             'tags' => []
588             },
589             ....
590             ]
591             Returns 0 on failure
592            
593             =cut
594              
595             sub fetch_Appliances {
596 0     0 0   my ($self,$location_id) = @_;
597            
598             # check if $location_id is defined
599 0 0         if (!defined $location_id) {
600 0 0         if (!defined $self->{'location_id'}) {
601 0 0         print "\nNeurio->fetch_Appliances(): \$location_id is a required parameter\n\n" if ($self->{'debug'});
602 0           $self->{'last_code'} = '0';
603 0           $self->{'last_reason'} = 'Neurio->fetch_Appliances(): \$location_id is a required parameters';
604 0           return 0;
605             } else {
606 0           $location_id = $self->{'location_id'};
607             }
608             }
609 0           my $url = $self->{'Appliances_url'}."?locationId=$location_id";
610              
611 0           return $self->__process_get($url);
612             }
613              
614              
615             #******************************************************************************
616             =head2 fetch_Appliances_Specific - Fetch information about a specific appliance
617              
618             Retrieves information about a specific appliance.
619            
620             The applicance_id parameter is determined by using the fetch_Appliance method
621             which returns a list of appliances with their IDs
622              
623             $Neurio->fetch_Appliances_Specific($appliance_id);
624              
625             This method accepts the following parameters:
626             - $appliance_id : id of the appliance - Required
627            
628             Returns a Perl data structure on success:
629             $VAR1 = {
630             'locationId' => 'xxxxxxxxxxxxx,
631             'name' => 'lighting_appliance',
632             'id' => 'yyyyyyyyyyyyyyy',
633             'label' => 'Range Light on Medium',
634             'tags' => []
635             };
636             Returns 0 on failure
637            
638             =cut
639              
640             sub fetch_Appliances_Specific {
641 0     0 0   my ($self,$appliance_id) = @_;
642            
643             # make sure $id is defined
644 0 0         if (!defined $appliance_id) {
645 0 0         print "\nNeurio->fetch_Appliances_Specific(): \$appliance_id is a required parameter\n\n" if ($self->{'debug'});
646 0           $self->{'last_code'} = '0';
647 0           $self->{'last_reason'} = 'Neurio->fetch_Appliances_Specific(): \$appliance_id is a required parameters';
648 0           return 0;
649             }
650              
651 0           my $url = $self->{'Appliances_Specific_url'}.$appliance_id;
652            
653 0           return $self->__process_get($url);
654             }
655              
656              
657             #******************************************************************************
658             =head2 fetch_Appliances_Stats - Fetch usage data for a given appliance
659              
660             Retrieves usage data for a specific appliance at a specific location.
661            
662             The applicance_id parameter is determined by using the fetch_Appliance method
663             which returns a list of appliances with their IDs
664              
665             $Neurio->fetch_Appliances_Stats($location_id,$appliance_id,$start,$granularity,$end,$frequency,$perPage,$page);
666              
667             This method accepts the following parameters:
668             - $location_Id : id of a location - Required
669             - $appliance_id : id of the appliance - Required
670             - $start : yyyy-mm-ddThh:mm:ssZ - Required
671             specified using ISO8601 format
672             - $granularity : seconds|minutes|hours|days - Required
673             - $end : yyyy-mm-ddThh:mm:ssZ - Required
674             specified using ISO8601 format
675             - $frequency : an integer - Required
676             - $perPage : number of results per page - Optional
677             - $page : page number to return - Optional
678            
679             Returns an array of Perl data structures on success
680             $VAR1 = [
681             {
682             'energy' => 152927,
683             'averagePower' => '110',
684             'timeOn' => 1398,
685             'guesses' => {},
686             'end' => '2014-09-05T14:00:00.000Z',
687             'lastEvent' => {
688             'energy' => 74124,
689             'averagePower' => '109',
690             'guesses' => {},
691             'end' => '2014-09-05T13:50:44.055Z',
692             'groupIds' => [
693             'aaaaaaaaaaaaaaaaa'
694             ],
695             'id' => '5EGh7o8eQJuIvsdA4qMkEw',
696             'appliance' => {
697             'locationId' => 'ccccccccccccccccc-3',
698             'name' => 'refrigerator',
699             'id' => 'bbbbbbbbbbbbbbbbb',
700             'label' => '',
701             'tags' => []
702             },
703             'start' => '2014-09-05T13:39:20.115Z'
704             },
705             'groupIds' => [
706             'aaaaaaaaaaaaaaaaa'
707             ],
708             'eventCount' => 2,
709             'usagePercentage' => '2.465231',
710             'id' => 'ddddddddddddddd',
711             'appliance' => {
712             'locationId' => 'ccccccccccccccccc-3',
713             'name' => 'refrigerator',
714             'id' => 'bbbbbbbbbbbbbbbbb',
715             'label' => '',
716             'tags' => []
717             },
718             'start' => '2014-09-05T13:00:00.000Z'
719             },
720             ......
721             ]
722             Returns 0 on failure
723            
724             =cut
725              
726             sub fetch_Appliances_Stats {
727 0     0 0   my ($self,$location_id,$appliance_id,$start,$granularity,$end,$frequency,$perPage,$page) = @_;
728            
729             # make sure $location_id is defined
730 0 0         if (!defined $location_id) {
731 0 0         print "\nNeurio->fetch_Appliances_Stats(): \$location_id is a required parameter\n\n" if ($self->{'debug'});
732 0           $self->{'last_code'} = '0';
733 0           $self->{'last_reason'} = 'Neurio->fetch_Appliances_Stats(): \$location_id is a required parameters';
734 0           return 0;
735             }
736             # make sure $appliance_id is defined
737 0 0         if (!defined $appliance_id) {
738 0 0         print "\nNeurio->fetch_Appliances_Stats(): \$appliance_id is a required parameter\n\n" if ($self->{'debug'});
739 0           $self->{'last_code'} = '0';
740 0           $self->{'last_reason'} = 'Neurio->fetch_Appliances_Stats(): \$appliance_id is a required parameters';
741 0           return 0;
742             }
743             # make sure $start, $granularity, $end and $frequqncy are defined
744 0 0 0       if ((!defined $start) || (!defined $granularity) || (!defined $end) || (!defined $frequency)) {
      0        
      0        
745 0 0         print "\nNeurio->fetch_Appliances_Stats(): \$start, \$granularity, \$end and \$frequency are required parameters\n\n" if ($self->{'debug'});
746 0           $self->{'last_code'} = '0';
747 0           $self->{'last_reason'} = 'Neurio->fetch_Appliances_Stats(): \$start, \$granularity, \$end and \$frequency are required parameters';
748 0           return 0;
749             }
750             # make sure $granularity is one of the correct values
751 0 0         if (!($granularity =~ /[seconds|minutes|hours|days]/)) {
752 0 0         print "\nNeurio->fetch_Appliances_Stats(): Found \$granularity of $granularity\nOnly values of 'seconds, minutes, hours or days' are supported for \$granularity\n\n" if ($self->{'debug'});
753 0           $self->{'last_code'} = '0';
754 0           $self->{'last_reason'} = 'Neurio->fetch_Appliances_Stats(): Only values of "seconds, minutes, hours or days" are supported for \$granularity';
755 0           return 0;
756             }
757            
758 0           my $url = $self->{'Appliances_Stats_url'}."?locationId=$location_id&appliance_id=$appliance_id&start=$start&granularity=$granularity&end=$end&frequency=$frequency";
759            
760             # if optional parameter is defined, add it
761 0 0         if (defined $perPage) {
762 0           $url = $url . "&perPage=$perPage";
763             }
764             # if optional parameter is defined, add it
765 0 0         if (defined $page) {
766 0           $url = $url . "&page=$page";
767             }
768            
769 0           return $self->__process_get($url);
770             }
771              
772              
773             #******************************************************************************
774             =head2 fetch_Appliances_Events_by_Location - Fetch events for a specific location
775              
776             Retrieves events for a specific location. An event is an interval when an
777             appliance was in use.
778            
779             The applicance_id parameter can be determined by using the fetch_Appliance method
780             which returns a list of appliances with their IDs.
781            
782             The function has the following 2 possibilities for parameters:
783              
784             $Neurio->fetch_Appliances_Events_by_Location($location_id, $start,$end,$perPage,$page);
785             $Neurio->fetch_Appliances_Events_by_Location($location_id, $since,$perPage,$page);
786              
787             This method accepts the following parameters:
788             - $location_Id : id of a location - Required
789             - $start : yyyy-mm-ddThh:mm:ssZ - Required
790             specified using ISO8601 format
791             - $end : yyyy-mm-ddThh:mm:ssZ - Required
792             specified using ISO8601 format
793             - $since : yyyy-mm-ddThh:mm:ssZ - Required
794             specified using ISO8601 format
795             - $perPage : number of results per page - Optional
796             - $page : page number to return - Optional
797            
798             Returns an array of Perl data structures on success
799             [
800             {
801             "id" : "1cRsH7KQTeONMzjSuRJ2aw",
802             "createdAt" : "2014-04-21T22:28:32Z",
803             "updatedAt" : "2014-04-21T22:45:32Z",
804             "appliance" : {
805             "id" : "2SMROBfiTA6huhV7Drrm1g",
806             "name" : "television",
807             "label" : "upstairs TV",
808             "tags" : ["bedroom_television", "42 inch LED"],
809             "locationId" : "0qX7nB-8Ry2bxIMTK0EmXw"
810             },
811             "start" : "2014-04-21T05:26:10.785Z",
812             "end" : "2014-04-21T05:36:00.547Z",
813             "guesses" : {"dryer1" : 0.78, "dishwasher_2014" : 0.12},
814             "energy" : 247896,
815             "averagePower" : 122,
816             "groupIds" : [ "2pMROafiTA6huhV7Drrm1g", "4SmROBfiTA6huhV7Drrm1h" ],
817             "cycleCount" : 5,
818             "isRunning" : false
819             },
820             ...
821             ]
822             Returns 0 on failure
823            
824             =cut
825              
826             sub fetch_Appliances_Events_by_Location {
827 0     0 0   my ($self,$location_id,$start,$end,$perPage,$page) = @_;
828 0           my ($url);
829            
830             # make sure $location_id is defined
831 0 0         if (!defined $location_id) {
832 0 0         print "\nNeurio->fetch_Appliances_Events_by_Location(): \$location_id is a required parameter\n\n" if ($self->{'debug'});
833 0           $self->{'last_code'} = '0';
834 0           $self->{'last_reason'} = 'Neurio->fetch_Appliances_Events_by_Location(): \$location_id is a required parameter';
835 0           return 0;
836             }
837             # make sure $start (or $since) is defined
838 0 0         if (!defined $start) {
839 0 0         print "\nNeurio->fetch_Appliances_Events_by_Location(): \$start is a required parameter\n\n" if ($self->{'debug'});
840 0           $self->{'last_code'} = '0';
841 0           $self->{'last_reason'} = 'Neurio->fetch_Appliances_Events_by_Location(): \$start is a required parameter';
842 0           return 0;
843             }
844            
845             # check if $end is in ISO8601 format. If it is, then it is $end. If not, then $since was specified
846 0 0         if (defined $end) {
847 0 0         if (defined eval{DateTime::Format::ISO8601->parse_datetime($end)}) {
  0            
848 0           $url = $self->{'Appliances_Events_url'}."?locationId=$location_id&start=$start&end=$end";
849             } else {
850 0           $perPage = $end;
851 0           $page = $perPage;
852 0           $url = $self->{'Appliances_Events_url'}."?locationId=$location_id&since=$start";
853             }
854             } else {
855 0           $url = $self->{'Appliances_Events_url'}."?locationId=$location_id&since=$start";
856             }
857            
858             # if optional parameter is defined, add it
859 0 0         if (defined $perPage) {
860 0           $url = $url . "&perPage=$perPage";
861             }
862             # if optional parameter is defined, add it
863 0 0         if (defined $page) {
864 0           $url = $url . "&page=$page";
865             }
866              
867 0           return $self->__process_get($url);
868             }
869              
870              
871             #******************************************************************************
872             =head2 fetch_Appliances_Events_by_Appliance - Fetch events for a specific appliance
873              
874             Retrieves events for a specific appliance. An event is an interval when an
875             appliance was in use.
876            
877             The applicance_id parameter can be determined by using the fetch_Appliance method
878             which returns a list of appliances with their IDs.
879            
880             $Neurio->fetch_Appliances_Events_by_Appliance($appliance_id,$start,$end,$perPage,$page);
881              
882             This method accepts the following parameters:
883             - $appliance_id : id of the appliance - Required
884             - $start : yyyy-mm-ddThh:mm:ssZ - Required
885             specified using ISO8601 format
886             - $end : yyyy-mm-ddThh:mm:ssZ - Required
887             specified using ISO8601 format
888             - $since : yyyy-mm-ddThh:mm:ssZ - Required
889             specified using ISO8601 format
890             - $perPage : number of results per page - Optional
891             - $page : page number to return - Optional
892            
893             Returns an array of Perl data structures on success
894             [
895             {
896             "id" : "1cRsH7KQTeONMzjSuRJ2aw",
897             "createdAt" : "2014-04-21T22:28:32Z",
898             "updatedAt" : "2014-04-21T22:45:32Z",
899             "appliance" : {
900             "id" : "2SMROBfiTA6huhV7Drrm1g",
901             "name" : "television",
902             "label" : "upstairs TV",
903             "tags" : ["bedroom_television", "42 inch LED"],
904             "locationId" : "0qX7nB-8Ry2bxIMTK0EmXw"
905             },
906             "start" : "2014-04-21T05:26:10.785Z",
907             "end" : "2014-04-21T05:36:00.547Z",
908             "guesses" : {"dryer1" : 0.78, "dishwasher_2014" : 0.12},
909             "energy" : 247896,
910             "averagePower" : 122,
911             "groupIds" : [ "2pMROafiTA6huhV7Drrm1g", "4SmROBfiTA6huhV7Drrm1h" ],
912             "cycleCount" : 5,
913             "isRunning" : false
914             },
915             ...
916             ]
917             Returns 0 on failure
918            
919             =cut
920              
921             sub fetch_Appliances_Events_by_Appliance {
922 0     0 0   my ($self,$appliance_id,$start,$end,$perPage,$page) = @_;
923            
924             # make sure $appliance_id is defined
925 0 0         if (!defined $appliance_id) {
926 0 0         print "\nNeurio->fetch_Appliances_Events_by_Appliance(): \$appliance_id is a required parameter\n\n" if ($self->{'debug'});
927 0           $self->{'last_code'} = '0';
928 0           $self->{'last_reason'} = 'Neurio->fetch_Appliances_Events_by_Appliance(): \$appliance_id is a required parameters';
929 0           return 0;
930             }
931             # make sure $start and $end are defined
932 0 0 0       if ((!defined $start) || (!defined $end)) {
933 0 0         print "\nNeurio->fetch_Appliances_Events_by_Appliance(): \$start and \$end are required parameters\n\n" if ($self->{'debug'});
934 0           $self->{'last_code'} = '0';
935 0           $self->{'last_reason'} = 'Neurio->fetch_Appliances_Events_by_Appliance(): \$start and \$end are required parameters';
936 0           return 0;
937             }
938              
939 0           my $url = $self->{'Appliances_Events_url'}."?applianceId=$appliance_id&start=$start&end=$end";
940            
941             # if optional parameter is defined, add it
942 0 0         if (defined $perPage) {
943 0           $url = $url . "&perPage=$perPage";
944             }
945             # if optional parameter is defined, add it
946 0 0         if (defined $page) {
947 0           $url = $url . "&page=$page";
948             }
949            
950 0           return $self->__process_get($url);
951             }
952              
953              
954             #******************************************************************************
955             =head2 dump_Object - shows the contents of the local Neurio object
956              
957             shows the contents of the local Neurio object in human readable form
958              
959             $Neurio->dump_Object();
960              
961             This method accepts no parameters
962            
963             Returns nothing
964            
965             =cut
966              
967             sub dump_Object {
968 0     0 0   my $self = shift;
969            
970 0           print "Key : ".substr($self->{'key'}, 0,120)."\n";
971 0           print "SecretKey : ".substr($self->{'secret'}, 0,120)."\n";
972 0           print "Sensor_ID : ".substr($self->{'sensor_id'}, 0,120)."\n";
973 0           print "Location_ID : ".substr($self->{'location_id'}, 0,120)."\n";
974 0           print "Access_token : ".substr($self->{'access_token'}, 0,120)."\n";
975 0           print "Base 64 : ".substr($self->{'base64'}, 0,120)."\n";
976 0           print "Base URL : ".substr($self->{'base_url'}, 0,120)."\n";
977 0           print "Samples_Recent_Live URL : ".substr($self->{'Samples_Recent_Live_url'}, 0,120)."\n";
978 0           print "Samples_Last_Live URL : ".substr($self->{'Samples_Last_Live_url'}, 0,120)."\n";
979 0           print "Samples URL : ".substr($self->{'Samples_url'}, 0,120)."\n";
980 0           print "Samples_Full URL : ".substr($self->{'Samples_Full_url'}, 0,120)."\n";
981 0           print "Stats_Energy URL : ".substr($self->{'Stats_Energy_url'}, 0,120)."\n";
982 0           print "Appliances URL : ".substr($self->{'Appliances_url'}, 0,120)."\n";
983 0           print "Appliances_Specific URL : ".substr($self->{'Appliances_Specific_url'}, 0,120)."\n";
984 0           print "Appliances_Stats URL : ".substr($self->{'Appliances_Stats_url'}, 0,120)."\n";
985 0           print "Appliances_Events URL : ".substr($self->{'Appliances_Events_url'}, 0,120)."\n";
986 0           print "debug : ".substr($self->{'debug'}, 0,120)."\n";
987 0           print "last_code : ".substr($self->{'last_code'}, 0,120)."\n";
988 0           print "last_reason : ".substr($self->{'last_reason'}, 0,120)."\n";
989 0           print "\n";
990             }
991              
992              
993             #******************************************************************************
994             =head2 get_last_reason - returns the text generated by the most recent fetch
995              
996             Returns the HTTP Header reason for the most recent fetch command
997              
998             $Neurio->get_last_reason();
999              
1000             This method accepts no parameters
1001            
1002             Returns the textual reason
1003            
1004             =cut
1005              
1006             sub get_last_reason {
1007 0     0 0   my $self = shift;
1008 0           return $self->{'last_reason'};
1009             }
1010              
1011             #******************************************************************************
1012             =head2 get_last_code - returns the code generated by the most recent fetch
1013              
1014             Returns the HTTP Header code for the most recent fetch command
1015              
1016             $Neurio->get_last_code();
1017              
1018             This method accepts no parameters
1019            
1020             Returns the numeric code
1021            
1022             =cut
1023              
1024             sub get_last_code {
1025 0     0 0   my $self = shift;
1026 0           return $self->{'last_code'};
1027             }
1028              
1029             #******************************************************************************
1030             sub __process_get {
1031 0     0     my $self = shift;
1032 0           my $url = shift;
1033 0           my $response = $self->{'ua'}->get($url,"Authorization"=>"Bearer ".$self->{'access_token'});
1034              
1035 0           $self->{'last_code'} = $response->code;
1036              
1037 0 0         if (($response->code) eq '200') {
1038 0           $self->{'last_reason'} = '';
1039             } else {
1040 0           $self->{'last_reason'} = $response->message;
1041             }
1042              
1043 0 0         if ($response->is_success) {
1044 0           return decode_json($response->content);
1045             } else {
1046 0 0         print "\n".(caller(1))[3]."(): Failed with return code ".$self->get_last_code()." - ".$self->get_last_reason()."\n" if ($self->{'debug'});
1047 0           return 0;
1048             }
1049             }
1050              
1051             #******************************************************************************
1052             =head1 AUTHOR
1053              
1054             Kedar Warriner, C
1055              
1056             =head1 BUGS
1057              
1058             Please report any bugs or feature requests to C
1059             or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Device-Neurio
1060             I will be notified, and then you'll automatically be notified of progress on
1061             your bug as I make changes.
1062              
1063             =head1 SUPPORT
1064              
1065             You can find documentation for this module with the perldoc command.
1066              
1067             perldoc Device::Neurio
1068              
1069             You can also look for information at:
1070              
1071             =over 5
1072              
1073             =item * RT: CPAN's request tracker
1074              
1075             L
1076              
1077             =item * AnnoCPAN: Annotated CPAN documentation
1078              
1079             L
1080              
1081             =item * CPAN Ratings
1082              
1083             L
1084              
1085             =item * Search CPAN
1086              
1087             L
1088              
1089             =back
1090              
1091             =head1 ACKNOWLEDGEMENTS
1092              
1093             Many thanks to:
1094             The guys at Energy Aware Technologies for creating the Neurio sensor and
1095             developping the API.
1096             Everyone involved with CPAN.
1097              
1098             =head1 LICENSE AND COPYRIGHT
1099              
1100             Copyright 2014 Kedar Warriner .
1101              
1102             This program is free software; you can redistribute it and/or modify it
1103             under the terms of either: the GNU General Public License as published
1104             by the Free Software Foundation; or the Artistic License.
1105              
1106             See http://dev.perl.org/licenses/ for more information.
1107              
1108             =cut
1109              
1110             #******************************************************************************
1111             1; # End of Device::Neurio - Return success to require/use statement
1112             #******************************************************************************
1113              
1114