From 3c56a30d01c61f419d78030e67cc61b3197b89dc Mon Sep 17 00:00:00 2001 From: Adrian Jagielak Date: Thu, 24 Jul 2025 16:34:58 +0200 Subject: [PATCH] Format the codebase using prettier --- futurehome/config.yaml | 2 +- futurehome/src/admin.ts | 39 +- futurehome/src/client.ts | 50 +- futurehome/src/fimp/fimp.ts | 92 ++- futurehome/src/fimp/helpers.ts | 13 +- futurehome/src/fimp/inclusion_report.ts | 33 +- futurehome/src/fimp/state.ts | 50 +- futurehome/src/fimp/vinculum_pd7_device.ts | 15 +- futurehome/src/ha/globals.ts | 4 +- futurehome/src/ha/publish_device.ts | 8 +- futurehome/src/ha/update_availability.ts | 16 +- futurehome/src/ha/update_state.ts | 27 +- futurehome/src/index.ts | 166 ++++-- futurehome/src/logger.ts | 2 +- futurehome/src/mqtt/demo_client.ts | 74 ++- futurehome/src/mqtt/demo_data/device.json | 525 ++++-------------- futurehome/src/mqtt/demo_data/state.json | 8 +- futurehome/src/mqtt/interface.ts | 42 +- futurehome/src/mqtt/real_client.ts | 33 +- futurehome/src/services/basic.ts | 17 +- futurehome/src/services/battery.ts | 11 +- futurehome/src/services/color_ctrl.ts | 76 ++- futurehome/src/services/fan_ctrl.ts | 23 +- futurehome/src/services/out_bin_switch.ts | 13 +- futurehome/src/services/out_lvl_switch.ts | 17 +- futurehome/src/services/scene_ctrl.ts | 29 +- futurehome/src/services/sensor_accelx.ts | 11 +- futurehome/src/services/sensor_accely.ts | 11 +- futurehome/src/services/sensor_accelz.ts | 11 +- futurehome/src/services/sensor_airflow.ts | 11 +- futurehome/src/services/sensor_airq.ts | 11 +- futurehome/src/services/sensor_anglepos.ts | 11 +- futurehome/src/services/sensor_atmo.ts | 11 +- futurehome/src/services/sensor_baro.ts | 11 +- futurehome/src/services/sensor_co.ts | 11 +- futurehome/src/services/sensor_co2.ts | 11 +- futurehome/src/services/sensor_contact.ts | 11 +- futurehome/src/services/sensor_current.ts | 11 +- futurehome/src/services/sensor_dew.ts | 13 +- futurehome/src/services/sensor_direct.ts | 11 +- futurehome/src/services/sensor_distance.ts | 11 +- futurehome/src/services/sensor_elresist.ts | 11 +- futurehome/src/services/sensor_freq.ts | 11 +- futurehome/src/services/sensor_gp.ts | 11 +- futurehome/src/services/sensor_gust.ts | 13 +- futurehome/src/services/sensor_humid.ts | 11 +- futurehome/src/services/sensor_lumin.ts | 11 +- futurehome/src/services/sensor_moist.ts | 11 +- futurehome/src/services/sensor_noise.ts | 11 +- futurehome/src/services/sensor_power.ts | 11 +- futurehome/src/services/sensor_presence.ts | 11 +- futurehome/src/services/sensor_rain.ts | 11 +- futurehome/src/services/sensor_rotation.ts | 11 +- futurehome/src/services/sensor_seismicint.ts | 11 +- futurehome/src/services/sensor_seismicmag.ts | 11 +- futurehome/src/services/sensor_solarrad.ts | 11 +- futurehome/src/services/sensor_tank.ts | 11 +- futurehome/src/services/sensor_temp.ts | 13 +- futurehome/src/services/sensor_tidelvl.ts | 11 +- futurehome/src/services/sensor_uv.ts | 11 +- futurehome/src/services/sensor_veloc.ts | 11 +- futurehome/src/services/sensor_voltage.ts | 11 +- futurehome/src/services/sensor_watflow.ts | 11 +- futurehome/src/services/sensor_watpressure.ts | 11 +- futurehome/src/services/sensor_wattemp.ts | 11 +- futurehome/src/services/sensor_weight.ts | 11 +- futurehome/src/services/sensor_wind.ts | 11 +- futurehome/src/services/thermostat.ts | 35 +- futurehome/src/utils.ts | 2 +- 69 files changed, 984 insertions(+), 895 deletions(-) diff --git a/futurehome/config.yaml b/futurehome/config.yaml index 2464cff..0c3f66c 100644 --- a/futurehome/config.yaml +++ b/futurehome/config.yaml @@ -1,6 +1,6 @@ # https://developers.home-assistant.io/docs/add-ons/configuration#add-on-config name: Futurehome -version: "0.0.33" +version: "0.0.34" slug: futurehome description: Local Futurehome Smarthub integration url: "https://github.com/adrianjagielak/home-assistant-futurehome" diff --git a/futurehome/src/admin.ts b/futurehome/src/admin.ts index c5e4545..3b552a6 100644 --- a/futurehome/src/admin.ts +++ b/futurehome/src/admin.ts @@ -1,53 +1,56 @@ -import { v4 as uuidv4 } from "uuid"; -import { IMqttClient } from "./mqtt/interface"; +import { v4 as uuidv4 } from 'uuid'; +import { IMqttClient } from './mqtt/interface'; export function exposeSmarthubTools( ha: IMqttClient, fimp: IMqttClient, - hubAddr = "pt:j1/mt:cmd/rt:app/rn:zb/ad:1" + hubAddr = 'pt:j1/mt:cmd/rt:app/rn:zb/ad:1', ) { - const base = "homeassistant/switch/fh_zb_pairing"; + const base = 'homeassistant/switch/fh_zb_pairing'; const device = { - identifiers: ["futurehome_hub"], - name: "Futurehome Hub", - model: "Smarthub", + identifiers: ['futurehome_hub'], + name: 'Futurehome Hub', + model: 'Smarthub', }; ha.publish( `${base}/config`, JSON.stringify({ - name: "Zigbee Pairing", - uniq_id: "fh_zb_pairing", + name: 'Zigbee Pairing', + uniq_id: 'fh_zb_pairing', cmd_t: `${base}/set`, stat_t: `${base}/state`, device, }), - { retain: true, qos: 2 } + { retain: true, qos: 2 }, ); // // keep last known state locally // let pairingOn = false; ha.subscribe(`${base}/set`); - ha.on("message", (topic, payload) => { + ha.on('message', (topic, payload) => { if (topic !== `${base}/set`) return; - const turnOn = payload.toString() === "ON"; + const turnOn = payload.toString() === 'ON'; // // optimistic update so the UI flips instantly // pairingOn = turnOn; - ha.publish(`${base}/state`, turnOn ? "ON" : "OFF", { retain: true, qos: 2 }); + ha.publish(`${base}/state`, turnOn ? 'ON' : 'OFF', { + retain: true, + qos: 2, + }); // placeholder FIMP message – adjust to real API if different fimp.publish( hubAddr, JSON.stringify({ - type: "cmd.pairing_mode.set", - service: "zigbee", + type: 'cmd.pairing_mode.set', + service: 'zigbee', uid: uuidv4(), - val_t: "str", - val: turnOn ? "start" : "stop", + val_t: 'str', + val: turnOn ? 'start' : 'stop', }), - { qos: 1 } + { qos: 1 }, ); }); diff --git a/futurehome/src/client.ts b/futurehome/src/client.ts index b88faad..2e2344e 100644 --- a/futurehome/src/client.ts +++ b/futurehome/src/client.ts @@ -1,26 +1,48 @@ -import { DemoFimpMqttClient } from "./mqtt/demo_client"; -import { IMqttClient } from "./mqtt/interface"; -import { RealMqttClient } from "./mqtt/real_client"; +import { DemoFimpMqttClient } from './mqtt/demo_client'; +import { IMqttClient } from './mqtt/interface'; +import { RealMqttClient } from './mqtt/real_client'; -export function connectHub(opts: { hubIp: string; username: string; password: string; demo: boolean; }): Promise { +export function connectHub(opts: { + hubIp: string; + username: string; + password: string; + demo: boolean; +}): Promise { const url = `mqtt://${opts.hubIp}`; return makeClient(url, 1884, opts.username, opts.password, opts.demo); } -export async function connectHA(opts: { mqttHost: string; mqttPort: number; mqttUsername: string; mqttPassword: string; }): Promise<{ ha: IMqttClient; retainedMessages: RetainedMessage[] }> { +export async function connectHA(opts: { + mqttHost: string; + mqttPort: number; + mqttUsername: string; + mqttPassword: string; +}): Promise<{ ha: IMqttClient; retainedMessages: RetainedMessage[] }> { const url = `mqtt://${opts.mqttHost}`; - const ha = await makeClient(url, opts.mqttPort, opts.mqttUsername, opts.mqttPassword, false); - const retainedMessages = await waitForHARetainedMessages(ha) + const ha = await makeClient( + url, + opts.mqttPort, + opts.mqttUsername, + opts.mqttPassword, + false, + ); + const retainedMessages = await waitForHARetainedMessages(ha); return { ha, retainedMessages }; } -function makeClient(url: string, port: number, username: string, password: string, demo: boolean): Promise { +function makeClient( + url: string, + port: number, + username: string, + password: string, + demo: boolean, +): Promise { return new Promise((resolve, reject) => { const client = demo ? new DemoFimpMqttClient() : new RealMqttClient(); client.connect(url, { port, username, password, protocolVersion: 4 }); - client.once("connect", () => resolve(client)); - client.once("error", reject); + client.once('connect', () => resolve(client)); + client.once('error', reject); }); } @@ -28,14 +50,18 @@ export type RetainedMessage = { topic: string; message: string }; async function waitForHARetainedMessages( client: IMqttClient, - timeoutMs = 3000 + timeoutMs = 3000, ): Promise { const topicPattern = /^homeassistant\/device\/futurehome.*$/; return new Promise((resolve, reject) => { const retainedMessages: RetainedMessage[] = []; - const messageHandler = (topic: string, message: Buffer, packet: { retain?: boolean }) => { + const messageHandler = ( + topic: string, + message: Buffer, + packet: { retain?: boolean }, + ) => { if (packet.retain && topicPattern.test(topic)) { retainedMessages.push({ topic, message: message.toString() }); } diff --git a/futurehome/src/fimp/fimp.ts b/futurehome/src/fimp/fimp.ts index 7a19526..ed470f8 100644 --- a/futurehome/src/fimp/fimp.ts +++ b/futurehome/src/fimp/fimp.ts @@ -1,6 +1,6 @@ -import { v4 as uuidv4 } from "uuid"; -import { log } from "../logger"; -import { IMqttClient } from "../mqtt/interface"; +import { v4 as uuidv4 } from 'uuid'; +import { log } from '../logger'; +import { IMqttClient } from '../mqtt/interface'; let fimp: IMqttClient | undefined = undefined; @@ -21,7 +21,21 @@ export type FimpResponse = { ver?: any; }; -type FimpValueType = 'string' | 'int' | 'float' | 'bool' | 'null' | 'str_array' | 'int_array' | 'float_array' | 'str_map' | 'int_map' | 'float_map' | 'bool_map' | 'object' | 'bin'; +type FimpValueType = + | 'string' + | 'int' + | 'float' + | 'bool' + | 'null' + | 'str_array' + | 'int_array' + | 'float_array' + | 'str_map' + | 'int_map' + | 'float_map' + | 'bool_map' + | 'object' + | 'bin'; export async function sendFimpMsg({ address, @@ -40,27 +54,27 @@ export async function sendFimpMsg({ }): Promise { const uid = uuidv4(); const topic = `pt:j1/mt:cmd${address}`; - const message = JSON.stringify( - { - corid: null, - ctime: new Date().toISOString(), - props: {}, - resp_to: 'pt:j1/mt:rsp/rt:app/rn:ha-futurehome/ad:addon', - serv: service, - src: 'ha-futurehome', - tags: [], - 'type': cmd, - uid: uid, - val: val, - val_t: val_t, - ver: '1', - }, - ); + const message = JSON.stringify({ + corid: null, + ctime: new Date().toISOString(), + props: {}, + resp_to: 'pt:j1/mt:rsp/rt:app/rn:ha-futurehome/ad:addon', + serv: service, + src: 'ha-futurehome', + tags: [], + type: cmd, + uid: uid, + val: val, + val_t: val_t, + ver: '1', + }); return new Promise((resolve, reject) => { const timeout = setTimeout(() => { fimp?.removeListener('message', onResponse); - const error = new Error(`Timeout waiting for FIMP response (uid: ${uid}, service: ${service}, cmd: ${cmd})`); + const error = new Error( + `Timeout waiting for FIMP response (uid: ${uid}, service: ${service}, cmd: ${cmd})`, + ); log.warn(error.message, error.stack); reject(error); }, timeoutMs); @@ -72,13 +86,17 @@ export async function sendFimpMsg({ if (msg.type === 'evt.error.report') { fimp?.removeListener('message', onResponse); - const error = new Error(`Received FIMP response for message ${uid}: error (evt.error.report) (matched using uid)`); + const error = new Error( + `Received FIMP response for message ${uid}: error (evt.error.report) (matched using uid)`, + ); log.warn(error.message, error.stack); reject(error); return; } - log.debug(`Received FIMP response for message ${uid} (matched using uid).`); + log.debug( + `Received FIMP response for message ${uid} (matched using uid).`, + ); clearTimeout(timeout); fimp?.removeListener('message', onResponse); @@ -90,13 +108,17 @@ export async function sendFimpMsg({ if (msg.type === 'evt.error.report') { fimp?.removeListener('message', onResponse); - const error = new Error(`Received FIMP response for message ${uid}: error (evt.error.report) (matched using topic)`); + const error = new Error( + `Received FIMP response for message ${uid}: error (evt.error.report) (matched using topic)`, + ); log.warn(error.message, error.stack); reject(error); return; } - log.debug(`Received FIMP response for message ${uid} (matched using topic).`); + log.debug( + `Received FIMP response for message ${uid} (matched using topic).`, + ); clearTimeout(timeout); fimp?.removeListener('message', onResponse); @@ -107,13 +129,23 @@ export async function sendFimpMsg({ const hasValidType = msg.type != null && msg.type.startsWith('evt.'); const reqCmdParts = cmd.split('.'); const resCmdParts = msg.type?.split('.') ?? []; - const hasThreeParts = resCmdParts.length === 3 && reqCmdParts.length === 3; + const hasThreeParts = + resCmdParts.length === 3 && reqCmdParts.length === 3; const middlePartMatches = resCmdParts[1] === reqCmdParts[1]; const endsWithLastPart = cmd.endsWith(resCmdParts.at(-1)!); - const reqEndsWithSetAndResEndsWithReport = reqCmdParts[2] === 'set' && resCmdParts[2] === 'report' + const reqEndsWithSetAndResEndsWithReport = + reqCmdParts[2] === 'set' && resCmdParts[2] === 'report'; const sameService = msg.serv === service; - if (hasValidType && hasThreeParts && middlePartMatches && (endsWithLastPart || reqEndsWithSetAndResEndsWithReport) && sameService) { - log.debug(`Received FIMP response for message ${uid} (matched using event name).`); + if ( + hasValidType && + hasThreeParts && + middlePartMatches && + (endsWithLastPart || reqEndsWithSetAndResEndsWithReport) && + sameService + ) { + log.debug( + `Received FIMP response for message ${uid} (matched using event name).`, + ); clearTimeout(timeout); fimp?.removeListener('message', onResponse); @@ -136,4 +168,4 @@ val_t: "${val_t}" fimp?.publish(topic, message, { qos: 1 }); }); -} \ No newline at end of file +} diff --git a/futurehome/src/fimp/helpers.ts b/futurehome/src/fimp/helpers.ts index c699c7a..b7f4431 100644 --- a/futurehome/src/fimp/helpers.ts +++ b/futurehome/src/fimp/helpers.ts @@ -1,10 +1,12 @@ /// Returns the adapter address of the device associated with the given service address. /// The service address may belong to any service on the device. -export function adapterAddressFromServiceAddress(serviceAddress: string): string { +export function adapterAddressFromServiceAddress( + serviceAddress: string, +): string { const parts = serviceAddress.split('/'); if (parts.length < 4) { - throw new Error("Invalid address format"); + throw new Error('Invalid address format'); } const adapterPart = parts[2]; // e.g., "rn:zigbee" @@ -16,11 +18,13 @@ export function adapterAddressFromServiceAddress(serviceAddress: string): string /// Returns the adapter service name of the device associated with the given service address. /// The service address may belong to any service on the device. -export function adapterServiceFromServiceAddress(serviceAddress: string): string { +export function adapterServiceFromServiceAddress( + serviceAddress: string, +): string { const parts = serviceAddress.split('/'); if (parts.length < 3) { - throw new Error("Invalid address format"); + throw new Error('Invalid address format'); } const adapterPart = parts[2]; // e.g., "rn:zigbee" @@ -31,5 +35,4 @@ export function adapterServiceFromServiceAddress(serviceAddress: string): string } return adapterName; - } diff --git a/futurehome/src/fimp/inclusion_report.ts b/futurehome/src/fimp/inclusion_report.ts index 9ebdfde..c5686bf 100644 --- a/futurehome/src/fimp/inclusion_report.ts +++ b/futurehome/src/fimp/inclusion_report.ts @@ -1,27 +1,31 @@ -import { log } from "../logger"; -import { sendFimpMsg } from "./fimp"; +import { log } from '../logger'; +import { sendFimpMsg } from './fimp'; export type InclusionReport = { address?: string | null; // Household device ID product_name?: string | null; // e.g. "SWITCH-ZR03-1" - product_hash?: string | null; // e.g. "zb - eWeLink - SWITCH-ZR03-1" - product_id?: string | null; // e.g. "SWITCH-ZR03-1" - manufacturer_id?: string | null; // e.g. "eWeLink" - device_id?: string | null; // e.g. "b4:0e:cf:d1:bc:2a:00:00" - hw_ver?: string | null; // e.g. "0" - sw_ver?: string | null; // e.g. "0x0" - comm_tech?: string | null; // e.g. "zigbee" - power_source?: string | null; // e.g. "battery" + product_hash?: string | null; // e.g. "zb - eWeLink - SWITCH-ZR03-1" + product_id?: string | null; // e.g. "SWITCH-ZR03-1" + manufacturer_id?: string | null; // e.g. "eWeLink" + device_id?: string | null; // e.g. "b4:0e:cf:d1:bc:2a:00:00" + hw_ver?: string | null; // e.g. "0" + sw_ver?: string | null; // e.g. "0x0" + comm_tech?: string | null; // e.g. "zigbee" + power_source?: string | null; // e.g. "battery" services?: InclusionReportService[] | null; }; export type InclusionReportService = { name?: string | null; address?: string | null; - props?: { [key: string]: any } | null + props?: { [key: string]: any } | null; }; -export async function getInclusionReport(parameters: { adapterAddress: string; adapterService: string; deviceId: string }): Promise { +export async function getInclusionReport(parameters: { + adapterAddress: string; + adapterService: string; + deviceId: string; +}): Promise { try { const inclusionReport = await sendFimpMsg({ address: parameters.adapterAddress, @@ -33,6 +37,9 @@ export async function getInclusionReport(parameters: { adapterAddress: string; a return inclusionReport.val; } catch (e) { - log.error(`Failed getting inclusion report for adapterAddress: ${parameters.adapterAddress}, adapterService: ${parameters.adapterService}, deviceId: ${parameters.deviceId}`, e) + log.error( + `Failed getting inclusion report for adapterAddress: ${parameters.adapterAddress}, adapterService: ${parameters.adapterService}, deviceId: ${parameters.deviceId}`, + e, + ); } } diff --git a/futurehome/src/fimp/state.ts b/futurehome/src/fimp/state.ts index f419f13..e3cfc0b 100644 --- a/futurehome/src/fimp/state.ts +++ b/futurehome/src/fimp/state.ts @@ -1,20 +1,34 @@ export type DeviceState = { id?: number | null; - services?: DeviceStateService[] | null + services?: DeviceStateService[] | null; }; export type DeviceStateService = { addr?: string; attributes?: Attribute[]; name?: string; -} +}; export type Attribute = { name: string; values: AttributeValue[]; -} +}; -export type AttributeValue = StringValue | IntValue | FloatValue | BoolValue | NullValue | StrArrayValue | IntArrayValue | FloatArrayValue | StrMapValue | IntMapValue | FloatMapValue | BoolMapValue | ObjectValue | BinValue; +export type AttributeValue = + | StringValue + | IntValue + | FloatValue + | BoolValue + | NullValue + | StrArrayValue + | IntArrayValue + | FloatArrayValue + | StrMapValue + | IntMapValue + | FloatMapValue + | BoolMapValue + | ObjectValue + | BinValue; export type Timestamp = string; @@ -22,49 +36,49 @@ export type StringValue = { ts: Timestamp; val: string; val_t: 'string'; -} +}; export type IntValue = { ts: Timestamp; val: number; val_t: 'int'; -} +}; export type FloatValue = { ts: Timestamp; val: number; val_t: 'float'; -} +}; export type BoolValue = { ts: Timestamp; val: boolean; val_t: 'bool'; -} +}; export type NullValue = { ts: Timestamp; val?: null; val_t: 'null'; -} +}; export type StrArrayValue = { ts: Timestamp; val: string[]; val_t: 'str_array'; -} +}; export type IntArrayValue = { ts: Timestamp; val: number[]; val_t: 'int_array'; -} +}; export type FloatArrayValue = { ts: Timestamp; val: number[]; val_t: 'float_array'; -} +}; export type StrMapValue = { ts: Timestamp; @@ -72,7 +86,7 @@ export type StrMapValue = { [key: string]: string; }; val_t: 'str_map'; -} +}; export type IntMapValue = { ts: Timestamp; @@ -80,7 +94,7 @@ export type IntMapValue = { [key: string]: number; }; val_t: 'int_map'; -} +}; export type FloatMapValue = { ts: Timestamp; @@ -88,7 +102,7 @@ export type FloatMapValue = { [key: string]: number; }; val_t: 'float_map'; -} +}; export type BoolMapValue = { ts: Timestamp; @@ -96,7 +110,7 @@ export type BoolMapValue = { [key: string]: boolean; }; val_t: 'bool_map'; -} +}; export type ObjectValue = { ts: Timestamp; @@ -104,10 +118,10 @@ export type ObjectValue = { [key: string]: any; }; val_t: 'object'; -} +}; export type BinValue = { ts: Timestamp; val: string; val_t: 'bin'; -} +}; diff --git a/futurehome/src/fimp/vinculum_pd7_device.ts b/futurehome/src/fimp/vinculum_pd7_device.ts index 04aea72..127aee2 100644 --- a/futurehome/src/fimp/vinculum_pd7_device.ts +++ b/futurehome/src/fimp/vinculum_pd7_device.ts @@ -8,7 +8,20 @@ export type VinculumPd7Device = { model?: string | null; // "Model alias", e.g. "TS0202" modelAlias?: string | null; - functionality?: 'appliance' | 'climate' | 'energy' | 'ev_charger' | 'lighting' | 'media' | 'other' | 'power' | 'safety' | 'security' | 'shading' | string | null; + functionality?: + | 'appliance' + | 'climate' + | 'energy' + | 'ev_charger' + | 'lighting' + | 'media' + | 'other' + | 'power' + | 'safety' + | 'security' + | 'shading' + | string + | null; services?: Record | null; type?: { // User-defined device type (e.g. "sensor", "chargepoint", or "light") diff --git a/futurehome/src/ha/globals.ts b/futurehome/src/ha/globals.ts index 3cd71f2..3c02f13 100644 --- a/futurehome/src/ha/globals.ts +++ b/futurehome/src/ha/globals.ts @@ -1,5 +1,5 @@ -import { IMqttClient } from "../mqtt/interface"; -import { CommandHandlers } from "./publish_device"; +import { IMqttClient } from '../mqtt/interface'; +import { CommandHandlers } from './publish_device'; export let ha: IMqttClient | undefined = undefined; diff --git a/futurehome/src/ha/publish_device.ts b/futurehome/src/ha/publish_device.ts index f1e24ef..b33f3b5 100644 --- a/futurehome/src/ha/publish_device.ts +++ b/futurehome/src/ha/publish_device.ts @@ -274,7 +274,8 @@ export function haPublishDevice(parameters: { }, origin: { name: 'futurehome', - support_url: 'https://github.com/adrianjagielak/home-assistant-futurehome', + support_url: + 'https://github.com/adrianjagielak/home-assistant-futurehome', }, components: components, state_topic: stateTopic, @@ -283,7 +284,10 @@ export function haPublishDevice(parameters: { }; log.debug(`Publishing HA device "${configTopic}"`); - ha?.publish(configTopic, JSON.stringify(abbreviateHaMqttKeys(config)), { retain: true, qos: 2 }); + ha?.publish(configTopic, JSON.stringify(abbreviateHaMqttKeys(config)), { + retain: true, + qos: 2, + }); return { commandHandlers: handlers }; } diff --git a/futurehome/src/ha/update_availability.ts b/futurehome/src/ha/update_availability.ts index 3ad7aa5..551d46b 100644 --- a/futurehome/src/ha/update_availability.ts +++ b/futurehome/src/ha/update_availability.ts @@ -1,5 +1,5 @@ -import { log } from "../logger"; -import { ha } from "./globals"; +import { log } from '../logger'; +import { ha } from './globals'; /** * Example raw FIMP availaility (from evt.network.all_nodes_report) input: @@ -20,11 +20,15 @@ topic: homeassistant/device/futurehome_123456_1/availability online ``` */ -export function haUpdateAvailability(parameters: { hubId: string, deviceAvailability: any }) { - const availabilityTopic = `homeassistant/device/futurehome_${parameters.hubId}_${parameters.deviceAvailability.address?.toString()}/availability` +export function haUpdateAvailability(parameters: { + hubId: string; + deviceAvailability: any; +}) { + const availabilityTopic = `homeassistant/device/futurehome_${parameters.hubId}_${parameters.deviceAvailability.address?.toString()}/availability`; - const availability = parameters.deviceAvailability?.status === "UP" ? "online" : "offline"; + const availability = + parameters.deviceAvailability?.status === 'UP' ? 'online' : 'offline'; - log.debug(`Publishing HA availability "${availabilityTopic}"`) + log.debug(`Publishing HA availability "${availabilityTopic}"`); ha?.publish(availabilityTopic, availability, { retain: true, qos: 2 }); } diff --git a/futurehome/src/ha/update_state.ts b/futurehome/src/ha/update_state.ts index 5521c77..28abcd7 100644 --- a/futurehome/src/ha/update_state.ts +++ b/futurehome/src/ha/update_state.ts @@ -1,6 +1,6 @@ -import { DeviceState } from "../fimp/state"; -import { log } from "../logger"; -import { ha } from "./globals"; +import { DeviceState } from '../fimp/state'; +import { log } from '../logger'; +import { ha } from './globals'; /** * Example raw FIMP state input: @@ -77,8 +77,8 @@ topic: homeassistant/device/futurehome_123456_1/state */ const haStateCache: Record< - string, // state topic - Record> // payload (addr → { attr → value }) + string, // state topic + Record> // payload (addr → { attr → value }) > = {}; /** @@ -88,7 +88,10 @@ const haStateCache: Record< * Example MQTT topic produced for hub 123456 and device id 1: * homeassistant/device/futurehome_123456_1/state */ -export function haUpdateState(parameters: { hubId: string; deviceState: DeviceState }) { +export function haUpdateState(parameters: { + hubId: string; + deviceState: DeviceState; +}) { const stateTopic = `homeassistant/device/futurehome_${parameters.hubId}_${parameters.deviceState.id?.toString()}/state`; const haState: Record> = {}; @@ -126,9 +129,13 @@ export function haUpdateState(parameters: { hubId: string; deviceState: DeviceSt * The prefix "pt:j1/mt:evt" is removed before matching so that the remainder * exactly matches the address keys stored in the cached HA payloads. */ -export function haUpdateStateSensorReport(parameters: { topic: string; value: any, attrName: string }) { +export function haUpdateStateSensorReport(parameters: { + topic: string; + value: any; + 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 sensorAddr = parameters.topic.replace(/^pt:j1\/mt:evt/, ''); for (const [stateTopic, payload] of Object.entries(haStateCache)) { if (!payload[sensorAddr]) continue; @@ -136,7 +143,9 @@ export function haUpdateStateSensorReport(parameters: { topic: string; value: an // Update the reading in‑place payload[sensorAddr][parameters.attrName] = parameters.value; - log.debug(`Publishing updated sensor value for "${sensorAddr}" to "${stateTopic}"`); + log.debug( + `Publishing updated sensor value for "${sensorAddr}" to "${stateTopic}"`, + ); ha?.publish(stateTopic, JSON.stringify(payload), { retain: true, qos: 2 }); haStateCache[stateTopic] = payload; diff --git a/futurehome/src/index.ts b/futurehome/src/index.ts index b3e3279..89ceba8 100644 --- a/futurehome/src/index.ts +++ b/futurehome/src/index.ts @@ -1,15 +1,15 @@ -import { connectHub, connectHA, RetainedMessage } from "./client"; -import { log } from "./logger"; -import { FimpResponse, sendFimpMsg, setFimp } from "./fimp/fimp"; -import { haCommandHandlers, setHa, setHaCommandHandlers } from "./ha/globals"; -import { CommandHandlers, haPublishDevice } from "./ha/publish_device"; -import { haUpdateState, haUpdateStateSensorReport } from "./ha/update_state"; -import { VinculumPd7Device } from "./fimp/vinculum_pd7_device"; -import { haUpdateAvailability } from "./ha/update_availability"; -import { delay } from "./utils"; +import { connectHub, connectHA, RetainedMessage } from './client'; +import { log } from './logger'; +import { FimpResponse, sendFimpMsg, setFimp } from './fimp/fimp'; +import { haCommandHandlers, setHa, setHaCommandHandlers } from './ha/globals'; +import { CommandHandlers, haPublishDevice } from './ha/publish_device'; +import { haUpdateState, haUpdateStateSensorReport } from './ha/update_state'; +import { VinculumPd7Device } from './fimp/vinculum_pd7_device'; +import { haUpdateAvailability } from './ha/update_availability'; +import { delay } from './utils'; (async () => { - const hubIp = process.env.FH_HUB_IP || "futurehome-smarthub.local"; + const hubIp = process.env.FH_HUB_IP || 'futurehome-smarthub.local'; const hubUsername = process.env.FH_USERNAME || ''; const hubPassword = process.env.FH_PASSWORD || ''; const demoMode = (process.env.DEMO_MODE || '').toLowerCase().includes('true'); @@ -20,13 +20,20 @@ import { delay } from "./utils"; const mqttPassword = process.env.MQTT_PWD || ''; // 1) Connect to HA broker (for discovery + state + availability + commands) - log.info("Connecting to HA broker..."); - const { ha, retainedMessages } = await connectHA({ mqttHost, mqttPort, mqttUsername, mqttPassword, }); + log.info('Connecting to HA broker...'); + const { ha, retainedMessages } = await connectHA({ + mqttHost, + mqttPort, + mqttUsername, + mqttPassword, + }); setHa(ha); - log.info("Connected to HA broker"); + log.info('Connected to HA broker'); if (!demoMode && (!hubUsername || !hubPassword)) { - log.info("Empty username or password in non-demo mode. Removing all Futurehome devices from Home Assistant..."); + log.info( + 'Empty username or password in non-demo mode. Removing all Futurehome devices from Home Assistant...', + ); const publishWithDelay = (messages: RetainedMessage[], index = 0) => { if (index >= messages.length) return; @@ -42,17 +49,22 @@ import { delay } from "./utils"; } // 2) Connect to Futurehome hub (FIMP traffic) - log.info("Connecting to Futurehome hub..."); - const fimp = await connectHub({ hubIp, username: hubUsername, password: hubPassword, demo: demoMode }); - fimp.subscribe("#"); + log.info('Connecting to Futurehome hub...'); + const fimp = await connectHub({ + hubIp, + username: hubUsername, + password: hubPassword, + demo: demoMode, + }); + fimp.subscribe('#'); setFimp(fimp); - log.info("Connected to Futurehome hub"); + log.info('Connected to Futurehome hub'); const house = await sendFimpMsg({ address: '/rt:app/rn:vinculum/ad:1', service: 'vinculum', cmd: 'cmd.pd7.request', - val: { cmd: "get", component: null, param: { components: ['house'] } }, + val: { cmd: 'get', component: null, param: { components: ['house'] } }, val_t: 'object', timeoutMs: 30000, }); @@ -62,16 +74,20 @@ import { delay } from "./utils"; address: '/rt:app/rn:vinculum/ad:1', service: 'vinculum', cmd: 'cmd.pd7.request', - val: { cmd: "get", component: null, param: { components: ['device'] } }, + val: { cmd: 'get', component: null, param: { components: ['device'] } }, val_t: 'object', timeoutMs: 30000, }); - const haConfig = retainedMessages.filter(msg => msg.topic.endsWith("/config")); + const haConfig = retainedMessages.filter((msg) => + msg.topic.endsWith('/config'), + ); - const regex = new RegExp(`^homeassistant/device/futurehome_${hubId}_([a-zA-Z0-9]+)/config$`); + const regex = new RegExp( + `^homeassistant/device/futurehome_${hubId}_([a-zA-Z0-9]+)/config$`, + ); for (const haDevice of haConfig) { - log.debug('Found existing HA device', haDevice.topic) + log.debug('Found existing HA device', haDevice.topic); const match = haDevice.topic.match(regex); @@ -80,15 +96,18 @@ import { delay } from "./utils"; const idNumber = Number(deviceId); if (!isNaN(idNumber)) { - const basicDeviceData: { services?: { [key: string]: any } } = devices.val.param.device.find((d: any) => d?.id === idNumber); - const firstServiceAddr = basicDeviceData?.services ? Object.values(basicDeviceData.services)[0]?.addr : undefined;; + const basicDeviceData: { services?: { [key: string]: any } } = + devices.val.param.device.find((d: any) => d?.id === idNumber); + const firstServiceAddr = basicDeviceData?.services + ? Object.values(basicDeviceData.services)[0]?.addr + : undefined; if (!basicDeviceData || !firstServiceAddr) { log.debug('Device was removed, removing from HA.'); ha?.publish(haDevice.topic, '', { retain: true, qos: 2 }); await delay(50); } - } else if (deviceId.toLowerCase() === "hub") { + } else if (deviceId.toLowerCase() === 'hub') { // Hub admin tools, ignore } else { log.debug('Invalid format, removing.'); @@ -106,11 +125,15 @@ import { delay } from "./utils"; const commandHandlers: CommandHandlers = {}; for (const device of devices.val.param.device) { try { - const vinculumDeviceData: VinculumPd7Device = device - const deviceId = vinculumDeviceData.id.toString() - const firstServiceAddr = vinculumDeviceData.services ? Object.values(vinculumDeviceData.services)[0]?.addr : undefined;; + const vinculumDeviceData: VinculumPd7Device = device; + const deviceId = vinculumDeviceData.id.toString(); + const firstServiceAddr = vinculumDeviceData.services + ? Object.values(vinculumDeviceData.services)[0]?.addr + : undefined; - if (!firstServiceAddr) { continue; } + if (!firstServiceAddr) { + continue; + } // This is problematic when the adapter doesn't respond, so we are not getting the inclusion report for now. I'm leaving it here since we might want it in the future. // // Get additional metadata like manufacutrer or sw/hw version directly from the adapter @@ -119,14 +142,27 @@ import { delay } from "./utils"; // const deviceInclusionReport = await getInclusionReport({ adapterAddress, adapterService, deviceId }); const deviceInclusionReport = undefined; - const result = haPublishDevice({ hubId, vinculumDeviceData, deviceInclusionReport }); + const result = haPublishDevice({ + hubId, + vinculumDeviceData, + deviceInclusionReport, + }); await delay(50); Object.assign(commandHandlers, result.commandHandlers); - if (!retainedMessages.some(msg => msg.topic === `homeassistant/device/futurehome_${hubId}_${deviceId}/availability`)) { + if ( + !retainedMessages.some( + (msg) => + msg.topic === + `homeassistant/device/futurehome_${hubId}_${deviceId}/availability`, + ) + ) { // Set initial availability - haUpdateAvailability({ hubId, deviceAvailability: { address: deviceId, status: 'UP' } }); + haUpdateAvailability({ + hubId, + deviceAvailability: { address: deviceId, status: 'UP' }, + }); await delay(50); } } catch (e) { @@ -142,10 +178,12 @@ import { delay } from "./utils"; // todo // exposeSmarthubTools(); - fimp.on("message", async (topic, buf) => { + fimp.on('message', async (topic, buf) => { try { const msg: FimpResponse = JSON.parse(buf.toString()); - log.debug(`Received FIMP message on topic "${topic}":\n${JSON.stringify(msg, null, 0)}`); + log.debug( + `Received FIMP message on topic "${topic}":\n${JSON.stringify(msg, null, 0)}`, + ); switch (msg.type) { case 'evt.pd7.response': { @@ -163,8 +201,12 @@ import { delay } from "./utils"; if (devices) { const newDeviceIds = new Set(devices.map((d: any) => d?.id)); - const addedDeviceIds = [...newDeviceIds].filter(id => !knownDeviceIds.has(id)); - const removedDeviceIds = [...knownDeviceIds].filter(id => !newDeviceIds.has(id)); + const addedDeviceIds = [...newDeviceIds].filter( + (id) => !knownDeviceIds.has(id), + ); + const removedDeviceIds = [...knownDeviceIds].filter( + (id) => !newDeviceIds.has(id), + ); log.info(`Added devices: ${addedDeviceIds}`); log.info(`Removed devices: ${removedDeviceIds}`); @@ -190,14 +232,19 @@ import { delay } from "./utils"; case 'evt.open.report': case 'evt.lvl.report': case 'evt.alarm.report': - case 'evt.binary.report': - { - haUpdateStateSensorReport({ topic, value: msg.val, attrName: msg.type.split('.')[1] }) - break; - } + case 'evt.binary.report': { + haUpdateStateSensorReport({ + topic, + value: msg.val, + attrName: msg.type.split('.')[1], + }); + break; + } case 'evt.network.all_nodes_report': { const devicesAvailability = msg.val; - if (!devicesAvailability) { return; } + if (!devicesAvailability) { + return; + } for (const deviceAvailability of devicesAvailability) { haUpdateAvailability({ hubId, deviceAvailability }); await delay(50); @@ -206,50 +253,59 @@ import { delay } from "./utils"; } } } catch (e) { - log.warn("Bad FIMP JSON", e, topic, buf); + log.warn('Bad FIMP JSON', e, topic, buf); } }); const pollState = () => { - log.debug("Refreshing Vinculum state after 30 seconds..."); + log.debug('Refreshing Vinculum state after 30 seconds...'); sendFimpMsg({ address: '/rt:app/rn:vinculum/ad:1', service: 'vinculum', cmd: 'cmd.pd7.request', - val: { cmd: "get", component: null, param: { components: ['state'] } }, + val: { cmd: 'get', component: null, param: { components: ['state'] } }, val_t: 'object', timeoutMs: 30000, - }).catch(e => log.warn("Failed to request state", e)); + }).catch((e) => log.warn('Failed to request state', e)); }; // Request initial state pollState(); // Then poll every 30 seconds - if (!demoMode) { setInterval(pollState, 30 * 1000); } + if (!demoMode) { + setInterval(pollState, 30 * 1000); + } const pollDevices = () => { - log.debug("Refreshing Vinculum devices after 30 minutes..."); + log.debug('Refreshing Vinculum devices after 30 minutes...'); sendFimpMsg({ address: '/rt:app/rn:vinculum/ad:1', service: 'vinculum', cmd: 'cmd.pd7.request', - val: { cmd: "get", component: null, param: { components: ['device'] } }, + val: { cmd: 'get', component: null, param: { components: ['device'] } }, val_t: 'object', timeoutMs: 30000, - }).catch(e => log.warn("Failed to request state", e)); + }).catch((e) => log.warn('Failed to request state', e)); }; // Poll devices every 30 minutes (1800000 ms) - if (!demoMode) { setInterval(pollDevices, 30 * 60 * 1000); } + if (!demoMode) { + setInterval(pollDevices, 30 * 60 * 1000); + } ha.on('message', (topic, buf) => { // Handle Home Assistant command messages const handler = haCommandHandlers?.[topic]; if (handler) { - log.debug(`Handling Home Assistant command topic: ${topic}, payload: ${buf.toString()}`); + log.debug( + `Handling Home Assistant command topic: ${topic}, payload: ${buf.toString()}`, + ); handler(buf.toString()).catch((e) => { - log.warn(`Failed executing handler for topic: ${topic}, payload: ${buf.toString()}`, e); + log.warn( + `Failed executing handler for topic: ${topic}, payload: ${buf.toString()}`, + e, + ); }); } - }) + }); })(); diff --git a/futurehome/src/logger.ts b/futurehome/src/logger.ts index 09e5a40..42969b2 100644 --- a/futurehome/src/logger.ts +++ b/futurehome/src/logger.ts @@ -31,4 +31,4 @@ export const log = { warn: (...args: unknown[]) => _log('warn', ...args), error: (...args: unknown[]) => _log('error', ...args), fatal: (...args: unknown[]) => _log('fatal', ...args), -}; \ No newline at end of file +}; diff --git a/futurehome/src/mqtt/demo_client.ts b/futurehome/src/mqtt/demo_client.ts index 033c0c9..0a145b7 100644 --- a/futurehome/src/mqtt/demo_client.ts +++ b/futurehome/src/mqtt/demo_client.ts @@ -11,26 +11,37 @@ export class DemoFimpMqttClient implements IMqttClient { private onceConnectHandlers: (() => void)[] = []; private onceErrorHandlers: OnErrorCallback[] = []; - connect(_url: string, _options: { - port: number; - username: string; - password: string; - protocolVersion: 4; - }): void { + connect( + _url: string, + _options: { + port: number; + username: string; + password: string; + protocolVersion: 4; + }, + ): void { setTimeout(() => { this.onceConnectHandlers.forEach((h) => h()); }, 100); } - subscribe(topicObject: string, opts?: { qos: 0 | 1 | 2 }, callback?: (err: Error | null) => void): void; - subscribe(_topic: string, _opts?: any, _callback?: any): void { } + subscribe( + topicObject: string, + opts?: { qos: 0 | 1 | 2 }, + callback?: (err: Error | null) => void, + ): void; + subscribe(_topic: string, _opts?: any, _callback?: any): void {} - publish(topic: string, value: string, _options: { - retain?: boolean; - qos: 0 | 1 | 2; - }): void { + publish( + topic: string, + value: string, + _options: { + retain?: boolean; + qos: 0 | 1 | 2; + }, + ): void { setTimeout(() => { - const msg = JSON.parse(value) + const msg = JSON.parse(value); const sendResponse = (response: FimpResponse) => { response.corid = response.corid ?? msg.uid; @@ -38,14 +49,35 @@ export class DemoFimpMqttClient implements IMqttClient { for (const handler of this.messageHandlers) { handler(topic, buffer, { retain: false } as any); } - } + }; - if (msg.serv == 'vinculum' && msg.type == 'cmd.pd7.request' && msg.val?.param?.components?.includes('house')) { - sendResponse({ type: 'evt.pd7.response', val: { param: { house: { hubId: '000000004c38b232' } } } }) - } else if (msg.serv == 'vinculum' && msg.type == 'cmd.pd7.request' && msg.val?.param?.components?.includes('device')) { - sendResponse({ type: 'evt.pd7.response', val: { param: { device: demo_data__device } } }); - } else if (msg.serv == 'vinculum' && msg.type == 'cmd.pd7.request' && msg.val?.param?.components?.includes('state')) { - sendResponse({ type: 'evt.pd7.response', val: { param: { state: { devices: demo_data__state } } } }) + if ( + msg.serv == 'vinculum' && + msg.type == 'cmd.pd7.request' && + msg.val?.param?.components?.includes('house') + ) { + sendResponse({ + type: 'evt.pd7.response', + val: { param: { house: { hubId: '000000004c38b232' } } }, + }); + } else if ( + msg.serv == 'vinculum' && + msg.type == 'cmd.pd7.request' && + msg.val?.param?.components?.includes('device') + ) { + sendResponse({ + type: 'evt.pd7.response', + val: { param: { device: demo_data__device } }, + }); + } else if ( + msg.serv == 'vinculum' && + msg.type == 'cmd.pd7.request' && + msg.val?.param?.components?.includes('state') + ) { + sendResponse({ + type: 'evt.pd7.response', + val: { param: { state: { devices: demo_data__state } } }, + }); } }, 100); } @@ -92,4 +124,4 @@ export class DemoFimpMqttClient implements IMqttClient { this.onceErrorHandlers.forEach((h) => h(err)); this.onceErrorHandlers = []; } -} \ No newline at end of file +} diff --git a/futurehome/src/mqtt/demo_data/device.json b/futurehome/src/mqtt/demo_data/device.json index f084753..e452f68 100644 --- a/futurehome/src/mqtt/demo_data/device.json +++ b/futurehome/src/mqtt/demo_data/device.json @@ -23,16 +23,11 @@ "out_bin_switch": { "addr": "/rt:dev/rn:flow/ad:1/sv:out_bin_switch/ad:XFhAkhMmXNwCt4M_0", "enabled": true, - "intf": [ - "cmd.binary.set" - ], + "intf": ["cmd.binary.set"], "props": {} } }, - "supports": [ - "clear", - "poll" - ], + "supports": ["clear", "poll"], "thing": 26, "type": { "subtype": null, @@ -65,10 +60,7 @@ "modelAlias": "Heatit - Z-TRM3", "param": { "energy": 1594.5, - "supportedThermostatModes": [ - "off", - "heat" - ], + "supportedThermostatModes": ["off", "heat"], "targetTemperature": 21, "thermostatMode": "heat", "timestamp": "2025-06-16 22:13:38 +0200", @@ -100,19 +92,12 @@ "meter_elec": { "addr": "/rt:dev/rn:zw/ad:1/sv:meter_elec/ad:8_0", "enabled": true, - "intf": [ - "cmd.meter.get_report", - "evt.meter.report" - ], + "intf": ["cmd.meter.get_report", "evt.meter.report"], "props": { "is_secure": false, "is_unsecure": true, "sup_export_units": [], - "sup_units": [ - "kWh", - "W", - "V" - ] + "sup_units": ["kWh", "W", "V"] } }, "thermostat": { @@ -129,13 +114,8 @@ "props": { "is_secure": false, "is_unsecure": true, - "sup_modes": [ - "off", - "heat" - ], - "sup_setpoints": [ - "heat" - ], + "sup_modes": ["off", "heat"], + "sup_setpoints": ["heat"], "sup_temperatures": { "heat": { "max": 35, @@ -147,20 +127,14 @@ "version": { "addr": "/rt:dev/rn:zw/ad:1/sv:version/ad:8_0", "enabled": true, - "intf": [ - "cmd.version.get_report", - "evt.version.report" - ], + "intf": ["cmd.version.get_report", "evt.version.report"], "props": { "is_secure": false, "is_unsecure": true } } }, - "supports": [ - "clear", - "poll" - ], + "supports": ["clear", "poll"], "thing": 125, "type": { "subtype": null, @@ -186,10 +160,7 @@ "modelAlias": "Heatit - Z-TRM3", "param": { "energy": 3714.10009765625, - "supportedThermostatModes": [ - "off", - "heat" - ], + "supportedThermostatModes": ["off", "heat"], "targetTemperature": 14, "thermostatMode": "heat", "timestamp": "2025-07-23 19:50:36 +0200", @@ -215,19 +186,12 @@ "meter_elec": { "addr": "/rt:dev/rn:zw/ad:1/sv:meter_elec/ad:8_1", "enabled": true, - "intf": [ - "cmd.meter.get_report", - "evt.meter.report" - ], + "intf": ["cmd.meter.get_report", "evt.meter.report"], "props": { "is_secure": false, "is_unsecure": true, "sup_export_units": [], - "sup_units": [ - "kWh", - "W", - "V" - ] + "sup_units": ["kWh", "W", "V"] } }, "thermostat": { @@ -244,13 +208,8 @@ "props": { "is_secure": false, "is_unsecure": true, - "sup_modes": [ - "off", - "heat" - ], - "sup_setpoints": [ - "heat" - ], + "sup_modes": ["off", "heat"], + "sup_setpoints": ["heat"], "sup_temperatures": { "heat": { "max": 35, @@ -260,10 +219,7 @@ } } }, - "supports": [ - "clear", - "poll" - ], + "supports": ["clear", "poll"], "thing": 125, "type": { "subtype": null, @@ -297,11 +253,7 @@ "basic": { "addr": "/rt:dev/rn:zw/ad:1/sv:basic/ad:8_2", "enabled": true, - "intf": [ - "cmd.lvl.get_report", - "cmd.lvl.set", - "evt.lvl.report" - ], + "intf": ["cmd.lvl.get_report", "cmd.lvl.set", "evt.lvl.report"], "props": { "is_secure": false, "is_unsecure": true @@ -324,23 +276,15 @@ "sensor_temp": { "addr": "/rt:dev/rn:zw/ad:1/sv:sensor_temp/ad:8_2", "enabled": true, - "intf": [ - "cmd.sensor.get_report", - "evt.sensor.report" - ], + "intf": ["cmd.sensor.get_report", "evt.sensor.report"], "props": { "is_secure": false, "is_unsecure": true, - "sup_units": [ - "C" - ] + "sup_units": ["C"] } } }, - "supports": [ - "clear", - "poll" - ], + "supports": ["clear", "poll"], "thing": 125, "type": { "subtype": null, @@ -374,11 +318,7 @@ "basic": { "addr": "/rt:dev/rn:zw/ad:1/sv:basic/ad:8_3", "enabled": true, - "intf": [ - "cmd.lvl.get_report", - "cmd.lvl.set", - "evt.lvl.report" - ], + "intf": ["cmd.lvl.get_report", "cmd.lvl.set", "evt.lvl.report"], "props": { "is_secure": false, "is_unsecure": true @@ -401,23 +341,15 @@ "sensor_temp": { "addr": "/rt:dev/rn:zw/ad:1/sv:sensor_temp/ad:8_3", "enabled": true, - "intf": [ - "cmd.sensor.get_report", - "evt.sensor.report" - ], + "intf": ["cmd.sensor.get_report", "evt.sensor.report"], "props": { "is_secure": false, "is_unsecure": true, - "sup_units": [ - "C" - ] + "sup_units": ["C"] } } }, - "supports": [ - "clear", - "poll" - ], + "supports": ["clear", "poll"], "thing": 125, "type": { "subtype": null, @@ -451,11 +383,7 @@ "basic": { "addr": "/rt:dev/rn:zw/ad:1/sv:basic/ad:8_4", "enabled": true, - "intf": [ - "cmd.lvl.get_report", - "cmd.lvl.set", - "evt.lvl.report" - ], + "intf": ["cmd.lvl.get_report", "cmd.lvl.set", "evt.lvl.report"], "props": { "is_secure": false, "is_unsecure": true @@ -478,24 +406,16 @@ "sensor_temp": { "addr": "/rt:dev/rn:zw/ad:1/sv:sensor_temp/ad:8_4", "enabled": true, - "intf": [ - "cmd.sensor.get_report", - "evt.sensor.report" - ], + "intf": ["cmd.sensor.get_report", "evt.sensor.report"], "props": { "is_secure": false, "is_unsecure": true, - "sup_units": [ - "C" - ], + "sup_units": ["C"], "thing_role": "main" } } }, - "supports": [ - "clear", - "poll" - ], + "supports": ["clear", "poll"], "thing": 125, "type": { "subtype": null, @@ -532,11 +452,7 @@ "basic": { "addr": "/rt:dev/rn:zw/ad:1/sv:basic/ad:9_0", "enabled": true, - "intf": [ - "cmd.lvl.get_report", - "cmd.lvl.set", - "evt.lvl.report" - ], + "intf": ["cmd.lvl.get_report", "cmd.lvl.set", "evt.lvl.report"], "props": { "is_secure": true, "is_unsecure": true @@ -564,20 +480,11 @@ "meter_elec": { "addr": "/rt:dev/rn:zw/ad:1/sv:meter_elec/ad:9_0", "enabled": true, - "intf": [ - "cmd.meter.get_report", - "cmd.meter.reset", - "evt.meter.report" - ], + "intf": ["cmd.meter.get_report", "cmd.meter.reset", "evt.meter.report"], "props": { "is_secure": true, "is_unsecure": false, - "sup_units": [ - "kWh", - "W", - "V", - "A" - ] + "sup_units": ["kWh", "W", "V", "A"] } }, "out_bin_switch": { @@ -596,11 +503,7 @@ "scene_ctrl": { "addr": "/rt:dev/rn:zw/ad:1/sv:scene_ctrl/ad:9_0", "enabled": true, - "intf": [ - "cmd.scene.get_report", - "cmd.scene.set", - "evt.scene.report" - ], + "intf": ["cmd.scene.get_report", "cmd.scene.set", "evt.scene.report"], "props": { "is_secure": true, "is_unsecure": false, @@ -610,37 +513,25 @@ "sensor_temp": { "addr": "/rt:dev/rn:zw/ad:1/sv:sensor_temp/ad:9_0", "enabled": true, - "intf": [ - "cmd.sensor.get_report", - "evt.sensor.report" - ], + "intf": ["cmd.sensor.get_report", "evt.sensor.report"], "props": { "is_secure": true, "is_unsecure": false, - "sup_units": [ - "C", - "F" - ], + "sup_units": ["C", "F"], "thing_role": "main" } }, "version": { "addr": "/rt:dev/rn:zw/ad:1/sv:version/ad:9_0", "enabled": true, - "intf": [ - "cmd.version.get_report", - "evt.version.report" - ], + "intf": ["cmd.version.get_report", "evt.version.report"], "props": { "is_secure": true, "is_unsecure": true } } }, - "supports": [ - "clear", - "poll" - ], + "supports": ["clear", "poll"], "thing": 131, "type": { "subtype": null, @@ -677,9 +568,7 @@ "problem": false, "room": 4, "services": {}, - "supports": [ - "clear" - ], + "supports": ["clear"], "thing": 132, "type": { "subtype": null, @@ -714,10 +603,7 @@ "enabled": true, "intf": [], "props": { - "in_services": [ - "out_bin_switch", - "out_lvl_switch" - ], + "in_services": ["out_bin_switch", "out_lvl_switch"], "is_secure": true, "is_unsecure": false } @@ -725,9 +611,7 @@ "indicator_ctrl": { "addr": "/rt:dev/rn:zigbee/ad:1/sv:indicator_ctrl/ad:2_11", "enabled": true, - "intf": [ - "cmd.indicator.set_visual_element" - ], + "intf": ["cmd.indicator.set_visual_element"], "props": { "is_secure": true, "is_unsecure": false @@ -761,10 +645,7 @@ } } }, - "supports": [ - "clear", - "poll" - ], + "supports": ["clear", "poll"], "thing": 134, "type": { "subtype": null, @@ -813,18 +694,13 @@ "props": { "is_secure": true, "is_unsecure": false, - "out_services": [ - "out_bin_switch", - "out_lvl_switch" - ] + "out_services": ["out_bin_switch", "out_lvl_switch"] } }, "battery": { "addr": "/rt:dev/rn:zigbee/ad:1/sv:battery/ad:4_1", "enabled": true, - "intf": [ - "evt.lvl.report" - ], + "intf": ["evt.lvl.report"], "props": { "is_secure": true, "is_unsecure": false @@ -833,9 +709,7 @@ "indicator_ctrl": { "addr": "/rt:dev/rn:zigbee/ad:1/sv:indicator_ctrl/ad:4_1", "enabled": true, - "intf": [ - "cmd.indicator.set_visual_element" - ], + "intf": ["cmd.indicator.set_visual_element"], "props": { "is_secure": true, "is_unsecure": false @@ -844,26 +718,19 @@ "scene_ctrl": { "addr": "/rt:dev/rn:zigbee/ad:1/sv:scene_ctrl/ad:4_1", "enabled": true, - "intf": [ - "evt.scene.report" - ], + "intf": ["evt.scene.report"], "props": { "is_secure": true, "is_unsecure": false } } }, - "supports": [ - "clear", - "poll" - ], + "supports": ["clear", "poll"], "thing": 136, "type": { "subtype": "scene", "supported": { - "input": [ - "scene" - ] + "input": ["scene"] }, "type": "input" } @@ -903,18 +770,13 @@ "props": { "is_secure": true, "is_unsecure": false, - "out_services": [ - "out_bin_switch", - "out_lvl_switch" - ] + "out_services": ["out_bin_switch", "out_lvl_switch"] } }, "battery": { "addr": "/rt:dev/rn:zigbee/ad:1/sv:battery/ad:6_1", "enabled": true, - "intf": [ - "evt.lvl.report" - ], + "intf": ["evt.lvl.report"], "props": { "is_secure": true, "is_unsecure": false @@ -923,9 +785,7 @@ "indicator_ctrl": { "addr": "/rt:dev/rn:zigbee/ad:1/sv:indicator_ctrl/ad:6_1", "enabled": true, - "intf": [ - "cmd.indicator.set_visual_element" - ], + "intf": ["cmd.indicator.set_visual_element"], "props": { "is_secure": true, "is_unsecure": false @@ -934,26 +794,19 @@ "scene_ctrl": { "addr": "/rt:dev/rn:zigbee/ad:1/sv:scene_ctrl/ad:6_1", "enabled": true, - "intf": [ - "evt.scene.report" - ], + "intf": ["evt.scene.report"], "props": { "is_secure": true, "is_unsecure": false } } }, - "supports": [ - "clear", - "poll" - ], + "supports": ["clear", "poll"], "thing": 142, "type": { "subtype": "scene", "supported": { - "input": [ - "scene" - ] + "input": ["scene"] }, "type": "input" } @@ -973,13 +826,7 @@ "model": "zb - IKEA of Sweden - TRADFRI bulb E27 CWS opal 600lm", "modelAlias": "TRADFRI bulb E27 CWS opal 600lm", "param": { - "color": [ - 0, - 0, - 0, - 0, - 0 - ], + "color": [0, 0, 0, 0, 0], "dimValue": 100, "power": "off", "timestamp": "2023-03-19 16:44:21 +0100" @@ -992,11 +839,7 @@ "enabled": true, "intf": [], "props": { - "in_services": [ - "color", - "out_bin_switch", - "out_lvl_switch" - ], + "in_services": ["color", "out_bin_switch", "out_lvl_switch"], "is_secure": true, "is_unsecure": false } @@ -1004,27 +847,17 @@ "color_ctrl": { "addr": "/rt:dev/rn:zigbee/ad:1/sv:color_ctrl/ad:3_1", "enabled": true, - "intf": [ - "cmd.color.get_report", - "cmd.color.set", - "evt.color.report" - ], + "intf": ["cmd.color.get_report", "cmd.color.set", "evt.color.report"], "props": { "is_secure": true, "is_unsecure": false, - "sup_components": [ - "red", - "green", - "blue" - ] + "sup_components": ["red", "green", "blue"] } }, "indicator_ctrl": { "addr": "/rt:dev/rn:zigbee/ad:1/sv:indicator_ctrl/ad:3_1", "enabled": true, - "intf": [ - "cmd.indicator.set_visual_element" - ], + "intf": ["cmd.indicator.set_visual_element"], "props": { "is_secure": true, "is_unsecure": false @@ -1070,20 +903,12 @@ "evt.meter.report" ], "props": { - "sup_modes": [ - "off", - "on" - ], - "sup_units": [ - "W" - ] + "sup_modes": ["off", "on"], + "sup_units": ["W"] } } }, - "supports": [ - "clear", - "poll" - ], + "supports": ["clear", "poll"], "thing": 144, "type": { "subtype": null, @@ -1118,9 +943,7 @@ "indicator_ctrl": { "addr": "/rt:dev/rn:zigbee/ad:1/sv:indicator_ctrl/ad:9_1", "enabled": true, - "intf": [ - "cmd.indicator.set_visual_element" - ], + "intf": ["cmd.indicator.set_visual_element"], "props": { "is_secure": true, "is_unsecure": false @@ -1129,16 +952,11 @@ "sensor_temp": { "addr": "/rt:dev/rn:zigbee/ad:1/sv:sensor_temp/ad:9_1", "enabled": true, - "intf": [ - "cmd.sensor.get_report", - "evt.sensor.report" - ], + "intf": ["cmd.sensor.get_report", "evt.sensor.report"], "props": { "is_secure": true, "is_unsecure": false, - "sup_units": [ - "C" - ], + "sup_units": ["C"], "thing_role": "main" } }, @@ -1154,16 +972,11 @@ "is_secure": true, "is_unsecure": false, "sup_modes": [], - "sup_setpoints": [ - "heat" - ] + "sup_setpoints": ["heat"] } } }, - "supports": [ - "clear", - "poll" - ], + "supports": ["clear", "poll"], "thing": 147, "type": { "subtype": null, @@ -1197,9 +1010,7 @@ "indicator_ctrl": { "addr": "/rt:dev/rn:zigbee/ad:1/sv:indicator_ctrl/ad:7_1", "enabled": true, - "intf": [ - "cmd.indicator.set_visual_element" - ], + "intf": ["cmd.indicator.set_visual_element"], "props": { "is_secure": true, "is_unsecure": false @@ -1230,10 +1041,7 @@ "props": {} } }, - "supports": [ - "clear", - "poll" - ], + "supports": ["clear", "poll"], "thing": 150, "type": { "subtype": null, @@ -1274,9 +1082,7 @@ "indicator_ctrl": { "addr": "/rt:dev/rn:zigbee/ad:1/sv:indicator_ctrl/ad:5_1", "enabled": true, - "intf": [ - "cmd.indicator.set_visual_element" - ], + "intf": ["cmd.indicator.set_visual_element"], "props": { "is_secure": true, "is_unsecure": false @@ -1307,10 +1113,7 @@ "props": {} } }, - "supports": [ - "clear", - "poll" - ], + "supports": ["clear", "poll"], "thing": 151, "type": { "subtype": null, @@ -1362,19 +1165,13 @@ "props": { "is_secure": true, "is_unsecure": false, - "out_services": [ - "color", - "out_bin_switch", - "out_lvl_switch" - ] + "out_services": ["color", "out_bin_switch", "out_lvl_switch"] } }, "battery": { "addr": "/rt:dev/rn:zigbee/ad:1/sv:battery/ad:12_1", "enabled": true, - "intf": [ - "evt.lvl.report" - ], + "intf": ["evt.lvl.report"], "props": { "is_secure": true, "is_unsecure": false @@ -1383,9 +1180,7 @@ "indicator_ctrl": { "addr": "/rt:dev/rn:zigbee/ad:1/sv:indicator_ctrl/ad:12_1", "enabled": true, - "intf": [ - "cmd.indicator.set_visual_element" - ], + "intf": ["cmd.indicator.set_visual_element"], "props": { "is_secure": true, "is_unsecure": false @@ -1394,26 +1189,19 @@ "scene_ctrl": { "addr": "/rt:dev/rn:zigbee/ad:1/sv:scene_ctrl/ad:12_1", "enabled": true, - "intf": [ - "evt.scene.report" - ], + "intf": ["evt.scene.report"], "props": { "is_secure": true, "is_unsecure": false } } }, - "supports": [ - "clear", - "poll" - ], + "supports": ["clear", "poll"], "thing": 153, "type": { "subtype": "scene", "supported": { - "input": [ - "scene" - ] + "input": ["scene"] }, "type": "input" } @@ -1453,19 +1241,13 @@ "props": { "is_secure": true, "is_unsecure": false, - "out_services": [ - "color", - "out_bin_switch", - "out_lvl_switch" - ] + "out_services": ["color", "out_bin_switch", "out_lvl_switch"] } }, "battery": { "addr": "/rt:dev/rn:zigbee/ad:1/sv:battery/ad:14_1", "enabled": true, - "intf": [ - "evt.lvl.report" - ], + "intf": ["evt.lvl.report"], "props": { "is_secure": true, "is_unsecure": false @@ -1474,9 +1256,7 @@ "indicator_ctrl": { "addr": "/rt:dev/rn:zigbee/ad:1/sv:indicator_ctrl/ad:14_1", "enabled": true, - "intf": [ - "cmd.indicator.set_visual_element" - ], + "intf": ["cmd.indicator.set_visual_element"], "props": { "is_secure": true, "is_unsecure": false @@ -1485,26 +1265,19 @@ "scene_ctrl": { "addr": "/rt:dev/rn:zigbee/ad:1/sv:scene_ctrl/ad:14_1", "enabled": true, - "intf": [ - "evt.scene.report" - ], + "intf": ["evt.scene.report"], "props": { "is_secure": true, "is_unsecure": false } } }, - "supports": [ - "clear", - "poll" - ], + "supports": ["clear", "poll"], "thing": 155, "type": { "subtype": "scene", "supported": { - "input": [ - "scene" - ] + "input": ["scene"] }, "type": "input" } @@ -1534,9 +1307,7 @@ "indicator_ctrl": { "addr": "/rt:dev/rn:zigbee/ad:1/sv:indicator_ctrl/ad:10_2", "enabled": true, - "intf": [ - "cmd.indicator.set_visual_element" - ], + "intf": ["cmd.indicator.set_visual_element"], "props": { "is_secure": true, "is_unsecure": false @@ -1556,16 +1327,8 @@ "props": { "is_secure": true, "is_unsecure": false, - "sup_extended_vals": [ - "i1", - "p_import_react", - "u1", - "p_export_react" - ], - "sup_units": [ - "kWh", - "W" - ] + "sup_extended_vals": ["i1", "p_import_react", "u1", "p_export_react"], + "sup_units": ["kWh", "W"] } }, "ota": { @@ -1582,17 +1345,12 @@ } } }, - "supports": [ - "clear", - "poll" - ], + "supports": ["clear", "poll"], "thing": 158, "type": { "subtype": "main_elec", "supported": { - "meter": [ - "main_elec" - ] + "meter": ["main_elec"] }, "type": "meter" } @@ -1622,9 +1380,7 @@ "indicator_ctrl": { "addr": "/rt:dev/rn:zigbee/ad:1/sv:indicator_ctrl/ad:11_2", "enabled": true, - "intf": [ - "cmd.indicator.set_visual_element" - ], + "intf": ["cmd.indicator.set_visual_element"], "props": { "is_secure": true, "is_unsecure": false @@ -1648,10 +1404,7 @@ "is_unsecure": false, "serial_number": "6970631401991295", "sup_extended_vals": [], - "sup_units": [ - "kWh", - "W" - ] + "sup_units": ["kWh", "W"] } }, "ota": { @@ -1668,17 +1421,12 @@ } } }, - "supports": [ - "clear", - "poll" - ], + "supports": ["clear", "poll"], "thing": 160, "type": { "subtype": null, "supported": { - "meter": [ - "main_elec" - ] + "meter": ["main_elec"] }, "type": null } @@ -1718,18 +1466,13 @@ "props": { "is_secure": true, "is_unsecure": false, - "out_services": [ - "out_bin_switch", - "out_lvl_switch" - ] + "out_services": ["out_bin_switch", "out_lvl_switch"] } }, "battery": { "addr": "/rt:dev/rn:zigbee/ad:1/sv:battery/ad:8_1", "enabled": true, - "intf": [ - "evt.lvl.report" - ], + "intf": ["evt.lvl.report"], "props": { "is_secure": true, "is_unsecure": false @@ -1738,9 +1481,7 @@ "indicator_ctrl": { "addr": "/rt:dev/rn:zigbee/ad:1/sv:indicator_ctrl/ad:8_1", "enabled": true, - "intf": [ - "cmd.indicator.set_visual_element" - ], + "intf": ["cmd.indicator.set_visual_element"], "props": { "is_secure": true, "is_unsecure": false @@ -1749,26 +1490,19 @@ "scene_ctrl": { "addr": "/rt:dev/rn:zigbee/ad:1/sv:scene_ctrl/ad:8_1", "enabled": true, - "intf": [ - "evt.scene.report" - ], + "intf": ["evt.scene.report"], "props": { "is_secure": true, "is_unsecure": false } } }, - "supports": [ - "clear", - "poll" - ], + "supports": ["clear", "poll"], "thing": 161, "type": { "subtype": "scene", "supported": { - "input": [ - "scene" - ] + "input": ["scene"] }, "type": "input" } @@ -1797,16 +1531,11 @@ "out_bin_switch": { "addr": "/rt:dev/rn:flow/ad:1/sv:out_bin_switch/ad:oYinQN8bgwxeDt9_0", "enabled": true, - "intf": [ - "cmd.binary.set" - ], + "intf": ["cmd.binary.set"], "props": {} } }, - "supports": [ - "clear", - "poll" - ], + "supports": ["clear", "poll"], "thing": 165, "type": { "subtype": null, @@ -1847,16 +1576,11 @@ "out_bin_switch": { "addr": "/rt:dev/rn:flow/ad:1/sv:out_bin_switch/ad:tfnGPTUArLR0Vzs_0", "enabled": true, - "intf": [ - "cmd.binary.set" - ], + "intf": ["cmd.binary.set"], "props": {} } }, - "supports": [ - "clear", - "poll" - ], + "supports": ["clear", "poll"], "thing": 166, "type": { "subtype": null, @@ -1899,9 +1623,7 @@ "indicator_ctrl": { "addr": "/rt:dev/rn:zigbee/ad:1/sv:indicator_ctrl/ad:1_1", "enabled": true, - "intf": [ - "cmd.indicator.set_visual_element" - ], + "intf": ["cmd.indicator.set_visual_element"], "props": { "is_secure": true, "is_unsecure": false @@ -1924,16 +1646,8 @@ "is_secure": true, "is_unsecure": false, "serial_number": "6970631401991295", - "sup_extended_vals": [ - "u1", - "i1", - "p_import_react", - "p_export_react" - ], - "sup_units": [ - "kWh", - "W" - ] + "sup_extended_vals": ["u1", "i1", "p_import_react", "p_export_react"], + "sup_units": ["kWh", "W"] } }, "ota": { @@ -1952,30 +1666,21 @@ "sensor_temp": { "addr": "/rt:dev/rn:zigbee/ad:1/sv:sensor_temp/ad:1_1", "enabled": true, - "intf": [ - "evt.sensor.report" - ], + "intf": ["evt.sensor.report"], "props": { "is_secure": true, "is_unsecure": false, - "sup_units": [ - "C" - ], + "sup_units": ["C"], "thing_role": "main" } } }, - "supports": [ - "clear", - "poll" - ], + "supports": ["clear", "poll"], "thing": 167, "type": { "subtype": null, "supported": { - "meter": [ - "main_elec" - ] + "meter": ["main_elec"] }, "type": "meter" } @@ -2008,9 +1713,7 @@ "enabled": true, "intf": [], "props": { - "in_services": [ - "out_bin_switch" - ], + "in_services": ["out_bin_switch"], "is_secure": true, "is_unsecure": false } @@ -2018,9 +1721,7 @@ "indicator_ctrl": { "addr": "/rt:dev/rn:zigbee/ad:1/sv:indicator_ctrl/ad:13_2", "enabled": true, - "intf": [ - "cmd.indicator.set_visual_element" - ], + "intf": ["cmd.indicator.set_visual_element"], "props": { "is_secure": true, "is_unsecure": false @@ -2052,10 +1753,7 @@ "p_export_react", "p_export" ], - "sup_units": [ - "kWh", - "W" - ] + "sup_units": ["kWh", "W"] } }, "ota": { @@ -2082,10 +1780,7 @@ "props": {} } }, - "supports": [ - "clear", - "poll" - ], + "supports": ["clear", "poll"], "thing": 168, "type": { "subtype": null, diff --git a/futurehome/src/mqtt/demo_data/state.json b/futurehome/src/mqtt/demo_data/state.json index 3b0c046..0426bfd 100644 --- a/futurehome/src/mqtt/demo_data/state.json +++ b/futurehome/src/mqtt/demo_data/state.json @@ -474,9 +474,7 @@ { "ts": "2022-02-19 16:19:10 +0100", "val": { - "members": [ - "3_1" - ] + "members": ["3_1"] }, "val_t": "object" } @@ -972,9 +970,7 @@ { "ts": "2023-01-05 00:31:29 +0100", "val": { - "members": [ - "3_1" - ] + "members": ["3_1"] }, "val_t": "object" } diff --git a/futurehome/src/mqtt/interface.ts b/futurehome/src/mqtt/interface.ts index 22f78ef..bf0cbe7 100644 --- a/futurehome/src/mqtt/interface.ts +++ b/futurehome/src/mqtt/interface.ts @@ -1,20 +1,31 @@ -import { IPublishPacket, OnErrorCallback, OnMessageCallback } from "mqtt/*"; +import { IPublishPacket, OnErrorCallback, OnMessageCallback } from 'mqtt/*'; export interface IMqttClient { - connect(url: string, options: { - port: number; - username: string; - password: string; - protocolVersion: 4; - }): void; + connect( + url: string, + options: { + port: number; + username: string; + password: string; + protocolVersion: 4; + }, + ): void; subscribe(topic: string): void; - subscribe(topicObject: string, opts?: { qos: 0 | 1 | 2 }, callback?: (err: Error | null) => void): void; + subscribe( + topicObject: string, + opts?: { qos: 0 | 1 | 2 }, + callback?: (err: Error | null) => void, + ): void; - publish(topic: string, value: string, options: { - retain?: boolean; - qos: 0 | 1 | 2; - }): void; + publish( + topic: string, + value: string, + options: { + retain?: boolean; + qos: 0 | 1 | 2; + }, + ): void; on(event: 'message', handler: OnMessageCallback): void; on(event: 'error', handler: OnErrorCallback): void; @@ -22,8 +33,11 @@ export interface IMqttClient { off(event: 'message', handler: OnMessageCallback): void; off(event: 'error', handler: OnErrorCallback): void; - removeListener(event: 'message', handler: (topic: string, payload: Buffer, packet: IPublishPacket) => void): void; + removeListener( + event: 'message', + handler: (topic: string, payload: Buffer, packet: IPublishPacket) => void, + ): void; once(event: 'connect', handler: () => void): void; once(event: 'error', handler: OnErrorCallback): void; -} \ No newline at end of file +} diff --git a/futurehome/src/mqtt/real_client.ts b/futurehome/src/mqtt/real_client.ts index dcc0366..6e52dd2 100644 --- a/futurehome/src/mqtt/real_client.ts +++ b/futurehome/src/mqtt/real_client.ts @@ -8,16 +8,23 @@ export class RealMqttClient implements IMqttClient { this.client = {} as MqttClient; // gets initialized in connect() } - connect(url: string, options: { - port: number; - username: string; - password: string; - protocolVersion: 4; - }): void { + connect( + url: string, + options: { + port: number; + username: string; + password: string; + protocolVersion: 4; + }, + ): void { this.client = connect(url, options); } - subscribe(topicObject: string, opts?: { qos: 0 | 1 | 2 }, callback?: (err: Error | null) => void): void; + subscribe( + topicObject: string, + opts?: { qos: 0 | 1 | 2 }, + callback?: (err: Error | null) => void, + ): void; subscribe(topic: string, opts?: any, callback?: any): void { if (opts) { this.client.subscribe(topic, opts, callback); @@ -26,10 +33,14 @@ export class RealMqttClient implements IMqttClient { } } - publish(topic: string, value: string, options: { - retain?: boolean; - qos: 0 | 1 | 2; - }): void { + publish( + topic: string, + value: string, + options: { + retain?: boolean; + qos: 0 | 1 | 2; + }, + ): void { this.client.publish(topic, value, options); } diff --git a/futurehome/src/services/basic.ts b/futurehome/src/services/basic.ts index 1b9c90b..e42138e 100644 --- a/futurehome/src/services/basic.ts +++ b/futurehome/src/services/basic.ts @@ -7,14 +7,17 @@ // command_topic → cmd.lvl.set // ─────────────────────────────────────────────────────────────── -import { sendFimpMsg } from "../fimp/fimp"; -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { sendFimpMsg } from '../fimp/fimp'; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function basic__components( topicPrefix: string, _device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { // MQTT topic that HA will publish commands to const cmdTopic = `${topicPrefix}${svc.addr}/command`; @@ -45,9 +48,9 @@ export function basic__components( await sendFimpMsg({ address: svc.addr!, - service: "basic", - cmd: "cmd.lvl.set", - val_t: "int", + service: 'basic', + cmd: 'cmd.lvl.set', + val_t: 'int', val: lvl, }); }, diff --git a/futurehome/src/services/battery.ts b/futurehome/src/services/battery.ts index 2a43e0d..3f3e219 100644 --- a/futurehome/src/services/battery.ts +++ b/futurehome/src/services/battery.ts @@ -1,11 +1,14 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { HaMqttComponent } from "../ha/mqtt_components/_component"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { HaMqttComponent } from '../ha/mqtt_components/_component'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function battery__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const components: Record = {}; diff --git a/futurehome/src/services/color_ctrl.ts b/futurehome/src/services/color_ctrl.ts index dac597a..1443994 100644 --- a/futurehome/src/services/color_ctrl.ts +++ b/futurehome/src/services/color_ctrl.ts @@ -1,12 +1,18 @@ -import { sendFimpMsg } from "../fimp/fimp"; -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { LightComponent } from "../ha/mqtt_components/light"; -import { ServiceComponentsCreationResult, CommandHandlers } from "../ha/publish_device"; +import { sendFimpMsg } from '../fimp/fimp'; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { LightComponent } from '../ha/mqtt_components/light'; +import { + ServiceComponentsCreationResult, + CommandHandlers, +} from '../ha/publish_device'; export function color_ctrl__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const supComponents: string[] = svc.props?.sup_components ?? []; @@ -15,7 +21,10 @@ export function color_ctrl__components( } // Check if we have RGB support (minimum requirement for a useful light) - const hasRgb = supComponents.includes('red') && supComponents.includes('green') && supComponents.includes('blue'); + const hasRgb = + supComponents.includes('red') && + supComponents.includes('green') && + supComponents.includes('blue'); if (!hasRgb) { return undefined; // No RGB support, skip this service } @@ -76,7 +85,10 @@ export function color_ctrl__components( lightComponent.color_temp_value_template = `{{ (1000000 / value_json['${svc.addr}'].temp) | round(0) }}`; // Convert Kelvin to mireds lightComponent.min_mireds = 153; // ~6500K lightComponent.max_mireds = 370; // ~2700K - } else if (supComponents.includes('warm_w') && supComponents.includes('cold_w')) { + } else if ( + supComponents.includes('warm_w') && + supComponents.includes('cold_w') + ) { // Z-Wave style - warm/cold white mix lightComponent.color_temp_command_topic = colorTempCommandTopic; lightComponent.color_temp_state_topic = stateTopic; @@ -101,23 +113,23 @@ export function color_ctrl__components( await sendFimpMsg({ address: svc.addr!, - service: "color_ctrl", - cmd: "cmd.color.set", - val_t: "int_map", + service: 'color_ctrl', + cmd: 'cmd.color.set', + val_t: 'int_map', val: colorMap, }); } else if (payload === 'OFF') { // Turn off (all components to 0) const colorMap: Record = {}; - supComponents.forEach(component => { + supComponents.forEach((component) => { colorMap[component] = 0; }); await sendFimpMsg({ address: svc.addr!, - service: "color_ctrl", - cmd: "cmd.color.set", - val_t: "int_map", + service: 'color_ctrl', + cmd: 'cmd.color.set', + val_t: 'int_map', val: colorMap, }); } @@ -132,8 +144,17 @@ export function color_ctrl__components( const green = parseInt(parts[1], 10); const blue = parseInt(parts[2], 10); - if (Number.isNaN(red) || Number.isNaN(green) || Number.isNaN(blue)) return; - if (red < 0 || red > 255 || green < 0 || green > 255 || blue < 0 || blue > 255) return; + if (Number.isNaN(red) || Number.isNaN(green) || Number.isNaN(blue)) + return; + if ( + red < 0 || + red > 255 || + green < 0 || + green > 255 || + blue < 0 || + blue > 255 + ) + return; const colorMap: Record = { red, @@ -143,9 +164,9 @@ export function color_ctrl__components( await sendFimpMsg({ address: svc.addr!, - service: "color_ctrl", - cmd: "cmd.color.set", - val_t: "int_map", + service: 'color_ctrl', + cmd: 'cmd.color.set', + val_t: 'int_map', val: colorMap, }); }, @@ -167,12 +188,15 @@ export function color_ctrl__components( await sendFimpMsg({ address: svc.addr!, - service: "color_ctrl", - cmd: "cmd.color.set", - val_t: "int_map", + service: 'color_ctrl', + cmd: 'cmd.color.set', + val_t: 'int_map', val: colorMap, }); - } else if (supComponents.includes('warm_w') && supComponents.includes('cold_w')) { + } else if ( + supComponents.includes('warm_w') && + supComponents.includes('cold_w') + ) { // Z-Wave style - convert mireds to warm/cold white mix // Linear interpolation between cold (153 mireds) and warm (370 mireds) const warmRatio = (mireds - 153) / (370 - 153); @@ -189,9 +213,9 @@ export function color_ctrl__components( await sendFimpMsg({ address: svc.addr!, - service: "color_ctrl", - cmd: "cmd.color.set", - val_t: "int_map", + service: 'color_ctrl', + cmd: 'cmd.color.set', + val_t: 'int_map', val: colorMap, }); } diff --git a/futurehome/src/services/fan_ctrl.ts b/futurehome/src/services/fan_ctrl.ts index fa6b998..4a7f674 100644 --- a/futurehome/src/services/fan_ctrl.ts +++ b/futurehome/src/services/fan_ctrl.ts @@ -1,11 +1,14 @@ -import { sendFimpMsg } from "../fimp/fimp"; -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { sendFimpMsg } from '../fimp/fimp'; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function fan_ctrl__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const supModes: string[] = svc.props?.sup_modes ?? []; @@ -38,10 +41,10 @@ export function fan_ctrl__components( if (supModes.includes(mode) || mode === 'off') { await sendFimpMsg({ address: svc.addr!, - service: "fan_ctrl", - cmd: "cmd.mode.set", + service: 'fan_ctrl', + cmd: 'cmd.mode.set', val: mode, - val_t: "string", + val_t: 'string', }); } } else { @@ -49,10 +52,10 @@ export function fan_ctrl__components( if (supModes.includes(payload)) { await sendFimpMsg({ address: svc.addr!, - service: "fan_ctrl", - cmd: "cmd.mode.set", + service: 'fan_ctrl', + cmd: 'cmd.mode.set', val: payload, - val_t: "string", + val_t: 'string', }); } } diff --git a/futurehome/src/services/out_bin_switch.ts b/futurehome/src/services/out_bin_switch.ts index f1a0b94..5e20973 100644 --- a/futurehome/src/services/out_bin_switch.ts +++ b/futurehome/src/services/out_bin_switch.ts @@ -1,11 +1,14 @@ -import { sendFimpMsg } from "../fimp/fimp"; -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { sendFimpMsg } from '../fimp/fimp'; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function out_bin_switch__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const commandTopic = `${topicPrefix}${svc.addr}/command`; @@ -29,6 +32,6 @@ export function out_bin_switch__components( val_t: 'bool', }); }, - } + }, }; } diff --git a/futurehome/src/services/out_lvl_switch.ts b/futurehome/src/services/out_lvl_switch.ts index 2327b1f..104da9d 100644 --- a/futurehome/src/services/out_lvl_switch.ts +++ b/futurehome/src/services/out_lvl_switch.ts @@ -1,11 +1,14 @@ -import { sendFimpMsg } from "../fimp/fimp"; -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { sendFimpMsg } from '../fimp/fimp'; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function out_lvl_switch__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const commandTopic = `${topicPrefix}${svc.addr}/command`; @@ -35,10 +38,10 @@ export function out_lvl_switch__components( await sendFimpMsg({ address: svc.addr!, - service: "out_lvl_switch", - cmd: "cmd.lvl.set", + service: 'out_lvl_switch', + cmd: 'cmd.lvl.set', val: lvl, - val_t: "int", + val_t: 'int', }); }, }, diff --git a/futurehome/src/services/scene_ctrl.ts b/futurehome/src/services/scene_ctrl.ts index 3fec88f..c319e68 100644 --- a/futurehome/src/services/scene_ctrl.ts +++ b/futurehome/src/services/scene_ctrl.ts @@ -8,13 +8,16 @@ // /scene/command → cmd.scene.set // ───────────────────────────────────────────────────────────── -import { sendFimpMsg } from "../fimp/fimp"; -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { HaMqttComponent } from "../ha/mqtt_components/_component"; +import { sendFimpMsg } from '../fimp/fimp'; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { HaMqttComponent } from '../ha/mqtt_components/_component'; import { CommandHandlers, ServiceComponentsCreationResult, -} from "../ha/publish_device"; +} from '../ha/publish_device'; /** * Creates MQTT components for a single *scene_ctrl* service. @@ -22,33 +25,33 @@ import { export function scene_ctrl__components( topicPrefix: string, _device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const components: Record = {}; const handlers: CommandHandlers = {}; // ───────────── read-only entities ───────────── - if (svc.intf?.includes("evt.scene.report")) { + if (svc.intf?.includes('evt.scene.report')) { components[`${svc.addr}_scene`] = { unique_id: `${svc.addr}_scene`, platform: 'sensor', - unit_of_measurement: "", + unit_of_measurement: '', value_template: `{{ value_json['${svc.addr}'].scene }}`, }; } - if (svc.intf?.includes("evt.lvl.report")) { + if (svc.intf?.includes('evt.lvl.report')) { components[`${svc.addr}_lvl`] = { unique_id: `${svc.addr}_lvl`, platform: 'sensor', - unit_of_measurement: "", + unit_of_measurement: '', value_template: `{{ value_json['${svc.addr}'].lvl }}`, }; } // ───────────── writeable “select” (scene activator) ───────────── const supScenes: string[] = svc.props?.sup_scenes ?? []; - if (svc.intf?.includes("cmd.scene.set") && supScenes.length) { + if (svc.intf?.includes('cmd.scene.set') && supScenes.length) { const commandTopic = `${topicPrefix}${svc.addr}/scene/command`; components[`${svc.addr}_select`] = { @@ -65,9 +68,9 @@ export function scene_ctrl__components( await sendFimpMsg({ address: svc.addr!, - service: "scene_ctrl", - cmd: "cmd.scene.set", - val_t: "string", + service: 'scene_ctrl', + cmd: 'cmd.scene.set', + val_t: 'string', val: payload, }); }; diff --git a/futurehome/src/services/sensor_accelx.ts b/futurehome/src/services/sensor_accelx.ts index b47a99f..82e0378 100644 --- a/futurehome/src/services/sensor_accelx.ts +++ b/futurehome/src/services/sensor_accelx.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_accelx__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = undefined; const unit = svc.props?.sup_units?.[0] ?? 'm/s2'; @@ -18,6 +21,6 @@ export function sensor_accelx__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_accely.ts b/futurehome/src/services/sensor_accely.ts index ec92a7b..e7b631d 100644 --- a/futurehome/src/services/sensor_accely.ts +++ b/futurehome/src/services/sensor_accely.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_accely__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = undefined; const unit = svc.props?.sup_units?.[0] ?? 'm/s2'; @@ -18,6 +21,6 @@ export function sensor_accely__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_accelz.ts b/futurehome/src/services/sensor_accelz.ts index 98ea8ae..3b23e71 100644 --- a/futurehome/src/services/sensor_accelz.ts +++ b/futurehome/src/services/sensor_accelz.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_accelz__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = undefined; const unit = svc.props?.sup_units?.[0] ?? 'm/s2'; @@ -18,6 +21,6 @@ export function sensor_accelz__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_airflow.ts b/futurehome/src/services/sensor_airflow.ts index a2209af..0cc2b3b 100644 --- a/futurehome/src/services/sensor_airflow.ts +++ b/futurehome/src/services/sensor_airflow.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_airflow__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = undefined; const unit = svc.props?.sup_units?.[0] ?? 'm3/h'; @@ -18,6 +21,6 @@ export function sensor_airflow__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_airq.ts b/futurehome/src/services/sensor_airq.ts index c5884c2..4d254cb 100644 --- a/futurehome/src/services/sensor_airq.ts +++ b/futurehome/src/services/sensor_airq.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_airq__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = 'aqi'; const unit = svc.props?.sup_units?.[0] ?? 'pm25'; @@ -18,6 +21,6 @@ export function sensor_airq__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_anglepos.ts b/futurehome/src/services/sensor_anglepos.ts index 188002c..f3d9fc1 100644 --- a/futurehome/src/services/sensor_anglepos.ts +++ b/futurehome/src/services/sensor_anglepos.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_anglepos__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = undefined; const unit = svc.props?.sup_units?.[0] ?? '%'; @@ -18,6 +21,6 @@ export function sensor_anglepos__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_atmo.ts b/futurehome/src/services/sensor_atmo.ts index 3f15696..5f90839 100644 --- a/futurehome/src/services/sensor_atmo.ts +++ b/futurehome/src/services/sensor_atmo.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_atmo__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = 'atmospheric_pressure'; const unit = svc.props?.sup_units?.[0] ?? 'kPa'; @@ -18,6 +21,6 @@ export function sensor_atmo__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_baro.ts b/futurehome/src/services/sensor_baro.ts index 8ea6f31..4869c74 100644 --- a/futurehome/src/services/sensor_baro.ts +++ b/futurehome/src/services/sensor_baro.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_baro__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = 'atmospheric_pressure'; const unit = svc.props?.sup_units?.[0] ?? 'kPa'; @@ -18,6 +21,6 @@ export function sensor_baro__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_co.ts b/futurehome/src/services/sensor_co.ts index cbab6c5..2b08a88 100644 --- a/futurehome/src/services/sensor_co.ts +++ b/futurehome/src/services/sensor_co.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_co__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = 'carbon_monoxide'; const unit = svc.props?.sup_units?.[0] ?? 'mol/m3'; @@ -18,6 +21,6 @@ export function sensor_co__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_co2.ts b/futurehome/src/services/sensor_co2.ts index 3be4b04..97ef8bb 100644 --- a/futurehome/src/services/sensor_co2.ts +++ b/futurehome/src/services/sensor_co2.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_co2__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = 'carbon_dioxide'; const unit = svc.props?.sup_units?.[0] ?? 'ppm'; @@ -18,6 +21,6 @@ export function sensor_co2__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_contact.ts b/futurehome/src/services/sensor_contact.ts index 2077eeb..9993d8c 100644 --- a/futurehome/src/services/sensor_contact.ts +++ b/futurehome/src/services/sensor_contact.ts @@ -1,12 +1,15 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_contact__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { - const device_class = 'opening' + const device_class = 'opening'; return { components: { diff --git a/futurehome/src/services/sensor_current.ts b/futurehome/src/services/sensor_current.ts index 181bd87..62743e5 100644 --- a/futurehome/src/services/sensor_current.ts +++ b/futurehome/src/services/sensor_current.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_current__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = 'current'; const unit = svc.props?.sup_units?.[0] ?? 'A'; @@ -18,6 +21,6 @@ export function sensor_current__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_dew.ts b/futurehome/src/services/sensor_dew.ts index 1960875..de383c0 100644 --- a/futurehome/src/services/sensor_dew.ts +++ b/futurehome/src/services/sensor_dew.ts @@ -1,13 +1,16 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_dew__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { - const device_class = 'temperature' - let unit = svc.props?.sup_units?.[0] ?? "°C"; + const device_class = 'temperature'; + let unit = svc.props?.sup_units?.[0] ?? '°C'; if (unit === 'C') unit = '°C'; if (unit === 'F') unit = '°F'; diff --git a/futurehome/src/services/sensor_direct.ts b/futurehome/src/services/sensor_direct.ts index 6ff8c7b..b764369 100644 --- a/futurehome/src/services/sensor_direct.ts +++ b/futurehome/src/services/sensor_direct.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_direct__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = 'wind_direction'; const unit = svc.props?.sup_units?.[0] ?? '°'; @@ -18,6 +21,6 @@ export function sensor_direct__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_distance.ts b/futurehome/src/services/sensor_distance.ts index 5f6b327..2f7214d 100644 --- a/futurehome/src/services/sensor_distance.ts +++ b/futurehome/src/services/sensor_distance.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_distance__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = 'distance'; const unit = svc.props?.sup_units?.[0] ?? 'm'; @@ -18,6 +21,6 @@ export function sensor_distance__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_elresist.ts b/futurehome/src/services/sensor_elresist.ts index da90d1f..e333b5f 100644 --- a/futurehome/src/services/sensor_elresist.ts +++ b/futurehome/src/services/sensor_elresist.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_elresist__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = undefined; const unit = svc.props?.sup_units?.[0] ?? 'ohm/m'; @@ -18,6 +21,6 @@ export function sensor_elresist__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_freq.ts b/futurehome/src/services/sensor_freq.ts index 130d77d..17b9de8 100644 --- a/futurehome/src/services/sensor_freq.ts +++ b/futurehome/src/services/sensor_freq.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_freq__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = 'frequency'; const unit = svc.props?.sup_units?.[0] ?? 'Hz'; @@ -18,6 +21,6 @@ export function sensor_freq__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_gp.ts b/futurehome/src/services/sensor_gp.ts index 5c869d3..b556810 100644 --- a/futurehome/src/services/sensor_gp.ts +++ b/futurehome/src/services/sensor_gp.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_gp__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = undefined; const unit = svc.props?.sup_units?.[0] ?? '%'; @@ -18,6 +21,6 @@ export function sensor_gp__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_gust.ts b/futurehome/src/services/sensor_gust.ts index 14e99c1..ac33413 100644 --- a/futurehome/src/services/sensor_gust.ts +++ b/futurehome/src/services/sensor_gust.ts @@ -1,14 +1,17 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_gust__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = undefined; let unit = svc.props?.sup_units?.[0] ?? 'km/h'; - if (unit === 'kph') unit = 'km/h' + if (unit === 'kph') unit = 'km/h'; return { components: { @@ -19,6 +22,6 @@ export function sensor_gust__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_humid.ts b/futurehome/src/services/sensor_humid.ts index 2ed2c8b..1924d6f 100644 --- a/futurehome/src/services/sensor_humid.ts +++ b/futurehome/src/services/sensor_humid.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_humid__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = 'humidity'; const unit = svc.props?.sup_units?.[0] ?? '%'; @@ -18,6 +21,6 @@ export function sensor_humid__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_lumin.ts b/futurehome/src/services/sensor_lumin.ts index beffa2a..076e529 100644 --- a/futurehome/src/services/sensor_lumin.ts +++ b/futurehome/src/services/sensor_lumin.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_lumin__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = 'illuminance'; const unit = svc.props?.sup_units?.[0] ?? 'Lux'; @@ -18,6 +21,6 @@ export function sensor_lumin__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_moist.ts b/futurehome/src/services/sensor_moist.ts index 42702f6..2bb8ddf 100644 --- a/futurehome/src/services/sensor_moist.ts +++ b/futurehome/src/services/sensor_moist.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_moist__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = 'moisture'; const unit = svc.props?.sup_units?.[0] ?? '%'; @@ -18,6 +21,6 @@ export function sensor_moist__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_noise.ts b/futurehome/src/services/sensor_noise.ts index ab77045..ca99bc4 100644 --- a/futurehome/src/services/sensor_noise.ts +++ b/futurehome/src/services/sensor_noise.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_noise__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = 'sound_pressure'; const unit = svc.props?.sup_units?.[0] ?? 'dB'; @@ -18,6 +21,6 @@ export function sensor_noise__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_power.ts b/futurehome/src/services/sensor_power.ts index 5eca9f1..744977a 100644 --- a/futurehome/src/services/sensor_power.ts +++ b/futurehome/src/services/sensor_power.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_power__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = 'power'; const unit = svc.props?.sup_units?.[0] ?? 'W'; @@ -18,6 +21,6 @@ export function sensor_power__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_presence.ts b/futurehome/src/services/sensor_presence.ts index 96f7ccc..92006b6 100644 --- a/futurehome/src/services/sensor_presence.ts +++ b/futurehome/src/services/sensor_presence.ts @@ -1,12 +1,15 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_presence__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { - const device_class = 'occupancy' + const device_class = 'occupancy'; return { components: { diff --git a/futurehome/src/services/sensor_rain.ts b/futurehome/src/services/sensor_rain.ts index 7772d38..e8896a7 100644 --- a/futurehome/src/services/sensor_rain.ts +++ b/futurehome/src/services/sensor_rain.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_rain__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = 'precipitation_intensity'; const unit = svc.props?.sup_units?.[0] ?? 'mm/h'; @@ -18,6 +21,6 @@ export function sensor_rain__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_rotation.ts b/futurehome/src/services/sensor_rotation.ts index 3321291..e243f0d 100644 --- a/futurehome/src/services/sensor_rotation.ts +++ b/futurehome/src/services/sensor_rotation.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_rotation__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = undefined; const unit = svc.props?.sup_units?.[0] ?? 'rpm'; @@ -18,6 +21,6 @@ export function sensor_rotation__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_seismicint.ts b/futurehome/src/services/sensor_seismicint.ts index 1a153ac..39ae420 100644 --- a/futurehome/src/services/sensor_seismicint.ts +++ b/futurehome/src/services/sensor_seismicint.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_seismicint__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = undefined; const unit = svc.props?.sup_units?.[0] ?? 'EMCRO'; @@ -18,6 +21,6 @@ export function sensor_seismicint__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_seismicmag.ts b/futurehome/src/services/sensor_seismicmag.ts index 64c51e9..bce1f03 100644 --- a/futurehome/src/services/sensor_seismicmag.ts +++ b/futurehome/src/services/sensor_seismicmag.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_seismicmag__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = undefined; const unit = svc.props?.sup_units?.[0] ?? 'MB'; @@ -18,6 +21,6 @@ export function sensor_seismicmag__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_solarrad.ts b/futurehome/src/services/sensor_solarrad.ts index 3179633..8637a08 100644 --- a/futurehome/src/services/sensor_solarrad.ts +++ b/futurehome/src/services/sensor_solarrad.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_solarrad__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = undefined; const unit = svc.props?.sup_units?.[0] ?? 'W/m2'; @@ -18,6 +21,6 @@ export function sensor_solarrad__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_tank.ts b/futurehome/src/services/sensor_tank.ts index 883c5e9..5a0b381 100644 --- a/futurehome/src/services/sensor_tank.ts +++ b/futurehome/src/services/sensor_tank.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_tank__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = 'volume_storage'; const unit = svc.props?.sup_units?.[0] ?? 'l'; @@ -18,6 +21,6 @@ export function sensor_tank__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_temp.ts b/futurehome/src/services/sensor_temp.ts index b24c702..19e5711 100644 --- a/futurehome/src/services/sensor_temp.ts +++ b/futurehome/src/services/sensor_temp.ts @@ -1,13 +1,16 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_temp__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { - const device_class = 'temperature' - let unit = svc.props?.sup_units?.[0] ?? "°C"; + const device_class = 'temperature'; + let unit = svc.props?.sup_units?.[0] ?? '°C'; if (unit === 'C') unit = '°C'; if (unit === 'F') unit = '°F'; diff --git a/futurehome/src/services/sensor_tidelvl.ts b/futurehome/src/services/sensor_tidelvl.ts index 32ddc09..daec44c 100644 --- a/futurehome/src/services/sensor_tidelvl.ts +++ b/futurehome/src/services/sensor_tidelvl.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_tidelvl__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = undefined; const unit = svc.props?.sup_units?.[0] ?? 'm'; @@ -18,6 +21,6 @@ export function sensor_tidelvl__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_uv.ts b/futurehome/src/services/sensor_uv.ts index afa5eb1..a28adaf 100644 --- a/futurehome/src/services/sensor_uv.ts +++ b/futurehome/src/services/sensor_uv.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_uv__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = undefined; const unit = svc.props?.sup_units?.[0] ?? 'index'; @@ -18,6 +21,6 @@ export function sensor_uv__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_veloc.ts b/futurehome/src/services/sensor_veloc.ts index 86ca572..4200789 100644 --- a/futurehome/src/services/sensor_veloc.ts +++ b/futurehome/src/services/sensor_veloc.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_veloc__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = undefined; const unit = svc.props?.sup_units?.[0] ?? 'm/2'; @@ -18,6 +21,6 @@ export function sensor_veloc__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_voltage.ts b/futurehome/src/services/sensor_voltage.ts index e97afe4..8c18a71 100644 --- a/futurehome/src/services/sensor_voltage.ts +++ b/futurehome/src/services/sensor_voltage.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_voltage__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = 'voltage'; const unit = svc.props?.sup_units?.[0] ?? 'V'; @@ -18,6 +21,6 @@ export function sensor_voltage__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_watflow.ts b/futurehome/src/services/sensor_watflow.ts index e9a7477..59816fa 100644 --- a/futurehome/src/services/sensor_watflow.ts +++ b/futurehome/src/services/sensor_watflow.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_watflow__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = 'volume_flow_rate'; const unit = svc.props?.sup_units?.[0] ?? 'l/h'; @@ -18,6 +21,6 @@ export function sensor_watflow__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_watpressure.ts b/futurehome/src/services/sensor_watpressure.ts index 12fed0a..024ce0e 100644 --- a/futurehome/src/services/sensor_watpressure.ts +++ b/futurehome/src/services/sensor_watpressure.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_watpressure__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = 'pressure'; const unit = svc.props?.sup_units?.[0] ?? 'kPa'; @@ -18,6 +21,6 @@ export function sensor_watpressure__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_wattemp.ts b/futurehome/src/services/sensor_wattemp.ts index aaf98fa..bbc8822 100644 --- a/futurehome/src/services/sensor_wattemp.ts +++ b/futurehome/src/services/sensor_wattemp.ts @@ -1,13 +1,16 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_wattemp__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = 'temperature'; - let unit = svc.props?.sup_units?.[0] ?? "°C"; + let unit = svc.props?.sup_units?.[0] ?? '°C'; if (unit === 'C') unit = '°C'; if (unit === 'F') unit = '°F'; diff --git a/futurehome/src/services/sensor_weight.ts b/futurehome/src/services/sensor_weight.ts index 2cc4ad9..378c7e2 100644 --- a/futurehome/src/services/sensor_weight.ts +++ b/futurehome/src/services/sensor_weight.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_weight__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = 'weight'; const unit = svc.props?.sup_units?.[0] ?? 'kg'; @@ -18,6 +21,6 @@ export function sensor_weight__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/sensor_wind.ts b/futurehome/src/services/sensor_wind.ts index 02bae9c..9b0570c 100644 --- a/futurehome/src/services/sensor_wind.ts +++ b/futurehome/src/services/sensor_wind.ts @@ -1,10 +1,13 @@ -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ServiceComponentsCreationResult } from "../ha/publish_device"; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ServiceComponentsCreationResult } from '../ha/publish_device'; export function sensor_wind__components( topicPrefix: string, device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const device_class = 'wind_speed'; const unit = svc.props?.sup_units?.[0] ?? 'km/h'; @@ -18,6 +21,6 @@ export function sensor_wind__components( unit_of_measurement: unit, value_template: `{{ value_json['${svc.addr}'].sensor }}`, }, - } + }, }; } diff --git a/futurehome/src/services/thermostat.ts b/futurehome/src/services/thermostat.ts index 2658fa3..2615b7a 100644 --- a/futurehome/src/services/thermostat.ts +++ b/futurehome/src/services/thermostat.ts @@ -9,26 +9,29 @@ // temperature_command_topic → cmd.setpoint.set // ───────────────────────────────────────────────────────────────────────── -import { sendFimpMsg } from "../fimp/fimp"; -import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device"; -import { ClimateComponent } from "../ha/mqtt_components/climate"; +import { sendFimpMsg } from '../fimp/fimp'; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { ClimateComponent } from '../ha/mqtt_components/climate'; import { CommandHandlers, ServiceComponentsCreationResult, -} from "../ha/publish_device"; -import { haGetCachedState } from "../ha/update_state"; +} from '../ha/publish_device'; +import { haGetCachedState } from '../ha/update_state'; export function thermostat__components( topicPrefix: string, _device: VinculumPd7Device, - svc: VinculumPd7Service + svc: VinculumPd7Service, ): ServiceComponentsCreationResult | undefined { const supModes: string[] = svc.props?.sup_modes ?? []; const supSetpoints: string[] = svc.props?.sup_setpoints ?? []; if (!supModes.length) return undefined; // nothing useful to expose - const defaultSpType = supSetpoints[0] ?? "heat"; + const defaultSpType = supSetpoints[0] ?? 'heat'; const ranges: Record = svc.props?.sup_temperatures ?? {}; @@ -82,9 +85,9 @@ export function thermostat__components( if (!supModes.includes(payload)) return; await sendFimpMsg({ address: svc.addr!, - service: "thermostat", - cmd: "cmd.mode.set", - val_t: "string", + service: 'thermostat', + cmd: 'cmd.mode.set', + val_t: 'string', val: payload, }); }, @@ -95,13 +98,15 @@ export function thermostat__components( await sendFimpMsg({ address: svc.addr!, - service: "thermostat", - cmd: "cmd.setpoint.set", - val_t: "str_map", + service: 'thermostat', + cmd: 'cmd.setpoint.set', + val_t: 'str_map', val: { - type: haGetCachedState({ topic: `${topicPrefix}/state` })?.[svc.addr]?.mode ?? defaultSpType, + type: + haGetCachedState({ topic: `${topicPrefix}/state` })?.[svc.addr] + ?.mode ?? defaultSpType, temp: payload, - unit: "C", + unit: 'C', }, }); }, diff --git a/futurehome/src/utils.ts b/futurehome/src/utils.ts index 9968100..98eaa4f 100644 --- a/futurehome/src/utils.ts +++ b/futurehome/src/utils.ts @@ -1,3 +1,3 @@ export function delay(ms: number) { - return new Promise(resolve => setTimeout(resolve, ms)); + return new Promise((resolve) => setTimeout(resolve, ms)); }