Close

OpenMote Is Compatible with Esphome & Home Assistant

A project log for OpenMote: Arduino-Compatible Controller for Makers

Transform Your Old Wii Remotes into a Versatile Tool for Home Automation, Gaming, and DIY Projects

gangwa-labsGangwa Labs 10/11/2025 at 04:570 Comments

Hello again hackers!

I come bearing good news about the universal remote aspect of OpenMote! After 4 hours of bug fixing and chasing a corrupt platformio file I am happy to announce that OpenMote is fully compatible with Esphome and by extension Home assistant! I've provided a lovely gif showing the wireless and automation features of OpenMote!

https://drive.google.com/file/d/1KpuRrlwi4Olt1J8T5HpseYAywZVrz9lH/view?usp=sharing (sorry for the link can't figure out how to attach a gif or webp...)

In this demo OpenMote is Connecting to a home Wifi Network, sending MQTT calls to another esp32s3 and has full OTA (over the air updating) functionality.

I'm quite proud of the universality of OpenMote and am excited to see what everyone is able to build and control with it!

Tune in and follow this project as next update will be about Bluetooth keyboards and the possibilities that this opens up for OpenMote to control not just your computer but even your phone!?

I've attached the YAML file for OpenMote and the Light in this post so check it out if you want to replicate my project, you'll just have to switch keys for your own configurations.

esphome:
  name: light
  friendly_name: Light

esp32:
  board: esp32-s3-devkitc-1
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: ""

ota:
  - platform: esphome
    password: ""

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Light Fallback Hotspot"
    password: ""

mqtt:
  broker:    # 👈 MUST be your computer’s local IP
  port: 1883
  discovery: false
  # Listen for commands from the remote
  on_message:
    # Toggle command for the A button
    - topic: light_strip/command/toggle
      then:
        - light.toggle: my_led_strip

    # Next Color command for Button 1
    - topic: light_strip/command/color_up
      then:
        - lambda: |-
            static const std::vector<Color> colors = {
              Color(255, 0, 0),   // Red
              Color(255, 165, 0), // Orange
              Color(255, 255, 0), // Yellow
              Color(0, 255, 0),   // Green
              Color(0, 0, 255),   // Blue
              Color(75, 0, 130),  // Indigo
              Color(238, 130, 238),// Violet
              Color(255, 255, 255) // White
            };
            
            id(color_index) = (id(color_index) + 1) % colors.size();
            auto new_color = colors[id(color_index)];
            
            auto call = id(my_led_strip).turn_on();
            // ✅ CORRECTED LINE: Pass the R, G, and B components separately.
            call.set_rgb(new_color.r / 255.0f, new_color.g / 255.0f, new_color.b / 255.0f);
            call.perform();

    # Previous Color command for Button 2
    - topic: light_strip/command/color_down
      then:
        - lambda: |-
            static const std::vector<Color> colors = {
              Color(255, 0, 0),   // Red
              Color(255, 165, 0), // Orange
              Color(255, 255, 0), // Yellow
              Color(0, 255, 0),   // Green
              Color(0, 0, 255),   // Blue
              Color(75, 0, 130),  // Indigo
              Color(238, 130, 238),// Violet
              Color(255, 255, 255) // White
            };

            id(color_index)--;
            if (id(color_index) < 0) {
              id(color_index) = colors.size() - 1;
            }

            auto new_color = colors[id(color_index)];

            auto call = id(my_led_strip).turn_on();
            // ✅ CORRECTED LINE: Pass the R, G, and B components separately.
            call.set_rgb(new_color.r / 255.0f, new_color.g / 255.0f, new_color.b / 255.0f);
            call.perform();

# A global variable to keep track of which color is currently selected
globals:
  - id: color_index
    type: int
    restore_value: no
    initial_value: '0'

# Define the LED strip
light:
  - platform: fastled_clockless
    id: my_led_strip
    name: "LED Strip"
    pin: GPIO8
    num_leds: 86
    chipset: WS2812B
    rgb_order: GRB
    
captive_portal:
esphome:
  name: openmote
  friendly_name: openmote

esp32:
  variant: ESP32S3
  framework:
    type: arduino

# Enable logging
logger:
mqtt:
  broker: xxx.xxx.x.xxx # 👈 replace with your computer’s local IP or your MQTT server's IP
  port: 1883
  discovery: false
  id: mqtt_client
  ssl: false


# Enable Home Assistant API
api:
  encryption:
    key: "" #replace with your own Key!

ota:
  - platform: esphome
    password: "" #replace with your own Key!

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Openmote Fallback Hotspot"
    password: "" #replace with your own Key!

binary_sensor:
  - platform: gpio
    name: "A Button"
    pin:
      number: GPIO14
      mode: INPUT_PULLUP
      inverted: True
    on_press:
      - mqtt.publish:
          topic: light_strip/command/toggle
          payload: "TOGGLE"

  - platform: gpio
    name: "Button 1 (Next Color)"
    pin:
      number: GPIO37
      mode: INPUT_PULLUP
      inverted: True
    on_press:
      - mqtt.publish:
          topic: light_strip/command/color_up
          payload: "UP"

  - platform: gpio
    name: "Button 2 (Previous Color)"
    pin:
      number: GPIO38
      mode: INPUT_PULLUP
      inverted: True
    on_press:
      - mqtt.publish:
          topic: light_strip/command/color_down
          payload: "DOWN"
captive_portal:
    

Discussions