The gateway guide wires the R60ABD1 60 GHz sleep/breathing radar to an ESP32-S3 and publishes its frames to MQTT. This article is the consume half: pull that MQTT feed into Home Assistant, expose breathing rate and sleep state as entities, put them on a dashboard, and fire two sensible automations. Nothing here is tied to a vendor cloud — your broker, your HA.

The R60ABD1 is not a medical device. Treat the values as indicators, not a diagnosis.

What you need

Enable the MQTT integration

If Home Assistant is not connected to your broker yet, follow the MQTT setup walkthrough first (add the MQTT integration, point it at Mosquitto/EMQX, set credentials). This article assumes the MQTT integration is already connected — below we only declare the R60ABD1 sensors.

The payload

Baseline — exactly what the gateway guide publishes:

{"breath":22,"sleep":1}

Extended (optional) — extend the gateway’s publish to emit these extra keys (every key maps to a R60ABD1 §7 frame; all are safe to add):

{"breath":22,"breath_status":1,"occupancy":1,"sleep":1,"sleep_quality":86,"heart":68}

Entities in configuration.yaml

Baseline entities (breathing rate + raw sleep state):

mqtt:
  sensor:
    - name: "R60ABD1 Breathing Rate"
      unique_id: r60abd1_breathing_rate
      state_topic: "radar/R60ABD1/state"
      value_template: "{{ value_json.breath }}"
      unit_of_measurement: "breaths/min"
      expire_after: 30
    - name: "R60ABD1 Sleep State"
      unique_id: r60abd1_sleep_state
      state_topic: "radar/R60ABD1/state"
      value_template: "{{ value_json.sleep }}"
      expire_after: 1200

Map the numeric sleep state to text with a template sensor:

template:
  - sensor:
      - name: "R60ABD1 Sleep State Text"
        unique_id: r60abd1_sleep_state_text
        state_topic: "radar/R60ABD1/state"
        value_template: >-
          {% set m = {0:'Deep',1:'Light',2:'Awake',3:'Off-bed'} %}
          {{ m[value_json.sleep | int] if value_json.sleep is defined else 'unknown' }}

If you publish the extended payload, add:

mqtt:
  binary_sensor:
    - name: "R60ABD1 Occupancy"
      unique_id: r60abd1_occupancy
      state_topic: "radar/R60ABD1/state"
      value_template: "{{ value_json.occupancy }}"
      payload_on: "1"
      payload_off: "0"
      device_class: occupancy
      expire_after: 1200
  sensor:
    - name: "R60ABD1 Breathing Status"
      unique_id: r60abd1_breathing_status
      state_topic: "radar/R60ABD1/state"
      value_template: "{{ value_json.breath_status }}"
      expire_after: 30
    - name: "R60ABD1 Sleep Quality"
      unique_id: r60abd1_sleep_quality
      state_topic: "radar/R60ABD1/state"
      value_template: "{{ value_json.sleep_quality }}"
      unit_of_measurement: "%"
      expire_after: 1200
    - name: "R60ABD1 Heart Rate"
      unique_id: r60abd1_heart_rate
      state_topic: "radar/R60ABD1/state"
      value_template: "{{ value_json.heart }}"
      unit_of_measurement: "bpm"
      expire_after: 1200

expire_after marks the entity unavailable if the broker goes quiet, so a dropped gateway doesn’t leave a stale number on the dashboard.

Dashboard (Lovelace)

A small Entities card is enough to start:

type: entities
title: R60ABD1 Sleep & Breathing
entities:
  - entity: sensor.r60abd1_breathing_rate
  - entity: sensor.r60abd1_sleep_state_text
  - entity: binary_sensor.r60abd1_occupancy   # extended payload
  - entity: sensor.r60abd1_sleep_quality       # extended payload
  - entity: sensor.r60abd1_heart_rate          # extended payload

Or a Glance card for at-a-glance tiles. The entity_ids above assume the unique_id values set in the YAML; if you let HA auto-generate IDs, check Developer → States for the actual entity_id.

Automations

Two practical triggers. Both use the baseline payload (no extended keys required).

Breathing rate too high (matches the manual’s “high” threshold of >25/min):

automation:
  - alias: "R60ABD1 breathing rate high"
    trigger:
      - platform: numeric_state
        entity_id: sensor.r60abd1_breathing_rate
        above: 25
        for: "00:00:30"
    action:
      - service: notify.notify
        data:
          title: "R60ABD1 breathing alert"
          message: "Breathing rate above 25/min."

Off-bed / away (sleep state 3):

automation:
  - alias: "R60ABD1 off-bed"
    trigger:
      - platform: state
        entity_id: sensor.r60abd1_sleep_state
        to: "3"
    action:
      - service: notify.notify
        data:
          title: "R60ABD1 status"
          message: "Person is off-bed / away."

Notes and safety

Where to go next

Both the R60ABD1 module and the ESP32-S3 board are on Tindie.