Skip to content

Commit

Permalink
Merge pull request #12 from Burki24/patch-10
Browse files Browse the repository at this point in the history
ADD: Exposes save to .json files
  • Loading branch information
Nall-chan authored Oct 28, 2024
2 parents d07543d + d167d5f commit 1fc2faf
Show file tree
Hide file tree
Showing 4 changed files with 410 additions and 165 deletions.
137 changes: 128 additions & 9 deletions Device/module.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,40 +58,159 @@ public function GetConfigurationForm()
*/
protected function UpdateDeviceInfo(): bool
{
$Result = $this->SendData('/SymconExtension/request/getDeviceInfo/' . $this->ReadPropertyString('MQTTTopic'));
$this->SendDebug('result', json_encode($Result), 0);
$mqttTopic = $this->ReadPropertyString('MQTTTopic');
if (empty($mqttTopic)) {
IPS_LogMessage(__CLASS__, "MQTTTopic ist nicht gesetzt.");
return false;
}

$Result = $this->SendData('/SymconExtension/request/getDeviceInfo/' . $mqttTopic);
$this->SendDebug(__FUNCTION__ . ' :: ' . __LINE__ . ' result', json_encode($Result), 0);

if ($Result === false) {
IPS_LogMessage(__CLASS__, "SendData für MQTTTopic '$mqttTopic' fehlgeschlagen.");
return false;
}

if (array_key_exists('ieeeAddr', $Result)) {
if (empty($this->ReadPropertyString('IEEE')) && ($this->ReadPropertyString('IEEE') != $Result['ieeeAddr'])) {
// Einmalig die leere IEEE Adresse in der Konfig setzen.
$currentIEEE = $this->ReadPropertyString('IEEE');
if (empty($currentIEEE) && ($currentIEEE !== $Result['ieeeAddr'])) {
// Einmalig die leere IEEE Adresse in der Konfiguration setzen.
IPS_SetProperty($this->InstanceID, 'IEEE', $Result['ieeeAddr']);
IPS_ApplyChanges($this->InstanceID);
return true;
}

/**
* @todo Icon sollte auch manuell über die Form neu geladen werden können
*/
if (array_key_exists('model', $Result)) {
$Model = $Result['model'];
if ($Model != 'Unknown Model') { // nur wenn Z2M ein Model liefert
if ($this->ReadAttributeString('Model') != $Model) { // und das Model sich geändert hat
if ($Model !== 'Unknown Model') { // nur wenn Z2M ein Model liefert
if ($this->ReadAttributeString('Model') !== $Model) { // und das Model sich geändert hat
$Url = 'https://raw.githubusercontent.com/Koenkk/zigbee2mqtt.io/master/public/images/devices/' . $Model . '.png';
$this->SendDebug('loadImage', $Url, 0);
$ImageRaw = @file_get_contents($Url);
if ($ImageRaw) {
if ($ImageRaw !== false) {
$Icon = 'data:image/png;base64,' . base64_encode($ImageRaw);
$this->WriteAttributeString('Icon', $Icon);
$this->WriteAttributeString('Model', $Model);
} else {
IPS_LogMessage(__CLASS__, "Fehler beim Herunterladen des Icons von URL: $Url");
}
}
}

// *** Ergänzung: IEEE.json speichern ***
// Überprüfen, ob die benötigten Schlüssel existieren
if (isset($Result['ieeeAddr']) && isset($Result['exposes'])) {
// Extrahieren der benötigten Daten und Hinzufügen der Symcon-ID
$dataToSave = [
'symconId' => $this->InstanceID, // Hinzugefügt: Symcon-ID
'ieeeAddr' => $Result['ieeeAddr'],
'model' => $Result['model'],
'exposes' => $Result['exposes']
];

// JSON-Encode der Daten mit Pretty-Print
$jsonData = json_encode($dataToSave, JSON_PRETTY_PRINT);

if ($jsonData === false) {
IPS_LogMessage(__CLASS__, "Fehler beim JSON-Encoding der Daten für IEEE.json: " . json_last_error_msg());
} else {
// Pfad zum Kernel-Verzeichnis abrufen
$kernelDir = IPS_GetKernelDir();

// Sicherstellen, dass der Pfad mit einem Verzeichnis-Trenner endet
if (substr($kernelDir, -1) !== DIRECTORY_SEPARATOR) {
$kernelDir .= DIRECTORY_SEPARATOR;
}

// Pfad zum Zigbee2MQTTExposes-Verzeichnis erstellen
$verzeichnisName = 'Zigbee2MQTTExposes';
$vollerPfad = $kernelDir . $verzeichnisName . DIRECTORY_SEPARATOR;

// Sicherstellen, dass das Verzeichnis existiert (wird von ModulBase verwaltet)
// Daher ist diese Überprüfung optional, kann aber zur Sicherheit beibehalten werden
if (!file_exists($vollerPfad)) {
// Falls das Verzeichnis nicht existiert, versuchen es zu erstellen
if (!mkdir($vollerPfad, 0755, true)) {
IPS_LogMessage(__CLASS__, "Fehler beim Erstellen des Verzeichnisses '$verzeichnisName'.");
// Abbruch der Speicherung, da das Verzeichnis nicht existiert
return false;
} else {
IPS_LogMessage(__CLASS__, "Verzeichnis '$verzeichnisName' erfolgreich erstellt.");
}
}

// Dateipfad für die JSON-Datei basierend auf ieeeAddr
$instanceID = $this->InstanceID;
$ieeeAddr = $Result['ieeeAddr'];
// Optional: Entfernen von '0x' aus der IEEE-Adresse, falls gewünscht
// $ieeeAddr = ltrim($ieeeAddr, '0x');
$dateiPfad = $vollerPfad . $instanceID . '_' . $ieeeAddr . '.json';

// Schreiben der JSON-Daten in die Datei
if (file_put_contents($dateiPfad, $jsonData) !== false) {
IPS_LogMessage(__CLASS__, "IEEE.json erfolgreich als '$ieeeAddr.json' im Verzeichnis '$verzeichnisName' gespeichert.");
} else {
IPS_LogMessage(__CLASS__, "Fehler beim Schreiben von '$ieeeAddr.json' im Verzeichnis '$verzeichnisName'.");
}
}
} else {
IPS_LogMessage(__CLASS__, "Die erforderlichen Schlüssel 'ieeeAddr' oder 'exposes' fehlen in \$Result.");
}
}

// Aufruf der Methode aus der ModulBase-Klasse
$this->mapExposesToVariables($Result['exposes']);
return true;
}
trigger_error($this->Translate('Device not found. Check topic'), E_USER_NOTICE);
return false;
}

/**
* Destroy
*
* Diese Methode wird aufgerufen, wenn die Instanz gelöscht wird.
* Sie sorgt dafür, dass die zugehörige .json-Datei entfernt wird.
*
* @return void
*/
public function Destroy()
{
// Wichtig: Zuerst die Parent Destroy Methode aufrufen
parent::Destroy();

// Holen der InstanceID
$instanceID = $this->InstanceID;

// Holen des Kernel-Verzeichnisses
$kernelDir = IPS_GetKernelDir();

// Definieren des Verzeichnisnamens
$verzeichnisName = 'Zigbee2MQTTExposes';

// Konstruktion des vollständigen Pfads zum Verzeichnis
$vollerPfad = $kernelDir . $verzeichnisName . DIRECTORY_SEPARATOR;

// Konstruktion des erwarteten Dateinamens mit InstanceID und Wildcard für ieeeAddr
$dateiNamePattern = $instanceID . '_*.json';

// Vollständiger Pfad mit Muster
$dateiPfad = $vollerPfad . $dateiNamePattern;

// Suche nach Dateien, die dem Muster entsprechen
$files = glob($dateiPfad);

// Überprüfung und Löschung der gefundenen Dateien
foreach ($files as $file) {
if (is_file($file)) {
if (unlink($file)) {
IPS_LogMessage(__CLASS__, "Datei erfolgreich gelöscht: $file");
} else {
IPS_LogMessage(__CLASS__, "Fehler beim Löschen der Datei: $file");
}
}
}
}
}
120 changes: 109 additions & 11 deletions Group/module.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

class Zigbee2MQTTGroup extends \Zigbee2MQTT\ModulBase
{
/** @var mixed $ExtensionTopic Topic für den ReceiveFilter*/
/** @var mixed $ExtensionTopic Topic für den ReceiveFilter */
protected static $ExtensionTopic = 'getGroupInfo/';

/**
Expand All @@ -16,7 +16,7 @@ class Zigbee2MQTTGroup extends \Zigbee2MQTT\ModulBase
*/
public function Create()
{
//Never delete this line!
// Never delete this line!
parent::Create();
$this->RegisterPropertyInteger('GroupId', 0);
}
Expand All @@ -31,11 +31,9 @@ public function ApplyChanges()
$GroupId = $this->ReadPropertyInteger('GroupId');
$GroupId = $GroupId ? 'Group Id: ' . $GroupId : '';
$this->SetSummary($GroupId);

//Never delete this line!
parent::ApplyChanges();
}

/**
* UpdateDeviceInfo
*
Expand All @@ -45,19 +43,119 @@ public function ApplyChanges()
*/
protected function UpdateDeviceInfo(): bool
{
$Result = $this->SendData('/SymconExtension/request/getGroupInfo/' . $this->ReadPropertyString('MQTTTopic'));
$this->SendDebug('result', json_encode($Result), 0);
$mqttTopic = $this->ReadPropertyString('MQTTTopic');
if (empty($mqttTopic)) {
IPS_LogMessage(__CLASS__, "MQTTTopic ist nicht gesetzt.");
return false;
}

$Result = $this->SendData('/SymconExtension/request/getGroupInfo/' . $mqttTopic);
$this->SendDebug(__FUNCTION__ . ' :: ' . __LINE__ . ' result', json_encode($Result), 0);

if ($Result === false) {
IPS_LogMessage(__CLASS__, "SendData für MQTTTopic '$mqttTopic' fehlgeschlagen.");
return false;
}

if (array_key_exists('foundGroup', $Result)) {
if ($Result['foundGroup']) {
unset($Result['foundGroup']);
$this->mapExposesToVariables($Result);
return true;
}
unset($Result['foundGroup']);
// Aufruf der Methode aus der ModulBase-Klasse
$this->mapExposesToVariables($Result);
$this->SaveExposesToJson($Result);
return true;
}

trigger_error($this->Translate('Group not found. Check topic'), E_USER_NOTICE);
return false;
}

/**
* SaveExposesToJson
*
* Speichert die Exposes in einer JSON-Datei.
*
* @param array $Result Die Exposes-Daten.
*
* @return void
*/
private function SaveExposesToJson(array $Result): void
{
// Definieren des Verzeichnisnamens
$verzeichnisName = 'Zigbee2MQTTExposes';
$kernelDir = rtrim(IPS_GetKernelDir(), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
$neuesVerzeichnis = $kernelDir . $verzeichnisName;

// Gruppenspezifische Informationen
$groupID = $this->ReadPropertyInteger('GroupId');
if ($groupID === 0) {
IPS_LogMessage(__CLASS__, "GroupId ist nicht gesetzt. Exposes werden nicht gespeichert.");
return;
}

// Dateipfad für die JSON-Datei basierend auf InstanceID und groupID
$instanceID = $this->InstanceID;
$dateiPfad = $neuesVerzeichnis . DIRECTORY_SEPARATOR . $instanceID . '_' . $groupID . '.json';

// JSON-Daten mit Pretty-Print erstellen
$jsonData = json_encode($Result, JSON_PRETTY_PRINT);
if ($jsonData === false) {
IPS_LogMessage(__CLASS__, "Fehler beim JSON-Encoding der Exposes für Gruppe ID '$groupID': " . json_last_error_msg());
return;
}

// Schreiben der JSON-Daten in die Datei
if (file_put_contents($dateiPfad, $jsonData) !== false) {
IPS_LogMessage(__CLASS__, "Exposes erfolgreich als '{$instanceID}_{$groupID}.json' im Verzeichnis '$verzeichnisName' gespeichert.");
$this->SendDebug(__FUNCTION__ . ' :: ' . __LINE__, "Datei erfolgreich geschrieben: " . $dateiPfad, 0);
} else {
IPS_LogMessage(__CLASS__, "Fehler beim Schreiben von '{$instanceID}_{$groupID}.json' im Verzeichnis '$verzeichnisName'.");
$this->SendDebug(__FUNCTION__ . ' :: ' . __LINE__, "Fehler beim Schreiben der Datei: " . $dateiPfad, 0);
}
}

/**
* Destroy
*
* Diese Methode wird aufgerufen, wenn die Instanz gelöscht wird.
* Sie sorgt dafür, dass die zugehörige .json-Datei entfernt wird.
*
* @return void
*/
public function Destroy()
{
// Wichtig: Zuerst die Parent Destroy Methode aufrufen
parent::Destroy();

// Holen der InstanceID
$instanceID = $this->InstanceID;

// Holen des Kernel-Verzeichnisses
$kernelDir = IPS_GetKernelDir();

// Definieren des Verzeichnisnamens
$verzeichnisName = 'Zigbee2MQTTExposes';

// Konstruktion des vollständigen Pfads zum Verzeichnis
$vollerPfad = $kernelDir . $verzeichnisName . DIRECTORY_SEPARATOR;

// Gruppenspezifische Informationen
$dateiNamePattern = $instanceID . '_*.json';

// Vollständiger Pfad mit Muster
$dateiPfad = $vollerPfad . $dateiNamePattern;

// Suche nach Dateien, die dem Muster entsprechen
$files = glob($dateiPfad);

// Überprüfung und Löschung der gefundenen Dateien
foreach ($files as $file) {
if (is_file($file)) {
if (unlink($file)) {
IPS_LogMessage(__CLASS__, "Datei erfolgreich gelöscht: $file");
} else {
IPS_LogMessage(__CLASS__, "Fehler beim Löschen der Datei: $file");
}
}
}
}
}
Loading

0 comments on commit 1fc2faf

Please sign in to comment.