("ess", this);
@@ -36,4 +39,11 @@ public void run() {
}
}
+
+
+ @Override
+ public ThingStateChannels getStateChannel() {
+ return this.thingState;
+ }
+
}
diff --git a/edge/src/io/openems/impl/controller/channelthreshold/ChannelThresholdController.java b/edge/src/io/openems/impl/controller/channelthreshold/ChannelThresholdController.java
index 86d247d326b..35083d0abca 100644
--- a/edge/src/io/openems/impl/controller/channelthreshold/ChannelThresholdController.java
+++ b/edge/src/io/openems/impl/controller/channelthreshold/ChannelThresholdController.java
@@ -1,176 +1,183 @@
-/*******************************************************************************
- * OpenEMS - Open Source Energy Management System
- * Copyright (c) 2016, 2017 FENECON GmbH and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- * Contributors:
- * FENECON GmbH - initial API and implementation and initial documentation
- *******************************************************************************/
-package io.openems.impl.controller.channelthreshold;
-
-import java.util.Optional;
-
-import io.openems.api.channel.Channel;
-import io.openems.api.channel.ConfigChannel;
-import io.openems.api.channel.ReadChannel;
-import io.openems.api.channel.WriteChannel;
-import io.openems.api.controller.Controller;
-import io.openems.api.doc.ChannelInfo;
-import io.openems.api.doc.ThingInfo;
-import io.openems.api.exception.InvalidValueException;
-import io.openems.api.exception.WriteChannelException;
-import io.openems.core.ThingRepository;
-
-/*
- * Example config:
- *
- * {
- * "class": "io.openems.impl.controller.channelthreshold.ChannelThresholdController",
- * "priority": 65,
- * "thresholdChannelAddress": "ess0/Soc",
- * "outputChannelAddress": "output0/1",
- * "lowerThreshold": 75,
- * "upperThreshold": 80,
- * "invertOutput": true
- * }
- *
- */
-
-@ThingInfo(title = "Switch channel on threshold")
-public class ChannelThresholdController extends Controller {
-
- /*
- * Constructors
- */
- public ChannelThresholdController() {
- super();
- }
-
- public ChannelThresholdController(String thingId) {
- super(thingId);
- }
-
- /*
- * Fields
- */
- private ThingRepository repo = ThingRepository.getInstance();
- private ReadChannel thresholdChannel;
- private WriteChannel outputChannel;
- private boolean isActive = false;
-
- /*
- * Config
- */
- @SuppressWarnings("unchecked")
- @ChannelInfo(title = "Channel", description = "Address of the channel that indicates the switching by the min and max threshold.", type = String.class)
- public ConfigChannel thresholdChannelName = new ConfigChannel("thresholdChannelAddress", this)
- .addChangeListener((channel, newValue, oldValue) -> {
- Optional channelAddress = (Optional) newValue;
- if (channelAddress.isPresent()) {
- Optional ch = repo.getChannelByAddress(channelAddress.get());
- if (ch.isPresent()) {
- thresholdChannel = (ReadChannel) ch.get();
- } else {
- log.error("Channel " + channelAddress.get() + " not found");
- }
- } else {
- log.error("'outputChannelAddress' is not configured!");
- }
- });
-
- @SuppressWarnings("unchecked")
- @ChannelInfo(title = "Output", description = "Address of the digital output channel that should be switched.", type = String.class)
- public ConfigChannel outputChannelName = new ConfigChannel("outputChannelAddress", this)
- .addChangeListener((channel, newValue, oldValue) -> {
- Optional channelAddress = (Optional) newValue;
- if (channelAddress.isPresent()) {
- Optional ch = repo.getChannelByAddress(channelAddress.get());
- if (ch.isPresent()) {
- outputChannel = (WriteChannel) ch.get();
- } else {
- log.error("Channel " + channelAddress.get() + " not found");
- }
- } else {
- log.error("'outputChannelAddress' is not configured!");
- }
- });
-
- @ChannelInfo(title = "Low threshold", description = "Low threshold where the output should be switched on.", type = Long.class)
- public ConfigChannel lowerThreshold = new ConfigChannel("lowerThreshold", this);
-
- @ChannelInfo(title = "High threshold", description = "High threshold where the output should be switched off.", type = Long.class)
- public ConfigChannel upperThreshold = new ConfigChannel("upperThreshold", this);
-
- @ChannelInfo(title = "Hysteresis", description = "Hysteresis for lower and upper threshold", type = Long.class)
- public ConfigChannel hysteresis = new ConfigChannel("hysteresis", this);
-
- @ChannelInfo(title = "Invert-Output", description = "True if the digital output should be inverted.", type = Boolean.class)
- public ConfigChannel invertOutput = new ConfigChannel("invertOutput", this).defaultValue(false);
-
- /*
- * Methods
- */
- @Override
- public void run() {
- // Check if all parameters are available
- long threshold;
- long lowerThreshold;
- long upperThreshold;
- long hysteresis;
- boolean invertOutput;
- try {
- threshold = this.thresholdChannel.value();
- lowerThreshold = this.lowerThreshold.value();
- upperThreshold = this.upperThreshold.value();
- hysteresis = this.hysteresis.value();
- invertOutput = this.invertOutput.value();
- } catch (InvalidValueException e) {
- log.error("ChannelThresholdController error: " + e.getMessage());
- return;
- }
- try {
- if (isActive) {
- if (threshold < lowerThreshold || threshold > upperThreshold + hysteresis) {
- isActive = false;
- } else {
- on(invertOutput);
- }
- } else {
- if (threshold >= lowerThreshold + hysteresis && threshold <= upperThreshold) {
- isActive = true;
- } else {
- off(invertOutput);
- }
- }
- } catch (WriteChannelException e) {
- log.error("Failed to write Channel[" + outputChannel.address() + "]: " + e.getMessage());
- }
- }
-
- private void on(boolean invertOutput) throws WriteChannelException {
- Optional currentValueOpt = this.outputChannel.valueOptional();
- if (!currentValueOpt.isPresent() || currentValueOpt.get() != (true ^ invertOutput)) {
- outputChannel.pushWrite(true ^ invertOutput);
- }
- }
-
- private void off(boolean invertOutput) throws WriteChannelException {
- Optional currentValueOpt = this.outputChannel.valueOptional();
- if (!currentValueOpt.isPresent() || currentValueOpt.get() != (false ^ invertOutput)) {
- outputChannel.pushWrite(false ^ invertOutput);
- }
- }
-
-}
+/*******************************************************************************
+ * OpenEMS - Open Source Energy Management System
+ * Copyright (c) 2016, 2017 FENECON GmbH and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ * Contributors:
+ * FENECON GmbH - initial API and implementation and initial documentation
+ *******************************************************************************/
+package io.openems.impl.controller.channelthreshold;
+
+import java.util.Optional;
+
+import io.openems.api.channel.Channel;
+import io.openems.api.channel.ConfigChannel;
+import io.openems.api.channel.ReadChannel;
+import io.openems.api.channel.WriteChannel;
+import io.openems.api.channel.thingstate.ThingStateChannels;
+import io.openems.api.controller.Controller;
+import io.openems.api.doc.ChannelInfo;
+import io.openems.api.doc.ThingInfo;
+import io.openems.api.exception.InvalidValueException;
+import io.openems.api.exception.WriteChannelException;
+import io.openems.core.ThingRepository;
+
+/*
+ * Example config:
+ *
+ * {
+ * "class": "io.openems.impl.controller.channelthreshold.ChannelThresholdController",
+ * "priority": 65,
+ * "thresholdChannelAddress": "ess0/Soc",
+ * "outputChannelAddress": "output0/1",
+ * "lowerThreshold": 75,
+ * "upperThreshold": 80,
+ * "invertOutput": true
+ * }
+ *
+ */
+
+@ThingInfo(title = "Switch channel on threshold")
+public class ChannelThresholdController extends Controller {
+
+ private ThingStateChannels thingState = new ThingStateChannels(this);
+ /*
+ * Constructors
+ */
+ public ChannelThresholdController() {
+ super();
+ }
+
+ public ChannelThresholdController(String thingId) {
+ super(thingId);
+ }
+
+ /*
+ * Fields
+ */
+ private ThingRepository repo = ThingRepository.getInstance();
+ private ReadChannel thresholdChannel;
+ private WriteChannel outputChannel;
+ private boolean isActive = false;
+
+ /*
+ * Config
+ */
+ @SuppressWarnings("unchecked")
+ @ChannelInfo(title = "Channel", description = "Address of the channel that indicates the switching by the min and max threshold.", type = String.class)
+ public ConfigChannel thresholdChannelName = new ConfigChannel("thresholdChannelAddress", this)
+ .addChangeListener((channel, newValue, oldValue) -> {
+ Optional channelAddress = (Optional) newValue;
+ if (channelAddress.isPresent()) {
+ Optional ch = repo.getChannelByAddress(channelAddress.get());
+ if (ch.isPresent()) {
+ thresholdChannel = (ReadChannel) ch.get();
+ } else {
+ log.error("Channel " + channelAddress.get() + " not found");
+ }
+ } else {
+ log.error("'outputChannelAddress' is not configured!");
+ }
+ });
+
+ @SuppressWarnings("unchecked")
+ @ChannelInfo(title = "Output", description = "Address of the digital output channel that should be switched.", type = String.class)
+ public ConfigChannel outputChannelName = new ConfigChannel("outputChannelAddress", this)
+ .addChangeListener((channel, newValue, oldValue) -> {
+ Optional channelAddress = (Optional) newValue;
+ if (channelAddress.isPresent()) {
+ Optional ch = repo.getChannelByAddress(channelAddress.get());
+ if (ch.isPresent()) {
+ outputChannel = (WriteChannel) ch.get();
+ } else {
+ log.error("Channel " + channelAddress.get() + " not found");
+ }
+ } else {
+ log.error("'outputChannelAddress' is not configured!");
+ }
+ });
+
+ @ChannelInfo(title = "Low threshold", description = "Low threshold where the output should be switched on.", type = Long.class)
+ public ConfigChannel lowerThreshold = new ConfigChannel("lowerThreshold", this);
+
+ @ChannelInfo(title = "High threshold", description = "High threshold where the output should be switched off.", type = Long.class)
+ public ConfigChannel upperThreshold = new ConfigChannel("upperThreshold", this);
+
+ @ChannelInfo(title = "Hysteresis", description = "Hysteresis for lower and upper threshold", type = Long.class)
+ public ConfigChannel hysteresis = new ConfigChannel("hysteresis", this);
+
+ @ChannelInfo(title = "Invert-Output", description = "True if the digital output should be inverted.", type = Boolean.class)
+ public ConfigChannel invertOutput = new ConfigChannel("invertOutput", this).defaultValue(false);
+
+ /*
+ * Methods
+ */
+ @Override
+ public void run() {
+ // Check if all parameters are available
+ long threshold;
+ long lowerThreshold;
+ long upperThreshold;
+ long hysteresis;
+ boolean invertOutput;
+ try {
+ threshold = this.thresholdChannel.value();
+ lowerThreshold = this.lowerThreshold.value();
+ upperThreshold = this.upperThreshold.value();
+ hysteresis = this.hysteresis.value();
+ invertOutput = this.invertOutput.value();
+ } catch (InvalidValueException e) {
+ log.error("ChannelThresholdController error: " + e.getMessage());
+ return;
+ }
+ try {
+ if (isActive) {
+ if (threshold < lowerThreshold || threshold > upperThreshold + hysteresis) {
+ isActive = false;
+ } else {
+ on(invertOutput);
+ }
+ } else {
+ if (threshold >= lowerThreshold + hysteresis && threshold <= upperThreshold) {
+ isActive = true;
+ } else {
+ off(invertOutput);
+ }
+ }
+ } catch (WriteChannelException e) {
+ log.error("Failed to write Channel[" + outputChannel.address() + "]: " + e.getMessage());
+ }
+ }
+
+ private void on(boolean invertOutput) throws WriteChannelException {
+ Optional currentValueOpt = this.outputChannel.valueOptional();
+ if (!currentValueOpt.isPresent() || currentValueOpt.get() != (true ^ invertOutput)) {
+ outputChannel.pushWrite(true ^ invertOutput);
+ }
+ }
+
+ private void off(boolean invertOutput) throws WriteChannelException {
+ Optional currentValueOpt = this.outputChannel.valueOptional();
+ if (!currentValueOpt.isPresent() || currentValueOpt.get() != (false ^ invertOutput)) {
+ outputChannel.pushWrite(false ^ invertOutput);
+ }
+ }
+
+ @Override
+ public ThingStateChannels getStateChannel() {
+ return this.thingState;
+ }
+
+}
diff --git a/edge/src/io/openems/impl/controller/chargerlimitation/ChargeLimitationController.java b/edge/src/io/openems/impl/controller/chargerlimitation/ChargeLimitationController.java
index 1ad1f78fb13..586f0c3c5cf 100644
--- a/edge/src/io/openems/impl/controller/chargerlimitation/ChargeLimitationController.java
+++ b/edge/src/io/openems/impl/controller/chargerlimitation/ChargeLimitationController.java
@@ -1,67 +1,74 @@
-package io.openems.impl.controller.chargerlimitation;
-
-import java.util.List;
-
-import io.openems.api.channel.ConfigChannel;
-import io.openems.api.controller.Controller;
-import io.openems.api.doc.ChannelInfo;
-import io.openems.api.doc.ThingInfo;
-
-@ThingInfo(title = "Limit battery charge from DC", description = "Limits the maximum charge of the battery from DC connected charger.")
-public class ChargeLimitationController extends Controller {
-
- /*
- * Constructors
- */
-
- public ChargeLimitationController() {
- super();
- }
-
- public ChargeLimitationController(String thingId) {
- super(thingId);
- }
-
- /*
- * Config
- */
- @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class)
- public ConfigChannel ess = new ConfigChannel("ess", this);
-
- @ChannelInfo(title = "Chargers", description = "Sets the chargers.", type = Charger.class, isArray = true)
- public ConfigChannel> chargers = new ConfigChannel<>("chargers", this);
-
- /*
- * Methods
- */
- @Override
- public void run() {
- // try {
- // Ess ess = this.ess.value();
- // List chargers = this.chargers.value();
- // // calculate maximal chargePower
- // float power = ess.allowedCharge.value() + ess.getWrittenActivePower();
- // if (power > 0) {
- // float maxCurrent = 0l;
- // for (Charger c : chargers) {
- // maxCurrent += c.nominalCurrent.value();
- // }
- // for (Charger c : chargers) {
- // c.setPower(power / maxCurrent * c.nominalCurrent.value());
- // }
- // ess.setMaxCharge(ess.allowedCharge.value() - power);
- // } else {
- // for (Charger c : chargers) {
- // c.setPower(0);
- // }
- // }
- // } catch (InvalidValueException e) {
- // // TODO Auto-generated catch block
- // e.printStackTrace();
- // } catch (WriteChannelException e) {
- // // TODO Auto-generated catch block
- // e.printStackTrace();
- // }
- }
-
-}
+package io.openems.impl.controller.chargerlimitation;
+
+import java.util.List;
+
+import io.openems.api.channel.ConfigChannel;
+import io.openems.api.channel.thingstate.ThingStateChannels;
+import io.openems.api.controller.Controller;
+import io.openems.api.doc.ChannelInfo;
+import io.openems.api.doc.ThingInfo;
+
+@ThingInfo(title = "Limit battery charge from DC", description = "Limits the maximum charge of the battery from DC connected charger.")
+public class ChargeLimitationController extends Controller {
+
+ private ThingStateChannels thingState = new ThingStateChannels(this);
+ /*
+ * Constructors
+ */
+
+ public ChargeLimitationController() {
+ super();
+ }
+
+ public ChargeLimitationController(String thingId) {
+ super(thingId);
+ }
+
+ /*
+ * Config
+ */
+ @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class)
+ public ConfigChannel ess = new ConfigChannel("ess", this);
+
+ @ChannelInfo(title = "Chargers", description = "Sets the chargers.", type = Charger.class, isArray = true)
+ public ConfigChannel