Skip to content

Repository files navigation

🏢 Office Device Monitor

IUT Hackathon — Preliminary Round Submission

A real-time system that lets anyone monitor the electrical devices (lights and fans) of a 3-room office through two independent interfaces — a live web dashboard and a Discord bot — both backed by a single shared backend. Device state is simulated; no physical hardware is required for the demo.


Table of Contents


Project Overview

The office has three rooms — Drawing Room, Work Room 1, and Work Room 2 — each equipped with 2 fans and 3 lights (5 devices per room, 15 devices total). A backend simulator randomly flips device states every 8–15 seconds, driving a single in-memory store that acts as the authoritative source of truth. The React dashboard receives updates via Server-Sent Events (SSE) and re-renders without page refresh. The Discord bot queries the same REST API on demand and uses an LLM (Anthropic claude-haiku) to produce friendly, conversational responses. Both consumers always reflect the same live reality.


Architecture

[Simulator: flips 1–3 devices every 8–15 s]
        ↓
[Device Store: single in-memory source of truth (15 devices)]
        ↓
[Express Backend API — port 3001]
        │
        ├──SSE stream──►  [React Dashboard — port 5173]
        │                  Live device panel · Power meter · Alerts · Floorplan
        │
        └──REST polls──►  [Discord Bot]
                           !status · !room · !usage · Alert monitor (BONUS)
                                  ↓
                         [Anthropic LLM — claude-haiku-4-5]
                          Humanises raw JSON → friendly Discord messages

System Architecture

Both the dashboard and the bot read from the same backend. The bot never holds its own copy of device state, and neither does the dashboard — if they diverge, that is a bug.


Repository Structure

IUT_HACKATHON/
├── backend/              # Phase 1 — Node.js + Express backend
│   ├── deviceStore.js    # Single in-memory source of truth
│   ├── simulator.js      # Randomly flips devices every 8–15 s
│   ├── sseManager.js     # SSE client registry + broadcast
│   ├── alertEngine.js    # After-hours & stuck-on alert logic
│   ├── usageCalculator.js# Live wattage + kWh accumulator
│   ├── routes/api.js     # All REST + SSE endpoints
│   ├── server.js         # Entry point
│   └── .env.example
│
├── dashboard/            # Phase 2 — React (Vite) dashboard
│   └── src/
│       ├── hooks/        # useDevices (SSE), usePoller (REST)
│       └── components/   # DevicePanel, RoomCard, DeviceTile,
│                         #   UsageMeter, AlertsPanel,
│                         #   ConnectionBanner, Floorplan (BONUS)
│
├── bot/                  # Phase 3 — Discord bot (discord.js)
│   ├── bot.js            # Entry point + command router
│   ├── commands/         # status.js, room.js, usage.js
│   └── services/         # backendClient.js, llmClient.js,
│                         #   alertMonitor.js (BONUS)
│
├── diagrams/             # Phase 4
│   ├── system_architecture.png   # High-level system diagram
│   └── wiring_guide.md           # ESP32 wiring plan for Wokwi/Tinkercad
│
└── README.md

Setup & Run

All three services run independently. Start them in the order listed below.

Prerequisites

  • Node.js ≥ 18 (all three services)
  • A Discord bot token (for the bot only) — create one at discord.com/developers
  • An Anthropic API key (for LLM responses, optional — bot falls back to templates without it)

1. Backend (Phase 1)

cd backend
cp .env.example .env      # optional — defaults work without changes
npm install
npm start                 # or: npm run dev (uses nodemon)

Environment variables (.env):

Variable Default Description
PORT 3001 HTTP port
OFFICE_HOURS_START 9 Start of office hours (24h)
OFFICE_HOURS_END 17 End of office hours (24h)

