Add support for 'indicator_ctrl' service

This commit is contained in:
Adrian Jagielak 2025-07-24 22:50:34 +02:00
parent e8274850d1
commit dcab7a7112
No known key found for this signature in database
GPG Key ID: 0818CF7AF6C62BFB
6 changed files with 75 additions and 16 deletions

View File

@ -6,6 +6,7 @@
- Set 'battery' entity category to 'diagnostic' to hide it from the main HA view.
- Do not expose 'battery' entity twice if it supports both level and low/high binary state.
- Changed the default 'sensor_lumin' unit from 'Lux' to 'lx'.
- Added support for 'indicator_ctrl' service (identify devices).
# 0.1.0 (24.07.2025)

View File

@ -156,15 +156,15 @@ todo: links to the .ts service implementations below
## System or meta, not essential services
| Service | Implementation status |
| --- | --- |
| gateway | |
| association | |
| diagnostic | |
| indicator_ctrl | |
| ota | |
| parameters | |
| technology_specific | |
| time | |
| version | |
| dev_sys | |
| Service | Implementation status | Description |
| --- | --- | --- |
| gateway | | |
| association | | |
| diagnostic | | |
| indicator_ctrl | ✅ | Identify devices |
| ota | | |
| parameters | | |
| technology_specific | | |
| time | | |
| version | | |
| dev_sys | | |

View File

@ -43,6 +43,7 @@ export async function sendFimpMsg({
cmd,
val,
val_t,
props = {},
timeoutMs = 10000,
}: {
address: string;
@ -50,6 +51,7 @@ export async function sendFimpMsg({
cmd: string;
val: unknown;
val_t: FimpValueType;
props?: any;
timeoutMs?: number;
}): Promise<FimpResponse> {
const uid = uuidv4();
@ -57,7 +59,7 @@ export async function sendFimpMsg({
const message = JSON.stringify({
corid: null,
ctime: new Date().toISOString(),
props: {},
props: props,
resp_to: 'pt:j1/mt:rsp/rt:app/rn:ha-futurehome/ad:addon',
serv: service,
src: 'ha-futurehome',

View File

@ -8,6 +8,7 @@ import { basic__components } from '../services/basic';
import { battery__components } from '../services/battery';
import { color_ctrl__components } from '../services/color_ctrl';
import { fan_ctrl__components } from '../services/fan_ctrl';
import { indicator_ctrl__components } from '../services/indicator_ctrl';
import { out_bin_switch__components } from '../services/out_bin_switch';
import { out_lvl_switch__components } from '../services/out_lvl_switch';
import { scene_ctrl__components } from '../services/scene_ctrl';
@ -161,6 +162,7 @@ const serviceHandlers: {
battery: battery__components,
color_ctrl: color_ctrl__components,
fan_ctrl: fan_ctrl__components,
indicator_ctrl: indicator_ctrl__components,
out_bin_switch: out_bin_switch__components,
out_lvl_switch: out_lvl_switch__components,
scene_ctrl: scene_ctrl__components,

View File

@ -0,0 +1,54 @@
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';
export function indicator_ctrl__components(
topicPrefix: string,
device: VinculumPd7Device,
svc: VinculumPd7Service,
): ServiceComponentsCreationResult | undefined {
const components: Record<string, HaMqttComponent> = {};
const commandHandlers: CommandHandlers = {};
if (svc.intf?.includes('cmd.indicator.set_visual_element')) {
const commandTopic = `${topicPrefix}${svc.addr}/cmd.indicator.set_visual_element/command`;
components[`${svc.addr}/set_visual_element`] = {
unique_id: `${svc.addr}/set_visual_element`,
platform: 'button',
entity_category: 'diagnostic',
device_class: 'identify',
command_topic: commandTopic,
};
commandHandlers[commandTopic] = async (_payload: string) => {
await sendFimpMsg({
address: svc.addr,
service: 'indicator_ctrl',
cmd: 'cmd.indicator.set_visual_element',
val_t: 'null',
val: null,
props: {
duration: '3',
},
});
};
}
// cmd.indicator.set_text is not used anymore
// since cmd.indicator.set_visual_element should always be present when cmd.indicator.identify is,
// there's no need to handle cmd.indicator.identify separately.
return {
components,
commandHandlers,
};
}

View File

@ -28,7 +28,7 @@ export function scene_ctrl__components(
svc: VinculumPd7Service,
): ServiceComponentsCreationResult | undefined {
const components: Record<string, HaMqttComponent> = {};
const handlers: CommandHandlers = {};
const commandHandlers: CommandHandlers = {};
// ───────────── read-only entities ─────────────
if (svc.intf?.includes('evt.scene.report')) {
@ -63,7 +63,7 @@ export function scene_ctrl__components(
value_template: `{{ value_json['${svc.addr}'].scene }}`,
};
handlers[commandTopic] = async (payload: string) => {
commandHandlers[commandTopic] = async (payload: string) => {
if (!supScenes.includes(payload)) return; // ignore bogus payloads
await sendFimpMsg({
@ -81,6 +81,6 @@ export function scene_ctrl__components(
return {
components,
commandHandlers: Object.keys(handlers).length ? handlers : undefined,
commandHandlers,
};
}