Daten in Array schieben

Guten Morgen zusammen,

ich stehe irgendwie mit PHP auf Kriegsfuß, was Arrays angeht. Ich versuche Daten für de PV Prognose von Solcast abzurufen. Das klappt auch ganz gut und ich kann durch die einzelenen Datensätze, die mir als json zur Verfügung gestellt werden durchgehen, mit Wert und Zeitstempel auslesen.
Wie bekomme ich aber nun dese Werte in eine Array, welches ich für AC_AddLoggedValues() brauche.

Mein Script schaut aktuell so aus:

<?php

$Archivhandler = 54833;
$Archivvariable = 53672;
$ValueCount = 96; //Standardanzahl bei Solcast
$out = "https://api.solcast.com.au/rooftop_sites/xxxxxx/forecasts?format=json&api_key=xxxxxx"; 


//Datenabruf
$ch = curl_init($out);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$ergebnis = curl_exec($ch);
echo $ergebnis;
$fehler = curl_error($ch);
curl_close($ch);

//Parsen
$forecasts = json_decode($ergebnis,true);
$n=0;
do {
    $ts = strtotime($forecasts['forecasts'][$n]["period_end"]);  //Zeitstempel in Unix-Format
    $pv_val = floatval($forecasts['forecasts'][$n]["pv_estimate"]); //Wert
   
   //Hier die Werte ins Archiv der    $Archivvariable
  //Da fehlt mir der Code

    $n=$n+1;
} while ($n<$ValueCount);

echo $fehler;

Die JSON, die ich von Solcast bekomme schaut übrigens so aus.
forecasts.json (11,4 KB)

Du würdest mit diesem Code ein Array bekommen, das aus lauter Arrays mit deinen 2 Werten besteht.

$archive = array(); //Erstelle ein leeres Array

do {
    $ts = strtotime($forecasts['forecasts'][$n]["period_end"]);  //Zeitstempel in Unix-Format
    $pv_val = floatval($forecasts['forecasts'][$n]["pv_estimate"]); //Wert
   
    //Füge die Werte dem Array hinzu
    $archive[] = array(
        'ts' => $ts,
        'pv_val' => $pv_val
    );

    $n=$n+1;
} while ($n<$ValueCount);





Wenn du alles in einem Array haben willst:


  do {
    $ts = strtotime($forecasts['forecasts'][$n]["period_end"]);  //Zeitstempel in Unix-Format
    $pv_val = floatval($forecasts['forecasts'][$n]["pv_estimate"]); //Wert
   
    // Werte ins Archiv setzen
    $archive[] = $ts;
    $archive[] = $pv_val;
   
    $n=$n+1;
} while ($n<$ValueCount);


Und hier die 3. Möglichkeit. Die Funktion array_push() fügt ein oder mehrere Elemente am Ende eines Arrays hinzu. In diesem Beispiel werden der Zeitstempel und der Wert am Ende des Arrays $archive hinzugefügt.

do {
    $ts = strtotime($forecasts['forecasts'][$n]["period_end"]);  //Zeitstempel in Unix-Format
    $pv_val = floatval($forecasts['forecasts'][$n]["pv_estimate"]); //Wert
   
    // Werte ins Archiv setzen
    array_push($archive, $ts);
    array_push($archive, $pv_val);
   
    $n=$n+1;
} while ($n<$ValueCount);

1 „Gefällt mir“

Danke für den Tipp. De Daten hab ich jetzt im Array, so wie ich sie haben möchte.

Array
(
    [0] => Array
        (
            [TimeStamp] => 1672297200
            [Value] => 0
        )

    [1] => Array
        (
            [TimeStamp] => 1672299000
            [Value] => 0
        )

    [2] => Array
        (
            [TimeStamp] => 1672300800
            [Value] => 0,0597
        )

    [3] => Array
        (
            [TimeStamp] => 1672302600
            [Value] => 0,2149
        )

    [4] => Array
        (
            [TimeStamp] => 1672304400
            [Value] => 0,2209
        )

    [5] => Array
        (
            [TimeStamp] => 1672306200
            [Value] => 0,2746
        )

    [6] => Array
        (
            [TimeStamp] => 1672308000
            [Value] => 0,5407
        )

    [7] => Array
        (
            [TimeStamp] => 1672309800
            [Value] => 0,9977
        )

    [8] => Array
        (
            [TimeStamp] => 1672311600
            [Value] => 1,2027
        )

    [9] => Array
        (
            [TimeStamp] => 1672313400
            [Value] => 1,3025
        )

    [10] => Array
        (
            [TimeStamp] => 1672315200
            [Value] => 1,3452
        )

    [11] => Array
        (
            [TimeStamp] => 1672317000
            [Value] => 1,2625
        )

    [12] => Array
        (
            [TimeStamp] => 1672318800
            [Value] => 1,0881
        )

    [13] => Array
        (
            [TimeStamp] => 1672320600
            [Value] => 0,8293
        )

    [14] => Array
        (
            [TimeStamp] => 1672322400
            [Value] => 0,5143
        )

    [15] => Array
        (
            [TimeStamp] => 1672324200
            [Value] => 0,2627
        )

    [16] => Array
        (
            [TimeStamp] => 1672326000
            [Value] => 0,1015
        )

    [17] => Array
        (
            [TimeStamp] => 1672327800
            [Value] => 0,006
        )

    [18] => Array
        (
            [TimeStamp] => 1672329600
            [Value] => 0
        )

    [19] => Array
        (
            [TimeStamp] => 1672331400
            [Value] => 0
        )

    [20] => Array
        (
            [TimeStamp] => 1672333200
            [Value] => 0
        )

    [21] => Array
        (
            [TimeStamp] => 1672335000
            [Value] => 0
        )

    [22] => Array
        (
            [TimeStamp] => 1672336800
            [Value] => 0
        )

    [23] => Array
        (
            [TimeStamp] => 1672338600
            [Value] => 0
        )

    [24] => Array
        (
            [TimeStamp] => 1672340400
            [Value] => 0
        )

    [25] => Array
        (
            [TimeStamp] => 1672342200
            [Value] => 0
        )

    [26] => Array
        (
            [TimeStamp] => 1672344000
            [Value] => 0
        )

    [27] => Array
        (
            [TimeStamp] => 1672345800
            [Value] => 0
        )

    [28] => Array
        (
            [TimeStamp] => 1672347600
            [Value] => 0
        )

    [29] => Array
        (
            [TimeStamp] => 1672349400
            [Value] => 0
        )

    [30] => Array
        (
            [TimeStamp] => 1672351200
            [Value] => 0
        )

    [31] => Array
        (
            [TimeStamp] => 1672353000
            [Value] => 0
        )

    [32] => Array
        (
            [TimeStamp] => 1672354800
            [Value] => 0
        )

    [33] => Array
        (
            [TimeStamp] => 1672356600
            [Value] => 0
        )

    [34] => Array
        (
            [TimeStamp] => 1672358400
            [Value] => 0
        )

    [35] => Array
        (
            [TimeStamp] => 1672360200
            [Value] => 0
        )

    [36] => Array
        (
            [TimeStamp] => 1672362000
            [Value] => 0
        )

    [37] => Array
        (
            [TimeStamp] => 1672363800
            [Value] => 0
        )

    [38] => Array
        (
            [TimeStamp] => 1672365600
            [Value] => 0
        )

    [39] => Array
        (
            [TimeStamp] => 1672367400
            [Value] => 0
        )

    [40] => Array
        (
            [TimeStamp] => 1672369200
            [Value] => 0
        )

    [41] => Array
        (
            [TimeStamp] => 1672371000
            [Value] => 0
        )

    [42] => Array
        (
            [TimeStamp] => 1672372800
            [Value] => 0
        )

    [43] => Array
        (
            [TimeStamp] => 1672374600
            [Value] => 0
        )

    [44] => Array
        (
            [TimeStamp] => 1672376400
            [Value] => 0
        )

    [45] => Array
        (
            [TimeStamp] => 1672378200
            [Value] => 0
        )

    [46] => Array
        (
            [TimeStamp] => 1672380000
            [Value] => 0
        )

    [47] => Array
        (
            [TimeStamp] => 1672381800
            [Value] => 0
        )

    [48] => Array
        (
            [TimeStamp] => 1672383600
            [Value] => 0
        )

    [49] => Array
        (
            [TimeStamp] => 1672385400
            [Value] => 0
        )

    [50] => Array
        (
            [TimeStamp] => 1672387200
            [Value] => 0,0949
        )

    [51] => Array
        (
            [TimeStamp] => 1672389000
            [Value] => 0,2912
        )

    [52] => Array
        (
            [TimeStamp] => 1672390800
            [Value] => 0,6472
        )

    [53] => Array
        (
            [TimeStamp] => 1672392600
            [Value] => 1,3131
        )

    [54] => Array
        (
            [TimeStamp] => 1672394400
            [Value] => 1,7547
        )

    [55] => Array
        (
            [TimeStamp] => 1672396200
            [Value] => 1,8295
        )

    [56] => Array
        (
            [TimeStamp] => 1672398000
            [Value] => 1,7432
        )

    [57] => Array
        (
            [TimeStamp] => 1672399800
            [Value] => 1,5302
        )

    [58] => Array
        (
            [TimeStamp] => 1672401600
            [Value] => 1,2856
        )

    [59] => Array
        (
            [TimeStamp] => 1672403400
            [Value] => 1,128
        )

    [60] => Array
        (
            [TimeStamp] => 1672405200
            [Value] => 1,1198
        )

    [61] => Array
        (
            [TimeStamp] => 1672407000
            [Value] => 0,8907
        )

    [62] => Array
        (
            [TimeStamp] => 1672408800
            [Value] => 0,5332
        )

    [63] => Array
        (
            [TimeStamp] => 1672410600
            [Value] => 0,2596
        )

    [64] => Array
        (
            [TimeStamp] => 1672412400
            [Value] => 0,0989
        )

    [65] => Array
        (
            [TimeStamp] => 1672414200
            [Value] => 0,0062
        )

    [66] => Array
        (
            [TimeStamp] => 1672416000
            [Value] => 0
        )

    [67] => Array
        (
            [TimeStamp] => 1672417800
            [Value] => 0
        )

    [68] => Array
        (
            [TimeStamp] => 1672419600
            [Value] => 0
        )

    [69] => Array
        (
            [TimeStamp] => 1672421400
            [Value] => 0
        )

    [70] => Array
        (
            [TimeStamp] => 1672423200
            [Value] => 0
        )

    [71] => Array
        (
            [TimeStamp] => 1672425000
            [Value] => 0
        )

    [72] => Array
        (
            [TimeStamp] => 1672426800
            [Value] => 0
        )

    [73] => Array
        (
            [TimeStamp] => 1672428600
            [Value] => 0
        )

    [74] => Array
        (
            [TimeStamp] => 1672430400
            [Value] => 0
        )

    [75] => Array
        (
            [TimeStamp] => 1672432200
            [Value] => 0
        )

    [76] => Array
        (
            [TimeStamp] => 1672434000
            [Value] => 0
        )

    [77] => Array
        (
            [TimeStamp] => 1672435800
            [Value] => 0
        )

    [78] => Array
        (
            [TimeStamp] => 1672437600
            [Value] => 0
        )

    [79] => Array
        (
            [TimeStamp] => 1672439400
            [Value] => 0
        )

    [80] => Array
        (
            [TimeStamp] => 1672441200
            [Value] => 0
        )

    [81] => Array
        (
            [TimeStamp] => 1672443000
            [Value] => 0
        )

    [82] => Array
        (
            [TimeStamp] => 1672444800
            [Value] => 0
        )

    [83] => Array
        (
            [TimeStamp] => 1672446600
            [Value] => 0
        )

    [84] => Array
        (
            [TimeStamp] => 1672448400
            [Value] => 0
        )

    [85] => Array
        (
            [TimeStamp] => 1672450200
            [Value] => 0
        )

    [86] => Array
        (
            [TimeStamp] => 1672452000
            [Value] => 0
        )

    [87] => Array
        (
            [TimeStamp] => 1672453800
            [Value] => 0
        )

    [88] => Array
        (
            [TimeStamp] => 1672455600
            [Value] => 0
        )

    [89] => Array
        (
            [TimeStamp] => 1672457400
            [Value] => 0
        )

    [90] => Array
        (
            [TimeStamp] => 1672459200
            [Value] => 0
        )

    [91] => Array
        (
            [TimeStamp] => 1672461000
            [Value] => 0
        )

    [92] => Array
        (
            [TimeStamp] => 1672462800
            [Value] => 0
        )

    [93] => Array
        (
            [TimeStamp] => 1672464600
            [Value] => 0
        )

    [94] => Array
        (
            [TimeStamp] => 1672466400
            [Value] => 0
        )

    [95] => Array
        (
            [TimeStamp] => 1672468200
            [Value] => 0
        )

)

Soweit so gut, wenn ich de jetzt aber mit

38:     AC_AddLoggedValues($Archivhandler, $Archivvariable,$archive);

ins IPS Archiv schieben will, dann bekomme ich folgende Meldung:

Warning: Kann Daten mit einem neueren Zeitstempel, als die Daten welche noch nicht geschrieben wurden, nicht hinzufügen in C:\ProgramData\Symcon\scripts\20167.ips.php on line 38

Mal abgesehen vom Satzbau, was soll mir diese Meldung sagen? Die Variable ist zwar angelegt, aber es wurden da noch keine Daten geloggt. Nach Ausführung ist genau ein Wert im Archiv mit dem Wert 0

Ich glaube dein Array passt noch nicht zur Vorgabe in der Funktion AC_AddLoggedValues
In der Dokumentation steht es so:

// Add three additional data records to an Integer variable
AC_AddLoggedValues(12345, 34567, [
  [
    'TimeStamp' => 1128255120,
    'Value' => 30
  ],
  [
    'TimeStamp' => 1128257851,
    'Value' => 50
  ],
  [
    'TimeStamp' => 1128278514,
    'Value' => 130
  ]
]);

Bei dir sind Timestamp und Value in eckigen Klammern. Das ist die Schreibweise für ein key=>value Array

