// Basic init const electron = require("electron"); const { ScanList } = require("ethernet-ip-scanlist"); const _ = require("lodash"); const { app, BrowserWindow, ipcMain } = electron; const sqlite3 = require("sqlite3").verbose(); const db = new sqlite3.Database("./MaxWaterSystem.db"); const tagConfig = require("./tagList.json"); // To avoid being garbage collected let mainWindow; let scanList; app.on("ready", () => { mainWindow = new BrowserWindow({ width: 1000, height: 1000 }); mainWindow.loadURL(`file://${__dirname}/app/index.html`); // Wait for allowing react app to fully load // before starting to send initalized data. setTimeout(() => { setupDB(); initPLC("10.20.4.36", tagConfig.scan_list); }, 2000); }); function setupDB(){ db.run("CREATE TABLE IF NOT EXISTS tag_history (id INTEGER PRIMARY KEY, tag TEXT, value TEXT, reason TEXT, timestamp TEXT)"); } function clearAllHistory(){ db.run("DELETE FROM tag_history WHERE id > 0"); } function clearTagHistory(tagName){ db.run(`DELETE FROM tag_history WHERE tagName = "${tagName}"`); } function sendTagHistoryToDB(tag){ var stmt = db.prepare("INSERT INTO tag_history (tag, value, reason, timestamp) VALUES (?, ?, ?, ?)"); stmt.run(tag.tagName, tag.value, tag.lastSendReason, tag.lastSendTime.format()); stmt.finalize(); } function getTagHistory(tagName){ return new Promise((resolve, reject) => { db.all(`SELECT value, reason, timestamp FROM tag_history WHERE tag = "${tagName}" ORDER BY datetime(timestamp) DESC`, function(err, rows) { if (err) reject(err); resolve(rows); }); }); } function writeTag(tagName, tagValue){ scanList.tags[tagName].enipTag.value = tagValue; } function initPLC(ipAddress, tagList){ scanList = new ScanList(ipAddress); const setupTags = new Promise( (resolve) => { resolve(_.forEach(tagList, ({tag, vanityName, storePeriod, storeChangeDelta}) => { scanList.add(tag, vanityName, storePeriod, storeChangeDelta); if(tagConfig.history_tags.includes(tag)){ getTagHistory(tag).then((historyRows) => { // console.log("tag:history", {tag, historyRows}); mainWindow.webContents.send("tag:history", {tagName: tag, historyRows}); }, (err) => { console.log("getHistoryTag Error:", err); }); } })); }); setupTags.then(() => { scanList.on("Updated", (tag) => { mainWindow.webContents.send("tag:valueupdate", tag); }); scanList.on("newValue", (tag) => { sendTagHistoryToDB(tag); }); scanList.start(); const properties = { ...scanList.PLC.properties, ipAddress}; mainWindow.webContents.send("plc:connected", properties); }); } ipcMain.on("plc:initialize", (event, ipAddress, tagList) =>{ initPLC(ipAddress, tagList); }); ipcMain.on("tag:write", (event, tagName, value) => { writeTag(tagName, value); }); ipcMain.on("tag:new", (event, {tagName, vanityName, storePeriod, storeChangeDelta}) => { scanList.add(tagName, vanityName, storePeriod, storeChangeDelta); scanList.stop(); scanList.start(); }); ipcMain.on("tag:clearHistory", (event, tagName) => { clearTagHistory(tagName); }); ipcMain.on("tag:clearAllHistory", () => { clearAllHistory(); });