BuildIng a Smart Light Automation With C4002 MmWave Radar and ESPHome in Home Assistant

by Jaychouu in Circuits > Electronics

88 Views, 1 Favorites, 0 Comments

BuildIng a Smart Light Automation With C4002 MmWave Radar and ESPHome in Home Assistant

e1ae77f554ad43649332ab5838b31f65.png

Previous article: From PIR to mmWave: My Smart Lighting Automation in Home Assistant


This tutorial is a step-by-step guide to building a presence-sensing light automation system using FireBeetle 2 ESP32-C6, the C4002 mmWave radar sensor, and Home Assistant. The system automatically turns on the lights when someone is present and turns them off after the area is vacant.

Throughout this guide, you’ll learn the complete process, including ESPHome configuration, MQTT relay integration, and writing Home Assistant automation rules, enabling you to create a reliable and responsive light automation setup.

Supplies

Software Preparation

  1. Home Assistant host (Home Assistant OS / Supervised / Container versions are all supported)[https://www.home-assistant.io/installation/]
  2. Arduino IDE


Hardware Preparation

  1. FireBeetle 2 ESP32-C6 IoT Development Board x 2
  2. Fermion: C4002 mmWave Human Presence Sensor x 1
  3. Gravity: Easy Relay Module x 1
  4. USB LED x 1
  5. Jumper Wires 9" F/F x 1
  6. USB 3.0 to Type-C Cable x 2
  7. 4×AA Battery Holder x 1
  8. AA Batteries x 4
  9. DC Barrel Jack Adapter - Female x1

Connecting the C4002 for Human Presence Detection

f8d383af2f7c4f23a17a6f49af0f1a4a.png
7d702767960840a8bf1f17a69048440e.png
5ad463bd88df4effa9798528c1946b89.png
9f0c8ae5de204e2183d82596dbd18a18.png
5336143609554584982a309914ae511d.png
e0fa6cf0a8c54019a36a7f6b29068726.png
3bc11b3609d8429abed2a1f28e892fc1.png
920dbddc09b5497a86f95aa10f49c12e.png
4c4b97b19e404444a0165b227f0e3a70.png
12647a48d4df43f8b7d0c1ff4aec35cb.png
de6a49d48ba644b9a2cf7cfd8c93e897.png
ace481723cde435ca616d26f66684992.png
645084a6ad59499bbd9fbe7fa6433012.png
5b45ba9db61c4861a75b09fa8a78b9b7.png
c6682dd9db9646eba30c2f53dd894c56.png
4a11cad212bc4af1b868010a640c5a22.png
7384867d10994b2e921801cecdc163b0.png
cc28f57ed3e447ca9c06c74a6e039b5f.png
93d7bc99fe1442a5b9920819621ac5d3.png
26d9eb5c36d74e4795963ab7a401fd17.png
8d978e1142cb43e5a3f7c46e425a4a98.png
2a0eee54b4254783826c17f57e7ab4fa.png
9f719baeb3b14952b5990fc40fb49cf9.png
f5da0b5fe4284619b6a82a996e06f4a4.png
3a41f74a9d31423faa7e89ad01d22467.png
39c0ea316a03417e86de3f58480d4e9f.png
a6cf57864c4e433bae446d0d22899007.png
e1ae77f554ad43649332ab5838b31f65.png

Wiring Diagram of ESP32-C6 and C4002

Refer to the wiring diagram below to complete the connection between the ESP32-C6 and the C4002 mmWave radar sensor.For detailed wiring instructions, please refer to the C4002 Integration with Home Assistant Tutorial(https://www.instructables.com/Building-a-Native-Home-Assistant-MmWave-Presence-S/).


C4002 Integration with ESPHome

Log in to the Home Assistant system. Click on 'ESPHome Builder' in the left sidebar to enter the ESPHome page.


On the ESPHome page, click + NEW DEVICE.


Next, on the device creation wizard page, simply click CONTINUE.


Enter a custom device name (e.g., Presence Sensor), then click NEXT.


On the hardware model selection page, choose ESP32‑C6 for the FireBeetle 2 ESP32‑C6 you are using. When the page shows Configuration created, click SKIP.


After the device is successfully created, go to the ESPHome device management list and locate the newly created presence-sensor device.


Click EDIT — this will open the device’s YAML configuration file, as shown below.


Paste the following configuration code for the FireBeetle 2 ESP32-C6 and the C4002 sensor at the end of the YAML file.

# UART Configuration
uart:
id: uart_bus
tx_pin: GPIO5
rx_pin: GPIO4
baud_rate: 115200

# External components
external_components:
- source:
type: git
url: https://github.com/cdjq/esphome.git
ref: dev
components:
- dfrobot_c4002
refresh: 0s

# C4002 Component Configuration
dfrobot_c4002:
id: my_c4002
uart_id: uart_bus # Specify UART bus explicitly

# Sensor Configuration Section
sensor:
# C4002 Sensors
- platform: dfrobot_c4002
c4002_id: my_c4002
movement_distance:
name: "Motion Distance"
id: movement_distance_sensor
unit_of_measurement: "m"
accuracy_decimals: 2
icon: "mdi:ruler"
device_class: "distance"
state_class: "measurement"
existing_distance:
name: "Presence Distance"
id: existing_distance_sensor
unit_of_measurement: "m"
accuracy_decimals: 2
icon: "mdi:account"
device_class: "distance"
state_class: "measurement"
movement_speed:
name: "Motion Speed"
id: movement_speed_sensor
unit_of_measurement: "m/s"
accuracy_decimals: 2
icon: "mdi:speedometer"
device_class: "speed"
state_class: "measurement"
movement_direction:
name: "Motion Direction"
id: movement_direction_sensor
icon: "mdi:compass"
# internal: true # Comment out temporarily for data testing
target_status:
name: "Target Status"
id: target_status_sensor
icon: "mdi:target"
# internal: true # Comment out temporarily for data testing

# WiFi Signal Sensor
- platform: wifi_signal
name: "WiFi Signal Strength"
update_interval: 30s
unit_of_measurement: "dBm"
accuracy_decimals: 0
device_class: "signal_strength"
entity_category: "diagnostic"

text_sensor:
- platform: template
name: "Movement Direction Text"
id: movement_direction_text
icon: "mdi:directions"
lambda: |-
if (id(movement_direction_sensor).has_state()) {
int d = id(movement_direction_sensor).state;
if (d == 0) return {"Approaching"};
else if (d == 1) return {"No Direction"};
else if (d == 2) return {"Away"};
else return {"Unknown"};
}
return {"No Data"};
update_interval: 1s

- platform: template
name: "Target Status Text"
id: target_status_text
icon: "mdi:human-greeting"
lambda: |-
if (id(target_status_sensor).has_state()) {
int d = id(target_status_sensor).state;
if (d == 0) return {"No Target"};
else if (d == 1) return {"Static Presence"};
else if (d == 2) return {"Motion"};
else return {"Unknown"};
}
return {"No Data"};
update_interval: 1s

- platform: dfrobot_c4002
c4002_id: my_c4002
c4002_text_sensor:
name: "C4002 Log"
icon: "mdi:message-text-outline"

# Switch Configuration Section
switch:
- platform: dfrobot_c4002
c4002_id: my_c4002
switch_out_led:
name: "Out LED Switch"
icon: "mdi:led-on"
switch_run_led:
name: "Run LED Switch"
icon: "mdi:led-on"
switch_factory_reset:
name: "Factory Reset"
icon: "mdi:restart"
entity_category: "config"
switch_environmental_calibration:
name: "Sensor Calibration"
icon: "mdi:calibration"
entity_category: "config"

# Select Configuration Section - Fixed operating_mode
select:
- platform: dfrobot_c4002
c4002_id: my_c4002
operating_mode:
name: "OUT Mode"
icon: "mdi:account"
entity_category: "config"
options:
- "Mode_1"
- "Mode_2"
- "Mode_3"

# Number Configuration Section
number:
- platform: dfrobot_c4002
c4002_id: my_c4002
max_range:
name: "Max Detection Distance"
unit_of_measurement: "m"
icon: "mdi:ruler"
entity_category: "config"
min_range:
name: "Min Detection Distance"
unit_of_measurement: "m"
icon: "mdi:ruler"
entity_category: "config"
light_threshold:
name: "Light Threshold"
unit_of_measurement: "lx"
icon: "mdi:lightbulb"
entity_category: "config"
area1_min:
name: "Area 1 Min"
unit_of_measurement: "m"
icon: "mdi:ruler"
entity_category: "config"
area1_max:
name: "Area 1 Max"
unit_of_measurement: "m"
icon: "mdi:ruler"
entity_category: "config"
area2_min:
name: "Area 2 Min"
unit_of_measurement: "m"
icon: "mdi:ruler"
entity_category: "config"
area2_max:
name: "Area 2 Max"
unit_of_measurement: "m"
icon: "mdi:ruler"
entity_category: "config"
area3_min:
name: "Area 3 Min"
unit_of_measurement: "m"
icon: "mdi:ruler"
entity_category: "config"
area3_max:
name: "Area 3 Max"
unit_of_measurement: "m"
icon: "mdi:ruler"
entity_category: "config"
target_disappeard_delay_time:
name: "Target Disappear Delay"
unit_of_measurement: "s"
icon: "mdi:timer"
entity_category: "config"


Click INSTALL to start compiling the firmware.


A window will pop up to select the installation method. Choose Plug into this computer, then click Download project to start compiling the firmware.


After the firmware compilation is complete, click Download project, select Factory format in the flashing options, and download the firmware file (named presence-sensor.factory.bin).


Once the firmware download is complete, click Open ESPHome Web.


Make sure the FireBeetle 2 ESP32‑C6 is connected to your computer via a USB cable.


Then, on the flashing tool page, click CONNECT.


In the pop-up serial port selection box, choose the port corresponding to the FireBeetle 2 ESP32‑C6, then click Connect to complete the device connection.


Once the ESP32‑C6 is successfully connected to the flashing tool, click INSTALL on the page.


Click Choose File, select the previously downloaded presence-sensor.factory.bin firmware file, then click INSTALL to start flashing.


Wait for the firmware flashing to complete; the page will indicate when the process is successful.


Unplug the USB cable to disconnect the ESP32‑C6 from your computer. Then, following the wiring diagram below, connect the battery pack, ESP32‑C6, and C4002 to assemble the presence sensor module.


Return to the Home Assistant page, and you should see the presence sensor device online.


On the Home Assistant Overview page, click the three-dot icon in the top right corner and select Edit Dashboard.


Then, click + ADD CARD.


To display data from the C4002 sensor using a card, select an Entities card, then choose the entities related to the C4002 (e.g., Motion Distance).


You can customize the card name and icon, then click Save. The system will create a dedicated Entities card to view real-time data from the C4002 presence detection module, such as detected human motion.


Click Save, and you will see the newly added Entities card on the dashboard, displaying real-time data from the C4002 presence detection module, such as motion speed, distance, and direction.


In addition, you can choose different card types to achieve diverse data visualization effects.


It can display data such as the target status of the presence sensor, presence detection, motion detection, and detection range settings, as shown in the figure below.

Connecting the Relay to Control the Lights

6b52a997c3944b3d9b2140be07e90db2.png
d300246ee0ee43ce87de68c5d5a50951.png
78c88e3a6aa04137ab62fb3e8ed073d1.png
8198456ae2a04610bb2f2971c8c2d112.png
cca4b5170eb341da976cc3cd3ffe1237.png
0d38970ae27c4f9a890135d3e3007aff.png
909362953889470f8dc61d4857b684c2.png
4fe238cf47cb4b7cb7a7ec70ecf36712.png
e1f77ccfdff245a0ab285014121dd64d.png
2fefbab38c684f2cb2efdb2c59c84728.png
2f8dc4b0f35c43ff898345730525f96b.png
9a520d57ed5d4047a3ab6633b482394b.png
d0cc74241d05403b9ef667ef1b5eb14f.png
651c49717c0c49bdaf3d68b6fb9fbd3f.png
a47ab784e5534a129a39daf8db731e5a.png
156b1981307c49b6a399f480b79dacb6.png
55a9fb523b42402cb5a8cf8898ddfe40.png
ef137d293a50479f8c67eb1acc3984ae.png
91b1376b426c4142b170f9553be89f19.png
8cc1371badea40b59d0fbb6f69cff1e3.png
b2043818eea5468ea7d2a037443da48f.png
58bebda9ecf94e2090c8c095fe1b4a49.png
1a064f47cbe34893a9ab0b103cb65407.png
f96a9deb43ea4de08e9bb24c6304f4a2.png

Wiring Diagram for ESP32-C6 and Relay

Refer to the wiring diagram below to complete the wiring between the ESP32-C6, the relay, and the USB light.


Relay Integration into Home Assistant via MQTT

Home Assistant has a built-in MQTT integration. We can establish stable communication between Home Assistant and the ESP32-C6 through MQTT to achieve state synchronization and remote control of the relay (and the USB light), as shown in the figure below.


To establish communication between Home Assistant, the ESP32-C6, and the relay via MQTT, we first need to create an MQTT Broker responsible for sending and receiving messages. Here we use the official add-on in Home Assistant: Mosquitto Broker.

In Home Assistant, open Settings and go to Add-ons.


Then click Add-on store in the bottom-left corner, search for and install Mosquitto broker.


In Home Assistant, open Settings, go to Add-ons, then search for and install Mosquitto broker.

After installation, start the service. It is recommended to enable Start on boot and Watchdog to ensure stable system operation.


To ensure communication security, we need to create a login account for MQTT.

In Home Assistant, go to Settings, select People, and add a new user with a username and password.

This username and password will later be used in the ESP32 program to connect to the MQTT server.


We can write MQTT client code in the Arduino IDE to implement WiFi connection, MQTT communication, and relay driving for the ESP32-C6.

Note: The ESP32-C6 and the Home Assistant host must be connected to the same WiFi network to ensure they are on the same local area network (LAN).

Next, we will write the code for the ESP32-C6 to connect to the network and establish communication via MQTT. Open the Arduino IDE.


Copy and paste the following code into the file.

#include <WiFi.h>
#include <PubSubClient.h>

/* ================== WiFi Configuration ==================
Replace with your own WiFi SSID and password
*/
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";

/* ================== MQTT Configuration ==================
Replace with your MQTT broker IP address
Replace with your MQTT username and password
*/
const char* mqtt_server = "YOUR_MQTT_BROKER_IP";
const char* mqtt_user = "YOUR_MQTT_USERNAME";
const char* mqtt_pass = "YOUR_MQTT_PASSWORD";

/* ================== MQTT Topics ==================
You may change the topic names according to your project
*/
#define TOPIC_STATUS "c4002/status"
#define TOPIC_RELAY_SET "c4002/relay/set"
#define TOPIC_RELAY_STATE "c4002/relay/state"

/* ================== Relay Configuration ==================
Adjust the GPIO pin according to your hardware wiring
*/
#define RELAY_PIN 14
#define RELAY_ON LOW
#define RELAY_OFF HIGH

/* ================== MQTT Client ================== */
WiFiClient espClient;
PubSubClient client(espClient);

/* =================================================
MQTT Message Callback Function
This function is triggered when a subscribed topic
receives a message.
================================================= */
void callback(char* topic, byte* payload, unsigned int length) {

char msg[20];
memcpy(msg, payload, length);
msg[length] = '\0';

Serial.print("MQTT Received: ");
Serial.println(msg);

if (strcmp(topic, TOPIC_RELAY_SET) == 0) {

if (strcmp(msg, "ON") == 0) {
digitalWrite(RELAY_PIN, RELAY_ON);
client.publish(TOPIC_RELAY_STATE, "ON", true);
Serial.println("Relay turned ON");
}
else if (strcmp(msg, "OFF") == 0) {
digitalWrite(RELAY_PIN, RELAY_OFF);
client.publish(TOPIC_RELAY_STATE, "OFF", true);
Serial.println("Relay turned OFF");
}
}
}

/* =================================================
Connect to WiFi Network
================================================= */
void setup_wifi() {

Serial.print("Connecting to WiFi");
WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}

Serial.println("\nWiFi connected");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
}

/* =================================================
Reconnect to MQTT Broker
================================================= */
void reconnect() {

while (!client.connected()) {

Serial.print("Connecting to MQTT...");

if (client.connect("esp32_relay_client",
mqtt_user,
mqtt_pass,
TOPIC_STATUS,
0,
true,
"offline")) {

Serial.println("MQTT Connected");

// Publish online status (retained message)
client.publish(TOPIC_STATUS, "online", true);

// Subscribe to relay control topic
client.subscribe(TOPIC_RELAY_SET);

// Initialize relay state to OFF
digitalWrite(RELAY_PIN, RELAY_OFF);
client.publish(TOPIC_RELAY_STATE, "OFF", true);
}
else {
Serial.println("MQTT connection failed, retrying in 2 seconds...");
delay(2000);
}
}
}

/* =================================================
Setup Function (runs once at boot)
================================================= */
void setup() {

Serial.begin(115200);
delay(2000);

pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, RELAY_OFF);

setup_wifi();

client.setServer(mqtt_server, 1883);
client.setCallback(callback);

Serial.println("Relay system initialization completed");
}

