use of io.openems.backend.metadata.api.Edge in project openems by OpenEMS.
the class EdgeWebsocketServer method timedata.
private void timedata(int[] edgeIds, JsonObject jTimedata) {
for (int edgeId : edgeIds) {
Edge edge;
try {
edge = this.parent.metadataService.getEdge(edgeId);
} catch (OpenemsException e) {
log.warn(e.getMessage());
continue;
}
/*
* write data to timedataService
*/
try {
this.parent.timedataService.write(edgeId, jTimedata);
log.debug("Edge [" + edge.getName() + "] wrote " + jTimedata.entrySet().size() + " timestamps " + StringUtils.toShortString(jTimedata, 120));
} catch (Exception e) {
log.error("Unable to write Timedata: " + e.getClass().getSimpleName() + ": " + e.getMessage());
}
for (Entry<String, JsonElement> jTimedataEntry : jTimedata.entrySet()) {
try {
JsonObject jChannels = JsonUtils.getAsJsonObject(jTimedataEntry.getValue());
// set Odoo last update timestamp only for those channels
for (String channel : jChannels.keySet()) {
if (channel.endsWith("ActivePower") || channel.endsWith("ActivePowerL1") | channel.endsWith("ActivePowerL2") | channel.endsWith("ActivePowerL3") | channel.endsWith("Soc")) {
edge.setLastUpdate();
}
}
// set specific Odoo values
if (jChannels.has("ess0/Soc")) {
int soc = JsonUtils.getAsPrimitive(jChannels, "ess0/Soc").getAsInt();
edge.setSoc(soc);
}
if (jChannels.has("system0/PrimaryIpAddress")) {
String ipv4 = JsonUtils.getAsPrimitive(jChannels, "system0/PrimaryIpAddress").getAsString();
edge.setIpv4(ipv4);
}
} catch (OpenemsException e) {
log.error("Edgde [" + edge.getName() + "] error: " + e.getMessage());
}
}
}
}
use of io.openems.backend.metadata.api.Edge in project openems by OpenEMS.
the class EdgeWebsocketServer method _onOpen.
/**
* Open event of websocket. Parses the "apikey" and to authenticate Edge.
*/
@Override
protected void _onOpen(WebSocket websocket, ClientHandshake handshake) {
String apikey = "";
try {
// get apikey from handshake
Optional<String> apikeyOpt = Utils.parseApikeyFromHandshake(handshake);
if (!apikeyOpt.isPresent()) {
throw new OpenemsException("Apikey is missing in handshake");
}
apikey = apikeyOpt.get();
// get edgeId for apikey
int[] edgeIds = this.parent.metadataService.getEdgeIdsForApikey(apikey);
// if existing: close existing websocket for this apikey
synchronized (this.websocketsMap) {
for (int edgeId : edgeIds) {
if (this.websocketsMap.containsKey(edgeId)) {
WebSocket oldWebsocket = this.websocketsMap.get(edgeId);
oldWebsocket.closeConnection(CloseFrame.REFUSE, "Another Edge with this apikey [" + apikey + "] connected.");
}
// add websocket to local cache
this.websocketsMap.put(edgeId, websocket);
}
}
// store edgeIds together with WebSocket
websocket.setAttachment(edgeIds);
// send successful reply to openems
JsonObject jReply = DefaultMessages.openemsConnectionSuccessfulReply();
WebSocketUtils.send(websocket, jReply);
// announce Edge as online
for (int edgeId : edgeIds) {
Map<String, Object> properties = new HashMap<>();
properties.put(BackendEventConstants.PROPERTY_KEY_EDGE_ID, edgeId);
Event event = new Event(BackendEventConstants.TOPIC_EDGE_ONLINE, properties);
this.parent.eventAdmin.postEvent(event);
}
// log
for (int edgeId : edgeIds) {
Optional<Edge> edgeOpt = this.parent.metadataService.getEdgeOpt(edgeId);
if (edgeOpt.isPresent()) {
Edge edge = edgeOpt.get();
log.info(//
"Edge [" + edge.getName() + "]" + //
(edgeIds.length > 1 ? ", ID [" + edgeId + "]" : "") + " connected.");
// set last update timestamps in MetadataService
edge.setLastMessage();
} else {
log.info("Edge [ID:" + edgeId + "] connected. Apikey [" + apikey + "]. Websocket [" + websocket + "].");
}
}
} catch (OpenemsException e) {
// send connection failed to OpenEMS
JsonObject jReply = DefaultMessages.openemsConnectionFailedReply(e.getMessage());
WebSocketUtils.sendOrLogError(websocket, jReply);
// close websocket
websocket.closeConnection(CloseFrame.REFUSE, "Connection to backend failed. Apikey [" + apikey + "]. Error: " + e.getMessage());
}
}
use of io.openems.backend.metadata.api.Edge in project openems by OpenEMS.
the class Influx method write.
/**
* Takes a JsonObject and writes the points to influxDB.
*
* Format: { "timestamp1" { "channel1": value, "channel2": value }, "timestamp2"
* { "channel1": value, "channel2": value } }
*/
@Override
public void write(int edgeId, JsonObject jData) throws OpenemsException {
Edge edge = this.metadataService.getEdge(edgeId);
int influxId = InfluxdbUtils.parseNumberFromName(edge.getName());
TreeBasedTable<Long, String, Object> data = TreeBasedTable.create();
// get existing or create new DeviceCache
DeviceCache deviceCache = this.deviceCacheMap.get(edgeId);
if (deviceCache == null) {
deviceCache = new DeviceCache();
this.deviceCacheMap.put(edgeId, deviceCache);
}
// Sort incoming data by timestamp
TreeMap<Long, JsonObject> sortedData = new TreeMap<Long, JsonObject>();
for (Entry<String, JsonElement> entry : jData.entrySet()) {
try {
Long timestamp = Long.valueOf(entry.getKey());
JsonObject jChannels;
jChannels = JsonUtils.getAsJsonObject(entry.getValue());
sortedData.put(timestamp, jChannels);
} catch (OpenemsException e) {
log.error("Data error: " + e.getMessage());
}
}
// order)
for (Entry<Long, JsonObject> dataEntry : sortedData.entrySet()) {
Long timestamp = dataEntry.getKey();
JsonObject jChannels = dataEntry.getValue();
if (jChannels.entrySet().size() == 0) {
// no channel values available. abort.
continue;
}
// Check if cache is valid (it is not elder than 5 minutes compared to this
// timestamp)
long cacheTimestamp = deviceCache.getTimestamp();
if (timestamp < cacheTimestamp) {
// incoming data is older than cache -> do not apply cache
} else {
// incoming data is more recent than cache
// update cache timestamp
deviceCache.setTimestamp(timestamp);
if (timestamp < cacheTimestamp + 5 * 60 * 1000) {
// add cache data to write data
for (Entry<String, Object> cacheEntry : deviceCache.getChannelCacheEntries()) {
String channel = cacheEntry.getKey();
Object value = cacheEntry.getValue();
data.put(timestamp, channel, value);
}
} else {
// clear cache
if (cacheTimestamp != 0l) {
log.info("Edge [" + edge.getName() + "]: invalidate cache for influxId [" + influxId + "]. This timestamp [" + timestamp + "]. Cache timestamp [" + cacheTimestamp + "]");
}
deviceCache.clear();
}
// add incoming data to cache (this replaces already existing cache values)
for (Entry<String, JsonElement> channelEntry : jChannels.entrySet()) {
String channel = channelEntry.getKey();
Optional<Object> valueOpt = InfluxdbUtils.parseValue(channel, channelEntry.getValue());
if (valueOpt.isPresent()) {
Object value = valueOpt.get();
deviceCache.putToChannelCache(channel, value);
}
}
}
// add incoming data to write data
for (Entry<String, JsonElement> channelEntry : jChannels.entrySet()) {
String channel = channelEntry.getKey();
Optional<Object> valueOpt = InfluxdbUtils.parseValue(channel, channelEntry.getValue());
if (valueOpt.isPresent()) {
Object value = valueOpt.get();
data.put(timestamp, channel, value);
}
}
}
// Write data to default location
writeData(influxId, data);
// Hook to continue writing data to old Mini monitoring
if (edge.getProducttype().equals("MiniES 3-3")) {
writeDataToOldMiniMonitoring(edge, influxId, data);
}
}
use of io.openems.backend.metadata.api.Edge in project openems by OpenEMS.
the class UiWebsocketServer method _onOpen.
@Override
protected void _onOpen(WebSocket websocket, ClientHandshake handshake) {
User user;
// login using session_id from the cookie
Optional<String> sessionIdOpt = getFieldFromHandshakeCookie(handshake, "session_id");
try {
if (sessionIdOpt.isPresent()) {
// authenticate with Session-ID
user = this.parent.metadataService.authenticate(sessionIdOpt.get());
} else {
// authenticate without Session-ID
user = this.parent.metadataService.authenticate();
}
} catch (OpenemsException e) {
// send connection failed to browser
WebSocketUtils.sendOrLogError(websocket, DefaultMessages.uiLogoutReply());
log.warn("User connection failed. Session [" + sessionIdOpt.orElse("") + "] Error [" + e.getMessage() + "].");
websocket.closeConnection(CloseFrame.REFUSE, e.getMessage());
return;
}
UUID uuid = UUID.randomUUID();
synchronized (this.websocketsMap) {
// add websocket to local cache
this.websocketsMap.put(uuid, websocket);
}
// store userId together with the websocket
websocket.setAttachment(new WebsocketData(user.getId(), uuid));
// send connection successful to browser
JsonArray jEdges = new JsonArray();
for (Entry<Integer, Role> edgeRole : user.getEdgeRoles().entrySet()) {
int edgeId = edgeRole.getKey();
Role role = edgeRole.getValue();
Edge edge;
try {
edge = this.parent.metadataService.getEdge(edgeId);
JsonObject jEdge = edge.toJsonObject();
jEdge.addProperty("role", role.toString());
jEdges.add(jEdge);
} catch (OpenemsException e) {
log.warn("Unable to get Edge from MetadataService [ID:" + edgeId + "]: " + e.getMessage());
}
}
log.info("User [" + user.getName() + "] connected with Session [" + sessionIdOpt.orElse("") + "].");
JsonObject jReply = DefaultMessages.uiLoginSuccessfulReply("", /* empty token? */
jEdges);
WebSocketUtils.sendOrLogError(websocket, jReply);
}
use of io.openems.backend.metadata.api.Edge in project openems by OpenEMS.
the class Influx method queryHistoricData.
@Override
public JsonArray queryHistoricData(Optional<Integer> edgeIdOpt, ZonedDateTime fromDate, ZonedDateTime toDate, JsonObject channels, int resolution) throws OpenemsException {
// if given, query only this id. If not given, do not apply
Optional<Integer> influxIdOpt = Optional.empty();
// filter
if (edgeIdOpt.isPresent()) {
Edge edge = this.metadataService.getEdge(edgeIdOpt.get());
influxIdOpt = Optional.of(InfluxdbUtils.parseNumberFromName(edge.getName()));
}
InfluxDB influxDB = getInfluxDbConnection();
return InfluxdbUtils.queryHistoricData(influxDB, this.database, influxIdOpt, fromDate, toDate, channels, resolution);
}
Aggregations