星路

追寻那一缕星光,在漆黑夜晚前行

0%

【插件】Home Assistant通用定时器(升级版)

为了定期让家里暗卫的排风扇“开启-关闭-开启”循环工作,保证暗卫的排风时间,把之前的插件完善了下,顺便优化了一下代码结构,并加入了配置项、服务调用方法,嗯嗯,看起来更像一个标准插件了。


0. 功能说明

  • 支持多个定时任务
  • 可定义开/关/循环操作
  • 自动加载设备列表,无需额外配置
  • 采用看起来很厉害的环形定时队列
  • 可记忆设备上次设置的定时时间
  • 任务列表可查看正在执行的任务
  • 支持调用自定义服务,并可插件服务设置(2019-08-27新增)
  • 支持设置外部操作中断循环任务(2019-08-27新增)

    新手插件,可能存在未知的bug,使用本插件有风险!


1. 环境

  • Ubuntu 18.04 + HA 0.76.1

2. 过程

2.1. 配置项

  • configuration.yaml
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    #{HA配置目录}/configuration.yaml
    ```yaml
    # 完整版
    common_timer:
    domains: # 筛选设备(component)类型
    - light
    - automation
    - switch
    - script
    - input_boolean
    exclude: # 排除设备,使用entity_id
    - light.test
    pattern: '[\u4e00-\u9fa5]+' # >>注意:默认筛选friendly_name包含中文的设备,如果不筛选,设置为'.*'
    name: ct_control_panel # 控制面板的名称,需英文。如果有自定义分组页面,需把对应的group,例如goup.ct_control_panel加到分页
    friendly_name: 通用定时器 # 控制面板别名
    ratio: 5 # 时间比例,只用于周期任务:开⇌关[1:x]表示开状态设置1分钟,则关状态x分钟;关⇌开[1:x]表示关状态设置1分钟,则开状态x分钟
    info_panel:
    name: ct_info_panel # 任务列表面板名称,需英文。如果有自定义分组页面,需把对应的group,例如group.ct_info_panel加到分页
    friendly_name: 定时任务列表 #任务面板别名
    info_num_min: 1 # 任务列表面板常驻显示最小行
    info_num_max: 10 # 任务列表面板常驻显示最大行。注:如果最大最小设置一致,则常驻显示
    linked_user: common_timer_linked_user # 插件关联用户名,由插件自动创建,用于解决控制需要权限问题
    interrupt_loop: False # 外部操作是否中断循环任务

    默认配置

    如果只设置common_timer:,会默认按上面的样板配置进行设置。

    lovelace界面

    lovelace界面下任务列无法动态显示,info_num_min、info_num_max请设置一致。

代码内置配置

目前代码内置固定配置(以后再分离做可配置的),初始化会增加以下entity,请确保名称不会冲突。

  1. input_select.ct_domain: 用于选择设备类型
  2. input_select.ct_entity: 设备
  3. input_select.ct_operation: 操作类型
  4. input_text.ct_duration: 输入定时
  5. input_boolean.ct_switch: 开关按钮
  6. sensor.ct_record_x: 任务列表记录行
  • group.yaml(根据实际情况配置)
1
2
3
4
5
6
7
8
#{HA配置目录}/group.yaml
#参考
default_view:
view: yes
icon: mdi:home
entities:
- group.ct_control_panel
- group.ct_info_panel

分组

插件会生成group.ct_control_panel、group.ct_info_panel(具体名称通过配置设置),如果自定义过group.yaml的分组分页,需要配置放到要显示的分页里。

  • lovelace界面配置样例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
views:
- cards:
- entities:
- input_select.ct_domain
- input_select.ct_entity
- input_select.ct_operation
- input_text.ct_duration
- input_boolean.ct_switch
show_header_toggle: false
title: 通用定时器
type: entities
- entities: # 按任务列表面板常驻显示列数x列设置sensor.ct_record_0~sensor.ct_record_{x-1}
- sensor.ct_record_0
- sensor.ct_record_1
- sensor.ct_record_2
- sensor.ct_record_3
- sensor.ct_record_4
- sensor.ct_record_5
- sensor.ct_record_6
- sensor.ct_record_7
- sensor.ct_record_8
- sensor.ct_record_9
show_header_toggle: false
title: 定时任务列表
type: entities
badges: []
title: common_timer

注意

lovelace界面下任务列无法动态显示,info_num_min、info_num_max请设置一致。

2.2. 修改官方组件

本插件需要对官方的input_select、input_text、input_boolean组件进行修改。注意:新版本插件可忽略此步骤。

  • input_select.py

    1
    2
    3
    4
    5
    6
    #{HA安装目录}/components/input_select.py
    #……省略……#
    def async_setup(hass, config):
    """Set up an input select."""
    component = hass.data[DOMAIN] = EntityComponent(_LOGGER, DOMAIN, hass)
    #……省略……#
  • input_text.py

    1
    2
    3
    4
    5
    6
    #{HA安装目录}/components/input_text.py
    #……省略……#
    def async_setup(hass, config):
    """Set up an input text box."""
    component = hass.data[DOMAIN] = EntityComponent(_LOGGER, DOMAIN, hass)
    #……省略……#
  • input_boolean.py

    1
    2
    3
    4
    5
    6
    #{HA安装目录}/components/input_boolean.py
    #……省略……#
    async def async_setup(hass, config):
    """Set up an input boolean."""
    component = hass.data[DOMAIN] = EntityComponent(_LOGGER, DOMAIN, hass)
    #……省略……#

修改目的

把官方的几个input_xxx component修改一下,以便保存EntityComponent到全局变量hass.data[DOMAIN],插件初始化需要调用。

2.3. 配置

  • common_timer插件(github下载
    1
    2
    3
    #把common_timer目录放到custom_components下,包含2个文件。
    #{HA配置目录}/custom_components/common_timer/__init__.py
    #{HA配置目录}/custom_components/common_timer/services.yaml

其它改动

梳理了一遍代码,增加了塑料英文注释。


3. 新版本优化部署说明

修改安装目录下官方的input_select、input_text、input_boolean组件代码,当HA升级后会被覆盖又要重新修改。另外,使用docker方式部署(比如hassio),一般只映射配置目录,修改安装目录存在难度。因此新版本插件已经将input_select、input_text、input_boolean打包进来,如Home Assistant后续版本有对以上三个组件更新,可按以下方法进行同步更新:

  1. 找到对应组件文件,有两种方法:
  • 在HA安装目录下components文件夹,docker部署可以使用docker cp [容器id]:/usr/src/app/homeassistant/components [宿主机目录]复制components文件夹处理(注意不同容器安装目录可能不同,可以先进入容器使用find / -name homeassistant定位安装目录)
  • 去官方github下载相应版本releases包解压获取
  1. 拷贝组件到[HA配置目录]/custom_components目录下
  2. 修改组件py文件(以input_select为例,旧版本HA是input_select.py,新版本HA是input_select文件夹的__init__.py),将async def async_setup(hass, config):里的 component= EntityComponent(_LOGGER, DOMAIN, hass)=>component = hass.data[DOMAIN] = EntityComponent(_LOGGER, DOMAIN, hass)

Tips

同名组件会优先使用自定义组件目录(custom_components)下的组件。


4. 小结

  • 难点1,考虑日常应用,设置了人工介入操作则会中断周期任务,需要区分是插件控制设备还是别的地方控制。
  • 难点2,配置项有一些验证设置,都是参考其他插件来设置,具体验证过程还不了解。
  • 难点3,任务列表的记录行,考虑很久采取sensor来展示,但受限于不了解前端,样式暂无法进一步优化。
  • 找到了HA直接更改state的方法,但设备实际状态的控制还是需要通过调用service才能。