[Script] solarprognose.de (Full version)

Selbstverständlich habe ich nicht richtig gelesen und unterdessen sieht die Konfiguration so aus
Es werden auch Variablen generiert.
Es erscheint keine Fehlermeldung.

# Erste Anlage
$PVA['PVA Sagigass'] = [
    'token'     => '1234567890',  // (string) erstezen durch => '<api-token>'
    'project'   => 'mb-stern@****.ch',   // (string) erstezen durch => '<mail-adresse>'
    'id'        => '3088',     // (int) erstezen durch => <standort-id>
    'item'      => 'location', // standort-id
    'format'    => 'json',
    'type'      => 'hourly', // 'daily';
    'start'     => 0,
    'end'       => 1,
];

Doch weiterhin erhalte ich keine Daten.
Eine normale GET-Abfrage der API liefert aber Daten, daher scheinen meine Angaben richtig zu sein

http://www.solarprognose.de/web/solarprediction/api/v1?access-token=1234567890&item=location&id=3088&type=hourly)

Was mache ich wohl falsch?

Nachtrag:
Jetzt sind die Daten gekommen.
Ich hatte die Tages-Abfrage angepasst, das reichte nicht.
Erst als die stündliche Abfrage dazu kam hats funktioniert :smiley:

Hi,

heißt jetzt geht alles?

Gruß Heiko

Danke der Nachfrage…
Ja jetzt klappt es.
Ich habe aber den Eindruck, dass die Abfrage kurz nach Mitternacht zu keinem Ergebnis führt. Jedenfalls dann nicht, wenn ich die Zeit manuell einstelle.
Die stündlich Abfrage funktioniert, das ist die Hauptsache :smiley:

Hi Pitti,
sind jetzt nicht alle 3 Tarife „gratis“? Also eine Spende…
D.h. nicht mehr nur auf 1 Tag in die Zukunft beschnitten?

https://www.solarprognose.de/web/de-de/plan/order/2

lg

Hi cbeham,

ja - wie es aussieht ist es jetzt so :wink:

Für mich weißen die Prognosedaten leider eine ziemliche ungenau auf, so dass ich das Projekt nicht groß weiter verfolgen werde. solcast ist da für mich viel genauer und bietet die Vorhersage in 3 Bereichen (Sonnige, Normal, Bewölkter) an. Ist momentan mein Favorit.

Aber auch da, alles über 24h kannste meiner Meinung in die Tonne …

Gruß Heiko

Ok, dann mach ich mir die arbeit gar nicht. Danke für die Info.
Hast du nicht auch ein Modul für Solcast?

glg

Modul nicht, aber ein Script => [Script] solcast.de

Gruß Heiko

Danke Heiko!

In wie weit würdest du den Unterschied zwischen Soclast und Solarprognose definieren?

ich hätte auch die Möglichkeit auf der SolarWeb Seite von Fronius meine 2 Tagesvorschau zu parsen (wenn das geht?)

Und kein Tag ohne Probleme:

Unter ModulControl kann ich deine Scriptsammlung nicht hinzufügen:

Fehlermeldung:

Kann kein neues Modul erstellen
This modul cannot be updated!
This repository seems corrupted.
library, josn is at least missing! (Code: -32603)

Finde ihn speziell bei wechselhaften Wetter extrem, aber auch heute ist der Unterschied riesig:

Solarprognose.de => 51 kWh
SolCast.com => 36 kWh

Das ist schon ein großer Unterschied. Wenn man annimmt das heute so wie gestern wird, da hatte ich real 41 kWh dann liegt solcast schon recht gut!

Parsen warum nicht - ist immer ne frage ob man auf die Seite relativ „einfach“ kommt (Thema: Authentifizierung).

Gruß Heiko

Wie der Name schon sagt - Skriptbibliothek - keine Modul :slight_smile: Alles richtig gelesen?

Gruß Heiko

Ja, vor ein paar Tagen hatte ich mir das mal durchgelesen. Anscheinend aber nicht gemerkt :roll_eyes:

Aber ich lese halt auch viel den ganzen Tag…#

Ok, man braucht ein Login :slight_smile:
Ich werde mir dann das Solcast ansehen. Danke Pitti

Hallo Heiko,
habe auch dein aktuelles Skript am laufen mit dem Update vom v2.2.2024080. Wenn ich das Skript ausführe ist alles gut und nach einer Zeit bekomme ich immer ein Ausrufezeichen vor das Skript.

Die Variablen der Kategorie „Haus“ werden auch nicht befüllt. Bei der anlagen ID habe ich schon die ID des Standortes und die ID der Anlage eingefügt im Skript, beides ohne Erfolg.

Das Skript das ich nutze:

<?php

declare(strict_types=1);

################################################################################
# Script:   Amount.SolarForcast.ips.php
# Version:  2.2.20230326 / Update v2.2.20240801
# Author:   Heiko Wilknitz (@Pitti)
#
# Script zur Abholung und Aufbereitung der prognostizierten Solorproduktion
# von solarprognose.de.
#
# API
#   https://www.solarprognose.de/web/solarprediction/api/v1
#       ?access-token=ACCESS-TOKEN
#       &project=Hier Ihre Projekt-Website oder Ihre Kontakt-E-Mail
#       &item=ITEM
#       &id=ID
#       &type=hourly|daily
#       &_format=json|xml
#       &algorithm=mosmix|own-v1|clearsky
#       &day=DAY
#       &start_epoch_time=START_EPOCH_TIME&end_epoch_time=END_EPOCH_TIME
#       &start_day=START_DAY&end_day=END_DAY
#       &snomminixml=true # für snom VoIP Telefone
#
# ------------------------------ Installation ----------------------------------
#
# Dieses Skript richtet automatisch alle nötigen Objekte bei manueller
# Ausführung ein. Eine weitere manuelle Ausführung setzt alle benötigten Objekte
# wieder auf den Ausgangszustand.
#
# - Neues Skript erstellen
# - Diesen PHP-Code hineinkopieren
# - Abschnitt 'Konfiguration' mit eigenen Werten anpassen (__WWX austauschen)
# - Skript Abspeichern
# - Skript Ausführen
# - Visualisierung per Link auf entstandene Variablen erstellen
#
# ------------------------------ Changelog -------------------------------------
#
# 08.02.2023 - Initalversion (v1.0)
# 23.02.2023 - API Doc, Type fixes (v1.1)
# 15.03.2023 - Umstellung bzw. Erweiterung für mehrere Anlagen
#              und All-In-One Script (v2.0)
# 17.03.2023 - Fix für Archive Control (v2.1)
# 26.03.2023 - Fix Style & Logging (v2.2)
# 04.03.2024 - Fix für Archivdaten (v2.3)
#
# ------------------------------ Konfiguration ---------------------------------
#
# Global Debug Output Flag
$DEBUG = false;
#
# Globale Variable __WWX als Array via define() in __autoload definiert!!!
#
# Erste Anlage
$PVA['Haus'] = [
    'token'     => ['xxxxxxxxxxxxxxxxxxxx'],  // (string) erstezen durch => '<api-token>'
    'project'   => ['xxxxxxxxxxxxxx'],   // (string) erstezen durch => '<mail-adresse>'
    'id'        => ['xxxx'],     // (int) erstezen durch => <anlagen-id>
    'item'      => 'location',
    'format'    => 'json',
    'type'      => 'hourly', // 'daily';
    'start'     => 0,
    'end'       => 1,
];
#
# Weitere Anlage
# $PVA['Haus'] = [
#    'token'     => __WWX['SPD_TOKEN'],
#    'project'   => __WWX['SPD_MAIL'],
#    'id'        => __WWX['SPD_ID2'],
#    'item'      => 'location',
#    'format'    => 'json',
#    'type'      => 'daily';
#    'start'     => 0,
#    'end'       => 1,
# ];
#
################################################################################
#
# Requires include of the global function script via autoload (__autoload.php)
# or direct in the script (uncomment next line)!
require_once(IPS_GetKernelDir()."scripts".DIRECTORY_SEPARATOR.'System.Functions.ips.php');
# You can download it from here https://github.com/wilkware/ips-scripts
#
defined('WWX_FUNCTIONS') || die('Global function library not available!');

