Resurrecting Legacy Wemo Devices (Switches & Motion Sensors) with Home Assistant and Antigravity (agy)

By | July 3, 2026

In the smart home ecosystem, vendor deprecation is a common challenge. When hardware manufacturers terminate cloud support or deprecate mobile setup paths, legacy devices (like Gen 1 and Gen 2 Belkin Wemo smart plugs and motion detectors) often end up as e-waste.

However, because these devices run a completely local UPnP/SSDP control API, they can be reclaimed for 100% local, private smart home control. This guide walks through the network engineering hurdles, custom Python scripts, and Home Assistant configuration required to bring these legacy devices back to life.

1. Resetting Wemo Devices

To re-provision the devices, they must be factory-reset to clear old credentials and start broadcasting their setup networks:

  • Wemo Switch / Wemo Insight Plug: Unplug the switch ➔ hold down the physical Restore button on the top/front ➔ plug it back in while holding ➔ keep holding for 5–10 seconds until the status indicator flashes amber/orange and blue.
  • Wemo Motion Detector: Press and hold the physical reset pinhole button on the back of the sensor for 5–10 seconds until the status light flashes.

Once reset, the devices will broadcast their own setup Wi-Fi networks (e.g., WeMo.Switch.XXX or WeMo.Motion.XXX).

2. Solving Setup & Connection Hurdles

Provisioning legacy Wemo devices over local Wi-Fi presents two major network challenges:

  1. WEP Security Requirements: Older Wemo devices (like the Wemo Motion Detector) secure their temporary setup networks with WEP security using the default password configme, which causes modern network managers to prompt for security keys.
  2. Inactivity & Connection Drops: Legacy Wemo devices immediately terminate client Wi-Fi associations after 8–10 seconds if they do not receive active packets (Reason 4: Disassociated due to inactivity).
  3. Prerequisite: Install the pywemo see https://github.com/pywemo/pywemo
  4. Library Timeout Bugs: Default UPnP library calls (like pywemo.discovery.device_from_description) perform extensive XML descriptor lookups. If a single closed port times out, it aborts the scan, missing the active configuration port.

The Fast Provisioning Solution

To bypass these limitations, we write custom Python scripts that connect explicitly via SSID/BSSID with the configme password, disable host power-saving, and immediately trigger a high-frequency SOAP request to provision the device to your home Wi-Fi (vgv-sopor) within the brief connection window.

Here is the custom script used to provision the Wemo Switches: provision_wemo.py.
And here is the high-frequency script used for the Wemo Motion Detector: provision_motion_fast.py:

# /home/gvoina/scripts/provision_motion_fast.py
import time
import requests
import pywemo
import pywemo.discovery
import pywemo.ouimeaux_device
import subprocess

pywemo.discovery.REQUESTS_TIMEOUT = 10
pywemo.ouimeaux_device.REQUESTS_TIMEOUT = 10

SSID = "vgv-sopor"
PASSWORD = "xxxx"
BSSID = "EC:1A:59:7A:BA:E0"
WEMO_SSID = "WeMo.Motion.7B5"

# Temporarily disable autoconnect on home network to keep connection alive
subprocess.run(["nmcli", "connection", "modify", SSID, "connection.autoconnect", "no"])

try:
    connected = False
    for attempt in range(8):
        print(f"Connection attempt {attempt + 1}...")
        subprocess.run(["nmcli", "device", "wifi", "rescan"], capture_output=True)
        time.sleep(3)
        subprocess.run(["nmcli", "connection", "delete", WEMO_SSID], capture_output=True)
        res = subprocess.run(["nmcli", "device", "wifi", "connect", BSSID, "password", "configme"], capture_output=True, text=True)
        if res.returncode == 0:
            connected = True
            break
        time.sleep(3)
        
    if connected:
        print("Connected successfully! Starting high-frequency probe loop immediately...")
        url = "http://10.22.22.1:49152/setup.xml"
        device = None
        
        # Probe loop: check every 0.5s up to 20 seconds
        for i in range(40):
            try:
                r = requests.get(url, timeout=0.8)
                if r.status_code == 200:
                    device = pywemo.discovery.device_from_description(url)
                    if device:
                        break
            except Exception:
                pass
            time.sleep(0.5)
            
        if device:
            print("Sending Wi-Fi credentials now...")
            status, close_status = device.setup(ssid=SSID, password=PASSWORD, timeout=15.0)
            print(f"Success! Status: {status}, Close Status: {close_status}")
        else:
            print("Failed to reach device setup XML during the connection window.")
