Be Smart, Go Local.

Automating Home Office with the Apollo MSR-2 Presence Sensor

The Apollo MSR-2 is a reliable and feature-rich mmWave radar occupancy sensor. Read how I automate my home office with the MSR-2 and boost my productivity.

If you follow SmartHomeScene frequently, you are aware Apollo Automation is very often recommended throughout our content. Apollo produces well-made, feature-rich multi-sensors that run ESPHome firmware and work with Home Assistant out of the box. Any cloud dependency is completely eliminated from the picture and you are free to customize Apollo devices however you see fit.

Recently, Apollo automation officially joined the Works with Home Assistant program, certifying three of their devices. These are actually the first-ever ESPHome devices to receive the Works with Home Assistant certification and join the ever growing list of HA friendly brands.

The three devices Apollo chose to certify (for now) are:

Apollo MSR-2

Apollo MSR-2

Wi-Fi 2.4GHz

LD-2410B

ESPHome

Apollo MTR-1

Apollo MTR-1

Wi-Fi 2.4GHz

LD-2450

ESPHome

Apollo AIR-1

Apollo AIR-1

Wi-Fi 2.4GHz

CO2, CO, PM, VOC

ESPHome

SmartHomeScene has written, deep dive reviews on each of those sensors, linked above. You can check them out to understand why Apollo Automation is a fan-favorite brand and what it does better than most.

This article is a bit different. This article is a deep dive on the automation and utility aspect of the Apollo MSR-2, which has been deployed since day one in my office as a silent productivity partner. While the MSR-2 is primarily an occupancy sensor, it’s also a very feature-rich multi-sensor which opens up a canvas of automation possibility. It’s also the smallest smart presence sensor ever made.

Installing and positioning the MSR-2

The Apollo MSR-2 is a highly capable and reliable occupancy sensor. It’s based on the Hi-Link LD2410B mmWave radar sensor and has a still detection distance of 6 meters with an angle of 60×60° cone. It can be fine-tuned and adjusted to your space, eliminating any possible false triggers. This flexibility is what allows the MSR-2 to be fully utilized in a Home Assistant smart home, but can also be quite involved in making it work properly.

Every parameter of the MSR-2 is configured to match my office space, including distance and sensitivity. As my desk is pretty huge and can accommodate my PC case, I keep it on the desk to my left side. I installed the MSR-2 with a sticker on top of it and aimed it towards me and towards the office entrance on the opposite side. I managed to position and fine tune the sensor to capture everything I want to monitor in the office.

Here’s how it looks like:

Automating Home Office with Apollo MSR-2 Occupancy Sensor SmartHomeScene Hero Image

My PC motherboard also has an option to supply power to peripherals via USB even when the PC is turned off. This needs to be enabled in the BIOS and works very reliably for my model, MSI Tomahawk Z790. I use the this feature power the MSR-2 this way, eliminating the need for a separate 5V1A adapter.

Entering the office automations

When I enter the office, the first automation of the day is executed. This is a simple automation that sets the ceiling lights to a bright, cool white mode and toggles the SwitchBot Bot which turns on my coffee brewer. As my coffee maker is not smart, I need to clean and prepare everything the night before.

This automation is the simplest of the bunch and here’s how it looks like:

alias: Office - Morning Kickstart
description: >-
  Set lights to cool white, and toggle coffee maker when presence
  is detected in the morning.
triggers:
  - entity_id: binary_sensor.apollo_msr_2_radar_target
    to: "on"
    trigger: state
conditions:
  - condition: time
    after: "07:00:00"
    before: "08:00:00"
actions:
  - action: light.turn_on
    target:
      entity_id:
        - light.office_ceiling_light
    data:
      brightness_pct: 100
      rgb_color:
        - 255
        - 255
        - 255
  - action: switch.turn_on
    target:
      entity_id:
        - switch.coffee_maker_bot
    data: {}
mode: single

As I always enter the office between 07:00 – 08:00 AM on workdays, the condition ensures the automation does not run during the rest of the day. No other person uses this office, so this time-based condition is enough to trigger the automation reliably for me. You can expand on this and add more conditions if you need to, like an input Boolean helper, which would ensure the automation is run only when you need it to.

Further, I use the combined radar entity of the MSR-2 as a trigger which works very well. I could also use the moving target entity, but for this particular automation there is no need as the combined entity inherits its state from the still and moving entities anyway. The still target and moving target entities of the MSR-2 are useful for different purposes, more on those later.

Work day automations

The next automation is triggered when I actually sit on my work chair. This automation uses the Xiaomi Linptech Seat Pressure Sensor PS1BB as a trigger instead of the MSR-2. For reference, the PS1BB is an off-the-shelf solution for a pressure sensor, a thin contact band which can be installed under your bed, chair or sofa.

Here’s how it looks like under my own chair:

Xiaomi Linptech PS1BB Pressure Sensor - Installed under Chair
Xiaomi Linptech PS1BB Seat Pressure Sensor installed under my office chair

This automation does only two things. It powers on my PC via Wake-on-LAN and starts playing a work mode Spotify playlist on my smart office speakers. I used to boot up various Windows apps on a delay with this automation too, but I found it’s not necessary as I’ve set them to auto-start with Windows anyway. If you do need to start Windows app through Home Assistant, I found using HASS.Agent to be great at achieving this.

Here’s how this automation looks like:

alias: Office - PC Wakeup with Music Assistant
description: >-
  Wakes up the PC and starts playing "Work Mode" playlist using Music
  Assistant.
triggers:
  - entity_id: binary_sensor.linptech_ps1bb_pressure_state
    to: "on"
    trigger: state
actions:
  - action: wake_on_lan.send_magic_packet
    data:
      broadcast_port: 9
      mac: 04:7C:XX:XX:XX:XX
  - action: music_assistant.play_media
    data:
      media_id: spotify://playlist/xxxxx
      media_type: playlist
      target:
        entity_id: media_player.office_speakers
mode: single

It’s worth noting that Wake-on-LAN can be considered an unreliable way to boot up your PC for many people. It depends largely on your hardware, so whether or not you will be able to make it work is an unknown variable you must explore yourself. Obviously, using WoL is not the only solution to wake up a PC.

Tuya Zigbee Fingerbot Plus Button Pusher - Featured Image
Tuya Zigbee Fingerbot to wake up a PC

For a while, I used a Tuya Zigbee Fingerbot to boot up my PC. This was a testing experiment only, as Wake-on-LAN has always worked reliably for me with my MSI Tomahawk motherboard. The fingerbot on the other hand, may be the solution you need if you cannot make WoL work. As it’s a mechanical switch, it has never failed to trigger during the time I had it deployed as a wake up switch. It uses a single CR2 battery which lasts ages.

Focus mode input boolean

The first thing I wanted to solve was eliminate disruptions whenever I am heavily focused on a task. To achieve this, I created a simple input boolean called focus mode. Whenever the MSR-2 detects me sitting still in front of the PC for 20 minutes, it enables the input boolean focus mode. Conversely, whenever it detects me as away from keyboard for 5 minutes it disables it.

This simple automation uses the still target entity of the MSR-2 and works very reliably. Here’s how it looks like:

alias: Office - Manage Focus Mode
description: Enables/disables focus mode based on stillness.
triggers:
  - entity_id:
      - binary_sensor.apollo_msr_2_radar_still_target
    to: "on"
    for:
      minutes: 20
    id: detected
    trigger: state
  - entity_id:
      - binary_sensor.apollo_msr_2_radar_still_target
    to: "off"
    for:
      minutes: 5
    id: cleared
    trigger: state
actions:
  - choose:
      - conditions:
          - condition: trigger
            id: detected
        sequence:
          - target:
              entity_id: input_boolean.focus_mode
            action: input_boolean.turn_on
            data: {}
      - conditions:
          - condition: trigger
            id: cleared
        sequence:
          - target:
              entity_id: input_boolean.focus_mode
            action: input_boolean.turn_off
            data: {}
mode: single

Focus mode automation

Now, whenever focus mode is enabled it executes several actions in a separate automation. First, it sets my phone to do not disturb mode. This allows me to focus at the task at hand and not be disrupted by anyone or anything except contacts in my emergency list.

Turning on Do Not Disturb Mode on phone via Home Assistant
Do Not Disturb turned on via Home Assistant


I’ve written in detail how to control the do not disturb feature of a phone, by executing a command from Home Assistant. It requires a special accessibility permission which is prompted only when you initially send the command.

My Galaxy S24 even distinguishes when Do Not Disturb has been turned on from Home Assistant.

Next, it sets the office ceiling light to a warm yellow color with lower brightness. This is a personal preference as I found I am able to focus more easily with a warm light. All other ambient lights I have around the office are turned off during the day, as I found they are more of a distraction rather than help.

Finally, this mode changes the music playlist to a focus mode playlist, a curated list of soft tunes that go well with the work I’m doing for SmartHomeScene. For those curious, this is my own personal list based on the The Witcher Fantasy Ambient playlist on Spotify.

Here’s how this automation looks like:

