Category: Tips & Tricks

  • Interrupting the Stream: A Home Assistant Bedtime Reminder

    Interrupting the Stream: A Home Assistant Bedtime Reminder

    We rise early, so getting to bed at a reasonable hour can be a challenge, whether it’s summer and the sun is still up past 21:00, or we’re sucked into a streaming show. One of the first things I added to Home Assistant was an evening time announcement to subtly remind or shame us that it is getting late. Since we generally stream using the Apple TV, I added the Apple TV integration for Home Assistant.

    At first, I thought I could send a message to display on the screen every half hour in the evening using HomeKit, but I could not get any version of this example to work. I’m sure I am doing something wrong, or my old Apple TV, which barely runs tvOS 26, has issues. I would still love to add an on-screen notification if anyone has a working example.

    I landed on checking whether media was playing on the Apple TV, pausing whatever was playing, making the time announcement, and then letting it play again. Pausing what is playing, even ever so briefly, gets our attention and makes us aware of the time announcement.

    To do this, I first set a variable to get the state of the Apple TV:

      - variables:
          appletv_was_playing: '{{ is_state(''media_player.living_room'', ''playing'') }}'
    

    With that variable set, I can check its state and take action:

      - if:
          - condition: template
            value_template: '{{ appletv_was_playing }}'
        then:
          - action: remote.send_command
            target:
              entity_id: remote.living_room
            data:
              command: pause
    

    I announce the time on the various media players throughout the place using Chime TTS.

         - action: chime_tts.say
           target:
             entity_id:
               - media_player.bedroom
               - media_player.living_room
           data:
             announce: true
             cache: true
             volume_level: 0.4
             message: >
               {% from 'speech_macros.jinja' import say_time %}
               The time is {{ say_time(now()) }}.
    

    Then, as an extra measure, add a half-second delay as padding, and then resume whatever was playing. The announce flag interrupts any playing audio, but I have found it just plays over whatever the Apple TV is doing.

      - delay:
          milliseconds: 500
      - if:
          - condition: template
            value_template: '{{ appletv_was_playing }}'
        then:
          - action: remote.send_command
            target:
              entity_id: remote.living_room
            data:
              command: play
    

    I’m not accounting for a bunch of edge cases here: What happens if the Apple TV is paused, or if someone presses play during the announcement? I figured I would address these if they ever became an issue.

    As an aside, text-to-speech is unpredictable and sometimes entertaining in how it handles whatever now() tunneled into strftime() outputs. I found a set of natural-language speech macros written in Jinja and tweaked them to my liking, since we prefer 24-hour time. To use this, save these two macros as speech_macros.jinja file in your /config/custom_templates/ folder. Restart or run homeassistant.reload_custom_templates after adding the file.

    {% macro _round_min(t, round_min) %}
      {% set minute = ((t.minute + round_min / 2) // round_min) * round_min %}
      {% set hour = t.hour + (1 if minute == 60 else 0) %}
      {% set minute = 0 if minute == 60 else minute %}
      {{ "%02d:%02d:00" % (hour % 24, minute) }}
    {% endmacro %}
    
    {% macro say_time(t, round_min=0, format_24h=True) %}
      {% if t is undefined or not t is datetime %}
        Macro Arg Type Error: First argument must be a datetime object
      {% elif round_min is defined and not round_min is integer %}
        Macro Arg Type Error: Second argument must be an integer
      {% else %}
        {% if round_min > 0 %}
          {% set t = today_at(_round_min(t, round_min)) %}
        {% endif %}
        {% set hour = t.hour %}
        {% set minute = t.minute %}
    
        {% if format_24h %}
          {% if minute == 0 %}
            {{ t.strftime('%H') }} hundred
          {% else %}
            {{ t.strftime('%H:%M') }}
          {% endif %}
        {% else %}
          {% if hour == 0 and minute == 0 %}
            midnight
          {% elif hour == 12 and minute == 0 %}
            noon
          {% elif minute == 0 %}
            {{ t.strftime('%-I') }} o'clock {{ t.strftime('%p') }}
          {% elif minute < 10 %}
            {{ t.strftime('%-I Oh %-M %p') }}
          {% else %}
            {{ t.strftime('%-I:%M %p') }}
          {% endif %}
        {% endif %}
      {% endif %}
    {% endmacro %}
    

    You call this with {% from 'speech_macros.jinja' import say_time %} The time is {{ say_time(now()) }}. as your message.

    So these don’t play after we go to bed; I check, for of all things, that the white noise machine is turned on. A sign we have gone to bed. You may have other triggers, or you might set a boolean that resets every day.

    Do we get to bed on time? Most nights.

  • iPhone LinkedIn QR code

    iPhone LinkedIn QR code

    Ready access to LinkedIn, really?

    According to LinkedIn,

    The LinkedIn QR code makes it easy to meet someone offline, and stay in touch with them on LinkedIn. This feature provides a simple and efficient way to find LinkedIn members, and then connect with them by quickly scanning a QR code.

    We’re focussed on LinkedIn, but really this could be any QR code: Snapchat, Mastodon, Threads, Instagram… I’m not judging. LinkedIn has become our online resume, but also a professional connection platform. Personally, if I need to reach out to a Mac Admin, I’ll go to the Mac Admins Slack, but I have other connections from past consulting clients to friends and colleagues I have met along the way.

    A shortcut to QR codes

    To set up your LinkedIn QR code for easy access, we’ll start by saving it to a dedicated photo album. This makes it easier for the shortcut to locate the image later. As of the writing of this article, getting to your LinkedIn QR codes is the following 5 steps:

    1. Open the LinkedIn app on your mobile device.
    2. Tap the  QR code in the Search bar at the top of your LinkedIn homepage.
    3. Tap the My code tab to find your QR code.
    4. You can tap:
      1. Share my code to share your QR code via message, email or other third-party apps.
      2. Save to photos to save a copy of your QR code to your mobile device’s photo gallery.
    5. Tap an option from the dropdown that appears, and follow the prompts.

    For our purpose here, Save a copy of your QR code to your photo gallery, and choose the Save code only option.

    Save a copy of your QR code to your photo gallery, and choose the Save code only option.

    The goal in this step is to create a Photo Album with a single photo. That single photo being your QR code.

    1. Open up the Photos app, scroll down to Albums, and tap into Albums.
    2. Tap Create in the upper right, and select New Album.
    3. Give the album a name like “LI QR”.
    4. Click Add Photos and find your QR code.
    5. Click Create.
    6. Alternatively, find the QR code you saved to Photos, and tap into the photo. Tap the … in the upper right corner, and select Add to Album. Select the “LI QR” album.
    7. Another option would be to tap the + when viewing a the QR code image and create the Album with this QR code.
    Create a new album called "LI QR"

    Now, let’s create a shortcut to find and present this QR code. (You can also access this shortcut here.)

    1. Open the Short cuts app, and create a new shortcut.
    2. In the Search Actions field, type “Photos” and select the Find Photos option.
    3. Tap Add Filter and set it to “Album is” and then tap to find your “LI QR” album.
    4. Tap the Limit slider and set it to “Get 1 Item.”
    5. Add another action, this time searching for “Show Result” and it should be default add a Photos variable.
    6. Give it a name like Show LI QR and then tap Done in the upper right.
    7. Long press on the new shortcut and select Details.
    8. Under the Privacy tab, enable Allow Running When Locked.
    9. Tap Done in the upper right.
    Screenshot of the complete Shortcut workflow.

    Finally, let’s set up ready access to this shortcut by assigning it to the Double or Triple-tap Back accessibility function.

    1. In the Settings app, search for “Back Tap.” (Accessibility > Touch)
    2. Tap into Triple Tap and scroll down to Shortcuts.
    3. Select Show LI QR shortcut we created earlier.
    4. Back out or swipe to close the Settings app.
    5. Give the back of your phone a double or triple tap.
    Back Tap accessibility settings

    With this shortcut set up, you’ll never have to fumble through apps to find your LinkedIn QR code again. A quick tap on the back of your iPhone is all it takes to connect with new contacts on the spot. 

    This same shortcut can be used for other social media QR codes, like Instagram or Snapchat, so you’re ready for any networking situation. How are you utilizing Shortcuts?