Commit 80834e85 by Kornkitt Poolsup

First commit

parent 3db127d9
...@@ -56,11 +56,11 @@ function query_generator(device_id, range, endtime) { ...@@ -56,11 +56,11 @@ function query_generator(device_id, range, endtime) {
* Check whether the data is lie in range or not * Check whether the data is lie in range or not
* @param {double} x checked data * @param {double} x checked data
* @param {double} base base data to check range with * @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) { function lie_in_range(x, base) {
var upper = base + (1.25 * base * range); if (x - base <= 0.15 && x - base >= 0.75) return true;
var lower = base - (0.75 * base * range); var upper = base * 1.5;
var lower = base * 0.75;
if (x <= upper && x >= lower && x > 0) return true; if (x <= upper && x >= lower && x > 0) return true;
return false; return false;
} }
...@@ -69,16 +69,15 @@ function lie_in_range(x, base, range = 0.5) { ...@@ -69,16 +69,15 @@ function lie_in_range(x, base, range = 0.5) {
* Check whether data is lie below range or not * Check whether data is lie below range or not
* @param {double} x checked data * @param {double} x checked data
* @param {double} base base data to check range with * @param {double} base base data to check range with
* @param {double} range define range of data
*/ */
function below_range(x, base, range = 0.5) { function below_range(x, base) {
var lower = base - (0.75 * base * range); var lower = base * 0.75;
if (x < lower && x > 0) return true; if (x < lower && x > 0) return true;
return false; return false;
} }
function above_range(x, base, range = 0.5) { function above_range(x, base) {
var upper = base + (1.25 * base * range); var upper = base * 1.5;
if (x > upper) return true; if (x > upper) return true;
return false; return false;
} }
...@@ -157,20 +156,21 @@ function skew_remove_out(data) { ...@@ -157,20 +156,21 @@ function skew_remove_out(data) {
} }
function currentAverage(data, base_avg) { function currentAverage(data, base_avg) {
data = data.filter(x => {
if (x <= 0.15) return false;
return true;
});
var temp = []; var temp = [];
var below_temp = [];
var lowest = 999999;
if (base_avg <= 0) { if (base_avg <= 0) {
temp = data.filter(x => { temp = data.filter(x => {
if (x <= 0.01) return false; if (x <= 0.01) return false;
return true; return true;
}); });
// console.log(".." + temp);
temp = skew_remove_out(temp); temp = skew_remove_out(temp);
// console.log(base_avg + " " + temp);
} else { } else {
data.filter(x => { data.map(x => {
if (x <= 0.01) return false;
return true;
}).map(x => {
if (lie_in_range(x, base_avg)) { if (lie_in_range(x, base_avg)) {
temp.push(x); temp.push(x);
} else if (above_range(x, base_avg)) { } else if (above_range(x, base_avg)) {
...@@ -178,21 +178,19 @@ function currentAverage(data, base_avg) { ...@@ -178,21 +178,19 @@ function currentAverage(data, base_avg) {
for (var i = 0; i < count; i++) { for (var i = 0; i < count; i++) {
temp.push(x / count); temp.push(x / count);
} }
} else if (below_range(x, base_avg)) {
below_temp.push(x);
if (x < lowest) lowest = x;
} }
}); });
if (temp.length == 0) { if (temp.length == 0) {
temp = data.filter(x => { temp = below_temp.filter(x => {
if (x <= 0.1) return false; if (x <= 0.1) return false;
return true; return true;
}) });
// console.log(".." + temp);
temp = skew_remove_out(temp); temp = skew_remove_out(temp);
// console.log(base_avg + " " + temp);
} }
} }
// var avg = average(temp);
// if (avg > base_avg || below_range(avg, base_avg)) return avg;
// return base_avg;
return average(temp); return average(temp);
} }
...@@ -226,11 +224,9 @@ function currentAverageWeight(bt, data) { ...@@ -226,11 +224,9 @@ function currentAverageWeight(bt, data) {
var old_val = avg_arr[avg_arr.length - 2]; var old_val = avg_arr[avg_arr.length - 2];
avg = currentAverage(x, old_val); avg = currentAverage(x, old_val);
console.log(old_val + " _ " + avg);
if (bt[bt_index] - bt[bt_index - 1] <= ms('1w')) { if (bt[bt_index] - bt[bt_index - 1] <= ms('1w')) {
// check new average value with latest average value // check new average value with latest average value
if (avg > old_val && avg < old_val * 1.25) { if (avg > old_val) {
// if higher, use the new one // if higher, use the new one
avg_arr[avg_arr.length - 1] = avg; avg_arr[avg_arr.length - 1] = avg;
} else if (avg < old_val && avg > 0 && } else if (avg < old_val && avg > 0 &&
......
...@@ -53,6 +53,248 @@ function query_generator(device_id, range, endtime) { ...@@ -53,6 +53,248 @@ function query_generator(device_id, range, endtime) {
} }
/** /**
* Check whether the data is lie in range or not
* @param {double} x checked data
* @param {double} base base data to check range with
*/
function lie_in_range(x, base) {
// if (x - base <= 0.15 && x - base >= 0.75) return true;
var upper = base * 2;
var lower = base * 0.5;
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
*/
function below_range(x, base) {
var lower = base * 0.5;
if (x < lower && x > 0) return true;
return false;
}
function above_range(x, base) {
var upper = base * 2;
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 lowest(data) {
var min_data = 999999;
var have_min = false;
data.map(x => {
if (x < min_data) {
min_data = x;
have_min = true;
}
});
// console.log(min_data);
if (have_min && min_data > 0) return min_data;
else return 0;
}
function highest(data) {
var max_data = -999999;
var have_max = false;
data.map(x => {
if (x > max_data) {
max_data = x;
have_max = true;
}
});
if (have_max && max_data > 0) return max_data;
else return 0;
}
function currentAverage(data, base_avg) {
var temp = [];
var below_temp = [];
var lowest = 999999;
if (base_avg <= 0) {
temp = data.filter(x => {
if (x <= 0.01) return false;
return true;
});
temp = skew_remove_out(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);
}
} else if (below_range(x, base_avg)) {
below_temp.push(x);
if (x < lowest) lowest = x;
}
});
if (temp.length == 0) {
temp = below_temp.filter(x => {
if (x <= 0.1) return false;
return true;
});
temp = skew_remove_out(temp);
}
}
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);
// base_time = bt[bt_index];
}
// if no average yet
else 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);
if (bt[bt_index] - bt[bt_index - 1] <= ms('1w')) {
// 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);
}
} else {
console.log("check!" + avg);
if (avg > 0) 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 < (avg_arr[avg_arr.length - 1] * 1.25)) ||
(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.length <= 0) return 0;
else if (avg_arr[avg_arr.length - 1] <= 0)
return avg_arr[avg_arr.length - 2];
return avg_arr[avg_arr.length - 1];
}
/**
* Get approximate weight of data * Get approximate weight of data
* @param {string} device_id id of retrieved device * @param {string} device_id id of retrieved device
* @param {json} response response from REST API * @param {json} response response from REST API
...@@ -78,7 +320,6 @@ function getWeight(device_id, response) { ...@@ -78,7 +320,6 @@ function getWeight(device_id, response) {
temp_data_ext = [x[1]]; temp_data_ext = [x[1]];
} }
}); });
bt_ext.push(base_time); bt_ext.push(base_time);
data_ext.push(temp_data_ext); data_ext.push(temp_data_ext);
var avg = currentAverageWeight(bt_ext, data_ext); var avg = currentAverageWeight(bt_ext, data_ext);
......
This diff is collapsed. Click to expand it.
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"start": "node index5.js", "start": "node index6.js",
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1"
}, },
"author": "", "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