/* =================================================
Main Loop
================================================= */
void loop() {

if (!client.connected()) {
reconnect();
}

client.loop();
}

Due to differences in each user's network environment and Home Assistant configuration, several items in the code must be modified according to actual conditions.

Please replace "YOUR_WIFI_SSID" with the name of the WiFi network you are currently using, and replace "YOUR_WIFI_PASSWORD" with the corresponding WiFi password. It is mandatory to fill in the same WiFi network as the Home Assistant host to ensure the ESP32-C6 and Home Assistant are on the same local area network (LAN).

Please replace "mqtt_server" with the IP address of the Home Assistant host running the Mosquitto Broker. You can check the IPv4 address of the current device in Home Assistant under Settings → System → Network.

After modifying the WiFi and MQTT-related information in the code, you can flash the program to the ESP32-C6 development board. First, click Tools in the top menu of the Arduino IDE, find the Board option, and select DFRobot FireBeetle 2 ESP32-C6. Then go to Tools → Port and select the corresponding serial port device.

Copy and paste the following code into the file.


After confirming that the development board model and serial port are selected correctly, click the Upload button in the top-left corner of the Arduino IDE. The program will then start compiling and flashing to the ESP32-C6. Do not disconnect the USB connection during the flashing process.

Once the program is uploaded successfully, open the Home Assistant page and create an MQTT switch entity. The most common way is to add the configuration by editing the configuration.yaml file. Click File editor, locate the configuration.yaml file, and double-click to open it.


