ctucx.git: smartie-pwa

[js] smarthome web-gui

commit 9ce981278f4e692959eec3c6f5a9b4ce02595867
parent bc35ad7ba8fa6e9e373434fab34a294823fa62b5
Author: Milan Pässler <me@pbb.lc>
Date: Mon, 10 Jun 2019 11:32:44 +0200

unify archive fetching
4 files changed, 63 insertions(+), 56 deletions(-)
A
src/archive.js
|
39
+++++++++++++++++++++++++++++++++++++++
M
src/power-meter-history.js
|
43
++++++-------------------------------------
M
src/power-meter.js
|
28
+++++++++-------------------
M
src/util.js
|
9
+++++++++
diff --git a/src/archive.js b/src/archive.js
@@ -0,0 +1,39 @@
+"use strict";
+
+class Archive {
+	constructor() {
+		this.archive = {};
+		this._loading = {};
+		this._subscribers = [];
+	}
+
+	subscribe(callback) {
+		this._subscribers.push(callback);
+		this._updateSubscribers();
+	}
+
+	_updateSubscribers() {
+		for (let sub of this._subscribers) {
+			sub();
+		}
+	}
+
+	load(file) {
+		if (!this.archive[file]) {
+			this._loading[file] = true;
+			const p = fetch(`archive/${file}.json`)
+				.then(resp => resp.json())
+				.then(data => {
+					this.archive[file] = data;
+					this._loading[file] = undefined;
+					this._updateSubscribers();
+					return data;
+				}).catch(e => console.warn(e));
+			return {};
+		} else {
+			return this.archive[file];
+		}
+	}
+}
+
+export const archive = new Archive();
diff --git a/src/power-meter-history.js b/src/power-meter-history.js
@@ -2,7 +2,8 @@
 
 import { LitElement, html, css } from "lit-element";
 import { state } from "./state.js";
-import { pad, round } from "./util.js";
+import { pad, round, weekdays, months, get } from "./util.js";
+import { archive } from "./archive.js";
 
 import "@authentic/mwc-circular-progress";
 import "@authentic/mwc-icon";

@@ -12,12 +13,6 @@ import "@authentic/mwc-list";
 import "./card.js";
 import "./spinner.js";
 
