之前的教程基本都是面向初学者,我相信读者中不乏有代码好手,更有对 HASS 已经研究颇深的朋友。本篇简短教程姑且一步登天,和各位程序猿(媛)讨论如何活用 HA 中强大的 command-line 组件以快速实现期望功能。

初学乍练

HA 之中接入一个设备往往需要经由“平台——组件”这一流程,过程十分繁琐,有时我们只是想运行一些简单的 Python 代码,或者只是想测试一下效果,因此完全没有必要特别去创建平台。

HA 为此特别提供了名为 “Command Line” 的传感器组件,这个强无敌的组件能让你在 HA 中运行任何支持该平台的命令,还可以显示输出结果。

同其他传感器组件一样,使用 Command-Line,只需在configuration.yaml中添加如下配置:

sensor:
  - platform: command_line
    command: SENSOR_COMMAND

HA 官方给出了一些简单的应用例子,我们不妨来看一下:

显示 CPU 温度

我们知道在树莓派终端中输入 cat /sys/class/thermal/thermal_zone0/temp 指令便可以获取 CPU 温度的千倍值,想让 HA 运行指令只需将其写入配置文件中。

sensor:
  - platform: command_line
    name: CPU Temperature
    command: "cat /sys/class/thermal/thermal_zone0/temp"
    unit_of_measurement: "°C"
    value_template: '{{ value | multiply(0.001) }}'

重启 HA 后,HA 便会添加一个 sensor.CPU_Temerature 的传感器,之后就和其他组件一样,可以对其随意个性化配置。

抓取 HA 最新版本信息

HA 的包上传在 PyPI 上,自然版本信息也包括在内,通过抓取便可轻易获得。

sensor:
  - platform: command_line
    command: python3 -c "import requests; print(requests.get('https://pypi.python.org/pypi/homeassistant/json').json()['info']['version'])"
    name: HA release

同理,HA 内会生成名为 sensor.HA_release 的传感器组件。

该例中,我们简单涉及了一些数据抓取的技巧,在 HA 内其实提供了一个特别的用于数据抓取的组件:Scrape Sensor,这里也简单介绍一下。


渐入佳境

Scrape Sensor 组件顾名思义是用来抓取(刮削)数据的,但是实测下来,效果有限。

基本配置如下:

sensor:
  - platform: scrape
    resource: https://home-assistant.io
    select: ".current-version h1"

稍有前端基础的朋友应该很快就可以明白其意,最后的 select 可以设定需要抓取的类或者是对象。

比如你是 IFTTT 的重度患者,想要在 HA 前端显示所用的 Applets 的情况,就可以这样配置:

sensor:
  - platform: scrape
    resource: http://status.ifttt.com/
    name: IFTTT status
    select: '.component-status'

摸清楚原理,我们很快就会意识到 Scrape 只能用来刮削结构简单的静态网页,一旦网页稍微复杂一些,数据根本无法被 select 出。


小试牛刀

说了那么多官方示例,现在轮到我们自己动手实践了。

Commadn Line 的本质还是辅助性组件,想要指望其运行复杂的代码显然是不切实际的。个人认为该组件的重点在于信息展示上,因此也不难理解官方给出的例子都与数据抓取多多少少有一些关系。

HA 是建立在 Python 之上的,配合各类库的使用,Python 的数据抓取能力十分强大。Command Line 既然是 HA 里的小终端,那么自然支持运行外置代码文件。

作为长在海边的孩子,自己对潮汐情况比较关注。HA 的部分天气组件提供了潮汐数据,但涉及汉化、挑选和适配传感器,操作起来十分麻烦。于是我想到直接写一小段 Python 代码抓取潮汐数据。

from bs4 import BeautifulSoup
import requests
import time

#日期格式化
d = time.strftime("%Y-%m-%d", time.localtime())

#港口代码,前往 http://www.chinaports.com/chaoxi/ 取得
port_code = 122
port_code = str(port_code)

#获取数据
html = requests.get("http://www.chinaports.com/chaoxi/" + d + "/" + port_code).content
soup = BeautifulSoup(html, "html5lib", from_encoding="utf-8")
result = soup.find("table", class_="tidaltable")
detail = result("td")

#打印数据
count = len(detail)
if count == 8:
    first_height = int(detail[5].string)
    second_height = int(detail[6].string)
    if first_height > second_height:
        print ("涨潮:" + detail[1].string + " " + detail[3].string + ";退潮:" + detail[2].string)
    else:
        print ("涨潮:" + detail[2].string + " " + ";退潮: " + detail[1].string + " " + detail[3].string)
else:
    first_height = int(detail[6].string)
    second_height = int(detail[7].string)
    if first_height > second_height:
        print ("涨潮:" + detail[2].string + " " + detail[4].string + ";退潮:" + detail[1].string + " " + detail[3].string)
    else:
        print ("涨潮:" + detail[1].string + " " + detail[3].string + ";退潮:" + detail[2].string + " " + detail[4].string)

该段代码使用了 BeautifulSoup4 库,比起 Scrape Senso 抓取、整理数据的能力自然强多了。

然后将该 tide.py 文件存放在任意文件夹内,再配置 configuration.yaml 文件即可:

#潮汐
sensor:
  - platform: command_line
    name: Tide
    command: "python3 /home/pi/Downloads/tide.py"

#个性化
homeassistant:
    customize:
        sensor.tide:
        friendly_name: 潮汐
        icon: mdi:waves

重启 HA,潮汐时间就出现在主界面了:

null

看过这个小例子,相信各位程序员已经摩拳擦掌了。除了 Sensor 以外,Command-Line 还支持 Switch,Cover 等等 platform,详见组件页。由于精力有限,我没有测试其他语言的代码在 Command Line Sensor 中的运行情况,其它 platform 也还未认真钻研。可以肯定的是,该组件大大提升了 HA 的广度和深度,令人不禁想好好玩弄一番呢~

期待各位派友运用 Command Line 实现新颖的功能,欢迎留言分享与讨论。


作者的话

距离我发布本系列首篇文章至今已经快半年了,系列至今已有 10 篇教程。无独有偶,JailbreakHum在 《少数派季度作者颁奖礼开场发言》所阐述的『内容调整』的观点恰恰与我的初衷十分契合。可以说从一开始,我就在整个系列中尽量保证内容的入门性,也在现实中帮助了很多派友成功搭建系统。

在和派友的互动中我意识到碍于英文水平的局限,很多人无法进一步地享受 Home Assistant 带来的便利。鉴于此,我个人独立制作了一份更接地气的 中文文档 ,目前仍处于雏形阶段,还在快马加鞭中,希望可以帮助到更多的人,欢迎大家阅读+收藏。

良好的体验需要良性的互动维持,为了保持版面的整洁,请大家不要在系列所有文章下方评论区 PO 整段的错误代码。遇到问题请至『维护答疑篇』集中评论。