no message

This commit is contained in:
2025-11-14 10:13:43 +01:00
parent 7de43a4240
commit 35d07da440
2 changed files with 95 additions and 73 deletions
+26 -9
View File
@@ -33,34 +33,51 @@ class ShellyParser
public static function MapParams(array $params): array
{
$mapped = [
'input' => null,
'output' => null,
'outputs' => [], // switch:x → output
'inputs' => [], // input:x → state oder switch:x.input
'temperature' => null
];
// GEN3 / GEN4 Geräte → switch:0, switch:1, ...
foreach ($params as $key => $value) {
// -----------------------------
// OUTPUTS (switch:0 → output)
// -----------------------------
if (str_starts_with($key, 'switch:') && is_array($value)) {
// Output
$index = (int)substr($key, 7);
if (isset($value['output'])) {
$mapped['output'] = (bool)$value['output'];
$mapped['outputs'][$index] = (bool)$value['output'];
}
// Input (für Pro / Gen4 Geräte)
// Gen4 / Pro Geräte haben input im switch
if (isset($value['input'])) {
$mapped['input'] = (bool)$value['input'];
$mapped['inputs'][$index] = (bool)$value['input'];
}
}
// -----------------------------
// INPUTS (input:0 → state)
// -----------------------------
if (str_starts_with($key, 'input:') && is_array($value)) {
$index = (int)substr($key, 6);
if (isset($value['state'])) {
$mapped['inputs'][$index] = (bool)$value['state'];
}
}
}
// Temperatur suchen (beliebig tief)
// Temperatur-Suche (verschachtelt)
self::ExtractRecursive($params, $mapped);
return array_filter($mapped, fn($v) => $v !== null);
return $mapped;
}
private static function ExtractRecursive(array $data, array &$mapped): void
{
foreach ($data as $key => $value) {
+69 -64
View File
@@ -73,42 +73,29 @@ class Shelly_Parser_MQTT extends IPSModule
* ---------------------------------------------------------*/
public function RequestAction($Ident, $Value)
{
// Lokale Variable aktualisieren
$varID = @IPS_GetObjectIDByIdent($Ident, $this->InstanceID);
if (!$varID) {
// Falls Variable im Ordner liegt:
foreach (IPS_GetChildrenIDs($this->InstanceID) as $folder) {
foreach (IPS_GetChildrenIDs($folder) as $cid) {
if (IPS_GetObject($cid)['ObjectIdent'] === $Ident) {
$varID = $cid;
break 2;
}
}
}
}
// Output? z.B. BE_1_3_14_output_0
if (str_contains($Ident, '_output_')) {
if ($varID) {
SetValue($varID, $Value);
}
SetValue(IPS_GetObjectIDByIdent($Ident, $this->FindDeviceFolder($Ident)), $Value);
// Prüfen ob das ein Output ist
if (str_ends_with($Ident, '_output')) {
$deviceID = substr($Ident, 0, -strlen('_output'));
// Device & Index extrahieren
$parts = explode('_output_', $Ident);
$deviceID = $parts[0];
$index = (int)$parts[1];
$topic = $deviceID . '/rpc/Switch.Set';
$payload = json_encode([
'id' => 0,
'id' => $index,
'on' => (bool)$Value
]);
$this->Publish($topic, $payload);
if ($this->ReadPropertyBoolean('Debug')) {
IPS_LogMessage("Shelly_Parser_MQTT", "Switching $deviceID -> $Value");
}
return;
}
// andere Variablen (falls nötig)
throw new Exception("Unknown Ident $Ident");
}
@@ -157,72 +144,77 @@ class Shelly_Parser_MQTT extends IPSModule
/* ---------------------------------------------------------
* ONLINE-STATUS
* ---------------------------------------------------------*/
private function HandleOnline(string $deviceID, string $payload): void
{
$value = ($payload === 'true' || $payload === '1');
private function HandleOnline(string $deviceID, string $payload): void
{
$value = ($payload === 'true' || $payload === '1');
$varID = $this->EnsureBooleanVariable($deviceID, $deviceID . '_online', 'Online');
SetValue($varID, $value);
}
$varID = $this->EnsureBooleanVariable($deviceID, $deviceID . '_online', 'Online');
SetValue($varID, $value);
}
/* ---------------------------------------------------------
* RPC-EVENTS
* ---------------------------------------------------------*/
private function HandleRPC(string $deviceID, string $payload): void
/* ---------------------------------------------------------
* RPC-EVENTS
* ---------------------------------------------------------*/
private function HandleRPC(string $deviceID, string $payload): void
{
$json = json_decode($payload, true);
if (!is_array($json)) {
return;
}
// Shelly prüfen
// Gerätetyp setzen
$src = $json['src'] ?? '';
if (!is_string($src) || !str_starts_with($src, 'shelly')) {
if (!str_starts_with($src, 'shelly')) {
return;
}
// Typ extrahieren (z.B. "1minig3", "1g4", "plusplugs", ...)
$type = ShellyParser::ExtractType($src);
$typeID = $this->EnsureStringVariable($deviceID, $deviceID . '_type', 'Typ');
SetValue($typeID, $type);
// Parameter extrahieren
// Mappen
$params = $json['params'] ?? [];
if (!is_array($params)) {
return;
}
$mapped = ShellyParser::MapParams($params);
// Output
if (array_key_exists('output', $mapped)) {
$outID = $this->EnsureBooleanVariable($deviceID, $deviceID . '_output', 'Output');
IPS_SetVariableCustomAction($outID, $this->InstanceID);
SetValue($outID, (bool)$mapped['output']);
// -----------------------------------
// DYNAMISCHE OUTPUTS
// -----------------------------------
foreach ($mapped['outputs'] as $index => $value) {
$ident = $deviceID . "_output_" . $index;
$name = "Output $index";
$varID = $this->EnsureBooleanVariable($deviceID, $ident, $name);
// Aktionsskript aktivieren für Schalten
IPS_SetVariableCustomAction($varID, $this->InstanceID);
SetValue($varID, $value);
}
// -----------------------------------
// DYNAMISCHE INPUTS
// -----------------------------------
foreach ($mapped['inputs'] as $index => $value) {
// Input (GEN4 / PRO)
if (array_key_exists('input', $mapped)) {
$inID = $this->EnsureBooleanVariable(
$deviceID,
$deviceID . '_input',
'Input'
);
SetValue($inID, (bool)$mapped['input']);
$ident = $deviceID . "_input_" . $index;
$name = "Input $index";
$varID = $this->EnsureBooleanVariable($deviceID, $ident, $name);
SetValue($varID, $value);
}
// Temperatur (falls gefunden)
if (array_key_exists('temperature', $mapped)) {
$tempID = $this->EnsureFloatVariable(
$deviceID,
$deviceID . '_temperature',
'Temperatur'
);
SetValue($tempID, (float)$mapped['temperature']);
// -----------------------------------
// TEMPERATUR
// -----------------------------------
if ($mapped['temperature'] !== null) {
$tempID = $this->EnsureFloatVariable($deviceID, $deviceID . '_temperature', 'Temperatur');
SetValue($tempID, $mapped['temperature']);
}
}
/* ---------------------------------------------------------
* Helper für Variablen
* ---------------------------------------------------------*/
@@ -303,5 +295,18 @@ class Shelly_Parser_MQTT extends IPSModule
return $folderID;
}
private function FindDeviceFolder(string $Ident): int
{
foreach (IPS_GetChildrenIDs($this->InstanceID) as $folder) {
foreach (IPS_GetChildrenIDs($folder) as $cid) {
if (IPS_GetObject($cid)['ObjectIdent'] === $Ident) {
return $folder;
}
}
}
return 0;
}
}
?>