package Device::Neurio;

use warnings;
use strict;

BEGIN
{
  if ($^O eq "MSWin32")
  {
    print "Need to specify windows imports\n";
    exit(-1);
  }
  else
  {
    use LWP::UserAgent;
    use JSON qw( decode_json );
    use XML::Simple;
    use MIME::Base64 (qw(encode_base64));
    use Data::Dumper;
  }
}

=head1 NAME

Device::Neurio - Methods for configuring and controlling a Neurio module.

Please note that in order to use this module you will require three parameters
and an Energy Aware Neurio sensor installed in you house.

=head1 VERSION

Version 0.01

=cut

our $VERSION = '0.01';

#*****************************************************************

=head1 SYNOPSIS

This module provides a Perl interface to a Neurio sensor and allows access to the following functions:

 - new
 - connect
 - fetch_Last_Live
 - fetch_Recent_Live
 - fetch_Samples
 - fetch_Full_samples
 - fetch_Energy_Stats

The module is written entirely in Perl and has been tested with Raspbian Linux.

Here is some sample code:

 use Device::Neurio;

  my $Neurio = Device::Neurio->new($key,$secret,$sensor_id);

  $Neurio->connect();
  
  $data = $Neurio->fetch_Full_Samples("2014-06-16T19:20:21Z","2014-06-16T19:21:21Z","seconds","1");

  print Dumper($data);

  undef $Neurio;

=head1 SUBROUTINES/METHODS

=head2 new - the constructor for a Neurio object.

Creates a new instance to fetch data for a unique Neurio sensor.
In order to create the instance, the key, the secret key and the sensor_id 
must be known.

 my $Neurio = Device::Neurio->new($key,$secret,$sensor_id);

The Object is returned.
=cut

sub new {
    my $class = shift;
    my $self;

    $self->{'ua'}        = LWP::UserAgent->new();
    $self->{'key'}       = shift;
    $self->{'secret'}    = shift;
    $self->{'sensor_id'} = shift;
    $self->{'base64'}    = encode_base64($self->{'key'}.":".$self->{'secret'});
    chomp($self->{'base64'});
    
    bless $self, $class;
    
    return $self;
}

#*****************************************************************

=head2 connect - open a secure connection to the Neurio server.

Opens a secure connection via HTTPS to the Neurio server which provides
the set of API commands to access the sensor data.

 $Neurio->connect();
 
Returns 1 on success and 0 on failure
=cut

sub connect {
	my $self         = shift;
	my $access_token = '';
	
    # Submit request for authentiaction token.
    my $response = $self->{'ua'}->post( 'https://api-staging.neur.io/v1/oauth2/token',  
          { basic_authentication =>  $self->{'base64'},
        	Content_Type         => 'application/x-www-form-urlencoded',
        	grant_type           => 'client_credentials', 
        	client_id            => $self->{'key'},
        	client_secret        => $self->{'secret'},
          }
        );
    
    if($response->is_success) {
      my $return = $response->content;
      $return =~ /\"access_token\":\"(.*)\"\,\"token_type\"/;
      $self->{'access_token'} = $1;
      return 1;
    } else {
      print "Failed to connect\n";
      return 0;
    }
}

#*****************************************************************

=head2 fetch_Recent_Live - retrieve recent sensor readings

Fetches recent sensor readings from the Neurio server.  It accepts a 
parameter specifying the time of the last sample received.  The format for
the parameter is yyyy-mm-ddThh:mm:ssZ

 $Neurio->fetch_Recent_Live($last);
 
Return value is a Perl data structure containing all the raw data
=cut

sub fetch_Recent_Live {
    my $self             = shift;
    my $last             = shift;
    my $url              = "https://api-staging.neur.io/v1/samples/live?sensorId=".$self->{'sensor_id'}."&last=$last";
	my $response         = $self->{'ua'}->get($url,"Authorization"=>"Bearer ".$self->{'access_token'});
    my $decoded_response = decode_json($response->content);

    return $decoded_response;
}


#*****************************************************************

=head2 fetch_Last_Live - retrieve the last live sensor reading

Fetches the last live sensor reading from the Neurio server.  No parameters
are required

 $Neurio->fetch_Last_Live();
 
Return value is a Perl data structure containing all the raw data
=cut

sub fetch_Last_Live {
    my $self             = shift;
    my $url              = "https://api-staging.neur.io/v1/samples/live/last?sensorId=".$self->{'sensor_id'};
	my $response         = $self->{'ua'}->get($url,"Authorization"=>"Bearer ".$self->{'access_token'});
    my $decoded_response = decode_json($response->content);
     
    return $decoded_response;
}

