Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New design code #1

Open
wants to merge 40 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
f06c3f7
Add Upload to Garden Function
Mar 17, 2015
eaa598a
Changes in the getGarden function to match the requirements of the Ra…
amaurySaugrain Jul 30, 2015
804fe38
New version: multiple callback fixed and more...
bsautron Dec 8, 2015
1a3821d
version 1.0.0
bsautron Dec 8, 2015
bc38c6d
Concat json and new path to get image
bsautron Dec 17, 2015
6127e88
New name: flower-power-api
bsautron Dec 18, 2015
4e5f138
Update README.md
bsautron Dec 18, 2015
0036bdd
1.1.1
bsautron Dec 18, 2015
afd1fc4
v1.1.2
bsautron Dec 18, 2015
018b1ac
1.1.3
bsautron Dec 18, 2015
e88c05d
1.1.4
bsautron Dec 18, 2015
39bad31
1.1.5
bsautron Dec 18, 2015
e6e213d
async required
bsautron Dec 18, 2015
4b42234
1.1.6
bsautron Dec 18, 2015
dac8aed
Eject null and undefined sensors
bsautron Dec 29, 2015
60a1198
1.1.7
bsautron Dec 29, 2015
56cd147
Best parse error
bsautron Dec 30, 2015
162f678
1.1.8
bsautron Dec 30, 2015
b81d50f
Set auto refresh token
bsautron Dec 30, 2015
8283ebe
1.1.9
bsautron Dec 30, 2015
2a7191a
Update README.md
bsautron Dec 31, 2015
3cb7dc2
Dep: cli-color
bsautron Dec 31, 2015
e0322cd
1.1.10
bsautron Dec 31, 2015
02b2d9a
Dont need cli-color
bsautron Dec 31, 2015
7f81851
1.2.0
bsautron Dec 31, 2015
64a8489
A lot of parenthese
bsautron Dec 31, 2015
cdc2068
1.2.1
bsautron Dec 31, 2015
3dce62d
Get sample by location
bsautron Jan 6, 2016
be5c231
Update readme.md
bsautron Jan 6, 2016
a77340b
1.3.0
bsautron Jan 6, 2016
15a131f
New functions and doc
bsautron Jan 7, 2016
7ef8bed
1.4.0
bsautron Jan 7, 2016
cf3d6dd
Error herited not instancified - api.verify()
bsautron Jan 13, 2016
c6e0ef3
1.4.1
bsautron Jan 13, 2016
d21d7e8
callback(err) if the data is not a json
bsautron Jan 17, 2016
6f798c0
1.4.2
bsautron Jan 17, 2016
565189f
change url of server
muuuh Oct 8, 2016
21e0d3f
2.0.0
bsautron Dec 9, 2016
e90599a
getGarden end send samples
bsautron Dec 11, 2016
ff6b1d7
2.0.1
bsautron Dec 11, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,3 @@ results

npm-debug.log
node_modules

test2.js
36 changes: 36 additions & 0 deletions ApiError.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
function ApiError(code, body) {
this.code = code;
this.errors = [];

if (body.errors && body.errors.length > 0) {
this.errors = body.errors;
}
else this.errors.push(body);
return (this);
}

ApiError.prototype = Object.create(Error.prototype);
ApiError.prototype.constructor = ApiError;

ApiError.prototype.toString = function() {
var str = "CODE: " + this.code;

for (var error of this.errors) {
str += "\n";

if (error.error && error.error_description) {
str += error.error + ": " + error.error_description;
} else if (error.error_code && error.error_message) {
str += error.error_code + ": " + error.error_message;
} else if (typeof error == 'string') {
str += error;
} else {
var key = Object.keys(error)[0];
str += key + ": " + error[key];
}

}
return (str);
}

module.exports = ApiError;
228 changes: 228 additions & 0 deletions FlowerPowerCloud.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
var ApiError = require('./ApiError');
var async = require('async');
var request = require('request');
var qs = require('querystring');
var schedule = require('node-schedule');

const DEBUG = false;

function FlowerPowerCloud() {
this._token = {};
this._isLogged = false;
this.credentials = {};
this.autoRefresh = false;

var self = this;
var api = {
// Profile
'getProfile': {method: 'GET/json', path: '/user/v4/profile', auth: true},
'getUserVersions': {method: 'GET/json', path: '/user/v1/versions', auth: true},
'verify': {method: 'GET/json', path: '/user/v1/verify', auth: true},

// Garden
'getSyncGarden': {method: 'GET/json', path: '/sensor_data/v4/garden_locations_status', auth: true},
'getConfiguration': {method: 'GET/json', path: '/garden/v2/configuration', auth: true},
'getGarden': {method: 'GET/json', path: '/garden/v1/status', auth: true},
'sendSamples': {method: 'PUT/json', path: '/sensor_data/v8/sample', auth: true},
'getSyncData': {method: 'GET/json', path: '/sensor_data/v3/sync', auth: true},
'getFirmwareUpdate': {method: 'GET/json', path: '/sensor_data/v1/firmware_update', auth: true},
'getLocationSamples': {method: 'GET/json', path: '/sensor_data/v2/sample/location/:location_identifier', auth: true},
'getStatistics': {method: 'GET/json', path: '/sensor_data/v1/statistics/:location_identifier', auth: true},

// Images
'getImageLocation': {method: 'GET/json', path: '/image/v3/location/user_images/:location_identifier', auth: true},
};

for (var item in api) {
self.makeReqFunction(item, api[item]);
}
return this;
};

