Skip to content

Commit fc5b833

Browse files
fabianfncsfeilmeier
authored andcommitted
Simple implemention of cumulated values (OpenEMS#369, OpenEMS#91)
1 parent 4b224dc commit fc5b833

File tree

32 files changed

+745
-27
lines changed

32 files changed

+745
-27
lines changed

.project

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<projectDescription>
3+
<name>openems-develop</name>
4+
<comment>Project openems-develop created by Buildship.</comment>
5+
<projects>
6+
</projects>
7+
<buildSpec>
8+
<buildCommand>
9+
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
10+
<arguments>
11+
</arguments>
12+
</buildCommand>
13+
</buildSpec>
14+
<natures>
15+
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
16+
</natures>
17+
</projectDescription>

io.openems.backend.timedata.dummy/src/io/openems/backend/timedata/dummy/TimedataDummy.java

+7
Original file line numberDiff line numberDiff line change
@@ -110,4 +110,11 @@ public TreeBasedTable<ZonedDateTime, ChannelAddress, JsonElement> queryHistoricD
110110
return TreeBasedTable.create();
111111
}
112112

113+
@Override
114+
public Map<ChannelAddress, JsonElement> queryHistoricEnergy(String edgeId, ZonedDateTime fromDate,
115+
ZonedDateTime toDate, Set<ChannelAddress> channels) throws OpenemsNamedException {
116+
this.logWarn(this.log, "I do not support querying historic energy");
117+
return null;
118+
}
119+
113120
}

io.openems.backend.timedata.influx/src/io/openems/backend/timedata/influx/Influx.java

+8
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,14 @@ public TreeBasedTable<ZonedDateTime, ChannelAddress, JsonElement> queryHistoricD
213213
return this.influxConnector.queryHistoricData(influxEdgeId, fromDate, toDate, channels, resolution);
214214
}
215215

216+
@Override
217+
public Map<ChannelAddress, JsonElement> queryHistoricEnergy(String edgeId, ZonedDateTime fromDate,
218+
ZonedDateTime toDate, Set<ChannelAddress> channels) throws OpenemsNamedException {
219+
// parse the numeric EdgeId
220+
Optional<Integer> influxEdgeId = Optional.of(Influx.parseNumberFromName(edgeId));
221+
return this.influxConnector.queryHistoricEnergy(influxEdgeId, fromDate, toDate, channels);
222+
}
223+
216224
/**
217225
* Adds the value in the correct data format for InfluxDB.
218226
*

io.openems.backend.uiwebsocket.impl/src/io/openems/backend/uiwebsocket/impl/OnRequest.java

+28
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.openems.backend.uiwebsocket.impl;
22

33
import java.time.ZonedDateTime;
4+
import java.util.Map;
45
import java.util.Optional;
56
import java.util.UUID;
67
import java.util.concurrent.CompletableFuture;
@@ -24,12 +25,14 @@
2425
import io.openems.common.jsonrpc.request.EdgeRpcRequest;
2526
import io.openems.common.jsonrpc.request.GetEdgeConfigRequest;
2627
import io.openems.common.jsonrpc.request.QueryHistoricTimeseriesDataRequest;
28+
import io.openems.common.jsonrpc.request.QueryHistoricTimeseriesEnergyRequest;
2729
import io.openems.common.jsonrpc.request.SubscribeChannelsRequest;
2830
import io.openems.common.jsonrpc.request.SubscribeSystemLogRequest;
2931
import io.openems.common.jsonrpc.request.UpdateComponentConfigRequest;
3032
import io.openems.common.jsonrpc.response.EdgeRpcResponse;
3133
import io.openems.common.jsonrpc.response.GetEdgeConfigResponse;
3234
import io.openems.common.jsonrpc.response.QueryHistoricTimeseriesDataResponse;
35+
import io.openems.common.jsonrpc.response.QueryHistoricTimeseriesEnergyResponse;
3336
import io.openems.common.session.Role;
3437
import io.openems.common.session.User;
3538
import io.openems.common.types.ChannelAddress;
@@ -117,6 +120,11 @@ private CompletableFuture<JsonrpcResponseSuccess> handleEdgeRpcRequest(WsData ws
117120
QueryHistoricTimeseriesDataRequest.from(request));
118121
break;
119122

123+
case QueryHistoricTimeseriesEnergyRequest.METHOD:
124+
resultFuture = this.handleQueryHistoricEnergyRequest(edgeId, user,
125+
QueryHistoricTimeseriesEnergyRequest.from(request));
126+
break;
127+
120128
case GetEdgeConfigRequest.METHOD:
121129
resultFuture = this.handleGetEdgeConfigRequest(edgeId, user, GetEdgeConfigRequest.from(request));
122130
break;
@@ -213,6 +221,26 @@ private CompletableFuture<JsonrpcResponseSuccess> handleQueryHistoricDataRequest
213221
return CompletableFuture.completedFuture(new QueryHistoricTimeseriesDataResponse(request.getId(), data));
214222
}
215223

224+
/**
225+
* Handles a QueryHistoricEnergyequest.
226+
*
227+
* @param edgeId the Edge-ID
228+
* @param user the User - no specific level required
229+
* @param request the QueryHistoricEnergyRequest
230+
* @return the Future JSON-RPC Response
231+
* @throws OpenemsNamedException on error
232+
*/
233+
private CompletableFuture<JsonrpcResponseSuccess> handleQueryHistoricEnergyRequest(String edgeId, User user,
234+
QueryHistoricTimeseriesEnergyRequest request) throws OpenemsNamedException {
235+
Map<ChannelAddress, JsonElement> data;
236+
data = this.parent.timeData.queryHistoricEnergy(//
237+
edgeId, /* ignore Edge-ID */
238+
request.getFromDate(), request.getToDate(), request.getChannels());
239+
240+
// JSON-RPC response
241+
return CompletableFuture.completedFuture(new QueryHistoricTimeseriesEnergyResponse(request.getId(), data));
242+
}
243+
216244
/**
217245
* Handles a GetEdgeConfigRequest.
218246
*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
package io.openems.common.jsonrpc.request;
2+
3+
import java.time.ZoneId;
4+
import java.time.ZoneOffset;
5+
import java.time.ZonedDateTime;
6+
import java.time.format.DateTimeFormatter;
7+
import java.util.TreeSet;
8+
import java.util.UUID;
9+
10+
import com.google.gson.JsonArray;
11+
import com.google.gson.JsonElement;
12+
import com.google.gson.JsonObject;
13+
14+
import io.openems.common.exceptions.OpenemsError.OpenemsNamedException;
15+
import io.openems.common.exceptions.OpenemsException;
16+
import io.openems.common.jsonrpc.base.GenericJsonrpcRequest;
17+
import io.openems.common.jsonrpc.base.JsonrpcRequest;
18+
import io.openems.common.types.ChannelAddress;
19+
import io.openems.common.utils.JsonUtils;
20+
21+
/**
22+
* Represents a JSON-RPC Request for 'queryHistoricTimeseriesData'.
23+
*
24+
* <pre>
25+
* {
26+
* "jsonrpc": "2.0",
27+
* "id": "UUID",
28+
* "method": "queryHistoricTimeseriesEnergy",
29+
* "params": {
30+
* "timezone": Number,
31+
* "fromDate": YYYY-MM-DD,
32+
* "toDate": YYYY-MM-DD,
33+
* "channels": ChannelAddress[]
34+
* }
35+
* }
36+
* </pre>
37+
*/
38+
39+
public class QueryHistoricTimeseriesEnergyRequest extends JsonrpcRequest {
40+
41+
public final static String METHOD = "queryHistoricTimeseriesEnergy";
42+
43+
private final static DateTimeFormatter FORMAT = DateTimeFormatter.ISO_LOCAL_DATE;
44+
45+
public static QueryHistoricTimeseriesEnergyRequest from(JsonrpcRequest r) throws OpenemsNamedException {
46+
JsonObject p = r.getParams();
47+
int timezoneDiff = JsonUtils.getAsInt(p, "timezone");
48+
ZoneId timezone = ZoneId.ofOffset("", ZoneOffset.ofTotalSeconds(timezoneDiff * -1));
49+
ZonedDateTime fromDate = JsonUtils.getAsZonedDateTime(p, "fromDate", timezone);
50+
ZonedDateTime toDate = JsonUtils.getAsZonedDateTime(p, "toDate", timezone).plusDays(1);
51+
QueryHistoricTimeseriesEnergyRequest result = new QueryHistoricTimeseriesEnergyRequest(r.getId(), fromDate,
52+
toDate);
53+
JsonArray channels = JsonUtils.getAsJsonArray(p, "channels");
54+
for (JsonElement channel : channels) {
55+
ChannelAddress address = ChannelAddress.fromString(JsonUtils.getAsString(channel));
56+
result.addChannel(address);
57+
}
58+
return result;
59+
}
60+
61+
public static QueryHistoricTimeseriesEnergyRequest from(JsonObject j) throws OpenemsNamedException {
62+
return from(GenericJsonrpcRequest.from(j));
63+
}
64+
65+
private final int timezoneDiff;
66+
private final ZonedDateTime fromDate;
67+
private final ZonedDateTime toDate;
68+
private final TreeSet<ChannelAddress> channels = new TreeSet<>();
69+
70+
public QueryHistoricTimeseriesEnergyRequest(UUID id, ZonedDateTime fromDate, ZonedDateTime toDate)
71+
throws OpenemsNamedException {
72+
super(id, METHOD);
73+
74+
this.timezoneDiff = ZoneOffset.from(fromDate).getTotalSeconds();
75+
if (timezoneDiff != ZoneOffset.from(toDate).getTotalSeconds()) {
76+
throw new OpenemsException("FromDate and ToDate need to be in the same timezone!");
77+
}
78+
79+
this.fromDate = fromDate;
80+
this.toDate = toDate;
81+
}
82+
83+
public QueryHistoricTimeseriesEnergyRequest(ZonedDateTime fromDate, ZonedDateTime toDate)
84+
throws OpenemsNamedException {
85+
this(UUID.randomUUID(), fromDate, toDate);
86+
}
87+
88+
private void addChannel(ChannelAddress address) {
89+
this.channels.add(address);
90+
}
91+
92+
@Override
93+
public JsonObject getParams() {
94+
JsonArray channels = new JsonArray();
95+
for (ChannelAddress address : this.channels) {
96+
channels.add(address.toString());
97+
}
98+
return JsonUtils.buildJsonObject().addProperty("timezone", this.timezoneDiff) //
99+
.addProperty("fromDate", FORMAT.format(this.fromDate)) //
100+
.addProperty("toDate", FORMAT.format(this.toDate)) //
101+
.add("channels", channels) //
102+
.build();
103+
}
104+
105+
public ZonedDateTime getFromDate() {
106+
return fromDate;
107+
}
108+
109+
public ZonedDateTime getToDate() {
110+
return toDate;
111+
}
112+
113+
public TreeSet<ChannelAddress> getChannels() {
114+
return channels;
115+
}
116+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package io.openems.common.jsonrpc.response;
2+
3+
import java.util.Map;
4+
import java.util.Map.Entry;
5+
import java.util.UUID;
6+
7+
import com.google.gson.JsonElement;
8+
import com.google.gson.JsonObject;
9+
10+
import io.openems.common.jsonrpc.base.JsonrpcResponseSuccess;
11+
import io.openems.common.types.ChannelAddress;
12+
13+
/**
14+
* Represents a JSON-RPC Response for 'queryHistoricTimeseriesEnergy'.
15+
*
16+
* <pre>
17+
* {
18+
* "jsonrpc": "2.0",
19+
* "id": "UUID",
20+
* "result": {
21+
* "data": {
22+
* [channelAddress]: number | null
23+
* }
24+
* }
25+
* }
26+
* </pre>
27+
*/
28+
29+
public class QueryHistoricTimeseriesEnergyResponse extends JsonrpcResponseSuccess {
30+
31+
public static class EdgeInfo {
32+
protected final boolean online;
33+
34+
public EdgeInfo(boolean online) {
35+
this.online = online;
36+
}
37+
}
38+
39+
private final Map<ChannelAddress, JsonElement> data;
40+
41+
public QueryHistoricTimeseriesEnergyResponse(Map<ChannelAddress, JsonElement> data) {
42+
this(UUID.randomUUID(), data);
43+
}
44+
45+
public QueryHistoricTimeseriesEnergyResponse(UUID id, Map<ChannelAddress, JsonElement> data) {
46+
super(id);
47+
this.data = data;
48+
}
49+
50+
@Override
51+
public JsonObject getResult() {
52+
JsonObject result = new JsonObject();
53+
JsonObject p = new JsonObject();
54+
55+
for (Entry<ChannelAddress, JsonElement> entry : data.entrySet()) {
56+
p.add(entry.getKey().toString(), entry.getValue());
57+
}
58+
result.add("data", p);
59+
60+
return result;
61+
}
62+
}

io.openems.common/src/io/openems/common/timedata/CommonTimedataService.java

+13
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.time.Period;
44
import java.time.ZonedDateTime;
5+
import java.util.Map;
56
import java.util.Set;
67

78
import com.google.common.collect.TreeBasedTable;
@@ -46,8 +47,20 @@ public default TreeBasedTable<ZonedDateTime, ChannelAddress, JsonElement> queryH
4647
* @param channels the Channels
4748
* @param resolution the Resolution in seconds
4849
*/
50+
4951
public TreeBasedTable<ZonedDateTime, ChannelAddress, JsonElement> queryHistoricData(String edgeId,
5052
ZonedDateTime fromDate, ZonedDateTime toDate, Set<ChannelAddress> channels, int resolution)
5153
throws OpenemsNamedException;
5254

55+
/**
56+
* Queries historic energy.
57+
*
58+
* @param edgeId the Edge-ID; or null query all
59+
* @param fromDate the From-Date
60+
* @param toDate the To-Date
61+
* @param channels the Channels
62+
*/
63+
64+
public Map<ChannelAddress, JsonElement> queryHistoricEnergy(String edgeId, ZonedDateTime fromDate,
65+
ZonedDateTime toDate, Set<ChannelAddress> channels) throws OpenemsNamedException;
5366
}

io.openems.edge.controller.api.websocket/src/io/openems/edge/controller/api/websocket/OnRequest.java

+26-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.openems.edge.controller.api.websocket;
22

33
import java.time.ZonedDateTime;
4+
import java.util.Map;
45
import java.util.Optional;
56
import java.util.UUID;
67
import java.util.concurrent.CompletableFuture;
@@ -25,12 +26,14 @@
2526
import io.openems.common.jsonrpc.request.EdgeRpcRequest;
2627
import io.openems.common.jsonrpc.request.GetEdgeConfigRequest;
2728
import io.openems.common.jsonrpc.request.QueryHistoricTimeseriesDataRequest;
29+
import io.openems.common.jsonrpc.request.QueryHistoricTimeseriesEnergyRequest;
2830
import io.openems.common.jsonrpc.request.SubscribeChannelsRequest;
2931
import io.openems.common.jsonrpc.request.SubscribeSystemLogRequest;
3032
import io.openems.common.jsonrpc.request.UpdateComponentConfigRequest;
3133
import io.openems.common.jsonrpc.response.AuthenticateWithPasswordResponse;
3234
import io.openems.common.jsonrpc.response.EdgeRpcResponse;
3335
import io.openems.common.jsonrpc.response.QueryHistoricTimeseriesDataResponse;
36+
import io.openems.common.jsonrpc.response.QueryHistoricTimeseriesEnergyResponse;
3437
import io.openems.common.session.Role;
3538
import io.openems.common.types.ChannelAddress;
3639
import io.openems.common.websocket.SubscribedChannelsWorker;
@@ -101,6 +104,10 @@ private CompletableFuture<JsonrpcResponseSuccess> handleEdgeRpcRequest(WsData ws
101104
resultFuture = this.handleQueryHistoricDataRequest(user, QueryHistoricTimeseriesDataRequest.from(request));
102105
break;
103106

107+
case QueryHistoricTimeseriesEnergyRequest.METHOD:
108+
resultFuture = this.handleQueryHistoricEnergyRequest(QueryHistoricTimeseriesEnergyRequest.from(request));
109+
break;
110+
104111
case UpdateComponentConfigRequest.METHOD:
105112
resultFuture = this.handleUpdateComponentConfigRequest(user, UpdateComponentConfigRequest.from(request));
106113
break;
@@ -189,9 +196,8 @@ private CompletableFuture<JsonrpcResponseSuccess> handleSubscribeChannelsRequest
189196
*/
190197
private CompletableFuture<JsonrpcResponseSuccess> handleQueryHistoricDataRequest(EdgeUser user,
191198
QueryHistoricTimeseriesDataRequest request) throws OpenemsNamedException {
192-
TreeBasedTable<ZonedDateTime, ChannelAddress, JsonElement> data;
193-
data = this.parent.timedata.queryHistoricData(//
194-
null, /* igore Edge-ID */
199+
TreeBasedTable<ZonedDateTime, ChannelAddress, JsonElement> data = this.parent.getTimedata().queryHistoricData(//
200+
null, /* ignore Edge-ID */
195201
request.getFromDate(), //
196202
request.getToDate(), //
197203
request.getChannels());
@@ -200,6 +206,23 @@ private CompletableFuture<JsonrpcResponseSuccess> handleQueryHistoricDataRequest
200206
return CompletableFuture.completedFuture(new QueryHistoricTimeseriesDataResponse(request.getId(), data));
201207
}
202208

209+
/**
210+
* Handles a QueryHistoricEnergyRequest.
211+
*
212+
* @param request the QueryHistoricEnergyRequest
213+
* @return the Future JSPN-RPC Response
214+
* @throws OpenemsNamedException on error
215+
*/
216+
private CompletableFuture<JsonrpcResponseSuccess> handleQueryHistoricEnergyRequest(
217+
QueryHistoricTimeseriesEnergyRequest request) throws OpenemsNamedException {
218+
Map<ChannelAddress, JsonElement> data = this.parent.getTimedata().queryHistoricEnergy(//
219+
null, /* ignore Edge-ID */
220+
request.getFromDate(), request.getToDate(), request.getChannels());
221+
222+
// JSON-RPC response
223+
return CompletableFuture.completedFuture(new QueryHistoricTimeseriesEnergyResponse(request.getId(), data));
224+
}
225+
203226
/**
204227
* Handles a UpdateComponentConfigRequest.
205228
*

0 commit comments

Comments
 (0)