mirror of
https://github.com/sergeyyarkov/modbus-logger.git
synced 2026-10-11 02:18:51 +03:00
progress
This commit is contained in:
parent
8932402d3b
commit
0e10984830
@ -39,6 +39,21 @@ CREATE TABLE IF NOT EXISTS "display_values" (
|
|||||||
FOREIGN KEY("slave_id") REFERENCES modbus_slaves("id") ON DELETE CASCADE
|
FOREIGN KEY("slave_id") REFERENCES modbus_slaves("id") ON DELETE CASCADE
|
||||||
);
|
);
|
||||||
|
|
||||||
|
-- CREATE TABLE IF NOT EXISTS "modbus_log" (
|
||||||
|
-- "id" INTEGER,
|
||||||
|
-- "date" DATE NOT NULL,
|
||||||
|
-- "slave_id" INTEGER NOT NULL,
|
||||||
|
|
||||||
|
-- -- JSON Format:
|
||||||
|
-- -- {
|
||||||
|
-- -- graph: [{ reg_addr: 1 value: 4 }],
|
||||||
|
-- -- display_values: [{ reg_addr: 1, name: "CV1" }]
|
||||||
|
-- -- }
|
||||||
|
-- "data" TEXT NOT NULL,
|
||||||
|
-- PRIMARY KEY("id"),
|
||||||
|
-- FOREIGN KEY("slave_id") REFERENCES modbus_slaves("id") ON DELETE CASCADE
|
||||||
|
-- )
|
||||||
|
|
||||||
INSERT INTO "modbus_slaves" (
|
INSERT INTO "modbus_slaves" (
|
||||||
"id", "name", "g_display_reg_addr", "g_display_reg_format", "g_y_label", "is_logging"
|
"id", "name", "g_display_reg_addr", "g_display_reg_format", "g_y_label", "is_logging"
|
||||||
) VALUES
|
) VALUES
|
||||||
|
|||||||
@ -28,15 +28,21 @@
|
|||||||
<div class="border-r min-w-[256px] p-2.5 pt-5">
|
<div class="border-r min-w-[256px] p-2.5 pt-5">
|
||||||
<div class="flex flex-col space-y-1">
|
<div class="flex flex-col space-y-1">
|
||||||
<span class="italic text-sm">Devices:</span>
|
<span class="italic text-sm">Devices:</span>
|
||||||
<span x-show="devices.length === 0" class="text-gray-500 text-sm text-center block">No devices added.</span>
|
<span x-show="devices.length === 0" class="text-gray-500 text-sm text-center block"
|
||||||
|
>No devices added.</span
|
||||||
|
>
|
||||||
<div class="flex flex-col max-h-[520px] overflow-y-auto space-y-2">
|
<div class="flex flex-col max-h-[520px] overflow-y-auto space-y-2">
|
||||||
<template x-for="device in devices">
|
<template x-for="device in devices">
|
||||||
<button @click="selectDevice(device)" :class="{'bg-gray-100': selectedDevice?.id === device.id}" class="w-full select-none border px-2.5 py-3 text-left rounded-sm hover:bg-gray-100 cursor-pointer">
|
<button
|
||||||
|
@click="selectDevice(device)"
|
||||||
|
:class="{'bg-gray-100': selectedDevice?.id === device.id}"
|
||||||
|
class="w-full select-none border px-2.5 py-3 text-left rounded-sm hover:bg-gray-100 cursor-pointer"
|
||||||
|
>
|
||||||
<span x-text="device.name" class="text-md font-bold"></span>
|
<span x-text="device.name" class="text-md font-bold"></span>
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<button class="w-full text-center border-2 border-dashed rounded-sm hover:bg-gray-50 cursor-pointer text-left">
|
<button class="w-full text-center border-2 border-dashed rounded-sm hover:bg-gray-50 cursor-pointer">
|
||||||
<span class="text-4xl text-gray-400 select-none">+</span>
|
<span class="text-4xl text-gray-400 select-none">+</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -44,13 +50,12 @@
|
|||||||
<div>
|
<div>
|
||||||
<span class="italic text-sm">Connection:</span>
|
<span class="italic text-sm">Connection:</span>
|
||||||
<div class="flex flex-col mt-1.5">
|
<div class="flex flex-col mt-1.5">
|
||||||
<span class="text-sm">Status:
|
<span class="text-sm"
|
||||||
|
>Status:
|
||||||
<b x-show="$store.app.is_opened" class="text-green-700">Opened</b>
|
<b x-show="$store.app.is_opened" class="text-green-700">Opened</b>
|
||||||
<b x-show="!$store.app.is_opened" class="text-red-700">Closed</b>
|
<b x-show="!$store.app.is_opened" class="text-red-700">Closed</b>
|
||||||
</span>
|
</span>
|
||||||
<a class="text-sm" @click="$store.app.setPage('configuration')" href="#">
|
<a class="text-sm" @click="$store.app.setPage('configuration')" href="#"> Reconfigurate </a>
|
||||||
Reconfigurate
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -60,7 +65,12 @@
|
|||||||
<h2 x-text="selectedDevice?.name" class="font-bold text-3xl my-2"></h2>
|
<h2 x-text="selectedDevice?.name" class="font-bold text-3xl my-2"></h2>
|
||||||
<div>
|
<div>
|
||||||
<a href="#">Edit</a>
|
<a href="#">Edit</a>
|
||||||
<a @click="$store.confirmDialog.open('Remove device', `Delete ${selectedDevice.name}? All logs will be cleared.`, removeDevice, selectedDevice.id)" class="text-red-500" href="#">Delete</a>
|
<a
|
||||||
|
@click="$store.confirmDialog.open('Remove device', `Delete ${selectedDevice.name}? All logs will be cleared.`, removeDevice, selectedDevice.id)"
|
||||||
|
class="text-red-500"
|
||||||
|
href="#"
|
||||||
|
>Delete</a
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
@ -285,15 +295,25 @@
|
|||||||
</main>
|
</main>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<!-- Confirm dialog -->
|
||||||
<div x-show="$store.confirmDialog.isOpen" class="backdrop z-50">
|
<div x-show="$store.confirmDialog.isOpen" class="backdrop z-50">
|
||||||
<div role="dialog" @click.away="$store.confirmDialog.close()" class="px-4 py-3.5 ml-auto mr-auto mt-20 bg-white max-w-md border rounded-sm">
|
<div
|
||||||
|
role="dialog"
|
||||||
|
@click.away="$store.confirmDialog.close()"
|
||||||
|
class="px-4 py-3.5 ml-auto mr-auto mt-20 bg-white max-w-md border rounded-sm"
|
||||||
|
>
|
||||||
<div class="flex justify-between items-center">
|
<div class="flex justify-between items-center">
|
||||||
<h2 x-text="$store.confirmDialog.labels.title" class="font-bold text-lg"></h2>
|
<h2 x-text="$store.confirmDialog.labels.title" class="font-bold text-lg"></h2>
|
||||||
<button @click="$store.confirmDialog.close()" aria-label="Close">
|
<button @click="$store.confirmDialog.close()" aria-label="Close">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M6.4 19L5 17.6l5.6-5.6L5 6.4L6.4 5l5.6 5.6L17.6 5L19 6.4L13.4 12l5.6 5.6l-1.4 1.4l-5.6-5.6L6.4 19Z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M6.4 19L5 17.6l5.6-5.6L5 6.4L6.4 5l5.6 5.6L17.6 5L19 6.4L13.4 12l5.6 5.6l-1.4 1.4l-5.6-5.6L6.4 19Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr />
|
||||||
<p x-text="$store.confirmDialog.labels.body"></p>
|
<p x-text="$store.confirmDialog.labels.body"></p>
|
||||||
<div class="mt-4 flex justify-end space-x-2">
|
<div class="mt-4 flex justify-end space-x-2">
|
||||||
<button @click="$store.confirmDialog.confirm()" class="btn">Confirm</button>
|
<button @click="$store.confirmDialog.confirm()" class="btn">Confirm</button>
|
||||||
|
|||||||
@ -4,13 +4,7 @@ import api from "./api.js";
|
|||||||
import * as utils from "./utils/index.js";
|
import * as utils from "./utils/index.js";
|
||||||
|
|
||||||
const pages = ["loading", "monitoring", "configuration", "404"];
|
const pages = ["loading", "monitoring", "configuration", "404"];
|
||||||
let graphData = [];
|
let graphData = [[0, 0]];
|
||||||
const t = new Date();
|
|
||||||
|
|
||||||
for (var i = 10; i >= 0; i--) {
|
|
||||||
var x = new Date(t.getTime() - i * 1000);
|
|
||||||
graphData.push([x, Math.random()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener("alpine:init", async () => {
|
document.addEventListener("alpine:init", async () => {
|
||||||
Alpine.store("app", {
|
Alpine.store("app", {
|
||||||
@ -31,7 +25,7 @@ document.addEventListener("alpine:init", async () => {
|
|||||||
error: null,
|
error: null,
|
||||||
async init() {
|
async init() {
|
||||||
try {
|
try {
|
||||||
const connStatusEventSource = new EventSource('/api/modbus/status');
|
const connStatusEventSource = new EventSource("/api/modbus/status");
|
||||||
const { config } = await api.get("/app/config");
|
const { config } = await api.get("/app/config");
|
||||||
const { is_configured } = await api.get("/app/is_configured");
|
const { is_configured } = await api.get("/app/is_configured");
|
||||||
|
|
||||||
@ -39,7 +33,7 @@ document.addEventListener("alpine:init", async () => {
|
|||||||
|
|
||||||
if (config) this.config = config;
|
if (config) this.config = config;
|
||||||
if (is_configured) {
|
if (is_configured) {
|
||||||
connStatusEventSource.onmessage = (e) => (this.is_opened = e.data === 'true');
|
connStatusEventSource.onmessage = (e) => (this.is_opened = e.data === "true");
|
||||||
await utils.wait(500);
|
await utils.wait(500);
|
||||||
this.currentPage = "monitoring";
|
this.currentPage = "monitoring";
|
||||||
return;
|
return;
|
||||||
@ -63,28 +57,28 @@ document.addEventListener("alpine:init", async () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Alpine.data('monitoringPage', () => ({
|
Alpine.data("monitoringPage", () => ({
|
||||||
selectedDevice: null,
|
selectedDevice: null,
|
||||||
devices: [],
|
devices: [],
|
||||||
async init() {
|
async init() {
|
||||||
try {
|
try {
|
||||||
this.$store.app.currentPage = 'loading'
|
this.$store.app.currentPage = "loading";
|
||||||
var g = new Dygraph(document.getElementById("div_g"), graphData, {
|
var g = new Dygraph(document.getElementById("div_g"), graphData, {
|
||||||
drawPoints: false,
|
drawPoints: false,
|
||||||
showRoller: false,
|
showRoller: false,
|
||||||
ylabel: 'Y Label',
|
ylabel: "Y Label",
|
||||||
valueRange: [0.0, 1.8],
|
valueRange: [0.0, 1.8],
|
||||||
//labels: ["Time", "Random"],
|
//labels: ["Time", "Random"],
|
||||||
});
|
});
|
||||||
this.devices = await api.get('/modbus/devices');
|
this.devices = await api.get("/modbus/devices");
|
||||||
window.intervalId = setInterval(() => {
|
window.intervalId = setInterval(() => {
|
||||||
graphData.push([new Date(), Math.random()]);
|
graphData.push([new Date(), Math.random()]);
|
||||||
g.updateOptions({ file: graphData })
|
g.updateOptions({ file: graphData });
|
||||||
}, 500)
|
}, 500);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.$store.app.error = error;
|
this.$store.app.error = error;
|
||||||
} finally {
|
} finally {
|
||||||
this.$store.app.currentPage = 'monitoring'
|
this.$store.app.currentPage = "monitoring";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
selectDevice(device) {
|
selectDevice(device) {
|
||||||
@ -95,13 +89,13 @@ document.addEventListener("alpine:init", async () => {
|
|||||||
async removeDevice(id, ctx) {
|
async removeDevice(id, ctx) {
|
||||||
try {
|
try {
|
||||||
//await api.post('/modbus/remove_device', { id });
|
//await api.post('/modbus/remove_device', { id });
|
||||||
this.devices = _this.devices.filter(d => d.id != id);
|
this.devices = _this.devices.filter((d) => d.id != id);
|
||||||
this.selectedDevice = null;
|
this.selectedDevice = null;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error while removing device.', error)
|
console.error("Error while removing device.", error);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}))
|
}));
|
||||||
|
|
||||||
Alpine.data("configAppPage", () => ({
|
Alpine.data("configAppPage", () => ({
|
||||||
selectedConnectionType: "TCP",
|
selectedConnectionType: "TCP",
|
||||||
@ -137,12 +131,12 @@ document.addEventListener("alpine:init", async () => {
|
|||||||
Alpine.store("confirmDialog", {
|
Alpine.store("confirmDialog", {
|
||||||
isOpen: false,
|
isOpen: false,
|
||||||
labels: {
|
labels: {
|
||||||
title: 'Confirm dialog',
|
title: "Confirm dialog",
|
||||||
body: 'Are you sure you want to perform this action?',
|
body: "Are you sure you want to perform this action?",
|
||||||
},
|
},
|
||||||
cb: {
|
cb: {
|
||||||
fn: null,
|
fn: null,
|
||||||
args: []
|
args: [],
|
||||||
},
|
},
|
||||||
open(title, body, cb, ...args) {
|
open(title, body, cb, ...args) {
|
||||||
this.isOpen = true;
|
this.isOpen = true;
|
||||||
@ -156,6 +150,6 @@ document.addEventListener("alpine:init", async () => {
|
|||||||
},
|
},
|
||||||
close() {
|
close() {
|
||||||
this.isOpen = false;
|
this.isOpen = false;
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user