# IoT Device Onboarding to Home Assistant

Pattern for adding new WiFi IoT devices (smart plugs, switches, sensors) to the local network and Home Assistant.

## Phase 1: Get Device on WiFi

### Stock Firmware (eWeLink / Tuya)
1. Device broadcasts a setup AP when first powered or reset (e.g., `ITEAD-XXXX` or `SmartLife-XXXX`)
2. Connect phone to that AP, use the **eWeLink** or **Smart Life** app to configure WiFi
3. After WiFi config, the AP disappears and device joins the home network

### Tasmota / ESPHome (already flashed)
1. Device broadcasts its own AP (e.g., `tasmota-XXXX-XXXX` or `esphome-XXXX`)
2. Connect phone to the AP, browse to `http://192.168.4.1` to configure WiFi
3. After save, device reboots onto the home network

## Phase 2: Find the IP Address

Devices often get DHCP-assigned IPs that aren't immediately obvious.

**Method A — Router DHCP table:**
Browse to router admin (ASUS: `http://192.168.50.1`), check Client List for the new device.

**Method B — App device info:**
In eWeLink app: tap device → ⚙️ Settings → Network Info / Device IP.
In Tasmota web UI: Information → Network.

**Method C — ARP scan for new IPs:**
```python
# Compare current ARP table against known IPs to find new devices
import subprocess
arp_output = subprocess.run(['cat', '/proc/net/arp'], capture_output=True, text=True).stdout
new_ips = [line.split()[0] for line in arp_output.split('\n')[1:] if line.strip()
           and line.split()[0] not in known_ips]
```

**Method D — MAC vendor lookup:**
Identify unknown devices by MAC OUI:
```bash
curl -s "https://api.macvendors.com/XX:XX:XX"  # first 3 octets only
# Sonoff/ITEAD common prefixes: 68:C6:3A, EC:FA:BC, C8:2B:96, DC:4F:22, 84:F3:EB
```

**Method E — Port scan for IoT signatures:**
```bash
# Sonoff LAN API port (Tasmota HTTP on :80, eWeLink LAN on :8081)
curl -s -m2 "http://DEVICE_IP:8081/"
# Tasmota status endpoint
curl -s -m2 "http://DEVICE_IP/cm?cmnd=Status%200"
```

## Phase 3: Enable Local Control

### Stock Sonoff (eWeLink)
1. In eWeLink app: ⚙️ Settings → **LAN Control** → ON
2. This enables the local TCP API on port 8081
3. Now HA's **Sonoff LAN** integration can auto-discover it

#### Troubleshooting LAN Mode

**Symptom: port 8081 accepts TCP but never responds.** The device completes the TCP handshake (SYN-ACK) but no application-layer data is returned — HTTP, WebSocket, and raw protocol requests all time out silently. This means the LAN API service process on the device is hung or was never started, even though the port shows as listening.

**Fix:** Power-cycle the device. Unplug for 10 seconds and plug back in. After reboot, verify:

```bash
# TCP must succeed
nc -zv -w3 DEVICE_IP 8081
# Must return JSON (not timeout)
curl -s --max-time 3 http://DEVICE_IP:8081/zeroconf/info
```

If `zeroconf/info` returns a JSON payload with `deviceid`, `model`, `sw_version` etc., LAN mode is working correctly.

### Tasmota
- Already local. Set MQTT or use the HTTP API directly.
- Default web UI at `http://DEVICE_IP/`

## Phase 4: Add to Home Assistant

1. **Sonoff LAN** integration: Settings → Devices & Services → Add Integration → Sonoff LAN → auto-discovers
2. **Tasmota** integration: Settings → Add Integration → Tasmota (auto-discovers via MQTT or HTTP)
3. **ESPHome**: Add via ESPHome dashboard or manual YAML

Manual MQTT discovery also works for all three.

## Sonoff S31-Specific Notes

- **Model**: S31 Lite (WiFi smart plug with power monitoring)
- **Flash method**: tuya-convert (OTA) or serial (TX/RX/GND/3.3V — requires opening case)
- **Stock LAN API port**: 8081 (TCP)
- **Tasmota template**: `{"NAME":"Sonoff S31","GPIO":[0,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}`
- **Power monitoring**: HLW8012 chip — reports voltage, current, power, energy
