This commit is contained in:
sebseb7
2025-12-25 03:52:09 +01:00
parent 0aa7995a8a
commit 489e07d4e1
2 changed files with 45 additions and 0 deletions

View File

@@ -60,6 +60,8 @@ struct Config {
server_url: String,
api_key: String,
poll_interval_secs: u64,
#[serde(default)]
command_url: Option<String>, // HTTP URL for command polling (e.g., http://localhost:3905/api/outputs/commands)
devices: Vec<DeviceConfig>,
}

View File

@@ -266,6 +266,49 @@ module.exports = {
}
});
// Output bindings: map virtual outputs to physical devices
// Format: outputChannel -> { device, channel, type }
const OUTPUT_BINDINGS = {
'BigDehumid': { device: 'tapo', channel: 'r0', type: 'switch' },
'CO2Valve': { device: 'tapo', channel: 'c', type: 'switch' },
};
// 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 });
}
});
// GET /api/rules - List all rules
app.get('/api/rules', (req, res) => {
try {