Skip to content
Snippets Groups Projects
Commit d7fc1936 authored by Vojtěch Novotný's avatar Vojtěch Novotný
Browse files

smprace setup

parent cfe2ba6c
No related branches found
No related tags found
1 merge request!3Develop
#include <WiFi.h>
#include <HTTPClient.h>
#include <DHT.h>
// WiFi credentials
const char *ssid = "WIFI_NAME";
const char *password = "PWIFI_PW";
// Server url
const char *serverUrl = "http://1a68d31fc96915376990672871a32080.serveo.net/docs/thproject/index.php?p=";
// DHT sensor setup
#define DHTPIN 18 // Digital pin connected to the DHT sensor
#define DHTTYPE DHT11 // DHT 11
DHT dht(DHTPIN, DHTTYPE);
// Room identification - this varies for each ESP32, replace "room1", "room2", ...
const String roomId = "roomX";
// Time between measurements (in milliseconds)
const unsigned long interval = 60000; // 1 minute
unsigned long previousMillis = 0;
void setup()
{
Serial.begin(115200);
// Initialize DHT sensor
dht.begin();
// Connect to WiFi
WiFi.begin(ssid, password);
Serial.println("Connecting to WiFi...");
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi Connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
void loop()
{
unsigned long currentMillis = millis();
// Check if it's time to send data
if (currentMillis - previousMillis >= interval)
{
previousMillis = currentMillis;
// Read temperature and humidity
float humidity = dht.readHumidity();
float temperature = dht.readTemperature();
// Check if readings are valid
if (isnan(humidity) || isnan(temperature))
{
Serial.println("Failed to read from DHT sensor!");
return;
}
Serial.print("Temperature: ");
Serial.print(temperature);
Serial.print(" °C, Humidity: ");
Serial.print(humidity);
Serial.println(" %");
// Send data to server
sendDataToServer(temperature, humidity, roomId);
}
}
void sendDataToServer(float temperature, float humidity, String room)
{
// Check WiFi connection status
if (WiFi.status() == WL_CONNECTED)
{
HTTPClient http;
// Construct the URL with parameters
String url = String(serverUrl) + "data&room=" + room + "&temp=" + temperature + "&humidity=" + humidity;
// Begin HTTP connection
http.begin(url);
// Send HTTP GET request
int httpResponseCode = http.GET();
if (httpResponseCode > 0)
{
String response = http.getString();
Serial.println("HTTP Response code: " + String(httpResponseCode));
Serial.println("Response: " + response);
}
else
{
Serial.print("HTTP Error: ");
Serial.println(httpResponseCode);
}
// Free resources
http.end();
}
else
{
Serial.println("WiFi Disconnected");
// Attempt to reconnect
WiFi.reconnect();
}
}
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Monitoring Temperature & Humidity</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>
.sensor-card { margin-bottom: 20px; }
.reading { font-size: 2rem; font-weight: bold; }
.timestamp { font-size: 0.8rem; color: #666; }
.chart-container { height: 150px; margin-top: 10px; }
.phone-view .reading { font-size: 4rem; }
.phone-view .chart-container, .phone-view .timestamp { display: none; }
.phone-view .sensor-card { display: inline-block; width: 48%; margin-right: 2%; }
.phone-view .sensor-card:nth-child(2n) { margin-right: 0; }
.editable-title { cursor: pointer; }
.editable-title input { display: none; width: 100%; }
</style>
</head>
<body>
<div class="container mt-4">
<h1 class="mb-4 text-center">Monitoring Temperature & Humidity</h1>
<button id="toggle-phone-view" class="btn btn-primary mb-4">Toggle Phone View</button>
<div class="row" id="sensor-data"></div>
</div>
<script src="script.js"></script>
</body>
</html>
\ No newline at end of file
<?php
// File to store sensor data as JSON
$dataFile = 'sensor_data.json';
// Check if this is a data submission
if (isset($_GET['p']) && $_GET['p'] == 'data') {
if (isset($_GET['room']) && isset($_GET['temp']) && isset($_GET['humidity'])) {
$room = $_GET['room'];
$temperature = floatval($_GET['temp']);
$humidity = floatval($_GET['humidity']);
$timestamp = time();
// Read existing data
$data = [];
if (file_exists($dataFile)) {
$fileContent = file_get_contents($dataFile);
if (!empty($fileContent)) {
$data = json_decode($fileContent, true);
}
}
// Add or update room data
if (!isset($data[$room])) {
$data[$room] = [
'temperatures' => [],
'humidities' => [],
'timestamps' => []
];
}
// Append new readings (limit to last 48 readings(one per half hour))
$data[$room]['temperatures'][] = $temperature;
$data[$room]['humidities'][] = $humidity;
$data[$room]['timestamps'][] = $timestamp;
if (count($data[$room]['temperatures']) > 48) {
array_shift($data[$room]['temperatures']);
array_shift($data[$room]['humidities']);
array_shift($data[$room]['timestamps']);
}
file_put_contents($dataFile, json_encode($data));
echo "Data received successfully";
} else {
echo "Error: Missing parameters";
}
exit;
}
// If we're getting data
if (isset($_GET['p']) && $_GET['p'] == 'get') {
header('Content-Type: application/json');
echo file_exists($dataFile) ? file_get_contents($dataFile) : '{}';
exit;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Monitoring Temperature & Humidity</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>
.sensor-card { margin-bottom: 20px; }
.reading { font-size: 2rem; font-weight: bold; }
.timestamp { font-size: 0.8rem; color: #666; }
.chart-container { height: 150px; margin-top: 10px; }
</style>
</head>
<body>
<div class="container mt-4">
<h1 class="mb-4">Monitoring Temperature & Humidity</h1>
<div class="row" id="sensor-data"></div>
</div>
<script>
function formatTimestamp(timestamp) {
return new Date(timestamp * 1000).toLocaleString();
}
function loadSensorData() {
fetch('index.php?p=get')
.then(response => response.json())
.then(data => {
const sensorContainer = document.getElementById('sensor-data');
sensorContainer.innerHTML = '';
if (Object.keys(data).length === 0) {
sensorContainer.innerHTML = '<div class="col-12"><div class="alert alert-warning">No sensor data available yet.</div></div>';
return;
}
let html = '';
for (const [room, readings] of Object.entries(data)) {
const roomName = room.charAt(0).toUpperCase() + room.slice(1);
const ageInMinutes = Math.floor((Date.now() / 1000 - readings.timestamps[readings.timestamps.length - 1]) / 60);
html += `
<div class="col-md-6">
<div class="card sensor-card">
<div class="card-header bg-primary text-white">${roomName}</div>
<div class="card-body">
<div class="reading text-center">${readings.temperatures.at(-1).toFixed(1)}°C</div>
<div class="reading text-center">${readings.humidities.at(-1).toFixed(1)}%</div>
<div class="timestamp text-center">Last updated: ${formatTimestamp(readings.timestamps.at(-1))}
${ageInMinutes > 5 ? `<div class="text-danger">(${ageInMinutes} minutes ago)</div>` : ''}
</div>
<div class="chart-container"><canvas id="temp-chart-${room}"></canvas></div>
<div class="chart-container"><canvas id="hum-chart-${room}"></canvas></div>
</div>
</div>
</div>`;
}
sensorContainer.innerHTML = html;
for (const [room, readings] of Object.entries(data)) {
renderChart(`temp-chart-${room}`, readings.temperatures, readings.timestamps, 'Temperature (°C)', 'rgba(255, 99, 132, 1)');
renderChart(`hum-chart-${room}`, readings.humidities, readings.timestamps, 'Humidity (%)', 'rgba(54, 162, 235, 1)');
}
})
.catch(error => {
console.error('Error loading sensor data:', error);
document.getElementById('sensor-data').innerHTML = '<div class="col-12"><div class="alert alert-danger">Error loading sensor data. Please try again later.</div></div>';
});
}
function renderChart(canvasId, dataPoints, timestamps, label, color) {
new Chart(document.getElementById(canvasId).getContext('2d'), {
type: 'line',
data: {
labels: timestamps.map(t => formatTimestamp(t)),
datasets: [{
label: label,
data: dataPoints,
borderColor: color,
backgroundColor: color.replace('1)', '0.2)'),
fill: true,
tension: 0.4
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: { x: { display: false }, y: { beginAtZero: false } },
plugins: { legend: { display: false } }
}
});
}
loadSensorData();
setInterval(loadSensorData, 30000);
</script>
</body>
</html>
\ No newline at end of file
let roomNames = {};
function formatTimestamp(timestamp) {
return new Date(timestamp * 1000).toLocaleString();
}
function loadSensorData() {
fetch('index.php?p=get')
.then(response => response.json())
.then(data => {
const sensorContainer = document.getElementById('sensor-data');
sensorContainer.innerHTML = '';
if (Object.keys(data.sensorData).length === 0) {
sensorContainer.innerHTML = '<div class="col-12"><div class="alert alert-warning">No sensor data available yet.</div></div>';
return;
}
roomNames = data.roomNames;
let html = '';
for (const [room, readings] of Object.entries(data.sensorData)) {
const roomName = roomNames[room] || (room.charAt(0).toUpperCase() + room.slice(1));
const ageInMinutes = Math.floor((Date.now() / 1000 - readings.timestamps[readings.timestamps.length - 1]) / 60);
html += `
<div class="col-md-6 sensor-card">
<div class="card">
<div class="card-header bg-primary text-white text-center editable-title" onclick="editTitle(this)">
<span>${roomName}</span>
<input type="text" value="${roomName}" onblur="saveTitle(this, '${room}')" onkeypress="handleKeyPress(event, this, '${room}')">
</div>
<div class="card-body">
<div class="reading text-center">${readings.temperatures.at(-1).toFixed(1)}°C</div>
<div class="reading text-center">${readings.humidities.at(-1).toFixed(1)}%</div>
<div class="timestamp text-center">Last updated: ${formatTimestamp(readings.timestamps.at(-1))}
${ageInMinutes > 5 ? `<div class="text-danger">(${ageInMinutes} minutes ago)</div>` : ''}
</div>
<div class="chart-container"><canvas id="temp-chart-${room}"></canvas></div>
<div class="chart-container"><canvas id="hum-chart-${room}"></canvas></div>
</div>
</div>
</div>`;
}
sensorContainer.innerHTML = html;
for (const [room, readings] of Object.entries(data.sensorData)) {
renderChart(`temp-chart-${room}`, readings.temperatures, readings.timestamps, 'Temperature (°C)', 'rgba(255, 99, 132, 1)');
renderChart(`hum-chart-${room}`, readings.humidities, readings.timestamps, 'Humidity (%)', 'rgba(54, 162, 235, 1)');
}
})
.catch(error => {
console.error('Error loading sensor data:', error);
document.getElementById('sensor-data').innerHTML = '<div class="col-12"><div class="alert alert-danger">Error loading sensor data. Please try again later.</div></div>';
});
}
function renderChart(canvasId, dataPoints, timestamps, label, color) {
new Chart(document.getElementById(canvasId).getContext('2d'), {
type: 'line',
data: {
labels: timestamps.map(t => formatTimestamp(t)),
datasets: [{
label: label,
data: dataPoints,
borderColor: color,
backgroundColor: color.replace('1)', '0.2)'),
fill: true,
tension: 0.4
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: { x: { display: false }, y: { beginAtZero: false } },
plugins: { legend: { display: false } }
}
});
}
function editTitle(element) {
const span = element.querySelector('span');
const input = element.querySelector('input');
span.style.display = 'none';
input.style.display = 'block';
input.focus();
}
function saveTitle(input, room) {
const span = input.previousElementSibling;
span.textContent = input.value;
input.style.display = 'none';
span.style.display = 'block';
roomNames[room] = input.value;
saveRoomNames();
}
function handleKeyPress(event, input, room) {
if (event.key === 'Enter') {
saveTitle(input, room);
}
}
function saveRoomNames() {
fetch('index.php?p=saveNames', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(roomNames)
})
.then(response => response.text())
.then(data => {
console.log(data);
})
.catch(error => {
console.error('Error saving room names:', error);
});
}
document.getElementById('toggle-phone-view').addEventListener('click', () => {
document.body.classList.toggle('phone-view');
});
loadSensorData();
setInterval(loadSensorData, 30000);
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment