mirror of
https://github.com/IoTManagerProject/IoTManagerWeb.git
synced 2026-03-26 23:12:34 +03:00
optimization
This commit is contained in:
@@ -151,7 +151,7 @@ _settings_store: dict = {} # slot -> dict
|
|||||||
def get_settings(http_host: str, http_port: int, slot: int = 0) -> dict:
|
def get_settings(http_host: str, http_port: int, slot: int = 0) -> dict:
|
||||||
"""Settings JSON; serverip must point to mock HTTP for ver.json. System page needs timezone, wg, log, mqttin, i2c, pinSCL, pinSDA, i2cFreq."""
|
"""Settings JSON; serverip must point to mock HTTP for ver.json. System page needs timezone, wg, log, mqttin, i2c, pinSCL, pinSDA, i2cFreq."""
|
||||||
base = {
|
base = {
|
||||||
"name": "MockDevice",
|
"name": f"MockDevice-{slot}",
|
||||||
"apssid": "IoTmanager",
|
"apssid": "IoTmanager",
|
||||||
"appass": "",
|
"appass": "",
|
||||||
"routerssid": "",
|
"routerssid": "",
|
||||||
@@ -182,23 +182,25 @@ def get_settings(http_host: str, http_port: int, slot: int = 0) -> dict:
|
|||||||
return base
|
return base
|
||||||
|
|
||||||
|
|
||||||
def get_errors() -> dict:
|
def get_errors(slot: int = 0) -> dict:
|
||||||
"""Errors JSON for System page: bn, bt, bver, wver, timenow, upt, uptm, uptw, rssi, heap, freeBytes, fl, rst."""
|
"""Errors JSON for System page (per device): bn, bt, bver, wver, timenow, upt, uptm, uptw, rssi, heap, freeBytes, fl, rst."""
|
||||||
import time
|
import time
|
||||||
|
ts = int(time.time())
|
||||||
|
# Different system info per device slot so UI shows which device is selected
|
||||||
return {
|
return {
|
||||||
"bn": "esp32",
|
"bn": f"esp32-d{slot}",
|
||||||
"bt": "2024-01-01 12:00",
|
"bt": f"2024-0{1 + slot}-0{1 + slot} 12:00",
|
||||||
"bver": "1.0.0",
|
"bver": f"1.0.{slot}",
|
||||||
"wver": "4.2.0",
|
"wver": f"4.2.{slot}",
|
||||||
"timenow": str(int(time.time())),
|
"timenow": str(ts),
|
||||||
"upt": "1d 02:30",
|
"upt": f"{1 + slot}d 0{2 + slot}:{30 + slot * 5}",
|
||||||
"uptm": "1d 02:30",
|
"uptm": f"{1 + slot}d 0{2 + slot}:{30 + slot * 5}",
|
||||||
"uptw": "1d 02:30",
|
"uptw": f"{1 + slot}d 0{2 + slot}:{30 + slot * 5}",
|
||||||
"rssi": 5,
|
"rssi": -65 + slot * 10,
|
||||||
"heap": "120000",
|
"heap": str(120000 - slot * 10000),
|
||||||
"freeBytes": "2.1M",
|
"freeBytes": f"{2 - slot * 0.2:.1f}M",
|
||||||
"fl": "1024",
|
"fl": str(1024 + slot * 512),
|
||||||
"rst": "Software reset",
|
"rst": "Software reset" if slot == 0 else "Power-on reset",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -360,7 +362,7 @@ async def handle_ws_message(ws, message: str, slot: int) -> None:
|
|||||||
await send_bin("config", json.dumps(get_config_json()))
|
await send_bin("config", json.dumps(get_config_json()))
|
||||||
await send_bin("settin", json.dumps(get_settings(HTTP_HOST, HTTP_PORT, slot)))
|
await send_bin("settin", json.dumps(get_settings(HTTP_HOST, HTTP_PORT, slot)))
|
||||||
await send_bin("ssidli", json.dumps(get_ssid_list()))
|
await send_bin("ssidli", json.dumps(get_ssid_list()))
|
||||||
await send_bin("errors", json.dumps(get_errors()))
|
await send_bin("errors", json.dumps(get_errors(slot)))
|
||||||
return
|
return
|
||||||
|
|
||||||
if cmd == "/list|":
|
if cmd == "/list|":
|
||||||
@@ -380,12 +382,12 @@ async def handle_ws_message(ws, message: str, slot: int) -> None:
|
|||||||
return
|
return
|
||||||
|
|
||||||
if cmd == "/system|":
|
if cmd == "/system|":
|
||||||
await send_bin("errors", json.dumps(get_errors()))
|
await send_bin("errors", json.dumps(get_errors(slot)))
|
||||||
await send_bin("settin", json.dumps(get_settings(HTTP_HOST, HTTP_PORT, slot)))
|
await send_bin("settin", json.dumps(get_settings(HTTP_HOST, HTTP_PORT, slot)))
|
||||||
return
|
return
|
||||||
|
|
||||||
if cmd == "/dev|":
|
if cmd == "/dev|":
|
||||||
await send_bin("errors", json.dumps(get_errors()))
|
await send_bin("errors", json.dumps(get_errors(slot)))
|
||||||
await send_bin("settin", json.dumps(get_settings(HTTP_HOST, HTTP_PORT, slot)))
|
await send_bin("settin", json.dumps(get_settings(HTTP_HOST, HTTP_PORT, slot)))
|
||||||
await send_bin("config", json.dumps(get_config_json()))
|
await send_bin("config", json.dumps(get_config_json()))
|
||||||
await send_bin("itemsj", json.dumps(get_items_json()))
|
await send_bin("itemsj", json.dumps(get_items_json()))
|
||||||
@@ -414,7 +416,7 @@ async def handle_ws_message(ws, message: str, slot: int) -> None:
|
|||||||
try:
|
try:
|
||||||
data = json.loads(payload)
|
data = json.loads(payload)
|
||||||
_settings_store[slot] = data
|
_settings_store[slot] = data
|
||||||
await send_bin("errors", json.dumps(get_errors()))
|
await send_bin("errors", json.dumps(get_errors(slot)))
|
||||||
except json.JSONDecodeError:
|
except json.JSONDecodeError:
|
||||||
pass
|
pass
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -350,39 +350,25 @@ export default class WebSocketManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sortingLayout(ws) {
|
sortingLayout(ws) {
|
||||||
this.layoutJson.sort(function (a, b) {
|
this.layoutJson.sort((a, b) => (a.descr || "").localeCompare(b.descr || ""));
|
||||||
if (a.descr < b.descr) return -1;
|
const pageSet = new Set(this.layoutJson.map((w) => w.page));
|
||||||
if (a.descr > b.descr) return 1;
|
this.pages = [...pageSet].sort((a, b) => a.localeCompare(b)).map((page) => ({ page }));
|
||||||
return 0;
|
if (this.debug) console.log("[3]", ws, "layout sort, requested params...");
|
||||||
});
|
|
||||||
this.pages = [];
|
|
||||||
const newPage = Array.from(new Set(Array.from(this.layoutJson, ({ page }) => page)));
|
|
||||||
newPage.forEach(function (item) {
|
|
||||||
this.pages = [...this.pages, JSON.parse(JSON.stringify({ page: item }))];
|
|
||||||
}, this);
|
|
||||||
this.pages.sort(function (a, b) {
|
|
||||||
if (a.page < b.page) return -1;
|
|
||||||
if (a.page > b.page) return 1;
|
|
||||||
return 0;
|
|
||||||
});
|
|
||||||
this.layoutJson = this.layoutJson;
|
|
||||||
console.log("[3]", ws, "layout sort, requested params...");
|
|
||||||
this.wsSendMsg(ws, "/params|");
|
this.wsSendMsg(ws, "/params|");
|
||||||
this._emitLayoutJsonUpdated();
|
this._emitLayoutJsonUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
updateAllStatuses(ws) {
|
updateAllStatuses(ws) {
|
||||||
|
const topicToIndex = new Map();
|
||||||
|
for (let i = 0; i < this.layoutJson.length; i++) {
|
||||||
|
const t = this.layoutJson[i].topic;
|
||||||
|
if (t) topicToIndex.set(t.slice(t.lastIndexOf("/") + 1), i);
|
||||||
|
}
|
||||||
for (const [key, value] of Object.entries(this.paramsJson)) {
|
for (const [key, value] of Object.entries(this.paramsJson)) {
|
||||||
for (let i = 0; i < this.layoutJson.length; i++) {
|
const i = topicToIndex.get(key);
|
||||||
let topic = this.layoutJson[i].topic;
|
if (i !== undefined) {
|
||||||
if (topic) {
|
if (this.debug) console.log("[i]", "updated =>" + key, value);
|
||||||
topic = topic.substring(topic.lastIndexOf("/") + 1, topic.length);
|
this.layoutJson[i].status = value;
|
||||||
if (key === topic) {
|
|
||||||
console.log("[i]", "updated =>" + topic, value);
|
|
||||||
this.layoutJson[i].status = value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.wsSendMsg(ws, "/charts|");
|
this.wsSendMsg(ws, "/charts|");
|
||||||
@@ -390,51 +376,35 @@ export default class WebSocketManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateWidget(newStatusJson) {
|
updateWidget(newStatusJson) {
|
||||||
for (let i = 0; i < this.layoutJson.length; i++) {
|
const i = this.layoutJson.findIndex((w) => w.topic === newStatusJson.topic);
|
||||||
if (this.layoutJson[i].topic === newStatusJson.topic) {
|
if (i === -1) return;
|
||||||
this.layoutJson[i] = this.jsonConcat(this.layoutJson[i], newStatusJson);
|
this.jsonConcat(this.layoutJson[i], newStatusJson);
|
||||||
this.layoutJson[i].sent = false;
|
this.layoutJson[i].sent = false;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this._emitLayoutJsonUpdated();
|
this._emitLayoutJsonUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
async apdateWidgetByArray(newStatusJson) {
|
apdateWidgetByArray(newStatusJson) {
|
||||||
console.log("[i]", "collecting arrays");
|
const i = this.layoutJson.findIndex((w) => w.topic === newStatusJson.topic);
|
||||||
let error = true;
|
if (i === -1) {
|
||||||
if (this.layoutJson.length > 0) {
|
if (this.debug) console.log("[E]", "topic not found", newStatusJson.topic);
|
||||||
for (let i = 0; i < this.layoutJson.length; i++) {
|
this._emitLayoutJsonUpdated();
|
||||||
if (this.layoutJson[i].topic === newStatusJson.topic) {
|
return;
|
||||||
error = false;
|
|
||||||
this.layoutJson[i] = this.jsonConcatEx(this.layoutJson[i], newStatusJson);
|
|
||||||
let prevArr = this.layoutJson[i].status;
|
|
||||||
let newArr = newStatusJson.status;
|
|
||||||
if (prevArr) {
|
|
||||||
prevArr = [...prevArr, ...newArr];
|
|
||||||
this.layoutJson[i].status = prevArr;
|
|
||||||
} else {
|
|
||||||
this.layoutJson[i].status = newArr;
|
|
||||||
}
|
|
||||||
this.layoutJson[i].sent = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log("[E]", "layoutJson missing");
|
|
||||||
}
|
}
|
||||||
if (error) console.log("[E]", "topic not found ", newStatusJson.topic);
|
this.jsonConcatEx(this.layoutJson[i], newStatusJson);
|
||||||
|
const prev = this.layoutJson[i].status;
|
||||||
|
const next = newStatusJson.status;
|
||||||
|
this.layoutJson[i].status = Array.isArray(prev) ? [...prev, ...(next || [])] : next || [];
|
||||||
|
this.layoutJson[i].sent = false;
|
||||||
this._emitLayoutJsonUpdated();
|
this._emitLayoutJsonUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonConcat(o1, o2) {
|
jsonConcat(o1, o2) {
|
||||||
for (const key in o2) {
|
Object.assign(o1, o2);
|
||||||
o1[key] = o2[key];
|
|
||||||
}
|
|
||||||
return o1;
|
return o1;
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonConcatEx(o1, o2) {
|
jsonConcatEx(o1, o2) {
|
||||||
for (const key in o2) {
|
for (const key of Object.keys(o2)) {
|
||||||
if (key !== "status") o1[key] = o2[key];
|
if (key !== "status") o1[key] = o2[key];
|
||||||
}
|
}
|
||||||
return o1;
|
return o1;
|
||||||
@@ -479,12 +449,7 @@ export default class WebSocketManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getSelectedDeviceData(ws) {
|
getSelectedDeviceData(ws) {
|
||||||
for (let i = 0; i < this.deviceList.length; i++) {
|
this.selectedDeviceData = this.deviceList.find((d) => d.ws === ws);
|
||||||
if (this.deviceList[i].ws === ws) {
|
|
||||||
this.selectedDeviceData = this.deviceList[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedDeviceDataRefresh() {
|
selectedDeviceDataRefresh() {
|
||||||
@@ -493,18 +458,14 @@ export default class WebSocketManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
wsPush(ws, topic, status) {
|
wsPush(ws, topic, status) {
|
||||||
const key = topic.substring(topic.lastIndexOf("/") + 1, topic.length);
|
const key = topic.slice(topic.lastIndexOf("/") + 1);
|
||||||
this.wsSendMsg(ws, "/control|" + key + "/" + status);
|
this.wsSendMsg(ws, "/control|" + key + "/" + status);
|
||||||
}
|
}
|
||||||
|
|
||||||
addCoreMsg(msg) {
|
addCoreMsg(msg) {
|
||||||
if (this.coreMessages.length >= LOG_MAX_MESSAGES) this.coreMessages.shift();
|
if (this.coreMessages.length >= LOG_MAX_MESSAGES) this.coreMessages.shift();
|
||||||
this.coreMessages = [...this.coreMessages, { msg }];
|
this.coreMessages.push({ msg, time: Date.now() });
|
||||||
this.coreMessages.sort(function (a, b) {
|
this.coreMessages.sort((a, b) => (b.time || 0) - (a.time || 0));
|
||||||
if (a.time > b.time) return -1;
|
|
||||||
if (a.time < b.time) return 1;
|
|
||||||
return 0;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_getInput() {
|
_getInput() {
|
||||||
@@ -524,48 +485,30 @@ export default class WebSocketManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
generateLayout() {
|
generateLayout() {
|
||||||
|
const { mqttPrefix = "", id: settingsId = "" } = this.settingsJson;
|
||||||
|
const prefix = `${mqttPrefix}/${settingsId}/`;
|
||||||
const layout = [];
|
const layout = [];
|
||||||
for (let i = 0; i < this.configJson.length; i++) {
|
for (const config of this.configJson) {
|
||||||
const config = Object.assign({}, this.configJson[i]);
|
const widget = this.widgetsJson.find((w) => w.name === config.widget);
|
||||||
const setWidget = config.widget;
|
if (!widget) {
|
||||||
let error = true;
|
if (this.debug) console.log("[E]", "widget not found:", config.widget);
|
||||||
for (let w = 0; w < this.widgetsJson.length; w++) {
|
continue;
|
||||||
if (setWidget === this.widgetsJson[w].name) {
|
}
|
||||||
const widget = Object.assign({}, this.widgetsJson[w]);
|
if (config.widget !== "nil") {
|
||||||
widget.page = config.page;
|
const item = { ...widget, page: config.page, descr: config.descr, topic: prefix + config.id };
|
||||||
widget.descr = config.descr;
|
layout.push(item);
|
||||||
widget.topic =
|
if (item.widget === "chart" && item.type !== "bar") {
|
||||||
this.settingsJson.mqttPrefix + "/" + this.settingsJson.id + "/" + config.id;
|
layout.push({
|
||||||
if (setWidget !== "nil") layout.push(widget);
|
...this._getInput(),
|
||||||
if (widget.widget === "chart" && widget.type !== "bar") {
|
page: config.page,
|
||||||
const input = this._getInput();
|
descr: config.descr,
|
||||||
input.page = config.page;
|
topic: prefix + config.id + "-date",
|
||||||
input.topic =
|
});
|
||||||
this.settingsJson.mqttPrefix +
|
|
||||||
"/" +
|
|
||||||
this.settingsJson.id +
|
|
||||||
"/" +
|
|
||||||
config.id +
|
|
||||||
"-date";
|
|
||||||
input.descr = config.descr;
|
|
||||||
layout.push(input);
|
|
||||||
}
|
|
||||||
error = false;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
error = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (error) console.log("[E]", "error, widget not found: " + setWidget);
|
|
||||||
}
|
|
||||||
layout.sort(function (a, b) {
|
|
||||||
if (a.descr < b.descr) return -1;
|
|
||||||
if (a.descr > b.descr) return 1;
|
|
||||||
return 0;
|
|
||||||
});
|
|
||||||
for (let i = 0; i < layout.length; i++) {
|
|
||||||
layout[i].order = i;
|
|
||||||
}
|
}
|
||||||
|
layout.sort((a, b) => (a.descr || "").localeCompare(b.descr || ""));
|
||||||
|
layout.forEach((item, i) => (item.order = i));
|
||||||
return layout;
|
return layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user