tomassam 发表于 2019-4-27 17:12:35

多用户-房屋状态解决 - 集大成 - 基于状态机

本帖最后由 tomassam 于 2019-5-8 20:31 编辑

大家好, 一个月的学习吸收在论坛学习到很多, 发现大家对于**多用户**进出导致的系统判断家庭状态混乱, 没有提出过系统性的解决方案. 小弟现在将自己探索的方案分享给大家. 希望得到大家的review, 进行更进一步的调整.

总体而言, 我的思路是通过状态机进行系统状态改变的描述.
细节而言, 我将status_old -> status_new 的每一个规则通过automation进行了描述. 我使用了input_select这一组件进行交互. 细节问题将在帖子下方的楼层里进行描述/讨论.

谢谢大家!

====进入正文====
状态转化图参见图片, 主要分
home_status:
    options:
      - at_home# 用户在家状态, 此时系统松弛, 不进行异常检测
      - arrived# 用户进门状态(过度态), 将自动转化为 chkin 等待用户的认证
      - left # 用户出门(过度态), 将自动转化为 away_guard (一段时间后)
      - away_guard # 系统警戒状态, 一切异常(门窗, motion) 都会触发警报(小米网关的警报声)
      - abnormal # 异常状态, 出现任何和系统**当前**状态不符合的情景(HASS将播报**异常**)
      - chkin # 签入状态, 任何进门者必须双击进行认证


这几个状态


使用直觉:
1. 任何用户, 进门双击**无线开关**进行认证
2. 1用户是最后一位出门, 单击(短, mono_click) **无线开关**---告诉系统*短*时间进入警戒状态
2. 2用户不是最后一位出门, 长按(长, hold) **无线开关**---告诉系统*长*时间进入警戒状态 (因为家里还有人)

如此系统就能"知道"究竟该布防与否.

如果承认上述状态机之间的转化, 则系统运行的规律已描述完全. 只要**判定当前属于何种情景**, 添加对应的automation规则即可.
比方说, 回家播报室内天气如下


# 回家室内气候播报 (podcast)
- alias: back_home_report
initial_state: true
trigger:
    - platform: state
      entity_id: input_select.home_status
      to: 'at_home'
      for:
      seconds: 5
condition:
    condition: template
    value_template: "{{ states.binary_sensor.switch_158d000288bb36.attributes.last_action != 'hold' }}"
action:
    - service: tts.baidu_say
      data_template:
      message: "室内气候{{states('sensor.int_comfort_msg')}}, 温度{{states('sensor.temperature_158d0002ead228')}}, 湿度{{states('sensor.humidity_158d0002ead228')}}"




Q1: 为什么不用device tracker?
A1: 我的手机电池不行, 选用了emulated_hue进行回家前的关闭警戒
--
Q2: 为什么没看到该执行的自动化, 比如说警戒后播报*进入警戒状态*?
A2: 本文主要着重描述状态转化关系. (着重在验证理论的正确, 而不是理论成立后的应用, 后期会有)
---
Q3: 我需要如何部署?
A1: 如下:
a, 看懂状态转化图, 并将状态转化的自动化规则加入automations.yaml里
b, 调整configuration.yaml
添加以下代码片段(这是描述/更新/调整)的对象的declaration

# status_indicator -> its value be passed as for scene selection
input_select:
home_status:
    options:
      - at_home
      - arrived
      - left
      - away_guard
      - abnormal
      - chkin
    initial: abnormal

# 下方的components 要自行调整, 我将在下方楼层添加对应的参考链接.
# 这个是通过获取token, HA进行网关警戒状态的调节
switch:
- platform: xiaomi_gateway_alarm
    host: 192.168.0.102
    token: !secret gateway_token#gateway_token

# 这个是百度语音合成,
tts:
- platform: baidu
    # entity_id -> the speaker; 3-keys for API
    app_id: 16015220
    api_key: !secret bd_tts_api_key
    secret_key: !secret bd_tts_sec_key
    speed: 8
    #entity_id: media_player.vlc
# 这个是媒体播放器
media_player:
- platform: vlc
    #host: 127.0.0.1
# 这个是小米网关的信息(用于交互其他设备, 例如无线开关)
xiaomi_aqara:
discovery_retry: 10
gateways:
    - mac: !secret gateway_mac
      key: !secret gateway_key



emulated_hue:
type: alexa

# 文本中的secret都是我自己的密钥 存放于secrets.yaml 的信息, 请自行调整


c, 添加以下两个sensor

# status_machine for scene selection assignment
- platform: template
sensors:
    home_status:
      value_template: "{{ states.input_select.home_status.state }}"
      friendly_name: '家状态'
    button_press_mode:
      value_template: "{{ states.binary_sensor.switch_158d000288bb36.attributes.last_action }}"
      friendly_name: '按压状态'



d, 对应调整我提供yaml的传感器名字
例如, binary_sensor.door_window_sensor_158d0002897752, 修改为你的设备的名称(entity_id)
e, 调试并运行


Q4: 你用到了什么资源? 凭什么肯定不能再精简?
A4: 界定状态只用到了(无线开关), 门窗和motion sensors. 不能精简的原因: 原始方案(论坛有一个说老外离家回家判断的帖子), 只是少了无线开关. 但他只能单身汉使用, 站在门传感器的角度, 如果没有额外信息的引入, 在"门的"眼中, 他是无法分辨究竟是1st人离家 or 2nd人回家 (都对应, 原始status=at_home, 状态为门打开), 因此我们必须引入信息, 而无线开关就是我们引入信息的载体. 基于此, 得出无法精简的结论. (device tracker其实是信息某种意义上的另一存在模式)

Q5: 那你为什么不用MQTT? 不用蓝牙, 不用 device tracker?
A5: MQTT 开启我的HASS启动缓慢, 另外两个我的手机电池不好. (简单说就是不符合我的实际需求)

Q6: 我**仔细*review 你的想法, 想和你深入探讨, 怎么联系?
A6: 我的邮箱 [email protected] /或本贴

谢谢大家!
#################################################
# ----------------------------------------------#
# --- status_machine transition description --- #
# ------- (tell how a status is reached) -------#
# ----------------------------------------------#
#################################################

# --------------- BASIC TERMS ------------------#
# ~dest~   |state that input_select.home_status is assigned
# ~depart~   |state that BEFORE assignment is executed
# "initial_state: true" -- all status automation MUST be with HASS ALL the time!
# ----------------------------------------------#

# ---------------Interfact Intuition------------#
# once come back, **EACH** user should db_click to pass the auth_eval
# if leaving home, if
    # first to leave, long press to tell system wait long before *in_guard* (cuz there is others at home)
    # last to leave, click (short) to tell wait short before *in_guard* (cuz there is NO others at home)
# ----------------------------------------------#
# √ 进门 - just arrived
# 条件 # 主门(off->on) & 上一status是不在家,i.e. (away_guard | left)
# dest   | 'arrived'
# depart | 'away_guard' or 'left'# ----------------------------------------------#
- alias: just_arrived
initial_state: true
trigger:
    - platform: state
      entity_id: binary_sensor.door_window_sensor_158d0002897752
      from: 'off'
      to: 'on'
condition:
    condition: or
    conditions:
      - condition: state
      entity_id: sensor.home_status
      state: 'away_guard'
      - condition: state
      entity_id: sensor.home_status
      state: 'left'
action:
    - service: input_select.select_option
      data:
      entity_id: input_select.home_status
      option: arrived
# ----------------------------------------------#
# √ reach_check_in (before inspection)      
# 检测/签到 - checkin
# 条件 # (上一status是进门 & 停留>10s) | (出门立刻回家)         
# dest   | 'chkin'
# depart | 'arrived'
- alias: check_in
initial_state: true
trigger:
    - platform: state
      entity_id: input_select.home_status
      to: 'arrived'
      for:
      seconds: 3
    - platform: state
      entity_id: input_select.home_status
      from: 'left'
      to: 'arrived'
action:
    - service: input_select.select_option
      data:
      entity_id: input_select.home_status
      option: chkin
# ----------------------------------------------#
# √ 出门 - just_left
# 条件 # 上一status是(进门 | 在家 | chkin) &| 主门(off->on)
# dest   | 'left'
# depart | 'arrived' or 'chkin' or 'at_home'
- alias: just_left
initial_state: true
trigger:
    - platform: state
      entity_id: binary_sensor.door_window_sensor_158d0002897752
      from: 'off'
      to: 'on'
condition:
    condition: or
    conditions:
      - condition: state
      entity_id: sensor.home_status
      state: 'at_home'
      - condition: state
      entity_id: sensor.home_status
      state: 'arrived'
      - condition: state
      entity_id: sensor.home_status
      state: 'chkin'
action:
    - service: input_select.select_option
      data:
      entity_id: input_select.home_status
      option: left
# ----------------------------------------------#
# √ 离家 - really_away
# 条件 # 上一status是出门(left) & t>4min
# dest   | 'away_guard'
# depart | 'left'
- alias: really_away
initial_state: true
trigger:
    - platform: state
      entity_id: input_select.home_status
      to: 'left'
      for:
      minutes: 4
action:
    - service: input_select.select_option
      data:
      entity_id: input_select.home_status
      option: away_guard
# ----------------------------------------------#
# √ 检查 - inspection in case of ileagal intruder
# 条件 # 上一status是chkin(检测/签到) & 触发button
# 当前触发button: db_click
# dest   | 'at_home'
# depart | 'chkin'
- alias: chkin_inspect
initial_state: true
trigger:
    - platform: event
      event_type: xiaomi_aqara.click
      event_data:
      entity_id: binary_sensor.switch_158d000288bb36
      click_type: double      
condition:
    condition: state
    entity_id: sensor.home_status
    state: 'chkin'
action:
    - service: input_select.select_option
      data:
      entity_id: input_select.home_status
      option: 'at_home'
# ----------------------------------------------#
# √ 异常(外出) - abnormal (when_out)
# 条件 # 上一status是away_guard & 探测到运动
# NOTE: other like doors/windows can be added equivalently
# in form of triggers (bilateral)
# dest   | 'abnormal'
# depart | 'away_guard'
- alias: abnormal (when_out)
initial_state: true
trigger:
    - platform: state
      entity_id: binary_sensor.motion_sensor_158d00028433e7
      to: 'on'
    # add other items, all except main_gate is allowed!!
condition:
    condition: state
    entity_id: sensor.home_status
    state: 'away_guard'               
action:
    - service: input_select.select_option
      data:
      entity_id: input_select.home_status
      option: abnormal
    # - service: notify.alexia
    #   data:
    #   title: "[异常] 潜入"
    #   message: "高手潜入detected"
# ----------------------------------------------#
# √ 异常(入侵) - abnormal (ileagal_intruder)
# 条件 # 上一status是chkin & 没有签到动作
# dest   | 'abnormal'
# depart | 'chkin'
- alias: abnormal (ileagal_intruder)
initial_state: true
trigger:
    - platform: state
      entity_id: input_select.home_status
      to: 'chkin'
      for:
      seconds: 20
action:
    - service: input_select.select_option
      data:
      entity_id: input_select.home_status
      option: 'abnormal'
    # - service: notify.alexia
    #   data:
    #   title: "[异常] 入侵"
    #   message: "入侵detected"
# ----------------------------------------------#
# √ 异常(没关门) - abnormal (forget_close_door)
# 条件 # 上一status是left & forget_close_door
# dest   | 'abnormal'
# depart | 'left'
- alias: abnormal (forget_close_door)
initial_state: true
trigger:
    - platform: state
      entity_id: input_select.home_status
      to: 'left'
      for: '00:00:10'
condition:
    condition: state
    entity_id: binary_sensor.door_window_sensor_158d0002897752
    state: 'on'
    for:
      seconds: 5
action:
    - service: input_select.select_option
      data:
      entity_id: input_select.home_status
      option: 'abnormal'
    # - service: notify.alexia
    #   data:
    #   title: "[异常]没关门"
    #   message: "没关门"
# ----------------------------------------------#
# (多人)回家报备 - mate_examption
# 条件 # 上一status是left & (探测到家人运动 | 手动触发button)
# 当前判断button: db_click
# dest   | 'at_home'
# depart | 'left'
- alias: mate_examption
initial_state: true
trigger:
    - platform: event
      event_type: xiaomi_aqara.click
      event_data:
      entity_id: binary_sensor.switch_158d000288bb36
      click_type: double
condition:
    condition: or
    conditions:
      - condition: state
      entity_id: binary_sensor.motion_sensor_158d00028433e7
      state: 'on'
      - condition: state
      entity_id: sensor.home_status
      state: 'left'      
action:
    - service: input_select.select_option
      data:
      entity_id: input_select.home_status
      option: at_home
# ----------------------------------------------#
# √(早出发者)通知系统家里**仍**有人via 长按键
# 条件 # 上一status是left & (手动触发button)
# 当前判断button: hold
# dest   | 'at_home'
# depart | 'left'
- alias: mate_examption_amend
initial_state: true
trigger:
    - platform: state
      entity_id: input_select.home_status
      to: 'left'
condition:
    condition: and
    conditions:
      - condition: state
      entity_id: sensor.button_press_mode
      state: 'hold'
      - condition: template
      value_template: "{{ (as_timestamp(now())|int - as_timestamp(states.binary_sensor.switch_158d000288bb36.last_updated)|int) < 50 }}"
    # add "and" logic to confirm the hold is *rather current*, more trustworthy      
action:
    - service: input_select.select_option
      data:
      entity_id: input_select.home_status
      option: at_home
#################################################
# ----------------------------------------------#
# --- status_machine transition description --- #
# ------- end of the code block ----------------#
# ----------------------------------------------#
#################################################





#################################################
# ----------------------------------------------#
# ------ status_machine reset description ------#
# ------- (tell how system is de-armed) --------#
# ----------------------------------------------#
#################################################
# √ 手动清除异常 (at_home)
- alias: mute_abnormal_manual
initial_state: true
trigger:
    - platform: event
      event_type: xiaomi_aqara.click
      event_data:
      entity_id: binary_sensor.switch_158d000288bb36
      click_type: hold      
condition:
    condition: state
    entity_id: sensor.home_status
    state: 'abnormal'
action:
    - service: input_select.select_option
      data:
      entity_id: input_select.home_status
      option: 'at_home'
    # - service: notify.alexia
    #   data:
    #   title: "手动清除异常"
    #   message: ""   
# ----------------------------------------------#
# √ 自动清除异常 (at_home)
- alias: mute_abnormal_auto_resilliant
initial_state: true
trigger:
    - platform: time_pattern
      seconds: '/20'
condition:
    condition: and
    conditions:
      - condition: state
      entity_id: sensor.home_status
      state: 'abnormal'
      - condition: state
      entity_id: binary_sensor.door_window_sensor_158d0002897752
      state: 'off'
      - condition: state
      entity_id: binary_sensor.motion_sensor_158d00028433e7
      state: 'off'
action:
    - service: input_select.select_option
      data:
      entity_id: input_select.home_status
      option: 'away_guard'
#################################################
# ----------------------------------------------#
# --- status_machine reset description -------- #
# --------- end of the code block --------------#
# ----------------------------------------------#
#################################################

本帖最后由 tomassam 于 2019-5-8 20:31 编辑

大家好, 一个月的学习吸收在论坛学习到很多, 发现大家对于**多用户**进出导致的系统判断家庭状态混乱, 没有提出过系统性的解决方案. 小弟现在将自己探索的方案分享给大家. 希望得到大家的review, 进行更进一步的调整.

总体而言, 我的思路是通过状态机进行系统状态改变的描述.
细节而言, 我将status_old -> status_new 的每一个规则通过automation进行了描述. 我使用了input_select这一组件进行交互. 细节问题将在帖子下方的楼层里进行描述/讨论.

谢谢大家!

====进入正文====
状态转化图参见图片, 主要分
home_status:
    options:
      - at_home# 用户在家状态, 此时系统松弛, 不进行异常检测
      - arrived# 用户进门状态(过度态), 将自动转化为 chkin 等待用户的认证
      - left # 用户出门(过度态), 将自动转化为 away_guard (一段时间后)
      - away_guard # 系统警戒状态, 一切异常(门窗, motion) 都会触发警报(小米网关的警报声)
      - abnormal # 异常状态, 出现任何和系统**当前**状态不符合的情景(HASS将播报**异常**)
      - chkin # 签入状态, 任何进门者必须双击进行认证


这几个状态


使用直觉:
1. 任何用户, 进门双击**无线开关**进行认证
2. 1用户是最后一位出门, 单击(短, mono_click) **无线开关**---告诉系统*短*时间进入警戒状态
2. 2用户不是最后一位出门, 长按(长, hold) **无线开关**---告诉系统*长*时间进入警戒状态 (因为家里还有人)

如此系统就能"知道"究竟该布防与否.

如果承认上述状态机之间的转化, 则系统运行的规律已描述完全. 只要**判定当前属于何种情景**, 添加对应的automation规则即可.
比方说, 回家播报室内天气如下


# 回家室内气候播报 (podcast)
- alias: back_home_report
initial_state: true
trigger:
    - platform: state
      entity_id: input_select.home_status
      to: 'at_home'
      for:
      seconds: 5
condition:
    condition: template
    value_template: "{{ states.binary_sensor.switch_158d000288bb36.attributes.last_action != 'hold' }}"
action:
    - service: tts.baidu_say
      data_template:
      message: "室内气候{{states('sensor.int_comfort_msg')}}, 温度{{states('sensor.temperature_158d0002ead228')}}, 湿度{{states('sensor.humidity_158d0002ead228')}}"




Q1: 为什么不用device tracker?
A1: 我的手机电池不行, 选用了emulated_hue进行回家前的关闭警戒
--
Q2: 为什么没看到该执行的自动化, 比如说警戒后播报*进入警戒状态*?
A2: 本文主要着重描述状态转化关系. (着重在验证理论的正确, 而不是理论成立后的应用, 后期会有)
---
Q3: 我需要如何部署?
A1: 如下:
a, 看懂状态转化图, 并将状态转化的自动化规则加入automations.yaml里
b, 调整configuration.yaml
添加以下代码片段(这是描述/更新/调整)的对象的declaration

# status_indicator -> its value be passed as for scene selection
input_select:
home_status:
    options:
      - at_home
      - arrived
      - left
      - away_guard
      - abnormal
      - chkin
    initial: abnormal

# 下方的components 要自行调整, 我将在下方楼层添加对应的参考链接.
# 这个是通过获取token, HA进行网关警戒状态的调节
switch:
- platform: xiaomi_gateway_alarm
    host: 192.168.0.102
    token: !secret gateway_token#gateway_token

# 这个是百度语音合成,
tts:
- platform: baidu
    # entity_id -> the speaker; 3-keys for API
    app_id: 16015220
    api_key: !secret bd_tts_api_key
    secret_key: !secret bd_tts_sec_key
    speed: 8
    #entity_id: media_player.vlc
# 这个是媒体播放器
media_player:
- platform: vlc
    #host: 127.0.0.1
# 这个是小米网关的信息(用于交互其他设备, 例如无线开关)
xiaomi_aqara:
discovery_retry: 10
gateways:
    - mac: !secret gateway_mac
      key: !secret gateway_key



emulated_hue:
type: alexa

# 文本中的secret都是我自己的密钥 存放于secrets.yaml 的信息, 请自行调整


c, 添加以下两个sensor

# status_machine for scene selection assignment
- platform: template
sensors:
    home_status:
      value_template: "{{ states.input_select.home_status.state }}"
      friendly_name: '家状态'
    button_press_mode:
      value_template: "{{ states.binary_sensor.switch_158d000288bb36.attributes.last_action }}"
      friendly_name: '按压状态'



d, 对应调整我提供yaml的传感器名字
例如, binary_sensor.door_window_sensor_158d0002897752, 修改为你的设备的名称(entity_id)
e, 调试并运行


Q4: 你用到了什么资源? 凭什么肯定不能再精简?
A4: 界定状态只用到了(无线开关), 门窗和motion sensors. 不能精简的原因: 原始方案(论坛有一个说老外离家回家判断的帖子), 只是少了无线开关. 但他只能单身汉使用, 站在门传感器的角度, 如果没有额外信息的引入, 在"门的"眼中, 他是无法分辨究竟是1st人离家 or 2nd人回家 (都对应, 原始status=at_home, 状态为门打开), 因此我们必须引入信息, 而无线开关就是我们引入信息的载体. 基于此, 得出无法精简的结论. (device tracker其实是信息某种意义上的另一存在模式)

Q5: 那你为什么不用MQTT? 不用蓝牙, 不用 device tracker?
A5: MQTT 开启我的HASS启动缓慢, 另外两个我的手机电池不好. (简单说就是不符合我的实际需求)

Q6: 我**仔细*review 你的想法, 想和你深入探讨, 怎么联系?
A6: 我的邮箱 [email protected] /或本贴

谢谢大家!
#################################################
# ----------------------------------------------#
# --- status_machine transition description --- #
# ------- (tell how a status is reached) -------#
# ----------------------------------------------#
#################################################

# --------------- BASIC TERMS ------------------#
# ~dest~   |state that input_select.home_status is assigned
# ~depart~   |state that BEFORE assignment is executed
# "initial_state: true" -- all status automation MUST be with HASS ALL the time!
# ----------------------------------------------#

# ---------------Interfact Intuition------------#
# once come back, **EACH** user should db_click to pass the auth_eval
# if leaving home, if
    # first to leave, long press to tell system wait long before *in_guard* (cuz there is others at home)
    # last to leave, click (short) to tell wait short before *in_guard* (cuz there is NO others at home)
# ----------------------------------------------#
# √ 进门 - just arrived
# 条件 # 主门(off->on) & 上一status是不在家,i.e. (away_guard | left)
# dest   | 'arrived'
# depart | 'away_guard' or 'left'# ----------------------------------------------#
- alias: just_arrived
initial_state: true
trigger:
    - platform: state
      entity_id: binary_sensor.door_window_sensor_158d0002897752
      from: 'off'
      to: 'on'
condition:
    condition: or
    conditions:
      - condition: state
      entity_id: sensor.home_status
      state: 'away_guard'
      - condition: state
      entity_id: sensor.home_status
      state: 'left'
action:
    - service: input_select.select_option
      data:
      entity_id: input_select.home_status
      option: arrived
# ----------------------------------------------#
# √ reach_check_in (before inspection)      
# 检测/签到 - checkin
# 条件 # (上一status是进门 & 停留>10s) | (出门立刻回家)         
# dest   | 'chkin'
# depart | 'arrived'
- alias: check_in
initial_state: true
trigger:
    - platform: state
      entity_id: input_select.home_status
      to: 'arrived'
      for:
      seconds: 3
    - platform: state
      entity_id: input_select.home_status
      from: 'left'
      to: 'arrived'
action:
    - service: input_select.select_option
      data:
      entity_id: input_select.home_status
      option: chkin
# ----------------------------------------------#
# √ 出门 - just_left
# 条件 # 上一status是(进门 | 在家 | chkin) &| 主门(off->on)
# dest   | 'left'
# depart | 'arrived' or 'chkin' or 'at_home'
- alias: just_left
initial_state: true
trigger:
    - platform: state
      entity_id: binary_sensor.door_window_sensor_158d0002897752
      from: 'off'
      to: 'on'
condition:
    condition: or
    conditions:
      - condition: state
      entity_id: sensor.home_status
      state: 'at_home'
      - condition: state
      entity_id: sensor.home_status
      state: 'arrived'
      - condition: state
      entity_id: sensor.home_status
      state: 'chkin'
action:
    - service: input_select.select_option
      data:
      entity_id: input_select.home_status
      option: left
# ----------------------------------------------#
# √ 离家 - really_away
# 条件 # 上一status是出门(left) & t>4min
# dest   | 'away_guard'
# depart | 'left'
- alias: really_away
initial_state: true
trigger:
    - platform: state
      entity_id: input_select.home_status
      to: 'left'
      for:
      minutes: 4
action:
    - service: input_select.select_option
      data:
      entity_id: input_select.home_status
      option: away_guard
# ----------------------------------------------#
# √ 检查 - inspection in case of ileagal intruder
# 条件 # 上一status是chkin(检测/签到) & 触发button
# 当前触发button: db_click
# dest   | 'at_home'
# depart | 'chkin'
- alias: chkin_inspect
initial_state: true
trigger:
    - platform: event
      event_type: xiaomi_aqara.click
      event_data:
      entity_id: binary_sensor.switch_158d000288bb36
      click_type: double      
condition:
    condition: state
    entity_id: sensor.home_status
    state: 'chkin'
action:
    - service: input_select.select_option
      data:
      entity_id: input_select.home_status
      option: 'at_home'
# ----------------------------------------------#
# √ 异常(外出) - abnormal (when_out)
# 条件 # 上一status是away_guard & 探测到运动
# NOTE: other like doors/windows can be added equivalently
# in form of triggers (bilateral)
# dest   | 'abnormal'
# depart | 'away_guard'
- alias: abnormal (when_out)
initial_state: true
trigger:
    - platform: state
      entity_id: binary_sensor.motion_sensor_158d00028433e7
      to: 'on'
    # add other items, all except main_gate is allowed!!
condition:
    condition: state
    entity_id: sensor.home_status
    state: 'away_guard'               
action:
    - service: input_select.select_option
      data:
      entity_id: input_select.home_status
      option: abnormal
    # - service: notify.alexia
    #   data:
    #   title: "[异常] 潜入"
    #   message: "高手潜入detected"
# ----------------------------------------------#
# √ 异常(入侵) - abnormal (ileagal_intruder)
# 条件 # 上一status是chkin & 没有签到动作
# dest   | 'abnormal'
# depart | 'chkin'
- alias: abnormal (ileagal_intruder)
initial_state: true
trigger:
    - platform: state
      entity_id: input_select.home_status
      to: 'chkin'
      for:
      seconds: 20
action:
    - service: input_select.select_option
      data:
      entity_id: input_select.home_status
      option: 'abnormal'
    # - service: notify.alexia
    #   data:
    #   title: "[异常] 入侵"
    #   message: "入侵detected"
# ----------------------------------------------#
# √ 异常(没关门) - abnormal (forget_close_door)
# 条件 # 上一status是left & forget_close_door
# dest   | 'abnormal'
# depart | 'left'
- alias: abnormal (forget_close_door)
initial_state: true
trigger:
    - platform: state
      entity_id: input_select.home_status
      to: 'left'
      for: '00:00:10'
condition:
    condition: state
    entity_id: binary_sensor.door_window_sensor_158d0002897752
    state: 'on'
    for:
      seconds: 5
action:
    - service: input_select.select_option
      data:
      entity_id: input_select.home_status
      option: 'abnormal'
    # - service: notify.alexia
    #   data:
    #   title: "[异常]没关门"
    #   message: "没关门"
# ----------------------------------------------#
# (多人)回家报备 - mate_examption
# 条件 # 上一status是left & (探测到家人运动 | 手动触发button)
# 当前判断button: db_click
# dest   | 'at_home'
# depart | 'left'
- alias: mate_examption
initial_state: true
trigger:
    - platform: event
      event_type: xiaomi_aqara.click
      event_data:
      entity_id: binary_sensor.switch_158d000288bb36
      click_type: double
condition:
    condition: or
    conditions:
      - condition: state
      entity_id: binary_sensor.motion_sensor_158d00028433e7
      state: 'on'
      - condition: state
      entity_id: sensor.home_status
      state: 'left'      
action:
    - service: input_select.select_option
      data:
      entity_id: input_select.home_status
      option: at_home
# ----------------------------------------------#
# √(早出发者)通知系统家里**仍**有人via 长按键
# 条件 # 上一status是left & (手动触发button)
# 当前判断button: hold
# dest   | 'at_home'
# depart | 'left'
- alias: mate_examption_amend
initial_state: true
trigger:
    - platform: state
      entity_id: input_select.home_status
      to: 'left'
condition:
    condition: and
    conditions:
      - condition: state
      entity_id: sensor.button_press_mode
      state: 'hold'
      - condition: template
      value_template: "{{ (as_timestamp(now())|int - as_timestamp(states.binary_sensor.switch_158d000288bb36.last_updated)|int) < 50 }}"
    # add "and" logic to confirm the hold is *rather current*, more trustworthy      
action:
    - service: input_select.select_option
      data:
      entity_id: input_select.home_status
      option: at_home
#################################################
# ----------------------------------------------#
# --- status_machine transition description --- #
# ------- end of the code block ----------------#
# ----------------------------------------------#
#################################################





#################################################
# ----------------------------------------------#
# ------ status_machine reset description ------#
# ------- (tell how system is de-armed) --------#
# ----------------------------------------------#
#################################################
# √ 手动清除异常 (at_home)
- alias: mute_abnormal_manual
initial_state: true
trigger:
    - platform: event
      event_type: xiaomi_aqara.click
      event_data:
      entity_id: binary_sensor.switch_158d000288bb36
      click_type: hold      
condition:
    condition: state
    entity_id: sensor.home_status
    state: 'abnormal'
action:
    - service: input_select.select_option
      data:
      entity_id: input_select.home_status
      option: 'at_home'
    # - service: notify.alexia
    #   data:
    #   title: "手动清除异常"
    #   message: ""   
# ----------------------------------------------#
# √ 自动清除异常 (at_home)
- alias: mute_abnormal_auto_resilliant
initial_state: true
trigger:
    - platform: time_pattern
      seconds: '/20'
condition:
    condition: and
    conditions:
      - condition: state
      entity_id: sensor.home_status
      state: 'abnormal'
      - condition: state
      entity_id: binary_sensor.door_window_sensor_158d0002897752
      state: 'off'
      - condition: state
      entity_id: binary_sensor.motion_sensor_158d00028433e7
      state: 'off'
action:
    - service: input_select.select_option
      data:
      entity_id: input_select.home_status
      option: 'away_guard'
#################################################
# ----------------------------------------------#
# --- status_machine reset description -------- #
# --------- end of the code block --------------#
# ----------------------------------------------#
#################################################

tomassam 发表于 2019-4-27 17:16:49

小米网关警戒功能的接入   https://bbs.hassbian.com/forum.php?mod=viewthread&tid=6749&highlight=%E5%B0%8F%E7%B1%B3%E7%BD%91%E5%85%B3

tomassam 发表于 2019-4-27 17:18:47

百度tts+vlc   https://bbs.hassbian.com/forum.php?mod=viewthread&tid=6749&highlight=%E5%B0%8F%E7%B1%B3%E7%BD%91%E5%85%B3

tomassam 发表于 2019-4-27 17:19:54

被"继承发扬"的"老外"    https://bbs.hassbian.com/forum.php?mod=viewthread&tid=3349&highlight=%E8%80%81%E5%A4%96

tomassam 发表于 2019-4-27 17:21:40

状态机的百科    https://baike.baidu.com/item/%E7%8A%B6%E6%80%81%E6%9C%BA/6548513?fr=aladdin

发表于 2019-4-27 18:00:29

楼主厉害,建议把代码格式再调下,前面的明显是乱的,后面的就正常。

tomassam 发表于 2019-4-27 18:34:06

Jones 发表于 2019-4-27 18:00
楼主厉害,建议把代码格式再调下,前面的明显是乱的,后面的就正常。

Ha! Thanks Jones. I do it intentionally, since the assorted (poorly edit) scripts are not suitable for each user's demand (the assorted form will avoid them copy/paste and thus read the content more carefully).

Edited one I confirmed that it's applicable with simple copy/paste.

But thanks for noting the defects which may draw people's attention more significantly.

Sorry for not able to comment in ZH, which is not installed on my Ubuntu machines.

peter5858 发表于 2019-4-27 18:48:11

谢谢分享!!!收藏以后用

neroxps 发表于 2019-4-27 18:53:28

突然被楼主抛了我一脸书包····膜拜中。。。

咸味土豆 发表于 2019-4-27 20:01:48

没忍住第一次在论坛使用右键翻译中文(简体),结果还没成功,手动翻译之后发现说的非常有道理,膜拜一下。
页: [1] 2 3
查看完整版本: 多用户-房屋状态解决 - 集大成 - 基于状态机