Homeassitant 接入海信电视

2025年5月10日 · 645 字 · 2 分钟

ha

需求

家里的电视是海信 65E55H,无法接入米家 APP,现在想把它接入 Homeassistant。支持下列功能:

  1. 开机
  2. 关机
  3. 定时对屏幕截屏,在 Homeassistant 显示。

前置条件

  • 树莓派 192.168.1.66:接电视(HDMI)并负责 HDMI-CEC 开机 + ADB 控制(关机)
  • Home Assistant 运行在 192.168.1.188(Docker 容器)

解决方案总览

通过在树莓派上运行一个轻量的 HTTP API 接口(例如 Flask),让 Home Assistant 调用 HTTP 请求,来控制:

  • HDMI-CEC 开机
  • ADB 关机
  • ADB 定时截屏,缩放。Home Assistant 使用 iframe 访问图片。

树莓派上工程

.
├── app.py
├── docker-compose.yml
├── Dockerfile
├── requirements.txt
├── static
│   └── tv_screen.png
├── templates
│   └── show_tv.html
└── tv.sh

app.py

from flask import Flask, render_template
import subprocess
import os

app = Flask(__name__)

@app.route("/tv/on")
def tv_on():
    subprocess.run("echo 'on 0.0.0.0' | cec-client -s -d 1", shell=True)
    return "TV turned on"

@app.route("/tv/off")
def tv_off():
    subprocess.run("adb connect 192.168.1.15:5555 && adb shell input keyevent 26", shell=True)
    return "TV turned off"

@app.route("/tv/html")
def show_tv():
    return render_template("show_tv.html")    

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=9527)

docker-compose.yml

services:
  home:
    build: .
    environment:
      - TZ=Asia/Shanghai
      - FLASK_ENV=production  # 如果需要,可以设置环境变量      
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    restart: always
    devices:
      - "/dev/cec0:/dev/cec0"        # 映射主机的 cec0 设备
      - "/dev/cec1:/dev/cec1"        # 映射主机的 cec1 设备
    volumes:
      - "/root/.android:/root/.android"  # 映射 ADB 配置
      - .:/app
    network_mode: "host"
    command: python -u app.py

Dockerfile

FROM python:3.9-slim

RUN apt-get update && apt-get install -y cec-utils adb \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /app
COPY requirements.txt /requirements.txt
RUN pip3 install --user -r /requirements.txt

tv.sh

#!/bin/bash

# 设置出错立即退出
set -e

# ADB 连接电视,截图保存到本地
adb connect 192.168.1.15:5555
adb shell screencap -p /sdcard/screen.png
adb pull /sdcard/screen.png ./screen_raw.png

# 压缩图片(分辨率缩小为原来的 1/8)
ffmpeg -y -i ./screen_raw.png -vf "scale=iw/4:ih/4" ./screen.png

# 移动图片到 Flask 静态目录
mv ./screen.png ./static/tv_screen.png

# 清理中间文件
rm -f ./screen_raw.png
# crontab -l
*/30 * * * * cd /root/data/docker/home_auto && /root/data/docker/home_auto/tv.sh >> /root/data/docker/home_auto/tv.log 2>&1

templates/show_tv.html

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="refresh" content="300 ">
  <title>Hisense TV Screenshot</title>
  <style>
    html, body {
      margin: 0;
      padding: 0;
      background: transparent;
    }
    img {
      width: 100vw;
      height: 100vh;
      object-fit: contain;
      display: block;
    }
  </style>
</head>
<body>
  <img src="{{ url_for('static', filename='tv_screen.png') }}?t={{ ts }}" />
</body>
</html>

HomeAssistant 配置

configuration.yaml

rest_command:
  tv_turn_on:
    url: "http://192.168.1.66:5005/tv/on"
  tv_turn_off:
    url: "http://192.168.1.66:5005/tv/off"

添加卡片

type: vertical-stack
cards:
  - type: iframe
    url: http://192.168.1.66:9527/tv/html
    aspect_ratio: "1280:720"
    title: 海信电视
  - type: horizontal-stack
    cards:
      - show_name: true
        show_icon: true
        type: button
        name: 海信 65E55H 开机
        icon: mdi:television
        tap_action:
          action: call-service
          service: rest_command.tv_turn_on
        show_state: false
      - type: button
        name: 海信 65E55H 关机
        icon: mdi:television-off
        tap_action:
          action: call-service
          service: rest_command.tv_turn_off