Anwendungsbeispiel JsonMod - SolCast Solar-Vorhersage abrufen

Begonnen von freetz, 11 August 2021, 09:05:22

Vorheriges Thema - Nächstes Thema

Torxgewinde

Vielen Dank für die Definition für Solcast.
Ich denke es gibt noch einen Punkt bei der Zeitzone der nicht genau stimmt. Ich habe den aktuell gültigen Wert als UserReading dargestellt und musste dabei den Offset der Zeitzone mit einberechnen:

defmod Solcast JsonMod https://api.solcast.com.au/rooftop_sites/AAAA-BBBB-CCCC-DDDD/forecasts?format=json&api_key=ABCDEFGHIJKLMNOPQRSTUVWXYZ&hours=72
attr Solcast group Strom
attr Solcast interval 1,31 * * * *
attr Solcast readingList multi(jsonPath('$.forecasts[*]'), concat('pv_estimate_', property('period_end')), property('pv_estimate'));;\
single(jsonPath('$.forecasts[0].period'),'period','');;
attr Solcast stateFormat Jetzt: forecast_now W, Heute: forecast_today kWh, Morgen: forecast_tomorrow kWh, Übermorgen: forecast_overmorrow kWh
attr Solcast userReadings forecast_now {\
my $period = ReadingsVal($NAME, "period", 0);;\
$period =~ s/.*(\d\d).*/$1/;;\
\
my $offset = timegm(localtime()) - timelocal(localtime());;\
\
my ($date, $time) = split(" ", FmtDateTime(time()-$offset));;\
my ($hour, $min, $sec) = split(":", $time);;\
$time = $hour . $min . "00";;\
\
my ($date_plus, $time_plus) = split(" ", FmtDateTime(time()+30*60-$offset));;\
my ($hour_plus, $min_plus, $sec_plus) = split(":", $time_plus);;\
$time_plus = $hour_plus . $min_plus . "00";;\
\
my $hash = $defs{$NAME};;\
my $readings = $hash->{READINGS};;\
\
foreach my $reading ( keys %{$readings} ) {\
if ($reading =~ /$date/) {\
my ($dummy, $period_end) = split("T", $reading);;\
$period_end = substr($period_end, 0, 6);;\
\
##Log(0, "period_end: ".$period_end .">". $time ." && ". $time_plus);;\
\
if (($period_end > $time) && ($period_end <= $time_plus)) {\
##Log(0, "Treffer");;\
return round(1000*ReadingsVal($NAME,$reading,0),0);;\
}\
}\
}\
},\
forecast_today {\
my $total = 0;;\
my $period = ReadingsVal($NAME, "period", 0);;\
$period =~ s/.*(\d\d).*/$1/;;\
my ($date, $time) = split(" ", FmtDateTime(time()));;\
my ($hour, $min, $sec) = split(":", $time);;\
$time = $hour . $min . "00";;\
my $hash = $defs{$NAME};;\
my $readings = $hash->{READINGS};;\
foreach my $reading ( keys %{$readings} ) {\
if ($reading =~ /$date/) {\
my ($dummy, $period_end) = split("T", $reading);;\
$period_end = substr($period_end, 0, 6);;\
\
if ($period_end > $time)\
{\
my $val = ReadingsVal($NAME,$reading,0);;\
$total += $val/(60/$period);;\
}\
}\
}\
return round($total,2);;\
},\
forecast_tomorrow {\
use Time::Piece ();;\
use Time::Seconds;;\
\
my $total = 0;;\
my $period = ReadingsVal($NAME, "period", 0);;\
$period =~ s/.*(\d\d).*/$1/;;\
my ($date, $time) = split(" ", FmtDateTime(time()));;\
$date = Time::Piece->strptime($date, '%Y-%m-%d');;\
$date += ONE_DAY;;\
$date = $date->strftime('%Y-%m-%d');;\
my $hash = $defs{$NAME};;\
my $readings = $hash->{READINGS};;\
foreach my $reading (keys %{$readings}) {\
if ($reading =~ /$date/) {\
my $val = ReadingsVal($NAME, $reading, 0);;\
$total += $val/(60/$period);;\
}\
}\
return round($total,2);;\
},\
forecast_overmorrow {\
use Time::Piece ();;\
use Time::Seconds;;\
\
my $total = 0;;\
my $period = ReadingsVal($NAME, "period", 0);;\
$period =~ s/.*(\d\d).*/$1/;;\
my ($date, $time) = split(" ", FmtDateTime(time()));;\
$date = Time::Piece->strptime($date, '%Y-%m-%d');;\
$date += ONE_DAY;;\
$date += ONE_DAY;;\
$date = $date->strftime('%Y-%m-%d');;\
my $hash = $defs{$NAME};;\
my $readings = $hash->{READINGS};;\
foreach my $reading (keys %{$readings}) {\
if ($reading =~ /$date/) {\
my $val = ReadingsVal($NAME, $reading, 0);;\
$total += $val/(60/$period);;\
}\
}\
return round($total,2);;\
}
attr Solcast webCmd reread


Plotte ich mir die Werte von "forecast_now" now in einem Graphen über den Ertrag, passt das besser.

Ingo298

Hallo zusammen,
hier ist bezüglich der Solarvorschau alles gut erklärt wurden, leider hat jedoch Solcast den Request auf 10 pro Tag geändert. Momentan habe ich das über
interval*/59 7-17 * * *
gelöst. Aber ich denke für den Sommer wird das knapp werden.

Kann man das evtl. für https://www.solarprognose.de auch machen?
RPi2: Buster FHEM 5.9, FTUI, AMAD,10.1" Tablet; MiLight;IT;HM;Dect200;VZLogger

sn0000py

welches solcast verwendest du?
ich habe 50 API Abrufe pro Tag frei und brauche pro Stunde 3 Abfragen (3 Seiten Ost,Süd,West)

Ingo298

Zitat von: sn0000py am 03 Januar 2023, 18:36:58
welches solcast verwendest du?
ich habe 50 API Abrufe pro Tag frei und brauche pro Stunde 3 Abfragen (3 Seiten Ost,Süd,West)

Ich habe mich auf https://solcast.com/ als free User (Home User) registriert, gibt es da noch was anderes ?
Ich benötige nur eine Seite kann auch nur max. 2 Seiten bzw. Dachflächen in Solcast anlegen
RPi2: Buster FHEM 5.9, FTUI, AMAD,10.1" Tablet; MiLight;IT;HM;Dect200;VZLogger

sn0000py

ich glaub ich habe das gar nicht angelegt

https://api.solcast.com.au/world_pv_power/forecasts?latitude=47.1&longitude=14.1&capacity=18.085&tilt=28&azimuth=-60&loss_factor=0.9&hours=168&format=json&api_key=meinKey

so lese ich die direkt aus, und da darf ich 50 Aufrufe pro Tag machen

Ingo298

Zitat von: sn0000py am 03 Januar 2023, 19:45:36
ich glaub ich habe das gar nicht angelegt

https://api.solcast.com.au/world_pv_power/forecasts?latitude=47.1&longitude=14.1&capacity=18.085&tilt=28&azimuth=-60&loss_factor=0.9&hours=168&format=json&api_key=meinKey

so lese ich die direkt aus, und da darf ich 50 Aufrufe pro Tag machen

geht trotzdem nicht, Solcast hat das Tageslimit bei Neuregistrierung auf 10 gesetzt, aber troztdem dake
RPi2: Buster FHEM 5.9, FTUI, AMAD,10.1" Tablet; MiLight;IT;HM;Dect200;VZLogger

jnewton957

Zitat von: Torxgewinde am 21 Oktober 2022, 20:00:57
Vielen Dank für die Definition für Solcast.
Ich denke es gibt noch einen Punkt bei der Zeitzone der nicht genau stimmt. Ich habe den aktuell gültigen Wert als UserReading dargestellt und musste dabei den Offset der Zeitzone mit einberechnen:

defmod Solcast JsonMod https://api.solcast.com.au/rooftop_sites/AAAA-BBBB-CCCC-DDDD/forecasts?format=json&api_key=ABCDEFGHIJKLMNOPQRSTUVWXYZ&hours=72
attr Solcast group Strom
attr Solcast interval 1,31 * * * *
attr Solcast readingList multi(jsonPath('$.forecasts[*]'), concat('pv_estimate_', property('period_end')), property('pv_estimate'));;\
single(jsonPath('$.forecasts[0].period'),'period','');;
attr Solcast stateFormat Jetzt: forecast_now W, Heute: forecast_today kWh, Morgen: forecast_tomorrow kWh, Übermorgen: forecast_overmorrow kWh
attr Solcast userReadings forecast_now {\
my $period = ReadingsVal($NAME, "period", 0);;\
$period =~ s/.*(\d\d).*/$1/;;\
\
my $offset = timegm(localtime()) - timelocal(localtime());;\
\
my ($date, $time) = split(" ", FmtDateTime(time()-$offset));;\
my ($hour, $min, $sec) = split(":", $time);;\
$time = $hour . $min . "00";;\
\
my ($date_plus, $time_plus) = split(" ", FmtDateTime(time()+30*60-$offset));;\
my ($hour_plus, $min_plus, $sec_plus) = split(":", $time_plus);;\
$time_plus = $hour_plus . $min_plus . "00";;\
\
my $hash = $defs{$NAME};;\
my $readings = $hash->{READINGS};;\
\
foreach my $reading ( keys %{$readings} ) {\
if ($reading =~ /$date/) {\
my ($dummy, $period_end) = split("T", $reading);;\
$period_end = substr($period_end, 0, 6);;\
\
##Log(0, "period_end: ".$period_end .">". $time ." && ". $time_plus);;\
\
if (($period_end > $time) && ($period_end <= $time_plus)) {\
##Log(0, "Treffer");;\
return round(1000*ReadingsVal($NAME,$reading,0),0);;\
}\
}\
}\
},\
forecast_today {\
my $total = 0;;\
my $period = ReadingsVal($NAME, "period", 0);;\
$period =~ s/.*(\d\d).*/$1/;;\
my ($date, $time) = split(" ", FmtDateTime(time()));;\
my ($hour, $min, $sec) = split(":", $time);;\
$time = $hour . $min . "00";;\
my $hash = $defs{$NAME};;\
my $readings = $hash->{READINGS};;\
foreach my $reading ( keys %{$readings} ) {\
if ($reading =~ /$date/) {\
my ($dummy, $period_end) = split("T", $reading);;\
$period_end = substr($period_end, 0, 6);;\
\
if ($period_end > $time)\
{\
my $val = ReadingsVal($NAME,$reading,0);;\
$total += $val/(60/$period);;\
}\
}\
}\
return round($total,2);;\
},\
forecast_tomorrow {\
use Time::Piece ();;\
use Time::Seconds;;\
\
my $total = 0;;\
my $period = ReadingsVal($NAME, "period", 0);;\
$period =~ s/.*(\d\d).*/$1/;;\
my ($date, $time) = split(" ", FmtDateTime(time()));;\
$date = Time::Piece->strptime($date, '%Y-%m-%d');;\
$date += ONE_DAY;;\
$date = $date->strftime('%Y-%m-%d');;\
my $hash = $defs{$NAME};;\
my $readings = $hash->{READINGS};;\
foreach my $reading (keys %{$readings}) {\
if ($reading =~ /$date/) {\
my $val = ReadingsVal($NAME, $reading, 0);;\
$total += $val/(60/$period);;\
}\
}\
return round($total,2);;\
},\
forecast_overmorrow {\
use Time::Piece ();;\
use Time::Seconds;;\
\
my $total = 0;;\
my $period = ReadingsVal($NAME, "period", 0);;\
$period =~ s/.*(\d\d).*/$1/;;\
my ($date, $time) = split(" ", FmtDateTime(time()));;\
$date = Time::Piece->strptime($date, '%Y-%m-%d');;\
$date += ONE_DAY;;\
$date += ONE_DAY;;\
$date = $date->strftime('%Y-%m-%d');;\
my $hash = $defs{$NAME};;\
my $readings = $hash->{READINGS};;\
foreach my $reading (keys %{$readings}) {\
if ($reading =~ /$date/) {\
my $val = ReadingsVal($NAME, $reading, 0);;\
$total += $val/(60/$period);;\
}\
}\
return round($total,2);;\
}
attr Solcast webCmd reread


Plotte ich mir die Werte von "forecast_now" now in einem Graphen über den Ertrag, passt das besser.

Muss hier nicht auch noch die 99_myUtils.pm wegen des forecast_overmorrow und ggf. forecast_now angepasst werden, um die Daten auch im FTUI oder graph anzeigen zu können ?
FHEM5.8 auf Pi3
V 1.65 nanoCUL433 (IT)
nanoCUL JeeLink
V 1.66 nanoCUL868 (HM) (ESA2000WZ)
xELRO AB440, xDECT200, PCA301, xTFA30.3125, esp8266, HM, TabletUI, IR-Schreiblesekopf (Udo)

mähschaf

Guten Abend,

Die Sache mit der Zeitzone scheint ja nicht nur für mich eine spannende Herausforderung zu sein, wie ich hier in mehreren Beiträgen sehe.

Meine folgende Lösung finde ich nicht ganz unelegant, weshalb ich sie gerne teilen möchte. Attribut readingList:

multi(jsonPath('$.forecasts[*]'), concat('pv_estimate_', POSIX::strftime('%Y-%m-%d %H:%M', POSIX::localtime(HTTP::Date::str2time(property('period_end'))))), property('pv_estimate'))
single(jsonPath('$.forecasts[0].period'),'period','')


Einen schönen Abend Euch,
Martin