1
0
mirror of https://github.com/beestat/app.git synced 2025-05-24 02:14:03 -04:00

Added "More Info" temperature profiles modal with trendline formulas

Fixed for °C Hope all you Canadians and Australians are happy now.
This commit is contained in:
Jon Ziebell 2023-01-28 08:05:19 -05:00
parent b47debf3cc
commit 887f252e2b
4 changed files with 61 additions and 46 deletions

41
js/beestat/math.js Normal file
View File

@ -0,0 +1,41 @@
beestat.math = {};
/**
* Get a linear trendline from a set of data.
*
* @param {Object} data The data; at least two points required.
*
* @return {Object} The slope and intercept of the trendline.
*/
beestat.math.get_linear_trendline = function(data) {
// Requires at least two points.
if (Object.keys(data).length < 2) {
return null;
}
var sum_x = 0;
var sum_y = 0;
var sum_xy = 0;
var sum_x_squared = 0;
var n = 0;
for (var x in data) {
x = parseFloat(x);
var y = parseFloat(data[x]);
sum_x += x;
sum_y += y;
sum_xy += (x * y);
sum_x_squared += Math.pow(x, 2);
n++;
}
var slope = ((n * sum_xy) - (sum_x * sum_y)) /
((n * sum_x_squared) - (Math.pow(sum_x, 2)));
var intercept = ((sum_y) - (slope * sum_x)) / (n);
return {
'slope': slope,
'intercept': intercept
};
};

View File

@ -138,7 +138,7 @@ beestat.component.card.temperature_profiles.prototype.get_data_ = function() {
}
profile.deltas = deltas_converted;
var linear_trendline = this.get_linear_trendline_(profile.deltas);
var linear_trendline = beestat.math.get_linear_trendline(profile.deltas);
var min_max_keys = Object.keys(profile.deltas);
@ -215,49 +215,6 @@ beestat.component.card.temperature_profiles.prototype.get_data_ = function() {
return data;
};
/**
* Get a linear trendline from a set of data.
*
* IMPORTANT: This exists in the profile already but it's wrong to use it
* directly as it's not right for Celsius.
*
* @param {Object} data The data; at least two points required.
*
* @return {Object} The slope and intercept of the trendline.
*/
beestat.component.card.temperature_profiles.prototype.get_linear_trendline_ = function(data) {
// Requires at least two points.
if (Object.keys(data).length < 2) {
return null;
}
var sum_x = 0;
var sum_y = 0;
var sum_xy = 0;
var sum_x_squared = 0;
var n = 0;
for (var x in data) {
x = parseFloat(x);
var y = parseFloat(data[x]);
sum_x += x;
sum_y += y;
sum_xy += (x * y);
sum_x_squared += Math.pow(x, 2);
n++;
}
var slope = ((n * sum_xy) - (sum_x * sum_y)) /
((n * sum_x_squared) - (Math.pow(sum_x, 2)));
var intercept = ((sum_y) - (slope * sum_x)) / (n);
return {
'slope': slope,
'intercept': intercept
};
};
/**
* Get the title of the card.
*

View File

@ -29,13 +29,29 @@ beestat.component.modal.temperature_profiles_info.prototype.decorate_contents_ =
'resist'
].forEach(function(type) {
if (thermostat.profile.temperature[type] !== null) {
const profile = thermostat.profile.temperature[type];
// Convert the data to Celsius if necessary
const deltas_converted = {};
for (let key in profile.deltas) {
deltas_converted[beestat.temperature({'temperature': key})] =
beestat.temperature({
'temperature': (profile.deltas[key]),
'delta': true,
'round': 3
});
}
profile.deltas = deltas_converted;
const linear_trendline = beestat.math.get_linear_trendline(profile.deltas);
fields.push({
'name': beestat.series['indoor_' + type + '_delta'].name,
'value':
'Slope = ' +
thermostat.profile.temperature[type].linear_trendline.slope +
linear_trendline.slope.toFixed(4) +
'<br/>Intercept = ' +
thermostat.profile.temperature[type].linear_trendline.intercept
linear_trendline.intercept.toFixed(4) + beestat.setting('units.temperature')
});
}
});

View File

@ -49,6 +49,7 @@ if($setting->get('environment') === 'dev' || $setting->get('environment') === 'd
echo '<script src="/js/beestat/address.js"></script>' . PHP_EOL;
echo '<script src="/js/beestat/affiliate.js"></script>' . PHP_EOL;
echo '<script src="/js/beestat/date.js"></script>' . PHP_EOL;
echo '<script src="/js/beestat/math.js"></script>' . PHP_EOL;
// Layer
echo '<script src="/js/layer.js"></script>' . PHP_EOL;