diff --git a/README.md b/README.md index 799dc5e..c527478 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ todo: links to the .ts service implementations below | barrier_ctrl | | ✅ | | basic | | ✅ | | battery | | ✅ | -| chargepoint | [Futurehome Charge](https://www.futurehome.io/en_no/shop/charge) | | +| chargepoint | [Futurehome Charge](https://www.futurehome.io/en_no/shop/charge) | ✅ | | color_ctrl | | ✅ | | complex_alarm_system | | | | door_lock | | | @@ -75,7 +75,7 @@ todo: links to the .ts service implementations below | meter_elec | [HAN-Sensor](https://www.futurehome.io/en/shop/han-sensor) | | | out_bin_switch | [16A Puck Relé](https://www.futurehome.io/en_no/shop/puck-relay-16a) | ✅ | | out_lvl_switch | [Smart LED Dimmer](https://www.futurehome.io/en_no/shop/smart-led-dimmer-polar-white) | ✅ | -| power_regulator | | | +| power_regulator | [16A Puck Relé](https://www.futurehome.io/en_no/shop/puck-relay-16a) | | | scene_ctrl | [Modusbryter](https://www.futurehome.io/en_no/shop/modeswitch-white) | ✅ | | sensor_accelx | | ✅ | | sensor_accely | | ✅ | diff --git a/futurehome/CHANGELOG.md b/futurehome/CHANGELOG.md index 8862010..d40cf9c 100644 --- a/futurehome/CHANGELOG.md +++ b/futurehome/CHANGELOG.md @@ -1,6 +1,10 @@ +## 0.1.3 (25.07.2025) + +- Added support for 'chargepoint' service (EV chargers). + ## 0.1.2 (24.07.2025) - Added support for 'water_heater' service (devices such as water boiler or a water tank). diff --git a/futurehome/README.md b/futurehome/README.md index 5a03905..05d6994 100644 --- a/futurehome/README.md +++ b/futurehome/README.md @@ -63,7 +63,7 @@ todo: links to the .ts service implementations below | barrier_ctrl | | ✅ | | basic | | ✅ | | battery | | ✅ | -| chargepoint | [Futurehome Charge](https://www.futurehome.io/en_no/shop/charge) | | +| chargepoint | [Futurehome Charge](https://www.futurehome.io/en_no/shop/charge) | ✅ | | color_ctrl | | ✅ | | complex_alarm_system | | | | door_lock | | | @@ -74,7 +74,7 @@ todo: links to the .ts service implementations below | meter_elec | [HAN-Sensor](https://www.futurehome.io/en/shop/han-sensor) | | | out_bin_switch | [16A Puck Relé](https://www.futurehome.io/en_no/shop/puck-relay-16a) | ✅ | | out_lvl_switch | [Smart LED Dimmer](https://www.futurehome.io/en_no/shop/smart-led-dimmer-polar-white) | ✅ | -| power_regulator | | | +| power_regulator | [16A Puck Relé](https://www.futurehome.io/en_no/shop/puck-relay-16a) | | | scene_ctrl | [Modusbryter](https://www.futurehome.io/en_no/shop/modeswitch-white) | ✅ | | sensor_accelx | | ✅ | | sensor_accely | | ✅ | diff --git a/futurehome/config.yaml b/futurehome/config.yaml index 2a91ace..11c2ff5 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.1.2" +version: "0.1.3" slug: futurehome description: Local Futurehome Smarthub integration url: "https://github.com/adrianjagielak/home-assistant-futurehome" diff --git a/futurehome/src/ha/mqtt_components/alarm_control_panel.ts b/futurehome/src/ha/mqtt_components/alarm_control_panel.ts index cc715ad..61619c8 100644 --- a/futurehome/src/ha/mqtt_components/alarm_control_panel.ts +++ b/futurehome/src/ha/mqtt_components/alarm_control_panel.ts @@ -101,6 +101,12 @@ export interface AlarmControlPanelComponent { /** * [Icon](https://www.home-assistant.io/docs/configuration/customizing-devices/#icon) for the entity. + * + * The icon must be a Material Design Icons (MDI) string identifier, for example: `mdi:thermometer`, `mdi:battery`, or `mdi:water`. + * + * It is recommended to set the icon when the default icon or other entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity. In most cases, relying on the automatic icon selection ensures better consistency + * and compatibility with future updates. */ icon?: string; @@ -119,7 +125,10 @@ export interface AlarmControlPanelComponent { /** * The name of the alarm. - * Can be set to `null` if only the device name is relevant. + * + * It is recommended to set the name when entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity, to avoid showing the default 'MQTT' name. + * * Default: "MQTT Alarm" */ name?: string | null; diff --git a/futurehome/src/ha/mqtt_components/binary_sensor.ts b/futurehome/src/ha/mqtt_components/binary_sensor.ts index 7062d34..8075d0f 100644 --- a/futurehome/src/ha/mqtt_components/binary_sensor.ts +++ b/futurehome/src/ha/mqtt_components/binary_sensor.ts @@ -41,7 +41,7 @@ export interface BinarySensorComponent { /** * Sets the [class of the device](https://www.home-assistant.io/integrations/binary_sensor/#device-class), * changing the device state and icon that is displayed on the frontend. - * The `device_class` can be `null`. + * The `device_class` defaults to `null`. */ device_class?: string | null; @@ -98,7 +98,10 @@ export interface BinarySensorComponent { /** * The name of the binary sensor. - * Can be set to `null` if only the device name is relevant. + * + * It is recommended to set the name when entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity, to avoid showing the default 'MQTT' name. + * * Default: "MQTT binary sensor" */ name?: string | null; @@ -116,6 +119,12 @@ export interface BinarySensorComponent { /** * [Icon](https://www.home-assistant.io/docs/configuration/customizing-devices/#icon) for the entity. + * + * The icon must be a Material Design Icons (MDI) string identifier, for example: `mdi:thermometer`, `mdi:battery`, or `mdi:water`. + * + * It is recommended to set the icon when the default icon or other entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity. In most cases, relying on the automatic icon selection ensures better consistency + * and compatibility with future updates. */ icon?: string; diff --git a/futurehome/src/ha/mqtt_components/button.ts b/futurehome/src/ha/mqtt_components/button.ts index 08bc1ea..9537668 100644 --- a/futurehome/src/ha/mqtt_components/button.ts +++ b/futurehome/src/ha/mqtt_components/button.ts @@ -50,9 +50,9 @@ export interface ButtonComponent { /** * The [type/class](https://www.home-assistant.io/integrations/button/#device-class) of the button to set the icon in the frontend. - * The `device_class` can be `null`. + * The `device_class` defaults to `null` (generic button). */ - device_class?: string | null; + device_class?: 'identify' | 'restart' | 'update' | null; /** * Flag which defines if the entity should be enabled when first added. @@ -68,6 +68,12 @@ export interface ButtonComponent { /** * [Icon](https://www.home-assistant.io/docs/configuration/customizing-devices/#icon) for the entity. + * + * The icon must be a Material Design Icons (MDI) string identifier, for example: `mdi:thermometer`, `mdi:battery`, or `mdi:water`. + * + * It is recommended to set the icon when the default icon or other entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity. In most cases, relying on the automatic icon selection ensures better consistency + * and compatibility with future updates. */ icon?: string; @@ -86,7 +92,10 @@ export interface ButtonComponent { /** * The name to use when displaying this button. - * Can be set to `null` if only the device name is relevant. + * + * It is recommended to set the name when entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity, to avoid showing the default 'MQTT' name. + * * Default: "MQTT Button" */ name?: string | null; diff --git a/futurehome/src/ha/mqtt_components/camera.ts b/futurehome/src/ha/mqtt_components/camera.ts index 4509fac..6cc0475 100644 --- a/futurehome/src/ha/mqtt_components/camera.ts +++ b/futurehome/src/ha/mqtt_components/camera.ts @@ -53,6 +53,12 @@ export interface CameraComponent { /** * [Icon](https://www.home-assistant.io/docs/configuration/customizing-devices/#icon) for the entity. + * + * The icon must be a Material Design Icons (MDI) string identifier, for example: `mdi:thermometer`, `mdi:battery`, or `mdi:water`. + * + * It is recommended to set the icon when the default icon or other entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity. In most cases, relying on the automatic icon selection ensures better consistency + * and compatibility with future updates. */ icon?: string; @@ -77,7 +83,10 @@ export interface CameraComponent { /** * The name of the camera. - * Can be set to `null` if only the device name is relevant. + * + * It is recommended to set the name when entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity, to avoid showing the default 'MQTT' name. + * */ name?: string | null; diff --git a/futurehome/src/ha/mqtt_components/climate.ts b/futurehome/src/ha/mqtt_components/climate.ts index 6cea0c4..2f82aad 100644 --- a/futurehome/src/ha/mqtt_components/climate.ts +++ b/futurehome/src/ha/mqtt_components/climate.ts @@ -116,6 +116,12 @@ export interface ClimateComponent { /** * [Icon](https://www.home-assistant.io/docs/configuration/customizing-devices/#icon) for the entity. + * + * The icon must be a Material Design Icons (MDI) string identifier, for example: `mdi:thermometer`, `mdi:battery`, or `mdi:water`. + * + * It is recommended to set the icon when the default icon or other entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity. In most cases, relying on the automatic icon selection ensures better consistency + * and compatibility with future updates. */ icon?: string; @@ -186,7 +192,10 @@ export interface ClimateComponent { /** * The name of the HVAC. - * Can be set to `null` if only the device name is relevant. + * + * It is recommended to set the name when entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity, to avoid showing the default 'MQTT' name. + * * Default: "MQTT HVAC" */ name?: string | null; @@ -197,7 +206,7 @@ export interface ClimateComponent { object_id?: string; /** - * Flag that defines if the climate works in optimistic mode. + * Flag that defines if the climate works in optimistic mode (not waiting for state update before showing the change in Home Assistant). * Default: `true` if no state topic defined, else `false`. */ optimistic?: boolean; diff --git a/futurehome/src/ha/mqtt_components/cover.ts b/futurehome/src/ha/mqtt_components/cover.ts index 1144dca..303cf68 100644 --- a/futurehome/src/ha/mqtt_components/cover.ts +++ b/futurehome/src/ha/mqtt_components/cover.ts @@ -40,7 +40,7 @@ export interface CoverComponent { /** * Sets the [class of the device](https://www.home-assistant.io/integrations/cover/#device_class), * changing the device state and icon that is displayed on the frontend. - * The `device_class` can be `null` (generic cover). + * The `device_class` defaults to `null` (generic cover). */ device_class?: CoverDeviceClass; @@ -59,6 +59,12 @@ export interface CoverComponent { /** * [Icon](https://www.home-assistant.io/docs/configuration/customizing-devices/#icon) for the entity. + * + * The icon must be a Material Design Icons (MDI) string identifier, for example: `mdi:thermometer`, `mdi:battery`, or `mdi:water`. + * + * It is recommended to set the icon when the default icon or other entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity. In most cases, relying on the automatic icon selection ensures better consistency + * and compatibility with future updates. */ icon?: string; @@ -77,7 +83,10 @@ export interface CoverComponent { /** * The name of the cover. - * Can be set to `null` if only the device name is relevant. + * + * It is recommended to set the name when entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity, to avoid showing the default 'MQTT' name. + * * Default: "MQTT Cover" */ name?: string | null; @@ -88,7 +97,7 @@ export interface CoverComponent { object_id?: string; /** - * Flag that defines if switch works in optimistic mode. + * Flag that defines if switch works in optimistic mode (not waiting for state update before showing the change in Home Assistant). * Default: `false` if `state_topic` or `position_topic` defined, else `true`. */ optimistic?: boolean; @@ -255,7 +264,7 @@ export interface CoverComponent { tilt_opened_value?: number; /** - * Flag that determines if tilt works in optimistic mode. + * Flag that determines if tilt works in optimistic mode (not waiting for state update before showing the change in Home Assistant). * Default: `true` if `tilt_status_topic` is not defined, else `false`. */ tilt_optimistic?: boolean; diff --git a/futurehome/src/ha/mqtt_components/device_tracker.ts b/futurehome/src/ha/mqtt_components/device_tracker.ts index 12ac3dc..cbb872c 100644 --- a/futurehome/src/ha/mqtt_components/device_tracker.ts +++ b/futurehome/src/ha/mqtt_components/device_tracker.ts @@ -124,6 +124,12 @@ export interface DeviceTrackerComponent { /** * [Icon](https://www.home-assistant.io/docs/configuration/customizing-devices/#icon) for the entity. + * + * The icon must be a Material Design Icons (MDI) string identifier, for example: `mdi:thermometer`, `mdi:battery`, or `mdi:water`. + * + * It is recommended to set the icon when the default icon or other entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity. In most cases, relying on the automatic icon selection ensures better consistency + * and compatibility with future updates. */ icon?: string; } diff --git a/futurehome/src/ha/mqtt_components/event.ts b/futurehome/src/ha/mqtt_components/event.ts index 73135eb..6b1d9fc 100644 --- a/futurehome/src/ha/mqtt_components/event.ts +++ b/futurehome/src/ha/mqtt_components/event.ts @@ -48,7 +48,7 @@ export interface EventComponent { /** * The [type/class](https://www.home-assistant.io/integrations/event/#device-class) of the event to set the icon in the frontend. - * The `device_class` can be `null`. + * The `device_class` defaults to `null`. */ device_class?: string | null; diff --git a/futurehome/src/ha/mqtt_components/fan.ts b/futurehome/src/ha/mqtt_components/fan.ts index 6ba1e2c..50d6afd 100644 --- a/futurehome/src/ha/mqtt_components/fan.ts +++ b/futurehome/src/ha/mqtt_components/fan.ts @@ -159,7 +159,10 @@ export interface FanComponent { /** * The name of the fan. - * Can be set to `null` if only the device name is relevant. + * + * It is recommended to set the name when entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity, to avoid showing the default 'MQTT' name. + * * Default: "MQTT Fan" */ name?: string | null; @@ -176,7 +179,7 @@ export interface FanComponent { enabled_by_default?: boolean; /** - * Flag that defines if fan works in optimistic mode. + * Flag that defines if fan works in optimistic mode (not waiting for state update before showing the change in Home Assistant). * Default: `true` if no state topic defined, else `false`. */ optimistic?: boolean; @@ -195,6 +198,12 @@ export interface FanComponent { /** * [Icon](https://www.home-assistant.io/docs/configuration/customizing-devices/#icon) for the entity. + * + * The icon must be a Material Design Icons (MDI) string identifier, for example: `mdi:thermometer`, `mdi:battery`, or `mdi:water`. + * + * It is recommended to set the icon when the default icon or other entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity. In most cases, relying on the automatic icon selection ensures better consistency + * and compatibility with future updates. */ icon?: string; diff --git a/futurehome/src/ha/mqtt_components/humidifier.ts b/futurehome/src/ha/mqtt_components/humidifier.ts index c94957e..f8e7b14 100644 --- a/futurehome/src/ha/mqtt_components/humidifier.ts +++ b/futurehome/src/ha/mqtt_components/humidifier.ts @@ -79,7 +79,7 @@ export interface HumidifierComponent { action_topic?: string; /** - * Flag that defines if humidifier works in optimistic mode. + * Flag that defines if humidifier works in optimistic mode (not waiting for state update before showing the change in Home Assistant). * Defaults to `true` if no state topic defined, else `false`. */ optimistic?: boolean; @@ -190,7 +190,10 @@ export interface HumidifierComponent { /** * The name of the humidifier. - * Can be set to `null` if only the device name is relevant. + * + * It is recommended to set the name when entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity, to avoid showing the default 'MQTT' name. + * * Default: `"MQTT humidifier"` */ name?: string | null; @@ -215,6 +218,12 @@ export interface HumidifierComponent { /** * [Icon](https://www.home-assistant.io/docs/configuration/customizing-devices/#icon) for the entity. + * + * The icon must be a Material Design Icons (MDI) string identifier, for example: `mdi:thermometer`, `mdi:battery`, or `mdi:water`. + * + * It is recommended to set the icon when the default icon or other entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity. In most cases, relying on the automatic icon selection ensures better consistency + * and compatibility with future updates. */ icon?: string; diff --git a/futurehome/src/ha/mqtt_components/image.ts b/futurehome/src/ha/mqtt_components/image.ts index 5e77ea4..8ccef3f 100644 --- a/futurehome/src/ha/mqtt_components/image.ts +++ b/futurehome/src/ha/mqtt_components/image.ts @@ -88,7 +88,10 @@ export interface ImageComponent { /** * The name of the image. - * Can be set to `null` if only the device name is relevant. + * + * It is recommended to set the name when entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity, to avoid showing the default 'MQTT' name. + * */ name?: string | null; @@ -111,6 +114,12 @@ export interface ImageComponent { /** * [Icon](https://www.home-assistant.io/docs/configuration/customizing-devices/#icon) for the entity. + * + * The icon must be a Material Design Icons (MDI) string identifier, for example: `mdi:thermometer`, `mdi:battery`, or `mdi:water`. + * + * It is recommended to set the icon when the default icon or other entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity. In most cases, relying on the automatic icon selection ensures better consistency + * and compatibility with future updates. */ icon?: string; } diff --git a/futurehome/src/ha/mqtt_components/lawn_mower.ts b/futurehome/src/ha/mqtt_components/lawn_mower.ts index f96acf2..59df240 100644 --- a/futurehome/src/ha/mqtt_components/lawn_mower.ts +++ b/futurehome/src/ha/mqtt_components/lawn_mower.ts @@ -72,6 +72,12 @@ export interface LawnMowerComponent { /** * [Icon](https://www.home-assistant.io/docs/configuration/customizing-devices/#icon) for the entity. + * + * The icon must be a Material Design Icons (MDI) string identifier, for example: `mdi:thermometer`, `mdi:battery`, or `mdi:water`. + * + * It is recommended to set the icon when the default icon or other entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity. In most cases, relying on the automatic icon selection ensures better consistency + * and compatibility with future updates. */ icon?: string; @@ -89,7 +95,10 @@ export interface LawnMowerComponent { /** * The name of the lawn mower. - * Can be set to `null` if only the device name is relevant. + * + * It is recommended to set the name when entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity, to avoid showing the default 'MQTT' name. + * */ name?: string | null; @@ -99,7 +108,7 @@ export interface LawnMowerComponent { object_id?: string; /** - * Flag that defines if the lawn mower works in optimistic mode. + * Flag that defines if the lawn mower works in optimistic mode (not waiting for state update before showing the change in Home Assistant). * Default: `true` if no `activity_state_topic` defined, else `false`. */ optimistic?: boolean; diff --git a/futurehome/src/ha/mqtt_components/light.ts b/futurehome/src/ha/mqtt_components/light.ts index ef853ce..6ee9603 100644 --- a/futurehome/src/ha/mqtt_components/light.ts +++ b/futurehome/src/ha/mqtt_components/light.ts @@ -72,7 +72,7 @@ export interface LightComponent { brightness_value_template?: string; /** - * The flag that defines if the light works in optimistic mode. + * The flag that defines if the light works in optimistic mode (not waiting for state update before showing the change in Home Assistant). * Optimistic mode means the light immediately changes state after command, * without waiting for confirmation from state topic. * Default: `true` if no state topic defined, else `false`. @@ -348,6 +348,12 @@ export interface LightComponent { /** * [Icon](https://www.home-assistant.io/docs/configuration/customizing-devices/#icon) for the entity. + * + * The icon must be a Material Design Icons (MDI) string identifier, for example: `mdi:thermometer`, `mdi:battery`, or `mdi:water`. + * + * It is recommended to set the icon when the default icon or other entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity. In most cases, relying on the automatic icon selection ensures better consistency + * and compatibility with future updates. */ icon?: string; diff --git a/futurehome/src/ha/mqtt_components/lock.ts b/futurehome/src/ha/mqtt_components/lock.ts index 7b2de8b..7851867 100644 --- a/futurehome/src/ha/mqtt_components/lock.ts +++ b/futurehome/src/ha/mqtt_components/lock.ts @@ -72,6 +72,12 @@ export interface LockComponent { /** * [Icon](https://www.home-assistant.io/docs/configuration/customizing-devices/#icon) for the entity. + * + * The icon must be a Material Design Icons (MDI) string identifier, for example: `mdi:thermometer`, `mdi:battery`, or `mdi:water`. + * + * It is recommended to set the icon when the default icon or other entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity. In most cases, relying on the automatic icon selection ensures better consistency + * and compatibility with future updates. */ icon?: string; @@ -90,7 +96,10 @@ export interface LockComponent { /** * The name of the lock. - * Can be set to `null` if only the device name is relevant. + * + * It is recommended to set the name when entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity, to avoid showing the default 'MQTT' name. + * * Default: "MQTT Lock" */ name?: string | null; @@ -101,7 +110,7 @@ export interface LockComponent { object_id?: string; /** - * Flag that defines if lock works in optimistic mode. + * Flag that defines if lock works in optimistic mode (not waiting for state update before showing the change in Home Assistant). * Default: `true` if no `state_topic` defined, else `false`. */ optimistic?: boolean; diff --git a/futurehome/src/ha/mqtt_components/notify.ts b/futurehome/src/ha/mqtt_components/notify.ts index 99ef978..ea32936 100644 --- a/futurehome/src/ha/mqtt_components/notify.ts +++ b/futurehome/src/ha/mqtt_components/notify.ts @@ -51,6 +51,12 @@ export interface NotifyComponent { /** * [Icon](https://www.home-assistant.io/docs/configuration/customizing-devices/#icon) for the entity. + * + * The icon must be a Material Design Icons (MDI) string identifier, for example: `mdi:thermometer`, `mdi:battery`, or `mdi:water`. + * + * It is recommended to set the icon when the default icon or other entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity. In most cases, relying on the automatic icon selection ensures better consistency + * and compatibility with future updates. */ icon?: string; @@ -87,7 +93,10 @@ export interface NotifyComponent { /** * The name to use when displaying this notify entity. - * Can be set to `null` if only the device name is relevant. + * + * It is recommended to set the name when entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity, to avoid showing the default 'MQTT' name. + * * Default: "MQTT notify" */ name?: string | null; diff --git a/futurehome/src/ha/mqtt_components/number.ts b/futurehome/src/ha/mqtt_components/number.ts index ab1a089..66dd84b 100644 --- a/futurehome/src/ha/mqtt_components/number.ts +++ b/futurehome/src/ha/mqtt_components/number.ts @@ -86,8 +86,63 @@ export interface NumberComponent { /** * The [type/class](https://www.home-assistant.io/integrations/number/#device-class) of the number. The `device_class` can be `null`. + * The `device_class` defaults to `null` (generic number). */ - device_class?: string | null; + device_class?: + | 'apparent_power' + | 'aqi' + | 'area' + | 'atmospheric_pressure' + | 'battery' + | 'blood_glucose_concentration' + | 'carbon_dioxide' + | 'carbon_monoxide' + | 'current' + | 'data_rate' + | 'data_size' + | 'distance' + | 'duration' + | 'energy' + | 'energy_distance' + | 'energy_storage' + | 'frequency' + | 'gas' + | 'humidity' + | 'illuminance' + | 'irradiance' + | 'moisture' + | 'monetary' + | 'nitrogen_dioxide' + | 'nitrogen_monoxide' + | 'nitrous_oxide' + | 'ozone' + | 'ph' + | 'pm1' + | 'pm25' + | 'pm10' + | 'power_factor' + | 'power' + | 'precipitation' + | 'precipitation_intensity' + | 'pressure' + | 'reactive_energy' + | 'reactive_power' + | 'signal_strength' + | 'sound_pressure' + | 'speed' + | 'sulphur_dioxide' + | 'temperature' + | 'volatile_organic_compounds' + | 'volatile_organic_compounds_parts' + | 'voltage' + | 'volume' + | 'volume_flow_rate' + | 'volume_storage' + | 'water' + | 'weight' + | 'wind_direction' + | 'wind_speed' + | null; /** * Flag which defines if the entity should be enabled when first added. @@ -104,6 +159,12 @@ export interface NumberComponent { /** * [Icon](https://www.home-assistant.io/docs/configuration/customizing-devices/#icon) for the entity. + * + * The icon must be a Material Design Icons (MDI) string identifier, for example: `mdi:thermometer`, `mdi:battery`, or `mdi:water`. + * + * It is recommended to set the icon when the default icon or other entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity. In most cases, relying on the automatic icon selection ensures better consistency + * and compatibility with future updates. */ icon?: string; @@ -120,7 +181,7 @@ export interface NumberComponent { json_attributes_topic?: string; /** - * Flag that defines if number works in optimistic mode. + * Flag that defines if number works in optimistic mode (not waiting for state update before showing the change in Home Assistant). * Default: `true` if no `state_topic` defined, else `false`. */ optimistic?: boolean; diff --git a/futurehome/src/ha/mqtt_components/select.ts b/futurehome/src/ha/mqtt_components/select.ts index cd57642..7666575 100644 --- a/futurehome/src/ha/mqtt_components/select.ts +++ b/futurehome/src/ha/mqtt_components/select.ts @@ -50,7 +50,7 @@ export interface SelectComponent { options: string[]; /** - * Flag that defines if the select works in optimistic mode. + * Flag that defines if the select works in optimistic mode (not waiting for state update before showing the change in Home Assistant). * Default: `true` if no `state_topic` defined, else `false`. */ optimistic?: boolean; @@ -94,6 +94,12 @@ export interface SelectComponent { /** * [Icon](https://www.home-assistant.io/docs/configuration/customizing-devices/#icon) for the entity. + * + * The icon must be a Material Design Icons (MDI) string identifier, for example: `mdi:thermometer`, `mdi:battery`, or `mdi:water`. + * + * It is recommended to set the icon when the default icon or other entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity. In most cases, relying on the automatic icon selection ensures better consistency + * and compatibility with future updates. */ icon?: string; diff --git a/futurehome/src/ha/mqtt_components/sensor.ts b/futurehome/src/ha/mqtt_components/sensor.ts index 3d4cb21..9162c42 100644 --- a/futurehome/src/ha/mqtt_components/sensor.ts +++ b/futurehome/src/ha/mqtt_components/sensor.ts @@ -42,24 +42,91 @@ export interface SensorComponent { * * If a `value_template` is used to parse a JSON payload, a `null` value in the JSON * [will be rendered as](https://www.home-assistant.io/docs/configuration/templating/#using-value-templates-with-mqtt) `'None'`. - * Note that the `device_class` can be `null`. */ state_topic?: string; /** * The [type/class](https://www.home-assistant.io/integrations/sensor/#device-class) of the sensor to set the icon in the frontend. - * The `device_class` can be `null`. + * The `device_class` defaults to `null` (generic sensor). */ - device_class?: string | null; + device_class?: + | 'apparent_power' + | 'aqi' + | 'area' + | 'atmospheric_pressure' + | 'battery' + | 'blood_glucose_concentration' + | 'carbon_dioxide' + | 'carbon_monoxide' + | 'current' + | 'data_rate' + | 'data_size' + | 'date' + | 'distance' + | 'duration' + | 'energy' + | 'energy_distance' + | 'energy_storage' + | 'enum' + | 'frequency' + | 'gas' + | 'humidity' + | 'illuminance' + | 'irradiance' + | 'moisture' + | 'monetary' + | 'nitrogen_dioxide' + | 'nitrogen_monoxide' + | 'nitrous_oxide' + | 'ozone' + | 'ph' + | 'pm1' + | 'pm25' + | 'pm10' + | 'power_factor' + | 'power' + | 'precipitation' + | 'precipitation_intensity' + | 'pressure' + | 'reactive_energy' + | 'reactive_power' + | 'signal_strength' + | 'sound_pressure' + | 'speed' + | 'sulphur_dioxide' + | 'temperature' + | 'timestamp' + | 'volatile_organic_compounds' + | 'volatile_organic_compounds_parts' + | 'voltage' + | 'volume' + | 'volume_flow_rate' + | 'volume_storage' + | 'water' + | 'weight' + | 'wind_direction' + | 'wind_speed' + | null; /** * The [state_class](https://developers.home-assistant.io/docs/core/entity/sensor#available-state-classes) of the sensor. + * Defaults to 'measurement'. + * + * Possible values: + * - `measurement` - The state represents a measurement in present time, such as current temperature or humidity. + * - `measurement_angle` - Like `measurement`, but specifically for angles in degrees (°), e.g., wind direction. + * - `total` - Represents a total amount that can both increase and decrease, e.g., a net energy meter. + * - `total_increasing` - A monotonically increasing total that periodically resets to 0, e.g., daily water consumption. */ - state_class?: string; + state_class?: + | 'measurement' + | 'measurement_angle' + | 'total' + | 'total_increasing'; /** * Defines the units of measurement of the sensor, if any. - * The `unit_of_measurement` can be `null`. + * The `unit_of_measurement` defaults to `null`. */ unit_of_measurement?: string | null; @@ -76,7 +143,10 @@ export interface SensorComponent { /** * The name of the MQTT sensor. - * Can be set to `null` if only the device name is relevant. + * + * It is recommended to set the name when entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity, to avoid showing the default 'MQTT' name. + * * Default: "MQTT Sensor" */ name?: string | null; @@ -107,6 +177,12 @@ export interface SensorComponent { /** * [Icon](https://www.home-assistant.io/docs/configuration/customizing-devices/#icon) for the entity. + * + * The icon must be a Material Design Icons (MDI) string identifier, for example: `mdi:thermometer`, `mdi:battery`, or `mdi:water`. + * + * It is recommended to set the icon when the default icon or other entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity. In most cases, relying on the automatic icon selection ensures better consistency + * and compatibility with future updates. */ icon?: string; diff --git a/futurehome/src/ha/mqtt_components/siren.ts b/futurehome/src/ha/mqtt_components/siren.ts index e644498..b26272d 100644 --- a/futurehome/src/ha/mqtt_components/siren.ts +++ b/futurehome/src/ha/mqtt_components/siren.ts @@ -63,6 +63,12 @@ export interface SirenComponent { /** * [Icon](https://www.home-assistant.io/docs/configuration/customizing-devices/#icon) for the entity. + * + * The icon must be a Material Design Icons (MDI) string identifier, for example: `mdi:thermometer`, `mdi:battery`, or `mdi:water`. + * + * It is recommended to set the icon when the default icon or other entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity. In most cases, relying on the automatic icon selection ensures better consistency + * and compatibility with future updates. */ icon?: string; @@ -88,7 +94,7 @@ export interface SirenComponent { object_id?: string; /** - * Flag that defines if siren works in optimistic mode. + * Flag that defines if siren works in optimistic mode (not waiting for state update before showing the change in Home Assistant). * Default: `true` if no `state_topic` defined, else `false`. */ optimistic?: boolean; diff --git a/futurehome/src/ha/mqtt_components/switch.ts b/futurehome/src/ha/mqtt_components/switch.ts index 0b127c3..738bed1 100644 --- a/futurehome/src/ha/mqtt_components/switch.ts +++ b/futurehome/src/ha/mqtt_components/switch.ts @@ -45,8 +45,9 @@ export interface SwitchComponent { /** * The [type/class](https://www.home-assistant.io/integrations/switch/#device-class) of the switch to set the icon in the frontend. The `device_class` can be `null`. + * The `device_class` defaults to `null` (generic switch). */ - device_class?: string | null; + device_class?: 'outlet' | 'switch' | null; /** * Flag which defines if the entity should be enabled when first added. @@ -63,6 +64,12 @@ export interface SwitchComponent { /** * [Icon](https://www.home-assistant.io/docs/configuration/customizing-devices/#icon) for the entity. + * + * The icon must be a Material Design Icons (MDI) string identifier, for example: `mdi:thermometer`, `mdi:battery`, or `mdi:water`. + * + * It is recommended to set the icon when the default icon or other entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity. In most cases, relying on the automatic icon selection ensures better consistency + * and compatibility with future updates. */ icon?: string; @@ -80,7 +87,10 @@ export interface SwitchComponent { /** * The name to use when displaying this switch. - * Can be set to `null` if only the device name is relevant. + * + * It is recommended to set the name when entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity, to avoid showing the default 'MQTT' name. + * * Default: "MQTT Switch" */ name?: string | null; @@ -91,7 +101,7 @@ export interface SwitchComponent { object_id?: string; /** - * Flag that defines if switch works in optimistic mode. + * Flag that defines if switch works in optimistic mode (not waiting for state update before showing the change in Home Assistant). * Default: `true` if no `state_topic` defined, else `false`. */ optimistic?: boolean; diff --git a/futurehome/src/ha/mqtt_components/text.ts b/futurehome/src/ha/mqtt_components/text.ts index 82753df..e83d89e 100644 --- a/futurehome/src/ha/mqtt_components/text.ts +++ b/futurehome/src/ha/mqtt_components/text.ts @@ -57,7 +57,10 @@ export interface TextComponent { /** * The name of the text entity. - * Can be set to `null` if only the device name is relevant. + * + * It is recommended to set the name when entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity, to avoid showing the default 'MQTT' name. + * * Default: "MQTT Text" */ name?: string | null; diff --git a/futurehome/src/ha/mqtt_components/update.ts b/futurehome/src/ha/mqtt_components/update.ts index ab000d1..2b85d01 100644 --- a/futurehome/src/ha/mqtt_components/update.ts +++ b/futurehome/src/ha/mqtt_components/update.ts @@ -67,7 +67,7 @@ export interface UpdateComponent { /** * The type/class of the update to set the icon in the frontend. * See [device classes](https://www.home-assistant.io/integrations/update/#device-classes). - * Can be null. + * Defaults to `null`. */ device_class?: string | null; @@ -92,6 +92,12 @@ export interface UpdateComponent { /** * [Icon](https://www.home-assistant.io/docs/configuration/customizing-devices/#icon) for the entity. + * + * The icon must be a Material Design Icons (MDI) string identifier, for example: `mdi:thermometer`, `mdi:battery`, or `mdi:water`. + * + * It is recommended to set the icon when the default icon or other entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity. In most cases, relying on the automatic icon selection ensures better consistency + * and compatibility with future updates. */ icon?: string; diff --git a/futurehome/src/ha/mqtt_components/vacuum.ts b/futurehome/src/ha/mqtt_components/vacuum.ts index a005265..b31ffbe 100644 --- a/futurehome/src/ha/mqtt_components/vacuum.ts +++ b/futurehome/src/ha/mqtt_components/vacuum.ts @@ -63,7 +63,10 @@ export interface VacuumComponent { /** * The name of the vacuum. - * Can be set to `null` if only the device name is relevant. + * + * It is recommended to set the name when entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity, to avoid showing the default 'MQTT' name. + * * Default: "MQTT Vacuum" */ name?: string | null; diff --git a/futurehome/src/ha/mqtt_components/valve.ts b/futurehome/src/ha/mqtt_components/valve.ts index 463b1a8..598ccfa 100644 --- a/futurehome/src/ha/mqtt_components/valve.ts +++ b/futurehome/src/ha/mqtt_components/valve.ts @@ -64,7 +64,7 @@ export interface ValveComponent { value_template?: string; /** - * Flag that defines if the valve works in optimistic mode. + * Flag that defines if the valve works in optimistic mode (not waiting for state update before showing the change in Home Assistant). * Optimistic mode means the valve immediately changes state after command is sent, * without waiting for state update from the device. * Defaults to `false` if `state_topic` or position topics are defined; `true` otherwise. @@ -194,12 +194,21 @@ export interface ValveComponent { /** * [Icon](https://www.home-assistant.io/docs/configuration/customizing-devices/#icon) for the entity. + * + * The icon must be a Material Design Icons (MDI) string identifier, for example: `mdi:thermometer`, `mdi:battery`, or `mdi:water`. + * + * It is recommended to set the icon when the default icon or other entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity. In most cases, relying on the automatic icon selection ensures better consistency + * and compatibility with future updates. */ icon?: string; /** * The name of the valve. - * Can be set to `null` if only the device name is relevant. + * + * It is recommended to set the name when entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity, to avoid showing the default 'MQTT' name. + * * Default: "MQTT valve" */ name?: string | null; @@ -212,7 +221,7 @@ export interface ValveComponent { /** * Sets the [class of the device](https://www.home-assistant.io/integrations/valve/#device_class), * changing the device state and icon that is displayed on the frontend. - * The `device_class` can be `null`. + * The `device_class` defaults to `null`. */ device_class?: string | null; } diff --git a/futurehome/src/ha/mqtt_components/water_heater.ts b/futurehome/src/ha/mqtt_components/water_heater.ts index 52e1726..e86f6c0 100644 --- a/futurehome/src/ha/mqtt_components/water_heater.ts +++ b/futurehome/src/ha/mqtt_components/water_heater.ts @@ -32,7 +32,10 @@ export interface WaterHeaterComponent { /** * The name of the water heater. - * Can be set to `null` if only the device name is relevant. + * + * It is recommended to set the name when entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity, to avoid showing the default 'MQTT' name. + * * Default: "MQTT water heater" */ name?: string | null; @@ -57,6 +60,12 @@ export interface WaterHeaterComponent { /** * [Icon](https://www.home-assistant.io/docs/configuration/customizing-devices/#icon) for the entity. + * + * The icon must be a Material Design Icons (MDI) string identifier, for example: `mdi:thermometer`, `mdi:battery`, or `mdi:water`. + * + * It is recommended to set the icon when the default icon or other entity identifiers (such as `device_class` or `state_class`) + * do not accurately represent the purpose of the entity. In most cases, relying on the automatic icon selection ensures better consistency + * and compatibility with future updates. */ icon?: string; @@ -130,7 +139,7 @@ export interface WaterHeaterComponent { payload_off?: string; /** - * Flag that defines if the water heater works in optimistic mode. + * Flag that defines if the water heater works in optimistic mode (not waiting for state update before showing the change in Home Assistant). * Default: "`true` if no state topic defined, else `false`." */ optimistic?: boolean; diff --git a/futurehome/src/ha/publish_device.ts b/futurehome/src/ha/publish_device.ts index cd6b658..6b5a2f5 100644 --- a/futurehome/src/ha/publish_device.ts +++ b/futurehome/src/ha/publish_device.ts @@ -7,6 +7,7 @@ import { log } from '../logger'; import { barrier_ctrl__components } from '../services/barrier_ctrl'; import { basic__components } from '../services/basic'; import { battery__components } from '../services/battery'; +import { chargepoint__components } from '../services/chargepoint'; import { color_ctrl__components } from '../services/color_ctrl'; import { fan_ctrl__components } from '../services/fan_ctrl'; import { indicator_ctrl__components } from '../services/indicator_ctrl'; @@ -163,6 +164,7 @@ const serviceHandlers: { barrier_ctrl: barrier_ctrl__components, basic: basic__components, battery: battery__components, + chargepoint: chargepoint__components, color_ctrl: color_ctrl__components, fan_ctrl: fan_ctrl__components, indicator_ctrl: indicator_ctrl__components, diff --git a/futurehome/src/services/chargepoint.ts b/futurehome/src/services/chargepoint.ts new file mode 100644 index 0000000..9f4750a --- /dev/null +++ b/futurehome/src/services/chargepoint.ts @@ -0,0 +1,333 @@ +import { sendFimpMsg } from '../fimp/fimp'; +import { + VinculumPd7Device, + VinculumPd7Service, +} from '../fimp/vinculum_pd7_device'; +import { HaMqttComponent } from '../ha/mqtt_components/_component'; +import { SensorComponent } from '../ha/mqtt_components/sensor'; +import { SwitchComponent } from '../ha/mqtt_components/switch'; +import { NumberComponent } from '../ha/mqtt_components/number'; +import { SelectComponent } from '../ha/mqtt_components/select'; +import { + CommandHandlers, + ServiceComponentsCreationResult, +} from '../ha/publish_device'; + +export function chargepoint__components( + topicPrefix: string, + device: VinculumPd7Device, + svc: VinculumPd7Service, +): ServiceComponentsCreationResult | undefined { + const components: Record = {}; + const commandHandlers: CommandHandlers = {}; + + // Extract supported properties + const supStates = svc.props?.sup_states || []; + const supChargingModes = svc.props?.sup_charging_modes || []; + const supMaxCurrent = svc.props?.sup_max_current || 32; + const supPhaseModes = svc.props?.sup_phase_modes || []; + + // Main chargepoint state sensor + if (svc.intf?.includes('evt.state.report')) { + const stateComponent: SensorComponent = { + unique_id: `${svc.addr}_state`, + platform: 'sensor', + device_class: 'enum', + options: + supStates.length > 0 + ? supStates + : [ + 'disconnected', + 'ready_to_charge', + 'charging', + 'finished', + 'error', + 'unknown', + ], + value_template: `{{ value_json['${svc.addr}'].state | default('unknown') }}`, + icon: 'mdi:ev-station', + name: 'State', + }; + components[`${svc.addr}_state`] = stateComponent; + } + + // Cable lock switch (if supported) + if ( + svc.intf?.includes('cmd.cable_lock.set') || + svc.intf?.includes('evt.cable_lock.report') + ) { + const cableLockCommandTopic = `${topicPrefix}${svc.addr}/cable_lock/command`; + + const cableLockComponent: SwitchComponent = { + unique_id: `${svc.addr}_cable_lock`, + platform: 'switch', + command_topic: cableLockCommandTopic, + optimistic: false, + value_template: `{{ value_json['${svc.addr}'].cable_lock | default(false) | iif('ON', 'OFF') }}`, + payload_on: 'true', + payload_off: 'false', + name: 'Cable Lock', + icon: 'mdi:lock', + entity_category: 'config', + }; + components[`${svc.addr}_cable_lock`] = cableLockComponent; + + // Cable lock command handler + commandHandlers[cableLockCommandTopic] = async (payload: string) => { + const lockState = payload === 'true'; + + await sendFimpMsg({ + address: svc.addr, + service: 'chargepoint', + cmd: 'cmd.cable_lock.set', + val_t: 'bool', + val: lockState, + }); + }; + } + + // Current session energy sensor + if (svc.intf?.includes('evt.current_session.report')) { + const currentSessionComponent: SensorComponent = { + unique_id: `${svc.addr}_current_session`, + platform: 'sensor', + device_class: 'energy', + unit_of_measurement: 'kWh', + state_class: 'total_increasing', + value_template: `{{ value_json['${svc.addr}'].current_session | default(0) }}`, + name: 'Current Session Energy', + icon: 'mdi:lightning-bolt', + }; + components[`${svc.addr}_current_session`] = currentSessionComponent; + } + + // Maximum current setting + if ( + svc.intf?.includes('cmd.max_current.set') || + svc.intf?.includes('evt.max_current.report') + ) { + const maxCurrentCommandTopic = `${topicPrefix}${svc.addr}/max_current/command`; + + const maxCurrentComponent: NumberComponent = { + unique_id: `${svc.addr}_max_current`, + platform: 'number', + command_topic: maxCurrentCommandTopic, + optimistic: false, + min: 6, + max: supMaxCurrent, + step: 1, + unit_of_measurement: 'A', + device_class: 'current', + value_template: `{{ value_json['${svc.addr}'].max_current | default(16) }}`, + name: 'Maximum Current', + icon: 'mdi:current-ac', + entity_category: 'config', + }; + components[`${svc.addr}_max_current`] = maxCurrentComponent; + + // Max current command handler + commandHandlers[maxCurrentCommandTopic] = async (payload: string) => { + const current = parseInt(payload, 10); + if (Number.isNaN(current) || current < 6 || current > supMaxCurrent) { + return; + } + + await sendFimpMsg({ + address: svc.addr, + service: 'chargepoint', + cmd: 'cmd.max_current.set', + val_t: 'int', + val: current, + }); + }; + } + + // Session current setting (if supported) + if (svc.intf?.includes('cmd.current_session.set_current')) { + const sessionCurrentCommandTopic = `${topicPrefix}${svc.addr}/session_current/command`; + + const sessionCurrentComponent: NumberComponent = { + unique_id: `${svc.addr}_session_current`, + platform: 'number', + command_topic: sessionCurrentCommandTopic, + optimistic: false, + min: 6, + max: supMaxCurrent, + step: 1, + unit_of_measurement: 'A', + device_class: 'current', + value_template: `{{ value_json['${svc.addr}'].offered_current | default(6) }}`, + name: 'Session Current', + icon: 'mdi:current-ac', + }; + components[`${svc.addr}_session_current`] = sessionCurrentComponent; + + // Session current command handler + commandHandlers[sessionCurrentCommandTopic] = async (payload: string) => { + const current = parseInt(payload, 10); + if (Number.isNaN(current) || current < 6 || current > supMaxCurrent) { + return; + } + + await sendFimpMsg({ + address: svc.addr, + service: 'chargepoint', + cmd: 'cmd.current_session.set_current', + val_t: 'int', + val: current, + }); + }; + } + + // Phase mode selection (if 3-phase and supported) + if (supPhaseModes.length > 0 && svc.intf?.includes('cmd.phase_mode.set')) { + const phaseModeCommandTopic = `${topicPrefix}${svc.addr}/phase_mode/command`; + + const phaseModeComponent: SelectComponent = { + unique_id: `${svc.addr}_phase_mode`, + platform: 'select', + command_topic: phaseModeCommandTopic, + optimistic: false, + options: supPhaseModes, + value_template: `{{ value_json['${svc.addr}'].phase_mode | default('${supPhaseModes[0]}') }}`, + name: 'Phase Mode', + icon: 'mdi:sine-wave', + entity_category: 'config', + }; + components[`${svc.addr}_phase_mode`] = phaseModeComponent; + + // Phase mode command handler + commandHandlers[phaseModeCommandTopic] = async (payload: string) => { + if (!supPhaseModes.includes(payload)) { + return; + } + + await sendFimpMsg({ + address: svc.addr, + service: 'chargepoint', + cmd: 'cmd.phase_mode.set', + val_t: 'string', + val: payload, + }); + }; + } + + // Charging mode selection (if supported) + if (supChargingModes.length > 0) { + const chargingModeComponent: SensorComponent = { + unique_id: `${svc.addr}_charging_mode`, + platform: 'sensor', + device_class: 'enum', + options: supChargingModes, + value_template: `{{ value_json['${svc.addr}'].charging_mode | default('${supChargingModes[0]}') }}`, + name: 'Charging Mode', + icon: 'mdi:speedometer', + entity_category: 'diagnostic', + }; + components[`${svc.addr}_charging_mode`] = chargingModeComponent; + } + + // Single charge control switch (combines start/stop functionality) + if ( + svc.intf?.includes('cmd.charge.start') || + svc.intf?.includes('cmd.charge.stop') + ) { + const chargeControlCommandTopic = `${topicPrefix}${svc.addr}/charge_control/command`; + + const chargeControlComponent: SwitchComponent = { + unique_id: `${svc.addr}_charge_control`, + platform: 'switch', + command_topic: chargeControlCommandTopic, + optimistic: true, + // Switch state reflects whether the charger is actively charging + value_template: `{{ (value_json['${svc.addr}'].state == 'charging') | iif('ON', 'OFF') }}`, + name: 'Charging', + icon: 'mdi:ev-station', + }; + components[`${svc.addr}_charge_control`] = chargeControlComponent; + + // Charge control command handler + commandHandlers[chargeControlCommandTopic] = async (payload: string) => { + if (payload === 'ON') { + // Start charging + if (svc.intf?.includes('cmd.charge.start')) { + const props: any = {}; + + // Add charging mode if supported and we have one set + if (supChargingModes.length > 0) { + props.charging_mode = supChargingModes[0]; // Use first available mode as default + } + + await sendFimpMsg({ + address: svc.addr, + service: 'chargepoint', + cmd: 'cmd.charge.start', + val_t: 'null', + val: null, + props: Object.keys(props).length > 0 ? props : undefined, + }); + } + } else if (payload === 'OFF') { + // Stop charging + if (svc.intf?.includes('cmd.charge.stop')) { + await sendFimpMsg({ + address: svc.addr, + service: 'chargepoint', + cmd: 'cmd.charge.stop', + val_t: 'null', + val: null, + }); + } + } + }; + } + + // Additional diagnostic sensors for properties that might be reported + + // Previous session energy (if available in reports) + const previousSessionComponent: SensorComponent = { + unique_id: `${svc.addr}_previous_session`, + platform: 'sensor', + device_class: 'energy', + unit_of_measurement: 'kWh', + state_class: 'total', + value_template: `{{ value_json['${svc.addr}'].previous_session | default(0) }}`, + name: 'Previous Session Energy', + icon: 'mdi:lightning-bolt-outline', + entity_category: 'diagnostic', + }; + components[`${svc.addr}_previous_session`] = previousSessionComponent; + + // Offered current (dynamic load balancing value) + const offeredCurrentComponent: SensorComponent = { + unique_id: `${svc.addr}_offered_current`, + platform: 'sensor', + device_class: 'current', + unit_of_measurement: 'A', + state_class: 'measurement', + value_template: `{{ value_json['${svc.addr}'].offered_current | default(0) }}`, + name: 'Offered Current', + icon: 'mdi:current-ac', + entity_category: 'diagnostic', + }; + components[`${svc.addr}_offered_current`] = offeredCurrentComponent; + + // Cable current (if reported) + const cableCurrentComponent: SensorComponent = { + unique_id: `${svc.addr}_cable_current`, + platform: 'sensor', + device_class: 'current', + unit_of_measurement: 'A', + state_class: 'measurement', + value_template: `{{ value_json['${svc.addr}'].cable_current | default(0) }}`, + name: 'Cable Current Capacity', + icon: 'mdi:cable-data', + entity_category: 'diagnostic', + }; + components[`${svc.addr}_cable_current`] = cableCurrentComponent; + + return { + components, + commandHandlers, + }; +}