Hast du das genommen?

Dann würde es eine andere Fehlermeldung geben.

Das eine ist PHP Code, das andere eine Ausgabe mit print_r. Nicht verwechseln.

Michael

Ja stimmt. :+1 Beides sind Key=>Value Arrays

Mit welchem Zeistempel?


Also ziemlich genau der Zeitpunkt an em ich das Script ausgeführt habe.
Interessant daran ist, dass der Unix Zeitstempel für 11Uhr eigentlich dem in Position 54 des obigen Arrays entspricht und da ist halt eben keine 0 als Wert sondern 1,7547.
Warum aber hat er die Arraypaare 1-53 nicht geschrieben, da die doch in der Vergangnheit liegen? Checkt der vor dem Schreiben das komplette Array ab und verweigert das komplette Schreiben, sobald da ein Wert ungültig ist.

Versuchst du, Sätze in die Zukunft zu schreiben? Das wird nicht gehen.
Wenn die Archivierung eingeschaltet wird, wird ein Initalsatz geschrieben mit dem aktuellen Wert und der aktuellen Uhrzeit.
Dann - so meine Vermutung- wird das Array überprüft und mit der obigen Fehlermeldung abgelehnt, da wohl Sätze in der Zukunft liegen.

Kann ja so nicht sein, auch neue Werte sind ja immer in der Zukunft des Alten :slight_smile:
@Dr.Niels hat es in einem anderen Beitrag schon geschrieben.

Ist der Zeitstempel zu neu (bis zu einer Minute alt), dann klappt das nicht.

Damit ist die aktuelle Zeit gemeint.
Michael

Was wäre, wenn der Solcast und dein Server unterschiedliche Systemzeiten verwenden?
Vielleicht ist der Solcast auf Sommerzeit?

Das war vor 1 1/2 Jahren. Vielleicht hat sich das geändert. Zumindest in die Doku ist die Einschränkung nicht eingeflossen.
Auch ist es mir beim Übertragen von Werten von einer Variablen in eine andere nicht aufgefallen.
Oder bekommt man beim Lesen des Archivs auch nicht die neuesten Werte?

Werte aus der Zukunft können wohl nicht ins Archiv eingetragen werden. Das wurde hier auch schon diskutiert AC_ADDLOGGEDVALUES für Zukunftswerte
Da hatte dann @Dr.Niels das Problem dabei weiter erläutert.

Man könnte vielleicht jedes mal 24h vom Timestamp abziehen und dann abspeichern und wenn man sie braucht addiert man die Zeit wieder dazu.