After confirming that the development board model and serial port are selected correctly, click the Upload button in the top-left corner of the Arduino IDE. The program will then start compiling and flashing to the ESP32-C6. Do not disconnect the USB connection during the flashing process.

switch:
- name: "C4002 Relay"
unique_id: c4002_relay
command_topic: "c4002/relay/set"
state_topic: "c4002/relay/ state"
payload_on: "ON"
payload_off: "OFF"
retain: true

After pasting, see the image below.


After saving the file, click Settings, find System, click the button in the top right corner, select Restart Home Assistant, and restart Home Assistant to apply the configuration.


After completing Home Assistant setup, click Settings, then find Devices & services. You will see an entity appear under MQTT. Click on MQTT.


You can now see the newly created relay switch entity under the MQTT integration. Click MQTT to view detailed information about this entity, including its current state and control topics.


Return to the Overview page. Click the Edit Dashboard button in the top-right corner.


Then click + ADD CARD to add a card.


Select the Switch card.


Once you enter the card settings interface, find the previously created ESP32 Relay switch entity in the Entity dropdown menu, set its name to light, then click Save to confirm.


The completed setup page is shown below.


Now you can control the light on and off in the Home Assistant system using the light switch on the dashboard.

When you click the switch on the Home Assistant dashboard to turn it to the ON state, the system sends an on command to the ESP32-C6 via MQTT.After receiving the message, the ESP32-C6 controls the relay to close, thereby turning on the connected light.At the same time, the ESP32-C6 publishes the current state back to Home Assistant via MQTT, and the switch state on the dashboard immediately updates to On.


