AI-Powered Industrial Safety Intelligence for Zero-Harm Operations - ET AI Hackathon 2026, Problem Statement 1.
A unified intelligence layer that fuses IoT/SCADA sensors, permit-to-work logs, maintenance records, shift rosters and CCTV into a live compound-risk picture - catching the dangerous combinations no single sensor would flag, hours before an incident. Built and validated on a refinery/petrochemical model; designed source-agnostic so it drops onto power/steel/cement plants.
Full vision & glossary:
PROJECT_PLAN.md· Build bible (architecture, contracts, per-member plans):ARCHITECTURE.md· Decision log:docs/decisions.md· Stream references:docs/simulation.md(data) ·docs/engine.md(risk engine) ·docs/product.md(API + dashboard)
Prerequisites: Python 3.11, an internet connection for the first run (downloads ~5 MB of process data + the MiniLM embedding model), and ~3 GB free disk. Runs fully on CPU - no GPU needed. Every command below is run from the repo root. The dashboard and the API are two separate servers - run them in two separate terminals (each with the venv activated).
python -m venv .venv
# Windows (PowerShell): .venv\Scripts\Activate.ps1
# Windows (Git Bash) / *nix: source .venv/Scripts/activate # macOS/Linux: .venv/bin/activate
python -m pip install --upgrade pip
pip install -r requirements.txt # installs everything; wait for it to finishActivate the venv in every new terminal before running anything (a bare
streamlit/uvicornwith the venv inactive is the #1 "it won't start" cause -ModuleNotFoundError).
cp .env.example .env # then paste a free Groq or Gemini key for LIVE LLM narrationNo key? The LLM steps use built-in templates + a committed pre-cached S3 narrative, so the demo still runs end-to-end.
python scripts/download_data.py --tep # real TEP process data -> data/raw/tep/d*.dat
python -m src.simulation.scenario all # 12 scenario tapes -> data/scenarios/S1..S12python -m src.intelligence.corpus_build # embeds the committed corpus PDFs -> data/chroma/The corpus PDFs (CSB / OISD / Factories Act) are already in the repo under data/corpus/, so this
works offline except for a one-time MiniLM model download. Skip it and grounding degrades
gracefully (S3 still works from the committed pre-cache).
python -m src.engine.metrics # compound-vs-baseline headline numbers -> results.md
python scripts/run_demo.py --scenario S3 # narrated full-stack demo + scoreboard (~1 min)
pytest -q # full test suite# Terminal A - the command dashboard (self-contained; this is the demo surface):
streamlit run src/dashboard/app.py # opens http://localhost:8501
# Terminal B - the REST + WebSocket API (optional; the dashboard does NOT need it):
uvicorn src.api.main:app --port 8000 # http://localhost:8000/docsThe dashboard is self-contained (it replays scenarios through the real engine in-process), so for the demo you only strictly need Terminal A. The API is there for programmatic access / integration.
| Already committed (works on a fresh clone) | Regenerated by the steps above (git-ignored) |
|---|---|
Corpus PDFs (data/corpus/), ground-truth specs, pre-cached S3 narrative, annotated CCTV clip (data/vision/clip_07.annotated.mp4) |
TEP data (data/raw/, step 3), scenario tapes (data/scenarios/*.jsonl, step 3), RAG index (data/chroma/, step 4), results.* (step 5) |
The one thing you cannot regenerate from the repo is the raw CCTV source video (a 28 MB stock
clip, sourced manually) - which is why the annotated clip is committed instead, so the CCTV pane
plays out of the box. Rebuilding vision from scratch (scripts/freeze_vision.py) is therefore
optional and needs that raw clip + python scripts/download_data.py --vision for the YOLO weights.
ModuleNotFoundErroron start - the venv isn't activated in this terminal (see step 1).error while attempting to bind ... 8000/8501- a previous server is still running on that port. Stop it, or use another port:uvicorn ... --port 8010,streamlit run ... --server.port 8502.- Dashboard slow / killed on first load - the first scrub computes the whole scenario; on a low-RAM machine close other apps. Don't run the API, the dashboard, and a heavy build at once.
- CCTV pane says "clip not built" - you're on an older clone without the committed clip;
git pull.
flowchart LR
subgraph A["A · Data & Simulation"]
TEP["TEP process data<br/>(Downs & Vogel benchmark)"]
GEN["Permit / shift / maintenance /<br/>weather generators (seeded)"]
CV["CCTV vision - YOLOv8<br/>person + hard-hat events"]
TAPES["12 scenario tapes<br/>+ ground truth"]
TEP --> TAPES
GEN --> TAPES
CV --> TAPES
end
subgraph B["B · Risk Engine"]
AG["5 specialist agents<br/>sensor · permit · maintenance · shift · vision"]
CORE["Correlation core: knowledge graph +<br/>co-occurrence rules + digital bowtie +<br/>trend projection"]
BASE["Single-sensor baseline<br/>(measured side by side)"]
AG --> CORE
end
subgraph C["C · Knowledge & Language"]
RAG["CSB / OISD / Factories Act corpus<br/>MiniLM + ChromaDB (local)"]
SVC["Incident match · compliance ·<br/>copilot · handover · reports"]
LLM["LLM: Groq → Gemini → offline<br/>templates + pre-cached narratives"]
RAG --> SVC
LLM --> SVC
end
subgraph D["D · Command & Response"]
UI["ISA-101 HMI dashboard<br/>map · plume · evacuation · scoreboard"]
API["FastAPI + WebSocket"]
TG["Telegram alert to the<br/>safety officer's phone"]
end
TAPES -- "FeedRow v1.0" --> AG
TAPES -.-> BASE
CORE -- "RiskAssessment v1.0" --> SVC
CORE -- "RiskAssessment v1.0" --> UI
SVC -- "Grounding v1.0" --> UI
UI --> TG
API --> UI
Three frozen JSON contracts (FeedRow, RiskAssessment, Grounding) are the only coupling between
streams - each hop is schema-validated by the test gate. High-resolution version for slides:
docs/architecture.png.
| Deliverable | Where |
|---|---|
| Pitch deck (14 slides, dark HMI theme) | docs/deck/Sentinel_Deck.pptx - regenerate: python scripts/build_deck.py |
| Architecture diagram | docs/architecture.png (source: docs/architecture.svg) |
| Demo video shot-list + narration script | docs/demo_runbook.md (also the live stage script) |
| Jury Q&A prep (hard questions, honest answers) | docs/qa_prep.md |
| Measured results | results.md / results.json - regenerate: python -m src.engine.metrics |
| Decision log / receipts for every claim | docs/decisions.md |
contracts/ # SHARED. FeedRow / RiskAssessment / Grounding schemas + golden samples + plant_layout.json
src/common/ # Pydantic mirror of the contracts - import these, don't pass raw dicts
src/simulation # A: TEP loader, permit/maintenance/shift/weather generators, scenario tapes, replay
src/vision # A (P3): YOLOv8 CCTV PPE / person-in-zone detection
src/agents # B: sensor / permit / maintenance / shift / vision agents
src/engine # B: graph, rules, barriers (digital bowtie), trends, scorer, baseline, metrics
src/intelligence # C: llm client, RAG corpus, incident match, compliance, copilot, handover, report
src/api # D: FastAPI backend (+ telegram alerts)
src/dashboard # D: Streamlit command dashboard, plume + evacuation viz
scripts/ # download_data.py, make_demo.py
tests/ # contract guardrails (run before every PR)
| Member | Area | Reads |
|---|---|---|
| A | Data & simulation (+ vision) | ARCHITECTURE.md -> Member A |
| B | Risk engine, barriers, metrics | -> Member B |
| C | RAG, LLM, language products | -> Member C |
| D | API, dashboard, geo-viz, alerts | -> Member D |
- Branch
feat/<letter>-<thing>; push every work session (WIP is fine). PR todev;dev->mainonly at checkpoints. - Any change under
contracts/needs all-4 ack + a version bump. This is the #1 anti-chaos rule. - Never commit files >10 MB or
.env. Runpytest -qbefore every PR. - Human-in-the-loop only: the system detects, warns and recommends - it never controls the plant.
Budget: ₹0. All tools free (see ARCHITECTURE Part V).