beszel_api_mqtt.php
· 4.8 KiB · PHP
Ham
<?php
// cron a mettre en place
// Beszel stats mqtt
/* toutes les 30 secondes
* * * * * /usr/bin/php /path/beszel/beszel_api_mqtt.php > /dev/null 2>&1
* * * * * sleep 30 && /usr/bin/php /path/beszel/beszel_api_mqtt.php > /dev/null 2>&1
*/
// === CONFIGURATION ===
$baseUrl = 'url';
$username = 'mail';
$password = 'pass';
# mqtt HA
$mqttHost = 'ip'; // IP de ton Home Assistant
$mqttUser = 'user'; // identifiant MQTT
$mqttPass = 'pass'; // mot de passe MQTT
// === FONCTIONS ===
function getToken() {
global $baseUrl, $username, $password;
$payload = json_encode([
'identity' => $username,
'password' => $password
]);
$ch = curl_init($baseUrl . '/api/collections/users/auth-with-password');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'User-Agent: Mozilla/5.0'
],
CURLOPT_POSTFIELDS => $payload,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false
]);
$resp = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$err = curl_error($ch);
curl_close($ch);
if ($err) {
die("Erreur CURL: $err\n");
}
if ($code !== 200) {
die("Erreur auth ($code): $resp\nPayload envoyé: $payload\n");
}
$data = json_decode($resp, true);
return $data['token'] ?? null;
}
function apiGet($endpoint, $token) {
global $baseUrl;
$ch = curl_init($baseUrl . $endpoint);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer $token",
"Content-Type: application/json"
],
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false
]);
$resp = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($code !== 200) {
echo "Erreur API ($endpoint) : $code\n";
return ['items' => []];
}
return json_decode($resp, true);
}
function formatBytes($bytes, $precision = 2) {
$units = array('B', 'KB', 'MB', 'GB', 'TB');
for ($i = 0; $bytes > 1024 && $i < count($units) - 1; $i++) {
$bytes /= 1024;
}
return round($bytes, $precision) . ' ' . $units[$i];
}
// === AUTHENTIFICATION ===
$token = getToken();
if (!$token) {
die("⌠Impossible d'obtenir le token.\n");
}
// === RÉCUPÉRATION DES DONNÉES ===
$data = apiGet('/api/collections/systems/records?perPage=50&expand=latest_metrics', $token);
$systems = $data['items'] ?? [];
if (empty($systems)) {
die("âš ï¸ Aucune donnée reçue depuis Beszel.\n");
}
// === ENVOI DES DONNÉES MQTT + AUTO DISCOVERY ===
foreach ($systems as $sys) {
$device = preg_replace('/[^a-zA-Z0-9_-]/', '_', strtolower($sys['name'] ?? 'unknown'));
$info = $sys['info'] ?? [];
$payload = [
'cpu' => $info['cpu'] ?? 0,
'ram' => $info['mp'] ?? 0,
'load' => $info['la'][0] ?? 0,
'temp' => $info['t'] ?? 0,
'disk' => $info['dp'] ?? 0,
'gpu' => $info['g'] ?? 0,
'status' => $sys['status'] ?? 'unknown',
'time' => date('c')
];
$config = [
'cpu' => ['name' => 'CPU', 'unit' => '%', 'template' => '{{ value_json.cpu }}'],
'ram' => ['name' => 'RAM', 'unit' => '%', 'template' => '{{ value_json.ram }}'],
'load' => ['name' => 'Load', 'unit' => '', 'template' => '{{ value_json.load }}'],
'temp' => ['name' => 'Temp', 'unit' => '°C', 'template' => '{{ value_json.temp }}'],
'disk' => ['name' => 'Disk', 'unit' => '%', 'template' => '{{ value_json.disk }}'],
'gpu' => ['name' => 'GPU', 'unit' => '%', 'template' => '{{ value_json.gpu }}'],
];
// MQTT Discovery
foreach ($config as $key => $meta) {
$cfgPayload = json_encode([
'name' => "Beszel {$meta['name']} $device",
'state_topic' => "beszel/$device",
'unit_of_measurement' => $meta['unit'],
'value_template' => $meta['template'],
'unique_id' => "beszel_{$device}_{$key}",
'device' => [
'identifiers' => ["beszel_$device"],
'name' => "Beszel $device",
'manufacturer' => 'Beszel API'
]
]);
$topic = "homeassistant/sensor/$device/$key/config";
exec("mosquitto_pub -h $mqttHost -u $mqttUser -P $mqttPass -t '$topic' -m '$cfgPayload'");
}
// Envoi des données réelles
$json = json_encode($payload);
exec("mosquitto_pub -h $mqttHost -u $mqttUser -P $mqttPass -t 'beszel/$device' -m '$json'");
echo "✅ Données envoyées pour $device\n";
}
echo "🟢 Envoi MQTT terminé.\n";
?>
| 1 | <?php |
| 2 | |
| 3 | |
| 4 | // cron a mettre en place |
| 5 | // Beszel stats mqtt |
| 6 | /* toutes les 30 secondes |
| 7 | |
| 8 | * * * * * /usr/bin/php /path/beszel/beszel_api_mqtt.php > /dev/null 2>&1 |
| 9 | * * * * * sleep 30 && /usr/bin/php /path/beszel/beszel_api_mqtt.php > /dev/null 2>&1 |
| 10 | |
| 11 | */ |
| 12 | |
| 13 | // === CONFIGURATION === |
| 14 | $baseUrl = 'url'; |
| 15 | $username = 'mail'; |
| 16 | $password = 'pass'; |
| 17 | |
| 18 | # mqtt HA |
| 19 | $mqttHost = 'ip'; // IP de ton Home Assistant |
| 20 | $mqttUser = 'user'; // identifiant MQTT |
| 21 | $mqttPass = 'pass'; // mot de passe MQTT |
| 22 | |
| 23 | |
| 24 | // === FONCTIONS === |
| 25 | function getToken() { |
| 26 | global $baseUrl, $username, $password; |
| 27 | |
| 28 | $payload = json_encode([ |
| 29 | 'identity' => $username, |
| 30 | 'password' => $password |
| 31 | ]); |
| 32 | |
| 33 | $ch = curl_init($baseUrl . '/api/collections/users/auth-with-password'); |
| 34 | curl_setopt_array($ch, [ |
| 35 | CURLOPT_RETURNTRANSFER => true, |
| 36 | CURLOPT_POST => true, |
| 37 | CURLOPT_HTTPHEADER => [ |
| 38 | 'Content-Type: application/json', |
| 39 | 'User-Agent: Mozilla/5.0' |
| 40 | ], |
| 41 | CURLOPT_POSTFIELDS => $payload, |
| 42 | CURLOPT_SSL_VERIFYPEER => false, |
| 43 | CURLOPT_SSL_VERIFYHOST => false |
| 44 | ]); |
| 45 | |
| 46 | $resp = curl_exec($ch); |
| 47 | $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); |
| 48 | $err = curl_error($ch); |
| 49 | curl_close($ch); |
| 50 | |
| 51 | if ($err) { |
| 52 | die("Erreur CURL: $err\n"); |
| 53 | } |
| 54 | |
| 55 | if ($code !== 200) { |
| 56 | die("Erreur auth ($code): $resp\nPayload envoyé: $payload\n"); |
| 57 | } |
| 58 | |
| 59 | $data = json_decode($resp, true); |
| 60 | return $data['token'] ?? null; |
| 61 | } |
| 62 | |
| 63 | |
| 64 | function apiGet($endpoint, $token) { |
| 65 | global $baseUrl; |
| 66 | $ch = curl_init($baseUrl . $endpoint); |
| 67 | curl_setopt_array($ch, [ |
| 68 | CURLOPT_RETURNTRANSFER => true, |
| 69 | CURLOPT_HTTPHEADER => [ |
| 70 | "Authorization: Bearer $token", |
| 71 | "Content-Type: application/json" |
| 72 | ], |
| 73 | CURLOPT_SSL_VERIFYPEER => false, |
| 74 | CURLOPT_SSL_VERIFYHOST => false |
| 75 | ]); |
| 76 | $resp = curl_exec($ch); |
| 77 | $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); |
| 78 | curl_close($ch); |
| 79 | if ($code !== 200) { |
| 80 | echo "Erreur API ($endpoint) : $code\n"; |
| 81 | return ['items' => []]; |
| 82 | } |
| 83 | return json_decode($resp, true); |
| 84 | } |
| 85 | |
| 86 | function formatBytes($bytes, $precision = 2) { |
| 87 | $units = array('B', 'KB', 'MB', 'GB', 'TB'); |
| 88 | for ($i = 0; $bytes > 1024 && $i < count($units) - 1; $i++) { |
| 89 | $bytes /= 1024; |
| 90 | } |
| 91 | return round($bytes, $precision) . ' ' . $units[$i]; |
| 92 | } |
| 93 | |
| 94 | // === AUTHENTIFICATION === |
| 95 | $token = getToken(); |
| 96 | if (!$token) { |
| 97 | die("⌠Impossible d'obtenir le token.\n"); |
| 98 | } |
| 99 | |
| 100 | // === RÉCUPÉRATION DES DONNÉES === |
| 101 | $data = apiGet('/api/collections/systems/records?perPage=50&expand=latest_metrics', $token); |
| 102 | $systems = $data['items'] ?? []; |
| 103 | |
| 104 | if (empty($systems)) { |
| 105 | die("âš ï¸ Aucune donnée reçue depuis Beszel.\n"); |
| 106 | } |
| 107 | |
| 108 | // === ENVOI DES DONNÉES MQTT + AUTO DISCOVERY === |
| 109 | foreach ($systems as $sys) { |
| 110 | $device = preg_replace('/[^a-zA-Z0-9_-]/', '_', strtolower($sys['name'] ?? 'unknown')); |
| 111 | $info = $sys['info'] ?? []; |
| 112 | |
| 113 | $payload = [ |
| 114 | 'cpu' => $info['cpu'] ?? 0, |
| 115 | 'ram' => $info['mp'] ?? 0, |
| 116 | 'load' => $info['la'][0] ?? 0, |
| 117 | 'temp' => $info['t'] ?? 0, |
| 118 | 'disk' => $info['dp'] ?? 0, |
| 119 | 'gpu' => $info['g'] ?? 0, |
| 120 | 'status' => $sys['status'] ?? 'unknown', |
| 121 | 'time' => date('c') |
| 122 | ]; |
| 123 | |
| 124 | $config = [ |
| 125 | 'cpu' => ['name' => 'CPU', 'unit' => '%', 'template' => '{{ value_json.cpu }}'], |
| 126 | 'ram' => ['name' => 'RAM', 'unit' => '%', 'template' => '{{ value_json.ram }}'], |
| 127 | 'load' => ['name' => 'Load', 'unit' => '', 'template' => '{{ value_json.load }}'], |
| 128 | 'temp' => ['name' => 'Temp', 'unit' => '°C', 'template' => '{{ value_json.temp }}'], |
| 129 | 'disk' => ['name' => 'Disk', 'unit' => '%', 'template' => '{{ value_json.disk }}'], |
| 130 | 'gpu' => ['name' => 'GPU', 'unit' => '%', 'template' => '{{ value_json.gpu }}'], |
| 131 | ]; |
| 132 | |
| 133 | // MQTT Discovery |
| 134 | foreach ($config as $key => $meta) { |
| 135 | $cfgPayload = json_encode([ |
| 136 | 'name' => "Beszel {$meta['name']} $device", |
| 137 | 'state_topic' => "beszel/$device", |
| 138 | 'unit_of_measurement' => $meta['unit'], |
| 139 | 'value_template' => $meta['template'], |
| 140 | 'unique_id' => "beszel_{$device}_{$key}", |
| 141 | 'device' => [ |
| 142 | 'identifiers' => ["beszel_$device"], |
| 143 | 'name' => "Beszel $device", |
| 144 | 'manufacturer' => 'Beszel API' |
| 145 | ] |
| 146 | ]); |
| 147 | |
| 148 | $topic = "homeassistant/sensor/$device/$key/config"; |
| 149 | exec("mosquitto_pub -h $mqttHost -u $mqttUser -P $mqttPass -t '$topic' -m '$cfgPayload'"); |
| 150 | } |
| 151 | |
| 152 | // Envoi des données réelles |
| 153 | $json = json_encode($payload); |
| 154 | exec("mosquitto_pub -h $mqttHost -u $mqttUser -P $mqttPass -t 'beszel/$device' -m '$json'"); |
| 155 | |
| 156 | echo "✅ Données envoyées pour $device\n"; |
| 157 | } |
| 158 | |
| 159 | echo "🟢 Envoi MQTT terminé.\n"; |
| 160 | ?> |