When you click the switch on the dashboard to set it to the OFF state, Home Assistant will send a turn-off command to the ESP32-C6 via MQTT. After receiving the message, the ESP32-C6 will disconnect the relay circuit, thereby turning off the light.

Writing Automation Rules in Home Assistant

fba39576b6024272b03a841c1f297f48.png
d6b2f562e15244b79fad3f9e85d85863.png
edf7c42118d846d68b988b1639ab7d61.png
3721c00f1128458fb5bb35968b7cd806.png
9e06f6614af8461aa6662905e33f44cd.png
f9b61b97e1814432a7b82be3e1675353.png
a8e6ba58963745a7a888dddc58de2367.png
736461b89f1940f68a43cb892a86284b.png
a7d6d0a4a63d4fdb812f7c3761003e05.png
5515c65b96da43459bdd5f3a1a5abb16.png
ba37a5021d6b4c04aa2138c3799cb838.png
41467757afe74faeb419a5fe4e5ab3f7.png
aa30e8cc45104cdfbbf4e5ba0ef423f6.png
3e3a54fd93ef46dc8abfab53d90c0f86.png
9f20ab63816a4dd897c18ff46aa46d49.png
6a8849f01b0149e896524c6f5a65f877.png
dd518fad32b7484ea1534cc9cf2435c5.png
d1cc78b493884e5b8a855ac865211bd2.png
2f709b90c9e24e5ca7e8994e088cedb3.png
3fb5ec7e06f24a9199b1755d82aefc24.png
fdfbf26ad9a44344a6968c5e26f35cf7.png
e74981756a7d4c5dafbd08888bf53881.png
376939a3fd7440dbb9f0773499bceddc.png
abbb0c47506f404b8242bd1ffe2f2e8c.png

