Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save willwhui/7cd33c82853fc0d9a44852c3724842c5 to your computer and use it in GitHub Desktop.
Save willwhui/7cd33c82853fc0d9a44852c3724842c5 to your computer and use it in GitHub Desktop.
在haas on Raspberry 上设置一个random sensor触发的alert及automation
@willwhui
Copy link
Author

willwhui commented Oct 16, 2017

random sensor相关:

sensor:
  - platform: yr   <-----------默认的天气,不用管它
  - platform: random <-----新建的random sensor从这里开始
    name: random 1
    minimum: 0
    maximum: 100

alert相关:

https://home-assistant.io/components/alert/ 其中写道

  • The alert component, 看起来像是对通知类型的automaiton rule进行封装的组件
  • alert接收bool类型的 sensor components 的变化通知
  • 如果想要检测一个变化的数值范围(比如低温检测),需要利用"Template Binary Sensor"这种component,并且需要用到value_template
  • 如果最终想要触发一个短信类的通知,需要利用group notification来对手机号做个包装(待细究)

要用到tamplate

https://home-assistant.io/docs/configuration/templating/

要理解state object

https://home-assistant.io/docs/configuration/state_object/
state object,就是hass的state machine
各个entity将state写入到state object里面,形成一个以state为根的对象模型
states.component.name
也就是
states.entityID

要用到component notifiy

https://home-assistant.io/components/notify/

要用到component binary sensor

https://home-assistant.io/components/binary_sensor/
其中的 Template binary Sensor:
https://home-assistant.io/components/binary_sensor.template/

@willwhui
Copy link
Author

willwhui commented Oct 22, 2017

先根据random sensor发送一个Persistent notification (此条基于hass.io,后来玩不转,改原生hass了)

参照https://home-assistant.io/docs/automation/editor/ 利用hass.io的automation editor来编写一个规则
其中用到的Persitent_notification的定义见这里https://home-assistant.io/components/persistent_notification/
“用于在前端创建一个必须由用户消除的通知信息”

创建完成之后,得到的配置文件内容如下:

- action:
  - data:
      message: sensor value greater than 10
    service: persistent_notification.create
  alias: Random Automation  <------ 这个字符串我在editor里面是设置成为整个automation的name的,这里却被叫做alias
  condition: []
  id: '1508639450841'
  trigger:
  - above: '10'
    entity_id: sensor.random_1
    platform: numeric_state

乍一看格式相当之乱,不好理解。
仔细看有一定规律:每一个缩进级别都是以 '-'开头的,比如
aciton, condition, id, trigger是同一个级别的
action下面的data, service是同一个级别的

再仔细一看,它是倒序写出的:
按照官方文档的一个rule的顺序,应该是:
trigger, condition, aciton,尝试改写一下:

- id: '1508639450841'
  alias: Random Automation  <------ 这个字符串我在editor里面是设置成为整个automation的name的,这里却被叫做alias
  trigger:
  - platform: numeric_state
    entity_id: sensor.random_1
    above: '10'
  condition: []
  action:
  - service: persistent_notification.create
    data:
      message: sensor value greater than 10

这样就正常多了,但不知道实现这个editor的人为什么不。
对上面配置的解释,见下文:https://gist.github.com/willwhui/7cd33c82853fc0d9a44852c3724842c5#gistcomment-2240713

可以工作,但是因为系统时间不太对头,工作得不正常。求助无应答:

https://community.home-assistant.io/t/help-for-date-and-time/30218/3

@willwhui
Copy link
Author

willwhui commented Oct 23, 2017

根据random sensor 建立一个 binary sensor

binary_sensor:           # <---------- component type
  - platform: template # <---------- a kind of platform
    sensors:                #<----------- this kind "template binary sensor" of sensors
      randome_gt_10:       #<----------- a particular sensor
        friendly_name: "A random value greater than 10"
        # 以下2种写法均可,注意:省掉 " | float "是不行的,貌似系统会将字符串内码直接用作比较
        value_template: "{{ states.sensor.random_1.state | float > 10 }}"
        value_template: "{{ states('sensor.random_1') | float > 10 }}"

重新加载core configuration,或者干脆重启hass之后,可见正常工作。
在前端界面重启的方法:service里面有个homeassistant,有个restart可以call

@willwhui
Copy link
Author

willwhui commented Oct 23, 2017

建一个notify

Notify的解释在这里: https://home-assistant.io/components/notify/

The notify component makes it possible to send notifications to a wide variety of platforms.

创建一个notify组件后,这个组件一般用来作为服务被调用(手工的或者通过自动化规则)

建一个Twitter Notification: https://home-assistant.io/components/notify.twitter/

notify:
  - name: twitter_wang3an
    platform: twitter
    consumer_key: !secret twitter_consumer_key
    consumer_secret: !secret twitter_consumer_secret
    access_token: !secret twitter_access_token
    access_token_secret: !secret twitter_access_token_secret

按照说明生成配置,比较简单。

备注:
在创建twitter notify之后,发现系统时间滞后的问题导致无法正常调用twitter api:会被twitter服务器拒绝,因为和服务器时间相差太大。
在hass.io中怎么也改不了时间,于是改为重新搭建一个基于raspbing+python虚拟+hass的系统。
在搭建成功之后发现系统时间滞后的原因是无法访问互联网上的ntp时间服务器,通过将本地路由器设置为时间服务器,并以它为更新点的方式,解决了时间问题。参见:https://gist.github.com/willwhui/acc6a0ab8fc2f78040f1f822d62a5363#gistcomment-2238895

@willwhui
Copy link
Author

willwhui commented Oct 26, 2017

用alert把(包装了random sensor的)binary sensor 和(上面的twitter)notify连接起来

alert:
  test_twitter_wang3an:
    name: Test twitter wang3an <--------------- 这个名字也是发送到notify的消息,对应到twitter就是twitter内容
    done_message: The random value >= 50 now.
    entity_id: binary_sensor.random_change
    state: 'on'
    repeat: 
      - 1
      - 1
      - 1
      - 30
    can_acknowledge: True
    skip_first: False
    notifiers:
      - twitter_wang3an

@willwhui
Copy link
Author

willwhui commented Oct 27, 2017

用automation来触发twitter前需要了解的东西

