mirror of
https://github.com/beestat/app.git
synced 2025-05-24 02:14:03 -04:00
Fixed #254 - Smoothed data often terribly misrepresents real data
Smoothing is now automatically done for outdoor temperature and humidity. Removed smoothing option; disabled by default for all indoor series.
This commit is contained in:
parent
a84417b8d4
commit
2efcb60fcc
@ -23,14 +23,6 @@ beestat.runtime_sensor.get_data = function(thermostat_id, range) {
|
||||
}
|
||||
};
|
||||
|
||||
// A couple private helper functions for manipulating the min/max y values.
|
||||
var y_min_max = function(value) {
|
||||
if (value !== null) {
|
||||
data.metadata.chart.y_min = Math.min(data.metadata.chart.y_min, value);
|
||||
data.metadata.chart.y_max = Math.max(data.metadata.chart.y_max, value);
|
||||
}
|
||||
};
|
||||
|
||||
// Duration objects. These are passed by reference into the metadata.
|
||||
var durations = {};
|
||||
|
||||
@ -102,20 +94,6 @@ beestat.runtime_sensor.get_data = function(thermostat_id, range) {
|
||||
|
||||
var runtime_sensors = beestat.runtime_sensor.get_runtime_sensors_by_date_();
|
||||
|
||||
// Initialize moving average.
|
||||
var moving = [];
|
||||
var moving_count;
|
||||
if (beestat.setting('runtime_sensor_detail_smoothing') === true) {
|
||||
moving_count = 5;
|
||||
} else {
|
||||
moving_count = 1;
|
||||
}
|
||||
var offset;
|
||||
for (var i = 0; i < moving_count; i++) {
|
||||
offset = (i - Math.floor(moving_count / 2)) * 300000;
|
||||
moving.push(runtime_sensors[begin_m.valueOf() + offset]);
|
||||
}
|
||||
|
||||
// Loop.
|
||||
var current_m = begin_m;
|
||||
while (
|
||||
@ -137,13 +115,10 @@ beestat.runtime_sensor.get_data = function(thermostat_id, range) {
|
||||
return;
|
||||
}
|
||||
|
||||
var temperature_moving = beestat.temperature(
|
||||
beestat.runtime_sensor.get_average_(moving, sensor.sensor_id)
|
||||
);
|
||||
data.series['temperature_' + runtime_sensor.sensor_id].push(temperature_moving);
|
||||
y_min_max(temperature_moving);
|
||||
var temperature = beestat.temperature(runtime_sensor.temperature);
|
||||
data.series['temperature_' + runtime_sensor.sensor_id].push(temperature);
|
||||
data.metadata.series['temperature_' + runtime_sensor.sensor_id].active = true;
|
||||
data.metadata.series['temperature_' + runtime_sensor.sensor_id].data[current_m.valueOf()] = temperature_moving;
|
||||
data.metadata.series['temperature_' + runtime_sensor.sensor_id].data[current_m.valueOf()] = temperature;
|
||||
|
||||
if (runtime_sensor.occupancy === true) {
|
||||
let swimlane_properties =
|
||||
@ -181,14 +156,6 @@ beestat.runtime_sensor.get_data = function(thermostat_id, range) {
|
||||
}
|
||||
|
||||
current_m.add(5, 'minute');
|
||||
|
||||
/**
|
||||
* Remove the first row in the moving average and add the next one. Yes
|
||||
* this could introduce undefined values; that's ok. Those are handled in
|
||||
* the get_average_ function.
|
||||
*/
|
||||
moving.shift();
|
||||
moving.push(runtime_sensors[current_m.valueOf() + offset]);
|
||||
}
|
||||
|
||||
return data;
|
||||
@ -212,34 +179,3 @@ beestat.runtime_sensor.get_runtime_sensors_by_date_ = function() {
|
||||
}
|
||||
return runtime_sensors;
|
||||
};
|
||||
|
||||
/**
|
||||
* Given an array of runtime_sensors, get the average value of one of the
|
||||
* keys. Allows and ignores undefined values in order to keep a more accurate
|
||||
* moving average.
|
||||
*
|
||||
* @param {array} runtime_sensors
|
||||
* @param {string} sensor_id The index in the sub-array
|
||||
*
|
||||
* @return {number} The average.
|
||||
*/
|
||||
beestat.runtime_sensor.get_average_ = function(runtime_sensors, sensor_id) {
|
||||
var average = 0;
|
||||
var count = 0;
|
||||
for (var i = 0; i < runtime_sensors.length; i++) {
|
||||
if (
|
||||
runtime_sensors[i] !== undefined &&
|
||||
runtime_sensors[i][sensor_id] !== undefined &&
|
||||
runtime_sensors[i][sensor_id].temperature !== null
|
||||
) {
|
||||
average += runtime_sensors[i][sensor_id].temperature;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return average / count;
|
||||
};
|
||||
|
@ -152,12 +152,8 @@ beestat.runtime_thermostat.get_data = function(thermostat_id, range) {
|
||||
|
||||
// Initialize moving average.
|
||||
var moving = [];
|
||||
var moving_count;
|
||||
if (beestat.setting('runtime_thermostat_detail_smoothing') === true) {
|
||||
moving_count = 10;
|
||||
} else {
|
||||
moving_count = 1;
|
||||
}
|
||||
var moving_count = 15;
|
||||
|
||||
var offset;
|
||||
for (var i = 0; i < moving_count; i++) {
|
||||
offset = (i - Math.floor(moving_count / 2)) * 300000;
|
||||
@ -181,29 +177,8 @@ beestat.runtime_thermostat.get_data = function(thermostat_id, range) {
|
||||
|
||||
if (runtime_thermostat !== undefined) {
|
||||
/**
|
||||
* Things that use the moving average.
|
||||
* Outdoor temp/humidity (moving average).
|
||||
*/
|
||||
var indoor_humidity_moving = beestat.runtime_thermostat.get_average_(moving, 'indoor_humidity');
|
||||
data.series.indoor_humidity.push(indoor_humidity_moving);
|
||||
data.metadata.series.indoor_humidity.data[current_m.valueOf()] =
|
||||
runtime_thermostat.indoor_humidity;
|
||||
data.metadata.series.indoor_humidity.active = true;
|
||||
|
||||
var outdoor_humidity_moving = beestat.runtime_thermostat.get_average_(moving, 'outdoor_humidity');
|
||||
data.series.outdoor_humidity.push(outdoor_humidity_moving);
|
||||
data.metadata.series.outdoor_humidity.data[current_m.valueOf()] =
|
||||
runtime_thermostat.outdoor_humidity;
|
||||
data.metadata.series.outdoor_humidity.active = true;
|
||||
|
||||
var indoor_temperature_moving = beestat.temperature(
|
||||
beestat.runtime_thermostat.get_average_(moving, 'indoor_temperature')
|
||||
);
|
||||
data.series.indoor_temperature.push(indoor_temperature_moving);
|
||||
data.metadata.series.indoor_temperature.data[current_m.valueOf()] =
|
||||
beestat.temperature(runtime_thermostat.indoor_temperature);
|
||||
y_min_max(indoor_temperature_moving);
|
||||
data.metadata.series.indoor_temperature.active = true;
|
||||
|
||||
var outdoor_temperature_moving = beestat.temperature(
|
||||
beestat.runtime_thermostat.get_average_(moving, 'outdoor_temperature')
|
||||
);
|
||||
@ -213,6 +188,32 @@ beestat.runtime_thermostat.get_data = function(thermostat_id, range) {
|
||||
y_min_max(outdoor_temperature_moving);
|
||||
data.metadata.series.outdoor_temperature.active = true;
|
||||
|
||||
var outdoor_humidity_moving = beestat.runtime_thermostat.get_average_(
|
||||
moving,
|
||||
'outdoor_humidity'
|
||||
);
|
||||
data.series.outdoor_humidity.push(outdoor_humidity_moving);
|
||||
data.metadata.series.outdoor_humidity.data[current_m.valueOf()] =
|
||||
runtime_thermostat.outdoor_humidity;
|
||||
data.metadata.series.outdoor_humidity.active = true;
|
||||
|
||||
/**
|
||||
* Indoor temp/humidity.
|
||||
*/
|
||||
data.series.indoor_humidity.push(runtime_thermostat.indoor_humidity);
|
||||
data.metadata.series.indoor_humidity.data[current_m.valueOf()] =
|
||||
runtime_thermostat.indoor_humidity;
|
||||
data.metadata.series.indoor_humidity.active = true;
|
||||
|
||||
var indoor_temperature = beestat.temperature(
|
||||
runtime_thermostat.indoor_temperature
|
||||
);
|
||||
data.series.indoor_temperature.push(indoor_temperature);
|
||||
data.metadata.series.indoor_temperature.data[current_m.valueOf()] =
|
||||
indoor_temperature;
|
||||
y_min_max(indoor_temperature);
|
||||
data.metadata.series.indoor_temperature.active = true;
|
||||
|
||||
/**
|
||||
* Add setpoints, but only when relevant. For example: Only show the
|
||||
* heat setpoint line when the heat is actually on.
|
||||
|
@ -12,7 +12,6 @@ beestat.setting = function(key, opt_value, opt_callback) {
|
||||
var user = beestat.user.get();
|
||||
|
||||
var defaults = {
|
||||
'runtime_thermostat_detail_smoothing': true,
|
||||
'runtime_thermostat_detail_range_type': 'dynamic',
|
||||
'runtime_thermostat_detail_range_static_begin': moment()
|
||||
.subtract(3, 'day')
|
||||
@ -20,7 +19,6 @@ beestat.setting = function(key, opt_value, opt_callback) {
|
||||
'runtime_thermostat_detail_range_static_end': moment().format('MM/DD/YYYY'),
|
||||
'runtime_thermostat_detail_range_dynamic': 3,
|
||||
|
||||
'runtime_sensor_detail_smoothing': true,
|
||||
'runtime_sensor_detail_range_type': 'dynamic',
|
||||
'runtime_sensor_detail_range_static_begin': moment()
|
||||
.subtract(3, 'day')
|
||||
|
@ -24,7 +24,6 @@ beestat.component.card.runtime_sensor_detail = function(thermostat_id) {
|
||||
|
||||
beestat.dispatcher.addEventListener(
|
||||
[
|
||||
'setting.runtime_sensor_detail_smoothing',
|
||||
'setting.runtime_sensor_detail_range_type',
|
||||
'setting.runtime_sensor_detail_range_dynamic',
|
||||
'cache.runtime_thermostat',
|
||||
@ -305,22 +304,6 @@ beestat.component.card.runtime_sensor_detail.prototype.decorate_top_right_ = fun
|
||||
self.charts_.temperature.reset_zoom();
|
||||
}));
|
||||
|
||||
if (beestat.setting('runtime_sensor_detail_smoothing') === true) {
|
||||
menu.add_menu_item(new beestat.component.menu_item()
|
||||
.set_text('Disable Smothing')
|
||||
.set_icon('chart_line')
|
||||
.set_callback(function() {
|
||||
beestat.setting('runtime_sensor_detail_smoothing', false);
|
||||
}));
|
||||
} else {
|
||||
menu.add_menu_item(new beestat.component.menu_item()
|
||||
.set_text('Enable Smoothing')
|
||||
.set_icon('chart_bell_curve')
|
||||
.set_callback(function() {
|
||||
beestat.setting('runtime_sensor_detail_smoothing', true);
|
||||
}));
|
||||
}
|
||||
|
||||
menu.add_menu_item(new beestat.component.menu_item()
|
||||
.set_text('Help')
|
||||
.set_icon('help_circle')
|
||||
|
@ -24,7 +24,6 @@ beestat.component.card.runtime_thermostat_detail = function(thermostat_id) {
|
||||
|
||||
beestat.dispatcher.addEventListener(
|
||||
[
|
||||
'setting.runtime_thermostat_detail_smoothing',
|
||||
'setting.runtime_thermostat_detail_range_type',
|
||||
'setting.runtime_thermostat_detail_range_dynamic',
|
||||
'cache.runtime_thermostat'
|
||||
@ -291,22 +290,6 @@ beestat.component.card.runtime_thermostat_detail.prototype.decorate_top_right_ =
|
||||
self.charts_.temperature.reset_zoom();
|
||||
}));
|
||||
|
||||
if (beestat.setting('runtime_thermostat_detail_smoothing') === true) {
|
||||
menu.add_menu_item(new beestat.component.menu_item()
|
||||
.set_text('Disable Smothing')
|
||||
.set_icon('chart_line')
|
||||
.set_callback(function() {
|
||||
beestat.setting('runtime_thermostat_detail_smoothing', false);
|
||||
}));
|
||||
} else {
|
||||
menu.add_menu_item(new beestat.component.menu_item()
|
||||
.set_text('Enable Smoothing')
|
||||
.set_icon('chart_bell_curve')
|
||||
.set_callback(function() {
|
||||
beestat.setting('runtime_thermostat_detail_smoothing', true);
|
||||
}));
|
||||
}
|
||||
|
||||
menu.add_menu_item(new beestat.component.menu_item()
|
||||
.set_text('Help')
|
||||
.set_icon('help_circle')
|
||||
|
Loading…
x
Reference in New Issue
Block a user