FlowerPowerCloud.url = 'https://api-flower-power-pot.parrot.com';

FlowerPowerCloud.prototype.makeReqFunction = function(name, req) {
var self = this;

FlowerPowerCloud.prototype[name] = function(data, callback) {
self.invoke(req, data, callback);
};
};

FlowerPowerCloud.prototype.makeHeader = function(req, data) {
var options = {headers: {}};
var verb = req.method.split('/')[0];
var type = req.method.split('/')[1];

switch (type) {
case 'urlencoded':
options.body = qs.stringify(data);
options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
break;
case 'json':
options.body = JSON.stringify(data);
options.headers['Content-Type'] = 'application/json';
break;
default:
options.body = data;
options.headers['Content-Type'] = 'text/plain';
break;
}

options.url = FlowerPowerCloud.url + req.path;
options.method = verb;
options.headers['Authorization'] = (req.auth) ? "Bearer " + this._token.access_token : "";

return options;
};

FlowerPowerCloud.prototype.makeUrl = function(req, data) {
var self = this;

if (data) {
for (var item in data.url) {
req.path = req.path.replace(':' + item, data.url[item]);
}
delete data.url;
}
if (DEBUG) self.loggerReq(req, data);
return req;
};

FlowerPowerCloud.prototype.loggerReq = function(req, data) {
console.log(req.method, req.path);
for (var key in data) {
console.log(key + ":", data[key]);
}
};

FlowerPowerCloud.prototype.invoke = function(req, data, callback) {
var options = {};
var self = this;

if (typeof data == 'function') {
callback = data;
data = null;
}
if (data && typeof data !== 'object') {
return callback(new Error('Data is not a json'));
}
req = self.makeUrl(req, data);
options = self.makeHeader(req, data);

if (DEBUG) console.log(options);
request(options, function(err, res, body) {
if (typeof body == 'string') {
try {
body = JSON.parse(body);
} catch (e) {};
}
if (err) callback(err, null);
else if (res.statusCode != 200 || (body.errors && body.errors.length > 0)) {
return callback(new ApiError(res.statusCode, body), null);
}
else if (callback) {
var results = body;

return callback(null, results);
}
else throw "Give me a callback";
});
};

FlowerPowerCloud.prototype.login = function(data, callback) {
var req = {method: 'POST/urlencoded', path: '/user/v2/authenticate'};
var self = this;

if (typeof data['auto-refresh'] != 'undefined') {
self.autoRefresh = data['auto-refresh'];
delete data['auto-refresh'];
}
self.credentials = data;
data['grant_type'] = 'password';
self.invoke(req, data, function(err, res) {
if (err) callback(err);
else self.setToken(res, callback);
});
};

FlowerPowerCloud.prototype.setToken = function(token, callback) {
var self = this;

self._token = token;
self._isLogged = true;
if (self.autoRefresh) {
var job = new schedule.Job(function() {
self.refresh(token);
});
job.schedule(new Date(Date.now() + (token['expires_in'] - 1440) * 1000));
}
if (typeof callback == 'function') callback(null, token);
}

FlowerPowerCloud.prototype.refresh = function(token) {
var req = {method: 'POST/urlencoded', path: '/user/v2/authenticate'};
var self = this;

var data = {
'client_id': self.credentials['client_id'],
'client_secret': self.credentials['client_secret'],
'refresh_token': token.refresh_token,
'grant_type': 'refresh_token'
};

self.invoke(req, data, function(err, res) {
if (err) callback(err);
else self.setToken(res);
});
};

// FlowerPowerCloud.prototype.getGarden = function(callback) {
// var self = this;
//
// async.parallel({
// syncGarden: self.getSyncGarden,
// syncData: self.getSyncData,
// }, function(err, res) {
// if (err) callback(err);
// else callback(null, self.concatJson(res.syncData, res.syncGarden));
// });
// };

FlowerPowerCloud.prototype.concatJson = function(json1, json2) {
var dest = json1;
var self = this;

for (var key in json2) {
if (typeof json1[key] == 'object' && typeof json2[key] == 'object') {
dest[key] = self.concatJson(json1[key], json2[key]);
}
else {
dest[key] = json2[key];
}
}
return dest;
}

// 'url1': {
// 'getProfile',
// 'getUserVersions',
// 'getSyncGarden',
// 'sendSamples',
// 'getSyncData',
// 'getFirmwareUpdate',
// 'getLocationSamples',
// 'getStatistics',
// },
// 'url2': {
// 'searchName',
// 'suggest',
// 'suggestLocation'
// },
// 'url3': {
// 'infoPlant',
// 'plantdataVersion',
// 'listPopularityPlant',
// }

module.exports = FlowerPowerCloud;
Loading