Skip to content

19bk/edge-ai-anomaly-detector

Repository files navigation

Edge AI Anomaly Detector on ESP32 (Simulated)

Portfolio project for an embedded and intelligent systems application: an ESP32-style firmware simulator that runs anomaly detection on industrial sensor data fully offline, with optional MQTT logging and a HAL that can be swapped for real hardware later.

Demo GIF

What this shows

  • Edge ML deployment with an embedded-friendly Isolation Forest
  • ESP32-style setup() + loop() application structure
  • Clean hardware abstraction via SimulatorHAL and ESP32HAL
  • Offline inference with optional MQTT event publishing
  • Exported model artifacts for both Python simulation and future C porting

Architecture

CLI (Click) -> main.py (firmware loop) -> HAL (simulator | esp32)
                  |                         |
                  v                         v
             ml/detector.py           hal/simulator.py
                  |
                  v
           ml/preprocessing.py
                  |
                  v
        comms/mqtt_logger.py

Demo flow

  1. The simulator generates ESP32-like sensor readings every 100 ms.
  2. A sliding window of 20 samples is converted into 12 runtime features.
  3. The detector scales features and runs Isolation Forest inference locally.
  4. The app toggles LED and buzzer states on anomalies.
  5. If MQTT is configured, JSON events are published without changing app logic.

Model

  • Algorithm: Isolation Forest
  • Dataset: data/ai4i2020.csv
  • Window size: 20 samples
  • Runtime features: 12
  • Exports: joblib model, scaler JSON, tree JSON for future embedded translation

The original requested feature list adds up to 13 values. This implementation keeps the trained model at 12 features to stay aligned with the embedded-size goal:

  • rolling mean, max, and delta for process temperature
  • rolling mean, max, and delta for vibration
  • rolling mean, max, and delta for rotational speed
  • torque mean
  • torque MAD
  • tool wear

The simulator still computes vibration_torque_ratio and exposes it in telemetry, but it is not included in the trained feature vector.

Project layout

edge-ai-anomaly-detector/
├── assets/demo.gif
├── data/ai4i2020.csv
├── firmware/README.md
├── models/
├── notebooks/training.ipynb
├── src/anomaly_detector/
│   ├── cli.py
│   ├── main.py
│   ├── display.py
│   ├── hal/
│   ├── ml/
│   └── comms/
├── tests/
├── pyproject.toml
└── README.md

Quick start

cd /Users/bernard/dev/edge-ai-anomaly-detector
python3 -m pip install -e .
anomaly-detector train --data data/ai4i2020.csv
anomaly-detector run -n 200

If editable install is blocked by an older local pip setup, run with:

PYTHONPATH=src python3 -m anomaly_detector.cli train --data data/ai4i2020.csv
PYTHONPATH=src python3 -m anomaly_detector.cli run -n 200

Live demo

Run the deployable web dashboard locally:

PYTHONPATH=src python3 -m anomaly_detector.cli serve --host 0.0.0.0 --port 8000

Then open:

http://localhost:8000

The live demo runs the simulator continuously in the background and exposes:

  • / for the dashboard
  • /api/status for the latest live sample and detection state
  • /api/history for recent inference history
  • /demo.gif for the terminal-style demo preview

CLI

Train the model:

anomaly-detector train --data data/ai4i2020.csv

Run the simulator:

anomaly-detector run -n 200

Run with MQTT:

anomaly-detector run --mqtt-broker localhost

Useful runtime options:

anomaly-detector run -n 200 --threshold -0.05 --anomaly-rate 0.05

Artifacts

Training produces:

  • models/model.joblib
  • models/scaler_params.json
  • models/model_trees.json

Tests

pytest

Verified locally:

  • training completed successfully
  • model artifacts were created
  • pytest passed
  • simulator run produced anomaly detections and colored terminal output

Making the demo always live

This repo now includes a deployable FastAPI dashboard, so a public always-live demo can be hosted directly:

  • easiest always-on host: Fly.io
  • simplest managed alternative: Railway
  • good for portfolio visuals but not free-always-on: Hugging Face Spaces

Recommended path

Use Fly.io with the included web UI. It is the cleanest fit if you want a URL that stays up and continuously runs the simulator loop.

Why:

  • Fly.io supports keeping app processes available across regions and documents controls for app availability: https://fly.io/docs/apps/app-availability/
  • you can run a lightweight Python web process continuously instead of exposing a raw CLI
  • it maps well to a small real-time dashboard for portfolio reviewers

Hosting options

  • Fly.io Best choice if you want an always-live URL. Use one small machine and keep it running.
  • Railway Viable if you deploy a small FastAPI dashboard. Railway documents a Serverless mode that scales to zero after inactivity; inference: for an always-live demo you should avoid that mode and use a normal service instead. Docs: https://docs.railway.com/reference/public-networking#serverless
  • Hugging Face Spaces Good if you turn the demo into Gradio or Streamlit, but free hardware sleeps after inactivity. Hugging Face documents sleep behavior and paid options for avoiding it: https://huggingface.co/docs/hub/spaces-gpus#sleep-time

What I would do

Deploy the included app with:

fly launch --copy-config --no-deploy
fly deploy

The included fly.toml keeps one machine running so the demo stays available.

ESP32 swap path

The runtime depends on the abstract interface in src/anomaly_detector/hal/base.py. To move to real hardware later:

  1. implement the methods in src/anomaly_detector/hal/esp32.py
  2. instantiate ESP32HAL(...) instead of SimulatorHAL(...)
  3. keep the rest of the application unchanged

About

ESP32-style edge AI anomaly detector with a live web demo, Isolation Forest inference, HAL abstraction, and MQTT fallback logging.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages