feat: Add a real-time Shelly device status dashboard with WebSocket updates and associated model images.
This commit is contained in:
18
server.js
18
server.js
@@ -4,6 +4,7 @@ import path from 'path';
|
||||
import sqlite3 from 'sqlite3';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { initRuleEngine, loadRules, runRules, watchRules } from './rule_engine.js';
|
||||
import { broadcastEvent, startStatusServer } from './status_server.js';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
@@ -143,6 +144,7 @@ function checkAndLogEvent(mac, component, field, type, event, connectionId = nul
|
||||
if (connectionId) console.log(`[ID: ${connectionId}] Event logged: ${event} on ${component} (${field})`);
|
||||
db.run("INSERT INTO events (channel_id, event, timestamp) VALUES (?, ?, ?)", [channelId, String(event), new Date().toISOString()]);
|
||||
forwardToUpstream();
|
||||
broadcastEvent(mac, component, field, type, event);
|
||||
runRules(mac, component, field, type, event);
|
||||
return;
|
||||
}
|
||||
@@ -160,6 +162,7 @@ function checkAndLogEvent(mac, component, field, type, event, connectionId = nul
|
||||
if (connectionId) console.log(`[ID: ${connectionId}] Status change logged: ${event} on ${component} (${field})`);
|
||||
db.run("INSERT INTO events (channel_id, event, timestamp) VALUES (?, ?, ?)", [channelId, currentEventStr, new Date().toISOString()]);
|
||||
forwardToUpstream();
|
||||
broadcastEvent(mac, component, field, type, currentEventStr);
|
||||
runRules(mac, component, field, type, currentEventStr);
|
||||
}
|
||||
});
|
||||
@@ -179,6 +182,9 @@ loadRules().then(() => {
|
||||
console.error('Error loading rules:', err);
|
||||
});
|
||||
|
||||
// Start status dashboard server
|
||||
startStatusServer();
|
||||
|
||||
// Global counter for connection IDs
|
||||
let connectionIdCounter = 0;
|
||||
|
||||
@@ -349,11 +355,17 @@ wss.on('connection', (ws, req) => {
|
||||
if (data.method === 'NotifyEvent') {
|
||||
if (data.params && data.params.events) {
|
||||
const mac = connectionDeviceMap.get(connectionId);
|
||||
// Even if we don't have MAC from map yet (unlikely for identified device), we can try data.src or skip
|
||||
// Known button event types to store
|
||||
const knownButtonEvents = ['single_push', 'double_push', 'triple_push', 'long_push', 'btn_down', 'btn_up'];
|
||||
|
||||
if (mac) {
|
||||
data.params.events.forEach(evt => {
|
||||
// Pass the button event (btn_down/up/etc) as values
|
||||
checkAndLogEvent(mac, evt.component, 'button', 'enum', evt.event, connectionId);
|
||||
// Only store known input button events
|
||||
if (evt.component.startsWith('input') && knownButtonEvents.includes(evt.event)) {
|
||||
checkAndLogEvent(mac, evt.component, 'button', 'enum', evt.event, connectionId);
|
||||
} else {
|
||||
console.log(`[ID: ${connectionId}] Skipped unknown event: ${evt.component} -> ${evt.event}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user