Web Interface
In this blog, I want to show you an improvement I added to my project, which is uploading sensor data to the web. I feel that having the data on the screen and the monitor connected to the Raspberry Pi is something simple, it could be done with an Arduino. That's why I set up a web server on the Raspberry Pi to create my own web API and receive and store the sensor data. I did this using the Flask framework.
Now, in addition to having the .py file, we also have an HTML file.
from flask import Flask, render_template, jsonify
import Adafruit_DHT
import random
from datetime import datetime
app = Flask(__name__)
sensor = Adafruit_DHT.DHT11
pin = 23
temperature_history = []
motion_sensor_state = False
flame_sensor_state = False
rain_sensor_state = False
@app.route('/data')
def get_sensor_data():
humidity, temperature = Adafruit_DHT.read_retry(sensor, pin)
data = {
'temperature': temperature,
'humidity': humidity
}
return jsonify(data)
def get_temperature():
temperature = random.uniform(20, 30)
return round(temperature, 2)
def get_humidity():
humidity = random.uniform(40, 60)
return round(humidity, 2)
def update_temperature_history(temperature):
current_time = datetime.now().strftime("%H:%M:%S")
temperature_history.append((temperature, current_time))
def get_motion_sensor_state():
return random.choice([True, False])
def get_flame_sensor_state():
return random.choice([True, False])
def get_rain_sensor_state():
return random.choice([True, False])
@app.route('/')
def index():
return render_template('index.html')
@app.route('/api/sensor-data')
def sensor_data():
temperature = get_temperature()
humidity = get_humidity()
update_temperature_history(temperature)
global motion_sensor_state, flame_sensor_state, rain_sensor_state
motion_sensor_state = get_motion_sensor_state()
flame_sensor_state = get_flame_sensor_state()
rain_sensor_state = get_rain_sensor_state()
return jsonify({
'temperature': temperature,
'humidity': humidity,
'motion_sensor': motion_sensor_state,
'flame_sensor': flame_sensor_state,
'rain_sensor': rain_sensor_state
})
@app.route('/api/temperature-history')
def temperature_history_data():
return jsonify({'temperature_history': temperature_history})
@app.route('/graph')
def render_graph_page():
return render_template('index.html')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
<!DOCTYPE html>
<html>
<head>
<title>Pi-Sense Web</title>
<style>
body {
background-color: #001f3f;
color: white;
font-family: Arial, sans-serif;
}
.container {
max-width: 600px;
margin: 0 auto;
padding: 20px;
}
.data-item {
margin-bottom: 10px;
}
.data-item label {
font-size: 16px;
display: inline-block;
width: 120px;
}
.data-item span {
font-weight: bold;
margin-left: 10px;
}
.graph-container {
margin-top: 20px;
}
</style>
</head>
<body>
<div class="container">
<div class="data-item">
<label>Temperature:</label>
<span id="temperature"></span>
</div>
<div class="data-item">
<label>Humidity:</label>
<span id="humidity"></span>
</div>
<div class="data-item">
<label>Motion:</label>
<span id="motion"></span>
</div>
<div class="data-item">
<label>Rain:</label>
<span id="rain"></span>
</div>
<div class="data-item">
<label>Flame:</label>
<span id="flame"></span>
</div>
<div class="graph-container">
<canvas id="temperatureGraph"></canvas>
</div>
</div>
<script>
function updateData() {
fetch('/data')
.then((response) => response.json())
.then((data) => {
document.getElementById('temperature').textContent = data.temperature;
document.getElementById('humidity').textContent = data.humidity;
document.getElementById('motion').textContent = data.motion;
document.getElementById('rain').textContent = data.rain;
document.getElementById('flame').textContent = data.flame;
})
.catch((error) => {
console.error('Error:', error);
});
}
function updateGraph() {
fetch('/graph')
.then((response) => response.json())
.then((data) => {
const ctx = document.getElementById('temperatureGraph').getContext('2d');
new Chart(ctx, {
type: 'line',
data: {
labels: data.times,
datasets: [
{
label: 'Temperature (°C)',
data: data.values,
backgroundColor: 'rgba(0, 31, 63, 0.3)',
borderColor: 'rgba(0, 31, 63, 1)',
borderWidth: 1,
},
],
},
options: {
scales: {
x: {
display: true,
title: {
display: true,
text: 'Time (s)',
font: {
size: 14,
},
color: '#001f3f',
},
},
y: {
display: true,
title: {
display: true,
text: 'Temperature (°C)',
font: {
size: 14,
},
color: '#001f3f',
},
},
},
},
});
})
.catch((error) => {
console.error('Error:', error);
});
}
setInterval(() => {
updateData();
updateGraph();
}, 1500);
</script>
</body>
</html>
The web interface looks as follows:

The interface has the same appearance, but now it can be viewed from any phone, tablet, or computer with internet access. This way, we are achieving the main objective: allowing scientists to know the conditions of their experiment or observed object without the need to be physically present.