mirror of
https://github.com/adrianjagielak/home-assistant-futurehome.git
synced 2025-09-13 15:47:08 +00:00
Use full device field names in MQTT discovery messages
This commit is contained in:
parent
09b98321a1
commit
6770d1c0c1
@ -1,6 +1,6 @@
|
|||||||
# https://developers.home-assistant.io/docs/add-ons/configuration#add-on-config
|
# https://developers.home-assistant.io/docs/add-ons/configuration#add-on-config
|
||||||
name: Futurehome
|
name: Futurehome
|
||||||
version: "0.0.31"
|
version: "0.0.32"
|
||||||
slug: futurehome
|
slug: futurehome
|
||||||
description: Local Futurehome Smarthub integration
|
description: Local Futurehome Smarthub integration
|
||||||
url: "https://github.com/adrianjagielak/home-assistant-futurehome"
|
url: "https://github.com/adrianjagielak/home-assistant-futurehome"
|
||||||
|
@ -1,98 +1,160 @@
|
|||||||
import { InclusionReport } from "../fimp/inclusion_report";
|
import { InclusionReport } from '../fimp/inclusion_report';
|
||||||
import { VinculumPd7Device, VinculumPd7Service } from "../fimp/vinculum_pd7_device";
|
import {
|
||||||
import { log } from "../logger";
|
VinculumPd7Device,
|
||||||
import { basic__components } from "../services/basic";
|
VinculumPd7Service,
|
||||||
import { battery__components } from "../services/battery";
|
} from '../fimp/vinculum_pd7_device';
|
||||||
import { color_ctrl__components } from "../services/color_ctrl";
|
import { log } from '../logger';
|
||||||
import { fan_ctrl__components } from "../services/fan_ctrl";
|
import { basic__components } from '../services/basic';
|
||||||
import { out_bin_switch__components } from "../services/out_bin_switch";
|
import { battery__components } from '../services/battery';
|
||||||
import { out_lvl_switch__components } from "../services/out_lvl_switch";
|
import { color_ctrl__components } from '../services/color_ctrl';
|
||||||
import { scene_ctrl__components } from "../services/scene_ctrl";
|
import { fan_ctrl__components } from '../services/fan_ctrl';
|
||||||
import { sensor_accelx__components } from "../services/sensor_accelx";
|
import { out_bin_switch__components } from '../services/out_bin_switch';
|
||||||
import { sensor_accely__components } from "../services/sensor_accely";
|
import { out_lvl_switch__components } from '../services/out_lvl_switch';
|
||||||
import { sensor_accelz__components } from "../services/sensor_accelz";
|
import { scene_ctrl__components } from '../services/scene_ctrl';
|
||||||
import { sensor_airflow__components } from "../services/sensor_airflow";
|
import { sensor_accelx__components } from '../services/sensor_accelx';
|
||||||
import { sensor_airq__components } from "../services/sensor_airq";
|
import { sensor_accely__components } from '../services/sensor_accely';
|
||||||
import { sensor_anglepos__components } from "../services/sensor_anglepos";
|
import { sensor_accelz__components } from '../services/sensor_accelz';
|
||||||
import { sensor_atmo__components } from "../services/sensor_atmo";
|
import { sensor_airflow__components } from '../services/sensor_airflow';
|
||||||
import { sensor_baro__components } from "../services/sensor_baro";
|
import { sensor_airq__components } from '../services/sensor_airq';
|
||||||
import { sensor_co__components } from "../services/sensor_co";
|
import { sensor_anglepos__components } from '../services/sensor_anglepos';
|
||||||
import { sensor_co2__components } from "../services/sensor_co2";
|
import { sensor_atmo__components } from '../services/sensor_atmo';
|
||||||
import { sensor_contact__components } from "../services/sensor_contact";
|
import { sensor_baro__components } from '../services/sensor_baro';
|
||||||
import { sensor_current__components } from "../services/sensor_current";
|
import { sensor_co__components } from '../services/sensor_co';
|
||||||
import { sensor_dew__components } from "../services/sensor_dew";
|
import { sensor_co2__components } from '../services/sensor_co2';
|
||||||
import { sensor_direct__components } from "../services/sensor_direct";
|
import { sensor_contact__components } from '../services/sensor_contact';
|
||||||
import { sensor_distance__components } from "../services/sensor_distance";
|
import { sensor_current__components } from '../services/sensor_current';
|
||||||
import { sensor_elresist__components } from "../services/sensor_elresist";
|
import { sensor_dew__components } from '../services/sensor_dew';
|
||||||
import { sensor_freq__components } from "../services/sensor_freq";
|
import { sensor_direct__components } from '../services/sensor_direct';
|
||||||
import { sensor_gp__components } from "../services/sensor_gp";
|
import { sensor_distance__components } from '../services/sensor_distance';
|
||||||
import { sensor_gust__components } from "../services/sensor_gust";
|
import { sensor_elresist__components } from '../services/sensor_elresist';
|
||||||
import { sensor_humid__components } from "../services/sensor_humid";
|
import { sensor_freq__components } from '../services/sensor_freq';
|
||||||
import { sensor_lumin__components } from "../services/sensor_lumin";
|
import { sensor_gp__components } from '../services/sensor_gp';
|
||||||
import { sensor_moist__components } from "../services/sensor_moist";
|
import { sensor_gust__components } from '../services/sensor_gust';
|
||||||
import { sensor_noise__components } from "../services/sensor_noise";
|
import { sensor_humid__components } from '../services/sensor_humid';
|
||||||
import { sensor_power__components } from "../services/sensor_power";
|
import { sensor_lumin__components } from '../services/sensor_lumin';
|
||||||
import { sensor_presence__components } from "../services/sensor_presence";
|
import { sensor_moist__components } from '../services/sensor_moist';
|
||||||
import { sensor_rain__components } from "../services/sensor_rain";
|
import { sensor_noise__components } from '../services/sensor_noise';
|
||||||
import { sensor_rotation__components } from "../services/sensor_rotation";
|
import { sensor_power__components } from '../services/sensor_power';
|
||||||
import { sensor_seismicint__components } from "../services/sensor_seismicint";
|
import { sensor_presence__components } from '../services/sensor_presence';
|
||||||
import { sensor_seismicmag__components } from "../services/sensor_seismicmag";
|
import { sensor_rain__components } from '../services/sensor_rain';
|
||||||
import { sensor_solarrad__components } from "../services/sensor_solarrad";
|
import { sensor_rotation__components } from '../services/sensor_rotation';
|
||||||
import { sensor_tank__components } from "../services/sensor_tank";
|
import { sensor_seismicint__components } from '../services/sensor_seismicint';
|
||||||
import { sensor_temp__components } from "../services/sensor_temp";
|
import { sensor_seismicmag__components } from '../services/sensor_seismicmag';
|
||||||
import { sensor_tidelvl__components } from "../services/sensor_tidelvl";
|
import { sensor_solarrad__components } from '../services/sensor_solarrad';
|
||||||
import { sensor_uv__components } from "../services/sensor_uv";
|
import { sensor_tank__components } from '../services/sensor_tank';
|
||||||
import { sensor_veloc__components } from "../services/sensor_veloc";
|
import { sensor_temp__components } from '../services/sensor_temp';
|
||||||
import { sensor_voltage__components } from "../services/sensor_voltage";
|
import { sensor_tidelvl__components } from '../services/sensor_tidelvl';
|
||||||
import { sensor_watflow__components } from "../services/sensor_watflow";
|
import { sensor_uv__components } from '../services/sensor_uv';
|
||||||
import { sensor_watpressure__components } from "../services/sensor_watpressure";
|
import { sensor_veloc__components } from '../services/sensor_veloc';
|
||||||
import { sensor_wattemp__components } from "../services/sensor_wattemp";
|
import { sensor_voltage__components } from '../services/sensor_voltage';
|
||||||
import { sensor_weight__components } from "../services/sensor_weight";
|
import { sensor_watflow__components } from '../services/sensor_watflow';
|
||||||
import { thermostat__components } from "../services/thermostat";
|
import { sensor_watpressure__components } from '../services/sensor_watpressure';
|
||||||
import { ha } from "./globals";
|
import { sensor_wattemp__components } from '../services/sensor_wattemp';
|
||||||
import { HaMqttComponent } from "./mqtt_components/_component";
|
import { sensor_weight__components } from '../services/sensor_weight';
|
||||||
|
import { thermostat__components } from '../services/thermostat';
|
||||||
|
import { ha } from './globals';
|
||||||
|
import { HaMqttComponent } from './mqtt_components/_component';
|
||||||
|
|
||||||
type HaDeviceConfig = {
|
type HaDeviceConfig = {
|
||||||
// device
|
/**
|
||||||
dev: {
|
* Information about the device this sensor is a part of to tie it into the [device registry](https://developers.home-assistant.io/docs/device_registry_index/).
|
||||||
ids: string | null | undefined,
|
* Only works when [`unique_id`](#unique_id) is set.
|
||||||
name: string | null | undefined,
|
* At least one of identifiers or connections must be present to identify the device.
|
||||||
// manufacturer
|
*/
|
||||||
mf: string | null | undefined,
|
device?: {
|
||||||
// model
|
/**
|
||||||
mdl: string | null | undefined,
|
* A link to the webpage that can manage the configuration of this device.
|
||||||
// software version
|
* Can be either an `http://`, `https://` or an internal `homeassistant://` URL.
|
||||||
sw: string | null | undefined,
|
*/
|
||||||
// serial number
|
configuration_url?: string;
|
||||||
sn: string | null | undefined,
|
|
||||||
// hardware number
|
/**
|
||||||
hw: string | null | undefined,
|
* A list of connections of the device to the outside world as a list of tuples `[connection_type, connection_identifier]`.
|
||||||
|
* For example the MAC address of a network interface:
|
||||||
|
* `"connections": [["mac", "02:5b:26:a8:dc:12"]]`.
|
||||||
|
*/
|
||||||
|
connections?: Array<[string, string]>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The hardware version of the device.
|
||||||
|
*/
|
||||||
|
hw_version?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of IDs that uniquely identify the device.
|
||||||
|
* For example a serial number.
|
||||||
|
*/
|
||||||
|
identifiers?: string | string[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The manufacturer of the device.
|
||||||
|
*/
|
||||||
|
manufacturer?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The model of the device.
|
||||||
|
*/
|
||||||
|
model?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The model identifier of the device.
|
||||||
|
*/
|
||||||
|
model_id?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the device.
|
||||||
|
*/
|
||||||
|
name?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The serial number of the device.
|
||||||
|
*/
|
||||||
|
serial_number?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Suggest an area if the device isn’t in one yet.
|
||||||
|
*/
|
||||||
|
suggested_area?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The firmware version of the device.
|
||||||
|
*/
|
||||||
|
sw_version?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identifier of a device that routes messages between this device and Home Assistant.
|
||||||
|
* Examples of such devices are hubs, or parent devices of a sub-device.
|
||||||
|
* This is used to show device topology in Home Assistant.
|
||||||
|
*/
|
||||||
|
via_device?: string;
|
||||||
};
|
};
|
||||||
// origin
|
origin: {
|
||||||
o: {
|
name: 'futurehome';
|
||||||
name: 'futurehome',
|
url: 'https://github.com/adrianjagielak/home-assistant-futurehome';
|
||||||
url: 'https://github.com/adrianjagielak/home-assistant-futurehome',
|
|
||||||
};
|
};
|
||||||
// components
|
components: {
|
||||||
cmps: {
|
|
||||||
[key: string]: HaMqttComponent;
|
[key: string]: HaMqttComponent;
|
||||||
},
|
};
|
||||||
// state topic
|
state_topic: string;
|
||||||
stat_t: string,
|
availability_topic: string;
|
||||||
// availability topic
|
qos: number;
|
||||||
avty_t: string,
|
};
|
||||||
qos: number,
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ServiceComponentsCreationResult = {
|
export type ServiceComponentsCreationResult = {
|
||||||
components: { [key: string]: HaMqttComponent };
|
components: { [key: string]: HaMqttComponent };
|
||||||
commandHandlers?: CommandHandlers;
|
commandHandlers?: CommandHandlers;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type CommandHandlers = { [topic: string]: (payload: string) => Promise<void> }
|
export type CommandHandlers = {
|
||||||
|
[topic: string]: (payload: string) => Promise<void>;
|
||||||
|
};
|
||||||
|
|
||||||
const serviceHandlers: {
|
const serviceHandlers: {
|
||||||
[name: string]: (topicPrefix: string, device: VinculumPd7Device, svc: VinculumPd7Service) => ServiceComponentsCreationResult | undefined
|
[name: string]: (
|
||||||
|
topicPrefix: string,
|
||||||
|
device: VinculumPd7Device,
|
||||||
|
svc: VinculumPd7Service,
|
||||||
|
) => ServiceComponentsCreationResult | undefined;
|
||||||
} = {
|
} = {
|
||||||
basic: basic__components,
|
basic: basic__components,
|
||||||
battery: battery__components,
|
battery: battery__components,
|
||||||
@ -144,17 +206,29 @@ const serviceHandlers: {
|
|||||||
thermostat: thermostat__components,
|
thermostat: thermostat__components,
|
||||||
};
|
};
|
||||||
|
|
||||||
export function haPublishDevice(parameters: { hubId: string, vinculumDeviceData: VinculumPd7Device, deviceInclusionReport: InclusionReport | undefined }): { commandHandlers: CommandHandlers } {
|
export function haPublishDevice(parameters: {
|
||||||
|
hubId: string;
|
||||||
|
vinculumDeviceData: VinculumPd7Device;
|
||||||
|
deviceInclusionReport: InclusionReport | undefined;
|
||||||
|
}): { commandHandlers: CommandHandlers } {
|
||||||
const components: { [key: string]: HaMqttComponent } = {};
|
const components: { [key: string]: HaMqttComponent } = {};
|
||||||
const handlers: CommandHandlers = {};
|
const handlers: CommandHandlers = {};
|
||||||
|
|
||||||
// e.g. "homeassistant/device/futurehome_123456_1"
|
// e.g. "homeassistant/device/futurehome_123456_1"
|
||||||
const topicPrefix = `homeassistant/device/futurehome_${parameters.hubId}_${parameters.vinculumDeviceData.id}`;
|
const topicPrefix = `homeassistant/device/futurehome_${parameters.hubId}_${parameters.vinculumDeviceData.id}`;
|
||||||
|
|
||||||
for (const [svcName, svc] of Object.entries(parameters.vinculumDeviceData.services ?? {})) {
|
for (const [svcName, svc] of Object.entries(
|
||||||
if (!svcName) { continue; }
|
parameters.vinculumDeviceData.services ?? {},
|
||||||
if (!svc.addr) { continue; }
|
)) {
|
||||||
if (!svc.enabled) { continue; }
|
if (!svcName) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!svc.addr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!svc.enabled) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const handler = serviceHandlers[svcName];
|
const handler = serviceHandlers[svcName];
|
||||||
if (!handler) {
|
if (!handler) {
|
||||||
@ -164,7 +238,9 @@ export function haPublishDevice(parameters: { hubId: string, vinculumDeviceData:
|
|||||||
|
|
||||||
const result = handler(topicPrefix, parameters.vinculumDeviceData, svc);
|
const result = handler(topicPrefix, parameters.vinculumDeviceData, svc);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
log.error(`Invalid service data prevented component creation: ${parameters.vinculumDeviceData} ${svc}`);
|
log.error(
|
||||||
|
`Invalid service data prevented component creation: ${parameters.vinculumDeviceData} ${svc}`,
|
||||||
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,26 +248,36 @@ export function haPublishDevice(parameters: { hubId: string, vinculumDeviceData:
|
|||||||
Object.assign(handlers, result.commandHandlers);
|
Object.assign(handlers, result.commandHandlers);
|
||||||
}
|
}
|
||||||
|
|
||||||
const configTopic = `${topicPrefix}/config`
|
const configTopic = `${topicPrefix}/config`;
|
||||||
const stateTopic = `${topicPrefix}/state`
|
const stateTopic = `${topicPrefix}/state`;
|
||||||
const availabilityTopic = `${topicPrefix}/availability`
|
const availabilityTopic = `${topicPrefix}/availability`;
|
||||||
const config: HaDeviceConfig = {
|
const config: HaDeviceConfig = {
|
||||||
dev: {
|
device: {
|
||||||
ids: parameters.vinculumDeviceData.id.toString(),
|
identifiers: parameters.vinculumDeviceData.id.toString(),
|
||||||
name: parameters.vinculumDeviceData?.client?.name ?? parameters.vinculumDeviceData?.modelAlias ?? parameters.deviceInclusionReport?.product_name,
|
name:
|
||||||
mf: parameters.deviceInclusionReport?.manufacturer_id,
|
parameters.vinculumDeviceData?.client?.name ??
|
||||||
mdl: parameters.vinculumDeviceData?.modelAlias ?? parameters.deviceInclusionReport?.product_id,
|
parameters.vinculumDeviceData?.modelAlias ??
|
||||||
sw: parameters.deviceInclusionReport?.sw_ver,
|
parameters.deviceInclusionReport?.product_name ??
|
||||||
sn: parameters.deviceInclusionReport?.product_hash,
|
undefined,
|
||||||
hw: parameters.deviceInclusionReport?.hw_ver,
|
manufacturer:
|
||||||
|
parameters.deviceInclusionReport?.manufacturer_id ?? undefined,
|
||||||
|
model:
|
||||||
|
parameters.vinculumDeviceData?.modelAlias ??
|
||||||
|
parameters.deviceInclusionReport?.product_id ??
|
||||||
|
undefined,
|
||||||
|
sw_version: parameters.deviceInclusionReport?.sw_ver ?? undefined,
|
||||||
|
serial_number:
|
||||||
|
parameters.deviceInclusionReport?.product_hash ?? undefined,
|
||||||
|
hw_version: parameters.deviceInclusionReport?.hw_ver ?? undefined,
|
||||||
|
via_device: 'todo_hub_id',
|
||||||
},
|
},
|
||||||
o: {
|
origin: {
|
||||||
name: 'futurehome',
|
name: 'futurehome',
|
||||||
url: 'https://github.com/adrianjagielak/home-assistant-futurehome',
|
url: 'https://github.com/adrianjagielak/home-assistant-futurehome',
|
||||||
},
|
},
|
||||||
cmps: components,
|
components: components,
|
||||||
stat_t: stateTopic,
|
state_topic: stateTopic,
|
||||||
avty_t: availabilityTopic,
|
availability_topic: availabilityTopic,
|
||||||
qos: 2,
|
qos: 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user