mdnaimurrahman.com
Office Energy Monitor
Date
Jul 2026
Category
Full Stack
Source Code

Office Energy Monitor

"Lights, Fans, Discord: The Boss's Big Idea"

A real-time office energy monitoring system with a live web dashboard and Discord bot. Monitor all 15 electrical devices (fans and lights) across 3 office rooms through both a web interface and Discord commands.

Quick Testing

WhatLink
Live Dashboardhttps://office-energy-monitor-s7py.onrender.com
Add Discord Bot to your serverInvite Bot

No setup required. The dashboard is live and the bot is already running. Just open the dashboard URL or click the invite link to add the bot to any Discord server you control, then try commands like !status, !room drawing, and !usage.

Architecture

Everything runs in a single FastAPI process — the simulator, in-memory store, alert engine, REST/WebSocket API, served frontend, and Discord bot.

Devices → FastAPI (simulator + store + API + WS + bot) → Dashboard + Discord → User

System Diagram

Screenshots

Dashboard Overview

Dashboard Overview

Device Grid

Device Grid

Power Meter & Power Trend Chart

Power Meter and Power Trend Chart

Floor Plan

Floor Plan

Demo Scenario Control

Demo Control

Discord Bot

Discord Bot

Wokwi Circuit

Wokwi Circuit

Features

Web Dashboard

  • Live Device Status Grid — 15 devices grouped by room with real-time on/off indicators
  • Power Consumption Meter — total office watts + per-room breakdown + daily kWh + estimated cost (BDT)
  • Interactive Floor Plan — SVG top-view with animated fans (spin) and glowing lights
  • Power Trend Chart — real-time line chart of power consumption over time
  • Active Alerts Panel — timestamped after-hours and room-on-2h warnings
  • Change Logs — full device state change history with timestamps
  • Demo Scenario Control — trigger preset states (all-on, energy-saver, lunch-break, after-hours-forgotten) for live demos
  • Last Updated Indicator — proves real-time data flow ("Updated 3s ago")
  • Dark/Light Theme — toggleable with localStorage persistence

Discord Bot

CommandDescription
!statusOverview of all devices across all rooms
!room <name>Detailed breakdown of a specific room
!usageReal-time power consumption, daily kWh, and estimated cost
!helpList all available commands
  • Rich embed responses with color-coded severity and room fields
  • Humanized, conversational summaries via Groq LLM (with fallback if no API key)
  • Proactive alert posting to a designated Discord channel

Hardware Schematic

  • Wokwi-compatible ESP32 circuit modeling one room (Drawing Room)
  • 3 yellow LEDs (lights), 2 blue LEDs (fans), 5 slide switches, 5 resistors
  • Firmware reads switch states, mirrors to LEDs, outputs JSON every second

Simulation

Devices toggle randomly with correlated room behavior: when one device turns ON, nearby devices in the same room have a boosted chance of turning ON too. Office hours (configurable from the dashboard or env) are only used by the alert engine to detect after-hours violations — the simulator itself does not depend on real time.

Demo scenarios can force specific states for live presentations: all-on, energy-saver, lunch-break, after-hours-forgotten.

Tech Stack

LayerTechnology
BackendPython + FastAPI + uvicorn
Real-timeNative WebSockets
StateIn-memory dict (Pydantic models)
PersistenceSQLite (cumulative kWh + change logs)
FrontendReact + Vite + TypeScript
StylingTailwindCSS v4
AnimationsFramer Motion + CSS + SVG SMIL
ChartsRecharts
Botdiscord.py (in-process)
LLMGroq (Llama 3.3-70b) with templated fallback
CircuitWokwi (ESP32)
DiagramHand-crafted SVG

Setup

Prerequisites

  • Python 3.12+
  • Node.js 18+
  • uv (Python package manager)
  • pnpm or npm

1. Clone and install dependencies

git clone https://github.com/mdnaimur0/office-energy-monitor.git
cd office-energy-monitor

# Python dependencies
uv sync

# Dashboard dependencies
cd dashboard
pnpm install
cd ..

2. Configure environment

