Use localized state display for timeline charts (#746)

* Fix import typo

* Use localized state names on timeline charts

* Track language in cache metadata
This commit is contained in:
Adam Mills 2017-12-23 14:02:33 -05:00 committed by GitHub
parent 1b60a93fcc
commit 38088acf14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 22 deletions

View File

@ -12,7 +12,7 @@
<link rel="import" href="../../bower_components/paper-listbox/paper-listbox.html"> <link rel="import" href="../../bower_components/paper-listbox/paper-listbox.html">
<link rel="import" href="../../bower_components/paper-item/paper-item.html"> <link rel="import" href="../../bower_components/paper-item/paper-item.html">
<link rel='import' href='../..//src/util/hass-mixins.html'> <link rel='import' href='../../src/util/hass-mixins.html'>
<link rel="import" href="../../src/components/ha-menu-button.html"> <link rel="import" href="../../src/components/ha-menu-button.html">
<link rel="import" href="../../src/components/ha-start-voice-button.html"> <link rel="import" href="../../src/components/ha-start-voice-button.html">

View File

@ -1,5 +1,8 @@
<link rel="import" href="../../bower_components/polymer/polymer-element.html"> <link rel="import" href="../../bower_components/polymer/polymer-element.html">
<link rel='import' href='../../src/util/hass-mixins.html'>
<link rel='import' href='../../src/util/hass-util.html'>
<script> <script>
{ {
const RECENT_THRESHOLD = 60000; // 1 minute const RECENT_THRESHOLD = 60000; // 1 minute
@ -8,7 +11,7 @@
const LINE_ATTRIBUTES_TO_KEEP = ['temperature', 'current_temperature', 'target_temp_low', 'target_temp_high', 'operation']; const LINE_ATTRIBUTES_TO_KEEP = ['temperature', 'current_temperature', 'target_temp_low', 'target_temp_high', 'operation'];
window.stateHistoryCache = window.stateHistoryCache || {}; window.stateHistoryCache = window.stateHistoryCache || {};
function computeHistory(stateHistory) { function computeHistory(stateHistory, localize, language) {
const lineChartDevices = {}; const lineChartDevices = {};
const timelineDevices = []; const timelineDevices = [];
@ -31,7 +34,10 @@
name: window.hassUtil.computeStateName(stateInfo[0]), name: window.hassUtil.computeStateName(stateInfo[0]),
entity_id: stateInfo[0].entity_id, entity_id: stateInfo[0].entity_id,
data: stateInfo data: stateInfo
.map(state => ({ state: state.state, last_changed: state.last_changed })) .map(state => ({
state: window.hassUtil.computeStateDisplay(localize, state, language),
last_changed: state.last_changed,
}))
.filter((element, index, arr) => { .filter((element, index, arr) => {
if (index === 0) return true; if (index === 0) return true;
return element.state !== arr[index - 1].state; return element.state !== arr[index - 1].state;
@ -87,7 +93,10 @@
return { line: unitStates, timeline: timelineDevices }; return { line: unitStates, timeline: timelineDevices };
} }
class HaStateHistoryData extends Polymer.Element { /*
* @appliesMixin window.hassMixins.LocalizeMixin
*/
class HaStateHistoryData extends window.hassMixins.LocalizeMixin(Polymer.Element) {
static get is() { return 'ha-state-history-data'; } static get is() { return 'ha-state-history-data'; }
static get properties() { static get properties() {
return { return {
@ -123,7 +132,7 @@
static get observers() { static get observers() {
return [ return [
'filterChanged(filterType, entityId, startTime, endTime, cacheConfig)', 'filterChanged(filterType, entityId, startTime, endTime, cacheConfig, localize, language)',
]; ];
} }
@ -144,20 +153,20 @@
} }
} }
filterChanged(filterType, entityId, startTime, endTime, cacheConfig) { filterChanged(filterType, entityId, startTime, endTime, cacheConfig, localize, language) {
if (!this.hass) return; if (!this.hass) return;
this._madeFirstCall = true; this._madeFirstCall = true;
let data; let data;
if (filterType === 'date') { if (filterType === 'date') {
if (!startTime || !endTime) return; if (!startTime || !endTime) return;
data = this.getDate(startTime, endTime); data = this.getDate(startTime, endTime, localize, language);
} else if (filterType === 'recent-entity') { } else if (filterType === 'recent-entity') {
if (!entityId) return; if (!entityId) return;
if (cacheConfig) { if (cacheConfig) {
data = this.getRecentWithCacheRefresh(entityId, cacheConfig); data = this.getRecentWithCacheRefresh(entityId, cacheConfig, localize, language);
} else { } else {
data = this.getRecent(entityId, startTime, endTime); data = this.getRecent(entityId, startTime, endTime, localize, language);
} }
} else { } else {
return; return;
@ -171,26 +180,27 @@
}); });
} }
getEmptyCache() { getEmptyCache(language) {
return { return {
prom: Promise.resolve({ line: [], timeline: [] }), prom: Promise.resolve({ line: [], timeline: [] }),
language: language,
data: { line: [], timeline: [] }, data: { line: [], timeline: [] },
}; };
} }
getRecentWithCacheRefresh(entityId, cacheConfig) { getRecentWithCacheRefresh(entityId, cacheConfig, localize, language) {
if (this._refreshTimeoutId) { if (this._refreshTimeoutId) {
window.clearInterval(this._refreshTimeoutId); window.clearInterval(this._refreshTimeoutId);
} }
if (cacheConfig.refresh) { if (cacheConfig.refresh) {
this._refreshTimeoutId = window.setInterval(() => { this._refreshTimeoutId = window.setInterval(() => {
this.getRecentWithCache(entityId, cacheConfig) this.getRecentWithCache(entityId, cacheConfig, localize, language)
.then((stateHistory) => { .then((stateHistory) => {
this._setData(Object.assign({}, stateHistory)); this._setData(Object.assign({}, stateHistory));
}); });
}, cacheConfig.refresh * 1000); }, cacheConfig.refresh * 1000);
} }
return this.getRecentWithCache(entityId, cacheConfig); return this.getRecentWithCache(entityId, cacheConfig, localize, language);
} }
mergeLine(historyLines, cacheLines) { mergeLine(historyLines, cacheLines) {
@ -254,7 +264,7 @@
}); });
} }
getRecentWithCache(entityId, cacheConfig) { getRecentWithCache(entityId, cacheConfig, localize, language) {
const cacheKey = cacheConfig.cacheKey; const cacheKey = cacheConfig.cacheKey;
const endTime = new Date(); const endTime = new Date();
const originalStartTime = new Date(endTime); const originalStartTime = new Date(endTime);
@ -262,14 +272,15 @@
let startTime = originalStartTime; let startTime = originalStartTime;
let appendingToCache = false; let appendingToCache = false;
let cache = window.stateHistoryCache[cacheKey]; let cache = window.stateHistoryCache[cacheKey];
if (cache && startTime >= cache.startTime && startTime <= cache.endTime) { if (cache && startTime >= cache.startTime && startTime <= cache.endTime
&& cache.language === language) {
startTime = cache.endTime; startTime = cache.endTime;
appendingToCache = true; appendingToCache = true;
if (endTime <= cache.endTime) { if (endTime <= cache.endTime) {
return cache.prom; return cache.prom;
} }
} else { } else {
cache = window.stateHistoryCache[cacheKey] = this.getEmptyCache(); cache = window.stateHistoryCache[cacheKey] = this.getEmptyCache(language);
} }
// Use Promise.all in order to make sure the old and the new fetches have both completed. // Use Promise.all in order to make sure the old and the new fetches have both completed.
const prom = Promise.all([cache.prom, const prom = Promise.all([cache.prom,
@ -277,7 +288,7 @@
// Use only data from the new fetch. Old fetch is already stored in cache.data // Use only data from the new fetch. Old fetch is already stored in cache.data
.then(oldAndNew => oldAndNew[1]) .then(oldAndNew => oldAndNew[1])
// Convert data into format state-history-chart-* understands. // Convert data into format state-history-chart-* understands.
.then(stateHistory => computeHistory(stateHistory)) .then(stateHistory => computeHistory(stateHistory, localize, language))
// Merge old and new. // Merge old and new.
.then((stateHistory) => { .then((stateHistory) => {
this.mergeLine(stateHistory.line, cache.data.line); this.mergeLine(stateHistory.line, cache.data.line);
@ -296,16 +307,16 @@
return prom; return prom;
} }
getRecent(entityId, startTime, endTime) { getRecent(entityId, startTime, endTime, localize, language) {
const cacheKey = entityId; const cacheKey = entityId;
const cache = RECENT_CACHE[cacheKey]; const cache = RECENT_CACHE[cacheKey];
if (cache && Date.now() - cache.created < RECENT_THRESHOLD) { if (cache && Date.now() - cache.created < RECENT_THRESHOLD && cache.language === language) {
return cache.data; return cache.data;
} }
const prom = this.fetchRecent(entityId, startTime, endTime).then( const prom = this.fetchRecent(entityId, startTime, endTime).then(
stateHistory => computeHistory(stateHistory), stateHistory => computeHistory(stateHistory, localize, language),
() => { () => {
RECENT_CACHE[entityId] = false; RECENT_CACHE[entityId] = false;
return null; return null;
@ -314,6 +325,7 @@
RECENT_CACHE[cacheKey] = { RECENT_CACHE[cacheKey] = {
created: Date.now(), created: Date.now(),
language: language,
data: prom, data: prom,
}; };
return prom; return prom;
@ -335,11 +347,11 @@
return this.hass.callApi('GET', url); return this.hass.callApi('GET', url);
} }
getDate(startTime, endTime) { getDate(startTime, endTime, localize, language) {
const filter = startTime.toISOString() + '?end_time=' + endTime.toISOString(); const filter = startTime.toISOString() + '?end_time=' + endTime.toISOString();
const prom = this.hass.callApi('GET', 'history/period/' + filter).then( const prom = this.hass.callApi('GET', 'history/period/' + filter).then(
stateHistory => computeHistory(stateHistory), stateHistory => computeHistory(stateHistory, localize, language),
() => null () => null
); );