Files
Enelix-Utils/ShellyModul/libs/ShellyParser.php
T
dh 4cbec75d56
Tests / test (push) Successful in 42s
Shelly MQTT Modul implementieren
2026-09-17 09:46:07 +00:00

137 lines
3.6 KiB
PHP

<?php
declare(strict_types=1);
final class ShellyParser
{
/**
* Extrahiert den Modellteil aus einer Shelly-RPC-Source.
*/
public static function extractType(string $source): string
{
if (preg_match('/^shelly([a-z0-9]+)-/i', trim($source), $matches) !== 1) {
return 'unknown';
}
return strtolower($matches[1]);
}
/**
* @return array{outputs: array<int, bool>, inputs: array<int, bool>, temperature: ?float}
*/
public static function mapParams(array $params): array
{
$mapped = [
'outputs' => [],
'inputs' => [],
'temperature' => null,
];
foreach ($params as $component => $value) {
if (!is_string($component) || !is_array($value)) {
continue;
}
if (preg_match('/^switch:(\d+)$/', $component, $matches) === 1) {
$index = (int) $matches[1];
$output = self::toBoolean($value['output'] ?? null);
$input = self::toBoolean($value['input'] ?? null);
if ($output !== null) {
$mapped['outputs'][$index] = $output;
}
if ($input !== null) {
$mapped['inputs'][$index] = $input;
}
}
if (preg_match('/^input:(\d+)$/', $component, $matches) === 1) {
$state = self::toBoolean($value['state'] ?? null);
if ($state !== null) {
$mapped['inputs'][(int) $matches[1]] = $state;
}
}
}
$mapped['temperature'] = self::findTemperature($params);
ksort($mapped['outputs']);
ksort($mapped['inputs']);
return $mapped;
}
public static function toBoolean($value): ?bool
{
if (is_bool($value)) {
return $value;
}
if ($value === 1 || $value === '1') {
return true;
}
if ($value === 0 || $value === '0') {
return false;
}
if (is_string($value)) {
$normalized = strtolower(trim($value));
if (in_array($normalized, ['true', 'on', 'online'], true)) {
return true;
}
if (in_array($normalized, ['false', 'off', 'offline'], true)) {
return false;
}
}
return null;
}
private static function findTemperature(array $data): ?float
{
foreach ($data as $key => $value) {
if (!is_string($key)) {
continue;
}
$lowerKey = strtolower($key);
if ($lowerKey === 'temperature') {
$temperature = self::temperatureFromValue($value);
if ($temperature !== null) {
return $temperature;
}
}
if ($lowerKey === 'tc' && is_numeric($value)) {
return (float) $value;
}
if (is_array($value)) {
$temperature = self::findTemperature($value);
if ($temperature !== null) {
return $temperature;
}
}
}
return null;
}
private static function temperatureFromValue($value): ?float
{
if (is_numeric($value)) {
return (float) $value;
}
if (!is_array($value)) {
return null;
}
foreach (['tC', 'tc', 't'] as $key) {
if (array_key_exists($key, $value) && is_numeric($value[$key])) {
return (float) $value[$key];
}
}
return null;
}
}