diff --git a/agents/ac-infinity/src/ac-client.js b/agents/ac-infinity/src/ac-client.js index 3ba31a5..2f005fa 100644 --- a/agents/ac-infinity/src/ac-client.js +++ b/agents/ac-infinity/src/ac-client.js @@ -276,8 +276,15 @@ export class ACInfinityClient { // Constrain level 0-10 const safeLevel = Math.max(0, Math.min(10, Math.round(level))); - // Mode 1 = ON (Manual), 0 = OFF - const mode = safeLevel === 0 ? 0 : 1; + // AtType Constants from reverse engineering + const AtType = { + OFF: 1, + ON: 2, + AUTO: 3 + }; + + // Mode 2 = ON (Manual), 1 = OFF + const mode = safeLevel === 0 ? AtType.OFF : AtType.ON; // Merge with existing settings // We need to send back mostly specific keys. @@ -293,7 +300,11 @@ export class ACInfinityClient { // Add mode/speak params.append('mode', mode.toString()); - params.append('speak', safeLevel.toString()); + + // NOTE: In Mode 1 (OFF), 'speak' sets the Minimum Speed (usually 0). + // In Mode 2 (ON), 'speak' sets the Maximum/Target Speed. + const speakValue = mode === AtType.OFF ? 0 : safeLevel; + params.append('speak', speakValue.toString()); // Copy other relevant fields from settings if they exist to maintain state // Common fields seen in other implementations: @@ -331,7 +342,7 @@ export class ACInfinityClient { throw new ACInfinityClientError(`Set mode failed: ${JSON.stringify(data)}`); } - console.log(`[AC] Set device ${devId} port ${port} to level ${safeLevel} (mode ${mode})`); + console.log(`[AC] Set device ${devId} port ${port} to level ${safeLevel} (mode ${mode}: ${mode === 1 ? 'OFF' : 'ON'})`); return true; } catch (error) { console.error('[AC] Error setting device port:', error); diff --git a/debug_db.js b/debug_db.js new file mode 100644 index 0000000..dcb5eed --- /dev/null +++ b/debug_db.js @@ -0,0 +1,17 @@ +const Database = require('better-sqlite3'); +const path = require('path'); + +const dbPath = path.resolve(__dirname, 'server/data/sensors.db'); +const db = new Database(dbPath, { readonly: true }); + +console.log('--- RULES ---'); +const rules = db.prepare('SELECT * FROM rules').all(); +console.log(JSON.stringify(rules, null, 2)); + +console.log('\n--- OUTPUT CHANNELS ---'); +const outputs = db.prepare('SELECT * FROM output_events WHERE channel = "CircFanLevel" ORDER BY timestamp DESC LIMIT 10').all(); +console.table(outputs); + +console.log('\n--- SENSOR DATA (ac:tent:temperature) ---'); +const sensors = db.prepare('SELECT * FROM sensor_events WHERE device = "ac" AND channel = "tent:temperature" ORDER BY timestamp DESC LIMIT 5').all(); +console.table(sensors); diff --git a/uiserver/debug_db.js b/uiserver/debug_db.js new file mode 100644 index 0000000..3611edc --- /dev/null +++ b/uiserver/debug_db.js @@ -0,0 +1,17 @@ +const Database = require('better-sqlite3'); +const path = require('path'); + +const dbPath = path.resolve(__dirname, '../server/data/sensors.db'); +const db = new Database(dbPath, { readonly: true }); + +console.log('--- RULES ---'); +const rules = db.prepare('SELECT * FROM rules').all(); +console.log(JSON.stringify(rules, null, 2)); + +console.log('\n--- OUTPUT CHANNELS ---'); +const outputs = db.prepare("SELECT * FROM output_events WHERE channel = 'CircFanLevel' ORDER BY timestamp DESC LIMIT 10").all(); +console.table(outputs); + +console.log('\n--- SENSOR DATA (ac:tent:temperature) ---'); +const sensors = db.prepare("SELECT * FROM sensor_events WHERE device = 'ac' AND channel = 'tent:temperature' ORDER BY timestamp DESC LIMIT 5").all(); +console.table(sensors); diff --git a/uiserver/webpack.config.js b/uiserver/webpack.config.js index 4389447..4572d77 100644 --- a/uiserver/webpack.config.js +++ b/uiserver/webpack.config.js @@ -297,10 +297,15 @@ function syncOutputStates() { if (row.value > 0) { const binding = OUTPUT_BINDINGS[row.channel]; if (binding) { + let commandValue = row.value; + if (binding.type === 'switch') { + commandValue = row.value > 0 ? 1 : 0; + } + const success = sendCommandToDevicePrefix(`${binding.device}:`, { device: binding.channel, action: 'set_state', - value: 1 + value: commandValue }); if (!success) { @@ -747,9 +752,7 @@ module.exports = { `); const last = lastStmt.get(channel); - if (channel === 'CircFanLevel') { - console.log('[RuleRunner] Debug Bindings:', JSON.stringify(OUTPUT_BINDINGS['CircFanLevel'])); - } + // Debug log removed const valueChanged = !last || Math.abs(last.value - value) >= Number.EPSILON;