Wir wechseln das Forum am 14.11.24 auf die Forensoftware Discourse. Zwischen Montag Abend und Dienstag Nachmittag wird das Forum deaktiviert. Danach sind wir hoffentlich mit neuem Forum inkl. der vorhandenen Beiträge wieder am Start! Hier zum Forenbeitrag!

influxdb komplexe A...
 
Benachrichtigungen
Alles löschen

influxdb komplexe Abfrage

9 Beiträge
3 Benutzer
0 Reactions
1,178 Ansichten
(@ghostsg)
Vorsichtiger Stromfühler
Beigetreten: Vor 3 Jahren
Beiträge: 38
Themenstarter  

Hallo zusammen,

ich bastel gerade an einem InfluxDB-Select zur Bestimmung der restlichen Ah meines Akkus.
Mein Wechselrichter liefert leider nur die Lade- bzw. Entladeampere und trackt den Akkuverbrauch/Akkuladung ansonsten nicht.

Mit InfluxDB kann man über die Funktion integral() dennoch per Select die Ah ermitteln.
Soweit so gut.

Ich nutze für die Anzeige der Daten Grafana und hier stoße ich dann auf ein "Abfrageproblem für Influx".
Ich habe derzeit zwei Selects, die ich fahren muss um an die gewünschten Daten zu kommen.

1. Select - Bestimmung der letzten Vollladung des Akkus (in meinem Fall per Wechselrichter auf 56V eingestellt / 230 Ah volle Ladung).
2. Select - Integralfunktion zum ermitteln der Ah für Zeitraum X AB Zeitpunkt der letzten Vollladung.

Das Problem ist, dass ich diese beiden Selects nicht vereint bekomme. In Grafana kann ich für den Grafen logischerweise nur einen Select vorgeben.
Er müsste aber dynamisch das Ergebnis des 1. Selects als Zeitpunkt für den 2. Select übernehmen.

Ich werde bei Influx aber nicht schlau, wie die Syntax für den Subquery hier lauten muss.

Anbei die Selects:
1. Zeitpunkt der letzten Volladung bestimmen:
SELECT * FROM "Batterie" WHERE "Spannung" = 56 ORDER BY "time" DESC LIMIT 1

2. per Integralfunktion die Ah Stunden ermittlen, die seitdem entladen wurden:
SELECT 230-sum("Ah_Entladen") AS Rest_Ah FROM
(SELECT (integral("Ladestrom") / 3600)*-1 AS Ah_Entladen FROM "Batterie" WHERE time > 1660130106000000000 AND "Ladestrom" <= 0 GROUP BY time(1d))

Der Timestamp in der WHERE Bedingung ist hier gemeint. Da müsste eigentlich der Subquery hin.
Das lässt Influx aber nicht zu.

Wäre cool, wenn da jemand eine Idee hätte Smile


   
Zitat
(@und-mehr)
Heroischer Stromgenerator
Beigetreten: Vor 3 Jahren
Beiträge: 1148
 

Kann influx noch sql?

Meinst du so was:?

SELECT 230-sum("Ah_Entladen") AS Rest_Ah FROM
(SELECT (integral("Ladestrom") / 3600)*-1 AS Ah_Entladen
FROM
"Batterie"
WHERE time > (select max(time) time from "Batterie" WHERE "Spannung" = 56)
AND "Ladestrom" <= 0
GROUP BY
time(1d)
)

..,-


   
AntwortZitat
(@ghostsg)
Vorsichtiger Stromfühler
Beigetreten: Vor 3 Jahren
Beiträge: 38
Themenstarter  

Ja genau,

nur das die DB diesen Abfrage so nicht zulässt.


   
AntwortZitat
(@und-mehr)
Heroischer Stromgenerator
Beigetreten: Vor 3 Jahren
Beiträge: 1148
 

Schade,
wahrscheinlich steht der Programmierer auf Gänsefüße um alles was fremd und keine Zahl ist.

WHERE "time" > (select max("time") "time" from "Batterie" WHERE "Spannung" = 56)

..,-


   
AntwortZitat
(@ghostsg)
Vorsichtiger Stromfühler
Beigetreten: Vor 3 Jahren
Beiträge: 38
Themenstarter  

soweit ich die Docs von Influx verstanden habe ist ein Subquery mit "SELECT" Statement in der WHERE Bedingung nicht zulässig.
Wenn das so ist, fehlt mir die Idee, wie man das sonst darstellen soll.


   
AntwortZitat
(@und-mehr)
Heroischer Stromgenerator
Beigetreten: Vor 3 Jahren
Beiträge: 1148
 

kann es joinen?

SELECT 230-sum("Ah_Entladen") AS Rest_Ah FROM
(SELECT (integral("Batterie.Ladestrom") / 3600)*-1 AS Ah_Entladen
FROM
"Batterie"
join (select max("time") "time" from "Batterie" WHERE "Spannung" = 56) "max56"
on "Batterie.time" > "max56.time"
WHERE "Batterie.Ladestrom" <= 0
GROUP BY
time(1d)
)

..,-


   
AntwortZitat
profantus
(@profantus)
Mitglied Wiki-Moderatoren
Beigetreten: Vor 3 Jahren
Beiträge: 1198
 

Influx kann contiuous queries. Damit kannst du eine neue Zeitreihe über einen Query auf einer bestehenden Zeitreihe erstelle.
Schau mal hier https://docs.influxdata.com/influxdb/v1.8/query_language/continuous_queries/
Den ersten select steckst du in den contiuous query, den 2. Select machst du auf der neuen Zeitreihe.

HOWTO Wechselrichter Dimensionierung


   
AntwortZitat
(@ghostsg)
Vorsichtiger Stromfühler
Beigetreten: Vor 3 Jahren
Beiträge: 38
Themenstarter  

das sieht interessant aus mit den continueous queries. das schaue ich mir mal näher an Smile


   
AntwortZitat
(@ghostsg)
Vorsichtiger Stromfühler
Beigetreten: Vor 3 Jahren
Beiträge: 38
Themenstarter  

Mit den Continueous Querys kam ich leider auch nicht weiter....

ich habe es jetzt "von hinten durch die Brust ins Auge" gelöst. Nicht schön, aber funktioniert:

Mittels php-Script frage ich die benötigen Daten aus der InfluxDB ab, bereite Sie auf und schreibe Sie dann Abfragefertig in eine mySQL DB.
Das php-Script läuft einfach alle 5 min als Cron und in Grafana habe ich dann einen simplen Select für die mySQL Daten.

Wen es interessiert, hier das php-Script:

<?php
//Variablen
$battery_capacity_in_Ah = 230;

//DB-Verbindung
$mysqli = new mysqli('HOST', 'USER', 'PASSWORD', 'DB');
if ($mysqli->connect_errno)
{
die("Verbindung fehlgeschlagen: " . $mysqli->connect_error);
}
$mysqli->set_charset('utf8');

//Letzte Voll-Ladung der PV-Batterie aus InfluxDB abfragen
$postRequest = array(
'q' => 'SELECT * FROM "Batterie" WHERE "Spannung" = 56 ORDER BY time DESC LIMIT 1',
'db' => 'solaranzeige'
);

$cURLConnection = curl_init(' http://192.168.XX.XX:8086/query ');
curl_setopt($cURLConnection, CURLOPT_POSTFIELDS, $postRequest);
curl_setopt($cURLConnection, CURLOPT_RETURNTRANSFER, true);

$apiResponse = curl_exec($cURLConnection);
curl_close($cURLConnection);

// $apiResponse - available data from the API request
$jsonArrayResponse = json_decode($apiResponse,true);
$timestamp = strtotime($jsonArrayResponse['results'][0]['series'][0]['values'][0][0]);
$timestamp_mysql = date("Y-m-d H:i:s",$timestamp);
$timestamp_influx = $timestamp."000000000";

//Ladezustände der Batterie aus InfluxDB
//Ah Geladen seit letztem Full Load
$postRequest = array(
'q' => 'SELECT sum("Ah_Laden") AS Ah_Laden FROM (SELECT (integral("Ladestrom") / 3600)*-1 AS Ah_Laden FROM "Batterie" WHERE time > '.$timestamp_influx.' AND "Ladestrom" >= 0 GROUP BY time(1h))', 'db' => 'solaranzeige');

$cURLConnection = curl_init(' http://192.168.XX.XX:8086/query ');
curl_setopt($cURLConnection, CURLOPT_POSTFIELDS, $postRequest);
curl_setopt($cURLConnection, CURLOPT_RETURNTRANSFER, true);

$apiResponse = curl_exec($cURLConnection);
curl_close($cURLConnection);

// $apiResponse - available data from the API request
$jsonArrayResponse = json_decode($apiResponse,true);
$geladen = $jsonArrayResponse['results'][0]['series'][0]['values'][0][1]*-1;

//Ah Entladen seit letztem Full Load
$postRequest = array(
'q' => 'SELECT sum("Ah_Laden") AS Ah_Laden FROM (SELECT (integral("Ladestrom") / 3600) AS Ah_Laden FROM "Batterie" WHERE time > '.$timestamp_influx.' AND "Ladestrom" <= 0 GROUP BY time(1h))', 'db' => 'solaranzeige');

$cURLConnection = curl_init(' http://192.168.XX.XX:8086/query ');
curl_setopt($cURLConnection, CURLOPT_POSTFIELDS, $postRequest);
curl_setopt($cURLConnection, CURLOPT_RETURNTRANSFER, true);

$apiResponse = curl_exec($cURLConnection);
curl_close($cURLConnection);

// $apiResponse - available data from the API request
$jsonArrayResponse = json_decode($apiResponse,true);
$entladen = $jsonArrayResponse['results'][0]['series'][0]['values'][0][1]*-1;
$rest_ah = $battery_capacity_in_Ah+$geladen-$entladen;

//Ergebnise in MySQL DB eintragen
$insert = "
INSERT INTO
pv_battery
(
last_full_load,
ah_entladen,
ah_geladen,
ah_rest
)
VALUES
(
'$timestamp_mysql',
$entladen,
$geladen,
$rest_ah
)";
$insertergebnis = mysqli_query($mysqli, $insert) OR die($insert.mysqli_error($mysqli));
unset($insertergebnis);
echo "Batteriekapazität: $battery_capacity_in_Ah<br>Geladen: $geladen<br>Entladen: $entladen<br>Rest-Ah: $rest_ah";
?>


   
AntwortZitat
Teilen: