feat: Implement real-time rule status updates and dashboard display via WebSockets.

This commit is contained in:
sebseb7
2026-01-18 05:52:54 -05:00
parent a381b0e121
commit e226032d0b
4 changed files with 247 additions and 6 deletions

View File

@@ -15,13 +15,15 @@ const RULES_DIR = path.join(__dirname, 'rules');
let rules = [];
let db = null;
let sendRPCToDevice = null;
let statusUpdateCallback = null;
/**
* Initialize rule engine with database and RPC function
*/
export function initRuleEngine(database, rpcFunction) {
export function initRuleEngine(database, rpcFunction, onStatusUpdate = null) {
db = database;
sendRPCToDevice = rpcFunction;
statusUpdateCallback = onStatusUpdate;
}
/**
@@ -112,7 +114,7 @@ function getAllChannelStates() {
/**
* Create context object passed to rule scripts
*/
function createContext(triggerEvent) {
function createContext(triggerEvent, ruleName) {
return {
// The event that triggered this evaluation
trigger: triggerEvent,
@@ -144,6 +146,13 @@ function createContext(triggerEvent) {
}
},
// Push status update to dashboard
updateStatus: (status) => {
if (statusUpdateCallback) {
statusUpdateCallback(ruleName, status);
}
},
// Logging
log: (...args) => console.log('[Rule]', ...args)
};
@@ -156,10 +165,10 @@ export async function runRules(mac, component, field, type, event) {
// Cast event value to proper type
const typedEvent = castValue(event, type);
const triggerEvent = { mac, component, field, type, event: typedEvent };
const ctx = createContext(triggerEvent);
for (const rule of rules) {
try {
const ctx = createContext(triggerEvent, rule._filename);
if (typeof rule.run === 'function') {
await rule.run(ctx);
} else if (typeof rule === 'function') {
@@ -179,6 +188,36 @@ export async function reloadRules() {
await loadRules();
}
/**
* Get status from all rules that have a getStatus() hook
*/
export async function getRulesStatus() {
const statuses = [];
for (const rule of rules) {
try {
if (typeof rule.getStatus === 'function') {
const status = await rule.getStatus();
statuses.push({
name: rule._filename,
status
});
} else {
statuses.push({
name: rule._filename,
status: null
});
}
} catch (err) {
console.error(`Error getting status from rule ${rule._filename}:`, err);
statuses.push({
name: rule._filename,
status: { error: err.message }
});
}
}
return statuses;
}
/**
* Watch rules directory for changes and auto-reload
*/