"When the room is occupied, the lights turn on; when the room is unoccupied, the lights turn off." Therefore, the trigger for the automatic lighting automation should be "room occupancy status". The entity sensor.esp32_c6_target_status_text – which is output by the C4002 millimeter-wave radar sensor in Home Assistant for target detection – returns three states: unoccupied, person stationary, and person moving. For ease of use in automations, we need to convert it into a binary sensor that only indicates two states: occupied or unoccupied.

On the Home Assistant interface, click 'File editor', locate the configuration.yaml file, and double-click to open it.


Add the following content at the end of the configuration.yaml file to create a binary sensor. When the sensor state is Motion or Static Presence, the binary sensor will show on (occupied); otherwise, it will show off (unoccupied).

template:
- binary_sensor:
- name: "Room Occupancy"
unique_id: room_occupancy_binary
device_class: occupancy
state: >
{{ is_state('sensor.esp32_c6_target_status_text', 'Motion')
or is_state('sensor.esp32_c6_target_status_text', 'Static Presence') }}

After saving the file, click 'Settings', find 'System', click the button in the top right corner, select 'Restart Home Assistant', restart Home Assistant to make the configuration take effect.


After the restart is complete, click 'Settings' and find 'Developer tools'.


Click the States tab, enter binary_sensor.room_occupancy in the Entity search box. You can find the occupancy binary sensor we created and its status: 'on' means occupied, 'off' means unoccupied.


