[Modul] OpenWeatherMap

Aktuelle Version liefert:

11.10.2018 20:25:27 | OpenWeatherData | Puffer > 8kb

Ich speichere die Ergebnisse zur eventuelle weiteren Verwendung per SetBuffer() und anscheinen ist das grösser als die 8kb.
Das ist nur eine Meldung eines Soft-Limits. Ich kenne leider keine Möglichkeit, das Limit zu erhöhen.

demel

Mehrere Buffer nutzen :smiley:
Michael

ich habe schon zwei Buffer, ich wollte nachher mal gzencode() einbauen.

demel

Sicher das es auf jedem System installiert und verwendbar ist?
PHP: Installation - Manual
Warum nicht dynamisch mehrere Buffer belegen?
Michael

hmm, das ist eine gute Frage, wie bei IPS das php compliliert ist. bei Rasbian und Ubuntu ist es drin.
vielleicht liest das paresy zufällig und kann dazu was sagen.

könnte man natürlich machen, ist halt etwas umständlicher (was natürlich kein Argument ist) - ich würde dann ja die json-Struktur, die ich bekomme, per json_encode() in einen String verwandeln und den in 8kb-Teile aufteilen.

Bisher habe ich die Warnung bzgl. 8Kb-Grenze nicht wirklich beachtet, weil es ja nur ein soft-limit ist. Andererseits ist auch eine solche Warnung lästig.

Ich benutze das häufiger, wie z.B. hier: ich speichere das Ergebnis des HTTP-request original per SetBuffer ab und biete die Möglichkeit, das jemand diese Daten holen kann um „was auch immer“ damit zu machen.
genauer gesagt sind es zwei requests, also 2 Buffer.

demel

Mhhh… Ich habe den Trait noch gar nicht einzeln auf GitHub.
Hier gibt es einen ‚unendlich‘ großen Buffer, sofern der Name mit ‚Multi_‘ beginnt.
IPSSqueezeBox/SqueezeBoxTraits.php at 6bbdccc23a0de51bb3fbc114cefc3acf23c27a14 · Nall-chan/IPSSqueezeBox · GitHub
Michael

Hallo demel42,

Super Arbeit. Danke erst einmal an dieser Stelle.
Besonders Gut finde ich, das alle Werte erst einmal in Variablen gespeichert werden. So kann man sich vieles in eigenen script einfach anpassen.

Folgendes ist mir noch ausgefallen:
1.In der Variable Zusammenfassung des Wetters sind die Werte für Windgeschwindikeit immer die gleichen bei der html Ausgabe.
In den einzelnen Variablen Windgeschwindigkeit auf der Console stimmen die Werte
2.Die neuen Variablen Wetterbedingung-Symbol und Wetterbedingung-ID bitte noch mit Sufix #1,#2,… ergänzen

Danke und Mach weiter So!
Thomas

danke für die Info, ist gefixed Für die fehlende Suffixes musst Du natürlich diese Variablen nochmal löschen

gruß
demel

[ul]
[li]Bugfix: z.T. fehlende Suffixe bei Vorhersage-Variablen, falsche Windgeschwindigkeit in der HTML-Darstellung
[/li][li]in der HTML-Darstellung wird die WIndgeschwindigkeit ohne Nachkommastellen ausgegeben
[/li][/ul]

Hallo Michael,

ich bin erst heute gekommen, deinen Vorschlag zu „studieren“.

Wenn ich das richtig verstehe, werden ‚Multi_‘ in lokalen Variablen des Moduls gespeichert (‚BufferListe_‘* & ‚Part_‘*). Aber diese Variablen überleben dich die Laufzeit des Modul-Aufrufs nicht, oder?

Mein Anwendungsfall ist in allen Fällen aber dieser: die Update-Funktion des Moduls speichert Roh-Daten, die dann z.B. von einem Script abgefragt werden. Das Script wird nicht innerhalb des Aufrufs der Update-Funktion aufgerufen.

Ich habe das mal testhalber bei mir eingebaut und das bestätigt mir das.

Wahrscheinlich habe ich den Code falsch verstanden, aber Du machst ja eine Fallunterschiedung von ‚Multi_‘ und nicht ‚Multi_‘. Nicht ‚Multi_‘ werden per SetBuffer() gesichert aber ‚Mulit_‘ nur in Modul-lokalen Variablen. Ich hätte erwartet, das ‚Multi_‘ auf mit SetBuffer() gesichert werden, aber eben mehreren (analog zu den Variablen).

:confused:

Gruß
demel

__get und __set sind Magic Functions.
Die werden automatisch aufgerufen für Eigenschaften welche nicht in einer Klasse deklariert wurden.
Darum funktioniert dann einfach Zuweisungen und auslesen mit $this->DiesKommtInDenBuffer, es wird dann in einem Instanzbuffer mit dem Namen DiesKommtInDenBuffer geschrieben/gelesen.
Michael

ok, interessante Information

ich habe nun die Funktionen in meine trait nun auch __set / __get genannt und rufen die so auf:


