Correction connexion PDO et liaison dynamique du graphique
This commit is contained in:
19
config.php
19
config.php
@@ -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;
|
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
@@ -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'],
|
||||||
echo "Événement sécurité inséré : " . json_encode($data) . "\n";
|
':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";
|
||||||
|
} 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);
|
||||||
|
|||||||
@@ -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();
|
||||||
Reference in New Issue
Block a user