Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions docs/iot_setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@

# IoT Device Setup Guide

This guide provides instructions for setting up, configuring, and deploying the IoT sensors for the LifeLine-ICT project.

## 1. Overview

The IoT layer consists of two main components:

1. **Sensor Nodes**: ESP32 microcontrollers connected to rainfall and water level sensors.
2. **Data Logger**: A Python script that acts as a simple backend to receive and log data from the sensors.

## 2. Hardware Requirements

* **Microcontroller**: ESP32 Development Board
* **Rainfall Sensor**: Tipping Bucket Rain Gauge (connected to a digital GPIO pin)
* **Water Level Sensor**: HC-SR04 Ultrasonic Sensor

## 3. Sensor Code Setup (Arduino)

The code for the sensors is written in C++ using the Arduino framework.

### 3.1. Prerequisites

* [Arduino IDE](https://www.arduino.cc/en/software) or [PlatformIO](https://platformio.org/)
* ESP32 Board Support Package installed in your IDE.
* Libraries: `WiFi`, `HTTPClient` (usually included with the ESP32 package).

### 3.2. Configuration

There are two sketch files located in `iot/sensors/`:

* `rainfall_sensor.ino`
* `water_level_sensor.ino`

In both files, you **must** update the following configuration variables at the top of the file:

```cpp
// --- Configuration ---
const char* ssid = "YOUR_WIFI_SSID"; // Your WiFi network name
const char* password = "YOUR_WIFI_PASSWORD"; // Your WiFi password
const char* api_endpoint = "http://<YOUR_SERVER_IP>:5000/data"; // URL of the data logger
```

### 3.3. Pin Configuration

* **Rainfall Sensor**: The `rain_sensor_pin` is set to `GPIO14`. You can change this if needed.
* **Water Level Sensor**: The `trig_pin` and `echo_pin` are set to `GPIO12` and `GPIO13` respectively.

### 3.4. Uploading the Code

1. Open the desired `.ino` file in your IDE.
2. Select your ESP32 board from the board manager.
3. Select the correct COM port.
4. Click "Upload" to flash the code to the ESP32.

## 4. Data Logger Setup (Python)

The data logger is a simple Flask web server that listens for incoming data from the sensors and logs it to a CSV file.

### 4.1. Prerequisites

* Python 3.x
* Flask library

### 4.2. Installation

Navigate to the `iot/logging/` directory and install Flask:

```bash
pip install Flask
```

### 4.3. Running the Server

From the `iot/logging/` directory, run the following command:

```bash
python log_data.py
```

The server will start and listen on all network interfaces at `http://0.0.0.0:5000`.

### 4.4. Logged Data

Sensor data will be appended to the `sensor_data.csv` file in the `iot/logging/` directory. The file will have the following columns:

* `timestamp`
* `sensor_type`
* `value`
50 changes: 50 additions & 0 deletions iot/logging/log_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@

from flask import Flask, request, jsonify
import csv
import os
from datetime import datetime

app = Flask(__name__)

# --- Configuration ---
LOG_FILE = 'sensor_data.csv'

# --- CSV Header ---
CSV_HEADER = ['timestamp', 'sensor_type', 'value']

# --- Initialize CSV file ---
if not os.path.exists(LOG_FILE):
with open(LOG_FILE, 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow(CSV_HEADER)

@app.route('/data', methods=['POST'])
def log_data():
"""Receives sensor data and logs it to a CSV file."""
try:
data = request.get_json()
if not data or 'sensor_type' not in data or 'value' not in data:
return jsonify({'error': 'Invalid payload'}), 400

timestamp = datetime.utcnow().isoformat()
sensor_type = data['sensor_type']
value = data['value']

# --- Log to console ---
print(f"Received data: {timestamp}, {sensor_type}, {value}")

# --- Append to CSV ---
with open(LOG_FILE, 'a', newline='') as f:
writer = csv.writer(f)
writer.writerow([timestamp, sensor_type, value])

return jsonify({'status': 'success'}), 201

except Exception as e:
print(f"Error processing request: {e}")
return jsonify({'error': 'Internal Server Error'}), 500

if __name__ == '__main__':
# To install dependencies: pip install Flask
# To run: python log_data.py
app.run(host='0.0.0.0', port=5000, debug=True)
73 changes: 73 additions & 0 deletions iot/sensors/rainfall_sensor.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#include <WiFi.h>
#include <HTTPClient.h>

// --- Configuration ---
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
const char* api_endpoint = "http://your-backend-api.com/data"; // Placeholder

// --- Sensor Pin ---
const int rain_sensor_pin = 14; // GPIO14

// --- Sensor State ---
volatile int tip_count = 0;
const float bucket_size_mm = 0.2794; // mm of rain per tip
unsigned long last_tip_time = 0;

// --- Debounce ---
const long debounce_delay = 50; // ms

// --- Interrupt Service Routine (ISR) ---
void IRAM_ATTR handle_interrupt() {
if ((millis() - last_tip_time) > debounce_delay) {
tip_count++;
last_tip_time = millis();
}
}

void setup() {
Serial.begin(115200);
Serial.println("Starting Rainfall Sensor...");

// --- Initialize WiFi ---
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi...");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nConnected to WiFi!");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());

// --- Initialize Sensor Pin ---
pinMode(rain_sensor_pin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(rain_sensor_pin), handle_interrupt, FALLING);
}

