Correction connexion PDO et liaison dynamique du graphique

This commit is contained in:
Enzo Freitas
2026-06-04 17:05:49 +02:00
parent 8c86c42c04
commit 4177359d9a
3 changed files with 106 additions and 80 deletions

View File

@@ -1,18 +1,25 @@
<?php <?php
define('DB_HOST', 'smarthome_db'); define('DB_HOST', 'mariadb');
define('DB_USER', 'smarthome_user'); define('DB_USER', 'smarthome_user');
define('DB_PASSWORD', 'SH_LaSalle_SD8'); define('DB_PASSWORD', 'SH_LaSalle_SD8');
define('DB_NAME', 'smarthome'); define('DB_NAME', 'smarthome');
define('JWT_SECRET', 'smarthome_secret_key_2024_smart_home_project_very_long_key'); define('JWT_SECRET', 'smarthome_secret_key_2024_smart_home_project_very_long_key');
define('MQTT_BROKER', 'localhost');
define('MQTT_BROKER', 'mosquitto');
define('MQTT_PORT', 1883); define('MQTT_PORT', 1883);
define('MQTT_TOPIC_CLIMATE', 'smarthome/climate'); define('MQTT_TOPIC_CLIMATE', 'smarthome/climate');
define('MQTT_TOPIC_SECURITY', 'smarthome/security'); define('MQTT_TOPIC_SECURITY', 'smarthome/security');
function get_db() { function get_db() {
$conn = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); try {
if ($conn->connect_error) { $pdo = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=utf8", DB_USER, DB_PASSWORD, [
die(json_encode(['error' => 'Connexion échouée : ' . $conn->connect_error])); PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
]);
return $pdo;
} catch (PDOException $e) {
die(json_encode(['error' => 'Connexion échouée : ' . $e->getMessage()]));
} }
return $conn;
} }
?> ?>

View File

@@ -5,27 +5,38 @@ require_once 'vendor/autoload.php';
use PhpMqtt\Client\MqttClient; use PhpMqtt\Client\MqttClient;
use PhpMqtt\Client\ConnectionSettings; use PhpMqtt\Client\ConnectionSettings;
function insert_climate($data) { try {
$db = get_db(); $db = get_db();
$stmt = $db->prepare("INSERT INTO climate_data (temperature, humidity, pressure, luminosity) VALUES (?, ?, ?, ?)"); } catch (Exception $e) {
$stmt->bind_param("dddd", die("Impossible de démarrer le script : " . $e->getMessage() . "\n");
$data['temperature'],
$data['humidity'],
$data['pressure'],
$data['luminosity']
);
$stmt->execute();
$db->close();
echo "Donnée climatique insérée : " . json_encode($data) . "\n";
} }
function insert_security($data) { function insert_climate($db, $data) {
$db = get_db(); try {
$stmt = $db->prepare("INSERT INTO security_events (event_type, location) VALUES (?, ?)"); $stmt = $db->prepare("INSERT INTO climate_data (temperature, humidity, pressure, luminosity) VALUES (:temp, :hum, :pres, :lum)");
$stmt->bind_param("ss", $data['event_type'], $data['location']); $stmt->execute([
$stmt->execute(); ':temp' => $data['temperature'],
$db->close(); ':hum' => $data['humidity'],
':pres' => $data['pressure'],
':lum' => $data['luminosity']
]);
echo "Donnée climatique insérée : " . json_encode($data) . "\n";
} catch (PDOException $e) {
echo "Erreur d'insertion climat : " . $e->getMessage() . "\n";
}
}
function insert_security($db, $data) {
try {
$stmt = $db->prepare("INSERT INTO security_events (event_type, location) VALUES (:event, :loc)");
$stmt->execute([
':event' => $data['event_type'],
':loc' => $data['location']
]);
echo "Événement sécurité inséré : " . json_encode($data) . "\n"; echo "Événement sécurité inséré : " . json_encode($data) . "\n";
} catch (PDOException $e) {
echo "Erreur d'insertion sécurité : " . $e->getMessage() . "\n";
}
} }
$mqtt = new MqttClient(MQTT_BROKER, MQTT_PORT); $mqtt = new MqttClient(MQTT_BROKER, MQTT_PORT);
@@ -33,14 +44,18 @@ $settings = (new ConnectionSettings())->setKeepAliveInterval(60);
$mqtt->connect($settings); $mqtt->connect($settings);
echo "Connecté au broker MQTT\n"; echo "Connecté au broker MQTT\n";
$mqtt->subscribe(MQTT_TOPIC_CLIMATE, function($topic, $message) { $mqtt->subscribe(MQTT_TOPIC_CLIMATE, function($topic, $message) use ($db) {
$data = json_decode($message, true); $data = json_decode($message, true);
insert_climate($data); if ($data) {
insert_climate($db, $data);
}
}, 0); }, 0);
$mqtt->subscribe(MQTT_TOPIC_SECURITY, function($topic, $message) { $mqtt->subscribe(MQTT_TOPIC_SECURITY, function($topic, $message) use ($db) {
$data = json_decode($message, true); $data = json_decode($message, true);
insert_security($data); if ($data) {
insert_security($db, $data);
}
}, 0); }, 0);
$mqtt->loop(true); $mqtt->loop(true);

View File

@@ -1,15 +1,11 @@
/* global Chart */ /* global Chart */
// -------------------------------
// 1⃣ Sélection des widgets
// -------------------------------
const climat = document.querySelector('.widget.climat'); const climat = document.querySelector('.widget.climat');
const securite = document.querySelector('.widget.securite'); const securite = document.querySelector('.widget.securite');
const energie = document.querySelector('.widget.energie'); const energie = document.querySelector('.widget.energie');
const lumiere = document.querySelector('.widget.lumiere'); const lumiere = document.querySelector('.widget.lumiere');
const alertes = document.querySelector('.widget.alertes'); const alertes = document.querySelector('.widget.alertes');
// -------------------------------
// 2⃣ Hover dynamique sur les widgets
// -------------------------------
function setupHover(widget, colorNormal, colorHover) { function setupHover(widget, colorNormal, colorHover) {
widget.addEventListener('mouseenter', () => { widget.addEventListener('mouseenter', () => {
widget.style.backgroundColor = colorHover; widget.style.backgroundColor = colorHover;
@@ -18,31 +14,33 @@ function setupHover(widget, colorNormal, colorHover) {
widget.style.backgroundColor = colorNormal; widget.style.backgroundColor = colorNormal;
}); });
} }
setupHover(climat, '#ADD8E6', '#87CEEB'); setupHover(climat, '#ADD8E6', '#87CEEB');
setupHover(securite, '#D3D3D3', '#C0C0C0'); setupHover(securite, '#D3D3D3', '#C0C0C0');
setupHover(energie, '#FFFACD', '#FAFAD2'); setupHover(energie, '#FFFACD', '#FAFAD2');
setupHover(lumiere, '#F5F5DC', '#FFF8DC'); setupHover(lumiere, '#F5F5DC', '#FFF8DC');
// -------------------------------
// 3⃣ Simulation d'alerte visuelle
// -------------------------------
function showAlert(widget) { function showAlert(widget) {
widget.classList.add('alert'); widget.classList.add('alert');
} }
showAlert(climat); showAlert(climat);
alertes.style.display = 'block'; alertes.style.display = 'block';
// -------------------------------
// 4⃣ Graphique Chart.js let monGraphique = null;
// -------------------------------
const canvasTemp = document.getElementById('graph-temp'); const canvasTemp = document.getElementById('graph-temp');
if(canvasTemp) {
function creerGraphique(labels, valeurs) {
if (!canvasTemp) return;
const ctx = canvasTemp.getContext('2d'); const ctx = canvasTemp.getContext('2d');
new Chart(ctx, {
monGraphique = new Chart(ctx, {
type: 'line', type: 'line',
data: { data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May'], labels: labels,
datasets: [{ datasets: [{
label: 'Température', label: 'Température',
data: [20, 22, 19, 23, 21], data: valeurs,
borderColor: 'blue', borderColor: 'blue',
backgroundColor: 'rgba(173,216,230,0.2)', backgroundColor: 'rgba(173,216,230,0.2)',
tension: 0.4 tension: 0.4
@@ -54,49 +52,55 @@ if(canvasTemp) {
legend: { display: true } legend: { display: true }
}, },
scales: { scales: {
x: { display: true, title: { display: true, text: 'Mois' } }, x: { display: true, title: { display: true, text: 'Temps' } },
y: { display: true, title: { display: true, text: '°C' } } y: { display: true, title: { display: true, text: '°C' } }
} }
} }
}); });
} }
// -------------------------------
// 5⃣ Données réelles depuis l'API async function chargerDonnees() {
// ------------------------------- try {
const API_BASE = "http://192.168.10.1:8080"; const res = await fetch('api/get_data.php');
const data = await res.json();
if (data.status === 'success') {
if (data.climate) {
document.getElementById("temperature").textContent = data.climate.temperature + " °C";
document.getElementById("humidity").textContent = data.climate.humidity + " %";
document.getElementById("pressure").textContent = data.climate.pressure + " hPa";
document.getElementById("luminosity").textContent = data.climate.luminosity + " lux";
}
if (data.security) {
document.getElementById("event_type").textContent = data.security.event_type;
document.getElementById("location").textContent = data.security.location;
}
if (data.graph && data.graph.length > 0) {
const labels = data.graph.map(point => {
const date = new Date(point.timestamp);
return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
});
const temperatures = data.graph.map(point => point.temperature);
if (monGraphique) {
monGraphique.data.labels = labels;
monGraphique.data.datasets[0].data = temperatures;
monGraphique.update();
} else {
creerGraphique(labels, temperatures);
}
}
}
} catch (error) {
console.error("Erreur lors du chargement de l'API :", error);
}
}
async function init() { async function init() {
const res = await fetch(`${API_BASE}/auth.php`, { await chargerDonnees();
method: "POST", setInterval(chargerDonnees, 5000);
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ username: "admin", password: "admin123" })
});
const data = await res.json();
const token = data.token;
await chargerClimat(token);
await chargerSecurite(token);
}
async function chargerClimat(token) {
const res = await fetch(`${API_BASE}/routes/climate.php`, {
headers: { "Authorization": "Bearer " + token }
});
const data = await res.json();
const last = Array.isArray(data) ? data[data.length - 1] : data;
document.getElementById("temperature").textContent = last.temperature + " °C";
document.getElementById("humidity").textContent = last.humidity + " %";
document.getElementById("pressure").textContent = last.pressure + " hPa";
document.getElementById("luminosity").textContent = last.luminosity + " lux";
}
async function chargerSecurite(token) {
const res = await fetch(`${API_BASE}/routes/security.php`, {
headers: { "Authorization": "Bearer " + token }
});
const data = await res.json();
const last = Array.isArray(data) ? data[data.length - 1] : data;
document.getElementById("event_type").textContent = last.event_type;
document.getElementById("location").textContent = last.location;
} }
init(); init();