Commit f784b190 authored by Jan Mayer's avatar Jan Mayer
Browse files

adaption to datamodel

parent 91d0076d
......@@ -31,14 +31,13 @@ public class ClientCoupler extends Coupler {
NetworkType primaryNetwork;
NetworkType secondaryNetwork;
double opCost;
public Double opCostFC[] = new Double[topologyConfig.getNrStepsMPC()];;
double costCO2;
public double[] costCO2Array = new double[topologyConfig.getNrStepsMPC()];
public BasicClient client;
public NodeId setpointId;
public NodeId setpointsId;
public List<UaMonitoredItem> itemsCost;
......@@ -63,10 +62,8 @@ public class ClientCoupler extends Coupler {
NodeId maxPowerId,
NodeId effHeatId,
NodeId effElecId,
NodeId opCostId,
NodeId priceFCId,
NodeId costCO2Id,
NodeId setpointsId,
NodeId setpointId,
int port)
throws InterruptedException, ExecutionException {
......@@ -75,18 +72,12 @@ public class ClientCoupler extends Coupler {
this.client = client;
this.setpointId = setpointId;
this.setpointsId = setpointsId;
this.primaryNetwork = this.setNetworkType(client, nodeIdPrimSector);
this.secondaryNetwork = this.setNetworkType(client, nodeIdSecSector);
if (client.readValue(Integer.MAX_VALUE, TimestampsToReturn.Neither, costCO2Id).getValue().getValue().getClass().isArray()) {
this.costCO2Array = client.readFinalDoubleArrayValue(costCO2Id);
this.costCO2 = costCO2Array[0];
} else {
this.costCO2 = client.readFinalDoubleValue(costCO2Id);
Arrays.fill(costCO2Array, costCO2);
}
// ========= Subscription ==============
// * Price (if not static)
// subscription if array with price forecast is available at the EMS
if (client.readValue(Integer.MAX_VALUE, TimestampsToReturn.Neither, priceFCId).getValue().getValue().getClass().isArray()) {
......@@ -140,11 +131,8 @@ public class ClientCoupler extends Coupler {
e.printStackTrace();
}
this.opCost = opCostFC[0];
} else {
this.opCost = client.readFinalDoubleValue(priceFCId);
Arrays.fill(opCostFC, opCost);
Arrays.fill(opCostFC, client.readFinalDoubleValue(priceFCId));
}
}
......@@ -156,10 +144,9 @@ public class ClientCoupler extends Coupler {
couplerMessage.id = fullActorPath;
couplerMessage.primaryNetwork = primaryNetwork;
couplerMessage.secondaryNetwork = secondaryNetwork;
couplerMessage.operationalCostEUR = opCost;
// provide monetary costs both as scalar and as Array
couplerMessage.operationalCostEUR = opCostFC[0];
couplerMessage.varOperationalCostEUR = Stream.of(opCostFC).mapToDouble(Double::doubleValue).toArray();
// System.out.println("varopCosts-Length = " + couplerMessage.varOperationalCostEUR.length);
// TODO: once experienced strange bug for cm.varOperationalCostEUR: "Index 4 out of bounds for length 4", although mpc was 5?!
couplerMessage.operationalCostCO2 = costCO2;
couplerMessage.efficiencyElec = efficiencyElec;
couplerMessage.efficiencyHeat = efficiencyHeat;
......@@ -183,26 +170,22 @@ public class ClientCoupler extends Coupler {
{
optimizationAdvice = optResult.resultMap.get(key);
// Write scalar setpoint to EMS (single value)
DataValue singlevalueSetpoint = new DataValue(new Variant(optimizationAdvice[0]), null, null);
client.writeValue(setpointId, singlevalueSetpoint);
// If available: write setpoint array to EMS (length = mpc)
try {
if (client.readValue(Integer.MAX_VALUE, TimestampsToReturn.Neither, setpointsId).getValue().getValue().getClass().isArray()) {
try { // If setpoint-Node is an Array, write whole solution vector
if ((this.setpointId != null) && (client.readValue(Integer.MAX_VALUE, TimestampsToReturn.Neither, setpointId).getValue().getValue().getClass().isArray())) {
DataValue data = new DataValue(new Variant(optimizationAdvice), null, null);
client.writeValue(setpointsId, data);
client.writeValue(setpointId, data);
} else { // Standard case: Write setpoint to EMS as single value
DataValue singlevalueSetpoint = new DataValue(new Variant(optimizationAdvice[0]), null, null);
client.writeValue(setpointId, singlevalueSetpoint);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
......
......@@ -9,7 +9,6 @@ import java.util.concurrent.ExecutionException;
import java.util.function.BiConsumer;
import java.util.stream.Stream;
import org.apache.commons.lang3.ArrayUtils;
import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaMonitoredItem;
import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaSubscription;
import org.eclipse.milo.opcua.stack.core.AttributeId;
......@@ -37,18 +36,20 @@ public class ClientDemand extends Consumer implements CurrentTimeStepSubscriber
private int currentTimeStep;
public BasicClient client;
public NodeId nodeId;
public NodeId setpointsGridBuyId;
public NodeId setpointGridBuyId;
public NodeId setpointsGridSellId;
public NodeId setpointGridSellId;
double buyPrice;
double sellPrice;
double costCO2;
double maxBuylimit;
/** Consumption profile values */
public Double consumptionProfile[];
public Double networkBuyCostFC[] = new Double[topologyConfig.getNrStepsMPC()];
public Double networkSellCostFC[] = new Double[topologyConfig.getNrStepsMPC()];
public Double networkCO2CostFC[] = new Double[topologyConfig.getNrStepsMPC()];
public Double varNetworkBuyCap[] = new Double[topologyConfig.getNrStepsMPC()];
public double[] optimizationAdviceBuy;
public double[] optimizationAdviceSell;
......@@ -56,6 +57,7 @@ public class ClientDemand extends Consumer implements CurrentTimeStepSubscriber
public List<UaMonitoredItem> itemsDemand;
boolean priceIsArray = false;
boolean maxBuyArray = false;
/**
......@@ -71,46 +73,59 @@ public class ClientDemand extends Consumer implements CurrentTimeStepSubscriber
public ClientDemand(BasicClient client,
String name,
NodeId nodeIdSector,
NodeId nodeIdConsumption,
NodeId arrayDemandForecastId,
NodeId buyPriceId,
NodeId sellPriceId,
NodeId setpointsGridBuyId,
NodeId costCO2FCId,
NodeId maxBuyLimitId,
NodeId setpointGridBuyId,
NodeId setpointsGridSellId,
NodeId setpointGridSellId,
int port) {
int port) throws InterruptedException, ExecutionException {
super(name, port);
this.client = client;
this.setpointsGridBuyId = setpointsGridBuyId;
this.setpointGridBuyId = setpointGridBuyId;
this.setpointsGridSellId = setpointsGridSellId;
this.setpointGridSellId = setpointGridSellId;
this.networkType = setNetworkType(client, nodeIdSector);
// Read optional Nodes
if ((costCO2FCId != null) && (this.networkType == NetworkType.ELECTRICITY)){
this.costCO2 = client.readFinalDoubleValue(costCO2FCId);
} else this.costCO2 = 0.474; // default 0.474 g/kWh
System.out.println(" . grid emission factor is set to " + this.costCO2 + " kg/kWh.");
Arrays.fill(networkCO2CostFC, costCO2);
networkType = setNetworkType(client, nodeIdSector);
// nodeIdConsumption (= current demand) is not needed at the moment
// (because it is assumed that forecast is perfect).
if ((maxBuyLimitId != null) && (this.networkType == NetworkType.ELECTRICITY)){
if (!client.readValue(Integer.MAX_VALUE, TimestampsToReturn.Neither, maxBuyLimitId)
.getValue().getValue().getClass().isArray()) {
this.maxBuylimit = client.readFinalDoubleValue(maxBuyLimitId);
System.out.println(" . max. power from grid set to " + this.maxBuylimit + " kW.");
} else if (client.readValue(Integer.MAX_VALUE, TimestampsToReturn.Neither, maxBuyLimitId)
.getValue().getValue().getClass().isArray()) {
this.maxBuyArray = true; // subscription is necessary
}
} else this.maxBuylimit = 9999.0;
Arrays.fill(varNetworkBuyCap, maxBuylimit);
// ========= Subscription ==============
// * BuyPrice (if not static)
// * SellPrice (if not static)
// * maxBuylimit (if not static) - To be implemented if maxBuylimit == True
// monitoring parameters
int clientHandle = 1543453; // just random numbers
// TODO: Improve integration of OPC UA Subscriptions of multiple variables
try {
if ((client.readValue(Integer.MAX_VALUE, TimestampsToReturn.Neither, buyPriceId).getValue().getValue().getClass().isArray())
&& (client.readValue(Integer.MAX_VALUE, TimestampsToReturn.Neither, sellPriceId).getValue().getValue().getClass().isArray())) {
priceIsArray = true;
System.out.println(" . Price for network " + this.networkType + " is an Array.");
}
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (ExecutionException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
if ((client.readValue(Integer.MAX_VALUE, TimestampsToReturn.Neither, buyPriceId).getValue().getValue().getClass().isArray())
&& (client.readValue(Integer.MAX_VALUE, TimestampsToReturn.Neither, sellPriceId).getValue().getValue().getClass().isArray())) {
priceIsArray = true;
System.out.println(" . Price for network " + this.networkType + " is an Array.");
}
if (priceIsArray) {
Arrays.fill(networkBuyCostFC, 0.0);
......@@ -141,17 +156,10 @@ public class ClientDemand extends Consumer implements CurrentTimeStepSubscriber
.setValueConsumer(buyPriceFC);
// creating the subscriptions
UaSubscription subscriptionBuyPrice;
try {
subscriptionBuyPrice = client.getSubscriptionManager().createSubscription(1000.0).get();
itemsDemand = subscriptionBuyPrice
.createMonitoredItems(TimestampsToReturn.Both, Arrays.asList(requestBuyPrice), onItemCreatedBuyPrice).get();
UaSubscription subscriptionBuyPrice = client.getSubscriptionManager().createSubscription(1000.0).get();
itemsDemand = subscriptionBuyPrice
.createMonitoredItems(TimestampsToReturn.Both, Arrays.asList(requestBuyPrice), onItemCreatedBuyPrice).get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
this.buyPrice = networkBuyCostFC[0];
// networkBuyCostFC
......@@ -185,41 +193,24 @@ public class ClientDemand extends Consumer implements CurrentTimeStepSubscriber
.setValueConsumer(sellPriceFC);
// creating the subscriptions
UaSubscription subscriptionSellPrice;
try {
subscriptionSellPrice = client.getSubscriptionManager().createSubscription(1000.0).get();
UaSubscription subscriptionSellPrice = client.getSubscriptionManager().createSubscription(1000.0).get();
itemsDemand = subscriptionSellPrice
.createMonitoredItems(TimestampsToReturn.Both, Arrays.asList(requestSellPrice), onItemCreatedSellPrice).get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
this.sellPrice = networkSellCostFC[0];
} else {
System.out.println(" . Price for network " + this.networkType + " is single value.");
try {
buyPrice = client.readFinalDoubleValue(buyPriceId);
sellPrice = client.readFinalDoubleValue(sellPriceId);
} catch (InterruptedException e) {
System.out.println(" . ERR: Cannot read buyprice or sellprice from Node " + buyPriceId.toString() + ", " + sellPriceId.toString());
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// System.out.println("prices are " + buyPrice + ", " + sellPrice);
buyPrice = client.readFinalDoubleValue(buyPriceId);
sellPrice = client.readFinalDoubleValue(sellPriceId);
Arrays.fill(networkBuyCostFC, buyPrice);
Arrays.fill(networkSellCostFC, sellPrice);
}
// Subscription for Demand
consumptionProfile = new Double[topologyConfig.getNrStepsMPC()];
Arrays.fill(consumptionProfile, 0.0);
......@@ -249,18 +240,9 @@ public class ClientDemand extends Consumer implements CurrentTimeStepSubscriber
.setValueConsumer(demand);
// creating the subscriptions
UaSubscription subscriptionDemand;
try {
subscriptionDemand = client.getSubscriptionManager().createSubscription(1000.0).get();
UaSubscription subscriptionDemand = client.getSubscriptionManager().createSubscription(1000.0).get();
itemsDemand = subscriptionDemand
.createMonitoredItems(TimestampsToReturn.Both, Arrays.asList(requestDemand), onItemCreatedDemand).get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
......@@ -293,9 +275,11 @@ public class ClientDemand extends Consumer implements CurrentTimeStepSubscriber
demandMessage.setDemandVector(demandVectorB);
demandMessage.forecastType = "Profile";
demandMessage.networkType = networkType;
demandMessage.varNetworkBuyCostEUR = ArrayUtils.toPrimitive(networkBuyCostFC);
// = Stream.of(networkBuyCostFC).mapToDouble(Double::doubleValue).toArray();
demandMessage.varNetworkBuyCostEUR = Stream.of(networkBuyCostFC).mapToDouble(Double::doubleValue).toArray();
demandMessage.varNetworkSellCostEUR = Stream.of(networkSellCostFC).mapToDouble(Double::doubleValue).toArray();
// Optional Datapotins
demandMessage.varNetworkCostCO2 = Stream.of(networkSellCostFC).mapToDouble(Double::doubleValue).toArray();
demandMessage.varNetworkBuyCap = Stream.of(varNetworkBuyCap).mapToDouble(Double::doubleValue).toArray();
super.updateDisplay(demandMessage);
}
......@@ -306,25 +290,30 @@ public class ClientDemand extends Consumer implements CurrentTimeStepSubscriber
for (String key : optResult.resultMap.keySet()) {
if ((key.equals("ElecBuy")) && (this.networkType == NetworkType.ELECTRICITY)) {
optimizationAdviceBuy = optResult.resultMap.get(key);
DataValue singlevalueBuySetpoint = new DataValue(new Variant(optimizationAdviceBuy[0]), null, null);
client.writeValue(setpointGridBuyId, singlevalueBuySetpoint);
try {
if (client.readValue(Integer.MAX_VALUE, TimestampsToReturn.Neither, setpointsGridBuyId).getValue().getValue().getClass().isArray()) {
if (client.readValue(Integer.MAX_VALUE, TimestampsToReturn.Neither, setpointGridBuyId).getValue().getValue().getClass().isArray()) {
DataValue data = new DataValue(new Variant(optimizationAdviceBuy), null, null);
client.writeValue(setpointsGridBuyId, data);
client.writeValue(setpointGridBuyId, data);
} else {
DataValue singlevalueBuySetpoint = new DataValue(new Variant(optimizationAdviceBuy[0]), null, null);
client.writeValue(setpointGridBuyId, singlevalueBuySetpoint);
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
if ((key.equals("ElecSell")) && (this.networkType == NetworkType.ELECTRICITY)) {
optimizationAdviceSell = optResult.resultMap.get(key);
DataValue singlevalueSellSetpoint = new DataValue(new Variant(optimizationAdviceSell[0]), null, null);
client.writeValue(setpointGridSellId, singlevalueSellSetpoint);
try {
if (client.readValue(Integer.MAX_VALUE, TimestampsToReturn.Neither, setpointsGridSellId).getValue().getValue().getClass().isArray()) {
if (client.readValue(Integer.MAX_VALUE, TimestampsToReturn.Neither, setpointGridSellId).getValue().getValue().getClass().isArray()) {
DataValue data = new DataValue(new Variant(optimizationAdviceSell), null, null);
client.writeValue(setpointsGridSellId, data);
client.writeValue(setpointGridSellId, data);
} else {
DataValue singlevalueSellSetpoint = new DataValue(new Variant(optimizationAdviceSell[0]), null, null);
client.writeValue(setpointGridSellId, singlevalueSellSetpoint);
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
......
......@@ -31,14 +31,12 @@ import memap.messages.extension.NetworkType;
public class ClientProducer extends Producer {
NetworkType networkType;
public double opCost;
public Double opCostFC[];
public Double opCostFC[] = new Double[topologyConfig.getNrStepsMPC()];
public double costCO2;
public double[] costCO2Array = new double[topologyConfig.getNrStepsMPC()];
public BasicClient client;
public NodeId setpointId;
public NodeId setpointsId;
public List<UaMonitoredItem> itemsCost;
......@@ -60,30 +58,21 @@ public class ClientProducer extends Producer {
NodeId minPowerId,
NodeId maxPowerId,
NodeId effId,
NodeId opCostId,
NodeId priceFCId,
NodeId costCO2Id,
NodeId setpointsId,
NodeId costCO2Id,
NodeId setpointId,
int port)
throws InterruptedException, ExecutionException {
super(name, client.readFinalDoubleValue(minPowerId), client.readFinalDoubleValue(maxPowerId),
client.readFinalDoubleValue(effId), port);
// TODO an in superclass device:
this.client = client;
this.setpointId = setpointId;
this.setpointsId = setpointsId;
this.networkType = this.setNetworkType(client, nodeIdSector);
if (client.readValue(Integer.MAX_VALUE, TimestampsToReturn.Neither, costCO2Id).getValue().getValue().getClass().isArray()) {
this.costCO2Array = client.readFinalDoubleArrayValue(costCO2Id);
this.costCO2 = costCO2Array[0];
} else {
this.costCO2 = client.readFinalDoubleValue(costCO2Id);
Arrays.fill(costCO2Array, costCO2);
}
// ========= Subscription ==============
// * Price (if not static)
// subscription if array with price forecast is available at the EMS
if (client.readValue(Integer.MAX_VALUE, TimestampsToReturn.Neither, priceFCId).getValue().getValue().getClass().isArray()) {
......@@ -91,7 +80,6 @@ public class ClientProducer extends Producer {
System.out.println(" . Producer price is forecast array.");
// Subscription to variable primary energy costs
opCostFC = new Double[topologyConfig.getNrStepsMPC()];
Arrays.fill(opCostFC, 0.0);
// subscribe to the Value attribute of the server's CurrentTime node
......@@ -137,12 +125,9 @@ public class ClientProducer extends Producer {
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
this.opCost = opCostFC[0];
} else {
this.opCost = client.readFinalDoubleValue(opCostId);
Arrays.fill(this.opCostFC, opCost);
Arrays.fill(this.opCostFC, client.readFinalDoubleValue(priceFCId));
}
}
......@@ -152,7 +137,8 @@ public class ClientProducer extends Producer {
producerMessage.name = actorName;
producerMessage.minPower = minPower;
producerMessage.maxPower = maxPower;
producerMessage.operationalCostEUR = opCost;
// provide monetary costs both as scalar and as Array
producerMessage.operationalCostEUR = opCostFC[0];
producerMessage.varOperationalCostEUR = Stream.of(opCostFC).mapToDouble(Double::doubleValue).toArray();
producerMessage.operationalCostCO2 = costCO2;
producerMessage.efficiency = efficiency;
......@@ -171,28 +157,19 @@ public class ClientProducer extends Producer {
for (String key : optResult.resultMap.keySet()) {
if (key.equals(actorName + "_withEfficiency")) {
optimizationAdvice = optResult.resultMap.get(key);
// Write scalar setpoint to EMS (single value)
DataValue singlevalueSetpoint = new DataValue(new Variant(optimizationAdvice[0]), null, null);
client.writeValue(setpointId, singlevalueSetpoint);
// If available: write setpoint array to EMS (length = mpc)
try {
if (client.readValue(Integer.MAX_VALUE, TimestampsToReturn.Neither, setpointsId).getValue().getValue().getClass().isArray()) {
try { // If setpoint-Node is an Array, write whole solution vector
if (client.readValue(Integer.MAX_VALUE, TimestampsToReturn.Neither, setpointId).getValue().getValue().getClass().isArray()) {
DataValue data = new DataValue(new Variant(optimizationAdvice), null, null);
client.writeValue(setpointsId, data);
client.writeValue(setpointId, data);
} else { // Standard case: Write setpoint to EMS as single value
DataValue singlevalueSetpoint = new DataValue(new Variant(optimizationAdvice[0]), null, null);
client.writeValue(setpointId, singlevalueSetpoint);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
}
}
}
......
......@@ -33,11 +33,8 @@ public class ClientStorage extends Storage {
double costCO2;
double minimumSoc;
public BasicClient client;
public NodeId calculatedSocId;
public NodeId inputSetpointId;
public NodeId inputSetpointsId;
public NodeId outputSetpointId;
public NodeId outputSetpointsId;
public List<UaMonitoredItem> itemsDemand;
......@@ -58,8 +55,7 @@ public class ClientStorage extends Storage {
BasicClient client,
String name,
NodeId capacityId,
NodeId stateOfCharge,
NodeId calculatedSocId,
NodeId stateOfCharge,
NodeId minimumSocId,
NodeId maxChargingId,
NodeId maxDischargingId,
......@@ -69,8 +65,6 @@ public class ClientStorage extends Storage {
NodeId nodeIdSector,
NodeId opCostId,
NodeId costCO2Id,
NodeId inputSetpointsId,
NodeId outputSetpointsId,
NodeId inputSetpointId,
NodeId outputSetpointId,
int port) throws InterruptedException, ExecutionException {
......@@ -84,20 +78,22 @@ public class ClientStorage extends Storage {
client.readFinalDoubleValue(storageLossId),
port);
this.client = client;
// setpoints as scalar and array
this.inputSetpointId = inputSetpointId;
this.inputSetpointsId = inputSetpointsId;
this.outputSetpointId = outputSetpointId;
this.outputSetpointsId = outputSetpointsId;
this.networkType = setNetworkType(client, nodeIdSector);
this.opCost = client.readFinalDoubleValue(opCostId);
this.costCO2 = client.readFinalDoubleValue(costCO2Id);
this.calculatedSocId = calculatedSocId;
if (minimumSocId != null) this.minimumSoc = client.readFinalDoubleValue(minimumSocId);
// System.out.println("Initial SOC = " + this.stateOfCharge);
// Read optional Nodes
if (minimumSocId != null) {
this.minimumSoc = client.readFinalDoubleValue(minimumSocId);
System.out.println(" . a mimumum SOC is set to " + this.minimumSoc*100 + "%.");
} else this.minimumSoc = 0;
// ========= Subscription ==============
// * State Of Charge
// subscribe to the Value attribute of the server's CurrentTime node
ReadValueId readValueIdConsumption = new ReadValueId(stateOfCharge, AttributeId.Value.uid(), null,
......@@ -119,9 +115,8 @@ public class ClientStorage extends Storage {
Variant var = value.getValue();
if (var.getValue() instanceof Number) {
this.stateOfCharge = (Double) value.getValue().getValue();
// System.out.println("SOC updated");
} else {
System.out.println("Value " + value + " is not in Number[] format");
System.out.println(" . ERR: Value " + value + " is not in Number[] format");
}
};
......@@ -168,12 +163,15 @@ public class ClientStorage extends Storage {
for (String key : optResult.resultMap.keySet()) {
if (key.equals(actorName + "_Charge")) {
optimizationAdviceInput = optResult.resultMap.get(key);
DataValue singlevalueInputSetpoint = new DataValue(new Variant(optimizationAdviceInput[0]), null, null);
client.writeValue(inputSetpointId, singlevalueInputSetpoint);
try {
if (client.readValue(Integer.MAX_VALUE, TimestampsToReturn.Neither, inputSetpointsId).getValue().getValue().getClass().isArray()) {
try { // If setpoint-Node is an Array, write whole solution vector
if ((this.inputSetpointId != null) && (client.readValue(Integer.MAX_VALUE, TimestampsToReturn.Neither, inputSetpointId).getValue().getValue().getClass().isArray())) {
DataValue data = new DataValue(new Variant(optimizationAdviceInput), null, null);
client.writeValue(inputSetpointsId, data);
client.writeValue(inputSetpointId, data);
} else { // Standard case: Write setpoint to EMS as single value
DataValue singlevalueInputSetpoint = new DataValue(new Variant(optimizationAdviceInput[0]), null, null);
client.writeValue(inputSetpointId, singlevalueInputSetpoint);
}