class OpenWeatherData extends IPSModule
{
    use OpenWeatherMapCommon;
...
    public function UpdateCurrent()
    {
...
        $this->__set('Current', json_encode($jdata));
        $data = $this->__get('Current');
        $this->__set('Multi_Current', json_encode($jdata));
        $data = $this->__get('Multi_Current');

Bei __get(‚Current‘) kommt diese Meldung:

Notice: unserialize(): Error at offset 0 of 441 bytes in /var/lib/symcon/modules/IPSymconOpenWeatherMap/libs/common.php on line 206

Das ist diese Zeile:


    public function __get($name)
    {
...
        return unserialize($this->GetBuffer($name));

Wenn ich das unserialise() entferne, geht es - ist ja auch kein korrespondierendes serialise() im __set().

Aber dann kommt das:

Warning: Invalid argument supplied for foreach() in /var/lib/symcon/modules/IPSymconOpenWeatherMap/libs/common.php on line 201

Das ist diese Zeile

foreach ($this->{"BufferListe_" . $name} as $BufferIndex) {

Debug eingebaut


<?php

trait OpenWeatherMapCommon
{

...
    public function __get($name)
    {
        if (strpos($name, 'Multi_') === 0) {
            $Lines = "";
$this->SendDebug(__FUNCTION__, 'BufferListe_' . $name . '=' . print_r($this->{"BufferListe_" . $name}, true), 0);
            foreach ($this->{"BufferListe_" . $name} as $BufferIndex) {
                $Lines .= $this->{'Part_' . $name . $BufferIndex};
            }
            return unserialize($Lines);
        }
        return $this->GetBuffer($name);
    }

    public function __set($name, $value)
    {
        $Data = serialize($value);
        if (strpos($name, 'Multi_') === 0) {
            $OldBuffers = $this->{"BufferListe_" . $name};
            if ($OldBuffers == false) {
                $OldBuffers = array();
            }
            $Lines = str_split($Data, 8000);
            foreach ($Lines as $BufferIndex => $BufferLine) {
                $this->{'Part_' . $name . $BufferIndex} = $BufferLine;
            }
            $NewBuffers = array_keys($Lines);
            $this->{"BufferListe_" . $name} = $NewBuffers;
$this->SendDebug(__FUNCTION__, 'BufferListe_' . $name . '=' . print_r($NewBuffers, true), 0);
            $DelBuffers = array_diff_key($OldBuffers, $NewBuffers);
            foreach ($DelBuffers as $DelBuffer) {
                $this->{'Part_' . $name . $DelBuffer} = "";
            }
            return;
        }
        $this->SetBuffer($name, $Data);
    }

__set | BufferListe_Multi_Current=Array<LF>(<LF> [0] => 0<LF>)<LF>

__get | BufferListe_Multi_Current=a:1:{i:0;i:0;}

Die Daten passen in 8000 Bytes, daher ist das ok, das es nur ein ‚Part‘ ist.

Ich bin jetzt völlig verwirrt …

demel

Du musst da gar nicht serialiesieren oder mit JSON bearbeiten. Du kannst alles, sogar Objekte so speichern.
Und einfach Eigenschaften ansprechen.
Nicht __set oder __get direkt aufrufen.
Wichtig: Den Buffer z.b. im Create oder Applychanges einmal initialisieren mit z.b. einem leeren String, Array oder was auch immer du da speichern willst.

Michael

das deserialize war in Deiner Vorlage. Bei __set() steckst Du Data ohne serialise() hinein, bei __get() holst du die Daten und rufst darauf deserialise() auf.

Das verstehe ich leider nicht, Ich habe in diesem Fall eine json-Struktur, das ist der Rückgabewert eine vorigen http-Aufrufs. Das ist in der Variable jdata. Wie soll ich da eine Eigenschaft ansprechen?

Tut mir leid, da ist mein Blick wohl etwas vernagelt.

Wichtig: Den Buffer z.b. im Create oder Applychanges einmal initialisieren mit z.b. einem leeren String, Array oder was auch immer du da speichern willst.

Ok

demel

Dann habe ich das vorhin falsch verstanden. Dachte das war dein Code.

Einfach zuweisen… Egal was es ist.
$this->Multi_MeineDaten = … Irgendwas, alles (scalare Daten, Array, Objekte… alles außer Ressourcen).
PHP Doku: PHP: Ãœberladung - Manual

Michael

jetzt habe ich es verstanden.
Ich hatte die ganze Zeit überlegt, was die Eigenschaft der Variable ist und nicht die Eigenschaft der Instanz/Moduls. Falscher Blickwinkel :banghead:

danke
demel

  • Umstellung der internen Speicherung zur Vermeidung der Warnung Puffer > 8kb.

Ich habe die Vorschläge von Nall-chan umgesetzt und damit sollte die o.g. Meldung der Vergangenheit angehören.

demel

  • Modul OpenWeatherStation hinzugefügt.

Damit können eigene Wetterdaten an OpenWeather übertragen werden.

demel

Mal eine Frage in die Runde: Nutzt einer von euch IPSView und wenn ja, wie habt ihr die Darstellung der Daten aus dem OpenWeather Modul zusammengebaut?