Energieberechnung für Photovoltaik

PVbeiNacht

Benutzer
Beiträge
14
Liebes Forum.
Ich betreibe bei mir eine Photovoltaikanlage mit einer Victron Venus GX Auswerteeinheit. Aus der lese ich ca. 150 Werte pro Sekunde per MODBUS-TCP über ioBroker als Docker in eine MariaDB10 ein.
Nun möchte ich mittels einer Aggregatfunktion die Energie berechnen.
Die Tabelle (ts_number) ist folgend aufgebaut:
Code:
id    ts               val    ack _from q
14    1583162122689    0.7    1    2    0
16    1583162120627    175.7  1    2    0
14    1583162120627    0.6    1    2    0
52    1583162120624    0.5    1    2    0
10    1583162120599    0      1    2    0
14    1583162118563    0.7    1    2    0
16    1583162118563    175.7  1    2    0
23    1583162118563    42     1    2    0
52    1583162118563    0.6    1    2    0
Die aktuelle Leistung wird unter id=23 abgelegt.
Ich möchte nun die Energie als integrierte Leistung (hier in Watt) berechnen, d.h. Leistung/Zeiteinheit und das dann aufsummieren. Die Zeit ist hier in Millisekunden angegeben.

Meine ersten Versuche haben mich über die LAG Funktion geführt leider kann ich das Ergebnis nicht aufsummieren:
Code:
SET @sum := 0.0;
SET @zwi := 0.0;
SELECT
  row_number() OVER (ORDER BY ts DESC) AS Nummer,
  from_unixtime(floor(ts/1000)) AS time_sec,
  val AS VALUE,
  @zwi := (ts - (lag(ts) over (ORDER BY ts))) * val/1000 AS WS,
  (@sum := @zwi/3600000 + @sum) AS Gesamt
FROM ts_number
WHERE id=23
ORDER BY ts DESC
Das Ergebnis sieht dann so aus:
Code:
Nummer time_sec             VALUE WS        Gesamt
1    2020-03-02 16:31:46    41    84.337    0.00000000000000000000000000000000000000
2    2020-03-02 16:31:44    43    95.589    0.00000000000000000000000000000000000000
3    2020-03-02 16:31:42    40    165.8     0.00000000000000000000000000000000000000
4    2020-03-02 16:31:38    43    88.494    0.00000000000000000000000000000000000000
Was mache ich falsch?
Danke für Eure Hilfe!
 
Zuletzt bearbeitet:
Werbung:
eigentlich einfach, WENN man eine DB hat, die das kann.

Code:
test=# create table pvbeinacht(ts timestamp, leistung int);
CREATE TABLE
test=*# insert into pvbeinacht select '2020-03-01 09:00:00'::date + s * '5minutes'::interval, random()*100 from generate_series(1,20) s;
INSERT 0 20
test=*# select * from pvbeinacht ;
         ts          | leistung
---------------------+----------
 2020-03-01 00:05:00 |       11
 2020-03-01 00:10:00 |       43
 2020-03-01 00:15:00 |       47
 2020-03-01 00:20:00 |       51
 2020-03-01 00:25:00 |       42
 2020-03-01 00:30:00 |       97
 2020-03-01 00:35:00 |       30
 2020-03-01 00:40:00 |       95
 2020-03-01 00:45:00 |        7
 2020-03-01 00:50:00 |       33
 2020-03-01 00:55:00 |       92
 2020-03-01 01:00:00 |       57
 2020-03-01 01:05:00 |       32
 2020-03-01 01:10:00 |       81
 2020-03-01 01:15:00 |       33
 2020-03-01 01:20:00 |        0
 2020-03-01 01:25:00 |       58
 2020-03-01 01:30:00 |       75
 2020-03-01 01:35:00 |       87
 2020-03-01 01:40:00 |       66
(20 rows)

test=*# select *, sum(leistung) over (order by ts) from pvbeinacht ;
         ts          | leistung | sum  
---------------------+----------+------
 2020-03-01 00:05:00 |       11 |   11
 2020-03-01 00:10:00 |       43 |   54
 2020-03-01 00:15:00 |       47 |  101
 2020-03-01 00:20:00 |       51 |  152
 2020-03-01 00:25:00 |       42 |  194
 2020-03-01 00:30:00 |       97 |  291
 2020-03-01 00:35:00 |       30 |  321
 2020-03-01 00:40:00 |       95 |  416
 2020-03-01 00:45:00 |        7 |  423
 2020-03-01 00:50:00 |       33 |  456
 2020-03-01 00:55:00 |       92 |  548
 2020-03-01 01:00:00 |       57 |  605
 2020-03-01 01:05:00 |       32 |  637
 2020-03-01 01:10:00 |       81 |  718
 2020-03-01 01:15:00 |       33 |  751
 2020-03-01 01:20:00 |        0 |  751
 2020-03-01 01:25:00 |       58 |  809
 2020-03-01 01:30:00 |       75 |  884
 2020-03-01 01:35:00 |       87 |  971
 2020-03-01 01:40:00 |       66 | 1037
(20 rows)

test=*# select *, sum(leistung) over (order by ts) as summe, ts - lag(ts) over (order by ts) as zeitdifferenz from pvbeinacht ;
         ts          | leistung | summe | zeitdifferenz
---------------------+----------+-------+---------------
 2020-03-01 00:05:00 |       11 |    11 |
 2020-03-01 00:10:00 |       43 |    54 | 00:05:00
 2020-03-01 00:15:00 |       47 |   101 | 00:05:00
 2020-03-01 00:20:00 |       51 |   152 | 00:05:00
 2020-03-01 00:25:00 |       42 |   194 | 00:05:00
 2020-03-01 00:30:00 |       97 |   291 | 00:05:00
 2020-03-01 00:35:00 |       30 |   321 | 00:05:00
 2020-03-01 00:40:00 |       95 |   416 | 00:05:00
 2020-03-01 00:45:00 |        7 |   423 | 00:05:00
 2020-03-01 00:50:00 |       33 |   456 | 00:05:00
 2020-03-01 00:55:00 |       92 |   548 | 00:05:00
 2020-03-01 01:00:00 |       57 |   605 | 00:05:00
 2020-03-01 01:05:00 |       32 |   637 | 00:05:00
 2020-03-01 01:10:00 |       81 |   718 | 00:05:00
 2020-03-01 01:15:00 |       33 |   751 | 00:05:00
 2020-03-01 01:20:00 |        0 |   751 | 00:05:00
 2020-03-01 01:25:00 |       58 |   809 | 00:05:00
 2020-03-01 01:30:00 |       75 |   884 | 00:05:00
 2020-03-01 01:35:00 |       87 |   971 | 00:05:00
 2020-03-01 01:40:00 |       66 |  1037 | 00:05:00
(20 rows)

test=*#

Zeitdifferenz ist aufgrund meiner generierten Daten immer gleich, und das jetzt weiter zu berechnen wie Du es brauchst überlasse ich Dir zur Übung.
 
Danke für die schnelle Antwort.
Eine Schwierigkeit habe ich vielleicht nicht ausführlich beschrieben: die Zeitdifferenz "ts - lag(ts) over (order by ts)" muss mit der aktuellen Leistung "leistung" multipliziert werden um den Integralabschnitt zu erhalten der dann erst summiert werden soll.

Wenn ich daher
Code:
select *,
    sum(val*(ts - lag(ts) over (ORDER BY ts)/1000)) over (order by ts DESC) as summe,
    ts - lag(ts) over (order by ts) as zeitdifferenz
from ts_number
WHERE id=23;
ausführe bekomme ich die Fehlermeldung:
Window functions can not be used as arguments to group functions.
 
Ich denke die fehlerhafte Zuweisung des Ergebnisses der Window-Funktion 'LAG' an eine Session-Variable liegt an einer Nichtkonformität innerhalb der MariaDB10.3.2. Die Funktion 'LAG' wurde erst in Version 10.2.2 eingeführt (Sept. 2016).

Ich habe eine andere Lösung für das Problem gefunden indem ich ein jeder Zeile ein Bit toggeln lasse und mit entsprechender Zuweisung und Auslesung von Variablen den aktuellen und den vorhergehenden Zeitstempel ermittle:
Code:
SELECT
# Umrechnung Ws (Wattsekunden) in kWh
    MAX(@erg)/3660000000 AS ERGEBNIS_kWh
FROM
(
    SELECT
            @zts1:=IF(@tgl=0,ts,@zts1) AS zts1,
# Abfangen des ersten @zts2=0
            @zts2:=IF(@tgl=1,ts,IF(@zts2=0,ts,@zts2)) AS zts2,
            @tgl:=IF(@tgl=0,1,0) AS BUHL, # toggelt in jeder Zeile
# Aufsummieren von Zeile zu Zeile
            @erg:=@erg+IF(@tgl=1,@zts2-@zts1,@zts1-@zts2)*val AS Ergebnis
    FROM ts_number t, (SELECT @zts1:=0, @zts2:=0, @tgl:=0, @erg:=0) AS a
    WHERE id=23 AND val IS NOT NULL
    ORDER BY ts DESC
) AS b
Im Anhang sind Rohdaten falls jemand die Abfrage testen will.
 

Anhänge

  • iobroker05.03.20.csv.txt
    675 Bytes · Aufrufe: 0
Werbung:
Zurück
Oben