Skip to content

Commit 0a0c79e

Browse files
committed
update README
1 parent e8e29d1 commit 0a0c79e

1 file changed

Lines changed: 389 additions & 1 deletion

File tree

README.md

Lines changed: 389 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,391 @@
11
# HydroSense Monitor
22

3-
Monitoring system for hydroponic farming that tracks sensor data and alerts growers to environmental issues.
3+
A hydroponic monitoring system that ingests sensor readings, applies intelligent classification rules, and provides real-time alerts through a React dashboard.
4+
5+
## Live Demo
6+
7+
**Frontend:** [https://hydro-sense-monitor.3jn045m1dbz0y.eu-central-1.cs.amazonlightsail.com/](https://hydro-sense-monitor.3jn045m1dbz0y.eu-central-1.cs.amazonlightsail.com/)
8+
**Backend API:** [https://hydro-sense-monitor.3jn045m1dbz0y.eu-central-1.cs.amazonlightsail.com/api/v1](https://hydro-sense-monitor.3jn045m1dbz0y.eu-central-1.cs.amazonlightsail.com/api/v1)
9+
10+
### Backend API docs
11+
12+
[https://documenter.getpostman.com/view/21567880/2sB2x2Ju3M](https://documenter.getpostman.com/view/21567880/2sB2x2Ju3M)
13+
14+
## Project Structure
15+
16+
````
17+
hydro-sense-monitor/
18+
├── backend/
19+
│ ├── app/
20+
│ │ ├── api/routes/ # FastAPI endpoints
21+
│ │ ├── core/ # Configuration
22+
│ │ ├── tests/ # Backend test suite
23+
│ │ ├── main.py # Application entry point
24+
│ │ └── schemas.py # Pydantic models
25+
│ └── pyproject.toml # Python dependencies
26+
├── frontend/
27+
│ ├── app/
28+
│ │ ├── common/components/ # Reusable UI components
29+
│ │ ├── routes/ # Page components
30+
│ │ └── lib/ # API client & utilities
31+
│ ├── tests/ # Frontend test suite
32+
│ └── package.json # Node dependencies
33+
├── docker/ # Container configurations
34+
├── .github/workflows/ # CI/CD pipeline
35+
└── README.md
36+
````
37+
38+
## Quick Start
39+
40+
### Backend (FastAPI)
41+
42+
```bash
43+
cd backend
44+
uv sync
45+
uv run uvicorn backend.app.main:app --reload
46+
```
47+
48+
Server runs at `http://localhost:8000`
49+
50+
### Frontend (React + TypeScript)
51+
52+
```bash
53+
cd frontend
54+
pnpm install
55+
pnpm dev
56+
```
57+
58+
Frontend available at `http://localhost:5173`
59+
60+
## API Endpoints
61+
62+
### `POST /api/v1/sensor`
63+
64+
Submit sensor readings and receive health classification.
65+
66+
**Request:**
67+
68+
```json
69+
{
70+
"unitId": "greenhouse-123",
71+
"timestamp": "2025-05-24T12:34:56Z",
72+
"readings": { "pH": 6.5, "temp": 22.1, "ec": 1.2 }
73+
}
74+
```
75+
76+
**Response:**
77+
78+
```json
79+
{
80+
"status": "OK",
81+
"classification": "Healthy"
82+
}
83+
```
84+
85+
### `GET /api/v1/alerts?unitId=greenhouse-123`
86+
87+
Retrieve the last 10 readings classified as "Needs Attention" for a specific unit.
88+
89+
**Response:**
90+
91+
```json
92+
{
93+
"unitId": "greenhouse-123",
94+
"alerts": [
95+
{
96+
"unitId": "greenhouse-123",
97+
"timestamp": "2025-05-24T12:34:56Z",
98+
"readings": { "pH": 4.2, "temp": 22.1, "ec": 1.2 },
99+
"classification": "Needs Attention"
100+
}
101+
],
102+
"unitExists": true,
103+
"totalReadings": 15
104+
}
105+
```
106+
107+
### `GET /api/v1/units`
108+
109+
Get overview of all hydroponic units with health status and recent activity.
110+
111+
**Response:**
112+
113+
```json
114+
{
115+
"units": [
116+
{
117+
"unitId": "greenhouse-123",
118+
"lastReading": { /* Latest sensor reading */ },
119+
"totalReadings": 25,
120+
"alertsCount": 3,
121+
"healthStatus": "warning"
122+
}
123+
],
124+
"totalUnits": 5
125+
}
126+
```
127+
128+
### `GET /healthcheck`
129+
130+
System health verification endpoint.
131+
132+
**Response:**
133+
134+
```json
135+
{
136+
"status": "Server is running!"
137+
}
138+
```
139+
140+
## Design Decisions
141+
142+
### pH Classification Thresholds
143+
144+
- **Healthy**: pH 5.5 - 7.0 (inclusive)
145+
- **Needs Attention**: pH < 5.5 or pH > 7.0
146+
147+
This range provides the sweet spot for nutrient availability in hydroponic systems. If the pH goes too high or too low, plants lose the ability to take up nutrients - it's like the nutrients are there but out of reach.
148+
149+
### Health Status System
150+
151+
Units are categorized based on recent alert frequency:
152+
153+
- **Healthy**: 0 alerts in last 10 readings
154+
- **Warning**: 1-3 alerts in last 10 readings
155+
- **Critical**: 4+ alerts in last 10 readings
156+
157+
# Data Storage
158+
159+
Uses in-memory storage for simplicity and speed. The data structure uses a list for readings and a dict for quick alert lookups by `unitId`. For production environment, consider:
160+
161+
- PostgreSQL/Supabase for persistent storage
162+
- Redis for caching frequently accessed readings
163+
- Message queues (RabbitMQ) for high-volume sensor inputs
164+
165+
## Enhancement: Units Health Overview
166+
167+
**Implementation**: A minimal "View All Units" dashboard that displays a grid of all hydroponic units with color-coded health indicators, enabling growers to instantly assess their entire operation.
168+
169+
**Value**: This bird's-eye view eliminates the need to check each unit individually and helps prioritize which units need immediate attention. The interface includes:
170+
171+
- **Modal Interface**: Clean overlay with unit grid layout
172+
- **Health Status Indicators**: Color-coded badges (green/yellow/red)
173+
- **Quick Actions**: Click any unit to jump directly to its alert details
174+
- **Pagination**: Handles large numbers of units efficiently
175+
- **Real-time Refresh**: One-click update of all unit statuses
176+
177+
This small addition lets you zoom out from single units to see the big picture of your whole operation, making life way easier for growers/commercial hydroponic farms.
178+
179+
## Testing
180+
181+
### Backend Tests (pytest)
182+
183+
```bash
184+
cd backend
185+
uv run pytest app/tests/ -v
186+
```
187+
188+
**Coverage includes:**
189+
190+
- Payload validation and error handling
191+
- pH classification logic accuracy
192+
- Alert storage and retrieval functionality
193+
- API endpoint behavior and responses
194+
195+
### Frontend Tests (Jest + React Testing Library)
196+
197+
```bash
198+
cd frontend
199+
pnpm test
200+
```
201+
202+
**Coverage includes:**
203+
204+
- Component rendering and user interactions
205+
- Color logic for health status indicators
206+
- Alert fetching and error handling
207+
- Random reading generation and API integration
208+
- Units Health Dashboard functionality
209+
210+
### Production-Critical Test Cases
211+
212+
Beyond standard test coverage, two critical production scenarios are covered:
213+
214+
1. **Out-of-Order Timestamps** (`test_out_of_order_timestamps`)
215+
216+
- **Problem**: Sensors may send readings with non-chronological timestamps due to network delays, buffering, or clock sync issues
217+
- **Solution**: System accepts and stores readings correctly while maintaining proper temporal ordering for alerts
218+
219+
2. **Malformed JSON Payloads** (`test_malformed_json_payload`)
220+
221+
- **Problem**: Invalid JSON from network corruption, client bugs, or malicious requests could crash the system
222+
- **Solution**: Robust error handling with appropriate HTTP status codes and descriptive error messages without exposing internal details
223+
224+
225+
## Environment Configuration
226+
227+
### Backend Environment Variables
228+
229+
Create `.env` in `backend/` directory:
230+
231+
```bash
232+
PROJECT_NAME="HydroSense Monitor API"
233+
BACKEND_CORS_ORIGINS=http://localhost:3000,http://127.0.0.1:3000,http://localhost:5173
234+
```
235+
236+
### Frontend Environment Variables
237+
238+
Create `.env` in `frontend/` directory:
239+
240+
```bash
241+
VITE_API_URL=http://127.0.0.1:8000/api/v1
242+
VITE_SHOW_DEV_TOOLS=true
243+
```
244+
245+
You can set `VITE_SHOW_DEV_TOOLS=false` to hide development tools (Generate Random Reading)
246+
247+
248+
249+
## CI/CD Pipeline
250+
251+
Automated GitHub Actions workflow provides:
252+
253+
- **Testing**: Full backend (pytest) and frontend (Jest) test suites
254+
- **Building**: Docker containerization for both services
255+
- **Deployment**: AWS Lightsail deployment with multi-container orchestration
256+
- **Quality Assurance**: Linting and type checking
257+
258+
***
259+
260+
## How Total Readings and Alerts Count Work
261+
262+
### Total Readings
263+
264+
- What it counts: The total number of sensor readings ever submitted
265+
for that unit
266+
- Behavior: Always increases, never decreases
267+
- All units show "1" because each has submitted
268+
only one reading so far
269+
270+
### Alerts Count
271+
272+
- What it counts: The total number of readings classified as "Needs
273+
Attention" (pH < 5.5 or pH > 7.0) for that unit
274+
- Behavior: Can only increase or stay the same, never decreases
275+
276+
### Health Status (the colored badge)
277+
278+
- Based on recent performance - only the last 10 readings:
279+
280+
- 🟢 HEALTHY: 0 alerts in last 10 readings
281+
- 🟡 WARNING: 1-3 alerts in last 10 readings
282+
- 🔴 CRITICAL: 4+ alerts in last 10 readings
283+
284+
285+
### Example:
286+
287+
If `tomato-row-6`unit (currently showing pH 4.6) continues sending readings:
288+
289+
- After 5 more readings: Total Readings: 6
290+
- If 3 are healthy (pH 5.5-7.0): Alerts Count: 3 (original 1 + 2 new
291+
alerts)
292+
- Health Status would depend on the last 10 readings pattern
293+
294+
The counts provide historical context (total performance) while the
295+
health status shows current condition (recent performance).
296+
297+
***
298+
299+
## Demonstrating Health Status Transitions
300+
301+
### Unit Transitions from HEALTHY → WARNING → CRITICAL
302+
303+
Create a Healthy Unit (0 alerts in last 10)
304+
305+
306+
307+
**POST /api/v1/sensor** - Submit 10 healthy readings
308+
309+
```jsonc
310+
// Reading 1-10: All healthy (pH between 5.5-7.0)
311+
{
312+
"unitId": "tomato-row-6",
313+
"timestamp": "2025-06-05T10:00:00Z",
314+
"readings": {
315+
"pH": 6.5,
316+
"temp": 22.5,
317+
"ec": 1.8
318+
}
319+
}
320+
```
321+
322+
**Result:** After 10 readings with pH 5.5-7.0, unit shows 🟢 HEALTHY
323+
324+
### Transition to WARNING (1-3 alerts in last 10)
325+
326+
**POST /api/v1/sensor** - Add 2 bad readings
327+
328+
```jsonc
329+
// Reading 11: Bad pH (alert)
330+
{
331+
"unitId": "tomato-row-6",
332+
"timestamp": "2025-06-05T10:11:00Z",
333+
"readings": {
334+
"pH": 5.2, // < 5.5 = Alert!
335+
"temp": 22.5,
336+
"ec": 1.8
337+
}
338+
}
339+
// Reading 12: Another bad pH
340+
{
341+
"unitId": "tomato-row-6",
342+
"timestamp": "2025-06-05T10:12:00Z",
343+
"readings": {
344+
"pH": 7.8, // > 7.0 = Alert!
345+
"temp": 22.5,
346+
"ec": 1.8
347+
}
348+
}
349+
```
350+
351+
**Result:** Last 10 readings (3-12) have 2 alerts → 🟡 **WARNING**
352+
353+
### Transition to CRITICAL (4+ alerts in last 10)
354+
355+
**POST /api/v1/sensor** - Add more bad readings
356+
357+
```jsonc
358+
// Readings 13-16: All bad pH values
359+
{
360+
"unitId": "tomato-row-6",
361+
"timestamp": "2025-06-05T10:13:00Z",
362+
"readings": {
363+
"pH": 4.8, // alert!
364+
"temp": 22.5,
365+
"ec": 1.8
366+
}
367+
}
368+
```
369+
370+
**Result:** Last 10 readings (7-16) have 5 alerts → 🔴 **CRITICAL**
371+
372+
### Recovery from CRITICAL → WARNING → HEALTHY
373+
374+
Begin recovery with `tomato-row-6` unit.
375+
376+
**POST /api/v1/sensor** - Add good readings
377+
378+
```jsonc
379+
{
380+
"unitId": "tomato-row-6",
381+
"timestamp": "2025-06-05T11:00:00Z",
382+
"readings": {
383+
"pH": 6.2, // Healthy!
384+
"temp": 22.5,
385+
"ec": 1.8
386+
}
387+
}
388+
```
389+
390+
**After adding 7 healthy readings:** Last 10 have only 3 alerts → 🟡 WARNING
391+
**After adding 10 healthy readings:** Last 10 have 0 alerts → 🟢 HEALTHY

0 commit comments

Comments
 (0)