void loop() {
// Report every 15 minutes (900,000 ms)
delay(900000);

if (tip_count > 0) {
float rainfall_mm = tip_count * bucket_size_mm;
Serial.printf("Rainfall detected: %.4f mm\n", rainfall_mm);

// --- Send data to backend ---
send_data(rainfall_mm);

// --- Reset count ---
tip_count = 0;
} else {
Serial.println("No rainfall detected in the last 15 minutes.");
}
}

void send_data(float rainfall) {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin(api_endpoint);
http.addHeader("Content-Type", "application/json");

// --- Create JSON payload ---
String json_payload = "{\"sensor_type\":\"rainfall\", \"value\":
84 changes: 84 additions & 0 deletions iot/sensors/water_level_sensor.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#include <WiFi.h>
#include <HTTPClient.h>

// --- Configuration ---
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
const char* api_endpoint = "http://your-backend-api.com/data"; // Placeholder

// --- Sensor Pins (HC-SR04 Ultrasonic Sensor) ---
const int trig_pin = 12; // GPIO12
const int echo_pin = 13; // GPIO13

// --- Sensor Calibration ---
// Distance from sensor to bottom of the water body when empty
const float container_height_cm = 100.0;

void setup() {
Serial.begin(115200);
Serial.println("Starting Water Level Sensor...");

// --- Initialize WiFi ---
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi...");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("
Connected to WiFi!");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());

// --- Initialize Sensor Pins ---
pinMode(trig_pin, OUTPUT);
pinMode(echo_pin, INPUT);
}

void loop() {
// Report every 5 minutes (300,000 ms)
delay(300000);

float water_level_cm = read_water_level();
Serial.printf("Current water level: %.2f cm
", water_level_cm);

// --- Send data to backend ---
send_data(water_level_cm);
}

float read_water_level() {
// --- Trigger the sensor ---
digitalWrite(trig_pin, LOW);
delayMicroseconds(2);
digitalWrite(trig_pin, HIGH);
delayMicroseconds(10);
digitalWrite(trig_pin, LOW);

// --- Read the echo ---
long duration = pulseIn(echo_pin, HIGH);

// --- Calculate distance in cm ---
// Speed of sound = 343 m/s = 0.0343 cm/us
// Distance = (duration * speed of sound) / 2
float distance_cm = (duration * 0.0343) / 2;

// --- Calculate water level ---
float water_level = container_height_cm - distance_cm;

// --- Clamp values to avoid negative readings ---
if (water_level < 0) {
water_level = 0;
}

return water_level;
}

void send_data(float water_level) {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin(api_endpoint);
http.addHeader("Content-Type", "application/json");

// --- Create JSON payload ---
String json_payload = "{\"sensor_type\":\"water_level\", \"value\":
39 changes: 39 additions & 0 deletions issues.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Issues

Here is a summary of the open issues in this repository:

* **#10: ADD DATABASE MIGRATIONS & VERSIONING**
* Status: Open
* Opened on: Sep 29, 2025

* **#9: HANDLE CORS / SECURITY CONFIGURATION ISSUES**
* Status: Open
* Opened on: Sep 29, 2025

* **#8: EMAIL & SMS NOTIFICATION SERVICE**
* Status: Open
* Opened on: Sep 29, 2025

* **#7: FILE UPLOAD & DOCUMENT MANAGEMENT ENDPOINT**
* Status: Open
* Opened on: Sep 29, 2025

* **#6: AUDIT LOG / ACTIVITY TRACKING**
* Status: Open
* Opened on: Sep 29, 2025

* **#5: CRUD APIS FOR RESOURCES / ENTITIES**
* Status: Open
* Opened on: Sep 29, 2025

* **#4: IMPLEMENT USER AUTHENTICATION & JWT**
* Status: Open
* Opened on: Sep 29, 2025

* **#3: BACKEND & ANALYTICS SETUP**
* Status: Open
* Opened on: Sep 2, 2025

* **#2: IOT LAYER SETUP**
* Status: Open
* Opened on: Sep 2, 2025