cp .env.example .env

Edit .env with your settings:

# Backend / simulation
ELECTRICITY_RATE_PER_KWH=8.0     # BDT per kWh
OFFICE_OPEN_HOUR=9
OFFICE_CLOSE_HOUR=17

# Discord bot (leave blank to disable)
DISCORD_TOKEN=your-bot-token
ALERT_CHANNEL_ID=123456789012345678
GROQ_API_KEY=your-groq-key        # optional; falls back to templated replies

3. Run in development (two terminals)

# Terminal 1 — Backend (API + WS + simulator + bot)
uv run uvicorn app.main:app --reload --port 8000

# Terminal 2 — Dashboard dev server
cd dashboard
pnpm run dev

Open http://localhost:5173 (Vite default) — the dev server proxies /api and /ws to the backend.

4. Run as single-process demo

cd dashboard && pnpm run build && cd ..
uv run uvicorn app.main:app --port 8000

Open http://localhost:8000 — dashboard + API + WebSocket + Discord bot, all in one process.

Project Structure

office-energy-monitor/
├── pyproject.toml           # uv-managed dependencies
├── uv.lock                  # lockfile
├── .python-version          # Python 3.12
├── .env.example             # environment variables template
├── app/                     # FastAPI application package
│   ├── main.py              # app entry point, lifespan, routes
│   ├── store.py             # in-memory source of truth (15 devices)
│   ├── services.py          # shared read logic (API + bot)
│   ├── simulator.py         # random device state mutation loop
│   ├── alerts.py            # after-hours / room-on-2h engine
│   ├── ws.py                # WebSocket connection manager
│   ├── routes.py            # REST API + scenario endpoints
│   ├── db.py                # SQLite cumulative kWh + change logs
│   ├── models.py            # Pydantic models (Device, Alert, Usage)
│   └── bot/
│       ├── __init__.py      # discord.py bot, embeds, commands
│       └── llm.py           # Groq client + templated fallback
├── dashboard/               # React + Vite + TypeScript frontend
│   ├── public/favicon.svg   # SVG bolt icon
│   ├── src/
│   │   ├── api/ws.ts        # reconnecting WebSocket + scenario trigger
│   │   ├── components/      # DeviceGrid, PowerMeter, PowerChart, FloorPlan,
│   │   │                    # AlertsPanel, LogsPanel, DemoControl, ThemeToggle
│   │   ├── types.ts         # TypeScript types mirroring backend models
│   │   └── App.tsx          # main dashboard layout
│   ├── index.html
│   └── vite.config.ts       # dev proxy to FastAPI
├── hardware/
│   ├── diagram.json         # Wokwi ESP32 circuit
│   ├── sketch.ino           # ESP32 firmware (LED status output)
│   └── README.md            # wiring explanation
├── docs/
│   ├── system-diagram.svg   # architecture diagram (with hardware + LLM)
│   └── screenshots/         # dashboard screenshots
├── others/
│   └── office-layout-top-view.png
└── README.md

API Endpoints

MethodEndpointDescription
GET/api/stateCurrent state of all 15 devices
GET/api/rooms/{id}Detailed status of a specific room
GET/api/usagePower consumption + daily kWh + estimated cost
GET/api/alertsActive alerts
GET/api/logsRecent device state change logs
POST/api/scenario/{name}Trigger a demo scenario (all-on, energy-saver, lunch-break, after-hours-forgotten, normal)
WS/wsReal-time state + alerts broadcast

Data Model

The office has 3 rooms × 5 devices = 15 devices total.

RoomFansLightsTotal
Drawing Room235
Work Room 1235
Work Room 2235

Power consumption: Fan ON = 60W, Light ON = 15W. Max office capacity = 495W.

License

MIT


Hackathon

This project was originally developed for the Hackathon Preliminary Round of Techathon Nationals & Rover Summit - a national event organized by IUT Robotics Society. We are proud to have been shortlisted as finalists - Top 26 teams among 270+ teams.

Team Members

Copyright © 2026 by Md. Naimur Rahman | All Rights Reserved