no message
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
|
||||
Reference in New Issue
Block a user