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

Fixed runtime data not auto-updating, added data age check when resuming from background

This commit is contained in:
Jon Ziebell 2023-10-17 17:59:24 -04:00
parent 1c8b97381f
commit e3db43a44e
9 changed files with 92 additions and 40 deletions

View File

@ -62,7 +62,7 @@ beestat.api.prototype.send = function(opt_api_call) {
*/ */
if (this.callback_ !== undefined) { if (this.callback_ !== undefined) {
window.setTimeout(function() { window.setTimeout(function() {
self.callback_(self.cached_batch_api_calls_); self.callback_(self.cached_batch_api_calls_, true);
}, 0); }, 0);
} }
} else { } else {
@ -81,7 +81,7 @@ beestat.api.prototype.send = function(opt_api_call) {
* problems. * problems.
*/ */
window.setTimeout(function() { window.setTimeout(function() {
self.callback_(cached.data); self.callback_(cached.data, true);
}, 0); }, 0);
} }
} else { } else {
@ -262,7 +262,7 @@ beestat.api.prototype.load_ = function(response_text) {
// Callback // Callback
if (this.callback_ !== undefined) { if (this.callback_ !== undefined) {
this.callback_(response.data); this.callback_(response.data, false);
} }
}; };

View File

@ -7,26 +7,36 @@ beestat.cache = {
* *
* @param {string} key The cache key to update. * @param {string} key The cache key to update.
* @param {object} value The data to be placed in that key. * @param {object} value The data to be placed in that key.
* @param {boolean} dispatch Whether or not to dispatch the event. Default
* true.
*/ */
beestat.cache.set = function(key, value) { beestat.cache.set = function(key, value, dispatch) {
if (key.substring(0, 5) === 'data.') { if (key.substring(0, 5) === 'data.') {
beestat.cache.data[key.substring(5)] = value; beestat.cache.data[key.substring(5)] = value;
} else { } else {
beestat.cache[key] = value; beestat.cache[key] = value;
} }
if (dispatch !== false) {
beestat.dispatcher.dispatchEvent('cache.' + key); beestat.dispatcher.dispatchEvent('cache.' + key);
}
}; };
/** /**
* Delete data from the cache. Dispatches an event when done. * Delete data from the cache. Dispatches an event when done.
* *
* @param {string} key The cache key to delete. * @param {string} key The cache key to delete.
* @param {boolean} dispatch Whether or not to dispatch the event. Default
* true.
*/ */
beestat.cache.delete = function(key) { beestat.cache.delete = function(key, dispatch) {
if (key.substring(0, 5) === 'data.') { if (key.substring(0, 5) === 'data.') {
delete beestat.cache.data[key.substring(5)]; delete beestat.cache.data[key.substring(5)];
} else { } else {
delete beestat.cache[key]; delete beestat.cache[key];
} }
if (dispatch !== false) {
beestat.dispatcher.dispatchEvent('cache.' + key); beestat.dispatcher.dispatchEvent('cache.' + key);
}
}; };

View File

@ -1,19 +1,41 @@
beestat.enable_poll = function() { beestat.enable_poll = function() {
window.clearTimeout(beestat.poll_timeout); window.clearTimeout(beestat.poll_timeout);
if (beestat.poll_intervals.length > 0) {
beestat.poll_timeout = window.setTimeout( beestat.poll_timeout = window.setTimeout(
beestat.poll, beestat.poll,
Math.min.apply(null, beestat.poll_intervals) 60000 * 5
); );
};
beestat.enable_poll_watcher = function() {
window.clearTimeout(beestat.poll_watcher_timeout);
beestat.poll_watcher_timeout = window.setTimeout(
beestat.poll_watcher,
1000
);
};
/**
* Check every second for when the last successful poll was. Used for when the
* app is sent to the background and the polling stops to ensure an update is
* run immediately.
*/
beestat.poll_watcher = function() {
if (
beestat.poll_last !== undefined &&
beestat.poll_last.isBefore(moment().subtract(6, 'minute')) === true
) {
window.clearTimeout(beestat.poll_timeout);
beestat.poll();
} }
beestat.enable_poll_watcher();
}; };
/** /**
* Poll the database for changes and update the cache. * Poll the database for changes and update the cache.
*/ */
window.last_poll = moment();
beestat.poll = function() { beestat.poll = function() {
window.last_poll = moment(); beestat.poll_last = moment();
var api = new beestat.api(); var api = new beestat.api();
@ -88,14 +110,38 @@ beestat.poll = function() {
beestat.cache.set('sensor', response.sensor); beestat.cache.set('sensor', response.sensor);
beestat.cache.set('ecobee_thermostat', response.ecobee_thermostat); beestat.cache.set('ecobee_thermostat', response.ecobee_thermostat);
beestat.cache.set('ecobee_sensor', response.ecobee_sensor); beestat.cache.set('ecobee_sensor', response.ecobee_sensor);
beestat.enable_poll(); beestat.enable_poll();
beestat.ecobee.notify_if_down(); beestat.ecobee.notify_if_down();
}); });
api.send(); api.send();
};
// Five minutes /**
beestat.default_poll_interval = 300000; * Send this every poll but don't specifically do anything with the
beestat.poll_intervals = [beestat.default_poll_interval]; * response. The caching won't allow it to send every time, but it should at
* least keep up.
*/
new beestat.api()
.add_call(
'runtime',
'sync',
{
'thermostat_id': beestat.setting('thermostat_id')
}
)
.set_callback(function(response, from_cache) {
if (from_cache === false) {
// Delete this cached data so the charts update.
beestat.cache.delete('data.runtime_thermostat_detail__runtime_thermostat');
beestat.cache.delete('data.runtime_sensor_detail__runtime_thermostat');
beestat.cache.delete('data.runtime_sensor_detail__runtime_sensor');
beestat.cache.delete('data.air_quality_detail__runtime_thermostat');
beestat.cache.delete('data.air_quality_detail__runtime_sensor');
beestat.cache.delete('data.three_d__runtime_sensor');
beestat.cache.delete('data.three_d__runtime_thermostat');
}
})
.send();
};

