mirror of
https://github.com/beestat/app.git
synced 2025-05-24 02:14:03 -04:00
Loading now doesn't break if the sync fails, and as a bonus that made it trivial to display whether or not ecobee is down.
This commit is contained in:
parent
deaf81e214
commit
a6564305b0
@ -857,7 +857,7 @@ final class database extends \mysqli {
|
|||||||
');
|
');
|
||||||
$row = $result->fetch_assoc();
|
$row = $result->fetch_assoc();
|
||||||
if($row['lock'] !== 1) {
|
if($row['lock'] !== 1) {
|
||||||
throw new \Exception('Could not get lock.', 1209);
|
throw new exception('Could not get lock.', 1209);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,8 @@ class runtime extends cora\api {
|
|||||||
*
|
*
|
||||||
* @param int $thermostat_id Optional thermostat_id to sync. If not set will
|
* @param int $thermostat_id Optional thermostat_id to sync. If not set will
|
||||||
* sync all thermostats attached to this user.
|
* sync all thermostats attached to this user.
|
||||||
|
*
|
||||||
|
* @return boolean true if the sync ran, false if not.
|
||||||
*/
|
*/
|
||||||
public function sync($thermostat_id = null) {
|
public function sync($thermostat_id = null) {
|
||||||
// Skip this for the demo
|
// Skip this for the demo
|
||||||
@ -42,54 +44,58 @@ class runtime extends cora\api {
|
|||||||
|
|
||||||
set_time_limit(0);
|
set_time_limit(0);
|
||||||
|
|
||||||
if($thermostat_id === null) {
|
try {
|
||||||
$thermostat_ids = array_keys(
|
if($thermostat_id === null) {
|
||||||
$this->api(
|
$thermostat_ids = array_keys(
|
||||||
'thermostat',
|
$this->api(
|
||||||
'read_id',
|
'thermostat',
|
||||||
[
|
'read_id',
|
||||||
'attributes' => [
|
[
|
||||||
'inactive' => 0
|
'attributes' => [
|
||||||
|
'inactive' => 0
|
||||||
|
]
|
||||||
]
|
]
|
||||||
]
|
)
|
||||||
)
|
);
|
||||||
);
|
|
||||||
} else {
|
|
||||||
$this->user_lock($thermostat_id);
|
|
||||||
$thermostat_ids = [$thermostat_id];
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach($thermostat_ids as $thermostat_id) {
|
|
||||||
// Get a lock to ensure that this is not invoked more than once at a time
|
|
||||||
// per thermostat.
|
|
||||||
$lock_name = 'runtime->sync(' . $thermostat_id . ')';
|
|
||||||
$this->database->get_lock($lock_name);
|
|
||||||
|
|
||||||
$thermostat = $this->api('thermostat', 'get', $thermostat_id);
|
|
||||||
|
|
||||||
if(
|
|
||||||
$thermostat['sync_begin'] === $thermostat['first_connected'] ||
|
|
||||||
(
|
|
||||||
$thermostat['sync_begin'] !== null &&
|
|
||||||
strtotime($thermostat['sync_begin']) <= strtotime('-1 year')
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
$this->sync_forwards($thermostat_id);
|
|
||||||
} else {
|
} else {
|
||||||
$this->sync_backwards($thermostat_id);
|
$this->user_lock($thermostat_id);
|
||||||
|
$thermostat_ids = [$thermostat_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
// If only syncing one thermostat this will delay the sync of the other
|
foreach($thermostat_ids as $thermostat_id) {
|
||||||
// thermostat. Not a huge deal, just FYI.
|
// Get a lock to ensure that this is not invoked more than once at a time
|
||||||
$this->api(
|
// per thermostat.
|
||||||
'user',
|
$lock_name = 'runtime->sync(' . $thermostat_id . ')';
|
||||||
'update_sync_status',
|
$this->database->get_lock($lock_name);
|
||||||
[
|
|
||||||
'key' => 'runtime'
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->database->release_lock($lock_name);
|
$thermostat = $this->api('thermostat', 'get', $thermostat_id);
|
||||||
|
|
||||||
|
if(
|
||||||
|
$thermostat['sync_begin'] === $thermostat['first_connected'] ||
|
||||||
|
(
|
||||||
|
$thermostat['sync_begin'] !== null &&
|
||||||
|
strtotime($thermostat['sync_begin']) <= strtotime('-1 year')
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
$this->sync_forwards($thermostat_id);
|
||||||
|
} else {
|
||||||
|
$this->sync_backwards($thermostat_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If only syncing one thermostat this will delay the sync of the other
|
||||||
|
// thermostat. Not a huge deal, just FYI.
|
||||||
|
$this->api(
|
||||||
|
'user',
|
||||||
|
'update_sync_status',
|
||||||
|
[
|
||||||
|
'key' => 'runtime'
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->database->release_lock($lock_name);
|
||||||
|
}
|
||||||
|
} catch(cora\exception $e) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,9 +46,10 @@ class sensor extends cora\crud {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sync all sensors connected to this account. Once Nest support is
|
* Sync all sensors for the current user. If we fail to get a lock, fail
|
||||||
* added this will need to check for all connected accounts and run the
|
* silently (catch the exception) and just return false.
|
||||||
* appropriate ones.
|
*
|
||||||
|
* @return boolean true if the sync ran, false if not.
|
||||||
*/
|
*/
|
||||||
public function sync() {
|
public function sync() {
|
||||||
// Skip this for the demo
|
// Skip this for the demo
|
||||||
@ -56,20 +57,24 @@ class sensor extends cora\crud {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$lock_name = 'sensor->sync(' . $this->session->get_user_id() . ')';
|
try {
|
||||||
$this->database->get_lock($lock_name);
|
$lock_name = 'sensor->sync(' . $this->session->get_user_id() . ')';
|
||||||
|
$this->database->get_lock($lock_name);
|
||||||
|
|
||||||
$this->api('ecobee_sensor', 'sync');
|
$this->api('ecobee_sensor', 'sync');
|
||||||
|
|
||||||
$this->api(
|
$this->api(
|
||||||
'user',
|
'user',
|
||||||
'update_sync_status',
|
'update_sync_status',
|
||||||
[
|
[
|
||||||
'key' => 'sensor'
|
'key' => 'sensor'
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->database->release_lock($lock_name);
|
$this->database->release_lock($lock_name);
|
||||||
|
} catch(cora\exception $e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,26 +22,35 @@ class thermostat extends cora\crud {
|
|||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sync all thermostats for the current user with their associated service.
|
* Sync all thermostats for the current user. If we fail to get a lock, fail
|
||||||
|
* silently (catch the exception) and just return false.
|
||||||
|
*
|
||||||
|
* @return boolean true if the sync ran, false if not.
|
||||||
*/
|
*/
|
||||||
public function sync() {
|
public function sync() {
|
||||||
// Skip this for the demo
|
// Skip this for the demo
|
||||||
if($this->setting->is_demo() === true) {
|
if($this->setting->is_demo() === true) {
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$lock_name = 'thermostat->sync(' . $this->session->get_user_id() . ')';
|
try {
|
||||||
$this->database->get_lock($lock_name);
|
$lock_name = 'thermostat->sync(' . $this->session->get_user_id() . ')';
|
||||||
|
$this->database->get_lock($lock_name);
|
||||||
|
|
||||||
$this->api('ecobee_thermostat', 'sync');
|
$this->api('ecobee_thermostat', 'sync');
|
||||||
|
|
||||||
$this->api(
|
$this->api(
|
||||||
'user',
|
'user',
|
||||||
'update_sync_status',
|
'update_sync_status',
|
||||||
['key' => 'thermostat']
|
['key' => 'thermostat']
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->database->release_lock($lock_name);
|
$this->database->release_lock($lock_name);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch(cora\exception $e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -20,7 +20,6 @@ beestat.ecobee_thermostat_models = {
|
|||||||
'vulcanSmart': 'SmartThermostat'
|
'vulcanSmart': 'SmartThermostat'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a default value for an argument if it is not currently set.
|
* Get a default value for an argument if it is not currently set.
|
||||||
*
|
*
|
||||||
@ -106,16 +105,6 @@ beestat.get_thermostat_color = function(thermostat_id) {
|
|||||||
return beestat.style.color.bluegray.dark;
|
return beestat.style.color.bluegray.dark;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the current user.
|
|
||||||
*
|
|
||||||
* @return {object}
|
|
||||||
*/
|
|
||||||
beestat.get_user = function() {
|
|
||||||
var user_id = Object.keys(beestat.cache.user)[0];
|
|
||||||
return beestat.cache.user[user_id];
|
|
||||||
};
|
|
||||||
|
|
||||||
// Register service worker
|
// Register service worker
|
||||||
if ('serviceWorker' in navigator) {
|
if ('serviceWorker' in navigator) {
|
||||||
window.addEventListener('load', function() {
|
window.addEventListener('load', function() {
|
||||||
|
@ -178,8 +178,6 @@ beestat.api.prototype.load_ = function(response_text) {
|
|||||||
) {
|
) {
|
||||||
window.location.href = '/';
|
window.location.href = '/';
|
||||||
return;
|
return;
|
||||||
} else if (response.data && response.data.error_code === 1209) {
|
|
||||||
// Could not get lock; safe to ignore as that means sync is running.
|
|
||||||
} else if (response.success !== true) {
|
} else if (response.success !== true) {
|
||||||
beestat.error(
|
beestat.error(
|
||||||
'API call failed: ' + response.data.error_message,
|
'API call failed: ' + response.data.error_message,
|
||||||
|
25
js/beestat/ecobee.js
Normal file
25
js/beestat/ecobee.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
beestat.ecobee = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check to see if ecobee is down. If so, render the footer component.
|
||||||
|
*/
|
||||||
|
beestat.ecobee.notify_if_down = function() {
|
||||||
|
if (
|
||||||
|
beestat.cache !== undefined &&
|
||||||
|
beestat.cache.thermostat !== undefined &&
|
||||||
|
beestat.user.get() !== undefined
|
||||||
|
) {
|
||||||
|
var last_update = moment.utc(beestat.user.get().sync_status.thermostat);
|
||||||
|
var down = last_update.isBefore(moment().subtract(15, 'minutes'));
|
||||||
|
|
||||||
|
if (beestat.ecobee.down_notification_ === undefined) {
|
||||||
|
beestat.ecobee.down_notification_ = new beestat.component.down_notification();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (down === true) {
|
||||||
|
beestat.ecobee.down_notification_.render($('body'));
|
||||||
|
} else {
|
||||||
|
beestat.ecobee.down_notification_.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
@ -95,6 +95,8 @@ beestat.poll = function() {
|
|||||||
beestat.cache.set('ecobee_sensor', response.ecobee_sensor);
|
beestat.cache.set('ecobee_sensor', response.ecobee_sensor);
|
||||||
beestat.enable_poll();
|
beestat.enable_poll();
|
||||||
beestat.dispatcher.dispatchEvent('poll');
|
beestat.dispatcher.dispatchEvent('poll');
|
||||||
|
|
||||||
|
beestat.ecobee.notify_if_down();
|
||||||
});
|
});
|
||||||
|
|
||||||
api.send();
|
api.send();
|
||||||
|
@ -6,8 +6,6 @@ beestat.component = function() {
|
|||||||
// Give every component a state object to use for storing data.
|
// Give every component a state object to use for storing data.
|
||||||
this.state_ = {};
|
this.state_ = {};
|
||||||
|
|
||||||
// this.render_count_ = 0;
|
|
||||||
|
|
||||||
this.layer_ = beestat.current_layer;
|
this.layer_ = beestat.current_layer;
|
||||||
|
|
||||||
if (this.rerender_on_breakpoint_ === true) {
|
if (this.rerender_on_breakpoint_ === true) {
|
||||||
@ -28,26 +26,27 @@ beestat.extend(beestat.component, rocket.EventTarget);
|
|||||||
* @return {beestat.component} This
|
* @return {beestat.component} This
|
||||||
*/
|
*/
|
||||||
beestat.component.prototype.render = function(parent) {
|
beestat.component.prototype.render = function(parent) {
|
||||||
var self = this;
|
if (this.rendered_ === false) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
if (parent !== undefined) {
|
if (parent !== undefined) {
|
||||||
this.component_container_ = $.createElement('div')
|
this.component_container_ = $.createElement('div')
|
||||||
.style('position', 'relative');
|
.style('position', 'relative');
|
||||||
this.decorate_(this.component_container_);
|
this.decorate_(this.component_container_);
|
||||||
parent.appendChild(this.component_container_);
|
parent.appendChild(this.component_container_);
|
||||||
} else {
|
} else {
|
||||||
this.decorate_();
|
this.decorate_();
|
||||||
|
}
|
||||||
|
|
||||||
|
// The element should now exist on the DOM.
|
||||||
|
setTimeout(function() {
|
||||||
|
self.dispatchEvent('render');
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
// The render function was called.
|
||||||
|
this.rendered_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The element should now exist on the DOM.
|
|
||||||
setTimeout(function() {
|
|
||||||
self.dispatchEvent('render');
|
|
||||||
}, 0);
|
|
||||||
|
|
||||||
// The render function was called.
|
|
||||||
this.rendered_ = true;
|
|
||||||
// this.render_count_++;
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -71,21 +70,20 @@ beestat.component.prototype.rerender = function() {
|
|||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
self.dispatchEvent('render');
|
self.dispatchEvent('render');
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
// this.render_count_++;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove this component from the page.
|
* Remove this component from the page.
|
||||||
*/
|
*/
|
||||||
beestat.component.prototype.dispose = function() {
|
beestat.component.prototype.dispose = function() {
|
||||||
var child = this.component_container_.parentNode();
|
if (this.rendered_ === true) {
|
||||||
var parent = child.parentNode();
|
var child = this.component_container_;
|
||||||
parent.removeChild(child);
|
var parent = child.parentNode();
|
||||||
this.rendered_ = false;
|
parent.removeChild(child);
|
||||||
|
this.rendered_ = false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
beestat.component.prototype.decorate_ = function() {
|
beestat.component.prototype.decorate_ = function() {
|
||||||
|
34
js/component/down_notification.js
Normal file
34
js/component/down_notification.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
* Ecobee is down!
|
||||||
|
*/
|
||||||
|
beestat.component.down_notification = function() {
|
||||||
|
beestat.component.apply(this, arguments);
|
||||||
|
};
|
||||||
|
beestat.extend(beestat.component.down_notification, beestat.component);
|
||||||
|
|
||||||
|
beestat.component.down_notification.prototype.rerender_on_breakpoint_ = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decorate a floating banner at the bottom of the page.
|
||||||
|
*
|
||||||
|
* @param {rocket.Elements} parent
|
||||||
|
*/
|
||||||
|
beestat.component.down_notification.prototype.decorate_ = function(parent) {
|
||||||
|
var div = $.createElement('div');
|
||||||
|
div.style({
|
||||||
|
'position': 'fixed',
|
||||||
|
'bottom': '0px',
|
||||||
|
'left': '0px',
|
||||||
|
'width': '100%',
|
||||||
|
'text-align': 'center',
|
||||||
|
'padding-left': beestat.style.size.gutter,
|
||||||
|
'padding-right': beestat.style.size.gutter,
|
||||||
|
'background': beestat.style.color.red.dark
|
||||||
|
});
|
||||||
|
|
||||||
|
var last_update = moment.utc(beestat.user.get().sync_status.thermostat).local()
|
||||||
|
.format('h:m a');
|
||||||
|
div.appendChild($.createElement('p').innerText('Ecobee seems to be down. Your data will update as soon as possible. Last update was at ' + last_update + '.'));
|
||||||
|
|
||||||
|
parent.appendChild(div);
|
||||||
|
};
|
@ -19,7 +19,6 @@ beestat.component.menu.prototype.decorate_ = function(parent) {
|
|||||||
.set_bubble_text(this.bubble_text_)
|
.set_bubble_text(this.bubble_text_)
|
||||||
.set_bubble_color(this.bubble_color_)
|
.set_bubble_color(this.bubble_color_)
|
||||||
.set_text_color('#fff')
|
.set_text_color('#fff')
|
||||||
// .set_background_hover_color(beestat.style.color.bluegray.light)
|
|
||||||
.set_background_hover_color('rgba(255, 255, 255, 0.1')
|
.set_background_hover_color('rgba(255, 255, 255, 0.1')
|
||||||
.addEventListener('click', function() {
|
.addEventListener('click', function() {
|
||||||
// Did I just try to open the same menu as last time?
|
// Did I just try to open the same menu as last time?
|
||||||
@ -41,12 +40,20 @@ beestat.component.menu.prototype.decorate_ = function(parent) {
|
|||||||
* Close this menu by hiding the container and removing the event listeners.
|
* Close this menu by hiding the container and removing the event listeners.
|
||||||
*/
|
*/
|
||||||
beestat.component.menu.prototype.dispose = function() {
|
beestat.component.menu.prototype.dispose = function() {
|
||||||
|
var self = this;
|
||||||
|
beestat.component.menu.open_menu.rendered_ = false;
|
||||||
|
this.rendered_ = false;
|
||||||
|
|
||||||
if (beestat.component.menu.open_menu !== undefined) {
|
if (beestat.component.menu.open_menu !== undefined) {
|
||||||
var container = beestat.component.menu.open_menu.container_;
|
var container = beestat.component.menu.open_menu.container_;
|
||||||
container.style('transform', 'scale(0)');
|
container.style('transform', 'scale(0)');
|
||||||
|
|
||||||
delete beestat.component.menu.open_menu;
|
delete beestat.component.menu.open_menu;
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
|
self.menu_items_.forEach(function(menu_item) {
|
||||||
|
menu_item.dispose();
|
||||||
|
});
|
||||||
|
|
||||||
container.parentNode().removeChild(container);
|
container.parentNode().removeChild(container);
|
||||||
}, 200);
|
}, 200);
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ beestat.component.menu_item.prototype.decorate_ = function(parent) {
|
|||||||
.render(parent);
|
.render(parent);
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
parent.addEventListener('mouseenter', function() {
|
parent.addEventListener('mouseenter', function() {
|
||||||
parent.style({
|
parent.style({
|
||||||
'background': beestat.style.color.blue.light,
|
'background': beestat.style.color.blue.light,
|
||||||
'color': '#fff'
|
'color': '#fff'
|
||||||
@ -48,7 +48,7 @@ beestat.component.menu_item.prototype.decorate_ = function(parent) {
|
|||||||
});
|
});
|
||||||
parent.addEventListener('click', function() {
|
parent.addEventListener('click', function() {
|
||||||
self.menu_.dispose();
|
self.menu_.dispose();
|
||||||
if(self.callback_ !== undefined) {
|
if (self.callback_ !== undefined) {
|
||||||
self.callback_();
|
self.callback_();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -31,6 +31,7 @@ if($setting->get('environment') === 'dev' || $setting->get('environment') === 'd
|
|||||||
echo '<script src="/js/beestat/highcharts.js"></script>' . PHP_EOL;
|
echo '<script src="/js/beestat/highcharts.js"></script>' . PHP_EOL;
|
||||||
echo '<script src="/js/beestat/get_sync_progress.js"></script>' . PHP_EOL;
|
echo '<script src="/js/beestat/get_sync_progress.js"></script>' . PHP_EOL;
|
||||||
echo '<script src="/js/beestat/user.js"></script>' . PHP_EOL;
|
echo '<script src="/js/beestat/user.js"></script>' . PHP_EOL;
|
||||||
|
echo '<script src="/js/beestat/ecobee.js"></script>' . PHP_EOL;
|
||||||
|
|
||||||
// Layer
|
// Layer
|
||||||
echo '<script src="/js/layer.js"></script>' . PHP_EOL;
|
echo '<script src="/js/layer.js"></script>' . PHP_EOL;
|
||||||
@ -42,6 +43,7 @@ if($setting->get('environment') === 'dev' || $setting->get('environment') === 'd
|
|||||||
// Component
|
// Component
|
||||||
echo '<script src="/js/component.js"></script>' . PHP_EOL;
|
echo '<script src="/js/component.js"></script>' . PHP_EOL;
|
||||||
echo '<script src="/js/component/alert.js"></script>' . PHP_EOL;
|
echo '<script src="/js/component/alert.js"></script>' . PHP_EOL;
|
||||||
|
echo '<script src="/js/component/down_notification.js"></script>' . PHP_EOL;
|
||||||
echo '<script src="/js/component/card.js"></script>' . PHP_EOL;
|
echo '<script src="/js/component/card.js"></script>' . PHP_EOL;
|
||||||
echo '<script src="/js/component/card/runtime_thermostat_summary.js"></script>' . PHP_EOL;
|
echo '<script src="/js/component/card/runtime_thermostat_summary.js"></script>' . PHP_EOL;
|
||||||
echo '<script src="/js/component/card/alerts.js"></script>' . PHP_EOL;
|
echo '<script src="/js/component/card/alerts.js"></script>' . PHP_EOL;
|
||||||
|
@ -22,6 +22,8 @@ beestat.layer.prototype.render = function() {
|
|||||||
|
|
||||||
body.innerHTML('');
|
body.innerHTML('');
|
||||||
body.appendChild(container);
|
body.appendChild(container);
|
||||||
|
|
||||||
|
beestat.ecobee.notify_if_down();
|
||||||
};
|
};
|
||||||
|
|
||||||
beestat.layer.prototype.decorate_ = function(parent) {
|
beestat.layer.prototype.decorate_ = function(parent) {
|
||||||
|
@ -128,7 +128,6 @@ beestat.layer.load.prototype.decorate_ = function(parent) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
api.set_callback(function(response) {
|
api.set_callback(function(response) {
|
||||||
|
|
||||||
beestat.cache.set('user', response.user);
|
beestat.cache.set('user', response.user);
|
||||||
|
|
||||||
// Rollbar isn't defined on dev.
|
// Rollbar isn't defined on dev.
|
||||||
@ -217,6 +216,8 @@ beestat.layer.load.prototype.decorate_ = function(parent) {
|
|||||||
|
|
||||||
(new beestat.layer.dashboard()).render();
|
(new beestat.layer.dashboard()).render();
|
||||||
|
|
||||||
|
beestat.ecobee.notify_if_down();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If never seen an announcement, or if there is an unread important
|
* If never seen an announcement, or if there is an unread important
|
||||||
* announcement, show the modal.
|
* announcement, show the modal.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user