Endpoints (all on http://localhost:3001):

Method Path Description
GET /api/devices All 15 devices
GET /api/rooms/:room 5 devices for one room (drawing, work1, work2)
GET /api/usage Total watts, per-room watts, estimated kWh
GET /api/alerts Active after-hours and stuck-on alerts
GET /api/events SSE stream — pushed on every simulator tick

2. Dashboard (Phase 2)

Requires the backend to be running first.

cd dashboard
npm install
npm run dev               # Vite dev server on http://localhost:5173

No environment variables needed. The Vite dev server proxies all /api requests to localhost:3001 automatically.

Open http://localhost:5173 in your browser. The dashboard will:

  • Connect to the SSE stream immediately and show a live snapshot
  • Update device states in real time without any page refresh
  • Poll /api/usage every 5 seconds and /api/alerts every 10 seconds
  • Show a red banner at the top if the backend becomes unreachable
  • Offer a Floorplan tab (BONUS) with an animated SVG showing spinning fans and glowing lights

3. Discord Bot (Phase 3)

Requires the backend to be running. The bot does NOT require the dashboard.

cd bot
cp .env.example .env      # fill in your tokens
npm install
npm start

Environment variables (.env):

Variable Required Description
DISCORD_TOKEN ✅ Yes Bot token from Discord Developer Portal
ANTHROPIC_API_KEY ⚠️ Optional Enables LLM-powered responses; falls back to templates without it
BACKEND_URL defaults to http://localhost:3001 Backend base URL
ALERT_CHANNEL_ID ⚠️ Optional Channel ID for proactive alert posts (BONUS)

Commands:

Command Description
!status Summarises all 3 rooms' device states
!room <name> Detail for one room (drawing, work1, work2)
!usage Current total wattage + today's estimated kWh
!help Lists available commands

BONUS — Proactive alerts: If ALERT_CHANNEL_ID is set, the bot polls /api/alerts every 30 seconds and posts a message when a new alert appears. Each alert ID is tracked so the same alert is never posted twice per trigger cycle.

Note on Discord privileges: The bot requires the Message Content Intent to be enabled in the Discord Developer Portal (Bot → Privileged Gateway Intents → Message Content Intent ✅).


Device Count — 15, not 18

The original problem-statement PDF (page 2) mentions "18 devices" in two places but its own summary box on the same page states the correct count. The actual office layout is:

  • 3 rooms × (2 fans + 3 lights) = 3 × 5 = 15 devices

A fan rated at 60 W and a light rated at 15 W gives a maximum possible draw of 165 W per room (2×60 + 3×15) and 495 W total across the office. This system uses 15 consistently throughout all code, API responses, and documentation.


Assumptions & Design Decisions

Area Decision Rationale
Office hours 09:00–17:00, every day (no weekend distinction) Spec says "9 AM–5 PM"; no weekday/weekend rule given — simplest correct interpretation
After-hours alerts One alert per ON device (not one per room) Finer granularity; the boss knows exactly which devices are on
Stuck-on condition ALL 5 devices in a room must be ON for ≥ 2 h Matches spec exactly; partial-room stuck-on is not flagged
kWh estimation Σ (watts × elapsed_hours) accumulated since server start or midnight No database; accumulator resets on restart or at midnight. "Since server start or midnight — whichever is later" is noted in usageCalculator.js
Simulator interval 8–15 seconds, randomised on each tick Feels organic; avoids all-devices-changing-at-once visual noise
Simulator flip count 1–3 devices per tick Same reason; 1 makes the dashboard feel too slow, >3 too chaotic
SSE vs WebSockets SSE (as spec requires) One-way push, HTTP/1.1 compatible, native EventSource auto-reconnect
LLM model claude-haiku-4-5 Fastest, cheapest Anthropic model; 256-token responses sufficient for 1-3 sentence summaries
Alert monitor poll 30 seconds (bot-side) Dashboard polls at 10 s; bot uses 30 s since it's a notifier, not a live UI
CORS cors() with wildcard origin Development convenience; in production this would be locked to specific origins

Diagrams

System Architecture (4a)

See diagrams/system_architecture.png

Hardware/Electrical Schematic (4b)

The schematic below represents the circuit wiring diagram for the Drawing Room (2 fans + 3 lights on an ESP32 with a 5-channel relay module and ACS712 current sensor), built in Wokwi:

Hardware/Electrical Schematic

Full wiring plan, pin-mapping table, and assembly steps can be found in diagrams/wiring_guide.md.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages