|
|
廣播(Broadcast)大概是 Google 音箱最被低估的功能。
基本用法大家都會(「OK Google,廣播吃飯了」),
這篇講進階的。

從 HA 發廣播
Google Home 整合本身沒有提供廣播的服務,
但有兩種變通做法。
做法一:用 TTS 播到指定的音箱(推薦)
- - action: tts.cloud_say
- target:
- entity_id: media_player.客廳音箱
- data:
- message: 洗衣機洗好了
複製代碼
這其實比 Google 原生的廣播更好,因為:
- 可以指定播到哪一台(原生廣播是全部一起)
- 內容可以是動態的
- 可以控制音量
- 不會有「廣播」的那個提示音(有人覺得吵)
做法二:用 Google 常式當中介
在 Google Home App 建一個常式,動作是「廣播某段文字」,
然後 HA 觸發那個常式(透過虛擬開關)。
缺點:內容是寫死的,不能動態。
所以我幾乎都用做法一。
技巧一:分房播報
不要什麼都全屋廣播。只播給需要知道的人。
- script:
- smart_announce:
- alias: 智慧播報
- fields:
- message:
- description: 要講的內容
- required: true
- selector:
- text:
- area:
- description: 播到哪裡(all / occupied / 房間名)
- default: occupied
- selector:
- text:
- volume:
- description: 音量 0-1
- default: 0.5
- selector:
- number: {min: 0, max: 1, step: 0.05}
- sequence:
- - variables:
- # 依 area 決定要播到哪些音箱
- targets: >
- {% if area == 'all' %}
- {{ ['media_player.客廳音箱',
- 'media_player.主臥音箱',
- 'media_player.書房音箱'] }}
- {% elif area == 'occupied' %}
- {% set r = namespace(list=[]) %}
- {% if is_state('binary_sensor.客廳有人','on') %}
- {% set r.list = r.list + ['media_player.客廳音箱'] %}
- {% endif %}
- {% if is_state('binary_sensor.主臥有人','on') %}
- {% set r.list = r.list + ['media_player.主臥音箱'] %}
- {% endif %}
- {% if is_state('binary_sensor.書房有人','on') %}
- {% set r.list = r.list + ['media_player.書房音箱'] %}
- {% endif %}
- {{ r.list if r.list | count > 0
- else ['media_player.客廳音箱'] }}
- {% else %}
- {{ ['media_player.' ~ area ~ '音箱'] }}
- {% endif %}
- - repeat:
- for_each: "{{ targets }}"
- sequence:
- - action: media_player.volume_set
- target:
- entity_id: "{{ repeat.item }}"
- data:
- volume_level: "{{ volume }}"
- - action: tts.cloud_say
- target:
- entity_id: "{{ repeat.item }}"
- data:
- message: "{{ message }}"
- mode: queued
- max: 10
複製代碼
用法:
- - action: script.smart_announce
- data:
- message: 洗衣機好了
- area: occupied # 只播給有人的房間
- volume: 0.5
複製代碼
namespace 那個寫法是 Jinja 在迴圈裡累加清單的標準做法,
直接用 `set r = r + [...]` 在 if 區塊裡不會生效。