View File

@ -19,7 +19,6 @@ beestat.component.card.air_quality_detail = function(thermostat_id) {
* for when rerendering. * for when rerendering.
*/ */
var change_function = beestat.debounce(function() { var change_function = beestat.debounce(function() {
self.get_data_(true);
self.rerender(); self.rerender();
}, 10); }, 10);
@ -43,6 +42,8 @@ beestat.extend(beestat.component.card.air_quality_detail, beestat.component.card
beestat.component.card.air_quality_detail.prototype.decorate_contents_ = function(parent) { beestat.component.card.air_quality_detail.prototype.decorate_contents_ = function(parent) {
var self = this; var self = this;
delete this.data_;
this.charts_ = { this.charts_ = {
'occupancy': new beestat.component.chart.runtime_sensor_detail_occupancy( 'occupancy': new beestat.component.chart.runtime_sensor_detail_occupancy(
this.get_data_() this.get_data_()
@ -347,10 +348,10 @@ beestat.component.card.air_quality_detail.prototype.has_data_ = function() {
* *
* @return {object} The data. * @return {object} The data.
*/ */
beestat.component.card.air_quality_detail.prototype.get_data_ = function(force) { beestat.component.card.air_quality_detail.prototype.get_data_ = function() {
const self = this; const self = this;
if (this.data_ === undefined || force === true) { if (this.data_ === undefined) {
var range = { var range = {
'type': beestat.setting('air_quality_detail_range_type'), 'type': beestat.setting('air_quality_detail_range_type'),
'dynamic': beestat.setting('air_quality_detail_range_dynamic'), 'dynamic': beestat.setting('air_quality_detail_range_dynamic'),

View File

@ -19,7 +19,6 @@ beestat.component.card.runtime_sensor_detail = function(thermostat_id) {
* for when rerendering. * for when rerendering.
*/ */
var change_function = beestat.debounce(function() { var change_function = beestat.debounce(function() {
self.get_data_(true);
self.rerender(); self.rerender();
}, 10); }, 10);
@ -43,6 +42,8 @@ beestat.extend(beestat.component.card.runtime_sensor_detail, beestat.component.c
beestat.component.card.runtime_sensor_detail.prototype.decorate_contents_ = function(parent) { beestat.component.card.runtime_sensor_detail.prototype.decorate_contents_ = function(parent) {
var self = this; var self = this;
delete this.data_;
this.charts_ = { this.charts_ = {
'equipment': new beestat.component.chart.runtime_thermostat_detail_equipment( 'equipment': new beestat.component.chart.runtime_thermostat_detail_equipment(
this.get_data_() this.get_data_()
@ -356,10 +357,10 @@ beestat.component.card.runtime_sensor_detail.prototype.has_data_ = function() {
* *
* @return {object} The data. * @return {object} The data.
*/ */
beestat.component.card.runtime_sensor_detail.prototype.get_data_ = function(force) { beestat.component.card.runtime_sensor_detail.prototype.get_data_ = function() {
const self = this; const self = this;
if (this.data_ === undefined || force === true) { if (this.data_ === undefined) {
var range = { var range = {
'type': beestat.setting('runtime_sensor_detail_range_type'), 'type': beestat.setting('runtime_sensor_detail_range_type'),
'dynamic': beestat.setting('runtime_sensor_detail_range_dynamic'), 'dynamic': beestat.setting('runtime_sensor_detail_range_dynamic'),

View File

@ -19,15 +19,11 @@ beestat.component.card.runtime_thermostat_detail = function(thermostat_id) {
* for when rerendering. * for when rerendering.
*/ */
var change_function = beestat.debounce(function() { var change_function = beestat.debounce(function() {
self.get_data_(true);
self.rerender(); self.rerender();
}, 10); }, 10);
beestat.dispatcher.addEventListener( beestat.dispatcher.addEventListener(
[
'cache.data.runtime_thermostat_detail__runtime_thermostat', 'cache.data.runtime_thermostat_detail__runtime_thermostat',
'cache.thermostat'
],
change_function change_function
); );
@ -43,6 +39,8 @@ beestat.extend(beestat.component.card.runtime_thermostat_detail, beestat.compone
beestat.component.card.runtime_thermostat_detail.prototype.decorate_contents_ = function(parent) { beestat.component.card.runtime_thermostat_detail.prototype.decorate_contents_ = function(parent) {
var self = this; var self = this;
delete this.data_;
this.charts_ = { this.charts_ = {
'equipment': new beestat.component.chart.runtime_thermostat_detail_equipment( 'equipment': new beestat.component.chart.runtime_thermostat_detail_equipment(
this.get_data_() this.get_data_()
@ -339,12 +337,10 @@ beestat.component.card.runtime_thermostat_detail.prototype.has_data_ = function(
* Get data. This doesn't directly or indirectly make any API calls, but it * Get data. This doesn't directly or indirectly make any API calls, but it
* caches the data so it doesn't have to loop over everything more than once. * caches the data so it doesn't have to loop over everything more than once.
* *
* @param {boolean} force Force get the data?
*
* @return {object} The data. * @return {object} The data.
*/ */
beestat.component.card.runtime_thermostat_detail.prototype.get_data_ = function(force) { beestat.component.card.runtime_thermostat_detail.prototype.get_data_ = function() {
if (this.data_ === undefined || force === true) { if (this.data_ === undefined) {
var range = { var range = {
'type': beestat.setting('runtime_thermostat_detail_range_type'), 'type': beestat.setting('runtime_thermostat_detail_range_type'),
'dynamic': beestat.setting('runtime_thermostat_detail_range_dynamic'), 'dynamic': beestat.setting('runtime_thermostat_detail_range_dynamic'),

View File

@ -28,7 +28,6 @@ beestat.component.card.three_d = function() {
const change_function = beestat.debounce(function() { const change_function = beestat.debounce(function() {
self.state_.scene_camera_state = self.scene_.get_camera_state(); self.state_.scene_camera_state = self.scene_.get_camera_state();
self.get_data_(true);
self.rerender(); self.rerender();
}, 10); }, 10);
@ -82,6 +81,8 @@ beestat.component.card.three_d.prototype.decorate_ = function(parent) {
* @param {rocket.Elements} parent * @param {rocket.Elements} parent
*/ */
beestat.component.card.three_d.prototype.decorate_contents_ = function(parent) { beestat.component.card.three_d.prototype.decorate_contents_ = function(parent) {
delete this.data_;
const drawing_pane_container = document.createElement('div'); const drawing_pane_container = document.createElement('div');
drawing_pane_container.style.overflowX = 'hidden'; drawing_pane_container.style.overflowX = 'hidden';
@ -883,9 +884,9 @@ beestat.component.card.three_d.prototype.decorate_legend_ = function(parent) {
* *
* @return {object} The data. * @return {object} The data.
*/ */
beestat.component.card.three_d.prototype.get_data_ = function(force) { beestat.component.card.three_d.prototype.get_data_ = function() {
const self = this; const self = this;
if (this.data_ === undefined || force === true) { if (this.data_ === undefined) {
const sensor_ids_map = beestat.floor_plan.get_sensor_ids_map(this.floor_plan_id_); const sensor_ids_map = beestat.floor_plan.get_sensor_ids_map(this.floor_plan_id_);
const thermostat_ids_map = beestat.floor_plan.get_thermostat_ids_map(this.floor_plan_id_); const thermostat_ids_map = beestat.floor_plan.get_thermostat_ids_map(this.floor_plan_id_);

View File

@ -38,10 +38,6 @@ beestat.component.modal.thermostat_info.prototype.decorate_contents_ = function(
'name': 'First Connected', 'name': 'First Connected',
'value': moment.utc(ecobee_thermostat.runtime.firstConnected).local() 'value': moment.utc(ecobee_thermostat.runtime.firstConnected).local()
.format('MMM Do, YYYY') .format('MMM Do, YYYY')
},
{
'name': '#',
'value': window.last_poll.format()
} }
]; ];

View File

@ -276,6 +276,7 @@ beestat.layer.load.prototype.decorate_ = function(parent) {
// Enable polling for live updates // Enable polling for live updates
beestat.enable_poll(); beestat.enable_poll();
beestat.enable_poll_watcher();
(new beestat.layer.detail()).render(); (new beestat.layer.detail()).render();