From 7d863d656f295fd6856722077255023e3da895ff Mon Sep 17 00:00:00 2001 From: litinoveweedle <15144712+litinoveweedle@users.noreply.github.com> Date: Sat, 1 Jun 2024 22:41:10 +0200 Subject: [PATCH] Add support for ZHA zigbee IR remotes as controller --- custom_components/smartir/controller.py | 31 +++++++++++++++++++++ docs/CLIMATE.md | 22 ++++++++++++++- docs/FAN.md | 21 ++++++++++++++- docs/MEDIA_PLAYER.md | 36 ++++++++++++++++++------- docs/README.md | 1 + info.md | 1 + 6 files changed, 101 insertions(+), 11 deletions(-) diff --git a/custom_components/smartir/controller.py b/custom_components/smartir/controller.py index 2de75a2e..0aef29b0 100644 --- a/custom_components/smartir/controller.py +++ b/custom_components/smartir/controller.py @@ -12,6 +12,7 @@ MQTT_CONTROLLER = "MQTT" LOOKIN_CONTROLLER = "LOOKin" ESPHOME_CONTROLLER = "ESPHome" +ZHA_CONTROLLER = "ZHA" ENC_BASE64 = "Base64" ENC_HEX = "Hex" @@ -23,6 +24,7 @@ MQTT_COMMANDS_ENCODING = [ENC_RAW] LOOKIN_COMMANDS_ENCODING = [ENC_PRONTO, ENC_RAW] ESPHOME_COMMANDS_ENCODING = [ENC_RAW] +ZHA_COMMANDS_ENCODING = [ENC_RAW] def get_controller(hass, controller, encoding, controller_data, delay): @@ -33,6 +35,7 @@ def get_controller(hass, controller, encoding, controller_data, delay): MQTT_CONTROLLER: MQTTController, LOOKIN_CONTROLLER: LookinController, ESPHOME_CONTROLLER: ESPHomeController, + ZHA_CONTROLLER: ZHAController, } try: return controllers[controller]( @@ -182,6 +185,34 @@ async def send(self, command): ) +class ZHAController(AbstractController): + """Controls a ZHA device.""" + + def check_encoding(self, encoding): + """Check if the encoding is supported by the controller.""" + if encoding not in ZHA_COMMANDS_ENCODING: + raise Exception( + "The encoding is not supported " "by the ESPHome controller." + ) + + async def send(self, command): + """Send a command.""" + service_data = json.loads(self._controller_data) + if not isinstance(service_data, dict): + raise Exception("Wrong json config for ZHA controller") + for key in ["ieee", "endpoint_id", "cluster_id", "cluster_type", "command"]: + if not service_data.get(key): + raise Exception( + "Missing '%s' parameter in config for ZHA controller", key + ) + service_data["params"] = { + "code": command, + } + await self.hass.services.async_call( + "zha", "issue_zigbee_cluster_command", service_data + ) + + class Helper: """Static shared functions.""" diff --git a/docs/CLIMATE.md b/docs/CLIMATE.md index e1ddf62a..9fb39a83 100644 --- a/docs/CLIMATE.md +++ b/docs/CLIMATE.md @@ -9,7 +9,7 @@ Find your device's brand code [here](CLIMATE.md#available-codes-for-climate-devi | `name` | string | optional | The name of the device | | `unique_id` | string | optional | An ID that uniquely identifies this device. If two devices have the same unique ID, Home Assistant will raise an exception. | | `device_code` | number | required | (Accepts only positive numbers) | -| `controller_data` | string | required | The data required for the controller to function. Enter the entity_id of the Broadlink remote **(must be an already configured device)**, or the entity id of the Xiaomi IR controller, or the MQTT topic on which to send commands. | +| `controller_data` | string | required | The data required for the controller to function. Enter the entity_id of the Broadlink remote **(must be an already configured device)**, or the entity id of the Xiaomi IR controller, or the MQTT topic on which to send commands, or the ZHA zigbee cluster to send commands to. | | `delay` | number | optional | Adjusts the delay in seconds between multiple commands. The default is 0.5 | | `temperature_sensor` | string | optional | *entity_id* for a temperature sensor | | `humidity_sensor` | string | optional | *entity_id* for a humidity sensor | @@ -76,6 +76,26 @@ climate: power_sensor: binary_sensor.ac_power ``` +## Example (using ZHA controller and a TuYa ZS06): +```yaml +climate: + - platform: smartir + name: Office AC + unique_id: office_ac + device_code: 9000 + controller_data: '{ + "ieee":"XX:XX:XX:XX:XX:XX:XX:XX", + "endpoint_id": 1, + "cluster_id": 57348, + "cluster_type": "in", + "command": 2, + "command_type": "server" + }' + temperature_sensor: sensor.temperature + humidity_sensor: sensor.humidity + power_sensor: binary_sensor.ac_power +``` + ## Example (using ESPHome): ESPHome configuration example: ```yaml diff --git a/docs/FAN.md b/docs/FAN.md index d27b0e98..bbe4763d 100644 --- a/docs/FAN.md +++ b/docs/FAN.md @@ -9,7 +9,7 @@ Find your device's brand code [here](FAN.md#available-codes-for-fan-devices) and | `name` | string | optional | The name of the device | | `unique_id` | string | optional | An ID that uniquely identifies this device. If two devices have the same unique ID, Home Assistant will raise an exception. | | `device_code` | number | required | (Accepts only positive numbers) | -| `controller_data` | string | required | The data required for the controller to function. Enter the entity_id of the Broadlink remote **(must be an already configured device)**, or the entity id of the Xiaomi IR controller, or the MQTT topic on which to send commands. | +| `controller_data` | string | required | The data required for the controller to function. Enter the entity_id of the Broadlink remote **(must be an already configured device)**, or the entity id of the Xiaomi IR controller, or the MQTT topic on which to send commands, or the ZHA zigbee cluster to send commands to. | | `delay` | number | optional | Adjusts the delay in seconds between multiple commands. The default is 0.5 | | `power_sensor` | string | optional | *entity_id* for a sensor that monitors whether your device is actually `on` or `off`. This may be a power monitor sensor. (Accepts only on/off states) | | `power_sensor_restore_state` | boolean | optional | If `power_sensor` is set, and the device is likely to decrease power consumption bellow `power_sensors` threshold (for instance, a fan with speed in auto fluctuating mode), setting this to `true` will cause the entity fan state to update dynamically between OFF and last known ON speed, following the state of the `power_sensor`. | @@ -104,6 +104,25 @@ fan: power_sensor: binary_sensor.fan_power ``` +## Example (using ZHA controller and a TuYa ZS06): + +```yaml +fan: + - platform: smartir + name: Bedroom fan + unique_id: bedroom_fan + device_code: 5000 + controller_data: '{ + "ieee":"XX:XX:XX:XX:XX:XX:XX:XX", + "endpoint_id": 1, + "cluster_id": 57348, + "cluster_type": "in", + "command": 2, + "command_type": "server" + }' + power_sensor: binary_sensor.fan_power +``` + ## Available codes for Fan devices The following are the code files created by the amazing people in the community. Before you start creating your own code file, try if one of them works for your device. **Please open an issue if your device is working and not included in the supported models.** diff --git a/docs/MEDIA_PLAYER.md b/docs/MEDIA_PLAYER.md index c17c03a8..51633dcc 100644 --- a/docs/MEDIA_PLAYER.md +++ b/docs/MEDIA_PLAYER.md @@ -4,15 +4,15 @@ For this platform to work, we need a .json file containing all the necessary IR Find your device's brand code [here](MEDIA_PLAYER.md#available-codes-for-tv-devices) and add the number in the `device_code` field. If your device is not working, you will need to learn your own codes and place the .json file in `smartir/custom_codes/media_player/` subfolders. Please note that the `device_code` field only accepts positive numbers. The .json extension is not required. ## Configuration variables: -| Name | Type | Default | Description | -| ----------------- | :----: | :------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `name` | string | optional | The name of the device | -| `unique_id` | string | optional | An ID that uniquely identifies this device. If two devices have the same unique ID, Home Assistant will raise an exception. | -| `device_code` | number | required | (Accepts only positive numbers) | -| `controller_data` | string | required | The data required for the controller to function. Enter the entity_id of the Broadlink remote **(must be an already configured device)**, or the entity id of the Xiaomi IR controller, or the MQTT topic on which to send commands. | -| `delay` | number | optional | Adjusts the delay in seconds between multiple commands. The default is 0.5 | -| `power_sensor` | string | optional | *entity_id* for a sensor that monitors whether your device is actually `on` or `off`. This may be a power monitor sensor. (Accepts only on/off states) | -| `source_names` | dict | optional | Override the names of sources as displayed in HomeAssistant (see below) | +| Name | Type | Default | Description | +| ----------------- | :----: | :------: | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `name` | string | optional | The name of the device | +| `unique_id` | string | optional | An ID that uniquely identifies this device. If two devices have the same unique ID, Home Assistant will raise an exception. | +| `device_code` | number | required | (Accepts only positive numbers) | +| `controller_data` | string | required | The data required for the controller to function. Enter the entity_id of the Broadlink remote **(must be an already configured device)**, or the entity id of the Xiaomi IR controller, or the MQTT topic on which to send commands, or the ZHA zigbee cluster to send commands to. | +| `delay` | number | optional | Adjusts the delay in seconds between multiple commands. The default is 0.5 | +| `power_sensor` | string | optional | *entity_id* for a sensor that monitors whether your device is actually `on` or `off`. This may be a power monitor sensor. (Accepts only on/off states) | +| `source_names` | dict | optional | Override the names of sources as displayed in HomeAssistant (see below) | ## Example (using broadlink controller): Add a Broadlink RM device named "Bedroom" via config flow (read the [docs](https://www.home-assistant.io/integrations/broadlink/)). @@ -97,6 +97,24 @@ media_player: power_sensor: binary_sensor.tv_power ``` +## Example (using ZHA controller and a TuYa ZS06): +```yaml +media_player: + - platform: smartir + name: Living room TV + unique_id: living_room_tv + device_code: 5000 + controller_data: '{ + "ieee":"XX:XX:XX:XX:XX:XX:XX:XX", + "endpoint_id": 1, + "cluster_id": 57348, + "cluster_type": "in", + "command": 2, + "command_type": "server" + }' + power_sensor: binary_sensor.tv_power +``` + ### Overriding Source Names Source names in device files are usually set to the name that the media player uses. These often aren't very descriptive, so you can override these names in the configuration file. You can also remove a source by setting its name to `null`. diff --git a/docs/README.md b/docs/README.md index d8f96ef8..1ef89d86 100644 --- a/docs/README.md +++ b/docs/README.md @@ -9,6 +9,7 @@ SmartIR currently supports the following controllers: * [LOOK.in Remote](http://look-in.club/devices/remote) * [ESPHome User-defined service for remote transmitter](https://esphome.io/components/api.html#user-defined-services) * [MQTT Publish service](https://www.home-assistant.io/docs/mqtt/service/) +* [ZHA Zigbee IR remote](https://www.home-assistant.io/integrations/zha/) (May require custom zha quirk for given controller) More than 120 climate devices are currently supported out-of-the-box, mainly for the Broadlink controller, thanks to our awesome community. diff --git a/info.md b/info.md index f7e9ef3e..86ddaaa2 100644 --- a/info.md +++ b/info.md @@ -5,6 +5,7 @@ SmartIR currently supports the following controllers: * [LOOK.in Remote](http://look-in.club/devices/remote) * [ESPHome User-defined service for remote transmitter](https://esphome.io/components/api.html#user-defined-services) * [MQTT Publish service](https://www.home-assistant.io/docs/mqtt/service/) +* [ZHA Zigbee IR remote](https://www.home-assistant.io/integrations/zha/) (May require custom zha quirk for given controller) More than 120 climate devices are currently supported out-of-the-box, mainly for the Broadlink controller, thanks to our awesome community.
Please don't forget to [**star**](https://github.com/smartHomeHub/SmartIR/) the repository if you had fun! [**"Buy Me A Coffee**"](https://www.buymeacoffee.com/vassilis) is also welcome. It will help in further development.