找回密碼
 立即註冊
惟家LINE群QRCODE
    查看: 1|回覆: 0

    Google 廣播的進階用法:分房、分時段、動態內容

    [複製鏈接]

    !lvup!   100%

    363

    主題

    27

    回帖

    2200萬

    積分

    管理員

    積分
    22005752
    發表於 3 天前 | 顯示全部樓層 |閱讀模式
    廣播(Broadcast)大概是 Google 音箱最被低估的功能。

    基本用法大家都會(「OK Google,廣播吃飯了」),
    這篇講進階的。



    從 HA 發廣播

    Google Home 整合本身沒有提供廣播的服務
    但有兩種變通做法。

    做法一:用 TTS 播到指定的音箱(推薦)
    1. - action: tts.cloud_say
    2.   target:
    3.     entity_id: media_player.客廳音箱
    4.   data:
    5.     message: 洗衣機洗好了
    複製代碼

    這其實比 Google 原生的廣播更好,因為:


    • 可以指定播到哪一台(原生廣播是全部一起)
    • 內容可以是動態的
    • 可以控制音量
    • 不會有「廣播」的那個提示音(有人覺得吵)


    做法二:用 Google 常式當中介

    在 Google Home App 建一個常式,動作是「廣播某段文字」,
    然後 HA 觸發那個常式(透過虛擬開關)。

    缺點:內容是寫死的,不能動態。

    所以我幾乎都用做法一。

    技巧一:分房播報

    不要什麼都全屋廣播。只播給需要知道的人
    1. script:
    2.   smart_announce:
    3.     alias: 智慧播報
    4.     fields:
    5.       message:
    6.         description: 要講的內容
    7.         required: true
    8.         selector:
    9.           text:
    10.       area:
    11.         description: 播到哪裡(all / occupied / 房間名)
    12.         default: occupied
    13.         selector:
    14.           text:
    15.       volume:
    16.         description: 音量 0-1
    17.         default: 0.5
    18.         selector:
    19.           number: {min: 0, max: 1, step: 0.05}
    20.     sequence:
    21.       - variables:
    22.           # 依 area 決定要播到哪些音箱
    23.           targets: >
    24.             {% if area == 'all' %}
    25.               {{ ['media_player.客廳音箱',
    26.                   'media_player.主臥音箱',
    27.                   'media_player.書房音箱'] }}
    28.             {% elif area == 'occupied' %}
    29.               {% set r = namespace(list=[]) %}
    30.               {% if is_state('binary_sensor.客廳有人','on') %}
    31.                 {% set r.list = r.list + ['media_player.客廳音箱'] %}
    32.               {% endif %}
    33.               {% if is_state('binary_sensor.主臥有人','on') %}
    34.                 {% set r.list = r.list + ['media_player.主臥音箱'] %}
    35.               {% endif %}
    36.               {% if is_state('binary_sensor.書房有人','on') %}
    37.                 {% set r.list = r.list + ['media_player.書房音箱'] %}
    38.               {% endif %}
    39.               {{ r.list if r.list | count > 0
    40.                  else ['media_player.客廳音箱'] }}
    41.             {% else %}
    42.               {{ ['media_player.' ~ area ~ '音箱'] }}
    43.             {% endif %}
    44.       - repeat:
    45.           for_each: "{{ targets }}"
    46.           sequence:
    47.             - action: media_player.volume_set
    48.               target:
    49.                 entity_id: "{{ repeat.item }}"
    50.               data:
    51.                 volume_level: "{{ volume }}"
    52.             - action: tts.cloud_say
    53.               target:
    54.                 entity_id: "{{ repeat.item }}"
    55.               data:
    56.                 message: "{{ message }}"
    57.     mode: queued
    58.     max: 10
    複製代碼

    用法
    1. - action: script.smart_announce
    2.   data:
    3.     message: 洗衣機好了
    4.     area: occupied        # 只播給有人的房間
    5.     volume: 0.5
    複製代碼

    namespace 那個寫法是 Jinja 在迴圈裡累加清單的標準做法,
    直接用 `set r = r + [...]` 在 if 區塊裡不會生效。



    技巧二:依時段調整音量和內容
    1. script:
    2.   time_aware_announce:
    3.     alias: 分時段播報
    4.     fields:
    5.       message: {required: true, selector: {text: }}
    6.     sequence:
    7.       - variables:
    8.           hour: "{{ now().hour }}"
    9.           vol: >
    10.             {% if hour < 7 or hour >= 22 %}0.25
    11.             {% elif hour < 9 %}0.4
    12.             {% else %}0.55
    13.             {% endif %}
    14.           should_speak: >
    15.             {{ not is_state('input_select.house_mode', '睡覺') }}
    16.       - condition: "{{ should_speak }}"
    17.       - action: media_player.volume_set
    18.         target: {entity_id: media_player.客廳音箱}
    19.         data: {volume_level: "{{ vol }}"}
    20.       - action: tts.cloud_say
    21.         target: {entity_id: media_player.客廳音箱}
    22.         data: {message: "{{ message }}"}
    23.     mode: queued
    複製代碼

    「睡覺模式就不播」這個條件很重要。
    沒有它的話,半夜洗衣機洗好會把全家吵醒。

    技巧三:播報前先暫停正在播的東西

    如果音箱正在放音樂,TTS 會直接蓋過去,而且播完不會恢復。
    1. sequence:
    2.   - variables:
    3.       was_playing: "{{ is_state('media_player.客廳音箱','playing') }}"
    4.   - if: "{{ was_playing }}"
    5.     then:
    6.       - action: media_player.media_pause
    7.         target: {entity_id: media_player.客廳音箱}
    8.       - delay: "00:00:01"
    9.   - action: tts.cloud_say
    10.     target: {entity_id: media_player.客廳音箱}
    11.     data: {message: "{{ message }}"}
    12.   # 等播完(TTS 的長度不固定,用狀態判斷)
    13.   - wait_template: >
    14.       {{ not is_state('media_player.客廳音箱','playing') }}
    15.     timeout: "00:00:30"
    16.   - if: "{{ was_playing }}"
    17.     then:
    18.       - delay: "00:00:01"
    19.       - action: media_player.media_play
    20.         target: {entity_id: media_player.客廳音箱}
    複製代碼

    技巧四:真正實用的五個播報場景

    1. 出門前的天氣與提醒
    1. triggers:
    2.   - trigger: state
    3.     entity_id: binary_sensor.玄關感應
    4.     to: "on"
    5. conditions:
    6.   - condition: time
    7.     after: "06:30:00"
    8.     before: "09:00:00"
    9.   - condition: state
    10.     entity_id: input_boolean.今天已播報
    11.     state: "off"
    12. actions:
    13.   - action: input_boolean.turn_on
    14.     target: {entity_id: input_boolean.今天已播報}
    15.   - action: script.smart_announce
    16.     data:
    17.       area: 玄關
    18.       message: >
    19.         今天 {{ states('sensor.室外溫度') }} 度。
    20.         {% if states('sensor.降雨機率') | float(0) > 40 %}
    21.         降雨機率 {{ states('sensor.降雨機率') }}%,記得帶傘。
    22.         {% endif %}
    23.         {% if now().weekday() == 1 %}今天要倒垃圾。{% endif %}
    複製代碼

    那個「今天已播報」的旗標是必要的,
    不然你在玄關走來走去會被播報十次。

    (記得加一個每天凌晨重設的自動化。)

    2. 洗衣機好了

    前面講 wait_template 那篇有完整範例。

    3. 門窗忘記關
    1. message: >
    2.   {{ trigger.to_state.name }} 已經開著
    3.   {{ (now() - trigger.to_state.last_changed).total_seconds() // 60 | int }}
    4.   分鐘了
    複製代碼

    4. 家庭對講機

    做幾個 script,用手機的 HA App 或捷徑觸發:


    • 「吃飯了」→ 播到所有有人的房間
    • 「我在忙」→ 播到客廳
    • 「下來一下」→ 播到樓上


    這個比用喊的有效,而且不用提高音量。

    5. 小孩的作息提醒
    1. triggers:
    2.   - trigger: time
    3.     at: "21:00:00"
    4. actions:
    5.   - action: script.smart_announce
    6.     data:
    7.       area: 次臥
    8.       message: 九點了,該準備睡覺囉
    9.       volume: 0.45
    複製代碼

    比家長自己喊有效,因為「不是我在唸你,是機器說的」。



    幾個實務上的坑

    坑一:TTS 的中文發音


    • 數字:「26.5」可能唸成「二六點五」。寫成「二十六點五度」比較保險
    • 英文夾雜:「PM2.5」可能唸得很怪
    • 標點符號:適當加逗號可以控制停頓


    解法:測試的時候用開發者工具的「動作」直接試
    聽起來怪就改寫法。

    坑二:音箱正在播 Spotify 時

    有些音樂服務被 TTS 打斷後不會自己恢復,
    而且「恢復」的動作可能會從頭播。

    這個沒有完美解法,我的做法是「重要的才播,不重要的用手機推播」。

    坑三:多台音箱同時播會不同步

    上面的 repeat 寫法是一台一台播,會有時間差。

    要同步的話,可以先在 Google Home App 裡建立一個「喇叭群組」,
    那個群組在 HA 裡會是一個 media_player 實體,對它播就會同步。

    坑四:Nest Hub 會顯示字幕

    有螢幕的裝置播 TTS 時會顯示文字。
    內容有隱私疑慮的話要注意(例如「某某人回家了」)。

    ---

    我家最常用的其實是「吃飯了」這個。

    聽起來很蠢,但不用走到樓上喊,而且小孩不能說「我沒聽到」

    這大概是我做過投資報酬率最高的自動化之一。
    您需要登入後纔可以回帖 登入 | 立即註冊

    本版積分規則

    Archiver|手機版|惟家的智能論壇

    GMT+8, 2026-9-24 11:29 , Processed in 0.074508 second(s), 24 queries .

    快速回覆 返回頂部 返回列表