alias: Office - Focus Mode Automation ON
description: >-
  Turn on Do Not Disturb, change ceiling lights to warm color, change Spotify
  playlist
triggers:
  - trigger: state
    entity_id:
      - input_boolean.focus_mode
    to: "on"
conditions: []
actions:
  - action: notify.mobile_app_s24_ultra
    data:
      message: command_dnd
      data:
        command: priority_only
  - action: light.turn_on
    metadata: {}
    data:
      kelvin: 2000
      brightness_pct: 60
    target:
      entity_id: light.office_ceiling_light
  - action: music_assistant.play_media
    data:
      media_id: spotify://playlist/xxxxx
      media_type: playlist
      target:
        entity_id: media_player.office_speakers
mode: single

Now, whenever I’m actively working, the state of the above devices stays like I set them up until I turn off Focus Mode. However, when Focus mode gets turned off during the day, it only reverts back the Do Not Disturb Mode on my phone. I leave the lights and music playing even if I’m not in the office. Everything gets turned off when I leave the office at the end of the day, explained further bellow.

Here’s how this automation looks like:

alias: Office - Focus Mode Automation OFF
description: >-
  Turn off Do Not Disturb
triggers:
  - trigger: state
    entity_id:
      - input_boolean.focus_mode
    to: "off"
conditions: []
actions:
  - action: notify.mobile_app_s24_ultra
    data:
      message: command_dnd
      data:
        command: off
mode: single

Handling incoming calls

Unfortunately, it appears I get the highest amount of phone calls while I’m working and I’m focused. My emergency contact list is thin because of this, and the people close to me know not to call me during those hours of the work day except for emergencies. But, when they do, do not disturb mode is bypassed automatically and the calls come as they normally would. Note: This is a smartphone feature, not an automation.

image here blinking in blue apoolo

For every other incoming call, I use an automation to notify me that I have a call pending when focus mode is active. This simple automation blinks the on-board LED of the Apollo MSR-2 in blue, whenever the phone state changes to ringing. As the MSR-2 is always in my peripheral vision, I notice the blink and choose whether I want to react or no, depending on what I’m doing.

Here’s how this simple automation looks like:

alias: Office - Manage Incoming Calls
description: Blink the light in blue when there's an incoming call when in Focus Mode
triggers:
  - trigger: state
    entity_id:
      - sensor.sm_s928b_phone_state
    to: ringing
conditions:
  - condition: state
    entity_id: input_boolean.focus_mode
    state: "on"
actions:
  - repeat:
      count: 5
      sequence:
        - target:
            entity_id: light.apollo_msr_2_rgb_light
          data:
            rgb_color:
              - 26
              - 24
              - 175
            brightness_pct: 100
          action: light.turn_on
        - delay:
            milliseconds: 500
        - target:
            entity_id: light.apollo_msr_2_rgb_light
          action: light.turn_off
          data: {}
        - delay:
            milliseconds: 500
mode: single

Whenever the phone rings while focus mode is active, the on-board LED of the MSR-2 blinks 5 times notifying me of the call pending. The sensor is called phone state and you can enable it in the Home Assistant companion app.

Device testing mode automations

If you follow SmartHomeScene frequently, you already know I examine the hardware in detail of every smart device I review. This process includes actually dismantling the device, taking a lot of photos and writing an overview of each component worth talking about. For example, here’s the latest Zemismart MTP1 Roller Shade Driver disassembled on my work bench:

Zemismart Matter Over Thread Roller Shade Driver MTP1 Review: Fully Dismantled
Zemismart MTP1 Thread Roller Shade Driver Disassembled

I have a separate desk in the corner of my office that I use as a workbench. This is where devices get dismantled and photographed as well as new, DIY devices are created. Now, taking images require sufficient light, which I handle by utilizing the zones feature of the MSR-2.

Whenever I move to the corner of the office, the MSR-2 detects me in zone 3 and triggers an automation that set the ceiling lights to bright white at 100% and turns on a spotlight lamp (similar to this Zigbee floodlight), illuminating the space for taking images.

Here how it looks like:

alias: Office - Device testing mode
description: "Set lights to device testing mode, at 100% brightness"
triggers:
  - entity_id:
      - binary_sensor.apollo_msr_2_radar_zone_3_occupancy
    to: "on"
    trigger: state
    id: zone_occupied
  - entity_id:
      - binary_sensor.apollo_msr_2_radar_zone_3_occupancy
    to: "off"
    trigger: state
    id: zone_cleared
