From d68aa6adca0752318731b4a7207876b4b61e6681 Mon Sep 17 00:00:00 2001 From: Adrian Jagielak Date: Fri, 25 Jul 2025 16:03:41 +0200 Subject: [PATCH] Update demo mode fake state handling --- futurehome/CHANGELOG.md | 1 + futurehome/src/fimp/fimp.ts | 2 +- futurehome/src/ha/update_state.ts | 14 +++++++------- futurehome/src/mqtt/demo_client.ts | 18 ++++++++++++++++-- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/futurehome/CHANGELOG.md b/futurehome/CHANGELOG.md index 8522077..26017df 100644 --- a/futurehome/CHANGELOG.md +++ b/futurehome/CHANGELOG.md @@ -5,6 +5,7 @@ - Added support for 'media_player' service. - Removed demo mode 'optimistic' override causing switches to look weird. +- Updated demo mode fake state handling. ## 0.1.3 (25.07.2025) diff --git a/futurehome/src/fimp/fimp.ts b/futurehome/src/fimp/fimp.ts index 5b8e910..fee5aa5 100644 --- a/futurehome/src/fimp/fimp.ts +++ b/futurehome/src/fimp/fimp.ts @@ -164,7 +164,7 @@ address: "${address}", service: "${service}", uid: "${uid}", cmd: "${cmd}", -val: "${JSON.stringify(val)}", +val: ${JSON.stringify(val)}, val_t: "${val_t}" `); diff --git a/futurehome/src/ha/update_state.ts b/futurehome/src/ha/update_state.ts index 187cfe6..5dd081f 100644 --- a/futurehome/src/ha/update_state.ts +++ b/futurehome/src/ha/update_state.ts @@ -273,10 +273,10 @@ export function haUpdateStateValueReport(parameters: { attrName: string; }) { // Strip the FIMP envelope so we end up with "/rt:dev/…/ad:x_y" - const sensorAddr = parameters.topic.replace(/^pt:j1\/mt:evt/, ''); + const addr = parameters.topic.replace(/^pt:j1\/mt:evt/, ''); for (const [stateTopic, payload] of Object.entries(haStateCache)) { - if (!payload[sensorAddr]) continue; + if (!payload[addr]) continue; // Check if the new value has a type property if ( @@ -289,7 +289,7 @@ export function haUpdateStateValueReport(parameters: { const { type: _, ...valueWithoutType } = parameters.value; // Get current attribute value - const currentAttrValue = payload[sensorAddr][parameters.attrName]; + const currentAttrValue = payload[addr][parameters.attrName]; if ( currentAttrValue && @@ -297,23 +297,23 @@ export function haUpdateStateValueReport(parameters: { !Array.isArray(currentAttrValue) ) { // Current value is already a type map, update the specific type - payload[sensorAddr][parameters.attrName] = { + payload[addr][parameters.attrName] = { ...currentAttrValue, [type]: valueWithoutType, }; } else { // Current value is not a type map, convert it to one - payload[sensorAddr][parameters.attrName] = { + payload[addr][parameters.attrName] = { [type]: valueWithoutType, }; } } else { // Handle regular value update (non-typed) - payload[sensorAddr][parameters.attrName] = parameters.value; + payload[addr][parameters.attrName] = parameters.value; } log.debug( - `Publishing updated sensor value for "${sensorAddr}" to "${stateTopic}"`, + `Publishing updated state value for "${addr}" to "${stateTopic}"`, ); ha?.publish(stateTopic, JSON.stringify(payload), { retain: true, qos: 2 }); diff --git a/futurehome/src/mqtt/demo_client.ts b/futurehome/src/mqtt/demo_client.ts index d0f4eff..2f4a913 100644 --- a/futurehome/src/mqtt/demo_client.ts +++ b/futurehome/src/mqtt/demo_client.ts @@ -40,14 +40,17 @@ export class DemoFimpMqttClient implements IMqttClient { qos: 0 | 1 | 2; }, ): void { + const responseTopic = topic.replace(/^pt:j1\/mt:cmd/, 'pt:j1/mt:evt'); + setTimeout(() => { const msg = JSON.parse(value); const sendResponse = (response: FimpResponse) => { response.corid = response.corid ?? msg.uid; + response.serv = response.serv ?? msg.serv; const buffer = Buffer.from(JSON.stringify(response)); for (const handler of this.messageHandlers) { - handler(topic, buffer, { retain: false } as any); + handler(responseTopic, buffer, { retain: false } as any); } }; @@ -78,10 +81,21 @@ export class DemoFimpMqttClient implements IMqttClient { type: 'evt.pd7.response', val: { param: { state: { devices: demo_data__state } } }, }); + } else if ( + msg.type.split('.').length === 3 && + msg.type.split('.')[0] === 'cmd' && + msg.type.split('.')[2] === 'set' + ) { + sendResponse({ + type: `evt.${msg.type.split('.')[1]}.report`, + val: msg.val, + val_t: msg.val_t, + props: msg.props, + }); } else { sendResponse({}); } - }, 100); + }, 300); } on(event: 'message', handler: OnMessageCallback): void;