# Home Assistant integration `ezcoo-usb-control` publishes an MQTT discovery payload, so the matrix appears in Home Assistant as a single device with two `select` entities — one per HDMI output — without any YAML. - [Prerequisites](#prerequisites) - [Discovery](#discovery) - [Entities](#entities) - [Example automations](#example-automations) - [Route Apple TV to the living-room TV](#route-apple-tv-to-the-living-room-tv) - [Mirror both outputs to the same input](#mirror-both-outputs-to-the-same-input) - [Lovelace card](#lovelace-card) - [Troubleshooting](#troubleshooting) ## Prerequisites - Home Assistant is connected to the **same MQTT broker** that the bridge is configured to use. - The [MQTT integration](https://www.home-assistant.io/integrations/mqtt/) is enabled and its **Discovery prefix** matches `mqtt.discovery_prefix` in the bridge config (default: `homeassistant`). - `ezcoo-usb-control` is running and reports `online` on `/availability`. ## Discovery On startup the bridge publishes a retained device-level discovery payload to: ``` /device/ezcoo_matrix/config ``` With defaults that resolves to `homeassistant/device/ezcoo_matrix/config`. You can inspect it with: ```sh mosquitto_sub -h -t 'homeassistant/device/ezcoo_matrix/config' -v ``` Home Assistant picks the payload up automatically and creates the device. Removing the retained message (or stopping the bridge with the broker configured to drop retained messages) makes the entities disappear. ## Entities By default the bridge registers a single device, **EZCOO HDMI Matrix**, with two entities: | Entity ID | Type | Options | Source topic | |---|---|---|---| | `select.ezcoo_hdmi_matrix_output_1` | `select` | `IN1`, `IN2`, `IN3`, `IN4` | `ezcoo/output1/state` | | `select.ezcoo_hdmi_matrix_output_2` | `select` | `IN1`, `IN2`, `IN3`, `IN4` | `ezcoo/output2/state` | Setting an option publishes to `ezcoo/output/set`; the bridge then issues the corresponding `EZS OUT VS IN` command to the matrix and re-publishes the confirmed state. > Entity IDs can be renamed in the Home Assistant UI. The examples below > use the default slugs — adjust if you renamed yours. ## Example automations ### Route Apple TV to the living-room TV Switch output 1 to input 2 whenever the Apple TV starts playing: ```yaml - alias: "Route Apple TV to living-room TV" trigger: - platform: state entity_id: media_player.apple_tv to: "playing" action: - service: select.select_option target: entity_id: select.ezcoo_hdmi_matrix_output_1 data: option: "IN2" ``` ### Mirror both outputs to the same input Whenever either output is changed (via Home Assistant, the front panel, or the IR remote), this automation routes the *other* output to the same input — so both displays always show the same source. The template condition prevents a feedback loop when the second `select` is already in sync. ```yaml alias: EZCOO HDMI Matrix — sync outputs description: "" triggers: - trigger: state entity_id: - select.ezcoo_hdmi_matrix_output_1 - select.ezcoo_hdmi_matrix_output_2 not_to: - unknown - unavailable conditions: [] actions: - variables: target: |- {% if trigger.entity_id == 'select.ezcoo_hdmi_matrix_output_1' %} select.ezcoo_hdmi_matrix_output_2 {% else %} select.ezcoo_hdmi_matrix_output_1 {% endif %} - condition: template value_template: "{{ states(target) != trigger.to_state.state }}" - action: select.select_option target: entity_id: "{{ target }}" data: option: "{{ trigger.to_state.state }}" mode: single max_exceeded: silent ``` ## Lovelace card A minimal Lovelace entities card: ```yaml type: entities title: HDMI Matrix entities: - entity: select.ezcoo_hdmi_matrix_output_1 name: Output 1 - entity: select.ezcoo_hdmi_matrix_output_2 name: Output 2 ``` ## Troubleshooting - **Entities don't appear.** Confirm the broker has a retained payload on `homeassistant/device/ezcoo_matrix/config`, and that Home Assistant's MQTT integration uses the same discovery prefix. - **Entities are stuck on `unavailable`.** The bridge publishes `offline` to `ezcoo/availability` as its Last Will. Check `journalctl -u ezcoo-usb-control` for connection errors. - **Changing a `select` does nothing.** Watch `ezcoo/output/set` with `mosquitto_sub` — if the message arrives, the failure is on the serial side; run the bridge with `--debug` to see the command exchange. - **Automations fire in a loop.** When reacting to `select` state changes, always guard with a template condition that compares current vs target state (see the *sync outputs* example above).