家里用的是三星的洗衣机和烘干机,买的时候为了完成时有提醒特地挑了带有「智能监控」功能的机型。然而对应的三星洗衣机的 app 几乎没法用,推送和状态更新都有问题。于是我打算自己实现一个类似的功能。

因为洗衣机和烘干机用电量比较大,通过监控用电量很容易判断出设备当前的运行状态,于是我决定用智能插座来实现这个功能。现在很多智能插座都有电量检测的功能,选择的时候要注意插座支持的最大电量,我用了 TP-Link 的 HS110,支持最多 1500 瓦的设备,对于一般的洗衣机和烘干机来说绰绰有余。和智能插座对接的系统依然是 Home Assistant,它对 HS110 的支持很好,可以方便地读出设备当前用电量。

接下来是 Home Assistant 的配置部分,主要分状态定义和自动化脚本。

为了简化我只用两种状态(空闲和运转)描述洗衣机和烘干机的状态(代码只给出了洗衣机部分,烘干机部分几乎一样):

input_select:
  washer_status:
    name: Washer Status
    options:
      - Idle
      - Running
    initial: Idle

为什么要定义状态而不是直接通过用电量判断呢?因为这些机器运转过程里会有几次几乎不用电的阶段,如果只通过用电量很容易产生错误信号,用电量配合状态持续时间才能做出更精准的判断。

接下来定义虚拟的洗衣机传感器,我们会通过自动化脚本更新这个传感器的值:

sensor:
  - platform: template
    sensors:
      washer_status:
        value_template: '{{ states.input_select.washer_status.state}}'
        friendly_name: 'Washer Status'

自动化脚本分两块,一块是检测到电量后的更新洗衣机状态为运转。这里我用了 10 瓦作为运转开始的阈值。

automation:
  - alias: Set washer active when power detected
    trigger:
    - platform: numeric_state
      entity_id: switch.hs110_washer
      value_template: '{{ state.attributes.current_power_w }}'
      above: 10
    condition:
      condition: or
      conditions:
        - condition: state
          entity_id: sensor.washer_status
          state: Idle
    action:
    - service: input_select.select_option
      data:
        entity_id: input_select.washer_status
        option: Running

另一块是设备停止运转的检测,根据不同的设备可能要进行微调。我这里设置了洗衣机用电低于 3 瓦且超过 1 分钟以上后,把状态切换成空置并通过 Twilio 发送短信通知。

automation:
  - alias: Set washer inactive
    trigger:
    - platform: numeric_state
      entity_id: switch.hs110_washer
      value_template: '{{ state.attributes.current_power_w }}'
      below: 3
      for:
        minutes: 1
    condition:
      condition: or
      conditions:
        - condition: state
          entity_id: sensor.washer_status
          state: Running
    action:
    - service: input_select.select_option
      data:
        entity_id: input_select.washer_status
        option: Idle
    - service: notify.twilio_sms
      data:
        message: Washer finished at {{ now() }}
        target:
          - 15555555555

这个脚本用了一个多月没出现误报,虽然一开始折腾一点,最后还是省了我们不少时间。

关于智能家居和 Home Assistant 的更多信息,可以参考我写的其他文章