Bubelbub / SmartHome-PHP

MIT License
15 stars 10 forks source link

Session Lifetime und andere Fragen #6

Open adn77 opened 9 years ago

adn77 commented 9 years ago

Erstmal vielen Dank für die hervorragende Arbeit! Ich war lange Zeit skeptisch, ob man mit einem "geschlossenen" System wie RWE als HomeAutomation-Fan glücklich werden kann.

Ich nutze die Bibliothek auf einem PowerPC NAS mit statischem HTML und Shell-Scripten per CGI-Schnittstelle an mini_httpd.

Um in meiner Home-Grafik die Temperatur und den Verlauf anzeigen zu können, hole ich per CRON alle fünf Minuten die Soll/Ist/Humidity Werte der Raumthermostate. Dazu habe ich auf der example.php basierend ein kleines Script geschrieben.

1.) Mir erschließt sich noch nicht ganz das Objektmodell. Welche Aufrufe sind minimal notwendig, um Werte auszulesen, aktuell brauche ich: $sh->getEntities(); $sh->getAllLogicalDeviceStates(); und iteriere dann über $sh->getLogicalDevices()

2.) Da der Verbindungsaufbau etwas Zeit kostet, wird im Beispiel versucht, die SessionID, etc. zu cachen. Allerdings wird der Cache nie ungültig gemacht.

$sh = new \Bubelbub\SmartHomePHP\SmartHome('smarti', 'user', 'password');

$configFile = $path .'/shc.cache';
$config = new SimpleXMLElement('<SmartHomeConfiguration />');

if(file_exists($configFile))
{
        try{$config = new SimpleXMLElement($configFile, 0, true);}catch(Exception $ex){}
}

if(!file_exists($configFile))
{
        $config->addChild('SessionId', $sh->getSessionId());
        $config->addChild('ClientId', $sh->getClientId());
        $config->addChild('Version', $sh->getVersion());
        $config->addChild('ConfigurationVersion', $sh->getConfigVersion());
        $config->saveXML($configFile);
}
else
{
        $sh->setSessionId((string) $config->SessionId);
        $sh->setClientId((string) $config->ClientId);
        $sh->setVersion((string) $config->Version);
        $sh->setConfigVersion((string) $config->ConfigurationVersion);
}

$sh->getEntities();
$sh->getAllLogicalDeviceStates();

Gibt es eine Eigenschaft, die ich abfragen kann, ob der erste Verbindungsaufbau unerfolgreich war, so dass ich das cache-File neu anlegen kann? Kennt alternativ jemand die Session-Timeouts, dann könnte ich per CRON das cache-File einfach löschen.

Vielen Dank schonmal!

Bubelbub commented 9 years ago

Also kurz zum Cache: Der soll nie ungültig werden, da, sobald die Verbindung aufgrund eines ungültigen Tokens geschlossen wird, die Verbindung erneut aufgebaut wird. D.h. das System hilft sich selbst und weiß was zu tun ist. Das ganze zu löschen ist aufgrund der Version etc. auch unnötig. Da wird ja noch mehr drinnen gespeichert.

Zum anderen Punkt: Ja das kann man noch besser gestalten. Habe ich sogar vor... Wenn die Zeit nicht begrenzt wäre :(

Du kannst per Foreach die ganzen Geräte-States durchgehen. In der neuesten Version holt er automatisch die Werte/Geräte wenn keine abgerufen wurden.=

adn77 commented 9 years ago

Wow, das war eine schnelle Antwort, danke!

Mein Cache von letzter Woche hatte z.B. eine ConfigVersion=30, wenn ich ihn neu erstelle habe ich ConfigVersion=33. Meine Frage bezog sich darauf, wie ich den erneuten Verbindungsaufbau mitbekomme und daraufhin auch die Cache-Datei neu schreiben kann.

Der andere Punkt sollte in keiner Weise eine Kritik darstellen! Ich wollte nur unnötige Anfragen an die Station vermeiden und deshalb nicht einfach irgendwelche Methoden aufrufen. Aktuell verwende ich wie im Beispiel eine foreach über getLogicalDevices(), nachdem ich $sh->getEntities(); $sh->getAllLogicalDeviceStates(); aufgerufen habe.

Bubelbub commented 9 years ago

Der Cache wird immer nach Beendigung des Programms gespeichert/aktualisiert/erneuert.

Die Config Version hat in deinem Fall kein Problem verursacht und spielt auch keine Rolle. Wenn der Token abgelaufen ist sollte sich das Programm - automatisch - einen neuen holen. Teste es einfach mal indem du einen falschen Token in der Cache Datei einträgst! :)=

adn77 commented 9 years ago

Genau diesen Mechanismus meine ich... mein cache-File wird immer nur dann geschrieben, wenn es nicht existiert (siehe Code oben). Wahrscheinlich fehlt mir noch ein Stück Code, um es auch bei geänderten Parametern zu speichern... wie sollte das aussehen?

Bubelbub commented 9 years ago

Das System macht das automatisch...

Ändere den Token beispielsweise und starte das Programm nochmal...

Die Config-Value erzeugt seitens RWE Zentrale keinen Fehler sodass das ignoriert wird vom System. Der Session Token hingegen wird bei der Beendigung des Programms im Cache gespeichert.=

adn77 commented 9 years ago

Sorry, ich steh auf'm Schlauch. Hab das Token geändert, das Cache-File wird NICHT neu geschrieben.

Das "System" kennt mein Cache File doch überhaupt nicht... dafür müsste es doch das $config Objekt benutzen...

Bubelbub commented 9 years ago

Ou ou. Sorry!

Ich hab die Versionen verwechselt... Bei der, die ich gerade entwickle, also die aktuelle im Master Branch nur etwas neuer, wird diese $config Abwicklung besser gehandelt.

Das ist ja auch nur eine example.php ^^ Kannst du ja so umschreiben, dass nach einem Befehl nochmal die Session Variable gesetzt wird.

Sry!

Ich überarbeite das am Wochenende direkt!=

adn77 commented 9 years ago

:) hab's kapiert, also nach dem ersten getEntities() einfach ein getSessionId() machen und falls diese von der gespeicherten abweicht das configFile neu schreiben.

(Hatte extra schon die Master version geclont... bin gespannt auf weitere Neuerungen!)

Bubelbub commented 9 years ago

Ja Wünsche nehme ich gerne entgegen ^^=

adn77 commented 8 years ago

Nochmal zur Klarstellung, falls sich noch jemand über sie Sessions wundert: Die SessionID ändert sich mit jeder Kommunikation (jedem Request) mit der Zentrale - die example.php ist dahingehend unglücklich gewählt...

Zunächst gibt es eine SessionID beim Login. Die nächste Verbindung von getEntities() erhält eine neue SessionID. Sofern die Daten nicht bereits in einer Datenstruktur vorliegen, erzeugt getAllLogicalDeviceStates() eine weitere SessionID.

Wollte man den Login-Prozess bei der nächsten Verbindung abkürzen, so muss die jeweils letzte SessionID in das Config-File geschrieben werden - sozusagen am Ende des Programs:

    $config->addChild('SessionId', $sh->getSessionId());
    $config->addChild('ClientId', $sh->getClientId());
    $config->addChild('Version', $sh->getVersion());
    $config->addChild('ConfigurationVersion', $sh->getConfigVersion());
    $config->saveXML($configFile);