找回密码
 立即注册

微信扫码登录

搜索
查看: 1902|回复: 7

[基础教程] 通过红外和局域网协议将TCL电视接入HomeAssistant

[复制链接]

0

主题

6

回帖

127

积分

注册会员

积分
127
金钱
121
HASS币
0
发表于 2026-5-25 10:11:30 | 显示全部楼层 |阅读模式
本帖最后由 th0mas 于 2026-5-25 13:55 编辑

介绍如何通过红外和局域网协议将TCL电视接入HomeAssistant,让 TCL 电视同时支持:

  • iPhone 家庭 App / 控制中心遥控器
  • Home Assistant media_player 实体
  • 小爱同学语音按键

普通按键通过 TCL 电视的局域网控制协议发送;电源键使用红外发送,因为很多电视关机或待机时无法稳定接受局域网控制。

方案概览

iPhone 控制中心遥控器
  -> HomeKit Bridge
  -> media_player.tcl_tv
  -> homekit_tv_remote_key_pressed
  -> shell_command.tcl_tv_key
  -> tcl_remote.py
  -> TCL TV

小爱同学
  -> 米家虚拟事件
  -> Home Assistant 自动化
  -> shell_command.tcl_tv_key
  -> tcl_remote.py
  -> TCL TV

电源开关
  -> Home Assistant script
  -> 和家亲 GK01 红外发射器
  -> TCL TV

硬件与软件要求

  • 一台支持 TCL Smart Remote / TCL+ 局域网遥控协议的 TCL 电视
  • 一台 Home Assistant 主机
  • 一台红外发射器
  • 本文使用便宜的“和家亲 GK01”红外设备,并刷入 / 接入 ESPHome
  • iPhone 遥控器需要 Home Assistant 的 HomeKit Bridge
  • 小爱语音控制需要米家中枢虚拟事件,或其它能在 HA 中产生事件的等价方案

建议给电视设置固定 IP,例如:

192.168.1.100

下文用 <TV_IP> 表示电视 IP,请替换成你自己的地址。

放置脚本

tcl_remote.py 放到 Home Assistant 配置目录:

/config/scripts/tcl_tv/tcl_remote.py

确保 Home Assistant 主机可以执行:

python3 /config/scripts/tcl_tv/tcl_remote.py --ip <TV_IP> send home

如果电视要求 AES 加密,脚本需要 pycryptodome,或系统中有 openssl 作为 fallback。Home Assistant OS / Alpine 环境通常已经带有 openssl

启用 Packages

如果你使用 package 管理配置,在 configuration.yaml 中加入:

homeassistant:
  packages: !include_dir_named packages

然后创建:

/config/packages/tcl_tv.yaml

电视在线状态

这里用 ping 判断电视是否在线。多数电视开机后会响应 ICMP,关机后不会响应。

command_line:
  - binary_sensor:
      name: TCL TV Power
      unique_id: tcl_tv_power_ping
      command: "ping -W 1 -c 1 <TV_IP> >/dev/null 2>&1 && echo on || echo off"
      command_timeout: 3
      device_class: connectivity
      payload_on: "on"
      payload_off: "off"
      scan_interval: 10

TCL 局域网按键服务

创建一个 shell_command,把 HA 服务调用转成 tcl_remote.py send <key>

shell_command:
  tcl_tv_key: >-
    python3 /config/scripts/tcl_tv/tcl_remote.py --ip <TV_IP> send {{ key }}

可以在开发者工具中测试:

service: shell_command.tcl_tv_key
data:
  key: home

常用按键:

up
down
left
right
ok
back
menu
home
vol_up
vol_down
mute
ch_up
ch_down

红外电源开关

电视电源建议用红外。本文使用“和家亲 GK01”作为廉价红外发射器,接入 ESPHome 后,可以在 HA 中通过服务发送红外码。

示例服务名:

esphome.gk01_send_ir_data

不同 ESPHome 节点的服务名会不同,请在 HA 的“开发者工具 -> 服务”中查找实际名称。

先学习或录制电视电源键红外码,然后创建脚本:

script:
  tcl_tv_power_toggle:
    alias: TCL TV Power Toggle
    mode: single
    sequence:
      - service: esphome.gk01_send_ir_data
        data:
          ir_data: "<POWER_IR_CODE>"

其中 <POWER_IR_CODE> 替换成你的电视电源红外码。

为了避免 HomeKit 的“开机 / 关机”被当成无条件 toggle,可以结合 ping 状态做保护:

