Post

My Home Office Welcomes Me with a Personalized Morning Update

My Home Office Welcomes Me with a Personalized Morning Update

Mornings in my house are busy—with two young kids and three dogs, there’s always something going on. To stay on track, I built a desktop dashboard for my home office, but I wanted something hands-free to remind me of my schedule without checking a screen. That’s why I created a Good Morning Message that plays on my HomePod mini when I enter my office, giving me the weather, calendar updates, and important events. In this post, I’ll show you how I set it up using Home Assistant, Bermude BLE, and Chime TTS to make mornings smoother.

What I Used for This Project

Setting Up the ESP32 Boards

  1. Install the ESPHome integration in Home Assistant.
  2. Install ESPHome on the ESP32 boards as a Bluetooth Proxy. You can use either the ESPHome Ready-Made Projects website or the ESPHome Builder add-on for Home Assistant.
  3. After adding the Bluetooth proxies to Home Assistant, assign them to Areas. These Areas will be used by the Bermuda BLE Trilateration integration to determine where devices are detected.

ESPHome ESP Home Builder

Private BLE Integration

Since everyone in my home uses Apple devices, I am using the Private BLE integration. Follow the instructions in the integration’s documentation to retrieve the Identity Resolving Key (IRK) for your devices.

Once you have the IRK, add an entry for your device key in the integration.

Private BLE Add private BLE entry

Bermuda BLE Trilateration

  1. Install Bermuda BLE Trilateration from HACS.
  2. Restart Home Assistant.
  3. Open Devices & Services.
  4. Add the Bermuda BLE Trilateration integration.

After installation, the integration will automatically discover your Bluetooth Proxies.

Configuring Bermuda BLE Trilateration

  1. In the Bermuda BLE Trilateration integration settings, use Select Devices to choose which devices you want to track.
  2. This will create additional entities for each tracked Bluetooth device, showing:
    • The area where the device is detected
    • The distance from each BLE proxy

The USB Bluetooth adapter on your Home Assistant server does not work well with this integration, as it does not include a timestamp in the advertisement packets. Area distance tracking is not supported when using the server’s Bluetooth.

Bermuda BLE Config Bermuda BLE Config

Setting Up Chime TTS

  1. Install Chime TTS from HACS.
  2. Restart Home Assistant.
  3. Open Devices & Services.
  4. Add the Chime TTS integration.
  5. Configure Chime TTS and set the default TTS platform.

The Announcement Script

I use the AccuWeather integration for weather updates and the CalDAV integration to retrieve my calendar events.

My morning announcement includes:

  • The date
  • The current and high temperatures
  • The daily and nightly weather conditions
  • Events from my family and work calendars

How the Script Works

  1. Retrieving Calendar Events: The script fetches events from my family and work calendars for the next 12 hours. I chose 12 hours to avoid announcements about events happening the next day if I enter my office later in the morning. The events are stored in the agenda variable.
  2. Generating the Audio Announcement: The Chime TTS integration generates the spoken message, using a chime sound at the beginning to signal that an announcement is coming.
  3. Personalized Greeting: The message dynamically selects “Good morning,” “Good afternoon,” or “Good evening” based on the current time.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
sequence:
  - action: calendar.get_events
    target:
      entity_id:
        - calendar.family_jackie
        - calendar.christopher_hansen
    data:
      duration:
        hours: 12
        minutes: 0
        seconds: 0
    response_variable: agenda
  - action: chime_tts.say
    metadata: {}
    data:
      chime_path: bells
      announce: false
      message: >-
        {% set current_hour = now().strftime('%H') | int %}
        {% if current_hour < 12 %}
          {% set greeting = 'Good morning' %}
        {% elif current_hour < 18 %}
          {% set greeting = 'Good afternoon' %}
        {% else %}
          {% set greeting = 'Good evening' %}
        {% endif %}
        
        {{ greeting }} Chris, it is {{ now().date() }}. 

        Currently the Real Feel temperature is {{ state_attr('weather.home',
        'temperature') }} degrees, with a high of {{
        states('sensor.home_realfeel_temperature_max_day_0') }}

        Today it will {{ states('sensor.home_condition_day_0') }}

        Tonight {{ states('sensor.home_condition_night_0') }}

        Your family calendar

        {% for event in agenda["calendar.family_jackie"]["events"] %}   
          {{ (event.start |   as_datetime).strftime('%I:%M %p') }} {{event.summary }}. 
        {% endfor %}

        Your work calendar

        {% for event in agenda["calendar.christopher_hansen"]["events"] %}   
          {{ (event.start |   as_datetime).strftime('%I:%M %p') }} {{event.summary }}. 
        {% endfor %}

        Have a productive day!
    target:
      entity_id: media_player.office
alias: Good morning Chris
description: Good morning message for Chris

Automations

To ensure the Good Morning Message plays only once per day, I created an input boolean.

Good Morning Chris Automation

This automation triggers the script when:

  • The presence sensor detects the office becoming occupied.
  • My Apple Watch is detected in the office area.
  • The input boolean is off.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
alias: Good Morning Chris
triggers:
  - trigger: state
    entity_id: binary_sensor.office_presence_sensor
    to: "on"
conditions:
  - condition: state
    entity_id: sensor.chris_apple_watch_area
    attribute: area_name
    state: Office
  - condition: state
    entity_id: input_boolean.good_morning_message
    state: "off"
actions:
  - action: script.good_morning_chris
  - action: input_boolean.turn_on
    target:
      entity_id: input_boolean.good_morning_message
mode: single

Nightly Reset Automation

At 4:00 AM, an automation resets the good_morning_message boolean, allowing the announcement to trigger again the next day.

1
2
3
4
5
6
7
8
9
10
11
12
alias: Nightly helper reset
triggers:
  - trigger: time
    at: "04:00:00"
conditions: []
actions:
  - action: input_boolean.turn_off
    target:
      entity_id: input_boolean.good_morning_message
mode: single

Conclusion

This project has been a great addition to my morning routine. It keeps me on track by giving me an audible summary of my day while I settle into work. Combined with my desk dashboard, I now have a complete overview of my agenda every morning.

Affiliate Disclosure
Chris Hansen Tech is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to Amazon.com. As an Amazon Associate, I earn from qualifying purchases.

This post is licensed under CC BY-SA 4.0 by the author.