ctucx.git: smartie-pwa

[js] smarthome web-gui

commit 3d0277f80c9b4d74d36621b6de79c65f2d1065bc
parent 735b9127def9bb697b21df80398357c73e6ac75a
Author: Milan Pässler <me@pbb.lc>
Date: Sun, 21 Jul 2019 17:23:31 +0200

foo
6 files changed, 5 insertions(+), 219 deletions(-)
D
server/.gitignore
|
1
-
D
server/index.js
|
181
-------------------------------------------------------------------------------
D
server/package.json
|
7
-------
D
server/yarn.lock
|
25
-------------------------
M
src/layout.js
|
4
++--
M
src/state.js
|
6
+++---
diff --git a/server/.gitignore b/server/.gitignore
@@ -1 +0,0 @@
-node_modules
diff --git a/server/index.js b/server/index.js
@@ -1,181 +0,0 @@
-"use strict";
-
-const url       = require("url");
-const http      = require("http");
-const net       = require("net");
-const modbus    = require("modbus-tcp");
-const WebSocket = require("ws");
-const fetch     = require("node-fetch");
-
-const state = {};
-
-function broadcastState() {
-	wss.broadcast(JSON.stringify(state));
-}
-
-const server = http.createServer(function(req, res) {
-	let requestUrl = url.parse(req.url);
-	if (req.method === "GET" && requestUrl.pathname === "/powermeter.json") {
-		res.writeHead(200, { "Content-Type": "application/json; charset=utf-8" });
-		res.end(JSON.stringify(state.powermeter));
-	} else {
-		res.writeHead(404, { 'Content-Type': 'text/plain' });
-		res.end('404');
-	}
-});
-
-const wss = new WebSocket.Server({ server });
-
-wss.broadcast = function broadcast(data) {
-	wss.clients.forEach(function each(client) {
-		if (client.readyState === WebSocket.OPEN) {
-			client.send(data);
-		}
-	});
-};
-
-wss.on('connection', function connection(ws) {
-	ws.send(JSON.stringify(state));
-});
-
-setInterval(function sendKeepalive() {
-	wss.broadcast("");
-}, 1000);
-
-
-const client = new modbus.Client();
-const socket = new net.Socket();
-socket.on("close", function(e) {
-	console.log("reconnecting", e);
-	socket.setTimeout(300, function() {
-		socket.connect({'host': '192.168.1.1', 'port': 502 });
-	});
-});
-socket.connect({'host': '192.168.1.1', 'port': 502 });
-client.pipe(socket);
-
-/* lights */
-
-const lights = [
-	"Deckenbeleuchtung",
-	"Bett",
-	"Kueche",
-	"Bad",
-];
-
-wss.on('connection', function connection(ws) {
-	ws.on('message', function incoming(message) {
-		const input = String(message).split(' ');
-
-		if (input[0] == 'set' && input[1] < 9 && (input[2] == 'on' || input[2] == 'off')) {
-			let val = 0;
-
-			if (input[2] == 'on') {
-				val = 1;
-			}
-
-			setRelay(input[1], val);
-		}
-	});
-});
-
-function mapToNames(data) {
-	return lights.map((name, id) => {
-		return {
-			name,
-			id: id + 1,
-			value: data[id],
-		};
-	});
-}
-
-function setRelay(id, val) {
-	client.writeSingleCoil(10, '10'+id, val);
-	client.readCoils(10, 101, 108, function (err, data){
-		state.lights = mapToNames(data);
-		broadcastState();
-	})
-}
-
-function readRelays(ws) {
-	client.readCoils(10, 101, 108, function (err, data){
-		state.lights = mapToNames(data);
-	});
-}
-
-readRelays();
-
-/* powermeter */
-
-state.powermeter = {
-	60: { name: "Kueche" },
-	50: { name: "Sonstiges" },
-};
-
-const registers = {
-	voltage: 0,
-	power: 12,
-	frequency: 70,
-	import: 72,
-	cosphi: 30,
-};
-
-function unixTimestamp() {
-	return Math.floor(Number(new Date()) / 1000);
-}
-
-function round(num, places) {
-        const factor = Math.pow(10, places);
-        return Math.round(num * factor) / factor;
-}
-
-function getFloat32Register(counterId, registerId, client, socket) {
-	return new Promise(function(fulfill, reject) {
-		client.readInputRegisters(counterId, registerId, registerId+1, function (err, data) {
-			if (err) return reject();
-
-	// Create a buffer
-	var buf = new ArrayBuffer(4);
-	// Create a data view of it
-	var view = new DataView(buf);
-
-	// set bytes
-	view.setUint8(0, data[0][0]);
-	view.setUint8(1, data[0][1]);
-	view.setUint8(2, data[1][0]);
-	view.setUint8(3, data[1][1]);
-
-			//const buf = Buffer.concat(data).buffer;
-			//const view = new DataView(buf);
-			const num = view.getFloat32(0);
-
-			fulfill(num);
-		});
-	});
-}
-
-async function fetchValues() {
-	for (let [id, counter] of Object.entries(state.powermeter)) {
-		for (let key of Object.keys(registers)) {
-			try {
-				counter.values[key] = round(await getFloat32Register(id, registers[key], client, socket), 2);
-				counter.lastUpdated = unixTimestamp();
-			} catch(e) {}
-		}
-	}
-	broadcastState();
-}
-
-
-for (let [id, counter] of Object.entries(state.powermeter)) {
-	counter.values = Object.keys(registers).reduce(function(result, key) {
-		result[key] = 0;
-		return result;
-	}, {});
-	counter.lastUpdated = unixTimestamp();
-}
-
-setInterval(fetchValues, 20000);
-fetchValues();
-
-server.listen(8080);
diff --git a/server/package.json b/server/package.json
@@ -1,7 +0,0 @@
-{
-  "dependencies": {
-    "modbus-tcp": "^0.4.13",
-    "node-fetch": "^2.6.0",
-    "ws": "^7.0.0"
-  }
-}
diff --git a/server/yarn.lock b/server/yarn.lock
@@ -1,25 +0,0 @@
-# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
-# yarn lockfile v1
-
-
-async-limiter@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8"
-  integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==
-
-modbus-tcp@^0.4.13:
-  version "0.4.13"
-  resolved "https://registry.yarnpkg.com/modbus-tcp/-/modbus-tcp-0.4.13.tgz#3e0e93af516d78a19f0f62686e64558e6ae6426b"
-  integrity sha512-TytYObBTQhEMzjfFgGK3iESUoneH9WJRWHoZkt7PBuNnnx2nSOW0tOLC1YeQKNi/Qv7Xv0IjbVhxOoHyXOaV9g==
-
-node-fetch@^2.6.0:
-  version "2.6.0"
-  resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd"
-  integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==
-
-ws@^7.0.0:
-  version "7.0.0"
-  resolved "https://registry.yarnpkg.com/ws/-/ws-7.0.0.tgz#79351cbc3f784b3c20d0821baf4b4ff809ffbf51"
-  integrity sha512-cknCal4k0EAOrh1SHHPPWWh4qm93g1IuGGGwBjWkXmCG7LsDtL8w9w+YVfaF+KSVwiHQKDIMsSLBVftKf9d1pg==
-  dependencies:
-    async-limiter "^1.0.0"
diff --git a/src/layout.js b/src/layout.js
@@ -17,9 +17,9 @@ import "./spinner.js";
 import "./row.js";
 
 const createRedirect = (id) => {
-	const config = state.config.views.filter(view => view.url == id);
+	const config = state.config.views.filter(view => view.url == id)[0];
 	const redirect = document.createElement("script");
-  redirect.innerHTML = `window.location = "${config.destination}";`;
+	redirect.innerHTML = `window.location = "${config.destination}";`;
 };
 
 const viewTypes = {
diff --git a/src/state.js b/src/state.js
@@ -38,7 +38,7 @@ class State {
 	}
 
 	_initWS() {
-		this.ws = new WebSocket(`ws://${window.location.hostname}/ws`);
+		this.ws = new WebSocket(`${window.location.protocol === "https:" ? "wss" : "ws"}://${window.location.hostname}/${window.location.pathname.split("/").slice(0, -1).join("/")}/ws`);
 		this.ws.onclose = () => {
 			this.connected = false;
 			this._initWS();

@@ -53,11 +53,11 @@ class State {
 			}));
 		};
 		this.ws.onmessage = (msg) => {
-			/*clearInterval(this._timeout);
+			clearInterval(this._timeout);
 			this._timeout = setTimeout(() => {
 				this.ws.close();
 				this.ws.onclose();
-			}, 2000);*/
+			}, 2000);
 			if (!msg.data.length) return; // keepalive
 			this._setData(JSON.parse(msg.data));
 		};