#*****************************************************************

=head2 fetch_Samples - retrieves sensor readings within the parameters specified.

Fetches sensor reading from the Neurio server.  
It accepts the following 4 parameters:
  - start       : yyyy-mm-ddThh:mm:ssZ
  - end         : yyyy-mm-ddThh:mm:ssZ
  - granularity : seconds|minutes|hours|days
  - freqnecy    : an integer

 $Neurio->fetch_Samples($last);
 
Return value is a Perl data structure containing all the raw data
=cut

sub fetch_Samples {
    my $self             = shift;
    my $start            = shift;
    my $end              = shift;
    my $granularity      = shift;
    my $frequency        = shift;
    my $url              = "https://api-staging.neur.io/v1/samples?sensorId=".$self->{'sensor_id'}."&start=$start&end=$end&granularity=$granularity&frequency=$frequency";
	my $response         = $self->{'ua'}->get($url,"Authorization"=>"Bearer ".$self->{'access_token'});
    my $decoded_response = decode_json($response->content);
     
    return $decoded_response;
}

#*****************************************************************

=head2 fetch_Full_Samples - retrieves full sensor readings within the parameters 
specified.

Fetches full sensor reading from the Neurio server for all phases.  
It accepts the following 4 parameters:
  - start       : yyyy-mm-ddThh:mm:ssZ
  - end         : yyyy-mm-ddThh:mm:ssZ
  - granularity : seconds|minutes|hours|days
  - freqnecy    : an integer

 
Return value is a Perl data structure containing all the raw data
=cut

sub fetch_Full_Samples {
    my $self             = shift;
    my $start            = shift;
    my $end              = shift;
    my $granularity      = shift;
    my $frequency        = shift;
    my $url              = "https://api-staging.neur.io/v1/samples/full?sensorId=".$self->{'sensor_id'}."&start=$start&end=$end&granularity=$granularity&frequency=$frequency";
	my $response         = $self->{'ua'}->get($url,"Authorization"=>"Bearer ".$self->{'access_token'});
    my $decoded_response = decode_json($response->content);
     
    return $decoded_response;
}

#*****************************************************************

=head2 fetch_Energy_Stats - retrieves energy statistics within the parameters 
specified.

Fetches full sensor reading from the Neurio server for all phases.  
It accepts the following 4 parameters:
  - start       : yyyy-mm-ddThh:mm:ssZ
  - end         : yyyy-mm-ddThh:mm:ssZ
  - granularity : seconds|minutes|hours|days
  - freqnecy    : an integer

 $Neurio->fetch_Samples($last);
 
Return value is a Perl data structure containing all the raw data
=cut

sub fetch_Energy_Stats {
    my $self        = shift;
    my $start       = shift;
    my $end         = shift;
    my $granularity = shift;
    my $frequency   = shift;
    my $url         = "https://api-staging.neur.io/v1/samples/stats?sensorId=".$self->{'sensor_id'}."&start=$start&end=$end&granularity=$granularity&frequency=$frequency";
	my $response = $self->{'ua'}->get($url,"Authorization"=>"Bearer ".$self->{'access_token'});

print Dumper($response);
exit(0);

    my $decoded_response = decode_json($response->content);
     
    return $decoded_response;
}


#*****************************************************************

=head1 AUTHOR

Kedar Warriner, C<< <kedarwarriner at gmail dot com> >>

=head1 BUGS

Please report any bugs or feature requests to C<bug-device-Neurio at rt.cpan.org>, or through
the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Device-Neurio>. 
I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.



=head1 SUPPORT

You can find documentation for this module with the perldoc command.

  perldoc Device::Neurio


You can also look for information at:

=over 5

=item * RT: CPAN's request tracker

L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Device-Neurio>

=item * AnnoCPAN: Annotated CPAN documentation

L<http://annocpan.org/dist/Device-Neurio>

=item * CPAN Ratings

L<http://cpanratings.perl.org/d/Device-Neurio>

=item * Search CPAN

L<http://search.cpan.org/dist/Device-Neurio/>

=back


=head1 ACKNOWLEDGEMENTS

Many thanks to:
  The guys at Energy Aware Technologies for creating the Neurio sensor and 
  developping the API.
  Everyone involved with CPAN.

=head1 LICENSE AND COPYRIGHT

Copyright 2014 Kedar Warriner.

This program is free software; you can redistribute it and/or modify it
under the terms of either: the GNU General Public License as published
by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.


=cut

#********************************************************************
1; # End of Device::Neurio - Return success to require/use statement
#********************************************************************

