mirror of
https://github.com/adrianjagielak/home-assistant-futurehome.git
synced 2025-09-13 07:37:09 +00:00
Add support for 'parameters' service
This commit is contained in:
parent
9aac6c489f
commit
b882cbab91
@ -65,8 +65,9 @@ todo add info about factory reset hub to restore 30 day trial
|
||||
|
||||
| Name | Service | Implementation status | Home Assistant entity |
|
||||
| --- | --- | --- | --- |
|
||||
| Identify device | [indicator_ctrl](https://github.com/adrianjagielak/home-assistant-futurehome/blob/master/futurehome/src/services/indicator_ctrl.ts) | | ✅ | [Button](https://www.home-assistant.io/integrations/button/) |
|
||||
| Reboot device | [dev_sys](https://github.com/adrianjagielak/home-assistant-futurehome/blob/master/futurehome/src/services/dev_sys.ts) | | ✅ | [Button](https://www.home-assistant.io/integrations/button/) |
|
||||
| Identify device | [indicator_ctrl](https://github.com/adrianjagielak/home-assistant-futurehome/blob/master/futurehome/src/services/indicator_ctrl.ts) | | ✅ | [Button](https://www.home-assistant.io/integrations/button/) |
|
||||
| Advanced configuration of a device | [parameters](https://github.com/adrianjagielak/home-assistant-futurehome/blob/master/futurehome/src/services/parameters.ts) | | ✅ | [Button](https://www.home-assistant.io/integrations/button/), [Sensor](https://www.home-assistant.io/integrations/sensor/), [Number](https://www.home-assistant.io/integrations/number/), [Select](https://www.home-assistant.io/integrations/select/), [Text](https://www.home-assistant.io/integrations/text/) |
|
||||
|
||||
## Other system, meta, unused, or not essential services
|
||||
|
||||
@ -80,10 +81,9 @@ todo add info about factory reset hub to restore 30 day trial
|
||||
| inverter_grid_conn | No devices or hub support this stub service. |
|
||||
| inverter_solar_conn | No devices or hub support this stub service. |
|
||||
| ota | Managing OTA updates of devices |
|
||||
| parameters | |
|
||||
| Power regulator | [power_regulator](https://github.com/adrianjagielak/home-assistant-futurehome/blob/master/futurehome/src/services/power_regulator.ts) | [16A Puck Relé](https://www.futurehome.io/en_no/shop/puck-relay-16a) | | |
|
||||
| power_regulator | Automation. Easily reproducible using Home Assistant's built-in configuration. |
|
||||
| schedule | No devices or hub support this stub service. |
|
||||
| technology_specific | |
|
||||
| technology_specific | Should be covered by other services |
|
||||
| time | Z-wave service for setting and reading time |
|
||||
| time_parameters | Z-wave service for setting and reading time |
|
||||
| version | Device hardware and software versions. Exposed through other means. |
|
||||
|
@ -12,6 +12,7 @@
|
||||
- Added support for 'doorman' service (Yale door locks).
|
||||
- Added support for 'complex_alarm_system' service (part of alarm sirens control).
|
||||
- Added support for 'dev_sys' service (reboot device).
|
||||
- Added support for 'parameters' service (advanced configuration of a device).
|
||||
|
||||
## 0.1.5 (25.07.2025)
|
||||
|
||||
|
@ -64,8 +64,9 @@ todo add info about factory reset hub to restore 30 day trial
|
||||
|
||||
| Name | Service | Implementation status | Home Assistant entity |
|
||||
| --- | --- | --- | --- |
|
||||
| Identify device | [indicator_ctrl](https://github.com/adrianjagielak/home-assistant-futurehome/blob/master/futurehome/src/services/indicator_ctrl.ts) | | ✅ | [Button](https://www.home-assistant.io/integrations/button/) |
|
||||
| Reboot device | [dev_sys](https://github.com/adrianjagielak/home-assistant-futurehome/blob/master/futurehome/src/services/dev_sys.ts) | | ✅ | [Button](https://www.home-assistant.io/integrations/button/) |
|
||||
| Identify device | [indicator_ctrl](https://github.com/adrianjagielak/home-assistant-futurehome/blob/master/futurehome/src/services/indicator_ctrl.ts) | | ✅ | [Button](https://www.home-assistant.io/integrations/button/) |
|
||||
| Advanced configuration of a device | [parameters](https://github.com/adrianjagielak/home-assistant-futurehome/blob/master/futurehome/src/services/parameters.ts) | | ✅ | [Button](https://www.home-assistant.io/integrations/button/), [Sensor](https://www.home-assistant.io/integrations/sensor/), [Number](https://www.home-assistant.io/integrations/number/), [Select](https://www.home-assistant.io/integrations/select/), [Text](https://www.home-assistant.io/integrations/text/) |
|
||||
|
||||
## Other system, meta, unused, or not essential services
|
||||
|
||||
@ -79,10 +80,9 @@ todo add info about factory reset hub to restore 30 day trial
|
||||
| inverter_grid_conn | No devices or hub support this stub service. |
|
||||
| inverter_solar_conn | No devices or hub support this stub service. |
|
||||
| ota | Managing OTA updates of devices |
|
||||
| parameters | |
|
||||
| Power regulator | [power_regulator](https://github.com/adrianjagielak/home-assistant-futurehome/blob/master/futurehome/src/services/power_regulator.ts) | [16A Puck Relé](https://www.futurehome.io/en_no/shop/puck-relay-16a) | | |
|
||||
| power_regulator | Automation. Easily reproducible using Home Assistant's built-in configuration. |
|
||||
| schedule | No devices or hub support this stub service. |
|
||||
| technology_specific | |
|
||||
| technology_specific | Should be covered by other services |
|
||||
| time | Z-wave service for setting and reading time |
|
||||
| time_parameters | Z-wave service for setting and reading time |
|
||||
| version | Device hardware and software versions. Exposed through other means. |
|
||||
|
@ -22,6 +22,7 @@ import { indicator_ctrl__components } from '../services/indicator_ctrl';
|
||||
import { media_player__components } from '../services/media_player';
|
||||
import { out_bin_switch__components } from '../services/out_bin_switch';
|
||||
import { out_lvl_switch__components } from '../services/out_lvl_switch';
|
||||
import { parameters__components } from '../services/parameters';
|
||||
import { scene_ctrl__components } from '../services/scene_ctrl';
|
||||
import { schedule_entry__components } from '../services/schedule_entry';
|
||||
import { siren_ctrl__components } from '../services/siren_ctrl';
|
||||
@ -169,6 +170,7 @@ const serviceHandlers: {
|
||||
meter_cooling: _meter__components,
|
||||
out_bin_switch: out_bin_switch__components,
|
||||
out_lvl_switch: out_lvl_switch__components,
|
||||
parameters: parameters__components,
|
||||
scene_ctrl: scene_ctrl__components,
|
||||
schedule_entry: schedule_entry__components,
|
||||
sensor_accelx: _sensor_numeric__components,
|
||||
@ -301,9 +303,6 @@ export function haPublishDevice(parameters: {
|
||||
svcName,
|
||||
);
|
||||
if (!result) {
|
||||
log.error(
|
||||
`Invalid service data prevented component creation: ${parameters.vinculumDeviceData} ${svc}`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -179,6 +179,7 @@ const attributeTypeKeyMap: Record<string, string> = {
|
||||
alarm: 'event',
|
||||
meter: 'props.unit',
|
||||
meter_export: 'props.unit',
|
||||
param: 'parameter_id',
|
||||
};
|
||||
|
||||
function getNestedValue(obj: any, path: string): any {
|
||||
@ -211,10 +212,21 @@ function processAttributeValues(values: any[], attrName?: string): any {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Sort by timestamp to get the latest values first
|
||||
// Special handling for "param" attributes
|
||||
if (attrName === 'param') {
|
||||
const paramMap: Record<string, any> = {};
|
||||
for (const entry of values) {
|
||||
if (entry.parameter_id) {
|
||||
paramMap[entry.parameter_id] = { ...entry };
|
||||
}
|
||||
}
|
||||
return paramMap;
|
||||
}
|
||||
|
||||
// Sort by timestamp to get the latest values first (only if ts exists)
|
||||
const sortedValues = [...values].sort((a, b) => {
|
||||
const tsA = new Date(a.ts).getTime();
|
||||
const tsB = new Date(b.ts).getTime();
|
||||
const tsA = a.ts ? new Date(a.ts).getTime() : 0;
|
||||
const tsB = b.ts ? new Date(b.ts).getTime() : 0;
|
||||
return tsB - tsA; // Latest first
|
||||
});
|
||||
|
||||
|
@ -2303,9 +2303,9 @@
|
||||
"type": "meter"
|
||||
},
|
||||
"services": {
|
||||
"meter_heat": {
|
||||
"name": "meter_heat",
|
||||
"addr": "/rt:dev/rn:hoiax/ad:1/sv:meter_heat/ad:298",
|
||||
"meter_heating": {
|
||||
"name": "meter_heating",
|
||||
"addr": "/rt:dev/rn:hoiax/ad:1/sv:meter_heating/ad:298",
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"sup_units": ["kWh", "W"]
|
||||
|
@ -1091,6 +1091,26 @@
|
||||
}
|
||||
],
|
||||
"name": "meter_elec"
|
||||
},
|
||||
{
|
||||
"addr": "/rt:dev/rn:cloud_adapter/ad:1/sv:parameters/ad:3_1",
|
||||
"attributes": [
|
||||
{
|
||||
"name": "param",
|
||||
"values": [
|
||||
{
|
||||
"parameter_id": "cable_always_locked",
|
||||
"value_type": "bool",
|
||||
"value": false
|
||||
},
|
||||
{
|
||||
"parameter_id": "free_charging",
|
||||
"value_type": "bool",
|
||||
"value": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -1668,7 +1688,7 @@
|
||||
"id": 298,
|
||||
"services": [
|
||||
{
|
||||
"addr": "/rt:dev/rn:hoiax/ad:1/sv:meter_heat/ad:298",
|
||||
"addr": "/rt:dev/rn:hoiax/ad:1/sv:meter_heating/ad:298",
|
||||
"attributes": [
|
||||
{
|
||||
"name": "meter",
|
||||
@ -1692,7 +1712,7 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"name": "meter_heat"
|
||||
"name": "meter_heating"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
100
futurehome/src/services/parameters.ts
Normal file
100
futurehome/src/services/parameters.ts
Normal file
@ -0,0 +1,100 @@
|
||||
import { sendFimpMsg } from '../fimp/fimp';
|
||||
import {
|
||||
VinculumPd7Device,
|
||||
VinculumPd7Service,
|
||||
} from '../fimp/vinculum_pd7_device';
|
||||
import { haGetCachedState } from '../ha/update_state';
|
||||
import {
|
||||
ServiceComponentsCreationResult,
|
||||
CommandHandlers,
|
||||
} from '../ha/publish_device';
|
||||
import { HaMqttComponent } from '../ha/mqtt_components/_component';
|
||||
|
||||
export function parameters__components(
|
||||
topicPrefix: string,
|
||||
device: VinculumPd7Device,
|
||||
svc: VinculumPd7Service,
|
||||
_svcName: string,
|
||||
): ServiceComponentsCreationResult | undefined {
|
||||
const components: Record<string, HaMqttComponent> = {};
|
||||
const commandHandlers: CommandHandlers = {};
|
||||
const stateTopic = `${topicPrefix}/state`;
|
||||
|
||||
// Fetch cached state for this service to discover known parameters :contentReference[oaicite:2]{index=2}
|
||||
const currentState = haGetCachedState({ topic: stateTopic })?.[svc.addr];
|
||||
const paramMap = currentState?.param;
|
||||
if (!paramMap) {
|
||||
// No parameters known → nothing to expose
|
||||
return;
|
||||
}
|
||||
|
||||
// Single MQTT topic for setting any parameter
|
||||
const setParamTopic = `${topicPrefix}${svc.addr}/set_param/command`;
|
||||
|
||||
// Iterate over each parameter in the cached state :contentReference[oaicite:3]{index=3}
|
||||
for (const [paramId, param] of Object.entries(paramMap)) {
|
||||
const valueType = (param as any).value_type as string;
|
||||
const uniqueId = `${svc.addr}_${paramId}`;
|
||||
const name = paramId.replace(/_/g, ' ');
|
||||
const valueTemplate = `{{ value_json['${svc.addr}'].param.${paramId}.value }}`;
|
||||
|
||||
if (valueType === 'bool') {
|
||||
components[uniqueId] = {
|
||||
unique_id: uniqueId,
|
||||
platform: 'switch',
|
||||
name,
|
||||
state_topic: stateTopic,
|
||||
value_template: valueTemplate,
|
||||
command_topic: setParamTopic,
|
||||
payload_on: `{"parameter_id":"${paramId}","value_type":"${valueType}","value":true}`,
|
||||
payload_off: `{"parameter_id":"${paramId}","value_type":"${valueType}","value":false}`,
|
||||
};
|
||||
} else if (
|
||||
['int', 'float', 'double', 'uint8', 'uint16', 'uint32'].includes(
|
||||
valueType,
|
||||
)
|
||||
) {
|
||||
components[uniqueId] = {
|
||||
unique_id: uniqueId,
|
||||
platform: 'number',
|
||||
name,
|
||||
state_topic: stateTopic,
|
||||
value_template: valueTemplate,
|
||||
command_topic: setParamTopic,
|
||||
command_template: `{"parameter_id":"${paramId}","value_type":"${valueType}","value":{{ value }}}`,
|
||||
};
|
||||
} else {
|
||||
components[uniqueId] = {
|
||||
unique_id: uniqueId,
|
||||
platform: 'text',
|
||||
name,
|
||||
state_topic: stateTopic,
|
||||
value_template: valueTemplate,
|
||||
command_topic: setParamTopic,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Single handler for all set_param commands
|
||||
commandHandlers[setParamTopic] = async (payload: string) => {
|
||||
let valObj: any;
|
||||
try {
|
||||
valObj = JSON.parse(payload);
|
||||
} catch {
|
||||
// Invalid JSON: ignore
|
||||
return;
|
||||
}
|
||||
await sendFimpMsg({
|
||||
address: svc.addr!,
|
||||
service: 'parameters',
|
||||
cmd: 'cmd.param.set',
|
||||
val: valObj,
|
||||
val_t: 'object',
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
components,
|
||||
commandHandlers,
|
||||
};
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user