automation概念:https://home-assistant.io/docs/automation/
在examples (https://home-assistant.io/docs/automation/examples/)中,如果能主动解释以下几点就好了:

automation:
# Turns on lights 1 hour before sunset if people are home
# and if people get home between 16:00-23:00
  - alias: 'Rule 1 Light on in the evening'  <---------- rule名字
    trigger:
      # Prefix the first line of each trigger configuration
      # with a '-' to enter multiple
      - platform: sun  <----------------------- platform的名字(类型)是关键:决定了后续的几个标签(event,offset)说明见后文
        event: sunset
        offset: '-01:00:00'
      - platform: state
        entity_id: group.all_devices
        to: 'home'
    condition:
      # Prefix the first line of each condition configuration
      # with a '-'' to enter multiple
      - condition: state <------------------- condition的名字(类型)是关键:决定了后续的几个标签(entity_id, stat)说明见后文
        entity_id: group.all_devices
        state: 'home'
      - condition: time
        after: '16:00:00'
        before: '23:00:00'
    action:
      service: homeassistant.turn_on    <---- service-domain.service-name 但service是怎么注册上去的呢?
      entity_id: group.living_room      <----- 应该是service对应的参数,由service-domain.service-name决定,但说明在哪里?

# Turn off lights when everybody leaves the house
  - alias: 'Rule 2 - Away Mode'
    trigger:
      platform: state
      entity_id: group.all_devices
      to: 'not_home'
    action:
      service: light.turn_off
      entity_id: group.all_lights

# Notify when Paulus leaves the house in the evening
  - alias: 'Leave Home notification'
    trigger:
      platform: zone
      event: leave
      zone: zone.home
      entity_id: device_tracker.paulus
    condition:
      condition: time
      after: '20:00'
    action:
      service: notify.notify     <------- 看起来有个notify domain下的service name是"notify",真这样的话,可以不这么举例子吗?
      data:
        message: 'Paulus left the house'

重点:

@willwhui
Copy link
Author

willwhui commented Oct 27, 2017

action中的普通service

参见https://home-assistant.io/docs/automation/action/
及其中提到的The action part follows the script syntax

调用规则:貌似比较简单?

automation:
# Turns on lights 1 hour before sunset if people are home
# and if people get home between 16:00-23:00
  - alias: 'Rule 1 Light on in the evening'
    trigger:
      (略)
    condition:
      (略)
    action:
      service: homeassistant.turn_on    <---- service-domain.service-name
      entity_id: group.living_room      <----- 影响的entiy

# Turn off lights when everybody leaves the house
  - alias: 'Rule 2 - Away Mode'
    trigger:
      (略)
    condition:
      (略)
    action:
      service: notify.notify    <---- service-domain.service-name,notify类型的service没有必要指定entity_id
      data:     <----- 这是个需要接受的数据,最终会被封装成json
        message: 'Paulus left the house'   <------ 一个或多个key-value

问题:

  • service domain和service name看起来就是在前端界面的service页面中查看 http://ip:8123/dev-service
  • 注册服务的机制还不太清楚,比如alert, notify自动注册了服务
  • 服务需要接受的数据定义,看起来是要到servie组件的说明里面去看

@willwhui
Copy link
Author

willwhui commented Oct 27, 2017

action中的特殊service:场景(scene)

参见:https://home-assistant.io/components/scene/

You can create scenes that capture the states you want certain entities to be.

不知道为什么要用'capture'这个单词,难道是美语俗语?
根据上下文的意思和实际用途,这句话是这个意思:
“你可以创建一些场景,将特定的实体(entities,虚拟的或者真实的设备)设定到指定的状态。
类似于”

You can create scenes that set up the states you want certain entities to be.

例子:

scene:
  - name: Romantic   <--------- 一个场景name
    entities:     <--------- 对应的实体们开始了
      light.tv_back_light: on    <--------- 单独设置此实体的state
      light.ceiling:        <--------- 设置此实体的多个状态
        state: on      <--------- state
        xy_color: [0.33, 0.66]  <-------- attribute
        brightness: 200  <-------- attribute

调用规则:貌似也很简单?

例子:

automation:
  trigger:
    (略)
  action:
    service: scene.turn_on   <------- 或者:scene.turn_off,其实也可以理解为 domain.name?这样也就不是特殊的东西了
    entity_id: scene.romantic <------- 影响的entity

@willwhui
Copy link
Author

willwhui commented Oct 27, 2017

用automation来触发twitter

- alias: 'Random sensor trigger twitter'
  trigger:
    platform: state
    entity_id: binary_sensor.random_change
    to: "on"
  action:
    service: notify.twitter_wang3an
    data:
      message: A random value less than 50 triggered this.

像上面这样写,只触发一次就没动静了,为什么呢?
看日志:

Oct 27 18:41:55 raspberrypi hass[941]: 2017-10-27 18:41:55 INFO (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=sensor.random_1, old_state=<state sensor.random_1=84; icon=mdi:hanger, friendly_name=random 1 @ 2017-10-27T18:41:24.308602+08:00>, new_state=<state sensor.random_1=27; icon=mdi:hanger, friendly_name=random 1 @ 2017-10-27T18:41:55.307233+08:00>>
^---- 上面这句是说:random值变了
Oct 27 18:41:55 raspberrypi hass[941]: 2017-10-27 18:41:55 INFO (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=binary_sensor.random_change, old_state=<state binary_sensor.random_change=off; friendly_name=A random value less than 50 @ 2017-10-27T18:38:18.315139+08:00>, new_state=<state binary_sensor.random_change=on; friendly_name=A random value less than 50 @ 2017-10-27T18:41:55.316416+08:00>>
^---- 上面这句说:binary_sensor.random_change的值变成on了(符合预期)
Oct 27 18:41:55 raspberrypi hass[941]: 2017-10-27 18:41:55 INFO (MainThread) [homeassistant.components.automation] Executing Random sensor trigger twitter
^---- 上面这句说:执行automation中(符合预期)
Oct 27 18:41:55 raspberrypi hass[941]: 2017-10-27 18:41:55 INFO (MainThread) [homeassistant.core] Bus:Handling <Event logbook_entry[L]: entity_id=automation.random_sensor_trigger_twitter, name=Random sensor trigger twitter, domain=automation, message=has been triggered>
^---- 写日志文件
Oct 27 18:41:55 raspberrypi hass[941]: 2017-10-27 18:41:55 INFO (MainThread) [homeassistant.helpers.script] Script Random sensor trigger twitter: Running script
^---- 运行scrip中
Oct 27 18:41:55 raspberrypi hass[941]: 2017-10-27 18:41:55 INFO (MainThread) [homeassistant.helpers.script] Script Random sensor trigger twitter: Executing step call service
^---- 可以call service了(符合预期)
Oct 27 18:41:55 raspberrypi hass[941]: 2017-10-27 18:41:55 INFO (MainThread) [homeassistant.core] Bus:Handling <Event call_service[L]: service=twitter_wang3an, domain=notify, service_data=message=A random value less than 50 triggered this., service_call_id=1971673456-3>
^---- bus处理事件:调用service=twitter_wang3an(符合预期)
Oct 27 18:41:56 raspberrypi hass[941]: 2017-10-27 18:41:56 ERROR (Thread-5) [homeassistant.components.notify.twitter] Error 403: [{'message': 'Status is a duplicate.', 'code': 187}]
^---- 返回错误:Status is a duplicate。莫非是twitter防止灌水用的?
Oct 27 18:41:56 raspberrypi hass[941]: 2017-10-27 18:41:56 INFO (MainThread) [homeassistant.core] Bus:Handling <Event service_executed[L]: service_call_id=1971673456-3>
^---- 调用结束

信息里面有一个:
Error 403: [{'message': 'Status is a duplicate.', 'code': 187}]
原来是twitter干的:防止重复发送
参见:https://twittercommunity.com/t/status-is-a-duplicate/16928

修改一下触发后发送的内容:

- alias: 'Random sensor trigger twitter'
  trigger:
    platform: state
    entity_id: binary_sensor.random_change
    to: "on"
  action:
    service: notify.twitter_wang3an
    data:
      message: A random value less than 50 triggered this.

@willwhui
Copy link
Author

willwhui commented Nov 2, 2017

小坑

  • 你可以在alias的平级增加id: 1508639450841这样一行(数字任意,避免和现有id重复)
    这样就可以在hass的前端的configuration模块中,被automation模块识别列出了
    但是:
    一旦你对任何一个automaiton模块进行修改和保存,那么automations.xml中的所有内容都会被重写。
    功能虽正常,但注释全被销毁,语句顺序也发生一定的变化。
    所以还是别这样搞了。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment