Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for ZHA zigbee IR remotes as controller #1178

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 28 additions & 2 deletions custom_components/smartir/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
MQTT_CONTROLLER = 'MQTT'
LOOKIN_CONTROLLER = 'LOOKin'
ESPHOME_CONTROLLER = 'ESPHome'
ZHA_CONTROLLER = 'zha'

ENC_BASE64 = 'Base64'
ENC_HEX = 'Hex'
Expand All @@ -35,7 +36,8 @@ def get_controller(hass, controller, encoding, controller_data, delay):
XIAOMI_CONTROLLER: XiaomiController,
MQTT_CONTROLLER: MQTTController,
LOOKIN_CONTROLLER: LookinController,
ESPHOME_CONTROLLER: ESPHomeController
ESPHOME_CONTROLLER: ESPHomeController,
ZHA_CONTROLLER: ZhaController
}
try:
return controllers[controller](hass, controller, encoding, controller_data, delay)
Expand Down Expand Up @@ -183,4 +185,28 @@ async def send(self, command):
service_data = {'command': json.loads(command)}

await self.hass.services.async_call(
'esphome', self._controller_data, service_data)
'esphome', self._controller_data, service_data)


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 ESPHOME_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 k in ['ieee', 'endpoint_id', 'cluster_id', 'cluster_type', 'command']:
if not service_data.get(k):
raise Exception(f"Missing {k} parameter in config for ZHA controller")
service_data['params'] = {
'code': command,
}
await self.hass.services.async_call(
'zha', 'issue_zigbee_cluster_command', service_data)
24 changes: 23 additions & 1 deletion docs/CLIMATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ _Please note that the device_code field only accepts positive numbers. The .json
| `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 |
Expand Down Expand Up @@ -123,6 +123,28 @@ climate:
power_sensor: binary_sensor.ac_power
```

## Example (using ZHA controller and a TuYa ZS06):
```yaml
smartir:

climate:
- platform: smartir
name: Office AC
unique_id: office_ac
device_code: 9000
controller_data: '{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this be an entity_id or something for ease of use--and single source of truth?

I'm also not 100% sure if cluster_id etc. can change dynamically. This would remove the need to keep updating this part of the config.

Copy link
Author

@anmar anmar Jan 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can't be an entity ID, as that's not how ZHA sends zigbee commands. It could be the IEEE address for the IR remote. Though if we don't include cluster data in the config, it won't work for any other remote that uses a different cluster/command numbers. Currently you need a quirk file to get the TuYa ZS06 working in ZHA, so the clusters used are probably going to change for other devices.

Edit: forgot to mention, clusted_id is set in code for the cluster definition see the quirk file. So for the same device it will only change if ZHA changes cluster definitions in code.

"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
```

## Available codes for climate 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.**
Contributing to your own code files is welcome. However, we do not accept incomplete files as well as files related to MQTT controllers.
Expand Down
23 changes: 22 additions & 1 deletion docs/FAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Find your device's brand code [here](FAN.md#available-codes-for-fan-devices) and
**name** (Optional): The name of the device<br />
**unique_id** (Optional): An ID that uniquely identifies this device. If two devices have the same unique ID, Home Assistant will raise an exception.<br />
**device_code** (Required): ...... (Accepts only positive numbers)<br />
**controller_data** (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.<br />
**controller_data** (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.<br />
**delay** (Optional): Adjusts the delay in seconds between multiple commands. The default is 0.5 <br />
**power_sensor** (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)<br />

Expand Down Expand Up @@ -115,6 +115,27 @@ fan:
power_sensor: binary_sensor.fan_power
```

## Example (using ZHA controller and a TuYa ZS06):

```yaml
smartir:

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.**
Expand Down
22 changes: 21 additions & 1 deletion docs/MEDIA_PLAYER.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Find your device's brand code [here](MEDIA_PLAYER.md#available-codes-for-tv-devi
**name** (Optional): The name of the device<br />
**unique_id** (Optional): An ID that uniquely identifies this device. If two devices have the same unique ID, Home Assistant will raise an exception.<br />
**device_code** (Required): ...... (Accepts only positive numbers)<br />
**controller_data** (Required): The data required for the controller to function. Enter the IP address of the Broadlink device **(must be an already configured device)**, or the entity id of the Xiaomi IR controller, or the MQTT topic on which to send commands.<br />
**controller_data** (Required): The data required for the controller to function. Enter the IP address of the Broadlink device **(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.<br />
**delay** (Optional): Adjusts the delay in seconds between multiple commands. The default is 0.5 <br />
**power_sensor** (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)<br />
**source_names** (Optional): Override the names of sources as displayed in HomeAssistant (see below)<br />
Expand Down Expand Up @@ -107,6 +107,26 @@ media_player:
power_sensor: binary_sensor.tv_power
```

## Example (using ZHA controller and a TuYa ZS06):
```yaml
smartir:

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`.

Expand Down
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,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/)

More than 120 climate devices are currently supported out-of-the-box, mainly for the Broadlink controller, thanks to our awesome community.<br><br>
Don't forget to **star** the repository if you had fun!<br><br>
Expand Down