找回密碼
 立即註冊
惟家LINE群QRCODE
    查看: 1|回覆: 0

    用 HDMI-CEC 和 ADB 控制電視:兩條路的做法

    [複製鏈接]

    !lvup!   100%

    363

    主題

    27

    回帖

    2200萬

    積分

    管理員

    積分
    22005752
    發表於 3 天前 | 顯示全部樓層 |閱讀模式
    電視是家裡最難接進 HA 的裝置之一。

    這篇講兩種不用依賴廠商雲端的做法。



    先看你的電視是什麼


    • Android TV / Google TV → 用 ADB,功能最完整
    • Sony / Philips 等有 REST API 的 → 用官方整合
    • LG webOS → HA 有 webOS 整合,功能不錯
    • Samsung Tizen → HA 有 SamsungTV 整合
    • 沒有智能功能的舊電視HDMI-CEC 或紅外線


    路線一:ADB(Android TV / Google TV)

    ADB(Android Debug Bridge)是 Android 的除錯介面,
    可以下指令、讀狀態、啟動 App。

    設定步驟

    1. 在電視上開啟開發者選項


    • 設定 → 系統 → 關於 → 連續點「版本號碼」七次
    • 會出現「開發人員選項」
    • 進去打開 USB 偵錯網路偵錯(有的話)


    2. 固定電視的 IP

    用 DHCP 保留(前面有一篇專門講)。

    3. HA 加入整合

    設定 → 裝置與服務 → 新增整合 → Android TV Remote

    (這是 2023 之後的官方整合,取代了舊的 androidtv 自訂整合。)

    輸入 IP,電視上會跳出配對碼,輸入即可。

    能做什麼
    1. # 開關機
    2. - action: media_player.turn_on
    3.   target: {entity_id: media_player.android_tv}
    4. # 送遙控按鍵
    5. - action: remote.send_command
    6.   target: {entity_id: remote.android_tv}
    7.   data:
    8.     command:
    9.       - DPAD_DOWN
    10.       - DPAD_DOWN
    11.       - DPAD_CENTER
    12. # 啟動特定 App
    13. - action: media_player.select_source
    14.   target: {entity_id: media_player.android_tv}
    15.   data:
    16.     source: "Netflix"
    17. # 音量
    18. - action: media_player.volume_set
    19.   target: {entity_id: media_player.android_tv}
    20.   data: {volume_level: 0.3}
    複製代碼

    常用的按鍵代碼


    • HOME / BACK / MENU
    • DPAD_UP / DOWN / LEFT / RIGHT / CENTER
    • VOLUME_UP / VOLUME_DOWN / MUTE
    • MEDIA_PLAY_PAUSE / MEDIA_NEXT / MEDIA_PREVIOUS
    • POWER


    狀態回報

    Android TV Remote 整合可以知道:


    • 電視開著還關著
    • 目前在跑哪個 App(app_id 屬性)
    • 播放狀態

    1. template:
    2.   - binary_sensor:
    3.       - name: 正在看 Netflix
    4.         state: >
    5.           {{ state_attr('media_player.android_tv', 'app_id')
    6.              == 'com.netflix.ninja' }}
    複製代碼

    這個拿來做「看 Netflix 時自動調燈」很方便。



    路線二:HDMI-CEC

    CEC(Consumer Electronics Control)是 HDMI 線裡的一條控制線,
    讓裝置之間可以互相控制。

    你可能已經在用了:用機上盒的遙控器開電視、
    或者插上 Chromecast 電視自動切換輸入 —— 那就是 CEC。

    各廠牌的 CEC 名稱不同(這個很多人不知道):


    • Sony —— BRAVIA Sync
    • Samsung —— Anynet+
    • LG —— SIMPLINK
    • Panasonic —— VIERA Link
    • Sharp —— Aquos Link
    • Philips —— EasyLink
    • Toshiba —— Regza Link


    第一步:在電視設定裡把它打開(預設常常是關的)。

    硬體:你需要一個 CEC 介面


    • 樹莓派 —— 內建 CEC(HDMI 輸出本來就支援),最便宜
    • Pulse-Eight USB-CEC Adapter —— 專用的,但比較貴
    • 有些 HDMI 擷取卡


    用樹莓派的話
    1. sudo apt install cec-utils
    2. # 掃描 CEC 匯流排上有什麼
    3. echo 'scan' | cec-client -s -d 1
    4. # 開電視
    5. echo 'on 0' | cec-client -s -d 1
    6. # 關電視(待機)
    7. echo 'standby 0' | cec-client -s -d 1
    8. # 切換到某個輸入(把自己設為 active source)
    9. echo 'as' | cec-client -s -d 1
    複製代碼

    接進 HA

    HA 曾經有內建的 HDMI-CEC 整合,
    它在較新的版本已經被移除了(維護困難)。

    現在的做法有兩種:

    做法 A:用 shell_command
    1. shell_command:
    2.   tv_on: >
    3.     ssh -i /config/ssh/id_rsa pi@192.168.1.60
    4.     "echo 'on 0' | cec-client -s -d 1"
    5.   tv_off: >
    6.     ssh -i /config/ssh/id_rsa pi@192.168.1.60
    7.     "echo 'standby 0' | cec-client -s -d 1"
    複製代碼

    做法 B:在樹莓派上跑一個小服務(推薦)

    寫一個簡單的 HTTP 服務,接收指令並轉成 CEC:
    1. # /home/pi/cec_server.py
    2. from http.server import BaseHTTPRequestHandler, HTTPServer
    3. import subprocess, os
    4. TOKEN = os.environ.get('CEC_TOKEN', '')
    5. CMDS = {
    6.     '/on':      "on 0",
    7.     '/off':     "standby 0",
    8.     '/active':  "as",
    9. }
    10. class H(BaseHTTPRequestHandler):
    11.     def do_POST(self):
    12.         if self.headers.get('X-Token') != TOKEN:
    13.             self.send_response(403); self.end_headers(); return
    14.         cmd = CMDS.get(self.path)
    15.         if not cmd:
    16.             self.send_response(404); self.end_headers(); return
    17.         subprocess.run(['cec-client', '-s', '-d', '1'],
    18.                        input=cmd.encode(), timeout=10)
    19.         self.send_response(200); self.end_headers()
    20.         self.wfile.write(b'ok')
    21.     def log_message(self, *a):
    22.         pass
    23. HTTPServer(('0.0.0.0', 8099), H).serve_forever()
    複製代碼

    加一個權杖檢查,不要讓內網任何人都能控制你的電視。

    HA 這邊用 rest_command
    1. rest_command:
    2.   tv_on:
    3.     url: "http://192.168.1.60:8099/on"
    4.     method: POST
    5.     headers:
    6.       X-Token: !secret cec_token
    7.   tv_off:
    8.     url: "http://192.168.1.60:8099/off"
    9.     method: POST
    10.     headers:
    11.       X-Token: !secret cec_token
    複製代碼

    比 shell_command 好:不依賴 HA 容器裡有沒有 ssh、
    錯誤訊息清楚、而且可以加驗證。



    CEC 的限制(要有心理準備)


    • 各廠牌實作不一致 —— 同樣的指令在不同電視上行為可能不同
    • 有些功能只有單向 —— 可以開機但不知道現在是開是關
    • 會有意外的連動 —— 關電視的時候可能把音響也一起關了
    • HDMI 線材品質會影響 —— 便宜的線可能沒接 CEC 那條腳位
    • 切換器 / 分配器常常會斷掉 CEC


    所以我的建議是


    • 有 ADB 或官方整合就用那個,CEC 當備案
    • CEC 適合「只想要開關機」的簡單需求
    • 舊電視沒有別的辦法時才用


    路線三:紅外線(最後手段)

    用萬用紅外線遙控器(Broadlink、或 ESP32 + IR 模組)學碼。

    優點:什麼電視都能用。

    缺點


    • 完全單向 —— 不知道電視現在是開是關
    • 要對準(或者裝在電視附近)
    • 切換輸入之類的多步驟操作容易失步


    補救單向問題的方法


    • 配一個功率監控插座(電視開著功率明顯不同)
    • 或者一個光敏電阻貼在電視的電源指示燈上

    1. template:
    2.   - binary_sensor:
    3.       - name: 電視開著
    4.         unique_id: tv_is_on
    5.         state: >
    6.           {{ states('sensor.tv_power') | float(0) > 30 }}
    7.         delay_off: "00:00:30"
    複製代碼

    有了這個之後,紅外線的「切換」就可以變成「確保開/關」
    1. script:
    2.   ensure_tv_on:
    3.     sequence:
    4.       - if:
    5.           - condition: state
    6.             entity_id: binary_sensor.電視開著
    7.             state: "off"
    8.         then:
    9.           - action: remote.send_command
    10.             target: {entity_id: remote.ir_blaster}
    11.             data:
    12.               device: tv
    13.               command: power
    14.           - wait_template: >
    15.               {{ is_state('binary_sensor.電視開著','on') }}
    16.             timeout: "00:00:20"
    複製代碼

    實用的自動化

    看電視時自動調燈
    1. alias: 看電視調燈
    2. triggers:
    3.   - trigger: state
    4.     entity_id: binary_sensor.電視開著
    5.     to: "on"
    6.     for: "00:02:00"
    7. conditions:
    8.   - condition: sun
    9.     after: sunset
    10. actions:
    11.   - action: light.turn_on
    12.     target: {entity_id: light.living_room_main}
    13.     data: {brightness_pct: 25, transition: 5}
    14.   - action: light.turn_on
    15.     target: {entity_id: light.screen_bias}
    16.     data: {brightness_pct: 12, color_temp_kelvin: 6500}
    17. mode: single
    複製代碼

    太晚了提醒
    1. alias: 看太晚提醒
    2. triggers:
    3.   - trigger: time
    4.     at: "23:30:00"
    5. conditions:
    6.   - condition: state
    7.     entity_id: binary_sensor.電視開著
    8.     state: "on"
    9. actions:
    10.   - action: media_player.volume_set
    11.     target: {entity_id: media_player.tv}
    12.     data: {volume_level: 0.15}
    13.   - action: script.smart_announce
    14.     data:
    15.       area: 客廳
    16.       message: 已經十一點半了
    17. mode: single
    複製代碼

    降低音量比直接關掉溫和多了,而且不會被家人討厭。)

    ---

    我家的電視是 Android TV,所以用 ADB 整合,功能最完整。

    但我還是留了一個紅外線遙控器的備案
    因為 ADB 整合偶爾會在電視系統更新後失效。

    任何單一控制路徑都會有失效的一天,留個備案比較安心。
    您需要登入後纔可以回帖 登入 | 立即註冊

    本版積分規則

    Archiver|手機版|惟家的智能論壇

    GMT+8, 2026-9-24 12:12 , Processed in 0.080027 second(s), 24 queries .

    快速回覆 返回頂部 返回列表