actions:
  - choose:
      - conditions:
          - condition: trigger
            id: zone_occupied
        sequence:
          - data:
              brightness_pct: 100
              kelvin: 6500
            action: light.turn_on
            target:
              entity_id:
                - light.office_ceiling_light
                - light.office_spotlight_lamp 
      - conditions:
          - condition: trigger
            id: zone_cleared
        sequence:
          - action: light.turn_off
            data: {}
            target:
              entity_id: light.office_spotlight_lamp
mode: single

This automation is rather simple and uses IDs to trigger or reverse the actions once I exit zone 3. I set the off action to turn off only the spotlight when I’m out of the area, but keep the ceiling lights at full white. Those change back to dimmer, warmer color once I’m back in front of the PC and into focus mode.

Health automation

People who work in offices and sit on a chair all day, know how bad this can get for a persons health. If you sit too much, don’t stretch or don’t drink enough water it can be very bad for your health. This is why it’s important to stand up, stretch from time to time and drink enough water. I keep a jug next to my keyboard at arms length at all times. A simple glance reminds me to stay hydrated throughout my work day.

Now, this is where the Apollo MSR-2 truly shines. Once my work day is underway, I use the MSR-2 to keep me refreshed, healthy and in check. I created an automation utilizing the Piezo buzzer of the MSR-2, to remind me to stand up, stretch and maybe do a few sit-ups. Debatable, but at least I try.

As health cannot be sacrificed for anything, this automation runs on a fixed timer, ignoring everything else like my focus mode boolean. Every 50th minute of every hour during workdays, the automation triggers and plays Mission Impossible through the MSR-2’s piezo buzzer. The automation is conditioned only by the time of day, so it wont run after hours. Here’s how it looks like:

alias: Office - Health Automation
description: Remind me to stand up, stretch and do a few sit-ups
triggers:
  - trigger: time_pattern
    minutes: "50"
conditions:
  - condition: time
    after: "08:00:00"
    before: "16:00:00"
    weekday:
      - mon
      - tue
      - wed
      - thu
      - fri
actions:
  - action: esphome.apollo_msr_2_play_buzzer
    data:
      song_str: >-
        mission_imp:d=16,o=6,b=95:32d,32d#,32d,32d#,32d,32d#,32d,32d#,32d,32d,32d#,32e,32f,32f#,32g,g,8p,g,8p,a#,p,c7,p,g,8p,g,8p,f,p,f#,p,g,8p,g,8p,a#,p,c7,p,g,8p,g,8p,f,p,f#,p,a#,g,2d,32p,a#,g,2c#,32p,a#,g,2c,a#5,8c,2p,32p,a#5,g5,2f#,32p,a#5,g5,2f,32p,a#5,g5,2e,d#,8d
mode: single

Leaving the office automations

When I leave the office at the end of the day, a simple automation turns everything off behind me. This automation is triggered by the main MSR-2 radar target entity, conditioned by the time of day. As I usually leave after 16:00, it only executes if this condition is met. Here’s how it looks like:

alias: Office - Leaving The Office
description: Turn off everything when no presence is detected after 16:00 PM
triggers:
  - trigger: state
    entity_id:
      - binary_sensor.apollo_msr_2_radar_target
    to: "off"
conditions:
  - condition: time
    after: "16:00:00"
    before: "07:00:00"
actions:
  - action: light.turn_off
    metadata: {}
    data: {}
    target:
      entity_id:
        - light.office_ceiling_light
        - light.office_spotlight_lamp
        - light.office_ambient_puck
  - action: media_player.turn_off
    data: {}
    target:
      entity_id: media_player.office_speakers
mode: single

My PC goes to sleep automatically after 20 minutes of inactivity. The only thing that I need to do manually is clean and prepare the coffee maker for the next morning. With this automation, my work day is completed.

Final Thoughts

Automating my office with the MSR-2 is an ongoing work in progress. For now, these automations keep me focused, productive and in check. The flexibility and features of the MSR-2 is what essentially allows my office to be automated to this level. I’ve mentioned many times I consider the Apollo Automation MSR-2 to be the best presence sensor for Home Assistant ever made, all things considered.

While I prefer using Zigbee in a smart home, ESPHome-based occupancy sensors like the MSR-2 are miles ahead of Zigbee sensors. At least, that has been the case up to this point. Check out the Reviews section to find more reviews on presence sensors, a device type I review very frequently on SmartHomeScene. Or check out the curated list of best occupancy sensors for Home Assistant.

Apollo Automation devices are available on their Official Webstore (US) and OpenCircuit (EU)

You got any ideas for automating the office? Share them in the comments bellow.

Leave a Comment