finally:
    # Re-enable autoconnect and restore home connection
    subprocess.run(["nmcli", "connection", "modify", SSID, "connection.autoconnect", "yes"])
    subprocess.run(["nmcli", "device", "wifi", "connect", SSID, "password", PASSWORD])

3. Configuring Home Assistant

Standard UPnP/SSDP discovery broadcasts do not cross Docker bridge networks reliably. To ensure your Wemo devices register instantly and remain stable across restarts, configure them as static IPs in your configuration.yaml:

wemo:
  discovery: true
  static:
    - 192.168.1.57   # Wemo Switch 1 (Lampa Dormitor)
    - 192.168.1.190  # Wemo Switch 2 (Lampa Birou)
    - 192.168.1.47   # Wemo Switch 3 (Imprimanta)
    - 192.168.1.123  # Wemo Switch 4 (Masina Spalat)
    - 192.168.1.25   # Wemo Motion Detector (WeMo Motion)

Restart Home Assistant to apply the new static configuration:

docker restart homeassistant

4. Automation Rules

With the Wemo devices fully integrated into Home Assistant, we can configure automations to tie them together. For example, we can turn on the office desk lamp (switch.wemo_switch_2) automatically when the motion detector (binary_sensor.wemo_motion) registers movement.

Add the following rule to your automations.yaml:

- id: 'wemo_motion_turn_on_office_lamp'
  alias: Turn on Office Lamp on Motion
  description: Turn on Lampa Birou when motion is detected
  trigger:
  - platform: state
    entity_id: binary_sensor.wemo_motion
    to: 'on'
  condition: []
  action:
  - service: switch.turn_on
    target:
      entity_id: switch.wemo_switch_2
  mode: single

Trigger a hot-reload of Home Assistant’s automation configs (without restarting) using this command or through the UI:

curl -X POST -H "Authorization: Bearer <API_TOKEN>" http://localhost:8123/api/services/automation/reload

5. Local Command-Line Control

You can verify and control the state of your Wemo devices locally on your host laptop using Python’s pywemo library:

import pywemo

# Discover all local Wemo devices on the subnet
devices = pywemo.discover_devices()
for d in devices:
    print(f"Device: {d.name} | Type: {type(d).__name__} | IP: {d.host} | State: {d.get_state()}")
    
# Control a device directly
if devices:
    my_switch = devices[0]
    my_switch.on()  # Turn switch ON
    my_switch.off() # Turn switch OFF

6. Integrating with Antigravity (agy)

To check the status of your Wemo devices or toggle their power via your developer AI assistant agy, you can configure the following rules in .agents/AGENTS.md:

### 1. Home Assistant State & Control
You can retrieve the live state of any Home Assistant entity or control Wemo devices using the following scripts:
* **Query sensor/device state**: `bash /home/gvoina/scripts/get_ha_sensor.sh <entity_id>`
  * *Example*: `bash /home/gvoina/scripts/get_ha_sensor.sh binary_sensor.wemo_motion`

Now you can control your resurrected devices from anywhere:

agy "Is the bedroom lamp currently turned on?"
agy "Tell Home Assistant to turn off the desk lamp."

agy will query the Home Assistant API locally or run the control script, verifying your device telemetry in real-time.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.