Commit 585f3235 by Kornkitt Poolsup

update

parent f6b305e7
......@@ -9,10 +9,22 @@ var kairos_url = 'http://' + kairos_usr + ":" + kairos_pwd +
'@nxn1.kube.nexpie.com:' +
kairos_prt + '/';
/**
* Round time to the previous absolube scale time
* @param {integer} t time for scale in milliseconds
* @param {string} scale how rough of time to scale
* @param {string} gmt Greenwich mean time; default is '7h'
*/
function timeRoundDown(t, scale = '1h', gmt = '7h') {
return t - (t % ms(scale)) - ms(gmt);
}
/**
* Generate a query from device_id
* @param {string} device_id id of retrieved device
* @param {string} range how far to get the data
* @param {integer} endtime gets data until when
*/
function query_generator(device_id, range, endtime) {
var mls = ms('1s');
var now = endtime ? endtime : new Date().getTime()
......@@ -40,13 +52,35 @@ function query_generator(device_id, range, endtime) {
return q_data;
}
/**
* Check whether the data is lie in range or not
* @param {double} x checked data
* @param {double} base base data to check range with
* @param {double} range define range of data
*/
function lie_in_range(x, base, range = 0.5) {
var upper = base + (1.5 * base * range);
var lower = base - (base * range);
if (x < upper && x > lower) return true;
var upper = base + (1.25 * base * range);
var lower = base - (0.75 * base * range);
if (x <= upper && x >= lower && x > 0) return true;
return false;
}
/**
* Check whether data is lie below range or not
* @param {double} x checked data
* @param {double} base base data to check range with
* @param {double} range define range of data
*/
function below_range(x, base, range = 0.5) {
var lower = base - (0.75 * base * range);
if (x < lower && x > 0) return true;
return false;
}
/**
* Average the data
* @param {list} data list of array data
*/
function average(data) {
if (data.length <= 0) return 0;
var sum = 0;
......@@ -54,39 +88,62 @@ function average(data) {
return sum / data.length;
}
function allSameValue (data) {
if (data.length <= 1) return true;
let temp = data[1];
data.map(x => {
if (x !== temp) return false;
});
return true;
}
/**
* Get approximate weight of data
* @param {string} device_id id of retrieved device
* @param {json} response response from REST API
*/
function getWeight(device_id, response) {
var final = [];
response.map(res => {
var data = res.values;
var base_time = timeRoundDown(data[0][0], '1d');
var data_in_bt = [];
var base_avg = 0;
var base_avg = -1;
data.map(x => {
var data_bt = timeRoundDown(x[0], '1d');
if (data_bt === base_time) {
if (base_avg === 0 || lie_in_range(x[1], base_avg))
data_in_bt.push(x[1]);
} else {
if (data_bt !== base_time) {
var avg = average(data_in_bt);
if (avg >= base_avg) base_avg = avg;
console.log(base_time + " | " + base_avg + " | " +
x[1] + " | " + lie_in_range(x[1], base_avg));
if ((avg >= base_avg && avg > 0) ||
(avg < below_range(avg, base_avg)))
base_avg = avg;
if (avg === 0) base_avg = -1;
// console.log(base_time + " | " + avg + " | " + base_avg);
base_time = data_bt;
if (lie_in_range(x[1], base_avg)) {
data_in_bt = [x[1]];
} else data_in_bt = [];
data_in_bt = [x[1]];
} else {
if (base_avg === -1 || lie_in_range(x[1], base_avg))
data_in_bt.push(x[1]);
}
});
var avg = average(data_in_bt);
if (avg >= base_avg) base_avg = avg;
console.log(base_time + " | " + base_avg);
if (avg >= base_avg && avg > 0 ||
avg < below_range(avg, base_avg))
base_avg = avg;
if (avg === 0) base_avg = -1;
if (base_avg < 0) base_avg = 0;
// console.log(base_time + " | " + avg + " | " + base_avg);
final.push([device_id, base_avg]);
});
return final;
}
function currentWeight(device_id, traceback = '4w') {
/**
* Retrieve data from device_id to get current approximate weight
* @param {string} device_id id of the retrived device
* @param {string} traceback how far to trace data back
*/
function currentWeight(device_id, traceback = '1y') {
var q_data = query_generator(device_id, traceback);
rest.get(kairos_url +
......
var rest = require('restler');
var ms = require('ms');
var sc = require('./status_code');
var kairos_usr = 'tsdbadmin';
var kairos_pwd = 'RzuCqG14NrWXMfbj*s6m8v';
var kairos_prt = '32223';
var kairos_url = 'http://' + kairos_usr + ":" + kairos_pwd +
'@nxn1.kube.nexpie.com:' +
kairos_prt + '/';
function timeRoundDown(t, scale = '1h', gmt = '7h') {
return t - (t % ms(scale)) - ms(gmt);
}
function query_generator(device_id, range, endtime) {
var mls = ms('1s');
var now = endtime ? endtime : new Date().getTime()
var q_data = {
start_absolute: now - ms(range),
end_absoulte: now,
metrics: [{
name: device_id,
group_by: [{
name: "tag",
tags: ["attr"]
}],
tags: {
attr: ["a12"]
},
aggregators: [{
name: 'avg',
sampling: {
value: mls,
unit: "milliseconds"
}
}]
}]
}
return q_data;
}
function lie_in_range(x, base, range = 0.5) {
var upper = base + (1.5 * base * range);
var lower = base - (base * range);
if (x < upper && x > lower) return true;
return false;
}
function average(data) {
if (data.length <= 0) return 0;
var sum = 0;
data.map(x => sum += x);
return sum / data.length;
}
function getWeight(device_id, response) {
var final = [];
response.map(res => {
var data = res.values;
var base_time = timeRoundDown(data[0][0], '1d');
var data_in_bt = [];
var base_avg = 0;
data.map(x => {
var data_bt = timeRoundDown(x[0], '1d');
if (data_bt === base_time) {
if (base_avg === 0 || lie_in_range(x[1], base_avg))
data_in_bt.push(x[1]);
} else {
var avg = average(data_in_bt);
if (avg >= base_avg) base_avg = avg;
// console.log(base_time + " | " + base_avg);
base_time = data_bt;
data_in_bt = [x[1]];
}
});
var avg = average(data_in_bt);
if (avg >= base_avg) base_avg = avg;
// console.log(base_time + " | " + base_avg);
final.push([device_id, base_avg]);
});
return final;
}
function currentWeight(device_id, traceback = '1y') {
var q_data = query_generator(device_id, traceback);
rest.get(kairos_url +
'api/v1/datapoints/query?query=' +
JSON.stringify(q_data)
).on('complete', function (qres, response) {
console.log('status code (qres): ' +
sc.http_codeToStatus(response.statusCode));
var res = qres.queries[0].results;
var f = getWeight(device_id, res);
console.log(f);
});
}
/**
* For testing and debugging in sequence
*/
function run_all() {
var dev = [
'4c988381-2cd9-4334-914d-971241bcf3c2',
'f592b419-380d-4875-9c99-354a4579d03c'
];
dev.map(x => currentWeight(x));
}
run_all();
var rest = require('restler');
var ms = require('ms');
var sc = require('./status_code');
var kairos_usr = 'tsdbadmin';
var kairos_pwd = 'RzuCqG14NrWXMfbj*s6m8v';
var kairos_prt = '32223';
var kairos_url = 'http://' + kairos_usr + ":" + kairos_pwd +
'@nxn1.kube.nexpie.com:' +
kairos_prt + '/';
/**
* Round time to the previous absolube scale time
* @param {integer} t time for scale in milliseconds
* @param {string} scale how rough of time to scale
* @param {string} gmt Greenwich mean time; default is '7h'
*/
function timeRoundDown(t, scale = '1h', gmt = '7h') {
return t - (t % ms(scale)) - ms(gmt);
}
/**
* Generate a query from device_id
* @param {string} device_id id of retrieved device
* @param {string} range how far to get the data
* @param {integer} endtime gets data until when
*/
function query_generator(device_id, range, endtime) {
var mls = ms('1s');
var now = endtime ? endtime : new Date().getTime()
var q_data = {
start_absolute: now - ms(range),
end_absoulte: now,
metrics: [{
name: device_id,
group_by: [{
name: "tag",
tags: ["attr"]
}],
tags: {
attr: ["a12"]
},
aggregators: [{
name: 'avg',
sampling: {
value: mls,
unit: "milliseconds"
}
}]
}]
}
return q_data;
}
/**
* Check whether the data is lie in range or not
* @param {double} x checked data
* @param {double} base base data to check range with
* @param {double} range define range of data
*/
function lie_in_range(x, base, range = 0.5) {
var upper = base + (1.25 * base * range);
var lower = base - (0.75 * base * range);
if (x <= upper && x >= lower && x > 0) return true;
return false;
}
/**
* Check whether data is lie below range or not
* @param {double} x checked data
* @param {double} base base data to check range with
* @param {double} range define range of data
*/
function below_range(x, base, range = 0.5) {
var lower = base - (0.75 * base * range);
if (x < lower && x > 0) return true;
return false;
}
function above_range(x, base, range = 0.5) {
var upper = base + (1.25 * base * range);
if (x > upper) return true;
return false;
}
/**
* Average the data
* @param {list} data list of array data
*/
function average(data) {
if (data.length <= 0) return 0;
var sum = 0;
data.map(x => sum += x);
return sum / data.length;
}
// find the value at percentile 'range' (0 to 1)
function percentile(data, range) {
var p = (data.length + 1) * range;
var index = Math.floor(p) - 1;
var val = data[index] +
(p - index) * (data[index + 1] - data[index]);
return val;
}
// check skewed of data
function skewed(data) {
data = data.sort((a, b) => a - b); // sort data increasing
var q1 = percentile(data, 0.25);
var q2 = percentile(data, 0.5);
var q3 = percentile(data, 0.75);
var lower_range = q2 - q1;
var upper_range = q3 - q2;
var ratio = lower_range / upper_range;
if (ratio < 0.5) return 'right';
else if (ratio > 1.5) return 'left';
return 'normal';
}
// find the outlier and whether clear it or not - left skewed
function skew_remove_out(data) {
if (data.length <= 0) return [0];
data = data.sort((a, b) => a - b); // sort data increasing
var skew = skewed(data);
var q1 = percentile(data, 0.25);
var q2 = percentile(data, 0.5);
var q3 = percentile(data, 0.75);
var iqr = q3 - q1;
var bound, lower, upper;
// console.log(skew + " / " + q1 + " / " + q2 + " / " + q3);
if (skew == 'normal') {
bound = iqr;
lower = q1 - bound;
upper = q3 + bound;
} else if (skew == 'right') {
bound = q2 - q1;
lower = q1 - bound;
upper = q2 + bound;
} else {
bound = q3 - q2;
lower = q2 - bound;
upper = q3 + bound;
}
var outs = []; // outlier
var not_outs = []; // data without outlier
data.map(x => {
if (x < lower || x > upper) outs.push(x);
else not_outs.push(x);
});
return not_outs;
}
function currentAverage(data, base_avg) {
var temp = [];
if (base_avg <= 0) {
temp = data.filter(x => {
if (x <= 0.1) return false;
return true;
})
// console.log(".." + temp);
temp = skew_remove_out(temp);
// console.log(base_avg + " " + temp);
} else {
data.map(x => {
if (lie_in_range(x, base_avg)) {
temp.push(x);
} else if (above_range(x, base_avg)) {
var count = Math.round(x / base_avg);
for (var i = 0; i < count; i++) {
temp.push(x / count);
}
}
});
}
// var avg = average(temp);
// if (avg > base_avg || below_range(avg, base_avg)) return avg;
// return base_avg;
return average(temp);
}
function currentAverageWeight(bt, data) {
if (data.length <= 0 || bt.length <= 0) return 0;
var bt_index = 0;
var avg_arr = [];
data.map(x => {
x = x.sort((a, b) => a - b); // sort data increasing
var avg;
if (bt_index !== 0 &&
bt[bt_index] - bt[bt_index - 1] !== ms('1d')) {
// in case there are no data passing for some day
if (avg_arr.length > 1 &&
avg_arr[avg_arr.length - 1] !== -1)
avg_arr.push(-1);
console.log("in!");
// base_time = bt[bt_index];
}
// if no average yet
if (avg_arr.length <= 0) {
avg = currentAverage(x, 0);
if (avg > 0) avg_arr.push(avg);
}
// check if there is any day skip or previous zero data
else if (avg_arr[avg_arr.length - 1] === -1 &&
avg_arr.length > 1) {
// get latest average value that != -1
var old_val = avg_arr[avg_arr.length - 2];
avg = currentAverage(x, old_val);
// check new average value with latest average value
if (avg > old_val) {
// if higher, use the new one
avg_arr[avg_arr.length - 1] = avg;
} else if (avg < old_val && avg > 0 &&
lie_in_range(avg, old_val)) {
// if lower but still in range, use the latest one
avg_arr[avg_arr.length - 1] = old_val;
} else if (below_range(avg, old_val) && avg > 0) {
// if lower below the lower bound, use new one,
// however, mark with -1 to confirm the new set of data
avg_arr.push(avg);
}
}
// if no day skip then continue
else {
avg = currentAverage(x, avg_arr[avg_arr.length - 1]);
if (avg > avg_arr[avg_arr.length - 1] ||
(avg > 0 &&
below_range(avg, avg_arr[avg_arr.length - 1]))) {
avg_arr.push(avg);
} else {
avg_arr.push(-1);
}
}
console.log(bt[bt_index] + " / " + bt[bt_index - 1] + " = " +
(bt[bt_index] - bt[bt_index - 1]) + " | " + avg + " / " +
avg_arr[avg_arr.length - 1] + " = " +
avg_arr.length + " | " +
bt_index + " / " + (bt.length - 1));
// base_time += ms('1d');
// bt_index++;
bt_index++;
});
if (avg_arr[avg_arr.length - 1] <= 0 || avg_arr.length <= 0) return 0;
return avg_arr[avg_arr.length - 1];
}
/**
* Get approximate weight of data
* @param {string} device_id id of retrieved device
* @param {json} response response from REST API
*/
function getWeight(device_id, response) {
var final = [];
response.map(res => {
var data = res.values;
var data_ext = [];
var bt_ext = [];
var base_time = timeRoundDown(data[0][0], '1d');
var temp_data_ext = [];
data.map(x => {
if (timeRoundDown(x[0], '1d') === base_time) {
temp_data_ext.push(x[1]);
} else {
bt_ext.push(base_time);
data_ext.push(temp_data_ext);
base_time = timeRoundDown(x[0], '1d');
temp_data_ext = [x[1]];
}
});
bt_ext.push(base_time);
data_ext.push(temp_data_ext);
var avg = currentAverageWeight(bt_ext, data_ext);
final.push([device_id, avg]);
});
return final;
}
/**
* Retrieve data from device_id to get current approximate weight
* @param {string} device_id id of the retrived device
* @param {string} traceback how far to trace data back
*/
function currentWeight(device_id, traceback = '1y') {
var q_data = query_generator(device_id, traceback);
rest.get(kairos_url +
'api/v1/datapoints/query?query=' +
JSON.stringify(q_data)
).on('complete', function (qres, response) {
console.log('status code (qres): ' +
sc.http_codeToStatus(response.statusCode));
var res = qres.queries[0].results;
var f = getWeight(device_id, res);
console.log(f);
});
}
/**
* For testing and debugging in sequence
*/
function run_all() {
var dev = [
'4c988381-2cd9-4334-914d-971241bcf3c2',
'f592b419-380d-4875-9c99-354a4579d03c'
];
dev.map(x => currentWeight(x));
}
run_all();
......@@ -4,7 +4,7 @@
"description": "",
"main": "index.js",
"scripts": {
"start": "node index4.js",
"start": "node index5.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment