地牛Wake Up! 地震預報連動HA自動化 Node-Red版

大家好,我是新人
最近看到這篇地震預報連動的教學
[分享] “地牛Wake Up!”地震預報連動HA自動化
非常感謝作者 及文中提供資訊的人!

但由於對使用系統內建的自動化來做的方式很不擅長
所以想改用Node-Red來做(雖然也是初學)

以下做一些分享:

這是我想要達到的流程

  1. 從另一台Windows電腦傳地震即時通知至HomeAssistant
  2. HomeAssistant中Node-Red針對不同大小的地震有不同訊息內容
  3. 通知(警報)

通知部分又分

  • 智慧音箱語音通知
  • HomeAssistant內部通知
  • Telegram通知(需要預先開bot跟建立群組)

首先是Windows安裝"地牛Wake Up!"與設定
地牛Wake Up!下載網址


03
04

05
bat檔的內容: (感謝先前提到的文章作者提供~)


@echo off

REM 設定你的HA網址
set DST=http://192.168.2.2:8123

REM TOKEN從HA UI左邊的使用者下面去創建永久權杖 然後複製到這邊
set TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI2NmViOTU5ZTM1YWQ0Y2Y3YjM0ZDM1MTQ0NWNhYjdlNCIsImlhdCI6MTY2OTA5NTEwOCwiZXhwIjoxOTg0NDU1MTA4fQ.GNpzAfvNT3wldlRfr54SlD7kOSKeP20umDdLfV0PU2E


REM 以下呼叫HA

REM 保險起見先把HA地震強度設為0
curl.exe -X POST -H "Authorization: Bearer %TOKEN%" -H "Content-Type: application/json" %DST%/api/states/sensor.earthquake_alert_level -d "{\"state\": \"0\"}"

REM 把地震強度與到達時間傳入HA
REM 因為觸發條件式以強度為準 故要先傳入抵達時間 再傳地震強度
curl.exe -X POST -H "Authorization: Bearer %TOKEN%" -H "Content-Type: application/json" %DST%/api/states/sensor.earthquake_alert_arrive_second -d "{\"state\": \"%2\"}"
curl.exe -X POST -H "Authorization: Bearer %TOKEN%" -H "Content-Type: application/json" %DST%/api/states/sensor.earthquake_alert_level -d "{\"state\": \"%1\"}"

REM 一小段時間後把HA歸0 不做也沒關係
timeout /t 5
curl.exe -X POST -H "Authorization: Bearer %TOKEN%" -H "Content-Type: application/json" %DST%/api/states/sensor.earthquake_alert_level -d "{\"state\": \"0\"}"
curl.exe -X POST -H "Authorization: Bearer %TOKEN%" -H "Content-Type: application/json" %DST%/api/states/sensor.earthquake_alert_arrive_second -d "{\"state\": \"0\"}"

接下來到HomeAssistant這邊
1.設定sensor,放在-template下,因為我的template.yaml是獨立的,這邊可能看個人的配置
總之要在configuration → template → sensor →
這兩個sensor僅負責"儲存"從Windows傳過來的地震資訊

- sensor:
    #地震警報
    - name: earthquake_alert_level
      #預估地震規模"
      state: "0"

    - name: earthquake_alert_arrive_second
      #預估幾秒後到達"
      state: "0"
  1. HACS中安裝 Microsoft Edge TTS文字轉語音(如果沒有HACS的話請先照教學)

12-2

  1. Telegram設定 (如果沒有要用可以跳過)
    關於bot的設定請另外找教學喔

  2. Node-Red: 將以下內容匯入至Node-Red>

[{"id":"ca82bb87c2ad5613","type":"switch","z":"9ddd4063b403a680","name":"","property":"level","propertyType":"msg","rules":[{"t":"eq","v":"3","vt":"str"},{"t":"eq","v":"4","vt":"str"},{"t":"eq","v":"5-","vt":"str"},{"t":"eq","v":"5+","vt":"str"},{"t":"eq","v":"6-","vt":"str"},{"t":"eq","v":"6+","vt":"str"},{"t":"eq","v":"7","vt":"str"},{"t":"gt","v":"7","vt":"str"}],"checkall":"false","repair":true,"outputs":8,"x":290,"y":160,"wires":[["ca19b6205b7406bf","0248639418f4ef78"],["ca19b6205b7406bf","4bf006cbc2814b24"],["ca19b6205b7406bf","4bf006cbc2814b24"],["ca19b6205b7406bf","b39f1c558b8da89f"],["ca19b6205b7406bf","b39f1c558b8da89f"],["ca19b6205b7406bf","b39f1c558b8da89f"],["ca19b6205b7406bf","b39f1c558b8da89f"],["b39f1c558b8da89f"]]},{"id":"866ae2971336a6d2","type":"server-state-changed","z":"9ddd4063b403a680","name":"Sensor Earthquake","server":"0be9869e6aa91d45","version":4,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.earthquake_alert_level","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is_not","outputs":1,"output_only_on_state_change":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"},{"property":"level","propertyType":"msg","value":"","valueType":"entityState"}],"x":110,"y":120,"wires":[["3207230ff0635d3a"]]},{"id":"ca19b6205b7406bf","type":"debug","z":"9ddd4063b403a680","name":"debug 2","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":480,"y":20,"wires":[]},{"id":"0af2d8136219c170","type":"api-call-service","z":"9ddd4063b403a680","name":"語音播報","server":"0be9869e6aa91d45","version":5,"debugenabled":false,"domain":"tts","service":"edge_tts_say","areaId":[],"deviceId":[],"entityId":["media_player.spkfang_jian_de_nesthub"],"data":"{\"message\":\"{{messageMain}} {{messageMain}}\",\"language\":\"zh-TW-HsiaoChenNeural\"}","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"all","x":840,"y":160,"wires":[[]]},{"id":"9e35850ff861876a","type":"debug","z":"9ddd4063b403a680","name":"debug 3","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":280,"y":20,"wires":[]},{"id":"23f351a5204fb636","type":"api-call-service","z":"9ddd4063b403a680","name":"設定音量","server":"0be9869e6aa91d45","version":5,"debugenabled":false,"domain":"media_player","service":"volume_set","areaId":[],"deviceId":[],"entityId":["media_player.spkfang_jian_de_nesthub"],"data":"{\"volume_level\": 0.4}","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":660,"y":100,"wires":[["c72eeba7da012617"]]},{"id":"ac9d9e6f5b9c93da","type":"api-call-service","z":"9ddd4063b403a680","name":"設定音量","server":"0be9869e6aa91d45","version":5,"debugenabled":false,"domain":"media_player","service":"volume_set","areaId":[],"deviceId":[],"entityId":["media_player.spkfang_jian_de_nesthub"],"data":"{\"volume_level\": 0.4}","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":660,"y":160,"wires":[["c72eeba7da012617"]]},{"id":"a8fa0b2ea43a8b44","type":"api-call-service","z":"9ddd4063b403a680","name":"設定音量","server":"0be9869e6aa91d45","version":5,"debugenabled":false,"domain":"media_player","service":"volume_set","areaId":[],"deviceId":[],"entityId":["media_player.spkfang_jian_de_nesthub"],"data":"{\"volume_level\": 0.4}","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":660,"y":220,"wires":[["c72eeba7da012617"]]},{"id":"3207230ff0635d3a","type":"api-render-template","z":"9ddd4063b403a680","name":"地震級數及秒數","server":"0be9869e6aa91d45","version":0,"template":"{% set offsetSecond=3 %}\n\n{% if (states.sensor.earthquake_alert_arrive_second.state) |int -offsetSecond < 0 %}\n{{ (states.sensor.earthquake_alert_level.state) | replace(\"-\",\"減\")}}級地震現在發生中。\n{% else %}\n{% set arriveSecond = (states.sensor.earthquake_alert_arrive_second.state) |int -offsetSecond %}\n{{ (states.sensor.earthquake_alert_level.state) | replace(\"-\",\"減\")}}級地震{{arriveSecond }}秒後抵達。\n{% endif %}\n\n","resultsLocation":"messageMain","resultsLocationType":"msg","templateLocation":"","templateLocationType":"none","x":120,"y":180,"wires":[["ca82bb87c2ad5613","9e35850ff861876a"]]},{"id":"6060e68e1aebf4af","type":"debug","z":"9ddd4063b403a680","name":"debug 5","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":680,"y":20,"wires":[]},{"id":"0248639418f4ef78","type":"template","z":"9ddd4063b403a680","name":"小型地震","field":"messageMain","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"小地震發生,{{ messageMain }}","output":"str","x":480,"y":100,"wires":[["6060e68e1aebf4af","23f351a5204fb636","abd78f4f3e4c7b2a"]]},{"id":"4bf006cbc2814b24","type":"template","z":"9ddd4063b403a680","name":"中型地震","field":"messageMain","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"注意,中型地震發生,{{ messageMain }}","output":"str","x":480,"y":160,"wires":[["ac9d9e6f5b9c93da","6060e68e1aebf4af","abd78f4f3e4c7b2a"]]},{"id":"b39f1c558b8da89f","type":"template","z":"9ddd4063b403a680","name":"強烈地震","field":"messageMain","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"注意,強烈地震發生,{{ messageMain }},現在立即找掩護!!","output":"str","x":480,"y":220,"wires":[["a8fa0b2ea43a8b44","6060e68e1aebf4af","abd78f4f3e4c7b2a"]]},{"id":"c61cb90e893d6960","type":"api-call-service","z":"9ddd4063b403a680","name":"HA通知","server":"0be9869e6aa91d45","version":5,"debugenabled":false,"domain":"notify","service":"persistent_notification","areaId":[],"deviceId":[],"entityId":[],"data":"{\"message\":\"{{messageMain}}\",\"title\":\"地震警報\"}","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":840,"y":280,"wires":[[]]},{"id":"4783f72f5b46941a","type":"api-call-service","z":"9ddd4063b403a680","name":"Telegram通知","server":"0be9869e6aa91d45","version":5,"debugenabled":true,"domain":"notify","service":"telegram_important","areaId":[],"deviceId":[],"entityId":[],"data":"{\"message\":\"{{messageMain}}\",\"title\":\"地震警報\"}","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":860,"y":360,"wires":[[]]},{"id":"c72eeba7da012617","type":"junction","z":"9ddd4063b403a680","x":760,"y":160,"wires":[["0af2d8136219c170"]]},{"id":"abd78f4f3e4c7b2a","type":"junction","z":"9ddd4063b403a680","x":660,"y":280,"wires":[["c61cb90e893d6960","4783f72f5b46941a"]]},{"id":"0be9869e6aa91d45","type":"server","name":"Home Assistant","version":5,"addon":false,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":"30","areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":": ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"default","statusTimeFormat":"h:m","enableGlobalContextStore":false}]

17

Node-Red中: “設定音量” 與 “語音播報” 這些Node中有需要設定撥放器的entity_id
請按照個人家中的配置設定
最好把家中所有支援的裝置都設定進來
(可以用Helper把家中所有撥放器設成一個群組,NR使用這個群組去撥放語音,之後新增裝置就不用在NR裡一個一個改,只要在群組內新增)
有群組之後如果做別的警報流程也可以重複利用(例如火災警報 防盜系統等等)

到此基本上就已經安裝完成了
接下來是測試
按下APP中的重現,會呼叫bat → HA中的sensor值被改變 → Node-Red觸發流程

也可以做幾個bat,修改內容讓他送出固定的地震級數跟到達時間,這樣執行bat就能測試不同大小地震發生的情形,我另外還做了一個不存在的8級bat測試XD
11

18

大概,就這樣了
有想到再補充~

請問通知的變數可以用line notify嗎? 不知道語法要怎麼寫

請問您提供的.BAT檔一樣是適用MAC版的地牛嗎?

.bat是Windows用的喔~