POC-eWeLink

eWeLink / Sonoff local-control PoC

Build Release GitHub release

A local React + Node.js dashboard for listing and controlling Sonoff/eWeLink devices. Credentials stay in the Express backend and are never delivered to the browser. The backend uses the baugp/ewelink-api fork directly from GitHub.

Architecture

React / Vite β†’ REST API β†’ Node.js / Express β†’ ewelink-api β†’ eWeLink API β†’ Sonoff devices

Requirements

Configuration

Copy backend/.env.example to backend/.env, then pick one of the two login modes. backend/.env is ignored by Git. Do not use VITE_ variables for these values.

OAuth with your own app (needed to switch devices)

  1. Create an app on the eWeLink developer platform and register http://localhost:3000/api/oauth/callback as its redirect URL.
  2. Set its credentials:

    EWELINK_APP_ID=your-app-id
    EWELINK_APP_SECRET=your-app-secret
    
  3. Start the app and click Connect eWeLink on the dashboard (or open http://localhost:3000/api/oauth/login), then sign in with your eWeLink account.

The backend stores the resulting tokens in backend/.ewelink-token.json (ignored by Git) and refreshes them automatically. Access tokens last 30 days and refresh tokens 60; if the refresh token expires, the dashboard asks you to connect again. EWELINK_OAUTH_REDIRECT_URL and FRONTEND_URL override the callback URL and where the browser lands afterwards.

eWeLink refuses email/password login for developer apps (error 407), which is why this mode needs the browser step.

Password login (read-only)

EWELINK_REGION=eu
EWELINK_USERNAME=you@example.com
EWELINK_PASSWORD=your-password

This uses the app ID built into ewelink-api, which eWeLink only allows on read paths: listing devices works, but turning them on or off fails with eWeLink error 407.

EWELINK_REGION is the region the account was created in (eu, us, as or cn), which is not necessarily where you live: an account created in Brazil lives in us. If the region is wrong, eWeLink answers the login with the right one and the backend retries there automatically, logging the switch. Authentication failures are logged with the eWeLink error code and message in the backend console; the API responses stay generic.

Install and run

npm install
npm run dev

The root install script installs backend and frontend dependencies. Open http://localhost:5173. The backend runs on http://localhost:3000.

To run the two services independently:

npm run dev:backend
npm run dev:frontend

Build the frontend with npm run build.

Tests and coverage

npm test               # backend (node:test) and frontend (Vitest) suites, both with coverage
npm run coverage:report  # one Markdown table from both lcov reports

The backend uses Node’s built-in test runner against the real ewelink-api module with its network layer stubbed, so the eWeLink v2 response shapes (the thingList wrapper, the wrong-region answer, token rejection) are exercised exactly as the cloud sends them. The frontend uses Vitest with jsdom and React Testing Library. Coverage lands in backend/coverage/lcov.info and frontend/coverage/lcov.info.

CI and releases

API documentation

With the backend running, open Scalar API Reference. The raw OpenAPI document is available at http://localhost:3000/openapi.json.

REST API

Features

Limitations

This is intentionally a PoC. It has no database, user authentication, multi-user support, persistent device configuration, cloud deployment, advanced automation, scheduling, scenes, or device grouping.