This commit is contained in:
sebseb7
2025-12-26 01:41:49 +01:00
parent ad7a0d1768
commit 758684c598
9 changed files with 681 additions and 623 deletions

73
uiserver/api/outputs.js Normal file
View File

@@ -0,0 +1,73 @@
/**
* Outputs API - Output channel definitions and values
*/
module.exports = function setupOutputsApi(app, { db, OUTPUT_CHANNELS, OUTPUT_BINDINGS }) {
// GET /api/outputs - List output channel definitions
app.get('/api/outputs', (req, res) => {
res.json(OUTPUT_CHANNELS);
});
// GET /api/outputs/values - Get current output values
app.get('/api/outputs/values', (req, res) => {
try {
if (!db) throw new Error('Database not connected');
const result = {};
const stmt = db.prepare(`
SELECT channel, value FROM output_events
WHERE id IN (
SELECT MAX(id) FROM output_events GROUP BY channel
)
`);
const rows = stmt.all();
rows.forEach(row => {
result[row.channel] = row.value;
});
// Fill in defaults for missing channels
OUTPUT_CHANNELS.forEach(ch => {
if (result[ch.channel] === undefined) {
result[ch.channel] = 0;
}
});
res.json(result);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// GET /api/outputs/commands - Get desired states for bound devices
// Agents poll this to get commands. Returns { "device:channel": { state: 0|1 } }
app.get('/api/outputs/commands', (req, res) => {
try {
if (!db) throw new Error('Database not connected');
// Get current output values
const stmt = db.prepare(`
SELECT channel, value FROM output_events
WHERE id IN (
SELECT MAX(id) FROM output_events GROUP BY channel
)
`);
const rows = stmt.all();
const outputValues = {};
rows.forEach(row => {
outputValues[row.channel] = row.value;
});
// Map to device commands
const commands = {};
for (const [outputChannel, binding] of Object.entries(OUTPUT_BINDINGS)) {
const value = outputValues[outputChannel] ?? 0;
const deviceKey = `${binding.device}:${binding.channel}`;
commands[deviceKey] = {
state: value > 0 ? 1 : 0,
source: outputChannel
};
}
res.json(commands);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
};