技巧二:依時段調整音量和內容
- script:
- time_aware_announce:
- alias: 分時段播報
- fields:
- message: {required: true, selector: {text: }}
- sequence:
- - variables:
- hour: "{{ now().hour }}"
- vol: >
- {% if hour < 7 or hour >= 22 %}0.25
- {% elif hour < 9 %}0.4
- {% else %}0.55
- {% endif %}
- should_speak: >
- {{ not is_state('input_select.house_mode', '睡覺') }}
- - condition: "{{ should_speak }}"
- - action: media_player.volume_set
- target: {entity_id: media_player.客廳音箱}
- data: {volume_level: "{{ vol }}"}
- - action: tts.cloud_say
- target: {entity_id: media_player.客廳音箱}
- data: {message: "{{ message }}"}
- mode: queued
複製代碼
「睡覺模式就不播」這個條件很重要。
沒有它的話,半夜洗衣機洗好會把全家吵醒。
技巧三:播報前先暫停正在播的東西
如果音箱正在放音樂,TTS 會直接蓋過去,而且播完不會恢復。
- sequence:
- - variables:
- was_playing: "{{ is_state('media_player.客廳音箱','playing') }}"
- - if: "{{ was_playing }}"
- then:
- - action: media_player.media_pause
- target: {entity_id: media_player.客廳音箱}
- - delay: "00:00:01"
- - action: tts.cloud_say
- target: {entity_id: media_player.客廳音箱}
- data: {message: "{{ message }}"}
- # 等播完(TTS 的長度不固定,用狀態判斷)
- - wait_template: >
- {{ not is_state('media_player.客廳音箱','playing') }}
- timeout: "00:00:30"
- - if: "{{ was_playing }}"
- then:
- - delay: "00:00:01"
- - action: media_player.media_play
- target: {entity_id: media_player.客廳音箱}
複製代碼
技巧四:真正實用的五個播報場景
1. 出門前的天氣與提醒
- triggers:
- - trigger: state
- entity_id: binary_sensor.玄關感應
- to: "on"
- conditions:
- - condition: time
- after: "06:30:00"
- before: "09:00:00"
- - condition: state
- entity_id: input_boolean.今天已播報
- state: "off"
- actions:
- - action: input_boolean.turn_on
- target: {entity_id: input_boolean.今天已播報}
- - action: script.smart_announce
- data:
- area: 玄關
- message: >
- 今天 {{ states('sensor.室外溫度') }} 度。
- {% if states('sensor.降雨機率') | float(0) > 40 %}
- 降雨機率 {{ states('sensor.降雨機率') }}%,記得帶傘。
- {% endif %}
- {% if now().weekday() == 1 %}今天要倒垃圾。{% endif %}
複製代碼
那個「今天已播報」的旗標是必要的,
不然你在玄關走來走去會被播報十次。
(記得加一個每天凌晨重設的自動化。)
2. 洗衣機好了
前面講 wait_template 那篇有完整範例。
3. 門窗忘記關
- message: >
- {{ trigger.to_state.name }} 已經開著
- {{ (now() - trigger.to_state.last_changed).total_seconds() // 60 | int }}
- 分鐘了
複製代碼
4. 家庭對講機
做幾個 script,用手機的 HA App 或捷徑觸發:
- 「吃飯了」→ 播到所有有人的房間
- 「我在忙」→ 播到客廳
- 「下來一下」→ 播到樓上
這個比用喊的有效,而且不用提高音量。
5. 小孩的作息提醒
- triggers:
- - trigger: time
- at: "21:00:00"
- actions:
- - action: script.smart_announce
- data:
- area: 次臥
- message: 九點了,該準備睡覺囉
- volume: 0.45
複製代碼
比家長自己喊有效,因為「不是我在唸你,是機器說的」。

幾個實務上的坑
坑一:TTS 的中文發音
- 數字:「26.5」可能唸成「二六點五」。寫成「二十六點五度」比較保險
- 英文夾雜:「PM2.5」可能唸得很怪
- 標點符號:適當加逗號可以控制停頓
解法:測試的時候用開發者工具的「動作」直接試,
聽起來怪就改寫法。
坑二:音箱正在播 Spotify 時
有些音樂服務被 TTS 打斷後不會自己恢復,
而且「恢復」的動作可能會從頭播。
這個沒有完美解法,我的做法是「重要的才播,不重要的用手機推播」。
坑三:多台音箱同時播會不同步
上面的 repeat 寫法是一台一台播,會有時間差。
要同步的話,可以先在 Google Home App 裡建立一個「喇叭群組」,
那個群組在 HA 裡會是一個 media_player 實體,對它播就會同步。
坑四:Nest Hub 會顯示字幕
有螢幕的裝置播 TTS 時會顯示文字。
內容有隱私疑慮的話要注意(例如「某某人回家了」)。
---
我家最常用的其實是「吃飯了」這個。
聽起來很蠢,但不用走到樓上喊,而且小孩不能說「我沒聽到」。
這大概是我做過投資報酬率最高的自動化之一。 |
|