require_once IPS_GetKernelDir() . 'scripts' . DIRECTORY_SEPARATOR . 'System.QuickChart.ips.php';

// INSTALLATION
if ($_IPS['SENDER'] == 'Execute') {
    // Event 1 mal am Tag
    $midnight = mktime(0, 0, 15);
    CreateEventByName($_IPS['SELF'], 'UpdateDaily', $midnight);
    // Event aller 1 Stunde von  05:00 bis 18:00 Uhr - TODO: Timer im Sommer vielleicht anpassen
    $from = mktime(5, 0, 15);
    $to = mktime(18, 0, 15);
    CreateEventByNameFromTo($_IPS['SELF'], 'UpdateHourly', 3, 1, $from, $to);
    // Variablen pro Anlage anlegen
    foreach ($PVA as $name => $plant) {
        // Kategorie erzeugen
        $cid = CreateCategoryByName($_IPS['SELF'], $name);
        $vid = CreateVariableByName($cid, 'Daten', 3);
        $vid = CreateVariableByName($cid, 'Tabellarischer Verlauf', 3, 10, 'Database', '~HTMLBox');
        $vid = CreateVariableByName($cid, 'Graphischer Verlauf', 3, 11, 'Graph', '~HTMLBox');
        $vid = CreateVariableByName($cid, 'Prognose Heute', 2, 20, '', '~Electricity');
        // Archivierung aktivieren (Typ: Zähler)
        RegisterArchive($vid, false);
        $vid = CreateVariableByName($cid, 'Prognose Morgen', 2, 21, '', '~Electricity');
        $vid = CreateVariableByName($cid, 'Aktuelle Stunde', 2, 22, '', '~Electricity');
    }
}
// WEBFRONT
elseif ($_IPS['SENDER'] == 'WebFront') {
    // Benutzer hat etwas geändert!
}
// VARIABLENAENDERUNG
elseif ($_IPS['SENDER'] == 'Variable') {
    // Varaible hat sich geändert!
}
// TIMER EVENT
elseif ($_IPS['SENDER'] == 'TimerEvent') {
    $event = IPS_GetName($_IPS['EVENT']);
    if ($event == 'UpdateDaily') {
        foreach ($PVA as $name => $plant) {
            // Kategorie erzeugen oder lesen
            $cid = CreateCategoryByName($_IPS['SELF'], $name);
            // Mitternacht - Reset auf 0
            $vid = CreateVariableByName($cid, 'Prognose Heute', 2);
            SetValueFloat($vid, 0);
            $vid = CreateVariableByName($cid, 'Prognose Morgen', 2);
            SetValueFloat($vid, 0);
            $vid = CreateVariableByName($cid, 'Aktuelle Stunde', 2);
            SetValueFloat($vid, 0);
        }
    } elseif ($event == 'UpdateHourly') {
        foreach ($PVA as $name => $plant) {
            // Kategorie erzeugen oder lesen
            $cid = CreateCategoryByName($_IPS['SELF'], $name);
            // von 08:00 bis 18:00 - TODO: Timer im Sommer vielleicht anpassen
            $data = UpdateForecast($plant);
            // Save
            $vid = CreateVariableByName($cid, 'Daten', 3);
            $json = json_encode($data);
            SetValueString($vid, $json);
            // aktuellen Werte abgleichen wenn notwendig
            $vid = CreateVariableByName($cid, 'Prognose Heute', 2);
            if ($data['Heute'] > 0) {
                $lv = GetValueFloat($vid);
                if ($lv < $data['Heute']) {
                    SetValueFloat($vid, $data['Heute']);
                } elseif ($lv == $data['Heute']) {
                    // Do nothing
                } else {
                    //Den letzten Wert, der in der Datenbank gespeichert wurde, holen
                    $aid = IPS_GetInstanceListByModuleID(ExtractGuid('Archive Control'))[0];
                    $last = AC_GetLoggedValues($aid, $vid, 0, 0, 1)[0];
                    AC_DeleteVariableData($aid, $vid, $last['TimeStamp'], 0);
                    SetValueFloat($vid, $data['Heute']);
                    IPS_Sleep(1000);
                    AC_ReAggregateVariable($aid, $vid);
                }
            }
            unset($data['Heute']);
            $vid = CreateVariableByName($cid, 'Prognose Morgen', 2);
            SetValueFloat($vid, $data['Morgen']);
            unset($data['Morgen']);
            $vid = CreateVariableByName($cid, 'Aktuelle Stunde', 2);
            SetValueFloat($vid, $data['Stunde']);
            unset($data['Stunde']);
            // SVG Chart
            $svg = DrawChart($data);
            $svg = str_replace(['1024pt', '325pt'], '100%', $svg);
            $vid = CreateVariableByName($cid, 'Graphischer Verlauf', 3);
            SetValueString($vid, $svg);
            // HTML Table
            $html = BuildHtml($data);
            $vid = CreateVariableByName($cid, 'Tabellarischer Verlauf', 3);
            SetValueString($vid, $html);
        }
    }
}