Open the dashboard → click Edit Dashboard in the top-right corner.


Click + Add Card, select Entities Card, then choose the entity named Room Occupancy. You can intuitively see that the motion or static status detected by the C4002 has been converted into the binary sensor status.


Next, we will create the automatic light on/off rule. Open the Home Assistant left menu → Settings, click Automations & ScenesAutomations.


Click the + Add Automation in the bottom right corner and select Start with an empty automation.


Click 'ADD trigger', select 'Entity', then select 'State'.Click 'ADD trigger', select 'Entity', then select 'State'.


On the right side, select Room Occupancy for the Entity field. Set To (state) to Detected. Set For (duration) to 00:01:00 (1 minute). This means the automation will be triggered when the room remains in the "Detected (occupied)" state for 1 minute. Finally, set the trigger name to 'when room occupancy changes to detected for 1m'.


After setting up the trigger, we need to add a condition to prevent false triggering.

The C4002 radar has a wide detection range and may detect people outside the room, causing the light to turn on unnecessarily. To improve accuracy, we add a distance limit: only activate when the target is less than 2 meters away (inside the room).

Now configure the Condition:

Click Add condition and select Template.


Enter the following code and click Save.

{% set p = states('sensor.esp32_c6_motion_distance') | float(99) %}
{% set m = states('sensor.esp32_c6_presence_distance') | float(99) %}
{{ p < 2 or m < 2 }}

In this code, we first read the values of two distance sensors: p represents the distance to a moving target, and m represents the distance to a stationary presence. By using float(99) as a fallback, if the sensor temporarily has no data or returns an abnormal value, it will default to 99. This prevents automation errors or false triggers caused by missing data. The final judgment logic is: the condition is met if either the moving distance or stationary distance is less than 2 meters.


In the automation editor, click Add Action, select Switch as the action type, then choose Turn on as the action.


In the switch list, select the relay entity used to control the light: C4002 Relay (corresponding to switch.c4002_relay).

When the automation is triggered and passes the condition check, Home Assistant will send an ON command to the relay, closing the circuit and turning on the light.


After configuring the automatic light-on rule, we need to set up an "auto light-off on prolonged vacancy" rule. This ensures the system automatically turns off the light when the room is unoccupied for a set period, balancing energy efficiency with smart control.

Continue by clicking + Add Automation in the bottom-right corner and select: Start with an empty automation.

Click ADD Trigger, then set the Trigger type: select Entity, then State.Set Entity to Room Occupancy.Set To (state) to Clear.Set For (duration) to 00:01:00 (1 minute).


This setting means: the automation is triggered when the Room Occupancy state changes to Clear (unoccupied) and remains so for 1 minute.

The prerequisite for auto light-off should be: if the room is unoccupied for 1 minute and the light is on, the light-off action is executed. Therefore, set the condition to the light being in the "on" state.

Click Add Condition, select Entity, then click State.


Set Entity to C4002 Relay and State to On. Click Save.


Set up the light-off action the same way:

click Add Action, select Switch, choose Turn off as the action, and select the entity C4002 Relay.


After configuring the automatic light-on and light-off rules, we enter the stage of system verification and tracing to ensure the entire automation loop works as expected.

You can click Trace to track the automatic execution process of events.


First, you can intuitively check the status changes of the Room Occupancy binary sensor on the Home Assistant dashboard.

When someone enters the room, the status changes from off (unoccupied) to on (occupied).

After a 1-minute delay, the relay closes automatically and the light turns on.


When the room has been unoccupied for one minute and the light is on, the relay turns off and the light switches off automatically.