-const archive = {};
-const loading = {};
-
-const weekdays = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"];
-const months = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sept","Oct","Nov","Dec"];
-
 const formatName = (type, name) => {
 	if (type == "day") {
 		const date = new Date(`${name.substr(0, 4)}-${name.substr(4, 2)}-${name.substr(6, 2)}`);

@@ -44,14 +39,8 @@ class PowerMeterHistory extends LitElement {
 		this.year = now.getFullYear();
 		this.month = pad(now.getMonth() + 1, 2);
 
-		fetch(`archive/metadata.json`)
-			.then(resp => resp.json())
-			.then(metadata => {
-				this.metadata = metadata;
-				this.requestUpdate();
-			});
-
 		state.subscribe(this.loadData.bind(this));
+		archive.subscribe(this.loadData.bind(this));
 	}
 
 	async loadData(e) {

@@ -61,7 +50,7 @@ class PowerMeterHistory extends LitElement {
 		if (this.type === "day") this.sel += "_" + this.month;
 
 		await Promise.all(Object.entries(state.data.powermeter).map(async ([id, p]) => {
-			const data = await this.load(`${this.type}/${id}_${this.sel}`);
+			const data = await archive.load(`${this.type}/${id}_${this.sel}`);
 			if(!data) return;
 			for (let day of Object.keys(data)) {
 				if (!d[day]) d[day] = {};

@@ -80,22 +69,6 @@ class PowerMeterHistory extends LitElement {
 		};
 	}
 
-	async load(file) {
-		if (!archive[file] && !loading[file]) {
-			console.log("loading " + file);
-			loading[file] = true;
-			return fetch(`archive/${file}.json`)
-				.then(resp => resp.json())
-				.then(data => {
-					archive[file] = data;
-					loading[file] = undefined;
-					return data;
-				}).catch(e => console.warn(e));
-		} else {
-			return archive[file];
-		}
-	}
-
 	render() {
 		const now = new Date();
 		return html`

@@ -112,18 +85,14 @@ class PowerMeterHistory extends LitElement {
 				<mwc-select label="Year">
 					<mwc-menu slot="menu" class="year-sel" @MDCMenu:selected=${this.handleSelected("year")}>
 						<mwc-list>
-							${this.metadata ? html`
-								${Object.keys(this.metadata.availableData).map(m => html`<mwc-list-item value="${m}">${m}</mwc-list-item>`)}
-							` : html``}
+							${Object.keys(get(archive.load("metadata"), [ "availableData" ], {})).map(m => html`<mwc-list-item value="${m}">${m}</mwc-list-item>`)}
 						</mwc-list>
 					</mwc-menu>
 				</mwc-select>
 				<mwc-select label="Month" class="${this.type == "day" ? "" : "hidden"}">
 					<mwc-menu slot="menu" class="month-sel" @MDCMenu:selected=${this.handleSelected("month")}>
 						<mwc-list>
-							${this.metadata ? html`
-								${this.metadata.availableData[this.year].map(m => html`<mwc-list-item value="${m}">${Number(m)}</mwc-list-item>`)}
-							` : html``}
+							${get(archive.load("metadata"), [ "availableData", this.year ], []).map(m => html`<mwc-list-item value="${m}">${Number(m)}</mwc-list-item>`)}
 						</mwc-list>
 					</mwc-menu>
 				</mwc-select>
diff --git a/src/power-meter.js b/src/power-meter.js
@@ -2,39 +2,29 @@
 
 import { LitElement, html, css } from "lit-element";
 import { state } from "./state.js";
-import { pad, formatDate, round } from "./util.js";
+import { pad, formatDate, round, get } from "./util.js";
+import { archive } from "./archive.js";
 
 import "@authentic/mwc-circular-progress";
 import "@authentic/mwc-icon";
 import "./card.js";
 import "./spinner.js";
 
-const archive = {};
-const loading = {};
-
 class PowerMeter extends LitElement {
 	constructor() {
 		super(...arguments);
 		state.subscribe(this.requestUpdate.bind(this));
+		archive.subscribe(this.requestUpdate.bind(this));
 	}
 
-	load(file, key, key2) {
-		if (!archive[file] && !loading[file]) {
-			loading[file] = true;
-			fetch(`archive/${file}.json`)
-				.then(resp => resp.json())
-				.then(data => {
-					archive[file] = data;
-					loading[file] = undefined;
-					this.requestUpdate();
-				});
-		} else {
-			return archive[file][key][key2];
-		}
+	getImport(id) {
+		const now = new Date();
+		const file = archive.load(`day/${id}_${now.getFullYear()}_${pad(now.getMonth() + 1, 2)}`);
+		const value = get(file, [ `${now.getFullYear()}${pad(now.getMonth() + 1, 2)}${pad(now.getDate(), 2)}`, "imported" ]);
+		return value ? round(value, 2) + "kWh" : "-";
 	}
 
 	render() {
-		const now = new Date();
 		return html`
 			${state.data.powermeter ? html`
 				<div id="connection-status">

@@ -64,7 +54,7 @@ class PowerMeter extends LitElement {
 								<div class="table-column">${d.values.cosphi}</div>
 								<div class="table-column">${d.values.frequency}</div>
 								<div class="table-column">${d.values.import} kWh</div>
-								<div class="table-column">${round(this.load(`day/${id}_${now.getFullYear()}_${pad(now.getMonth() + 1, 2)}`, `${now.getFullYear()}${pad(now.getMonth() + 1, 2)}${pad(now.getDate(), 2)}`, "imported"), 2)} kWh</div>
+								<div class="table-column">${this.getImport(id)}</div>
 							</div>
 						`)}
 					</div>
diff --git a/src/util.js b/src/util.js
@@ -20,3 +20,12 @@ export const formatDate = (date) => (
 	pad(date.getMinutes(), 2)
 );
 
+export const weekdays = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"];
+export const months = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sept","Oct","Nov","Dec"];
+
+export const get = (obj, path, def) => {
+	path.forEach(p => {
+		if (obj) obj = obj[p];
+	});
+	return obj || def;
+};