-
-
Save willwhui/7cd33c82853fc0d9a44852c3724842c5 to your computer and use it in GitHub Desktop.
在haas on Raspberry 上设置一个random sensor触发的alert及automation |
先根据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
根据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
建一个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
用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
用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'
重点:
- 对triggers的platform类型的说明:https://home-assistant.io/docs/automation/trigger/
- 对condition的类型的说明:https://home-assistant.io/docs/automation/condition/
- 参见其中的 so see that page for a full list of available conditions
- action的作用就是call service(可多个),分两种
- 普通:service:service-domain.service.name 这是由各种组件注册上去的,具体规则见下文
- 特殊:自定义的场景(scene),具体规则见下文
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组件的说明里面去看
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
用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.
小坑
- 你可以在alias的平级增加
id: 1508639450841
这样一行(数字任意,避免和现有id重复)
这样就可以在hass的前端的configuration模块中,被automation模块识别列出了
但是:
一旦你对任何一个automaiton模块进行修改和保存,那么automations.xml中的所有内容都会被重写。
功能虽正常,但注释全被销毁,语句顺序也发生一定的变化。
所以还是别这样搞了。
random sensor相关:
alert相关:
https://home-assistant.io/components/alert/ 其中写道
要用到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/