script:
  tcl_tv_turn_on:
    alias: TCL TV Turn On
    mode: single
    sequence:
      - condition: state
        entity_id: binary_sensor.tcl_tv_power
        state: "off"
      - service: script.tcl_tv_power_toggle
      - delay: "00:00:08"
      - service: homeassistant.update_entity
        target:
          entity_id: binary_sensor.tcl_tv_power

  tcl_tv_turn_off:
    alias: TCL TV Turn Off
    mode: single
    sequence:
      - condition: state
        entity_id: binary_sensor.tcl_tv_power
        state: "on"
      - service: script.tcl_tv_power_toggle
      - delay: "00:00:08"
      - service: homeassistant.update_entity
        target:
          entity_id: binary_sensor.tcl_tv_power

创建 Home Assistant 电视实体

使用 Universal Media Player 包装成一个 media_player

media_player:
  - platform: universal
    name: TCL TV
    unique_id: tcl_tv_homekit_remote
    device_class: tv
    state_template: >-
      {% if is_state('binary_sensor.tcl_tv_power', 'on') %}
        on
      {% else %}
        off
      {% endif %}
    commands:
      turn_on:
        service: script.tcl_tv_turn_on
      turn_off:
        service: script.tcl_tv_turn_off
      volume_up:
        service: shell_command.tcl_tv_key
        data:
          key: vol_up
      volume_down:
        service: shell_command.tcl_tv_key
        data:
          key: vol_down
      volume_mute:
        service: shell_command.tcl_tv_key
        data:
          key: mute
      media_play:
        service: shell_command.tcl_tv_key
        data:
          key: ok
      media_pause:
        service: shell_command.tcl_tv_key
        data:
          key: ok

暴露到 iPhone HomeKit

把电视实体作为单独 HomeKit accessory 暴露:

homekit:
  - name: TCL TV
    mode: accessory
    port: 21064
    filter:
      include_entities:
        - media_player.tcl_tv

然后重启 Home Assistant,在 iPhone 家庭 App 中添加 TCL TV 配件。添加后,iPhone 控制中心的遥控器就可以看到这台电视。

iPhone 遥控器方向键

iPhone 遥控器的方向键、确认、返回等会在 HA 中触发 homekit_tv_remote_key_pressed 事件。添加自动化:

automation:
  - id: tcl_tv_homekit_remote_keys
    alias: TCL TV - HomeKit Remote Keys
    mode: queued
    triggers:
      - trigger: event
        event_type: homekit_tv_remote_key_pressed
    variables:
      key_map:
        arrow_up: up
        arrow_down: down
        arrow_left: left
        arrow_right: right
        select: ok
        back: back
        exit: back
        information: menu
        play_pause: ok
      event_entity: "{{ trigger.event.data.get('entity_id') }}"
      key_name: "{{ trigger.event.data.get('key_name') }}"
    conditions:
      - condition: template
        value_template: "{{ key_name in key_map }}"
      - condition: template
        value_template: "{{ event_entity in [none, 'media_player.tcl_tv'] }}"
      - condition: state
        entity_id: binary_sensor.tcl_tv_power
        state: "on"
    actions:
      - service: shell_command.tcl_tv_key
        data:
          key: "{{ key_map[key_name] }}"

小爱同学语音按键

小爱同学可以通过“米家虚拟事件”转发到 HA。思路是:

小爱语音短句 -> 米家自动化 -> 触发虚拟事件 -> HA 自动化 -> TCL 按键

先确认你的虚拟事件实体 ID,例如:

event.xiaomi_virtual_event

下文用 <XIAOMI_EVENT_ENTITY> 表示。

HA 自动化:

automation:
  - id: tcl_tv_xiaoai_remote_keys
    alias: TCL TV - Xiaoai Remote Keys
    mode: queued
    triggers:
      - trigger: state
        entity_id: <XIAOMI_EVENT_ENTITY>
        not_from:
          - unavailable
        not_to:
          - unavailable
          - unknown
    variables:
      event_name: "{{ trigger.to_state.attributes.get('事件名称') }}"
      key_map:
        电视上: up
        电视下: down
        电视左: left
        电视右: right
        电视确定: ok
        电视返回: back
        电视首页: home
        电视菜单: menu
        电视静音: mute
        电视音量加: vol_up
        电视音量减: vol_down
        电视频道加: ch_up
        电视频道减: ch_down
    conditions:
      - condition: template
        value_template: >-
          {% set age = as_timestamp(now()) - as_timestamp(trigger.to_state.state, 0) %}
          {{ age >= 0 and age <= 5 }}
      - condition: template
        value_template: "{{ event_name in key_map }}"
      - condition: state
        entity_id: binary_sensor.tcl_tv_power
        state: "on"
    actions:
      - service: shell_command.tcl_tv_key
        data:
          key: "{{ key_map[event_name] }}"

然后在米家 / 小爱里创建语音自动化:

听到“电视上”     -> 触发虚拟事件,事件名称:电视上
听到“电视下”     -> 触发虚拟事件,事件名称:电视下
听到“电视左”     -> 触发虚拟事件,事件名称:电视左
听到“电视右”     -> 触发虚拟事件,事件名称:电视右
听到“电视确定”   -> 触发虚拟事件,事件名称:电视确定
听到“电视返回”   -> 触发虚拟事件,事件名称:电视返回
听到“电视首页”   -> 触发虚拟事件,事件名称:电视首页
听到“电视菜单”   -> 触发虚拟事件,事件名称:电视菜单
听到“电视静音”   -> 触发虚拟事件,事件名称:电视静音
听到“电视音量加” -> 触发虚拟事件,事件名称:电视音量加
听到“电视音量减” -> 触发虚拟事件,事件名称:电视音量减

电源开关建议继续用红外单独处理,例如“小爱同学,打开电视 / 关闭电视”触发 HA 的 script.tcl_tv_turn_onscript.tcl_tv_turn_off

完整示例

把下面内容保存为 /config/packages/tcl_tv.yaml,并替换:

  • <TV_IP>
  • <POWER_IR_CODE>
  • esphome.gk01_send_ir_data
  • <XIAOMI_EVENT_ENTITY>
command_line:
  - binary_sensor:
      name: TCL TV Power
      unique_id: tcl_tv_power_ping
      command: "ping -W 1 -c 1 <TV_IP> >/dev/null 2>&1 && echo on || echo off"
      command_timeout: 3
      device_class: connectivity
      payload_on: "on"
      payload_off: "off"
      scan_interval: 10

shell_command:
  tcl_tv_key: >-
    python3 /config/scripts/tcl_tv/tcl_remote.py --ip <TV_IP> send {{ key }}

script:
  tcl_tv_power_toggle:
    alias: TCL TV Power Toggle
    mode: single
    sequence:
      - service: esphome.gk01_send_ir_data
        data:
          ir_data: "<POWER_IR_CODE>"

  tcl_tv_turn_on:
    alias: TCL TV Turn On
    mode: single
    sequence:
      - condition: state
        entity_id: binary_sensor.tcl_tv_power
        state: "off"
      - service: script.tcl_tv_power_toggle
      - delay: "00:00:08"
      - service: homeassistant.update_entity
        target:
          entity_id: binary_sensor.tcl_tv_power

  tcl_tv_turn_off:
    alias: TCL TV Turn Off
    mode: single
    sequence:
      - condition: state
        entity_id: binary_sensor.tcl_tv_power
        state: "on"
      - service: script.tcl_tv_power_toggle
      - delay: "00:00:08"
      - service: homeassistant.update_entity
        target:
          entity_id: binary_sensor.tcl_tv_power

media_player:
  - platform: universal
    name: TCL TV
    unique_id: tcl_tv_homekit_remote
    device_class: tv
    state_template: >-
      {% if is_state('binary_sensor.tcl_tv_power', 'on') %}
        on
      {% else %}
        off
      {% endif %}
    commands:
      turn_on:
        service: script.tcl_tv_turn_on
      turn_off:
        service: script.tcl_tv_turn_off
      volume_up:
        service: shell_command.tcl_tv_key
        data:
          key: vol_up
      volume_down:
        service: shell_command.tcl_tv_key
        data:
          key: vol_down
      volume_mute:
        service: shell_command.tcl_tv_key
        data:
          key: mute
      media_play:
        service: shell_command.tcl_tv_key
        data:
          key: ok
      media_pause:
        service: shell_command.tcl_tv_key
        data:
          key: ok

homekit:
  - name: TCL TV
    mode: accessory
    port: 21064
    filter:
      include_entities:
        - media_player.tcl_tv

automation:
  - id: tcl_tv_homekit_remote_keys
    alias: TCL TV - HomeKit Remote Keys
    mode: queued
    triggers:
      - trigger: event
        event_type: homekit_tv_remote_key_pressed
    variables:
      key_map:
        arrow_up: up
        arrow_down: down
        arrow_left: left
        arrow_right: right
        select: ok
        back: back
        exit: back
        information: menu
        play_pause: ok
      event_entity: "{{ trigger.event.data.get('entity_id') }}"
      key_name: "{{ trigger.event.data.get('key_name') }}"
    conditions:
      - condition: template
        value_template: "{{ key_name in key_map }}"
      - condition: template
        value_template: "{{ event_entity in [none, 'media_player.tcl_tv'] }}"
      - condition: state
        entity_id: binary_sensor.tcl_tv_power
        state: "on"
    actions:
      - service: shell_command.tcl_tv_key
        data:
          key: "{{ key_map[key_name] }}"

  - id: tcl_tv_xiaoai_remote_keys
    alias: TCL TV - Xiaoai Remote Keys
    mode: queued
    triggers:
      - trigger: state
        entity_id: <XIAOMI_EVENT_ENTITY>
        not_from:
          - unavailable
        not_to:
          - unavailable
          - unknown
    variables:
      event_name: "{{ trigger.to_state.attributes.get('事件名称') }}"
      key_map:
        电视上: up
        电视下: down
        电视左: left
        电视右: right
        电视确定: ok
        电视返回: back
        电视首页: home
        电视菜单: menu
        电视静音: mute
        电视音量加: vol_up
        电视音量减: vol_down
        电视频道加: ch_up
        电视频道减: ch_down
    conditions:
      - condition: template
        value_template: >-
          {% set age = as_timestamp(now()) - as_timestamp(trigger.to_state.state, 0) %}
          {{ age >= 0 and age <= 5 }}
      - condition: template
        value_template: "{{ event_name in key_map }}"
      - condition: state
        entity_id: binary_sensor.tcl_tv_power
        state: "on"
    actions:
      - service: shell_command.tcl_tv_key
        data:
          key: "{{ key_map[event_name] }}"

生效与验证

  1. 保存 package。
  2. 在 HA 中执行配置检查。
  3. 重启 Home Assistant,让 command_linemedia_playerhomekit 完整加载。
  4. 检查实体:
binary_sensor.tcl_tv_power
media_player.tcl_tv
automation.tcl_tv_homekit_remote_keys
automation.tcl_tv_xiaoai_remote_keys
  1. 手动测试:
service: shell_command.tcl_tv_key
data:
  key: home
  1. 在 iPhone 家庭 App 中添加 TCL TV 配件。
  2. 在小爱 / 米家中创建虚拟事件自动化。

注意事项

  • ping 判断状态不是绝对可靠。如果电视待机仍响应 ping,会显示为开机;如果开机但阻止 ICMP,会显示为关机。
  • shell_command 中不要使用 {{ key | quote }},Home Assistant 的模板环境不一定提供 quote filter。这里的 key 来自固定映射,不应直接暴露给任意输入。
  • HomeKit 的 TV accessory 建议使用 mode: accessory 单独暴露,避免和其它 HomeKit Bridge 实体混在一起。
  • 语音方向键体验会比遥控器慢,适合作为补充控制。



涉及到的代码:https://github.com/jarvis2f/tcl-remote
回复

使用道具 举报

0

主题

20

回帖

231

积分

中级会员

积分
231
金钱
211
HASS币
0
发表于 2026-5-27 13:36:44 | 显示全部楼层
感谢分享,太需要这个了
回复

使用道具 举报

0

主题

2

回帖

28

积分

新手上路

积分
28
金钱
26
HASS币
0
发表于 2026-6-10 15:03:24 | 显示全部楼层
非常感谢,通过这个方式已经搞定了。
回复

使用道具 举报

1

主题

49

回帖

1181

积分

金牌会员

积分
1181
金钱
1131
HASS币
0
发表于 2026-6-18 08:35:01 | 显示全部楼层
感谢分享。学习了。
回复

使用道具 举报

8

主题

191

回帖

1355

积分

金牌会员

积分
1355
金钱
1156
HASS币
0
发表于 2026-8-26 10:50:10 | 显示全部楼层
感谢楼主分享, 有个问题,我按照教程接入了homekit,但是homekit中只有电源键,没有其他按键,是怎么回事呀?要怎么在homekit中配置按键呀
回复

使用道具 举报

0

主题

10

回帖

63

积分

注册会员

积分
63
金钱
53
HASS币
0
发表于 2026-8-26 12:15:50 | 显示全部楼层
感谢分享,值得学习。
回复

使用道具 举报

0

主题

6

回帖

127

积分

注册会员

积分
127
金钱
121
HASS币
0
 楼主| 发表于 2026-8-30 16:53:19 | 显示全部楼层
a784174467 发表于 2026-8-26 10:50
感谢楼主分享, 有个问题,我按照教程接入了homekit,但是homekit中只有电源键,没有其他按键,是怎么回事 ...

不会的啊,按上面的配置了之后会出现所有的按键的
回复

使用道具 举报

8

主题

191

回帖

1355

积分

金牌会员

积分
1355
金钱
1156
HASS币
0
发表于 2026-9-2 16:51:53 | 显示全部楼层
th0mas 发表于 2026-8-30 16:53
不会的啊,按上面的配置了之后会出现所有的按键的

哦哦,找到了,原来要在控制中心中打开才有,我之前一直在家庭app里找,谢谢大佬!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Hassbian ( 晋ICP备17001384号-1 )|网站地图

GMT+8, 2026-9-16 05:37 , Processed in 0.017049 second(s), 4 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表