The IoT Smart Switch is a battery-powered wireless device designed to control smart home appliances such as
plug sockets and light bulbs. Primarily intended for wall-mounting near doors, it allows users to toggle multiple
lamps with a single press. Designed to resemble a standard light switch, it seamlessly blends into the home environment.
The switch consists of a 3D-printed enclosure and button, housing an ESP32-WROOM development board and a battery. When pressed,
it sends a signal via ESP-NOW to a nearby smart home hub, which then relays the message to a Home Assistant server using MQTT.
Home Assistant automations, such as toggling a smart plug, can be configured to trigger upon receiving the MQTT message.
The hub is essential for maximizing battery life and minimizing delay. While the switch could
function without a hub by sending MQTT messages directly to the Home Assistant server over WiFi,
this approach has significant downsides. Maintaining a WiFi connection consumes a lot of power, meaning
the battery would only last a few days—far from ideal for a wall-mounted device.
One way to extend battery life is by putting the switch into deep sleep, only waking it up to reestablish a WiFi
connection when pressed. However, this introduces another issue: the process of reconnecting to WiFi and the Home
Assistant MQTT broker takes about 10 seconds, creating an unacceptable delay between pressing the switch and turning
on the lights. This completely undermines the device's convenience.
By introducing a hub, the switch can remain in deep sleep, preserving battery life.
When pressed, it wakes up and communicates with the hub using ESP-NOW, a peer-to-peer protocol with minimal latency.
Since the hub is plugged into a power source, it can maintain a constant WiFi connection and instantly relay the ESP-NOW
message to the Home Assistant server, ensuring the lights respond without delay.
The devlopment board has a power indicator LED which is always on even whilst in sleep mode. This is wasteful and reduces the battery life significantly. I desoldered the LED to maximise battery life.
The firmware is written in C++ and optimizes battery life by using the ESP32's
deep sleep functionality. When the button is pressed the device wakes up,
sends a message to the hub over ESP-NOW, then goes back to sleep.
This snippet highlights the key logic behind the switch's functionality:
// Configure ESP-NOW broadcast peer
ESP_NOW_Broadcast_Peer broadcast_peer(ESPNOW_WIFI_CHANNEL, WIFI_IF_STA, NULL);
// Configure wake-up source (when the button is pressed)
esp_sleep_enable_ext0_wakeup((gpio_num_t)BUTTON_GPIO, LOW);
// Prepare message
char data[32];
snprintf(data, sizeof(data), "button 1 has been pressed #%lu", msg_count++);
Serial.printf("Broadcasting message: %s\n", data);
// Send message
if (!broadcast_peer.send_message((uint8_t *)data, sizeof(data))) {
Serial.println("Failed to broadcast message");
}
// Enter deep sleep mode
Serial.println("Going to sleep now...");
esp_deep_sleep_start();