Das war ja meine Idee, um damit umzugehen. Das problem ist ja auch bei anderen Systemen bekannt. Ich hab mal vor Jahren Module für ABB SCADA System geschrieben die über OPC mit dem System kommuniziert haben und die kannten auch nur aktuelle und Vergangenheiswerte. Es führte einfach kein Weg rein, dass man da Prognostizierte Werte in die Zukunft schreiben konnte. letztendlich haben wir dann eine zusätzliche Oracle-Datenbank aufgesetzt, die parallel lief und in der man das konnte. Allgemein würde ich sagen, dass Systeme, die keine Zukunftsdaten erfassen können in einem Zeitalter in dem man sehr viel mittels Prognosen optimieren kann, nicht mehr zeitgemäß sind.

Es ist ja nicht so, dass es keine Lösung gäbe, jedoch würde das einen ziemlichen Umbau in IPSymcon bedeuten. InfluxDB kann zum Beispiel auch Daten in die Zukunft schreiben und ist zudem um Größenordnungen performanter und effizienter als das was als Datenbank unter IPSymcon werkelt. Ich hab das Grafana Modul mit IPS am Laufen und manchmal braucht es gut 4-5 Sekunden bis ein Graph aufgebaut ist, obwohl beide Systeme auf ein und dem selben Rechner laufen. Bei einer InfluxDB-Verbindung zu Grafana geht das in Sekundenbruchteilen. Vielleict liegt das aber auch an der Umsetzung des Grafana Moduls. Da bin ich mir nicht sicher.

Das Problem der Datenbankperformance wird umso brennender, wenn man versucht über IPSymcon zum Beispiel ein Energiedatenmanagement aufzubauen was zwingend Echtzeitdaten braucht. Ich habe das mal versucht und dazu muss ich meine Wechselrichter, das Batteriemanagementsystem und den Einspeisezähler im Sekundenrhytmus auslesen. Wenn ich das aber mache, bekomme ich Performanceprobleme und die Datenbank ist ziemlich schnell riesengroß. Letztendlich hilft dann immer nur das Löschen der Werte, die älter als ein paar Stunden sind.

1 „Gefällt mir“

Ich nutze auch Grafana, schon wegen der Optik und unzähligen grafischen Möglichkeiten. Ich habe einen Server im Internet mit SQL-Datenbank. Die IPSymcon Variablen gehen über das Modul ArchivMySQL dorthin und die Grafana Dashboards greifen darauf zu. Auch eine Gastherme mit EMS+ Bus lese ich so aus und habe nahezu Echtzeitdaten. Ich musste in der Datenbankkonfiguration nur mal die MaxConnections hochstellen, weil ich mittlerweile zu viele Projekte mit Zugriffen habe. Weil es gut läuft hab ich mir eine Lösung mit InfluxDB bis jetzt noch offen gehalten. Auf dem Server im Internet kann ich komfortabel Backups machen lassen und ich bin soweit zufrieden.

Also ich hab die Daten jetzt zeitversetzt um zwei Tage zurück versetzt im Archiv. Rechnen kann man damit jetzt schon, wenn man eben einfach dann wieder 48h dazu addiert.
Was mache ich allerdings mit Diagrammen (IPSymcon, HighCharts, Grafana)? Gibt es da eine Möglichkeit die Zeitstempel während der Anzeige so zu verbiegen, dass wieder die korrekten Zeiten angezeigt werden? Dann könnte ich in einem Diagramm die Prohnose und die real gemessenen Werte anzeigen lassen, wenn ich die rückgespeicherten Prognosedaten quasi aus der Vergangenheit wieder in die Gegenwart mappe.

ich arbeite noch nicht lange mit IPS, aber 20 Jahre mit Datenbanken.
Die Graphiken die man im IPS View machen kann erinnern mich an das letzte Jahrhundert.

Da müssen die IPS macher also schnell etwas unternehmen. Sonst wird IPS zum Spielzeug.
Es macht keinen Sinn ein lokale IP Symcon System zu haben und dann cloud datenbanken nbenbei.
Gerade bei Daten die man häufig abfragen muss um genaue Daten zu haben sind dann die Möglichkeiten in IPS sehr begrenzt, es kommt dann schnell die Meldung „Zu viele Werte für einen Rohgraphen“ da kann selbst die alte Homematic CCU mehr Datenpunkt in den Diagrammen anzeigen.

Das wichtigste heute ist doch eine gescheite Datenbank, am Angebot liegt es nicht.

Schau mal bei den Spezialschaltern. Da gibt es die Einstellungen, um das Limit hochzusetzen. Im Standard ist ein sehr konservativer Wert gesetzt.