WeMos D1 Mini (ESP8266) — Example Bundle

Includes: Arduino sketch to run on the WeMos D1 (ESP8266), an HTML/JS front-end to call it, and a small Python (Flask) proxy to forward requests from browsers if needed (CORS/network reasons).

Quick UI

Arduino Sketch (WeMos D1 Mini / ESP8266)

Upload this with Arduino IDE (Board: WeMos D1 R2 & mini) or PlatformIO. Replace SSID/PASSWORD before uploading.

// WeMos D1 Mini (ESP8266) - simple web API to control the built-in LED
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";
ESP8266WebServer server(80);

const int LED_PIN = LED_BUILTIN; // builtin LED (D4) - note: inverted on many boards
bool ledState = false; // logical state (true = ON)

void setLed(bool on) {
  // LED_BUILTIN on many ESP boards is active LOW
  digitalWrite(LED_PIN, on ? LOW : HIGH);
  ledState = on;
}

String jsonResponse() {
  String s = "{";
  s += "\"led\":"; s += (ledState ? "true" : "false");
  s += "}";
  return s;
}

void handleGet() {
  server.sendHeader("Access-Control-Allow-Origin", "*");
  server.send(200, "application/json", jsonResponse());
}

void handleToggle() {
  setLed(!ledState);
  handleGet();
}

void handleOn() {
  setLed(true);
  handleGet();
}

void handleOff() {
  setLed(false);
  handleGet();
}

void handleNotFound() {
  server.send(404, "text/plain", "Not found");
}

void setup() {
  Serial.begin(115200);
  pinMode(LED_PIN, OUTPUT);
  setLed(false); // start OFF

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.print("Connecting to WiFi");
  unsigned long start = millis();
  while (WiFi.status() != WL_CONNECTED) {
    delay(250);
    Serial.print(".");
    if (millis() - start > 20000) break; // timeout
  }
  Serial.println();

  if (WiFi.status() == WL_CONNECTED) {
    Serial.print("Connected, IP: ");
    Serial.println(WiFi.localIP());
  } else {
    Serial.println("WiFi not connected -- start AP or retry");
  }

  // API endpoints
  server.on("/led", HTTP_GET, handleGet);
  server.on("/led/toggle", HTTP_GET, handleToggle);
  server.on("/led/on", HTTP_GET, handleOn);
  server.on("/led/off", HTTP_GET, handleOff);
  server.onNotFound(handleNotFound);

  server.begin();
  Serial.println("HTTP server started");
}

void loop() {
  server.handleClient();
  // nothing else needed
}
  

Python Proxy (Flask)

Use this when your browser can't talk directly to the device (CORS or network segmentation). Set DEVICE_IP to your device address. Requires: pip install flask requests

#!/usr/bin/env python3
# flask_proxy.py - simple proxy to forward requests to WeMos device
from flask import Flask, jsonify, request
import requests

app = Flask(__name__)

# Set this to your WeMos device local IP or keep it dynamic from query param
DEVICE_IP = "192.168.1.50"  # change to your device

def forward(path):
    url = f"http://{DEVICE_IP}{path}"
    try:
        r = requests.get(url, timeout=3)
        r.raise_for_status()
        return jsonify(r.json())
    except Exception as e:
        return jsonify({"error": str(e)}), 502

@app.route('/api/led', methods=['GET'])
def get_state():
    return forward('/led')

@app.route('/api/led/toggle', methods=['GET'])
def toggle():
    return forward('/led/toggle')

@app.route('/api/led/on', methods=['GET'])
def on():
    return forward('/led/on')

@app.route('/api/led/off', methods=['GET'])
def off():
    return forward('/led/off')

if __name__ == '__main__':
    # Run on 0.0.0.0 so other devices can access the proxy
    app.run(host='0.0.0.0', port=5000, debug=True)
  

Notes