#----------------------------------- Functions ---------------------------------

function UpdateForecast($plant)
{
    $url = 'https://www.solarprognose.de/web/solarprediction/api/v1?access-token=' .
        $plant['token'] . '&project=' .
        $plant['project'] . '&item=' .
        $plant['item'] . '&id=' .
        $plant['id'] . '&type=' .
        $plant['type'] . '&_format=' .
        $plant['format'] . '&algorithm=own-v1&start_day=' .
        $plant['start'] . '&end_day=' .
        $plant['end'];
    //EchoDebug('URL: ', $url);
    $json = file_get_contents($url);
    //EchoDebug('Daten :', $json);
    $result = [];
    if ($json !== false) {
        $data = json_decode($json, true);
        // Heute, Morgen und aktuelle Stunde
        $ad = date('d.m.Y');
        $at = date('H') . ':00';
        $result['Heute'] = 0;
        $result['Morgen'] = 0;
        $result['Stunde'] = 0;
        // Stundenwerte
        foreach ($data['data'] as $key => $values) {
            // Tag
            $dd = date('d.m.Y', $key);
            // Uhrzeit
            $dt = date('H:i', $key);
            // Werte hochzählen
            if ($ad == $dd) { // Heute
                $result['Heute'] += $values[0];
            } else { // Morgen
                $result['Morgen'] += $values[0];
            }
            if (($ad == $dd) && ($at == $dt)) {
                $result['Stunde'] = $values[0];
            }
            // Pro Tag ein Feld
            if (!isset($result[$ad])) {
                $result[$ad] = [];
            }
            // Stundenwerte und akkumulierten Werte
            $result[$dd][$dt] = $values;
        }
    }
    return $result;
}

function BuildHtml($data)
{
    // Rows
    $rows = array_keys($data);
    // cols
    $cols = max(count($data[$rows[0]]), count($data[$rows[1]]));
    // html
    $html = '';
    $html .= '<table class="wwx">';
    foreach ($data as $day => $hours) {
        $count = 0;
        $th = '<thead class="orange"><th><center>' . $day . '</center></th>';
        $tr1 = '<tr><td>kW/h</td>';
        $tr2 = '<tr><td>&sum; kWh</td>';
        foreach ($hours as $hour => $values) {
            $th .= '<th>' . $hour . '</th>';
            $tr1 .= '<td>' . $values[0] . '</td>';
            $tr2 .= '<td>' . $values[1] . '</td>';
            $count++;
        }
        for ($i = $count; $i < $cols; $i++) {
            $th .= '<th>-</th>';
            $tr1 .= '<td>-</td>';
            $tr2 .= '<td>-</td>';
        }
        $html .= $th . '</thead>';
        $html .= $tr1 . '</tr>';
        $html .= $tr2 . '</tr>';
    }
    $html .= '</table>';
    return $html;
}

function DrawChart($data)
{
    $axis_x = [];
    $axis_y = [];
    // prepeare dataset
    foreach ($data as $day => $hours) {
        foreach ($hours as $hour => $values) {
            $axis_x[] = '\'' . $hour . '\'';
            $axis_y[] = intval($values[0] * 1000);
        }
    }
    // new chart object
    $chart = new QuickChart(['width' => 1024, 'height' => 325, 'format' => 'svg']);
    // chart config
    $chart->setConfig("{
    type: 'line',
    data: {
        labels: [" . implode(',', $axis_x) . "],
        datasets: [
        {
            backgroundColor: 'rgba(255, 125, 0, 0.1)',
            borderColor: 'rgb(255, 125, 0)',
            borderWidth: 1,
            lineTension: 0.4,
            pointRadius: 1,
            fill: true,
            data: [" . implode(',', $axis_y) . "]
        }]
    },
    options: {
        legend: {
            labels: {
                fontColor: 'rgb(255, 255, 255)'
            },
            display: false
        },
        scales: {
        xAxes: [{
            ticks: {
                fontColor: '#fff',
            },
            gridLines: {
                color: 'rgba(211, 211, 211, 0.2)',
                borderDash: [5,5]
            },
            scaleLabel: {
            fontColor: '#fff',
            display: false,
            labelString: 'Uhrzeit'
            }
        }],
        yAxes: [{
            ticks: {
                fontColor: '#fff'
            },
            gridLines: {
                color: 'rgba(211, 211, 211, 0.2)',
                borderDash: [5,5]
            },
            scaleLabel: {
            fontColor: '#fff',
            display: true,
            labelString: 'Leistung (kW)'
            }
        }]
        }
    }
    }");
    return $chart->toBinary();
}

################################################################################

Hast du eine Idee woran das liegen kann?

VG
Stefan

Hi Stefan,

Setzt doch mal Debug auf true und lass Dir mal die URL ausgeben (EchoDebug auskommentieren) und dann die URL direkt im Browser aufrufen und schauen was passiert.

Gruß Heiko

Wenn ich die URL im Browser eingebe mit meinem Token bekomme ich eine XML angezeigt, richtig?

Hallo Heiko,
hast du das Skript noch in Benutzung?

LG
Stefan

Eigentlich sollte da ein JSON zurück kommen.

Nein, es läuft glaube noch bei mir, aber bin von der Anzeige auf solcast umgestiegen. Einfach bessere Werte.

Bin gerade auf Messe, deshalb etwas langsam im Antworten

Ok, bei SolCast habe ich das gleiche Problem. Es kommen keine Werte rein.

Das komische ist von Solarprognose habe ich noch ein anderes Skript am laufen von @hfichtinger und das funktioniert. Dann kann es schon mal am API Schlüssel nicht liegen.

Dann noch viel Spaß auf der Messe.

LG

1 „Gefällt mir“

Ich verstehe es nicht, habe jetzt bestimmt schon gefühlte 100x die Skripte durchgeschaut, finde keine Fehler mit meinen Angaben. Bei SolCast gibt man ja nur den API Token ein und die RID.

Ich schau mir das morgen mal an, bin leider noch auf der Rückreise von der DMEXCO

1 „Gefällt mir“