Aktueller Stand
This commit is contained in:
parent
d52c9b4094
commit
5cc9f50e94
153
src/main/java/info/peper/vz/rest/Calculator.java
Normal file
153
src/main/java/info/peper/vz/rest/Calculator.java
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
package info.peper.vz.rest;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import info.peper.vz.rest.bo.db.Aggregate2;
|
||||||
|
|
||||||
|
public final class Calculator {
|
||||||
|
|
||||||
|
public static List<Aggregate2> processHouseMulti(final int houseId,
|
||||||
|
final long startTimestamp,
|
||||||
|
final long endTimestamp,
|
||||||
|
final long interval,
|
||||||
|
final int[] channelIdsSolar,
|
||||||
|
final int[] channelIdsMeter,
|
||||||
|
final Connection con) throws SQLException {
|
||||||
|
final List<Aggregate2> result = new LinkedList<Aggregate2>();
|
||||||
|
|
||||||
|
final PreparedStatement[] stmtSolar = new PreparedStatement[channelIdsSolar.length];
|
||||||
|
final PreparedStatement[] stmtMeter = new PreparedStatement[channelIdsMeter.length];
|
||||||
|
final ResultSet[] rsSolar = new ResultSet[channelIdsSolar.length];
|
||||||
|
final ResultSet[] rsMeter = new ResultSet[channelIdsMeter.length];
|
||||||
|
long[] currentTsSolar = new long[channelIdsSolar.length];
|
||||||
|
long[] currentTsMeter = new long[channelIdsMeter.length];
|
||||||
|
boolean[] noNextRecordSolar = new boolean[channelIdsSolar.length];
|
||||||
|
boolean[] noNextRecordMeter = new boolean[channelIdsMeter.length];
|
||||||
|
|
||||||
|
for (int i = 0; i < channelIdsSolar.length; i++) {
|
||||||
|
stmtSolar[i] = con.prepareStatement("SELECT * FROM volkszaehler.data WHERE channel_id=? AND timestamp>? ORDER BY timestamp;");
|
||||||
|
stmtSolar[i].setInt(1, channelIdsSolar[i]);
|
||||||
|
stmtSolar[i].setLong(2, startTimestamp);
|
||||||
|
stmtSolar[i].setFetchSize(1000);
|
||||||
|
rsSolar[i] = stmtSolar[i].executeQuery();
|
||||||
|
currentTsSolar[i] = startTimestamp;
|
||||||
|
noNextRecordSolar[i] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < channelIdsMeter.length; i++) {
|
||||||
|
stmtMeter[i] = con.prepareStatement("SELECT * FROM volkszaehler.data WHERE channel_id=? AND timestamp>? ORDER BY timestamp;");
|
||||||
|
stmtMeter[i].setInt(1, channelIdsMeter[i]);
|
||||||
|
stmtMeter[i].setLong(2, startTimestamp);
|
||||||
|
stmtMeter[i].setFetchSize(1000);
|
||||||
|
rsMeter[i] = stmtMeter[i].executeQuery();
|
||||||
|
currentTsMeter[i] = startTimestamp;
|
||||||
|
noNextRecordMeter[i] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Starting...");
|
||||||
|
long intervalProduced = 0;
|
||||||
|
long intervalObtained = 0;
|
||||||
|
long intervalInjected = 0;
|
||||||
|
|
||||||
|
long intervalStartTimestamp = startTimestamp;
|
||||||
|
long intervalEndTimestamp = startTimestamp + interval;
|
||||||
|
|
||||||
|
// Eigentliche Verarbeitung
|
||||||
|
|
||||||
|
while (getMinOfArray(currentTsSolar) <= endTimestamp || getMinOfArray(currentTsMeter) <= endTimestamp) {
|
||||||
|
System.out.print(intervalStartTimestamp + ": ");
|
||||||
|
|
||||||
|
for (int iSolar = 0; iSolar < channelIdsSolar.length; iSolar++) {
|
||||||
|
currentTsSolar[iSolar] = intervalStartTimestamp;
|
||||||
|
|
||||||
|
while (currentTsSolar[iSolar] < intervalEndTimestamp && (noNextRecordSolar[iSolar] || rsSolar[iSolar].next())) {
|
||||||
|
if (noNextRecordSolar[iSolar]) {
|
||||||
|
noNextRecordSolar[iSolar] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final long tsSolar = rsSolar[iSolar].getLong("timestamp");
|
||||||
|
final double value = rsSolar[iSolar].getDouble("value") > 1.0 ? rsSolar[iSolar].getDouble("value") : 0.0;
|
||||||
|
final long tsDiff = (tsSolar < intervalEndTimestamp) ? tsSolar - currentTsSolar[iSolar] : intervalEndTimestamp - currentTsSolar[iSolar];
|
||||||
|
|
||||||
|
currentTsSolar[iSolar] = tsSolar;
|
||||||
|
|
||||||
|
intervalProduced += Math.round(value * tsDiff);
|
||||||
|
|
||||||
|
if (currentTsSolar[iSolar] >= intervalEndTimestamp) {
|
||||||
|
noNextRecordSolar[iSolar] = true;
|
||||||
|
}
|
||||||
|
System.out.print(".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double meterValue = 0;
|
||||||
|
for (int iMeter = 0; iMeter < channelIdsMeter.length; iMeter++) {
|
||||||
|
currentTsMeter[iMeter] = intervalStartTimestamp;
|
||||||
|
|
||||||
|
while (currentTsMeter[iMeter] < intervalEndTimestamp && (noNextRecordMeter[iMeter] || rsMeter[iMeter].next())) {
|
||||||
|
if (noNextRecordMeter[iMeter]) {
|
||||||
|
noNextRecordMeter[iMeter] = false;
|
||||||
|
}
|
||||||
|
final long tsMeter = rsMeter[iMeter].getLong("timestamp");
|
||||||
|
final double value = rsMeter[iMeter].getDouble("value");
|
||||||
|
final long tsDiff = (tsMeter < intervalEndTimestamp) ? tsMeter - currentTsMeter[iMeter] : intervalEndTimestamp - currentTsMeter[iMeter];
|
||||||
|
|
||||||
|
currentTsMeter[iMeter] = tsMeter;
|
||||||
|
|
||||||
|
meterValue += Math.round(value * tsDiff);
|
||||||
|
|
||||||
|
if (currentTsMeter[iMeter] >= intervalEndTimestamp) {
|
||||||
|
noNextRecordMeter[iMeter] = true;
|
||||||
|
}
|
||||||
|
System.out.print("#");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (meterValue > 0.0) {
|
||||||
|
intervalObtained += Math.round(meterValue);
|
||||||
|
} else {
|
||||||
|
intervalInjected += Math.abs(Math.round(meterValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(" " + intervalProduced + " / " + intervalObtained + " / " + intervalInjected);
|
||||||
|
|
||||||
|
result.add(new Aggregate2(houseId, intervalStartTimestamp, intervalEndTimestamp, intervalProduced, intervalObtained, intervalInjected));
|
||||||
|
|
||||||
|
intervalStartTimestamp += interval;
|
||||||
|
intervalEndTimestamp += interval;
|
||||||
|
|
||||||
|
intervalInjected = 0;
|
||||||
|
intervalObtained = 0;
|
||||||
|
intervalProduced = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aufräumen
|
||||||
|
for (int i = 0; i < channelIdsSolar.length; i++) {
|
||||||
|
rsSolar[i].close();
|
||||||
|
stmtSolar[i].close();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < channelIdsMeter.length; i++) {
|
||||||
|
rsMeter[i].close();
|
||||||
|
stmtMeter[i].close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long getMinOfArray(final long[] input) {
|
||||||
|
long result = Long.MAX_VALUE;
|
||||||
|
for (long i : input) {
|
||||||
|
if (i < result) {
|
||||||
|
result = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -8,14 +8,12 @@ import java.io.InputStreamReader;
|
|||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.DriverManager;
|
import java.sql.DriverManager;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.time.temporal.TemporalAccessor;
|
import java.time.temporal.TemporalAccessor;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import info.peper.vz.rest.bo.db.Aggregate2;
|
import info.peper.vz.rest.bo.db.Aggregate2;
|
||||||
@ -38,7 +36,14 @@ public class FillAggregateTableMain3 {
|
|||||||
final long startTimeStamp = getTimestamp("2022-05-20T09:00:00");
|
final long startTimeStamp = getTimestamp("2022-05-20T09:00:00");
|
||||||
final long finalEndTimeStamp = getTimestamp("2025-03-09T15:00:00");
|
final long finalEndTimeStamp = getTimestamp("2025-03-09T15:00:00");
|
||||||
|
|
||||||
final List<Aggregate2> aggregates = processHouse(1, startTimeStamp, finalEndTimeStamp, 60*1000, 4, 1, con);
|
final List<Aggregate2> aggregates = Calculator.processHouseMulti(
|
||||||
|
1,
|
||||||
|
startTimeStamp,
|
||||||
|
finalEndTimeStamp,
|
||||||
|
60*1000,
|
||||||
|
new int[] {4},
|
||||||
|
new int[] {1},
|
||||||
|
con);
|
||||||
saveValues(con, aggregates, 1);
|
saveValues(con, aggregates, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,244 +51,17 @@ public class FillAggregateTableMain3 {
|
|||||||
final long startTimeStamp = getTimestamp("2024-06-23T17:00:00");
|
final long startTimeStamp = getTimestamp("2024-06-23T17:00:00");
|
||||||
final long finalEndTimeStamp = getTimestamp("2025-03-09T15:00:00");
|
final long finalEndTimeStamp = getTimestamp("2025-03-09T15:00:00");
|
||||||
|
|
||||||
final List<Aggregate2> aggregates = processHouseMulti(2, startTimeStamp, finalEndTimeStamp, 60*1000, new int[] {24}, new int[] {18, 19, 20}, con);
|
final List<Aggregate2> aggregates = Calculator.processHouseMulti(
|
||||||
|
2,
|
||||||
|
startTimeStamp,
|
||||||
|
finalEndTimeStamp,
|
||||||
|
60*1000,
|
||||||
|
new int[] {24},
|
||||||
|
new int[] {18, 19, 20},
|
||||||
|
con);
|
||||||
saveValues(con, aggregates, 2);
|
saveValues(con, aggregates, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<Aggregate2> processHouse(final int houseId,
|
|
||||||
final long startTimestamp,
|
|
||||||
final long endTimestamp,
|
|
||||||
final long interval,
|
|
||||||
final int channelIdSolar,
|
|
||||||
final int channelIdMeter,
|
|
||||||
final Connection con) throws SQLException {
|
|
||||||
final List<Aggregate2> result = new LinkedList<Aggregate2>();
|
|
||||||
try (final PreparedStatement stmtSolar = con.prepareStatement("SELECT * FROM volkszaehler.data WHERE channel_id=? AND timestamp>? ORDER BY timestamp;");
|
|
||||||
final PreparedStatement stmtMeter = con.prepareStatement("SELECT * FROM volkszaehler.data WHERE channel_id=? AND timestamp>? ORDER BY timestamp;");) {
|
|
||||||
stmtSolar.setInt(1, channelIdSolar);
|
|
||||||
stmtSolar.setLong(2, startTimestamp);
|
|
||||||
stmtSolar.setFetchSize(1000);
|
|
||||||
stmtMeter.setInt(1, channelIdMeter);
|
|
||||||
stmtMeter.setLong(2, startTimestamp);
|
|
||||||
stmtMeter.setFetchSize(1000);
|
|
||||||
|
|
||||||
try (final ResultSet rsSolar = stmtSolar.executeQuery(); final ResultSet rsMeter = stmtMeter.executeQuery()) {
|
|
||||||
System.out.println("Starting...");
|
|
||||||
long intervalProduced = 0;
|
|
||||||
long intervalObtained = 0;
|
|
||||||
long intervalInjected = 0;
|
|
||||||
|
|
||||||
long currentTsSolar = startTimestamp;
|
|
||||||
long currentTsMeter = startTimestamp;
|
|
||||||
|
|
||||||
long intervalStartTimestamp = startTimestamp;
|
|
||||||
long intervalEndTimestamp = startTimestamp + interval;
|
|
||||||
|
|
||||||
boolean noNextRecordSolar = false;
|
|
||||||
boolean noNextRecordMeter = false;
|
|
||||||
|
|
||||||
while (currentTsSolar <= endTimestamp || currentTsMeter <= endTimestamp) {
|
|
||||||
|
|
||||||
currentTsSolar = intervalStartTimestamp;
|
|
||||||
currentTsMeter = intervalStartTimestamp;
|
|
||||||
|
|
||||||
System.out.print(intervalStartTimestamp + ": ");
|
|
||||||
|
|
||||||
while (currentTsSolar < intervalEndTimestamp && (noNextRecordSolar || rsSolar.next())) {
|
|
||||||
if (noNextRecordSolar) {
|
|
||||||
noNextRecordSolar = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final long tsSolar = rsSolar.getLong("timestamp");
|
|
||||||
final double value = rsSolar.getDouble("value") > 1.0 ? rsSolar.getDouble("value") : 0.0;
|
|
||||||
final long tsDiff = (tsSolar < intervalEndTimestamp) ? tsSolar - currentTsSolar : intervalEndTimestamp - currentTsSolar;
|
|
||||||
|
|
||||||
currentTsSolar = tsSolar;
|
|
||||||
|
|
||||||
intervalProduced += Math.round(value * tsDiff);
|
|
||||||
|
|
||||||
if (currentTsSolar >= intervalEndTimestamp) {
|
|
||||||
noNextRecordSolar = true;
|
|
||||||
}
|
|
||||||
System.out.print(".");
|
|
||||||
}
|
|
||||||
|
|
||||||
while (currentTsMeter < intervalEndTimestamp && (noNextRecordMeter || rsMeter.next())) {
|
|
||||||
if (noNextRecordMeter) {
|
|
||||||
noNextRecordMeter = false;
|
|
||||||
}
|
|
||||||
final long tsMeter = rsMeter.getLong("timestamp");
|
|
||||||
final double value = rsMeter.getDouble("value");
|
|
||||||
final long tsDiff = (tsMeter < intervalEndTimestamp) ? tsMeter - currentTsMeter : intervalEndTimestamp - currentTsMeter;
|
|
||||||
|
|
||||||
currentTsMeter = tsMeter;
|
|
||||||
|
|
||||||
if (value > 0.0) {
|
|
||||||
intervalObtained += Math.round(value * tsDiff);
|
|
||||||
} else {
|
|
||||||
intervalInjected += Math.abs(Math.round(value * tsDiff));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentTsMeter >= intervalEndTimestamp) {
|
|
||||||
noNextRecordMeter = true;
|
|
||||||
}
|
|
||||||
System.out.print("#");
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println(" " + intervalProduced + " / " + intervalObtained + " / " + intervalInjected);
|
|
||||||
|
|
||||||
result.add(new Aggregate2(houseId, intervalStartTimestamp, intervalEndTimestamp, intervalProduced, intervalObtained, intervalInjected));
|
|
||||||
|
|
||||||
intervalStartTimestamp += interval;
|
|
||||||
intervalEndTimestamp += interval;
|
|
||||||
|
|
||||||
intervalInjected = 0;
|
|
||||||
intervalObtained = 0;
|
|
||||||
intervalProduced = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<Aggregate2> processHouseMulti(final int houseId,
|
|
||||||
final long startTimestamp,
|
|
||||||
final long endTimestamp,
|
|
||||||
final long interval,
|
|
||||||
final int[] channelIdsSolar,
|
|
||||||
final int[] channelIdsMeter,
|
|
||||||
final Connection con) throws SQLException {
|
|
||||||
final List<Aggregate2> result = new LinkedList<Aggregate2>();
|
|
||||||
|
|
||||||
final PreparedStatement[] stmtSolar = new PreparedStatement[channelIdsSolar.length];
|
|
||||||
final PreparedStatement[] stmtMeter = new PreparedStatement[channelIdsMeter.length];
|
|
||||||
final ResultSet[] rsSolar = new ResultSet[channelIdsSolar.length];
|
|
||||||
final ResultSet[] rsMeter = new ResultSet[channelIdsMeter.length];
|
|
||||||
long[] currentTsSolar = new long[channelIdsSolar.length];
|
|
||||||
long[] currentTsMeter = new long[channelIdsMeter.length];
|
|
||||||
boolean[] noNextRecordSolar = new boolean[channelIdsSolar.length];
|
|
||||||
boolean[] noNextRecordMeter = new boolean[channelIdsMeter.length];
|
|
||||||
|
|
||||||
for (int i = 0; i < channelIdsSolar.length; i++) {
|
|
||||||
stmtSolar[i] = con.prepareStatement("SELECT * FROM volkszaehler.data WHERE channel_id=? AND timestamp>? ORDER BY timestamp;");
|
|
||||||
stmtSolar[i].setInt(1, channelIdsSolar[i]);
|
|
||||||
stmtSolar[i].setLong(2, startTimestamp);
|
|
||||||
stmtSolar[i].setFetchSize(1000);
|
|
||||||
rsSolar[i] = stmtSolar[i].executeQuery();
|
|
||||||
currentTsSolar[i] = startTimestamp;
|
|
||||||
noNextRecordSolar[i] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < channelIdsMeter.length; i++) {
|
|
||||||
stmtMeter[i] = con.prepareStatement("SELECT * FROM volkszaehler.data WHERE channel_id=? AND timestamp>? ORDER BY timestamp;");
|
|
||||||
stmtMeter[i].setInt(1, channelIdsMeter[i]);
|
|
||||||
stmtMeter[i].setLong(2, startTimestamp);
|
|
||||||
stmtMeter[i].setFetchSize(1000);
|
|
||||||
rsMeter[i] = stmtMeter[i].executeQuery();
|
|
||||||
currentTsMeter[i] = startTimestamp;
|
|
||||||
noNextRecordMeter[i] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println("Starting...");
|
|
||||||
long intervalProduced = 0;
|
|
||||||
long intervalObtained = 0;
|
|
||||||
long intervalInjected = 0;
|
|
||||||
|
|
||||||
long intervalStartTimestamp = startTimestamp;
|
|
||||||
long intervalEndTimestamp = startTimestamp + interval;
|
|
||||||
|
|
||||||
// Eigentliche Verarbeitung
|
|
||||||
|
|
||||||
while (getMinOfArray(currentTsSolar) <= endTimestamp || getMinOfArray(currentTsMeter) <= endTimestamp) {
|
|
||||||
System.out.print(intervalStartTimestamp + ": ");
|
|
||||||
|
|
||||||
for (int iSolar = 0; iSolar < channelIdsSolar.length; iSolar++) {
|
|
||||||
currentTsSolar[iSolar] = intervalStartTimestamp;
|
|
||||||
|
|
||||||
while (currentTsSolar[iSolar] < intervalEndTimestamp && (noNextRecordSolar[iSolar] || rsSolar[iSolar].next())) {
|
|
||||||
if (noNextRecordSolar[iSolar]) {
|
|
||||||
noNextRecordSolar[iSolar] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final long tsSolar = rsSolar[iSolar].getLong("timestamp");
|
|
||||||
final double value = rsSolar[iSolar].getDouble("value") > 1.0 ? rsSolar[iSolar].getDouble("value") : 0.0;
|
|
||||||
final long tsDiff = (tsSolar < intervalEndTimestamp) ? tsSolar - currentTsSolar[iSolar] : intervalEndTimestamp - currentTsSolar[iSolar];
|
|
||||||
|
|
||||||
currentTsSolar[iSolar] = tsSolar;
|
|
||||||
|
|
||||||
intervalProduced += Math.round(value * tsDiff);
|
|
||||||
|
|
||||||
if (currentTsSolar[iSolar] >= intervalEndTimestamp) {
|
|
||||||
noNextRecordSolar[iSolar] = true;
|
|
||||||
}
|
|
||||||
System.out.print(".");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
double meterValue = 0;
|
|
||||||
for (int iMeter = 0; iMeter < channelIdsMeter.length; iMeter++) {
|
|
||||||
currentTsMeter[iMeter] = intervalStartTimestamp;
|
|
||||||
|
|
||||||
while (currentTsMeter[iMeter] < intervalEndTimestamp && (noNextRecordMeter[iMeter] || rsMeter[iMeter].next())) {
|
|
||||||
if (noNextRecordMeter[iMeter]) {
|
|
||||||
noNextRecordMeter[iMeter] = false;
|
|
||||||
}
|
|
||||||
final long tsMeter = rsMeter[iMeter].getLong("timestamp");
|
|
||||||
final double value = rsMeter[iMeter].getDouble("value");
|
|
||||||
final long tsDiff = (tsMeter < intervalEndTimestamp) ? tsMeter - currentTsMeter[iMeter] : intervalEndTimestamp - currentTsMeter[iMeter];
|
|
||||||
|
|
||||||
currentTsMeter[iMeter] = tsMeter;
|
|
||||||
|
|
||||||
meterValue += Math.round(value * tsDiff);
|
|
||||||
|
|
||||||
if (currentTsMeter[iMeter] >= intervalEndTimestamp) {
|
|
||||||
noNextRecordMeter[iMeter] = true;
|
|
||||||
}
|
|
||||||
System.out.print("#");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (meterValue > 0.0) {
|
|
||||||
intervalObtained += Math.round(meterValue);
|
|
||||||
} else {
|
|
||||||
intervalInjected += Math.abs(Math.round(meterValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println(" " + intervalProduced + " / " + intervalObtained + " / " + intervalInjected);
|
|
||||||
|
|
||||||
result.add(new Aggregate2(houseId, intervalStartTimestamp, intervalEndTimestamp, intervalProduced, intervalObtained, intervalInjected));
|
|
||||||
|
|
||||||
intervalStartTimestamp += interval;
|
|
||||||
intervalEndTimestamp += interval;
|
|
||||||
|
|
||||||
intervalInjected = 0;
|
|
||||||
intervalObtained = 0;
|
|
||||||
intervalProduced = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Aufräumen
|
|
||||||
for (int i = 0; i < channelIdsSolar.length; i++) {
|
|
||||||
rsSolar[i].close();
|
|
||||||
stmtSolar[i].close();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < channelIdsMeter.length; i++) {
|
|
||||||
rsMeter[i].close();
|
|
||||||
stmtMeter[i].close();
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static long getMinOfArray(final long[] input) {
|
|
||||||
long result = Long.MAX_VALUE;
|
|
||||||
for (long i : input) {
|
|
||||||
if (i < result) {
|
|
||||||
result = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void saveValues(final Connection con, final List<Aggregate2> aggregates, final int houseId) throws SQLException {
|
private static void saveValues(final Connection con, final List<Aggregate2> aggregates, final int houseId) throws SQLException {
|
||||||
System.out.println("Saving entries... : " + aggregates.size());
|
System.out.println("Saving entries... : " + aggregates.size());
|
||||||
try (final PreparedStatement stmt = con.prepareStatement("INSERT INTO tobias_aggregate2 (house_id, timestamp_start, timestamp_end, produced_energy, obtained_energy, injected_energy) VALUES (?, ?, ?, ?, ?, ?)")) {
|
try (final PreparedStatement stmt = con.prepareStatement("INSERT INTO tobias_aggregate2 (house_id, timestamp_start, timestamp_end, produced_energy, obtained_energy, injected_energy) VALUES (?, ?, ?, ?, ?, ?)")) {
|
||||||
|
|||||||
@ -12,9 +12,6 @@ import org.slf4j.LoggerFactory;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
@ -86,7 +83,7 @@ class VzRestController {
|
|||||||
@RequestParam("timestampEnd")final long timestampEnd,
|
@RequestParam("timestampEnd")final long timestampEnd,
|
||||||
@RequestParam("houseId")final int houseId) {
|
@RequestParam("houseId")final int houseId) {
|
||||||
final List<Aggregate2> aggregates = jdbcTemplate.query(
|
final List<Aggregate2> aggregates = jdbcTemplate.query(
|
||||||
"SELECT MIN(timestamp_start) AS min_ts_start, MAX(timestamp_end) AS max_ts_end, SUM(produced_energy) AS sum_produced, SUM(obtained_energy) AS sum_obtained, SUM(injected_energy) AS sum_injected FROM volkszaehler.tobias_aggregate2 WHERE house_id=? AND timestamp_start>=? AND timestamp_end<=?;",
|
"SELECT MIN(timestamp_start) AS min_ts_start, MAX(timestamp_end) AS max_ts_end, SUM(produced_energy)/3600 AS sum_produced, SUM(obtained_energy)/3600 AS sum_obtained, SUM(injected_energy)/3600 AS sum_injected FROM volkszaehler.tobias_aggregate2 WHERE house_id=? AND timestamp_start>=? AND timestamp_end<=?;",
|
||||||
(rs, rowNum) -> new Aggregate2(houseId, rs.getLong("min_ts_start"), rs.getLong("max_ts_end"),
|
(rs, rowNum) -> new Aggregate2(houseId, rs.getLong("min_ts_start"), rs.getLong("max_ts_end"),
|
||||||
rs.getLong("sum_produced"), rs.getLong("sum_obtained"), rs.getLong("sum_injected")),
|
rs.getLong("sum_produced"), rs.getLong("sum_obtained"), rs.getLong("sum_injected")),
|
||||||
houseId ,timestampStart, timestampEnd);
|
houseId ,timestampStart, timestampEnd);
|
||||||
@ -95,30 +92,16 @@ class VzRestController {
|
|||||||
}
|
}
|
||||||
final Aggregate2 aggregate = aggregates.iterator().next();
|
final Aggregate2 aggregate = aggregates.iterator().next();
|
||||||
|
|
||||||
double sumPos = aggregate.getSumPositive();
|
log.debug("energyProduced: " + aggregate.getProducedEnergy() + " / energyObtained: " + aggregate.getObtainedEnergy() + " / injectedEnergy: " + aggregate.getInjectedEnergy());
|
||||||
double sumNeg = aggregate.getSumNegative();
|
|
||||||
log.debug("sumPos: " + sumPos + " / sumNeg: " + sumNeg);
|
|
||||||
log.debug("timestampStart: " + timestampStart);
|
log.debug("timestampStart: " + timestampStart);
|
||||||
log.debug("timestampEnd: " + timestampEnd);
|
log.debug("timestampEnd: " + timestampEnd);
|
||||||
log.debug("firstTimestamp: " + aggregate.getTimestampStart());
|
log.debug("firstTimestamp: " + aggregate.getTimestampStart());
|
||||||
log.debug("lastTimestamp: " + aggregate.getTimestampEnd());
|
log.debug("lastTimestamp: " + aggregate.getTimestampEnd());
|
||||||
|
|
||||||
if (timestampStart < aggregate.getTimestampStart() ) {
|
return new Sums2(
|
||||||
final Sums startSums = getSums(timestampStart, aggregate.getTimestampStart(), channelId);
|
Math.round(aggregate.getInjectedEnergy()),
|
||||||
sumPos += startSums.getSumPositive();
|
Math.round(aggregate.getObtainedEnergy()),
|
||||||
sumNeg += startSums.getSumNegative();
|
Math.round(aggregate.getProducedEnergy()));
|
||||||
log.debug("Start: " + startSums.toString());
|
|
||||||
}
|
|
||||||
if (timestampEnd > aggregate.getTimestampEnd()) {
|
|
||||||
final Sums endSums = getSums(aggregate.getTimestampEnd(), timestampEnd, channelId);
|
|
||||||
sumPos += endSums.getSumPositive();
|
|
||||||
sumNeg += endSums.getSumNegative();
|
|
||||||
log.debug("End: " + endSums.toString());
|
|
||||||
|
|
||||||
}
|
|
||||||
sumPos /= 3600;
|
|
||||||
sumNeg /= 3600;
|
|
||||||
return new Sums(Math.round(sumPos), Math.round(sumNeg));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/data/sumsWithFactor")
|
@GetMapping("/data/sumsWithFactor")
|
||||||
@ -230,15 +213,38 @@ class VzRestController {
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/data/summary2")
|
||||||
|
String getSummary2(@RequestParam("timestampStart")final long timestampStart,
|
||||||
|
@RequestParam("timestampEnd")final long timestampEnd,
|
||||||
|
@RequestParam("contractId")final int contractId) {
|
||||||
|
final NumberFormat formatCurrency = new DecimalFormat("#,##0.00", new DecimalFormatSymbols(Locale.GERMAN));
|
||||||
|
final NumberFormat formatPercent = new DecimalFormat("#,##0.00", new DecimalFormatSymbols(Locale.GERMAN));
|
||||||
|
final NumberFormat formatEnergy = new DecimalFormat("#,##0", new DecimalFormatSymbols(Locale.GERMAN));
|
||||||
|
final List<EnergyPrice> prices = this.getPrices(timestampStart, timestampEnd, contractId);
|
||||||
|
|
||||||
@GetMapping("/test/{name}")
|
|
||||||
String hello(@PathVariable("name")final String name) {
|
float savedMoney = 0;
|
||||||
return "Hello " + name + "!";
|
long totalProduced = 0;
|
||||||
|
long totalObtained = 0;
|
||||||
|
long totalInjected = 0;
|
||||||
|
for (EnergyPrice price : prices) {
|
||||||
|
final long tsStart = Math.max(price.getTimestampStart(), timestampStart);
|
||||||
|
final long tsEnd = Math.min(price.getTimestampEnd(), timestampEnd);
|
||||||
|
final Sums2 sums = getData2(tsStart, tsEnd, contractId);
|
||||||
|
savedMoney += (float)(sums.getProduced() - sums.getInjected())/1000000 * price.getPrice();
|
||||||
|
totalProduced += sums.getProduced();
|
||||||
|
totalObtained += sums.getObtained();
|
||||||
|
totalInjected += sums.getInjected();
|
||||||
}
|
}
|
||||||
|
final StringBuilder sb = new StringBuilder();
|
||||||
@PostMapping("/test")
|
sb.append("Erzeugter Strom von der Photovoltaik: " + formatEnergy.format(totalProduced/1000000) + " kWh\n");
|
||||||
Aggregate newAggregate(@RequestBody final Aggregate aggregate) {
|
sb.append("Eingespeister Strom von der Photovoltaik: " + formatEnergy.format(totalInjected/1000000) + " kWh\n");
|
||||||
return aggregateRep.save(aggregate);
|
sb.append("Genutzter Strom von der Photovoltaik: " + formatEnergy.format((totalProduced-totalInjected)/1000000) + " kWh (=");
|
||||||
|
sb.append(formatPercent.format((float)(totalProduced-totalInjected)/(float)totalProduced*100) + " %)\n");
|
||||||
|
sb.append("Bezogener Strom: " + formatEnergy.format(totalObtained/1000000) + " kWh\n");
|
||||||
|
sb.append("Autakie: " + formatPercent.format((float)(totalProduced-totalInjected)/(float)(totalObtained+totalProduced-totalInjected)*100) + " %\n");
|
||||||
|
sb.append("Eingespartes Geld: " + formatCurrency.format(savedMoney) + "€\n");
|
||||||
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Sums getSums(final long startTimestamp,
|
private Sums getSums(final long startTimestamp,
|
||||||
|
|||||||
81
src/main/java/info/peper/vz/rest/bo/db/House.java
Normal file
81
src/main/java/info/peper/vz/rest/bo/db/House.java
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
package info.peper.vz.rest.bo.db;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.IdClass;
|
||||||
|
|
||||||
|
@Entity(name = "tobias_house")
|
||||||
|
@IdClass(House.CompositeKey.class)
|
||||||
|
public class House {
|
||||||
|
public static class CompositeKey implements Serializable {
|
||||||
|
private static final long serialVersionUID = 3097284483123288289L;
|
||||||
|
private int houseId;
|
||||||
|
private int type;
|
||||||
|
private int channelId;
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(channelId, houseId, type);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
CompositeKey other = (CompositeKey) obj;
|
||||||
|
return channelId == other.channelId && houseId == other.houseId && type == other.type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
House() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public House(int houseId, int type, int channelId) {
|
||||||
|
super();
|
||||||
|
this.houseId = houseId;
|
||||||
|
this.type = type;
|
||||||
|
this.channelId = channelId;
|
||||||
|
}
|
||||||
|
@Id
|
||||||
|
@Column(name="house_id")
|
||||||
|
private int houseId;
|
||||||
|
@Id
|
||||||
|
@Column(name="type")
|
||||||
|
private int type;
|
||||||
|
@Id
|
||||||
|
@Column(name="channel_id")
|
||||||
|
private int channelId;
|
||||||
|
|
||||||
|
public int getHouseId() {
|
||||||
|
return houseId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHouseId(int houseId) {
|
||||||
|
this.houseId = houseId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(int type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getChannelId() {
|
||||||
|
return channelId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChannelId(int channelId) {
|
||||||
|
this.channelId = channelId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user