From 5bd19422ddf245ef51bf8bb31192a9863655c4a5 Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Fri, 25 Aug 2017 16:33:47 +0200 Subject: [PATCH 01/55] Add original setup script and templates --- edge/template/FeneconCommercialDC.json | 93 ----------- setup/devices | 1 + setup/setup.sh | 129 +++++++++++++++ .../templates/FENECON Commercial AC.json | 148 ++++++++--------- setup/templates/FENECON Commercial DC.json | 93 +++++++++++ .../templates/FENECON Commercial Hybrid.json | 103 ++++++++++++ .../templates/FENECON Pro 9-12.json | 154 +++++++++--------- 7 files changed, 477 insertions(+), 244 deletions(-) delete mode 100644 edge/template/FeneconCommercialDC.json create mode 100644 setup/devices create mode 100644 setup/setup.sh rename edge/template/FeneconCommercialAC.json => setup/templates/FENECON Commercial AC.json (93%) create mode 100644 setup/templates/FENECON Commercial DC.json create mode 100644 setup/templates/FENECON Commercial Hybrid.json rename edge/template/FeneconPro.json => setup/templates/FENECON Pro 9-12.json (93%) diff --git a/edge/template/FeneconCommercialDC.json b/edge/template/FeneconCommercialDC.json deleted file mode 100644 index 093d6cb2c6d..00000000000 --- a/edge/template/FeneconCommercialDC.json +++ /dev/null @@ -1,93 +0,0 @@ -{ - "things": [ - { - "class": "io.openems.impl.protocol.modbus.ModbusTcp", - "ip": "10.4.0.15", - "cycleTime": 500, - "devices": [ - { - "id": "_device0", - "class": "io.openems.impl.device.commercial.FeneconCommercialDC", - "modbusUnitId": 100, - "ess": { - "id": "ess0", - "minSoc": 15, - "chargeSoc": 10 - }, - "charger": { - "id": "charger0" - } - } - ] - }, - { - "class": "io.openems.impl.protocol.modbus.ModbusRtu", - "databits": 8, - "serialinterface": "/dev/ttyUSB0", - "parity": "none", - "baudrate": 9600, - "stopbits": 1, - "cycleTime": 500, - "devices": [ - { - "id": "_device1", - "class": "io.openems.impl.device.socomec.Socomec", - "meter": { - "id": "meter0", - "type": "grid" - }, - "modbusUnitId": 5 - } - ] - } - ], - "scheduler": { - "class": "io.openems.impl.scheduler.SimpleScheduler", - "cycleTime": 500, - "controllers": [ - { - "class": "io.openems.impl.controller.symmetric.commercialworkstate.AlwaysOnController", - "priority": 0, - "esss": [ - "ess0" - ] - }, - { - "class": "io.openems.impl.controller.symmetric.avoidtotaldischarge.AvoidTotalDischargeController", - "priority": 100, - "esss": [ - "ess0" - ] - }, - { - "class": "io.openems.impl.controller.symmetric.balancing.BalancingController", - "esss": [ - "ess0" - ], - "meter": "meter0", - "priority": 50 - }, - { - "class": "io.openems.impl.controller.debuglog.DebugLogController", - "esss": [ - "ess0" - ], - "priority": 150, - "meters": [ - "meter0" - ] - } - ] - }, - "persistence": [ - { - "class": "io.openems.impl.persistence.influxdb.InfluxdbPersistence", - "ip": "127.0.0.1", - "fems": 0 - }, - { - "class": "io.openems.impl.persistence.fenecon.FeneconPersistence", - "apikey": "" - } - ] -} diff --git a/setup/devices b/setup/devices new file mode 100644 index 00000000000..67aec8d47c3 --- /dev/null +++ b/setup/devices @@ -0,0 +1 @@ +#name;password;apikey;packages \ No newline at end of file diff --git a/setup/setup.sh b/setup/setup.sh new file mode 100644 index 00000000000..d7d7eb967a2 --- /dev/null +++ b/setup/setup.sh @@ -0,0 +1,129 @@ +#!/bin/bash +# +# Script to automatically setup a FEMS. +# Setup parameters are taken from the first line of a devices file in the format: +# ;;; +# +set -e + +# Define status files +FINISHED_1=/opt/fems-setup/finished_1 +FINISHED_2=/opt/fems-setup/finished_2 +DEVICES=/opt/fems-setup/devices + +# First stage: Copy filesystem to internal eMMC +if [ ! -e $FINISHED_1 ]; then + echo "#" + echo "# Starting first stage of FEMS setup" + echo "#" + + if [ "$(cat /boot/uboot/fems-setup/devices | wc -l)" == "1" ]; then + echo "# No devices left in configuration file" + echo "#" + echo "# Aborting" + exit 1 + fi + + echo "# Copy filesystem to internal eMMC" + cd /opt/scripts/tools/eMMC + ./bbb-eMMC-flasher-eewiki-ext4.sh || true + + echo "# Mount target filesystem" + /bin/mount /dev/mmcblk1p1 /mnt + + echo "# Copy setup script to target" + mkdir -p /mnt/opt/fems-setup + cp /boot/uboot/fems-setup/setup.sh /mnt/opt/fems-setup/ + + echo "# Copy current fems data to target" + /usr/bin/head -n 2 /boot/uboot/fems-setup/devices > /mnt/opt/fems-setup/devices + + echo "# Remove fems from devices list" + /bin/sed --expression='2d' /boot/uboot/fems-setup/devices --in-place + + echo "# Mark first stage as finished" + touch /mnt$FINISHED_1 + /bin/umount /mnt + + echo "# Blink all LEDs" + echo timer | tee /sys/class/leds/beaglebone:green:usr?/trigger >/dev/null + + read -p "Press [Enter] key to shutdown" + + echo "# Shutdown system" + /sbin/shutdown -h now + +elif [ ! -e $FINISHED_2 ]; then + echo "#" + echo "# Starting second stage of FEMS setup" + echo "#" + + FEMS=$(head -n 2 $DEVICES | tail -n 1 | cut -d ";" -f 1) + PASSWORD=$(head -n 2 $DEVICES | tail -n 1 | cut -d ";" -f 2) + + echo "# Set password for user fems" + echo "fems:${PASSWORD}" | /usr/sbin/chpasswd + + echo "# Set name to ${FEMS}" + echo $FEMS > /etc/hostname + /bin/sed "s/\(127.0.1.1.*\)fems.*/\1$FEMS/" /etc/hosts --in-place + echo $FEMS > /etc/mailname + rm -fv /etc/ssh/ssh_host_* + dpkg-reconfigure openssh-server + rm /etc/udev/rules.d/70-persistent-net.rules + + echo "# Blink all LEDs" + echo timer | tee /sys/class/leds/beaglebone:green:usr?/trigger >/dev/null + + echo "# Mark second stage as finished" + touch $FINISHED_2 + + read -p "Press [Enter] key to reboot" + echo "# Rebooting system" + reboot + +else + echo "#" + echo "# Starting third stage of FEMS setup" + echo "#" + + PACKAGES=$(head -n 2 $DEVICES | tail -n 1 | cut -d ";" -f 4) + + echo "# Add FENECON debian repository" + wget -O - http://fenecon.de/debian/fems.gpg.key | apt-key add - + wget http://fenecon.de/debian/fems.list -O /etc/apt/sources.list.d/fems.list + echo "# Add Debian Backports repository" + echo "deb http://ftp.de.debian.org/debian/ jessie-backports main contrib non-free" > /etc/apt/sources.list.d/jessie-backports.list + echo "# Refresh apt cache" + /usr/bin/aptitude update + echo "# Install openjdk 8" + /usr/bin/apt install -t jessie-backports openjdk-8-jre-headless + + # this is not working... + #echo "# preset apikey for dpkg-configure" + #. /usr/share/debconf/confmodule + #db_set fems-openhab-addon-fems/apikey $APIKEY + + # TODO remove setup-script from /opt/fems-setup + + if [ "${PACKAGES}" != "" ]; then + echo "# Install packages: ${PACKAGES}" + /usr/bin/aptitude install --assume-yes $PACKAGES + else + echo "# Install NO packages!" + fi + + echo "# Finialize setup with fems-autoupdate fems" + /usr/bin/fems-autoupdate fems + + echo "# Blink all LEDs" + echo timer | tee /sys/class/leds/beaglebone:green:usr?/trigger >/dev/null + + echo "#" + echo "# Finished setup" + echo "#" + + read -p "Press [Enter] key to reboot" + echo "# Rebooting system" + reboot +fi diff --git a/edge/template/FeneconCommercialAC.json b/setup/templates/FENECON Commercial AC.json similarity index 93% rename from edge/template/FeneconCommercialAC.json rename to setup/templates/FENECON Commercial AC.json index cc4e0289762..29e6a5fea00 100644 --- a/edge/template/FeneconCommercialAC.json +++ b/setup/templates/FENECON Commercial AC.json @@ -1,74 +1,74 @@ -{ - "things": [ - { - "class": "io.openems.impl.protocol.modbus.ModbusTcp", - "ip": "10.4.0.10", - "devices": [ - { - "class": "io.openems.impl.device.commercial.FeneconCommercialAC", - "modbusUnitId": 100, - "ess": { - "id": "ess0", - "minSoc": 15, - "chargeSoc": 10 - } - } - ] - }, - { - "class": "io.openems.impl.protocol.modbus.ModbusRtu", - "serialinterface": "/dev/ttyUSB0", - "baudrate": 9600, - "databits": 8, - "parity": "none", - "stopbits": 1, - "devices": [ - { - "class": "io.openems.impl.device.socomec.Socomec", - "modbusUnitId": 5, - "meter": { - "id": "meter0" - } - } - ] - } - ], - "scheduler": { - "class": "io.openems.impl.scheduler.SimpleScheduler", - "controllers": [ - { - "priority": 150, - "class": "io.openems.impl.controller.debuglog.DebugLogController", - "esss": "ess0", - "meters": "meter0" - }, - { - "priority": 100, - "class": "io.openems.impl.controller.symmetric.avoidtotaldischarge.AvoidTotalDischargeController", - "esss": "ess0" - }, - { - "priority": 50, - "class": "io.openems.impl.controller.symmetric.balancing.BalancingController", - "esss": "ess0", - "meter": "meter0" - }, - { - "priority": 0, - "class": "io.openems.impl.controller.symmetric.commercialenergysaver.EnergysavingController", - "esss": "ess0" - } - ] - }, - "persistence": [ - { - "class": "io.openems.impl.persistence.influxdb.InfluxdbPersistence", - "ip": "127.0.0.1", - "fems": 0 - }, - { - "class": "io.openems.impl.persistence.fenecon.FeneconPersistence", - "apikey": "XXX" - } - ] -} +{ + "things": [ + { + "class": "io.openems.impl.protocol.modbus.ModbusTcp", + "ip": "10.4.0.10", + "devices": [ + { + "class": "io.openems.impl.device.commercial.FeneconCommercialAC", + "modbusUnitId": 100, + "ess": { + "id": "ess0", + "minSoc": 15, + "chargeSoc": 10 + } + } + ] + }, + { + "class": "io.openems.impl.protocol.modbus.ModbusRtu", + "serialinterface": "/dev/ttyUSB0", + "baudrate": 9600, + "databits": 8, + "parity": "none", + "stopbits": 1, + "devices": [ + { + "class": "io.openems.impl.device.socomec.Socomec", + "modbusUnitId": 5, + "meter": { + "id": "meter0" + } + } + ] + } + ], + "scheduler": { + "class": "io.openems.impl.scheduler.SimpleScheduler", + "controllers": [ + { + "priority": 150, + "class": "io.openems.impl.controller.debuglog.DebugLogController", + "esss": "ess0", + "meters": "meter0" + }, + { + "priority": 100, + "class": "io.openems.impl.controller.symmetric.avoidtotaldischarge.AvoidTotalDischargeController", + "esss": "ess0" + }, + { + "priority": 50, + "class": "io.openems.impl.controller.symmetric.balancing.BalancingController", + "esss": "ess0", + "meter": "meter0" + }, + { + "priority": 0, + "class": "io.openems.impl.controller.symmetric.commercialenergysaver.EnergysavingController", + "esss": "ess0" + } + ] + }, + "persistence": [ + { + "class": "io.openems.impl.persistence.influxdb.InfluxdbPersistence", + "ip": "127.0.0.1", + "fems": "###FEMS_ID###" + }, + { + "class": "io.openems.impl.persistence.fenecon.FeneconPersistence", + "apikey": "###APIKEY###" + } + ] +} diff --git a/setup/templates/FENECON Commercial DC.json b/setup/templates/FENECON Commercial DC.json new file mode 100644 index 00000000000..41416fcbc27 --- /dev/null +++ b/setup/templates/FENECON Commercial DC.json @@ -0,0 +1,93 @@ +{ + "things": [ + { + "class": "io.openems.impl.protocol.modbus.ModbusTcp", + "ip": "10.4.0.15", + "cycleTime": 500, + "devices": [ + { + "id": "_device0", + "class": "io.openems.impl.device.commercial.FeneconCommercialDC", + "modbusUnitId": 100, + "ess": { + "id": "ess0", + "minSoc": 15, + "chargeSoc": 10 + }, + "charger": { + "id": "charger0" + } + } + ] + }, + { + "class": "io.openems.impl.protocol.modbus.ModbusRtu", + "databits": 8, + "serialinterface": "/dev/ttyUSB0", + "parity": "none", + "baudrate": 9600, + "stopbits": 1, + "cycleTime": 500, + "devices": [ + { + "id": "_device1", + "class": "io.openems.impl.device.socomec.Socomec", + "meter": { + "id": "meter0", + "type": "grid" + }, + "modbusUnitId": 5 + } + ] + } + ], + "scheduler": { + "class": "io.openems.impl.scheduler.SimpleScheduler", + "cycleTime": 500, + "controllers": [ + { + "class": "io.openems.impl.controller.symmetric.commercialworkstate.AlwaysOnController", + "priority": 0, + "esss": [ + "ess0" + ] + }, + { + "class": "io.openems.impl.controller.symmetric.avoidtotaldischarge.AvoidTotalDischargeController", + "priority": 100, + "esss": [ + "ess0" + ] + }, + { + "class": "io.openems.impl.controller.symmetric.balancing.BalancingController", + "esss": [ + "ess0" + ], + "meter": "meter0", + "priority": 50 + }, + { + "class": "io.openems.impl.controller.debuglog.DebugLogController", + "esss": [ + "ess0" + ], + "priority": 150, + "meters": [ + "meter0" + ] + } + ] + }, + "persistence": [ + { + "class": "io.openems.impl.persistence.influxdb.InfluxdbPersistence", + "ip": "127.0.0.1", + "fems": "###FEMS_ID###" + }, + { + "class": "io.openems.impl.persistence.fenecon.FeneconPersistence", + "apikey": "###APIKEY###" + } + ] +} \ No newline at end of file diff --git a/setup/templates/FENECON Commercial Hybrid.json b/setup/templates/FENECON Commercial Hybrid.json new file mode 100644 index 00000000000..993beb25323 --- /dev/null +++ b/setup/templates/FENECON Commercial Hybrid.json @@ -0,0 +1,103 @@ +{ + "things": [ + { + "class": "io.openems.impl.protocol.modbus.ModbusTcp", + "ip": "10.4.0.15", + "port": 502, + "devices": [ + { + "class": "io.openems.impl.device.commercial.FeneconCommercialDC", + "ess": { + "id": "ess0", + "minSoc": 15, + "chargeSoc": 10 + }, + "charger": { + "id": "charger0" + }, + "modbusUnitId": 100 + } + ] + }, + { + "class": "io.openems.impl.protocol.modbus.ModbusRtu", + "serialinterface": "/dev/ttyUSB0", + "baudrate": 9600, + "databits": 8, + "parity": "none", + "stopbits": 1, + "devices": [ + { + "class": "io.openems.impl.device.socomec.Socomec", + "modbusUnitId": 5, + "meter": { + "id": "meter0", + "type": "grid" + } + } + ] + } + ], + "scheduler": { + "class": "io.openems.impl.scheduler.SimpleScheduler", + "controllers": [ + { + "class": "io.openems.impl.controller.symmetric.commercialworkstate.AlwaysOnController", + "priority": 0, + "esss": [ + "ess0" + ] + }, + { + "class": "io.openems.impl.controller.symmetric.avoidtotaldischarge.AvoidTotalDischargeController", + "priority": 100, + "esss": [ + "ess0" + ], + "maxSoc": 95 + }, + { + "class": "io.openems.impl.controller.symmetric.balancingsurplus.BalancingSurplusController", + "meter": "meter0", + "ess": "ess0", + "priority": 50, + "surplusMinSoc": 85, + "chargers": [ + "charger0" + ] + }, + { + "class": "io.openems.impl.controller.debuglog.DebugLogController", + "priority": 151, + "esss": [ + "ess0" + ], + "meters": [ + "meter0", + "meter1" + ] + }, + { + "class": "io.openems.impl.controller.api.websocket.WebsocketApiController", + "port": 8085, + "priority": -2147483648 + }, + { + "class": "io.openems.impl.controller.api.rest.RestApiController", + "priority": -2147483648, + "port": 8084 + } + ] + }, + "persistence": [ + { + "class": "io.openems.impl.persistence.influxdb.InfluxdbPersistence", + "ip": "127.0.0.1", + "fems": "###FEMS_ID###" + }, + { + "class": "io.openems.impl.persistence.fenecon.FeneconPersistence", + "apikey": "###APIKEY###" + } + ] +} \ No newline at end of file diff --git a/edge/template/FeneconPro.json b/setup/templates/FENECON Pro 9-12.json similarity index 93% rename from edge/template/FeneconPro.json rename to setup/templates/FENECON Pro 9-12.json index c520cbcf718..f66dc51e79f 100644 --- a/edge/template/FeneconPro.json +++ b/setup/templates/FENECON Pro 9-12.json @@ -1,77 +1,77 @@ -{ - "things": [ - { - "class": "io.openems.impl.protocol.modbus.ModbusRtu", - "serialinterface": "/dev/ttyUSB0", - "baudrate": 9600, - "databits": 8, - "parity": "none", - "stopbits": 1, - "devices": [ - { - "class": "io.openems.impl.device.pro.FeneconPro", - "modbusUnitId": 4, - "ess": { - "id": "ess0", - "minSoc": 15 - }, - "meter": { - "id": "meter1" - } - }, - { - "class": "io.openems.impl.device.socomec.Socomec", - "modbusUnitId": 5, - "meter": { - "id": "meter0", - "type": "grid" - } - } - ] - } - ], - "scheduler": { - "class": "io.openems.impl.scheduler.SimpleScheduler", - "controllers": [ - { - "priority": 150, - "class": "io.openems.impl.controller.debuglog.DebugLogController", - "esss": [ "ess0" ], - "meters": [ "meter0", "meter1" ], - "rtc": "ess0" - }, - { - "priority": 100, - "class": "io.openems.impl.controller.asymmetric.avoidtotaldischarge.AvoidTotalDischargeController", - "esss": "ess0" - }, - { - "priority": 50, - "class": "io.openems.impl.controller.asymmetric.balancing.BalancingController", - "esss": "ess0", - "meter": "meter0" - }, - { - "priority": 1, - "class": "io.openems.impl.controller.clocksync.ClockSyncController", - "rtc": "ess0" - }, - { - "priority": 0, - "class": "io.openems.impl.controller.feneconprosetup.FeneconProSetupController", - "esss": "ess0" - } - ] - }, - "persistence": [ - { - "class": "io.openems.impl.persistence.influxdb.InfluxdbPersistence", - "ip": "127.0.0.1", - "fems": 0 - }, - { - "class": "io.openems.impl.persistence.fenecon.FeneconPersistence", - "apikey": "" - } - ] -} +{ + "things": [ + { + "class": "io.openems.impl.protocol.modbus.ModbusRtu", + "serialinterface": "/dev/ttyUSB0", + "baudrate": 9600, + "databits": 8, + "parity": "none", + "stopbits": 1, + "devices": [ + { + "class": "io.openems.impl.device.pro.FeneconPro", + "modbusUnitId": 4, + "ess": { + "id": "ess0", + "minSoc": 15 + }, + "meter": { + "id": "meter1" + } + }, + { + "class": "io.openems.impl.device.socomec.Socomec", + "modbusUnitId": 5, + "meter": { + "id": "meter0", + "type": "grid" + } + } + ] + } + ], + "scheduler": { + "class": "io.openems.impl.scheduler.SimpleScheduler", + "controllers": [ + { + "priority": 150, + "class": "io.openems.impl.controller.debuglog.DebugLogController", + "esss": [ "ess0" ], + "meters": [ "meter0", "meter1" ], + "rtc": "ess0" + }, + { + "priority": 100, + "class": "io.openems.impl.controller.asymmetric.avoidtotaldischarge.AvoidTotalDischargeController", + "esss": "ess0" + }, + { + "priority": 50, + "class": "io.openems.impl.controller.asymmetric.balancing.BalancingController", + "esss": "ess0", + "meter": "meter0" + }, + { + "priority": 1, + "class": "io.openems.impl.controller.clocksync.ClockSyncController", + "rtc": "ess0" + }, + { + "priority": 0, + "class": "io.openems.impl.controller.feneconprosetup.FeneconProSetupController", + "esss": "ess0" + } + ] + }, + "persistence": [ + { + "class": "io.openems.impl.persistence.influxdb.InfluxdbPersistence", + "ip": "127.0.0.1", + "fems": "###FEMS_ID###" + }, + { + "class": "io.openems.impl.persistence.fenecon.FeneconPersistence", + "apikey": "###APIKEY###" + } + ] +} From 179393f3e6b0e63e0e7851b5b051873eee39b2fb Mon Sep 17 00:00:00 2001 From: Lisa Kaindl Date: Wed, 30 Aug 2017 17:06:01 +0200 Subject: [PATCH 02/55] Write Apikey into /etc/fems --- setup/setup.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup/setup.sh b/setup/setup.sh index d7d7eb967a2..49f354d9081 100644 --- a/setup/setup.sh +++ b/setup/setup.sh @@ -41,6 +41,9 @@ if [ ! -e $FINISHED_1 ]; then echo "# Remove fems from devices list" /bin/sed --expression='2d' /boot/uboot/fems-setup/devices --in-place + echo "# Write Apikey into /etc/fems" + /usr/bin/head -n 2 devices | tail -n 1 | cut -d ";" -f 3 > /mnt/etc/fems + echo "# Mark first stage as finished" touch /mnt$FINISHED_1 /bin/umount /mnt From 3dcd3a0a003d397de82620ce4bc48639b8c27307 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Ro=C3=9Fmann?= Date: Thu, 30 Nov 2017 16:48:40 +0100 Subject: [PATCH 03/55] remove systemState control --- .../controller/asymmetric/balancing/BalancingController.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/edge/src/io/openems/impl/controller/asymmetric/balancing/BalancingController.java b/edge/src/io/openems/impl/controller/asymmetric/balancing/BalancingController.java index 0954fe54a10..871aa531c83 100644 --- a/edge/src/io/openems/impl/controller/asymmetric/balancing/BalancingController.java +++ b/edge/src/io/openems/impl/controller/asymmetric/balancing/BalancingController.java @@ -26,7 +26,6 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.controller.Controller; -import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; import io.openems.api.exception.InvalidValueException; @@ -71,9 +70,6 @@ public BalancingController(String thingId) { @Override public void run() { try { - for (Ess ess : esss.value()) { - ess.setWorkState.pushWriteFromLabel(EssNature.START); - } long[] calculatedPowers = new long[3]; long calculatedPowerSum = 0; // calculateRequiredPower From 2fd9eb517ab999c1b7d818e916a758ee32cd17b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Ro=C3=9Fmann?= Date: Thu, 30 Nov 2017 16:48:54 +0100 Subject: [PATCH 04/55] fix setWorkstate labels --- edge/src/io/openems/impl/device/pro/FeneconProEss.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/edge/src/io/openems/impl/device/pro/FeneconProEss.java b/edge/src/io/openems/impl/device/pro/FeneconProEss.java index 2770d34bf49..6f769e7b293 100644 --- a/edge/src/io/openems/impl/device/pro/FeneconProEss.java +++ b/edge/src/io/openems/impl/device/pro/FeneconProEss.java @@ -636,8 +636,8 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { .label(0, "Local control") // .label(1, START) // "Remote control on grid starting" .label(2, "Remote control off grid starting") // - .label(3, STOP)// - .label(4, "Emergency Stop"))), + .label(3, STANDBY)// + .label(4, STOP))), new WriteableModbusRegisterRange(206, // new SignedWordElement(206, setActivePowerL1 = new ModbusWriteLongChannel("SetActivePowerL1", this).unit("W")), // From f3599644588e886d32f51650175668612c02bdc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Ro=C3=9Fmann?= Date: Thu, 30 Nov 2017 16:49:29 +0100 Subject: [PATCH 05/55] add alwaysOnController to run ess anytime --- .../alwayson/AlwaysOnController.java | 73 +++++++++++++++++++ .../controller/systemstate/alwayson/Ess.java | 41 +++++++++++ 2 files changed, 114 insertions(+) create mode 100644 edge/src/io/openems/impl/controller/systemstate/alwayson/AlwaysOnController.java create mode 100644 edge/src/io/openems/impl/controller/systemstate/alwayson/Ess.java diff --git a/edge/src/io/openems/impl/controller/systemstate/alwayson/AlwaysOnController.java b/edge/src/io/openems/impl/controller/systemstate/alwayson/AlwaysOnController.java new file mode 100644 index 00000000000..aa50064fc11 --- /dev/null +++ b/edge/src/io/openems/impl/controller/systemstate/alwayson/AlwaysOnController.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * 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.systemstate.alwayson; + +import java.util.Set; + +import io.openems.api.channel.ConfigChannel; +import io.openems.api.controller.Controller; +import io.openems.api.device.nature.ess.EssNature; +import io.openems.api.doc.ChannelInfo; +import io.openems.api.doc.ThingInfo; +import io.openems.api.exception.InvalidValueException; +import io.openems.api.exception.WriteChannelException; + +/** + * @author matthias.rossmann + */ +@ThingInfo(title = "Keep always running", description = "Tries to keep the Ess always running. Use if Off-Grid functionality is required.") +public class AlwaysOnController extends Controller { + + /* + * Constructors + */ + public AlwaysOnController() { + super(); + } + + public AlwaysOnController(String thingId) { + super(thingId); + } + + /* + * Config + */ + @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class, isArray = true) + public final ConfigChannel> esss = new ConfigChannel>("esss", this); + + /* + * Methods + */ + @Override + public void run() { + try { + for (Ess ess : esss.value()) { + try { + ess.setWorkState.pushWriteFromLabel(EssNature.START); + } catch (WriteChannelException e) { + log.error("", e); + } + } + } catch (InvalidValueException e) { + log.error("No Storage Found!", e); + } + } +} diff --git a/edge/src/io/openems/impl/controller/systemstate/alwayson/Ess.java b/edge/src/io/openems/impl/controller/systemstate/alwayson/Ess.java new file mode 100644 index 00000000000..3a904854a1f --- /dev/null +++ b/edge/src/io/openems/impl/controller/systemstate/alwayson/Ess.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * OpenEMS - Open Source Energy Management System + * Copyright (c) 2016 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.systemstate.alwayson; + +import io.openems.api.channel.ReadChannel; +import io.openems.api.channel.WriteChannel; +import io.openems.api.controller.IsThingMap; +import io.openems.api.controller.ThingMap; +import io.openems.api.device.nature.ess.EssNature; + +@IsThingMap(type = EssNature.class) +public class Ess extends ThingMap { + + public final WriteChannel setWorkState; + public final ReadChannel systemState; + + public Ess(EssNature ess) { + super(ess); + setWorkState = ess.setWorkState().required(); + systemState = ess.systemState().required(); + } + +} From 3b30437ad4ba5e847a67c992085722e4cc14c912 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Ro=C3=9Fmann?= Date: Thu, 30 Nov 2017 16:51:33 +0100 Subject: [PATCH 06/55] add TimeOnController to start/stop ess on configured time --- .../impl/controller/systemstate/time/Ess.java | 41 +++++ .../systemstate/time/TimeOnController.java | 147 ++++++++++++++++++ 2 files changed, 188 insertions(+) create mode 100644 edge/src/io/openems/impl/controller/systemstate/time/Ess.java create mode 100644 edge/src/io/openems/impl/controller/systemstate/time/TimeOnController.java diff --git a/edge/src/io/openems/impl/controller/systemstate/time/Ess.java b/edge/src/io/openems/impl/controller/systemstate/time/Ess.java new file mode 100644 index 00000000000..096cba1c93e --- /dev/null +++ b/edge/src/io/openems/impl/controller/systemstate/time/Ess.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * OpenEMS - Open Source Energy Management System + * Copyright (c) 2016 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.systemstate.time; + +import io.openems.api.channel.ReadChannel; +import io.openems.api.channel.WriteChannel; +import io.openems.api.controller.IsThingMap; +import io.openems.api.controller.ThingMap; +import io.openems.api.device.nature.ess.EssNature; + +@IsThingMap(type = EssNature.class) +public class Ess extends ThingMap { + + public final WriteChannel setWorkState; + public final ReadChannel systemState; + + public Ess(EssNature ess) { + super(ess); + setWorkState = ess.setWorkState().required(); + systemState = ess.systemState().required(); + } + +} diff --git a/edge/src/io/openems/impl/controller/systemstate/time/TimeOnController.java b/edge/src/io/openems/impl/controller/systemstate/time/TimeOnController.java new file mode 100644 index 00000000000..fd2ba843568 --- /dev/null +++ b/edge/src/io/openems/impl/controller/systemstate/time/TimeOnController.java @@ -0,0 +1,147 @@ +/******************************************************************************* + * 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.systemstate.time; + +import java.time.LocalTime; +import java.util.Optional; +import java.util.Set; + +import io.openems.api.channel.Channel; +import io.openems.api.channel.ChannelChangeListener; +import io.openems.api.channel.ConfigChannel; +import io.openems.api.controller.Controller; +import io.openems.api.device.nature.ess.EssNature; +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.common.session.Role; + +/** + * @author matthias.rossmann + */ +@ThingInfo(title = "Keep always running", description = "Tries to keep the Ess always running. Use if Off-Grid functionality is required.") +public class TimeOnController extends Controller implements ChannelChangeListener { + + /* + * Constructors + */ + public TimeOnController() { + super(); + } + + public TimeOnController(String thingId) { + super(thingId); + } + + /* + * Config + */ + @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class, isArray = true) + public final ConfigChannel> esss = new ConfigChannel>("esss", this); + + @ChannelInfo(title = "Time-On", description = "", type = String.class, writeRoles = { Role.OWNER }) + public ConfigChannel timeOn = new ConfigChannel("timeOn", this).addChangeListener(this); + @ChannelInfo(title = "Time-Off", description = "", type = String.class, writeRoles = { Role.OWNER }) + public ConfigChannel timeOff = new ConfigChannel("timeOff", this).addChangeListener(this); + + /* + * Fields + */ + private LocalTime timeStart; + private LocalTime timeStop; + + enum State { + START, STOP + } + + private State currentState = State.STOP; + + /* + * Methods + */ + @Override + public void run() { + try { + System.out.println(currentState.toString()); + switch (currentState) { + case START: + if (isOpen(timeStop, timeStart, LocalTime.now())) { + this.currentState = State.STOP; + } else { + for (Ess ess : esss.value()) { + System.out.println(ess.systemState.value()); + try { + ess.setWorkState.pushWriteFromLabel(EssNature.START); + } catch (WriteChannelException e) { + log.error("", e); + } + } + } + break; + case STOP: + if (isOpen(timeStart, timeStop, LocalTime.now())) { + this.currentState = State.START; + } else { + for (Ess ess : esss.value()) { + System.out.println(ess.systemState.value()); + try { + ess.setWorkState.pushWriteFromLabel(EssNature.STOP); + } catch (WriteChannelException e) { + log.error("", e); + } + } + } + break; + default: + log.error("no state set."); + break; + } + } catch (InvalidValueException e) { + log.error("No Storage Found!", e); + } + } + + public static boolean isOpen(LocalTime start, LocalTime end, LocalTime time) { + if (start.isAfter(end)) { + return !time.isBefore(start) || !time.isAfter(end); + } else { + return !time.isBefore(start) && !time.isAfter(end); + } + } + + @Override + public void channelChanged(Channel channel, Optional newValue, Optional oldValue) { + if (channel.equals(timeOn)) { + if (newValue.isPresent()) { + timeStart = LocalTime.parse((String) newValue.get()); + } else { + timeStart = null; + } + } else if (channel.equals(timeOff)) { + if (newValue.isPresent()) { + timeStop = LocalTime.parse((String) newValue.get()); + } else { + timeStop = null; + } + } + } +} From 0d1c6090dc6bf1ac490292c02b0c6f8c178d5853 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Ro=C3=9Fmann?= Date: Thu, 30 Nov 2017 18:00:06 +0100 Subject: [PATCH 07/55] add ThresholdOnController to start/stop ess according to possible power --- .../systemstate/powerthreshold/Ess.java | 80 +++++++++++ .../systemstate/powerthreshold/Meter.java | 65 +++++++++ .../powerthreshold/ThresholdOnController.java | 133 ++++++++++++++++++ 3 files changed, 278 insertions(+) create mode 100644 edge/src/io/openems/impl/controller/systemstate/powerthreshold/Ess.java create mode 100644 edge/src/io/openems/impl/controller/systemstate/powerthreshold/Meter.java create mode 100644 edge/src/io/openems/impl/controller/systemstate/powerthreshold/ThresholdOnController.java diff --git a/edge/src/io/openems/impl/controller/systemstate/powerthreshold/Ess.java b/edge/src/io/openems/impl/controller/systemstate/powerthreshold/Ess.java new file mode 100644 index 00000000000..f94686bb07d --- /dev/null +++ b/edge/src/io/openems/impl/controller/systemstate/powerthreshold/Ess.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * OpenEMS - Open Source Energy Management System + * Copyright (c) 2016 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.systemstate.powerthreshold; + +import java.util.ArrayList; +import java.util.List; + +import io.openems.api.channel.ReadChannel; +import io.openems.api.channel.WriteChannel; +import io.openems.api.controller.IsThingMap; +import io.openems.api.controller.ThingMap; +import io.openems.api.device.nature.ess.AsymmetricEssNature; +import io.openems.api.device.nature.ess.EssNature; +import io.openems.api.device.nature.ess.SymmetricEssNature; + +@IsThingMap(type = EssNature.class) +public class Ess extends ThingMap { + + public final WriteChannel setWorkState; + public final ReadChannel systemState; + public final ReadChannel soc; + public final ReadChannel minSoc; + private List> activePowerChannels = new ArrayList<>(); + + public enum State { + ON, OFF, UNKNOWN + } + + public State currentState = State.UNKNOWN; + + public Ess(EssNature ess) { + super(ess); + setWorkState = ess.setWorkState().required(); + systemState = ess.systemState().required(); + this.minSoc = ess.minSoc().required(); + this.soc = ess.soc().required(); + if (ess instanceof SymmetricEssNature) { + SymmetricEssNature e = (SymmetricEssNature) ess; + activePowerChannels.add(e.activePower().required()); + } else if (ess instanceof AsymmetricEssNature) { + AsymmetricEssNature e = (AsymmetricEssNature) ess; + activePowerChannels.add(e.activePowerL1().required()); + activePowerChannels.add(e.activePowerL2().required()); + activePowerChannels.add(e.activePowerL3().required()); + } + } + + public Long getPower() { + Long power = null; + for (ReadChannel powerChannel : activePowerChannels) { + if (powerChannel.valueOptional().isPresent()) { + if (power == null) { + power = powerChannel.valueOptional().get(); + } else { + power += powerChannel.valueOptional().get(); + } + } + } + return power; + } + +} diff --git a/edge/src/io/openems/impl/controller/systemstate/powerthreshold/Meter.java b/edge/src/io/openems/impl/controller/systemstate/powerthreshold/Meter.java new file mode 100644 index 00000000000..86a16ec294a --- /dev/null +++ b/edge/src/io/openems/impl/controller/systemstate/powerthreshold/Meter.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * OpenEMS - Open Source Energy Management System + * Copyright (c) 2016 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.systemstate.powerthreshold; + +import java.util.ArrayList; +import java.util.List; + +import io.openems.api.channel.ReadChannel; +import io.openems.api.controller.IsThingMap; +import io.openems.api.controller.ThingMap; +import io.openems.api.device.nature.meter.AsymmetricMeterNature; +import io.openems.api.device.nature.meter.MeterNature; +import io.openems.api.device.nature.meter.SymmetricMeterNature; + +@IsThingMap(type = MeterNature.class) +public class Meter extends ThingMap { + + private List> activePowerChannels = new ArrayList<>(); + + public Meter(MeterNature meter) { + super(meter); + if (meter instanceof SymmetricMeterNature) { + SymmetricMeterNature m = (SymmetricMeterNature) meter; + activePowerChannels.add(m.activePower().required()); + } else if (meter instanceof AsymmetricMeterNature) { + AsymmetricMeterNature m = (AsymmetricMeterNature) meter; + activePowerChannels.add(m.activePowerL1().required()); + activePowerChannels.add(m.activePowerL2().required()); + activePowerChannels.add(m.activePowerL3().required()); + } + } + + public Long getPower() { + Long power = null; + for (ReadChannel powerChannel : activePowerChannels) { + if (powerChannel.valueOptional().isPresent()) { + if (power == null) { + power = powerChannel.valueOptional().get(); + } else { + power += powerChannel.valueOptional().get(); + } + } + } + return power; + } + +} diff --git a/edge/src/io/openems/impl/controller/systemstate/powerthreshold/ThresholdOnController.java b/edge/src/io/openems/impl/controller/systemstate/powerthreshold/ThresholdOnController.java new file mode 100644 index 00000000000..1310fe90de0 --- /dev/null +++ b/edge/src/io/openems/impl/controller/systemstate/powerthreshold/ThresholdOnController.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * 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.systemstate.powerthreshold; + +import java.util.Set; + +import com.google.common.base.Optional; + +import io.openems.api.channel.ConfigChannel; +import io.openems.api.controller.Controller; +import io.openems.api.device.nature.ess.EssNature; +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.impl.controller.systemstate.powerthreshold.Ess.State; + +/** + * @author matthias.rossmann + */ +@ThingInfo(title = "Stop if not useable", description = "Starts the ess if the GridFeed power is lager than a defined threshold. The ess will be stoped if the ess are empty and the GridFeed power is below a defined threshold.") +public class ThresholdOnController extends Controller { + + /* + * Constructors + */ + public ThresholdOnController() { + super(); + } + + public ThresholdOnController(String thingId) { + super(thingId); + } + + /* + * Config + */ + @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class, isArray = true) + public final ConfigChannel> esss = new ConfigChannel>("esss", this); + + @ChannelInfo(title = "Grid-Meter", description = "Sets the grid meter.", type = Meter.class) + public final ConfigChannel meter = new ConfigChannel("meter", this); + + @ChannelInfo(title = "Power Threshold Start", description = "If the Grid-Feed Power is lager than this Threshold, the System will be started", type = Long.class) + public final ConfigChannel onThreshold = new ConfigChannel<>("onThreshold", this); + @ChannelInfo(title = "Power Threshold Stop", description = "If the Grid-Feed Power is smaler than this Threshold and the ess is empty, the System will be stopped.", type = Long.class) + public final ConfigChannel offThreshold = new ConfigChannel<>("offThreshold", this); + @ChannelInfo(title = "Time Lag Start", description = "The time the power has to be above the onThreshold to start the ess.", type = Long.class) + public final ConfigChannel onTimelag = new ConfigChannel<>("onTimelag", this); + @ChannelInfo(title = "Time Lag Stop", description = "The time,in minutes, the power has to be below the offThreshold to stop the ess.", type = Long.class) + public final ConfigChannel offTimelag = new ConfigChannel<>("offTimelag", this); + + /* + * Fields + */ + private long timePowerAboveStartThreshold = System.currentTimeMillis(); + private long timePowerBelowStopThreshold = System.currentTimeMillis(); + + /* + * Methods + */ + @Override + public void run() { + try { + long calculatedPower = meter.value().getPower(); + for (Ess ess : esss.value()) { + calculatedPower += ess.getPower(); + } + if (calculatedPower >= onThreshold.value()) { + timePowerAboveStartThreshold = System.currentTimeMillis(); + } + if (calculatedPower < offThreshold.value()) { + timePowerBelowStopThreshold = System.currentTimeMillis(); + } + for (Ess ess : esss.value()) { + switch (ess.currentState) { + case OFF: + if (System.currentTimeMillis() - timePowerAboveStartThreshold > onTimelag.value() * 1000 * 60) { + ess.currentState = State.ON; + } else { + try { + ess.setWorkState.pushWriteFromLabel(EssNature.STOP); + } catch (WriteChannelException e) { + log.error("", e); + } + } + break; + case ON: + if (System.currentTimeMillis() - timePowerBelowStopThreshold > offTimelag.value() * 1000 * 60 + && ess.soc.value() <= ess.minSoc.value()) { + ess.currentState = State.OFF; + } else { + try { + ess.setWorkState.pushWriteFromLabel(EssNature.START); + } catch (WriteChannelException e) { + log.error("", e); + } + } + break; + case UNKNOWN: + default: + if (ess.systemState.labelOptional().equals(Optional.of(EssNature.STOP))) { + ess.currentState = State.OFF; + } else { + ess.currentState = State.ON; + } + break; + } + + } + } catch (InvalidValueException e) { + log.error("No Storage Found!", e); + } + } +} From 271d5c150bcbfbd0075c3c61dc2cddda115832a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Ro=C3=9Fmann?= Date: Thu, 30 Nov 2017 18:00:31 +0100 Subject: [PATCH 08/55] add Constructor with json config --- .../simulator/FixValueLoadGenerator.java | 47 +++++++++++-------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/edge/src/io/openems/impl/device/simulator/FixValueLoadGenerator.java b/edge/src/io/openems/impl/device/simulator/FixValueLoadGenerator.java index 18c2719249f..248e48fe308 100644 --- a/edge/src/io/openems/impl/device/simulator/FixValueLoadGenerator.java +++ b/edge/src/io/openems/impl/device/simulator/FixValueLoadGenerator.java @@ -1,20 +1,27 @@ -package io.openems.impl.device.simulator; - -public class FixValueLoadGenerator implements LoadGenerator { - - private long value; - - public long getValue() { - return value; - } - - public void setValue(long value) { - this.value = value; - } - - @Override - public long getLoad() { - return value; - } - -} +package io.openems.impl.device.simulator; + +import com.google.gson.JsonObject; + +public class FixValueLoadGenerator implements LoadGenerator { + + private long value; + + public long getValue() { + return value; + } + + public void setValue(long value) { + this.value = value; + } + + @Override + public long getLoad() { + return value; + } + + public FixValueLoadGenerator(JsonObject config) { + this.value = config.get("value").getAsLong(); + } + + +} From d75b0d80126d84f06214a6aa70e6a11a55651a13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Ro=C3=9Fmann?= Date: Thu, 30 Nov 2017 18:00:52 +0100 Subject: [PATCH 09/55] add spanner bhkw doc --- .../io/openems/impl/device/spanner/Readme.md | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 edge/src/io/openems/impl/device/spanner/Readme.md diff --git a/edge/src/io/openems/impl/device/spanner/Readme.md b/edge/src/io/openems/impl/device/spanner/Readme.md new file mode 100644 index 00000000000..42d4bdc7fdf --- /dev/null +++ b/edge/src/io/openems/impl/device/spanner/Readme.md @@ -0,0 +1,32 @@ +# BHKW Meter + + +Following Values are implemented: + +|ChannelName|Unit| +|---|---| +|ActivePower|| +|ActivePowerL1|W| +|ActivePowerL2|W| +|ActivePowerL3|W| +|alias|| +|ApparentPower|| +|CosPhiL1|| +|CosPhiL2|| +|SocPhiL3|| +|CurrentL1|mA| +|CurrentL2|mA| +|CurrentL3|mA| +|FrequencyL3|mHZ| +|FrequencyL3|mHZ| +|maxActivePower|| +|minActivePower|| +|ReactivePower|| +|ReactivePowerL1|| +|ReactivePowerL2|| +|ReactivePowerL3|| +|type|| +|VoltageL1|mV| +|VoltageL1|mV| +|VoltageL2|mV| +|VoltageL3|mV| From 8eb0a110f5cf33fe4def794934da050818e7d30f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Ro=C3=9Fmann?= Date: Fri, 1 Dec 2017 16:48:53 +0100 Subject: [PATCH 10/55] add pro ess to readme --- edge/src/io/openems/impl/device/Readme.md | 1 + edge/src/io/openems/impl/device/pro/Readme.md | 109 ++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/edge/src/io/openems/impl/device/Readme.md b/edge/src/io/openems/impl/device/Readme.md index e5696bf72d1..63464f0a01b 100644 --- a/edge/src/io/openems/impl/device/Readme.md +++ b/edge/src/io/openems/impl/device/Readme.md @@ -13,6 +13,7 @@ * [KMTronic Relay board Output](kmtronic/Readme.md) * [KEBA KeContact EVCS](keba/Readme.md) * [Custom: Riedmann PLC](custom/riedmann/Readme.md) +* [FENECON Pro ESS](pro/Readme.md) * [Simulated Grid Meter](simulator/Readme.md) * [Simulator Output](simulator/Readme.md) * [FENECON Commercial ESS](commercial/Readme.md) diff --git a/edge/src/io/openems/impl/device/pro/Readme.md b/edge/src/io/openems/impl/device/pro/Readme.md index 3eae66dc7d8..5bcb49882f6 100644 --- a/edge/src/io/openems/impl/device/pro/Readme.md +++ b/edge/src/io/openems/impl/device/pro/Readme.md @@ -1,3 +1,112 @@ +# FENECON Pro ESS + + +Following Values are implemented: + +|ChannelName|Unit| +|---|---| +|ActivePowerL1|W| +|ActivePowerL2|W| +|ActivePowerL3|W| +|alias|| +|AllowedApparent|| +|AllowedCharge|W| +|AllowedDischarge|W| +|BatteryCurrent|mA| +|BatteryGroupAlarm|1: Fail, The system should be stopped
2: Common low voltage alarm
4: Common high voltage alarm
8: Charging over current alarm
16: Discharging over current alarm
32: Over temperature alarm
64: Interal communication abnormal
| +|BatteryGroupState|0: Initial
1: Stop
2: Starting
3: Running
4: Stopping
5: Fail
| +|BatteryPower|W| +|BatteryTemperatureSection1|°C| +|BatteryTemperatureSection10|°C| +|BatteryTemperatureSection11|°C| +|BatteryTemperatureSection12|°C| +|BatteryTemperatureSection13|°C| +|BatteryTemperatureSection14|°C| +|BatteryTemperatureSection15|°C| +|BatteryTemperatureSection16|°C| +|BatteryTemperatureSection2|°C| +|BatteryTemperatureSection3|°C| +|BatteryTemperatureSection4|°C| +|BatteryTemperatureSection5|°C| +|BatteryTemperatureSection6|°C| +|BatteryTemperatureSection7|°C| +|BatteryTemperatureSection8|°C| +|BatteryTemperatureSection9|°C| +|BatteryVoltage|mV| +|BatteryVoltageSection1|mV| +|BatteryVoltageSection10|mV| +|BatteryVoltageSection11|mV| +|BatteryVoltageSection12|mV| +|BatteryVoltageSection13|mV| +|BatteryVoltageSection14|mV| +|BatteryVoltageSection15|mV| +|BatteryVoltageSection16|mV| +|BatteryVoltageSection2|mV| +|BatteryVoltageSection3|mV| +|BatteryVoltageSection4|mV| +|BatteryVoltageSection5|mV| +|BatteryVoltageSection6|mV| +|BatteryVoltageSection7|mV| +|BatteryVoltageSection8|mV| +|BatteryVoltageSection9|mV| +|capacity|Wh| +|chargeSoc|| +|ControlMode|1: Remote
2: Local
| +|CurrentL1|mA| +|CurrentL2|mA| +|CurrentL3|mA| +|FrequencyL1|mHz| +|FrequencyL2|mHz| +|FrequencyL3|mHz| +|GridMode|0: Off-Grid
1: On-Grid
| +|maxNominalPower|VA| +|minSoc|| +|PcsAlarm1L1|1: Grid undervoltage
2: Grid overvoltage
4: Grid under frequency
8: Grid over frequency
16: Grid power supply off
32: Grid condition unmeet
64: DC under voltage
128: Input over resistance
256: Combination error
512: Comm with inverter error
1024: Tme error
| +|PcsAlarm1L2|1: Grid undervoltage
2: Grid overvoltage
4: Grid under frequency
8: Grid over frequency
16: Grid power supply off
32: Grid condition unmeet
64: DC under voltage
128: Input over resistance
256: Combination error
512: Comm with inverter error
1024: Tme error
| +|PcsAlarm1L3|1: Grid undervoltage
2: Grid overvoltage
4: Grid under frequency
8: Grid over frequency
16: Grid power supply off
32: Grid condition unmeet
64: DC under voltage
128: Input over resistance
256: Combination error
512: Comm with inverter error
1024: Tme error
| +|PcsAlarm2L1|| +|PcsAlarm2L2|| +|PcsAlarm2L3|| +|PcsFault1L1|1: Control current overload 100%
2: Control current overload 110%
4: Control current overload 150%
8: Control current overload 200%
16: Control current overload 120%
32: Control current overload 300%
64: Control transient load 300%
128: Grid over current
256: Locking waveform too many times
512: Inverter voltage zero drift error
1024: Grid voltage zero drift error
2048: Control current zero drift error
4096: Inverter current zero drift error
8192: Grid current zero drift error
16384: PDP protection
32768: Hardware control current protection
| +|PcsFault1L2|1: Control current overload 100%
2: Control current overload 110%
4: Control current overload 150%
8: Control current overload 200%
16: Control current overload 120%
32: Control current overload 300%
64: Control transient load 300%
128: Grid over current
256: Locking waveform too many times
512: Inverter voltage zero drift error
1024: Grid voltage zero drift error
2048: Control current zero drift error
4096: Inverter current zero drift error
8192: Grid current zero drift error
16384: PDP protection
32768: Hardware control current protection
| +|PcsFault1L3|1: Control current overload 100%
2: Control current overload 110%
4: Control current overload 150%
8: Control current overload 200%
16: Control current overload 120%
32: Control current overload 300%
64: Control transient load 300%
128: Grid over current
256: Locking waveform too many times
512: Inverter voltage zero drift error
1024: Grid voltage zero drift error
2048: Control current zero drift error
4096: Inverter current zero drift error
8192: Grid current zero drift error
16384: PDP protection
32768: Hardware control current protection
| +|PcsFault2L1|1: Hardware AC volt. protection
2: Hardware DC curr. protection
4: Hardware temperature protection
8: No capturing signal
16: DC overvoltage
32: DC disconnected
64: Inverter undervoltage
128: Inverter overvoltage
256: Current sensor fail
512: Voltage sensor fail
1024: Power uncontrollable
2048: Current uncontrollable
4096: Fan error
8192: Phase lack
16384: Inverter relay fault
32768: Grid relay fault
| +|PcsFault2L2|1: Hardware AC volt. protection
2: Hardware DC curr. protection
4: Hardware temperature protection
8: No capturing signal
16: DC overvoltage
32: DC disconnected
64: Inverter undervoltage
128: Inverter overvoltage
256: Current sensor fail
512: Voltage sensor fail
1024: Power uncontrollable
2048: Current uncontrollable
4096: Fan error
8192: Phase lack
16384: Inverter relay fault
32768: Grid relay fault
| +|PcsFault2L3|1: Hardware AC volt. protection
2: Hardware DC curr. protection
4: Hardware temperature protection
8: No capturing signal
16: DC overvoltage
32: DC disconnected
64: Inverter undervoltage
128: Inverter overvoltage
256: Current sensor fail
512: Voltage sensor fail
1024: Power uncontrollable
2048: Current uncontrollable
4096: Fan error
8192: Phase lack
16384: Inverter relay fault
32768: Grid relay fault
| +|PcsFault3L1|1: Control panel overtemp
2: Power panel overtemp
4: DC input overcurrent
8: Capacitor overtemp
16: Radiator overtemp
32: Transformer overtemp
64: Combination comm error
128: EEPROM error
256: Load current zero drift error
512: Current limit-R error
1024: Phase sync error
2048: External PV current zero drift error
4096: External grid current zero drift error
| +|PcsFault3L2|1: Control panel overtemp
2: Power panel overtemp
4: DC input overcurrent
8: Capacitor overtemp
16: Radiator overtemp
32: Transformer overtemp
64: Combination comm error
128: EEPROM error
256: Load current zero drift error
512: Current limit-R error
1024: Phase sync error
2048: External PV current zero drift error
4096: External grid current zero drift error
| +|PcsFault3L3|1: Control panel overtemp
2: Power panel overtemp
4: DC input overcurrent
8: Capacitor overtemp
16: Radiator overtemp
32: Transformer overtemp
64: Combination comm error
128: EEPROM error
256: Load current zero drift error
512: Current limit-R error
1024: Phase sync error
2048: External PV current zero drift error
4096: External grid current zero drift error
| +|PcsMode|0: Emergency
1: ConsumersPeakPattern
2: Economic
3: Eco
4: Debug
5: SmoothPv
6: Remote
| +|PcsOperationState|0: Self-checking
1: Standby
2: Off grid PV
3: Off grid
4: On-Grid
5: Fail
6: bypass 1
7: bypass 2
| +|PhaseAllowedApparentPower|VA| +|ReactivePowerL1|var| +|ReactivePowerL2|var| +|ReactivePowerL3|var| +|Day|| +|Hour|| +|Minute|| +|Month|| +|Second|| +|Year|| +|SetActivePowerL1|W| +|SetActivePowerL2|W| +|SetActivePowerL3|W| +|SetPcsMode|0: Emergency
1: ConsumersPeakPattern
2: Economic
3: Eco
4: Debug
5: SmoothPv
6: Remote
| +|SetReactivePowerL1|Var| +|SetReactivePowerL2|Var| +|SetReactivePowerL3|Var| +|SetSetupMode|0: Off
1: On
| +|SetWorkState|0: Local control
1: Start
2: Remote control off grid starting
3: Standby
4: Stop
| +|SetupMode|0: Off
1: On
| +|Soc|%| +|SystemState|0: Standby
1: Start Off-Grid
2: Start
3: Fault
4: Off-grid PV
| +|TotalBatteryChargeEnergy|Wh| +|TotalBatteryDischargeEnergy|Wh| +|VoltageL1|mV| +|VoltageL2|mV| +|VoltageL3|mV| +|Warning|| +|WorkMode|2: Economy
6: Remote
8: Timing
| # FENECON Pro Meter From d855fe4424a4d0ad60460b548e2f4b8aff0282f3 Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Thu, 7 Dec 2017 11:54:27 +0100 Subject: [PATCH 11/55] Reset version to 1.8.0-SNAPSHOT --- backend/pom.xml | 2 +- common/pom.xml | 2 +- edge/pom.xml | 2 +- ui/pom.xml | 2 +- ui/src/app/about/about.component.html | 8 ++++---- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/backend/pom.xml b/backend/pom.xml index 4f8294e5a3a..e5347760e34 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -5,7 +5,7 @@ http://openems.io io.openems edge - 1.7.1 + 1.8.0-SNAPSHOT jar https://github.com/OpenEMS/openems diff --git a/common/pom.xml b/common/pom.xml index b8a0378d7b8..f70db0b716a 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -5,7 +5,7 @@ http://openems.io io.openems common - 1.7.1 + 1.8.0-SNAPSHOT jar https://github.com/OpenEMS/openems diff --git a/edge/pom.xml b/edge/pom.xml index c45ec706482..0f4117d0541 100644 --- a/edge/pom.xml +++ b/edge/pom.xml @@ -5,7 +5,7 @@ http://openems.io io.openems edge - 1.7.1 + 1.8.0-SNAPSHOT jar https://github.com/OpenEMS/openems diff --git a/ui/pom.xml b/ui/pom.xml index 22d120aebca..e6c4ad5c1c9 100644 --- a/ui/pom.xml +++ b/ui/pom.xml @@ -7,7 +7,7 @@ io.openems pom - 1.7.1 + 1.8.0-SNAPSHOT edge pom diff --git a/ui/src/app/about/about.component.html b/ui/src/app/about/about.component.html index b080627a381..cfa0c59ecd2 100644 --- a/ui/src/app/about/about.component.html +++ b/ui/src/app/about/about.component.html @@ -16,14 +16,14 @@
  • About.Sourcecode
  • -
  • + +
  • About.Build: v1.8.0-SNAPSHOT -
  • --> +

    From 9adbceea2c5a0862aaa5b1b2de5b98ae922e29ec Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Mon, 11 Dec 2017 11:50:09 +0100 Subject: [PATCH 12/55] Update angular-cli to 1.6 --- ui/package-lock.json | 232 +++++++++++++++++++++---------------------- ui/package.json | 7 +- ui/src/polyfills.ts | 2 +- ui/tslint.json | 1 - 4 files changed, 119 insertions(+), 123 deletions(-) diff --git a/ui/package-lock.json b/ui/package-lock.json index 61b43f78a4c..93e0e809964 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -1,13 +1,13 @@ { "name": "openems-ui", - "version": "1.7.0-SNAPSHOT", + "version": "1.8.0-SNAPSHOT", "lockfileVersion": 1, "requires": true, "dependencies": { "@angular-devkit/build-optimizer": { - "version": "0.0.34", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.0.34.tgz", - "integrity": "sha512-uSvyKtkDnfnBt6GGJ0m1nFI9IylKq6KoQil04GobhDCXFyin6Gbr50focx3jaizwDuh4v/x11fEUi5/cSUkKhA==", + "version": "0.0.35", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.0.35.tgz", + "integrity": "sha512-7JxZZAYFSCc0tP6+NrRn3b2Cd1b9d+a3+OfwVNyNsNd2unelqUMko2hm0KLbC8BXcXt/OILg1E/ZgLAXSS47nw==", "dev": true, "requires": { "loader-utils": "1.1.0", @@ -34,13 +34,14 @@ } }, "@angular-devkit/schematics": { - "version": "0.0.38", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-0.0.38.tgz", - "integrity": "sha512-vvyn7p/t4EKLSONGIw9jot9iMM3lEvdMDfnLkgubznIiIFxH9I+aYw9BBV2AmwE7OASHrCRpwFf7K2EqJ0f9+A==", + "version": "0.0.41", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-0.0.41.tgz", + "integrity": "sha512-eSXyRLM7g9NvNUwDd71iPjHEL0Zutg9PcLUSCrwFXR3Z8S6iStO2FpZACNmz5/Y7ksWLy5/1wjLuDJCHS4X/ig==", "dev": true, "requires": { "@angular-devkit/core": "0.0.22", "@ngtools/json-schema": "1.1.0", + "@schematics/schematics": "0.0.10", "minimist": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "rxjs": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.2.tgz" } @@ -53,27 +54,27 @@ } }, "@angular/cdk": { - "version": "5.0.0-rc.2", - "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-5.0.0-rc.2.tgz", - "integrity": "sha512-/qQu+VXwBaFbn0eZDcRmY/RFyWTxdo/sWbkhnQlpGjrjbCs4Xj3CNHJxQwBVpowkjWguisc3PQQI2mvdJ0p0Rw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-5.0.0.tgz", + "integrity": "sha512-+u67Bns23tuCUGUCWhqkR/+onCwB4ObRURUv7ar2+BHw5VIvzML+IOCi1BJRF7gqvL+IVYQpLuY2cQh0J2SbBQ==", "requires": { "tslib": "https://registry.npmjs.org/tslib/-/tslib-1.8.0.tgz" } }, "@angular/cli": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-1.5.5.tgz", - "integrity": "sha512-qAooJraZwT9o2W7yx6gY6fnc7PEMlGzu60ELZJfC51MnoYMPKiIEFYeWanCSNju1P7jfpeBXuwp1qEMZCX73Zw==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-1.6.0.tgz", + "integrity": "sha512-X049QAgSKy5J48byyo3T6iBTHubTC66QBMshMpTT7PWAaSq3HpPPE1xW0WwgFIXZWMQIsmncaqPwmnFmxljUdw==", "dev": true, "requires": { - "@angular-devkit/build-optimizer": "0.0.34", - "@angular-devkit/schematics": "0.0.38", + "@angular-devkit/build-optimizer": "0.0.35", + "@angular-devkit/schematics": "0.0.41", "@ngtools/json-schema": "1.1.0", - "@ngtools/webpack": "1.8.5", - "@schematics/angular": "0.1.8", + "@ngtools/webpack": "1.9.0", + "@schematics/angular": "0.1.10", "autoprefixer": "6.7.7", "chalk": "2.2.2", - "circular-dependency-plugin": "3.0.0", + "circular-dependency-plugin": "4.3.0", "common-tags": "1.5.1", "copy-webpack-plugin": "4.2.3", "core-object": "3.1.5", @@ -82,9 +83,9 @@ "denodeify": "1.2.1", "ember-cli-string-utils": "1.1.0", "exports-loader": "0.6.4", - "extract-text-webpack-plugin": "3.0.0", + "extract-text-webpack-plugin": "3.0.2", "file-loader": "1.1.5", - "fs-extra": "4.0.2", + "fs-extra": "4.0.3", "glob": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", "html-webpack-plugin": "2.30.1", "istanbul-instrumenter-loader": "2.0.0", @@ -114,15 +115,15 @@ "style-loader": "0.13.2", "stylus": "0.54.5", "stylus-loader": "3.0.1", - "uglifyjs-webpack-plugin": "1.0.0", + "uglifyjs-webpack-plugin": "1.1.2", "url-loader": "0.6.2", - "webpack": "3.8.1", - "webpack-concat-plugin": "1.4.0", + "webpack": "3.10.0", + "webpack-concat-plugin": "1.4.2", "webpack-dev-middleware": "1.12.2", - "webpack-dev-server": "2.9.5", + "webpack-dev-server": "2.9.7", "webpack-merge": "4.1.1", "webpack-sources": "1.1.0", - "webpack-subresource-integrity": "1.0.1", + "webpack-subresource-integrity": "1.0.3", "zone.js": "https://registry.npmjs.org/zone.js/-/zone.js-0.8.18.tgz" }, "dependencies": { @@ -223,9 +224,9 @@ "dev": true }, "@angular/material": { - "version": "5.0.0-rc.2", - "resolved": "https://registry.npmjs.org/@angular/material/-/material-5.0.0-rc.2.tgz", - "integrity": "sha512-ecwzpNItU3mFjHxq802dkvMKfuZ3A18P+eSmXRDvLPBW6G0egm3mCincEepESQ75pRkRE35CSeYR/Peiy7Hzww==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@angular/material/-/material-5.0.0.tgz", + "integrity": "sha512-rzF061r4aYgaf2WI12Jk0+Rd4c1VBObdeMDFWRa3XKIcvETtkz+DXFH1n+vIC4YabfPgrdJRPrzdrZ7fKhRz6g==", "requires": { "tslib": "https://registry.npmjs.org/tslib/-/tslib-1.8.0.tgz" } @@ -267,9 +268,9 @@ "dev": true }, "@ngtools/webpack": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-1.8.5.tgz", - "integrity": "sha512-caqEQuxypjZTQkO4wRykX4Mp7FCHUApTym5Yjr6VuM+zR4uVzjBceIaT/3a0X+p6iU4dmd6DpT2y96xki/YVSQ==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-1.9.0.tgz", + "integrity": "sha512-+9EFOELj9D7zarsKTiIFSbTL2Pr3jYdRJ/cEuSoTxzZUDq7f3urq9ILbcy3DTaDlZs2CCYKwgz+In8QnDtw4fg==", "dev": true, "requires": { "chalk": "2.2.2", @@ -324,14 +325,20 @@ "integrity": "sha1-AA8thjxMlMgY4UFu9DzKLFwMWEg=" }, "@schematics/angular": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-0.1.8.tgz", - "integrity": "sha512-88QrOoS0gQ6BdKulP01dTPmfPwLhvzb4jCcKkp0g8kvzTkIadlORmC9bQtucJI5huPU2bglVfmPgAk2ZwMSLDA==", + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-0.1.10.tgz", + "integrity": "sha512-ykq4FL0WTygkpvIcGDxnxHHT2uvJMWseDeAujmfyZpzdT9X22GOTURNo3LjvOIhhVUpMVZvnAYqjV46KqB702g==", "dev": true, "requires": { "@angular-devkit/core": "0.0.22" } }, + "@schematics/schematics": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/@schematics/schematics/-/schematics-0.0.10.tgz", + "integrity": "sha512-9vr9W1X6oRp42pbiGRIk3L+T6SoFtHlAGrzbh6rbFQDNXT4UCHarqDigow+DEL6PR2ptXZO9WeLcad4it7zNyA==", + "dev": true + }, "@types/d3": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/@types/d3/-/d3-4.12.0.tgz", @@ -372,12 +379,12 @@ "@types/d3-array": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-1.2.1.tgz", - "integrity": "sha512-YBaAfimGdWE4nDuoGVKsH89/dkz2hWZ0i8qC+xxqmqi+XJ/aXiRF0jPtzXmN7VdkpVjy1xuDmM5/m1FNuB6VWA==" + "integrity": "sha1-5IlgUgjUahydmA0uV3L6nHXZ7GU=" }, "@types/d3-axis": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-1.0.9.tgz", - "integrity": "sha512-fNUnI2a0F3xiE/nGrTdDpZG4sdcRIB4X59p9jgY8O7RQiKrVqyb433YCCYSqVID4CVyoq5v3bSFliUEk0FOMsw==", + "integrity": "sha1-Ys57yNBDVCmM2lfz8dH4Vq1puJo=", "requires": { "@types/d3-selection": "1.2.0" } @@ -413,7 +420,7 @@ "@types/d3-drag": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-1.2.0.tgz", - "integrity": "sha512-AePmm0sXj0Tpl0uQWvwmbAf1QR3yCy9aRhjJ9mRDDSZlHBdY0SCpUtdZC9uG9Q+pyHT/dEt1R2FT/sj+5k/bVA==", + "integrity": "sha1-XuYnlDLIlPhcty/NqRGpWbrhGVI=", "requires": { "@types/d3-selection": "1.2.0" } @@ -431,12 +438,12 @@ "@types/d3-force": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-1.1.0.tgz", - "integrity": "sha512-a39Uu/ltLaMpj6K0elEB1oAqhx9rlTB5X/O75uTUqyTW2CfjhPXg6hFsX1lF8oeMc29kqGJZ4g9Pf6mET25bVw==" + "integrity": "sha1-QJJco1ErY71CT3yWheF4G1sKHX4=" }, "@types/d3-format": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-1.2.1.tgz", - "integrity": "sha512-dXhA9jzCbzu6Va8ZVUQ60nu6jqA5vhPhKGR4nY3lDYfjT05GyKEKuEhfwTaSTybWczY4nLEkzv9wLQCQd5+3cA==" + "integrity": "sha1-lDX7F3HS+/aoWMkyGPQJfJqjlsE=" }, "@types/d3-geo": { "version": "1.9.4", @@ -462,7 +469,7 @@ "@types/d3-path": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-1.0.6.tgz", - "integrity": "sha512-YHW4cs+wOU9gFUzudjJs9TkrB/8GOgKhq32ZyNaZ2rzZjOhkqG486sGr9XSh4C91CcgIg1FRGoDaN29Ropx9nw==" + "integrity": "sha1-wafS3Aeylf3RyE2r5EBN+ZG0hpM=" }, "@types/d3-polygon": { "version": "1.0.5", @@ -495,7 +502,7 @@ "@types/d3-scale": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-1.0.10.tgz", - "integrity": "sha512-2CCyRc9o7oawNqNXuv6P1QBFH4PYnZt4IZK6J5nKykQjzezPC/RqCeRDBTk0JhBC8pLcLWYzGR6G2zG2OUwPag==", + "integrity": "sha1-jFwdylShWe7QQrRnGduzvbfoyEI=", "requires": { "@types/d3-time": "1.0.7" } @@ -508,7 +515,7 @@ "@types/d3-shape": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-1.2.1.tgz", - "integrity": "sha512-y0QmQtKns0IHBoG80yGLo6rmznHjZs/JODxc9kOgQgkCUe2e07X9DPghXE1KbTTAIr9U85Xm8YSbSzx/ytxyYg==", + "integrity": "sha1-ysLZ8BIvFzIgwyyMFS3ELuk0nfI=", "requires": { "@types/d3-path": "1.0.6" } @@ -516,12 +523,12 @@ "@types/d3-time": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-1.0.7.tgz", - "integrity": "sha512-X5ZQYiJIM38XygNwld4gZ++Vtw2ftgo3KOfZOY4n/sCudUxclxf/3THBvuG8UqSV+EQ0ezYjT5eyvcrrmixOWA==" + "integrity": "sha1-QmbXyb4V+oElaojR0FLWHNjcVyw=" }, "@types/d3-time-format": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-2.1.0.tgz", - "integrity": "sha512-/myT3I7EwlukNOX2xVdMzb8FRgNzRMpsZddwst9Ld/VFe6LyJyRp0s32l/V9XoUzk+Gqu56F/oGk6507+8BxrA==" + "integrity": "sha1-AR4Pt5N740qaj1gK4eLy8TNqiiI=" }, "@types/d3-timer": { "version": "1.0.6", @@ -531,7 +538,7 @@ "@types/d3-transition": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-1.1.1.tgz", - "integrity": "sha512-GHTghl0YYB8gGgbyKxVLHyAp9Na0HqsX2U7M0u0lGw4IdfEaslooykweZ8fDHW13T+KZeZAuzhbmqBZVFO+6kg==", + "integrity": "sha1-wgn85qlm1mljVt1CsJGpxsx5kp8=", "requires": { "@types/d3-selection": "1.2.0" } @@ -539,12 +546,12 @@ "@types/d3-voronoi": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/@types/d3-voronoi/-/d3-voronoi-1.1.7.tgz", - "integrity": "sha512-/dHFLK5jhXTb/W4XEQcFydVk8qlIAo85G3r7+N2fkBFw190l0R1GQ8C1VPeXBb2GfSU5GbT2hjlnE7i7UY5Gvg==" + "integrity": "sha1-wKFFzwQ5WSfgFwb/bE/4Ncl6js4=" }, "@types/d3-zoom": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-1.7.0.tgz", - "integrity": "sha512-eIivt2ehMUXqS0guuVzRSMr5RGhO958g9EKxIJv3Z23suPnX4VQI9k1TC/bLuwKq0IWp9a1bEEcIy+PNJv9BtA==", + "integrity": "sha1-EiG79kNIIPBEyAtVHFUZuBcAiWE=", "requires": { "@types/d3-interpolate": "1.1.6", "@types/d3-selection": "1.2.0" @@ -895,7 +902,7 @@ "dev": true, "requires": { "browserslist": "1.7.7", - "caniuse-db": "1.0.30000775", + "caniuse-db": "1.0.30000782", "normalize-range": "0.1.2", "num2fraction": "1.2.2", "postcss": "5.2.18", @@ -1271,8 +1278,8 @@ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", "dev": true, "requires": { - "caniuse-db": "1.0.30000775", - "electron-to-chromium": "1.3.27" + "caniuse-db": "1.0.30000782", + "electron-to-chromium": "1.3.28" } }, "buffer": { @@ -1374,15 +1381,15 @@ "dev": true, "requires": { "browserslist": "1.7.7", - "caniuse-db": "1.0.30000775", + "caniuse-db": "1.0.30000782", "lodash.memoize": "4.1.2", "lodash.uniq": "4.5.0" } }, "caniuse-db": { - "version": "1.0.30000775", - "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000775.tgz", - "integrity": "sha1-BLzN0CFO3yW5f2GglmCfetaQQzM=", + "version": "1.0.30000782", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000782.tgz", + "integrity": "sha1-2IFbzhV4w1Cs7REyUHMBIF4Pq1M=", "dev": true }, "caseless": { @@ -1521,9 +1528,9 @@ } }, "circular-dependency-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-3.0.0.tgz", - "integrity": "sha1-m2hpLjWw41EJmNAWS2rlARvqV2A=", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-4.3.0.tgz", + "integrity": "sha512-L3W9L1S0wC64rq+QSaZzmWnJW7cVBgimxI2lNEFEX5biwlRG8EHRM68JFi+CX5ZkCGUWJHIpnhdVs181Zlq3wA==", "dev": true }, "clap": { @@ -2218,7 +2225,7 @@ "d3-drag": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.1.tgz", - "integrity": "sha512-Cg8/K2rTtzxzrb0fmnYOUeZHvwa4PHzwXOLZZPwtEs2SKLLKLXeYwZKBB+DlOxUvFmarOnmt//cU4+3US2lyyQ==", + "integrity": "sha1-343UxQL7SQ/HRiBGqK2YpcR5KC0=", "requires": { "d3-dispatch": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.3.tgz", "d3-selection": "1.2.0" @@ -2363,7 +2370,7 @@ "d3-request": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/d3-request/-/d3-request-1.0.6.tgz", - "integrity": "sha512-FJj8ySY6GYuAJHZMaCQ83xEYE4KbkPkmxZ3Hu6zA1xxG2GD+z6P+Lyp+zjdsHf0xEbp2xcluDI50rCS855EQ6w==", + "integrity": "sha1-oQRKnvTsKMgkFxyTefrm15R0sZ8=", "requires": { "d3-collection": "https://registry.npmjs.org/d3-collection/-/d3-collection-1.0.4.tgz", "d3-dispatch": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.3.tgz", @@ -2738,9 +2745,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.27", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.27.tgz", - "integrity": "sha1-eOy4o5kGYYe7N07t412ccFZagD0=", + "version": "1.3.28", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.28.tgz", + "integrity": "sha1-jdTmRYCGZE6fnwoc8y4qH53/2e4=", "dev": true }, "elliptic": { @@ -2897,12 +2904,12 @@ "dev": true }, "errno": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.4.tgz", - "integrity": "sha1-uJbiOp5ei6M4cfyZar02NfyaHH0=", + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.5.tgz", + "integrity": "sha512-tv2H+e3KBnMmNRuoVG24uorOj3XfYo+/nJJd07PUISRr0kaMKQKL5kyD+6ANXk1ZIIsvbORsjvHnCfC4KIc7uQ==", "dev": true, "requires": { - "prr": "0.0.0" + "prr": "1.0.1" } }, "error-ex": { @@ -3267,9 +3274,9 @@ } }, "extract-text-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.0.tgz", - "integrity": "sha1-kMqnkHvESfM1AF46x1MrQbAN5hI=", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.2.tgz", + "integrity": "sha512-bt/LZ4m5Rqt/Crl2HiKuAl/oqg0psx1tsTLkvWbJen1CtD+fftkZhMaQ9HOtY2gWsl2Wq+sABmMVi9z3DhKWQQ==", "dev": true, "requires": { "async": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", @@ -3466,9 +3473,9 @@ } }, "fs-extra": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.2.tgz", - "integrity": "sha1-+RcExT0bRh+JNFKwwwfZmXZHq2s=", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", "dev": true, "requires": { "graceful-fs": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", @@ -3850,7 +3857,7 @@ "ncname": "1.0.0", "param-case": "2.1.1", "relateurl": "0.2.7", - "uglify-js": "3.2.0" + "uglify-js": "3.2.2" }, "dependencies": { "commander": { @@ -4946,7 +4953,7 @@ "integrity": "sha1-zBJg9RyQCp7A2R+2mYE54CUHtjs=", "dev": true, "requires": { - "errno": "0.1.4", + "errno": "0.1.5", "graceful-fs": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", "image-size": "0.5.5", "mime": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", @@ -5431,7 +5438,7 @@ "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", "dev": true, "requires": { - "errno": "0.1.4", + "errno": "0.1.5", "readable-stream": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz" } }, @@ -7452,9 +7459,9 @@ } }, "prr": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz", - "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", "dev": true }, "pseudomap": { @@ -7546,13 +7553,6 @@ "integrity": "sha1-DPf4T5Rj/wrlHExLFC2VvjdyTZw=", "dev": true }, - "queueing-subject": { - "version": "https://registry.npmjs.org/queueing-subject/-/queueing-subject-0.1.1.tgz", - "integrity": "sha1-Q/hXsrJjJ2/0GM3YZbfXjV1kHZ0=", - "requires": { - "rxjs": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.2.tgz" - } - }, "randomatic": { "version": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", "integrity": "sha1-x6vpzIuHwLqodrGf3oP9RkeX44w=", @@ -8995,9 +8995,9 @@ "dev": true }, "uglify-js": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.2.0.tgz", - "integrity": "sha512-L98DlTshoPGnZGF8pr3MoE+CCo6n9joktHNHMPkckeBV8xTVc4CWtC0kGGhQsIvnX2Ug4nXFTAeE7SpTrPX2tg==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.2.2.tgz", + "integrity": "sha512-++1NO/zZIEdWf6cDIGceSJQPX31SqIpbVAHwFG5+240MtZqPG/NIPoinj8zlXQtAfMBqEt1Jyv2FiLP3n9gVhQ==", "dev": true, "requires": { "commander": "2.12.2", @@ -9025,16 +9025,16 @@ "optional": true }, "uglifyjs-webpack-plugin": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.0.0.tgz", - "integrity": "sha1-HFi12x7QQ+AkrvZvit4l4UggYmQ=", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.1.2.tgz", + "integrity": "sha512-k07cmJTj+8vZMSc3BaQ9uW7qVl2MqDts4ti4KaNACXEcXSw2vQM2S8olSk/CODxvcSFGvUHzNSqA8JQlhgUJPw==", "dev": true, "requires": { "cacache": "10.0.1", "find-cache-dir": "1.0.0", "schema-utils": "0.3.0", - "source-map": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "uglify-es": "3.2.0", + "source-map": "0.6.1", + "uglify-es": "3.2.2", "webpack-sources": "1.1.0", "worker-farm": "1.5.2" }, @@ -9045,22 +9045,20 @@ "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==", "dev": true }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, "uglify-es": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.2.0.tgz", - "integrity": "sha512-eD4rjK4o6rzrvE1SMZJLQFEVMnWRUyIu6phJ0BXk5TIthMmP5B4QP0HI8o3bkQB5wf1N4WHA0leZAQyQBAd+Jg==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.2.2.tgz", + "integrity": "sha512-l+s5VLzFwGJfS+fbqaGf/Dfwo1MF13jLOF2ekL0PytzqEqQ6cVppvHf4jquqFok+35USMpKjqkYxy6pQyUcuug==", "dev": true, "requires": { "commander": "2.12.2", "source-map": "0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", - "dev": true - } } } } @@ -9359,9 +9357,9 @@ } }, "webpack": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.8.1.tgz", - "integrity": "sha1-sWloqBEAq+YWCLAVPJFZ74uyvYM=", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.10.0.tgz", + "integrity": "sha512-fxxKXoicjdXNUMY7LIdY89tkJJJ0m1Oo8PQutZ5rLgWbV5QVKI15Cn7+/IHnRTd3vfKfiwBx6SBqlorAuNA8LA==", "dev": true, "requires": { "acorn": "5.2.1", @@ -9642,9 +9640,9 @@ } }, "webpack-concat-plugin": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/webpack-concat-plugin/-/webpack-concat-plugin-1.4.0.tgz", - "integrity": "sha1-pus/AILQPHnY7i8VGMf0jkTuEsU=", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/webpack-concat-plugin/-/webpack-concat-plugin-1.4.2.tgz", + "integrity": "sha512-HdV2xOq4twtL2ThR9NSCCQ888v1JBMpJfm3k2mA1I5LkS2+/6rv8q/bb9yTSaR0fVaMtANZi4Wkz0xc33MAt6w==", "dev": true, "requires": { "md5": "2.2.1", @@ -9748,9 +9746,9 @@ } }, "webpack-dev-server": { - "version": "2.9.5", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.9.5.tgz", - "integrity": "sha512-o0lS6enIxyOPiRJTh8vcgK5TsGNTn7lH1q/pNniAgs46mCE8sQYeqv7Y/oAIh/+u4kiBsFizLJo5EWC+ezz6FQ==", + "version": "2.9.7", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.9.7.tgz", + "integrity": "sha512-Pu7uoQFgQj5RE5wmlfkpYSzihMKxulwEuO2xCsaMnAnyRSApwoVi3B8WCm9XbigyWTHaIMzYGkB90Vr6leAeTQ==", "dev": true, "requires": { "ansi-html": "0.0.7", @@ -9872,9 +9870,9 @@ } }, "webpack-subresource-integrity": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-1.0.1.tgz", - "integrity": "sha1-H8CdRkl9pm5GdDoqUdLMOFucsO0=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-1.0.3.tgz", + "integrity": "sha1-wGBtQAkLBwzeQovsjfNgMhbkcus=", "dev": true, "requires": { "webpack-core": "0.6.9" @@ -9947,7 +9945,7 @@ "integrity": "sha512-XxiQ9kZN5n6mmnW+mFJ+wXjNNI/Nx4DIdaAKLX1Bn6LYBWlN/zaBhu34DQYPZ1AJobQuu67S2OfDdNSVULvXkQ==", "dev": true, "requires": { - "errno": "0.1.4", + "errno": "0.1.5", "xtend": "4.0.1" } }, diff --git a/ui/package.json b/ui/package.json index d4ba9857791..bd024984051 100644 --- a/ui/package.json +++ b/ui/package.json @@ -15,14 +15,14 @@ "private": true, "dependencies": { "@angular/animations": "^5.0.0", - "@angular/cdk": "5.0.0-rc.2", + "@angular/cdk": "^5.0.0", "@angular/common": "^5.0.0", "@angular/compiler": "^5.0.0", "@angular/core": "^5.0.0", "@angular/flex-layout": "2.0.0-beta.10-4905443", "@angular/forms": "^5.0.0", "@angular/http": "^5.0.0", - "@angular/material": "5.0.0-rc.2", + "@angular/material": "^5.0.0", "@angular/platform-browser": "^5.0.0", "@angular/platform-browser-dynamic": "^5.0.0", "@angular/platform-server": "^5.0.0", @@ -53,7 +53,6 @@ "ng2-charts": "^1.6.0", "ng2-cookies": "^1.0.12", "ngx-loading": "^1.0.9", - "queueing-subject": "^0.1.1", "roboto-fontface": "0.8.0", "rxjs": "^5.5.2", "rxjs-websockets": "4.0.0", @@ -61,7 +60,7 @@ "zone.js": "^0.8.14" }, "devDependencies": { - "@angular/cli": "1.5.5", + "@angular/cli": "1.6.0", "@angular/compiler-cli": "^5.0.0", "@angular/language-service": "^5.0.0", "@types/jasmine": "~2.5.53", diff --git a/ui/src/polyfills.ts b/ui/src/polyfills.ts index 8675ae82049..87abf4d27d2 100644 --- a/ui/src/polyfills.ts +++ b/ui/src/polyfills.ts @@ -56,7 +56,7 @@ import 'web-animations-js'; // Run `npm install --save web-animations-js`. /*************************************************************************************************** - * Zone JS is required by Angular itself. + * Zone JS is required by default for Angular itself. */ import 'zone.js/dist/zone'; // Included with Angular CLI. diff --git a/ui/tslint.json b/ui/tslint.json index 20ad878fe78..a2e30eff294 100644 --- a/ui/tslint.json +++ b/ui/tslint.json @@ -130,7 +130,6 @@ "app", "kebab-case" ], - "angular-whitespace": [true, "check-interpolation"], "no-output-on-prefix": true, "use-input-property-decorator": true, "use-output-property-decorator": true, From 1aecaac8dab082c9c9bcf48b8396a9b706b1cbf3 Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Tue, 12 Dec 2017 17:31:57 +0100 Subject: [PATCH 13/55] Ignore -10000 for Mini grid meter --- .../impl/device/minireadonly/FeneconMiniGridMeter.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/edge/src/io/openems/impl/device/minireadonly/FeneconMiniGridMeter.java b/edge/src/io/openems/impl/device/minireadonly/FeneconMiniGridMeter.java index 55eb43e0937..c123feefd99 100644 --- a/edge/src/io/openems/impl/device/minireadonly/FeneconMiniGridMeter.java +++ b/edge/src/io/openems/impl/device/minireadonly/FeneconMiniGridMeter.java @@ -93,14 +93,15 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { ModbusProtocol protocol = new ModbusProtocol( // new ModbusRegisterRange(4004, // new SignedWordElement(4004, // - this.activePower = new ModbusReadLongChannel("ActivePower", this).unit("W").negate())), + this.activePower = new ModbusReadLongChannel("ActivePower", this).unit("W").negate() + .ignore(-10000l))), new ModbusRegisterRange(5003, // new UnsignedDoublewordElement(5003, // this.sellToGridEnergy = new ModbusReadLongChannel("SellToGridEnergy", this).unit("Wh") - .multiplier(2)), + .multiplier(2)), new UnsignedDoublewordElement(5005, // this.buyFromGridEnergy = new ModbusReadLongChannel("BuyFromGridEnergy", this).unit("Wh") - .multiplier(2)))); + .multiplier(2)))); return protocol; } From bc922106622323fadf1177494450136eab946328 Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Tue, 12 Dec 2017 17:32:18 +0100 Subject: [PATCH 14/55] Implement Socomec Single Phase Meter --- .../device/socomec/SocomecSinglePhase.java | 62 +++++++ .../socomec/SocomecSinglePhaseMeter.java | 154 ++++++++++++++++++ 2 files changed, 216 insertions(+) create mode 100644 edge/src/io/openems/impl/device/socomec/SocomecSinglePhase.java create mode 100644 edge/src/io/openems/impl/device/socomec/SocomecSinglePhaseMeter.java diff --git a/edge/src/io/openems/impl/device/socomec/SocomecSinglePhase.java b/edge/src/io/openems/impl/device/socomec/SocomecSinglePhase.java new file mode 100644 index 00000000000..c04b9d9ef54 --- /dev/null +++ b/edge/src/io/openems/impl/device/socomec/SocomecSinglePhase.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * 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.device.socomec; + +import java.util.HashSet; +import java.util.Set; + +import io.openems.api.bridge.Bridge; +import io.openems.api.channel.ConfigChannel; +import io.openems.api.device.nature.DeviceNature; +import io.openems.api.doc.ChannelInfo; +import io.openems.api.doc.ThingInfo; +import io.openems.api.exception.OpenemsException; +import io.openems.impl.protocol.modbus.ModbusDevice; + +@ThingInfo(title = "Socomec") +public class SocomecSinglePhase extends ModbusDevice { + + /* + * Constructors + */ + public SocomecSinglePhase(Bridge parent) throws OpenemsException { + super(parent); + } + + /* + * Config + */ + @ChannelInfo(title = "Meter", description = "Sets the meter nature.", type = SocomecSinglePhaseMeter.class) + public final ConfigChannel meter = new ConfigChannel<>("meter", this); + + /* + * Methods + */ + @Override + protected Set getDeviceNatures() { + Set natures = new HashSet<>(); + if (meter.valueOptional().isPresent()) { + natures.add(meter.valueOptional().get()); + } + return natures; + } + +} diff --git a/edge/src/io/openems/impl/device/socomec/SocomecSinglePhaseMeter.java b/edge/src/io/openems/impl/device/socomec/SocomecSinglePhaseMeter.java new file mode 100644 index 00000000000..5c7c879cc38 --- /dev/null +++ b/edge/src/io/openems/impl/device/socomec/SocomecSinglePhaseMeter.java @@ -0,0 +1,154 @@ +/******************************************************************************* + * 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.device.socomec; + +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.ReadChannel; +import io.openems.api.device.Device; +import io.openems.api.device.nature.meter.SymmetricMeterNature; +import io.openems.api.doc.ThingInfo; +import io.openems.api.exception.ConfigException; +import io.openems.impl.protocol.modbus.ModbusDeviceNature; +import io.openems.impl.protocol.modbus.ModbusReadLongChannel; +import io.openems.impl.protocol.modbus.internal.DummyElement; +import io.openems.impl.protocol.modbus.internal.ModbusProtocol; +import io.openems.impl.protocol.modbus.internal.SignedDoublewordElement; +import io.openems.impl.protocol.modbus.internal.UnsignedDoublewordElement; +import io.openems.impl.protocol.modbus.internal.range.ModbusRegisterRange; + +@ThingInfo(title = "Socomec Single Phase Meter") +public class SocomecSinglePhaseMeter extends ModbusDeviceNature implements SymmetricMeterNature { + + /* + * Constructors + */ + public SocomecSinglePhaseMeter(String thingId, Device parent) throws ConfigException { + super(thingId, parent); + } + + /* + * Config + */ + private final ConfigChannel type = new ConfigChannel("type", this); + + @Override + public ConfigChannel type() { + return type; + } + + private final ConfigChannel maxActivePower = new ConfigChannel("maxActivePower", this); + + @Override + public ConfigChannel maxActivePower() { + return maxActivePower; + } + + private final ConfigChannel minActivePower = new ConfigChannel("minActivePower", this); + + @Override + public ConfigChannel minActivePower() { + return minActivePower; + } + + /* + * Inherited Channels + */ + private ModbusReadLongChannel activePower; + private ModbusReadLongChannel apparentPower; + private ModbusReadLongChannel reactivePower; + private ModbusReadLongChannel frequency; + private ModbusReadLongChannel voltageL1; + + @Override + public ModbusReadLongChannel activePower() { + return activePower; + } + + @Override + public ModbusReadLongChannel apparentPower() { + return apparentPower; + } + + @Override + public ModbusReadLongChannel reactivePower() { + return reactivePower; + } + + @Override + public ReadChannel frequency() { + return frequency; + } + + /* + * This Channels + */ + public ModbusReadLongChannel activeNegativeEnergy; + public ModbusReadLongChannel activePositiveEnergy; + public ModbusReadLongChannel reactiveNegativeEnergy; + public ModbusReadLongChannel reactivePositiveEnergy; + public ModbusReadLongChannel apparentEnergy; + public ModbusReadLongChannel current; + + /* + * Methods + */ + @Override + protected ModbusProtocol defineModbusProtocol() throws ConfigException { + return new ModbusProtocol( // + new ModbusRegisterRange(0xc558, // + new UnsignedDoublewordElement(0xc558, // + voltageL1 = new ModbusReadLongChannel("VoltageL1", this).unit("mV").multiplier(1)), + new DummyElement(0xc55A, 0xc55D), + new UnsignedDoublewordElement(0xc55E, // + frequency = new ModbusReadLongChannel("Frequency", this).unit("mHZ").multiplier(1)), + new DummyElement(0xc560, 0xc565), + new UnsignedDoublewordElement(0xc566, // + current = new ModbusReadLongChannel("Current", this).unit("mA")), + new SignedDoublewordElement(0xc568, // + activePower = new ModbusReadLongChannel("ActivePower", this).unit("W").multiplier(1)), + new SignedDoublewordElement(0xc56A, // + reactivePower = new ModbusReadLongChannel("ReactivePower", this).unit("var") + .multiplier(1)), + new SignedDoublewordElement(0xc56C, // + apparentPower = new ModbusReadLongChannel("ApparentPower", this).unit("VA") + .multiplier(1))), + new ModbusRegisterRange(0xc652, // + new UnsignedDoublewordElement(0xc652, // + activePositiveEnergy = new ModbusReadLongChannel( + "ActivePositiveEnergy", this).unit("kWh")), + new UnsignedDoublewordElement(0xc654, // + reactivePositiveEnergy = new ModbusReadLongChannel( + "ReactivePositiveEnergy", this).unit("kvarh")), + new UnsignedDoublewordElement(0xc656, // + apparentEnergy = new ModbusReadLongChannel("ApparentEnergy", this).unit("kVAh")), + new UnsignedDoublewordElement(0xc658, // + activeNegativeEnergy = new ModbusReadLongChannel( + "ActiveNegativeEnergy", this).unit("kWh")), + new UnsignedDoublewordElement(0xc65a, // + reactiveNegativeEnergy = new ModbusReadLongChannel("ReactiveNegativeEnergy", this) + .unit("kvarh")))); + } + + @Override + public ReadChannel voltage() { + return this.voltageL1; + } +} From 947107deb846e8e00a5491c2a682bbd0b55d0f10 Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Wed, 13 Dec 2017 12:34:37 +0100 Subject: [PATCH 15/55] Use absolute url for energy monitor gradient --- .../energymonitor/chart/section/abstractsection.component.ts | 1 + .../overview/energymonitor/chart/section/section.component.html | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ui/src/app/device/overview/energymonitor/chart/section/abstractsection.component.ts b/ui/src/app/device/overview/energymonitor/chart/section/abstractsection.component.ts index f5045195bf8..dd8cca16eaa 100644 --- a/ui/src/app/device/overview/energymonitor/chart/section/abstractsection.component.ts +++ b/ui/src/app/device/overview/energymonitor/chart/section/abstractsection.component.ts @@ -102,6 +102,7 @@ export class EnergyFlow { export abstract class AbstractSection { + public url: string = window.location.href; public valuePath: string = ""; public outlinePath: string = ""; public energyFlow: EnergyFlow; diff --git a/ui/src/app/device/overview/energymonitor/chart/section/section.component.html b/ui/src/app/device/overview/energymonitor/chart/section/section.component.html index 672da885c54..74d8444959a 100644 --- a/ui/src/app/device/overview/energymonitor/chart/section/section.component.html +++ b/ui/src/app/device/overview/energymonitor/chart/section/section.component.html @@ -23,5 +23,5 @@ - + \ No newline at end of file From e32ad4fc516351f7f080cc3775d77e146b4f6b24 Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Wed, 13 Dec 2017 13:11:43 +0100 Subject: [PATCH 16/55] Fix CommercialAC template (add grid meter type & production meter with unitid 6) --- edge/template/FeneconCommercialAC.json | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/edge/template/FeneconCommercialAC.json b/edge/template/FeneconCommercialAC.json index 2cd32f2fd04..70c49b193cb 100644 --- a/edge/template/FeneconCommercialAC.json +++ b/edge/template/FeneconCommercialAC.json @@ -27,7 +27,16 @@ "class": "io.openems.impl.device.socomec.Socomec", "modbusUnitId": 5, "meter": { - "id": "meter0" + "id": "meter0", + "type": "grid" + } + }, + { + "class": "io.openems.impl.device.socomec.Socomec", + "modbusUnitId": 6, + "meter": { + "id": "meter1", + "type": "production" } } ] @@ -40,7 +49,7 @@ "priority": 150, "class": "io.openems.impl.controller.debuglog.DebugLogController", "esss": "ess0", - "meters": "meter0" + "meters": [ "meter0", "meter1" ] }, { "priority": 100, From ab42780e2d09d05b4ceae96555aa80941e5d1197 Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Wed, 13 Dec 2017 13:12:56 +0100 Subject: [PATCH 17/55] Fix black arrow in energymonitor on negative consumption. Make svg gradient url absolute. --- .../energymonitor/chart/section/abstractsection.component.ts | 2 ++ .../energymonitor/chart/section/section.component.html | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ui/src/app/device/overview/energymonitor/chart/section/abstractsection.component.ts b/ui/src/app/device/overview/energymonitor/chart/section/abstractsection.component.ts index dd8cca16eaa..07709742882 100644 --- a/ui/src/app/device/overview/energymonitor/chart/section/abstractsection.component.ts +++ b/ui/src/app/device/overview/energymonitor/chart/section/abstractsection.component.ts @@ -109,6 +109,7 @@ export abstract class AbstractSection { public square: SvgSquare; public squarePosition: SvgSquarePosition; public name: string = ""; + public sectionId: string = ""; protected valueRatio: number = 0; protected valueText: string = ""; @@ -127,6 +128,7 @@ export abstract class AbstractSection { public color: string, protected translate: TranslateService ) { + this.sectionId = translateName; this.name = translate.instant(translateName); this.energyFlow = this.initEnergyFlow(0); } diff --git a/ui/src/app/device/overview/energymonitor/chart/section/section.component.html b/ui/src/app/device/overview/energymonitor/chart/section/section.component.html index 74d8444959a..906f3015c50 100644 --- a/ui/src/app/device/overview/energymonitor/chart/section/section.component.html +++ b/ui/src/app/device/overview/energymonitor/chart/section/section.component.html @@ -17,11 +17,11 @@ --> - - + \ No newline at end of file From 45f44c49261b2604097794ad1c934da6d8ea2eac Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Wed, 13 Dec 2017 13:13:34 +0100 Subject: [PATCH 18/55] Remove energymonitor circles for energyflow --- .../energymonitor/chart/section/section.component.html | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ui/src/app/device/overview/energymonitor/chart/section/section.component.html b/ui/src/app/device/overview/energymonitor/chart/section/section.component.html index 906f3015c50..de23d05c4df 100644 --- a/ui/src/app/device/overview/energymonitor/chart/section/section.component.html +++ b/ui/src/app/device/overview/energymonitor/chart/section/section.component.html @@ -10,11 +10,6 @@ - Date: Thu, 14 Dec 2017 15:45:20 +0100 Subject: [PATCH 19/55] improved fems-setup --- setup/setup.sh | 105 ++++++++++++++--- setup/templates/FENECON Mini.json | 61 ++++++++++ setup/templates/FENECON Pro 9-12.json | 6 +- setup/templates/FENECON Pro AC-Insel.json | 96 ++++++++++++++++ setup/templates/FENECON Pro Cluster.json | 94 +++++++++++++++ setup/templates/FENECON Pro Heizstab.json | 107 ++++++++++++++++++ .../FENECON Pro W\303\244rmepumpe.json" | 103 +++++++++++++++++ 7 files changed, 549 insertions(+), 23 deletions(-) create mode 100644 setup/templates/FENECON Mini.json create mode 100644 setup/templates/FENECON Pro AC-Insel.json create mode 100644 setup/templates/FENECON Pro Cluster.json create mode 100644 setup/templates/FENECON Pro Heizstab.json create mode 100644 "setup/templates/FENECON Pro W\303\244rmepumpe.json" diff --git a/setup/setup.sh b/setup/setup.sh index 49f354d9081..aa12150d0d0 100644 --- a/setup/setup.sh +++ b/setup/setup.sh @@ -23,7 +23,44 @@ if [ ! -e $FINISHED_1 ]; then echo "# Aborting" exit 1 fi - + +#selection process +CHOICE=$(whiptail --menu "Wähle aus:" 18 40 9 \ + "FENECON Mini" "" \ + "FENECON DESS" "" \ + "FENECON Pro" "" \ + "FENECON Pro AC-Insel" "" \ + "FENECON Pro Heizstab" "" \ + "FENECON Pro Wärmepumpe" "" \ + "FENECON Commercial AC" "" \ + "FENECON Commercial DC" "" \ + "FENECON Commercial Hybrid" "" 3>&1 1>&2 2>&3) + + if [ $? = 0 ]; then + + case $CHOICE in + "FENECON Mini") echo "Es wurde Mini gewählt";; + "FENECON DESS") echo "Es wurde Pro Hybrid gewählt";; + "FENECON Pro") echo "Es wurde Pro 9-12 gewählt";; + "FENECON Pro AC-Insel") echo "Es wurde AC-Insel gewählt";; + "FENECON Pro Heizstab") echo "Es wurde Heizstab gewählt";; + "FENECON Pro Waermepumpe") echo "Es wurde Wärmepumpe gewählt";; + "FENECON Commercial AC") echo "Es wurde Commercial AC gewählt";; + "FENECON Commercial DC") echo "Es wurde Commercial DC gewählt";; + "FENECON Commercial Hybrid") echo "Es wurde Comemrcial Hybrid gewählt";; + + esac + + else + echo "Nichts ausgewählt" + exit + fi + echo "#save variable to file" + touch /opt/choice && echo $CHOICE > /opt/choice + + echo "# Copy templates to target" + cp -r /boot/uboot/fems-setup/templates /opt/fems-setup/ + echo "# Copy filesystem to internal eMMC" cd /opt/scripts/tools/eMMC ./bbb-eMMC-flasher-eewiki-ext4.sh || true @@ -40,10 +77,7 @@ if [ ! -e $FINISHED_1 ]; then echo "# Remove fems from devices list" /bin/sed --expression='2d' /boot/uboot/fems-setup/devices --in-place - - echo "# Write Apikey into /etc/fems" - /usr/bin/head -n 2 devices | tail -n 1 | cut -d ";" -f 3 > /mnt/etc/fems - + echo "# Mark first stage as finished" touch /mnt$FINISHED_1 /bin/umount /mnt @@ -54,16 +88,18 @@ if [ ! -e $FINISHED_1 ]; then read -p "Press [Enter] key to shutdown" echo "# Shutdown system" - /sbin/shutdown -h now + shutdown -h now elif [ ! -e $FINISHED_2 ]; then echo "#" echo "# Starting second stage of FEMS setup" echo "#" - FEMS=$(head -n 2 $DEVICES | tail -n 1 | cut -d ";" -f 1) - PASSWORD=$(head -n 2 $DEVICES | tail -n 1 | cut -d ";" -f 2) + cd /opt/fems-setup + FEMS=$(head -n 2 devices | tail -n 1 | cut -d ";" -f 1) + PASSWORD=$(head -n 2 devices | tail -n 1 | cut -d ";" -f 2) + echo "# Set password for user fems" echo "fems:${PASSWORD}" | /usr/sbin/chpasswd @@ -90,7 +126,8 @@ else echo "# Starting third stage of FEMS setup" echo "#" - PACKAGES=$(head -n 2 $DEVICES | tail -n 1 | cut -d ";" -f 4) + cd /opt/fems-setup + PACKAGES=$(head -n 2 devices | tail -n 1 | cut -d ";" -f 4) echo "# Add FENECON debian repository" wget -O - http://fenecon.de/debian/fems.gpg.key | apt-key add - @@ -100,8 +137,39 @@ else echo "# Refresh apt cache" /usr/bin/aptitude update echo "# Install openjdk 8" - /usr/bin/apt install -t jessie-backports openjdk-8-jre-headless - + /usr/bin/apt install -t jessie-backports openjdk-8-jre-headless -y + + CHOICE=$(cat /opt/choice) + + if [ "$CHOICE" == "FENECON DESS" ]; then + + aptitude install fems-dess fems-fenecononlinemonitoring --assume-yes + + else + aptitude install openems openems-fems openems-ui influxdb grafana + + # copy config and set name + apikey + CHOICE=$(cat /opt/choice) + mkdir -p /opt/config.d + + echo "# Write Apikey into /etc/fems" + APIKEY=$(head -n 2 /opt/fems-setup/devices | tail -n 1 | cut -d ";" -f 3) + echo "apikey=${APIKEY}" > /etc/fems + + cp "/opt/fems-setup/templates/$CHOICE.json" "/opt/config.d/$CHOICE.json" + NAME=$(head -n 2 /opt/fems-setup/devices | tail -n 1 | cut -d ";" -f 1) + + sed "s/\"###FEMS_ID###\"/${NAME:4}/" --in-place "/opt/config.d/$CHOICE.json" + + APIKEY=$(head -n 2 /opt/fems-setup/devices | tail -n 1 | cut -d ";" -f 3) + sed "s/###APIKEY###/$APIKEY/" --in-place "/opt/config.d/$CHOICE.json" + + CHOICE=$(cat /opt/choice) + mv "/opt/config.d/$CHOICE.json" "/etc/openems.d/config.json" + unlink /opt/choice + + fi + # this is not working... #echo "# preset apikey for dpkg-configure" #. /usr/share/debconf/confmodule @@ -111,22 +179,23 @@ else if [ "${PACKAGES}" != "" ]; then echo "# Install packages: ${PACKAGES}" - /usr/bin/aptitude install --assume-yes $PACKAGES + /usr/bin/aptitude install --assume-yes $PACKAGES -y + else echo "# Install NO packages!" fi - echo "# Finialize setup with fems-autoupdate fems" - /usr/bin/fems-autoupdate fems - - echo "# Blink all LEDs" - echo timer | tee /sys/class/leds/beaglebone:green:usr?/trigger >/dev/null + #echo "# Finialize setup with fems-autoupdate fems" + #/usr/bin/fems-autoupdate fems echo "#" echo "# Finished setup" echo "#" - read -p "Press [Enter] key to reboot" + + fems-autoupdate fems -y || true + echo "# Blink all LEDs" + echo timer | tee /sys/class/leds/beaglebone:green:usr?/trigger >/dev/null echo "# Rebooting system" reboot fi diff --git a/setup/templates/FENECON Mini.json b/setup/templates/FENECON Mini.json new file mode 100644 index 00000000000..61ddfa0694a --- /dev/null +++ b/setup/templates/FENECON Mini.json @@ -0,0 +1,61 @@ +{ + "things": [ + { + "class": "io.openems.impl.protocol.modbus.ModbusRtu", + "serialinterface": "/dev/ttyUSB0", + "baudrate": 9600, + "databits": 8, + "parity": "none", + "stopbits": 1, + "devices": [ + { + "class": "io.openems.impl.device.minireadonly.FeneconMini", + "modbusUnitId": 4, + "ess": { + "id": "ess0", + "minSoc": 15 + }, + "gridMeter": { + "id": "meter0" + }, + "productionMeter": { + "id": "meter1" + }, + "consumptionMeter": { + "id": "meter2" + } + } + ] + } + ], + "scheduler": { + "class": "io.openems.impl.scheduler.SimpleScheduler", + "cycleTime": 10000, + "controllers": [ + { + "priority": 150, + "class": "io.openems.impl.controller.debuglog.DebugLogController", + "esss": [ + "ess0" + ], + "meters": [ + "meter0", + "meter1", + "meter2" + ] + } + ] + }, + "persistence": [ + { + "class": "io.openems.impl.persistence.influxdb.InfluxdbPersistence", + "ip": "127.0.0.1", + "fems": "###FEMS_ID###" + }, + { + "class": "io.openems.impl.persistence.fenecon.FeneconPersistence", + "apikey": "###APIKEY###" + } + ] +} + diff --git a/setup/templates/FENECON Pro 9-12.json b/setup/templates/FENECON Pro 9-12.json index f66dc51e79f..6baa00a8e55 100644 --- a/setup/templates/FENECON Pro 9-12.json +++ b/setup/templates/FENECON Pro 9-12.json @@ -55,11 +55,6 @@ "priority": 1, "class": "io.openems.impl.controller.clocksync.ClockSyncController", "rtc": "ess0" - }, - { - "priority": 0, - "class": "io.openems.impl.controller.feneconprosetup.FeneconProSetupController", - "esss": "ess0" } ] }, @@ -75,3 +70,4 @@ } ] } + diff --git a/setup/templates/FENECON Pro AC-Insel.json b/setup/templates/FENECON Pro AC-Insel.json new file mode 100644 index 00000000000..b4407b765fd --- /dev/null +++ b/setup/templates/FENECON Pro AC-Insel.json @@ -0,0 +1,96 @@ +{ + "things": [ + { + "class": "io.openems.impl.protocol.modbus.ModbusRtu", + "serialinterface": "/dev/ttyUSB0", + "baudrate": 9600, + "databits": 8, + "parity": "none", + "stopbits": 1, + "devices": [ + { + "class": "io.openems.impl.device.pro.FeneconPro", + "modbusUnitId": 4, + "ess": { + "id": "ess0", + "minSoc": 15 + }, + "meter": { + "id": "meter1" + } + }, + { + "class": "io.openems.impl.device.socomec.Socomec", + "modbusUnitId": 5, + "meter": { + "id": "meter0", + "type": "grid" + } + }, + { + "class": "io.openems.impl.device.kmtronic.KMTronicRelay", + "output": { + "id": "output0" + }, + "modbusUnitId": 1 + } + ] + } + ], + "scheduler": { + "class": "io.openems.impl.scheduler.SimpleScheduler", + "controllers": [ + { + "priority": 150, + "class": "io.openems.impl.controller.debuglog.DebugLogController", + "esss": [ "ess0" ], + "meters": [ "meter0", "meter1" ], + "rtc": "ess0" + }, + { + "priority": 100, + "class": "io.openems.impl.controller.asymmetric.avoidtotaldischarge.AvoidTotalDischargeController", + "esss": "ess0" + }, + { + "priority": 50, + "class": "io.openems.impl.controller.asymmetric.balancing.BalancingController", + "esss": "ess0", + "meter": "meter0" + }, + { + "priority": 1, + "class": "io.openems.impl.controller.clocksync.ClockSyncController", + "rtc": "ess0" + }, + { + "priority": 0, + "class": "io.openems.impl.controller.feneconprosetup.FeneconProSetupController", + "esss": "ess0" + }, + { + "class": "io.openems.impl.controller.acisland.AcIsland", + "minSoc": 90, + "onGridOutputChannelAddress": "output0/2", + "offGridOutputChannelAddress": "output0/3", + "maxSoc": 95, + "switchDelay": 10000, + "ess": "ess0", + "priority": 0 + } + + ] + }, + "persistence": [ + { + "class": "io.openems.impl.persistence.influxdb.InfluxdbPersistence", + "ip": "127.0.0.1", + "fems": "###FEMS_ID###" + }, + { + "class": "io.openems.impl.persistence.fenecon.FeneconPersistence", + "apikey": "###APIKEY###" + } + ] +} + diff --git a/setup/templates/FENECON Pro Cluster.json b/setup/templates/FENECON Pro Cluster.json new file mode 100644 index 00000000000..2a9d1445910 --- /dev/null +++ b/setup/templates/FENECON Pro Cluster.json @@ -0,0 +1,94 @@ +{ + "things": [ + { + "class": "io.openems.impl.protocol.modbus.ModbusRtu", + "serialinterface": "/dev/ttyUSB0", + "baudrate": 9600, + "databits": 8, + "parity": "none", + "stopbits": 1, + "devices": [ + { + "class": "io.openems.impl.device.pro.FeneconPro", + "modbusUnitId": 4, + "ess": { + "id": "ess0", + "minSoc": 15 + }, + "meter": { + "id": "meter1" + } + }, + { + "class": "io.openems.impl.device.socomec.Socomec", + "modbusUnitId": 5, + "meter": { + "id": "meter0", + "type": "grid" + } + } + ] + }, + { + "class": "io.openems.impl.protocol.modbus.ModbusRtu", + "serialinterface": "/dev/ttyUSB1", + "baudrate": 9600, + "databits": 8, + "parity": "none", + "stopbits": 1, + "devices": [ + { + "class": "io.openems.impl.device.pro.FeneconPro", + "modbusUnitId": 4, + "ess": { + "id": "ess1", + "minSoc": 15 + }, + "meter": { + "id": "meter2" + } + } + ] + } + ], + "scheduler": { + "class": "io.openems.impl.scheduler.SimpleScheduler", + "controllers": [ + { + "priority": 150, + "class": "io.openems.impl.controller.debuglog.DebugLogController", + "esss": [ "ess0", "ess1" ], + "meters": [ "meter0", "meter1", "meter2" ], + "rtc": "ess0" + }, + { + "priority": 100, + "class": "io.openems.impl.controller.asymmetric.avoidtotaldischarge.AvoidTotalDischargeController", + "esss": [ "ess0", "ess1" ] + }, + { + "priority": 50, + "class": "io.openems.impl.controller.asymmetric.balancing.BalancingController", + "esss": [ "ess0", "ess1" ], + "meter": "meter0" + }, + { + "priority": 1, + "class": "io.openems.impl.controller.clocksync.ClockSyncController", + "rtc": "ess0" + } + ] + }, + "persistence": [ + { + "class": "io.openems.impl.persistence.influxdb.InfluxdbPersistence", + "ip": "127.0.0.1", + "fems": "###FEMS_ID###" + }, + { + "class": "io.openems.impl.persistence.fenecon.FeneconPersistence", + "apikey": "###APIKEY###" + } + ] +} + diff --git a/setup/templates/FENECON Pro Heizstab.json b/setup/templates/FENECON Pro Heizstab.json new file mode 100644 index 00000000000..203b385b971 --- /dev/null +++ b/setup/templates/FENECON Pro Heizstab.json @@ -0,0 +1,107 @@ +{ + "things": [ + { + "class": "io.openems.impl.protocol.modbus.ModbusRtu", + "serialinterface": "/dev/ttyUSB0", + "baudrate": 9600, + "databits": 8, + "parity": "none", + "stopbits": 1, + "devices": [ + { + "class": "io.openems.impl.device.pro.FeneconPro", + "modbusUnitId": 4, + "ess": { + "id": "ess0", + "minSoc": 15 + }, + "meter": { + "id": "meter1" + } + }, + { + "class": "io.openems.impl.device.socomec.Socomec", + "modbusUnitId": 5, + "meter": { + "id": "meter0", + "type": "grid" + } + }, + { + "class": "io.openems.impl.device.kmtronic.KMTronicRelayRev1", + "output": { + "id": "output0" + }, + "modbusUnitId": 1 + } + ] + } + ], + "scheduler": { + "class": "io.openems.impl.scheduler.SimpleScheduler", + "controllers": [ + { + "priority": 150, + "class": "io.openems.impl.controller.debuglog.DebugLogController", + "esss": [ "ess0" ], + "meters": [ "meter0", "meter1" ], + "rtc": "ess0" + }, + { + "priority": 100, + "class": "io.openems.impl.controller.asymmetric.avoidtotaldischarge.AvoidTotalDischargeController", + "esss": "ess0" + }, + { + "priority": 50, + "class": "io.openems.impl.controller.asymmetric.balancing.BalancingController", + "esss": "ess0", + "meter": "meter0" + }, + { + "priority": 1, + "class": "io.openems.impl.controller.clocksync.ClockSyncController", + "rtc": "ess0" + }, + { + "class": "io.openems.impl.controller.channelthreshold.ChannelThresholdController", + "priority": 60, + "thresholdChannelAddress": "ess0/Soc", + "outputChannelAddress": "output0/2", + "lowerThreshold": 92, + "upperThreshold": 100, + "hysteresis": 5 + }, + { + "class": "io.openems.impl.controller.channelthreshold.ChannelThresholdController", + "priority": 59, + "thresholdChannelAddress": "ess0/Soc", + "outputChannelAddress": "output0/3", + "lowerThreshold": 94, + "upperThreshold": 100, + "hysteresis": 5 + }, + { + "class": "io.openems.impl.controller.channelthreshold.ChannelThresholdController", + "priority": 58, + "thresholdChannelAddress": "ess0/Soc", + "outputChannelAddress": "output0/4", + "lowerThreshold": 96, + "upperThreshold": 100, + "hysteresis": 5 + } + ] + }, + "persistence": [ + { + "class": "io.openems.impl.persistence.influxdb.InfluxdbPersistence", + "ip": "127.0.0.1", + "fems": "###FEMS_ID###" + }, + { + "class": "io.openems.impl.persistence.fenecon.FeneconPersistence", + "apikey": "###APIKEY###" + } + ] +} + diff --git "a/setup/templates/FENECON Pro W\303\244rmepumpe.json" "b/setup/templates/FENECON Pro W\303\244rmepumpe.json" new file mode 100644 index 00000000000..7cb313fccbd --- /dev/null +++ "b/setup/templates/FENECON Pro W\303\244rmepumpe.json" @@ -0,0 +1,103 @@ +{ + "things": [ + { + "class": "io.openems.impl.protocol.modbus.ModbusRtu", + "serialinterface": "/dev/ttyUSB0", + "baudrate": 9600, + "databits": 8, + "parity": "none", + "stopbits": 1, + "devices": [ + { + "class": "io.openems.impl.device.pro.FeneconPro", + "modbusUnitId": 4, + "ess": { + "id": "ess0", + "minSoc": 15 + }, + "meter": { + "id": "meter1" + } + }, + { + "class": "io.openems.impl.device.socomec.Socomec", + "modbusUnitId": 5, + "meter": { + "id": "meter0", + "type": "grid" + } + }, + { + "class": "io.openems.impl.device.kmtronic.KMTronicRelayRev1", + "output": { + "id": "output0" + }, + "modbusUnitId": 1 + } + ] + } + ], + "scheduler": { + "class": "io.openems.impl.scheduler.SimpleScheduler", + "controllers": [ + { + "priority": 150, + "class": "io.openems.impl.controller.debuglog.DebugLogController", + "esss": [ + "ess0" + ], + "meters": [ + "meter0", + "meter1" + ], + "rtc": "ess0" + }, + { + "priority": 100, + "class": "io.openems.impl.controller.asymmetric.avoidtotaldischarge.AvoidTotalDischargeController", + "esss": "ess0" + }, + { + "priority": 50, + "class": "io.openems.impl.controller.asymmetric.balancing.BalancingController", + "esss": "ess0", + "meter": "meter0" + }, + { + "priority": 1, + "class": "io.openems.impl.controller.clocksync.ClockSyncController", + "rtc": "ess0" + }, + { + "class": "io.openems.impl.controller.channelthreshold.ChannelThresholdController", + "priority": 60, + "thresholdChannelAddress": "ess0/Soc", + "outputChannelAddress": "output0/2", + "lowerThreshold": 0, + "upperThreshold": 40, + "hysteresis": 5 + }, + { + "class": "io.openems.impl.controller.channelthreshold.ChannelThresholdController", + "priority": 65, + "thresholdChannelAddress": "ess0/Soc", + "outputChannelAddress": "output0/3", + "lowerThreshold": 75, + "upperThreshold": 100, + "hysteresis": 5 + } + ] + }, + "persistence": [ + { + "class": "io.openems.impl.persistence.influxdb.InfluxdbPersistence", + "ip": "127.0.0.1", + "fems": "###FEMS_ID###" + }, + { + "class": "io.openems.impl.persistence.fenecon.FeneconPersistence", + "apikey": "###APIKEY###" + } + ] +} + From 693ebe84d7e430498a60b5ca9de0f42eb77bf012 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Ro=C3=9Fmann?= Date: Fri, 15 Dec 2017 11:49:18 +0100 Subject: [PATCH 20/55] add CosPhi --- .../src/io/openems/impl/device/pqplus/PqPlusUMD97Meter.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/edge/src/io/openems/impl/device/pqplus/PqPlusUMD97Meter.java b/edge/src/io/openems/impl/device/pqplus/PqPlusUMD97Meter.java index 993ce8014d2..3787574ab75 100644 --- a/edge/src/io/openems/impl/device/pqplus/PqPlusUMD97Meter.java +++ b/edge/src/io/openems/impl/device/pqplus/PqPlusUMD97Meter.java @@ -165,11 +165,11 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { reactivePower = new ModbusReadLongChannel("ReactivePower", this) // .unit("Var")), // new FloatElement(19044, // - cosPhiL1 = new ModbusReadLongChannel("CosPhiL1", this)), // + cosPhiL1 = new ModbusReadLongChannel("CosPhiL1", this)).multiplier(2), // new FloatElement(19046, // - cosPhiL2 = new ModbusReadLongChannel("CosPhiL2", this)), // + cosPhiL2 = new ModbusReadLongChannel("CosPhiL2", this)).multiplier(2), // new FloatElement(19048, // - cosPhiL3 = new ModbusReadLongChannel("CosPhiL3", this)), // + cosPhiL3 = new ModbusReadLongChannel("CosPhiL3", this)).multiplier(2), // new FloatElement(19050, // frequency = new ModbusReadLongChannel("Frequency", this).unit("mHz")) // .multiplier(3))); From 212b12a94d893292ede4d07f8bd1d3a6124141e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Ro=C3=9Fmann?= Date: Fri, 15 Dec 2017 11:50:00 +0100 Subject: [PATCH 21/55] add Optional methods on Channel --- edge/src/io/openems/api/channel/ReadChannel.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/edge/src/io/openems/api/channel/ReadChannel.java b/edge/src/io/openems/api/channel/ReadChannel.java index 047c82686aa..b9bf6cb07b2 100644 --- a/edge/src/io/openems/api/channel/ReadChannel.java +++ b/edge/src/io/openems/api/channel/ReadChannel.java @@ -182,6 +182,14 @@ public Optional valueOptional() { return value; }; + public boolean isValuePresent() { + return value.isPresent(); + } + + public T getValue() { + return value.get(); + } + public String unitOptional() { return unit; } From b0b19ab8a44a0dff8ec46040582677de9d9e1c88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Ro=C3=9Fmann?= Date: Fri, 15 Dec 2017 11:50:39 +0100 Subject: [PATCH 22/55] fix soc thresholds --- .../FEMS App SG-Ready W\303\244rmepumpe.json" | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git "a/edge/template/app/FEMS App SG-Ready W\303\244rmepumpe.json" "b/edge/template/app/FEMS App SG-Ready W\303\244rmepumpe.json" index 09c737b319e..52a33605fb7 100644 --- "a/edge/template/app/FEMS App SG-Ready W\303\244rmepumpe.json" +++ "b/edge/template/app/FEMS App SG-Ready W\303\244rmepumpe.json" @@ -1,19 +1,19 @@ -{ - "class": "io.openems.impl.controller.channelthreshold.ChannelThresholdController", - "priority": 60, - "thresholdChannelAddress": "ess0/Soc", - "outputChannelAddress": "output0/0", - "lowerThreshold": 40, - "upperThreshold": 45, - "hysteresis": 5 -}, -{ - "class": "io.openems.impl.controller.channelthreshold.ChannelThresholdController", - "priority": 65, - "thresholdChannelAddress": "ess0/Soc", - "outputChannelAddress": "output0/1", - "lowerThreshold": 75, - "upperThreshold": 80, - "invertOutput": true, - "hysteresis": 5 +{ + "class": "io.openems.impl.controller.channelthreshold.ChannelThresholdController", + "priority": 60, + "thresholdChannelAddress": "ess0/Soc", + "outputChannelAddress": "output0/0", + "lowerThreshold": 0, + "upperThreshold": 40, + "hysteresis": 5 +}, +{ + "class": "io.openems.impl.controller.channelthreshold.ChannelThresholdController", + "priority": 65, + "thresholdChannelAddress": "ess0/Soc", + "outputChannelAddress": "output0/1", + "lowerThreshold": 80, + "upperThreshold": 100, + "invertOutput": true, + "hysteresis": 5 } \ No newline at end of file From 776d27e2cbb0e8dafe00f8e410d33d12297110d7 Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Thu, 21 Dec 2017 09:35:14 +0100 Subject: [PATCH 23/55] Improve ModbusRTU log messages --- .../openems/impl/protocol/modbus/ModbusRtu.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/edge/src/io/openems/impl/protocol/modbus/ModbusRtu.java b/edge/src/io/openems/impl/protocol/modbus/ModbusRtu.java index e5a445dad27..9e2f94d67d9 100644 --- a/edge/src/io/openems/impl/protocol/modbus/ModbusRtu.java +++ b/edge/src/io/openems/impl/protocol/modbus/ModbusRtu.java @@ -51,23 +51,23 @@ public void channelUpdated(Channel channel, Optional newValue) { */ @ChannelInfo(title = "Baudrate", description = "Sets the baudrate (e.g. 9600).", type = Integer.class) public final ConfigChannel baudrate = new ConfigChannel("baudrate", this) - .addUpdateListener(channelUpdateListener); + .addUpdateListener(channelUpdateListener); @ChannelInfo(title = "Databits", description = "Sets the databits (e.g. 8).", type = Integer.class) public final ConfigChannel databits = new ConfigChannel("databits", this) - .addUpdateListener(channelUpdateListener); + .addUpdateListener(channelUpdateListener); @ChannelInfo(title = "Parity", description = "Sets the parity (e.g. 'even').", type = String.class) public final ConfigChannel parity = new ConfigChannel("parity", this) - .addUpdateListener(channelUpdateListener); + .addUpdateListener(channelUpdateListener); @ChannelInfo(title = "Serial interface", description = "Sets the serial interface (e.g. /dev/ttyUSB0).", type = String.class) public final ConfigChannel serialinterface = new ConfigChannel("serialinterface", this) - .addUpdateListener(channelUpdateListener); + .addUpdateListener(channelUpdateListener); @ChannelInfo(title = "Stopbits", description = "Sets the stopbits (e.g. 1).", type = Integer.class) public final ConfigChannel stopbits = new ConfigChannel("stopbits", this) - .addUpdateListener(channelUpdateListener); + .addUpdateListener(channelUpdateListener); /* * Fields @@ -130,7 +130,7 @@ private SerialConnection getModbusConnection() throws OpenemsModbusException { if (!baudrate.valueOptional().isPresent() || !databits.valueOptional().isPresent() || !parity.valueOptional().isPresent() || !serialinterface.valueOptional().isPresent() || !stopbits.valueOptional().isPresent()) { - throw new OpenemsModbusException("Modbus-RTU is not configured completely"); + throw new OpenemsModbusException(this.id() + ": Modbus-RTU is not configured completely"); } SerialParameters params = new SerialParameters(); params.setPortName(serialinterface.valueOptional().get()); @@ -148,7 +148,8 @@ private SerialConnection getModbusConnection() throws OpenemsModbusException { serialCon.open(); serialCon.getModbusTransport().setTimeout(1000); } catch (Exception e) { - throw new OpenemsModbusException("Unable to open Modbus-RTU connection: " + connection); + throw new OpenemsModbusException(this.id() + ": Unable to open Modbus-RTU connection to [" + + serialinterface.valueOptional().orElse("UNDEFINED") + "]: " + e.getMessage()); } } return connection.get(); From 1aa1f1a36cfdbe62de1f59dd2b74b70678d0b606 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Ro=C3=9Fmann?= Date: Mon, 8 Jan 2018 12:17:44 +0100 Subject: [PATCH 24/55] Add ThingStateChannel to generalize Error handling --- edge/src/io/openems/api/bridge/Bridge.java | 8 + .../api/channel/BitToBooleanChannel.java | 30 ++++ .../io/openems/api/channel/ChannelEnum.java | 9 ++ .../api/channel/StaticValueChannel.java | 146 +++++++++--------- .../openems/api/channel/StatusBitChannel.java | 132 ++++++---------- .../api/channel/StatusBitChannels.java | 71 --------- .../io/openems/api/channel/ThingState.java | 58 +++++++ .../api/channel/ThingStateChannel.java | 118 ++++++++++++++ edge/src/io/openems/api/thing/Thing.java | 20 +++ .../impl/protocol/modbus/ModbusBridge.java | 4 + .../impl/protocol/modbus/ModbusRtu.java | 26 +++- .../impl/protocol/modbus/ModbusTcp.java | 20 ++- 12 files changed, 407 insertions(+), 235 deletions(-) create mode 100644 edge/src/io/openems/api/channel/BitToBooleanChannel.java create mode 100644 edge/src/io/openems/api/channel/ChannelEnum.java delete mode 100644 edge/src/io/openems/api/channel/StatusBitChannels.java create mode 100644 edge/src/io/openems/api/channel/ThingState.java create mode 100644 edge/src/io/openems/api/channel/ThingStateChannel.java diff --git a/edge/src/io/openems/api/bridge/Bridge.java b/edge/src/io/openems/api/bridge/Bridge.java index 10b8113108c..7fbc86c3fb5 100644 --- a/edge/src/io/openems/api/bridge/Bridge.java +++ b/edge/src/io/openems/api/bridge/Bridge.java @@ -32,6 +32,7 @@ import io.openems.api.bridge.BridgeEvent.Position; import io.openems.api.channel.DebugChannel; +import io.openems.api.channel.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.scheduler.Scheduler; import io.openems.api.thing.Thing; @@ -55,6 +56,7 @@ public abstract class Bridge extends Thread implements Thing { private DebugChannel requiredCycleTime = new DebugChannel<>("RequiredCycleTime", this); private List eventListener = new ArrayList<>(); private DebugChannel readOtherTaskReadCount = new DebugChannel<>("ReadOtherTaskReadCount", this); + protected ThingStateChannel thingState; /** * Initialize the Thread with a name @@ -64,6 +66,7 @@ public abstract class Bridge extends Thread implements Thing { public Bridge() { log = LoggerFactory.getLogger(this.getClass()); setName(THINGID_PREFIX + instanceCounter++); + thingState = new ThingStateChannel(this); } @Override @@ -127,6 +130,11 @@ public synchronized List getDevices() { return Collections.unmodifiableList(this.devices); } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + public void triggerWrite() { // set the Write-flag isWriteTriggered.set(true); diff --git a/edge/src/io/openems/api/channel/BitToBooleanChannel.java b/edge/src/io/openems/api/channel/BitToBooleanChannel.java new file mode 100644 index 00000000000..2baa2bcbdcc --- /dev/null +++ b/edge/src/io/openems/api/channel/BitToBooleanChannel.java @@ -0,0 +1,30 @@ +package io.openems.api.channel; + +import java.util.Optional; + +import io.openems.api.thing.Thing; + +public class BitToBooleanChannel extends ReadChannel implements ChannelChangeListener{ + + private ReadChannel valueChannel; + private int bitIndex; + + public BitToBooleanChannel(String id, Thing parent, ReadChannel channel, int bitIndex){ + super(id, parent); + this.valueChannel = channel; + this.valueChannel.addChangeListener(this); + this.bitIndex = bitIndex; + } + + @Override + public void channelChanged(Channel channel, Optional newValue, Optional oldValue) { + if(valueChannel.isValuePresent()) { + if(valueChannel.getValue().longValue() << ~bitIndex < 0) { + updateValue(true); + }else { + updateValue(false); + } + } + } + +} diff --git a/edge/src/io/openems/api/channel/ChannelEnum.java b/edge/src/io/openems/api/channel/ChannelEnum.java new file mode 100644 index 00000000000..3061228f920 --- /dev/null +++ b/edge/src/io/openems/api/channel/ChannelEnum.java @@ -0,0 +1,9 @@ +package io.openems.api.channel; + +import java.util.Locale; + +public interface ChannelEnum { + int getValue(); + + String getName(Locale locale); +} diff --git a/edge/src/io/openems/api/channel/StaticValueChannel.java b/edge/src/io/openems/api/channel/StaticValueChannel.java index 2358e07844d..b4273699397 100644 --- a/edge/src/io/openems/api/channel/StaticValueChannel.java +++ b/edge/src/io/openems/api/channel/StaticValueChannel.java @@ -1,71 +1,75 @@ -/******************************************************************************* - * 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.api.channel; - -import io.openems.api.thing.Thing; - -public class StaticValueChannel extends ReadChannel { - - public StaticValueChannel(String id, Thing parent, T value) { - super(id, parent); - this.updateValue(value); - } - - @Override public StaticValueChannel unit(String unit) { - super.unit(unit); - return this; - } - - @Override public StaticValueChannel multiplier(Long multiplier) { - super.multiplier(multiplier); - return this; - } - - @Override public StaticValueChannel delta(Long delta) { - super.delta(delta); - return this; - } - - @Override public StaticValueChannel required() { - return this; - } - - @Override public StaticValueChannel interval(T min, T max) { - super.interval(min, max); - return this; - } - - @Override public StaticValueChannel addUpdateListener(ChannelUpdateListener... listeners) { - super.addUpdateListener(listeners); - return this; - } - - @Override public StaticValueChannel addChangeListener(ChannelChangeListener... listeners) { - super.addChangeListener(listeners); - return this; - } - - @Override public StaticValueChannel label(T value, String label) { - super.label(value, label); - return this; - } - -} +/******************************************************************************* + * 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.api.channel; + +import io.openems.api.thing.Thing; + +public class StaticValueChannel extends ReadChannel { + + public StaticValueChannel(String id, Thing parent, T value) { + super(id, parent); + this.updateValue(value); + } + + @Override public StaticValueChannel unit(String unit) { + super.unit(unit); + return this; + } + + @Override public StaticValueChannel multiplier(Long multiplier) { + super.multiplier(multiplier); + return this; + } + + @Override public StaticValueChannel delta(Long delta) { + super.delta(delta); + return this; + } + + @Override public StaticValueChannel required() { + return this; + } + + @Override public StaticValueChannel interval(T min, T max) { + super.interval(min, max); + return this; + } + + @Override public StaticValueChannel addUpdateListener(ChannelUpdateListener... listeners) { + super.addUpdateListener(listeners); + return this; + } + + @Override public StaticValueChannel addChangeListener(ChannelChangeListener... listeners) { + super.addChangeListener(listeners); + return this; + } + + @Override public StaticValueChannel label(T value, String label) { + super.label(value, label); + return this; + } + + public void setValue(T b) { + this.updateValue(b); + } + +} diff --git a/edge/src/io/openems/api/channel/StatusBitChannel.java b/edge/src/io/openems/api/channel/StatusBitChannel.java index 17ec2b4af2e..b6d6aa93a91 100644 --- a/edge/src/io/openems/api/channel/StatusBitChannel.java +++ b/edge/src/io/openems/api/channel/StatusBitChannel.java @@ -1,86 +1,46 @@ -/******************************************************************************* - * 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.api.channel; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Map.Entry; -import java.util.Optional; -import java.util.Set; -import java.util.StringJoiner; - -import io.openems.api.device.nature.DeviceNature; -import io.openems.impl.protocol.modbus.ModbusReadChannel; - -public class StatusBitChannel extends ModbusReadChannel { - - public StatusBitChannel(String id, DeviceNature nature) { - super(id, nature); - } - - /** - * Get labels for all set bits - * Example: Value is 5, Labels are 1=One; 2=Two; 4=Four -> this method returns [One, Four] - * - * @return - */ - public Set labels() { - Set result = new HashSet<>(); - Optional valueOptional = valueOptional(); - if (valueOptional.isPresent() && !this.labels.isEmpty()) { - long value = valueOptional.get(); - long max = Collections.max(this.labels.keySet()); - if (max * 2 <= value) { - value = value & (max - 1); - } - for (Entry entry : this.labels.descendingMap().entrySet()) { - if (entry.getKey() <= value) { - result.add(entry.getValue()); - value -= entry.getKey(); - } - } - } - return result; - }; - - @Override - public Optional labelOptional() { - Set labels = this.labels(); - if (labels.isEmpty()) { - return Optional.empty(); - } else { - StringJoiner joiner = new StringJoiner(","); - for (String label : labels) { - joiner.add(this.id() + "/" + label); - } - return Optional.of(joiner.toString()); - } - }; - - @Override - public StatusBitChannel label(Long value, String label) { - return (StatusBitChannel) super.label(value, label); - } - - public StatusBitChannel label(int value, String label) { - return (StatusBitChannel) super.label(Long.valueOf(value), label); - } -} +/******************************************************************************* + * 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.api.channel; + +import io.openems.api.device.nature.DeviceNature; +import io.openems.api.exception.ConfigException; +import io.openems.impl.protocol.modbus.ModbusReadChannel; + +public class StatusBitChannel extends ModbusReadChannel { + + private final ThingStateChannel thingState; + + public StatusBitChannel(String id, DeviceNature nature, ThingStateChannel thingStateChannel) { + super(id, nature); + this.thingState = thingStateChannel; + } + + public StatusBitChannel warningBit(int i, int j) throws ConfigException { + thingState.addWarningChannel(new BitToBooleanChannel("Warning\\"+i, this.parent(), this, j)); + return this; + } + + public StatusBitChannel faultBit(int i, int j) throws ConfigException { + thingState.addFaultChannel(new BitToBooleanChannel("Fault\\"+i, this.parent(), this, j)); + return this; + } + +} diff --git a/edge/src/io/openems/api/channel/StatusBitChannels.java b/edge/src/io/openems/api/channel/StatusBitChannels.java deleted file mode 100644 index 21e5b4f0e7e..00000000000 --- a/edge/src/io/openems/api/channel/StatusBitChannels.java +++ /dev/null @@ -1,71 +0,0 @@ -/******************************************************************************* - * OpenEMS - Open Source Energy Management System - * Copyright (c) 2016 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.api.channel; - -import java.util.HashSet; -import java.util.Optional; -import java.util.Set; -import java.util.StringJoiner; - -import io.openems.api.thing.Thing; - -public class StatusBitChannels extends ReadChannel { - private final Set channels = new HashSet<>(); - - public StatusBitChannels(String id, Thing parent) { - super(id, parent); - } - - public StatusBitChannel channel(StatusBitChannel channel) { - this.channels.add(channel); - return channel; - } - - public Set labels() { - Set result = new HashSet<>(); - for (StatusBitChannel channel : channels) { - result.addAll(channel.labels()); - } - return result; - } - - @Override public Optional labelOptional() { - Set labels = this.labels(); - if (labels.isEmpty()) { - return Optional.empty(); - } else { - StringJoiner joiner = new StringJoiner(","); - for (String label : labels) { - joiner.add(label); - } - return Optional.of(joiner.toString()); - } - }; - - @Override public String toString() { - Optional string = labelOptional(); - if (string.isPresent()) { - return string.get(); - } else { - return ""; - } - } -} diff --git a/edge/src/io/openems/api/channel/ThingState.java b/edge/src/io/openems/api/channel/ThingState.java new file mode 100644 index 00000000000..b6bfbbfc2a5 --- /dev/null +++ b/edge/src/io/openems/api/channel/ThingState.java @@ -0,0 +1,58 @@ +package io.openems.api.channel; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public enum ThingState implements ChannelEnum { + RUN(0), WARNING(1), FAULT(2); + + private static Map resources = new HashMap<>(); + + private int value; + + private ThingState(int value) { + this.value = value; + } + + @Override + public int getValue() { + return this.value; + } + + @Override + public String getName(Locale locale) { + ResourceBundle resource = getResource(locale); + if(resource != null) { + try { + return resource.getString(name()); + }catch(MissingResourceException e) { + // no handling needed + } + } + return name(); + } + + private static ResourceBundle getResource(Locale locale) { + ResourceBundle resource = resources.get(locale); + if (resource != null) { + return resource; + } else { + try { + resource = ResourceBundle.getBundle("ThingStateNames", locale); + resources.put(locale, resource); + return resource; + } catch (MissingResourceException e) { + try { + resource = ResourceBundle.getBundle("ThingStateNames"); + resources.put(locale, resource); + return resource; + } catch (MissingResourceException ex) { + return null; + } + } + } + } +} diff --git a/edge/src/io/openems/api/channel/ThingStateChannel.java b/edge/src/io/openems/api/channel/ThingStateChannel.java new file mode 100644 index 00000000000..b96a37d00f0 --- /dev/null +++ b/edge/src/io/openems/api/channel/ThingStateChannel.java @@ -0,0 +1,118 @@ +package io.openems.api.channel; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; + +import io.openems.api.exception.ConfigException; +import io.openems.api.thing.Thing; + +public class ThingStateChannel extends ReadChannel implements ChannelChangeListener { + + private List> warningChannels; + private List> faultChannels; + private List childChannels; + private Set channelNames; + + public ThingStateChannel(Thing parent){ + super("State", parent); + this.warningChannels = new ArrayList<>(); + this.faultChannels = new ArrayList<>(); + this.channelNames = new HashSet<>(); + this.childChannels = new ArrayList<>(); + } + + public void addWarningChannel(ReadChannel channel) throws ConfigException { + if (!this.channelNames.contains(channel.address())) { + this.warningChannels.add(channel); + this.channelNames.add(channel.address()); + channel.addChangeListener(this); + } else { + throw new ConfigException("A channel with the name [" + channel.address() + "] is already registered!"); + } + } + + public void removeWarningChannel(ReadChannel channel) { + channel.removeChangeListener(this); + this.channelNames.remove(channel.address()); + this.warningChannels.remove(channel); + } + + public void addFaultChannel(ReadChannel channel) throws ConfigException { + if (!this.channelNames.contains(channel.address())) { + this.faultChannels.add(channel); + this.channelNames.add(channel.address()); + channel.addChangeListener(this); + } else { + throw new ConfigException("A channel with the name [" + channel.address() + "] is already registered!"); + } + } + + public void removeFaultChannel(ReadChannel channel) { + channel.removeChangeListener(this); + this.channelNames.remove(channel.address()); + this.faultChannels.remove(channel); + } + + public List> getWarningChannels() { + List> warningChannels = new ArrayList<>(); + warningChannels.addAll(this.warningChannels); + for(ThingStateChannel child : this.childChannels) { + warningChannels.addAll(child.getWarningChannels()); + } + return warningChannels; + } + + public List> getFaultChannels() { + List> faultChannels = new ArrayList<>(); + faultChannels.addAll(this.faultChannels); + for(ThingStateChannel child : this.childChannels) { + faultChannels.addAll(child.getFaultChannels()); + } + return this.faultChannels; + } + + public void addChildChannel(ThingStateChannel child) { + this.childChannels.add(child); + child.addChangeListener(this); + } + + public void removeChildChannel(ThingStateChannel child) { + child.removeChangeListener(this); + this.childChannels.add(child); + } + + @Override + public void channelChanged(Channel channel, Optional newValue, Optional oldValue) { + for(ThingStateChannel child : this.childChannels) { + if(child.isValuePresent()) { + switch(child.getValue()) { + case FAULT: + updateValue(ThingState.FAULT); + return; + case WARNING: + updateValue(ThingState.WARNING); + return; + default: + break; + } + } + } + for (ReadChannel faultChannel : faultChannels) { + if (faultChannel.isValuePresent() && faultChannel.getValue()) { + updateValue(ThingState.FAULT); + return; + } + } + for (ReadChannel warningChannel : warningChannels) { + if (warningChannel.isValuePresent() && warningChannel.getValue()) { + updateValue(ThingState.WARNING); + return; + } + } + updateValue(ThingState.RUN); + } + +} diff --git a/edge/src/io/openems/api/thing/Thing.java b/edge/src/io/openems/api/thing/Thing.java index 473468da5b1..65aeb15fe3d 100644 --- a/edge/src/io/openems/api/thing/Thing.java +++ b/edge/src/io/openems/api/thing/Thing.java @@ -20,6 +20,11 @@ *******************************************************************************/ package io.openems.api.thing; +import io.openems.api.channel.ReadChannel; +import io.openems.api.channel.ThingState; +import io.openems.api.channel.ThingStateChannel; +import io.openems.api.doc.ChannelInfo; + public interface Thing { public String id(); @@ -40,6 +45,21 @@ public default void init() { } + @ChannelInfo(type = ThingState.class) + public ThingStateChannel getStateChannel(); + + @SuppressWarnings("unchecked") + public default ReadChannel[] getFaultChannels(){ + ThingStateChannel stateChannel = getStateChannel(); + return stateChannel.getFaultChannels().toArray(new ReadChannel[stateChannel.getFaultChannels().size()]); + } + + @SuppressWarnings("unchecked") + public default ReadChannel[] getWarningChannels(){ + ThingStateChannel stateChannel = getStateChannel(); + return stateChannel.getWarningChannels().toArray(new ReadChannel[stateChannel.getWarningChannels().size()]); + } + /** * Sets the Thing annotation. This method is called after the thing was initialized via init() * diff --git a/edge/src/io/openems/impl/protocol/modbus/ModbusBridge.java b/edge/src/io/openems/impl/protocol/modbus/ModbusBridge.java index 2709c6b9e7d..8f4782954dd 100644 --- a/edge/src/io/openems/impl/protocol/modbus/ModbusBridge.java +++ b/edge/src/io/openems/impl/protocol/modbus/ModbusBridge.java @@ -51,6 +51,10 @@ @ThingInfo(title = "Modbus") public abstract class ModbusBridge extends Bridge { + public ModbusBridge() { + super(); + } + /* * Abstract Methods */ diff --git a/edge/src/io/openems/impl/protocol/modbus/ModbusRtu.java b/edge/src/io/openems/impl/protocol/modbus/ModbusRtu.java index e5a445dad27..fdb94ababf8 100644 --- a/edge/src/io/openems/impl/protocol/modbus/ModbusRtu.java +++ b/edge/src/io/openems/impl/protocol/modbus/ModbusRtu.java @@ -31,9 +31,11 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ChannelUpdateListener; import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.StaticValueChannel; import io.openems.api.device.Device; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; +import io.openems.api.exception.ConfigException; import io.openems.api.exception.OpenemsModbusException; @ThingInfo(title = "Modbus/RTU") @@ -51,28 +53,38 @@ public void channelUpdated(Channel channel, Optional newValue) { */ @ChannelInfo(title = "Baudrate", description = "Sets the baudrate (e.g. 9600).", type = Integer.class) public final ConfigChannel baudrate = new ConfigChannel("baudrate", this) - .addUpdateListener(channelUpdateListener); + .addUpdateListener(channelUpdateListener); @ChannelInfo(title = "Databits", description = "Sets the databits (e.g. 8).", type = Integer.class) public final ConfigChannel databits = new ConfigChannel("databits", this) - .addUpdateListener(channelUpdateListener); + .addUpdateListener(channelUpdateListener); @ChannelInfo(title = "Parity", description = "Sets the parity (e.g. 'even').", type = String.class) public final ConfigChannel parity = new ConfigChannel("parity", this) - .addUpdateListener(channelUpdateListener); + .addUpdateListener(channelUpdateListener); @ChannelInfo(title = "Serial interface", description = "Sets the serial interface (e.g. /dev/ttyUSB0).", type = String.class) public final ConfigChannel serialinterface = new ConfigChannel("serialinterface", this) - .addUpdateListener(channelUpdateListener); + .addUpdateListener(channelUpdateListener); @ChannelInfo(title = "Stopbits", description = "Sets the stopbits (e.g. 1).", type = Integer.class) public final ConfigChannel stopbits = new ConfigChannel("stopbits", this) - .addUpdateListener(channelUpdateListener); + .addUpdateListener(channelUpdateListener); /* * Fields */ private Optional connection = Optional.empty(); + private StaticValueChannel configurationFault; + private StaticValueChannel connectionFault; + + public ModbusRtu() throws ConfigException { + super(); + this.configurationFault = new StaticValueChannel("Fault\0", this, false); + super.thingState.addFaultChannel(this.configurationFault); + this.connectionFault = new StaticValueChannel("Fault\1", this, false); + super.thingState.addFaultChannel(this.connectionFault); + } /* * Methods @@ -130,6 +142,7 @@ private SerialConnection getModbusConnection() throws OpenemsModbusException { if (!baudrate.valueOptional().isPresent() || !databits.valueOptional().isPresent() || !parity.valueOptional().isPresent() || !serialinterface.valueOptional().isPresent() || !stopbits.valueOptional().isPresent()) { + this.configurationFault.setValue(true); throw new OpenemsModbusException("Modbus-RTU is not configured completely"); } SerialParameters params = new SerialParameters(); @@ -141,13 +154,16 @@ private SerialConnection getModbusConnection() throws OpenemsModbusException { params.setEncoding(Modbus.SERIAL_ENCODING_RTU); params.setEcho(false); connection = Optional.of(new SerialConnection(params)); + this.configurationFault.setValue(false); } if (!connection.get().isOpen()) { try { SerialConnection serialCon = connection.get(); serialCon.open(); serialCon.getModbusTransport().setTimeout(1000); + this.connectionFault.setValue(false); } catch (Exception e) { + this.connectionFault.setValue(true); throw new OpenemsModbusException("Unable to open Modbus-RTU connection: " + connection); } } diff --git a/edge/src/io/openems/impl/protocol/modbus/ModbusTcp.java b/edge/src/io/openems/impl/protocol/modbus/ModbusTcp.java index fe13704a32d..f1d03ff7c7b 100644 --- a/edge/src/io/openems/impl/protocol/modbus/ModbusTcp.java +++ b/edge/src/io/openems/impl/protocol/modbus/ModbusTcp.java @@ -33,9 +33,11 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ChannelUpdateListener; import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.StaticValueChannel; import io.openems.api.device.Device; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; +import io.openems.api.exception.ConfigException; import io.openems.api.exception.InvalidValueException; import io.openems.api.exception.OpenemsModbusException; @@ -54,11 +56,11 @@ public void channelUpdated(Channel channel, Optional newValue) { */ @ChannelInfo(title = "IP address", description = "Sets the IP address (e.g. 10.0.0.15).", type = Inet4Address.class) public final ConfigChannel ip = new ConfigChannel("ip", this) - .addUpdateListener(channelUpdateListener); + .addUpdateListener(channelUpdateListener); @ChannelInfo(title = "Port", description = "Sets the port (e.g. 502).", type = Integer.class, defaultValue = "502") public final ConfigChannel port = new ConfigChannel("port", this) - .addUpdateListener(channelUpdateListener); + .addUpdateListener(channelUpdateListener); /* * Fields @@ -66,6 +68,16 @@ public void channelUpdated(Channel channel, Optional newValue) { private static Logger log = LoggerFactory.getLogger(ModbusTcp.class); private Optional connection = Optional.empty(); + private StaticValueChannel configurationFault; + private StaticValueChannel connectionFault; + + public ModbusTcp() throws ConfigException { + super(); + this.configurationFault = new StaticValueChannel("Fault\0", this, false); + super.thingState.addFaultChannel(this.configurationFault); + this.connectionFault = new StaticValueChannel("Fault\1", this, false); + super.thingState.addFaultChannel(this.connectionFault); + } /* * Methods @@ -124,7 +136,9 @@ private TCPMasterConnection getModbusConnection() throws OpenemsModbusException TCPMasterConnection tcpCon = new TCPMasterConnection(ip.value()); tcpCon.setPort(port.valueOptional().orElse(502)); connection = Optional.of(tcpCon); + this.configurationFault.setValue(false); } catch (InvalidValueException e) { + this.configurationFault.setValue(true); throw new OpenemsModbusException("Modbus-TCP is not configured completely"); } } @@ -133,7 +147,9 @@ private TCPMasterConnection getModbusConnection() throws OpenemsModbusException TCPMasterConnection tcpCon = connection.get(); tcpCon.connect(); tcpCon.getModbusTransport().setTimeout(1000); + this.connectionFault.setValue(false); } catch (Exception e) { + this.connectionFault.setValue(true); throw new OpenemsModbusException("Unable to open Modbus-TCP connection: " + ip.valueOptional().get()); } } From 0c6055819bb1a3ddb2c73d63025c669c7dfa2cd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Ro=C3=9Fmann?= Date: Mon, 8 Jan 2018 13:24:25 +0100 Subject: [PATCH 25/55] add Translation utils --- .../api/translation/ChannelTranslation.java | 63 +++++++++++++ .../translation/ControllerTranslation.java | 10 ++ .../api/translation/DeviceTranslation.java | 11 +++ .../api/translation/ThingTranslation.java | 91 +++++++++++++++++++ .../api/translation/TranslationException.java | 32 +++++++ .../openems/api/translation/Translator.java | 49 ++++++++++ 6 files changed, 256 insertions(+) create mode 100644 edge/src/io/openems/api/translation/ChannelTranslation.java create mode 100644 edge/src/io/openems/api/translation/ControllerTranslation.java create mode 100644 edge/src/io/openems/api/translation/DeviceTranslation.java create mode 100644 edge/src/io/openems/api/translation/ThingTranslation.java create mode 100644 edge/src/io/openems/api/translation/TranslationException.java create mode 100644 edge/src/io/openems/api/translation/Translator.java diff --git a/edge/src/io/openems/api/translation/ChannelTranslation.java b/edge/src/io/openems/api/translation/ChannelTranslation.java new file mode 100644 index 00000000000..848d87ddc83 --- /dev/null +++ b/edge/src/io/openems/api/translation/ChannelTranslation.java @@ -0,0 +1,63 @@ +package io.openems.api.translation; + +import java.util.HashMap; +import java.util.Locale; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +public class ChannelTranslation { + + private final String channelId; + private final HashMap channelNameTranslations; + private final HashMap channelDescriptionTranslations; + + public ChannelTranslation(String channelId,String defaultChannelName, String defaultChannelDescription) throws TranslationException { + this.channelId = channelId; + this.channelNameTranslations = new HashMap<>(); + this.channelDescriptionTranslations = new HashMap<>(); + setChannelNameTranslation(Locale.ENGLISH, defaultChannelName); + setChannelDescriptionTranslation(Locale.ENGLISH, defaultChannelDescription); + } + + public String getId() { + return this.channelId; + } + + public void setChannelNameTranslation(Locale locale, String translation) throws TranslationException { + if (locale != null && translation != null && translation.length() > 0) { + this.channelNameTranslations.put(locale, translation); + } else { + throw new TranslationException("The Locale or translation is Empty!"); + } + } + + public void setChannelDescriptionTranslation(Locale locale, String translation) throws TranslationException { + if (locale != null && translation != null && translation.length() > 0) { + this.channelDescriptionTranslations.put(locale, translation); + } else { + throw new TranslationException("The Locale or translation is Empty!"); + } + } + + public String getChannelName(Locale locale) { + if(this.channelNameTranslations.containsKey(locale)) { + return this.channelNameTranslations.get(locale); + } + return this.channelNameTranslations.get(Locale.ENGLISH); + } + + public String getChannelDescription(Locale locale) { + if(this.channelDescriptionTranslations.containsKey(locale)) { + return this.channelDescriptionTranslations.get(locale); + } + return this.channelDescriptionTranslations.get(Locale.ENGLISH); + } + + public JsonElement getAsJson(Locale locale) { + JsonObject translation = new JsonObject(); + translation.addProperty("name", this.channelNameTranslations.get(locale)); + translation.addProperty("description", this.channelDescriptionTranslations.get(locale)); + return translation; + } +} diff --git a/edge/src/io/openems/api/translation/ControllerTranslation.java b/edge/src/io/openems/api/translation/ControllerTranslation.java new file mode 100644 index 00000000000..08fc0d88a4b --- /dev/null +++ b/edge/src/io/openems/api/translation/ControllerTranslation.java @@ -0,0 +1,10 @@ +package io.openems.api.translation; + +public class ControllerTranslation extends ThingTranslation{ + + public ControllerTranslation(Class thingClass, String defaultThingName, String defaultThingDescription) + throws TranslationException { + super(thingClass, defaultThingName, defaultThingDescription); + } + +} diff --git a/edge/src/io/openems/api/translation/DeviceTranslation.java b/edge/src/io/openems/api/translation/DeviceTranslation.java new file mode 100644 index 00000000000..1119a386cff --- /dev/null +++ b/edge/src/io/openems/api/translation/DeviceTranslation.java @@ -0,0 +1,11 @@ +package io.openems.api.translation; + +public class DeviceTranslation extends ThingTranslation{ + + public DeviceTranslation(Class thingClass, String defaultThingName, String defaultThingDescription) + throws TranslationException { + super(thingClass, defaultThingName, defaultThingDescription); + } + + +} diff --git a/edge/src/io/openems/api/translation/ThingTranslation.java b/edge/src/io/openems/api/translation/ThingTranslation.java new file mode 100644 index 00000000000..a4d11aaaac5 --- /dev/null +++ b/edge/src/io/openems/api/translation/ThingTranslation.java @@ -0,0 +1,91 @@ +package io.openems.api.translation; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +public abstract class ThingTranslation { + + private final Class thingClass; + private final HashMap channels; + private final HashMap thingNameTranslations; + private final HashMap thingDescriptionTranslations; + + public ThingTranslation(Class thingClass, String defaultThingName, String defaultThingDescription) throws TranslationException { + this.thingClass = thingClass; + this.channels = new HashMap<>(); + this.thingNameTranslations = new HashMap<>(); + this.thingDescriptionTranslations = new HashMap<>(); + this.setNameTranslation(Locale.ENGLISH, defaultThingName); + this.setDescriptionTranslation(Locale.ENGLISH, defaultThingDescription); + } + + public Class getThingClass() { + return this.thingClass; + } + + public void addChannelTranslation(ChannelTranslation translation) throws TranslationException { + if (translation != null && translation.getId() != null) { + if (this.channels.containsKey(translation.getId())) { + throw new TranslationException("The ChannelTranslation for "+translation.getId()+" is already existing!"); + } else { + this.channels.put(translation.getId(), translation); + } + } else { + throw new TranslationException("The channeltranslation is null!"); + } + } + /** + * Get the Channel Translatin by the ChannelId. + * @param channelId + * @return the Translation object or null. + */ + public ChannelTranslation getChannelTranslation(String channelId) { + return this.channels.get(channelId); + } + + public void setNameTranslation(Locale locale, String translation) throws TranslationException { + if (locale != null && translation != null && translation.length() > 0) { + this.thingNameTranslations.put(locale, translation); + } else { + throw new TranslationException("The Locale or translation is Empty!"); + } + } + + public void setDescriptionTranslation(Locale locale, String translation) throws TranslationException { + if (locale != null && translation != null && translation.length() > 0) { + this.thingDescriptionTranslations.put(locale, translation); + } else { + throw new TranslationException("The Locale or translation is Empty!"); + } + } + + public String getName(Locale locale) { + if(this.thingNameTranslations.containsKey(locale)) { + return this.thingNameTranslations.get(locale); + } + return this.thingNameTranslations.get(Locale.ENGLISH); + } + + public String getDescription(Locale locale) { + if(this.thingDescriptionTranslations.containsKey(locale)) { + return this.thingDescriptionTranslations.get(locale); + } + return this.thingDescriptionTranslations.get(Locale.ENGLISH); + } + + public JsonElement getAsJson(Locale locale) { + JsonObject translation = new JsonObject(); + translation.addProperty("name", this.thingNameTranslations.get(locale)); + translation.addProperty("description", this.thingDescriptionTranslations.get(locale)); + JsonObject channelTranslations = new JsonObject(); + for(Map.Entry channelTranslation: this.channels.entrySet()) { + channelTranslations.add(channelTranslation.getKey(), channelTranslation.getValue().getAsJson(locale)); + } + translation.add("channels", channelTranslations); + return translation; + } +} diff --git a/edge/src/io/openems/api/translation/TranslationException.java b/edge/src/io/openems/api/translation/TranslationException.java new file mode 100644 index 00000000000..06825f431df --- /dev/null +++ b/edge/src/io/openems/api/translation/TranslationException.java @@ -0,0 +1,32 @@ +package io.openems.api.translation; + +public class TranslationException extends RuntimeException { + + /** + * + */ + private static final long serialVersionUID = -189217968357389677L; + + public TranslationException() { + super(); + } + + public TranslationException(String arg0, Throwable arg1, boolean arg2, boolean arg3) { + super(arg0, arg1, arg2, arg3); + } + + public TranslationException(String arg0, Throwable arg1) { + super(arg0, arg1); + } + + public TranslationException(String arg0) { + super(arg0); + } + + public TranslationException(Throwable arg0) { + super(arg0); + } + + + +} diff --git a/edge/src/io/openems/api/translation/Translator.java b/edge/src/io/openems/api/translation/Translator.java new file mode 100644 index 00000000000..31a6104ec64 --- /dev/null +++ b/edge/src/io/openems/api/translation/Translator.java @@ -0,0 +1,49 @@ +package io.openems.api.translation; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import com.google.gson.JsonObject; + +public class Translator { + + private static Translator instance; + private Map, ThingTranslation> thingTranslations; + + private Translator() { + this.thingTranslations = new HashMap<>(); + } + + public static Translator getInstance() { + if(instance == null) { + instance = new Translator(); + } + return instance; + } + + public void addThingTranslation(ThingTranslation translation) throws TranslationException { + if (translation != null && translation.getThingClass() != null) { + if (this.thingTranslations.containsKey(translation.getThingClass())) { + throw new TranslationException("The ThingTranslation for "+translation.getThingClass()+" is already existing!"); + } else { + this.thingTranslations.put(translation.getThingClass(), translation); + } + } else { + throw new TranslationException("The thingtranslation is null!"); + } + } + + public ThingTranslation getThingTranslation(Class thingClass) { + return this.thingTranslations.get(thingClass); + } + + public JsonObject getAsJson(Locale locale) { + JsonObject translation = new JsonObject(); + for(Map.Entry, ThingTranslation> thingTranslation:thingTranslations.entrySet()) { + translation.add(thingTranslation.getKey().getName(), thingTranslation.getValue().getAsJson(locale)); + } + return translation; + } + +} From ad83bf6748f3459c87732e2709fb33cae5408a28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Ro=C3=9Fmann?= Date: Tue, 9 Jan 2018 16:35:24 +0100 Subject: [PATCH 26/55] Add ThingStateChannel to generalize the ErrorHandling of devices and Controllers restructure some Packages --- .../openems/api/channel/StatusBitChannel.java | 132 ++++++++++++------ .../api/channel/StatusBitChannels.java | 71 ++++++++++ .../api/channel/ValueToBooleanChannel.java | 30 ++++ .../api/channel/thingstate/FaultEnum.java | 9 ++ .../channel/{ => thingstate}/ThingState.java | 4 +- .../{ => thingstate}/ThingStateChannel.java | 5 +- .../api/channel/thingstate/WarningEnum.java | 9 ++ edge/src/io/openems/api/thing/Thing.java | 4 +- .../modbus/ModbusBitWrappingChannel.java | 51 +++++++ 9 files changed, 265 insertions(+), 50 deletions(-) create mode 100644 edge/src/io/openems/api/channel/StatusBitChannels.java create mode 100644 edge/src/io/openems/api/channel/ValueToBooleanChannel.java create mode 100644 edge/src/io/openems/api/channel/thingstate/FaultEnum.java rename edge/src/io/openems/api/channel/{ => thingstate}/ThingState.java (93%) rename edge/src/io/openems/api/channel/{ => thingstate}/ThingStateChannel.java (95%) create mode 100644 edge/src/io/openems/api/channel/thingstate/WarningEnum.java create mode 100644 edge/src/io/openems/impl/protocol/modbus/ModbusBitWrappingChannel.java diff --git a/edge/src/io/openems/api/channel/StatusBitChannel.java b/edge/src/io/openems/api/channel/StatusBitChannel.java index b6d6aa93a91..17ec2b4af2e 100644 --- a/edge/src/io/openems/api/channel/StatusBitChannel.java +++ b/edge/src/io/openems/api/channel/StatusBitChannel.java @@ -1,46 +1,86 @@ -/******************************************************************************* - * 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.api.channel; - -import io.openems.api.device.nature.DeviceNature; -import io.openems.api.exception.ConfigException; -import io.openems.impl.protocol.modbus.ModbusReadChannel; - -public class StatusBitChannel extends ModbusReadChannel { - - private final ThingStateChannel thingState; - - public StatusBitChannel(String id, DeviceNature nature, ThingStateChannel thingStateChannel) { - super(id, nature); - this.thingState = thingStateChannel; - } - - public StatusBitChannel warningBit(int i, int j) throws ConfigException { - thingState.addWarningChannel(new BitToBooleanChannel("Warning\\"+i, this.parent(), this, j)); - return this; - } - - public StatusBitChannel faultBit(int i, int j) throws ConfigException { - thingState.addFaultChannel(new BitToBooleanChannel("Fault\\"+i, this.parent(), this, j)); - return this; - } - -} +/******************************************************************************* + * 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.api.channel; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.Set; +import java.util.StringJoiner; + +import io.openems.api.device.nature.DeviceNature; +import io.openems.impl.protocol.modbus.ModbusReadChannel; + +public class StatusBitChannel extends ModbusReadChannel { + + public StatusBitChannel(String id, DeviceNature nature) { + super(id, nature); + } + + /** + * Get labels for all set bits + * Example: Value is 5, Labels are 1=One; 2=Two; 4=Four -> this method returns [One, Four] + * + * @return + */ + public Set labels() { + Set result = new HashSet<>(); + Optional valueOptional = valueOptional(); + if (valueOptional.isPresent() && !this.labels.isEmpty()) { + long value = valueOptional.get(); + long max = Collections.max(this.labels.keySet()); + if (max * 2 <= value) { + value = value & (max - 1); + } + for (Entry entry : this.labels.descendingMap().entrySet()) { + if (entry.getKey() <= value) { + result.add(entry.getValue()); + value -= entry.getKey(); + } + } + } + return result; + }; + + @Override + public Optional labelOptional() { + Set labels = this.labels(); + if (labels.isEmpty()) { + return Optional.empty(); + } else { + StringJoiner joiner = new StringJoiner(","); + for (String label : labels) { + joiner.add(this.id() + "/" + label); + } + return Optional.of(joiner.toString()); + } + }; + + @Override + public StatusBitChannel label(Long value, String label) { + return (StatusBitChannel) super.label(value, label); + } + + public StatusBitChannel label(int value, String label) { + return (StatusBitChannel) super.label(Long.valueOf(value), label); + } +} diff --git a/edge/src/io/openems/api/channel/StatusBitChannels.java b/edge/src/io/openems/api/channel/StatusBitChannels.java new file mode 100644 index 00000000000..bdbe790d4eb --- /dev/null +++ b/edge/src/io/openems/api/channel/StatusBitChannels.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * OpenEMS - Open Source Energy Management System + * Copyright (c) 2016 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.api.channel; + +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; +import java.util.StringJoiner; + +import io.openems.api.thing.Thing; + +public class StatusBitChannels extends ReadChannel { + private final Set channels = new HashSet<>(); + + public StatusBitChannels(String id, Thing parent) { + super(id, parent); + } + + public StatusBitChannel channel(StatusBitChannel channel) { + this.channels.add(channel); + return channel; + } + + public Set labels() { + Set result = new HashSet<>(); + for (StatusBitChannel channel : channels) { + result.addAll(channel.labels()); + } + return result; + } + + @Override public Optional labelOptional() { + Set labels = this.labels(); + if (labels.isEmpty()) { + return Optional.empty(); + } else { + StringJoiner joiner = new StringJoiner(","); + for (String label : labels) { + joiner.add(label); + } + return Optional.of(joiner.toString()); + } + }; + + @Override public String toString() { + Optional string = labelOptional(); + if (string.isPresent()) { + return string.get(); + } else { + return ""; + } + } +} diff --git a/edge/src/io/openems/api/channel/ValueToBooleanChannel.java b/edge/src/io/openems/api/channel/ValueToBooleanChannel.java new file mode 100644 index 00000000000..7264b88e5e2 --- /dev/null +++ b/edge/src/io/openems/api/channel/ValueToBooleanChannel.java @@ -0,0 +1,30 @@ +package io.openems.api.channel; + +import java.util.Optional; + +import io.openems.api.thing.Thing; + +public class ValueToBooleanChannel extends ReadChannel implements ChannelChangeListener{ + + private ReadChannel valueChannel; + private long value; + + public ValueToBooleanChannel(String id, Thing parent, ReadChannel channel, long value) { + super(id, parent); + this.valueChannel = channel; + this.valueChannel.addChangeListener(this); + this.value = value; + } + + @Override + public void channelChanged(Channel channel, Optional newValue, Optional oldValue) { + if(valueChannel.isValuePresent()) { + if(valueChannel.getValue().longValue() == value) { + updateValue(true); + }else { + updateValue(false); + } + } + } + +} diff --git a/edge/src/io/openems/api/channel/thingstate/FaultEnum.java b/edge/src/io/openems/api/channel/thingstate/FaultEnum.java new file mode 100644 index 00000000000..b43a5ab34f5 --- /dev/null +++ b/edge/src/io/openems/api/channel/thingstate/FaultEnum.java @@ -0,0 +1,9 @@ +package io.openems.api.channel.thingstate; + +public interface FaultEnum { + int getValue(); + + default String getChannelId() { + return "Fault/"+this.getValue(); + } +} diff --git a/edge/src/io/openems/api/channel/ThingState.java b/edge/src/io/openems/api/channel/thingstate/ThingState.java similarity index 93% rename from edge/src/io/openems/api/channel/ThingState.java rename to edge/src/io/openems/api/channel/thingstate/ThingState.java index b6bfbbfc2a5..920f8a93d9f 100644 --- a/edge/src/io/openems/api/channel/ThingState.java +++ b/edge/src/io/openems/api/channel/thingstate/ThingState.java @@ -1,4 +1,4 @@ -package io.openems.api.channel; +package io.openems.api.channel.thingstate; import java.util.HashMap; import java.util.Locale; @@ -6,6 +6,8 @@ import java.util.MissingResourceException; import java.util.ResourceBundle; +import io.openems.api.channel.ChannelEnum; + public enum ThingState implements ChannelEnum { RUN(0), WARNING(1), FAULT(2); diff --git a/edge/src/io/openems/api/channel/ThingStateChannel.java b/edge/src/io/openems/api/channel/thingstate/ThingStateChannel.java similarity index 95% rename from edge/src/io/openems/api/channel/ThingStateChannel.java rename to edge/src/io/openems/api/channel/thingstate/ThingStateChannel.java index b96a37d00f0..0a432beb802 100644 --- a/edge/src/io/openems/api/channel/ThingStateChannel.java +++ b/edge/src/io/openems/api/channel/thingstate/ThingStateChannel.java @@ -1,4 +1,4 @@ -package io.openems.api.channel; +package io.openems.api.channel.thingstate; import java.util.ArrayList; import java.util.HashSet; @@ -6,6 +6,9 @@ import java.util.Optional; import java.util.Set; +import io.openems.api.channel.Channel; +import io.openems.api.channel.ChannelChangeListener; +import io.openems.api.channel.ReadChannel; import io.openems.api.exception.ConfigException; import io.openems.api.thing.Thing; diff --git a/edge/src/io/openems/api/channel/thingstate/WarningEnum.java b/edge/src/io/openems/api/channel/thingstate/WarningEnum.java new file mode 100644 index 00000000000..a3fedf985be --- /dev/null +++ b/edge/src/io/openems/api/channel/thingstate/WarningEnum.java @@ -0,0 +1,9 @@ +package io.openems.api.channel.thingstate; + +public interface WarningEnum { + int getValue(); + + default String getChannelId() { + return "Warning/"+this.getValue(); + } +} diff --git a/edge/src/io/openems/api/thing/Thing.java b/edge/src/io/openems/api/thing/Thing.java index 65aeb15fe3d..aa07b6d6f0a 100644 --- a/edge/src/io/openems/api/thing/Thing.java +++ b/edge/src/io/openems/api/thing/Thing.java @@ -21,8 +21,8 @@ package io.openems.api.thing; import io.openems.api.channel.ReadChannel; -import io.openems.api.channel.ThingState; -import io.openems.api.channel.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingState; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.doc.ChannelInfo; public interface Thing { diff --git a/edge/src/io/openems/impl/protocol/modbus/ModbusBitWrappingChannel.java b/edge/src/io/openems/impl/protocol/modbus/ModbusBitWrappingChannel.java new file mode 100644 index 00000000000..ba2a073c79d --- /dev/null +++ b/edge/src/io/openems/impl/protocol/modbus/ModbusBitWrappingChannel.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * 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.protocol.modbus; + +import io.openems.api.channel.BitToBooleanChannel; +import io.openems.api.channel.thingstate.FaultEnum; +import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.WarningEnum; +import io.openems.api.device.nature.DeviceNature; +import io.openems.api.exception.ConfigException; + +public class ModbusBitWrappingChannel extends ModbusReadChannel { + + private final ThingStateChannel thingState; + + public ModbusBitWrappingChannel(String id, DeviceNature nature, ThingStateChannel thingStateChannel) { + super(id, nature); + this.thingState = thingStateChannel; + } + + public ModbusBitWrappingChannel warningBit(int bitIndex,WarningEnum warningCode) throws ConfigException { + thingState.addWarningChannel( + new BitToBooleanChannel(warningCode.getChannelId(), this.parent(), this, bitIndex)); + return this; + } + + public ModbusBitWrappingChannel faultBit( int bitIndex,FaultEnum faultCode) throws ConfigException { + thingState.addFaultChannel( + new BitToBooleanChannel(faultCode.getChannelId(), this.parent(), this, bitIndex)); + return this; + } + +} From 6d108b4a6580a73151d7c84be090cca47f2d32a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Ro=C3=9Fmann?= Date: Tue, 9 Jan 2018 16:40:02 +0100 Subject: [PATCH 27/55] implement ThingStateChannel for all Devices to get a compiling Framework further error mapping is required to forward all errors to the ThingState --- edge/src/io/openems/api/bridge/Bridge.java | 2 +- edge/src/io/openems/api/device/Device.java | 28 +- .../api/device/nature/ess/EssNature.java | 173 +++-- .../FeneconProSetupController.java | 171 ++--- .../riedmann/RiedmannController.java | 7 + .../impl/device/bcontrol/BControl.java | 4 +- .../impl/device/bcontrol/BControlMeter.java | 9 + .../openems/impl/device/byd/Bem125ktla01.java | 2 +- .../impl/device/byd/Bem125ktla01Ess.java | 105 ++- .../io/openems/impl/device/byd/Warning.java | 17 + .../carlogavazzi/em300series/EM300.java | 2 +- .../carlogavazzi/em300series/EM300Meter.java | 31 +- .../commercial/FeneconCommercialAC.java | 2 +- .../commercial/FeneconCommercialCharger.java | 655 +++++++++--------- .../commercial/FeneconCommercialDC.java | 4 +- .../commercial/FeneconCommercialEss.java | 299 ++++---- .../impl/device/commercial/Warning.java | 19 + .../impl/device/custom/riedmann/Riedmann.java | 2 +- .../custom/riedmann/RiedmannNatureImpl.java | 10 +- .../impl/device/janitza/JanitzaUMG96RME.java | 2 +- .../device/janitza/JanitzaUMG96RMEMeter.java | 37 +- .../src/io/openems/impl/device/keba/Keba.java | 2 +- .../io/openems/impl/device/keba/KebaEvcs.java | 9 + .../impl/device/kmtronic/KMTronicRelay.java | 2 +- .../device/kmtronic/KMTronicRelayOutput.java | 9 + .../kmtronic/KMTronicRelayOutputRev1.java | 9 + .../device/kmtronic/KMTronicRelayRev1.java | 2 +- .../openems/impl/device/mini/FeneconMini.java | 2 +- .../impl/device/mini/FeneconMiniEss.java | 218 +++--- .../impl/device/minireadonly/FeneconMini.java | 13 +- .../FeneconMiniConsumptionMeter.java | 11 +- .../device/minireadonly/FeneconMiniEss.java | 14 +- .../minireadonly/FeneconMiniGridMeter.java | 9 + .../FeneconMiniProductionMeter.java | 9 + .../impl/device/pqplus/PqPlusUMD97.java | 2 +- .../impl/device/pqplus/PqPlusUMD97Meter.java | 9 + .../io/openems/impl/device/pro/FaultEss.java | 21 + .../openems/impl/device/pro/FeneconPro.java | 7 +- .../impl/device/pro/FeneconProEss.java | 457 ++++++------ .../impl/device/pro/FeneconProPvMeter.java | 36 +- .../openems/impl/device/pro/WarningEss.java | 21 + .../impl/device/pro/WarningPvMeter.java | 18 + .../src/io/openems/impl/device/refu/Refu.java | 2 +- .../io/openems/impl/device/refu/RefuEss.java | 239 +++---- .../impl/device/simulator/Simulator.java | 14 +- .../simulator/SimulatorAsymmetricEss.java | 15 +- .../device/simulator/SimulatorCharger.java | 9 + .../device/simulator/SimulatorGridMeter.java | 8 + .../device/simulator/SimulatorOutput.java | 8 + .../simulator/SimulatorProductionMeter.java | 8 + .../simulator/SimulatorRiedmannNature.java | 13 +- .../simulator/SimulatorSymmetricEss.java | 19 +- .../openems/impl/device/sma/SunnyIsland6.java | 2 +- .../impl/device/sma/SunnyIsland6Ess.java | 17 +- .../openems/impl/device/socomec/Socomec.java | 2 +- .../impl/device/socomec/SocomecB30.java | 2 +- .../impl/device/socomec/SocomecB30Meter.java | 13 +- .../impl/device/socomec/SocomecMeter.java | 27 +- .../device/socomec/SocomecSinglePhase.java | 2 +- .../socomec/SocomecSinglePhaseMeter.java | 9 + .../io/openems/impl/device/spanner/BHKW.java | 2 +- .../impl/device/spanner/BHKWMeter.java | 9 + .../impl/device/studer/StuderVs70.java | 2 +- .../impl/device/studer/StuderVs70Charger.java | 9 + .../io/openems/impl/device/system/System.java | 23 +- .../impl/device/system/SystemNature.java | 11 +- .../device/system/esscluster/EssCluster.java | 2 +- .../system/esscluster/EssClusterNature.java | 17 +- .../system/metercluster/MeterCluster.java | 2 +- .../metercluster/MeterClusterNature.java | 20 +- .../io/openems/impl/device/wago/WagoFB.java | 378 +++++----- .../openems/impl/device/wago/WagoFBInput.java | 216 +++--- .../impl/device/wago/WagoFBOutput.java | 218 +++--- 73 files changed, 2068 insertions(+), 1711 deletions(-) create mode 100644 edge/src/io/openems/impl/device/byd/Warning.java create mode 100644 edge/src/io/openems/impl/device/commercial/Warning.java create mode 100644 edge/src/io/openems/impl/device/pro/FaultEss.java create mode 100644 edge/src/io/openems/impl/device/pro/WarningEss.java create mode 100644 edge/src/io/openems/impl/device/pro/WarningPvMeter.java diff --git a/edge/src/io/openems/api/bridge/Bridge.java b/edge/src/io/openems/api/bridge/Bridge.java index 7fbc86c3fb5..d7a9866442d 100644 --- a/edge/src/io/openems/api/bridge/Bridge.java +++ b/edge/src/io/openems/api/bridge/Bridge.java @@ -32,7 +32,7 @@ import io.openems.api.bridge.BridgeEvent.Position; import io.openems.api.channel.DebugChannel; -import io.openems.api.channel.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.scheduler.Scheduler; import io.openems.api.thing.Thing; diff --git a/edge/src/io/openems/api/device/Device.java b/edge/src/io/openems/api/device/Device.java index 5202cf3b045..d5e7b551464 100644 --- a/edge/src/io/openems/api/device/Device.java +++ b/edge/src/io/openems/api/device/Device.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.Set; import org.slf4j.Logger; @@ -30,21 +31,27 @@ import io.openems.api.bridge.Bridge; import io.openems.api.bridge.BridgeReadTask; import io.openems.api.bridge.BridgeWriteTask; +import io.openems.api.channel.Channel; +import io.openems.api.channel.ChannelChangeListener; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.nature.DeviceNature; import io.openems.api.exception.OpenemsException; import io.openems.api.thing.Thing; -public abstract class Device implements Thing { +public abstract class Device implements Thing, ChannelChangeListener { public final static String THINGID_PREFIX = "_device"; private static int instanceCounter = 0; protected final Logger log; private Bridge bridge = null; private final String thingId; + private ThingStateChannel thingState; public Device(Bridge parent) throws OpenemsException { this.thingId = THINGID_PREFIX + instanceCounter++; log = LoggerFactory.getLogger(this.getClass()); this.bridge = parent; + this.thingState = new ThingStateChannel(this); + this.thingState.addChildChannel(this.bridge.getStateChannel()); } public Bridge getBridge() { @@ -98,4 +105,23 @@ public List getWriteTasks() { } return writeTasks; } + + @Override + public void channelChanged(Channel channel, Optional newValue, Optional oldValue) { + if (oldValue.isPresent()) { + if (oldValue.get() instanceof DeviceNature) { + this.thingState.removeChildChannel(((DeviceNature) oldValue.get()).getStateChannel()); + } + } + if (newValue.isPresent()) { + if (newValue.get() instanceof DeviceNature) { + this.thingState.addChildChannel(((DeviceNature) newValue.get()).getStateChannel()); + } + } + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } } diff --git a/edge/src/io/openems/api/device/nature/ess/EssNature.java b/edge/src/io/openems/api/device/nature/ess/EssNature.java index b735451c74f..f99f0b50d51 100644 --- a/edge/src/io/openems/api/device/nature/ess/EssNature.java +++ b/edge/src/io/openems/api/device/nature/ess/EssNature.java @@ -1,88 +1,85 @@ -/******************************************************************************* - * OpenEMS - Open Source Energy Management System - * Copyright (c) 2016 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.api.device.nature.ess; - -import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.ReadChannel; -import io.openems.api.channel.StatusBitChannels; -import io.openems.api.channel.WriteChannel; -import io.openems.api.device.nature.DeviceNature; -import io.openems.api.doc.ChannelInfo; - -public interface EssNature extends DeviceNature { - /* - * Constants - */ - public final int DEFAULT_MINSOC = 10; - - public final String OFF = "Off"; - public final String ON = "On"; - - public final String OFF_GRID = "Off-Grid"; - public final String ON_GRID = "On-Grid"; - - public final String STANDBY = "Standby"; - public final String START = "Start"; - public final String STOP = "Stop"; - public final String FAULT = "Fault"; - - /* - * Config - */ - @ChannelInfo(title = "Min-SOC", description = "Sets the minimal SOC.", type = Integer.class) - public ConfigChannel minSoc(); - - @ChannelInfo(title = "Charge-SOC", description = "Sets the force charge SOC.", type = Integer.class, isOptional = true) - public ConfigChannel chargeSoc(); - - /* - * Read Channels - */ - public ReadChannel gridMode(); - - @ChannelInfo(type = Long.class) - public ReadChannel soc(); - - @ChannelInfo(type = Long.class) - public ReadChannel systemState(); - - @ChannelInfo(type = Long.class) - public ReadChannel allowedCharge(); - - @ChannelInfo(type = Long.class) - public ReadChannel allowedDischarge(); - - @ChannelInfo(type = Long.class) - public ReadChannel allowedApparent(); - - @ChannelInfo(type = Long.class) - public ReadChannel capacity(); - - @ChannelInfo(type = Long.class) - public ReadChannel maxNominalPower(); - - public StatusBitChannels warning(); - - /* - * Write Channels - */ - public WriteChannel setWorkState(); -} +/******************************************************************************* + * OpenEMS - Open Source Energy Management System + * Copyright (c) 2016 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.api.device.nature.ess; + +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.ReadChannel; +import io.openems.api.channel.WriteChannel; +import io.openems.api.device.nature.DeviceNature; +import io.openems.api.doc.ChannelInfo; + +public interface EssNature extends DeviceNature { + /* + * Constants + */ + public final int DEFAULT_MINSOC = 10; + + public final String OFF = "Off"; + public final String ON = "On"; + + public final String OFF_GRID = "Off-Grid"; + public final String ON_GRID = "On-Grid"; + + public final String STANDBY = "Standby"; + public final String START = "Start"; + public final String STOP = "Stop"; + public final String FAULT = "Fault"; + + /* + * Config + */ + @ChannelInfo(title = "Min-SOC", description = "Sets the minimal SOC.", type = Integer.class) + public ConfigChannel minSoc(); + + @ChannelInfo(title = "Charge-SOC", description = "Sets the force charge SOC.", type = Integer.class, isOptional = true) + public ConfigChannel chargeSoc(); + + /* + * Read Channels + */ + public ReadChannel gridMode(); + + @ChannelInfo(type = Long.class) + public ReadChannel soc(); + + @ChannelInfo(type = Long.class) + public ReadChannel systemState(); + + @ChannelInfo(type = Long.class) + public ReadChannel allowedCharge(); + + @ChannelInfo(type = Long.class) + public ReadChannel allowedDischarge(); + + @ChannelInfo(type = Long.class) + public ReadChannel allowedApparent(); + + @ChannelInfo(type = Long.class) + public ReadChannel capacity(); + + @ChannelInfo(type = Long.class) + public ReadChannel maxNominalPower(); + + /* + * Write Channels + */ + public WriteChannel setWorkState(); +} diff --git a/edge/src/io/openems/impl/controller/feneconprosetup/FeneconProSetupController.java b/edge/src/io/openems/impl/controller/feneconprosetup/FeneconProSetupController.java index f9a48e41ea8..6f5600ccb6f 100644 --- a/edge/src/io/openems/impl/controller/feneconprosetup/FeneconProSetupController.java +++ b/edge/src/io/openems/impl/controller/feneconprosetup/FeneconProSetupController.java @@ -1,82 +1,89 @@ -/******************************************************************************* - * 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.feneconprosetup; - -import java.util.List; - -import io.openems.api.channel.ConfigChannel; -import io.openems.api.controller.Controller; -import io.openems.api.device.nature.ess.EssNature; -import io.openems.api.doc.ChannelInfo; -import io.openems.api.doc.ThingInfo; -import io.openems.api.exception.InvalidValueException; -import io.openems.api.exception.WriteChannelException; - -@ThingInfo(title = "Initial setup for FENECON Pro", description = "Sets the correct factory settings for FENECON Pro energy storage systems.") -public class FeneconProSetupController extends Controller { - - /* - * Constructors - */ - public FeneconProSetupController() { - super(); - } - - public FeneconProSetupController(String thingId) { - super(thingId); - } - - /* - * Config - */ - @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class, isArray = true) - public ConfigChannel> esss = new ConfigChannel>("esss", this); - - /* - * Methods - */ - @Override - public void run() { - try { - for (Ess ess : esss.value()) { - if (ess.pcsMode.labelOptional().isPresent() && ess.pcsMode.labelOptional().get().equals("Debug")) { - if (ess.setupMode.labelOptional().isPresent() - && ess.setupMode.labelOptional().get().equals(EssNature.ON)) { - ess.setPcsMode.pushWriteFromLabel("Remote"); - log.info("Set " + ess.id() + " to Remote mode."); - } else { - log.info(ess.id() + " is not in Remote mode. Go to Setting Mode."); - ess.setSetupMode.pushWriteFromLabel(EssNature.ON); - } - } else { - if (ess.setupMode.labelOptional().isPresent() - && ess.setupMode.labelOptional().get().equals(EssNature.ON)) { - ess.setSetupMode.pushWriteFromLabel(EssNature.OFF); - log.info(ess.id() + " Switch setting mode Off"); - } - } - } - } catch (InvalidValueException | WriteChannelException e) { - log.error("Failed to Finish Setup", e); - } - } - -} +/******************************************************************************* + * 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.feneconprosetup; + +import java.util.List; + +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.controller.Controller; +import io.openems.api.device.nature.ess.EssNature; +import io.openems.api.doc.ChannelInfo; +import io.openems.api.doc.ThingInfo; +import io.openems.api.exception.InvalidValueException; +import io.openems.api.exception.WriteChannelException; + +@ThingInfo(title = "Initial setup for FENECON Pro", description = "Sets the correct factory settings for FENECON Pro energy storage systems.") +public class FeneconProSetupController extends Controller { + + /* + * Constructors + */ + public FeneconProSetupController() { + super(); + } + + public FeneconProSetupController(String thingId) { + super(thingId); + } + + /* + * Config + */ + @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class, isArray = true) + public ConfigChannel> esss = new ConfigChannel>("esss", this); + + /* + * Methods + */ + @Override + public void run() { + try { + for (Ess ess : esss.value()) { + if (ess.pcsMode.labelOptional().isPresent() && ess.pcsMode.labelOptional().get().equals("Debug")) { + if (ess.setupMode.labelOptional().isPresent() + && ess.setupMode.labelOptional().get().equals(EssNature.ON)) { + ess.setPcsMode.pushWriteFromLabel("Remote"); + log.info("Set " + ess.id() + " to Remote mode."); + } else { + log.info(ess.id() + " is not in Remote mode. Go to Setting Mode."); + ess.setSetupMode.pushWriteFromLabel(EssNature.ON); + } + } else { + if (ess.setupMode.labelOptional().isPresent() + && ess.setupMode.labelOptional().get().equals(EssNature.ON)) { + ess.setSetupMode.pushWriteFromLabel(EssNature.OFF); + log.info(ess.id() + " Switch setting mode Off"); + } + } + } + } catch (InvalidValueException | WriteChannelException e) { + log.error("Failed to Finish Setup", e); + } + } + + @Override + public ThingStateChannel getStateChannel() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/edge/src/io/openems/impl/controller/riedmann/RiedmannController.java b/edge/src/io/openems/impl/controller/riedmann/RiedmannController.java index bd82ddcad55..bf43aef2880 100644 --- a/edge/src/io/openems/impl/controller/riedmann/RiedmannController.java +++ b/edge/src/io/openems/impl/controller/riedmann/RiedmannController.java @@ -5,6 +5,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ChannelChangeListener; import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -251,4 +252,10 @@ public void channelChanged(Channel channel, Optional newValue, Optional ol updateWaterLevelBorehole3On = true; } } + + @Override + public ThingStateChannel getStateChannel() { + // TODO Auto-generated method stub + return null; + } } diff --git a/edge/src/io/openems/impl/device/bcontrol/BControl.java b/edge/src/io/openems/impl/device/bcontrol/BControl.java index dbcc94a993f..2512607fe05 100644 --- a/edge/src/io/openems/impl/device/bcontrol/BControl.java +++ b/edge/src/io/openems/impl/device/bcontrol/BControl.java @@ -22,7 +22,8 @@ public BControl(Bridge parent) throws OpenemsException { * Config */ @ChannelInfo(title = "Meter", description = "Sets the meter nature.", type = BControlMeter.class) - public final ConfigChannel meter = new ConfigChannel<>("meter", this); + public final ConfigChannel meter = new ConfigChannel("meter", this) + .addChangeListener(this); /* * Methods @@ -35,4 +36,5 @@ protected Set getDeviceNatures() { } return natures; } + } diff --git a/edge/src/io/openems/impl/device/bcontrol/BControlMeter.java b/edge/src/io/openems/impl/device/bcontrol/BControlMeter.java index b32d37154f9..66937ef915e 100644 --- a/edge/src/io/openems/impl/device/bcontrol/BControlMeter.java +++ b/edge/src/io/openems/impl/device/bcontrol/BControlMeter.java @@ -3,6 +3,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.FunctionalReadChannel; import io.openems.api.channel.ReadChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.AsymmetricMeterNature; import io.openems.api.device.nature.meter.SymmetricMeterNature; @@ -18,8 +19,11 @@ @ThingInfo(title = "B-Control Energy Meter") public class BControlMeter extends ModbusDeviceNature implements SymmetricMeterNature, AsymmetricMeterNature { + private ThingStateChannel thingState; + public BControlMeter(String thingId, Device parent) throws ConfigException { super(thingId, parent); + this.thingState = new ThingStateChannel(this); } /* @@ -268,4 +272,9 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { }, apparentPowerPos, apparentPowerNeg).unit("VA"); return mp; } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } } diff --git a/edge/src/io/openems/impl/device/byd/Bem125ktla01.java b/edge/src/io/openems/impl/device/byd/Bem125ktla01.java index c4073abb549..08d454ea019 100644 --- a/edge/src/io/openems/impl/device/byd/Bem125ktla01.java +++ b/edge/src/io/openems/impl/device/byd/Bem125ktla01.java @@ -48,7 +48,7 @@ public Bem125ktla01(Bridge parent) throws OpenemsException { * Config */ @ChannelInfo(title = "Ess", description = "Sets the Ess nature.", type = Bem125ktla01Ess.class) - public final ConfigChannel ess = new ConfigChannel("ess", this); + public final ConfigChannel ess = new ConfigChannel("ess", this).addChangeListener(this); /* * Methods diff --git a/edge/src/io/openems/impl/device/byd/Bem125ktla01Ess.java b/edge/src/io/openems/impl/device/byd/Bem125ktla01Ess.java index 5d37bf711b4..d696097c5eb 100644 --- a/edge/src/io/openems/impl/device/byd/Bem125ktla01Ess.java +++ b/edge/src/io/openems/impl/device/byd/Bem125ktla01Ess.java @@ -23,13 +23,13 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; -import io.openems.api.channel.StatusBitChannel; -import io.openems.api.channel.StatusBitChannels; import io.openems.api.channel.WriteChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.ess.SymmetricEssNature; import io.openems.api.doc.ThingInfo; import io.openems.api.exception.ConfigException; +import io.openems.impl.protocol.modbus.ModbusBitWrappingChannel; import io.openems.impl.protocol.modbus.ModbusDeviceNature; import io.openems.impl.protocol.modbus.ModbusReadChannel; import io.openems.impl.protocol.modbus.ModbusReadLongChannel; @@ -69,6 +69,7 @@ public ConfigChannel chargeSoc() { /* * Inherited Channels */ + private ThingStateChannel thingState = new ThingStateChannel(this); private ModbusReadChannel soc; private StaticValueChannel allowedCharge = new StaticValueChannel("AllowedCharge", this, 0L); private StaticValueChannel allowedDischarge = new StaticValueChannel("AllowedDischarge", this, 0L); @@ -84,12 +85,10 @@ public ConfigChannel chargeSoc() { private ModbusWriteChannel setWorkState; private StaticValueChannel maxNominalPower = new StaticValueChannel<>("maxNominalPower", this, 0L); private StaticValueChannel capacity = new StaticValueChannel<>("capacity", this, 170000L).unit("Wh"); - public StatusBitChannels warning; public ModbusReadChannel sysAlarmInfo; - public StatusBitChannel sysWorkStatus; - public StatusBitChannel sysControlMode; - public StatusBitChannel sysAlarmInfo2; + public ModbusReadChannel sysWorkStatus; + public ModbusReadChannel sysControlMode; public ModbusReadChannel batteryStackVoltage; public ModbusReadChannel batteryStackCurrent; public ModbusReadChannel batteryStackPower; @@ -133,11 +132,6 @@ public ReadChannel allowedApparent() { return allowedApparent; } - @Override - public StatusBitChannels warning() { - return warning; - } - @Override public WriteChannel setWorkState() { return setWorkState; @@ -178,60 +172,56 @@ public WriteChannel setReactivePower() { */ @Override protected ModbusProtocol defineModbusProtocol() throws ConfigException { - warning = new StatusBitChannels("Warning", this); return new ModbusProtocol( // new ModbusRegisterRange(0x0100, // new UnsignedWordElement(0x100, // sysAlarmInfo = new ModbusReadLongChannel("SysAlarmInfo", this)// - .label(0, "Warning State")// - .label(1, "Protection State")// - .label(2, "Derating State")// - .label(4, "Charge Forbidden").label(16, "Discharge Forbidden")), + .label(1, "Warning State")// + .label(2, "Protection State")// + .label(4, "Derating State")// + .label(8, "Charge Forbidden")// + .label(16, "Discharge Forbidden")), new UnsignedWordElement(0x101, // - sysWorkStatus = new StatusBitChannel("SysWorkStatus", this)// - .label(0, "Initial") // - .label(1, "Fault") // - .label(2, "Stop") // - .label(4, "Hot Standby") // - .label(8, "Monitoring") // - .label(16, "Standby") // - .label(32, "Operation") // - .label(64, "Debug")), // + sysWorkStatus = new ModbusReadLongChannel("SysWorkStatus", this)// + .label(1, "Initial") // + .label(2, "Fault") // + .label(4, "Stop") // + .label(8, "Hot Standby") // + .label(16, "Monitoring") // + .label(32, "Standby") // + .label(64, "Operation") // + .label(128, "Debug")), // new UnsignedWordElement(0x102, // - sysControlMode = new StatusBitChannel("SysControlMode", this)// - .label(0, "Remote") // - .label(1, "Local")), // + sysControlMode = new ModbusReadLongChannel("SysControlMode", this)// + .label(1, "Remote") // + .label(2, "Local")), // new DummyElement(0x103)), new ModbusRegisterRange(0x0110, // new UnsignedWordElement(0x110, // - sysAlarmInfo = new StatusBitChannel("SysAlarmInfo", this)// - .label(0, "Status abnormal of AC surge protector") // - .label(1, "Close of control switch") // - .label(2, "Emergency stop") // - .label(4, "Status abnormal of frog detector") // - .label(8, "Serious leakage") // - .label(16, "Normal_leakage")), // + new ModbusBitWrappingChannel("SysAlarmInfo", this, thingState)// + .warningBit(1, Warning.Status_abnormal_of_AC_surge_protector) // Status abnormal of AC surge protector + .warningBit(2, Warning.Close_of_control_switch) // Close of control switch + .warningBit(3, Warning.Emergency_stop) // Emergency stop + .warningBit(5, Warning.Status_abnormal_of_frog_detector) // Status_abnormal_of_frog_detector + .warningBit(6, Warning.Serious_leakage) // Serious_leakage + .warningBit(7, Warning.Normal_leakage)), // Normal_leakage new UnsignedWordElement(0x111, // - sysAlarmInfo2 = new StatusBitChannel("SysAlarmInfo2", this)// - .label(0, "Failure of temperature sensor in control cabinet") // - .label(1, "Close of control switch") // - /* - * TODO new OnOffBitItem(9, "Failure_of_humidity_sensor_in_control_cabinet"), // - * new OnOffBitItem(12, "Failure_of_storage_device"), // - * new OnOffBitItem(13, "Exceeding_of_humidity_in_control_cabinet")))); - */ - )), new ModbusRegisterRange(0x1300, new UnsignedWordElement(0x1300, // - batteryStackVoltage = new ModbusReadLongChannel("BatteryStackVoltage", this) - .multiplier(2).unit("mV")), + new ModbusBitWrappingChannel("SysAlarmInfo2", this, thingState)// + .warningBit(0, Warning.Failure_of_temperature_sensor_in_control_cabinet) // Failure of temperature sensor in control cabinet + .warningBit(9, Warning.Failure_of_humidity_sensor_in_control_cabinet) // Failure_of_humidity_sensor_in_control_cabinet + .warningBit(12, Warning.Failure_of_storage_device) // Failure_of_storage_device + .warningBit(13, Warning.Exceeding_of_humidity_in_control_cabinet)) // Exceeding_of_humidity_in_control_cabinet + ), new ModbusRegisterRange(0x1300, new UnsignedWordElement(0x1300, // + batteryStackVoltage = new ModbusReadLongChannel("BatteryStackVoltage", this).multiplier(2) + .unit("mV")), new UnsignedWordElement(0x1301, // batteryStackCurrent = new ModbusReadLongChannel("BatteryStackCurrent", this) - .multiplier(2).unit("mA")), + .multiplier(2).unit("mA")), new UnsignedWordElement(0x1302, // - batteryStackPower = new ModbusReadLongChannel("BatteryStackPower", this) - .multiplier(2).unit("W")), + batteryStackPower = new ModbusReadLongChannel( + "BatteryStackPower", this).multiplier(2).unit("W")), new UnsignedWordElement(0x1303, // - batteryStackSoc = soc = new ModbusReadLongChannel("BatteryStackSoc", this) - .unit("%")), + batteryStackSoc = soc = new ModbusReadLongChannel("BatteryStackSoc", this).unit("%")), new UnsignedWordElement(0x1304, // batteryStackSoh = new ModbusReadLongChannel("BatteryStackSoh", this).unit("%")), new UnsignedWordElement(0x1305, // @@ -250,15 +240,20 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { batteryStackTotalCapacity = new ModbusReadLongChannel( "BatteryStackTotalCapacity", this).unit("Wh")), new UnsignedDoublewordElement(0x130A, // - batteryStackTotalCharge = new ModbusReadLongChannel("BatteryStackTotalCharge", - this).unit("kWh")), + batteryStackTotalCharge = new ModbusReadLongChannel("BatteryStackTotalCharge", this) + .unit("kWh")), new UnsignedDoublewordElement(0x130C, // - batteryStackTotalDischarge = new ModbusReadLongChannel( - "BatteryStackTotalDischarge", this).unit("kWh")))); + batteryStackTotalDischarge = new ModbusReadLongChannel("BatteryStackTotalDischarge", + this).unit("kWh")))); } @Override public StaticValueChannel capacity() { return capacity; } + + @Override + public ThingStateChannel getStateChannel() { + return thingState; + } } diff --git a/edge/src/io/openems/impl/device/byd/Warning.java b/edge/src/io/openems/impl/device/byd/Warning.java new file mode 100644 index 00000000000..9565d2a4382 --- /dev/null +++ b/edge/src/io/openems/impl/device/byd/Warning.java @@ -0,0 +1,17 @@ +package io.openems.impl.device.byd; + +import io.openems.api.channel.thingstate.WarningEnum; + +public enum Warning implements WarningEnum{ + Status_abnormal_of_AC_surge_protector(0),Close_of_control_switch(1),Emergency_stop(2),Status_abnormal_of_frog_detector(3),Serious_leakage(4),Normal_leakage(5),Failure_of_temperature_sensor_in_control_cabinet(6),Failure_of_humidity_sensor_in_control_cabinet(7),Failure_of_storage_device(8),Exceeding_of_humidity_in_control_cabinet(9); + private final int value; + + private Warning(int value) { + this.value = value; + } + + @Override + public int getValue() { + return this.value; + } +} diff --git a/edge/src/io/openems/impl/device/carlogavazzi/em300series/EM300.java b/edge/src/io/openems/impl/device/carlogavazzi/em300series/EM300.java index ec79b02e489..728f6398046 100644 --- a/edge/src/io/openems/impl/device/carlogavazzi/em300series/EM300.java +++ b/edge/src/io/openems/impl/device/carlogavazzi/em300series/EM300.java @@ -45,7 +45,7 @@ public EM300(Bridge parent) throws OpenemsException { * Config */ @ChannelInfo(title = "Meter", description = "Sets the meter nature.", type = EM300Meter.class) - public final ConfigChannel meter = new ConfigChannel<>("meter", this); + public final ConfigChannel meter = new ConfigChannel("meter", this).addChangeListener(this); /* * Methods diff --git a/edge/src/io/openems/impl/device/carlogavazzi/em300series/EM300Meter.java b/edge/src/io/openems/impl/device/carlogavazzi/em300series/EM300Meter.java index e0765d2b88e..2bf41d1e5a7 100644 --- a/edge/src/io/openems/impl/device/carlogavazzi/em300series/EM300Meter.java +++ b/edge/src/io/openems/impl/device/carlogavazzi/em300series/EM300Meter.java @@ -22,6 +22,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.AsymmetricMeterNature; import io.openems.api.device.nature.meter.SymmetricMeterNature; @@ -40,11 +41,14 @@ @ThingInfo(title = "Socomec Meter") public class EM300Meter extends ModbusDeviceNature implements SymmetricMeterNature, AsymmetricMeterNature { + private ThingStateChannel thingState; + /* * Constructors */ public EM300Meter(String thingId, Device parent) throws ConfigException { super(thingId, parent); + this.thingState = new ThingStateChannel(this); } /* @@ -206,44 +210,49 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { currentL3 = new ModbusReadLongChannel("CurrentL3", this).unit("mA")), new SignedDoublewordElement(19, // activePowerL1 = new ModbusReadLongChannel("ActivePowerL1", this).unit("W") - .multiplier(-1)), + .multiplier(-1)), new SignedDoublewordElement(21, // activePowerL2 = new ModbusReadLongChannel("ActivePowerL2", this).unit("W") - .multiplier(-1)), + .multiplier(-1)), new SignedDoublewordElement(23, // activePowerL3 = new ModbusReadLongChannel("ActivePowerL3", this).unit("W") - .multiplier(-1)), + .multiplier(-1)), new SignedDoublewordElement(25, // reactivePowerL1 = new ModbusReadLongChannel("ReactivePowerL1", this).unit("var") - .multiplier(-1)), + .multiplier(-1)), new SignedDoublewordElement(27, // reactivePowerL2 = new ModbusReadLongChannel("ReactivePowerL2", this).unit("var") - .multiplier(-1)), + .multiplier(-1)), new SignedDoublewordElement(29, // reactivePowerL3 = new ModbusReadLongChannel("ReactivePowerL3", this) - .unit("var").multiplier(-1)), + .unit("var").multiplier(-1)), new DummyElement(31, 40), new SignedDoublewordElement(41, // activePower = new ModbusReadLongChannel("ActivePower", this).unit("W").multiplier(-1)), new SignedDoublewordElement(43, // apparentPower = new ModbusReadLongChannel("ApparentPower", this).unit("VA") - .multiplier(-1)), + .multiplier(-1)), new SignedDoublewordElement(45, // reactivePower = new ModbusReadLongChannel("ReactivePower", this) - .unit("var").multiplier(-1))), + .unit("var").multiplier(-1))), new ModbusInputRegisterRange(52, new SignedWordElement(52, // frequency = new ModbusReadLongChannel("Frequency", this).unit("mHZ").multiplier(2)), new UnsignedDoublewordElement(53, // activePositiveEnergy = new ModbusReadLongChannel("ActivePositiveEnergy", this) - .unit("kWh").multiplier(1)), + .unit("kWh").multiplier(1)), new UnsignedDoublewordElement(55, // reactivePositiveEnergy = new ModbusReadLongChannel("ReactivePositiveEnergy", this) - .unit("kvarh").multiplier(-1))), + .unit("kvarh").multiplier(-1))), new ModbusRegisterRange(79, // new UnsignedDoublewordElement(79, // activeNegativeEnergy = new ModbusReadLongChannel( "ActiveNegativeEnergy", this).unit("kWh").multiplier(-1)), new UnsignedDoublewordElement(81, // reactiveNegativeEnergy = new ModbusReadLongChannel("ReactiveNegativeEnergy", this) - .unit("kvarh").multiplier(-1)))); + .unit("kvarh").multiplier(-1)))); + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; } } diff --git a/edge/src/io/openems/impl/device/commercial/FeneconCommercialAC.java b/edge/src/io/openems/impl/device/commercial/FeneconCommercialAC.java index 20deb3e77a4..d4efd99fa95 100644 --- a/edge/src/io/openems/impl/device/commercial/FeneconCommercialAC.java +++ b/edge/src/io/openems/impl/device/commercial/FeneconCommercialAC.java @@ -45,7 +45,7 @@ public FeneconCommercialAC(Bridge parent) throws OpenemsException { * Config */ @ChannelInfo(title = "Ess", description = "Sets the Ess nature.", type = FeneconCommercialEss.class) - public final ConfigChannel ess = new ConfigChannel<>("ess", this); + public final ConfigChannel ess = new ConfigChannel("ess", this).addChangeListener(this); /* * Methods diff --git a/edge/src/io/openems/impl/device/commercial/FeneconCommercialCharger.java b/edge/src/io/openems/impl/device/commercial/FeneconCommercialCharger.java index 544d9a8cd74..2df39e909df 100644 --- a/edge/src/io/openems/impl/device/commercial/FeneconCommercialCharger.java +++ b/edge/src/io/openems/impl/device/commercial/FeneconCommercialCharger.java @@ -27,6 +27,7 @@ import io.openems.api.channel.StatusBitChannel; import io.openems.api.channel.StatusBitChannels; import io.openems.api.channel.WriteChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.charger.ChargerNature; import io.openems.api.doc.ThingInfo; @@ -54,6 +55,7 @@ public class FeneconCommercialCharger extends ModbusDeviceNature implements Char */ public FeneconCommercialCharger(String thingId, Device parent) throws ConfigException { super(thingId, parent); + this.thingState = new ThingStateChannel(this); } /* @@ -70,6 +72,8 @@ public FeneconCommercialCharger(String thingId, Device parent) throws ConfigExce private final ConfigChannel maxActualPower = new ConfigChannel("maxActualPower", this); + private ThingStateChannel thingState; + @Override public ConfigChannel maxActualPower() { return maxActualPower; @@ -219,80 +223,80 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { ModbusProtocol protocol = new ModbusProtocol(// new WriteableModbusRegisterRange(0x0503, new UnsignedWordElement(0x0503, pvPowerLimitCommand = new ModbusWriteLongChannel("PvPowerLimitCommand", this).multiplier(2) - .unit("W"))), + .unit("W"))), new ModbusRegisterRange(0xA000, // new UnsignedWordElement(0xA000, bmsDCDCWorkState = new ModbusReadLongChannel("BmsDCDCWorkState", this)// - .label(2, "Initial")// - .label(4, "Stop")// - .label(8, "Ready")// - .label(16, "Running")// - .label(32, "Fault")// - .label(64, "Debug")// - .label(128, "Locked")), + .label(2, "Initial")// + .label(4, "Stop")// + .label(8, "Ready")// + .label(16, "Running")// + .label(32, "Fault")// + .label(64, "Debug")// + .label(128, "Locked")), new UnsignedWordElement(0xA001, bmsDCDCWorkMode = new ModbusReadLongChannel("BmsDCDCWorkMode", this)// - .label(128, "Constant Current")// - .label(256, "Constant Voltage")// - .label(512, "Boost MPPT"))), + .label(128, "Constant Current")// + .label(256, "Constant Voltage")// + .label(512, "Boost MPPT"))), new ModbusRegisterRange(0xA100, // new UnsignedWordElement(0xA100, bmsDCDCSuggestiveInformation1 = warning - .channel(new StatusBitChannel("BmsDCDCSuggestiveInformation1", this)// - .label(1, "Current sampling channel abnormity on high voltage side")// - .label(2, "Current sampling channel abnormity on low voltage side")// - .label(64, "EEPROM parameters over range")// - .label(128, "Update EEPROM failed")// - .label(256, "Read EEPROM failed")// - .label(512, "Current sampling channel abnormity before inductance"))), + .channel(new StatusBitChannel("BmsDCDCSuggestiveInformation1", this)// + .label(1, "Current sampling channel abnormity on high voltage side")// + .label(2, "Current sampling channel abnormity on low voltage side")// + .label(64, "EEPROM parameters over range")// + .label(128, "Update EEPROM failed")// + .label(256, "Read EEPROM failed")// + .label(512, "Current sampling channel abnormity before inductance"))), new UnsignedWordElement(0xA101, bmsDCDCSuggestiveInformation2 = warning - .channel(new StatusBitChannel("BmsDCDCSuggestiveInformation2", this)// - .label(1, "Reactor power decrease caused by overtemperature")// - .label(2, "IGBT power decrease caused by overtemperature")// - .label(4, "Temperature chanel3 power decrease caused by overtemperature")// - .label(8, "Temperature chanel4 power decrease caused by overtemperature")// - .label(16, "Temperature chanel5 power decrease caused by overtemperature")// - .label(32, "Temperature chanel6 power decrease caused by overtemperature")// - .label(64, "Temperature chanel7 power decrease caused by overtemperature")// - .label(128, "Temperature chanel8 power decrease caused by overtemperature")// - .label(256, "Fan 1 stop failed")// - .label(512, "Fan 2 stop failed")// - .label(1024, "Fan 3 stop failed")// - .label(2048, "Fan 4 stop failed")// - .label(4096, "Fan 1 sartup failed")// - .label(8192, "Fan 2 sartup failed")// - .label(16384, "Fan 3 sartup failed")// - .label(32768, "Fan 4 sartup failed"))), + .channel(new StatusBitChannel("BmsDCDCSuggestiveInformation2", this)// + .label(1, "Reactor power decrease caused by overtemperature")// + .label(2, "IGBT power decrease caused by overtemperature")// + .label(4, "Temperature chanel3 power decrease caused by overtemperature")// + .label(8, "Temperature chanel4 power decrease caused by overtemperature")// + .label(16, "Temperature chanel5 power decrease caused by overtemperature")// + .label(32, "Temperature chanel6 power decrease caused by overtemperature")// + .label(64, "Temperature chanel7 power decrease caused by overtemperature")// + .label(128, "Temperature chanel8 power decrease caused by overtemperature")// + .label(256, "Fan 1 stop failed")// + .label(512, "Fan 2 stop failed")// + .label(1024, "Fan 3 stop failed")// + .label(2048, "Fan 4 stop failed")// + .label(4096, "Fan 1 sartup failed")// + .label(8192, "Fan 2 sartup failed")// + .label(16384, "Fan 3 sartup failed")// + .label(32768, "Fan 4 sartup failed"))), new UnsignedWordElement(0xA102, bmsDCDCSuggestiveInformation3 = warning - .channel(new StatusBitChannel("BmsDCDCSuggestiveInformation3", this)// - .label(1, "High voltage side overvoltage")// - .label(2, "High voltage side undervoltage")// - .label(4, "EEPROM parameters over range")// - .label(8, "High voltage side voltage change unconventionally"))), + .channel(new StatusBitChannel("BmsDCDCSuggestiveInformation3", this)// + .label(1, "High voltage side overvoltage")// + .label(2, "High voltage side undervoltage")// + .label(4, "EEPROM parameters over range")// + .label(8, "High voltage side voltage change unconventionally"))), new UnsignedWordElement(0xA103, bmsDCDCSuggestiveInformation4 = warning - .channel(new StatusBitChannel("BmsDCDCSuggestiveInformation4", this)// - .label(1, "Current abnormity before DC Converter work on high voltage side")// - .label(2, "Current abnormity before DC Converter work on low voltage side")// - .label(4, "Initial Duty Ratio abnormity before DC Converter work")// - .label(8, "Voltage abnormity before DC Converter work on high voltage side")// - .label(16, "Voltage abnormity before DC Converter work on low voltage side"))), + .channel(new StatusBitChannel("BmsDCDCSuggestiveInformation4", this)// + .label(1, "Current abnormity before DC Converter work on high voltage side")// + .label(2, "Current abnormity before DC Converter work on low voltage side")// + .label(4, "Initial Duty Ratio abnormity before DC Converter work")// + .label(8, "Voltage abnormity before DC Converter work on high voltage side")// + .label(16, "Voltage abnormity before DC Converter work on low voltage side"))), new UnsignedWordElement(0xA104, bmsDCDCSuggestiveInformation5 = warning - .channel(new StatusBitChannel("BmsDCDCSuggestiveInformation5", this)// - .label(1, "High voltage breaker inspection abnormity")// - .label(2, "Low voltage breaker inspection abnormity")// - .label(4, "DC precharge contactor inspection abnormity")// - .label(8, "DC precharge contactor open unsuccessfully")// - .label(16, "DC main contactor inspection abnormity")// - .label(32, "DC main contactor open unsuccessfully")// - .label(64, "Output contactor close unsuccessfully")// - .label(128, "Output contactor open unsuccessfully")// - .label(256, "AC main contactor close unsuccessfully")// - .label(512, "AC main contactor open unsuccessfully")// - .label(1024, "NegContactor open unsuccessfully")// - .label(2048, "NegContactor close unsuccessfully")// - .label(4096, "NegContactor state abnormal"))), + .channel(new StatusBitChannel("BmsDCDCSuggestiveInformation5", this)// + .label(1, "High voltage breaker inspection abnormity")// + .label(2, "Low voltage breaker inspection abnormity")// + .label(4, "DC precharge contactor inspection abnormity")// + .label(8, "DC precharge contactor open unsuccessfully")// + .label(16, "DC main contactor inspection abnormity")// + .label(32, "DC main contactor open unsuccessfully")// + .label(64, "Output contactor close unsuccessfully")// + .label(128, "Output contactor open unsuccessfully")// + .label(256, "AC main contactor close unsuccessfully")// + .label(512, "AC main contactor open unsuccessfully")// + .label(1024, "NegContactor open unsuccessfully")// + .label(2048, "NegContactor close unsuccessfully")// + .label(4096, "NegContactor state abnormal"))), new DummyElement(0xA105, 0xA10F), new UnsignedWordElement(0xA110, bmsDCDCAbnormity1 = warning.channel(new StatusBitChannel("BmsDCDCAbnormity1", this)// @@ -402,136 +406,136 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { new DummyElement(0xA117, 0xA11F), new UnsignedWordElement(0xA120, bmsDCDCSwitchState = new StatusBitChannel("BmsDCDCSwitchState", this)// - .label(1, "DC precharge contactor")// - .label(2, "DC main contactor")// - .label(4, "Output contactor")// - .label(8, "Output breaker")// - .label(16, "Input breaker")// - .label(32, "AC contactor")// - .label(64, "Emergency stop button")// - .label(128, "NegContactor"))), + .label(1, "DC precharge contactor")// + .label(2, "DC main contactor")// + .label(4, "Output contactor")// + .label(8, "Output breaker")// + .label(16, "Input breaker")// + .label(32, "AC contactor")// + .label(64, "Emergency stop button")// + .label(128, "NegContactor"))), new ModbusRegisterRange(0xA130, // new SignedWordElement(0xA130, bmsDCDCOutputVoltage = new ModbusReadLongChannel("BmsDCDCOutputVoltage", this) - .unit("mV").multiplier(2)), + .unit("mV").multiplier(2)), new SignedWordElement(0xA131, bmsDCDCOutputCurrent = new ModbusReadLongChannel("BmsDCDCOutputCurrent", this) - .unit("mA").multiplier(2)), + .unit("mA").multiplier(2)), new SignedWordElement(0xA132, bmsDCDCOutputPower = new ModbusReadLongChannel("BmsDCDCOutputPower", this).unit("W") - .multiplier(2)), + .multiplier(2)), new SignedWordElement(0xA133, bmsDCDCInputVoltage = new ModbusReadLongChannel("BmsDCDCInputVoltage", this).unit("mV") - .multiplier(2)), + .multiplier(2)), new SignedWordElement(0xA134, bmsDCDCInputCurrent = new ModbusReadLongChannel("BmsDCDCInputCurrent", this).unit("mA") - .multiplier(2)), + .multiplier(2)), new SignedWordElement(0xA135, bmsDCDCInputPower = new ModbusReadLongChannel("BmsDCDCInputPower", this).unit("W") - .multiplier(2)), + .multiplier(2)), new SignedWordElement(0xA136, bmsDCDCInputEnergy = new ModbusReadLongChannel("BmsDCDCInputEnergy", this).unit("Wh") - .multiplier(2)), + .multiplier(2)), new SignedWordElement(0xA137, bmsDCDCOutputEnergy = new ModbusReadLongChannel("BmsDCDCOutputEnergy", this).unit("Wh") - .multiplier(2)), + .multiplier(2)), new DummyElement(0xA138, 0xA13F), new SignedWordElement(0xA140, bmsDCDCReactorTemperature = new ModbusReadLongChannel("BmsDCDCReactorTemperature", this) - .unit("°C")), + .unit("°C")), new SignedWordElement(0xA141, bmsDCDCIgbtTemperature = new ModbusReadLongChannel("BmsDCDCIgbtTemperature", this) - .unit("°C")), + .unit("°C")), new DummyElement(0xA142, 0xA14F), new UnsignedDoublewordElement(0xA150, bmsDCDCInputTotalChargeEnergy = new ModbusReadLongChannel( "BmsDCDCInputTotalChargeEnergy", this).unit("Wh").multiplier(2)) - .wordOrder(WordOrder.LSWMSW), + .wordOrder(WordOrder.LSWMSW), new UnsignedDoublewordElement(0xA152, bmsDCDCInputTotalDischargeEnergy = new ModbusReadLongChannel( "BmsDCDCInputTotalDischargeEnergy", this).unit("Wh").multiplier(2)) - .wordOrder(WordOrder.LSWMSW), + .wordOrder(WordOrder.LSWMSW), new UnsignedDoublewordElement(0xA154, bmsDCDCOutputTotalChargeEnergy = new ModbusReadLongChannel( "BmsDCDCOutputTotalChargeEnergy", this).unit("Wh").multiplier(2)) - .wordOrder(WordOrder.LSWMSW), + .wordOrder(WordOrder.LSWMSW), new UnsignedDoublewordElement(0xA156, bmsDCDCOutputTotalDischargeEnergy = new ModbusReadLongChannel( "BmsDCDCOutputTotalDischargeEnergy", this).unit("Wh") - .multiplier(2)).wordOrder(WordOrder.LSWMSW)), + .multiplier(2)).wordOrder(WordOrder.LSWMSW)), new ModbusRegisterRange(0xA300, // new UnsignedWordElement(0xA300, bmsDCDC1WorkState = new ModbusReadLongChannel("BmsDCDC1WorkState", this)// - .label(2, "Initial")// - .label(4, "Stop")// - .label(8, "Ready")// - .label(16, "Running")// - .label(32, "Fault")// - .label(64, "Debug")// - .label(128, "Locked")), + .label(2, "Initial")// + .label(4, "Stop")// + .label(8, "Ready")// + .label(16, "Running")// + .label(32, "Fault")// + .label(64, "Debug")// + .label(128, "Locked")), new UnsignedWordElement(0xA301, bmsDCDC1WorkMode = new ModbusReadLongChannel("BmsDCDC1WorkMode", this)// - .label(128, "Constant Current")// - .label(256, "Constant Voltage")// - .label(512, "Boost MPPT"))), + .label(128, "Constant Current")// + .label(256, "Constant Voltage")// + .label(512, "Boost MPPT"))), new ModbusRegisterRange(0xA400, // new UnsignedWordElement(0xA400, bmsDCDC1SuggestiveInformation1 = warning - .channel(new StatusBitChannel("BmsDCDC1SuggestiveInformation1", this)// - .label(1, "Current sampling channel abnormity on high voltage side")// - .label(2, "Current sampling channel abnormity on low voltage side")// - .label(64, "EEPROM parameters over range")// - .label(128, "Update EEPROM failed")// - .label(256, "Read EEPROM failed")// - .label(512, "Current sampling channel abnormity before inductance"))), + .channel(new StatusBitChannel("BmsDCDC1SuggestiveInformation1", this)// + .label(1, "Current sampling channel abnormity on high voltage side")// + .label(2, "Current sampling channel abnormity on low voltage side")// + .label(64, "EEPROM parameters over range")// + .label(128, "Update EEPROM failed")// + .label(256, "Read EEPROM failed")// + .label(512, "Current sampling channel abnormity before inductance"))), new UnsignedWordElement(0xA401, bmsDCDC1SuggestiveInformation2 = warning - .channel(new StatusBitChannel("BmsDCDC1SuggestiveInformation2", this)// - .label(1, "Reactor power decrease caused by overtemperature")// - .label(2, "IGBT power decrease caused by overtemperature")// - .label(4, "Temperature chanel3 power decrease caused by overtemperature")// - .label(8, "Temperature chanel4 power decrease caused by overtemperature")// - .label(16, "Temperature chanel5 power decrease caused by overtemperature")// - .label(32, "Temperature chanel6 power decrease caused by overtemperature")// - .label(64, "Temperature chanel7 power decrease caused by overtemperature")// - .label(128, "Temperature chanel8 power decrease caused by overtemperature")// - .label(256, "Fan 1 stop failed")// - .label(512, "Fan 2 stop failed")// - .label(1024, "Fan 3 stop failed")// - .label(2048, "Fan 4 stop failed")// - .label(4096, "Fan 1 sartup failed")// - .label(8192, "Fan 2 sartup failed")// - .label(16384, "Fan 3 sartup failed")// - .label(32768, "Fan 4 sartup failed"))), + .channel(new StatusBitChannel("BmsDCDC1SuggestiveInformation2", this)// + .label(1, "Reactor power decrease caused by overtemperature")// + .label(2, "IGBT power decrease caused by overtemperature")// + .label(4, "Temperature chanel3 power decrease caused by overtemperature")// + .label(8, "Temperature chanel4 power decrease caused by overtemperature")// + .label(16, "Temperature chanel5 power decrease caused by overtemperature")// + .label(32, "Temperature chanel6 power decrease caused by overtemperature")// + .label(64, "Temperature chanel7 power decrease caused by overtemperature")// + .label(128, "Temperature chanel8 power decrease caused by overtemperature")// + .label(256, "Fan 1 stop failed")// + .label(512, "Fan 2 stop failed")// + .label(1024, "Fan 3 stop failed")// + .label(2048, "Fan 4 stop failed")// + .label(4096, "Fan 1 sartup failed")// + .label(8192, "Fan 2 sartup failed")// + .label(16384, "Fan 3 sartup failed")// + .label(32768, "Fan 4 sartup failed"))), new UnsignedWordElement(0xA402, bmsDCDC1SuggestiveInformation3 = warning - .channel(new StatusBitChannel("BmsDCDC1SuggestiveInformation3", this)// - .label(1, "High voltage side overvoltage")// - .label(2, "High voltage side undervoltage")// - .label(4, "EEPROM parameters over range")// - .label(8, "High voltage side voltage change unconventionally"))), + .channel(new StatusBitChannel("BmsDCDC1SuggestiveInformation3", this)// + .label(1, "High voltage side overvoltage")// + .label(2, "High voltage side undervoltage")// + .label(4, "EEPROM parameters over range")// + .label(8, "High voltage side voltage change unconventionally"))), new UnsignedWordElement(0xA403, bmsDCDC1SuggestiveInformation4 = warning - .channel(new StatusBitChannel("BmsDCDC1SuggestiveInformation4", this)// - .label(1, "Current abnormity before DC Converter work on high voltage side")// - .label(2, "Current abnormity before DC Converter work on low voltage side")// - .label(4, "Initial Duty Ratio abnormity before DC Converter work")// - .label(8, "Voltage abnormity before DC Converter work on high voltage side")// - .label(16, "Voltage abnormity before DC Converter work on low voltage side"))), + .channel(new StatusBitChannel("BmsDCDC1SuggestiveInformation4", this)// + .label(1, "Current abnormity before DC Converter work on high voltage side")// + .label(2, "Current abnormity before DC Converter work on low voltage side")// + .label(4, "Initial Duty Ratio abnormity before DC Converter work")// + .label(8, "Voltage abnormity before DC Converter work on high voltage side")// + .label(16, "Voltage abnormity before DC Converter work on low voltage side"))), new UnsignedWordElement(0xA404, bmsDCDC1SuggestiveInformation5 = warning - .channel(new StatusBitChannel("BmsDCDC1SuggestiveInformation5", this)// - .label(1, "High voltage breaker inspection abnormity")// - .label(2, "Low voltage breaker inspection abnormity")// - .label(4, "DC precharge contactor inspection abnormity")// - .label(8, "DC precharge contactor open unsuccessfully")// - .label(16, "DC main contactor inspection abnormity")// - .label(32, "DC main contactor open unsuccessfully")// - .label(64, "Output contactor close unsuccessfully")// - .label(128, "Output contactor open unsuccessfully")// - .label(256, "AC main contactor close unsuccessfully")// - .label(512, "AC main contactor open unsuccessfully")// - .label(1024, "NegContactor open unsuccessfully")// - .label(2048, "NegContactor close unsuccessfully")// - .label(4096, "NegContactor state abnormal"))), + .channel(new StatusBitChannel("BmsDCDC1SuggestiveInformation5", this)// + .label(1, "High voltage breaker inspection abnormity")// + .label(2, "Low voltage breaker inspection abnormity")// + .label(4, "DC precharge contactor inspection abnormity")// + .label(8, "DC precharge contactor open unsuccessfully")// + .label(16, "DC main contactor inspection abnormity")// + .label(32, "DC main contactor open unsuccessfully")// + .label(64, "Output contactor close unsuccessfully")// + .label(128, "Output contactor open unsuccessfully")// + .label(256, "AC main contactor close unsuccessfully")// + .label(512, "AC main contactor open unsuccessfully")// + .label(1024, "NegContactor open unsuccessfully")// + .label(2048, "NegContactor close unsuccessfully")// + .label(4096, "NegContactor state abnormal"))), new DummyElement(0xA405, 0xA40F), new UnsignedWordElement(0xA410, bmsDCDC1Abnormity1 = warning.channel(new StatusBitChannel("BmsDCDC1Abnormity1", this)// @@ -641,136 +645,136 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { new DummyElement(0xA417, 0xA41F), new UnsignedWordElement(0xA420, bmsDCDC1SwitchState = new StatusBitChannel("BmsDCDC1SwitchState", this)// - .label(1, "DC precharge contactor")// - .label(2, "DC main contactor")// - .label(4, "Output contactor")// - .label(8, "Output breaker")// - .label(16, "Input breaker")// - .label(32, "AC contactor")// - .label(64, "Emergency stop button")// - .label(128, "NegContactor"))), + .label(1, "DC precharge contactor")// + .label(2, "DC main contactor")// + .label(4, "Output contactor")// + .label(8, "Output breaker")// + .label(16, "Input breaker")// + .label(32, "AC contactor")// + .label(64, "Emergency stop button")// + .label(128, "NegContactor"))), new ModbusRegisterRange(0xA430, // new SignedWordElement(0xA430, bmsDCDC1OutputVoltage = new ModbusReadLongChannel("BmsDCDC1OutputVoltage", this) - .unit("mV").multiplier(2)), + .unit("mV").multiplier(2)), new SignedWordElement(0xA431, bmsDCDC1OutputCurrent = new ModbusReadLongChannel("BmsDCDC1OutputCurrent", this) - .unit("mA").multiplier(2)), + .unit("mA").multiplier(2)), new SignedWordElement(0xA432, bmsDCDC1OutputPower = new ModbusReadLongChannel("BmsDCDC1OutputPower", this).unit("W") - .multiplier(2)), + .multiplier(2)), new SignedWordElement(0xA433, bmsDCDC1InputVoltage = new ModbusReadLongChannel("BmsDCDC1InputVoltage", this) - .unit("mV").multiplier(2)), + .unit("mV").multiplier(2)), new SignedWordElement(0xA434, bmsDCDC1InputCurrent = new ModbusReadLongChannel("BmsDCDC1InputCurrent", this) - .unit("mA").multiplier(2)), + .unit("mA").multiplier(2)), new SignedWordElement(0xA435, bmsDCDC1InputPower = new ModbusReadLongChannel("BmsDCDC1InputPower", this).unit("W") - .multiplier(2)), + .multiplier(2)), new SignedWordElement(0xA436, bmsDCDC1InputEnergy = new ModbusReadLongChannel("BmsDCDC1InputEnergy", this).unit("Wh") - .multiplier(2)), + .multiplier(2)), new SignedWordElement(0xA437, bmsDCDC1OutputEnergy = new ModbusReadLongChannel("BmsDCDC1OutputEnergy", this) - .unit("Wh").multiplier(2)), + .unit("Wh").multiplier(2)), new DummyElement(0xA438, 0xA43F), new SignedWordElement(0xA440, bmsDCDC1ReactorTemperature = new ModbusReadLongChannel("BmsDCDC1ReactorTemperature", this).unit("°C")), new SignedWordElement(0xA441, bmsDCDC1IgbtTemperature = new ModbusReadLongChannel("BmsDCDC1IgbtTemperature", this) - .unit("°C")), + .unit("°C")), new DummyElement(0xA442, 0xA44F), new UnsignedDoublewordElement(0xA450, bmsDCDC1InputTotalChargeEnergy = new ModbusReadLongChannel( "BmsDCDC1InputTotalChargeEnergy", this).unit("Wh").multiplier(2)) - .wordOrder(WordOrder.LSWMSW), + .wordOrder(WordOrder.LSWMSW), new UnsignedDoublewordElement(0xA452, bmsDCDC1InputTotalDischargeEnergy = new ModbusReadLongChannel( "BmsDCDC1InputTotalDischargeEnergy", this).unit("Wh").multiplier(2)) - .wordOrder(WordOrder.LSWMSW), + .wordOrder(WordOrder.LSWMSW), new UnsignedDoublewordElement(0xA454, bmsDCDC1OutputTotalChargeEnergy = new ModbusReadLongChannel( "BmsDCDC1OutputTotalChargeEnergy", this).unit("Wh").multiplier(2)) - .wordOrder(WordOrder.LSWMSW), + .wordOrder(WordOrder.LSWMSW), new UnsignedDoublewordElement(0xA456, bmsDCDC1OutputTotalDischargeEnergy = new ModbusReadLongChannel( "BmsDCDC1OutputTotalDischargeEnergy", this).unit("Wh") - .multiplier(2)).wordOrder(WordOrder.LSWMSW)), + .multiplier(2)).wordOrder(WordOrder.LSWMSW)), new ModbusRegisterRange(0xA600, // new UnsignedWordElement(0xA600, pvDCDCWorkState = new ModbusReadLongChannel("PvDCDCWorkState", this)// - .label(2, "Initial")// - .label(4, "Stop")// - .label(8, "Ready")// - .label(16, "Running")// - .label(32, "Fault")// - .label(64, "Debug")// - .label(128, "Locked")), + .label(2, "Initial")// + .label(4, "Stop")// + .label(8, "Ready")// + .label(16, "Running")// + .label(32, "Fault")// + .label(64, "Debug")// + .label(128, "Locked")), new UnsignedWordElement(0xA601, pvDCDCWorkMode = new ModbusReadLongChannel("PvDCDCWorkMode", this)// - .label(128, "Constant Current")// - .label(256, "Constant Voltage")// - .label(512, "Boost MPPT"))), + .label(128, "Constant Current")// + .label(256, "Constant Voltage")// + .label(512, "Boost MPPT"))), new ModbusRegisterRange(0xA700, // new UnsignedWordElement(0xA700, pvDCDCSuggestiveInformation1 = warning - .channel(new StatusBitChannel("PvDCDCSuggestiveInformation1", this)// - .label(1, "Current sampling channel abnormity on high voltage side")// - .label(2, "Current sampling channel abnormity on low voltage side")// - .label(64, "EEPROM parameters over range")// - .label(128, "Update EEPROM failed")// - .label(256, "Read EEPROM failed")// - .label(512, "Current sampling channel abnormity before inductance"))), + .channel(new StatusBitChannel("PvDCDCSuggestiveInformation1", this)// + .label(1, "Current sampling channel abnormity on high voltage side")// + .label(2, "Current sampling channel abnormity on low voltage side")// + .label(64, "EEPROM parameters over range")// + .label(128, "Update EEPROM failed")// + .label(256, "Read EEPROM failed")// + .label(512, "Current sampling channel abnormity before inductance"))), new UnsignedWordElement(0xA701, pvDCDCSuggestiveInformation2 = warning - .channel(new StatusBitChannel("PvDCDCSuggestiveInformation2", this)// - .label(1, "Reactor power decrease caused by overtemperature")// - .label(2, "IGBT power decrease caused by overtemperature")// - .label(4, "Temperature chanel3 power decrease caused by overtemperature")// - .label(8, "Temperature chanel4 power decrease caused by overtemperature")// - .label(16, "Temperature chanel5 power decrease caused by overtemperature")// - .label(32, "Temperature chanel6 power decrease caused by overtemperature")// - .label(64, "Temperature chanel7 power decrease caused by overtemperature")// - .label(128, "Temperature chanel8 power decrease caused by overtemperature")// - .label(256, "Fan 1 stop failed")// - .label(512, "Fan 2 stop failed")// - .label(1024, "Fan 3 stop failed")// - .label(2048, "Fan 4 stop failed")// - .label(4096, "Fan 1 sartup failed")// - .label(8192, "Fan 2 sartup failed")// - .label(16384, "Fan 3 sartup failed")// - .label(32768, "Fan 4 sartup failed"))), + .channel(new StatusBitChannel("PvDCDCSuggestiveInformation2", this)// + .label(1, "Reactor power decrease caused by overtemperature")// + .label(2, "IGBT power decrease caused by overtemperature")// + .label(4, "Temperature chanel3 power decrease caused by overtemperature")// + .label(8, "Temperature chanel4 power decrease caused by overtemperature")// + .label(16, "Temperature chanel5 power decrease caused by overtemperature")// + .label(32, "Temperature chanel6 power decrease caused by overtemperature")// + .label(64, "Temperature chanel7 power decrease caused by overtemperature")// + .label(128, "Temperature chanel8 power decrease caused by overtemperature")// + .label(256, "Fan 1 stop failed")// + .label(512, "Fan 2 stop failed")// + .label(1024, "Fan 3 stop failed")// + .label(2048, "Fan 4 stop failed")// + .label(4096, "Fan 1 sartup failed")// + .label(8192, "Fan 2 sartup failed")// + .label(16384, "Fan 3 sartup failed")// + .label(32768, "Fan 4 sartup failed"))), new UnsignedWordElement(0xA702, pvDCDCSuggestiveInformation3 = warning - .channel(new StatusBitChannel("PvDCDCSuggestiveInformation3", this)// - .label(1, "High voltage side overvoltage")// - .label(2, "High voltage side undervoltage")// - .label(4, "EEPROM parameters over range")// - .label(8, "High voltage side voltage change unconventionally"))), + .channel(new StatusBitChannel("PvDCDCSuggestiveInformation3", this)// + .label(1, "High voltage side overvoltage")// + .label(2, "High voltage side undervoltage")// + .label(4, "EEPROM parameters over range")// + .label(8, "High voltage side voltage change unconventionally"))), new UnsignedWordElement(0xA703, pvDCDCSuggestiveInformation4 = warning - .channel(new StatusBitChannel("PvDCDCSuggestiveInformation4", this)// - .label(1, "Current abnormity before DC Converter work on high voltage side")// - .label(2, "Current abnormity before DC Converter work on low voltage side")// - .label(4, "Initial Duty Ratio abnormity before DC Converter work")// - .label(8, "Voltage abnormity before DC Converter work on high voltage side")// - .label(16, "Voltage abnormity before DC Converter work on low voltage side"))), + .channel(new StatusBitChannel("PvDCDCSuggestiveInformation4", this)// + .label(1, "Current abnormity before DC Converter work on high voltage side")// + .label(2, "Current abnormity before DC Converter work on low voltage side")// + .label(4, "Initial Duty Ratio abnormity before DC Converter work")// + .label(8, "Voltage abnormity before DC Converter work on high voltage side")// + .label(16, "Voltage abnormity before DC Converter work on low voltage side"))), new UnsignedWordElement(0xA704, pvDCDCSuggestiveInformation5 = warning - .channel(new StatusBitChannel("PvDCDCSuggestiveInformation5", this)// - .label(1, "High voltage breaker inspection abnormity")// - .label(2, "Low voltage breaker inspection abnormity")// - .label(4, "DC precharge contactor inspection abnormity")// - .label(8, "DC precharge contactor open unsuccessfully")// - .label(16, "DC main contactor inspection abnormity")// - .label(32, "DC main contactor open unsuccessfully")// - .label(64, "Output contactor close unsuccessfully")// - .label(128, "Output contactor open unsuccessfully")// - .label(256, "AC main contactor close unsuccessfully")// - .label(512, "AC main contactor open unsuccessfully")// - .label(1024, "NegContactor open unsuccessfully")// - .label(2048, "NegContactor close unsuccessfully")// - .label(4096, "NegContactor state abnormal"))), + .channel(new StatusBitChannel("PvDCDCSuggestiveInformation5", this)// + .label(1, "High voltage breaker inspection abnormity")// + .label(2, "Low voltage breaker inspection abnormity")// + .label(4, "DC precharge contactor inspection abnormity")// + .label(8, "DC precharge contactor open unsuccessfully")// + .label(16, "DC main contactor inspection abnormity")// + .label(32, "DC main contactor open unsuccessfully")// + .label(64, "Output contactor close unsuccessfully")// + .label(128, "Output contactor open unsuccessfully")// + .label(256, "AC main contactor close unsuccessfully")// + .label(512, "AC main contactor open unsuccessfully")// + .label(1024, "NegContactor open unsuccessfully")// + .label(2048, "NegContactor close unsuccessfully")// + .label(4096, "NegContactor state abnormal"))), new DummyElement(0xA705, 0xA70F), new UnsignedWordElement(0xA710, pvDCDCAbnormity1 = warning.channel(new StatusBitChannel("PvDCDCAbnormity1", this)// @@ -880,46 +884,46 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { new DummyElement(0xA717, 0xA71F), new UnsignedWordElement(0xA720, pvDCDCSwitchState = new StatusBitChannel("PvDCDCSwitchState", this)// - .label(1, "DC precharge contactor")// - .label(2, "DC main contactor")// - .label(4, "Output contactor")// - .label(8, "Output breaker")// - .label(16, "Input breaker")// - .label(32, "AC contactor")// - .label(64, "Emergency stop button")// - .label(128, "NegContactor"))), + .label(1, "DC precharge contactor")// + .label(2, "DC main contactor")// + .label(4, "Output contactor")// + .label(8, "Output breaker")// + .label(16, "Input breaker")// + .label(32, "AC contactor")// + .label(64, "Emergency stop button")// + .label(128, "NegContactor"))), new ModbusRegisterRange(0xA730, // new SignedWordElement(0xA730, pvDCDCOutputVoltage = new ModbusReadLongChannel("PvDCDCOutputVoltage", this).unit("mV") - .multiplier(2)), + .multiplier(2)), new SignedWordElement(0xA731, pvDCDCOutputCurrent = new ModbusReadLongChannel("PvDCDCOutputCurrent", this).unit("mA") - .multiplier(2)), + .multiplier(2)), new SignedWordElement(0xA732, pvDCDCOutputPower = new ModbusReadLongChannel("PvDCDCOutputPower", this).unit("W") - .multiplier(2)), + .multiplier(2)), new SignedWordElement(0xA733, pvDCDCInputVoltage = new ModbusReadLongChannel("PvDCDCInputVoltage", this).unit("mV") - .multiplier(2)), + .multiplier(2)), new SignedWordElement(0xA734, pvDCDCInputCurrent = new ModbusReadLongChannel("PvDCDCInputCurrent", this).unit("mA") - .multiplier(2)), + .multiplier(2)), new SignedWordElement(0xA735, pvDCDCInputPower = new ModbusReadLongChannel("PvDCDCInputPower", this).unit("W") - .multiplier(2)), + .multiplier(2)), new SignedWordElement(0xA736, pvDCDCInputEnergy = new ModbusReadLongChannel("PvDCDCInputEnergy", this).unit("Wh") - .multiplier(2)), + .multiplier(2)), new SignedWordElement(0xA737, pvDCDCOutputEnergy = new ModbusReadLongChannel("PvDCDCOutputEnergy", this).unit("Wh") - .multiplier(2)), + .multiplier(2)), new DummyElement(0xA738, 0xA73F), new SignedWordElement(0xA740, pvDCDCReactorTemperature = new ModbusReadLongChannel("PvDCDCReactorTemperature", this) - .unit("°C")), + .unit("°C")), new SignedWordElement(0xA741, pvDCDCIgbtTemperature = new ModbusReadLongChannel("PvDCDCIgbtTemperature", this) - .unit("°C")), + .unit("°C")), new DummyElement(0xA742, 0xA74F), new UnsignedDoublewordElement(0xA750, pvDCDCInputTotalChargeEnergy = new ModbusReadLongChannel("PvDCDCInputTotalChargeEnergy", @@ -927,88 +931,88 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { new UnsignedDoublewordElement(0xA752, pvDCDCInputTotalDischargeEnergy = new ModbusReadLongChannel( "PvDCDCInputTotalDischargeEnergy", this).unit("Wh").multiplier(2)) - .wordOrder(WordOrder.LSWMSW), + .wordOrder(WordOrder.LSWMSW), new UnsignedDoublewordElement(0xA754, pvDCDCOutputTotalChargeEnergy = new ModbusReadLongChannel( "PvDCDCOutputTotalChargeEnergy", this).unit("Wh").multiplier(2)) - .wordOrder(WordOrder.LSWMSW), + .wordOrder(WordOrder.LSWMSW), new UnsignedDoublewordElement(0xA756, pvDCDCOutputTotalDischargeEnergy = new ModbusReadLongChannel( "PvDCDCOutputTotalDischargeEnergy", this).unit("Wh") - .multiplier(2)).wordOrder(WordOrder.LSWMSW)), + .multiplier(2)).wordOrder(WordOrder.LSWMSW)), new ModbusRegisterRange(0xA900, // new UnsignedWordElement(0xA900, pvDCDC1WorkState = new ModbusReadLongChannel("PvDCDC1WorkState", this)// - .label(2, "Initial")// - .label(4, "Stop")// - .label(8, "Ready")// - .label(16, "Running")// - .label(32, "Fault")// - .label(64, "Debug")// - .label(128, "Locked")), + .label(2, "Initial")// + .label(4, "Stop")// + .label(8, "Ready")// + .label(16, "Running")// + .label(32, "Fault")// + .label(64, "Debug")// + .label(128, "Locked")), new UnsignedWordElement(0xA901, pvDCDC1WorkMode = new ModbusReadLongChannel("PvDCDC1WorkMode", this)// - .label(128, "Constant Current")// - .label(256, "Constant Voltage")// - .label(512, "Boost MPPT"))), + .label(128, "Constant Current")// + .label(256, "Constant Voltage")// + .label(512, "Boost MPPT"))), new ModbusRegisterRange(0xAA00, // new UnsignedWordElement(0xAA00, pvDCDC1SuggestiveInformation1 = warning - .channel(new StatusBitChannel("PvDCDC1SuggestiveInformation1", this)// - .label(1, "Current sampling channel abnormity on high voltage side")// - .label(2, "Current sampling channel abnormity on low voltage side")// - .label(64, "EEPROM parameters over range")// - .label(128, "Update EEPROM failed")// - .label(256, "Read EEPROM failed")// - .label(512, "Current sampling channel abnormity before inductance"))), + .channel(new StatusBitChannel("PvDCDC1SuggestiveInformation1", this)// + .label(1, "Current sampling channel abnormity on high voltage side")// + .label(2, "Current sampling channel abnormity on low voltage side")// + .label(64, "EEPROM parameters over range")// + .label(128, "Update EEPROM failed")// + .label(256, "Read EEPROM failed")// + .label(512, "Current sampling channel abnormity before inductance"))), new UnsignedWordElement(0xAA01, pvDCDC1SuggestiveInformation2 = warning - .channel(new StatusBitChannel("PvDCDC1SuggestiveInformation2", this)// - .label(1, "Reactor power decrease caused by overtemperature")// - .label(2, "IGBT power decrease caused by overtemperature")// - .label(4, "Temperature chanel3 power decrease caused by overtemperature")// - .label(8, "Temperature chanel4 power decrease caused by overtemperature")// - .label(16, "Temperature chanel5 power decrease caused by overtemperature")// - .label(32, "Temperature chanel6 power decrease caused by overtemperature")// - .label(64, "Temperature chanel7 power decrease caused by overtemperature")// - .label(128, "Temperature chanel8 power decrease caused by overtemperature")// - .label(256, "Fan 1 stop failed")// - .label(512, "Fan 2 stop failed")// - .label(1024, "Fan 3 stop failed")// - .label(2048, "Fan 4 stop failed")// - .label(4096, "Fan 1 sartup failed")// - .label(8192, "Fan 2 sartup failed")// - .label(16384, "Fan 3 sartup failed")// - .label(32768, "Fan 4 sartup failed"))), + .channel(new StatusBitChannel("PvDCDC1SuggestiveInformation2", this)// + .label(1, "Reactor power decrease caused by overtemperature")// + .label(2, "IGBT power decrease caused by overtemperature")// + .label(4, "Temperature chanel3 power decrease caused by overtemperature")// + .label(8, "Temperature chanel4 power decrease caused by overtemperature")// + .label(16, "Temperature chanel5 power decrease caused by overtemperature")// + .label(32, "Temperature chanel6 power decrease caused by overtemperature")// + .label(64, "Temperature chanel7 power decrease caused by overtemperature")// + .label(128, "Temperature chanel8 power decrease caused by overtemperature")// + .label(256, "Fan 1 stop failed")// + .label(512, "Fan 2 stop failed")// + .label(1024, "Fan 3 stop failed")// + .label(2048, "Fan 4 stop failed")// + .label(4096, "Fan 1 sartup failed")// + .label(8192, "Fan 2 sartup failed")// + .label(16384, "Fan 3 sartup failed")// + .label(32768, "Fan 4 sartup failed"))), new UnsignedWordElement(0xAA02, pvDCDC1SuggestiveInformation3 = warning - .channel(new StatusBitChannel("PvDCDC1SuggestiveInformation3", this)// - .label(1, "High voltage side overvoltage")// - .label(2, "High voltage side undervoltage")// - .label(4, "EEPROM parameters over range")// - .label(8, "High voltage side voltage change unconventionally"))), + .channel(new StatusBitChannel("PvDCDC1SuggestiveInformation3", this)// + .label(1, "High voltage side overvoltage")// + .label(2, "High voltage side undervoltage")// + .label(4, "EEPROM parameters over range")// + .label(8, "High voltage side voltage change unconventionally"))), new UnsignedWordElement(0xAA03, pvDCDC1SuggestiveInformation4 = warning - .channel(new StatusBitChannel("PvDCDC1SuggestiveInformation4", this)// - .label(1, "Current abnormity before DC Converter work on high voltage side")// - .label(2, "Current abnormity before DC Converter work on low voltage side")// - .label(4, "Initial Duty Ratio abnormity before DC Converter work")// - .label(8, "Voltage abnormity before DC Converter work on high voltage side")// - .label(16, "Voltage abnormity before DC Converter work on low voltage side"))), + .channel(new StatusBitChannel("PvDCDC1SuggestiveInformation4", this)// + .label(1, "Current abnormity before DC Converter work on high voltage side")// + .label(2, "Current abnormity before DC Converter work on low voltage side")// + .label(4, "Initial Duty Ratio abnormity before DC Converter work")// + .label(8, "Voltage abnormity before DC Converter work on high voltage side")// + .label(16, "Voltage abnormity before DC Converter work on low voltage side"))), new UnsignedWordElement(0xAA04, pvDCDC1SuggestiveInformation5 = warning - .channel(new StatusBitChannel("PvDCDC1SuggestiveInformation5", this)// - .label(1, "High voltage breaker inspection abnormity")// - .label(2, "Low voltage breaker inspection abnormity")// - .label(4, "DC precharge contactor inspection abnormity")// - .label(8, "DC precharge contactor open unsuccessfully")// - .label(16, "DC main contactor inspection abnormity")// - .label(32, "DC main contactor open unsuccessfully")// - .label(64, "Output contactor close unsuccessfully")// - .label(128, "Output contactor open unsuccessfully")// - .label(256, "AC main contactor close unsuccessfully")// - .label(512, "AC main contactor open unsuccessfully")// - .label(1024, "NegContactor open unsuccessfully")// - .label(2048, "NegContactor close unsuccessfully")// - .label(4096, "NegContactor state abnormal"))), + .channel(new StatusBitChannel("PvDCDC1SuggestiveInformation5", this)// + .label(1, "High voltage breaker inspection abnormity")// + .label(2, "Low voltage breaker inspection abnormity")// + .label(4, "DC precharge contactor inspection abnormity")// + .label(8, "DC precharge contactor open unsuccessfully")// + .label(16, "DC main contactor inspection abnormity")// + .label(32, "DC main contactor open unsuccessfully")// + .label(64, "Output contactor close unsuccessfully")// + .label(128, "Output contactor open unsuccessfully")// + .label(256, "AC main contactor close unsuccessfully")// + .label(512, "AC main contactor open unsuccessfully")// + .label(1024, "NegContactor open unsuccessfully")// + .label(2048, "NegContactor close unsuccessfully")// + .label(4096, "NegContactor state abnormal"))), new DummyElement(0xAA05, 0xAA0F), new UnsignedWordElement(0xAA10, pvDCDC1Abnormity1 = warning.channel(new StatusBitChannel("PvDCDC1Abnormity1", this)// @@ -1118,63 +1122,63 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { new DummyElement(0xAA17, 0xAA1F), new UnsignedWordElement(0xAA20, pvDCDC1SwitchState = new StatusBitChannel("PvDCDC1SwitchState", this)// - .label(1, "DC precharge contactor")// - .label(2, "DC main contactor")// - .label(4, "Output contactor")// - .label(8, "Output breaker")// - .label(16, "Input breaker")// - .label(32, "AC contactor")// - .label(64, "Emergency stop button")// - .label(128, "NegContactor"))), + .label(1, "DC precharge contactor")// + .label(2, "DC main contactor")// + .label(4, "Output contactor")// + .label(8, "Output breaker")// + .label(16, "Input breaker")// + .label(32, "AC contactor")// + .label(64, "Emergency stop button")// + .label(128, "NegContactor"))), new ModbusRegisterRange(0xAA30, // new SignedWordElement(0xAA30, pvDCDC1OutputVoltage = new ModbusReadLongChannel("PvDCDC1OutputVoltage", this) - .unit("mV").multiplier(2)), + .unit("mV").multiplier(2)), new SignedWordElement(0xAA31, pvDCDC1OutputCurrent = new ModbusReadLongChannel("PvDCDC1OutputCurrent", this) - .unit("mA").multiplier(2)), + .unit("mA").multiplier(2)), new SignedWordElement(0xAA32, pvDCDC1OutputPower = new ModbusReadLongChannel("PvDCDC1OutputPower", this).unit("W") - .multiplier(2)), + .multiplier(2)), new SignedWordElement(0xAA33, pvDCDC1InputVoltage = new ModbusReadLongChannel("PvDCDC1InputVoltage", this).unit("mV") - .multiplier(2)), + .multiplier(2)), new SignedWordElement(0xAA34, pvDCDC1InputCurrent = new ModbusReadLongChannel("PvDCDC1InputCurrent", this).unit("mA") - .multiplier(2)), + .multiplier(2)), new SignedWordElement(0xAA35, pvDCDC1InputPower = new ModbusReadLongChannel("PvDCDC1InputPower", this).unit("W") - .multiplier(2)), + .multiplier(2)), new SignedWordElement(0xAA36, pvDCDC1InputEnergy = new ModbusReadLongChannel("PvDCDC1InputEnergy", this).unit("Wh") - .multiplier(2)), + .multiplier(2)), new SignedWordElement(0xAA37, pvDCDC1OutputEnergy = new ModbusReadLongChannel("PvDCDC1OutputEnergy", this).unit("Wh") - .multiplier(2)), + .multiplier(2)), new DummyElement(0xAA38, 0xAA3F), new SignedWordElement(0xAA40, pvDCDC1ReactorTemperature = new ModbusReadLongChannel("PvDCDC1ReactorTemperature", this) - .unit("°C")), + .unit("°C")), new SignedWordElement(0xAA41, pvDCDC1IgbtTemperature = new ModbusReadLongChannel("PvDCDC1IgbtTemperature", this) - .unit("°C")), + .unit("°C")), new DummyElement(0xAA42, 0xAA4F), new UnsignedDoublewordElement(0xAA50, pvDCDC1InputTotalChargeEnergy = new ModbusReadLongChannel( "PvDCDC1InputTotalChargeEnergy", this).unit("Wh").multiplier(2)) - .wordOrder(WordOrder.LSWMSW), + .wordOrder(WordOrder.LSWMSW), new UnsignedDoublewordElement(0xAA52, pvDCDC1InputTotalDischargeEnergy = new ModbusReadLongChannel( "PvDCDC1InputTotalDischargeEnergy", this).unit("Wh").multiplier(2)) - .wordOrder(WordOrder.LSWMSW), + .wordOrder(WordOrder.LSWMSW), new UnsignedDoublewordElement(0xAA54, pvDCDC1OutputTotalChargeEnergy = new ModbusReadLongChannel( "PvDCDC1OutputTotalChargeEnergy", this).unit("Wh").multiplier(2)) - .wordOrder(WordOrder.LSWMSW), + .wordOrder(WordOrder.LSWMSW), new UnsignedDoublewordElement(0xAA56, pvDCDC1OutputTotalDischargeEnergy = new ModbusReadLongChannel( "PvDCDC1OutputTotalDischargeEnergy", this).unit("Wh").multiplier(2)) - .wordOrder(WordOrder.LSWMSW))); + .wordOrder(WordOrder.LSWMSW))); actualPower = new FunctionalReadChannel("ActualPower", this, (channels) -> { long erg = 0; try { @@ -1222,4 +1226,9 @@ public ReadChannel getInputVoltage() { return inputVoltage; } + @Override + public ThingStateChannel getStateChannel() { + return thingState; + } + } diff --git a/edge/src/io/openems/impl/device/commercial/FeneconCommercialDC.java b/edge/src/io/openems/impl/device/commercial/FeneconCommercialDC.java index d2116529678..aeb8d21aeb5 100644 --- a/edge/src/io/openems/impl/device/commercial/FeneconCommercialDC.java +++ b/edge/src/io/openems/impl/device/commercial/FeneconCommercialDC.java @@ -45,10 +45,10 @@ public FeneconCommercialDC(Bridge parent) throws OpenemsException { * Config */ @ChannelInfo(title = "Ess", description = "Sets the Ess nature.", type = FeneconCommercialEss.class) - public final ConfigChannel ess = new ConfigChannel("ess", this); + public final ConfigChannel ess = new ConfigChannel("ess", this).addChangeListener(this); @ChannelInfo(title = "Charger", description = "Sets the inverter nature.", type = FeneconCommercialCharger.class) - public final ConfigChannel charger = new ConfigChannel<>("charger", this); + public final ConfigChannel charger = new ConfigChannel("charger", this).addChangeListener(this); /* * Methods diff --git a/edge/src/io/openems/impl/device/commercial/FeneconCommercialEss.java b/edge/src/io/openems/impl/device/commercial/FeneconCommercialEss.java index 3d0162c6659..4d89f253350 100644 --- a/edge/src/io/openems/impl/device/commercial/FeneconCommercialEss.java +++ b/edge/src/io/openems/impl/device/commercial/FeneconCommercialEss.java @@ -24,11 +24,12 @@ import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; import io.openems.api.channel.StatusBitChannel; -import io.openems.api.channel.StatusBitChannels; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.ess.SymmetricEssNature; import io.openems.api.doc.ThingInfo; import io.openems.api.exception.ConfigException; +import io.openems.impl.protocol.modbus.ModbusBitWrappingChannel; import io.openems.impl.protocol.modbus.ModbusDeviceNature; import io.openems.impl.protocol.modbus.ModbusReadLongChannel; import io.openems.impl.protocol.modbus.ModbusWriteLongChannel; @@ -44,6 +45,8 @@ @ThingInfo(title = "FENECON Commercial ESS") public class FeneconCommercialEss extends ModbusDeviceNature implements SymmetricEssNature { + private ThingStateChannel thingState; + /* * Constructors */ @@ -55,6 +58,7 @@ public FeneconCommercialEss(String thingId, Device parent) throws ConfigExceptio chargeSoc.updateValue((Integer) newValue.get() - 2, false); } }); + this.thingState = new ThingStateChannel(this); } /* @@ -90,7 +94,6 @@ public ConfigChannel chargeSoc() { private StaticValueChannel maxNominalPower = new StaticValueChannel<>("maxNominalPower", this, 40000L) .unit("VA"); private StaticValueChannel capacity = new StaticValueChannel<>("capacity", this, 40000L).unit("Wh"); - public StatusBitChannels warning; @Override public ModbusReadLongChannel soc() { @@ -152,11 +155,6 @@ public ModbusReadLongChannel allowedApparent() { return allowedApparent; } - @Override - public StatusBitChannels warning() { - return warning; - } - @Override public ReadChannel maxNominalPower() { return maxNominalPower; @@ -216,7 +214,6 @@ public ReadChannel maxNominalPower() { */ @Override protected ModbusProtocol defineModbusProtocol() throws ConfigException { - warning = new StatusBitChannels("Warning", this); return new ModbusProtocol( // new ModbusRegisterRange(0x0101, // new UnsignedWordElement(0x0101, // @@ -261,30 +258,26 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { .label(1, "CESS")), // new DummyElement(0x010B, 0x010F), // new UnsignedWordElement(0x0110, // - suggestiveInformation1 = warning - .channel(new StatusBitChannel("SuggestiveInformation1", this) // - .label(4, "EmergencyStop") // - .label(64, "KeyManualStop"))), // + new ModbusBitWrappingChannel("SuggestiveInformation1", this,this.thingState) // + .warningBit(2, Warning.EmergencyStop) //EmergencyStop + .warningBit(6, Warning.KeyManualStop)), //KeyManualStop new UnsignedWordElement(0x0111, // - suggestiveInformation2 = warning - .channel(new StatusBitChannel("SuggestiveInformation2", this) // - .label(4, "EmergencyStop") // - .label(64, "KeyManualStop"))), // + new ModbusBitWrappingChannel("SuggestiveInformation2", this,this.thingState) // + .warningBit(3, Warning.TransformerPhaseBTemperatureSensorInvalidation) //Transformer phase B temperature sensor invalidation + .warningBit(12, Warning.SDMemoryCardInvalidation)), //SD memory card invalidation new DummyElement(0x0112, 0x0124), // new UnsignedWordElement(0x0125, // - suggestiveInformation3 = warning - .channel(new StatusBitChannel("SuggestiveInformation3", this) // - .label(1, "Inverter communication abnormity") // - .label(2, "Battery stack communication abnormity") // - .label(4, "Multifunctional ammeter communication abnormity") // - .label(16, "Remote communication abnormity")// - .label(256, "PV DC1 communication abnormity")// - .label(512, "PV DC2 communication abnormity")// - )), // + suggestiveInformation3 = new StatusBitChannel("SuggestiveInformation3", this) // + .label(1, "Inverter communication abnormity") // + .label(2, "Battery stack communication abnormity") // + .label(4, "Multifunctional ammeter communication abnormity") // + .label(16, "Remote communication abnormity")// + .label(256, "PV DC1 communication abnormity")// + .label(512, "PV DC2 communication abnormity")// + ), // new UnsignedWordElement(0x0126, // - suggestiveInformation4 = warning - .channel(new StatusBitChannel("SuggestiveInformation4", this) // - .label(8, "Transformer severe overtemperature"))), // + suggestiveInformation4 = new StatusBitChannel("SuggestiveInformation4", this) // + .label(8, "Transformer severe overtemperature")), // new DummyElement(0x0127, 0x014F), // new UnsignedWordElement(0x0150, // switchState = new StatusBitChannel("BatteryStringSwitchState", this) // @@ -296,138 +289,135 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { ), // new ModbusRegisterRange(0x0180, // new UnsignedWordElement(0x0180, - abnormity1 = warning.channel(new StatusBitChannel("Abnormity1", this)// - .label(1, "DC precharge contactor close unsuccessfully") // - .label(2, "AC precharge contactor close unsuccessfully") // - .label(4, "AC main contactor close unsuccessfully") // - .label(8, "DC electrical breaker 1 close unsuccessfully") // - .label(16, "DC main contactor close unsuccessfully") // - .label(32, "AC breaker trip") // - .label(64, "AC main contactor open when running") // - .label(128, "DC main contactor open when running") // - .label(256, "AC main contactor open unsuccessfully") // - .label(512, "DC electrical breaker 1 open unsuccessfully") // - .label(1024, "DC main contactor open unsuccessfully") // - .label(2048, "Hardware PDP fault") // - .label(4096, "Master stop suddenly"))), + abnormity1 = new StatusBitChannel("Abnormity1", this)// + .label(1, "DC precharge contactor close unsuccessfully") // + .label(2, "AC precharge contactor close unsuccessfully") // + .label(4, "AC main contactor close unsuccessfully") // + .label(8, "DC electrical breaker 1 close unsuccessfully") // + .label(16, "DC main contactor close unsuccessfully") // + .label(32, "AC breaker trip") // + .label(64, "AC main contactor open when running") // + .label(128, "DC main contactor open when running") // + .label(256, "AC main contactor open unsuccessfully") // + .label(512, "DC electrical breaker 1 open unsuccessfully") // + .label(1024, "DC main contactor open unsuccessfully") // + .label(2048, "Hardware PDP fault") // + .label(4096, "Master stop suddenly")), new DummyElement(0x0181), new UnsignedWordElement(0x0182, - abnormity2 = warning.channel(new StatusBitChannel("Abnormity2", this) // - .label(1, "DC short circuit protection") // - .label(2, "DC overvoltage protection") // - .label(4, "DC undervoltage protection") // - .label(8, "DC inverse/no connection protection") // - .label(16, "DC disconnection protection") // - .label(32, "Commuting voltage abnormity protection") // - .label(64, "DC overcurrent protection") // - .label(128, "Phase 1 peak current over limit protection") // - .label(256, "Phase 2 peak current over limit protection") // - .label(512, "Phase 3 peak current over limit protection") // - .label(1024, "Phase 1 grid voltage sampling invalidation") // - .label(2048, "Phase 2 virtual current over limit protection") // - .label(4096, "Phase 3 virtual current over limit protection") // - .label(8192, "Phase 1 grid voltage sampling invalidation2") // TODO same as - // above - .label(16384, "Phase 2 grid voltage sampling invalidation") // - .label(32768, "Phase 3 grid voltage sampling invalidation"))), + abnormity2 = new StatusBitChannel("Abnormity2", this) // + .label(1, "DC short circuit protection") // + .label(2, "DC overvoltage protection") // + .label(4, "DC undervoltage protection") // + .label(8, "DC inverse/no connection protection") // + .label(16, "DC disconnection protection") // + .label(32, "Commuting voltage abnormity protection") // + .label(64, "DC overcurrent protection") // + .label(128, "Phase 1 peak current over limit protection") // + .label(256, "Phase 2 peak current over limit protection") // + .label(512, "Phase 3 peak current over limit protection") // + .label(1024, "Phase 1 grid voltage sampling invalidation") // + .label(2048, "Phase 2 virtual current over limit protection") // + .label(4096, "Phase 3 virtual current over limit protection") // + .label(8192, "Phase 1 grid voltage sampling invalidation2") // TODO same as + // above + .label(16384, "Phase 2 grid voltage sampling invalidation") // + .label(32768, "Phase 3 grid voltage sampling invalidation")), new UnsignedWordElement(0x0183, - abnormity3 = warning.channel(new StatusBitChannel("Abnormity3", this) // - .label(1, "Phase 1 invert voltage sampling invalidation") // - .label(2, "Phase 2 invert voltage sampling invalidation") // - .label(4, "Phase 3 invert voltage sampling invalidation") // - .label(8, "AC current sampling invalidation") // - .label(16, "DC current sampling invalidation") // - .label(32, "Phase 1 overtemperature protection") // - .label(64, "Phase 2 overtemperature protection") // - .label(128, "Phase 3 overtemperature protection") // - .label(256, "Phase 1 temperature sampling invalidation") // - .label(512, "Phase 2 temperature sampling invalidation") // - .label(1024, "Phase 3 temperature sampling invalidation") // - .label(2048, "Phase 1 precharge unmet protection") // - .label(4096, "Phase 2 precharge unmet protection") // - .label(8192, "Phase 3 precharge unmet protection") // - .label(16384, "Unadaptable phase sequence error protection")// - .label(132768, "DSP protection"))), + abnormity3 = new StatusBitChannel("Abnormity3", this) // + .label(1, "Phase 1 invert voltage sampling invalidation") // + .label(2, "Phase 2 invert voltage sampling invalidation") // + .label(4, "Phase 3 invert voltage sampling invalidation") // + .label(8, "AC current sampling invalidation") // + .label(16, "DC current sampling invalidation") // + .label(32, "Phase 1 overtemperature protection") // + .label(64, "Phase 2 overtemperature protection") // + .label(128, "Phase 3 overtemperature protection") // + .label(256, "Phase 1 temperature sampling invalidation") // + .label(512, "Phase 2 temperature sampling invalidation") // + .label(1024, "Phase 3 temperature sampling invalidation") // + .label(2048, "Phase 1 precharge unmet protection") // + .label(4096, "Phase 2 precharge unmet protection") // + .label(8192, "Phase 3 precharge unmet protection") // + .label(16384, "Unadaptable phase sequence error protection")// + .label(132768, "DSP protection")), new UnsignedWordElement(0x0184, - abnormity4 = warning.channel(new StatusBitChannel("Abnormity4", this) // - .label(1, "Phase 1 grid voltage severe overvoltage protection") // - .label(2, "Phase 1 grid voltage general overvoltage protection") // - .label(4, "Phase 2 grid voltage severe overvoltage protection") // - .label(8, "Phase 2 grid voltage general overvoltage protection") // - .label(16, "Phase 3 grid voltage severe overvoltage protection") // - .label(32, "Phase 3 grid voltage general overvoltage protection") // - .label(64, "Phase 1 grid voltage severe undervoltage protection") // - .label(128, "Phase 1 grid voltage general undervoltage protection") // - .label(256, "Phase 2 grid voltage severe undervoltage protection") // - .label(512, "Phase 2 grid voltage general undervoltage protection") // - .label(1024, "Phase 2 Inverter voltage general overvoltage protection") // - .label(2048, "Phase 3 Inverter voltage severe overvoltage protection") // - .label(4096, "Phase 3 Inverter voltage general overvoltage protection") // - .label(8192, "Inverter peak voltage high protection cause by AC disconnect"))), + abnormity4 = new StatusBitChannel("Abnormity4", this) // + .label(1, "Phase 1 grid voltage severe overvoltage protection") // + .label(2, "Phase 1 grid voltage general overvoltage protection") // + .label(4, "Phase 2 grid voltage severe overvoltage protection") // + .label(8, "Phase 2 grid voltage general overvoltage protection") // + .label(16, "Phase 3 grid voltage severe overvoltage protection") // + .label(32, "Phase 3 grid voltage general overvoltage protection") // + .label(64, "Phase 1 grid voltage severe undervoltage protection") // + .label(128, "Phase 1 grid voltage general undervoltage protection") // + .label(256, "Phase 2 grid voltage severe undervoltage protection") // + .label(512, "Phase 2 grid voltage general undervoltage protection") // + .label(1024, "Phase 2 Inverter voltage general overvoltage protection") // + .label(2048, "Phase 3 Inverter voltage severe overvoltage protection") // + .label(4096, "Phase 3 Inverter voltage general overvoltage protection") // + .label(8192, "Inverter peak voltage high protection cause by AC disconnect")), new UnsignedWordElement(0x0185, - abnormity5 = warning.channel(new StatusBitChannel("Abnormity5", this) // - .label(1, "Phase 1 grid loss") // - .label(2, "Phase 2 grid loss") // - .label(4, "Phase 3 grid loss") // - .label(8, "Islanding protection") // - .label(16, "Phase 1 under voltage ride through") // - .label(32, "Phase 2 under voltage ride through") // - .label(64, "Phase 3 under voltage ride through ") // - .label(128, "Phase 1 Inverter voltage severe overvoltage protection") // - .label(256, "Phase 1 Inverter voltage general overvoltage protection") // - .label(512, "Phase 2 Inverter voltage severe overvoltage protection") // - .label(1024, "Phase 2 Inverter voltage general overvoltage protection") // - .label(2048, "Phase 3 Inverter voltage severe overvoltage protection") // - .label(4096, "Phase 3 Inverter voltage general overvoltage protection") // - .label(8192, "Inverter peak voltage high protection cause by AC disconnect"))), + abnormity5 = new StatusBitChannel("Abnormity5", this) // + .label(1, "Phase 1 grid loss") // + .label(2, "Phase 2 grid loss") // + .label(4, "Phase 3 grid loss") // + .label(8, "Islanding protection") // + .label(16, "Phase 1 under voltage ride through") // + .label(32, "Phase 2 under voltage ride through") // + .label(64, "Phase 3 under voltage ride through ") // + .label(128, "Phase 1 Inverter voltage severe overvoltage protection") // + .label(256, "Phase 1 Inverter voltage general overvoltage protection") // + .label(512, "Phase 2 Inverter voltage severe overvoltage protection") // + .label(1024, "Phase 2 Inverter voltage general overvoltage protection") // + .label(2048, "Phase 3 Inverter voltage severe overvoltage protection") // + .label(4096, "Phase 3 Inverter voltage general overvoltage protection") // + .label(8192, "Inverter peak voltage high protection cause by AC disconnect")), new UnsignedWordElement(0x0186, - suggestiveInformation5 = warning - .channel(new StatusBitChannel("SuggestiveInformation5", this) // - .label(1, "DC precharge contactor inspection abnormity") // - .label(2, "DC breaker 1 inspection abnormity ") // - .label(4, "DC breaker 2 inspection abnormity ") // - .label(8, "AC precharge contactor inspection abnormity ") // - .label(16, "AC main contactor inspection abnormity ") // - .label(32, "AC breaker inspection abnormity ") // - .label(64, "DC breaker 1 close unsuccessfully") // - .label(128, "DC breaker 2 close unsuccessfully") // - .label(256, "Control signal close abnormally inspected by system") // - .label(512, "Control signal open abnormally inspected by system") // - .label(1024, "Neutral wire contactor close unsuccessfully") // - .label(2048, "Neutral wire contactor open unsuccessfully") // - .label(4096, "Work door open") // - .label(8192, "Emergency stop") // - .label(16384, "AC breaker close unsuccessfully")// - .label(132768, "Control switch stop"))), + suggestiveInformation5 = new StatusBitChannel("SuggestiveInformation5", this) // + .label(1, "DC precharge contactor inspection abnormity") // + .label(2, "DC breaker 1 inspection abnormity ") // + .label(4, "DC breaker 2 inspection abnormity ") // + .label(8, "AC precharge contactor inspection abnormity ") // + .label(16, "AC main contactor inspection abnormity ") // + .label(32, "AC breaker inspection abnormity ") // + .label(64, "DC breaker 1 close unsuccessfully") // + .label(128, "DC breaker 2 close unsuccessfully") // + .label(256, "Control signal close abnormally inspected by system") // + .label(512, "Control signal open abnormally inspected by system") // + .label(1024, "Neutral wire contactor close unsuccessfully") // + .label(2048, "Neutral wire contactor open unsuccessfully") // + .label(4096, "Work door open") // + .label(8192, "Emergency stop") // + .label(16384, "AC breaker close unsuccessfully")// + .label(132768, "Control switch stop")), new UnsignedWordElement(0x0187, - suggestiveInformation6 = warning - .channel(new StatusBitChannel("SuggestiveInformation6", this) // - .label(1, "General overload") // - .label(2, "Severe overload") // - .label(4, "Battery current over limit") // - .label(8, "Power decrease caused by overtemperature") // - .label(16, "Inverter general overtemperature") // - .label(32, "AC three-phase current unbalance") // - .label(64, "Rstore factory setting unsuccessfully") // - .label(128, "Pole-board invalidation") // - .label(256, "Self-inspection failed") // - .label(512, "Receive BMS fault and stop") // - .label(1024, "Refrigeration equipment invalidation") // - .label(2048, "Large temperature difference among IGBT three phases") // - .label(4096, "EEPROM parameters over range") // - .label(8192, "EEPROM parameters backup failed") // - .label(16384, "DC breaker close unsuccessfully"))), + suggestiveInformation6 = new StatusBitChannel("SuggestiveInformation6", this) // + .label(1, "General overload") // + .label(2, "Severe overload") // + .label(4, "Battery current over limit") // + .label(8, "Power decrease caused by overtemperature") // + .label(16, "Inverter general overtemperature") // + .label(32, "AC three-phase current unbalance") // + .label(64, "Rstore factory setting unsuccessfully") // + .label(128, "Pole-board invalidation") // + .label(256, "Self-inspection failed") // + .label(512, "Receive BMS fault and stop") // + .label(1024, "Refrigeration equipment invalidation") // + .label(2048, "Large temperature difference among IGBT three phases") // + .label(4096, "EEPROM parameters over range") // + .label(8192, "EEPROM parameters backup failed") // + .label(16384, "DC breaker close unsuccessfully")), new UnsignedWordElement(0x0188, - suggestiveInformation7 = warning - .channel(new StatusBitChannel("SuggestiveInformation7", this) // - .label(1, "Communication between inverter and BSMU disconnected") // - .label(2, "Communication between inverter and Master disconnected") // - .label(4, "Communication between inverter and UC disconnected") // - .label(8, "BMS start overtime controlled by PCS") // - .label(16, "BMS stop overtime controlled by PCS") // - .label(32, "Sync signal invalidation") // - .label(64, "Sync signal continuous caputure fault") // - .label(128, "Sync signal several times caputure fault")))), + suggestiveInformation7 = new StatusBitChannel("SuggestiveInformation7", this) // + .label(1, "Communication between inverter and BSMU disconnected") // + .label(2, "Communication between inverter and Master disconnected") // + .label(4, "Communication between inverter and UC disconnected") // + .label(8, "BMS start overtime controlled by PCS") // + .label(16, "BMS stop overtime controlled by PCS") // + .label(32, "Sync signal invalidation") // + .label(64, "Sync signal continuous caputure fault") // + .label(128, "Sync signal several times caputure fault"))), new ModbusRegisterRange(0x0200, // new SignedWordElement(0x0200, // batteryVoltage = new ModbusReadLongChannel("BatteryVoltage", this).unit("mV") @@ -538,6 +528,11 @@ public StaticValueChannel capacity() { return capacity; } + @Override + public ThingStateChannel getStateChannel() { + return thingState; + } + // @IsChannel(id = "BatteryAccumulatedCharge") // public final ModbusReadChannel _batteryAccumulatedCharge = new OldModbusChannelBuilder().nature(this).unit("Wh") // .build(); diff --git a/edge/src/io/openems/impl/device/commercial/Warning.java b/edge/src/io/openems/impl/device/commercial/Warning.java new file mode 100644 index 00000000000..cd2fabcd87c --- /dev/null +++ b/edge/src/io/openems/impl/device/commercial/Warning.java @@ -0,0 +1,19 @@ +package io.openems.impl.device.commercial; + +import io.openems.api.channel.thingstate.WarningEnum; + +public enum Warning implements WarningEnum { + EmergencyStop(0),KeyManualStop(1),TransformerPhaseBTemperatureSensorInvalidation(2),SDMemoryCardInvalidation(3); + + private final int value; + + private Warning(int value) { + this.value = value; + } + + @Override + public int getValue() { + return this.value; + } + +} diff --git a/edge/src/io/openems/impl/device/custom/riedmann/Riedmann.java b/edge/src/io/openems/impl/device/custom/riedmann/Riedmann.java index 1aae8f47974..25c7be93058 100644 --- a/edge/src/io/openems/impl/device/custom/riedmann/Riedmann.java +++ b/edge/src/io/openems/impl/device/custom/riedmann/Riedmann.java @@ -15,7 +15,7 @@ public class Riedmann extends ModbusDevice { @ChannelInfo(title = "", type = RiedmannNatureImpl.class) - public final ConfigChannel device = new ConfigChannel("device", this); + public final ConfigChannel device = new ConfigChannel("device", this).addChangeListener(this); public Riedmann(Bridge parent) throws OpenemsException { super(parent); diff --git a/edge/src/io/openems/impl/device/custom/riedmann/RiedmannNatureImpl.java b/edge/src/io/openems/impl/device/custom/riedmann/RiedmannNatureImpl.java index d8e12bc555b..da00a146601 100644 --- a/edge/src/io/openems/impl/device/custom/riedmann/RiedmannNatureImpl.java +++ b/edge/src/io/openems/impl/device/custom/riedmann/RiedmannNatureImpl.java @@ -1,5 +1,6 @@ package io.openems.impl.device.custom.riedmann; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.doc.ThingInfo; import io.openems.api.exception.ConfigException; @@ -57,6 +58,7 @@ public class RiedmannNatureImpl extends ModbusDeviceNature implements RiedmannNa private ModbusWriteChannel setWaterLevelBorehole2Off; private ModbusWriteChannel setWaterLevelBorehole3On; private ModbusWriteChannel setWaterLevelBorehole3Off; + private ThingStateChannel thingState; @Override public ModbusReadChannel getWaterlevel() { @@ -260,6 +262,7 @@ public ModbusWriteChannel getSetWaterLevelBorehole3Off() { public RiedmannNatureImpl(String thingId, Device parent) throws ConfigException { super(thingId, parent); + this.thingState = new ThingStateChannel(this); } @Override @@ -343,7 +346,12 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { new SignedWordElement(75, // getWaterLevelBorehole3Off = new ModbusReadLongChannel("GetWaterLevelBorehole3Off", this)) // - )); + )); + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; } } diff --git a/edge/src/io/openems/impl/device/janitza/JanitzaUMG96RME.java b/edge/src/io/openems/impl/device/janitza/JanitzaUMG96RME.java index 1fcce77cae0..7a8168ad9a0 100644 --- a/edge/src/io/openems/impl/device/janitza/JanitzaUMG96RME.java +++ b/edge/src/io/openems/impl/device/janitza/JanitzaUMG96RME.java @@ -45,7 +45,7 @@ public JanitzaUMG96RME(Bridge parent) throws OpenemsException { * Config */ @ChannelInfo(title = "Meter", description = "Sets the meter nature.", type = JanitzaUMG96RMEMeter.class) - public final ConfigChannel meter = new ConfigChannel<>("meter", this); + public final ConfigChannel meter = new ConfigChannel("meter", this).addChangeListener(this); /* * Methods diff --git a/edge/src/io/openems/impl/device/janitza/JanitzaUMG96RMEMeter.java b/edge/src/io/openems/impl/device/janitza/JanitzaUMG96RMEMeter.java index 6cc44b58394..d52fa1a5189 100644 --- a/edge/src/io/openems/impl/device/janitza/JanitzaUMG96RMEMeter.java +++ b/edge/src/io/openems/impl/device/janitza/JanitzaUMG96RMEMeter.java @@ -22,6 +22,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.AsymmetricMeterNature; import io.openems.api.device.nature.meter.SymmetricMeterNature; @@ -37,11 +38,14 @@ @ThingInfo(title = "Janitza UMG96RM Meter") public class JanitzaUMG96RMEMeter extends ModbusDeviceNature implements SymmetricMeterNature, AsymmetricMeterNature { + private ThingStateChannel thingState; + /* * Constructors */ public JanitzaUMG96RMEMeter(String thingId, Device parent) throws ConfigException { super(thingId, parent); + this.thingState = new ThingStateChannel(this); } /* @@ -127,14 +131,14 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { new ModbusRegisterRange(800, // new FloatElement(800, // frequency = new ModbusReadLongChannel("Frequency", this).unit("mHz")) // - .multiplier(3), + .multiplier(3), new DummyElement(802, 807), new FloatElement(808, voltageL1 = new ModbusReadLongChannel("VoltageL1", this).unit("mV")) - .multiplier(3), + .multiplier(3), new FloatElement(810, voltageL2 = new ModbusReadLongChannel("VoltageL2", this).unit("mV")) - .multiplier(3), + .multiplier(3), new FloatElement(812, voltageL3 = new ModbusReadLongChannel("VoltageL3", this).unit("mV")) - .multiplier(3), + .multiplier(3), new DummyElement(814, 859), new FloatElement(860, // currentL1 = new ModbusReadLongChannel("CurrentL1", this).unit("mA")).multiplier(3), new FloatElement(862, // @@ -145,32 +149,32 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { current = new ModbusReadLongChannel("Current", this).unit("mA")).multiplier(3), new FloatElement(868, // activePowerL1 = new ModbusReadLongChannel("ActivePowerL1", this) // - .unit("W")), // + .unit("W")), // new FloatElement(870, // activePowerL2 = new ModbusReadLongChannel("ActivePowerL2", this) // - .unit("W")), // + .unit("W")), // new FloatElement(872, // activePowerL3 = new ModbusReadLongChannel("ActivePowerL3", this) // - .unit("W")), // + .unit("W")), // new FloatElement(874, // activePower = new ModbusReadLongChannel("ActivePower", this) // - .unit("W")), // + .unit("W")), // new FloatElement(876, // reactivePowerL1 = new ModbusReadLongChannel("ReactivePowerL1", this) // - .unit("Var")), // + .unit("Var")), // new FloatElement(878, // reactivePowerL2 = new ModbusReadLongChannel("ReactivePowerL2", this) // - .unit("Var")), // + .unit("Var")), // new FloatElement(880, // reactivePowerL3 = new ModbusReadLongChannel("ReactivePowerL3", this) // - .unit("Var")), // + .unit("Var")), // new FloatElement(882, // reactivePower = new ModbusReadLongChannel("ReactivePower", this) // - .unit("Var")), // + .unit("Var")), // new DummyElement(884, 889), new FloatElement(890, // apparentPower = new ModbusReadLongChannel("ApparentPower", this) // - .unit("VA")) // - )); + .unit("VA")) // + )); } @Override @@ -232,4 +236,9 @@ public ReadChannel voltageL2() { public ReadChannel voltageL3() { return voltageL3; } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } } diff --git a/edge/src/io/openems/impl/device/keba/Keba.java b/edge/src/io/openems/impl/device/keba/Keba.java index b4e1b66907d..6558ec81a34 100644 --- a/edge/src/io/openems/impl/device/keba/Keba.java +++ b/edge/src/io/openems/impl/device/keba/Keba.java @@ -57,7 +57,7 @@ public Keba(Bridge parent) throws OpenemsException { public ConfigChannel ip = new ConfigChannel("ip", this); @ChannelInfo(title = "evcs", description = "Sets the EVCS nature.", type = KebaEvcs.class) - public final ConfigChannel evcs = new ConfigChannel("evcs", this); + public final ConfigChannel evcs = new ConfigChannel("evcs", this).addChangeListener(this); /* * Methods diff --git a/edge/src/io/openems/impl/device/keba/KebaEvcs.java b/edge/src/io/openems/impl/device/keba/KebaEvcs.java index 436db9d500e..3729e0966b2 100644 --- a/edge/src/io/openems/impl/device/keba/KebaEvcs.java +++ b/edge/src/io/openems/impl/device/keba/KebaEvcs.java @@ -20,6 +20,7 @@ *******************************************************************************/ package io.openems.impl.device.keba; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.nature.evcs.EvcsNature; import io.openems.api.doc.ThingInfo; import io.openems.api.exception.ConfigException; @@ -29,8 +30,11 @@ @ThingInfo(title = "KEBA KeContact EVCS") public class KebaEvcs extends KebaDeviceNature implements EvcsNature { + private ThingStateChannel thingState; + public KebaEvcs(String thingId, KebaDevice parent) throws ConfigException { super(thingId, parent); + this.thingState = new ThingStateChannel(this); } @Override @@ -38,4 +42,9 @@ public String toString() { return state.format() + ";" + plug.format() + ";current:" + currUser.format() + "|" + currHardware.format() + ";energy:" + energySession.format() + "|" + energyTotal.format(); } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } } diff --git a/edge/src/io/openems/impl/device/kmtronic/KMTronicRelay.java b/edge/src/io/openems/impl/device/kmtronic/KMTronicRelay.java index ad16eaa1a07..71b47108e9d 100644 --- a/edge/src/io/openems/impl/device/kmtronic/KMTronicRelay.java +++ b/edge/src/io/openems/impl/device/kmtronic/KMTronicRelay.java @@ -45,7 +45,7 @@ public KMTronicRelay(Bridge parent) throws OpenemsException { * Config */ @ChannelInfo(title = "Output", description = "Sets the output nature.", type = KMTronicRelayOutput.class) - public final ConfigChannel output = new ConfigChannel<>("output", this); + public final ConfigChannel output = new ConfigChannel("output", this).addChangeListener(this); /* * Methods diff --git a/edge/src/io/openems/impl/device/kmtronic/KMTronicRelayOutput.java b/edge/src/io/openems/impl/device/kmtronic/KMTronicRelayOutput.java index 769a86cf0a4..5c7b93c4125 100644 --- a/edge/src/io/openems/impl/device/kmtronic/KMTronicRelayOutput.java +++ b/edge/src/io/openems/impl/device/kmtronic/KMTronicRelayOutput.java @@ -20,6 +20,7 @@ *******************************************************************************/ package io.openems.impl.device.kmtronic; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.io.OutputNature; import io.openems.api.doc.ThingInfo; @@ -33,12 +34,15 @@ @ThingInfo(title = "KMTronic Relay board Output") public class KMTronicRelayOutput extends ModbusDeviceNature implements OutputNature { + private ThingStateChannel thingState; + /* * Constructors */ public KMTronicRelayOutput(String thingId, Device parent) throws ConfigException { super(thingId, parent); outputs = new ModbusCoilWriteChannel[8]; + this.thingState = new ThingStateChannel(this); } /* @@ -68,4 +72,9 @@ public ModbusCoilWriteChannel[] setOutput() { return outputs; } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/device/kmtronic/KMTronicRelayOutputRev1.java b/edge/src/io/openems/impl/device/kmtronic/KMTronicRelayOutputRev1.java index e5dadf7ddf4..f63b049af9e 100644 --- a/edge/src/io/openems/impl/device/kmtronic/KMTronicRelayOutputRev1.java +++ b/edge/src/io/openems/impl/device/kmtronic/KMTronicRelayOutputRev1.java @@ -20,6 +20,7 @@ *******************************************************************************/ package io.openems.impl.device.kmtronic; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.io.OutputNature; import io.openems.api.doc.ThingInfo; @@ -33,12 +34,15 @@ @ThingInfo(title = "KMTronic Relay board Output") public class KMTronicRelayOutputRev1 extends ModbusDeviceNature implements OutputNature { + private ThingStateChannel thingState; + /* * Constructors */ public KMTronicRelayOutputRev1(String thingId, Device parent) throws ConfigException { super(thingId, parent); outputs = new ModbusCoilWriteChannel[7]; + this.thingState = new ThingStateChannel(this); } /* @@ -67,4 +71,9 @@ public ModbusCoilWriteChannel[] setOutput() { return outputs; } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/device/kmtronic/KMTronicRelayRev1.java b/edge/src/io/openems/impl/device/kmtronic/KMTronicRelayRev1.java index f380c2a7bf4..4062af41254 100644 --- a/edge/src/io/openems/impl/device/kmtronic/KMTronicRelayRev1.java +++ b/edge/src/io/openems/impl/device/kmtronic/KMTronicRelayRev1.java @@ -45,7 +45,7 @@ public KMTronicRelayRev1(Bridge parent) throws OpenemsException { * Config */ @ChannelInfo(title = "Output", description = "Sets the output nature.", type = KMTronicRelayOutputRev1.class) - public final ConfigChannel output = new ConfigChannel<>("output", this); + public final ConfigChannel output = new ConfigChannel("output", this).addChangeListener(this); /* * Methods diff --git a/edge/src/io/openems/impl/device/mini/FeneconMini.java b/edge/src/io/openems/impl/device/mini/FeneconMini.java index 1a3e21a08bd..6bf6f34848f 100644 --- a/edge/src/io/openems/impl/device/mini/FeneconMini.java +++ b/edge/src/io/openems/impl/device/mini/FeneconMini.java @@ -45,7 +45,7 @@ public FeneconMini(Bridge parent) throws OpenemsException { * Config */ @ChannelInfo(title = "Ess", description = "Sets the Ess nature.", type = FeneconMiniEss.class) - public final ConfigChannel ess = new ConfigChannel<>("ess", this); + public final ConfigChannel ess = new ConfigChannel("ess", this).addChangeListener(this); /* * Methods diff --git a/edge/src/io/openems/impl/device/mini/FeneconMiniEss.java b/edge/src/io/openems/impl/device/mini/FeneconMiniEss.java index ffcf2de55af..3a3cee72302 100644 --- a/edge/src/io/openems/impl/device/mini/FeneconMiniEss.java +++ b/edge/src/io/openems/impl/device/mini/FeneconMiniEss.java @@ -27,6 +27,7 @@ import io.openems.api.channel.StatusBitChannel; import io.openems.api.channel.StatusBitChannels; import io.openems.api.channel.WriteChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.device.nature.ess.SymmetricEssNature; @@ -49,6 +50,8 @@ @ThingInfo(title = "FENECON Mini ESS") public class FeneconMiniEss extends ModbusDeviceNature implements SymmetricEssNature, RealTimeClockNature { + private ThingStateChannel thingState; + /* * Constructors */ @@ -60,6 +63,7 @@ public FeneconMiniEss(String thingId, Device parent) throws ConfigException { chargeSoc.updateValue((Integer) newValue.get() - 2, false); } }); + this.thingState = new ThingStateChannel(this); } /* @@ -150,11 +154,6 @@ public WriteChannel setReactivePower() { return setReactivePower; } - @Override - public StatusBitChannels warning() { - return warning; - } - @Override public ReadChannel allowedApparent() { return phaseAllowedApparent; @@ -231,30 +230,30 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { ModbusProtocol protokol = new ModbusProtocol(new ModbusRegisterRange(100, // new UnsignedWordElement(100, // systemState = new ModbusReadLongChannel("SystemState", this) // - .label(0, STANDBY) // - .label(1, "Start Off-Grid") // - .label(2, START) // - .label(3, FAULT) // - .label(4, "Off-grid PV")), + .label(0, STANDBY) // + .label(1, "Start Off-Grid") // + .label(2, START) // + .label(3, FAULT) // + .label(4, "Off-grid PV")), new UnsignedWordElement(101, // controlMode = new ModbusReadLongChannel("ControlMode", this) // - .label(1, "Remote") // - .label(2, "Local")), // + .label(1, "Remote") // + .label(2, "Local")), // new DummyElement(102, 103), // new UnsignedDoublewordElement(104, // totalBatteryChargeEnergy = new ModbusReadLongChannel("TotalBatteryChargeEnergy", this) - .unit("Wh")), // + .unit("Wh")), // new UnsignedDoublewordElement(106, // totalBatteryDischargeEnergy = new ModbusReadLongChannel("TotalBatteryDischargeEnergy", this) - .unit("Wh")), // + .unit("Wh")), // new UnsignedWordElement(108, // batteryGroupState = new ModbusReadLongChannel("BatteryGroupState", this) // - .label(0, "Initial") // - .label(1, "Stop") // - .label(2, "Starting") // - .label(3, "Running") // - .label(4, "Stopping") // - .label(5, "Fail")), + .label(0, "Initial") // + .label(1, "Stop") // + .label(2, "Starting") // + .label(3, "Running") // + .label(4, "Stopping") // + .label(5, "Fail")), new UnsignedWordElement(109, // soc = new ModbusReadLongChannel("Soc", this).unit("%").interval(0, 100)), new UnsignedWordElement(110, // @@ -265,23 +264,23 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { batteryPower = new ModbusReadLongChannel("BatteryPower", this).unit("W")), new UnsignedWordElement(113, // batteryGroupAlarm = new ModbusReadLongChannel("BatteryGroupAlarm", this) - .label(1, "Fail, The system should be stopped") // - .label(2, "Common low voltage alarm") // - .label(4, "Common high voltage alarm") // - .label(8, "Charging over current alarm") // - .label(16, "Discharging over current alarm") // - .label(32, "Over temperature alarm")// - .label(64, "Interal communication abnormal")), + .label(1, "Fail, The system should be stopped") // + .label(2, "Common low voltage alarm") // + .label(4, "Common high voltage alarm") // + .label(8, "Charging over current alarm") // + .label(16, "Discharging over current alarm") // + .label(32, "Over temperature alarm")// + .label(64, "Interal communication abnormal")), new UnsignedWordElement(114, // pcsOperationState = new ModbusReadLongChannel("PcsOperationState", this) - .label(0, "Self-checking") // - .label(1, "Standby") // - .label(2, "Off grid PV") // - .label(3, "Off grid") // - .label(4, ON_GRID) // - .label(5, "Fail") // - .label(6, "bypass 1") // - .label(7, "bypass 2")), + .label(0, "Self-checking") // + .label(1, "Standby") // + .label(2, "Off grid PV") // + .label(3, "Off grid") // + .label(4, ON_GRID) // + .label(5, "Fail") // + .label(6, "bypass 1") // + .label(7, "bypass 2")), new DummyElement(115, 117), // new SignedWordElement(118, // current = new ModbusReadLongChannel("Current", this).unit("mA").multiplier(2)), @@ -312,63 +311,63 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { .label(256, "Combination error")// .label(512, "Comm with inverter error")// .label(1024, "Tme error")// - )), new UnsignedWordElement(151, pcsAlarm2 = warning.channel(new StatusBitChannel("PcsAlarm2", this)// - )), new UnsignedWordElement(152, warning.channel(pcsFault1 = new StatusBitChannel("PcsFault1", this)// - .label(1, "Control current overload 100%")// - .label(2, "Control current overload 110%")// - .label(4, "Control current overload 150%")// - .label(8, "Control current overload 200%")// - .label(16, "Control current overload 120%")// - .label(32, "Control current overload 300%")// - .label(64, "Control transient load 300%")// - .label(128, "Grid over current")// - .label(256, "Locking waveform too many times")// - .label(512, "Inverter voltage zero drift error")// - .label(1024, "Grid voltage zero drift error")// - .label(2048, "Control current zero drift error")// - .label(4096, "Inverter current zero drift error")// - .label(8192, "Grid current zero drift error")// - .label(16384, "PDP protection")// - .label(32768, "Hardware control current protection")// - )), new UnsignedWordElement(153, warning.channel(pcsFault2 = new StatusBitChannel("PcsFault2", this)// - .label(1, "Hardware AC volt. protection")// - .label(2, "Hardware DC curr. protection")// - .label(4, "Hardware temperature protection")// - .label(8, "No capturing signal")// - .label(16, "DC overvoltage")// - .label(32, "DC disconnected")// - .label(64, "Inverter undervoltage")// - .label(128, "Inverter overvoltage")// - .label(256, "Current sensor fail")// - .label(512, "Voltage sensor fail")// - .label(1024, "Power uncontrollable")// - .label(2048, "Current uncontrollable")// - .label(4096, "Fan error")// - .label(8192, "Phase lack")// - .label(16384, "Inverter relay fault")// - .label(32768, "Grid relay fault")// - )), new UnsignedWordElement(154, warning.channel(pcsFault3 = new StatusBitChannel("PcsFault3", this)// - .label(1, "Control panel overtemp")// - .label(2, "Power panel overtemp")// - .label(4, "DC input overcurrent")// - .label(8, "Capacitor overtemp")// - .label(16, "Radiator overtemp")// - .label(32, "Transformer overtemp")// - .label(64, "Combination comm error")// - .label(128, "EEPROM error")// - .label(256, "Load current zero drift error")// - .label(512, "Current limit-R error")// - .label(1024, "Phase sync error")// - .label(2048, "External PV current zero drift error")// - .label(4096, "External grid current zero drift error")// - ))), // + )), new UnsignedWordElement(151, pcsAlarm2 = warning.channel(new StatusBitChannel("PcsAlarm2", this)// + )), new UnsignedWordElement(152, warning.channel(pcsFault1 = new StatusBitChannel("PcsFault1", this)// + .label(1, "Control current overload 100%")// + .label(2, "Control current overload 110%")// + .label(4, "Control current overload 150%")// + .label(8, "Control current overload 200%")// + .label(16, "Control current overload 120%")// + .label(32, "Control current overload 300%")// + .label(64, "Control transient load 300%")// + .label(128, "Grid over current")// + .label(256, "Locking waveform too many times")// + .label(512, "Inverter voltage zero drift error")// + .label(1024, "Grid voltage zero drift error")// + .label(2048, "Control current zero drift error")// + .label(4096, "Inverter current zero drift error")// + .label(8192, "Grid current zero drift error")// + .label(16384, "PDP protection")// + .label(32768, "Hardware control current protection")// + )), new UnsignedWordElement(153, warning.channel(pcsFault2 = new StatusBitChannel("PcsFault2", this)// + .label(1, "Hardware AC volt. protection")// + .label(2, "Hardware DC curr. protection")// + .label(4, "Hardware temperature protection")// + .label(8, "No capturing signal")// + .label(16, "DC overvoltage")// + .label(32, "DC disconnected")// + .label(64, "Inverter undervoltage")// + .label(128, "Inverter overvoltage")// + .label(256, "Current sensor fail")// + .label(512, "Voltage sensor fail")// + .label(1024, "Power uncontrollable")// + .label(2048, "Current uncontrollable")// + .label(4096, "Fan error")// + .label(8192, "Phase lack")// + .label(16384, "Inverter relay fault")// + .label(32768, "Grid relay fault")// + )), new UnsignedWordElement(154, warning.channel(pcsFault3 = new StatusBitChannel("PcsFault3", this)// + .label(1, "Control panel overtemp")// + .label(2, "Power panel overtemp")// + .label(4, "DC input overcurrent")// + .label(8, "Capacitor overtemp")// + .label(16, "Radiator overtemp")// + .label(32, "Transformer overtemp")// + .label(64, "Combination comm error")// + .label(128, "EEPROM error")// + .label(256, "Load current zero drift error")// + .label(512, "Current limit-R error")// + .label(1024, "Phase sync error")// + .label(2048, "External PV current zero drift error")// + .label(4096, "External grid current zero drift error")// + ))), // new WriteableModbusRegisterRange(200, // new UnsignedWordElement(200, setWorkState = new ModbusWriteLongChannel("SetWorkState", this)// - .label(0, "Local control") // - .label(1, START) // "Remote control on grid starting" - .label(2, "Remote control off grid starting") // - .label(3, STOP)// - .label(4, "Emergency Stop"))), + .label(0, "Local control") // + .label(1, START) // "Remote control on grid starting" + .label(2, "Remote control off grid starting") // + .label(3, STOP)// + .label(4, "Emergency Stop"))), new WriteableModbusRegisterRange(201, // new SignedWordElement(201, setActivePower = new ModbusWriteLongChannel("SetActivePower", this).unit("W")), // @@ -384,28 +383,28 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { new WriteableModbusRegisterRange(30558, new UnsignedWordElement(30558, setSetupMode = new ModbusWriteLongChannel("SetSetupMode", this).label(0, EssNature.OFF) - .label(1, EssNature.ON))), + .label(1, EssNature.ON))), new WriteableModbusRegisterRange(30559, new UnsignedWordElement(30559, setPcsMode = new ModbusWriteLongChannel("SetPcsMode", this)// - .label(0, "Emergency")// - .label(1, "ConsumersPeakPattern")// - .label(2, "Economic")// - .label(3, "Eco")// - .label(4, "Debug")// - .label(5, "SmoothPv")// - .label(6, "Remote"))), + .label(0, "Emergency")// + .label(1, "ConsumersPeakPattern")// + .label(2, "Economic")// + .label(3, "Eco")// + .label(4, "Debug")// + .label(5, "SmoothPv")// + .label(6, "Remote"))), new ModbusRegisterRange(30157, new UnsignedWordElement(30157, setupMode = new ModbusReadLongChannel("SetupMode", this)// - .label(0, EssNature.OFF)// - .label(1, EssNature.ON)), + .label(0, EssNature.OFF)// + .label(1, EssNature.ON)), new UnsignedWordElement(30158, pcsMode = new ModbusReadLongChannel("PcsMode", this)// - .label(0, "Emergency")// - .label(1, "ConsumersPeakPattern")// - .label(2, "Economic")// - .label(3, "Eco")// - .label(4, "Debug")// - .label(5, "SmoothPv")// - .label(6, "Remote")))); + .label(0, "Emergency")// + .label(1, "ConsumersPeakPattern")// + .label(2, "Economic")// + .label(3, "Eco")// + .label(4, "Debug")// + .label(5, "SmoothPv")// + .label(6, "Remote")))); gridMode = new FunctionalReadChannel("GridMode", this, (channels) -> { ReadChannel state = channels[0]; try { @@ -447,4 +446,9 @@ public StaticValueChannel capacity() { return capacity; } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/device/minireadonly/FeneconMini.java b/edge/src/io/openems/impl/device/minireadonly/FeneconMini.java index 3f4f7b3965a..7caf8685bba 100644 --- a/edge/src/io/openems/impl/device/minireadonly/FeneconMini.java +++ b/edge/src/io/openems/impl/device/minireadonly/FeneconMini.java @@ -29,6 +29,7 @@ import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; import io.openems.api.exception.OpenemsException; +import io.openems.impl.device.mini.FeneconMiniEss; import io.openems.impl.protocol.modbus.ModbusDevice; @ThingInfo(title = "FENECON Mini") @@ -45,18 +46,18 @@ public FeneconMini(Bridge parent) throws OpenemsException { * Config */ @ChannelInfo(title = "Ess", description = "Sets the Ess nature.", type = FeneconMiniEss.class) - public final ConfigChannel ess = new ConfigChannel<>("ess", this); + public final ConfigChannel ess = new ConfigChannel("ess", this).addChangeListener(this); @ChannelInfo(title = "GridMeter", description = "Sets the GridMeter nature.", type = FeneconMiniGridMeter.class) - public final ConfigChannel gridMeter = new ConfigChannel<>("gridMeter", this); + public final ConfigChannel gridMeter = new ConfigChannel("gridMeter", this).addChangeListener(this); @ChannelInfo(title = "ProductionMeter", description = "Sets the ProductionMeter nature.", type = FeneconMiniProductionMeter.class) - public final ConfigChannel productionMeter = new ConfigChannel<>("productionMeter", - this); + public final ConfigChannel productionMeter = new ConfigChannel("productionMeter", + this).addChangeListener(this); @ChannelInfo(title = "ConsumptionMeter", description = "Sets the ConsumptionMeter nature.", type = FeneconMiniConsumptionMeter.class) - public final ConfigChannel consumptionMeter = new ConfigChannel<>("consumptionMeter", - this); + public final ConfigChannel consumptionMeter = new ConfigChannel("consumptionMeter", + this).addChangeListener(this); /* * Methods diff --git a/edge/src/io/openems/impl/device/minireadonly/FeneconMiniConsumptionMeter.java b/edge/src/io/openems/impl/device/minireadonly/FeneconMiniConsumptionMeter.java index f8abdcd134d..a8504e86b31 100644 --- a/edge/src/io/openems/impl/device/minireadonly/FeneconMiniConsumptionMeter.java +++ b/edge/src/io/openems/impl/device/minireadonly/FeneconMiniConsumptionMeter.java @@ -3,6 +3,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.SymmetricMeterNature; import io.openems.api.doc.ThingInfo; @@ -17,11 +18,14 @@ @ThingInfo(title = "FENECON Mini Consumption-Meter") public class FeneconMiniConsumptionMeter extends ModbusDeviceNature implements SymmetricMeterNature { + private ThingStateChannel thingState; + /* * Constructors */ public FeneconMiniConsumptionMeter(String thingId, Device parent) throws ConfigException { super(thingId, parent); + this.thingState = new ThingStateChannel(this); } /* @@ -96,8 +100,13 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { new ModbusRegisterRange(4005, // new UnsignedWordElement(4005, // this.activePower = new ModbusReadLongChannel("ActivePower", this).unit("W") - .ignore(55536l)))); + .ignore(55536l)))); return protocol; } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/device/minireadonly/FeneconMiniEss.java b/edge/src/io/openems/impl/device/minireadonly/FeneconMiniEss.java index f8f7cedecbc..5a22f4dbf41 100644 --- a/edge/src/io/openems/impl/device/minireadonly/FeneconMiniEss.java +++ b/edge/src/io/openems/impl/device/minireadonly/FeneconMiniEss.java @@ -25,6 +25,7 @@ import io.openems.api.channel.StaticValueChannel; import io.openems.api.channel.StatusBitChannels; import io.openems.api.channel.WriteChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.ess.AsymmetricEssNature; import io.openems.api.doc.ThingInfo; @@ -40,6 +41,8 @@ @ThingInfo(title = "FENECON Mini ESS") public class FeneconMiniEss extends ModbusDeviceNature implements AsymmetricEssNature { + private ThingStateChannel thingState; + /* * Constructors */ @@ -51,6 +54,7 @@ public FeneconMiniEss(String thingId, Device parent) throws ConfigException { chargeSoc.updateValue((Integer) newValue.get() - 2, false); } }); + this.thingState = new ThingStateChannel(this); } /* @@ -205,11 +209,6 @@ public ReadChannel maxNominalPower() { return null; } - @Override - public StatusBitChannels warning() { - return this.warning; - } - @Override public ReadChannel reactivePowerL1() { return this.reactivePowerL1; @@ -415,4 +414,9 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { this.soc = new ModbusReadLongChannel("Soc", this).unit("%")))); return protocol; } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } } diff --git a/edge/src/io/openems/impl/device/minireadonly/FeneconMiniGridMeter.java b/edge/src/io/openems/impl/device/minireadonly/FeneconMiniGridMeter.java index c123feefd99..085fac447b5 100644 --- a/edge/src/io/openems/impl/device/minireadonly/FeneconMiniGridMeter.java +++ b/edge/src/io/openems/impl/device/minireadonly/FeneconMiniGridMeter.java @@ -3,6 +3,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.SymmetricMeterNature; import io.openems.api.doc.ThingInfo; @@ -17,11 +18,14 @@ @ThingInfo(title = "FENECON Mini Grid-Meter") public class FeneconMiniGridMeter extends ModbusDeviceNature implements SymmetricMeterNature { + private ThingStateChannel thingState; + /* * Constructors */ public FeneconMiniGridMeter(String thingId, Device parent) throws ConfigException { super(thingId, parent); + this.thingState = new ThingStateChannel(this); } /* @@ -106,4 +110,9 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { return protocol; } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/device/minireadonly/FeneconMiniProductionMeter.java b/edge/src/io/openems/impl/device/minireadonly/FeneconMiniProductionMeter.java index 2bccf623868..5f0ef09ef1e 100644 --- a/edge/src/io/openems/impl/device/minireadonly/FeneconMiniProductionMeter.java +++ b/edge/src/io/openems/impl/device/minireadonly/FeneconMiniProductionMeter.java @@ -3,6 +3,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.SymmetricMeterNature; import io.openems.api.doc.ThingInfo; @@ -17,11 +18,14 @@ @ThingInfo(title = "FENECON Mini Production-Meter") public class FeneconMiniProductionMeter extends ModbusDeviceNature implements SymmetricMeterNature { + private ThingStateChannel thingState; + /* * Constructors */ public FeneconMiniProductionMeter(String thingId, Device parent) throws ConfigException { super(thingId, parent); + this.thingState = new ThingStateChannel(this); } /* @@ -99,4 +103,9 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { return protocol; } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/device/pqplus/PqPlusUMD97.java b/edge/src/io/openems/impl/device/pqplus/PqPlusUMD97.java index 8a1ae0c1be2..e902deacf8f 100644 --- a/edge/src/io/openems/impl/device/pqplus/PqPlusUMD97.java +++ b/edge/src/io/openems/impl/device/pqplus/PqPlusUMD97.java @@ -45,7 +45,7 @@ public PqPlusUMD97(Bridge parent) throws OpenemsException { * Config */ @ChannelInfo(title = "Meter", description = "Sets the meter nature.", type = PqPlusUMD97Meter.class) - public final ConfigChannel meter = new ConfigChannel<>("meter", this); + public final ConfigChannel meter = new ConfigChannel("meter", this).addChangeListener(this); /* * Methods diff --git a/edge/src/io/openems/impl/device/pqplus/PqPlusUMD97Meter.java b/edge/src/io/openems/impl/device/pqplus/PqPlusUMD97Meter.java index 3787574ab75..031655cad4e 100644 --- a/edge/src/io/openems/impl/device/pqplus/PqPlusUMD97Meter.java +++ b/edge/src/io/openems/impl/device/pqplus/PqPlusUMD97Meter.java @@ -22,6 +22,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.SymmetricMeterNature; import io.openems.api.doc.ThingInfo; @@ -36,11 +37,14 @@ @ThingInfo(title = "PQ Plus UMD 97 Meter") public class PqPlusUMD97Meter extends ModbusDeviceNature implements SymmetricMeterNature { + private ThingStateChannel thingState; + /* * Constructors */ public PqPlusUMD97Meter(String thingId, Device parent) throws ConfigException { super(thingId, parent); + this.thingState = new ThingStateChannel(this); } /* @@ -175,4 +179,9 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { .multiplier(3))); } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/device/pro/FaultEss.java b/edge/src/io/openems/impl/device/pro/FaultEss.java new file mode 100644 index 00000000000..91155a0b0cd --- /dev/null +++ b/edge/src/io/openems/impl/device/pro/FaultEss.java @@ -0,0 +1,21 @@ +package io.openems.impl.device.pro; + +import io.openems.api.channel.thingstate.FaultEnum; + +public enum FaultEss implements FaultEnum { + ControlCurrentOverload100PercentL1(0), ControlCurrentOverload110PercentL1(1), ControlCurrentOverload150PercentL1(2), ControlCurrentOverload200PercentL1(3), ControlCurrentOverload120PercentL1(4), ControlCurrentOverload300PercentL1(5), ControlTransientLoad300PercentL1(6), GridOverCurrentL1(7), LockingWaveformTooManyTimesL1(8), InverterVoltageZeroDriftErrorL1(9), GridVoltageZeroDriftErrorL1(10), ControlCurrentZeroDriftErrorL1(11), InverterCurrentZeroDriftErrorL1(12), GridCurrentZeroDriftErrorL1(13), PDPProtectionL1(14), HardwareControlCurrentProtectionL1(15), HardwareACVoltageProtectionL1(16), HardwareDCCurrentProtectionL1(17), HardwareTemperatureProtectionL1(18), NoCapturingSignalL1(19), DCOvervoltageL1(20), DCDisconnectedL1(21), InverterUndervoltageL1(22), InverterOvervoltageL1(23), CurrentSensorFailL1(24), VoltageSensorFailL1(25), PowerUncontrollableL1(26), CurrentUncontrollableL1(27), FanErrorL1(28), PhaseLackL1(29), InverterRelayFaultL1(30), GridRealyFaultL1(31), ControlPanelOvertempL1(32), PowerPanelOvertempL1(33), DCInputOvercurrentL1(34), CapacitorOvertempL1(35), RadiatorOvertempL1(36), TransformerOvertempL1(37), CombinationCommErrorL1(38), EEPROMErrorL1(39), LoadCurrentZeroDriftErrorL1(40), CurrentLimitRErrorL1(41), PhaseSyncErrorL1(42), ExternalPVCurrentZeroDriftErrorL1(43), ExternalGridCurrentZeroDriftErrorL1(44), + ControlCurrentOverload100PercentL2(45), ControlCurrentOverload110PercentL2(46), ControlCurrentOverload150PercentL2(47), ControlCurrentOverload200PercentL2(48), ControlCurrentOverload120PercentL2(49), ControlCurrentOverload300PercentL2(50), ControlTransientLoad300PercentL2(51), GridOverCurrentL2(52), LockingWaveformTooManyTimesL2(53), InverterVoltageZeroDriftErrorL2(54), GridVoltageZeroDriftErrorL2(55), ControlCurrentZeroDriftErrorL2(56), InverterCurrentZeroDriftErrorL2(57), GridCurrentZeroDriftErrorL2(58), PDPProtectionL2(59), HardwareControlCurrentProtectionL2(60), HardwareACVoltageProtectionL2(61), HardwareDCCurrentProtectionL2(62), HardwareTemperatureProtectionL2(63), NoCapturingSignalL2(64), DCOvervoltageL2(65), DCDisconnectedL2(66), InverterUndervoltageL2(67), InverterOvervoltageL2(68), CurrentSensorFailL2(69), VoltageSensorFailL2(70), PowerUncontrollableL2(71), CurrentUncontrollableL2(72), FanErrorL2(73), PhaseLackL2(74), InverterRelayFaultL2(75), GridRealyFaultL2(76), ControlPanelOvertempL2(77), PowerPanelOvertempL2(78), DCInputOvercurrentL2(79), CapacitorOvertempL2(80), RadiatorOvertempL2(81), TransformerOvertempL2(82), CombinationCommErrorL2(83), EEPROMErrorL2(84), LoadCurrentZeroDriftErrorL2(85), CurrentLimitRErrorL2(86), PhaseSyncErrorL2(87), ExternalPVCurrentZeroDriftErrorL2(88), ExternalGridCurrentZeroDriftErrorL2(89), + ControlCurrentOverload100PercentL3(90), ControlCurrentOverload110PercentL3(91), ControlCurrentOverload150PercentL3(92), ControlCurrentOverload200PercentL3(93), ControlCurrentOverload120PercentL3(94), ControlCurrentOverload300PercentL3(95), ControlTransientLoad300PercentL3(96), GridOverCurrentL3(97), LockingWaveformTooManyTimesL3(98), InverterVoltageZeroDriftErrorL3(99), GridVoltageZeroDriftErrorL3(100), ControlCurrentZeroDriftErrorL3(101), InverterCurrentZeroDriftErrorL3(102), GridCurrentZeroDriftErrorL3(103), PDPProtectionL3(104), HardwareControlCurrentProtectionL3(105), HardwareACVoltageProtectionL3(106), HardwareDCCurrentProtectionL3(107), HardwareTemperatureProtectionL3(108), NoCapturingSignalL3(109), DCOvervoltageL3(110), DCDisconnectedL3(111), InverterUndervoltageL3(112), InverterOvervoltageL3(113), CurrentSensorFailL3(114), VoltageSensorFailL3(115), PowerUncontrollableL3(116), CurrentUncontrollableL3(117), FanErrorL3(118), PhaseLackL3(119), InverterRelayFaultL3(120), GridRealyFaultL3(121), ControlPanelOvertempL3(122), PowerPanelOvertempL3(123), DCInputOvercurrentL3(124), CapacitorOvertempL3(125), RadiatorOvertempL3(126), TransformerOvertempL3(127), CombinationCommErrorL3(128), EEPROMErrorL3(129), LoadCurrentZeroDriftErrorL3(130), CurrentLimitRErrorL3(131), PhaseSyncErrorL3(132), ExternalPVCurrentZeroDriftErrorL3(133), ExternalGridCurrentZeroDriftErrorL3(134), + SystemFault(135), BatteryFault(136), PCSFault(137); + + private final int value; + + private FaultEss(int value) { + this.value = value; + } + + @Override + public int getValue() { + return this.value; + } +} diff --git a/edge/src/io/openems/impl/device/pro/FeneconPro.java b/edge/src/io/openems/impl/device/pro/FeneconPro.java index f09a77b32da..8b239fa2daa 100644 --- a/edge/src/io/openems/impl/device/pro/FeneconPro.java +++ b/edge/src/io/openems/impl/device/pro/FeneconPro.java @@ -45,10 +45,12 @@ public FeneconPro(Bridge parent) throws OpenemsException { * Config */ @ChannelInfo(title = "Ess", description = "Sets the Ess nature.", type = FeneconProEss.class) - public final ConfigChannel ess = new ConfigChannel<>("ess", this); + public final ConfigChannel ess = new ConfigChannel("ess", this) + .addChangeListener(this); @ChannelInfo(title = "Meter", description = "Sets the meter nature.", type = FeneconProPvMeter.class) - public final ConfigChannel meter = new ConfigChannel<>("meter", this); + public final ConfigChannel meter = new ConfigChannel("meter", this) + .addChangeListener(this); /* * Methods @@ -69,4 +71,5 @@ protected Set getDeviceNatures() { } return natures; } + } diff --git a/edge/src/io/openems/impl/device/pro/FeneconProEss.java b/edge/src/io/openems/impl/device/pro/FeneconProEss.java index 2770d34bf49..3baaee09c30 100644 --- a/edge/src/io/openems/impl/device/pro/FeneconProEss.java +++ b/edge/src/io/openems/impl/device/pro/FeneconProEss.java @@ -20,13 +20,16 @@ *******************************************************************************/ package io.openems.impl.device.pro; +import java.util.Locale; +import java.util.ResourceBundle; + import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.FunctionalReadChannel; import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; -import io.openems.api.channel.StatusBitChannel; -import io.openems.api.channel.StatusBitChannels; +import io.openems.api.channel.ValueToBooleanChannel; import io.openems.api.channel.WriteChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.ess.AsymmetricEssNature; import io.openems.api.device.nature.ess.EssNature; @@ -34,6 +37,7 @@ import io.openems.api.doc.ThingInfo; import io.openems.api.exception.ConfigException; import io.openems.api.exception.InvalidValueException; +import io.openems.impl.protocol.modbus.ModbusBitWrappingChannel; import io.openems.impl.protocol.modbus.ModbusDeviceNature; import io.openems.impl.protocol.modbus.ModbusReadLongChannel; import io.openems.impl.protocol.modbus.ModbusWriteLongChannel; @@ -59,6 +63,7 @@ public FeneconProEss(String thingId, Device parent) throws ConfigException { chargeSoc.updateValue((Integer) newValue.get() - 2, false); } }); + ResourceBundle.getBundle("Messages", Locale.GERMAN); } /* @@ -67,6 +72,8 @@ public FeneconProEss(String thingId, Device parent) throws ConfigException { private ConfigChannel minSoc = new ConfigChannel("minSoc", this); private ConfigChannel chargeSoc = new ConfigChannel("chargeSoc", this); + private ThingStateChannel state = new ThingStateChannel(this); + @Override public ConfigChannel minSoc() { return minSoc; @@ -81,7 +88,6 @@ public ConfigChannel chargeSoc() { * Inherited Channels */ // ESS - private StatusBitChannels warning; private ModbusReadLongChannel allowedCharge; private ModbusReadLongChannel allowedDischarge; private ReadChannel gridMode; @@ -187,11 +193,6 @@ public WriteChannel setReactivePowerL3() { return setReactivePowerL3; } - @Override - public StatusBitChannels warning() { - return warning; - } - @Override public ReadChannel allowedApparent() { return allowedApparent; @@ -257,7 +258,6 @@ public WriteChannel rtcSecond() { public ModbusReadLongChannel voltageL3; public ModbusReadLongChannel pcsOperationState; public ModbusReadLongChannel batteryPower; - public ModbusReadLongChannel batteryGroupAlarm; public ModbusReadLongChannel batteryCurrent; public ModbusReadLongChannel batteryVoltage; public ModbusReadLongChannel batteryVoltageSection1; @@ -301,29 +301,12 @@ public WriteChannel rtcSecond() { public ModbusWriteLongChannel setSetupMode; public ModbusReadLongChannel setupMode; public ModbusReadLongChannel pcsMode; - public StatusBitChannel pcsAlarm1L1; - public StatusBitChannel pcsAlarm2L1; - public StatusBitChannel pcsFault1L1; - public StatusBitChannel pcsFault2L1; - public StatusBitChannel pcsFault3L1; - public StatusBitChannel pcsAlarm1L2; - public StatusBitChannel pcsAlarm2L2; - public StatusBitChannel pcsFault1L2; - public StatusBitChannel pcsFault2L2; - public StatusBitChannel pcsFault3L2; - public StatusBitChannel pcsAlarm1L3; - public StatusBitChannel pcsAlarm2L3; - public StatusBitChannel pcsFault1L3; - public StatusBitChannel pcsFault2L3; - public StatusBitChannel pcsFault3L3; /* * Methods */ @Override protected ModbusProtocol defineModbusProtocol() throws ConfigException { - warning = new StatusBitChannels("Warning", this); - ModbusProtocol protokol = new ModbusProtocol(new ModbusRegisterRange(100, // new UnsignedWordElement(100, // systemState = new ModbusReadLongChannel("SystemState", this) // @@ -364,15 +347,14 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { batteryCurrent = new ModbusReadLongChannel("BatteryCurrent", this).unit("mA").multiplier(2)), new SignedWordElement(112, // batteryPower = new ModbusReadLongChannel("BatteryPower", this).unit("W")), - new UnsignedWordElement(113, // - batteryGroupAlarm = new ModbusReadLongChannel("BatteryGroupAlarm", this) - .label(1, "Fail, The system should be stopped") // - .label(2, "Common low voltage alarm") // - .label(4, "Common high voltage alarm") // - .label(8, "Charging over current alarm") // - .label(16, "Discharging over current alarm") // - .label(32, "Over temperature alarm")// - .label(64, "Interal communication abnormal")), + new UnsignedWordElement(113, new ModbusBitWrappingChannel("BatteryGroupAlarm", this, state)// + .warningBit(0, WarningEss.FailTheSystemShouldBeStopped) // Fail, The system should be stopped + .warningBit(1, WarningEss.CommonLowVoltageAlarm) // Common low voltage alarm + .warningBit(2, WarningEss.CommonHighVoltageAlarm) // Common high voltage alarm + .warningBit(3, WarningEss.ChargingOverCurrentAlarm) // Charging over current alarm + .warningBit(4, WarningEss.DischargingOverCurrentAlarm) // Discharging over current alarm + .warningBit(5, WarningEss.OverTemperatureAlarm) // Over temperature alarm + .warningBit(6, WarningEss.InteralCommunicationAbnormal)), // Interal communication abnormal new UnsignedWordElement(114, // pcsOperationState = new ModbusReadLongChannel("PcsOperationState", this) .label(0, "Self-checking") // @@ -421,216 +403,189 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { new UnsignedWordElement(142, // allowedDischarge = new ModbusReadLongChannel("AllowedDischarge", this).unit("W"))), new ModbusRegisterRange(150, - new UnsignedWordElement(150, - pcsAlarm1L1 = warning.channel(new StatusBitChannel("PcsAlarm1L1", this)// - .label(1, "Grid undervoltage") // - .label(2, "Grid overvoltage") // - .label(4, "Grid under frequency") // - .label(8, "Grid over frequency") // - .label(16, "Grid power supply off") // - .label(32, "Grid condition unmeet")// - .label(64, "DC under voltage")// - .label(128, "Input over resistance")// - .label(256, "Combination error")// - .label(512, "Comm with inverter error")// - .label(1024, "Tme error")// - )), new UnsignedWordElement(151, - pcsAlarm2L1 = warning.channel(new StatusBitChannel("PcsAlarm2L1", this)// - )), - new UnsignedWordElement(152, - warning.channel(pcsFault1L1 = new StatusBitChannel("PcsFault1L1", this)// - .label(1, "Control current overload 100%")// - .label(2, "Control current overload 110%")// - .label(4, "Control current overload 150%")// - .label(8, "Control current overload 200%")// - .label(16, "Control current overload 120%")// - .label(32, "Control current overload 300%")// - .label(64, "Control transient load 300%")// - .label(128, "Grid over current")// - .label(256, "Locking waveform too many times")// - .label(512, "Inverter voltage zero drift error")// - .label(1024, "Grid voltage zero drift error")// - .label(2048, "Control current zero drift error")// - .label(4096, "Inverter current zero drift error")// - .label(8192, "Grid current zero drift error")// - .label(16384, "PDP protection")// - .label(32768, "Hardware control current protection")// - )), - new UnsignedWordElement(153, - warning.channel(pcsFault2L1 = new StatusBitChannel("PcsFault2L1", this)// - .label(1, "Hardware AC volt. protection")// - .label(2, "Hardware DC curr. protection")// - .label(4, "Hardware temperature protection")// - .label(8, "No capturing signal")// - .label(16, "DC overvoltage")// - .label(32, "DC disconnected")// - .label(64, "Inverter undervoltage")// - .label(128, "Inverter overvoltage")// - .label(256, "Current sensor fail")// - .label(512, "Voltage sensor fail")// - .label(1024, "Power uncontrollable")// - .label(2048, "Current uncontrollable")// - .label(4096, "Fan error")// - .label(8192, "Phase lack")// - .label(16384, "Inverter relay fault")// - .label(32768, "Grid relay fault")// - )), - new UnsignedWordElement(154, - warning.channel(pcsFault3L1 = new StatusBitChannel("PcsFault3L1", this)// - .label(1, "Control panel overtemp")// - .label(2, "Power panel overtemp")// - .label(4, "DC input overcurrent")// - .label(8, "Capacitor overtemp")// - .label(16, "Radiator overtemp")// - .label(32, "Transformer overtemp")// - .label(64, "Combination comm error")// - .label(128, "EEPROM error")// - .label(256, "Load current zero drift error")// - .label(512, "Current limit-R error")// - .label(1024, "Phase sync error")// - .label(2048, "External PV current zero drift error")// - .label(4096, "External grid current zero drift error")// - )), - new UnsignedWordElement(155, - warning.channel(pcsAlarm1L2 = new StatusBitChannel("PcsAlarm1L2", this)// - .label(1, "Grid undervoltage") // - .label(2, "Grid overvoltage") // - .label(4, "Grid under frequency") // - .label(8, "Grid over frequency") // - .label(16, "Grid power supply off") // - .label(32, "Grid condition unmeet")// - .label(64, "DC under voltage")// - .label(128, "Input over resistance")// - .label(256, "Combination error")// - .label(512, "Comm with inverter error")// - .label(1024, "Tme error")// - )), new UnsignedWordElement(156, - warning.channel(pcsAlarm2L2 = new StatusBitChannel("PcsAlarm2L2", this)// - )), - new UnsignedWordElement(157, - warning.channel(pcsFault1L2 = new StatusBitChannel("PcsFault1L2", this)// - .label(1, "Control current overload 100%")// - .label(2, "Control current overload 110%")// - .label(4, "Control current overload 150%")// - .label(8, "Control current overload 200%")// - .label(16, "Control current overload 120%")// - .label(32, "Control current overload 300%")// - .label(64, "Control transient load 300%")// - .label(128, "Grid over current")// - .label(256, "Locking waveform too many times")// - .label(512, "Inverter voltage zero drift error")// - .label(1024, "Grid voltage zero drift error")// - .label(2048, "Control current zero drift error")// - .label(4096, "Inverter current zero drift error")// - .label(8192, "Grid current zero drift error")// - .label(16384, "PDP protection")// - .label(32768, "Hardware control current protection")// - )), - new UnsignedWordElement(158, - warning.channel(pcsFault2L2 = new StatusBitChannel("PcsFault2L2", this)// - .label(1, "Hardware AC volt. protection")// - .label(2, "Hardware DC curr. protection")// - .label(4, "Hardware temperature protection")// - .label(8, "No capturing signal")// - .label(16, "DC overvoltage")// - .label(32, "DC disconnected")// - .label(64, "Inverter undervoltage")// - .label(128, "Inverter overvoltage")// - .label(256, "Current sensor fail")// - .label(512, "Voltage sensor fail")// - .label(1024, "Power uncontrollable")// - .label(2048, "Current uncontrollable")// - .label(4096, "Fan error")// - .label(8192, "Phase lack")// - .label(16384, "Inverter relay fault")// - .label(32768, "Grid relay fault")// - )), - new UnsignedWordElement(159, - warning.channel(pcsFault3L2 = new StatusBitChannel("PcsFault3L2", this)// - .label(1, "Control panel overtemp")// - .label(2, "Power panel overtemp")// - .label(4, "DC input overcurrent")// - .label(8, "Capacitor overtemp")// - .label(16, "Radiator overtemp")// - .label(32, "Transformer overtemp")// - .label(64, "Combination comm error")// - .label(128, "EEPROM error")// - .label(256, "Load current zero drift error")// - .label(512, "Current limit-R error")// - .label(1024, "Phase sync error")// - .label(2048, "External PV current zero drift error")// - .label(4096, "External grid current zero drift error")// - )), - new UnsignedWordElement(160, - warning.channel(pcsAlarm1L3 = new StatusBitChannel("PcsAlarm1L3", this)// - .label(1, "Grid undervoltage") // - .label(2, "Grid overvoltage") // - .label(4, "Grid under frequency") // - .label(8, "Grid over frequency") // - .label(16, "Grid power supply off") // - .label(32, "Grid condition unmeet")// - .label(64, "DC under voltage")// - .label(128, "Input over resistance")// - .label(256, "Combination error")// - .label(512, "Comm with inverter error")// - .label(1024, "Tme error")// - )), new UnsignedWordElement(161, - warning.channel(pcsAlarm2L3 = new StatusBitChannel("PcsAlarm2L3", this)// - )), - new UnsignedWordElement(162, - warning.channel(pcsFault1L3 = new StatusBitChannel("PcsFault1L3", this)// - .label(1, "Control current overload 100%")// - .label(2, "Control current overload 110%")// - .label(4, "Control current overload 150%")// - .label(8, "Control current overload 200%")// - .label(16, "Control current overload 120%")// - .label(32, "Control current overload 300%")// - .label(64, "Control transient load 300%")// - .label(128, "Grid over current")// - .label(256, "Locking waveform too many times")// - .label(512, "Inverter voltage zero drift error")// - .label(1024, "Grid voltage zero drift error")// - .label(2048, "Control current zero drift error")// - .label(4096, "Inverter current zero drift error")// - .label(8192, "Grid current zero drift error")// - .label(16384, "PDP protection")// - .label(32768, "Hardware control current protection")// - )), - new UnsignedWordElement(163, - warning.channel(pcsFault2L3 = new StatusBitChannel("PcsFault2L3", this)// - .label(1, "Hardware AC volt. protection")// - .label(2, "Hardware DC curr. protection")// - .label(4, "Hardware temperature protection")// - .label(8, "No capturing signal")// - .label(16, "DC overvoltage")// - .label(32, "DC disconnected")// - .label(64, "Inverter undervoltage")// - .label(128, "Inverter overvoltage")// - .label(256, "Current sensor fail")// - .label(512, "Voltage sensor fail")// - .label(1024, "Power uncontrollable")// - .label(2048, "Current uncontrollable")// - .label(4096, "Fan error")// - .label(8192, "Phase lack")// - .label(16384, "Inverter relay fault")// - .label(32768, "Grid relay fault")// - )), - new UnsignedWordElement(164, - warning.channel(pcsFault3L3 = new StatusBitChannel("PcsFault3L3", this)// - .label(1, "Control panel overtemp")// - .label(2, "Power panel overtemp")// - .label(4, "DC input overcurrent")// - .label(8, "Capacitor overtemp")// - .label(16, "Radiator overtemp")// - .label(32, "Transformer overtemp")// - .label(64, "Combination comm error")// - .label(128, "EEPROM error")// - .label(256, "Load current zero drift error")// - .label(512, "Current limit-R error")// - .label(1024, "Phase sync error")// - .label(2048, "External PV current zero drift error")// - .label(4096, "External grid current zero drift error")// - ))), // + new UnsignedWordElement(150, new ModbusBitWrappingChannel("PcsAlarm1L1", this, state)// + .warningBit(0, WarningEss.GridUndervoltageL1) // Grid undervoltage + .warningBit(1, WarningEss.GridOvervoltageL1) // Grid overvoltage + .warningBit(2, WarningEss.GridUnderFrequencyL1) // Grid under frequency + .warningBit(3, WarningEss.GridOverFrequencyL1) // Grid over frequency + .warningBit(4, WarningEss.GridPowerSupplyOffL1) // Grid power supply off + .warningBit(5, WarningEss.GridConditionUnmeetL1) // Grid condition unmeet + .warningBit(6, WarningEss.DCUnderVoltageL1) // DC under voltage + .warningBit(7, WarningEss.InputOverResistanceL1) // Input over resistance + .warningBit(8, WarningEss.CombinationErrorL1) // Combination error + .warningBit(9, WarningEss.CommWithInverterErrorL1) // Comm with inverter error + .warningBit(10, WarningEss.TmeErrorL1)), // Tme error + new UnsignedWordElement(151, new ModbusBitWrappingChannel("PcsAlarm2L1", this, state)), + new UnsignedWordElement(152, new ModbusBitWrappingChannel("PcsFault1L1", this, state)// + .faultBit(0, FaultEss.ControlCurrentOverload100PercentL1) // Control current overload 100% + .faultBit(1, FaultEss.ControlCurrentOverload110PercentL1) // Control current overload 110% + .faultBit(2, FaultEss.ControlCurrentOverload150PercentL1) // Control current overload 150% + .faultBit(3, FaultEss.ControlCurrentOverload200PercentL1) // Control current overload 200% + .faultBit(4, FaultEss.ControlCurrentOverload120PercentL1) // Control current overload 120% + .faultBit(5, FaultEss.ControlCurrentOverload300PercentL1) // Control current overload 300% + .faultBit(6, FaultEss.ControlTransientLoad300PercentL1) // Control transient load 300% + .faultBit(7, FaultEss.GridOverCurrentL1) // Grid over current + .faultBit(8, FaultEss.LockingWaveformTooManyTimesL1) // Locking waveform too many times + .faultBit(9, FaultEss.InverterVoltageZeroDriftErrorL1) // Inverter voltage zero drift error + .faultBit(10, FaultEss.GridVoltageZeroDriftErrorL1) // Grid voltage zero drift error + .faultBit(11, FaultEss.ControlCurrentZeroDriftErrorL1) // Control current zero drift error + .faultBit(12, FaultEss.InverterCurrentZeroDriftErrorL1) // Inverter current zero drift error + .faultBit(13, FaultEss.GridCurrentZeroDriftErrorL1) // Grid current zero drift error + .faultBit(14, FaultEss.PDPProtectionL1) // PDP protection + .faultBit(15, FaultEss.HardwareControlCurrentProtectionL1)), // Hardware control current protection + new UnsignedWordElement(153, new ModbusBitWrappingChannel("PcsFault2L1", this, state)// + .faultBit(0, FaultEss.HardwareACVoltageProtectionL1) // Hardware AC volt. protection + .faultBit(1, FaultEss.HardwareDCCurrentProtectionL1) // Hardware DC curr. protection + .faultBit(2, FaultEss.HardwareTemperatureProtectionL1) // Hardware temperature protection + .faultBit(3, FaultEss.NoCapturingSignalL1) // No capturing signal + .faultBit(4, FaultEss.DCOvervoltageL1) // DC overvoltage + .faultBit(5, FaultEss.DCDisconnectedL1) // DC disconnected + .faultBit(6, FaultEss.InverterUndervoltageL1) // Inverter undervoltage + .faultBit(7, FaultEss.InverterOvervoltageL1) // Inverter overvoltage + .faultBit(8, FaultEss.CurrentSensorFailL1) // Current sensor fail + .faultBit(9, FaultEss.VoltageSensorFailL1) // Voltage sensor fail + .faultBit(10, FaultEss.PowerUncontrollableL1) // Power uncontrollable + .faultBit(11, FaultEss.CurrentUncontrollableL1) // Current uncontrollable + .faultBit(12, FaultEss.FanErrorL1) // Fan error + .faultBit(13, FaultEss.PhaseLackL1) // Phase lack + .faultBit(14, FaultEss.InverterRelayFaultL1) // Inverter relay fault + .faultBit(15, FaultEss.GridRealyFaultL1)), // Grid relay fault + new UnsignedWordElement(154, new ModbusBitWrappingChannel("PcsFault3L1", this, state)// + .faultBit(0, FaultEss.ControlPanelOvertempL1) // Control panel overtemp + .faultBit(1, FaultEss.PowerPanelOvertempL1) // Power panel overtemp + .faultBit(2, FaultEss.DCInputOvercurrentL1) // DC input overcurrent + .faultBit(3, FaultEss.CapacitorOvertempL1) // Capacitor overtemp + .faultBit(4, FaultEss.RadiatorOvertempL1) // Radiator overtemp + .faultBit(5, FaultEss.TransformerOvertempL1) // Transformer overtemp + .faultBit(6, FaultEss.CombinationCommErrorL1) // Combination comm error + .faultBit(7, FaultEss.EEPROMErrorL1) // EEPROM error + .faultBit(8, FaultEss.LoadCurrentZeroDriftErrorL1) // Load current zero drift error + .faultBit(9, FaultEss.CurrentLimitRErrorL1) // Current limit-R error + .faultBit(10, FaultEss.PhaseSyncErrorL1) // Phase sync error + .faultBit(11, FaultEss.ExternalPVCurrentZeroDriftErrorL1) // External PV current zero drift error + .faultBit(12, FaultEss.ExternalGridCurrentZeroDriftErrorL1)), // External grid current zero drift error + new UnsignedWordElement(155, new ModbusBitWrappingChannel("PcsAlarm1L2", this, state)// + .warningBit(0, WarningEss.GridUndervoltageL2) // Grid undervoltage + .warningBit(1, WarningEss.GridOvervoltageL2) // Grid overvoltage + .warningBit(2, WarningEss.GridUnderFrequencyL2) // Grid under frequency + .warningBit(3, WarningEss.GridOverFrequencyL2) // Grid over frequency + .warningBit(4, WarningEss.GridPowerSupplyOffL2) // Grid power supply off + .warningBit(5, WarningEss.GridConditionUnmeetL2) // Grid condition unmeet + .warningBit(6, WarningEss.DCUnderVoltageL2) // DC under voltage + .warningBit(7, WarningEss.InputOverResistanceL2) // Input over resistance + .warningBit(8, WarningEss.CombinationErrorL2) // Combination error + .warningBit(9, WarningEss.CommWithInverterErrorL2) // Comm with inverter error + .warningBit(10, WarningEss.TmeErrorL2)), // Tme error + new UnsignedWordElement(156, new ModbusBitWrappingChannel("PcsAlarm2L2", this, state)), + new UnsignedWordElement(157, new ModbusBitWrappingChannel("PcsFault1L2", this, state)// + .faultBit(0, FaultEss.ControlCurrentOverload100PercentL2) // Control current overload 100% + .faultBit(1, FaultEss.ControlCurrentOverload110PercentL2) // Control current overload 110% + .faultBit(2, FaultEss.ControlCurrentOverload150PercentL2) // Control current overload 150% + .faultBit(3, FaultEss.ControlCurrentOverload200PercentL2) // Control current overload 200% + .faultBit(4, FaultEss.ControlCurrentOverload120PercentL2) // Control current overload 120% + .faultBit(5, FaultEss.ControlCurrentOverload300PercentL2) // Control current overload 300% + .faultBit(6, FaultEss.ControlTransientLoad300PercentL2) // Control transient load 300% + .faultBit(7, FaultEss.GridOverCurrentL2) // Grid over current + .faultBit(8, FaultEss.LockingWaveformTooManyTimesL2) // Locking waveform too many times + .faultBit(9, FaultEss.InverterVoltageZeroDriftErrorL2) // Inverter voltage zero drift error + .faultBit(10, FaultEss.GridVoltageZeroDriftErrorL2) // Grid voltage zero drift error + .faultBit(11, FaultEss.ControlCurrentZeroDriftErrorL2) // Control current zero drift error + .faultBit(12, FaultEss.InverterCurrentZeroDriftErrorL2) // Inverter current zero drift error + .faultBit(13, FaultEss.GridCurrentZeroDriftErrorL2) // Grid current zero drift error + .faultBit(14, FaultEss.PDPProtectionL2) // PDP protection + .faultBit(15, FaultEss.HardwareControlCurrentProtectionL2)), // Hardware control current protection + new UnsignedWordElement(158, new ModbusBitWrappingChannel("PcsFault2L2", this, state)// + .faultBit(0, FaultEss.HardwareACVoltageProtectionL2) // Hardware AC volt. protection + .faultBit(1, FaultEss.HardwareDCCurrentProtectionL2) // Hardware DC curr. protection + .faultBit(2, FaultEss.HardwareTemperatureProtectionL2) // Hardware temperature protection + .faultBit(3, FaultEss.NoCapturingSignalL2) // No capturing signal + .faultBit(4, FaultEss.DCOvervoltageL2) // DC overvoltage + .faultBit(5, FaultEss.DCDisconnectedL2) // DC disconnected + .faultBit(6, FaultEss.InverterUndervoltageL2) // Inverter undervoltage + .faultBit(7, FaultEss.InverterOvervoltageL2) // Inverter overvoltage + .faultBit(8, FaultEss.CurrentSensorFailL2) // Current sensor fail + .faultBit(9, FaultEss.VoltageSensorFailL2) // Voltage sensor fail + .faultBit(10, FaultEss.PowerUncontrollableL2) // Power uncontrollable + .faultBit(11, FaultEss.CurrentUncontrollableL2) // Current uncontrollable + .faultBit(12, FaultEss.FanErrorL2) // Fan error + .faultBit(13, FaultEss.PhaseLackL2) // Phase lack + .faultBit(14, FaultEss.InverterRelayFaultL2) // Inverter relay fault + .faultBit(15, FaultEss.GridRealyFaultL2)), // Grid relay fault + new UnsignedWordElement(159, new ModbusBitWrappingChannel("PcsFault3L2", this, state)// + .faultBit(0, FaultEss.ControlPanelOvertempL2) // Control panel overtemp + .faultBit(1, FaultEss.PowerPanelOvertempL2) // Power panel overtemp + .faultBit(2, FaultEss.DCInputOvercurrentL2) // DC input overcurrent + .faultBit(3, FaultEss.CapacitorOvertempL2) // Capacitor overtemp + .faultBit(4, FaultEss.RadiatorOvertempL2) // Radiator overtemp + .faultBit(5, FaultEss.TransformerOvertempL2) // Transformer overtemp + .faultBit(6, FaultEss.CombinationCommErrorL2) // Combination comm error + .faultBit(7, FaultEss.EEPROMErrorL2) // EEPROM error + .faultBit(8, FaultEss.LoadCurrentZeroDriftErrorL2) // Load current zero drift error + .faultBit(9, FaultEss.CurrentLimitRErrorL2) // Current limit-R error + .faultBit(10, FaultEss.PhaseSyncErrorL2) // Phase sync error + .faultBit(11, FaultEss.ExternalPVCurrentZeroDriftErrorL2) // External PV current zero drift error + .faultBit(12, FaultEss.ExternalGridCurrentZeroDriftErrorL2)), // External grid current zero drift error + new UnsignedWordElement(160, new ModbusBitWrappingChannel("PcsAlarm1L3", this, state)// + .warningBit(0, WarningEss.GridUndervoltageL3) // Grid undervoltage + .warningBit(1, WarningEss.GridOvervoltageL3) // Grid overvoltage + .warningBit(2, WarningEss.GridUnderFrequencyL3) // Grid under frequency + .warningBit(3, WarningEss.GridOverFrequencyL3) // Grid over frequency + .warningBit(4, WarningEss.GridPowerSupplyOffL3) // Grid power supply off + .warningBit(5, WarningEss.GridConditionUnmeetL3) // Grid condition unmeet + .warningBit(6, WarningEss.DCUnderVoltageL3) // DC under voltage + .warningBit(7, WarningEss.InputOverResistanceL3) // Input over resistance + .warningBit(8, WarningEss.CombinationErrorL3) // Combination error + .warningBit(9, WarningEss.CommWithInverterErrorL3) // Comm with inverter error + .warningBit(10, WarningEss.TmeErrorL3)), // Tme error + new UnsignedWordElement(161, new ModbusBitWrappingChannel("PcsAlarm2L3", this, state)), + new UnsignedWordElement(162, new ModbusBitWrappingChannel("PcsFault1L3", this, state)// + .faultBit(0, FaultEss.ControlCurrentOverload100PercentL3) // Control current overload 100% + .faultBit(1, FaultEss.ControlCurrentOverload110PercentL3) // Control current overload 110% + .faultBit(2, FaultEss.ControlCurrentOverload150PercentL3) // Control current overload 150% + .faultBit(3, FaultEss.ControlCurrentOverload200PercentL3) // Control current overload 200% + .faultBit(4, FaultEss.ControlCurrentOverload120PercentL3) // Control current overload 120% + .faultBit(5, FaultEss.ControlCurrentOverload300PercentL3) // Control current overload 300% + .faultBit(6, FaultEss.ControlTransientLoad300PercentL3) // Control transient load 300% + .faultBit(7, FaultEss.GridOverCurrentL3) // Grid over current + .faultBit(8, FaultEss.LockingWaveformTooManyTimesL3) // Locking waveform too many times + .faultBit(9, FaultEss.InverterVoltageZeroDriftErrorL3) // Inverter voltage zero drift error + .faultBit(10, FaultEss.GridVoltageZeroDriftErrorL3) // Grid voltage zero drift error + .faultBit(11, FaultEss.ControlCurrentZeroDriftErrorL3) // Control current zero drift error + .faultBit(12, FaultEss.InverterCurrentZeroDriftErrorL3) // Inverter current zero drift error + .faultBit(13, FaultEss.GridCurrentZeroDriftErrorL3) // Grid current zero drift error + .faultBit(14, FaultEss.PDPProtectionL3) // PDP protection + .faultBit(15, FaultEss.HardwareControlCurrentProtectionL3)), // Hardware control current protection + new UnsignedWordElement(163, new ModbusBitWrappingChannel("PcsFault2L3", this, state)// + .faultBit(0, FaultEss.HardwareACVoltageProtectionL3) // Hardware AC volt. protection + .faultBit(1, FaultEss.HardwareDCCurrentProtectionL3) // Hardware DC curr. protection + .faultBit(2, FaultEss.HardwareTemperatureProtectionL3) // Hardware temperature protection + .faultBit(3, FaultEss.NoCapturingSignalL3) // No capturing signal + .faultBit(4, FaultEss.DCOvervoltageL3) // DC overvoltage + .faultBit(5, FaultEss.DCDisconnectedL3) // DC disconnected + .faultBit(6, FaultEss.InverterUndervoltageL3) // Inverter undervoltage + .faultBit(7, FaultEss.InverterOvervoltageL3) // Inverter overvoltage + .faultBit(8, FaultEss.CurrentSensorFailL3) // Current sensor fail + .faultBit(9, FaultEss.VoltageSensorFailL3) // Voltage sensor fail + .faultBit(10, FaultEss.PowerUncontrollableL3) // Power uncontrollable + .faultBit(11, FaultEss.CurrentUncontrollableL3) // Current uncontrollable + .faultBit(12, FaultEss.FanErrorL3) // Fan error + .faultBit(13, FaultEss.PhaseLackL3) // Phase lack + .faultBit(14, FaultEss.InverterRelayFaultL3) // Inverter relay fault + .faultBit(15, FaultEss.GridRealyFaultL3)), // Grid relay fault + new UnsignedWordElement(164, new ModbusBitWrappingChannel("PcsFault3L3", this, state)// + .faultBit(0, FaultEss.ControlPanelOvertempL3) // Control panel overtemp + .faultBit(1, FaultEss.PowerPanelOvertempL3) // Power panel overtemp + .faultBit(2, FaultEss.DCInputOvercurrentL3) // DC input overcurrent + .faultBit(3, FaultEss.CapacitorOvertempL3) // Capacitor overtemp + .faultBit(4, FaultEss.RadiatorOvertempL3) // Radiator overtemp + .faultBit(5, FaultEss.TransformerOvertempL3) // Transformer overtemp + .faultBit(6, FaultEss.CombinationCommErrorL3) // Combination comm error + .faultBit(7, FaultEss.EEPROMErrorL3) // EEPROM error + .faultBit(8, FaultEss.LoadCurrentZeroDriftErrorL3) // Load current zero drift error + .faultBit(9, FaultEss.CurrentLimitRErrorL3) // Current limit-R error + .faultBit(10, FaultEss.PhaseSyncErrorL3) // Phase sync error + .faultBit(11, FaultEss.ExternalPVCurrentZeroDriftErrorL3) // External PV current zero drift error + .faultBit(12, FaultEss.ExternalGridCurrentZeroDriftErrorL3))), // External grid current zero drift error new WriteableModbusRegisterRange(200, // new UnsignedWordElement(200, setWorkState = new ModbusWriteLongChannel("SetWorkState", this)// .label(0, "Local control") // @@ -804,6 +759,13 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { return 0l; }, phaseAllowedApparent); + // FaultChannels + state.addFaultChannel(new ValueToBooleanChannel(FaultEss.SystemFault.getChannelId(), this, systemState, 3L)); + state.addFaultChannel(new ValueToBooleanChannel(FaultEss.BatteryFault.getChannelId(), this, batteryGroupState, 5L)); + state.addFaultChannel(new ValueToBooleanChannel(FaultEss.PCSFault.getChannelId(), this, pcsOperationState, 5L)); + // WarningChannels + state.addWarningChannel(new ValueToBooleanChannel(WarningEss.OFFGrid.getChannelId(), this, systemState, 1L)); + return protokol; } @@ -817,4 +779,9 @@ public ReadChannel maxNominalPower() { return maxNominalPower; } + @Override + public ThingStateChannel getStateChannel() { + return state; + } + } diff --git a/edge/src/io/openems/impl/device/pro/FeneconProPvMeter.java b/edge/src/io/openems/impl/device/pro/FeneconProPvMeter.java index 8a23afe0c03..343d33cb9b3 100644 --- a/edge/src/io/openems/impl/device/pro/FeneconProPvMeter.java +++ b/edge/src/io/openems/impl/device/pro/FeneconProPvMeter.java @@ -23,6 +23,8 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.FunctionalReadChannel; import io.openems.api.channel.ReadChannel; +import io.openems.api.channel.StaticValueChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.AsymmetricMeterNature; import io.openems.api.device.nature.meter.SymmetricMeterNature; @@ -46,6 +48,13 @@ public class FeneconProPvMeter extends ModbusDeviceNature implements AsymmetricM */ public FeneconProPvMeter(String thingId, Device parent) throws ConfigException { super(thingId, parent); + this.thingState = new ThingStateChannel(this); + this.negativePowerL1 = new StaticValueChannel(WarningPvMeter.NegativePowerL1.getChannelId(), this, false); + this.thingState.addWarningChannel(this.negativePowerL1); + this.negativePowerL2 = new StaticValueChannel(WarningPvMeter.NegativePowerL2.getChannelId(), this, false); + this.thingState.addWarningChannel(this.negativePowerL2); + this.negativePowerL3 = new StaticValueChannel(WarningPvMeter.NegativePowerL3.getChannelId(), this, false); + this.thingState.addWarningChannel(this.negativePowerL3); } /* @@ -94,6 +103,10 @@ public ConfigChannel minActivePower() { private ModbusReadChannel orginalActivePowerL1; private ModbusReadChannel orginalActivePowerL2; private ModbusReadChannel orginalActivePowerL3; + private ThingStateChannel thingState; + private StaticValueChannel negativePowerL1; + private StaticValueChannel negativePowerL2; + private StaticValueChannel negativePowerL3; @Override public ReadChannel activePowerL1() { @@ -199,30 +212,32 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { new ModbusRegisterRange(2035, // new UnsignedDoublewordElement(2035, // activeEnergyL1 = new ModbusReadLongChannel("ActiveEnergyL1", this) - .unit("Wh").multiplier(2)), + .unit("Wh").multiplier(2)), new DummyElement(2037, 2065), new UnsignedWordElement(2066, // orginalActivePowerL1 = new ModbusReadLongChannel("OriginalActivePowerL1", this) - .unit("W").delta(10000L))), + .unit("W").delta(10000L))), new ModbusRegisterRange(2135, // new UnsignedDoublewordElement(2135, // activeEnergyL2 = new ModbusReadLongChannel("ActiveEnergyL2", this) - .unit("Wh").multiplier(2)), + .unit("Wh").multiplier(2)), new DummyElement(2137, 2165), new UnsignedWordElement(2166, // orginalActivePowerL2 = new ModbusReadLongChannel("OriginalActivePowerL2", this) - .unit("W").delta(10000L))), + .unit("W").delta(10000L))), new ModbusRegisterRange(2235, // new UnsignedDoublewordElement(2235, // activeEnergyL3 = new ModbusReadLongChannel("ActiveEnergyL3", this) - .unit("Wh").multiplier(2)), + .unit("Wh").multiplier(2)), new DummyElement(2237, 2265), new UnsignedWordElement(2266, // orginalActivePowerL3 = new ModbusReadLongChannel("OriginalActivePowerL3", this) - .unit("W").delta(10000L)))); + .unit("W").delta(10000L)))); activePowerL1 = new FunctionalReadChannel("ActivePowerL1", this, (channels) -> { ReadChannel power = channels[0]; try { if (power.value() >= 0) { + this.negativePowerL1.setValue(false); return power.value(); } else { + this.negativePowerL1.setValue(true); return 0L; } } catch (InvalidValueException e) { @@ -233,8 +248,10 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { ReadChannel power = channels[0]; try { if (power.value() >= 0) { + this.negativePowerL2.setValue(false); return power.value(); } else { + this.negativePowerL2.setValue(true); return 0L; } } catch (InvalidValueException e) { @@ -245,8 +262,10 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { ReadChannel power = channels[0]; try { if (power.value() >= 0) { + this.negativePowerL3.setValue(false); return power.value(); } else { + this.negativePowerL3.setValue(true); return 0L; } } catch (InvalidValueException e) { @@ -275,4 +294,9 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { }, reactivePowerL1, reactivePowerL2, reactivePowerL3); return protocol; } + + @Override + public ThingStateChannel getStateChannel() { + return thingState; + } } diff --git a/edge/src/io/openems/impl/device/pro/WarningEss.java b/edge/src/io/openems/impl/device/pro/WarningEss.java new file mode 100644 index 00000000000..91f67799b2a --- /dev/null +++ b/edge/src/io/openems/impl/device/pro/WarningEss.java @@ -0,0 +1,21 @@ +package io.openems.impl.device.pro; + +import io.openems.api.channel.thingstate.WarningEnum; + +public enum WarningEss implements WarningEnum { + FailTheSystemShouldBeStopped(0), CommonLowVoltageAlarm(1), CommonHighVoltageAlarm(2), ChargingOverCurrentAlarm( + 3), DischargingOverCurrentAlarm(4), OverTemperatureAlarm(5), InteralCommunicationAbnormal(6), GridUndervoltageL1(7), GridOvervoltageL1(8), GridUnderFrequencyL1(9), GridOverFrequencyL1(10), GridPowerSupplyOffL1(11), GridConditionUnmeetL1(12), DCUnderVoltageL1(13), InputOverResistanceL1(14), CombinationErrorL1(15), CommWithInverterErrorL1(16), TmeErrorL1(17), + GridUndervoltageL2(18), GridOvervoltageL2(19), GridUnderFrequencyL2(20), GridOverFrequencyL2(21), GridPowerSupplyOffL2(22), GridConditionUnmeetL2(23), DCUnderVoltageL2(24), InputOverResistanceL2(25), CombinationErrorL2(26), CommWithInverterErrorL2(27), TmeErrorL2(28), + GridUndervoltageL3(29), GridOvervoltageL3(30), GridUnderFrequencyL3(31), GridOverFrequencyL3(32), GridPowerSupplyOffL3(33), GridConditionUnmeetL3(34), DCUnderVoltageL3(35), InputOverResistanceL3(36), CombinationErrorL3(37), CommWithInverterErrorL3(38), TmeErrorL3(39), + OFFGrid(40); + public final int value; + + private WarningEss(int value) { + this.value = value; + } + + @Override + public int getValue() { + return this.value; + } +} diff --git a/edge/src/io/openems/impl/device/pro/WarningPvMeter.java b/edge/src/io/openems/impl/device/pro/WarningPvMeter.java new file mode 100644 index 00000000000..e9752e61bf0 --- /dev/null +++ b/edge/src/io/openems/impl/device/pro/WarningPvMeter.java @@ -0,0 +1,18 @@ +package io.openems.impl.device.pro; + +import io.openems.api.channel.thingstate.WarningEnum; + +public enum WarningPvMeter implements WarningEnum { + NegativePowerL1(0),NegativePowerL2(1),NegativePowerL3(2); + + public final int value; + + private WarningPvMeter(int value) { + this.value = value; + } + + @Override + public int getValue() { + return this.value; + } +} diff --git a/edge/src/io/openems/impl/device/refu/Refu.java b/edge/src/io/openems/impl/device/refu/Refu.java index e3929445abb..510eede1aa9 100644 --- a/edge/src/io/openems/impl/device/refu/Refu.java +++ b/edge/src/io/openems/impl/device/refu/Refu.java @@ -45,7 +45,7 @@ public Refu(Bridge parent) throws OpenemsException { * Config */ @ChannelInfo(title = "Ess", description = "Sets the Ess nature.", type = RefuEss.class) - public final ConfigChannel ess = new ConfigChannel<>("ess", this); + public final ConfigChannel ess = new ConfigChannel("ess", this).addChangeListener(this); /* * Methods diff --git a/edge/src/io/openems/impl/device/refu/RefuEss.java b/edge/src/io/openems/impl/device/refu/RefuEss.java index 7170ff20463..44c93ca2e57 100644 --- a/edge/src/io/openems/impl/device/refu/RefuEss.java +++ b/edge/src/io/openems/impl/device/refu/RefuEss.java @@ -26,6 +26,7 @@ import io.openems.api.channel.StatusBitChannel; import io.openems.api.channel.StatusBitChannels; import io.openems.api.channel.WriteChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.ess.AsymmetricEssNature; import io.openems.api.device.nature.ess.SymmetricEssNature; @@ -46,6 +47,8 @@ @ThingInfo(title = "REFU battery inverter ESS") public class RefuEss extends ModbusDeviceNature implements SymmetricEssNature, AsymmetricEssNature { + private ThingStateChannel thingState; + /* * Constructors */ @@ -57,6 +60,7 @@ public RefuEss(String thingId, Device parent) throws ConfigException { chargeSoc.updateValue((Integer) newValue.get() - 2, false); } }); + this.thingState = new ThingStateChannel(this); } /* @@ -100,7 +104,6 @@ public ConfigChannel chargeSoc() { private StaticValueChannel maxNominalPower = new StaticValueChannel<>("maxNominalPower", this, 100000L) .unit("VA").unit("VA"); private StaticValueChannel capacity = new StaticValueChannel<>("capacity", this, 130000L).unit("Wh"); - public StatusBitChannels warning; /* * This Channels @@ -215,11 +218,6 @@ public ReadChannel allowedApparent() { return allowedApparent; } - @Override - public StatusBitChannels warning() { - return warning; - } - @Override public WriteChannel setWorkState() { return setWorkState; @@ -257,17 +255,17 @@ public WriteChannel setReactivePower() { @Override protected ModbusProtocol defineModbusProtocol() throws ConfigException { - warning = new StatusBitChannels("Warning", this); + StatusBitChannels warning = new StatusBitChannels("warning", this); return new ModbusProtocol( // new ModbusInputRegisterRange(0x100, // new UnsignedWordElement(0x100, // systemState = new ModbusReadLongChannel("SystemState", this) // - .label(0, STOP) // - .label(1, "Init") // - .label(2, "Pre-operation") // - .label(3, STANDBY) // - .label(4, START) // - .label(5, FAULT)), + .label(0, STOP) // + .label(1, "Init") // + .label(2, "Pre-operation") // + .label(3, STANDBY) // + .label(4, START) // + .label(5, FAULT)), new UnsignedWordElement(0x101, systemError1 = warning.channel(new StatusBitChannel("SystemError1", this)// .label(1, "BMS In Error")// @@ -281,15 +279,15 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { .label(256, "Overcurrent warning")// .label(512, "BMS Ready")// .label(1024, "TREX Ready")// - )), + )), new UnsignedWordElement(0x102, communicationInformations = new StatusBitChannel("CommunicationInformations", this)// - .label(1, "Gateway Initialized")// - .label(2, "Modbus Slave Status")// - .label(4, "Modbus Master Status")// - .label(8, "CAN Timeout")// - .label(16, "First Communication Ok")// - ), new UnsignedWordElement(0x103, inverterStatus = new StatusBitChannel("InverterStatus", this)// + .label(1, "Gateway Initialized")// + .label(2, "Modbus Slave Status")// + .label(4, "Modbus Master Status")// + .label(8, "CAN Timeout")// + .label(16, "First Communication Ok")// + ), new UnsignedWordElement(0x103, inverterStatus = new StatusBitChannel("InverterStatus", this)// .label(1, "Ready to Power on")// .label(2, "Ready for Operating")// .label(4, "Enabled")// @@ -301,22 +299,22 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { .label(4096, "DC relays 1 close")// .label(8192, "DC relays 2 close")// .label(16384, "Mains OK")// - ), new UnsignedWordElement(0x104, errorCode = new ModbusReadLongChannel("ErrorCode", this)), + ), new UnsignedWordElement(0x104, errorCode = new ModbusReadLongChannel("ErrorCode", this)), new UnsignedWordElement(0x105, dcDcStatus = new StatusBitChannel("DCDCStatus", this)// - .label(1, "Ready to Power on")// - .label(2, "Ready for Operating")// - .label(4, "Enabled")// - .label(8, "DCDC Fault")// - .label(128, "DCDC Warning")// - .label(256, "Voltage/Current mode")// - .label(512, "Power mode")// - ), new UnsignedWordElement(0x106, dcDcError = new ModbusReadLongChannel("DCDCError", this)), + .label(1, "Ready to Power on")// + .label(2, "Ready for Operating")// + .label(4, "Enabled")// + .label(8, "DCDC Fault")// + .label(128, "DCDC Warning")// + .label(256, "Voltage/Current mode")// + .label(512, "Power mode")// + ), new UnsignedWordElement(0x106, dcDcError = new ModbusReadLongChannel("DCDCError", this)), new SignedWordElement(0x107, batteryCurrentPcs = new ModbusReadLongChannel("BatteryCurrentPcs", this).unit("mA") - .multiplier(2)), // + .multiplier(2)), // new SignedWordElement(0x108, batteryVoltagePcs = new ModbusReadLongChannel("BatteryVoltagePcs", this).unit("mV") - .multiplier(2)), // + .multiplier(2)), // new SignedWordElement(0x109, current = new ModbusReadLongChannel("Current", this).unit("mA").multiplier(2)), // new SignedWordElement(0x10A, @@ -329,25 +327,25 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { activePower = new ModbusReadLongChannel("ActivePower", this).unit("W").multiplier(2)), // new SignedWordElement(0x10E, activePowerL1 = new ModbusReadLongChannel("ActivePowerL1", this).unit("W") - .multiplier(2)), // + .multiplier(2)), // new SignedWordElement(0x10F, activePowerL2 = new ModbusReadLongChannel("ActivePowerL2", this).unit("W") - .multiplier(2)), // + .multiplier(2)), // new SignedWordElement(0x110, activePowerL3 = new ModbusReadLongChannel("ActivePowerL3", this).unit("W") - .multiplier(2)), // + .multiplier(2)), // new SignedWordElement(0x111, reactivePower = new ModbusReadLongChannel("ReactivePower", this).unit("Var") - .multiplier(2)), // + .multiplier(2)), // new SignedWordElement(0x112, reactivePowerL1 = new ModbusReadLongChannel("ReactivePowerL1", this).unit("Var") - .multiplier(2)), // + .multiplier(2)), // new SignedWordElement(0x113, reactivePowerL2 = new ModbusReadLongChannel("ReactivePowerL2", this).unit("Var") - .multiplier(2)), // + .multiplier(2)), // new SignedWordElement(0x114, reactivePowerL3 = new ModbusReadLongChannel("ReactivePowerL3", this).unit("Var") - .multiplier(2)), // + .multiplier(2)), // new SignedWordElement(0x115, cosPhi3p = new ModbusReadLongChannel("CosPhi3p", this).unit("")), // new SignedWordElement(0x116, cosPhiL1 = new ModbusReadLongChannel("CosPhiL1", this).unit("")), // new SignedWordElement(0x117, cosPhiL2 = new ModbusReadLongChannel("CosPhiL2", this).unit("")), // @@ -355,45 +353,45 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { new ModbusInputRegisterRange(0x11A, // new SignedWordElement(0x11A, pcsAllowedCharge = new ModbusReadLongChannel("PcsAllowedCharge", this).unit("kW") - .multiplier(2)), + .multiplier(2)), new SignedWordElement(0x11B, pcsAllowedDischarge = new ModbusReadLongChannel("PcsAllowedDischarge", this).unit("kW") - .multiplier(2)), + .multiplier(2)), new UnsignedWordElement(0x11C, // batteryState = new ModbusReadLongChannel("BatteryState", this)// - .label(0, "Initial")// - .label(1, STOP)// - .label(2, "Starting")// - .label(3, START)// - .label(4, "Stopping")// - .label(5, "Fault")), // + .label(0, "Initial")// + .label(1, STOP)// + .label(2, "Starting")// + .label(3, START)// + .label(4, "Stopping")// + .label(5, "Fault")), // new UnsignedWordElement(0x11D, // batteryMode = new ModbusReadLongChannel("BatteryMode", this).label(0, "Normal Mode")), new SignedWordElement(0x11E, batteryVoltage = new ModbusReadLongChannel("BatteryVoltage", this).unit("mV") - .multiplier(2)), + .multiplier(2)), new SignedWordElement(0x11F, batteryCurrent = new ModbusReadLongChannel("BatteryCurrent", this).unit("mA") - .multiplier(2)), + .multiplier(2)), new SignedWordElement(0x120, // batteryPower = new ModbusReadLongChannel("BatteryPower", this).unit("W")// - .multiplier(2)), + .multiplier(2)), new UnsignedWordElement(0x121, // soc = new ModbusReadLongChannel("Soc", this).unit("%")), new UnsignedWordElement(0x122, // allowedChargeCurrent = new ModbusReadLongChannel("AllowedChargeCurrent", this) - .unit("mA")// - .multiplier(2)// - .negate()), + .unit("mA")// + .multiplier(2)// + .negate()), new UnsignedWordElement(0x123, // allowedDischargeCurrent = new ModbusReadLongChannel("AllowedDischargeCurrent", this) - .unit("mA").multiplier(2)), + .unit("mA").multiplier(2)), new UnsignedWordElement(0x124, // allowedCharge = new ModbusReadLongChannel("AllowedCharge", this).unit("W").multiplier(2) - .negate()), + .negate()), new UnsignedWordElement(0x125, // allowedDischarge = new ModbusReadLongChannel("AllowedDischarge", this).unit("W") - .multiplier(2)), + .multiplier(2)), new SignedDoublewordElement(0x126, // batteryChargeEnergy = new ModbusReadLongChannel("BatteryChargeEnergy", this).unit("kWh")).wordorder(WordOrder.LSWMSW), @@ -402,22 +400,22 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { "BatteryDischargeEnergy", this).unit("kWh")).wordorder(WordOrder.LSWMSW), new UnsignedWordElement(0x12A, // batteryOperationStatus = new StatusBitChannel("BatteryOperationStatus", this) - .label(1, "Battery group 1 operating")// - .label(2, "Battery group 2 operating")// - .label(4, "Battery group 3 operating")// - .label(8, "Battery group 4 operating")), + .label(1, "Battery group 1 operating")// + .label(2, "Battery group 2 operating")// + .label(4, "Battery group 3 operating")// + .label(8, "Battery group 4 operating")), new UnsignedWordElement(0x12B, // batteryHighestVoltage = new ModbusReadLongChannel("BatteryHighestVoltage", this) - .unit("mV")), + .unit("mV")), new UnsignedWordElement(0x12C, // batteryLowestVoltage = new ModbusReadLongChannel("BatteryLowestVoltage", this) - .unit("mV")), + .unit("mV")), new SignedWordElement(0x12D, // batteryHighestTemperature = new ModbusReadLongChannel("BatteryHighestTemperature", this) - .unit("�C")), + .unit("�C")), new SignedWordElement(0x12E, // batteryLowestTemperature = new ModbusReadLongChannel("BatteryLowestTemperature", this) - .unit("�C")), + .unit("�C")), new UnsignedWordElement(0x12F, // batteryStopRequest = new ModbusReadLongChannel("BatteryStopRequest", this)), new UnsignedWordElement(0x130, @@ -513,9 +511,9 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { .label(8, "Pre-charge failure on battery control group 4"))), new UnsignedWordElement(0x13D, batteryFault7 = warning.channel(new StatusBitChannel("BatteryFault7", this)// - )), new UnsignedWordElement(0x13E, - batteryFault8 = warning.channel(new StatusBitChannel("BatteryFault8", this)// - )), + )), new UnsignedWordElement(0x13E, + batteryFault8 = warning.channel(new StatusBitChannel("BatteryFault8", this)// + )), new UnsignedWordElement(0x13F, batteryFault9 = warning.channel(new StatusBitChannel("BatteryFault9", this)// .label(4, "Sampling circuit abnormal for BMU")// @@ -542,90 +540,90 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { .label(16384, "BMU power contactor open"))), new UnsignedWordElement(0x141, batteryFault11 = warning.channel(new StatusBitChannel("BatteryFault11", this)// - )), new UnsignedWordElement(0x142, - batteryFault12 = warning.channel(new StatusBitChannel("BatteryFault12", this)// - )), + )), new UnsignedWordElement(0x142, + batteryFault12 = warning.channel(new StatusBitChannel("BatteryFault12", this)// + )), new UnsignedWordElement(0x143, batteryFault13 = warning.channel(new StatusBitChannel("BatteryFault13", this)// - )), new UnsignedWordElement(0x144, - batteryFault14 = warning.channel(new StatusBitChannel("BatteryFault14", this)// - )), new UnsignedWordElement(0x145, batteryGroupControlStatus = warning - .channel(new StatusBitChannel("BatteryGroupControlStatus", this)// - )), new UnsignedWordElement(0x146, - errorLog1 = warning.channel(new StatusBitChannel("ErrorLog1", this)// - )), new UnsignedWordElement(0x147, - errorLog2 = warning.channel(new StatusBitChannel("ErrorLog2", this)// - )), new UnsignedWordElement(0x148, - errorLog3 = warning.channel(new StatusBitChannel("ErrorLog3", this)// - )), + )), new UnsignedWordElement(0x144, + batteryFault14 = warning.channel(new StatusBitChannel("BatteryFault14", this)// + )), new UnsignedWordElement(0x145, batteryGroupControlStatus = warning + .channel(new StatusBitChannel("BatteryGroupControlStatus", this)// + )), new UnsignedWordElement(0x146, + errorLog1 = warning.channel(new StatusBitChannel("ErrorLog1", this)// + )), new UnsignedWordElement(0x147, + errorLog2 = warning.channel(new StatusBitChannel("ErrorLog2", this)// + )), new UnsignedWordElement(0x148, + errorLog3 = warning.channel(new StatusBitChannel("ErrorLog3", this)// + )), new UnsignedWordElement(0x149, errorLog4 = warning.channel(new StatusBitChannel("ErrorLog4", this)// - )), new UnsignedWordElement(0x14a, - errorLog5 = warning.channel(new StatusBitChannel("ErrorLog5", this)// - )), new UnsignedWordElement(0x14b, - errorLog6 = warning.channel(new StatusBitChannel("ErrorLog6", this)// - )), + )), new UnsignedWordElement(0x14a, + errorLog5 = warning.channel(new StatusBitChannel("ErrorLog5", this)// + )), new UnsignedWordElement(0x14b, + errorLog6 = warning.channel(new StatusBitChannel("ErrorLog6", this)// + )), new UnsignedWordElement(0x14c, errorLog7 = warning.channel(new StatusBitChannel("ErrorLog7", this)// - )), new UnsignedWordElement(0x14d, - errorLog8 = warning.channel(new StatusBitChannel("ErrorLog8", this)// - )), new UnsignedWordElement(0x14e, - errorLog9 = warning.channel(new StatusBitChannel("ErrorLog9", this)// - )), + )), new UnsignedWordElement(0x14d, + errorLog8 = warning.channel(new StatusBitChannel("ErrorLog8", this)// + )), new UnsignedWordElement(0x14e, + errorLog9 = warning.channel(new StatusBitChannel("ErrorLog9", this)// + )), new UnsignedWordElement(0x14f, errorLog10 = warning.channel(new StatusBitChannel("ErrorLog10", this)// - )), new UnsignedWordElement(0x150, - errorLog11 = warning.channel(new StatusBitChannel("ErrorLog11", this)// - )), new UnsignedWordElement(0x151, - errorLog12 = warning.channel(new StatusBitChannel("ErrorLog12", this)// - )), + )), new UnsignedWordElement(0x150, + errorLog11 = warning.channel(new StatusBitChannel("ErrorLog11", this)// + )), new UnsignedWordElement(0x151, + errorLog12 = warning.channel(new StatusBitChannel("ErrorLog12", this)// + )), new UnsignedWordElement(0x152, errorLog13 = warning.channel(new StatusBitChannel("ErrorLog13", this)// - )), new UnsignedWordElement(0x153, - errorLog14 = warning.channel(new StatusBitChannel("ErrorLog14", this)// - )), new UnsignedWordElement(0x154, - errorLog15 = warning.channel(new StatusBitChannel("ErrorLog15", this)// - )), + )), new UnsignedWordElement(0x153, + errorLog14 = warning.channel(new StatusBitChannel("ErrorLog14", this)// + )), new UnsignedWordElement(0x154, + errorLog15 = warning.channel(new StatusBitChannel("ErrorLog15", this)// + )), new UnsignedWordElement(0x155, errorLog16 = warning.channel(new StatusBitChannel("ErrorLog16", this)// - ))), new WriteableModbusRegisterRange(0x200, // - new UnsignedWordElement(0x200, // - setWorkState = new ModbusWriteLongChannel("SetWorkState", this) // + ))), new WriteableModbusRegisterRange(0x200, // + new UnsignedWordElement(0x200, // + setWorkState = new ModbusWriteLongChannel("SetWorkState", this) // .label(0, STOP) // .label(1, START)), - new UnsignedWordElement(0x201, // - setSystemErrorReset = new ModbusWriteLongChannel("SetSystemErrorReset", - this)// - .label(0, OFF)// - .label(1, ON)), - new UnsignedWordElement(0x202, // - setOperationMode = new ModbusWriteLongChannel("SetOperationMode", this)// + new UnsignedWordElement(0x201, // + setSystemErrorReset = new ModbusWriteLongChannel("SetSystemErrorReset", + this)// + .label(0, OFF)// + .label(1, ON)), + new UnsignedWordElement(0x202, // + setOperationMode = new ModbusWriteLongChannel("SetOperationMode", this)// .label(0, "P/Q Set point")// .label(1, "IAC / cosphi set point"))), new WriteableModbusRegisterRange(0x203, new SignedWordElement(0x203, // setActivePower = new ModbusWriteLongChannel("SetActivePower", this)// - .unit("W").multiplier(2))), + .unit("W").multiplier(2))), new WriteableModbusRegisterRange(0x204, new SignedWordElement(0x204, // setActivePowerL1 = new ModbusWriteLongChannel("SetActivePowerL1", this)// - .unit("W").multiplier(2)), + .unit("W").multiplier(2)), new SignedWordElement(0x205, // setActivePowerL2 = new ModbusWriteLongChannel("SetActivePowerL2", this)// - .unit("W").multiplier(2)), + .unit("W").multiplier(2)), new SignedWordElement(0x206, // setActivePowerL3 = new ModbusWriteLongChannel("SetActivePowerL3", this)// - .unit("W").multiplier(2))), + .unit("W").multiplier(2))), new WriteableModbusRegisterRange(0x207, new SignedWordElement(0x207, // setReactivePower = new ModbusWriteLongChannel("SetReactivePower", this)// - .unit("W").multiplier(2))), + .unit("W").multiplier(2))), new WriteableModbusRegisterRange(0x208, new SignedWordElement(0x208, // setReactivePowerL1 = new ModbusWriteLongChannel("SetReactivePowerL1", this)// - .unit("W").multiplier(2)), + .unit("W").multiplier(2)), new SignedWordElement(0x209, // setReactivePowerL2 = new ModbusWriteLongChannel("SetReactivePowerL2", this)// - .unit("W").multiplier(2)), + .unit("W").multiplier(2)), new SignedWordElement(0x20A, // setReactivePowerL3 = new ModbusWriteLongChannel("SetReactivePowerL3", this)// - .unit("W").multiplier(2)))); + .unit("W").multiplier(2)))); // new ModbusInputRegisterRange(0x6040, // new UnsignedWordElement(0x6040, // // batteryInformation1 = new ModbusReadLongChannel("BatteryInformation1", this)), @@ -738,4 +736,9 @@ public WriteChannel setReactivePowerL3() { return setReactivePowerL3; } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/device/simulator/Simulator.java b/edge/src/io/openems/impl/device/simulator/Simulator.java index 62087affcaf..0cf07affe22 100644 --- a/edge/src/io/openems/impl/device/simulator/Simulator.java +++ b/edge/src/io/openems/impl/device/simulator/Simulator.java @@ -45,24 +45,24 @@ public Simulator(Bridge parent) throws OpenemsException { * Config */ @ChannelInfo(title = "symmetric Ess", description = "Sets the symmetric Ess nature.", type = SimulatorSymmetricEss.class, isOptional = true) - public final ConfigChannel symmetricEss = new ConfigChannel<>("symmetricEss", this); + public final ConfigChannel symmetricEss = new ConfigChannel("symmetricEss", this).addChangeListener(this); @ChannelInfo(title = "asymmetric Ess", description = "Sets the asymmetric Ess nature.", type = SimulatorAsymmetricEss.class, isOptional = true) - public final ConfigChannel asymmetricEss = new ConfigChannel<>("asymmetricEss", this); + public final ConfigChannel asymmetricEss = new ConfigChannel("asymmetricEss", this).addChangeListener(this); @ChannelInfo(title = "Charger", description = "Sets the Charger nature.", type = SimulatorCharger.class, isOptional = true) - public final ConfigChannel charger = new ConfigChannel<>("charger", this); + public final ConfigChannel charger = new ConfigChannel("charger", this).addChangeListener(this); @ChannelInfo(title = "Grid-Meter", description = "Sets the grid meter nature.", type = SimulatorGridMeter.class, isOptional = true) - public final ConfigChannel gridMeter = new ConfigChannel<>("gridMeter", this); + public final ConfigChannel gridMeter = new ConfigChannel("gridMeter", this).addChangeListener(this); @ChannelInfo(title = "Production-Meter", description = "Sets the production meter nature.", type = SimulatorProductionMeter.class, isOptional = true) - public final ConfigChannel productionMeter = new ConfigChannel<>("productionMeter", this); + public final ConfigChannel productionMeter = new ConfigChannel("productionMeter", this).addChangeListener(this); @ChannelInfo(title = "Sps", description = "Sets the Riedmann sps nature.", type = SimulatorRiedmannNature.class, isOptional = true) - public final ConfigChannel sps = new ConfigChannel<>("sps", this); + public final ConfigChannel sps = new ConfigChannel("sps", this).addChangeListener(this); @ChannelInfo(title = "Output", description = "Sets the output nature.", type = SimulatorOutput.class, isOptional = true) - public final ConfigChannel output = new ConfigChannel<>("output", this); + public final ConfigChannel output = new ConfigChannel("output", this).addChangeListener(this); /* * Methods diff --git a/edge/src/io/openems/impl/device/simulator/SimulatorAsymmetricEss.java b/edge/src/io/openems/impl/device/simulator/SimulatorAsymmetricEss.java index 29d60705365..62dc40c1594 100644 --- a/edge/src/io/openems/impl/device/simulator/SimulatorAsymmetricEss.java +++ b/edge/src/io/openems/impl/device/simulator/SimulatorAsymmetricEss.java @@ -33,8 +33,8 @@ import io.openems.api.channel.FunctionalReadChannel; import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; -import io.openems.api.channel.StatusBitChannels; import io.openems.api.channel.WriteChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.charger.ChargerNature; import io.openems.api.device.nature.ess.AsymmetricEssNature; @@ -59,6 +59,7 @@ public class SimulatorAsymmetricEss extends SimulatorDeviceNature private ThingRepository repo = ThingRepository.getInstance(); private LoadGenerator offGridActivePowerGenerator = new RandomLoadGenerator(); private LoadGenerator offGridReactivePowerGenerator = new RandomLoadGenerator(); + private ThingStateChannel thingState; /* * Constructors @@ -71,6 +72,7 @@ public SimulatorAsymmetricEss(String thingId, Device parent) throws ConfigExcept chargeSoc.updateValue((Integer) newValue.get() - 2, false); } }); + this.thingState = new ThingStateChannel(this); long initialSoc = SimulatorTools.addRandomLong(90, 90, 100, 5); this.energy = capacity.valueOptional().get() / 100 * initialSoc; this.soc = new FunctionalReadChannel("Soc", this, (channels) -> { @@ -123,7 +125,6 @@ public ConfigChannel chargeSoc() { /* * Inherited Channels */ - private StatusBitChannels warning = new StatusBitChannels("Warning", this);; private FunctionalReadChannel soc; private SimulatorReadChannel activePowerL1 = new SimulatorReadChannel<>("ActivePowerL1", this); private SimulatorReadChannel activePowerL2 = new SimulatorReadChannel<>("ActivePowerL2", this); @@ -183,11 +184,6 @@ public WriteChannel setWorkState() { return setWorkState; } - @Override - public StatusBitChannels warning() { - return warning; - } - @Override public ReadChannel allowedApparent() { return allowedApparent; @@ -389,4 +385,9 @@ private void getCharger() { } } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/device/simulator/SimulatorCharger.java b/edge/src/io/openems/impl/device/simulator/SimulatorCharger.java index 2f625d6bc26..6eca025a4b4 100644 --- a/edge/src/io/openems/impl/device/simulator/SimulatorCharger.java +++ b/edge/src/io/openems/impl/device/simulator/SimulatorCharger.java @@ -24,6 +24,7 @@ import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; import io.openems.api.channel.WriteChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.charger.ChargerNature; import io.openems.api.doc.ChannelInfo; @@ -36,11 +37,14 @@ @ThingInfo(title = "Simulator Charger") public class SimulatorCharger extends SimulatorDeviceNature implements ChargerNature { + private ThingStateChannel thingState; + /* * Constructors */ public SimulatorCharger(String thingId, Device parent) throws ConfigException { super(thingId, parent); + this.thingState = new ThingStateChannel(this); } /* @@ -101,4 +105,9 @@ public ReadChannel getInputVoltage() { return voltage; } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/device/simulator/SimulatorGridMeter.java b/edge/src/io/openems/impl/device/simulator/SimulatorGridMeter.java index fbe0016e4a3..3094323ed69 100644 --- a/edge/src/io/openems/impl/device/simulator/SimulatorGridMeter.java +++ b/edge/src/io/openems/impl/device/simulator/SimulatorGridMeter.java @@ -15,6 +15,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.FunctionalReadChannel; import io.openems.api.channel.ReadChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.ess.AsymmetricEssNature; import io.openems.api.device.nature.ess.EssNature; @@ -59,9 +60,11 @@ public class SimulatorGridMeter extends SimulatorMeter implements ChannelChangeL private List meterNatures = new ArrayList<>(); private LoadGenerator activePowerLoad; private LoadGenerator reactivePowerLoad; + private ThingStateChannel thingState; public SimulatorGridMeter(String thingId, Device parent) throws ConfigException { super(thingId, parent); + this.thingState = new ThingStateChannel(this); repo.addThingChangedListener(new ThingsChangedListener() { @Override @@ -372,4 +375,9 @@ public ReadChannel voltageL3() { return null; } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } \ No newline at end of file diff --git a/edge/src/io/openems/impl/device/simulator/SimulatorOutput.java b/edge/src/io/openems/impl/device/simulator/SimulatorOutput.java index 1189b5c2cd8..829f4dc6a64 100644 --- a/edge/src/io/openems/impl/device/simulator/SimulatorOutput.java +++ b/edge/src/io/openems/impl/device/simulator/SimulatorOutput.java @@ -1,6 +1,7 @@ package io.openems.impl.device.simulator; import io.openems.api.channel.WriteChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.io.OutputNature; import io.openems.api.doc.ThingInfo; @@ -22,12 +23,14 @@ public class SimulatorOutput extends SimulatorDeviceNature implements OutputNatu private SimulatorWriteChannel do9 = new SimulatorWriteChannel<>("DO9", this, false); private SimulatorWriteChannel do10 = new SimulatorWriteChannel<>("DO10", this, false); private SimulatorWriteChannel[] array; + private ThingStateChannel thingState; public SimulatorOutput(String thingId, Device parent) throws ConfigException { super(thingId, parent); @SuppressWarnings("unchecked") SimulatorWriteChannel[] array = new SimulatorWriteChannel[] { do1, do2, do3, do4, do5, do6, do7, do8, do9, do10 }; this.array = array; + this.thingState = new ThingStateChannel(this); } @Override @@ -40,4 +43,9 @@ protected void update() { } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/device/simulator/SimulatorProductionMeter.java b/edge/src/io/openems/impl/device/simulator/SimulatorProductionMeter.java index 8a156b1bf63..e553f8a3dad 100644 --- a/edge/src/io/openems/impl/device/simulator/SimulatorProductionMeter.java +++ b/edge/src/io/openems/impl/device/simulator/SimulatorProductionMeter.java @@ -11,6 +11,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.FunctionalReadChannel; import io.openems.api.channel.ReadChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; @@ -36,6 +37,7 @@ public class SimulatorProductionMeter extends SimulatorMeter implements ChannelC private FunctionalReadChannel apparentPower; private LoadGenerator activePowerGenerator; private LoadGenerator reactivePowerGenerator; + private ThingStateChannel thingState; public SimulatorProductionMeter(String thingId, Device parent) throws ConfigException { super(thingId, parent); @@ -43,6 +45,7 @@ public SimulatorProductionMeter(String thingId, Device parent) throws ConfigExce return ControllerUtils.calculateApparentPower(channels[0].valueOptional().orElse(0L), channels[1].valueOptional().orElse(0L)); }, activePower, reactivePower); + this.thingState = new ThingStateChannel(this); } @Override @@ -125,4 +128,9 @@ private LoadGenerator getGenerator(JsonObject config) { return null; } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/device/simulator/SimulatorRiedmannNature.java b/edge/src/io/openems/impl/device/simulator/SimulatorRiedmannNature.java index 493b15de6d8..2162fa6c91c 100644 --- a/edge/src/io/openems/impl/device/simulator/SimulatorRiedmannNature.java +++ b/edge/src/io/openems/impl/device/simulator/SimulatorRiedmannNature.java @@ -27,6 +27,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; import io.openems.api.channel.WriteChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; @@ -40,11 +41,14 @@ @ThingInfo(title = "Simulator ESS") public class SimulatorRiedmannNature extends SimulatorDeviceNature implements RiedmannNature, ChannelChangeListener { + private ThingStateChannel thingState; + /* * Constructors */ public SimulatorRiedmannNature(String thingId, Device parent) throws ConfigException { super(thingId, parent); + this.thingState = new ThingStateChannel(this); } /* @@ -69,10 +73,10 @@ public SimulatorRiedmannNature(String thingId, Device parent) throws ConfigExcep private ConfigChannel emergencyStop = new ConfigChannel("EmergencyStop", this).defaultValue(0L); @ChannelInfo(title = "SwitchStatePivotPump", type = Long.class) private ConfigChannel switchStatePivotPump = new ConfigChannel("SwitchStatePivotPump", this) - .defaultValue(1L); + .defaultValue(1L); @ChannelInfo(title = "SwitchStatePivotDrive", type = Long.class) private ConfigChannel switchStatePivotDrive = new ConfigChannel("SwitchStatePivotDrive", this) - .defaultValue(1L); + .defaultValue(1L); @ChannelInfo(title = "Error", type = Long.class) private ConfigChannel error = new ConfigChannel("Error", this).defaultValue(0L); private SimulatorReadChannel waterLevelBorehole1On = new SimulatorReadChannel("WaterLevelBorehole1On", @@ -337,4 +341,9 @@ protected void update() { } } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/device/simulator/SimulatorSymmetricEss.java b/edge/src/io/openems/impl/device/simulator/SimulatorSymmetricEss.java index 6bfc603b6b4..feeb35452b7 100644 --- a/edge/src/io/openems/impl/device/simulator/SimulatorSymmetricEss.java +++ b/edge/src/io/openems/impl/device/simulator/SimulatorSymmetricEss.java @@ -36,8 +36,8 @@ import io.openems.api.channel.FunctionalReadChannel; import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; -import io.openems.api.channel.StatusBitChannels; import io.openems.api.channel.WriteChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.charger.ChargerNature; import io.openems.api.device.nature.ess.EssNature; @@ -71,12 +71,14 @@ public class SimulatorSymmetricEss extends SimulatorDeviceNature implements Symm "reactivePowerGeneratorConfig", this).addChangeListener(this).addChangeListener(this); private LoadGenerator offGridActivePowerGenerator; private LoadGenerator offGridReactivePowerGenerator; + private ThingStateChannel thingState; /* * Constructors */ public SimulatorSymmetricEss(String thingId, Device parent) throws ConfigException { super(thingId, parent); + this.thingState = new ThingStateChannel(this); minSoc.addUpdateListener((channel, newValue) -> { // If chargeSoc was not set -> set it to minSoc minus 2 if (channel == minSoc && !chargeSoc.valueOptional().isPresent()) { @@ -120,10 +122,10 @@ public SimulatorSymmetricEss(String thingId, Device parent) throws ConfigExcepti private ConfigChannel chargeSoc = new ConfigChannel("chargeSoc", this); @ChannelInfo(title = "GridMode", type = Long.class) public ConfigChannel gridMode = new ConfigChannel("gridMode", this).label(0L, ON_GRID) - .label(1L, OFF_GRID).defaultValue(0L); + .label(1L, OFF_GRID).defaultValue(0L); @ChannelInfo(title = "SystemState", type = Long.class) public ConfigChannel systemState = new ConfigChannel("systemState", this) // - .label(1L, START).label(2L, STOP).label(5L, FAULT).defaultValue(1L); + .label(1L, START).label(2L, STOP).label(5L, FAULT).defaultValue(1L); @Override public ConfigChannel minSoc() { @@ -138,7 +140,6 @@ public ConfigChannel chargeSoc() { /* * Inherited Channels */ - private StatusBitChannels warning = new StatusBitChannels("Warning", this);; private FunctionalReadChannel soc; private SimulatorReadChannel activePower = new SimulatorReadChannel("ActivePower", this); private StaticValueChannel allowedApparent = new StaticValueChannel("AllowedApparent", this, 40000L); @@ -212,11 +213,6 @@ public WriteChannel setReactivePower() { return setReactivePower; } - @Override - public StatusBitChannels warning() { - return warning; - } - @Override public ReadChannel allowedApparent() { return allowedApparent; @@ -346,4 +342,9 @@ private void getCharger() { } } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/device/sma/SunnyIsland6.java b/edge/src/io/openems/impl/device/sma/SunnyIsland6.java index b053e3641cf..11acedeb328 100644 --- a/edge/src/io/openems/impl/device/sma/SunnyIsland6.java +++ b/edge/src/io/openems/impl/device/sma/SunnyIsland6.java @@ -22,7 +22,7 @@ public SunnyIsland6(Bridge parent) throws OpenemsException { * Config */ @ChannelInfo(title = "Ess", description = "Sets the Ess nature.", type = SunnyIsland6Ess.class) - public final ConfigChannel ess = new ConfigChannel<>("ess", this); + public final ConfigChannel ess = new ConfigChannel("ess", this).addChangeListener(this); /* * Methods diff --git a/edge/src/io/openems/impl/device/sma/SunnyIsland6Ess.java b/edge/src/io/openems/impl/device/sma/SunnyIsland6Ess.java index 65ffca682df..857908e92df 100644 --- a/edge/src/io/openems/impl/device/sma/SunnyIsland6Ess.java +++ b/edge/src/io/openems/impl/device/sma/SunnyIsland6Ess.java @@ -3,8 +3,8 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; -import io.openems.api.channel.StatusBitChannels; import io.openems.api.channel.WriteChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.ess.SymmetricEssNature; import io.openems.api.doc.ChannelInfo; @@ -23,8 +23,11 @@ @ThingInfo(title = "SMA SunnyIsland 6.0H") public class SunnyIsland6Ess extends ModbusDeviceNature implements SymmetricEssNature { + private ThingStateChannel thingState; + public SunnyIsland6Ess(String thingId, Device parent) throws ConfigException { super(thingId, parent); + this.thingState = new ThingStateChannel(this); } /* @@ -44,7 +47,6 @@ public ConfigChannel chargeSoc() { return chargeSoc; } - private StatusBitChannels warning; private ModbusReadLongChannel allowedCharge; private ModbusReadLongChannel allowedDischarge; private ReadChannel gridMode = new StaticValueChannel("GridMode", this, 1L).label(1L, ON_GRID); @@ -113,11 +115,6 @@ public ReadChannel maxNominalPower() { return nominalPower; } - @Override - public StatusBitChannels warning() { - return warning; - } - @Override public WriteChannel setWorkState() { return setControlMode; @@ -150,7 +147,6 @@ public WriteChannel setReactivePower() { @Override protected ModbusProtocol defineModbusProtocol() throws ConfigException { - warning = new StatusBitChannels("Warning", this); ModbusProtocol protokol = new ModbusProtocol( new ModbusRegisterRange(30201, @@ -202,4 +198,9 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { return protokol; } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/device/socomec/Socomec.java b/edge/src/io/openems/impl/device/socomec/Socomec.java index 88a5176ea3b..fa174b9dd3b 100644 --- a/edge/src/io/openems/impl/device/socomec/Socomec.java +++ b/edge/src/io/openems/impl/device/socomec/Socomec.java @@ -45,7 +45,7 @@ public Socomec(Bridge parent) throws OpenemsException { * Config */ @ChannelInfo(title = "Meter", description = "Sets the meter nature.", type = SocomecMeter.class) - public final ConfigChannel meter = new ConfigChannel<>("meter", this); + public final ConfigChannel meter = new ConfigChannel("meter", this).addChangeListener(this); /* * Methods diff --git a/edge/src/io/openems/impl/device/socomec/SocomecB30.java b/edge/src/io/openems/impl/device/socomec/SocomecB30.java index 3b79906bf77..7b2d8a09f80 100644 --- a/edge/src/io/openems/impl/device/socomec/SocomecB30.java +++ b/edge/src/io/openems/impl/device/socomec/SocomecB30.java @@ -45,7 +45,7 @@ public SocomecB30(Bridge parent) throws OpenemsException { * Config */ @ChannelInfo(title = "Meter", description = "Sets the meter nature.", type = SocomecB30Meter.class) - public final ConfigChannel meter = new ConfigChannel<>("meter", this); + public final ConfigChannel meter = new ConfigChannel("meter", this).addChangeListener(this); /* * Methods diff --git a/edge/src/io/openems/impl/device/socomec/SocomecB30Meter.java b/edge/src/io/openems/impl/device/socomec/SocomecB30Meter.java index 20d045c15ce..a9a98d7f20a 100644 --- a/edge/src/io/openems/impl/device/socomec/SocomecB30Meter.java +++ b/edge/src/io/openems/impl/device/socomec/SocomecB30Meter.java @@ -22,6 +22,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.AsymmetricMeterNature; import io.openems.api.device.nature.meter.SymmetricMeterNature; @@ -38,11 +39,14 @@ @ThingInfo(title = "Socomec B30 Meter") public class SocomecB30Meter extends ModbusDeviceNature implements SymmetricMeterNature, AsymmetricMeterNature { + private ThingStateChannel thingState; + /* * Constructors */ public SocomecB30Meter(String thingId, Device parent) throws ConfigException { super(thingId, parent); + this.thingState = new ThingStateChannel(this); } /* @@ -235,10 +239,15 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { this).unit("kvarh")), new DummyElement(0x4D8B), new UnsignedDoublewordElement(0x4D8C, // reactiveNegativeEnergy = new ModbusReadLongChannel("ReactiveNegativeEnergy", this) - .unit("kvarh")), + .unit("kvarh")), new DummyElement(0x4D8E), new UnsignedDoublewordElement(0x4D8F, // apparentEnergy = new ModbusReadLongChannel("ApparentEnergy", this).unit("kVAh"))) - ); + ); + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; } } diff --git a/edge/src/io/openems/impl/device/socomec/SocomecMeter.java b/edge/src/io/openems/impl/device/socomec/SocomecMeter.java index 8bb51421f6b..2ed69081b4f 100644 --- a/edge/src/io/openems/impl/device/socomec/SocomecMeter.java +++ b/edge/src/io/openems/impl/device/socomec/SocomecMeter.java @@ -22,6 +22,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.AsymmetricMeterNature; import io.openems.api.device.nature.meter.SymmetricMeterNature; @@ -38,11 +39,14 @@ @ThingInfo(title = "Socomec Meter") public class SocomecMeter extends ModbusDeviceNature implements SymmetricMeterNature, AsymmetricMeterNature { + private ThingStateChannel thingState; + /* * Constructors */ public SocomecMeter(String thingId, Device parent) throws ConfigException { super(thingId, parent); + this.thingState = new ThingStateChannel(this); } /* @@ -212,28 +216,28 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { activePower = new ModbusReadLongChannel("ActivePower", this).unit("W").multiplier(1)), new SignedDoublewordElement(0xc56A, // reactivePower = new ModbusReadLongChannel("ReactivePower", this).unit("var") - .multiplier(1)), + .multiplier(1)), new SignedDoublewordElement(0xc56C, // apparentPower = new ModbusReadLongChannel("ApparentPower", this).unit("VA") - .multiplier(1)), + .multiplier(1)), new DummyElement(0xc56E, 0xc56F), new SignedDoublewordElement(0xc570, // activePowerL1 = new ModbusReadLongChannel("ActivePowerL1", this).unit("W") - .multiplier(1)), + .multiplier(1)), new SignedDoublewordElement(0xc572, // activePowerL2 = new ModbusReadLongChannel("ActivePowerL2", this).unit("W") - .multiplier(1)), + .multiplier(1)), new SignedDoublewordElement(0xc574, // activePowerL3 = new ModbusReadLongChannel("ActivePowerL3", this).unit("W") - .multiplier(1)), + .multiplier(1)), new SignedDoublewordElement(0xc576, // reactivePowerL1 = new ModbusReadLongChannel("ReactivePowerL1", this).unit("var") - .multiplier(1)), + .multiplier(1)), new SignedDoublewordElement(0xc578, // reactivePowerL2 = new ModbusReadLongChannel("ReactivePowerL2", this).unit("var") - .multiplier(1)), + .multiplier(1)), new SignedDoublewordElement(0xc57A, // reactivePowerL3 = new ModbusReadLongChannel("ReactivePowerL3", this).unit("var") - .multiplier(1))), + .multiplier(1))), new ModbusRegisterRange(0xc652, // new UnsignedDoublewordElement(0xc652, // activePositiveEnergy = new ModbusReadLongChannel( @@ -248,6 +252,11 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { "ActiveNegativeEnergy", this).unit("kWh")), new UnsignedDoublewordElement(0xc65a, // reactiveNegativeEnergy = new ModbusReadLongChannel("ReactiveNegativeEnergy", this) - .unit("kvarh")))); + .unit("kvarh")))); + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; } } diff --git a/edge/src/io/openems/impl/device/socomec/SocomecSinglePhase.java b/edge/src/io/openems/impl/device/socomec/SocomecSinglePhase.java index c04b9d9ef54..e0d11d28283 100644 --- a/edge/src/io/openems/impl/device/socomec/SocomecSinglePhase.java +++ b/edge/src/io/openems/impl/device/socomec/SocomecSinglePhase.java @@ -45,7 +45,7 @@ public SocomecSinglePhase(Bridge parent) throws OpenemsException { * Config */ @ChannelInfo(title = "Meter", description = "Sets the meter nature.", type = SocomecSinglePhaseMeter.class) - public final ConfigChannel meter = new ConfigChannel<>("meter", this); + public final ConfigChannel meter = new ConfigChannel("meter", this).addChangeListener(this); /* * Methods diff --git a/edge/src/io/openems/impl/device/socomec/SocomecSinglePhaseMeter.java b/edge/src/io/openems/impl/device/socomec/SocomecSinglePhaseMeter.java index 5c7c879cc38..8de65f78f74 100644 --- a/edge/src/io/openems/impl/device/socomec/SocomecSinglePhaseMeter.java +++ b/edge/src/io/openems/impl/device/socomec/SocomecSinglePhaseMeter.java @@ -22,6 +22,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.SymmetricMeterNature; import io.openems.api.doc.ThingInfo; @@ -37,11 +38,14 @@ @ThingInfo(title = "Socomec Single Phase Meter") public class SocomecSinglePhaseMeter extends ModbusDeviceNature implements SymmetricMeterNature { + private ThingStateChannel thingState; + /* * Constructors */ public SocomecSinglePhaseMeter(String thingId, Device parent) throws ConfigException { super(thingId, parent); + this.thingState = new ThingStateChannel(this); } /* @@ -151,4 +155,9 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { public ReadChannel voltage() { return this.voltageL1; } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } } diff --git a/edge/src/io/openems/impl/device/spanner/BHKW.java b/edge/src/io/openems/impl/device/spanner/BHKW.java index a5573116272..822f1c38e63 100644 --- a/edge/src/io/openems/impl/device/spanner/BHKW.java +++ b/edge/src/io/openems/impl/device/spanner/BHKW.java @@ -45,7 +45,7 @@ public BHKW(Bridge parent) throws OpenemsException { * Config */ @ChannelInfo(title = "Meter", description = "Sets the meter nature.", type = BHKWMeter.class) - public final ConfigChannel meter = new ConfigChannel<>("meter", this); + public final ConfigChannel meter = new ConfigChannel("meter", this).addChangeListener(this); /* * Methods diff --git a/edge/src/io/openems/impl/device/spanner/BHKWMeter.java b/edge/src/io/openems/impl/device/spanner/BHKWMeter.java index b262692ef76..7b733ca8eae 100644 --- a/edge/src/io/openems/impl/device/spanner/BHKWMeter.java +++ b/edge/src/io/openems/impl/device/spanner/BHKWMeter.java @@ -24,6 +24,7 @@ import io.openems.api.channel.FunctionalReadChannel; import io.openems.api.channel.FunctionalReadChannelFunction; import io.openems.api.channel.ReadChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.AsymmetricMeterNature; import io.openems.api.device.nature.meter.SymmetricMeterNature; @@ -41,11 +42,14 @@ @ThingInfo(title = "BHKW Meter") public class BHKWMeter extends ModbusDeviceNature implements AsymmetricMeterNature, SymmetricMeterNature { + private ThingStateChannel thingState; + /* * Constructors */ public BHKWMeter(String thingId, Device parent) throws ConfigException { super(thingId, parent); + this.thingState = new ThingStateChannel(this); } /* @@ -293,4 +297,9 @@ public ReadChannel frequency() { public ReadChannel voltage() { return voltageL1; } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } } diff --git a/edge/src/io/openems/impl/device/studer/StuderVs70.java b/edge/src/io/openems/impl/device/studer/StuderVs70.java index 9e4bb00d9ce..ffbc9eb2b35 100644 --- a/edge/src/io/openems/impl/device/studer/StuderVs70.java +++ b/edge/src/io/openems/impl/device/studer/StuderVs70.java @@ -25,7 +25,7 @@ public StuderVs70(Bridge parent) throws OpenemsException { * Config */ @ChannelInfo(title = "Charger", description = "Sets the charger nature.", type = StuderVs70Charger.class) - public final ConfigChannel charger = new ConfigChannel<>("charger", this); + public final ConfigChannel charger = new ConfigChannel("charger", this).addChangeListener(this); /* * Methods diff --git a/edge/src/io/openems/impl/device/studer/StuderVs70Charger.java b/edge/src/io/openems/impl/device/studer/StuderVs70Charger.java index fa667a46dc3..22217704735 100644 --- a/edge/src/io/openems/impl/device/studer/StuderVs70Charger.java +++ b/edge/src/io/openems/impl/device/studer/StuderVs70Charger.java @@ -3,6 +3,7 @@ import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; import io.openems.api.channel.WriteChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.doc.ThingInfo; import io.openems.api.exception.ConfigException; @@ -15,11 +16,14 @@ @ThingInfo(title = "Studer VS-70 Charger") public class StuderVs70Charger extends StuderDeviceNature { + private ThingStateChannel thingState; + /* * Constructors */ public StuderVs70Charger(String thingId, Device parent) throws ConfigException { super(thingId, parent); + this.thingState = new ThingStateChannel(this); } /* @@ -76,4 +80,9 @@ protected StuderProtocol defineStuderProtocol() throws ConfigException { return p; } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/device/system/System.java b/edge/src/io/openems/impl/device/system/System.java index 228b451a18f..bb3e801d3ab 100644 --- a/edge/src/io/openems/impl/device/system/System.java +++ b/edge/src/io/openems/impl/device/system/System.java @@ -30,6 +30,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.DebugChannel; import io.openems.api.device.nature.DeviceNature; +import io.openems.api.device.nature.system.SystemNature; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; import io.openems.api.exception.OpenemsException; @@ -49,20 +50,20 @@ public System(Bridge parent) throws OpenemsException { * Config */ @ChannelInfo(title = "System", description = "Sets the system nature.", type = SystemNature.class) - public final ConfigChannel system = new ConfigChannel<>("system", this); + public final ConfigChannel system = new ConfigChannel("system", this).addChangeListener(this); @ChannelInfo(title = "Debug", description = "Enables DebugChannels to write into database", type = Boolean.class, isOptional = true, defaultValue = "false") public final ConfigChannel debug = new ConfigChannel("debug", this) - .addChangeListener(new ChannelChangeListener() { + .addChangeListener(new ChannelChangeListener() { - @Override - public void channelChanged(Channel channel, Optional newValue, Optional oldValue) { - if (newValue.isPresent() && (boolean) newValue.get()) { - DebugChannel.enableDebug(); - } else { - DebugChannel.disableDebug(); - } - } - }); + @Override + public void channelChanged(Channel channel, Optional newValue, Optional oldValue) { + if (newValue.isPresent() && (boolean) newValue.get()) { + DebugChannel.enableDebug(); + } else { + DebugChannel.disableDebug(); + } + } + }); /* * Methods diff --git a/edge/src/io/openems/impl/device/system/SystemNature.java b/edge/src/io/openems/impl/device/system/SystemNature.java index b62607f941a..2d613398f2c 100644 --- a/edge/src/io/openems/impl/device/system/SystemNature.java +++ b/edge/src/io/openems/impl/device/system/SystemNature.java @@ -32,6 +32,7 @@ import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.doc.ThingInfo; import io.openems.api.exception.ConfigException; @@ -42,6 +43,8 @@ @ThingInfo(title = "Operating system") public class SystemNature extends SystemDeviceNature implements io.openems.api.device.nature.system.SystemNature { + private ThingStateChannel thingState; + /* * Constructors */ @@ -51,12 +54,13 @@ public SystemNature(String thingId, Device parent) throws ConfigException { OPENEMS_STATIC_IPS = new Inet4Address[] { // // 192.168.100.100 (Inet4Address) InetAddress - .getByAddress(new byte[] { (byte) 192, (byte) 168, (byte) 100, (byte) 100 }), + .getByAddress(new byte[] { (byte) 192, (byte) 168, (byte) 100, (byte) 100 }), // 10.4.0.1 (Inet4Address) InetAddress.getByAddress(new byte[] { (byte) 10, (byte) 4, (byte) 0, (byte) 1 }) }; } catch (UnknownHostException e) { throw new ConfigException("Error initializing OpenEMS Static IP: " + e.getMessage()); } + this.thingState = new ThingStateChannel(this); } /* @@ -151,4 +155,9 @@ public void init() { listener.thingChannelsUpdated(this); } } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } } diff --git a/edge/src/io/openems/impl/device/system/esscluster/EssCluster.java b/edge/src/io/openems/impl/device/system/esscluster/EssCluster.java index c0f27d662e7..d1755ee83d3 100644 --- a/edge/src/io/openems/impl/device/system/esscluster/EssCluster.java +++ b/edge/src/io/openems/impl/device/system/esscluster/EssCluster.java @@ -15,7 +15,7 @@ public class EssCluster extends SystemDevice { @ChannelInfo(title = "EssCluster", description = "Sets the cluster nature.", type = EssClusterNature.class) - public final ConfigChannel cluster = new ConfigChannel<>("cluster", this); + public final ConfigChannel cluster = new ConfigChannel("cluster", this).addChangeListener(this); public EssCluster(Bridge parent) throws OpenemsException { super(parent); diff --git a/edge/src/io/openems/impl/device/system/esscluster/EssClusterNature.java b/edge/src/io/openems/impl/device/system/esscluster/EssClusterNature.java index de43b638952..7972166c136 100644 --- a/edge/src/io/openems/impl/device/system/esscluster/EssClusterNature.java +++ b/edge/src/io/openems/impl/device/system/esscluster/EssClusterNature.java @@ -19,8 +19,8 @@ import io.openems.api.channel.FunctionalWriteChannel; import io.openems.api.channel.FunctionalWriteChannelFunction; import io.openems.api.channel.ReadChannel; -import io.openems.api.channel.StatusBitChannels; import io.openems.api.channel.WriteChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.DeviceNature; import io.openems.api.device.nature.ess.EssNature; @@ -41,6 +41,7 @@ public class EssClusterNature extends SystemDeviceNature implements SymmetricEss private final Logger log = LoggerFactory.getLogger(EssClusterNature.class); private List listeners; + private ThingStateChannel thingState; private static ThingRepository repo = ThingRepository.getInstance(); @@ -185,7 +186,6 @@ public class EssClusterNature extends SystemDeviceNature implements SymmetricEss } return 1L; }).label(0L, EssNature.STOP).label(1L, EssNature.START).label(2L, EssNature.FAULT).label(3L, "UNDEFINED"); - private StatusBitChannels warning = new StatusBitChannels("Warning", this); private FunctionalWriteChannel setWorkState = new FunctionalWriteChannel("SetWorkState", this, new FunctionalWriteChannelFunction() { @@ -495,6 +495,7 @@ public EssClusterNature(String id, Device parent) throws ConfigException { super(id, parent); this.listeners = new ArrayList<>(); Config.getInstance().addBridgeInitializedEventListener(this); + this.thingState = new ThingStateChannel(this); } @Override @@ -542,11 +543,6 @@ public ReadChannel allowedApparent() { return allowedApparent; } - @Override - public StatusBitChannels warning() { - return warning; - } - @Override public WriteChannel setWorkState() { return setWorkState; @@ -625,6 +621,7 @@ private void loadEss() { setWorkState.removeChannel(ess.setWorkState()); setActivePower.removeChannel(ess.setActivePower()); setReactivePower.removeChannel(ess.setReactivePower()); + thingState.removeChildChannel(ess.getStateChannel()); } essList.clear(); if (essIds != null && isInitialized) { @@ -647,6 +644,7 @@ private void loadEss() { setWorkState.addChannel(ess.setWorkState()); setActivePower.addChannel(ess.setActivePower()); setReactivePower.addChannel(ess.setReactivePower()); + this.thingState.addChildChannel(ess.getStateChannel()); } } } @@ -682,4 +680,9 @@ public void onBridgeInitialized() { loadEss(); } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/device/system/metercluster/MeterCluster.java b/edge/src/io/openems/impl/device/system/metercluster/MeterCluster.java index 11922b18326..d4f4d6ba76b 100644 --- a/edge/src/io/openems/impl/device/system/metercluster/MeterCluster.java +++ b/edge/src/io/openems/impl/device/system/metercluster/MeterCluster.java @@ -15,7 +15,7 @@ public class MeterCluster extends SystemDevice { @ChannelInfo(title = "EssCluster", description = "Sets the cluster nature.", type = MeterClusterNature.class) - public final ConfigChannel cluster = new ConfigChannel<>("cluster", this); + public final ConfigChannel cluster = new ConfigChannel("cluster", this).addChangeListener(this); public MeterCluster(Bridge parent) throws OpenemsException { super(parent); diff --git a/edge/src/io/openems/impl/device/system/metercluster/MeterClusterNature.java b/edge/src/io/openems/impl/device/system/metercluster/MeterClusterNature.java index 97aea56418c..4f7eba92efc 100644 --- a/edge/src/io/openems/impl/device/system/metercluster/MeterClusterNature.java +++ b/edge/src/io/openems/impl/device/system/metercluster/MeterClusterNature.java @@ -14,6 +14,7 @@ import io.openems.api.channel.ChannelChangeListener; import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.AsymmetricMeterNature; import io.openems.api.device.nature.meter.SymmetricMeterNature; @@ -30,13 +31,14 @@ @ThingInfo(title = "Meter Cluster") public class MeterClusterNature extends SimulatorDeviceNature - implements SymmetricMeterNature, AsymmetricMeterNature, ChannelChangeListener { +implements SymmetricMeterNature, AsymmetricMeterNature, ChannelChangeListener { private final Logger log; private List listeners; private ThingRepository repo; private List symmetricMeterList = new ArrayList<>(); private List asymmetricMeterList = new ArrayList<>(); + private ThingStateChannel thingState; /* * Channels @@ -62,9 +64,10 @@ public class MeterClusterNature extends SimulatorDeviceNature public MeterClusterNature(String thingId, Device parent) throws ConfigException { super(thingId, parent); - log = LoggerFactory.getLogger(this.getClass()); + this.log = LoggerFactory.getLogger(this.getClass()); this.listeners = new ArrayList<>(); this.repo = ThingRepository.getInstance(); + this.thingState = new ThingStateChannel(this); } /* @@ -383,7 +386,13 @@ private void loadMeter() { // remove old ess synchronized (symmetricMeterList) { synchronized (asymmetricMeterList) { + for(SymmetricMeterNature meter: symmetricMeterList) { + this.thingState.removeChildChannel(meter.getStateChannel()); + } symmetricMeterList.clear(); + for(AsymmetricMeterNature meter: asymmetricMeterList) { + this.thingState.removeChangeListener(meter.getStateChannel()); + } asymmetricMeterList.clear(); if (meterIds != null) { for (JsonElement id : meterIds) { @@ -392,9 +401,11 @@ private void loadMeter() { if (nature.get() instanceof AsymmetricMeterNature) { AsymmetricMeterNature meter = (AsymmetricMeterNature) nature.get(); asymmetricMeterList.add(meter); + this.thingState.addChildChannel(meter.getStateChannel()); } else if (nature.get() instanceof SymmetricMeterNature) { SymmetricMeterNature meter = (SymmetricMeterNature) nature.get(); symmetricMeterList.add(meter); + this.thingState.addChildChannel(meter.getStateChannel()); } else { log.error("ThingID: " + id.getAsString() + " is no Meter!"); } @@ -428,4 +439,9 @@ public void removeListener(ThingChannelsUpdatedListener listener) { this.listeners.remove(listener); } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/device/wago/WagoFB.java b/edge/src/io/openems/impl/device/wago/WagoFB.java index 0f4f812f831..ae302bb8613 100644 --- a/edge/src/io/openems/impl/device/wago/WagoFB.java +++ b/edge/src/io/openems/impl/device/wago/WagoFB.java @@ -1,189 +1,189 @@ -/******************************************************************************* - * 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.device.wago; - -import java.io.IOException; -import java.io.InputStream; -import java.net.Inet4Address; -import java.net.URL; -import java.net.URLConnection; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; - -import org.slf4j.LoggerFactory; -import org.w3c.dom.Document; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.xml.sax.SAXException; - -import io.openems.api.bridge.Bridge; -import io.openems.api.channel.ConfigChannel; -import io.openems.api.device.nature.DeviceNature; -import io.openems.api.doc.ChannelInfo; -import io.openems.api.doc.ThingInfo; -import io.openems.api.exception.ConfigException; -import io.openems.api.exception.OpenemsException; -import io.openems.impl.protocol.modbus.ModbusDevice; - -/* - * Example config: - * - *

    - * {
    - *   "class": "io.openems.impl.protocol.modbus.ModbusTcp",
    - *   "ip": "172.16.86.1",
    - *   "devices": [
    - *     {
    - *       "class": "io.openems.impl.device.wago.WagoFB",
    - *       "modbusUnitId": 1,
    - *       "output": {
    - *         "id": "output0",
    - *         "ip": "172.16.86.1"
    - *       },
    - *       "input": {
    - *         "id": "input0",
    - *         "ip": "172.16.86.1"
    - *       }
    - *     }
    - *   ]
    - * }
    - * 
    - */ - -@ThingInfo(title = "WAGO I/O") -public class WagoFB extends ModbusDevice { - - /* - * Constructors - */ - public WagoFB(Bridge parent) throws OpenemsException { - super(parent); - } - - /* - * Config - */ - @ChannelInfo(title = "Output", description = "Sets the output nature.", type = WagoFBOutput.class) - public final ConfigChannel output = new ConfigChannel<>("output", this); - - @ChannelInfo(title = "Input", description = "Sets the input nature.", type = WagoFBInput.class) - public final ConfigChannel input = new ConfigChannel<>("input", this); - - /* - * Fields - */ - private static HashMap>> configCache = new HashMap<>(); - - /* - * Methods - */ - @Override - protected Set getDeviceNatures() { - Set natures = new HashSet<>(); - if (output.valueOptional().isPresent()) { - natures.add(output.valueOptional().get()); - } - if (input.valueOptional().isPresent()) { - natures.add(input.valueOptional().get()); - } - return natures; - } - - public static HashMap> getConfig(Inet4Address ip) throws ConfigException { - if (configCache.containsKey(ip)) { - return configCache.get(ip); - } else { - HashMap> channels = new HashMap<>(); - String username = "admin"; - String password = "wago"; - int ftpPort = 21; - URL url; - Document doc; - try { - url = new URL("ftp://" + username + ":" + password + "@" + ip.getHostAddress() + ":" + ftpPort - + "/etc/EA-config.xml;type=i"); - URLConnection urlc = url.openConnection(); - InputStream is = urlc.getInputStream(); - DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); - doc = dBuilder.parse(is); - doc.getDocumentElement().normalize(); - } catch (IOException | SAXException | ParserConfigurationException e) { - throw new ConfigException(e.getMessage()); - } - - Node wagoNode = doc.getElementsByTagName("WAGO").item(0); - if (wagoNode != null) { - HashMap moduleCounter = new HashMap(); - Node moduleNode = wagoNode.getFirstChild(); - while (moduleNode != null) { - if (moduleNode.getNodeType() == Node.ELEMENT_NODE) { - NamedNodeMap moduleAttrs = moduleNode.getAttributes(); - // String article = moduleAttrs.getNamedItem("ARTIKELNR").getNodeValue(); - String moduletype = moduleAttrs.getNamedItem("MODULETYPE").getNodeValue(); - if (!moduleCounter.containsKey(moduletype)) { - moduleCounter.put(moduletype, 0); - } - moduleCounter.replace(moduletype, moduleCounter.get(moduletype) + 1); - int index = 1; - Node channelNode = moduleNode.getFirstChild(); - while (channelNode != null) { - if (channelNode.getNodeType() == Node.ELEMENT_NODE) { - NamedNodeMap channelAttrs = channelNode.getAttributes(); - String channelType = channelAttrs.getNamedItem("CHANNELTYPE").getNodeValue(); - if (!channels.containsKey(channelType)) { - channels.put(channelType, new ArrayList()); - } - String channelName = ""; - switch (channelType) { - case "DO": - channelName = "DigitalOutput_" + moduleCounter.get(channelType) + "_" + index; - break; - case "DI": - channelName = "DigitalInput_" + moduleCounter.get(channelType) + "_" + index; - break; - default: - LoggerFactory.getLogger(WagoFB.class) - .debug("ChannelType: " + channelName + " nicht erkannt"); - break; - } - channels.get(channelType).add(channelName); - index++; - } - channelNode = channelNode.getNextSibling(); - } - } - moduleNode = moduleNode.getNextSibling(); - } - } - configCache.put(ip, channels); - return channels; - } - } - -} +///******************************************************************************* +// * 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.device.wago; +// +//import java.io.IOException; +//import java.io.InputStream; +//import java.net.Inet4Address; +//import java.net.URL; +//import java.net.URLConnection; +//import java.util.ArrayList; +//import java.util.HashMap; +//import java.util.HashSet; +//import java.util.List; +//import java.util.Set; +// +//import javax.xml.parsers.DocumentBuilder; +//import javax.xml.parsers.DocumentBuilderFactory; +//import javax.xml.parsers.ParserConfigurationException; +// +//import org.slf4j.LoggerFactory; +//import org.w3c.dom.Document; +//import org.w3c.dom.NamedNodeMap; +//import org.w3c.dom.Node; +//import org.xml.sax.SAXException; +// +//import io.openems.api.bridge.Bridge; +//import io.openems.api.channel.ConfigChannel; +//import io.openems.api.device.nature.DeviceNature; +//import io.openems.api.doc.ChannelInfo; +//import io.openems.api.doc.ThingInfo; +//import io.openems.api.exception.ConfigException; +//import io.openems.api.exception.OpenemsException; +//import io.openems.impl.protocol.modbus.ModbusDevice; +// +///* +// * Example config: +// * +// *
    +// * {
    +// *   "class": "io.openems.impl.protocol.modbus.ModbusTcp",
    +// *   "ip": "172.16.86.1",
    +// *   "devices": [
    +// *     {
    +// *       "class": "io.openems.impl.device.wago.WagoFB",
    +// *       "modbusUnitId": 1,
    +// *       "output": {
    +// *         "id": "output0",
    +// *         "ip": "172.16.86.1"
    +// *       },
    +// *       "input": {
    +// *         "id": "input0",
    +// *         "ip": "172.16.86.1"
    +// *       }
    +// *     }
    +// *   ]
    +// * }
    +// * 
    +// */ +// +//@ThingInfo(title = "WAGO I/O") +//public class WagoFB extends ModbusDevice { +// +// /* +// * Constructors +// */ +// public WagoFB(Bridge parent) throws OpenemsException { +// super(parent); +// } +// +// /* +// * Config +// */ +// @ChannelInfo(title = "Output", description = "Sets the output nature.", type = WagoFBOutput.class) +// public final ConfigChannel output = new ConfigChannel<>("output", this); +// +// @ChannelInfo(title = "Input", description = "Sets the input nature.", type = WagoFBInput.class) +// public final ConfigChannel input = new ConfigChannel<>("input", this); +// +// /* +// * Fields +// */ +// private static HashMap>> configCache = new HashMap<>(); +// +// /* +// * Methods +// */ +// @Override +// protected Set getDeviceNatures() { +// Set natures = new HashSet<>(); +// if (output.valueOptional().isPresent()) { +// natures.add(output.valueOptional().get()); +// } +// if (input.valueOptional().isPresent()) { +// natures.add(input.valueOptional().get()); +// } +// return natures; +// } +// +// public static HashMap> getConfig(Inet4Address ip) throws ConfigException { +// if (configCache.containsKey(ip)) { +// return configCache.get(ip); +// } else { +// HashMap> channels = new HashMap<>(); +// String username = "admin"; +// String password = "wago"; +// int ftpPort = 21; +// URL url; +// Document doc; +// try { +// url = new URL("ftp://" + username + ":" + password + "@" + ip.getHostAddress() + ":" + ftpPort +// + "/etc/EA-config.xml;type=i"); +// URLConnection urlc = url.openConnection(); +// InputStream is = urlc.getInputStream(); +// DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); +// DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); +// doc = dBuilder.parse(is); +// doc.getDocumentElement().normalize(); +// } catch (IOException | SAXException | ParserConfigurationException e) { +// throw new ConfigException(e.getMessage()); +// } +// +// Node wagoNode = doc.getElementsByTagName("WAGO").item(0); +// if (wagoNode != null) { +// HashMap moduleCounter = new HashMap(); +// Node moduleNode = wagoNode.getFirstChild(); +// while (moduleNode != null) { +// if (moduleNode.getNodeType() == Node.ELEMENT_NODE) { +// NamedNodeMap moduleAttrs = moduleNode.getAttributes(); +// // String article = moduleAttrs.getNamedItem("ARTIKELNR").getNodeValue(); +// String moduletype = moduleAttrs.getNamedItem("MODULETYPE").getNodeValue(); +// if (!moduleCounter.containsKey(moduletype)) { +// moduleCounter.put(moduletype, 0); +// } +// moduleCounter.replace(moduletype, moduleCounter.get(moduletype) + 1); +// int index = 1; +// Node channelNode = moduleNode.getFirstChild(); +// while (channelNode != null) { +// if (channelNode.getNodeType() == Node.ELEMENT_NODE) { +// NamedNodeMap channelAttrs = channelNode.getAttributes(); +// String channelType = channelAttrs.getNamedItem("CHANNELTYPE").getNodeValue(); +// if (!channels.containsKey(channelType)) { +// channels.put(channelType, new ArrayList()); +// } +// String channelName = ""; +// switch (channelType) { +// case "DO": +// channelName = "DigitalOutput_" + moduleCounter.get(channelType) + "_" + index; +// break; +// case "DI": +// channelName = "DigitalInput_" + moduleCounter.get(channelType) + "_" + index; +// break; +// default: +// LoggerFactory.getLogger(WagoFB.class) +// .debug("ChannelType: " + channelName + " nicht erkannt"); +// break; +// } +// channels.get(channelType).add(channelName); +// index++; +// } +// channelNode = channelNode.getNextSibling(); +// } +// } +// moduleNode = moduleNode.getNextSibling(); +// } +// } +// configCache.put(ip, channels); +// return channels; +// } +// } +// +//} diff --git a/edge/src/io/openems/impl/device/wago/WagoFBInput.java b/edge/src/io/openems/impl/device/wago/WagoFBInput.java index 3442befc43a..297df0b5956 100644 --- a/edge/src/io/openems/impl/device/wago/WagoFBInput.java +++ b/edge/src/io/openems/impl/device/wago/WagoFBInput.java @@ -1,108 +1,108 @@ -/******************************************************************************* - * 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.device.wago; - -import java.net.Inet4Address; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -import io.openems.api.channel.ConfigChannel; -import io.openems.api.device.Device; -import io.openems.api.device.nature.io.InputNature; -import io.openems.api.doc.ChannelInfo; -import io.openems.api.doc.ThingInfo; -import io.openems.api.exception.ConfigException; -import io.openems.api.exception.InvalidValueException; -import io.openems.impl.protocol.modbus.ModbusCoilReadChannel; -import io.openems.impl.protocol.modbus.ModbusDeviceNature; -import io.openems.impl.protocol.modbus.internal.CoilElement; -import io.openems.impl.protocol.modbus.internal.ModbusProtocol; -import io.openems.impl.protocol.modbus.internal.range.ModbusCoilRange; -import io.openems.impl.protocol.modbus.internal.range.ModbusRange; - -@ThingInfo(title = "WAGO I/O Input") -public class WagoFBInput extends ModbusDeviceNature implements InputNature { - - /* - * Constructors - */ - public WagoFBInput(String thingId, Device parent) throws ConfigException { - super(thingId, parent); - } - - /* - * Config - */ - @ChannelInfo(title = "IP address", description = "IP address of the WAGO device.", type = Inet4Address.class) - public ConfigChannel ip = new ConfigChannel("ip", this); - - /* - * This Channels - */ - private List channel = new ArrayList<>(); - - /* - * Methods - */ - @Override - public ModbusCoilReadChannel[] getInput() { - return channel.toArray(new ModbusCoilReadChannel[channel.size()]); - } - - @Override - protected ModbusProtocol defineModbusProtocol() throws ConfigException { - List ranges = new ArrayList<>(); - HashMap> channels; - try { - channels = WagoFB.getConfig(ip.value()); - for (String key : channels.keySet()) { - switch (key) { - case "DI": { - List elements = new ArrayList<>(); - int count = 0; - for (@SuppressWarnings("unused") String channel : channels.get(key)) { - ModbusCoilReadChannel ch = new ModbusCoilReadChannel(Integer.toString(count), this); - this.channel.add(ch); - elements.add(new CoilElement(count, ch)); - count++; - if (count % 63 == 0) { - ranges.add(new ModbusCoilRange(elements.get(0).getAddress(), - elements.toArray(new CoilElement[elements.size()]))); - elements.clear(); - } - } - if (this.channel.size() > 0) { - ranges.add(new ModbusCoilRange(elements.get(0).getAddress(), - elements.toArray(new CoilElement[elements.size()]))); - } - } - break; - } - } - } catch (InvalidValueException e) { - log.error("Ip-Address is Invalid", e); - } - ModbusProtocol protocol = new ModbusProtocol(ranges.toArray(new ModbusRange[ranges.size()])); - return protocol; - } - -} +///******************************************************************************* +// * 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.device.wago; +// +//import java.net.Inet4Address; +//import java.util.ArrayList; +//import java.util.HashMap; +//import java.util.List; +// +//import io.openems.api.channel.ConfigChannel; +//import io.openems.api.device.Device; +//import io.openems.api.device.nature.io.InputNature; +//import io.openems.api.doc.ChannelInfo; +//import io.openems.api.doc.ThingInfo; +//import io.openems.api.exception.ConfigException; +//import io.openems.api.exception.InvalidValueException; +//import io.openems.impl.protocol.modbus.ModbusCoilReadChannel; +//import io.openems.impl.protocol.modbus.ModbusDeviceNature; +//import io.openems.impl.protocol.modbus.internal.CoilElement; +//import io.openems.impl.protocol.modbus.internal.ModbusProtocol; +//import io.openems.impl.protocol.modbus.internal.range.ModbusCoilRange; +//import io.openems.impl.protocol.modbus.internal.range.ModbusRange; +// +//@ThingInfo(title = "WAGO I/O Input") +//public class WagoFBInput extends ModbusDeviceNature implements InputNature { +// +// /* +// * Constructors +// */ +// public WagoFBInput(String thingId, Device parent) throws ConfigException { +// super(thingId, parent); +// } +// +// /* +// * Config +// */ +// @ChannelInfo(title = "IP address", description = "IP address of the WAGO device.", type = Inet4Address.class) +// public ConfigChannel ip = new ConfigChannel("ip", this); +// +// /* +// * This Channels +// */ +// private List channel = new ArrayList<>(); +// +// /* +// * Methods +// */ +// @Override +// public ModbusCoilReadChannel[] getInput() { +// return channel.toArray(new ModbusCoilReadChannel[channel.size()]); +// } +// +// @Override +// protected ModbusProtocol defineModbusProtocol() throws ConfigException { +// List ranges = new ArrayList<>(); +// HashMap> channels; +// try { +// channels = WagoFB.getConfig(ip.value()); +// for (String key : channels.keySet()) { +// switch (key) { +// case "DI": { +// List elements = new ArrayList<>(); +// int count = 0; +// for (@SuppressWarnings("unused") String channel : channels.get(key)) { +// ModbusCoilReadChannel ch = new ModbusCoilReadChannel(Integer.toString(count), this); +// this.channel.add(ch); +// elements.add(new CoilElement(count, ch)); +// count++; +// if (count % 63 == 0) { +// ranges.add(new ModbusCoilRange(elements.get(0).getAddress(), +// elements.toArray(new CoilElement[elements.size()]))); +// elements.clear(); +// } +// } +// if (this.channel.size() > 0) { +// ranges.add(new ModbusCoilRange(elements.get(0).getAddress(), +// elements.toArray(new CoilElement[elements.size()]))); +// } +// } +// break; +// } +// } +// } catch (InvalidValueException e) { +// log.error("Ip-Address is Invalid", e); +// } +// ModbusProtocol protocol = new ModbusProtocol(ranges.toArray(new ModbusRange[ranges.size()])); +// return protocol; +// } +// +//} diff --git a/edge/src/io/openems/impl/device/wago/WagoFBOutput.java b/edge/src/io/openems/impl/device/wago/WagoFBOutput.java index 8bbb9ceca13..4534e82aa6c 100644 --- a/edge/src/io/openems/impl/device/wago/WagoFBOutput.java +++ b/edge/src/io/openems/impl/device/wago/WagoFBOutput.java @@ -1,109 +1,109 @@ -/******************************************************************************* - * 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.device.wago; - -import java.net.Inet4Address; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -import io.openems.api.channel.ConfigChannel; -import io.openems.api.device.Device; -import io.openems.api.device.nature.io.OutputNature; -import io.openems.api.doc.ChannelInfo; -import io.openems.api.doc.ThingInfo; -import io.openems.api.exception.ConfigException; -import io.openems.api.exception.InvalidValueException; -import io.openems.impl.protocol.modbus.ModbusCoilWriteChannel; -import io.openems.impl.protocol.modbus.ModbusDeviceNature; -import io.openems.impl.protocol.modbus.internal.CoilElement; -import io.openems.impl.protocol.modbus.internal.ModbusProtocol; -import io.openems.impl.protocol.modbus.internal.range.ModbusCoilRange; -import io.openems.impl.protocol.modbus.internal.range.ModbusRange; -import io.openems.impl.protocol.modbus.internal.range.WriteableModbusCoilRange; - -@ThingInfo(title = "WAGO I/O Output") -public class WagoFBOutput extends ModbusDeviceNature implements OutputNature { - - /* - * Constructors - */ - public WagoFBOutput(String thingId, Device parent) throws ConfigException { - super(thingId, parent); - } - - /* - * Config - */ - @ChannelInfo(title = "IP", description = "IP address of the WAGO device.", type = Inet4Address.class) - public ConfigChannel ip = new ConfigChannel("ip", this); - - /* - * This Channels - */ - private List channel = new ArrayList<>(); - - /* - * Methods - */ - @Override - public ModbusCoilWriteChannel[] setOutput() { - return channel.toArray(new ModbusCoilWriteChannel[channel.size()]); - } - - @Override - protected ModbusProtocol defineModbusProtocol() throws ConfigException { - List ranges = new ArrayList<>(); - HashMap> channels; - try { - channels = WagoFB.getConfig(ip.value()); - for (String key : channels.keySet()) { - switch (key) { - case "DO": { - List elements = new ArrayList<>(); - int count = 0; - for (@SuppressWarnings("unused") String channel : channels.get(key)) { - ModbusCoilWriteChannel ch = new ModbusCoilWriteChannel(Integer.toString(count), this); - this.channel.add(ch); - elements.add(new CoilElement(512 + count, ch)); - count++; - if (count % 63 == 0) { - ranges.add(new ModbusCoilRange(elements.get(0).getAddress(), - elements.toArray(new CoilElement[elements.size()]))); - elements.clear(); - } - } - if (this.channel.size() > 0) { - ranges.add(new WriteableModbusCoilRange(elements.get(0).getAddress(), - elements.toArray(new CoilElement[elements.size()]))); - } - } - break; - } - } - } catch (InvalidValueException e) { - log.error("Ip-Address is Invalid", e); - } - ModbusProtocol protocol = new ModbusProtocol(ranges.toArray(new ModbusRange[ranges.size()])); - return protocol; - } - -} +///******************************************************************************* +// * 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.device.wago; +// +//import java.net.Inet4Address; +//import java.util.ArrayList; +//import java.util.HashMap; +//import java.util.List; +// +//import io.openems.api.channel.ConfigChannel; +//import io.openems.api.device.Device; +//import io.openems.api.device.nature.io.OutputNature; +//import io.openems.api.doc.ChannelInfo; +//import io.openems.api.doc.ThingInfo; +//import io.openems.api.exception.ConfigException; +//import io.openems.api.exception.InvalidValueException; +//import io.openems.impl.protocol.modbus.ModbusCoilWriteChannel; +//import io.openems.impl.protocol.modbus.ModbusDeviceNature; +//import io.openems.impl.protocol.modbus.internal.CoilElement; +//import io.openems.impl.protocol.modbus.internal.ModbusProtocol; +//import io.openems.impl.protocol.modbus.internal.range.ModbusCoilRange; +//import io.openems.impl.protocol.modbus.internal.range.ModbusRange; +//import io.openems.impl.protocol.modbus.internal.range.WriteableModbusCoilRange; +// +//@ThingInfo(title = "WAGO I/O Output") +//public class WagoFBOutput extends ModbusDeviceNature implements OutputNature { +// +// /* +// * Constructors +// */ +// public WagoFBOutput(String thingId, Device parent) throws ConfigException { +// super(thingId, parent); +// } +// +// /* +// * Config +// */ +// @ChannelInfo(title = "IP", description = "IP address of the WAGO device.", type = Inet4Address.class) +// public ConfigChannel ip = new ConfigChannel("ip", this); +// +// /* +// * This Channels +// */ +// private List channel = new ArrayList<>(); +// +// /* +// * Methods +// */ +// @Override +// public ModbusCoilWriteChannel[] setOutput() { +// return channel.toArray(new ModbusCoilWriteChannel[channel.size()]); +// } +// +// @Override +// protected ModbusProtocol defineModbusProtocol() throws ConfigException { +// List ranges = new ArrayList<>(); +// HashMap> channels; +// try { +// channels = WagoFB.getConfig(ip.value()); +// for (String key : channels.keySet()) { +// switch (key) { +// case "DO": { +// List elements = new ArrayList<>(); +// int count = 0; +// for (@SuppressWarnings("unused") String channel : channels.get(key)) { +// ModbusCoilWriteChannel ch = new ModbusCoilWriteChannel(Integer.toString(count), this); +// this.channel.add(ch); +// elements.add(new CoilElement(512 + count, ch)); +// count++; +// if (count % 63 == 0) { +// ranges.add(new ModbusCoilRange(elements.get(0).getAddress(), +// elements.toArray(new CoilElement[elements.size()]))); +// elements.clear(); +// } +// } +// if (this.channel.size() > 0) { +// ranges.add(new WriteableModbusCoilRange(elements.get(0).getAddress(), +// elements.toArray(new CoilElement[elements.size()]))); +// } +// } +// break; +// } +// } +// } catch (InvalidValueException e) { +// log.error("Ip-Address is Invalid", e); +// } +// ModbusProtocol protocol = new ModbusProtocol(ranges.toArray(new ModbusRange[ranges.size()])); +// return protocol; +// } +// +//} From c838d941f8442ec57b6a95920d11a72a46d108c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Ro=C3=9Fmann?= Date: Tue, 9 Jan 2018 16:48:52 +0100 Subject: [PATCH 28/55] implement ThingStateChannel for scheduler to get a compiling Framework further error mapping is necessary to forward the errors to the ThingStateChannel --- .../src/io/openems/impl/scheduler/SimpleScheduler.java | 10 +++++++++- .../channelthreshold/ChannelThresholdScheduler.java | 9 +++++++++ .../openems/impl/scheduler/time/WeekTimeScheduler.java | 9 +++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/edge/src/io/openems/impl/scheduler/SimpleScheduler.java b/edge/src/io/openems/impl/scheduler/SimpleScheduler.java index c7d7c333bd0..d89554d2d38 100644 --- a/edge/src/io/openems/impl/scheduler/SimpleScheduler.java +++ b/edge/src/io/openems/impl/scheduler/SimpleScheduler.java @@ -27,6 +27,7 @@ import info.faljse.SDNotify.SDNotify; import io.openems.api.bridge.Bridge; import io.openems.api.channel.WriteChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.controller.Controller; import io.openems.api.doc.ThingInfo; import io.openems.api.scheduler.Scheduler; @@ -34,11 +35,13 @@ @ThingInfo(title = "App-Planner") public class SimpleScheduler extends Scheduler { + private ThingStateChannel thingState; + /* * Constructors */ public SimpleScheduler() { - + this.thingState = new ThingStateChannel(this); } /* @@ -71,4 +74,9 @@ protected boolean initialize() { return true; } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/scheduler/channelthreshold/ChannelThresholdScheduler.java b/edge/src/io/openems/impl/scheduler/channelthreshold/ChannelThresholdScheduler.java index 9c882c093f2..284bb6183ba 100644 --- a/edge/src/io/openems/impl/scheduler/channelthreshold/ChannelThresholdScheduler.java +++ b/edge/src/io/openems/impl/scheduler/channelthreshold/ChannelThresholdScheduler.java @@ -35,6 +35,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; import io.openems.api.channel.WriteChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.controller.Controller; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; @@ -47,8 +48,11 @@ @ThingInfo(title = "Channel threshold app-planer", description = "app-planer with thresholds on configured channel to run different controllers by threshold on channel.") public class ChannelThresholdScheduler extends Scheduler { + private ThingStateChannel thingState; + public ChannelThresholdScheduler() { thingRepository = ThingRepository.getInstance(); + this.thingState = new ThingStateChannel(this); } /* @@ -296,4 +300,9 @@ public boolean isBetween(long value) { return min <= value && value <= max; } } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } } diff --git a/edge/src/io/openems/impl/scheduler/time/WeekTimeScheduler.java b/edge/src/io/openems/impl/scheduler/time/WeekTimeScheduler.java index 1dfa15bfb56..162ee4937a1 100644 --- a/edge/src/io/openems/impl/scheduler/time/WeekTimeScheduler.java +++ b/edge/src/io/openems/impl/scheduler/time/WeekTimeScheduler.java @@ -37,6 +37,7 @@ import io.openems.api.bridge.Bridge; import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.WriteChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.controller.Controller; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; @@ -50,11 +51,14 @@ @ThingInfo(title = "Weekly App-Planner", description = "Define recurring weekly plans.") public class WeekTimeScheduler extends Scheduler { + private ThingStateChannel thingState; + /* * Constructors */ public WeekTimeScheduler() { thingRepository = ThingRepository.getInstance(); + this.thingState = new ThingStateChannel(this); } /* @@ -219,4 +223,9 @@ public synchronized void removeController(Controller controller) { // remove controller from all times super.removeController(controller); } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } } From c162086543c9c0c80b40bdca6026e919a3e785b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Ro=C3=9Fmann?= Date: Tue, 9 Jan 2018 17:00:52 +0100 Subject: [PATCH 29/55] implement ThingStateChannel and ChannelEnum --- .../persistence/fenecon/FeneconPersistence.java | 12 ++++++++++++ .../persistence/influxdb/InfluxdbPersistence.java | 15 +++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/edge/src/io/openems/impl/persistence/fenecon/FeneconPersistence.java b/edge/src/io/openems/impl/persistence/fenecon/FeneconPersistence.java index 682750d4a8d..0ef2609c01d 100644 --- a/edge/src/io/openems/impl/persistence/fenecon/FeneconPersistence.java +++ b/edge/src/io/openems/impl/persistence/fenecon/FeneconPersistence.java @@ -38,8 +38,10 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ChannelChangeListener; +import io.openems.api.channel.ChannelEnum; import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.controller.ThingMap; import io.openems.api.device.nature.DeviceNature; import io.openems.api.doc.ChannelInfo; @@ -66,6 +68,8 @@ @ThingInfo(title = "FENECON Persistence", description = "Establishes the connection to FENECON Cloud.") public class FeneconPersistence extends Persistence implements ChannelChangeListener { + private ThingStateChannel thingState; + private final static String DEFAULT_CONFIG_LANGUAGE = "en"; /* @@ -96,6 +100,7 @@ public class FeneconPersistence extends Persistence implements ChannelChangeList */ public FeneconPersistence() { this.websocketHandler = new EdgeWebsocketHandler(); + this.thingState = new ThingStateChannel(this); this.reconnectingWebsocket = new ReconnectingWebsocket(this.websocketHandler, (websocket) -> { /* * onOpen @@ -325,6 +330,8 @@ private void addChannelValueToQueue(Channel channel, Optional valueOpt) { fieldValue = new StringFieldValue(((Inet4Address) value).getHostAddress()); } else if (value instanceof Boolean) { fieldValue = new NumberFieldValue(((Boolean) value) ? 1 : 0); + } else if (value instanceof ChannelEnum) { + fieldValue = new NumberFieldValue(((ChannelEnum)value).getValue()); } else if (value instanceof DeviceNature || value instanceof JsonElement || value instanceof Map || value instanceof Set || value instanceof List || value instanceof ThingMap) { // ignore @@ -374,4 +381,9 @@ private Optional proxyInfo() { return Optional.empty(); } } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } } \ No newline at end of file diff --git a/edge/src/io/openems/impl/persistence/influxdb/InfluxdbPersistence.java b/edge/src/io/openems/impl/persistence/influxdb/InfluxdbPersistence.java index 53f17164c21..fd4c539aca4 100644 --- a/edge/src/io/openems/impl/persistence/influxdb/InfluxdbPersistence.java +++ b/edge/src/io/openems/impl/persistence/influxdb/InfluxdbPersistence.java @@ -36,9 +36,11 @@ import com.google.gson.JsonObject; import io.openems.api.channel.Channel; +import io.openems.api.channel.ChannelEnum; import io.openems.api.channel.ChannelUpdateListener; import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; import io.openems.api.exception.OpenemsException; @@ -49,6 +51,8 @@ @ThingInfo(title = "InfluxDB Persistence", description = "Persists data in an InfluxDB time-series database.") public class InfluxdbPersistence extends QueryablePersistence implements ChannelUpdateListener { + private ThingStateChannel thingState; + /* * Config */ @@ -70,6 +74,10 @@ public class InfluxdbPersistence extends QueryablePersistence implements Channel @ChannelInfo(title = "Sets the duration of each cycle in milliseconds", type = Integer.class) public ConfigChannel cycleTime = new ConfigChannel("cycleTime", this).defaultValue(10000); + public InfluxdbPersistence() { + this.thingState = new ThingStateChannel(this); + } + /* * Fields */ @@ -100,6 +108,8 @@ public void channelUpdated(Channel channel, Optional newValue) { fieldValue = new NumberFieldValue(field, (Number) value); } else if (value instanceof String) { fieldValue = new StringFieldValue(field, (String) value); + }else if (value instanceof ChannelEnum) { + fieldValue = new NumberFieldValue(field, ((ChannelEnum)value).getValue()); } else { return; } @@ -212,4 +222,9 @@ public JsonArray queryHistoricData(Optional deviceIdOpt, ZonedDateTime protected int getCycleTime() { return cycleTime.valueOptional().orElse(DEFAULT_CYCLETIME); } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } } \ No newline at end of file From 4a15a5b5da5657f4ae2d55e448080773d4293811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Ro=C3=9Fmann?= Date: Tue, 9 Jan 2018 17:03:30 +0100 Subject: [PATCH 30/55] implement ThingStateChannel --- .../AsymmetricSymmetricCombinationController.java | 11 +++++++++++ .../AsymmetricSymmetricCombinationEss.java | 9 ++++++++- .../AsymmetricSymmetricCombinationEssNature.java | 13 +++++++------ 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/edge/src/io/openems/impl/controller/asymmetricsymmetriccombination/AsymmetricSymmetricCombinationController.java b/edge/src/io/openems/impl/controller/asymmetricsymmetriccombination/AsymmetricSymmetricCombinationController.java index af5c738c258..5552310bb69 100644 --- a/edge/src/io/openems/impl/controller/asymmetricsymmetriccombination/AsymmetricSymmetricCombinationController.java +++ b/edge/src/io/openems/impl/controller/asymmetricsymmetriccombination/AsymmetricSymmetricCombinationController.java @@ -1,6 +1,7 @@ package io.openems.impl.controller.asymmetricsymmetriccombination; import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.controller.Controller; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; @@ -10,6 +11,8 @@ @ThingInfo(title = "starts power calculation of AsymmetricSymmetricCombination Ess device") public class AsymmetricSymmetricCombinationController extends Controller { + private ThingStateChannel thingState; + @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class) public final ConfigChannel ess = new ConfigChannel("ess", this); @@ -17,6 +20,7 @@ public class AsymmetricSymmetricCombinationController extends Controller { public AsymmetricSymmetricCombinationController() { super(); + this.thingState = new ThingStateChannel(this); } @@ -36,4 +40,11 @@ public void run() { } } + + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/device/system/asymmetricsymmetriccombinationess/AsymmetricSymmetricCombinationEss.java b/edge/src/io/openems/impl/device/system/asymmetricsymmetriccombinationess/AsymmetricSymmetricCombinationEss.java index 0ec3354d17b..9a56a5d709e 100644 --- a/edge/src/io/openems/impl/device/system/asymmetricsymmetriccombinationess/AsymmetricSymmetricCombinationEss.java +++ b/edge/src/io/openems/impl/device/system/asymmetricsymmetriccombinationess/AsymmetricSymmetricCombinationEss.java @@ -5,6 +5,7 @@ import io.openems.api.bridge.Bridge; import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.nature.DeviceNature; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; @@ -15,7 +16,7 @@ public class AsymmetricSymmetricCombinationEss extends SystemDevice { @ChannelInfo(title = "AsymmetricSymmetricCombinationEss", description = "Sets the wrapper nature to use asymmetric and symmetric controller together.", type = AsymmetricSymmetricCombinationEssNature.class) - public final ConfigChannel wrapper = new ConfigChannel<>("wrapper", this); + public final ConfigChannel wrapper = new ConfigChannel("wrapper", this).addChangeListener(this); public AsymmetricSymmetricCombinationEss(Bridge parent) throws OpenemsException { super(parent); @@ -31,4 +32,10 @@ protected Set getDeviceNatures() { return natures; } + @Override + public ThingStateChannel getStateChannel() { + // TODO Auto-generated method stub + return null; + } + } diff --git a/edge/src/io/openems/impl/device/system/asymmetricsymmetriccombinationess/AsymmetricSymmetricCombinationEssNature.java b/edge/src/io/openems/impl/device/system/asymmetricsymmetriccombinationess/AsymmetricSymmetricCombinationEssNature.java index 41271b0cfc2..9fe2ba1feb8 100644 --- a/edge/src/io/openems/impl/device/system/asymmetricsymmetriccombinationess/AsymmetricSymmetricCombinationEssNature.java +++ b/edge/src/io/openems/impl/device/system/asymmetricsymmetriccombinationess/AsymmetricSymmetricCombinationEssNature.java @@ -15,8 +15,8 @@ import io.openems.api.channel.FunctionalWriteChannelFunction; import io.openems.api.channel.ProxyReadChannel; import io.openems.api.channel.ReadChannel; -import io.openems.api.channel.StatusBitChannels; import io.openems.api.channel.WriteChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.ess.AsymmetricEssNature; import io.openems.api.device.nature.ess.EssNature; @@ -906,11 +906,6 @@ public ReadChannel maxNominalPower() { return maxNominalPower; } - @Override - public StatusBitChannels warning() { - return null; - } - @Override public WriteChannel setWorkState() { return setWorkState; @@ -1482,4 +1477,10 @@ public void onBridgeInitialized() { loadEss(); } + @Override + public ThingStateChannel getStateChannel() { + // TODO Auto-generated method stub + return null; + } + } From 2817ca25327e7890f49f398d9221b1419ecf6cee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Ro=C3=9Fmann?= Date: Tue, 9 Jan 2018 17:50:48 +0100 Subject: [PATCH 31/55] Implement ThingStateChannel for all Controller further error handling is required to forward the errors to the ThingStateChannel --- .../impl/controller/acisland/AcIsland.java | 7 + .../api/modbustcp/ModbusTcpApiController.java | 7 + .../api/rest/RestApiController.java | 167 +++--- .../api/websocket/WebsocketApiController.java | 239 ++++---- .../AvoidTotalChargeController.java | 7 + .../AvoidTotalDischargeController.java | 353 +++++------ .../balancing/BalancingController.java | 7 + ...BalancingBandgapActivePowerController.java | 7 + ...lancingBandgapReactivePowerController.java | 7 + .../BalancingCurrentController.java | 7 + .../capacitytest/CapacityTestController.java | 295 +++++----- .../FixValueActivePowerController.java | 7 + .../FixValueReactivePowerController.java | 157 ++--- ...aseRectificationActivePowerController.java | 8 + ...eRectificationReactivePowerController.java | 8 + .../PowerLimitationController.java | 321 +++++----- ...mmetricSymmetricCombinationController.java | 3 +- .../ChannelThresholdController.java | 359 +++++------ .../ChargeLimitationController.java | 141 ++--- .../clocksync/ClockSyncController.java | 235 ++++---- .../debuglog/DebugLogController.java | 201 ++++--- .../openems/impl/controller/debuglog/Ess.java | 192 +++--- .../EmergencyGeneratorController.java | 353 +++++------ .../impl/controller/evcs/EvcsController.java | 7 + .../FeneconProSetupController.java | 5 +- .../OffGridIndicationController.java | 11 +- .../OnGridIndicationController.java | 11 +- .../riedmann/RiedmannController.java | 4 +- .../riedmann/SystemStopController.java | 7 + .../SupplyBusSwitchController.java | 7 + .../AvoidTotalChargeController.java | 7 + .../AvoidTotalDischargeController.java | 7 + ...idTotalDischargeSocTimeLineController.java | 333 ++++++----- .../balancing/BalancingController.java | 7 + .../BalancingBandgapController.java | 241 ++++---- .../BalancingCosPhiController.java | 153 ++--- .../BalancingCurrentController.java | 189 +++--- .../BalancingOffsetController.java | 11 +- .../BalancingSurplusController.java | 255 ++++---- .../capacitytest/CapacityTestController.java | 305 +++++----- .../EnergysavingController.java | 239 ++++---- .../AlwaysOnController.java | 153 ++--- .../symmetric/cosphi/CosPhiController.java | 151 ++--- .../CosPhiCharacteristicController.java | 201 ++++--- .../fixvalue/FixValueController.java | 7 + .../OffGridPowerStationController.java | 555 +++++++++--------- .../PowerByFrequencyController.java | 189 +++--- .../PowerLimitationController.java | 209 +++---- .../powerramp/PowerRampController.java | 227 +++---- .../AvoidTotalDischargeController.java | 445 +++++++------- .../refuworkstate/WorkStateController.java | 7 + .../TimelineChargeController.java | 7 + .../VoltageCharacteristicController.java | 293 ++++----- .../testwrite/TestWriteController.java | 141 ++--- .../ThermalPowerStationController.java | 7 + .../controller/ThermalPowerStationTest.java | 273 ++++----- .../utils/channel/UnitTestReadChannel.java | 69 ++- .../utils/channel/UnitTestWriteChannel.java | 93 +-- .../UnitTestAsymmetricEssNature.java | 13 +- .../UnitTestAsymmetricMeterNature.java | 7 + .../UnitTestSymmetricEssNature.java | 13 +- .../UnitTestSymmetricMeterNature.java | 7 + 62 files changed, 4182 insertions(+), 3772 deletions(-) diff --git a/edge/src/io/openems/impl/controller/acisland/AcIsland.java b/edge/src/io/openems/impl/controller/acisland/AcIsland.java index efaf1fb9152..a45b04fa08f 100644 --- a/edge/src/io/openems/impl/controller/acisland/AcIsland.java +++ b/edge/src/io/openems/impl/controller/acisland/AcIsland.java @@ -25,6 +25,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.WriteChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -43,6 +44,7 @@ public class AcIsland extends Controller { private State currentState = State.UNKNOWN; private boolean isProducerDisconnected = false; private long timeProducerDisconnected; + private ThingStateChannel thingState = new ThingStateChannel(this); private enum State { OFFGRID, ONGRID, SWITCHTOOFFGRID, SWITCHTOONGRID, UNKNOWN @@ -289,4 +291,9 @@ private void switchOutput(WriteChannel outputChannel, boolean on,boolea outputChannel.pushWrite(on ^ invertOutput); } } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } } diff --git a/edge/src/io/openems/impl/controller/api/modbustcp/ModbusTcpApiController.java b/edge/src/io/openems/impl/controller/api/modbustcp/ModbusTcpApiController.java index d8097ba3bd3..4178b5ce19f 100644 --- a/edge/src/io/openems/impl/controller/api/modbustcp/ModbusTcpApiController.java +++ b/edge/src/io/openems/impl/controller/api/modbustcp/ModbusTcpApiController.java @@ -11,6 +11,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.controller.Controller; import io.openems.api.doc.ChannelDoc; import io.openems.api.doc.ChannelInfo; @@ -30,6 +31,7 @@ public class ModbusTcpApiController extends Controller { private Optional slaveOpt = Optional.empty(); private final ApiWorker apiWorker = new ApiWorker(); private final MyProcessImage processImage = new MyProcessImage(UNIT_ID, apiWorker); + private ThingStateChannel thingState = new ThingStateChannel(this); /* * Constructors @@ -137,4 +139,9 @@ protected void updateChannelMapping(Optional jMappingOpt) { } } } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } } \ No newline at end of file diff --git a/edge/src/io/openems/impl/controller/api/rest/RestApiController.java b/edge/src/io/openems/impl/controller/api/rest/RestApiController.java index ff4c391d014..ea4f93f2322 100644 --- a/edge/src/io/openems/impl/controller/api/rest/RestApiController.java +++ b/edge/src/io/openems/impl/controller/api/rest/RestApiController.java @@ -1,80 +1,87 @@ -/******************************************************************************* - * 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.api.rest; - -import java.util.Optional; - -import io.openems.api.channel.Channel; -import io.openems.api.channel.ConfigChannel; -import io.openems.api.controller.Controller; -import io.openems.api.doc.ChannelInfo; -import io.openems.api.doc.ThingInfo; -import io.openems.api.exception.OpenemsException; -import io.openems.core.utilities.api.ApiWorker; - -@ThingInfo(title = "REST-Api", description = "Use for external access to OpenEMS.") -public class RestApiController extends Controller { - - private final ApiWorker apiWorker = new ApiWorker(); - - /* - * Constructors - */ - public RestApiController() { - super(); - } - - public RestApiController(String thingId) { - super(thingId); - } - - /* - * Config - */ - @ChannelInfo(title = "Port", description = "Sets the port of the REST-Api Server.", type = Integer.class, defaultValue = "8084") - public final ConfigChannel port = new ConfigChannel("port", this); - - @ChannelInfo(title = "ChannelTimeout", description = "Sets the timeout for updates to channels.", type = Integer.class, defaultValue = "" - + ApiWorker.DEFAULT_TIMEOUT_SECONDS) - public final ConfigChannel channelTimeout = new ConfigChannel("channelTimeout", this) - .addChangeListener((Channel channel, Optional newValue, Optional oldValue) -> { - if (newValue.isPresent() && Integer.parseInt(newValue.get().toString()) >= 0) { - apiWorker.setTimeoutSeconds(Integer.parseInt(newValue.get().toString())); - } else { - apiWorker.setTimeoutSeconds(ApiWorker.DEFAULT_TIMEOUT_SECONDS); - } - }); - - /* - * Methods - */ - @Override - public void run() { - // Start REST-Api server - try { - ComponentSingleton.getComponent(this.port, this.apiWorker); - } catch (OpenemsException e) { - log.error(e.getMessage() + ": " + e.getCause()); - } - // API Worker - this.apiWorker.run(); - } -} +/******************************************************************************* + * 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.api.rest; + +import java.util.Optional; + +import io.openems.api.channel.Channel; +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.controller.Controller; +import io.openems.api.doc.ChannelInfo; +import io.openems.api.doc.ThingInfo; +import io.openems.api.exception.OpenemsException; +import io.openems.core.utilities.api.ApiWorker; + +@ThingInfo(title = "REST-Api", description = "Use for external access to OpenEMS.") +public class RestApiController extends Controller { + + private final ApiWorker apiWorker = new ApiWorker(); + private ThingStateChannel thingState = new ThingStateChannel(this); + + /* + * Constructors + */ + public RestApiController() { + super(); + } + + public RestApiController(String thingId) { + super(thingId); + } + + /* + * Config + */ + @ChannelInfo(title = "Port", description = "Sets the port of the REST-Api Server.", type = Integer.class, defaultValue = "8084") + public final ConfigChannel port = new ConfigChannel("port", this); + + @ChannelInfo(title = "ChannelTimeout", description = "Sets the timeout for updates to channels.", type = Integer.class, defaultValue = "" + + ApiWorker.DEFAULT_TIMEOUT_SECONDS) + public final ConfigChannel channelTimeout = new ConfigChannel("channelTimeout", this) + .addChangeListener((Channel channel, Optional newValue, Optional oldValue) -> { + if (newValue.isPresent() && Integer.parseInt(newValue.get().toString()) >= 0) { + apiWorker.setTimeoutSeconds(Integer.parseInt(newValue.get().toString())); + } else { + apiWorker.setTimeoutSeconds(ApiWorker.DEFAULT_TIMEOUT_SECONDS); + } + }); + + /* + * Methods + */ + @Override + public void run() { + // Start REST-Api server + try { + ComponentSingleton.getComponent(this.port, this.apiWorker); + } catch (OpenemsException e) { + log.error(e.getMessage() + ": " + e.getCause()); + } + // API Worker + this.apiWorker.run(); + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } +} diff --git a/edge/src/io/openems/impl/controller/api/websocket/WebsocketApiController.java b/edge/src/io/openems/impl/controller/api/websocket/WebsocketApiController.java index 49c6746788f..6a5f39dad96 100644 --- a/edge/src/io/openems/impl/controller/api/websocket/WebsocketApiController.java +++ b/edge/src/io/openems/impl/controller/api/websocket/WebsocketApiController.java @@ -1,116 +1,123 @@ -/******************************************************************************* - * 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.api.websocket; - -import java.io.IOException; -import java.util.Optional; - -import io.openems.api.channel.Channel; -import io.openems.api.channel.ChannelChangeListener; -import io.openems.api.channel.ConfigChannel; -import io.openems.api.controller.Controller; -import io.openems.api.doc.ChannelInfo; -import io.openems.api.doc.ThingInfo; -import io.openems.core.utilities.api.ApiWorker; - -@ThingInfo(title = "Websocket-API", description = "Required by OpenEMS-UI.") -public class WebsocketApiController extends Controller implements ChannelChangeListener { - - private final ApiWorker apiWorker = new ApiWorker(); - - /* - * Constructors - */ - public WebsocketApiController() { - super(); - } - - public WebsocketApiController(String thingId) { - super(thingId); - } - - /* - * Config - */ - @ChannelInfo(title = "Port", description = "Sets the port of the Websocket-Api Server.", type = Integer.class, defaultValue = "8085") - public final ConfigChannel port = new ConfigChannel("port", this).addChangeListener(this); - - @ChannelInfo(title = "ChannelTimeout", description = "Sets the timeout for updates to channels.", type = Integer.class, defaultValue = "" - + ApiWorker.DEFAULT_TIMEOUT_SECONDS) - public final ConfigChannel channelTimeout = new ConfigChannel("channelTimeout", this) - .addChangeListener((Channel channel, Optional newValue, Optional oldValue) -> { - if(newValue.isPresent() && Integer.parseInt(newValue.get().toString()) >= 0) { - apiWorker.setTimeoutSeconds(Integer.parseInt(newValue.get().toString())); - } else { - apiWorker.setTimeoutSeconds(ApiWorker.DEFAULT_TIMEOUT_SECONDS); - } - }); - - /* - * Fields - */ - private volatile WebsocketApiServer websocketApiServer = null; - - /* - * Methods - */ - @Override - public void run() { - // Start Websocket-Api server - if (websocketApiServer == null && port.valueOptional().isPresent()) { - try { - websocketApiServer = new WebsocketApiServer(apiWorker, port.valueOptional().get()); - websocketApiServer.start(); - log.info("Websocket-Api started on port [" + port.valueOptional().orElse(0) + "]."); - } catch (Exception e) { - log.error(e.getMessage() + ": " + e.getCause()); - } - } - // call AapiWorker - this.apiWorker.run(); - } - - @Override - public void channelChanged(Channel channel, Optional newValue, Optional oldValue) { - if (channel.equals(port)) { - if (this.websocketApiServer != null) { - try { - this.websocketApiServer.stop(); - } catch (IOException | InterruptedException e) { - log.error("Error closing websocket on port [" + oldValue + "]: " + e.getMessage()); - } - } - this.websocketApiServer = null; - } - } - - /** - * Send a log entry to all connected websockets - * - * @param string - * @param timestamp - * - * @param jMessage - */ - public void broadcastLog(long timestamp, String level, String source, String message) { - this.websocketApiServer.broadcastLog(timestamp, level, source, message); - } -} +/******************************************************************************* + * 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.api.websocket; + +import java.io.IOException; +import java.util.Optional; + +import io.openems.api.channel.Channel; +import io.openems.api.channel.ChannelChangeListener; +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.controller.Controller; +import io.openems.api.doc.ChannelInfo; +import io.openems.api.doc.ThingInfo; +import io.openems.core.utilities.api.ApiWorker; + +@ThingInfo(title = "Websocket-API", description = "Required by OpenEMS-UI.") +public class WebsocketApiController extends Controller implements ChannelChangeListener { + + private final ApiWorker apiWorker = new ApiWorker(); + private ThingStateChannel thingState = new ThingStateChannel(this); + + /* + * Constructors + */ + public WebsocketApiController() { + super(); + } + + public WebsocketApiController(String thingId) { + super(thingId); + } + + /* + * Config + */ + @ChannelInfo(title = "Port", description = "Sets the port of the Websocket-Api Server.", type = Integer.class, defaultValue = "8085") + public final ConfigChannel port = new ConfigChannel("port", this).addChangeListener(this); + + @ChannelInfo(title = "ChannelTimeout", description = "Sets the timeout for updates to channels.", type = Integer.class, defaultValue = "" + + ApiWorker.DEFAULT_TIMEOUT_SECONDS) + public final ConfigChannel channelTimeout = new ConfigChannel("channelTimeout", this) + .addChangeListener((Channel channel, Optional newValue, Optional oldValue) -> { + if(newValue.isPresent() && Integer.parseInt(newValue.get().toString()) >= 0) { + apiWorker.setTimeoutSeconds(Integer.parseInt(newValue.get().toString())); + } else { + apiWorker.setTimeoutSeconds(ApiWorker.DEFAULT_TIMEOUT_SECONDS); + } + }); + + /* + * Fields + */ + private volatile WebsocketApiServer websocketApiServer = null; + + /* + * Methods + */ + @Override + public void run() { + // Start Websocket-Api server + if (websocketApiServer == null && port.valueOptional().isPresent()) { + try { + websocketApiServer = new WebsocketApiServer(apiWorker, port.valueOptional().get()); + websocketApiServer.start(); + log.info("Websocket-Api started on port [" + port.valueOptional().orElse(0) + "]."); + } catch (Exception e) { + log.error(e.getMessage() + ": " + e.getCause()); + } + } + // call AapiWorker + this.apiWorker.run(); + } + + @Override + public void channelChanged(Channel channel, Optional newValue, Optional oldValue) { + if (channel.equals(port)) { + if (this.websocketApiServer != null) { + try { + this.websocketApiServer.stop(); + } catch (IOException | InterruptedException e) { + log.error("Error closing websocket on port [" + oldValue + "]: " + e.getMessage()); + } + } + this.websocketApiServer = null; + } + } + + /** + * Send a log entry to all connected websockets + * + * @param string + * @param timestamp + * + * @param jMessage + */ + public void broadcastLog(long timestamp, String level, String source, String message) { + this.websocketApiServer.broadcastLog(timestamp, level, source, message); + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } +} diff --git a/edge/src/io/openems/impl/controller/asymmetric/avoidtotalcharge/AvoidTotalChargeController.java b/edge/src/io/openems/impl/controller/asymmetric/avoidtotalcharge/AvoidTotalChargeController.java index a17ea82c0ef..49ad0f71392 100644 --- a/edge/src/io/openems/impl/controller/asymmetric/avoidtotalcharge/AvoidTotalChargeController.java +++ b/edge/src/io/openems/impl/controller/asymmetric/avoidtotalcharge/AvoidTotalChargeController.java @@ -10,6 +10,7 @@ */ import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.controller.Controller; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; @@ -19,6 +20,7 @@ @ThingInfo(title = "Avoid total charge of battery. (Asymmetric)", description = "Provides control over the battery's maximum state of charge at a specific time of day. For symmetric Ess.") public class AvoidTotalChargeController extends Controller { + private ThingStateChannel thingState = new ThingStateChannel(this); /* * Config */ @@ -168,4 +170,9 @@ private long getAsymmetricActivePower(long symmetricTotalActivePower, long gridM */ return (long) (((double)(gridMeterTotalActivePower + symmetricTotalActivePower) / (double) 3) - gridMeterActivePower); } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } } diff --git a/edge/src/io/openems/impl/controller/asymmetric/avoidtotaldischarge/AvoidTotalDischargeController.java b/edge/src/io/openems/impl/controller/asymmetric/avoidtotaldischarge/AvoidTotalDischargeController.java index dfb99303e4a..481145845c1 100644 --- a/edge/src/io/openems/impl/controller/asymmetric/avoidtotaldischarge/AvoidTotalDischargeController.java +++ b/edge/src/io/openems/impl/controller/asymmetric/avoidtotaldischarge/AvoidTotalDischargeController.java @@ -1,173 +1,180 @@ -/******************************************************************************* - * 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.asymmetric.avoidtotaldischarge; - -import java.util.Optional; -import java.util.Set; - -import io.openems.api.channel.ConfigChannel; -import io.openems.api.controller.Controller; -import io.openems.api.device.nature.ess.EssNature; -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.impl.controller.asymmetric.avoidtotaldischarge.Ess.State; - -@ThingInfo(title = "Avoid total discharge of battery (Asymmetric)", description = "Makes sure the battery is not going into critically low state of charge. For asymmetric Ess.") -public class AvoidTotalDischargeController extends Controller { - - /* - * Constructors - */ - public AvoidTotalDischargeController() { - super(); - } - - public AvoidTotalDischargeController(String id) { - super(id); - } - - /* - * Config - */ - @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class, isArray = true) - public final ConfigChannel> esss = new ConfigChannel>("esss", this); - @ChannelInfo(title = "Max Soc", description = "If the System is full the charge is blocked untill the soc decrease below the maxSoc.", type = Long.class, defaultValue = "95") - public final ConfigChannel maxSoc = new ConfigChannel("maxSoc", this); - - /* - * Methods - */ - @Override - public void run() { - try { - for (Ess ess : esss.value()) { - /* - * Calculate SetActivePower according to MinSoc - */ - switch (ess.currentState) { - case CHARGESOC: - if (ess.soc.value() > ess.minSoc.value()) { - ess.currentState = State.MINSOC; - } else { - try { - Optional currentMinValueL1 = ess.setActivePowerL1.writeMin(); - if (currentMinValueL1.isPresent() && currentMinValueL1.get() < 0) { - // Force Charge with minimum of MaxChargePower/5 - log.info("Force charge. Set ActivePowerL1=Max[" + currentMinValueL1.get() / 5 + "]"); - ess.setActivePowerL1.pushWriteMax(currentMinValueL1.get() / 5); - } else { - log.info("Avoid discharge. Set ActivePowerL1=Max[-1000 W]"); - ess.setActivePowerL1.pushWriteMax(-1000L); - } - } catch (WriteChannelException e) { - log.error("Unable to set ActivePowerL1: " + e.getMessage()); - } - try { - Optional currentMinValueL2 = ess.setActivePowerL2.writeMin(); - if (currentMinValueL2.isPresent() && currentMinValueL2.get() < 0) { - // Force Charge with minimum of MaxChargePower/5 - log.info("Force charge. Set ActivePowerL2=Max[" + currentMinValueL2.get() / 5 + "]"); - ess.setActivePowerL2.pushWriteMax(currentMinValueL2.get() / 5); - } else { - log.info("Avoid discharge. Set ActivePowerL2=Max[-1000 W]"); - ess.setActivePowerL2.pushWriteMax(-1000L); - } - } catch (WriteChannelException e) { - log.error("Unable to set ActivePowerL2: " + e.getMessage()); - } - try { - Optional currentMinValueL3 = ess.setActivePowerL3.writeMin(); - if (currentMinValueL3.isPresent() && currentMinValueL3.get() < 0) { - // Force Charge with minimum of MaxChargePower/5 - log.info("Force charge. Set ActivePowerL3=Max[" + currentMinValueL3.get() / 5 + "]"); - ess.setActivePowerL3.pushWriteMax(currentMinValueL3.get() / 5); - } else { - log.info("Avoid discharge. Set ActivePowerL3=Max[-1000 W]"); - ess.setActivePowerL3.pushWriteMax(-1000L); - } - } catch (WriteChannelException e) { - log.error("Unable to set ActivePowerL3: " + e.getMessage()); - } - } - break; - case MINSOC: - if (ess.soc.value() < ess.chargeSoc.value()) { - ess.currentState = State.CHARGESOC; - } else if (ess.soc.value() >= ess.minSoc.value() + 5) { - ess.currentState = State.NORMAL; - } else { - try { - long maxPower = 0; - if (!ess.setActivePowerL1.writeMax().isPresent() - || maxPower < ess.setActivePowerL1.writeMax().get()) { - ess.setActivePowerL1.pushWriteMax(maxPower); - } - if (!ess.setActivePowerL2.writeMax().isPresent() - || maxPower < ess.setActivePowerL2.writeMax().get()) { - ess.setActivePowerL2.pushWriteMax(maxPower); - } - if (!ess.setActivePowerL3.writeMax().isPresent() - || maxPower < ess.setActivePowerL3.writeMax().get()) { - ess.setActivePowerL3.pushWriteMax(maxPower); - } - } catch (WriteChannelException e) { - log.error(ess.id() + "Failed to set Max allowed power.", e); - } - } - break; - case NORMAL: - if (ess.soc.value() <= ess.minSoc.value()) { - ess.currentState = State.MINSOC; - } else if (ess.soc.value() >= 99 && ess.allowedCharge.value() == 0 - && ess.systemState.labelOptional().equals(Optional.of(EssNature.START))) { - ess.currentState = State.FULL; - } - break; - case FULL: - try { - ess.setActivePowerL1.pushWriteMin(0L); - } catch (WriteChannelException e) { - log.error("Unable to set ActivePowerL1: " + e.getMessage()); - } - try { - ess.setActivePowerL2.pushWriteMin(0L); - } catch (WriteChannelException e) { - log.error("Unable to set ActivePowerL2: " + e.getMessage()); - } - try { - ess.setActivePowerL3.pushWriteMin(0L); - } catch (WriteChannelException e) { - log.error("Unable to set ActivePowerL3: " + e.getMessage()); - } - if (ess.soc.value() < maxSoc.value()) { - ess.currentState = State.NORMAL; - } - break; - } - } - } catch (InvalidValueException e) { - log.error(e.getMessage()); - } - } - -} +/******************************************************************************* + * 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.asymmetric.avoidtotaldischarge; + +import java.util.Optional; +import java.util.Set; + +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.controller.Controller; +import io.openems.api.device.nature.ess.EssNature; +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.impl.controller.asymmetric.avoidtotaldischarge.Ess.State; + +@ThingInfo(title = "Avoid total discharge of battery (Asymmetric)", description = "Makes sure the battery is not going into critically low state of charge. For asymmetric Ess.") +public class AvoidTotalDischargeController extends Controller { + + private ThingStateChannel thingState = new ThingStateChannel(this); + /* + * Constructors + */ + public AvoidTotalDischargeController() { + super(); + } + + public AvoidTotalDischargeController(String id) { + super(id); + } + + /* + * Config + */ + @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class, isArray = true) + public final ConfigChannel> esss = new ConfigChannel>("esss", this); + @ChannelInfo(title = "Max Soc", description = "If the System is full the charge is blocked untill the soc decrease below the maxSoc.", type = Long.class, defaultValue = "95") + public final ConfigChannel maxSoc = new ConfigChannel("maxSoc", this); + + /* + * Methods + */ + @Override + public void run() { + try { + for (Ess ess : esss.value()) { + /* + * Calculate SetActivePower according to MinSoc + */ + switch (ess.currentState) { + case CHARGESOC: + if (ess.soc.value() > ess.minSoc.value()) { + ess.currentState = State.MINSOC; + } else { + try { + Optional currentMinValueL1 = ess.setActivePowerL1.writeMin(); + if (currentMinValueL1.isPresent() && currentMinValueL1.get() < 0) { + // Force Charge with minimum of MaxChargePower/5 + log.info("Force charge. Set ActivePowerL1=Max[" + currentMinValueL1.get() / 5 + "]"); + ess.setActivePowerL1.pushWriteMax(currentMinValueL1.get() / 5); + } else { + log.info("Avoid discharge. Set ActivePowerL1=Max[-1000 W]"); + ess.setActivePowerL1.pushWriteMax(-1000L); + } + } catch (WriteChannelException e) { + log.error("Unable to set ActivePowerL1: " + e.getMessage()); + } + try { + Optional currentMinValueL2 = ess.setActivePowerL2.writeMin(); + if (currentMinValueL2.isPresent() && currentMinValueL2.get() < 0) { + // Force Charge with minimum of MaxChargePower/5 + log.info("Force charge. Set ActivePowerL2=Max[" + currentMinValueL2.get() / 5 + "]"); + ess.setActivePowerL2.pushWriteMax(currentMinValueL2.get() / 5); + } else { + log.info("Avoid discharge. Set ActivePowerL2=Max[-1000 W]"); + ess.setActivePowerL2.pushWriteMax(-1000L); + } + } catch (WriteChannelException e) { + log.error("Unable to set ActivePowerL2: " + e.getMessage()); + } + try { + Optional currentMinValueL3 = ess.setActivePowerL3.writeMin(); + if (currentMinValueL3.isPresent() && currentMinValueL3.get() < 0) { + // Force Charge with minimum of MaxChargePower/5 + log.info("Force charge. Set ActivePowerL3=Max[" + currentMinValueL3.get() / 5 + "]"); + ess.setActivePowerL3.pushWriteMax(currentMinValueL3.get() / 5); + } else { + log.info("Avoid discharge. Set ActivePowerL3=Max[-1000 W]"); + ess.setActivePowerL3.pushWriteMax(-1000L); + } + } catch (WriteChannelException e) { + log.error("Unable to set ActivePowerL3: " + e.getMessage()); + } + } + break; + case MINSOC: + if (ess.soc.value() < ess.chargeSoc.value()) { + ess.currentState = State.CHARGESOC; + } else if (ess.soc.value() >= ess.minSoc.value() + 5) { + ess.currentState = State.NORMAL; + } else { + try { + long maxPower = 0; + if (!ess.setActivePowerL1.writeMax().isPresent() + || maxPower < ess.setActivePowerL1.writeMax().get()) { + ess.setActivePowerL1.pushWriteMax(maxPower); + } + if (!ess.setActivePowerL2.writeMax().isPresent() + || maxPower < ess.setActivePowerL2.writeMax().get()) { + ess.setActivePowerL2.pushWriteMax(maxPower); + } + if (!ess.setActivePowerL3.writeMax().isPresent() + || maxPower < ess.setActivePowerL3.writeMax().get()) { + ess.setActivePowerL3.pushWriteMax(maxPower); + } + } catch (WriteChannelException e) { + log.error(ess.id() + "Failed to set Max allowed power.", e); + } + } + break; + case NORMAL: + if (ess.soc.value() <= ess.minSoc.value()) { + ess.currentState = State.MINSOC; + } else if (ess.soc.value() >= 99 && ess.allowedCharge.value() == 0 + && ess.systemState.labelOptional().equals(Optional.of(EssNature.START))) { + ess.currentState = State.FULL; + } + break; + case FULL: + try { + ess.setActivePowerL1.pushWriteMin(0L); + } catch (WriteChannelException e) { + log.error("Unable to set ActivePowerL1: " + e.getMessage()); + } + try { + ess.setActivePowerL2.pushWriteMin(0L); + } catch (WriteChannelException e) { + log.error("Unable to set ActivePowerL2: " + e.getMessage()); + } + try { + ess.setActivePowerL3.pushWriteMin(0L); + } catch (WriteChannelException e) { + log.error("Unable to set ActivePowerL3: " + e.getMessage()); + } + if (ess.soc.value() < maxSoc.value()) { + ess.currentState = State.NORMAL; + } + break; + } + } + } catch (InvalidValueException e) { + log.error(e.getMessage()); + } + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + +} diff --git a/edge/src/io/openems/impl/controller/asymmetric/balancing/BalancingController.java b/edge/src/io/openems/impl/controller/asymmetric/balancing/BalancingController.java index 0954fe54a10..eb8bffaba96 100644 --- a/edge/src/io/openems/impl/controller/asymmetric/balancing/BalancingController.java +++ b/edge/src/io/openems/impl/controller/asymmetric/balancing/BalancingController.java @@ -25,6 +25,7 @@ import java.util.Optional; import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -36,6 +37,7 @@ @ThingInfo(title = "Self-consumption optimization (Asymmetric)", description = "Tries to keep the grid meter on zero. For asymmetric Ess.") public class BalancingController extends Controller { + private ThingStateChannel thingState = new ThingStateChannel(this); /* * Constructors */ @@ -325,4 +327,9 @@ private Tupel(T a, T b) { } } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/controller/asymmetric/balancingBandgap/BalancingBandgapActivePowerController.java b/edge/src/io/openems/impl/controller/asymmetric/balancingBandgap/BalancingBandgapActivePowerController.java index 01c5f084bf0..69899b5fa1e 100644 --- a/edge/src/io/openems/impl/controller/asymmetric/balancingBandgap/BalancingBandgapActivePowerController.java +++ b/edge/src/io/openems/impl/controller/asymmetric/balancingBandgap/BalancingBandgapActivePowerController.java @@ -21,6 +21,7 @@ package io.openems.impl.controller.asymmetric.balancingBandgap; import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.controller.Controller; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; @@ -32,6 +33,7 @@ @ThingInfo(title = "Self-consumption optimization (Asymmetric)", description = "Tries to keep the grid meter on zero. For asymmetric Ess.") public class BalancingBandgapActivePowerController extends Controller { + private ThingStateChannel thingState = new ThingStateChannel(this); /* * Constructors */ @@ -134,4 +136,9 @@ public void run() { } } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/controller/asymmetric/balancingBandgap/BalancingBandgapReactivePowerController.java b/edge/src/io/openems/impl/controller/asymmetric/balancingBandgap/BalancingBandgapReactivePowerController.java index 91782aff9c5..744d1ed88cf 100644 --- a/edge/src/io/openems/impl/controller/asymmetric/balancingBandgap/BalancingBandgapReactivePowerController.java +++ b/edge/src/io/openems/impl/controller/asymmetric/balancingBandgap/BalancingBandgapReactivePowerController.java @@ -21,6 +21,7 @@ package io.openems.impl.controller.asymmetric.balancingBandgap; import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.controller.Controller; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; @@ -32,6 +33,7 @@ @ThingInfo(title = "Self-consumption optimization (Asymmetric)", description = "Tries to keep the grid meter on zero. For asymmetric Ess.") public class BalancingBandgapReactivePowerController extends Controller { + private ThingStateChannel thingState = new ThingStateChannel(this); /* * Constructors */ @@ -134,4 +136,9 @@ public void run() { } } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/controller/asymmetric/balancingcurrent/BalancingCurrentController.java b/edge/src/io/openems/impl/controller/asymmetric/balancingcurrent/BalancingCurrentController.java index e6742a2ce70..49f28bb83a9 100644 --- a/edge/src/io/openems/impl/controller/asymmetric/balancingcurrent/BalancingCurrentController.java +++ b/edge/src/io/openems/impl/controller/asymmetric/balancingcurrent/BalancingCurrentController.java @@ -21,6 +21,7 @@ package io.openems.impl.controller.asymmetric.balancingcurrent; import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.controller.Controller; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; @@ -31,6 +32,7 @@ @ThingInfo(title = "Balancing current (Asymmetric)", description = "Tries to keep the grid meter at a given current. For asymmetric Ess.") public class BalancingCurrentController extends Controller { + private ThingStateChannel thingState = new ThingStateChannel(this); /* * Constructors */ @@ -91,4 +93,9 @@ public void run() { } } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/controller/asymmetric/capacitytest/CapacityTestController.java b/edge/src/io/openems/impl/controller/asymmetric/capacitytest/CapacityTestController.java index 68fe30c38b2..2c2e83885c7 100644 --- a/edge/src/io/openems/impl/controller/asymmetric/capacitytest/CapacityTestController.java +++ b/edge/src/io/openems/impl/controller/asymmetric/capacitytest/CapacityTestController.java @@ -1,144 +1,151 @@ -/******************************************************************************* - * 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.asymmetric.capacitytest; - -import java.io.FileWriter; -import java.io.IOException; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.List; -import java.util.Optional; - -import io.openems.api.channel.Channel; -import io.openems.api.channel.ChannelUpdateListener; -import io.openems.api.channel.ConfigChannel; -import io.openems.api.controller.Controller; -import io.openems.api.device.nature.ess.EssNature; -import io.openems.api.doc.ChannelInfo; -import io.openems.api.doc.ThingInfo; -import io.openems.api.exception.InvalidValueException; -import io.openems.api.exception.WriteChannelException; - -@ThingInfo(title = "Battery capacity test (Asymmetric)", description = "Executes a capacity test. For asymmetric Ess.") -public class CapacityTestController extends Controller { - - /* - * Constructors - */ - public CapacityTestController() { - super(); - initialize(); - } - - public CapacityTestController(String thingId) { - super(thingId); - initialize(); - } - - /* - * Config - */ - @ChannelInfo(title = "Power", description = "Discharge power of Ess.", type = Integer.class, defaultValue = "750") - public ConfigChannel power = new ConfigChannel("power", this); - - @ChannelInfo(title = "Log-File", description = "Path to save the logfile.", type = String.class) - public ConfigChannel logPath = new ConfigChannel("logPath", this); - - @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class, isArray = true) - public ConfigChannel> esss = new ConfigChannel>("esss", this); - - /* - * Fields - */ - private FileWriter fw; - - /* - * Methods - */ - private void initialize() { - logPath.addUpdateListener(new ChannelUpdateListener() { - - @Override - public void channelUpdated(Channel channel, Optional newValue) { - try { - if (fw != null) { - fw.close(); - } - fw = new FileWriter(logPath.value()); - fw.write("time;activePowerL1;activePowerL2;activePowerL3;soc\n"); - } catch (IOException e) { - log.error(e.getMessage()); - } catch (InvalidValueException e) { - log.error(e.getMessage()); - } - - } - }); - } - - @Override - public void run() { - try { - for (Ess ess : esss.value()) { - ess.setWorkState.pushWriteFromLabel(EssNature.START); - if (ess.empty) { - // Capacitytest - if (ess.full) { - // fully discharge ess - ess.setActivePowerL1.pushWrite((long) power.value()); - ess.setActivePowerL2.pushWrite((long) power.value()); - ess.setActivePowerL3.pushWrite((long) power.value()); - } else { - // fully charge ess - ess.setActivePowerL1.pushWrite((long) power.value() * -1); - ess.setActivePowerL2.pushWrite((long) power.value() * -1); - ess.setActivePowerL3.pushWrite((long) power.value() * -1); - if (ess.allowedCharge.value() <= 100l - && ess.systemState.labelOptional().equals(Optional.of(EssNature.START))) { - ess.full = true; - } - } - fw.append(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + ";" - + ess.activePowerL1.value() + ";" + ess.activePowerL2.value() + ";" - + ess.activePowerL3.value() + ";" + ess.soc.value() + "\n"); - fw.flush(); - } else { - // prepare for capacityTest - // Empty ess - ess.setActivePowerL1.pushWrite(ess.allowedDischarge.value() / 3); - ess.setActivePowerL2.pushWrite(ess.allowedDischarge.value() / 3); - ess.setActivePowerL3.pushWrite(ess.allowedDischarge.value() / 3); - if (ess.allowedDischarge.value() <= 100l - && ess.systemState.labelOptional().equals(Optional.of(EssNature.START))) { - ess.empty = true; - } - } - } - } catch (InvalidValueException e) { - log.error(e.getMessage()); - } catch (WriteChannelException e) { - log.error(e.getMessage()); - } catch (IOException e) { - log.error(e.getMessage()); - } - } - -} +/******************************************************************************* + * 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.asymmetric.capacitytest; + +import java.io.FileWriter; +import java.io.IOException; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; +import java.util.Optional; + +import io.openems.api.channel.Channel; +import io.openems.api.channel.ChannelUpdateListener; +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.controller.Controller; +import io.openems.api.device.nature.ess.EssNature; +import io.openems.api.doc.ChannelInfo; +import io.openems.api.doc.ThingInfo; +import io.openems.api.exception.InvalidValueException; +import io.openems.api.exception.WriteChannelException; + +@ThingInfo(title = "Battery capacity test (Asymmetric)", description = "Executes a capacity test. For asymmetric Ess.") +public class CapacityTestController extends Controller { + + private ThingStateChannel thingState = new ThingStateChannel(this); + /* + * Constructors + */ + public CapacityTestController() { + super(); + initialize(); + } + + public CapacityTestController(String thingId) { + super(thingId); + initialize(); + } + + /* + * Config + */ + @ChannelInfo(title = "Power", description = "Discharge power of Ess.", type = Integer.class, defaultValue = "750") + public ConfigChannel power = new ConfigChannel("power", this); + + @ChannelInfo(title = "Log-File", description = "Path to save the logfile.", type = String.class) + public ConfigChannel logPath = new ConfigChannel("logPath", this); + + @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class, isArray = true) + public ConfigChannel> esss = new ConfigChannel>("esss", this); + + /* + * Fields + */ + private FileWriter fw; + + /* + * Methods + */ + private void initialize() { + logPath.addUpdateListener(new ChannelUpdateListener() { + + @Override + public void channelUpdated(Channel channel, Optional newValue) { + try { + if (fw != null) { + fw.close(); + } + fw = new FileWriter(logPath.value()); + fw.write("time;activePowerL1;activePowerL2;activePowerL3;soc\n"); + } catch (IOException e) { + log.error(e.getMessage()); + } catch (InvalidValueException e) { + log.error(e.getMessage()); + } + + } + }); + } + + @Override + public void run() { + try { + for (Ess ess : esss.value()) { + ess.setWorkState.pushWriteFromLabel(EssNature.START); + if (ess.empty) { + // Capacitytest + if (ess.full) { + // fully discharge ess + ess.setActivePowerL1.pushWrite((long) power.value()); + ess.setActivePowerL2.pushWrite((long) power.value()); + ess.setActivePowerL3.pushWrite((long) power.value()); + } else { + // fully charge ess + ess.setActivePowerL1.pushWrite((long) power.value() * -1); + ess.setActivePowerL2.pushWrite((long) power.value() * -1); + ess.setActivePowerL3.pushWrite((long) power.value() * -1); + if (ess.allowedCharge.value() <= 100l + && ess.systemState.labelOptional().equals(Optional.of(EssNature.START))) { + ess.full = true; + } + } + fw.append(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + ";" + + ess.activePowerL1.value() + ";" + ess.activePowerL2.value() + ";" + + ess.activePowerL3.value() + ";" + ess.soc.value() + "\n"); + fw.flush(); + } else { + // prepare for capacityTest + // Empty ess + ess.setActivePowerL1.pushWrite(ess.allowedDischarge.value() / 3); + ess.setActivePowerL2.pushWrite(ess.allowedDischarge.value() / 3); + ess.setActivePowerL3.pushWrite(ess.allowedDischarge.value() / 3); + if (ess.allowedDischarge.value() <= 100l + && ess.systemState.labelOptional().equals(Optional.of(EssNature.START))) { + ess.empty = true; + } + } + } + } catch (InvalidValueException e) { + log.error(e.getMessage()); + } catch (WriteChannelException e) { + log.error(e.getMessage()); + } catch (IOException e) { + log.error(e.getMessage()); + } + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + +} diff --git a/edge/src/io/openems/impl/controller/asymmetric/fixvalue/FixValueActivePowerController.java b/edge/src/io/openems/impl/controller/asymmetric/fixvalue/FixValueActivePowerController.java index 91f7b8b4b55..fe3d01bdf18 100644 --- a/edge/src/io/openems/impl/controller/asymmetric/fixvalue/FixValueActivePowerController.java +++ b/edge/src/io/openems/impl/controller/asymmetric/fixvalue/FixValueActivePowerController.java @@ -23,6 +23,7 @@ import java.util.Set; import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.controller.Controller; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; @@ -33,6 +34,7 @@ @ThingInfo(title = "Fixed active and reactive power (Asymmetric)", description = "Charges or discharges the battery with a predefined, fixed power. For asymmetric Ess.") public class FixValueActivePowerController extends Controller { + private ThingStateChannel thingState = new ThingStateChannel(this); /* * Constructors */ @@ -76,4 +78,9 @@ public void run() { } } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/controller/asymmetric/fixvalue/FixValueReactivePowerController.java b/edge/src/io/openems/impl/controller/asymmetric/fixvalue/FixValueReactivePowerController.java index 918b35b3a03..46a44970b49 100644 --- a/edge/src/io/openems/impl/controller/asymmetric/fixvalue/FixValueReactivePowerController.java +++ b/edge/src/io/openems/impl/controller/asymmetric/fixvalue/FixValueReactivePowerController.java @@ -1,75 +1,82 @@ -/******************************************************************************* - * 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.asymmetric.fixvalue; - -import java.util.Set; - -import io.openems.api.channel.ConfigChannel; -import io.openems.api.controller.Controller; -import io.openems.api.doc.ChannelInfo; -import io.openems.api.doc.ThingInfo; -import io.openems.api.exception.InvalidValueException; - -@ThingInfo(title = "Fixed active and reactive power (Asymmetric)", description = "Charges or discharges the battery with a predefined, fixed power. For asymmetric Ess.") -public class FixValueReactivePowerController extends Controller { - - /* - * Constructors - */ - public FixValueReactivePowerController() { - super(); - } - - public FixValueReactivePowerController(String thingId) { - super(thingId); - } - - /* - * Config - */ - @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class, isArray = true) - public final ConfigChannel> esss = new ConfigChannel>("esss", this); - - @ChannelInfo(title = "ReactivePower L1", description = "Fixed reactive power for phase L1.", type = Long.class) - public final ConfigChannel reactivePowerL1 = new ConfigChannel<>("reactivePowerL1", this); - - @ChannelInfo(title = "ReactivePower L2", description = "Fixed reactive power for phase L2.", type = Long.class) - public final ConfigChannel reactivePowerL2 = new ConfigChannel<>("reactivePowerL2", this); - - @ChannelInfo(title = "ReactivePower L3", description = "Fixed reactive power for phase L3.", type = Long.class) - public final ConfigChannel reactivePowerL3 = new ConfigChannel<>("reactivePowerL3", this); - - /* - * Methods - */ - @Override - public void run() { - try { - for (Ess ess : esss.value()) { - ess.power.setReactivePower(reactivePowerL1.value(), reactivePowerL2.value(), reactivePowerL3.value()); - } - } catch (InvalidValueException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - -} +/******************************************************************************* + * 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.asymmetric.fixvalue; + +import java.util.Set; + +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.controller.Controller; +import io.openems.api.doc.ChannelInfo; +import io.openems.api.doc.ThingInfo; +import io.openems.api.exception.InvalidValueException; + +@ThingInfo(title = "Fixed active and reactive power (Asymmetric)", description = "Charges or discharges the battery with a predefined, fixed power. For asymmetric Ess.") +public class FixValueReactivePowerController extends Controller { + + private ThingStateChannel thingState = new ThingStateChannel(this); + /* + * Constructors + */ + public FixValueReactivePowerController() { + super(); + } + + public FixValueReactivePowerController(String thingId) { + super(thingId); + } + + /* + * Config + */ + @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class, isArray = true) + public final ConfigChannel> esss = new ConfigChannel>("esss", this); + + @ChannelInfo(title = "ReactivePower L1", description = "Fixed reactive power for phase L1.", type = Long.class) + public final ConfigChannel reactivePowerL1 = new ConfigChannel<>("reactivePowerL1", this); + + @ChannelInfo(title = "ReactivePower L2", description = "Fixed reactive power for phase L2.", type = Long.class) + public final ConfigChannel reactivePowerL2 = new ConfigChannel<>("reactivePowerL2", this); + + @ChannelInfo(title = "ReactivePower L3", description = "Fixed reactive power for phase L3.", type = Long.class) + public final ConfigChannel reactivePowerL3 = new ConfigChannel<>("reactivePowerL3", this); + + /* + * Methods + */ + @Override + public void run() { + try { + for (Ess ess : esss.value()) { + ess.power.setReactivePower(reactivePowerL1.value(), reactivePowerL2.value(), reactivePowerL3.value()); + } + } catch (InvalidValueException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + +} diff --git a/edge/src/io/openems/impl/controller/asymmetric/phaserectification/PhaseRectificationActivePowerController.java b/edge/src/io/openems/impl/controller/asymmetric/phaserectification/PhaseRectificationActivePowerController.java index 6e0c247cd54..9cfab63736e 100644 --- a/edge/src/io/openems/impl/controller/asymmetric/phaserectification/PhaseRectificationActivePowerController.java +++ b/edge/src/io/openems/impl/controller/asymmetric/phaserectification/PhaseRectificationActivePowerController.java @@ -1,6 +1,7 @@ package io.openems.impl.controller.asymmetric.phaserectification; import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.controller.Controller; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; @@ -12,6 +13,8 @@ @ThingInfo(title = "PhaseRectificationActivePowerController", description = "Sets the ess to the required activepower to get all three phases on the meter to the same level.") public class PhaseRectificationActivePowerController extends Controller { + private ThingStateChannel thingState = new ThingStateChannel(this); + @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class) public ConfigChannel ess = new ConfigChannel("ess", this); @@ -68,4 +71,9 @@ public void run() { } } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/controller/asymmetric/phaserectification/PhaseRectificationReactivePowerController.java b/edge/src/io/openems/impl/controller/asymmetric/phaserectification/PhaseRectificationReactivePowerController.java index efd65dcebb5..7780038dc89 100644 --- a/edge/src/io/openems/impl/controller/asymmetric/phaserectification/PhaseRectificationReactivePowerController.java +++ b/edge/src/io/openems/impl/controller/asymmetric/phaserectification/PhaseRectificationReactivePowerController.java @@ -1,6 +1,7 @@ package io.openems.impl.controller.asymmetric.phaserectification; import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.controller.Controller; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; @@ -11,6 +12,8 @@ @ThingInfo(title = "PhaseRectificationReactivePowerController", description = "Sets the ess to the required reactivepower to get all three phases on the meter to the same level.") public class PhaseRectificationReactivePowerController extends Controller { + private ThingStateChannel thingState = new ThingStateChannel(this); + @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class) public ConfigChannel ess = new ConfigChannel("ess", this); @@ -56,4 +59,9 @@ public void run() { } } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/controller/asymmetric/powerlimitation/PowerLimitationController.java b/edge/src/io/openems/impl/controller/asymmetric/powerlimitation/PowerLimitationController.java index b6a1ed69bfd..fa8642a8078 100644 --- a/edge/src/io/openems/impl/controller/asymmetric/powerlimitation/PowerLimitationController.java +++ b/edge/src/io/openems/impl/controller/asymmetric/powerlimitation/PowerLimitationController.java @@ -1,157 +1,164 @@ -/******************************************************************************* - * 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.asymmetric.powerlimitation; - -import io.openems.api.channel.ConfigChannel; -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; - -@ThingInfo(title = "Power limitation (Asymmetric)", description = "Limits the active and reactive power of the Ess. For Asymmetric Ess.") -public class PowerLimitationController extends Controller { - - /* - * Constructors - */ - public PowerLimitationController() { - super(); - } - - public PowerLimitationController(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 = "Min-Charge ActivePower", description = "The minimum allowed active power for discharge. Value is negative.", type = Long.class) - public ConfigChannel pMin = new ConfigChannel("pMin", this); - - @ChannelInfo(title = "Max-Charge ActivePower", description = "The maximum allowed active power for discharge. Value is positive.", type = Long.class) - public ConfigChannel pMax = new ConfigChannel("pMax", this); - - @ChannelInfo(title = "Min-Charge ReactivePower", description = "The minimum allowed reactive power for discharge. Value is negative.", type = Long.class) - public ConfigChannel qMin = new ConfigChannel("qMin", this); - - @ChannelInfo(title = "Max-Charge ReactivePower", description = "The maximum allowed reactive power for discharge. Value is positive.", type = Long.class) - public ConfigChannel qMax = new ConfigChannel("qMax", this); - - /* - * Methods - */ - @Override - public void run() { - try { - try { - if (pMax.value() < ess.value().setActivePowerL1.writeMax().orElse(Long.MAX_VALUE)) { - ess.value().setActivePowerL1.pushWriteMax(pMax.value()); - } - } catch (WriteChannelException | InvalidValueException e) { - log.error("Failed to write Max P value for [" + ess.value().id + "]: " + e.getMessage()); - } - try { - if (pMin.value() > ess.value().setActivePowerL1.writeMin().orElse(Long.MIN_VALUE)) { - ess.value().setActivePowerL1.pushWriteMin(pMin.value()); - } - } catch (WriteChannelException | InvalidValueException e) { - log.error("Failed to write Min P value for [" + ess.value().id + "]: " + e.getMessage()); - } - try { - if (qMin.value() > ess.value().setReactivePowerL1.writeMin().orElse(Long.MIN_VALUE)) { - ess.value().setReactivePowerL1.pushWriteMin(qMin.value()); - } - } catch (WriteChannelException | InvalidValueException e) { - log.error("Failed to write Min Q value for [" + ess.value().id + "]: " + e.getMessage()); - } - try { - if (qMax.value() < ess.value().setReactivePowerL1.writeMax().orElse(Long.MAX_VALUE)) { - ess.value().setReactivePowerL1.pushWriteMax(qMax.value()); - } - } catch (WriteChannelException | InvalidValueException e) { - log.error("Failed to write Max Q value for [" + ess.value().id + "]: " + e.getMessage()); - } - try { - if (pMax.value() < ess.value().setActivePowerL2.writeMax().orElse(Long.MAX_VALUE)) { - ess.value().setActivePowerL2.pushWriteMax(pMax.value()); - } - } catch (WriteChannelException | InvalidValueException e) { - log.error("Failed to write Max P value for [" + ess.value().id + "]: " + e.getMessage()); - } - try { - if (pMin.value() > ess.value().setActivePowerL2.writeMin().orElse(Long.MIN_VALUE)) { - ess.value().setActivePowerL2.pushWriteMin(pMin.value()); - } - } catch (WriteChannelException | InvalidValueException e) { - log.error("Failed to write Min P value for [" + ess.value().id + "]: " + e.getMessage()); - } - try { - if (qMin.value() > ess.value().setReactivePowerL2.writeMin().orElse(Long.MIN_VALUE)) { - ess.value().setReactivePowerL2.pushWriteMin(qMin.value()); - } - } catch (WriteChannelException | InvalidValueException e) { - log.error("Failed to write Min Q value for [" + ess.value().id + "]: " + e.getMessage()); - } - try { - if (qMax.value() < ess.value().setReactivePowerL2.writeMax().orElse(Long.MAX_VALUE)) { - ess.value().setReactivePowerL2.pushWriteMax(qMax.value()); - } - } catch (WriteChannelException | InvalidValueException e) { - log.error("Failed to write Max Q value for [" + ess.value().id + "]: " + e.getMessage()); - } - try { - if (pMax.value() < ess.value().setActivePowerL3.writeMax().orElse(Long.MAX_VALUE)) { - ess.value().setActivePowerL3.pushWriteMax(pMax.value()); - } - } catch (WriteChannelException | InvalidValueException e) { - log.error("Failed to write Max P value for [" + ess.value().id + "]: " + e.getMessage()); - } - try { - if (pMin.value() > ess.value().setActivePowerL3.writeMin().orElse(Long.MIN_VALUE)) { - ess.value().setActivePowerL3.pushWriteMin(pMin.value()); - } - } catch (WriteChannelException | InvalidValueException e) { - log.error("Failed to write Min P value for [" + ess.value().id + "]: " + e.getMessage()); - } - try { - if (qMin.value() > ess.value().setReactivePowerL3.writeMin().orElse(Long.MIN_VALUE)) { - ess.value().setReactivePowerL3.pushWriteMin(qMin.value()); - } - } catch (WriteChannelException | InvalidValueException e) { - log.error("Failed to write Min Q value for [" + ess.value().id + "]: " + e.getMessage()); - } - try { - if (qMax.value() < ess.value().setReactivePowerL3.writeMax().orElse(Long.MAX_VALUE)) { - ess.value().setReactivePowerL3.pushWriteMax(qMax.value()); - } - } catch (WriteChannelException | InvalidValueException e) { - log.error("Failed to write Max Q value for [" + ess.value().id + "]: " + e.getMessage()); - } - } catch (InvalidValueException e) { - log.error("No ess found.", e); - } - } - -} +/******************************************************************************* + * 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.asymmetric.powerlimitation; + +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +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; + +@ThingInfo(title = "Power limitation (Asymmetric)", description = "Limits the active and reactive power of the Ess. For Asymmetric Ess.") +public class PowerLimitationController extends Controller { + + private ThingStateChannel thingState = new ThingStateChannel(this); + /* + * Constructors + */ + public PowerLimitationController() { + super(); + } + + public PowerLimitationController(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 = "Min-Charge ActivePower", description = "The minimum allowed active power for discharge. Value is negative.", type = Long.class) + public ConfigChannel pMin = new ConfigChannel("pMin", this); + + @ChannelInfo(title = "Max-Charge ActivePower", description = "The maximum allowed active power for discharge. Value is positive.", type = Long.class) + public ConfigChannel pMax = new ConfigChannel("pMax", this); + + @ChannelInfo(title = "Min-Charge ReactivePower", description = "The minimum allowed reactive power for discharge. Value is negative.", type = Long.class) + public ConfigChannel qMin = new ConfigChannel("qMin", this); + + @ChannelInfo(title = "Max-Charge ReactivePower", description = "The maximum allowed reactive power for discharge. Value is positive.", type = Long.class) + public ConfigChannel qMax = new ConfigChannel("qMax", this); + + /* + * Methods + */ + @Override + public void run() { + try { + try { + if (pMax.value() < ess.value().setActivePowerL1.writeMax().orElse(Long.MAX_VALUE)) { + ess.value().setActivePowerL1.pushWriteMax(pMax.value()); + } + } catch (WriteChannelException | InvalidValueException e) { + log.error("Failed to write Max P value for [" + ess.value().id + "]: " + e.getMessage()); + } + try { + if (pMin.value() > ess.value().setActivePowerL1.writeMin().orElse(Long.MIN_VALUE)) { + ess.value().setActivePowerL1.pushWriteMin(pMin.value()); + } + } catch (WriteChannelException | InvalidValueException e) { + log.error("Failed to write Min P value for [" + ess.value().id + "]: " + e.getMessage()); + } + try { + if (qMin.value() > ess.value().setReactivePowerL1.writeMin().orElse(Long.MIN_VALUE)) { + ess.value().setReactivePowerL1.pushWriteMin(qMin.value()); + } + } catch (WriteChannelException | InvalidValueException e) { + log.error("Failed to write Min Q value for [" + ess.value().id + "]: " + e.getMessage()); + } + try { + if (qMax.value() < ess.value().setReactivePowerL1.writeMax().orElse(Long.MAX_VALUE)) { + ess.value().setReactivePowerL1.pushWriteMax(qMax.value()); + } + } catch (WriteChannelException | InvalidValueException e) { + log.error("Failed to write Max Q value for [" + ess.value().id + "]: " + e.getMessage()); + } + try { + if (pMax.value() < ess.value().setActivePowerL2.writeMax().orElse(Long.MAX_VALUE)) { + ess.value().setActivePowerL2.pushWriteMax(pMax.value()); + } + } catch (WriteChannelException | InvalidValueException e) { + log.error("Failed to write Max P value for [" + ess.value().id + "]: " + e.getMessage()); + } + try { + if (pMin.value() > ess.value().setActivePowerL2.writeMin().orElse(Long.MIN_VALUE)) { + ess.value().setActivePowerL2.pushWriteMin(pMin.value()); + } + } catch (WriteChannelException | InvalidValueException e) { + log.error("Failed to write Min P value for [" + ess.value().id + "]: " + e.getMessage()); + } + try { + if (qMin.value() > ess.value().setReactivePowerL2.writeMin().orElse(Long.MIN_VALUE)) { + ess.value().setReactivePowerL2.pushWriteMin(qMin.value()); + } + } catch (WriteChannelException | InvalidValueException e) { + log.error("Failed to write Min Q value for [" + ess.value().id + "]: " + e.getMessage()); + } + try { + if (qMax.value() < ess.value().setReactivePowerL2.writeMax().orElse(Long.MAX_VALUE)) { + ess.value().setReactivePowerL2.pushWriteMax(qMax.value()); + } + } catch (WriteChannelException | InvalidValueException e) { + log.error("Failed to write Max Q value for [" + ess.value().id + "]: " + e.getMessage()); + } + try { + if (pMax.value() < ess.value().setActivePowerL3.writeMax().orElse(Long.MAX_VALUE)) { + ess.value().setActivePowerL3.pushWriteMax(pMax.value()); + } + } catch (WriteChannelException | InvalidValueException e) { + log.error("Failed to write Max P value for [" + ess.value().id + "]: " + e.getMessage()); + } + try { + if (pMin.value() > ess.value().setActivePowerL3.writeMin().orElse(Long.MIN_VALUE)) { + ess.value().setActivePowerL3.pushWriteMin(pMin.value()); + } + } catch (WriteChannelException | InvalidValueException e) { + log.error("Failed to write Min P value for [" + ess.value().id + "]: " + e.getMessage()); + } + try { + if (qMin.value() > ess.value().setReactivePowerL3.writeMin().orElse(Long.MIN_VALUE)) { + ess.value().setReactivePowerL3.pushWriteMin(qMin.value()); + } + } catch (WriteChannelException | InvalidValueException e) { + log.error("Failed to write Min Q value for [" + ess.value().id + "]: " + e.getMessage()); + } + try { + if (qMax.value() < ess.value().setReactivePowerL3.writeMax().orElse(Long.MAX_VALUE)) { + ess.value().setReactivePowerL3.pushWriteMax(qMax.value()); + } + } catch (WriteChannelException | InvalidValueException e) { + log.error("Failed to write Max Q value for [" + ess.value().id + "]: " + e.getMessage()); + } + } catch (InvalidValueException e) { + log.error("No ess found.", e); + } + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + +} diff --git a/edge/src/io/openems/impl/controller/asymmetricsymmetriccombination/AsymmetricSymmetricCombinationController.java b/edge/src/io/openems/impl/controller/asymmetricsymmetriccombination/AsymmetricSymmetricCombinationController.java index 5552310bb69..dde66a7a8b6 100644 --- a/edge/src/io/openems/impl/controller/asymmetricsymmetriccombination/AsymmetricSymmetricCombinationController.java +++ b/edge/src/io/openems/impl/controller/asymmetricsymmetriccombination/AsymmetricSymmetricCombinationController.java @@ -11,7 +11,7 @@ @ThingInfo(title = "starts power calculation of AsymmetricSymmetricCombination Ess device") public class AsymmetricSymmetricCombinationController extends Controller { - private ThingStateChannel thingState; + private ThingStateChannel thingState = new ThingStateChannel(this); @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class) public final ConfigChannel ess = new ConfigChannel("ess", this); @@ -20,7 +20,6 @@ public class AsymmetricSymmetricCombinationController extends Controller { public AsymmetricSymmetricCombinationController() { super(); - this.thingState = new ThingStateChannel(this); } diff --git a/edge/src/io/openems/impl/controller/channelthreshold/ChannelThresholdController.java b/edge/src/io/openems/impl/controller/channelthreshold/ChannelThresholdController.java index 86d247d326b..014b3fd10ae 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.ThingStateChannel; +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 ThingStateChannel thingState = new ThingStateChannel(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 ThingStateChannel 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..7ca578f4c50 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.ThingStateChannel; +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 ThingStateChannel thingState = new ThingStateChannel(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> 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(); + // } + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + +} diff --git a/edge/src/io/openems/impl/controller/clocksync/ClockSyncController.java b/edge/src/io/openems/impl/controller/clocksync/ClockSyncController.java index bf61965d3bb..b8095d4d89a 100644 --- a/edge/src/io/openems/impl/controller/clocksync/ClockSyncController.java +++ b/edge/src/io/openems/impl/controller/clocksync/ClockSyncController.java @@ -1,114 +1,121 @@ -/******************************************************************************* - * 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.clocksync; - -import java.io.IOException; -import java.util.Calendar; -import java.util.Optional; - -import io.openems.api.channel.ConfigChannel; -import io.openems.api.controller.Controller; -import io.openems.api.doc.ChannelInfo; -import io.openems.api.doc.ThingInfo; -import io.openems.api.exception.WriteChannelException; - -@ThingInfo(title = "Sychronizes system clocks", description = "Synchronizes the sytem clocks of OpenEMS and a connected real-time clock device.") -public class ClockSyncController extends Controller { - - /* - * Constructors - */ - public ClockSyncController() { - super(); - } - - public ClockSyncController(String thingId) { - super(thingId); - } - - /* - * Config - */ - @ChannelInfo(title = "Real-time clock", description = "Sets the real-time clock device.", type = RealTimeClock.class, isOptional = true) - public final ConfigChannel rtc = new ConfigChannel("rtc", this); - - /* - * Fields - */ - private boolean isDateSet = false; - - /* - * Methods - */ - @Override - public void run() { - if (isDateSet) { - // Set time only once in the beginning - return; - } - if (rtc.valueOptional().isPresent()) { - RealTimeClock r = rtc.valueOptional().get(); - Optional rtcYear = r.year.valueOptional(); - Optional rtcMonth = r.month.valueOptional(); - Optional rtcDay = r.day.valueOptional(); - Optional rtcHour = r.hour.valueOptional(); - Optional rtcMinute = r.hour.valueOptional(); - Optional rtcSecond = r.second.valueOptional(); - - if (rtcYear.isPresent() && rtcMonth.isPresent() && rtcDay.isPresent() && rtcHour.isPresent() - && rtcMinute.isPresent() && rtcSecond.isPresent()) { - - Calendar systemNow = Calendar.getInstance(); - int year = systemNow.get(Calendar.YEAR); - if (year < 2016) { - // System date is wrong -> set system date from RTC - log.info("Setting system time from RTC: " + rtc.id() + ": " + rtcYear.get() + "-" + rtcMonth.get() - + "-" + rtcDay.get() + " " + rtcHour.get() + ":" + rtcMinute.get() + ":" + rtcSecond.get()); - try { - Runtime.getRuntime() - .exec(new String[] { "/usr/bin/timedatectl", "set-time", "2016-10-11 13:13:16" }); - // process is running in a separate process from now... - } catch (IOException e) { - log.error("Error while setting system time: ", e); - } - } else { - // System date is correct -> set RTC from system date - log.info("Setting RTC from system time: " + rtc.id() + ": " + systemNow.get(Calendar.YEAR) + "-" - + systemNow.get(Calendar.MONTH) + "-" + systemNow.get(Calendar.DAY_OF_MONTH) + " " - + systemNow.get(Calendar.HOUR_OF_DAY) + ":" + systemNow.get(Calendar.MINUTE) + ":" - + systemNow.get(Calendar.SECOND)); - try { - r.year.pushWrite(Long.valueOf(systemNow.get(Calendar.YEAR))); - r.month.pushWrite(Long.valueOf(systemNow.get(Calendar.MONTH))); - r.day.pushWrite(Long.valueOf(systemNow.get(Calendar.DAY_OF_MONTH))); - r.hour.pushWrite(Long.valueOf(systemNow.get(Calendar.HOUR_OF_DAY))); - r.minute.pushWrite(Long.valueOf(systemNow.get(Calendar.MINUTE))); - r.second.pushWrite(Long.valueOf(systemNow.get(Calendar.SECOND))); - } catch (WriteChannelException e) { - log.error("Error while setting RTC time: ", e); - } - } - - isDateSet = true; - } - } - } -} +/******************************************************************************* + * 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.clocksync; + +import java.io.IOException; +import java.util.Calendar; +import java.util.Optional; + +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.controller.Controller; +import io.openems.api.doc.ChannelInfo; +import io.openems.api.doc.ThingInfo; +import io.openems.api.exception.WriteChannelException; + +@ThingInfo(title = "Sychronizes system clocks", description = "Synchronizes the sytem clocks of OpenEMS and a connected real-time clock device.") +public class ClockSyncController extends Controller { + + private ThingStateChannel thingState = new ThingStateChannel(this); + /* + * Constructors + */ + public ClockSyncController() { + super(); + } + + public ClockSyncController(String thingId) { + super(thingId); + } + + /* + * Config + */ + @ChannelInfo(title = "Real-time clock", description = "Sets the real-time clock device.", type = RealTimeClock.class, isOptional = true) + public final ConfigChannel rtc = new ConfigChannel("rtc", this); + + /* + * Fields + */ + private boolean isDateSet = false; + + /* + * Methods + */ + @Override + public void run() { + if (isDateSet) { + // Set time only once in the beginning + return; + } + if (rtc.valueOptional().isPresent()) { + RealTimeClock r = rtc.valueOptional().get(); + Optional rtcYear = r.year.valueOptional(); + Optional rtcMonth = r.month.valueOptional(); + Optional rtcDay = r.day.valueOptional(); + Optional rtcHour = r.hour.valueOptional(); + Optional rtcMinute = r.hour.valueOptional(); + Optional rtcSecond = r.second.valueOptional(); + + if (rtcYear.isPresent() && rtcMonth.isPresent() && rtcDay.isPresent() && rtcHour.isPresent() + && rtcMinute.isPresent() && rtcSecond.isPresent()) { + + Calendar systemNow = Calendar.getInstance(); + int year = systemNow.get(Calendar.YEAR); + if (year < 2016) { + // System date is wrong -> set system date from RTC + log.info("Setting system time from RTC: " + rtc.id() + ": " + rtcYear.get() + "-" + rtcMonth.get() + + "-" + rtcDay.get() + " " + rtcHour.get() + ":" + rtcMinute.get() + ":" + rtcSecond.get()); + try { + Runtime.getRuntime() + .exec(new String[] { "/usr/bin/timedatectl", "set-time", "2016-10-11 13:13:16" }); + // process is running in a separate process from now... + } catch (IOException e) { + log.error("Error while setting system time: ", e); + } + } else { + // System date is correct -> set RTC from system date + log.info("Setting RTC from system time: " + rtc.id() + ": " + systemNow.get(Calendar.YEAR) + "-" + + systemNow.get(Calendar.MONTH) + "-" + systemNow.get(Calendar.DAY_OF_MONTH) + " " + + systemNow.get(Calendar.HOUR_OF_DAY) + ":" + systemNow.get(Calendar.MINUTE) + ":" + + systemNow.get(Calendar.SECOND)); + try { + r.year.pushWrite(Long.valueOf(systemNow.get(Calendar.YEAR))); + r.month.pushWrite(Long.valueOf(systemNow.get(Calendar.MONTH))); + r.day.pushWrite(Long.valueOf(systemNow.get(Calendar.DAY_OF_MONTH))); + r.hour.pushWrite(Long.valueOf(systemNow.get(Calendar.HOUR_OF_DAY))); + r.minute.pushWrite(Long.valueOf(systemNow.get(Calendar.MINUTE))); + r.second.pushWrite(Long.valueOf(systemNow.get(Calendar.SECOND))); + } catch (WriteChannelException e) { + log.error("Error while setting RTC time: ", e); + } + } + + isDateSet = true; + } + } + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } +} diff --git a/edge/src/io/openems/impl/controller/debuglog/DebugLogController.java b/edge/src/io/openems/impl/controller/debuglog/DebugLogController.java index 1fb4da9388b..5751f51fd6a 100644 --- a/edge/src/io/openems/impl/controller/debuglog/DebugLogController.java +++ b/edge/src/io/openems/impl/controller/debuglog/DebugLogController.java @@ -1,97 +1,104 @@ -/******************************************************************************* - * 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.debuglog; - -import java.util.Set; - -import io.openems.api.channel.ConfigChannel; -import io.openems.api.controller.Controller; -import io.openems.api.doc.ChannelInfo; -import io.openems.api.doc.ThingInfo; -import io.openems.api.exception.InvalidValueException; - -// TODO Access all relevant channels directly via ThingRepository - -@ThingInfo(title = "Output debugging information on systemlog") -public class DebugLogController extends Controller { - - /* - * Constructors - */ - public DebugLogController() { - super(); - } - - public DebugLogController(String thingId) { - super(thingId); - } - - /* - * Config - */ - @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class, isOptional = true, isArray = true) - public final ConfigChannel> esss = new ConfigChannel>("esss", this); - - @ChannelInfo(title = "Meters", description = "Sets the meters.", type = Meter.class, isOptional = true, isArray = true) - public final ConfigChannel> meters = new ConfigChannel>("meters", this); - - @ChannelInfo(title = "Real-time clock", description = "Sets the real-time clock.", type = RealTimeClock.class, isOptional = true) - public final ConfigChannel rtc = new ConfigChannel("rtc", this); - - @ChannelInfo(title = "EVCSs", description = "Sets the evcs.", type = Evcs.class, isOptional = true, isArray = true) - public final ConfigChannel> evcss = new ConfigChannel>("evcss", this); - - /* - * Methods - */ - @Override - public void run() { - try { - StringBuilder b = new StringBuilder(); - if (meters.valueOptional().isPresent()) { - for (Meter meter : meters.value()) { - b.append(meter.toString()); - b.append(" "); - } - } - if (rtc.valueOptional().isPresent()) { - b.append(rtc.valueOptional().get().toString()); - b.append(" "); - } - if (esss.valueOptional().isPresent()) { - for (Ess ess : esss.value()) { - b.append(ess.toString()); - b.append(" "); - } - } - if (evcss.valueOptional().isPresent()) { - for (Evcs evcs : evcss.value()) { - b.append(evcs.toString()); - b.append(" "); - } - } - log.info(b.toString()); - } catch (InvalidValueException e) { - e.printStackTrace(); - } - } - -} +/******************************************************************************* + * 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.debuglog; + +import java.util.Set; + +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.controller.Controller; +import io.openems.api.doc.ChannelInfo; +import io.openems.api.doc.ThingInfo; +import io.openems.api.exception.InvalidValueException; + +// TODO Access all relevant channels directly via ThingRepository + +@ThingInfo(title = "Output debugging information on systemlog") +public class DebugLogController extends Controller { + + private ThingStateChannel thingState = new ThingStateChannel(this); + /* + * Constructors + */ + public DebugLogController() { + super(); + } + + public DebugLogController(String thingId) { + super(thingId); + } + + /* + * Config + */ + @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class, isOptional = true, isArray = true) + public final ConfigChannel> esss = new ConfigChannel>("esss", this); + + @ChannelInfo(title = "Meters", description = "Sets the meters.", type = Meter.class, isOptional = true, isArray = true) + public final ConfigChannel> meters = new ConfigChannel>("meters", this); + + @ChannelInfo(title = "Real-time clock", description = "Sets the real-time clock.", type = RealTimeClock.class, isOptional = true) + public final ConfigChannel rtc = new ConfigChannel("rtc", this); + + @ChannelInfo(title = "EVCSs", description = "Sets the evcs.", type = Evcs.class, isOptional = true, isArray = true) + public final ConfigChannel> evcss = new ConfigChannel>("evcss", this); + + /* + * Methods + */ + @Override + public void run() { + try { + StringBuilder b = new StringBuilder(); + if (meters.valueOptional().isPresent()) { + for (Meter meter : meters.value()) { + b.append(meter.toString()); + b.append(" "); + } + } + if (rtc.valueOptional().isPresent()) { + b.append(rtc.valueOptional().get().toString()); + b.append(" "); + } + if (esss.valueOptional().isPresent()) { + for (Ess ess : esss.value()) { + b.append(ess.toString()); + b.append(" "); + } + } + if (evcss.valueOptional().isPresent()) { + for (Evcs evcs : evcss.value()) { + b.append(evcs.toString()); + b.append(" "); + } + } + log.info(b.toString()); + } catch (InvalidValueException e) { + e.printStackTrace(); + } + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + +} diff --git a/edge/src/io/openems/impl/controller/debuglog/Ess.java b/edge/src/io/openems/impl/controller/debuglog/Ess.java index 53938bc927a..8a85a48989e 100644 --- a/edge/src/io/openems/impl/controller/debuglog/Ess.java +++ b/edge/src/io/openems/impl/controller/debuglog/Ess.java @@ -1,89 +1,103 @@ -/******************************************************************************* - * 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.debuglog; - -import io.openems.api.controller.IsThingMap; -import io.openems.api.controller.ThingMap; -import io.openems.api.device.nature.ess.AsymmetricEssNature; -import io.openems.api.device.nature.ess.EssNature; -import io.openems.api.device.nature.ess.SymmetricEssNature; - -@IsThingMap(type = EssNature.class) -public class Ess extends ThingMap { - - private final EssNature ess; - - public Ess(EssNature ess) { - super(ess); - this.ess = ess; - - ess.allowedCharge().required(); - ess.allowedDischarge().required(); - ess.minSoc().required(); - ess.soc().required(); - ess.systemState().required(); - - if (ess instanceof AsymmetricEssNature) { - AsymmetricEssNature e = (AsymmetricEssNature) ess; - e.activePowerL1().required(); - e.activePowerL2().required(); - e.activePowerL3().required(); - e.reactivePowerL1().required(); - e.reactivePowerL2().required(); - e.reactivePowerL3().required(); - } - if (ess instanceof SymmetricEssNature) { - SymmetricEssNature e = (SymmetricEssNature) ess; - e.activePower().required(); - e.reactivePower().required(); - } - } - - @Override public String toString() { - StringBuilder b = new StringBuilder(); - b.append(ess.id() + " [" + // - "SOC:" + ess.soc().format() + "|"); - if (ess instanceof SymmetricEssNature) { - SymmetricEssNature e = (SymmetricEssNature) ess; - b.append("L:" + e.activePower().format() + ";" + e.reactivePower().format()); - } - if (ess instanceof AsymmetricEssNature && ess instanceof SymmetricEssNature) { - b.append("|"); - } - if (ess instanceof AsymmetricEssNature) { - AsymmetricEssNature e = (AsymmetricEssNature) ess; - b.append("L1:" + e.activePowerL1().format() + ";" + e.reactivePowerL1().format() + "|" + // - "L2:" + e.activePowerL2().format() + ";" + e.reactivePowerL2().format() + "|" + // - "L3:" + e.activePowerL3().format() + ";" + e.reactivePowerL3().format()); - } - b.append("|" + // - "Allowed:" + ess.allowedCharge().format() + ";" + ess.allowedDischarge().format()); - b.append("|" + // - "GridMode:" + ess.gridMode().labelOptional().orElse("unknown")); - String warn = ess.warning().toString(); - if (!warn.equals("")) { - b.append("|Warn:" + ess.warning()); - } - b.append("]"); - return b.toString(); - } - -} +/******************************************************************************* + * 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.debuglog; + +import java.util.List; +import java.util.stream.Collectors; + +import io.openems.api.channel.ReadChannel; +import io.openems.api.controller.IsThingMap; +import io.openems.api.controller.ThingMap; +import io.openems.api.device.nature.ess.AsymmetricEssNature; +import io.openems.api.device.nature.ess.EssNature; +import io.openems.api.device.nature.ess.SymmetricEssNature; + +@IsThingMap(type = EssNature.class) +public class Ess extends ThingMap { + + private final EssNature ess; + + public Ess(EssNature ess) { + super(ess); + this.ess = ess; + + ess.allowedCharge().required(); + ess.allowedDischarge().required(); + ess.minSoc().required(); + ess.soc().required(); + ess.systemState().required(); + + if (ess instanceof AsymmetricEssNature) { + AsymmetricEssNature e = (AsymmetricEssNature) ess; + e.activePowerL1().required(); + e.activePowerL2().required(); + e.activePowerL3().required(); + e.reactivePowerL1().required(); + e.reactivePowerL2().required(); + e.reactivePowerL3().required(); + } + if (ess instanceof SymmetricEssNature) { + SymmetricEssNature e = (SymmetricEssNature) ess; + e.activePower().required(); + e.reactivePower().required(); + } + } + + @Override public String toString() { + StringBuilder b = new StringBuilder(); + b.append(ess.id() + " [" + // + "SOC:" + ess.soc().format() + "|"); + if (ess instanceof SymmetricEssNature) { + SymmetricEssNature e = (SymmetricEssNature) ess; + b.append("L:" + e.activePower().format() + ";" + e.reactivePower().format()); + } + if (ess instanceof AsymmetricEssNature && ess instanceof SymmetricEssNature) { + b.append("|"); + } + if (ess instanceof AsymmetricEssNature) { + AsymmetricEssNature e = (AsymmetricEssNature) ess; + b.append("L1:" + e.activePowerL1().format() + ";" + e.reactivePowerL1().format() + "|" + // + "L2:" + e.activePowerL2().format() + ";" + e.reactivePowerL2().format() + "|" + // + "L3:" + e.activePowerL3().format() + ";" + e.reactivePowerL3().format()); + } + b.append("|" + // + "Allowed:" + ess.allowedCharge().format() + ";" + ess.allowedDischarge().format()); + b.append("|" + // + "GridMode:" + ess.gridMode().labelOptional().orElse("unknown")); + List> warningChannels = ess.getStateChannel().getWarningChannels().stream().filter(c -> c.isValuePresent() && c.getValue()).collect(Collectors.toList()); + List> faultChannels = ess.getStateChannel().getFaultChannels().stream().filter(c -> c.isValuePresent() && c.getValue()).collect(Collectors.toList()); + if(warningChannels.size() > 0) { + b.append("|Warn: "); + for(ReadChannel warning : warningChannels) { + b.append(", "+warning.address()); + } + } + if(faultChannels.size() > 0) { + b.append("|Fault: "); + for(ReadChannel fault : faultChannels) { + b.append(", "+fault.address()); + } + } + b.append("]"); + return b.toString(); + } + +} diff --git a/edge/src/io/openems/impl/controller/emergencygenerator/EmergencyGeneratorController.java b/edge/src/io/openems/impl/controller/emergencygenerator/EmergencyGeneratorController.java index 476f838c964..f411f44e9b5 100644 --- a/edge/src/io/openems/impl/controller/emergencygenerator/EmergencyGeneratorController.java +++ b/edge/src/io/openems/impl/controller/emergencygenerator/EmergencyGeneratorController.java @@ -1,173 +1,180 @@ -/******************************************************************************* - * 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.emergencygenerator; - -import java.util.Optional; - -import io.openems.api.channel.Channel; -import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.WriteChannel; -import io.openems.api.controller.Controller; -import io.openems.api.device.nature.ess.EssNature; -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; - -@ThingInfo(title = "External generator control", description = "Starts an external generator in case of emergency.") -public class EmergencyGeneratorController extends Controller { - - /* - * Constructors - */ - public EmergencyGeneratorController() { - super(); - } - - public EmergencyGeneratorController(String thingId) { - super(thingId); - } - - /* - * Config - */ - @ChannelInfo(title = "Ess", description = "Sets the Ess device.", type = Ess.class) - public ConfigChannel ess = new ConfigChannel("ess", this); - - @ChannelInfo(title = "Grid-meter", description = "Sets the grid-meter to detect if the system is Off-Grid or On-Grid.", type = Meter.class) - public ConfigChannel meter = new ConfigChannel("meter", this); - - @ChannelInfo(title = "Min-SOC", description = "If the SOC falls under this value and the system is Off-Grid the generator starts.", type = Long.class) - public ConfigChannel minSoc = new ConfigChannel("minSoc", this); - - @ChannelInfo(title = "Max-SOC", description = "If the system is Off-Grid and the generator is running, the generator stops if the SOC level increases over the Max-SOC.", type = Long.class) - public ConfigChannel maxSoc = new ConfigChannel("maxSoc", this); - - @ChannelInfo(title = "Invert-Output", description = "True if the digital output should be inverted.", type = Boolean.class) - public ConfigChannel invertOutput = new ConfigChannel<>("invertOutput", this); - - @ChannelInfo(title = "On-Grid output on", description = "This value indicates if the system is On-Grid to start(true) or stop(false) the generator.", type = Boolean.class, isOptional = true) - public ConfigChannel onGridOutputOn = new ConfigChannel("onGridOutputOn", this) - .defaultValue(false); - - /* - * Fields - */ - private ThingRepository repo = ThingRepository.getInstance(); - private WriteChannel outputChannel; - private boolean generatorOn = false; - private long lastPower = 0l; - private Long cooldownStartTime = null; - - /* - * Methods - */ - @SuppressWarnings("unchecked") - @ChannelInfo(title = "the address of the Digital Output where the generator is connected to.", type = String.class) - public ConfigChannel outputChannelAddress = 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!"); - } - }); - - @Override - public void run() { - try { - // Check if grid is available - if (!meter.value().voltage.valueOptional().isPresent()) { - // no meassurable voltage => Off-Grid - if (ess.value().gridMode.labelOptional().equals(Optional.of(EssNature.OFF_GRID)) && !generatorOn - && ess.value().soc.value() <= minSoc.value()) { - // switch generator on - startGenerator(); - generatorOn = true; - System.out.println("1: storage is empty. Start generator."); - } else if (ess.value().gridMode.labelOptional().equals(Optional.of(EssNature.ON_GRID)) && generatorOn - && ess.value().soc.value() >= maxSoc.value()) { - // switch generator off - if (cooldownStartTime == null) { - cooldownStartTime = System.currentTimeMillis(); - ess.value().setActivePowerL1.pushWrite(0l); - ess.value().setActivePowerL2.pushWrite(0l); - ess.value().setActivePowerL3.pushWrite(0l); - log.info("Start cooldownphase."); - } else if (cooldownStartTime + 1000 * 60 < System.currentTimeMillis()) { - stopGenerator(); - generatorOn = false; - lastPower = 0l; - cooldownStartTime = null; - System.out.println("Storage is full. Stop generator."); - } - } else if (generatorOn) { - startGenerator(); - if (ess.value().gridMode.labelOptional().equals(Optional.of(EssNature.ON_GRID))) { - if (lastPower > -1000) { - lastPower -= 20l; - } - ess.value().setActivePowerL1.pushWrite(lastPower); - ess.value().setActivePowerL2.pushWrite(lastPower); - ess.value().setActivePowerL3.pushWrite(lastPower); - System.out.println("Charge with " + lastPower * 3 + " kW"); - } - System.out.println("3: "); - } else if (!generatorOn) { - stopGenerator(); - lastPower = 0l; - System.out.println("4: "); - } - } else { - // Grid voltage is in the allowed range - if (onGridOutputOn.value()) { - startGenerator(); - } else { - stopGenerator(); - } - } - } catch (InvalidValueException e) { - log.error("Failed to read value!", e); - } catch (WriteChannelException e) { - log.error("Error due write to output [" + outputChannelAddress.valueOptional().orElse("") + "]", e); - } - } - - private void startGenerator() throws WriteChannelException, InvalidValueException { - if (outputChannel.value() != true ^ invertOutput.value()) { - outputChannel.pushWrite(true ^ invertOutput.value()); - } - } - - private void stopGenerator() throws InvalidValueException, WriteChannelException { - if (outputChannel.value() != false ^ invertOutput.value()) { - outputChannel.pushWrite(false ^ invertOutput.value()); - } - } - -} +/******************************************************************************* + * 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.emergencygenerator; + +import java.util.Optional; + +import io.openems.api.channel.Channel; +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.WriteChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.controller.Controller; +import io.openems.api.device.nature.ess.EssNature; +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; + +@ThingInfo(title = "External generator control", description = "Starts an external generator in case of emergency.") +public class EmergencyGeneratorController extends Controller { + + private ThingStateChannel thingState = new ThingStateChannel(this); + /* + * Constructors + */ + public EmergencyGeneratorController() { + super(); + } + + public EmergencyGeneratorController(String thingId) { + super(thingId); + } + + /* + * Config + */ + @ChannelInfo(title = "Ess", description = "Sets the Ess device.", type = Ess.class) + public ConfigChannel ess = new ConfigChannel("ess", this); + + @ChannelInfo(title = "Grid-meter", description = "Sets the grid-meter to detect if the system is Off-Grid or On-Grid.", type = Meter.class) + public ConfigChannel meter = new ConfigChannel("meter", this); + + @ChannelInfo(title = "Min-SOC", description = "If the SOC falls under this value and the system is Off-Grid the generator starts.", type = Long.class) + public ConfigChannel minSoc = new ConfigChannel("minSoc", this); + + @ChannelInfo(title = "Max-SOC", description = "If the system is Off-Grid and the generator is running, the generator stops if the SOC level increases over the Max-SOC.", type = Long.class) + public ConfigChannel maxSoc = new ConfigChannel("maxSoc", this); + + @ChannelInfo(title = "Invert-Output", description = "True if the digital output should be inverted.", type = Boolean.class) + public ConfigChannel invertOutput = new ConfigChannel<>("invertOutput", this); + + @ChannelInfo(title = "On-Grid output on", description = "This value indicates if the system is On-Grid to start(true) or stop(false) the generator.", type = Boolean.class, isOptional = true) + public ConfigChannel onGridOutputOn = new ConfigChannel("onGridOutputOn", this) + .defaultValue(false); + + /* + * Fields + */ + private ThingRepository repo = ThingRepository.getInstance(); + private WriteChannel outputChannel; + private boolean generatorOn = false; + private long lastPower = 0l; + private Long cooldownStartTime = null; + + /* + * Methods + */ + @SuppressWarnings("unchecked") + @ChannelInfo(title = "the address of the Digital Output where the generator is connected to.", type = String.class) + public ConfigChannel outputChannelAddress = 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!"); + } + }); + + @Override + public void run() { + try { + // Check if grid is available + if (!meter.value().voltage.valueOptional().isPresent()) { + // no meassurable voltage => Off-Grid + if (ess.value().gridMode.labelOptional().equals(Optional.of(EssNature.OFF_GRID)) && !generatorOn + && ess.value().soc.value() <= minSoc.value()) { + // switch generator on + startGenerator(); + generatorOn = true; + System.out.println("1: storage is empty. Start generator."); + } else if (ess.value().gridMode.labelOptional().equals(Optional.of(EssNature.ON_GRID)) && generatorOn + && ess.value().soc.value() >= maxSoc.value()) { + // switch generator off + if (cooldownStartTime == null) { + cooldownStartTime = System.currentTimeMillis(); + ess.value().setActivePowerL1.pushWrite(0l); + ess.value().setActivePowerL2.pushWrite(0l); + ess.value().setActivePowerL3.pushWrite(0l); + log.info("Start cooldownphase."); + } else if (cooldownStartTime + 1000 * 60 < System.currentTimeMillis()) { + stopGenerator(); + generatorOn = false; + lastPower = 0l; + cooldownStartTime = null; + System.out.println("Storage is full. Stop generator."); + } + } else if (generatorOn) { + startGenerator(); + if (ess.value().gridMode.labelOptional().equals(Optional.of(EssNature.ON_GRID))) { + if (lastPower > -1000) { + lastPower -= 20l; + } + ess.value().setActivePowerL1.pushWrite(lastPower); + ess.value().setActivePowerL2.pushWrite(lastPower); + ess.value().setActivePowerL3.pushWrite(lastPower); + System.out.println("Charge with " + lastPower * 3 + " kW"); + } + System.out.println("3: "); + } else if (!generatorOn) { + stopGenerator(); + lastPower = 0l; + System.out.println("4: "); + } + } else { + // Grid voltage is in the allowed range + if (onGridOutputOn.value()) { + startGenerator(); + } else { + stopGenerator(); + } + } + } catch (InvalidValueException e) { + log.error("Failed to read value!", e); + } catch (WriteChannelException e) { + log.error("Error due write to output [" + outputChannelAddress.valueOptional().orElse("") + "]", e); + } + } + + private void startGenerator() throws WriteChannelException, InvalidValueException { + if (outputChannel.value() != true ^ invertOutput.value()) { + outputChannel.pushWrite(true ^ invertOutput.value()); + } + } + + private void stopGenerator() throws InvalidValueException, WriteChannelException { + if (outputChannel.value() != false ^ invertOutput.value()) { + outputChannel.pushWrite(false ^ invertOutput.value()); + } + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + +} diff --git a/edge/src/io/openems/impl/controller/evcs/EvcsController.java b/edge/src/io/openems/impl/controller/evcs/EvcsController.java index 77aaa39e19a..d07752702f5 100644 --- a/edge/src/io/openems/impl/controller/evcs/EvcsController.java +++ b/edge/src/io/openems/impl/controller/evcs/EvcsController.java @@ -3,6 +3,7 @@ import java.util.Optional; import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.controller.Controller; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; @@ -26,6 +27,7 @@ public class EvcsController extends Controller { private Optional lastCurrentMilliAmp = Optional.empty(); private int lagCountdown = CONTROL_LAG; private int waitForValueSet = WAIT_FOR_VALUE_SET; + private ThingStateChannel thingState = new ThingStateChannel(this); /* * Constructors @@ -142,4 +144,9 @@ private void setCurrentMilliAmp(int currentMilliAmp) { log.error("Unable to set EVCS current: " + e.getMessage()); } } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } } diff --git a/edge/src/io/openems/impl/controller/feneconprosetup/FeneconProSetupController.java b/edge/src/io/openems/impl/controller/feneconprosetup/FeneconProSetupController.java index 6f5600ccb6f..406d101149d 100644 --- a/edge/src/io/openems/impl/controller/feneconprosetup/FeneconProSetupController.java +++ b/edge/src/io/openems/impl/controller/feneconprosetup/FeneconProSetupController.java @@ -34,6 +34,8 @@ @ThingInfo(title = "Initial setup for FENECON Pro", description = "Sets the correct factory settings for FENECON Pro energy storage systems.") public class FeneconProSetupController extends Controller { + private ThingStateChannel thingState = new ThingStateChannel(this); + /* * Constructors */ @@ -82,8 +84,7 @@ public void run() { @Override public ThingStateChannel getStateChannel() { - // TODO Auto-generated method stub - return null; + return this.thingState; } } diff --git a/edge/src/io/openems/impl/controller/offGridIndication/OffGridIndicationController.java b/edge/src/io/openems/impl/controller/offGridIndication/OffGridIndicationController.java index b55a0427bba..557e0b54a62 100644 --- a/edge/src/io/openems/impl/controller/offGridIndication/OffGridIndicationController.java +++ b/edge/src/io/openems/impl/controller/offGridIndication/OffGridIndicationController.java @@ -25,6 +25,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.WriteChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -42,6 +43,7 @@ public class OffGridIndicationController extends Controller { private boolean isProducerDisconnected = false; private long timeProducerDisconnected; private long startTime = System.currentTimeMillis(); + private ThingStateChannel thingState = new ThingStateChannel(this); private enum State { OFFGRID, ONGRID, SWITCHTOOFFGRID, SWITCHTOONGRID, UNKNOWN @@ -111,7 +113,7 @@ public void run() { currentState = State.SWITCHTOONGRID; } } - break; + break; case SWITCHTOOFFGRID: if (isOff()) { if (!isProducerDisconnected) { @@ -151,7 +153,7 @@ public void run() { } } } - break; + break; } } catch (InvalidValueException e) { @@ -170,4 +172,9 @@ private boolean isOff() throws InvalidValueException { return offGridOutputChannel.value() == false; } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/controller/onGridIndication/OnGridIndicationController.java b/edge/src/io/openems/impl/controller/onGridIndication/OnGridIndicationController.java index fa667d8e44a..4fb494bb973 100644 --- a/edge/src/io/openems/impl/controller/onGridIndication/OnGridIndicationController.java +++ b/edge/src/io/openems/impl/controller/onGridIndication/OnGridIndicationController.java @@ -25,6 +25,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.WriteChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -42,6 +43,7 @@ public class OnGridIndicationController extends Controller { private boolean isProducerDisconnected = false; private long timeProducerDisconnected; private long startTime = System.currentTimeMillis(); + private ThingStateChannel thingState = new ThingStateChannel(this); private enum State { OFFGRID, ONGRID, SWITCHTOOFFGRID, SWITCHTOONGRID, UNKNOWN @@ -113,7 +115,7 @@ public void run() { currentState = State.SWITCHTOONGRID; } } - break; + break; case SWITCHTOOFFGRID: if (isOff()) { currentState = State.OFFGRID; @@ -157,7 +159,7 @@ public void run() { } } } - break; + break; } } catch (InvalidValueException e) { @@ -176,4 +178,9 @@ private boolean isOnGrid() throws InvalidValueException { return onGridOutputChannel.value() == true; } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/controller/riedmann/RiedmannController.java b/edge/src/io/openems/impl/controller/riedmann/RiedmannController.java index bf43aef2880..9ef36f43159 100644 --- a/edge/src/io/openems/impl/controller/riedmann/RiedmannController.java +++ b/edge/src/io/openems/impl/controller/riedmann/RiedmannController.java @@ -17,6 +17,7 @@ @ThingInfo(title = "Sps parameter Controller") public class RiedmannController extends Controller implements ChannelChangeListener { + private ThingStateChannel thingState = new ThingStateChannel(this); /* * Config-Channel */ @@ -255,7 +256,6 @@ public void channelChanged(Channel channel, Optional newValue, Optional ol @Override public ThingStateChannel getStateChannel() { - // TODO Auto-generated method stub - return null; + return this.thingState; } } diff --git a/edge/src/io/openems/impl/controller/riedmann/SystemStopController.java b/edge/src/io/openems/impl/controller/riedmann/SystemStopController.java index e76fdf0e8a7..a9302af14c6 100644 --- a/edge/src/io/openems/impl/controller/riedmann/SystemStopController.java +++ b/edge/src/io/openems/impl/controller/riedmann/SystemStopController.java @@ -3,6 +3,7 @@ import java.util.Optional; import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -13,6 +14,7 @@ @ThingInfo(title = "SystemStopController") public class SystemStopController extends Controller { + private ThingStateChannel thingState = new ThingStateChannel(this); /* * Config-Channel */ @@ -67,4 +69,9 @@ public void run() { } } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/controller/supplybusswitch/SupplyBusSwitchController.java b/edge/src/io/openems/impl/controller/supplybusswitch/SupplyBusSwitchController.java index 1e69424381f..bbaa4159c69 100644 --- a/edge/src/io/openems/impl/controller/supplybusswitch/SupplyBusSwitchController.java +++ b/edge/src/io/openems/impl/controller/supplybusswitch/SupplyBusSwitchController.java @@ -32,6 +32,7 @@ import io.openems.api.channel.ChannelChangeListener; import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.WriteChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -46,6 +47,7 @@ @ThingInfo(title = "Supply Bus Switch") public class SupplyBusSwitchController extends Controller implements ChannelChangeListener { + private ThingStateChannel thingState = new ThingStateChannel(this); /* * Constructors */ @@ -211,4 +213,9 @@ private Ess getEss(String essName) throws InvalidValueException { return null; } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/controller/symmetric/avoidtotalcharge/AvoidTotalChargeController.java b/edge/src/io/openems/impl/controller/symmetric/avoidtotalcharge/AvoidTotalChargeController.java index 614138012df..8a2ee99c438 100644 --- a/edge/src/io/openems/impl/controller/symmetric/avoidtotalcharge/AvoidTotalChargeController.java +++ b/edge/src/io/openems/impl/controller/symmetric/avoidtotalcharge/AvoidTotalChargeController.java @@ -9,6 +9,7 @@ import java.util.Set; import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.controller.Controller; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; @@ -18,6 +19,7 @@ @ThingInfo(title = "Avoid total charge of battery. (Symmetric)", description = "Provides control over the battery's maximum state of charge at a specific time of day. For symmetric Ess.") public class AvoidTotalChargeController extends Controller { + private ThingStateChannel thingState = new ThingStateChannel(this); /* * Config */ @@ -155,4 +157,9 @@ public void run() { log.error(e.getMessage(),e); } } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } } diff --git a/edge/src/io/openems/impl/controller/symmetric/avoidtotaldischarge/AvoidTotalDischargeController.java b/edge/src/io/openems/impl/controller/symmetric/avoidtotaldischarge/AvoidTotalDischargeController.java index 0bdc89fa738..7804fdb65a9 100644 --- a/edge/src/io/openems/impl/controller/symmetric/avoidtotaldischarge/AvoidTotalDischargeController.java +++ b/edge/src/io/openems/impl/controller/symmetric/avoidtotaldischarge/AvoidTotalDischargeController.java @@ -24,6 +24,7 @@ import java.util.Set; import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -35,6 +36,7 @@ @ThingInfo(title = "Avoid total discharge of battery (Symmetric)", description = "Makes sure the battery is not going into critically low state of charge. For symmetric Ess.") public class AvoidTotalDischargeController extends Controller { + private ThingStateChannel thingState = new ThingStateChannel(this); /* * Constructors */ @@ -132,4 +134,9 @@ public void run() { log.error("no ess configured"+e.getMessage()); } } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } } diff --git a/edge/src/io/openems/impl/controller/symmetric/avoidtotaldischargesoctimeline/AvoidTotalDischargeSocTimeLineController.java b/edge/src/io/openems/impl/controller/symmetric/avoidtotaldischargesoctimeline/AvoidTotalDischargeSocTimeLineController.java index 2671f86bc9c..2576aef1faa 100644 --- a/edge/src/io/openems/impl/controller/symmetric/avoidtotaldischargesoctimeline/AvoidTotalDischargeSocTimeLineController.java +++ b/edge/src/io/openems/impl/controller/symmetric/avoidtotaldischargesoctimeline/AvoidTotalDischargeSocTimeLineController.java @@ -1,163 +1,170 @@ -/******************************************************************************* - * 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.symmetric.avoidtotaldischargesoctimeline; - -import java.time.LocalTime; -import java.time.format.DateTimeFormatter; -import java.util.Optional; -import java.util.Set; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; - -import io.openems.api.channel.Channel; -import io.openems.api.channel.ChannelChangeListener; -import io.openems.api.channel.ConfigChannel; -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.impl.controller.symmetric.avoidtotaldischargesoctimeline.Ess.State; - -@ThingInfo(title = "Avoid total discharge of battery (Symmetric)", description = "Makes sure the battery is not going into critically low state of charge. For symmetric Ess.") -public class AvoidTotalDischargeSocTimeLineController extends Controller implements ChannelChangeListener { - - /* - * Constructors - */ - public AvoidTotalDischargeSocTimeLineController() { - super(); - } - - public AvoidTotalDischargeSocTimeLineController(String thingId) { - super(thingId); - } - - /* - * Config - */ - @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class, isArray = true) - public final ConfigChannel> esss = new ConfigChannel>("esss", this).addChangeListener(this); - - @ChannelInfo(title = "Soc timeline", description = "This option configures an minsoc at a time for an ess. If no minsoc for an ess is configured the controller uses the minsoc of the ess.", type = JsonArray.class) - public final ConfigChannel socTimeline = new ConfigChannel("socTimeline", this) - .addChangeListener(this); - - /* - * Methods - */ - @Override - public void run() { - try { - LocalTime time = LocalTime.now(); - for (Ess ess : esss.value()) { - switch (ess.currentState) { - case CHARGESOC: - if (ess.soc.value() > ess.getMinSoc(time)) { - ess.currentState = State.MINSOC; - } else { - try { - Optional currentMinValue = ess.setActivePower.writeMin(); - if (currentMinValue.isPresent() && currentMinValue.get() < 0) { - // Force Charge with minimum of MaxChargePower/5 - log.info("Force charge. Set ActivePower=Max[" + currentMinValue.get() / 5 + "]"); - ess.setActivePower.pushWriteMax(currentMinValue.get() / 5); - } else { - log.info("Avoid discharge. Set ActivePower=Max[-1000 W]"); - ess.setActivePower.pushWriteMax(-1000L); - } - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - break; - case MINSOC: - if (ess.soc.value() < ess.getChargeSoc(time)) { - ess.currentState = State.CHARGESOC; - } else if (ess.soc.value() >= ess.getMinSoc(time) + 5) { - ess.currentState = State.NORMAL; - } else { - try { - long maxPower = 0; - if (!ess.setActivePower.writeMax().isPresent() - || maxPower < ess.setActivePower.writeMax().get()) { - ess.setActivePower.pushWriteMax(maxPower); - } - } catch (WriteChannelException e) { - log.error(ess.id() + "Failed to set Max allowed power.", e); - } - } - break; - case NORMAL: - if (ess.soc.value() <= ess.getMinSoc(time)) { - ess.currentState = State.MINSOC; - } - break; - } - - } - } catch (InvalidValueException e) { - log.error(e.getMessage()); - } - } - - private Ess getEss(String id) throws InvalidValueException { - for (Ess ess : esss.value()) { - if (ess.id().equals(id)) { - return ess; - } - } - return null; - } - - @Override - public void channelChanged(Channel channel, Optional newValue, Optional oldValue) { - if (channel.equals(esss) || channel.equals(socTimeline)) { - if (esss.valueOptional().isPresent() && socTimeline.valueOptional().isPresent() - && socTimeline.valueOptional().get() instanceof JsonArray) { - JsonArray timeline = socTimeline.valueOptional().get(); - for (JsonElement e : timeline) { - JsonObject obj = e.getAsJsonObject(); - int minSoc = obj.get("minSoc").getAsInt(); - int chargeSoc = obj.get("chargeSoc").getAsInt(); - LocalTime time = LocalTime.parse(obj.get("time").getAsString(), DateTimeFormatter.ISO_LOCAL_TIME); - JsonArray storages = obj.get("esss").getAsJsonArray(); - for (JsonElement storage : storages) { - Ess ess; - try { - ess = getEss(storage.getAsString()); - if (ess != null) { - ess.addTime(time, minSoc, chargeSoc); - } - } catch (InvalidValueException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - } - } - } - } - } - -} +/******************************************************************************* + * 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.symmetric.avoidtotaldischargesoctimeline; + +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.Optional; +import java.util.Set; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import io.openems.api.channel.Channel; +import io.openems.api.channel.ChannelChangeListener; +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +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.impl.controller.symmetric.avoidtotaldischargesoctimeline.Ess.State; + +@ThingInfo(title = "Avoid total discharge of battery (Symmetric)", description = "Makes sure the battery is not going into critically low state of charge. For symmetric Ess.") +public class AvoidTotalDischargeSocTimeLineController extends Controller implements ChannelChangeListener { + + private ThingStateChannel thingState = new ThingStateChannel(this); + /* + * Constructors + */ + public AvoidTotalDischargeSocTimeLineController() { + super(); + } + + public AvoidTotalDischargeSocTimeLineController(String thingId) { + super(thingId); + } + + /* + * Config + */ + @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class, isArray = true) + public final ConfigChannel> esss = new ConfigChannel>("esss", this).addChangeListener(this); + + @ChannelInfo(title = "Soc timeline", description = "This option configures an minsoc at a time for an ess. If no minsoc for an ess is configured the controller uses the minsoc of the ess.", type = JsonArray.class) + public final ConfigChannel socTimeline = new ConfigChannel("socTimeline", this) + .addChangeListener(this); + + /* + * Methods + */ + @Override + public void run() { + try { + LocalTime time = LocalTime.now(); + for (Ess ess : esss.value()) { + switch (ess.currentState) { + case CHARGESOC: + if (ess.soc.value() > ess.getMinSoc(time)) { + ess.currentState = State.MINSOC; + } else { + try { + Optional currentMinValue = ess.setActivePower.writeMin(); + if (currentMinValue.isPresent() && currentMinValue.get() < 0) { + // Force Charge with minimum of MaxChargePower/5 + log.info("Force charge. Set ActivePower=Max[" + currentMinValue.get() / 5 + "]"); + ess.setActivePower.pushWriteMax(currentMinValue.get() / 5); + } else { + log.info("Avoid discharge. Set ActivePower=Max[-1000 W]"); + ess.setActivePower.pushWriteMax(-1000L); + } + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + break; + case MINSOC: + if (ess.soc.value() < ess.getChargeSoc(time)) { + ess.currentState = State.CHARGESOC; + } else if (ess.soc.value() >= ess.getMinSoc(time) + 5) { + ess.currentState = State.NORMAL; + } else { + try { + long maxPower = 0; + if (!ess.setActivePower.writeMax().isPresent() + || maxPower < ess.setActivePower.writeMax().get()) { + ess.setActivePower.pushWriteMax(maxPower); + } + } catch (WriteChannelException e) { + log.error(ess.id() + "Failed to set Max allowed power.", e); + } + } + break; + case NORMAL: + if (ess.soc.value() <= ess.getMinSoc(time)) { + ess.currentState = State.MINSOC; + } + break; + } + + } + } catch (InvalidValueException e) { + log.error(e.getMessage()); + } + } + + private Ess getEss(String id) throws InvalidValueException { + for (Ess ess : esss.value()) { + if (ess.id().equals(id)) { + return ess; + } + } + return null; + } + + @Override + public void channelChanged(Channel channel, Optional newValue, Optional oldValue) { + if (channel.equals(esss) || channel.equals(socTimeline)) { + if (esss.valueOptional().isPresent() && socTimeline.valueOptional().isPresent() + && socTimeline.valueOptional().get() instanceof JsonArray) { + JsonArray timeline = socTimeline.valueOptional().get(); + for (JsonElement e : timeline) { + JsonObject obj = e.getAsJsonObject(); + int minSoc = obj.get("minSoc").getAsInt(); + int chargeSoc = obj.get("chargeSoc").getAsInt(); + LocalTime time = LocalTime.parse(obj.get("time").getAsString(), DateTimeFormatter.ISO_LOCAL_TIME); + JsonArray storages = obj.get("esss").getAsJsonArray(); + for (JsonElement storage : storages) { + Ess ess; + try { + ess = getEss(storage.getAsString()); + if (ess != null) { + ess.addTime(time, minSoc, chargeSoc); + } + } catch (InvalidValueException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + } + } + } + } + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + +} diff --git a/edge/src/io/openems/impl/controller/symmetric/balancing/BalancingController.java b/edge/src/io/openems/impl/controller/symmetric/balancing/BalancingController.java index c67333385cd..ef6a56d968f 100644 --- a/edge/src/io/openems/impl/controller/symmetric/balancing/BalancingController.java +++ b/edge/src/io/openems/impl/controller/symmetric/balancing/BalancingController.java @@ -26,6 +26,7 @@ import java.util.Optional; import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -36,6 +37,7 @@ @ThingInfo(title = "Self-consumption optimization (Symmetric)", description = "Tries to keep the grid meter on zero. For symmetric Ess. Ess-Cluster is supported.") public class BalancingController extends Controller { + private ThingStateChannel thingState = new ThingStateChannel(this); /* * Constructors */ @@ -193,4 +195,9 @@ private List getUseableEss() throws InvalidValueException { return useableEss; } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/controller/symmetric/balancingbandgap/BalancingBandgapController.java b/edge/src/io/openems/impl/controller/symmetric/balancingbandgap/BalancingBandgapController.java index 475b9d5f4de..97b4d389171 100644 --- a/edge/src/io/openems/impl/controller/symmetric/balancingbandgap/BalancingBandgapController.java +++ b/edge/src/io/openems/impl/controller/symmetric/balancingbandgap/BalancingBandgapController.java @@ -1,117 +1,124 @@ -/******************************************************************************* - * 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.symmetric.balancingbandgap; - -import io.openems.api.channel.ConfigChannel; -import io.openems.api.controller.Controller; -import io.openems.api.doc.ChannelInfo; -import io.openems.api.doc.ThingInfo; -import io.openems.api.exception.InvalidValueException; - -@ThingInfo(title = "Balancing bandgap (Symmetric)", description = "Tries to keep the grid meter within a bandgap. For symmetric Ess.") -public class BalancingBandgapController extends Controller { - - /* - * Constructors - */ - public BalancingBandgapController() { - super(); - } - - public BalancingBandgapController(String thingId) { - super(thingId); - } - - /* - * Config - */ - @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class) - public final ConfigChannel ess = new ConfigChannel("ess", this); - - @ChannelInfo(title = "Grid-Meter", description = "Sets the grid meter.", type = Meter.class) - public final ConfigChannel meter = new ConfigChannel("meter", this); - - @ChannelInfo(title = "Min-ActivePower", description = "Low boundary of active power bandgap.", type = Integer.class) - public final ConfigChannel minActivePower = new ConfigChannel<>("minActivePower", this); - - @ChannelInfo(title = "Max-ActivePower", description = "High boundary of active power bandgap.", type = Integer.class) - public final ConfigChannel maxActivePower = new ConfigChannel<>("maxActivePower", this); - - @ChannelInfo(title = "Min-ReactivePower", description = "Low boundary of reactive power bandgap.", type = Integer.class) - public final ConfigChannel minReactivePower = new ConfigChannel<>("minReactivePower", this); - - @ChannelInfo(title = "Max-ReactivePower", description = "High boundary of reactive power bandgap.", type = Integer.class) - public final ConfigChannel maxReactivePower = new ConfigChannel<>("maxReactivePower", this); - - @ChannelInfo(title = "Enable ActivePower", description = "Indicates if active power bandgap is enabled.", type = Boolean.class, defaultValue = "true") - public final ConfigChannel activePowerActivated = new ConfigChannel("activePowerActivated", this); - - @ChannelInfo(title = "Enable ReactivePower", description = "Indicates if reactive power bandgap is enabled.", type = Boolean.class, defaultValue = "true") - public final ConfigChannel reactivePowerActivated = new ConfigChannel("reactivePowerActivated", - this); - - /* - * Methods - */ - @Override - public void run() { - try { - Ess ess = this.ess.value(); - Meter meter = this.meter.value(); - // Calculate required sum values - long calculatedPower = meter.activePower.value() + ess.activePower.value(); - long calculatedReactivePower = meter.reactivePower.value() + ess.reactivePower.value(); - if (calculatedPower >= maxActivePower.value()) { - calculatedPower -= maxActivePower.value(); - } else if (calculatedPower <= minActivePower.value()) { - calculatedPower -= minActivePower.value(); - } else { - calculatedPower = 0; - } - if (calculatedReactivePower >= maxReactivePower.value()) { - calculatedReactivePower -= maxReactivePower.value(); - } else if (calculatedReactivePower <= minReactivePower.value()) { - calculatedReactivePower -= minReactivePower.value(); - } else { - calculatedReactivePower = 0; - } - if (reactivePowerActivated.value()) { - ess.power.setReactivePower(calculatedReactivePower); - } - if (activePowerActivated.value()) { - ess.power.setActivePower(calculatedPower); - } - ess.power.writePower(); - // write info message to log - String message = ess.id(); - if (activePowerActivated.value()) { - message = message + " Set ActivePower [" + ess.power.getActivePower() + "]"; - } - if (reactivePowerActivated.value()) { - message = message + " Set ReactivePower [" + ess.power.getReactivePower() + "]"; - } - log.info(message); - } catch (InvalidValueException e) { - log.error(e.getMessage()); - } - } - -} +/******************************************************************************* + * 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.symmetric.balancingbandgap; + +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.controller.Controller; +import io.openems.api.doc.ChannelInfo; +import io.openems.api.doc.ThingInfo; +import io.openems.api.exception.InvalidValueException; + +@ThingInfo(title = "Balancing bandgap (Symmetric)", description = "Tries to keep the grid meter within a bandgap. For symmetric Ess.") +public class BalancingBandgapController extends Controller { + + private ThingStateChannel thingState = new ThingStateChannel(this); + /* + * Constructors + */ + public BalancingBandgapController() { + super(); + } + + public BalancingBandgapController(String thingId) { + super(thingId); + } + + /* + * Config + */ + @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class) + public final ConfigChannel ess = new ConfigChannel("ess", this); + + @ChannelInfo(title = "Grid-Meter", description = "Sets the grid meter.", type = Meter.class) + public final ConfigChannel meter = new ConfigChannel("meter", this); + + @ChannelInfo(title = "Min-ActivePower", description = "Low boundary of active power bandgap.", type = Integer.class) + public final ConfigChannel minActivePower = new ConfigChannel<>("minActivePower", this); + + @ChannelInfo(title = "Max-ActivePower", description = "High boundary of active power bandgap.", type = Integer.class) + public final ConfigChannel maxActivePower = new ConfigChannel<>("maxActivePower", this); + + @ChannelInfo(title = "Min-ReactivePower", description = "Low boundary of reactive power bandgap.", type = Integer.class) + public final ConfigChannel minReactivePower = new ConfigChannel<>("minReactivePower", this); + + @ChannelInfo(title = "Max-ReactivePower", description = "High boundary of reactive power bandgap.", type = Integer.class) + public final ConfigChannel maxReactivePower = new ConfigChannel<>("maxReactivePower", this); + + @ChannelInfo(title = "Enable ActivePower", description = "Indicates if active power bandgap is enabled.", type = Boolean.class, defaultValue = "true") + public final ConfigChannel activePowerActivated = new ConfigChannel("activePowerActivated", this); + + @ChannelInfo(title = "Enable ReactivePower", description = "Indicates if reactive power bandgap is enabled.", type = Boolean.class, defaultValue = "true") + public final ConfigChannel reactivePowerActivated = new ConfigChannel("reactivePowerActivated", + this); + + /* + * Methods + */ + @Override + public void run() { + try { + Ess ess = this.ess.value(); + Meter meter = this.meter.value(); + // Calculate required sum values + long calculatedPower = meter.activePower.value() + ess.activePower.value(); + long calculatedReactivePower = meter.reactivePower.value() + ess.reactivePower.value(); + if (calculatedPower >= maxActivePower.value()) { + calculatedPower -= maxActivePower.value(); + } else if (calculatedPower <= minActivePower.value()) { + calculatedPower -= minActivePower.value(); + } else { + calculatedPower = 0; + } + if (calculatedReactivePower >= maxReactivePower.value()) { + calculatedReactivePower -= maxReactivePower.value(); + } else if (calculatedReactivePower <= minReactivePower.value()) { + calculatedReactivePower -= minReactivePower.value(); + } else { + calculatedReactivePower = 0; + } + if (reactivePowerActivated.value()) { + ess.power.setReactivePower(calculatedReactivePower); + } + if (activePowerActivated.value()) { + ess.power.setActivePower(calculatedPower); + } + ess.power.writePower(); + // write info message to log + String message = ess.id(); + if (activePowerActivated.value()) { + message = message + " Set ActivePower [" + ess.power.getActivePower() + "]"; + } + if (reactivePowerActivated.value()) { + message = message + " Set ReactivePower [" + ess.power.getReactivePower() + "]"; + } + log.info(message); + } catch (InvalidValueException e) { + log.error(e.getMessage()); + } + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + +} diff --git a/edge/src/io/openems/impl/controller/symmetric/balancingcosphi/BalancingCosPhiController.java b/edge/src/io/openems/impl/controller/symmetric/balancingcosphi/BalancingCosPhiController.java index 27967cd51d4..9e97196c96c 100644 --- a/edge/src/io/openems/impl/controller/symmetric/balancingcosphi/BalancingCosPhiController.java +++ b/edge/src/io/openems/impl/controller/symmetric/balancingcosphi/BalancingCosPhiController.java @@ -1,73 +1,80 @@ -/******************************************************************************* - * 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.symmetric.balancingcosphi; - -import io.openems.api.channel.ConfigChannel; -import io.openems.api.controller.Controller; -import io.openems.api.doc.ChannelInfo; -import io.openems.api.doc.ThingInfo; -import io.openems.api.exception.InvalidValueException; - -@ThingInfo(title = "Balancing Cos-Phi (Symmetric)", description = "Tries to keep the grid meter at a given cos-phi. For symmetric Ess.") -public class BalancingCosPhiController extends Controller { - - /* - * Constructors - */ - public BalancingCosPhiController() { - super(); - } - - public BalancingCosPhiController(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 = "Grid-Meter", description = "Sets the grid meter.", type = Meter.class) - public ConfigChannel meter = new ConfigChannel("meter", this); - - @ChannelInfo(title = "Cos-Phi", description = "Cos-phi which the grid-meter is trying to hold.", type = Double.class) - public ConfigChannel cosPhi = new ConfigChannel("cosPhi", this); - - /* - * Methods - */ - @Override - public void run() { - try { - double cosPhi = this.cosPhi.value(); - double phi = Math.acos(cosPhi); - long q = (long) ((meter.value().activePower.value() * Math.tan(phi)) - meter.value().reactivePower.value()) - * -1; - q += ess.value().reactivePower.value(); - ess.value().power.setReactivePower(q); - ess.value().power.writePower(); - log.info(ess.id() + " Set ReactivePower [" + ess.value().power.getReactivePower() + "]"); - } catch (InvalidValueException e) { - log.error("Failed to read value.", e); - } - } -} +/******************************************************************************* + * 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.symmetric.balancingcosphi; + +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.controller.Controller; +import io.openems.api.doc.ChannelInfo; +import io.openems.api.doc.ThingInfo; +import io.openems.api.exception.InvalidValueException; + +@ThingInfo(title = "Balancing Cos-Phi (Symmetric)", description = "Tries to keep the grid meter at a given cos-phi. For symmetric Ess.") +public class BalancingCosPhiController extends Controller { + + private ThingStateChannel thingState = new ThingStateChannel(this); + /* + * Constructors + */ + public BalancingCosPhiController() { + super(); + } + + public BalancingCosPhiController(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 = "Grid-Meter", description = "Sets the grid meter.", type = Meter.class) + public ConfigChannel meter = new ConfigChannel("meter", this); + + @ChannelInfo(title = "Cos-Phi", description = "Cos-phi which the grid-meter is trying to hold.", type = Double.class) + public ConfigChannel cosPhi = new ConfigChannel("cosPhi", this); + + /* + * Methods + */ + @Override + public void run() { + try { + double cosPhi = this.cosPhi.value(); + double phi = Math.acos(cosPhi); + long q = (long) ((meter.value().activePower.value() * Math.tan(phi)) - meter.value().reactivePower.value()) + * -1; + q += ess.value().reactivePower.value(); + ess.value().power.setReactivePower(q); + ess.value().power.writePower(); + log.info(ess.id() + " Set ReactivePower [" + ess.value().power.getReactivePower() + "]"); + } catch (InvalidValueException e) { + log.error("Failed to read value.", e); + } + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } +} diff --git a/edge/src/io/openems/impl/controller/symmetric/balancingcurrent/BalancingCurrentController.java b/edge/src/io/openems/impl/controller/symmetric/balancingcurrent/BalancingCurrentController.java index 39030e630ee..8bbf5fb2a82 100644 --- a/edge/src/io/openems/impl/controller/symmetric/balancingcurrent/BalancingCurrentController.java +++ b/edge/src/io/openems/impl/controller/symmetric/balancingcurrent/BalancingCurrentController.java @@ -1,91 +1,98 @@ -/******************************************************************************* - * 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.symmetric.balancingcurrent; - -import io.openems.api.channel.ConfigChannel; -import io.openems.api.controller.Controller; -import io.openems.api.doc.ChannelInfo; -import io.openems.api.doc.ThingInfo; -import io.openems.api.exception.InvalidValueException; - -@ThingInfo(title = "Balancing current (Symmetric)", description = "Tries to keep the grid meter at a given current. For symmetric Ess.") -public class BalancingCurrentController extends Controller { - - /* - * Constructors - */ - public BalancingCurrentController() { - super(); - } - - public BalancingCurrentController(String thingId) { - super(thingId); - } - - /* - * Config - */ - @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class) - public final ConfigChannel ess = new ConfigChannel("ess", this); - - @ChannelInfo(title = "Grid-Meter", description = "Sets the grid meter.", type = Meter.class) - public final ConfigChannel meter = new ConfigChannel("meter", this); - - @ChannelInfo(title = "Current offset", description = "The current to hold on the grid-meter.", type = Meter.class) - public final ConfigChannel currentOffset = new ConfigChannel<>("CurrentOffset", this); - - /* - * Methods - */ - @Override - public void run() { - try { - Ess ess = this.ess.value(); - // Calculate required sum values - long power = calculatePower() + ess.activePower.value(); - ess.power.setActivePower(power); - ess.power.writePower(); - log.info(ess.id() + " Set ActivePower [" + ess.power.getActivePower() + "]"); - } catch (InvalidValueException e) { - log.error(e.getMessage()); - } - } - - private long calculatePower() throws InvalidValueException { - long currentL1 = meter.value().currentL1.value(); - if (meter.value().activePowerL1.value() < 0) { - currentL1 *= -1; - } - long powerL1 = ((currentL1 - currentOffset.value() / 3) / 1000) * (meter.value().voltageL1.value() / 1000); - long currentL2 = meter.value().currentL2.value(); - if (meter.value().activePowerL2.value() < 0) { - currentL2 *= -1; - } - long powerL2 = ((currentL2 - currentOffset.value() / 3) / 1000) * (meter.value().voltageL2.value() / 1000); - long currentL3 = meter.value().currentL3.value(); - if (meter.value().activePowerL3.value() < 0) { - currentL3 *= -1; - } - long powerL3 = ((currentL3 - currentOffset.value() / 3) / 1000) * (meter.value().voltageL3.value() / 1000); - return powerL1 + powerL2 + powerL3; - } - -} +/******************************************************************************* + * 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.symmetric.balancingcurrent; + +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.controller.Controller; +import io.openems.api.doc.ChannelInfo; +import io.openems.api.doc.ThingInfo; +import io.openems.api.exception.InvalidValueException; + +@ThingInfo(title = "Balancing current (Symmetric)", description = "Tries to keep the grid meter at a given current. For symmetric Ess.") +public class BalancingCurrentController extends Controller { + + private ThingStateChannel thingState = new ThingStateChannel(this); + /* + * Constructors + */ + public BalancingCurrentController() { + super(); + } + + public BalancingCurrentController(String thingId) { + super(thingId); + } + + /* + * Config + */ + @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class) + public final ConfigChannel ess = new ConfigChannel("ess", this); + + @ChannelInfo(title = "Grid-Meter", description = "Sets the grid meter.", type = Meter.class) + public final ConfigChannel meter = new ConfigChannel("meter", this); + + @ChannelInfo(title = "Current offset", description = "The current to hold on the grid-meter.", type = Meter.class) + public final ConfigChannel currentOffset = new ConfigChannel<>("CurrentOffset", this); + + /* + * Methods + */ + @Override + public void run() { + try { + Ess ess = this.ess.value(); + // Calculate required sum values + long power = calculatePower() + ess.activePower.value(); + ess.power.setActivePower(power); + ess.power.writePower(); + log.info(ess.id() + " Set ActivePower [" + ess.power.getActivePower() + "]"); + } catch (InvalidValueException e) { + log.error(e.getMessage()); + } + } + + private long calculatePower() throws InvalidValueException { + long currentL1 = meter.value().currentL1.value(); + if (meter.value().activePowerL1.value() < 0) { + currentL1 *= -1; + } + long powerL1 = ((currentL1 - currentOffset.value() / 3) / 1000) * (meter.value().voltageL1.value() / 1000); + long currentL2 = meter.value().currentL2.value(); + if (meter.value().activePowerL2.value() < 0) { + currentL2 *= -1; + } + long powerL2 = ((currentL2 - currentOffset.value() / 3) / 1000) * (meter.value().voltageL2.value() / 1000); + long currentL3 = meter.value().currentL3.value(); + if (meter.value().activePowerL3.value() < 0) { + currentL3 *= -1; + } + long powerL3 = ((currentL3 - currentOffset.value() / 3) / 1000) * (meter.value().voltageL3.value() / 1000); + return powerL1 + powerL2 + powerL3; + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + +} diff --git a/edge/src/io/openems/impl/controller/symmetric/balancingoffset/BalancingOffsetController.java b/edge/src/io/openems/impl/controller/symmetric/balancingoffset/BalancingOffsetController.java index bdbe77a7857..f7429b498dc 100644 --- a/edge/src/io/openems/impl/controller/symmetric/balancingoffset/BalancingOffsetController.java +++ b/edge/src/io/openems/impl/controller/symmetric/balancingoffset/BalancingOffsetController.java @@ -25,6 +25,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ChannelChangeListener; import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.controller.Controller; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; @@ -37,6 +38,7 @@ @ThingInfo(title = "Balancing offset (Symmetric)", description = "Tries to keep the grid meter within an offset. For symmetric Ess.") public class BalancingOffsetController extends Controller { + private ThingStateChannel thingState = new ThingStateChannel(this); /* * Constructors */ @@ -111,9 +113,9 @@ public void run() { Ess ess = this.ess.value(); // Calculate required sum values long calculatedPower = meter.value().activePower.value() + ess.activePower.value() - - activePowerOffset.value(); + - activePowerOffset.value(); long calculatedReactivePower = meter.value().reactivePower.value() + ess.reactivePower.value() - - reactivePowerOffset.value(); + - reactivePowerOffset.value(); if (reactivePowerActivated.value()) { ess.power.setReactivePower(calculatedReactivePower); } @@ -135,4 +137,9 @@ public void run() { } } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/controller/symmetric/balancingsurplus/BalancingSurplusController.java b/edge/src/io/openems/impl/controller/symmetric/balancingsurplus/BalancingSurplusController.java index 58bd5ec0e92..dfee3cb8d6a 100644 --- a/edge/src/io/openems/impl/controller/symmetric/balancingsurplus/BalancingSurplusController.java +++ b/edge/src/io/openems/impl/controller/symmetric/balancingsurplus/BalancingSurplusController.java @@ -1,124 +1,131 @@ -/******************************************************************************* - * 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.symmetric.balancingsurplus; - -import java.util.Set; - -import io.openems.api.channel.ConfigChannel; -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.core.utilities.AvgFiFoQueue; - -@ThingInfo(title = "Self-consumption optimization with surplus feed-in (Symmetric)", description = "Tries to keep the grid meter on zero. For symmetric Ess. If ess is over the surplusMinSoc, the ess discharges with the power of the chargers. ") -public class BalancingSurplusController extends Controller { - - /* - * Constructors - */ - public BalancingSurplusController() { - super(); - } - - public BalancingSurplusController(String thingId) { - super(thingId); - } - - /* - * Config - */ - @ChannelInfo(title = "Ess", description = "Sets the Ess device.", type = Ess.class) - public final ConfigChannel ess = new ConfigChannel("ess", this); - - @ChannelInfo(title = "Charger", description = "Sets the Chargers connected to the ess.", type = Charger.class, isArray = true) - public final ConfigChannel> chargers = new ConfigChannel>("chargers", this); - - @ChannelInfo(title = "Surplus min soc", description = "The required Soc to start surplus feed-in.", type = Long.class) - public final ConfigChannel surplusMinSoc = new ConfigChannel("surplusMinSoc", this); - - @ChannelInfo(title = "Grid-Meter", description = "Sets the grid meter.", type = Meter.class) - public final ConfigChannel meter = new ConfigChannel("meter", this); - - private AvgFiFoQueue meterActivePower = new AvgFiFoQueue(3, 1.5); - private AvgFiFoQueue essActivePower = new AvgFiFoQueue(3, 1.5); - - private long surplus = 0L; - private boolean surplusOn = false; - - /* - * Methods - */ - - @Override - public void run() { - try { - Ess ess = this.ess.value(); - meterActivePower.add(meter.value().activePower.value()); - essActivePower.add((ess.activePower.value() - surplus)); - // Calculate required sum values - long calculatedPower = meterActivePower.avg() + essActivePower.avg(); - surplus = getSurplusPower(); - // in case the storage has surplus it isn't allowed to charge the storage ac - if (calculatedPower < 0 && surplus > 0) { - calculatedPower = 0; - } - if (getPvVoltage() < 200000 || surplus < 0) { - surplus = 0l; - } - calculatedPower += surplus; - ess.power.setActivePower(calculatedPower); - ess.power.writePower(); - } catch (InvalidValueException e) { - log.error(e.getMessage()); - } - } - - private long getSurplusPower() throws InvalidValueException { - long power = 0l; - if (ess.value().soc.value() >= surplusMinSoc.value() + 2) { - surplusOn = true; - } else if (ess.value().soc.value() < surplusMinSoc.value()) { - surplusOn = false; - } - if (surplusOn) { - for (Charger c : chargers.value()) { - power += c.power.value(); - } - long multiplier = ess.value().soc.value() - surplusMinSoc.value() - 2; - if (multiplier > 0) { - power += ess.value().nominalPower.value() * 0.25 / (100 - surplusMinSoc.value() - 2) * multiplier; - } - } - return power; - } - - private long getPvVoltage() throws InvalidValueException { - long voltage = 0; - for (Charger c : chargers.value()) { - if (c.inputVoltage.value() > voltage) { - voltage = c.inputVoltage.value(); - } - } - return voltage; - } - -} +/******************************************************************************* + * 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.symmetric.balancingsurplus; + +import java.util.Set; + +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +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.core.utilities.AvgFiFoQueue; + +@ThingInfo(title = "Self-consumption optimization with surplus feed-in (Symmetric)", description = "Tries to keep the grid meter on zero. For symmetric Ess. If ess is over the surplusMinSoc, the ess discharges with the power of the chargers. ") +public class BalancingSurplusController extends Controller { + + private ThingStateChannel thingState = new ThingStateChannel(this); + /* + * Constructors + */ + public BalancingSurplusController() { + super(); + } + + public BalancingSurplusController(String thingId) { + super(thingId); + } + + /* + * Config + */ + @ChannelInfo(title = "Ess", description = "Sets the Ess device.", type = Ess.class) + public final ConfigChannel ess = new ConfigChannel("ess", this); + + @ChannelInfo(title = "Charger", description = "Sets the Chargers connected to the ess.", type = Charger.class, isArray = true) + public final ConfigChannel> chargers = new ConfigChannel>("chargers", this); + + @ChannelInfo(title = "Surplus min soc", description = "The required Soc to start surplus feed-in.", type = Long.class) + public final ConfigChannel surplusMinSoc = new ConfigChannel("surplusMinSoc", this); + + @ChannelInfo(title = "Grid-Meter", description = "Sets the grid meter.", type = Meter.class) + public final ConfigChannel meter = new ConfigChannel("meter", this); + + private AvgFiFoQueue meterActivePower = new AvgFiFoQueue(3, 1.5); + private AvgFiFoQueue essActivePower = new AvgFiFoQueue(3, 1.5); + + private long surplus = 0L; + private boolean surplusOn = false; + + /* + * Methods + */ + + @Override + public void run() { + try { + Ess ess = this.ess.value(); + meterActivePower.add(meter.value().activePower.value()); + essActivePower.add((ess.activePower.value() - surplus)); + // Calculate required sum values + long calculatedPower = meterActivePower.avg() + essActivePower.avg(); + surplus = getSurplusPower(); + // in case the storage has surplus it isn't allowed to charge the storage ac + if (calculatedPower < 0 && surplus > 0) { + calculatedPower = 0; + } + if (getPvVoltage() < 200000 || surplus < 0) { + surplus = 0l; + } + calculatedPower += surplus; + ess.power.setActivePower(calculatedPower); + ess.power.writePower(); + } catch (InvalidValueException e) { + log.error(e.getMessage()); + } + } + + private long getSurplusPower() throws InvalidValueException { + long power = 0l; + if (ess.value().soc.value() >= surplusMinSoc.value() + 2) { + surplusOn = true; + } else if (ess.value().soc.value() < surplusMinSoc.value()) { + surplusOn = false; + } + if (surplusOn) { + for (Charger c : chargers.value()) { + power += c.power.value(); + } + long multiplier = ess.value().soc.value() - surplusMinSoc.value() - 2; + if (multiplier > 0) { + power += ess.value().nominalPower.value() * 0.25 / (100 - surplusMinSoc.value() - 2) * multiplier; + } + } + return power; + } + + private long getPvVoltage() throws InvalidValueException { + long voltage = 0; + for (Charger c : chargers.value()) { + if (c.inputVoltage.value() > voltage) { + voltage = c.inputVoltage.value(); + } + } + return voltage; + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + +} diff --git a/edge/src/io/openems/impl/controller/symmetric/capacitytest/CapacityTestController.java b/edge/src/io/openems/impl/controller/symmetric/capacitytest/CapacityTestController.java index 466d6a4563e..74e8157086c 100644 --- a/edge/src/io/openems/impl/controller/symmetric/capacitytest/CapacityTestController.java +++ b/edge/src/io/openems/impl/controller/symmetric/capacitytest/CapacityTestController.java @@ -1,149 +1,156 @@ -/******************************************************************************* - * 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.symmetric.capacitytest; - -import java.io.FileWriter; -import java.io.IOException; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.List; -import java.util.Optional; - -import io.openems.api.channel.Channel; -import io.openems.api.channel.ChannelUpdateListener; -import io.openems.api.channel.ConfigChannel; -import io.openems.api.controller.Controller; -import io.openems.api.device.nature.ess.EssNature; -import io.openems.api.doc.ChannelInfo; -import io.openems.api.doc.ThingInfo; -import io.openems.api.exception.InvalidValueException; -import io.openems.api.exception.WriteChannelException; - -@ThingInfo(title = "Battery capacity test (Symmetric)", description = "Executes a capacity test. For symmetric Ess.") -public class CapacityTestController extends Controller { - - /* - * Constructors - */ - public CapacityTestController() { - super(); - initialize(); - } - - public CapacityTestController(String thingId) { - super(thingId); - initialize(); - } - - /* - * Config - */ - @ChannelInfo(title = "Power", description = "Discharge power of Ess.", type = Integer.class, defaultValue = "750") - public ConfigChannel power = new ConfigChannel("power", this); - - @ChannelInfo(title = "Sleep", description = "Time to sleep after empty ess before start capacityTest.", type = Integer.class, defaultValue = "750") - public ConfigChannel sleep = new ConfigChannel("sleep", this); - - @ChannelInfo(title = "Log-File", description = "Path to save the logfile.", type = String.class) - public ConfigChannel logPath = new ConfigChannel("logPath", this); - - @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class, isArray = true) - public ConfigChannel> esss = new ConfigChannel>("esss", this); - - private Long start = null; - - /* - * Fields - */ - private FileWriter fw; - - /* - * Methods - */ - private void initialize() { - logPath.addUpdateListener(new ChannelUpdateListener() { - - @Override - public void channelUpdated(Channel channel, Optional newValue) { - try { - if (fw != null) { - fw.close(); - } - fw = new FileWriter(logPath.value()); - fw.write("time;activePower;soc\n"); - } catch (IOException e) { - log.error(e.getMessage()); - } catch (InvalidValueException e) { - log.error(e.getMessage()); - } - - } - }); - } - - @Override - public void run() { - if (start == null) { - start = System.currentTimeMillis(); - } - if (start != null && start + 5000 <= System.currentTimeMillis()) { - try { - for (Ess ess : esss.value()) { - ess.setWorkState.pushWriteFromLabel(EssNature.START); - if (ess.empty) { - if (ess.timeEmpty + sleep.value() <= System.currentTimeMillis()) { - // Capacitytest - if (ess.full) { - // fully discharge ess - ess.setActivePower.pushWrite((long) power.value()); - } else { - // fully charge ess - ess.setActivePower.pushWrite((long) power.value() * -1); - if (ess.allowedCharge.value() >= -100l - && ess.systemState.labelOptional().equals(Optional.of(EssNature.START))) { - ess.full = true; - } - } - fw.append(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) - + ";" + ess.activePower.value() + ";" + ess.soc.value() + "\n"); - fw.flush(); - } - } else { - // prepare for capacityTest - // Empty ess - ess.setActivePower.pushWrite(ess.allowedDischarge.value()); - if (ess.soc.value() <= ess.minSoc.value()) { - ess.empty = true; - ess.timeEmpty = System.currentTimeMillis(); - } - } - } - } catch (InvalidValueException e) { - log.error(e.getMessage()); - } catch (WriteChannelException e) { - log.error(e.getMessage()); - } catch (IOException e) { - log.error(e.getMessage()); - } - } - } - -} +/******************************************************************************* + * 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.symmetric.capacitytest; + +import java.io.FileWriter; +import java.io.IOException; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; +import java.util.Optional; + +import io.openems.api.channel.Channel; +import io.openems.api.channel.ChannelUpdateListener; +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.controller.Controller; +import io.openems.api.device.nature.ess.EssNature; +import io.openems.api.doc.ChannelInfo; +import io.openems.api.doc.ThingInfo; +import io.openems.api.exception.InvalidValueException; +import io.openems.api.exception.WriteChannelException; + +@ThingInfo(title = "Battery capacity test (Symmetric)", description = "Executes a capacity test. For symmetric Ess.") +public class CapacityTestController extends Controller { + + private ThingStateChannel thingState = new ThingStateChannel(this); + /* + * Constructors + */ + public CapacityTestController() { + super(); + initialize(); + } + + public CapacityTestController(String thingId) { + super(thingId); + initialize(); + } + + /* + * Config + */ + @ChannelInfo(title = "Power", description = "Discharge power of Ess.", type = Integer.class, defaultValue = "750") + public ConfigChannel power = new ConfigChannel("power", this); + + @ChannelInfo(title = "Sleep", description = "Time to sleep after empty ess before start capacityTest.", type = Integer.class, defaultValue = "750") + public ConfigChannel sleep = new ConfigChannel("sleep", this); + + @ChannelInfo(title = "Log-File", description = "Path to save the logfile.", type = String.class) + public ConfigChannel logPath = new ConfigChannel("logPath", this); + + @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class, isArray = true) + public ConfigChannel> esss = new ConfigChannel>("esss", this); + + private Long start = null; + + /* + * Fields + */ + private FileWriter fw; + + /* + * Methods + */ + private void initialize() { + logPath.addUpdateListener(new ChannelUpdateListener() { + + @Override + public void channelUpdated(Channel channel, Optional newValue) { + try { + if (fw != null) { + fw.close(); + } + fw = new FileWriter(logPath.value()); + fw.write("time;activePower;soc\n"); + } catch (IOException e) { + log.error(e.getMessage()); + } catch (InvalidValueException e) { + log.error(e.getMessage()); + } + + } + }); + } + + @Override + public void run() { + if (start == null) { + start = System.currentTimeMillis(); + } + if (start != null && start + 5000 <= System.currentTimeMillis()) { + try { + for (Ess ess : esss.value()) { + ess.setWorkState.pushWriteFromLabel(EssNature.START); + if (ess.empty) { + if (ess.timeEmpty + sleep.value() <= System.currentTimeMillis()) { + // Capacitytest + if (ess.full) { + // fully discharge ess + ess.setActivePower.pushWrite((long) power.value()); + } else { + // fully charge ess + ess.setActivePower.pushWrite((long) power.value() * -1); + if (ess.allowedCharge.value() >= -100l + && ess.systemState.labelOptional().equals(Optional.of(EssNature.START))) { + ess.full = true; + } + } + fw.append(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + + ";" + ess.activePower.value() + ";" + ess.soc.value() + "\n"); + fw.flush(); + } + } else { + // prepare for capacityTest + // Empty ess + ess.setActivePower.pushWrite(ess.allowedDischarge.value()); + if (ess.soc.value() <= ess.minSoc.value()) { + ess.empty = true; + ess.timeEmpty = System.currentTimeMillis(); + } + } + } + } catch (InvalidValueException e) { + log.error(e.getMessage()); + } catch (WriteChannelException e) { + log.error(e.getMessage()); + } catch (IOException e) { + log.error(e.getMessage()); + } + } + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + +} diff --git a/edge/src/io/openems/impl/controller/symmetric/commercialenergysaver/EnergysavingController.java b/edge/src/io/openems/impl/controller/symmetric/commercialenergysaver/EnergysavingController.java index 4e08618940f..908bf41bfa9 100644 --- a/edge/src/io/openems/impl/controller/symmetric/commercialenergysaver/EnergysavingController.java +++ b/edge/src/io/openems/impl/controller/symmetric/commercialenergysaver/EnergysavingController.java @@ -1,116 +1,123 @@ -/******************************************************************************* - * 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.symmetric.commercialenergysaver; - -import java.util.Optional; -import java.util.Set; - -import io.openems.api.channel.ConfigChannel; -import io.openems.api.controller.Controller; -import io.openems.api.device.nature.ess.SymmetricEssNature; -import io.openems.api.doc.ChannelInfo; -import io.openems.api.doc.ThingInfo; -import io.openems.api.exception.InvalidValueException; -import io.openems.api.exception.WriteChannelException; - -/** - * @author matthias.rossmann - */ -@ThingInfo(title = "Energy saving (Symmetric)", description = "Sends the Ess to Standby if no power is required for two minutes. Do not use if Off-Grid functionality is required. For symmetric Ess.") -public class EnergysavingController extends Controller { - - /* - * Constructors - */ - public EnergysavingController() { - super(); - } - - public EnergysavingController(String thingId) { - super(thingId); - } - - /* - * Config - */ - @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class, isArray = true) - public final ConfigChannel> esss = new ConfigChannel>("esss", this); - - /* - * Fields - */ - private Long lastTimeValueWritten = 0L; - - /* - * Methods - */ - @Override - public void run() { - try { - for (Ess ess : esss.value()) { - try { - Optional systemState = ess.systemState.labelOptional(); - if (systemState.isPresent()) { - if ((ess.setActivePower.peekWrite().isPresent() && ess.setActivePower.peekWrite().get() != 0) - || (ess.setReactivePower.peekWrite().isPresent() - && ess.setReactivePower.peekWrite().get() != 0)) { - if (!systemState.get().equals(SymmetricEssNature.START)) { - // Current system state is not START - if (ess.setWorkState.peekWriteLabel().orElse(SymmetricEssNature.START) - .equals(SymmetricEssNature.START)) { - // SetWorkState was not set to anything different than START before -> START the - // system - log.info("ESS [" + ess.id() + "] was stopped. Starting..."); - ess.setWorkState.pushWriteFromLabel(SymmetricEssNature.START); - } - } - lastTimeValueWritten = System.currentTimeMillis(); - } else { - /* - * go to Standby if no values were written since two minutes - */ - if (lastTimeValueWritten + 2 * 60 * 1000 < System.currentTimeMillis()) { - if (!systemState.isPresent() || (!systemState.get().equals(SymmetricEssNature.STANDBY) - && !systemState.get().equals("PV-Charge"))) { - // System state was not yet STANDBY or PV-Charge - if (ess.setWorkState.peekWriteLabel().orElse(SymmetricEssNature.STANDBY) - .equals(SymmetricEssNature.STANDBY)) { - // SetWorkState was not set to anything different than STANDBY before -> put the - // system - // in STANDBY - log.info("ESS [" + ess.id() - + "] had no written value since two minutes. Standby..."); - ess.setWorkState.pushWriteFromLabel(SymmetricEssNature.STANDBY); - } - } - } - } - } - } catch (WriteChannelException e) { - log.error("", e); - } - } - } catch (InvalidValueException e) { - log.error("", e); - } - } - -} +/******************************************************************************* + * 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.symmetric.commercialenergysaver; + +import java.util.Optional; +import java.util.Set; + +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.controller.Controller; +import io.openems.api.device.nature.ess.SymmetricEssNature; +import io.openems.api.doc.ChannelInfo; +import io.openems.api.doc.ThingInfo; +import io.openems.api.exception.InvalidValueException; +import io.openems.api.exception.WriteChannelException; + +/** + * @author matthias.rossmann + */ +@ThingInfo(title = "Energy saving (Symmetric)", description = "Sends the Ess to Standby if no power is required for two minutes. Do not use if Off-Grid functionality is required. For symmetric Ess.") +public class EnergysavingController extends Controller { + + private ThingStateChannel thingState = new ThingStateChannel(this); + /* + * Constructors + */ + public EnergysavingController() { + super(); + } + + public EnergysavingController(String thingId) { + super(thingId); + } + + /* + * Config + */ + @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class, isArray = true) + public final ConfigChannel> esss = new ConfigChannel>("esss", this); + + /* + * Fields + */ + private Long lastTimeValueWritten = 0L; + + /* + * Methods + */ + @Override + public void run() { + try { + for (Ess ess : esss.value()) { + try { + Optional systemState = ess.systemState.labelOptional(); + if (systemState.isPresent()) { + if ((ess.setActivePower.peekWrite().isPresent() && ess.setActivePower.peekWrite().get() != 0) + || (ess.setReactivePower.peekWrite().isPresent() + && ess.setReactivePower.peekWrite().get() != 0)) { + if (!systemState.get().equals(SymmetricEssNature.START)) { + // Current system state is not START + if (ess.setWorkState.peekWriteLabel().orElse(SymmetricEssNature.START) + .equals(SymmetricEssNature.START)) { + // SetWorkState was not set to anything different than START before -> START the + // system + log.info("ESS [" + ess.id() + "] was stopped. Starting..."); + ess.setWorkState.pushWriteFromLabel(SymmetricEssNature.START); + } + } + lastTimeValueWritten = System.currentTimeMillis(); + } else { + /* + * go to Standby if no values were written since two minutes + */ + if (lastTimeValueWritten + 2 * 60 * 1000 < System.currentTimeMillis()) { + if (!systemState.isPresent() || (!systemState.get().equals(SymmetricEssNature.STANDBY) + && !systemState.get().equals("PV-Charge"))) { + // System state was not yet STANDBY or PV-Charge + if (ess.setWorkState.peekWriteLabel().orElse(SymmetricEssNature.STANDBY) + .equals(SymmetricEssNature.STANDBY)) { + // SetWorkState was not set to anything different than STANDBY before -> put the + // system + // in STANDBY + log.info("ESS [" + ess.id() + + "] had no written value since two minutes. Standby..."); + ess.setWorkState.pushWriteFromLabel(SymmetricEssNature.STANDBY); + } + } + } + } + } + } catch (WriteChannelException e) { + log.error("", e); + } + } + } catch (InvalidValueException e) { + log.error("", e); + } + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + +} diff --git a/edge/src/io/openems/impl/controller/symmetric/commercialworkstate/AlwaysOnController.java b/edge/src/io/openems/impl/controller/symmetric/commercialworkstate/AlwaysOnController.java index c9b5b31bd32..00ee98e8bc1 100644 --- a/edge/src/io/openems/impl/controller/symmetric/commercialworkstate/AlwaysOnController.java +++ b/edge/src/io/openems/impl/controller/symmetric/commercialworkstate/AlwaysOnController.java @@ -1,73 +1,80 @@ -/******************************************************************************* - * 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.symmetric.commercialworkstate; - -import java.util.Set; - -import io.openems.api.channel.ConfigChannel; -import io.openems.api.controller.Controller; -import io.openems.api.device.nature.ess.EssNature; -import io.openems.api.doc.ChannelInfo; -import io.openems.api.doc.ThingInfo; -import io.openems.api.exception.InvalidValueException; -import io.openems.api.exception.WriteChannelException; - -/** - * @author matthias.rossmann - */ -@ThingInfo(title = "Keep always running (Symmetric)", description = "Tries to keep the Ess always running. Use if Off-Grid functionality is required. For symmetric Ess.") -public class AlwaysOnController extends Controller { - - /* - * Constructors - */ - public AlwaysOnController() { - super(); - } - - public AlwaysOnController(String thingId) { - super(thingId); - } - - /* - * Config - */ - @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class, isArray = true) - public final ConfigChannel> esss = new ConfigChannel>("esss", this); - - /* - * Methods - */ - @Override - public void run() { - try { - for (Ess ess : esss.value()) { - try { - ess.setWorkState.pushWriteFromLabel(EssNature.START); - } catch (WriteChannelException e) { - log.error("", e); - } - } - } catch (InvalidValueException e) { - log.error("No Storage Found!", e); - } - } -} +/******************************************************************************* + * 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.symmetric.commercialworkstate; + +import java.util.Set; + +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.controller.Controller; +import io.openems.api.device.nature.ess.EssNature; +import io.openems.api.doc.ChannelInfo; +import io.openems.api.doc.ThingInfo; +import io.openems.api.exception.InvalidValueException; +import io.openems.api.exception.WriteChannelException; + +/** + * @author matthias.rossmann + */ +@ThingInfo(title = "Keep always running (Symmetric)", description = "Tries to keep the Ess always running. Use if Off-Grid functionality is required. For symmetric Ess.") +public class AlwaysOnController extends Controller { + + private ThingStateChannel thingState = new ThingStateChannel(this); + /* + * Constructors + */ + public AlwaysOnController() { + super(); + } + + public AlwaysOnController(String thingId) { + super(thingId); + } + + /* + * Config + */ + @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class, isArray = true) + public final ConfigChannel> esss = new ConfigChannel>("esss", this); + + /* + * Methods + */ + @Override + public void run() { + try { + for (Ess ess : esss.value()) { + try { + ess.setWorkState.pushWriteFromLabel(EssNature.START); + } catch (WriteChannelException e) { + log.error("", e); + } + } + } catch (InvalidValueException e) { + log.error("No Storage Found!", e); + } + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } +} diff --git a/edge/src/io/openems/impl/controller/symmetric/cosphi/CosPhiController.java b/edge/src/io/openems/impl/controller/symmetric/cosphi/CosPhiController.java index d5689ee6296..e2852ee0aa6 100644 --- a/edge/src/io/openems/impl/controller/symmetric/cosphi/CosPhiController.java +++ b/edge/src/io/openems/impl/controller/symmetric/cosphi/CosPhiController.java @@ -1,72 +1,79 @@ -/******************************************************************************* - * 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.symmetric.cosphi; - -import io.openems.api.channel.ConfigChannel; -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.core.utilities.ControllerUtils; - -@ThingInfo(title = "Ess Cos-Phi (Symmetric)", description = "Keeps the Ess at a given cos-phi. For symmetric Ess.") -public class CosPhiController extends Controller { - - /* - * Constructors - */ - public CosPhiController() { - super(); - } - - public CosPhiController(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 = "Cos-Phi", description = "The cos-phi to hold on the storage.", type = Double.class) - public ConfigChannel cosPhi = new ConfigChannel("cosPhi", this); - - /* - * Methods - */ - @Override - public void run() { - try { - if (ess.value().setActivePower.peekWrite().isPresent()) { - ess.value().power.setReactivePower(ControllerUtils - .calculateReactivePower(ess.value().setActivePower.peekWrite().get(), cosPhi.value())); - ess.value().power.writePower(); - log.info("Set ReactivePower [" + ess.value().power.getReactivePower() + "]"); - } else { - log.error(ess.id() + " no ActivePower is Set."); - } - } catch (InvalidValueException e) { - log.error("No ess found.", e); - } - } - -} +/******************************************************************************* + * 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.symmetric.cosphi; + +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +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.core.utilities.ControllerUtils; + +@ThingInfo(title = "Ess Cos-Phi (Symmetric)", description = "Keeps the Ess at a given cos-phi. For symmetric Ess.") +public class CosPhiController extends Controller { + + private ThingStateChannel thingState = new ThingStateChannel(this); + /* + * Constructors + */ + public CosPhiController() { + super(); + } + + public CosPhiController(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 = "Cos-Phi", description = "The cos-phi to hold on the storage.", type = Double.class) + public ConfigChannel cosPhi = new ConfigChannel("cosPhi", this); + + /* + * Methods + */ + @Override + public void run() { + try { + if (ess.value().setActivePower.peekWrite().isPresent()) { + ess.value().power.setReactivePower(ControllerUtils + .calculateReactivePower(ess.value().setActivePower.peekWrite().get(), cosPhi.value())); + ess.value().power.writePower(); + log.info("Set ReactivePower [" + ess.value().power.getReactivePower() + "]"); + } else { + log.error(ess.id() + " no ActivePower is Set."); + } + } catch (InvalidValueException e) { + log.error("No ess found.", e); + } + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + +} diff --git a/edge/src/io/openems/impl/controller/symmetric/cosphicharacteristic/CosPhiCharacteristicController.java b/edge/src/io/openems/impl/controller/symmetric/cosphicharacteristic/CosPhiCharacteristicController.java index da7d3f8fae9..4f70085a097 100644 --- a/edge/src/io/openems/impl/controller/symmetric/cosphicharacteristic/CosPhiCharacteristicController.java +++ b/edge/src/io/openems/impl/controller/symmetric/cosphicharacteristic/CosPhiCharacteristicController.java @@ -1,97 +1,104 @@ -/******************************************************************************* - * 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.symmetric.cosphicharacteristic; - -import java.util.ArrayList; -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; -import io.openems.api.exception.InvalidValueException; -import io.openems.core.utilities.ControllerUtils; -import io.openems.core.utilities.Point; - -@ThingInfo(title = "Cos-Phi Characteristics (Symmetric)") -public class CosPhiCharacteristicController extends Controller { - - /* - * Constructors - */ - public CosPhiCharacteristicController() { - super(); - } - - public CosPhiCharacteristicController(String id) { - super(id); - } - - /* - * Config - */ - @ChannelInfo(title = "Ess", description = "Sets the Ess device.", type = Ess.class) - public ConfigChannel ess = new ConfigChannel<>("ess", this); - - @ChannelInfo(title = "Cos-Phi characteristic", description = "The points of the characteristic (x = PowerRatio, y = cosPhi).", type = Long[].class, isArray = true) - public ConfigChannel> cosPhiPoints = new ConfigChannel>("cosPhiPoints", this) - .addChangeListener((channel, newValue, oldValue) -> { - List points = new ArrayList<>(); - if (newValue.isPresent()) { - @SuppressWarnings("unchecked") List cosPhiPoints = (List) newValue.get(); - for (Long[] arr : cosPhiPoints) { - points.add(new Point(arr[0], arr[1])); - } - } else { - log.error("found no cosPhiPoints!"); - } - cosPhiCharacteristic = points; - }); - - /* - * Fields - */ - public List cosPhiCharacteristic; - - /* - * Methods - */ - @Override - public void run() { - try { - if (ess.value().setActivePower.peekWrite().isPresent()) { - double pRatio = (double) ess.value().setActivePower.peekWrite().get() - / (double) ess.value().nominalPower.value() * 100; - double cosPhi = ControllerUtils.getValueOfLine(cosPhiCharacteristic, pRatio) / 100; - ess.value().power.setReactivePower( - ControllerUtils.calculateReactivePower(ess.value().setActivePower.peekWrite().get(), cosPhi)); - ess.value().power.writePower(); - log.info("Set reactive power [{}] to get cosPhi [{}]", - new Object[] { ess.value().power.getReactivePower(), cosPhi }); - } else { - log.error(ess.id() + " no ActivePower is Set."); - } - } catch (InvalidValueException e) { - log.error("No ess found.", e); - } - } - -} +/******************************************************************************* + * 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.symmetric.cosphicharacteristic; + +import java.util.ArrayList; +import java.util.List; + +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +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.core.utilities.ControllerUtils; +import io.openems.core.utilities.Point; + +@ThingInfo(title = "Cos-Phi Characteristics (Symmetric)") +public class CosPhiCharacteristicController extends Controller { + + private ThingStateChannel thingState = new ThingStateChannel(this); + /* + * Constructors + */ + public CosPhiCharacteristicController() { + super(); + } + + public CosPhiCharacteristicController(String id) { + super(id); + } + + /* + * Config + */ + @ChannelInfo(title = "Ess", description = "Sets the Ess device.", type = Ess.class) + public ConfigChannel ess = new ConfigChannel<>("ess", this); + + @ChannelInfo(title = "Cos-Phi characteristic", description = "The points of the characteristic (x = PowerRatio, y = cosPhi).", type = Long[].class, isArray = true) + public ConfigChannel> cosPhiPoints = new ConfigChannel>("cosPhiPoints", this) + .addChangeListener((channel, newValue, oldValue) -> { + List points = new ArrayList<>(); + if (newValue.isPresent()) { + @SuppressWarnings("unchecked") List cosPhiPoints = (List) newValue.get(); + for (Long[] arr : cosPhiPoints) { + points.add(new Point(arr[0], arr[1])); + } + } else { + log.error("found no cosPhiPoints!"); + } + cosPhiCharacteristic = points; + }); + + /* + * Fields + */ + public List cosPhiCharacteristic; + + /* + * Methods + */ + @Override + public void run() { + try { + if (ess.value().setActivePower.peekWrite().isPresent()) { + double pRatio = (double) ess.value().setActivePower.peekWrite().get() + / (double) ess.value().nominalPower.value() * 100; + double cosPhi = ControllerUtils.getValueOfLine(cosPhiCharacteristic, pRatio) / 100; + ess.value().power.setReactivePower( + ControllerUtils.calculateReactivePower(ess.value().setActivePower.peekWrite().get(), cosPhi)); + ess.value().power.writePower(); + log.info("Set reactive power [{}] to get cosPhi [{}]", + new Object[] { ess.value().power.getReactivePower(), cosPhi }); + } else { + log.error(ess.id() + " no ActivePower is Set."); + } + } catch (InvalidValueException e) { + log.error("No ess found.", e); + } + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + +} diff --git a/edge/src/io/openems/impl/controller/symmetric/fixvalue/FixValueController.java b/edge/src/io/openems/impl/controller/symmetric/fixvalue/FixValueController.java index 0a0a28a5af4..d7c044f1fac 100644 --- a/edge/src/io/openems/impl/controller/symmetric/fixvalue/FixValueController.java +++ b/edge/src/io/openems/impl/controller/symmetric/fixvalue/FixValueController.java @@ -23,6 +23,7 @@ import java.util.List; import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.controller.Controller; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; @@ -31,6 +32,7 @@ @ThingInfo(title = "Fixed active and reactive power (Symmetric)", description = "Charges or discharges the battery with a predefined, fixed power. For symmetric Ess.") public class FixValueController extends Controller { + private ThingStateChannel thingState = new ThingStateChannel(this); /* * Constructors */ @@ -74,4 +76,9 @@ public void run() { } } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/controller/symmetric/offGridPowerStation/OffGridPowerStationController.java b/edge/src/io/openems/impl/controller/symmetric/offGridPowerStation/OffGridPowerStationController.java index 7db4f53bade..fd817fda488 100644 --- a/edge/src/io/openems/impl/controller/symmetric/offGridPowerStation/OffGridPowerStationController.java +++ b/edge/src/io/openems/impl/controller/symmetric/offGridPowerStation/OffGridPowerStationController.java @@ -1,274 +1,281 @@ -/******************************************************************************* - * 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.symmetric.offGridPowerStation; - -import java.util.Optional; - -import io.openems.api.channel.Channel; -import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.WriteChannel; -import io.openems.api.controller.Controller; -import io.openems.api.device.nature.ess.EssNature; -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; - -@ThingInfo(title = "External power station control", description = "Starts an thermal power station in case of off-Grid and empty ess.") -public class OffGridPowerStationController extends Controller { - - /* - * Constructors - */ - public OffGridPowerStationController() { - super(); - } - - public OffGridPowerStationController(String thingId) { - super(thingId); - } - - /* - * Config - */ - @ChannelInfo(title = "Ess", description = "Sets the Ess device.", type = Ess.class) - public ConfigChannel ess = new ConfigChannel("ess", this); - - @ChannelInfo(title = "Grid-meter", description = "Sets the grid-meter to detect if the system is Off-Grid or On-Grid.", type = Meter.class) - public ConfigChannel meter = new ConfigChannel("meter", this); - - @ChannelInfo(title = "Min-SOC", description = "If the SOC falls under this value and the system is Off-Grid the generator starts.", type = Long.class) - public ConfigChannel minSoc = new ConfigChannel("minSoc", this); - - @ChannelInfo(title = "Max-SOC", description = "If the system is Off-Grid and the generator is running, the generator stops if the SOC level increases over the Max-SOC.", type = Long.class) - public ConfigChannel maxSoc = new ConfigChannel("maxSoc", this); - - @ChannelInfo(title = "Invert-Output", description = "True if the digital output should be inverted.", type = Boolean.class) - public ConfigChannel invertOutput = new ConfigChannel<>("invertOutput", this); - - @ChannelInfo(title = "On-Grid output on", description = "This value indicates if the system is On-Grid to start(true) or stop(false) the generator.", type = Boolean.class, isOptional = true) - public ConfigChannel onGridOutputOn = new ConfigChannel("onGridOutputOn", this) - .defaultValue(false); - - @ChannelInfo(title = "time to wait before switch output on.", type = Long.class) - public ConfigChannel switchDelay = new ConfigChannel("switchDelay", this).defaultValue(10000L); - - /* - * Fields - */ - private ThingRepository repo = ThingRepository.getInstance(); - private WriteChannel outputChannel; - private long timeOnGrid = 0L; - private long timeOffGrid = 0L; - private long startTime = System.currentTimeMillis(); - private State currentState = State.UNKNOWN; - private OffGridState currentOffGridState = OffGridState.STOP; - - private enum State { - GOONGRID1, GOONGRID2, ONGRID, GOOFFGRID, OFFGRID, UNKNOWN - } - - private enum OffGridState { - STOPGENERATOR, STARTGENERATOR, STOP, RUNNING - } - - /* - * Methods - */ - @SuppressWarnings("unchecked") - @ChannelInfo(title = "the address of the Digital Output where the generator is connected to.", type = String.class) - public ConfigChannel outputChannelAddress = 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!"); - } - }); - - @Override - public void run() { - if (startTime + 1000 * 15 <= System.currentTimeMillis()) { - try { - switch (currentState) { - case GOOFFGRID: - if (isOff()) { - if (timeOffGrid + switchDelay.value() <= System.currentTimeMillis()) { - currentState = State.OFFGRID; - } - } else { - stopGenerator(); - timeOffGrid = System.currentTimeMillis(); - } - break; - case GOONGRID1: - if (isOff()) { - if (timeOnGrid + switchDelay.value() <= System.currentTimeMillis()) { - currentState = State.GOONGRID2; - } - } else { - stopGenerator(); - timeOnGrid = System.currentTimeMillis(); - } - break; - case GOONGRID2: - // check if outputstate is correct according to onGridOutputOn => !(1^1) = 1, !(1^0) = 0, - // !(0^1) = 0, !(0^0) = 1 - if (!(onGridOutputOn.value() ^ isOn())) { - currentState = State.ONGRID; - } else { - if (onGridOutputOn.value()) { - startGenerator(); - } else { - stopGenerator(); - } - } - break; - case ONGRID: - if (meter.value().voltage.valueOptional().isPresent() - || ess.value().gridMode.labelOptional().equals(Optional.of(EssNature.ON_GRID))) { - if (onGridOutputOn.value() ^ isOn()) { - currentState = State.GOONGRID2; - } - } else { - currentState = State.GOOFFGRID; - } - break; - case OFFGRID: - if (meter.value().voltage.valueOptional().isPresent()) { - currentState = State.GOONGRID1; - currentOffGridState = OffGridState.STOP; - } else { - switch (currentOffGridState) { - case RUNNING: - if (!ess.value().soc.valueOptional().isPresent() - || ess.value().soc.value() >= maxSoc.value()) { - currentOffGridState = OffGridState.STOPGENERATOR; - } - break; - case STARTGENERATOR: - if (isOn()) { - currentOffGridState = OffGridState.RUNNING; - } else { - startGenerator(); - } - break; - case STOP: - if (ess.value().soc.valueOptional().isPresent() - && ess.value().soc.value() <= minSoc.value()) { - currentOffGridState = OffGridState.STARTGENERATOR; - } - break; - case STOPGENERATOR: - if (isOff()) { - currentOffGridState = OffGridState.STOP; - } else { - stopGenerator(); - } - break; - } - } - log.info("current Off-Grid State: " + currentOffGridState); - break; - case UNKNOWN: - default: - if (meter.value().voltage.valueOptional().isPresent()) { - currentState = State.GOONGRID2; - } else { - currentState = State.GOOFFGRID; - } - break; - - } - log.info("current State: " + currentState); - // // Check if grid is available - // if (!meter.value().voltage.valueOptional().isPresent()) { - // // no meassurable voltage => Off-Grid - // if (!generatorOn && ess.value().soc.valueOptional().isPresent() - // && ess.value().soc.value() <= minSoc.value()) { - // // switch generator on - // startGenerator(); - // generatorOn = true; - // } else if (generatorOn && (!ess.value().soc.valueOptional().isPresent() - // || ess.value().soc.value() >= maxSoc.value())) { - // // switch generator off - // stopGenerator(); - // generatorOn = false; - // } else if (generatorOn) { - // startGenerator(); - // } else if (!generatorOn) { - // stopGenerator(); - // } - // switchedToOnGrid = false; - // } else { - // // Grid voltage is in the allowed range - // if (switchedToOnGrid) { - // if (timeOnGrid + switchDelay.value() <= System.currentTimeMillis()) { - // if (onGridOutputOn.value()) { - // startGenerator(); - // } else { - // stopGenerator(); - // } - // } - // } else { - // stopGenerator(); - // timeOnGrid = System.currentTimeMillis(); - // switchedToOnGrid = true; - // } - // } - } catch (InvalidValueException e) { - log.error("Failed to read value!", e); - } catch (WriteChannelException e) { - log.error("Error due write to output [" + outputChannelAddress.valueOptional().orElse("") + "]", - e); - } - } - - } - - private void startGenerator() throws WriteChannelException, InvalidValueException { - if (outputChannel.value() != true ^ invertOutput.value()) { - outputChannel.pushWrite(true ^ invertOutput.value()); - } - } - - private void stopGenerator() throws InvalidValueException, WriteChannelException { - if (outputChannel.value() != false ^ invertOutput.value()) { - outputChannel.pushWrite(false ^ invertOutput.value()); - } - } - - private boolean isOff() throws InvalidValueException { - return outputChannel.value() == false ^ invertOutput.value(); - } - - private boolean isOn() throws InvalidValueException { - return outputChannel.value() == true ^ invertOutput.value(); - } - -} +/******************************************************************************* + * 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.symmetric.offGridPowerStation; + +import java.util.Optional; + +import io.openems.api.channel.Channel; +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.WriteChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.controller.Controller; +import io.openems.api.device.nature.ess.EssNature; +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; + +@ThingInfo(title = "External power station control", description = "Starts an thermal power station in case of off-Grid and empty ess.") +public class OffGridPowerStationController extends Controller { + + private ThingStateChannel thingState = new ThingStateChannel(this); + /* + * Constructors + */ + public OffGridPowerStationController() { + super(); + } + + public OffGridPowerStationController(String thingId) { + super(thingId); + } + + /* + * Config + */ + @ChannelInfo(title = "Ess", description = "Sets the Ess device.", type = Ess.class) + public ConfigChannel ess = new ConfigChannel("ess", this); + + @ChannelInfo(title = "Grid-meter", description = "Sets the grid-meter to detect if the system is Off-Grid or On-Grid.", type = Meter.class) + public ConfigChannel meter = new ConfigChannel("meter", this); + + @ChannelInfo(title = "Min-SOC", description = "If the SOC falls under this value and the system is Off-Grid the generator starts.", type = Long.class) + public ConfigChannel minSoc = new ConfigChannel("minSoc", this); + + @ChannelInfo(title = "Max-SOC", description = "If the system is Off-Grid and the generator is running, the generator stops if the SOC level increases over the Max-SOC.", type = Long.class) + public ConfigChannel maxSoc = new ConfigChannel("maxSoc", this); + + @ChannelInfo(title = "Invert-Output", description = "True if the digital output should be inverted.", type = Boolean.class) + public ConfigChannel invertOutput = new ConfigChannel<>("invertOutput", this); + + @ChannelInfo(title = "On-Grid output on", description = "This value indicates if the system is On-Grid to start(true) or stop(false) the generator.", type = Boolean.class, isOptional = true) + public ConfigChannel onGridOutputOn = new ConfigChannel("onGridOutputOn", this) + .defaultValue(false); + + @ChannelInfo(title = "time to wait before switch output on.", type = Long.class) + public ConfigChannel switchDelay = new ConfigChannel("switchDelay", this).defaultValue(10000L); + + /* + * Fields + */ + private ThingRepository repo = ThingRepository.getInstance(); + private WriteChannel outputChannel; + private long timeOnGrid = 0L; + private long timeOffGrid = 0L; + private long startTime = System.currentTimeMillis(); + private State currentState = State.UNKNOWN; + private OffGridState currentOffGridState = OffGridState.STOP; + + private enum State { + GOONGRID1, GOONGRID2, ONGRID, GOOFFGRID, OFFGRID, UNKNOWN + } + + private enum OffGridState { + STOPGENERATOR, STARTGENERATOR, STOP, RUNNING + } + + /* + * Methods + */ + @SuppressWarnings("unchecked") + @ChannelInfo(title = "the address of the Digital Output where the generator is connected to.", type = String.class) + public ConfigChannel outputChannelAddress = 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!"); + } + }); + + @Override + public void run() { + if (startTime + 1000 * 15 <= System.currentTimeMillis()) { + try { + switch (currentState) { + case GOOFFGRID: + if (isOff()) { + if (timeOffGrid + switchDelay.value() <= System.currentTimeMillis()) { + currentState = State.OFFGRID; + } + } else { + stopGenerator(); + timeOffGrid = System.currentTimeMillis(); + } + break; + case GOONGRID1: + if (isOff()) { + if (timeOnGrid + switchDelay.value() <= System.currentTimeMillis()) { + currentState = State.GOONGRID2; + } + } else { + stopGenerator(); + timeOnGrid = System.currentTimeMillis(); + } + break; + case GOONGRID2: + // check if outputstate is correct according to onGridOutputOn => !(1^1) = 1, !(1^0) = 0, + // !(0^1) = 0, !(0^0) = 1 + if (!(onGridOutputOn.value() ^ isOn())) { + currentState = State.ONGRID; + } else { + if (onGridOutputOn.value()) { + startGenerator(); + } else { + stopGenerator(); + } + } + break; + case ONGRID: + if (meter.value().voltage.valueOptional().isPresent() + || ess.value().gridMode.labelOptional().equals(Optional.of(EssNature.ON_GRID))) { + if (onGridOutputOn.value() ^ isOn()) { + currentState = State.GOONGRID2; + } + } else { + currentState = State.GOOFFGRID; + } + break; + case OFFGRID: + if (meter.value().voltage.valueOptional().isPresent()) { + currentState = State.GOONGRID1; + currentOffGridState = OffGridState.STOP; + } else { + switch (currentOffGridState) { + case RUNNING: + if (!ess.value().soc.valueOptional().isPresent() + || ess.value().soc.value() >= maxSoc.value()) { + currentOffGridState = OffGridState.STOPGENERATOR; + } + break; + case STARTGENERATOR: + if (isOn()) { + currentOffGridState = OffGridState.RUNNING; + } else { + startGenerator(); + } + break; + case STOP: + if (ess.value().soc.valueOptional().isPresent() + && ess.value().soc.value() <= minSoc.value()) { + currentOffGridState = OffGridState.STARTGENERATOR; + } + break; + case STOPGENERATOR: + if (isOff()) { + currentOffGridState = OffGridState.STOP; + } else { + stopGenerator(); + } + break; + } + } + log.info("current Off-Grid State: " + currentOffGridState); + break; + case UNKNOWN: + default: + if (meter.value().voltage.valueOptional().isPresent()) { + currentState = State.GOONGRID2; + } else { + currentState = State.GOOFFGRID; + } + break; + + } + log.info("current State: " + currentState); + // // Check if grid is available + // if (!meter.value().voltage.valueOptional().isPresent()) { + // // no meassurable voltage => Off-Grid + // if (!generatorOn && ess.value().soc.valueOptional().isPresent() + // && ess.value().soc.value() <= minSoc.value()) { + // // switch generator on + // startGenerator(); + // generatorOn = true; + // } else if (generatorOn && (!ess.value().soc.valueOptional().isPresent() + // || ess.value().soc.value() >= maxSoc.value())) { + // // switch generator off + // stopGenerator(); + // generatorOn = false; + // } else if (generatorOn) { + // startGenerator(); + // } else if (!generatorOn) { + // stopGenerator(); + // } + // switchedToOnGrid = false; + // } else { + // // Grid voltage is in the allowed range + // if (switchedToOnGrid) { + // if (timeOnGrid + switchDelay.value() <= System.currentTimeMillis()) { + // if (onGridOutputOn.value()) { + // startGenerator(); + // } else { + // stopGenerator(); + // } + // } + // } else { + // stopGenerator(); + // timeOnGrid = System.currentTimeMillis(); + // switchedToOnGrid = true; + // } + // } + } catch (InvalidValueException e) { + log.error("Failed to read value!", e); + } catch (WriteChannelException e) { + log.error("Error due write to output [" + outputChannelAddress.valueOptional().orElse("") + "]", + e); + } + } + + } + + private void startGenerator() throws WriteChannelException, InvalidValueException { + if (outputChannel.value() != true ^ invertOutput.value()) { + outputChannel.pushWrite(true ^ invertOutput.value()); + } + } + + private void stopGenerator() throws InvalidValueException, WriteChannelException { + if (outputChannel.value() != false ^ invertOutput.value()) { + outputChannel.pushWrite(false ^ invertOutput.value()); + } + } + + private boolean isOff() throws InvalidValueException { + return outputChannel.value() == false ^ invertOutput.value(); + } + + private boolean isOn() throws InvalidValueException { + return outputChannel.value() == true ^ invertOutput.value(); + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + +} diff --git a/edge/src/io/openems/impl/controller/symmetric/powerbyfrequency/PowerByFrequencyController.java b/edge/src/io/openems/impl/controller/symmetric/powerbyfrequency/PowerByFrequencyController.java index c9d4959bea1..c222a3fe01b 100644 --- a/edge/src/io/openems/impl/controller/symmetric/powerbyfrequency/PowerByFrequencyController.java +++ b/edge/src/io/openems/impl/controller/symmetric/powerbyfrequency/PowerByFrequencyController.java @@ -1,91 +1,98 @@ -/******************************************************************************* - * 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.symmetric.powerbyfrequency; - -import io.openems.api.channel.ConfigChannel; -import io.openems.api.controller.Controller; -import io.openems.api.doc.ChannelInfo; -import io.openems.api.doc.ThingInfo; -import io.openems.api.exception.InvalidValueException; - -@ThingInfo(title = "Power by frequency (Symmetric)", description = "Tries to keep the grid meter at a given frequency. For symmetric Ess.") -public class PowerByFrequencyController extends Controller { - - /* - * Constructors - */ - public PowerByFrequencyController() { - super(); - } - - public PowerByFrequencyController(String thingId) { - super(thingId); - } - - /* - * Config - */ - @ChannelInfo(title = "Ess", description = "Sets the Ess device.", type = Ess.class) - public final ConfigChannel ess = new ConfigChannel<>("ess", this); - - @ChannelInfo(title = "Meter", description = "The meter for the frequency meassurement.", type = Meter.class) - public final ConfigChannel meter = new ConfigChannel<>("meter", this); - - @ChannelInfo(title = "Low SOC-Limit", description = "The low soc limit. Below this limit the Ess will charge with more power by the same frequency.", type = Integer.class, defaultValue = "30") - public final ConfigChannel lowSocLimit = new ConfigChannel("lowSocLimit", this); - - @ChannelInfo(title = "High SOC-Limit", description = "The upper soc limit. Above this limit the Ess will discharge with more power by the same frequency.", type = Integer.class, defaultValue = "70") - public final ConfigChannel highSocLimit = new ConfigChannel("highSocLimit", this); - - /* - * Methods - */ - @Override - public void run() { - try { - Ess ess = this.ess.value(); - Meter meter = this.meter.value(); - // Calculate required sum values - long activePower = 0L; - if (meter.frequency.value() >= 49990 && meter.frequency.value() <= 50010) { - // charge if SOC isn't in the expected range - if ((ess.soc.value() > highSocLimit.value() && meter.frequency.value() < 50000) - || (ess.soc.value() < lowSocLimit.value() && meter.frequency.value() > 50000)) { - activePower = (long) (ess.maxNominalPower.value() * (300.0 - 0.006 * meter.frequency.value())); - } - } else { - // calculate minimal Power for Frequency - activePower = (long) ((double) ess.maxNominalPower.value() * (250.0 - meter.frequency.value() / 200.0)); - if ((meter.frequency.value() < 50000 && ess.soc.value() > highSocLimit.value()) - || (meter.frequency.value() > 50000 && ess.soc.value() < lowSocLimit.value())) { - // calculate maximal Power for frequency - activePower = (long) (ess.maxNominalPower.value() * (300 - 0.006 * meter.frequency.value())); - } - } - ess.power.setActivePower(activePower); - ess.power.writePower(); - log.info(ess.id() + " Set ActivePower [" + ess.power.getActivePower() + "]"); - } catch (InvalidValueException e) { - log.error(e.getMessage()); - } - } - -} +/******************************************************************************* + * 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.symmetric.powerbyfrequency; + +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.controller.Controller; +import io.openems.api.doc.ChannelInfo; +import io.openems.api.doc.ThingInfo; +import io.openems.api.exception.InvalidValueException; + +@ThingInfo(title = "Power by frequency (Symmetric)", description = "Tries to keep the grid meter at a given frequency. For symmetric Ess.") +public class PowerByFrequencyController extends Controller { + + private ThingStateChannel thingState = new ThingStateChannel(this); + /* + * Constructors + */ + public PowerByFrequencyController() { + super(); + } + + public PowerByFrequencyController(String thingId) { + super(thingId); + } + + /* + * Config + */ + @ChannelInfo(title = "Ess", description = "Sets the Ess device.", type = Ess.class) + public final ConfigChannel ess = new ConfigChannel<>("ess", this); + + @ChannelInfo(title = "Meter", description = "The meter for the frequency meassurement.", type = Meter.class) + public final ConfigChannel meter = new ConfigChannel<>("meter", this); + + @ChannelInfo(title = "Low SOC-Limit", description = "The low soc limit. Below this limit the Ess will charge with more power by the same frequency.", type = Integer.class, defaultValue = "30") + public final ConfigChannel lowSocLimit = new ConfigChannel("lowSocLimit", this); + + @ChannelInfo(title = "High SOC-Limit", description = "The upper soc limit. Above this limit the Ess will discharge with more power by the same frequency.", type = Integer.class, defaultValue = "70") + public final ConfigChannel highSocLimit = new ConfigChannel("highSocLimit", this); + + /* + * Methods + */ + @Override + public void run() { + try { + Ess ess = this.ess.value(); + Meter meter = this.meter.value(); + // Calculate required sum values + long activePower = 0L; + if (meter.frequency.value() >= 49990 && meter.frequency.value() <= 50010) { + // charge if SOC isn't in the expected range + if ((ess.soc.value() > highSocLimit.value() && meter.frequency.value() < 50000) + || (ess.soc.value() < lowSocLimit.value() && meter.frequency.value() > 50000)) { + activePower = (long) (ess.maxNominalPower.value() * (300.0 - 0.006 * meter.frequency.value())); + } + } else { + // calculate minimal Power for Frequency + activePower = (long) ((double) ess.maxNominalPower.value() * (250.0 - meter.frequency.value() / 200.0)); + if ((meter.frequency.value() < 50000 && ess.soc.value() > highSocLimit.value()) + || (meter.frequency.value() > 50000 && ess.soc.value() < lowSocLimit.value())) { + // calculate maximal Power for frequency + activePower = (long) (ess.maxNominalPower.value() * (300 - 0.006 * meter.frequency.value())); + } + } + ess.power.setActivePower(activePower); + ess.power.writePower(); + log.info(ess.id() + " Set ActivePower [" + ess.power.getActivePower() + "]"); + } catch (InvalidValueException e) { + log.error(e.getMessage()); + } + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + +} diff --git a/edge/src/io/openems/impl/controller/symmetric/powerlimitation/PowerLimitationController.java b/edge/src/io/openems/impl/controller/symmetric/powerlimitation/PowerLimitationController.java index df36f48ed98..4a65279ec32 100644 --- a/edge/src/io/openems/impl/controller/symmetric/powerlimitation/PowerLimitationController.java +++ b/edge/src/io/openems/impl/controller/symmetric/powerlimitation/PowerLimitationController.java @@ -1,101 +1,108 @@ -/******************************************************************************* - * 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.symmetric.powerlimitation; - -import io.openems.api.channel.ConfigChannel; -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; - -@ThingInfo(title = "Power limitation (Symmetric)", description = "Limits the active and reactive power of the Ess. For symmetric Ess.") -public class PowerLimitationController extends Controller { - - /* - * Constructors - */ - public PowerLimitationController() { - super(); - } - - public PowerLimitationController(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 = "Min-Charge ActivePower", description = "The minimum allowed active power for discharge. Value is negative.", type = Long.class) - public ConfigChannel pMin = new ConfigChannel("pMin", this); - - @ChannelInfo(title = "Max-Charge ActivePower", description = "The maximum allowed active power for discharge. Value is positive.", type = Long.class) - public ConfigChannel pMax = new ConfigChannel("pMax", this); - - @ChannelInfo(title = "Min-Charge ReactivePower", description = "The minimum allowed reactive power for discharge. Value is negative.", type = Long.class) - public ConfigChannel qMin = new ConfigChannel("qMin", this); - - @ChannelInfo(title = "Max-Charge ReactivePower", description = "The maximum allowed reactive power for discharge. Value is positive.", type = Long.class) - public ConfigChannel qMax = new ConfigChannel("qMax", this); - - /* - * Methods - */ - @Override - public void run() { - try { - try { - if (pMax.value() < ess.value().setActivePower.writeMax().orElse(Long.MAX_VALUE)) { - ess.value().setActivePower.pushWriteMax(pMax.value()); - } - } catch (WriteChannelException | InvalidValueException e) { - log.error("Failed to write Max P value for [" + ess.value().id + "]: " + e.getMessage()); - } - try { - if (pMin.value() > ess.value().setActivePower.writeMin().orElse(Long.MIN_VALUE)) { - ess.value().setActivePower.pushWriteMin(pMin.value()); - } - } catch (WriteChannelException | InvalidValueException e) { - log.error("Failed to write Min P value for [" + ess.value().id + "]: " + e.getMessage()); - } - try { - if (qMin.value() > ess.value().setReactivePower.writeMin().orElse(Long.MIN_VALUE)) { - ess.value().setReactivePower.pushWriteMin(qMin.value()); - } - } catch (WriteChannelException | InvalidValueException e) { - log.error("Failed to write Min Q value for [" + ess.value().id + "]: " + e.getMessage()); - } - try { - if (qMax.value() < ess.value().setReactivePower.writeMax().orElse(Long.MAX_VALUE)) { - ess.value().setReactivePower.pushWriteMax(qMax.value()); - } - } catch (WriteChannelException | InvalidValueException e) { - log.error("Failed to write Max Q value for [" + ess.value().id + "]: " + e.getMessage()); - } - } catch (InvalidValueException e) { - log.error("No ess found.", e); - } - } - -} +/******************************************************************************* + * 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.symmetric.powerlimitation; + +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +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; + +@ThingInfo(title = "Power limitation (Symmetric)", description = "Limits the active and reactive power of the Ess. For symmetric Ess.") +public class PowerLimitationController extends Controller { + + private ThingStateChannel thingState = new ThingStateChannel(this); + /* + * Constructors + */ + public PowerLimitationController() { + super(); + } + + public PowerLimitationController(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 = "Min-Charge ActivePower", description = "The minimum allowed active power for discharge. Value is negative.", type = Long.class) + public ConfigChannel pMin = new ConfigChannel("pMin", this); + + @ChannelInfo(title = "Max-Charge ActivePower", description = "The maximum allowed active power for discharge. Value is positive.", type = Long.class) + public ConfigChannel pMax = new ConfigChannel("pMax", this); + + @ChannelInfo(title = "Min-Charge ReactivePower", description = "The minimum allowed reactive power for discharge. Value is negative.", type = Long.class) + public ConfigChannel qMin = new ConfigChannel("qMin", this); + + @ChannelInfo(title = "Max-Charge ReactivePower", description = "The maximum allowed reactive power for discharge. Value is positive.", type = Long.class) + public ConfigChannel qMax = new ConfigChannel("qMax", this); + + /* + * Methods + */ + @Override + public void run() { + try { + try { + if (pMax.value() < ess.value().setActivePower.writeMax().orElse(Long.MAX_VALUE)) { + ess.value().setActivePower.pushWriteMax(pMax.value()); + } + } catch (WriteChannelException | InvalidValueException e) { + log.error("Failed to write Max P value for [" + ess.value().id + "]: " + e.getMessage()); + } + try { + if (pMin.value() > ess.value().setActivePower.writeMin().orElse(Long.MIN_VALUE)) { + ess.value().setActivePower.pushWriteMin(pMin.value()); + } + } catch (WriteChannelException | InvalidValueException e) { + log.error("Failed to write Min P value for [" + ess.value().id + "]: " + e.getMessage()); + } + try { + if (qMin.value() > ess.value().setReactivePower.writeMin().orElse(Long.MIN_VALUE)) { + ess.value().setReactivePower.pushWriteMin(qMin.value()); + } + } catch (WriteChannelException | InvalidValueException e) { + log.error("Failed to write Min Q value for [" + ess.value().id + "]: " + e.getMessage()); + } + try { + if (qMax.value() < ess.value().setReactivePower.writeMax().orElse(Long.MAX_VALUE)) { + ess.value().setReactivePower.pushWriteMax(qMax.value()); + } + } catch (WriteChannelException | InvalidValueException e) { + log.error("Failed to write Max Q value for [" + ess.value().id + "]: " + e.getMessage()); + } + } catch (InvalidValueException e) { + log.error("No ess found.", e); + } + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + +} diff --git a/edge/src/io/openems/impl/controller/symmetric/powerramp/PowerRampController.java b/edge/src/io/openems/impl/controller/symmetric/powerramp/PowerRampController.java index 318cbccb27d..020689092a8 100644 --- a/edge/src/io/openems/impl/controller/symmetric/powerramp/PowerRampController.java +++ b/edge/src/io/openems/impl/controller/symmetric/powerramp/PowerRampController.java @@ -1,110 +1,117 @@ -/******************************************************************************* - * 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.symmetric.powerramp; - -import java.util.List; - -import io.openems.api.channel.ConfigChannel; -import io.openems.api.controller.Controller; -import io.openems.api.device.nature.ess.EssNature; -import io.openems.api.doc.ChannelInfo; -import io.openems.api.doc.ThingInfo; -import io.openems.api.exception.InvalidValueException; -import io.openems.core.utilities.ControllerUtils; -import io.openems.core.utilities.SymmetricPower; - -@ThingInfo(title = "Power ramp (Symmetric)", description = "Follows a power ramp. For symmetric Ess.") -public class PowerRampController extends Controller { - - /* - * Constructors - */ - public PowerRampController() { - super(); - } - - public PowerRampController(String thingId) { - super(thingId); - } - - /* - * Config - */ - @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class, isArray = true) - public ConfigChannel> esss = new ConfigChannel>("esss", this); - - @ChannelInfo(title = "Max-ActivePower", description = "The limit where the powerRamp stops. (pos/neg)", type = Integer.class) - public ConfigChannel pMax = new ConfigChannel("pMax", this); - - @ChannelInfo(title = "Cos-Phi", description = "The cos-phi to hold.", type = Double.class) - public ConfigChannel cosPhi = new ConfigChannel("cosPhi", this); - - @ChannelInfo(title = "Step", description = "Step to increase power.", type = Integer.class) - public ConfigChannel pStep = new ConfigChannel("pStep", this); - - @ChannelInfo(title = "Step-Wait", description = "Wait till next step in milliseconds.", type = Integer.class) - public ConfigChannel sleep = new ConfigChannel<>("sleep", this); - - /* - * Fields - */ - private long lastPower; - private long lastSet; - - /* - * Methods - */ - @Override - public void run() { - try { - for (Ess ess : esss.value()) { - try { - if (ess.gridMode.labelOptional().isPresent() - && ess.gridMode.labelOptional().get().equals(EssNature.OFF_GRID)) { - lastPower = 0; - } - SymmetricPower power = ess.power; - if (lastSet + sleep.value() < System.currentTimeMillis()) { - if (Math.abs(lastPower + pStep.value()) <= Math.abs(pMax.value())) { - power.setActivePower(lastPower + pStep.value()); - } else { - power.setActivePower(pMax.value()); - } - lastSet = System.currentTimeMillis(); - } else { - power.setActivePower(lastPower); - } - power.setReactivePower( - ControllerUtils.calculateReactivePower(power.getActivePower(), cosPhi.value())); - power.writePower(); - lastPower = power.getActivePower(); - log.info("Set ActivePower [" + power.getActivePower() + "] Set ReactivePower [" - + power.getReactivePower() + "]"); - } catch (InvalidValueException e) { - log.error("Failed to write fixed P/Q value for Ess " + ess.id, e); - } - } - } catch (InvalidValueException e) { - log.error("No ess found.", e); - } - } - -} +/******************************************************************************* + * 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.symmetric.powerramp; + +import java.util.List; + +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.controller.Controller; +import io.openems.api.device.nature.ess.EssNature; +import io.openems.api.doc.ChannelInfo; +import io.openems.api.doc.ThingInfo; +import io.openems.api.exception.InvalidValueException; +import io.openems.core.utilities.ControllerUtils; +import io.openems.core.utilities.SymmetricPower; + +@ThingInfo(title = "Power ramp (Symmetric)", description = "Follows a power ramp. For symmetric Ess.") +public class PowerRampController extends Controller { + + private ThingStateChannel thingState = new ThingStateChannel(this); + /* + * Constructors + */ + public PowerRampController() { + super(); + } + + public PowerRampController(String thingId) { + super(thingId); + } + + /* + * Config + */ + @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class, isArray = true) + public ConfigChannel> esss = new ConfigChannel>("esss", this); + + @ChannelInfo(title = "Max-ActivePower", description = "The limit where the powerRamp stops. (pos/neg)", type = Integer.class) + public ConfigChannel pMax = new ConfigChannel("pMax", this); + + @ChannelInfo(title = "Cos-Phi", description = "The cos-phi to hold.", type = Double.class) + public ConfigChannel cosPhi = new ConfigChannel("cosPhi", this); + + @ChannelInfo(title = "Step", description = "Step to increase power.", type = Integer.class) + public ConfigChannel pStep = new ConfigChannel("pStep", this); + + @ChannelInfo(title = "Step-Wait", description = "Wait till next step in milliseconds.", type = Integer.class) + public ConfigChannel sleep = new ConfigChannel<>("sleep", this); + + /* + * Fields + */ + private long lastPower; + private long lastSet; + + /* + * Methods + */ + @Override + public void run() { + try { + for (Ess ess : esss.value()) { + try { + if (ess.gridMode.labelOptional().isPresent() + && ess.gridMode.labelOptional().get().equals(EssNature.OFF_GRID)) { + lastPower = 0; + } + SymmetricPower power = ess.power; + if (lastSet + sleep.value() < System.currentTimeMillis()) { + if (Math.abs(lastPower + pStep.value()) <= Math.abs(pMax.value())) { + power.setActivePower(lastPower + pStep.value()); + } else { + power.setActivePower(pMax.value()); + } + lastSet = System.currentTimeMillis(); + } else { + power.setActivePower(lastPower); + } + power.setReactivePower( + ControllerUtils.calculateReactivePower(power.getActivePower(), cosPhi.value())); + power.writePower(); + lastPower = power.getActivePower(); + log.info("Set ActivePower [" + power.getActivePower() + "] Set ReactivePower [" + + power.getReactivePower() + "]"); + } catch (InvalidValueException e) { + log.error("Failed to write fixed P/Q value for Ess " + ess.id, e); + } + } + } catch (InvalidValueException e) { + log.error("No ess found.", e); + } + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + +} diff --git a/edge/src/io/openems/impl/controller/symmetric/refuavoidtotaldischarge/AvoidTotalDischargeController.java b/edge/src/io/openems/impl/controller/symmetric/refuavoidtotaldischarge/AvoidTotalDischargeController.java index a5d5f357979..d99ab883f5c 100644 --- a/edge/src/io/openems/impl/controller/symmetric/refuavoidtotaldischarge/AvoidTotalDischargeController.java +++ b/edge/src/io/openems/impl/controller/symmetric/refuavoidtotaldischarge/AvoidTotalDischargeController.java @@ -1,219 +1,226 @@ -/******************************************************************************* - * 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.symmetric.refuavoidtotaldischarge; - -import java.util.Optional; - -import io.openems.api.channel.Channel; -import io.openems.api.channel.ChannelChangeListener; -import io.openems.api.channel.ConfigChannel; -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.utilities.hysteresis.Hysteresis; - -@ThingInfo(title = "REFU: Avoid Total Discharge") -public class AvoidTotalDischargeController extends Controller { - - @ChannelInfo(title = "Storage, where total discharge should be avoided. For excample to reserve load for the Off-Grid power supply.", type = Ess.class) - public final ConfigChannel ess = new ConfigChannel("ess", this); - @ChannelInfo(title = "Delay, to allow Power after start", type = Long.class) - public final ConfigChannel powerDelay = new ConfigChannel<>("powerDelay", this); - @ChannelInfo(title = "Step to increase the allowed power after start delay.", type = Long.class) - public final ConfigChannel powerStep = new ConfigChannel<>("powerStep", this); - @ChannelInfo(title = "Soc limit to stop chargePower.", type = Long.class) - public final ConfigChannel maxSoc = new ConfigChannel("maxSoc", this) - .addChangeListener(new ChannelChangeListener() { - - @Override - public void channelChanged(Channel channel, Optional newValue, Optional oldValue) { - if (maxSoc.valueOptional().isPresent() && socHysteresis.valueOptional().isPresent()) { - try { - socMaxHysteresis = new Hysteresis(maxSoc.value() - socHysteresis.value(), maxSoc.value()); - } catch (InvalidValueException e) {} - } - } - }); - @ChannelInfo(title = "Soc hysteresis for max Soc limit.", type = Long.class) - public final ConfigChannel socHysteresis = new ConfigChannel("socHysteresis", this) - .addChangeListener(new ChannelChangeListener() { - - @Override - public void channelChanged(Channel channel, Optional newValue, Optional oldValue) { - if (maxSoc.valueOptional().isPresent() && socHysteresis.valueOptional().isPresent()) { - try { - socMaxHysteresis = new Hysteresis(maxSoc.value() - socHysteresis.value(), maxSoc.value()); - } catch (InvalidValueException e) {} - } - } - }); - private boolean isStart = false; - private long timeStartOccured = System.currentTimeMillis(); - private long lastPower = 0L; - private Hysteresis socMaxHysteresis; - - public AvoidTotalDischargeController() { - super(); - } - - public AvoidTotalDischargeController(String thingId) { - super(thingId); - } - - @Override - public void run() { - try { - Ess ess = this.ess.value(); - - if (ess.systemState.value() == 4) { - if (!isStart) { - timeStartOccured = System.currentTimeMillis(); - isStart = true; - } - } else { - isStart = false; - lastPower = 0L; - } - if (isStart && timeStartOccured + powerDelay.value() <= System.currentTimeMillis()) { - lastPower += powerStep.value(); - if (lastPower > ess.nominalPower.value()) { - lastPower = ess.nominalPower.value(); - } - } - try { - ess.setActivePower.pushWriteMin(lastPower * -1); - } catch (WriteChannelException e) { - // catch out of bounds - } - try { - ess.setActivePower.pushWriteMax(lastPower); - } catch (WriteChannelException e) { - // catch out of bounds - } - try { - ess.setReactivePower.pushWriteMin(lastPower * -1); - } catch (WriteChannelException e) { - // catch out of bounds - } - try { - ess.setReactivePower.pushWriteMax(lastPower); - } catch (WriteChannelException e) { - // catch out of bounds - } - - /* - * Calculate SetActivePower according to MinSoc - */ - - ess.socMinHysteresis.apply(ess.soc.value(), (state, multiplier) -> { - switch (state) { - case ASC: - case DESC: - if (!ess.isChargeSoc) { - try { - long maxPower = 0; - if (!ess.setActivePower.writeMax().isPresent() - || maxPower < ess.setActivePower.writeMax().get()) { - ess.setActivePower.pushWriteMax(maxPower); - } - } catch (WriteChannelException e) { - log.error(ess.id() + "Failed to set Max allowed power.", e); - } - } - break; - case BELOW: - if (!ess.isChargeSoc) { - try { - if (ess.soc.value() < ess.chargeSoc.value()) { - ess.isChargeSoc = true; - } - } catch (Exception e) { - log.error(e.getMessage()); - } - } - break; - case ABOVE: - ess.isChargeSoc = false; - default: - break; - } - if (ess.isChargeSoc) { - try { - Optional currentMinValue = ess.setActivePower.writeMin(); - if (currentMinValue.isPresent() && currentMinValue.get() < 0) { - // Force Charge with minimum of MaxChargePower/5 - log.info("Force charge. Set ActivePower=Max[" + currentMinValue.get() / 5 + "]"); - ess.setActivePower.pushWriteMax(currentMinValue.get() / 5); - } else { - log.info("Avoid discharge. Set ActivePower=Max[-1000 W]"); - ess.setActivePower.pushWriteMax(-1000L); - } - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - }); - - if (socMaxHysteresis != null) { - socMaxHysteresis.apply(ess.soc.value(), (state, multiplier) -> { - switch (state) { - case ABOVE: - try { - ess.setActivePower.pushWriteMin(0L); - } catch (WriteChannelException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - break; - case ASC: - try { - ess.setActivePower.pushWriteMin((long) (ess.allowedCharge.value() * multiplier)); - } catch (WriteChannelException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (InvalidValueException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - break; - case BELOW: - break; - case DESC: - try { - ess.setActivePower.pushWriteMin(0L); - } catch (WriteChannelException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - break; - default: - break; - } - }); - } - } catch (InvalidValueException e) { - log.error(e.getMessage()); - } - } -} +/******************************************************************************* + * 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.symmetric.refuavoidtotaldischarge; + +import java.util.Optional; + +import io.openems.api.channel.Channel; +import io.openems.api.channel.ChannelChangeListener; +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +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.utilities.hysteresis.Hysteresis; + +@ThingInfo(title = "REFU: Avoid Total Discharge") +public class AvoidTotalDischargeController extends Controller { + + private ThingStateChannel thingState = new ThingStateChannel(this); + @ChannelInfo(title = "Storage, where total discharge should be avoided. For excample to reserve load for the Off-Grid power supply.", type = Ess.class) + public final ConfigChannel ess = new ConfigChannel("ess", this); + @ChannelInfo(title = "Delay, to allow Power after start", type = Long.class) + public final ConfigChannel powerDelay = new ConfigChannel<>("powerDelay", this); + @ChannelInfo(title = "Step to increase the allowed power after start delay.", type = Long.class) + public final ConfigChannel powerStep = new ConfigChannel<>("powerStep", this); + @ChannelInfo(title = "Soc limit to stop chargePower.", type = Long.class) + public final ConfigChannel maxSoc = new ConfigChannel("maxSoc", this) + .addChangeListener(new ChannelChangeListener() { + + @Override + public void channelChanged(Channel channel, Optional newValue, Optional oldValue) { + if (maxSoc.valueOptional().isPresent() && socHysteresis.valueOptional().isPresent()) { + try { + socMaxHysteresis = new Hysteresis(maxSoc.value() - socHysteresis.value(), maxSoc.value()); + } catch (InvalidValueException e) {} + } + } + }); + @ChannelInfo(title = "Soc hysteresis for max Soc limit.", type = Long.class) + public final ConfigChannel socHysteresis = new ConfigChannel("socHysteresis", this) + .addChangeListener(new ChannelChangeListener() { + + @Override + public void channelChanged(Channel channel, Optional newValue, Optional oldValue) { + if (maxSoc.valueOptional().isPresent() && socHysteresis.valueOptional().isPresent()) { + try { + socMaxHysteresis = new Hysteresis(maxSoc.value() - socHysteresis.value(), maxSoc.value()); + } catch (InvalidValueException e) {} + } + } + }); + private boolean isStart = false; + private long timeStartOccured = System.currentTimeMillis(); + private long lastPower = 0L; + private Hysteresis socMaxHysteresis; + + public AvoidTotalDischargeController() { + super(); + } + + public AvoidTotalDischargeController(String thingId) { + super(thingId); + } + + @Override + public void run() { + try { + Ess ess = this.ess.value(); + + if (ess.systemState.value() == 4) { + if (!isStart) { + timeStartOccured = System.currentTimeMillis(); + isStart = true; + } + } else { + isStart = false; + lastPower = 0L; + } + if (isStart && timeStartOccured + powerDelay.value() <= System.currentTimeMillis()) { + lastPower += powerStep.value(); + if (lastPower > ess.nominalPower.value()) { + lastPower = ess.nominalPower.value(); + } + } + try { + ess.setActivePower.pushWriteMin(lastPower * -1); + } catch (WriteChannelException e) { + // catch out of bounds + } + try { + ess.setActivePower.pushWriteMax(lastPower); + } catch (WriteChannelException e) { + // catch out of bounds + } + try { + ess.setReactivePower.pushWriteMin(lastPower * -1); + } catch (WriteChannelException e) { + // catch out of bounds + } + try { + ess.setReactivePower.pushWriteMax(lastPower); + } catch (WriteChannelException e) { + // catch out of bounds + } + + /* + * Calculate SetActivePower according to MinSoc + */ + + ess.socMinHysteresis.apply(ess.soc.value(), (state, multiplier) -> { + switch (state) { + case ASC: + case DESC: + if (!ess.isChargeSoc) { + try { + long maxPower = 0; + if (!ess.setActivePower.writeMax().isPresent() + || maxPower < ess.setActivePower.writeMax().get()) { + ess.setActivePower.pushWriteMax(maxPower); + } + } catch (WriteChannelException e) { + log.error(ess.id() + "Failed to set Max allowed power.", e); + } + } + break; + case BELOW: + if (!ess.isChargeSoc) { + try { + if (ess.soc.value() < ess.chargeSoc.value()) { + ess.isChargeSoc = true; + } + } catch (Exception e) { + log.error(e.getMessage()); + } + } + break; + case ABOVE: + ess.isChargeSoc = false; + default: + break; + } + if (ess.isChargeSoc) { + try { + Optional currentMinValue = ess.setActivePower.writeMin(); + if (currentMinValue.isPresent() && currentMinValue.get() < 0) { + // Force Charge with minimum of MaxChargePower/5 + log.info("Force charge. Set ActivePower=Max[" + currentMinValue.get() / 5 + "]"); + ess.setActivePower.pushWriteMax(currentMinValue.get() / 5); + } else { + log.info("Avoid discharge. Set ActivePower=Max[-1000 W]"); + ess.setActivePower.pushWriteMax(-1000L); + } + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + }); + + if (socMaxHysteresis != null) { + socMaxHysteresis.apply(ess.soc.value(), (state, multiplier) -> { + switch (state) { + case ABOVE: + try { + ess.setActivePower.pushWriteMin(0L); + } catch (WriteChannelException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + break; + case ASC: + try { + ess.setActivePower.pushWriteMin((long) (ess.allowedCharge.value() * multiplier)); + } catch (WriteChannelException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InvalidValueException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + break; + case BELOW: + break; + case DESC: + try { + ess.setActivePower.pushWriteMin(0L); + } catch (WriteChannelException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + break; + default: + break; + } + }); + } + } catch (InvalidValueException e) { + log.error(e.getMessage()); + } + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } +} diff --git a/edge/src/io/openems/impl/controller/symmetric/refuworkstate/WorkStateController.java b/edge/src/io/openems/impl/controller/symmetric/refuworkstate/WorkStateController.java index 2a712b2b7af..137f14203a4 100644 --- a/edge/src/io/openems/impl/controller/symmetric/refuworkstate/WorkStateController.java +++ b/edge/src/io/openems/impl/controller/symmetric/refuworkstate/WorkStateController.java @@ -24,6 +24,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.DebugChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -37,6 +38,7 @@ @ThingInfo(title = "REFU Workstate (Symmetric)", description = "Sends the Ess to Standby if no power is required. Do not use if Off-Grid functionality is required. For symmetric Ess.") public class WorkStateController extends Controller { + private ThingStateChannel thingState = new ThingStateChannel(this); /* * Constructors */ @@ -213,4 +215,9 @@ public void run() { } } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/controller/symmetric/timelinecharge/TimelineChargeController.java b/edge/src/io/openems/impl/controller/symmetric/timelinecharge/TimelineChargeController.java index 034b2523a99..d432c8746bb 100644 --- a/edge/src/io/openems/impl/controller/symmetric/timelinecharge/TimelineChargeController.java +++ b/edge/src/io/openems/impl/controller/symmetric/timelinecharge/TimelineChargeController.java @@ -35,6 +35,7 @@ import com.google.gson.JsonObject; import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -51,6 +52,7 @@ @ThingInfo(title = "Timeline charge (Symmetric)") public class TimelineChargeController extends Controller { + private ThingStateChannel thingState = new ThingStateChannel(this); /* * Constructors */ @@ -419,4 +421,9 @@ public int getSoc() { } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/impl/controller/symmetric/voltagecharacteristic/VoltageCharacteristicController.java b/edge/src/io/openems/impl/controller/symmetric/voltagecharacteristic/VoltageCharacteristicController.java index 42df2c157dd..9c7f735083a 100644 --- a/edge/src/io/openems/impl/controller/symmetric/voltagecharacteristic/VoltageCharacteristicController.java +++ b/edge/src/io/openems/impl/controller/symmetric/voltagecharacteristic/VoltageCharacteristicController.java @@ -1,143 +1,150 @@ -/******************************************************************************* - * 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.symmetric.voltagecharacteristic; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -import io.openems.api.channel.Channel; -import io.openems.api.channel.ChannelChangeListener; -import io.openems.api.channel.ConfigChannel; -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.core.utilities.ControllerUtils; -import io.openems.core.utilities.Point; -import io.openems.core.utilities.SymmetricPower; - -@ThingInfo(title = "Voltage characteristics (Symmetric)") -public class VoltageCharacteristicController extends Controller { - - /* - * Constructors - */ - public VoltageCharacteristicController() { - super(); - initialize(); - } - - public VoltageCharacteristicController(String thingId) { - super(thingId); - initialize(); - } - - /* - * Config - */ - @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class) - public final ConfigChannel ess = new ConfigChannel("ess", this); - - @ChannelInfo(title = "Meter", description = "The meter to measure the Voltage.", type = Meter.class) - public final ConfigChannel meter = new ConfigChannel("meter", this); - - @ChannelInfo(title = "Nominal voltage", description = "The nominal voltage of the grid.", type = Integer.class) - public final ConfigChannel uNenn = new ConfigChannel<>("UNenn", this); - - @ChannelInfo(title = "ActivePower characteristics", description = "Characteristic points for active power.", type = Long[].class, isArray = true) - public final ConfigChannel> pByUCharacteristicPoints = new ConfigChannel<>("pByUCharacteristicPoints", - this); - - @ChannelInfo(title = "ReactivePower characteristics", description = "Characteristic points for reactive power.", type = Long[].class, isArray = true) - public final ConfigChannel> qByUCharacteristicPoints = new ConfigChannel<>("qByUCharacteristicPoints", - this); - - @ChannelInfo(title = "Enable ActivePower", description = "Indicates if active power characteristic is enabled.", type = Boolean.class, defaultValue = "true") - public final ConfigChannel activePowerActivated = new ConfigChannel<>("activePowerActivated", this); - - @ChannelInfo(title = "Enable ReactivePower", description = "Indicates if reactive power characteristic is enabled.", type = Boolean.class, defaultValue = "true") - public final ConfigChannel reactivePowerActivated = new ConfigChannel<>("reactivePowerActivated", this); - - /* - * Fields - */ - private List pCharacteristic; - private List qCharacteristic; - - /* - * Methods - */ - private void initialize() { - pByUCharacteristicPoints.addChangeListener(new ChannelChangeListener() { - - @Override - public void channelChanged(Channel channel, Optional newValue, Optional oldValue) { - try { - List points = new ArrayList<>(); - for (Long[] arr : pByUCharacteristicPoints.value()) { - points.add(new Point(arr[0], arr[1])); - } - pCharacteristic = points; - } catch (InvalidValueException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - }); - qByUCharacteristicPoints.addChangeListener(new ChannelChangeListener() { - - @Override - public void channelChanged(Channel channel, Optional newValue, Optional oldValue) { - try { - List points = new ArrayList<>(); - for (Long[] arr : qByUCharacteristicPoints.value()) { - points.add(new Point(arr[0], arr[1])); - } - qCharacteristic = points; - } catch (InvalidValueException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - }); - } - - @Override - public void run() { - try { - SymmetricPower power = ess.value().power; - double uRatio = (double) meter.value().voltage.value() / (double) uNenn.value() * 100.0; - long nominalActivePower = ess.value().maxNominalPower.value(); - long nominalReactivePower = ess.value().maxNominalPower.value(); - power.setActivePower( - (long) (nominalActivePower / 100.0 * ControllerUtils.getValueOfLine(pCharacteristic, uRatio))); - power.setReactivePower( - (long) (nominalReactivePower / 100.0 * ControllerUtils.getValueOfLine(qCharacteristic, uRatio))); - power.writePower(); - log.info(ess.id() + " Set ActivePower [" + power.getActivePower() + "], ReactivePower [" - + power.getReactivePower() + "]"); - } catch (InvalidValueException e) { - log.error("Failed to read Value.", e); - } - } - -} +/******************************************************************************* + * 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.symmetric.voltagecharacteristic; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import io.openems.api.channel.Channel; +import io.openems.api.channel.ChannelChangeListener; +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +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.core.utilities.ControllerUtils; +import io.openems.core.utilities.Point; +import io.openems.core.utilities.SymmetricPower; + +@ThingInfo(title = "Voltage characteristics (Symmetric)") +public class VoltageCharacteristicController extends Controller { + + private ThingStateChannel thingState = new ThingStateChannel(this); + /* + * Constructors + */ + public VoltageCharacteristicController() { + super(); + initialize(); + } + + public VoltageCharacteristicController(String thingId) { + super(thingId); + initialize(); + } + + /* + * Config + */ + @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class) + public final ConfigChannel ess = new ConfigChannel("ess", this); + + @ChannelInfo(title = "Meter", description = "The meter to measure the Voltage.", type = Meter.class) + public final ConfigChannel meter = new ConfigChannel("meter", this); + + @ChannelInfo(title = "Nominal voltage", description = "The nominal voltage of the grid.", type = Integer.class) + public final ConfigChannel uNenn = new ConfigChannel<>("UNenn", this); + + @ChannelInfo(title = "ActivePower characteristics", description = "Characteristic points for active power.", type = Long[].class, isArray = true) + public final ConfigChannel> pByUCharacteristicPoints = new ConfigChannel<>("pByUCharacteristicPoints", + this); + + @ChannelInfo(title = "ReactivePower characteristics", description = "Characteristic points for reactive power.", type = Long[].class, isArray = true) + public final ConfigChannel> qByUCharacteristicPoints = new ConfigChannel<>("qByUCharacteristicPoints", + this); + + @ChannelInfo(title = "Enable ActivePower", description = "Indicates if active power characteristic is enabled.", type = Boolean.class, defaultValue = "true") + public final ConfigChannel activePowerActivated = new ConfigChannel<>("activePowerActivated", this); + + @ChannelInfo(title = "Enable ReactivePower", description = "Indicates if reactive power characteristic is enabled.", type = Boolean.class, defaultValue = "true") + public final ConfigChannel reactivePowerActivated = new ConfigChannel<>("reactivePowerActivated", this); + + /* + * Fields + */ + private List pCharacteristic; + private List qCharacteristic; + + /* + * Methods + */ + private void initialize() { + pByUCharacteristicPoints.addChangeListener(new ChannelChangeListener() { + + @Override + public void channelChanged(Channel channel, Optional newValue, Optional oldValue) { + try { + List points = new ArrayList<>(); + for (Long[] arr : pByUCharacteristicPoints.value()) { + points.add(new Point(arr[0], arr[1])); + } + pCharacteristic = points; + } catch (InvalidValueException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + }); + qByUCharacteristicPoints.addChangeListener(new ChannelChangeListener() { + + @Override + public void channelChanged(Channel channel, Optional newValue, Optional oldValue) { + try { + List points = new ArrayList<>(); + for (Long[] arr : qByUCharacteristicPoints.value()) { + points.add(new Point(arr[0], arr[1])); + } + qCharacteristic = points; + } catch (InvalidValueException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + }); + } + + @Override + public void run() { + try { + SymmetricPower power = ess.value().power; + double uRatio = (double) meter.value().voltage.value() / (double) uNenn.value() * 100.0; + long nominalActivePower = ess.value().maxNominalPower.value(); + long nominalReactivePower = ess.value().maxNominalPower.value(); + power.setActivePower( + (long) (nominalActivePower / 100.0 * ControllerUtils.getValueOfLine(pCharacteristic, uRatio))); + power.setReactivePower( + (long) (nominalReactivePower / 100.0 * ControllerUtils.getValueOfLine(qCharacteristic, uRatio))); + power.writePower(); + log.info(ess.id() + " Set ActivePower [" + power.getActivePower() + "], ReactivePower [" + + power.getReactivePower() + "]"); + } catch (InvalidValueException e) { + log.error("Failed to read Value.", e); + } + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + +} diff --git a/edge/src/io/openems/impl/controller/testwrite/TestWriteController.java b/edge/src/io/openems/impl/controller/testwrite/TestWriteController.java index b6f01d62c71..b9536fa7383 100644 --- a/edge/src/io/openems/impl/controller/testwrite/TestWriteController.java +++ b/edge/src/io/openems/impl/controller/testwrite/TestWriteController.java @@ -1,67 +1,74 @@ -/******************************************************************************* - * 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.testwrite; - -import io.openems.api.channel.ConfigChannel; -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; - -@ThingInfo(title = "Test write") -public class TestWriteController extends Controller { - - /* - * Config - */ - @ChannelInfo(title = "Output", type = Output.class) - public ConfigChannel out = new ConfigChannel<>("out", this); - - @ChannelInfo(title = "Input", type = Input.class) - public ConfigChannel in = new ConfigChannel<>("in", this); - - /* - * Methods - */ - @Override - public void run() { - try { - out.value().output1.pushWrite(true); - log.info(in.value().input1.value().toString()); - } catch (WriteChannelException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (InvalidValueException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - // for (Ess ess : esss) { - // try { - // ess.setActivePower.pushWrite(500L); - // ess.setWorkState.pushWriteFromLabel(SymmetricEssNature.START); - // } catch (WriteChannelException e) { - // log.error("", e); - // } - // } - } - -} +/******************************************************************************* + * 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.testwrite; + +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +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; + +@ThingInfo(title = "Test write") +public class TestWriteController extends Controller { + + private ThingStateChannel thingState = new ThingStateChannel(this); + /* + * Config + */ + @ChannelInfo(title = "Output", type = Output.class) + public ConfigChannel out = new ConfigChannel<>("out", this); + + @ChannelInfo(title = "Input", type = Input.class) + public ConfigChannel in = new ConfigChannel<>("in", this); + + /* + * Methods + */ + @Override + public void run() { + try { + out.value().output1.pushWrite(true); + log.info(in.value().input1.value().toString()); + } catch (WriteChannelException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InvalidValueException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + // for (Ess ess : esss) { + // try { + // ess.setActivePower.pushWrite(500L); + // ess.setWorkState.pushWriteFromLabel(SymmetricEssNature.START); + // } catch (WriteChannelException e) { + // log.error("", e); + // } + // } + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + +} diff --git a/edge/src/io/openems/impl/controller/thermalpowerstation/ThermalPowerStationController.java b/edge/src/io/openems/impl/controller/thermalpowerstation/ThermalPowerStationController.java index ac706b85948..7d88f970fed 100644 --- a/edge/src/io/openems/impl/controller/thermalpowerstation/ThermalPowerStationController.java +++ b/edge/src/io/openems/impl/controller/thermalpowerstation/ThermalPowerStationController.java @@ -26,6 +26,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.WriteChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.controller.Controller; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; @@ -50,6 +51,7 @@ private enum State { private int switchOnCount = 0; private int switchOffCount = 0; private State currentState = State.UNDEFINED; + private ThingStateChannel thingState = new ThingStateChannel(this); /* * Constructors @@ -239,4 +241,9 @@ private long getProductionPower() throws InvalidValueException { return power; } + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } + } diff --git a/edge/src/io/openems/test/controller/ThermalPowerStationTest.java b/edge/src/io/openems/test/controller/ThermalPowerStationTest.java index b60f8ae097c..6cb1f342f13 100644 --- a/edge/src/io/openems/test/controller/ThermalPowerStationTest.java +++ b/edge/src/io/openems/test/controller/ThermalPowerStationTest.java @@ -1,133 +1,140 @@ -package io.openems.test.controller; - -import static org.junit.Assert.assertEquals; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; - -import io.openems.api.thing.Thing; -import io.openems.impl.controller.thermalpowerstation.Ess; -import io.openems.impl.controller.thermalpowerstation.Meter; -import io.openems.impl.controller.thermalpowerstation.ThermalPowerStationController; -import io.openems.test.utils.channel.UnitTestWriteChannel; -import io.openems.test.utils.devicenatures.UnitTestAsymmetricEssNature; -import io.openems.test.utils.devicenatures.UnitTestSymmetricMeterNature; - -public class ThermalPowerStationTest { - - private static ThermalPowerStationController controller; - private static UnitTestAsymmetricEssNature ess; - private static UnitTestWriteChannel outputChannel; - private static UnitTestSymmetricMeterNature meter; - private static Ess essThingMap; - private static Meter meterThingMap; - - @BeforeClass - public static void setUpBeforeClass() throws Exception { - ess = new UnitTestAsymmetricEssNature("ess0"); - meter = new UnitTestSymmetricMeterNature("meter0"); - controller = new ThermalPowerStationController(); - outputChannel = new UnitTestWriteChannel<>("0", new Thing() { - - @Override - public String id() { - return "output0"; - } - }); - essThingMap = new Ess(ess); - meterThingMap = new Meter(meter); - controller.ess.updateValue(essThingMap, true); - List meters = new ArrayList<>(); - meters.add(meterThingMap); - controller.meters.updateValue(meters, true); - controller.outputChannelOpt = Optional.of(outputChannel); - controller.productionLimit.updateValue(1000L, true); - controller.limitTimeRange.updateValue(1L, true); - controller.minSoc.updateValue(15L, true); - controller.maxSoc.updateValue(95L, true); - controller.invertOutput.updateValue(false, true); - } - - @Before - public void beforeTest() { - outputChannel.shadowCopyAndReset(); - } - - @Test - public void test1() { - ess.soc.setValue(15L); - meter.activePower.setValue(0L); - outputChannel.setValue(false); - controller.run(); - assertEquals(false, outputChannel.getWriteValue().isPresent()); - } - - @Test - public void test2() { - ess.soc.setValue(15L); - meter.activePower.setValue(0L); - outputChannel.setValue(true); - outputChannel.shadowCopyAndReset(); - // OFF - controller.run(); - assertEquals(false, outputChannel.getWriteValue().isPresent()); - outputChannel.shadowCopyAndReset(); - // SWITCH OFF - controller.run(); - assertEquals(true, outputChannel.getWriteValue().isPresent()); - boolean output = outputChannel.getWriteValue().get(); - assertEquals(false, output); - outputChannel.setValue(false); - outputChannel.shadowCopyAndReset(); - // SWITCH OFF - controller.run(); - assertEquals(false, outputChannel.getWriteValue().isPresent()); - outputChannel.shadowCopyAndReset(); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - // OFF - controller.run(); - assertEquals(false, outputChannel.getWriteValue().isPresent()); - outputChannel.shadowCopyAndReset(); - // SWITCH ON - controller.run(); - assertEquals(true, outputChannel.getWriteValue().isPresent()); - output = outputChannel.getWriteValue().get(); - assertEquals(true, output); - } - - @Test - public void test3() { - ess.soc.setValue(15L); - meter.activePower.setValue(5000L); - outputChannel.setValue(true); - outputChannel.shadowCopyAndReset(); - // OFF - controller.run(); - assertEquals(false, outputChannel.getWriteValue().isPresent()); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - controller.run(); - outputChannel.shadowCopyAndReset(); - assertEquals(false, outputChannel.getWriteValue().isPresent()); - outputChannel.shadowCopyAndReset(); - controller.run(); - assertEquals(true, outputChannel.getWriteValue().isPresent()); - boolean output = outputChannel.getWriteValue().get(); - assertEquals(false, output); - } - -} +package io.openems.test.controller; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.thing.Thing; +import io.openems.impl.controller.thermalpowerstation.Ess; +import io.openems.impl.controller.thermalpowerstation.Meter; +import io.openems.impl.controller.thermalpowerstation.ThermalPowerStationController; +import io.openems.test.utils.channel.UnitTestWriteChannel; +import io.openems.test.utils.devicenatures.UnitTestAsymmetricEssNature; +import io.openems.test.utils.devicenatures.UnitTestSymmetricMeterNature; + +public class ThermalPowerStationTest { + + private static ThermalPowerStationController controller; + private static UnitTestAsymmetricEssNature ess; + private static UnitTestWriteChannel outputChannel; + private static UnitTestSymmetricMeterNature meter; + private static Ess essThingMap; + private static Meter meterThingMap; + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + ess = new UnitTestAsymmetricEssNature("ess0"); + meter = new UnitTestSymmetricMeterNature("meter0"); + controller = new ThermalPowerStationController(); + outputChannel = new UnitTestWriteChannel<>("0", new Thing() { + + @Override + public String id() { + return "output0"; + } + + @Override + public ThingStateChannel getStateChannel() { + // TODO Auto-generated method stub + return null; + } + }); + essThingMap = new Ess(ess); + meterThingMap = new Meter(meter); + controller.ess.updateValue(essThingMap, true); + List meters = new ArrayList<>(); + meters.add(meterThingMap); + controller.meters.updateValue(meters, true); + controller.outputChannelOpt = Optional.of(outputChannel); + controller.productionLimit.updateValue(1000L, true); + controller.limitTimeRange.updateValue(1L, true); + controller.minSoc.updateValue(15L, true); + controller.maxSoc.updateValue(95L, true); + controller.invertOutput.updateValue(false, true); + } + + @Before + public void beforeTest() { + outputChannel.shadowCopyAndReset(); + } + + @Test + public void test1() { + ess.soc.setValue(15L); + meter.activePower.setValue(0L); + outputChannel.setValue(false); + controller.run(); + assertEquals(false, outputChannel.getWriteValue().isPresent()); + } + + @Test + public void test2() { + ess.soc.setValue(15L); + meter.activePower.setValue(0L); + outputChannel.setValue(true); + outputChannel.shadowCopyAndReset(); + // OFF + controller.run(); + assertEquals(false, outputChannel.getWriteValue().isPresent()); + outputChannel.shadowCopyAndReset(); + // SWITCH OFF + controller.run(); + assertEquals(true, outputChannel.getWriteValue().isPresent()); + boolean output = outputChannel.getWriteValue().get(); + assertEquals(false, output); + outputChannel.setValue(false); + outputChannel.shadowCopyAndReset(); + // SWITCH OFF + controller.run(); + assertEquals(false, outputChannel.getWriteValue().isPresent()); + outputChannel.shadowCopyAndReset(); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + // OFF + controller.run(); + assertEquals(false, outputChannel.getWriteValue().isPresent()); + outputChannel.shadowCopyAndReset(); + // SWITCH ON + controller.run(); + assertEquals(true, outputChannel.getWriteValue().isPresent()); + output = outputChannel.getWriteValue().get(); + assertEquals(true, output); + } + + @Test + public void test3() { + ess.soc.setValue(15L); + meter.activePower.setValue(5000L); + outputChannel.setValue(true); + outputChannel.shadowCopyAndReset(); + // OFF + controller.run(); + assertEquals(false, outputChannel.getWriteValue().isPresent()); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + controller.run(); + outputChannel.shadowCopyAndReset(); + assertEquals(false, outputChannel.getWriteValue().isPresent()); + outputChannel.shadowCopyAndReset(); + controller.run(); + assertEquals(true, outputChannel.getWriteValue().isPresent()); + boolean output = outputChannel.getWriteValue().get(); + assertEquals(false, output); + } + +} diff --git a/edge/src/io/openems/test/utils/channel/UnitTestReadChannel.java b/edge/src/io/openems/test/utils/channel/UnitTestReadChannel.java index 3f404e64e53..c7f444107be 100644 --- a/edge/src/io/openems/test/utils/channel/UnitTestReadChannel.java +++ b/edge/src/io/openems/test/utils/channel/UnitTestReadChannel.java @@ -1,31 +1,38 @@ -package io.openems.test.utils.channel; - -import io.openems.api.thing.Thing; - -public class UnitTestReadChannel extends io.openems.api.channel.ReadChannel { - - public UnitTestReadChannel(String deviceName,String id){ - super(id,new Thing() { - - @Override - public String id() { - return deviceName; - } - }); - } - - public UnitTestReadChannel(String id, Thing parent) { - super(id, parent); - } - - public void setValue(T value) { - this.updateValue(value); - } - - @Override - public UnitTestReadChannel label(T value, String label) { - super.label(value, label); - return this; - } - -} +package io.openems.test.utils.channel; + +import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.thing.Thing; + +public class UnitTestReadChannel extends io.openems.api.channel.ReadChannel { + + public UnitTestReadChannel(String deviceName,String id){ + super(id,new Thing() { + + @Override + public String id() { + return deviceName; + } + + @Override + public ThingStateChannel getStateChannel() { + // TODO Auto-generated method stub + return null; + } + }); + } + + public UnitTestReadChannel(String id, Thing parent) { + super(id, parent); + } + + public void setValue(T value) { + this.updateValue(value); + } + + @Override + public UnitTestReadChannel label(T value, String label) { + super.label(value, label); + return this; + } + +} diff --git a/edge/src/io/openems/test/utils/channel/UnitTestWriteChannel.java b/edge/src/io/openems/test/utils/channel/UnitTestWriteChannel.java index c7f2baaebfb..9954ce6a1c7 100644 --- a/edge/src/io/openems/test/utils/channel/UnitTestWriteChannel.java +++ b/edge/src/io/openems/test/utils/channel/UnitTestWriteChannel.java @@ -1,43 +1,50 @@ -package io.openems.test.utils.channel; - -import java.util.Optional; - -import io.openems.api.channel.ReadChannel; -import io.openems.api.channel.WriteChannel; -import io.openems.api.thing.Thing; - -public class UnitTestWriteChannel extends WriteChannel { - - public UnitTestWriteChannel(String deviceName, String id) { - super(id, new Thing() { - - @Override - public String id() { - return id; - } - }); - } - - public UnitTestWriteChannel(String id, Thing parent) { - super(id, parent); - } - - public void setValue(T value) { - this.updateValue(value); - } - - public Optional getWrittenValue() { - return writeShadowCopy; - } - - @Override - public UnitTestWriteChannel maxWriteChannel(ReadChannel channel) { - return (UnitTestWriteChannel) super.maxWriteChannel(channel); - } - - @Override - public UnitTestWriteChannel minWriteChannel(ReadChannel channel) { - return (UnitTestWriteChannel) super.minWriteChannel(channel); - } - -} +package io.openems.test.utils.channel; + +import java.util.Optional; + +import io.openems.api.channel.ReadChannel; +import io.openems.api.channel.WriteChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.thing.Thing; + +public class UnitTestWriteChannel extends WriteChannel { + + public UnitTestWriteChannel(String deviceName, String id) { + super(id, new Thing() { + + @Override + public String id() { + return id; + } + + @Override + public ThingStateChannel getStateChannel() { + // TODO Auto-generated method stub + return null; + } + }); + } + + public UnitTestWriteChannel(String id, Thing parent) { + super(id, parent); + } + + public void setValue(T value) { + this.updateValue(value); + } + + public Optional getWrittenValue() { + return writeShadowCopy; + } + + @Override + public UnitTestWriteChannel maxWriteChannel(ReadChannel channel) { + return (UnitTestWriteChannel) super.maxWriteChannel(channel); + } + + @Override + public UnitTestWriteChannel minWriteChannel(ReadChannel channel) { + return (UnitTestWriteChannel) super.minWriteChannel(channel); + } + +} diff --git a/edge/src/io/openems/test/utils/devicenatures/UnitTestAsymmetricEssNature.java b/edge/src/io/openems/test/utils/devicenatures/UnitTestAsymmetricEssNature.java index c41804a3e2b..d543562555d 100644 --- a/edge/src/io/openems/test/utils/devicenatures/UnitTestAsymmetricEssNature.java +++ b/edge/src/io/openems/test/utils/devicenatures/UnitTestAsymmetricEssNature.java @@ -8,8 +8,8 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; -import io.openems.api.channel.StatusBitChannels; import io.openems.api.channel.WriteChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.ess.AsymmetricEssNature; import io.openems.impl.device.simulator.SimulatorTools; @@ -92,11 +92,6 @@ public ReadChannel allowedApparent() { return allowedApparent; } - @Override - public StatusBitChannels warning() { - return null; - } - @Override public WriteChannel setWorkState() { return setWorkState; @@ -206,4 +201,10 @@ public List getWriteTasks() { return null; } + @Override + public ThingStateChannel getStateChannel() { + // TODO Auto-generated method stub + return null; + } + } diff --git a/edge/src/io/openems/test/utils/devicenatures/UnitTestAsymmetricMeterNature.java b/edge/src/io/openems/test/utils/devicenatures/UnitTestAsymmetricMeterNature.java index 5a9c3ac05c0..30ee1c2e72c 100644 --- a/edge/src/io/openems/test/utils/devicenatures/UnitTestAsymmetricMeterNature.java +++ b/edge/src/io/openems/test/utils/devicenatures/UnitTestAsymmetricMeterNature.java @@ -7,6 +7,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.AsymmetricMeterNature; import io.openems.test.utils.channel.UnitTestReadChannel; @@ -145,4 +146,10 @@ public List getWriteTasks() { return null; } + @Override + public ThingStateChannel getStateChannel() { + // TODO Auto-generated method stub + return null; + } + } diff --git a/edge/src/io/openems/test/utils/devicenatures/UnitTestSymmetricEssNature.java b/edge/src/io/openems/test/utils/devicenatures/UnitTestSymmetricEssNature.java index ec62384b11f..071ad40d96a 100644 --- a/edge/src/io/openems/test/utils/devicenatures/UnitTestSymmetricEssNature.java +++ b/edge/src/io/openems/test/utils/devicenatures/UnitTestSymmetricEssNature.java @@ -8,8 +8,8 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; -import io.openems.api.channel.StatusBitChannels; import io.openems.api.channel.WriteChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.device.nature.ess.SymmetricEssNature; @@ -84,11 +84,6 @@ public ReadChannel allowedApparent() { return allowedApparent; } - @Override - public StatusBitChannels warning() { - return null; - } - @Override public WriteChannel setWorkState() { return setWorkState; @@ -163,4 +158,10 @@ public List getWriteTasks() { return null; } + @Override + public ThingStateChannel getStateChannel() { + // TODO Auto-generated method stub + return null; + } + } diff --git a/edge/src/io/openems/test/utils/devicenatures/UnitTestSymmetricMeterNature.java b/edge/src/io/openems/test/utils/devicenatures/UnitTestSymmetricMeterNature.java index 17c4a535f01..f6b4d09176a 100644 --- a/edge/src/io/openems/test/utils/devicenatures/UnitTestSymmetricMeterNature.java +++ b/edge/src/io/openems/test/utils/devicenatures/UnitTestSymmetricMeterNature.java @@ -7,6 +7,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.SymmetricMeterNature; import io.openems.test.utils.channel.UnitTestReadChannel; @@ -101,4 +102,10 @@ public List getWriteTasks() { return null; } + @Override + public ThingStateChannel getStateChannel() { + // TODO Auto-generated method stub + return null; + } + } From e67c26f631dfc00a5b26e4199a6358133b576a35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Ro=C3=9Fmann?= Date: Wed, 10 Jan 2018 15:09:30 +0100 Subject: [PATCH 32/55] fix Classpath --- edge/src/io/openems/impl/device/system/System.java | 1 - 1 file changed, 1 deletion(-) diff --git a/edge/src/io/openems/impl/device/system/System.java b/edge/src/io/openems/impl/device/system/System.java index bb3e801d3ab..6ddaefdf2d9 100644 --- a/edge/src/io/openems/impl/device/system/System.java +++ b/edge/src/io/openems/impl/device/system/System.java @@ -30,7 +30,6 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.DebugChannel; import io.openems.api.device.nature.DeviceNature; -import io.openems.api.device.nature.system.SystemNature; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; import io.openems.api.exception.OpenemsException; From 951e8728deac9274a0e4fbd6ff5917ba292e4503 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Ro=C3=9Fmann?= Date: Wed, 10 Jan 2018 15:10:26 +0100 Subject: [PATCH 33/55] implement ChannelEnum to send Enum value to the UI and api --- .../io/openems/common/types}/ChannelEnum.java | 2 +- .../io/openems/common/utils/JsonUtils.java | 679 +++++++++--------- .../api/channel/thingstate/ThingState.java | 2 +- .../channel/thingstate/ThingStateChannel.java | 11 + edge/src/io/openems/core/ThingRepository.java | 10 +- .../io/openems/core/utilities/BitUtils.java | 1 + .../openems/core/utilities/OpenemsTypes.java | 10 +- .../fenecon/FeneconPersistence.java | 2 +- .../influxdb/InfluxdbPersistence.java | 2 +- 9 files changed, 373 insertions(+), 346 deletions(-) rename {edge/src/io/openems/api/channel => common/src/io/openems/common/types}/ChannelEnum.java (76%) diff --git a/edge/src/io/openems/api/channel/ChannelEnum.java b/common/src/io/openems/common/types/ChannelEnum.java similarity index 76% rename from edge/src/io/openems/api/channel/ChannelEnum.java rename to common/src/io/openems/common/types/ChannelEnum.java index 3061228f920..91112c17bbd 100644 --- a/edge/src/io/openems/api/channel/ChannelEnum.java +++ b/common/src/io/openems/common/types/ChannelEnum.java @@ -1,4 +1,4 @@ -package io.openems.api.channel; +package io.openems.common.types; import java.util.Locale; diff --git a/common/src/io/openems/common/utils/JsonUtils.java b/common/src/io/openems/common/utils/JsonUtils.java index 124da550902..a866ea09b4c 100644 --- a/common/src/io/openems/common/utils/JsonUtils.java +++ b/common/src/io/openems/common/utils/JsonUtils.java @@ -1,337 +1,342 @@ -package io.openems.common.utils; - -import java.net.Inet4Address; -import java.time.ZoneId; -import java.time.ZonedDateTime; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Map.Entry; -import java.util.Optional; -import java.util.Set; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.JsonParser; -import com.google.gson.JsonPrimitive; - -import io.openems.common.exceptions.NotImplementedException; -import io.openems.common.exceptions.OpenemsException; - -// TODO use getAsOptional***() as basis for getAs***() to avoid unnecessary exceptions -public class JsonUtils { - public static JsonArray getAsJsonArray(JsonElement jElement) throws OpenemsException { - if (!jElement.isJsonArray()) { - throw new OpenemsException("This is not a JsonArray: " + jElement); - } - return jElement.getAsJsonArray(); - }; - - public static JsonArray getAsJsonArray(JsonElement jElement, String memberName) throws OpenemsException { - JsonElement jSubElement = getSubElement(jElement, memberName); - if (!jSubElement.isJsonArray()) { - throw new OpenemsException("Element [" + memberName + "] is not a JsonArray: " + jSubElement); - } - return jSubElement.getAsJsonArray(); - }; - - public static Optional getAsOptionalJsonArray(JsonElement jElement, String memberName) { - try { - return Optional.of(getAsJsonArray(jElement, memberName)); - } catch (OpenemsException e) { - return Optional.empty(); - } - } - - public static JsonObject getAsJsonObject(JsonElement jElement) throws OpenemsException { - if (!jElement.isJsonObject()) { - throw new OpenemsException("This is not a JsonObject: " + jElement); - } - return jElement.getAsJsonObject(); - }; - - public static JsonObject getAsJsonObject(JsonElement jElement, String memberName) throws OpenemsException { - JsonElement jsubElement = getSubElement(jElement, memberName); - if (!jsubElement.isJsonObject()) { - throw new OpenemsException("Element [" + memberName + "] is not a JsonObject: " + jsubElement); - } - return jsubElement.getAsJsonObject(); - }; - - public static Optional getAsOptionalJsonObject(JsonElement jElement, String memberName) { - try { - return Optional.of(getAsJsonObject(jElement, memberName)); - } catch (OpenemsException e) { - return Optional.empty(); - } - } - - public static JsonPrimitive getAsPrimitive(JsonElement jElement, String memberName) throws OpenemsException { - JsonElement jSubElement = getSubElement(jElement, memberName); - return getAsPrimitive(jSubElement); - } - - public static JsonPrimitive getAsPrimitive(JsonElement jElement) throws OpenemsException { - if (!jElement.isJsonPrimitive()) { - throw new OpenemsException("This is not a JsonPrimitive: " + jElement); - } - return jElement.getAsJsonPrimitive(); - } - - public static String getAsString(JsonElement jElement) throws OpenemsException { - JsonPrimitive jPrimitive = getAsPrimitive(jElement); - if (!jPrimitive.isString()) { - throw new OpenemsException("This is not a String: " + jPrimitive); - } - return jPrimitive.getAsString(); - } - - public static boolean getAsBoolean(JsonElement jElement) throws OpenemsException { - JsonPrimitive jPrimitive = getAsPrimitive(jElement); - if (!jPrimitive.isBoolean()) { - throw new OpenemsException("This is not a Boolean: " + jPrimitive); - } - return jPrimitive.getAsBoolean(); - } - - public static Optional getAsOptionalString(JsonElement jElement, String memberName) { - try { - return Optional.of(getAsString(jElement, memberName)); - } catch (OpenemsException e) { - return Optional.empty(); - } - } - - public static String getAsString(JsonElement jElement, String memberName) throws OpenemsException { - JsonPrimitive jPrimitive = getAsPrimitive(jElement, memberName); - if (!jPrimitive.isString()) { - throw new OpenemsException("Element [" + memberName + "] is not a String: " + jPrimitive); - } - return jPrimitive.getAsString(); - } - - public static Optional getAsOptionalInt(JsonElement jElement, String memberName) { - try { - return Optional.of(getAsInt(jElement, memberName)); - } catch (OpenemsException e) { - return Optional.empty(); - } - } - - public static Optional getAsOptionalLong(JsonElement jElement, String memberName) { - try { - return Optional.of(getAsLong(jElement, memberName)); - } catch (OpenemsException e) { - return Optional.empty(); - } - } - - public static int getAsInt(JsonElement jElement, String memberName) throws OpenemsException { - JsonPrimitive jPrimitive = getAsPrimitive(jElement, memberName); - if (jPrimitive.isNumber()) { - return jPrimitive.getAsInt(); - } else if (jPrimitive.isString()) { - String string = jPrimitive.getAsString(); - return Integer.parseInt(string); - } - throw new OpenemsException("Element [" + memberName + "] is not an Integer: " + jPrimitive); - } - - public static boolean getAsBoolean(JsonElement jElement, String memberName) throws OpenemsException { - JsonPrimitive jPrimitive = getAsPrimitive(jElement, memberName); - if (!jPrimitive.isBoolean()) { - throw new OpenemsException("Element [" + memberName + "] is not a Boolean: " + jPrimitive); - } - return jPrimitive.getAsBoolean(); - } - - /** - * Takes a json in the form 'YYYY-MM-DD' and converts it to a ZonedDateTime with - * hour, minute and second set to zero. - * - * @param jElement - * @param memberName - * @param timezone - * @return - * @throws OpenemsException - */ - public static ZonedDateTime getAsZonedDateTime(JsonElement jElement, String memberName, ZoneId timezone) - throws OpenemsException { - String[] date = JsonUtils.getAsString(jElement, memberName).split("-"); - try { - int year = Integer.valueOf(date[0]); - int month = Integer.valueOf(date[1]); - int day = Integer.valueOf(date[2]); - return ZonedDateTime.of(year, month, day, 0, 0, 0, 0, timezone); - } catch (ArrayIndexOutOfBoundsException e) { - throw new OpenemsException("Element [" + memberName + "] is not a Date: " + jElement + ". Error: " + e); - } - } - - public static long getAsLong(JsonElement jElement, String memberName) throws OpenemsException { - JsonPrimitive jPrimitive = getAsPrimitive(jElement, memberName); - if (jPrimitive.isNumber()) { - return jPrimitive.getAsLong(); - } else if (jPrimitive.isString()) { - String string = jPrimitive.getAsString(); - return Long.parseLong(string); - } - throw new OpenemsException("[" + memberName + "] is not a Number: " + jPrimitive); - } - - public static JsonElement getSubElement(JsonElement jElement, String memberName) throws OpenemsException { - JsonObject jObject = getAsJsonObject(jElement); - if (!jObject.has(memberName)) { - throw new OpenemsException("Element [" + memberName + "] is not a Subelement of: " + jElement); - } - return jObject.get(memberName); - } - - /** - * Merges the second Object into the first object - * - * @param j1 - * @param j2 - * @return - */ - public static JsonObject merge(JsonObject j1, JsonObject j2) { - // TODO be smarter: merge down the tree - for (Entry entry : j2.entrySet()) { - j1.add(entry.getKey(), entry.getValue()); - } - return j1; - } - - public static Optional merge(Optional j1Opt, Optional j2Opt) { - if (j1Opt.isPresent() && j2Opt.isPresent()) { - return Optional.of(JsonUtils.merge(j1Opt.get(), j2Opt.get())); - } - if (j1Opt.isPresent()) { - return j1Opt; - } - return j2Opt; - } - - public static boolean hasElement(JsonElement j, String... paths) { - return getMatchingElements(j, paths).size() > 0; - } - - public static Set getMatchingElements(JsonElement j, String... paths) { - Set result = new HashSet(); - if (paths.length == 0) { - // last path element - result.add(j); - return result; - } - String path = paths[0]; - if (j.isJsonObject()) { - JsonObject jO = j.getAsJsonObject(); - if (jO.has(path)) { - List nextPathsList = new ArrayList(Arrays.asList(paths)); - nextPathsList.remove(0); - String[] nextPaths = nextPathsList.toArray(new String[0]); - result.addAll(getMatchingElements(jO.get(path), nextPaths)); - } - } else if (j.isJsonArray()) { - for (JsonElement jE : j.getAsJsonArray()) { - result.addAll(getMatchingElements(jE, paths)); - } - } else if (j.isJsonPrimitive()) { - JsonPrimitive jP = j.getAsJsonPrimitive(); - if (jP.isString()) { - if (jP.getAsString().equals(path)) { - result.add(jP); - } - } - } - return result; - } - - /** - * Pretty print a JsonElement - * - * @param j - */ - public static void prettyPrint(JsonElement j) { - Gson gson = new GsonBuilder().setPrettyPrinting().create(); - String json = gson.toJson(j); - System.out.println(json); - } - - /** - * Parses a string to a JsonElement - * - * @param string - * @return - */ - public static JsonElement parse(String string) throws OpenemsException { - try { - JsonParser parser = new JsonParser(); - return parser.parse(string); - } catch (JsonParseException e) { - throw new OpenemsException("Unable to parse [" + string + "] + to JSON: " + e.getMessage(), e); - } - } - - /* - * Copied from edge - * TODO! - */ - public static JsonElement getAsJsonElement(Object value) throws NotImplementedException { - // null - if (value == null) { - return null; - } - // optional - if (value instanceof Optional) { - if (!((Optional) value).isPresent()) { - return null; - } else { - value = ((Optional) value).get(); - } - } - if (value instanceof Number) { - /* - * Number - */ - return new JsonPrimitive((Number) value); - } else if (value instanceof String) { - /* - * String - */ - return new JsonPrimitive((String) value); - } else if (value instanceof Boolean) { - /* - * Boolean - */ - return new JsonPrimitive((Boolean) value); - } else if (value instanceof Inet4Address) { - /* - * Inet4Address - */ - return new JsonPrimitive(((Inet4Address) value).getHostAddress()); - } else if (value instanceof JsonElement) { - /* - * JsonElement - */ - return (JsonElement) value; - } else if (value instanceof Long[]){ - /* - * Long-Array - */ - JsonArray js = new JsonArray(); - for (Long l : (Long[]) value){ - js.add(new JsonPrimitive((Long) l)); - } - return js; - } - throw new NotImplementedException("Converter for [" + value + "]" + " of type [" // - + value.getClass().getSimpleName() + "]" // - + " to JSON is not implemented."); - } -} +package io.openems.common.utils; + +import java.net.Inet4Address; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.Set; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonParser; +import com.google.gson.JsonPrimitive; + +import io.openems.common.exceptions.NotImplementedException; +import io.openems.common.exceptions.OpenemsException; +import io.openems.common.types.ChannelEnum; + +// TODO use getAsOptional***() as basis for getAs***() to avoid unnecessary exceptions +public class JsonUtils { + public static JsonArray getAsJsonArray(JsonElement jElement) throws OpenemsException { + if (!jElement.isJsonArray()) { + throw new OpenemsException("This is not a JsonArray: " + jElement); + } + return jElement.getAsJsonArray(); + }; + + public static JsonArray getAsJsonArray(JsonElement jElement, String memberName) throws OpenemsException { + JsonElement jSubElement = getSubElement(jElement, memberName); + if (!jSubElement.isJsonArray()) { + throw new OpenemsException("Element [" + memberName + "] is not a JsonArray: " + jSubElement); + } + return jSubElement.getAsJsonArray(); + }; + + public static Optional getAsOptionalJsonArray(JsonElement jElement, String memberName) { + try { + return Optional.of(getAsJsonArray(jElement, memberName)); + } catch (OpenemsException e) { + return Optional.empty(); + } + } + + public static JsonObject getAsJsonObject(JsonElement jElement) throws OpenemsException { + if (!jElement.isJsonObject()) { + throw new OpenemsException("This is not a JsonObject: " + jElement); + } + return jElement.getAsJsonObject(); + }; + + public static JsonObject getAsJsonObject(JsonElement jElement, String memberName) throws OpenemsException { + JsonElement jsubElement = getSubElement(jElement, memberName); + if (!jsubElement.isJsonObject()) { + throw new OpenemsException("Element [" + memberName + "] is not a JsonObject: " + jsubElement); + } + return jsubElement.getAsJsonObject(); + }; + + public static Optional getAsOptionalJsonObject(JsonElement jElement, String memberName) { + try { + return Optional.of(getAsJsonObject(jElement, memberName)); + } catch (OpenemsException e) { + return Optional.empty(); + } + } + + public static JsonPrimitive getAsPrimitive(JsonElement jElement, String memberName) throws OpenemsException { + JsonElement jSubElement = getSubElement(jElement, memberName); + return getAsPrimitive(jSubElement); + } + + public static JsonPrimitive getAsPrimitive(JsonElement jElement) throws OpenemsException { + if (!jElement.isJsonPrimitive()) { + throw new OpenemsException("This is not a JsonPrimitive: " + jElement); + } + return jElement.getAsJsonPrimitive(); + } + + public static String getAsString(JsonElement jElement) throws OpenemsException { + JsonPrimitive jPrimitive = getAsPrimitive(jElement); + if (!jPrimitive.isString()) { + throw new OpenemsException("This is not a String: " + jPrimitive); + } + return jPrimitive.getAsString(); + } + + public static boolean getAsBoolean(JsonElement jElement) throws OpenemsException { + JsonPrimitive jPrimitive = getAsPrimitive(jElement); + if (!jPrimitive.isBoolean()) { + throw new OpenemsException("This is not a Boolean: " + jPrimitive); + } + return jPrimitive.getAsBoolean(); + } + + public static Optional getAsOptionalString(JsonElement jElement, String memberName) { + try { + return Optional.of(getAsString(jElement, memberName)); + } catch (OpenemsException e) { + return Optional.empty(); + } + } + + public static String getAsString(JsonElement jElement, String memberName) throws OpenemsException { + JsonPrimitive jPrimitive = getAsPrimitive(jElement, memberName); + if (!jPrimitive.isString()) { + throw new OpenemsException("Element [" + memberName + "] is not a String: " + jPrimitive); + } + return jPrimitive.getAsString(); + } + + public static Optional getAsOptionalInt(JsonElement jElement, String memberName) { + try { + return Optional.of(getAsInt(jElement, memberName)); + } catch (OpenemsException e) { + return Optional.empty(); + } + } + + public static Optional getAsOptionalLong(JsonElement jElement, String memberName) { + try { + return Optional.of(getAsLong(jElement, memberName)); + } catch (OpenemsException e) { + return Optional.empty(); + } + } + + public static int getAsInt(JsonElement jElement, String memberName) throws OpenemsException { + JsonPrimitive jPrimitive = getAsPrimitive(jElement, memberName); + if (jPrimitive.isNumber()) { + return jPrimitive.getAsInt(); + } else if (jPrimitive.isString()) { + String string = jPrimitive.getAsString(); + return Integer.parseInt(string); + } + throw new OpenemsException("Element [" + memberName + "] is not an Integer: " + jPrimitive); + } + + public static boolean getAsBoolean(JsonElement jElement, String memberName) throws OpenemsException { + JsonPrimitive jPrimitive = getAsPrimitive(jElement, memberName); + if (!jPrimitive.isBoolean()) { + throw new OpenemsException("Element [" + memberName + "] is not a Boolean: " + jPrimitive); + } + return jPrimitive.getAsBoolean(); + } + + /** + * Takes a json in the form 'YYYY-MM-DD' and converts it to a ZonedDateTime with + * hour, minute and second set to zero. + * + * @param jElement + * @param memberName + * @param timezone + * @return + * @throws OpenemsException + */ + public static ZonedDateTime getAsZonedDateTime(JsonElement jElement, String memberName, ZoneId timezone) + throws OpenemsException { + String[] date = JsonUtils.getAsString(jElement, memberName).split("-"); + try { + int year = Integer.valueOf(date[0]); + int month = Integer.valueOf(date[1]); + int day = Integer.valueOf(date[2]); + return ZonedDateTime.of(year, month, day, 0, 0, 0, 0, timezone); + } catch (ArrayIndexOutOfBoundsException e) { + throw new OpenemsException("Element [" + memberName + "] is not a Date: " + jElement + ". Error: " + e); + } + } + + public static long getAsLong(JsonElement jElement, String memberName) throws OpenemsException { + JsonPrimitive jPrimitive = getAsPrimitive(jElement, memberName); + if (jPrimitive.isNumber()) { + return jPrimitive.getAsLong(); + } else if (jPrimitive.isString()) { + String string = jPrimitive.getAsString(); + return Long.parseLong(string); + } + throw new OpenemsException("[" + memberName + "] is not a Number: " + jPrimitive); + } + + public static JsonElement getSubElement(JsonElement jElement, String memberName) throws OpenemsException { + JsonObject jObject = getAsJsonObject(jElement); + if (!jObject.has(memberName)) { + throw new OpenemsException("Element [" + memberName + "] is not a Subelement of: " + jElement); + } + return jObject.get(memberName); + } + + /** + * Merges the second Object into the first object + * + * @param j1 + * @param j2 + * @return + */ + public static JsonObject merge(JsonObject j1, JsonObject j2) { + // TODO be smarter: merge down the tree + for (Entry entry : j2.entrySet()) { + j1.add(entry.getKey(), entry.getValue()); + } + return j1; + } + + public static Optional merge(Optional j1Opt, Optional j2Opt) { + if (j1Opt.isPresent() && j2Opt.isPresent()) { + return Optional.of(JsonUtils.merge(j1Opt.get(), j2Opt.get())); + } + if (j1Opt.isPresent()) { + return j1Opt; + } + return j2Opt; + } + + public static boolean hasElement(JsonElement j, String... paths) { + return getMatchingElements(j, paths).size() > 0; + } + + public static Set getMatchingElements(JsonElement j, String... paths) { + Set result = new HashSet(); + if (paths.length == 0) { + // last path element + result.add(j); + return result; + } + String path = paths[0]; + if (j.isJsonObject()) { + JsonObject jO = j.getAsJsonObject(); + if (jO.has(path)) { + List nextPathsList = new ArrayList(Arrays.asList(paths)); + nextPathsList.remove(0); + String[] nextPaths = nextPathsList.toArray(new String[0]); + result.addAll(getMatchingElements(jO.get(path), nextPaths)); + } + } else if (j.isJsonArray()) { + for (JsonElement jE : j.getAsJsonArray()) { + result.addAll(getMatchingElements(jE, paths)); + } + } else if (j.isJsonPrimitive()) { + JsonPrimitive jP = j.getAsJsonPrimitive(); + if (jP.isString()) { + if (jP.getAsString().equals(path)) { + result.add(jP); + } + } + } + return result; + } + + /** + * Pretty print a JsonElement + * + * @param j + */ + public static void prettyPrint(JsonElement j) { + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + String json = gson.toJson(j); + System.out.println(json); + } + + /** + * Parses a string to a JsonElement + * + * @param string + * @return + */ + public static JsonElement parse(String string) throws OpenemsException { + try { + JsonParser parser = new JsonParser(); + return parser.parse(string); + } catch (JsonParseException e) { + throw new OpenemsException("Unable to parse [" + string + "] + to JSON: " + e.getMessage(), e); + } + } + + /* + * Copied from edge TODO! + */ + public static JsonElement getAsJsonElement(Object value) throws NotImplementedException { + // null + if (value == null) { + return null; + } + // optional + if (value instanceof Optional) { + if (!((Optional) value).isPresent()) { + return null; + } else { + value = ((Optional) value).get(); + } + } + if (value instanceof Number) { + /* + * Number + */ + return new JsonPrimitive((Number) value); + } else if(value instanceof ChannelEnum) { + /* + * ChannelEnum + */ + return new JsonPrimitive(((ChannelEnum)value).getValue()); + } else if (value instanceof String) { + /* + * String + */ + return new JsonPrimitive((String) value); + } else if (value instanceof Boolean) { + /* + * Boolean + */ + return new JsonPrimitive((Boolean) value); + } else if (value instanceof Inet4Address) { + /* + * Inet4Address + */ + return new JsonPrimitive(((Inet4Address) value).getHostAddress()); + } else if (value instanceof JsonElement) { + /* + * JsonElement + */ + return (JsonElement) value; + } else if (value instanceof Long[]){ + /* + * Long-Array + */ + JsonArray js = new JsonArray(); + for (Long l : (Long[]) value){ + js.add(new JsonPrimitive((Long) l)); + } + return js; + } + throw new NotImplementedException("Converter for [" + value + "]" + " of type [" // + + value.getClass().getSimpleName() + "]" // + + " to JSON is not implemented."); + } +} diff --git a/edge/src/io/openems/api/channel/thingstate/ThingState.java b/edge/src/io/openems/api/channel/thingstate/ThingState.java index 920f8a93d9f..b76ab28ddf6 100644 --- a/edge/src/io/openems/api/channel/thingstate/ThingState.java +++ b/edge/src/io/openems/api/channel/thingstate/ThingState.java @@ -6,7 +6,7 @@ import java.util.MissingResourceException; import java.util.ResourceBundle; -import io.openems.api.channel.ChannelEnum; +import io.openems.common.types.ChannelEnum; public enum ThingState implements ChannelEnum { RUN(0), WARNING(1), FAULT(2); diff --git a/edge/src/io/openems/api/channel/thingstate/ThingStateChannel.java b/edge/src/io/openems/api/channel/thingstate/ThingStateChannel.java index 0a432beb802..7d9357be1a8 100644 --- a/edge/src/io/openems/api/channel/thingstate/ThingStateChannel.java +++ b/edge/src/io/openems/api/channel/thingstate/ThingStateChannel.java @@ -25,6 +25,7 @@ public ThingStateChannel(Thing parent){ this.faultChannels = new ArrayList<>(); this.channelNames = new HashSet<>(); this.childChannels = new ArrayList<>(); + updateState(); } public void addWarningChannel(ReadChannel channel) throws ConfigException { @@ -32,6 +33,7 @@ public void addWarningChannel(ReadChannel channel) throws ConfigExcepti this.warningChannels.add(channel); this.channelNames.add(channel.address()); channel.addChangeListener(this); + updateState(); } else { throw new ConfigException("A channel with the name [" + channel.address() + "] is already registered!"); } @@ -41,6 +43,7 @@ public void removeWarningChannel(ReadChannel channel) { channel.removeChangeListener(this); this.channelNames.remove(channel.address()); this.warningChannels.remove(channel); + updateState(); } public void addFaultChannel(ReadChannel channel) throws ConfigException { @@ -48,6 +51,7 @@ public void addFaultChannel(ReadChannel channel) throws ConfigException this.faultChannels.add(channel); this.channelNames.add(channel.address()); channel.addChangeListener(this); + updateState(); } else { throw new ConfigException("A channel with the name [" + channel.address() + "] is already registered!"); } @@ -57,6 +61,7 @@ public void removeFaultChannel(ReadChannel channel) { channel.removeChangeListener(this); this.channelNames.remove(channel.address()); this.faultChannels.remove(channel); + updateState(); } public List> getWarningChannels() { @@ -80,15 +85,21 @@ public List> getFaultChannels() { public void addChildChannel(ThingStateChannel child) { this.childChannels.add(child); child.addChangeListener(this); + updateState(); } public void removeChildChannel(ThingStateChannel child) { child.removeChangeListener(this); this.childChannels.add(child); + updateState(); } @Override public void channelChanged(Channel channel, Optional newValue, Optional oldValue) { + updateState(); + } + + private void updateState() { for(ThingStateChannel child : this.childChannels) { if(child.isValuePresent()) { switch(child.getValue()) { diff --git a/edge/src/io/openems/core/ThingRepository.java b/edge/src/io/openems/core/ThingRepository.java index ad348f8b243..0a361cad382 100644 --- a/edge/src/io/openems/core/ThingRepository.java +++ b/edge/src/io/openems/core/ThingRepository.java @@ -31,6 +31,7 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Map.Entry; import java.util.Optional; import java.util.Set; @@ -155,7 +156,7 @@ public synchronized void addThing(Thing thing) { // Add Channels thingConfigChannels ThingDoc thingDoc = classRepository.getThingDoc(thing.getClass()); - for (ChannelDoc channelDoc : thingDoc.getConfigChannelDocs()) { + for (ChannelDoc channelDoc : thingDoc.getChannelDocs()) { Member member = channelDoc.getMember(); try { List channels = new ArrayList<>(); @@ -181,9 +182,9 @@ public synchronized void addThing(Thing thing) { continue; } for (Channel channel : channels) { + // Add Channel to thingChannels + thingChannels.put(thing, channel.id(), channel); if (channel instanceof ConfigChannel) { - // Add Channel to thingChannels - thingChannels.put(thing, channel.id(), channel); // Add Channel to configChannels thingConfigChannels.put(thing, (ConfigChannel) channel); @@ -408,7 +409,8 @@ public Optional getChannel(String thingId, String channelId) { if (thing == null) { return Optional.empty(); } - Channel channel = thingChannels.row(thing).get(channelId); + Map channels = thingChannels.row(thing); + Channel channel = channels.get(channelId); return Optional.ofNullable(channel); } diff --git a/edge/src/io/openems/core/utilities/BitUtils.java b/edge/src/io/openems/core/utilities/BitUtils.java index d75b521ad63..16ed9005b20 100644 --- a/edge/src/io/openems/core/utilities/BitUtils.java +++ b/edge/src/io/openems/core/utilities/BitUtils.java @@ -20,6 +20,7 @@ public static int getBitLength(Class type) throws NotImplementedException { case SHORT: return BYTES_SHORT * BITS; + case ENUM: case INTEGER: return BYTES_INT * BITS; diff --git a/edge/src/io/openems/core/utilities/OpenemsTypes.java b/edge/src/io/openems/core/utilities/OpenemsTypes.java index 6b916ab4da3..eea06aa8ab2 100644 --- a/edge/src/io/openems/core/utilities/OpenemsTypes.java +++ b/edge/src/io/openems/core/utilities/OpenemsTypes.java @@ -8,6 +8,7 @@ import io.openems.api.controller.ThingMap; import io.openems.api.device.nature.DeviceNature; import io.openems.api.exception.NotImplementedException; +import io.openems.common.types.ChannelEnum; /** * All types that are used somewhere in the system. This helps with type casting and reflection in certain classes, as @@ -36,7 +37,12 @@ public enum OpenemsTypes { /* * Things */ - DEVICE_NATURE, THING_MAP; + DEVICE_NATURE, THING_MAP, + /* + * Enum + */ + ENUM + ; public static OpenemsTypes get(Class type) throws NotImplementedException { if (Short.class.isAssignableFrom(type)) { @@ -74,6 +80,8 @@ public static OpenemsTypes get(Class type) throws NotImplementedException { } else if (ThingMap.class.isAssignableFrom(type)) { return THING_MAP; + }else if (ChannelEnum.class.isAssignableFrom(type)) { + return ENUM; } throw new NotImplementedException("Type [" + type + "] is not defined as OpenemsType."); } diff --git a/edge/src/io/openems/impl/persistence/fenecon/FeneconPersistence.java b/edge/src/io/openems/impl/persistence/fenecon/FeneconPersistence.java index 0ef2609c01d..b1f5a55eb78 100644 --- a/edge/src/io/openems/impl/persistence/fenecon/FeneconPersistence.java +++ b/edge/src/io/openems/impl/persistence/fenecon/FeneconPersistence.java @@ -38,7 +38,6 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ChannelChangeListener; -import io.openems.api.channel.ChannelEnum; import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; import io.openems.api.channel.thingstate.ThingStateChannel; @@ -52,6 +51,7 @@ import io.openems.api.thing.Thing; import io.openems.common.session.Role; import io.openems.common.types.ChannelAddress; +import io.openems.common.types.ChannelEnum; import io.openems.common.types.FieldValue; import io.openems.common.types.NullFieldValue; import io.openems.common.types.NumberFieldValue; diff --git a/edge/src/io/openems/impl/persistence/influxdb/InfluxdbPersistence.java b/edge/src/io/openems/impl/persistence/influxdb/InfluxdbPersistence.java index fd4c539aca4..aa3fb2bb2de 100644 --- a/edge/src/io/openems/impl/persistence/influxdb/InfluxdbPersistence.java +++ b/edge/src/io/openems/impl/persistence/influxdb/InfluxdbPersistence.java @@ -36,7 +36,6 @@ import com.google.gson.JsonObject; import io.openems.api.channel.Channel; -import io.openems.api.channel.ChannelEnum; import io.openems.api.channel.ChannelUpdateListener; import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; @@ -45,6 +44,7 @@ import io.openems.api.doc.ThingInfo; import io.openems.api.exception.OpenemsException; import io.openems.api.persistence.QueryablePersistence; +import io.openems.common.types.ChannelEnum; import io.openems.common.utils.InfluxdbUtils; import io.openems.core.Databus; From 5e875b4a8d03bb49c7eb12046ecc9daf5d49e10b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Ro=C3=9Fmann?= Date: Wed, 10 Jan 2018 15:11:17 +0100 Subject: [PATCH 34/55] add Subscription for ThingState --- ui/src/app/shared/device/config.ts | 16 ++- ui/yarn.lock | 168 ++++++++++++++++------------- 2 files changed, 108 insertions(+), 76 deletions(-) diff --git a/ui/src/app/shared/device/config.ts b/ui/src/app/shared/device/config.ts index d1c20fac1da..adf0798fbc9 100644 --- a/ui/src/app/shared/device/config.ts +++ b/ui/src/app/shared/device/config.ts @@ -143,9 +143,20 @@ export class ConfigImpl implements DefaultTypes.Config { this.evcsDevices = evcsDevices; } + public getStateChannels(): DefaultTypes.ChannelAddresses { + let result: DefaultTypes.ChannelAddresses = {} + + // Set "ignoreNatures" + for (let thingId in this.config.things) { + result[thingId] = ["State"]; + } + return result; + } + + /** - * Return ChannelAddresses of power channels - */ + * Return ChannelAddresses of power channels + */ public getPowerChannels(): DefaultTypes.ChannelAddresses { let ignoreNatures = { EssClusterNature: true }; let result: DefaultTypes.ChannelAddresses = {} @@ -234,6 +245,7 @@ export class ConfigImpl implements DefaultTypes.Config { } } // basic channels + merge(this.getStateChannels()); merge(this.getPowerChannels()); merge(this.getEssSocChannels()); // widget channels diff --git a/ui/yarn.lock b/ui/yarn.lock index c274a0d5a54..7b8f5ced82d 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -2,9 +2,9 @@ # yarn lockfile v1 -"@angular-devkit/build-optimizer@~0.0.34": - version "0.0.34" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.0.34.tgz#47a0482f5687db79d102cf9d416cf6fa6774d702" +"@angular-devkit/build-optimizer@~0.0.35": + version "0.0.36" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.0.36.tgz#e816ee9be22dbb777724f0281acfa72cfff184b7" dependencies: loader-utils "^1.1.0" source-map "^0.5.6" @@ -17,12 +17,13 @@ dependencies: source-map "^0.5.6" -"@angular-devkit/schematics@~0.0.38": - version "0.0.39" - resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-0.0.39.tgz#8821482d21f3d16798474983599c592063c881e7" +"@angular-devkit/schematics@~0.0.40": + version "0.0.42" + resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-0.0.42.tgz#34eea7136455545c8abd21edf94a36870a073fea" dependencies: "@angular-devkit/core" "0.0.22" "@ngtools/json-schema" "^1.1.0" + "@schematics/schematics" "0.0.11" minimist "^1.2.0" rxjs "^5.5.2" @@ -32,24 +33,24 @@ dependencies: tslib "^1.7.1" -"@angular/cdk@5.0.0-rc.2": - version "5.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@angular/cdk/-/cdk-5.0.0-rc.2.tgz#65a76381a0481e92990af4a105cd3bcbc53ee2af" +"@angular/cdk@^5.0.0": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@angular/cdk/-/cdk-5.0.4.tgz#f76a268e404f41aff0e908b21e7de9a5dfc07150" dependencies: tslib "^1.7.1" -"@angular/cli@1.5.5": - version "1.5.5" - resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-1.5.5.tgz#400ef304d88b13a82a72a4c4c42e2b53a0db04fd" +"@angular/cli@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-1.6.0.tgz#eba521f6a8e4c2db628300baddbc4da13ca96998" dependencies: - "@angular-devkit/build-optimizer" "~0.0.34" - "@angular-devkit/schematics" "~0.0.38" + "@angular-devkit/build-optimizer" "~0.0.35" + "@angular-devkit/schematics" "~0.0.40" "@ngtools/json-schema" "1.1.0" - "@ngtools/webpack" "1.8.5" - "@schematics/angular" "~0.1.8" + "@ngtools/webpack" "1.9.0" + "@schematics/angular" "~0.1.10" autoprefixer "^6.5.3" chalk "~2.2.0" - circular-dependency-plugin "^3.0.0" + circular-dependency-plugin "^4.2.1" common-tags "^1.3.1" copy-webpack-plugin "^4.1.1" core-object "^3.1.0" @@ -58,7 +59,7 @@ denodeify "^1.2.1" ember-cli-string-utils "^1.0.0" exports-loader "^0.6.3" - extract-text-webpack-plugin "3.0.0" + extract-text-webpack-plugin "^3.0.2" file-loader "^1.1.5" fs-extra "^4.0.0" glob "^7.0.3" @@ -89,10 +90,10 @@ style-loader "^0.13.1" stylus "^0.54.5" stylus-loader "^3.0.1" - uglifyjs-webpack-plugin "1.0.0" + uglifyjs-webpack-plugin "~1.1.2" url-loader "^0.6.2" - webpack "~3.8.1" - webpack-concat-plugin "1.4.0" + webpack "~3.10.0" + webpack-concat-plugin "^1.4.2" webpack-dev-middleware "~1.12.0" webpack-dev-server "~2.9.3" webpack-merge "^4.1.0" @@ -151,9 +152,9 @@ version "5.0.1" resolved "https://registry.yarnpkg.com/@angular/language-service/-/language-service-5.0.1.tgz#869e09dbd6e3d95c117c062d21dd1fd920ad44d6" -"@angular/material@5.0.0-rc.2": - version "5.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@angular/material/-/material-5.0.0-rc.2.tgz#c96bb3295787aa84aa3788d776e15611f77a70ed" +"@angular/material@^5.0.0": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@angular/material/-/material-5.0.4.tgz#8efb2fb12023711dbdaac5dc7b588096b40b0f64" dependencies: tslib "^1.7.1" @@ -187,9 +188,9 @@ version "1.1.0" resolved "https://registry.yarnpkg.com/@ngtools/json-schema/-/json-schema-1.1.0.tgz#c3a0c544d62392acc2813a42c8a0dc6f58f86922" -"@ngtools/webpack@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-1.8.5.tgz#f35b646f58db1d4ac5938031051a0f9187d91961" +"@ngtools/webpack@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-1.9.0.tgz#ef395c45be2de9beb93a2b9f5f171d28c344eb10" dependencies: chalk "~2.2.0" enhanced-resolve "^3.1.0" @@ -203,12 +204,16 @@ version "9.0.1" resolved "https://registry.yarnpkg.com/@ngx-translate/core/-/core-9.0.1.tgz#000f2d863c4c94c818e1416ef43cca2c5c0c5848" -"@schematics/angular@~0.1.8": - version "0.1.9" - resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-0.1.9.tgz#f4bd5da3da0e9414db7ee2a967a4789959c47a24" +"@schematics/angular@~0.1.10": + version "0.1.11" + resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-0.1.11.tgz#b5f15320bbb60969d66c76a8ef6545058ac81ece" dependencies: "@angular-devkit/core" "0.0.22" +"@schematics/schematics@0.0.11": + version "0.0.11" + resolved "https://registry.yarnpkg.com/@schematics/schematics/-/schematics-0.0.11.tgz#c8f70f270ed38f29b2873248126fd59abd635862" + "@types/d3-array@*": version "1.2.1" resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-1.2.1.tgz#e489605208d46a1c9d980d2e5772fa9c75d9ec65" @@ -459,6 +464,10 @@ ajv-keywords@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.0.tgz#a296e17f7bfae7c1ce4f7e0de53d29cb32162df0" +ajv-keywords@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" + ajv@^4.9.1: version "4.11.8" resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" @@ -988,9 +997,9 @@ bytes@2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.5.0.tgz#4c9423ea2d252c270c41b2bdefeff9bb6b62c06a" -cacache@^10.0.0: - version "10.0.1" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-10.0.1.tgz#3e05f6e616117d9b54665b1b20c8aeb93ea5d36f" +cacache@^10.0.1: + version "10.0.2" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-10.0.2.tgz#105a93a162bbedf3a25da42e1939ed99ffb145f8" dependencies: bluebird "^3.5.0" chownr "^1.0.1" @@ -1155,9 +1164,9 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: inherits "^2.0.1" safe-buffer "^5.0.1" -circular-dependency-plugin@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/circular-dependency-plugin/-/circular-dependency-plugin-3.0.0.tgz#9b68692e35b0e3510998d0164b6ae5011bea5760" +circular-dependency-plugin@^4.2.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/circular-dependency-plugin/-/circular-dependency-plugin-4.3.0.tgz#2a12824e584546e1aeea5865b7bf234a11c4a695" clap@^1.0.9: version "1.2.0" @@ -1289,6 +1298,10 @@ commander@2, commander@2.11.x, commander@^2.9.0, commander@~2.11.0: version "2.11.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" +commander@~2.12.1: + version "2.12.2" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.12.2.tgz#0f5946c427ed9ec0d91a46bb9def53e54650e555" + common-tags@^1.3.1: version "1.4.0" resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.4.0.tgz#1187be4f3d4cf0c0427d43f74eef1f73501614c0" @@ -2482,9 +2495,9 @@ extglob@^0.3.1: dependencies: is-extglob "^1.0.0" -extract-text-webpack-plugin@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.0.tgz#90caa7907bc449f335005e3ac7532b41b00de612" +extract-text-webpack-plugin@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.2.tgz#5f043eaa02f9750a9258b78c0a6e0dc1408fb2f7" dependencies: async "^2.4.1" loader-utils "^1.1.0" @@ -4933,12 +4946,6 @@ querystringify@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-1.0.0.tgz#6286242112c5b712fa654e526652bf6a13ff05cb" -queueing-subject@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/queueing-subject/-/queueing-subject-0.1.1.tgz#43f857b2b263276ff418cdd865b7d78d5d641d9d" - dependencies: - rxjs "^5.0.1" - randomatic@^1.1.3: version "1.1.7" resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" @@ -5226,12 +5233,6 @@ rxjs-websockets@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/rxjs-websockets/-/rxjs-websockets-4.0.0.tgz#a8d06c74b8629a9f9d56450eda5c3177542c80f4" -rxjs@^5.0.1: - version "5.4.3" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.4.3.tgz#0758cddee6033d68e0fd53676f0f3596ce3d483f" - dependencies: - symbol-observable "^1.0.1" - rxjs@^5.5.2: version "5.5.2" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.2.tgz#28d403f0071121967f18ad665563255d54236ac3" @@ -5285,6 +5286,13 @@ schema-utils@^0.3.0: dependencies: ajv "^5.0.0" +schema-utils@^0.4.2: + version "0.4.3" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.3.tgz#e2a594d3395834d5e15da22b48be13517859458e" + dependencies: + ajv "^5.0.0" + ajv-keywords "^2.1.0" + scss-tokenizer@^0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1" @@ -5361,6 +5369,10 @@ send@0.15.4: range-parser "~1.2.0" statuses "~1.3.1" +serialize-javascript@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.4.0.tgz#7c958514db6ac2443a8abc062dc9f7886a7f6005" + serve-index@^1.7.2: version "1.9.0" resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.0.tgz#d2b280fc560d616ee81b48bf0fa82abed2485ce7" @@ -5967,11 +5979,11 @@ typescript@~2.6.1: version "2.6.2" resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.6.2.tgz#3c5b6fd7f6de0914269027f03c0946758f7673a4" -uglify-es@^3.1.3: - version "3.1.9" - resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.1.9.tgz#6c82df628ac9eb7af9c61fd70c744a084abe6161" +uglify-es@^3.3.4: + version "3.3.5" + resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.5.tgz#cf7e695da81999f85196b15e2978862f13212f88" dependencies: - commander "~2.11.0" + commander "~2.12.1" source-map "~0.6.1" uglify-js@3.0.x: @@ -5994,18 +6006,6 @@ uglify-to-browserify@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" -uglifyjs-webpack-plugin@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.0.0.tgz#1c58b5db1ed043e024aef66f8ade25e148206264" - dependencies: - cacache "^10.0.0" - find-cache-dir "^1.0.0" - schema-utils "^0.3.0" - source-map "^0.5.6" - uglify-es "^3.1.3" - webpack-sources "^1.0.1" - worker-farm "^1.4.1" - uglifyjs-webpack-plugin@^0.4.6: version "0.4.6" resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz#b951f4abb6bd617e66f63eb891498e391763e309" @@ -6014,6 +6014,19 @@ uglifyjs-webpack-plugin@^0.4.6: uglify-js "^2.8.29" webpack-sources "^1.0.1" +uglifyjs-webpack-plugin@~1.1.2: + version "1.1.6" + resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.1.6.tgz#f4ba8449edcf17835c18ba6ae99b9d610857fb19" + dependencies: + cacache "^10.0.1" + find-cache-dir "^1.0.0" + schema-utils "^0.4.2" + serialize-javascript "^1.4.0" + source-map "^0.6.1" + uglify-es "^3.3.4" + webpack-sources "^1.1.0" + worker-farm "^1.5.2" + uid-number@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" @@ -6214,9 +6227,9 @@ webdriver-manager@^12.0.6: semver "^5.3.0" xml2js "^0.4.17" -webpack-concat-plugin@1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/webpack-concat-plugin/-/webpack-concat-plugin-1.4.0.tgz#a6eb3f0082d03c79d8ee2f1518c7f48e44ee12c5" +webpack-concat-plugin@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/webpack-concat-plugin/-/webpack-concat-plugin-1.4.2.tgz#b60bbb626ce5001911809d6e2329fa32f4978a88" dependencies: md5 "^2.2.1" uglify-js "^2.8.29" @@ -6283,15 +6296,22 @@ webpack-sources@^1.0.0, webpack-sources@^1.0.1: source-list-map "^2.0.0" source-map "~0.5.3" +webpack-sources@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54" + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + webpack-subresource-integrity@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/webpack-subresource-integrity/-/webpack-subresource-integrity-1.0.1.tgz#1fc09d46497da66e46743a2a51d2cc385b9cb0ed" dependencies: webpack-core "^0.6.8" -webpack@~3.8.1: - version "3.8.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.8.1.tgz#b16968a81100abe61608b0153c9159ef8bb2bd83" +webpack@~3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.10.0.tgz#5291b875078cf2abf42bdd23afe3f8f96c17d725" dependencies: acorn "^5.0.0" acorn-dynamic-import "^2.0.0" @@ -6366,7 +6386,7 @@ wordwrap@~0.0.2: version "0.0.3" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" -worker-farm@^1.4.1: +worker-farm@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.5.2.tgz#32b312e5dc3d5d45d79ef44acc2587491cd729ae" dependencies: From e623c2b6b0d13670ea04f4421fed25c68774f2cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Ro=C3=9Fmann?= Date: Thu, 11 Jan 2018 10:06:03 +0100 Subject: [PATCH 35/55] remove reactivePower setpoint use CosPhiController instead --- .../powerramp/PowerRampController.java | 214 +++++++++--------- 1 file changed, 104 insertions(+), 110 deletions(-) diff --git a/edge/src/io/openems/impl/controller/symmetric/powerramp/PowerRampController.java b/edge/src/io/openems/impl/controller/symmetric/powerramp/PowerRampController.java index 318cbccb27d..0c679b513fe 100644 --- a/edge/src/io/openems/impl/controller/symmetric/powerramp/PowerRampController.java +++ b/edge/src/io/openems/impl/controller/symmetric/powerramp/PowerRampController.java @@ -1,110 +1,104 @@ -/******************************************************************************* - * 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.symmetric.powerramp; - -import java.util.List; - -import io.openems.api.channel.ConfigChannel; -import io.openems.api.controller.Controller; -import io.openems.api.device.nature.ess.EssNature; -import io.openems.api.doc.ChannelInfo; -import io.openems.api.doc.ThingInfo; -import io.openems.api.exception.InvalidValueException; -import io.openems.core.utilities.ControllerUtils; -import io.openems.core.utilities.SymmetricPower; - -@ThingInfo(title = "Power ramp (Symmetric)", description = "Follows a power ramp. For symmetric Ess.") -public class PowerRampController extends Controller { - - /* - * Constructors - */ - public PowerRampController() { - super(); - } - - public PowerRampController(String thingId) { - super(thingId); - } - - /* - * Config - */ - @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class, isArray = true) - public ConfigChannel> esss = new ConfigChannel>("esss", this); - - @ChannelInfo(title = "Max-ActivePower", description = "The limit where the powerRamp stops. (pos/neg)", type = Integer.class) - public ConfigChannel pMax = new ConfigChannel("pMax", this); - - @ChannelInfo(title = "Cos-Phi", description = "The cos-phi to hold.", type = Double.class) - public ConfigChannel cosPhi = new ConfigChannel("cosPhi", this); - - @ChannelInfo(title = "Step", description = "Step to increase power.", type = Integer.class) - public ConfigChannel pStep = new ConfigChannel("pStep", this); - - @ChannelInfo(title = "Step-Wait", description = "Wait till next step in milliseconds.", type = Integer.class) - public ConfigChannel sleep = new ConfigChannel<>("sleep", this); - - /* - * Fields - */ - private long lastPower; - private long lastSet; - - /* - * Methods - */ - @Override - public void run() { - try { - for (Ess ess : esss.value()) { - try { - if (ess.gridMode.labelOptional().isPresent() - && ess.gridMode.labelOptional().get().equals(EssNature.OFF_GRID)) { - lastPower = 0; - } - SymmetricPower power = ess.power; - if (lastSet + sleep.value() < System.currentTimeMillis()) { - if (Math.abs(lastPower + pStep.value()) <= Math.abs(pMax.value())) { - power.setActivePower(lastPower + pStep.value()); - } else { - power.setActivePower(pMax.value()); - } - lastSet = System.currentTimeMillis(); - } else { - power.setActivePower(lastPower); - } - power.setReactivePower( - ControllerUtils.calculateReactivePower(power.getActivePower(), cosPhi.value())); - power.writePower(); - lastPower = power.getActivePower(); - log.info("Set ActivePower [" + power.getActivePower() + "] Set ReactivePower [" - + power.getReactivePower() + "]"); - } catch (InvalidValueException e) { - log.error("Failed to write fixed P/Q value for Ess " + ess.id, e); - } - } - } catch (InvalidValueException e) { - log.error("No ess found.", e); - } - } - -} +/******************************************************************************* + * 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.symmetric.powerramp; + +import java.util.List; + +import io.openems.api.channel.ConfigChannel; +import io.openems.api.controller.Controller; +import io.openems.api.device.nature.ess.EssNature; +import io.openems.api.doc.ChannelInfo; +import io.openems.api.doc.ThingInfo; +import io.openems.api.exception.InvalidValueException; +import io.openems.core.utilities.SymmetricPower; + +@ThingInfo(title = "Power ramp (Symmetric)", description = "Follows a power ramp. For symmetric Ess.") +public class PowerRampController extends Controller { + + /* + * Constructors + */ + public PowerRampController() { + super(); + } + + public PowerRampController(String thingId) { + super(thingId); + } + + /* + * Config + */ + @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class, isArray = true) + public ConfigChannel> esss = new ConfigChannel>("esss", this); + + @ChannelInfo(title = "Max-ActivePower", description = "The limit where the powerRamp stops. (pos/neg)", type = Integer.class) + public ConfigChannel pMax = new ConfigChannel("pMax", this); + + @ChannelInfo(title = "Step", description = "Step to increase power.", type = Integer.class) + public ConfigChannel pStep = new ConfigChannel("pStep", this); + + @ChannelInfo(title = "Step-Wait", description = "Wait till next step in milliseconds.", type = Integer.class) + public ConfigChannel sleep = new ConfigChannel<>("sleep", this); + + /* + * Fields + */ + private long lastPower; + private long lastSet; + + /* + * Methods + */ + @Override + public void run() { + try { + for (Ess ess : esss.value()) { + try { + if (ess.gridMode.labelOptional().isPresent() + && ess.gridMode.labelOptional().get().equals(EssNature.OFF_GRID)) { + lastPower = 0; + } + SymmetricPower power = ess.power; + if (lastSet + sleep.value() < System.currentTimeMillis()) { + if (Math.abs(lastPower + pStep.value()) <= Math.abs(pMax.value())) { + power.setActivePower(lastPower + pStep.value()); + } else { + power.setActivePower(pMax.value()); + } + lastSet = System.currentTimeMillis(); + } else { + power.setActivePower(lastPower); + } + power.writePower(); + lastPower = power.getActivePower(); + log.info("Set ActivePower [" + power.getActivePower() + "] Set ReactivePower [" + + power.getReactivePower() + "]"); + } catch (InvalidValueException e) { + log.error("Failed to write fixed P/Q value for Ess " + ess.id, e); + } + } + } catch (InvalidValueException e) { + log.error("No ess found.", e); + } + } + +} From 2793a6ac0a590f611ab59fcb0c1ae08afd8649e0 Mon Sep 17 00:00:00 2001 From: "hueseyin.sahutoglu" Date: Wed, 31 Jan 2018 13:57:08 +0100 Subject: [PATCH 36/55] Error Handling for Commercial, Mini, MIniReadOnly, Refu, Byd, CellVoltages for commercial --- .../impl/device/byd/Bem125ktla01Ess.java | 49 +- .../openems/impl/device/byd/WarningEss.java | 22 + .../impl/device/commercial/FaultCharger.java | 88 ++ .../impl/device/commercial/FaultEss.java | 35 + .../commercial/FeneconCommercialCharger.java | 1359 +++++++++-------- .../commercial/FeneconCommercialEss.java | 1213 +++++++++++++-- .../impl/device/commercial/Warning.java | 19 - .../device/commercial/WarningCharger.java | 57 + .../impl/device/commercial/WarningEss.java | 29 + .../io/openems/impl/device/mini/FaultEss.java | 28 + .../impl/device/mini/FeneconMiniEss.java | 160 +- .../openems/impl/device/mini/WarningEss.java | 21 + .../impl/device/minireadonly/FaultEss.java | 27 + .../device/minireadonly/FeneconMiniEss.java | 185 ++- .../impl/device/minireadonly/WarningEss.java | 38 + .../io/openems/impl/device/refu/FaultEss.java | 34 + .../io/openems/impl/device/refu/RefuEss.java | 418 ++--- .../openems/impl/device/refu/WarningEss.java | 29 + 18 files changed, 2707 insertions(+), 1104 deletions(-) create mode 100644 edge/src/io/openems/impl/device/byd/WarningEss.java create mode 100644 edge/src/io/openems/impl/device/commercial/FaultCharger.java create mode 100644 edge/src/io/openems/impl/device/commercial/FaultEss.java delete mode 100644 edge/src/io/openems/impl/device/commercial/Warning.java create mode 100644 edge/src/io/openems/impl/device/commercial/WarningCharger.java create mode 100644 edge/src/io/openems/impl/device/commercial/WarningEss.java create mode 100644 edge/src/io/openems/impl/device/mini/FaultEss.java create mode 100644 edge/src/io/openems/impl/device/mini/WarningEss.java create mode 100644 edge/src/io/openems/impl/device/minireadonly/FaultEss.java create mode 100644 edge/src/io/openems/impl/device/minireadonly/WarningEss.java create mode 100644 edge/src/io/openems/impl/device/refu/FaultEss.java create mode 100644 edge/src/io/openems/impl/device/refu/WarningEss.java diff --git a/edge/src/io/openems/impl/device/byd/Bem125ktla01Ess.java b/edge/src/io/openems/impl/device/byd/Bem125ktla01Ess.java index d696097c5eb..1a0f68c57cb 100644 --- a/edge/src/io/openems/impl/device/byd/Bem125ktla01Ess.java +++ b/edge/src/io/openems/impl/device/byd/Bem125ktla01Ess.java @@ -175,12 +175,19 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { return new ModbusProtocol( // new ModbusRegisterRange(0x0100, // new UnsignedWordElement(0x100, // - sysAlarmInfo = new ModbusReadLongChannel("SysAlarmInfo", this)// - .label(1, "Warning State")// - .label(2, "Protection State")// - .label(4, "Derating State")// - .label(8, "Charge Forbidden")// - .label(16, "Discharge Forbidden")), + new ModbusBitWrappingChannel("SysAlarmInfo", this, this.thingState)// + .warningBit(0, WarningEss.WarningState)// + .warningBit(1, WarningEss.ProtectionState)// + .warningBit(2, WarningEss.DeratingState)// + .warningBit(3, WarningEss.ChargeForbidden)// + .warningBit(4, WarningEss.DischargeForbidden)// + ),// + // sysAlarmInfo = new ModbusReadLongChannel("SysAlarmInfo", this)// + // .label(1, "Warning State")// + // .label(2, "Protection State")// + // .label(4, "Derating State")// + // .label(8, "Charge Forbidden")// + // .label(16, "Discharge Forbidden")), new UnsignedWordElement(0x101, // sysWorkStatus = new ModbusReadLongChannel("SysWorkStatus", this)// .label(1, "Initial") // @@ -199,18 +206,28 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { new ModbusRegisterRange(0x0110, // new UnsignedWordElement(0x110, // new ModbusBitWrappingChannel("SysAlarmInfo", this, thingState)// - .warningBit(1, Warning.Status_abnormal_of_AC_surge_protector) // Status abnormal of AC surge protector - .warningBit(2, Warning.Close_of_control_switch) // Close of control switch - .warningBit(3, Warning.Emergency_stop) // Emergency stop - .warningBit(5, Warning.Status_abnormal_of_frog_detector) // Status_abnormal_of_frog_detector - .warningBit(6, Warning.Serious_leakage) // Serious_leakage - .warningBit(7, Warning.Normal_leakage)), // Normal_leakage + .warningBit(1, WarningEss.StatusAbnormalOfACSurgeProtector) // Status abnormal of AC surge protector + .warningBit(2, WarningEss.CloseOfControlSwitch) // Close of control switch + .warningBit(3, WarningEss.EmergencyStop) // Emergency stop + .warningBit(5, WarningEss.StatusAbnormalOfFrogDetector) // Status_abnormal_of_frog_detector + .warningBit(6, WarningEss.SeriousLeakage) // Serious_leakage + .warningBit(7, WarningEss.NormalLeakage)), // Normal_leakage + // .warningBit(1, Warning.Status_abnormal_of_AC_surge_protector) // Status abnormal of AC surge protector + // .warningBit(2, Warning.Close_of_control_switch) // Close of control switch + // .warningBit(3, Warning.Emergency_stop) // Emergency stop + // .warningBit(5, Warning.Status_abnormal_of_frog_detector) // Status_abnormal_of_frog_detector + // .warningBit(6, Warning.Serious_leakage) // Serious_leakage + // .warningBit(7, Warning.Normal_leakage)), // Normal_leakage new UnsignedWordElement(0x111, // new ModbusBitWrappingChannel("SysAlarmInfo2", this, thingState)// - .warningBit(0, Warning.Failure_of_temperature_sensor_in_control_cabinet) // Failure of temperature sensor in control cabinet - .warningBit(9, Warning.Failure_of_humidity_sensor_in_control_cabinet) // Failure_of_humidity_sensor_in_control_cabinet - .warningBit(12, Warning.Failure_of_storage_device) // Failure_of_storage_device - .warningBit(13, Warning.Exceeding_of_humidity_in_control_cabinet)) // Exceeding_of_humidity_in_control_cabinet + .warningBit(0, WarningEss.FailureOfTemperatureSensorInControlCabinet) // Failure of temperature sensor in control cabinet + .warningBit(9, WarningEss.FailureOfHumiditySensorInControlCabinet) // Failure_of_humidity_sensor_in_control_cabinet + .warningBit(12,WarningEss.FailureOfStorageDevice) // Failure_of_storage_device + .warningBit(13,WarningEss.ExceedingOfHumidityInControlCabinet)) // Exceeding_of_humidity_in_control_cabinet + // .warningBit(0, Warning.Failure_of_temperature_sensor_in_control_cabinet) // Failure of temperature sensor in control cabinet + // .warningBit(9, Warning.Failure_of_humidity_sensor_in_control_cabinet) // Failure_of_humidity_sensor_in_control_cabinet + // .warningBit(12, Warning.Failure_of_storage_device) // Failure_of_storage_device + // .warningBit(13, Warning.Exceeding_of_humidity_in_control_cabinet)) // Exceeding_of_humidity_in_control_cabinet ), new ModbusRegisterRange(0x1300, new UnsignedWordElement(0x1300, // batteryStackVoltage = new ModbusReadLongChannel("BatteryStackVoltage", this).multiplier(2) .unit("mV")), diff --git a/edge/src/io/openems/impl/device/byd/WarningEss.java b/edge/src/io/openems/impl/device/byd/WarningEss.java new file mode 100644 index 00000000000..ec153c243d7 --- /dev/null +++ b/edge/src/io/openems/impl/device/byd/WarningEss.java @@ -0,0 +1,22 @@ +package io.openems.impl.device.byd; + +import io.openems.api.channel.thingstate.WarningEnum; + +public enum WarningEss implements WarningEnum { + + WarningState(0), ProtectionState(1), DeratingState(2), ChargeForbidden(3), DischargeForbidden(4), StatusAbnormalOfACSurgeProtector(5), + CloseOfControlSwitch(6), EmergencyStop(7), StatusAbnormalOfFrogDetector(8), SeriousLeakage(9), NormalLeakage(10), + FailureOfTemperatureSensorInControlCabinet(11), FailureOfHumiditySensorInControlCabinet(12), FailureOfStorageDevice(13), + ExceedingOfHumidityInControlCabinet(14); + + public final int value; + + private WarningEss(int value) { + this.value = value; + } + + @Override + public int getValue() { + return this.value; + } +} diff --git a/edge/src/io/openems/impl/device/commercial/FaultCharger.java b/edge/src/io/openems/impl/device/commercial/FaultCharger.java new file mode 100644 index 00000000000..f0f5b9aabb0 --- /dev/null +++ b/edge/src/io/openems/impl/device/commercial/FaultCharger.java @@ -0,0 +1,88 @@ +package io.openems.impl.device.commercial; + +import io.openems.api.channel.thingstate.FaultEnum; + +public enum FaultCharger implements FaultEnum{ + HighVoltageSideOfDCConverterUndervoltage(0), HighVoltageSideOfDCConverterOvervoltage(1), LowVoltageSideOfDCConverterUndervoltage(2), + LowVoltageSideOfDCConverterOvervoltage(3), HighVoltageSideOfDCConverterOvercurrentFault(4), LowVoltageSideOfDCConverterOvercurrentFault(5), DCConverterIGBTFault(6), DCConverterPrechargeUnmet(7), + BECUCommunicationDisconnected(8), DCConverterCommunicationDisconnected(9), CurrentConfigurationOverRange(10), TheBatteryRequestStop(11), OvercurrentRelayFault(12), LightningProtectionDeviceFault(13), + DCConverterPriamaryContactorDisconnectedAbnormally(14), DCDisconnectedAbnormallyOnLowVoltageSideOfDCConvetor(15), DCConvetorEEPROMAbnormity1(16), DCConvetorEEPROMAbnormity1Second(17), + EDCConvetorEEPROMAbnormity1(18), DCConvertorGeneralOverload(19), DCShortCircuit(20), PeakPulseCurrentProtection(21), DCDisconnectAbnormallyOnHighVoltageSideOfDCConvetor(22), EffectivePulseValueOverhigh(23), + DCConverteSevereOverload(24), DCBreakerDisconnectAbnormallyOnHighVoltageSideOfDCConvetor(25), DCBreakerDisconnectAbnormallyOnLowVoltageSideOfDCConvetor(26), DCConvetorPrechargeContactorCloseFailed(27), + DCConvetorMainContactorCloseFailed(28), ACContactorStateAbnormityOfDCConvetor(29), DCConvetorEmergencyStop(30), DCConverterChargingGunDisconnected(31), DCCurrentAbnormityBeforeDCConvetorWork(32), FuSeDisconnected(33), + DCConverterHardwareCurrentOrVoltageFault(34), DCConverterCrystalOscillatorCircuitInvalidation(35), DCConverterResetCircuitInvalidation(36), DCConverterSamplingCircuitInvalidation(37), + DCConverterDigitalIOCircuitInvalidation(38), DCConverterPWMCircuitInvalidation(39), DCConverterX5045CircuitInvalidation(40), DCConverterCANCircuitInvalidation(41), DCConverterSoftwareANDHardwareProtectionCircuitInvalidation(42), + DCConverterPowerCircuitInvalidation(43), DCConverterCPUInvalidation(44), DCConverterTINT0InterruptInvalidation(45), DCConverterADCInterruptInvalidation(46), DCConverterCAPITN4InterruptInvalidation(47), + DCConverterCAPINT6InterruptInvalidation(48), DCConverterT3PINTinterruptInvalidation(49), DCConverterT4PINTinterruptInvalidation(50), DCConverterPDPINTAInterruptInvalidation(51), DCConverterT1PINTInterruptInvalidation(52), + DCConverterRESVInterruptInvalidation(53), DCConverter100usTaskInvalidation(54), DCConverterClockInvalidation(55), DCConverterEMSMemoryInvalidation(56), DCConverterExteriorCommunicationInvalidation(57), + DCConverterIOInterfaceInvalidation(58), DCConverterInputVoltageBoundFault(59), DCConverterOutterVoltageBoundFault(60), DCConverterOutputVoltageBoundFault(61), DCConverterInductCurrentBoundFault(62), + DCConverterInputCurrentBoundFault(63), DCConverterOutputCurrentBoundFault(64), DCReactorOverTemperature(65), DCIGBTOverTemperature(66), DCConverterChanel3OverTemperature(67), DCConverterChanel4OverTemperature(68), + DCConverterChanel5OverTemperature(69), DCConverterChanel6OverTemperature(70), DCConverterChanel7OverTemperature(71), DCConverterChanel8OverTemperature(72), DCReactorTemperatureSamplingInvalidation(73), DCIGBTTemperatureSamplingInvalidation(74), + DCConverterChanel3TemperatureSamplingInvalidation(75), DCConverterChanel4TemperatureSamplingInvalidation(76), DCConverterChanel5TemperatureSamplingInvalidation(77), DCConverterChanel6TemperatureSamplingInvalidation(78), + DCConverterChanel7TemperatureSamplingInvalidation(79), DCConverterChanel8TemperatureSamplingInvalidation(80), DCConverterInductanceCurrentSamplingInvalidation(81), CurrentSamplingInvalidationOnTheLowVoltageSideOfDCConverter(82), + VoltageSamplingInvalidationOnTheLowVoltageSideOfDCConverter(83), InsulationInspectionFault(84), NegContactorCloseUnsuccessly(85), NegContactorCutWhenRunning(86), BmsDCDC1HighVoltageSideOfDCConverterUndervoltage(87), + BmsDCDC1HighVoltageSideOfDCConverterOvervoltage(88), BmsDCDC1LowVoltageSideOfDCConverterUndervoltage(89), BmsDCDC1LowVoltageSideOfDCConverterOvervoltage(90), BmsDCDC1HighVoltageSideOfDCConverterOvercurrentFault(91), + BmsDCDC1LowVoltageSideOfDCConverterOvercurrentFault(92), BmsDCDC1DCConverterIGBTFault(93), BmsDCDC1DCConverterPrechargeUnmet(94), BmsDCDC1BECUCommunicationDisconnected(95), BmsDCDC1DCConverterCommunicationDisconnected(96), + BmsDCDC1CurrentConfigurationOverRange(97), BmsDCDC1TheBatteryRequestStop(98), BmsDCDC1OvercurrentRelayFault(99), BmsDCDC1LightningProtectionDeviceFault(100), BmsDCDC1DCConverterPriamaryContactorDisconnectedAbnormally(101), + BmsDCDC1DCDisconnectedAbnormallyOnLowVoltageSideOfDCConvetor(102), BmsDCDC1DCConvetorEEPROMAbnormity1(103), BmsDCDC1DCConvetorEEPROMAbnormity1Second(104), BmsDCDC1EDCConvetorEEPROMAbnormity1(105), BsmDCDC1DCConvertorGeneralOverload(106), + BsmDCDC1DCShortCircuit(107), BsmDCDC1PeakPulseCurrentProtection(108), BsmDCDC1DCDisconnectAbnormallyOnHighVoltageSideOfDCConvetor(109), BsmDCDC1EffectivePulseValueOverhigh(110), BsmDCDC1DCConverteSevereOverload(111), + BsmDCDC1DCBreakerDisconnectAbnormallyOnHighVoltageSideOfDCConvetor(112), BsmDCDC1DCBreakerDisconnectAbnormallyOnLowVoltageSideOfDCConvetor(113), BsmDCDC1DCConvetorPrechargeContactorCloseFailed(114), BsmDCDC1DCConvetorMainContactorCloseFailed(115), + BsmDCDC1ACContactorStateAbnormityOfDCConvetor(116), BsmDCDC1DCConvetorEmergencyStop(117), BsmDCDC1DCConverterChargingGunDisconnected(118), BsmDCDC1DCCurrentAbnormityBeforeDCConvetorWork(119), BsmDCDC1FuSeDisconnected(120), + BsmDCDC1DCConverterHardwareCurrentOrVoltageFault(121), BmsDCDC1DCConverterCrystalOscillatorCircuitInvalidation(122), BmsDCDC1DCConverterResetCircuitInvalidation(123), BmsDCDC1DCConverterSamplingCircuitInvalidation(124), + BmsDCDC1DCConverterDigitalIOCircuitInvalidation(125), BmsDCDC1DCConverterPWMCircuitInvalidation(126), BmsDCDC1DCConverterX5045CircuitInvalidation(127), BmsDCDC1DCConverterCANCircuitInvalidation(128), + BmsDCDC1DCConverterSoftwareANDHardwareProtectionCircuitInvalidation(129), BmsDCDC1DCConverterPowerCircuitInvalidation(130), BmsDCDC1DCConverterCPUInvalidation(131), BmsDCDC1DCConverterT1PINTInterruptInvalidation(132), + BmsDCDC1DCConverterADCInterruptInvalidation(133), BmsDCDC1DCConverterCAPITN4InterruptInvalidation(134), BmsDCDC1DCConverterCAPINT6InterruptInvalidation(135), BmsDCDC1DCConverterT3PINTinterruptInvalidation(136), + BmsDCDC1DCConverterT4PINTinterruptInvalidation(137), BmsDCDC1DCConverterPDPINTAInterruptInvalidation(138), BmsDCDC1DCConverterT1PINTInterruptInvalidationSecond(139), BmsDCDC1DCConverterRESVInterruptInvalidation(140), + BmsDCDC1DCConverter100usTaskInvalidation(141), BmsDCDC1DCConverterClockInvalidation(142), BmsDCDC1DCConverterEMSMemoryInvalidation(143), BmsDCDC1DCConverterExteriorCommunicationInvalidation(144), BmsDCDC1DCConverterIOInterfaceInvalidation(145), + BmsDCDC1DCConverterInputVoltageBoundFault(146), BmsDCDC1DCConverterOutterVoltageBoundFault(147), BmsDCDC1DCConverterOutputVoltageBoundFault(148), BmsDCDC1DCConverterInductCurrentBoundFault(149), BmsDCDC1DCConverterInputCurrentBoundFault(150), + BmsDCDC1DCConverterOutputCurrentBoundFault(151), BmsDCDC1DCReactorOverTemperature(152), BmsDCDC1DCIGBTOverTemperature(153), BmsDCDC1DCConverterChanel3OverTemperature(154), BmsDCDC1DCConverterChanel4OverTemperature(155), + BmsDCDC1DCConverterChanel5OverTemperature(156), BmsDCDC1DCConverterChanel6OverTemperature(157), BmsDCDC1DCConverterChanel7OverTemperature(158), BmsDCDC1DCConverterChanel8OverTemperature(159), BmsDCDC1DCReactorTemperatureSamplingInvalidation(160), + BmsDCDC1DCIGBTTemperatureSamplingInvalidation(161), BmsDCDC1DCConverterChanel3TemperatureSamplingInvalidation(162), BmsDCDC1DCConverterChanel4TemperatureSamplingInvalidation(163), BmsDCDC1DCConverterChanel5TemperatureSamplingInvalidation(164), + BmsDCDC1DCConverterChanel6TemperatureSamplingInvalidation(165), BmsDCDC1DCConverterChanel7TemperatureSamplingInvalidation(166), BmsDCDC1DCConverterChanel8TemperatureSamplingInvalidation(167), BmsDCDC1DCConverterInductanceCurrentSamplingInvalidation(168), + BmsDCDC1CurrentSamplingInvalidationOnTheLowVoltageSideOfDCConverter(169), BmsDCDC1VoltageSamplingInvalidationOnTheLowVoltageSideOfDCConverter(170), BmsDCDC1InsulationInspectionFault(171), BmsDCDC1NegContactorCloseUnsuccessly(172), + BmsDCDC1NegContactorCutWhenRunning(173), PvDCDCHighVoltageSideOfDCConverterUndervoltage(174), PvDCDCHighVoltageSideOfDCConverterOvervoltage(175), PvDCDCLowVoltageSideOfDCConverterUndervoltage(176), PvDCDCLowVoltageSideOfDCConverterOvervoltage(177), + PvDCDCHighVoltageSideOfDCConverterOvercurrentFault(178), PvDCDCLowVoltageSideOfDCConverterOvercurrentFault(179), PvDCDCDCConverterIGBTFault(180), PvDCDCDCConverterPrechargeUnmet(181), PvDCDCBECUCommunicationDisconnected(182), + PvDCDCDCConverterCommunicationDisconnected(183), PvDCDCCurrentConfigurationOverRange(184), PvDCDCTheBatteryRequestStop(185), PvDCDCOvercurrentRelayFault(186), PvDCDCLightningProtectionDeviceFault(187), + PvDCDCDCConverterPriamaryContactorDisconnectedAbnormally(188), PvDCDCDCDisconnectedAbnormallyOnLowVoltageSideOfDCConvetor(189), PvDCDCDCConvetorEEPROMAbnormity1(190), PvDCDCDCConvetorEEPROMAbnormity1Second(191), PvDCDCEDCConvetorEEPROMAbnormity1(192), + PvDCDCDCConvertorGeneralOverload(193), PvDCDCDCShortCircuit(194), PvDCDCPeakPulseCurrentProtection(195), PvDCDCDCDisconnectAbnormallyOnHighVoltageSideOfDCConvetor(196), PvDCDCEffectivePulseValueOverhigh(197), PvDCDCDCConverteSevereOverload(198), + PvDCDCDCBreakerDisconnectAbnormallyOnHighVoltageSideOfDCConvetor(199), PvDCDCDCBreakerDisconnectAbnormallyOnLowVoltageSideOfDCConvetor(200), PvDCDCDCConvetorPrechargeContactorCloseFailed(201), PvDCDCDCConvetorMainContactorCloseFailed(202), + PvDCDCACContactorStateAbnormityOfDCConvetor(203), PvDCDCDCConvetorEmergencyStop(204), PvDCDCDCConverterChargingGunDisconnected(205), PvDCDCDCCurrentAbnormityBeforeDCConvetorWork(206), PvDCDCFuSeDisconnected(207), PvDCDCDCConverterHardwareCurrentOrVoltageFault(208), + PvDCConverterCrystalOscillatorCircuitInvalidation(209), PvDCConverterResetCircuitInvalidation(210), PvDCConverterSamplingCircuitInvalidation(211), PvDCConverterDigitalIOCircuitInvalidation(212), PvDCConverterPWMCircuitInvalidation(213), + PvDCConverterX5045CircuitInvalidation(214), PvDCConverterCANCircuitInvalidation(215), PvDCConverterSoftwareANDHardwareProtectionCircuitInvalidation(216), PvDCConverterPowerCircuitInvalidation(217), PvDCConverterCPUInvalidation(218), + PvDCConverterT1PINTInterruptInvalidation(219), PvDCConverterADCInterruptInvalidation(220), PvDCConverterCAPITN4InterruptInvalidation(221), PvDCConverterCAPINT6InterruptInvalidation(222), PvDCConverterT3PINTinterruptInvalidation(223), + PvDCConverterT4PINTinterruptInvalidation(224), PvDCConverterPDPINTAInterruptInvalidation(225), BvDCConverterT1PINTInterruptInvalidationSecond(226), PvDCConverterRESVInterruptInvalidation(227), PvDCConverter100usTaskInvalidation(228), + PvDCConverterClockInvalidation(229), PvDCConverterEMSMemoryInvalidation(230), PvDCConverterExteriorCommunicationInvalidation(231), PvDCConverterIOInterfaceInvalidation(232), PvDCConverterInputVoltageBoundFault(233), + PvDCConverterOutterVoltageBoundFault(234), PvDCConverterOutputVoltageBoundFault(235), PvDCConverterInductCurrentBoundFault(236), PvDCConverterInputCurrentBoundFault(237), PvDCConverterOutputCurrentBoundFault(238), PvDCDCDCReactorOverTemperature(239), + PvDCDCDCIGBTOverTemperature(240), PvDCDCDCConverterChanel3OverTemperature(241), PvDCDCDCConverterChanel4OverTemperature(242), PvDCDCDCConverterChanel5OverTemperature(243), PvDCDCDCConverterChanel6OverTemperature(244), + PvDCDCDCConverterChanel7OverTemperature(245), PvDCDCDCConverterChanel8OverTemperature(246), PvDCDCDCReactorTemperatureSamplingInvalidation(247), PvDCDCDCIGBTTemperatureSamplingInvalidation(248), PvDCDCDCConverterChanel3TemperatureSamplingInvalidation(249), + PvDCDCDCConverterChanel4TemperatureSamplingInvalidation(250), PvDCDCDCConverterChanel5TemperatureSamplingInvalidation(251), PvDCDCDCConverterChanel6TemperatureSamplingInvalidation(252), PvDCDCDCConverterChanel7TemperatureSamplingInvalidation(253), + PvDCDCDCConverterChanel8TemperatureSamplingInvalidation(254), PvDCDCDCConverterInductanceCurrentSamplingInvalidation(255), PvDCDCCurrentSamplingInvalidationOnTheLowVoltageSideOfDCConverter(256), PvDCDCVoltageSamplingInvalidationOnTheLowVoltageSideOfDCConverter(257), + PvDCDCInsulationInspectionFault(258), PvDCDCNegContactorCloseUnsuccessly(259), PvDCDCNegContactorCutWhenRunning(260), PvDCDC1HighVoltageSideOfDCConverterUndervoltage(261), PvDCDC1HighVoltageSideOfDCConverterOvervoltage(262), PvDCDC1LowVoltageSideOfDCConverterUndervoltage(263), + PvDCDC1LowVoltageSideOfDCConverterOvervoltage(264), PvDCDC1HighVoltageSideOfDCConverterOvercurrentFault(265), PvDCDC1LowVoltageSideOfDCConverterOvercurrentFault(266), PvDCDC1DCConverterIGBTFault(267), PvDCDC1DCConverterPrechargeUnmet(268), PvDCDC1BECUCommunicationDisconnected(269), + PvDCDC1DCConverterCommunicationDisconnected(270), PvDCDC1CurrentConfigurationOverRange(271), PvDCDC1TheBatteryRequestStop(272), PvDCDC1OvercurrentRelayFault(273), PvDCDC1LightningProtectionDeviceFault(274), PvDCDC1DCConverterPriamaryContactorDisconnectedAbnormally(275), + PvDCDC1DCDisconnectedAbnormallyOnLowVoltageSideOfDCConvetor(276), PvDCDC1DCConvetorEEPROMAbnormity1(277), PvDCDC1DCConvetorEEPROMAbnormity1Second(278), PvDCDC1EDCConvetorEEPROMAbnormity1(279), PvDCDC1DCConvertorGeneralOverload(280), PvDCDC1DCShortCircuit(281), + PvDCDC1PeakPulseCurrentProtection(282), PvDCDC1DCDisconnectAbnormallyOnHighVoltageSideOfDCConvetor(283), PvDCDC1EffectivePulseValueOverhigh(284), PvDCDC1DCConverteSevereOverload(285), PvDCDC1DCBreakerDisconnectAbnormallyOnHighVoltageSideOfDCConvetor(286), + PvDCDC1DCBreakerDisconnectAbnormallyOnLowVoltageSideOfDCConvetor(287), PvDCDC1DCConvetorPrechargeContactorCloseFailed(288), PvDCDC1DCConvetorMainContactorCloseFailed(289), PvDCDC1ACContactorStateAbnormityOfDCConvetor(290), PvDCDC1DCConvetorEmergencyStop(291), + PvDCDC1DCConverterChargingGunDisconnected(292), PvDCDC1DCCurrentAbnormityBeforeDCConvetorWork(293), PvDCDC1FuSeDisconnected(294), PvDCDC1DCConverterHardwareCurrentOrVoltageFault(295), PvDCDC1DCConverterCrystalOscillatorCircuitInvalidation(296), PvDCDC1DCConverterResetCircuitInvalidation(297), + PvDCDC1DCConverterSamplingCircuitInvalidation(298), PvDCDC1DCConverterDigitalIOCircuitInvalidation(299), PvDCDC1DCConverterPWMCircuitInvalidation(300), PvDCDC1DCConverterX5045CircuitInvalidation(301), PvDCDC1DCConverterCANCircuitInvalidation(302), + PvDCDC1DCConverterSoftwareANDHardwareProtectionCircuitInvalidation(303), PvDCDC1DCConverterPowerCircuitInvalidation(304), PvDCDC1DCConverterCPUInvalidation(305), PvDCDC1DCConverterT1PINTInterruptInvalidation(306), PvDCDC1DCConverterADCInterruptInvalidation(307), + PvDCDC1DCConverterCAPITN4InterruptInvalidation(308), PvDCDC1DCConverterCAPINT6InterruptInvalidation(309), PvDCDC1DCConverterT3PINTinterruptInvalidation(310), PvDCDC1DCConverterT4PINTinterruptInvalidation(311), PvDCDC1DCConverterPDPINTAInterruptInvalidation(312), + PvDCDC1DCConverterT1PINTInterruptInvalidationSecond(313), PvDCDC1DCConverterRESVInterruptInvalidation(314), PvDCDC1DCConverter100usTaskInvalidation(315), PvDCDC1DCConverterClockInvalidation(316), PvDCDC1DCConverterEMSMemoryInvalidation(317), + PvDCDC1DCConverterExteriorCommunicationInvalidation(318), PvDCDC1DCConverterIOInterfaceInvalidation(319), PvDCDC1DCConverterInputVoltageBoundFault(320), PvDCDC1DCConverterOutterVoltageBoundFault(321), PvDCDC1DCConverterOutputVoltageBoundFault(322), + PvDCDC1DCConverterInductCurrentBoundFault(323), PvDCDC1DCConverterInputCurrentBoundFault(324), PvDCDC1DCConverterOutputCurrentBoundFault(325), PvDCDC1DCReactorOverTemperature(326), PvDCDC1DCIGBTOverTemperature(327), PvDCDC1DCConverterChanel3OverTemperature(328), + PvDCDC1DCConverterChanel4OverTemperature(329), PvDCDC1DCConverterChanel5OverTemperature(330), PvDCDC1DCConverterChanel6OverTemperature(331), PvDCDC1DCConverterChanel7OverTemperature(332), PvDCDC1DCConverterChanel8OverTemperature(333), PvDCDC1DCReactorTemperatureSamplingInvalidation(334), + PvDCDC1DCIGBTTemperatureSamplingInvalidation(335), PvDCDC1DCConverterChanel3TemperatureSamplingInvalidation(336), PvDCDC1DCConverterChanel4TemperatureSamplingInvalidation(337), PvDCDC1DCConverterChanel5TemperatureSamplingInvalidation(338), PvDCDC1DCConverterChanel6TemperatureSamplingInvalidation(339), + PvDCDC1DCConverterChanel7TemperatureSamplingInvalidation(340), PvDCDC1DCConverterChanel8TemperatureSamplingInvalidation(341), PvDCDC1DCConverterInductanceCurrentSamplingInvalidation(342), PvDCDC1CurrentSamplingInvalidationOnTheLowVoltageSideOfDCConverter(343), + PvDCDC1VoltageSamplingInvalidationOnTheLowVoltageSideOfDCConverter(344), PvDCDC1InsulationInspectionFault(345), PvDCDC1NegContactorCloseUnsuccessly(346), PvDCDC1NegContactorCutWhenRunning(347); + + private final int value; + + private FaultCharger(int value) { + this.value = value; + } + + @Override + public int getValue() { + return this.value; + } +} diff --git a/edge/src/io/openems/impl/device/commercial/FaultEss.java b/edge/src/io/openems/impl/device/commercial/FaultEss.java new file mode 100644 index 00000000000..0e8e7f15c90 --- /dev/null +++ b/edge/src/io/openems/impl/device/commercial/FaultEss.java @@ -0,0 +1,35 @@ +package io.openems.impl.device.commercial; + +import io.openems.api.channel.thingstate.FaultEnum; + +public enum FaultEss implements FaultEnum { + + DCPrechargeContactorCloseUnsuccessfully(0), ACPrechargeContactorCloseUnsuccessfully(1), ACMainContactorCloseUnsuccessfully(2), DCElectricalBreaker1CloseUnsuccessfully(3), + DCMainContactorCloseUnsuccessfully(4), ACBreakerTrip(5), ACMainContactorOpenWhenRunning(6), DCMainContactorOpenWhenRunning(7), ACMainContactorOpenUnsuccessfully(8), + DCElectricalBreaker1OpenUnsuccessfully(9), DCMainContactorOpenUnsuccessfully(10), HardwarePDPFault(11), MasterStopSuddenly(12), DCShortCircuitProtection(13), DCOvervoltageProtection(14), + DCUndervoltageProtection(15), DCInverseNoConnectionProtection(16), DCDisconnectionProtection(17), CommutingVoltageAbnormityProtection(18), DCOvercurrentProtection(19), + Phase1PeakCurrentOverLimitProtection(20), Phase2PeakCurrentOverLimitProtection(21), Phase3PeakCurrentOverLimitProtection(22), Phase1GridVoltageSamplingInvalidation(23), + Phase2VirtualCurrentOverLimitProtection(24), Phase3VirtualCurrentOverLimitProtection(25), Phase1GridVoltageSamplingInvalidation2(26), Phase2ridVoltageSamplingInvalidation(27), + Phase3GridVoltageSamplingInvalidation(28), Phase1InvertVoltageSamplingInvalidation(29), Phase2InvertVoltageSamplingInvalidation(30), Phase3InvertVoltageSamplingInvalidation(31), + ACCurrentSamplingInvalidation(32), DCCurrentSamplingInvalidation(33), Phase1OvertemperatureProtection(34), Phase2OvertemperatureProtection(35), Phase3OvertemperatureProtection(36), + Phase1TemperatureSamplingInvalidation(37), Phase2TemperatureSamplingInvalidation(38), Phase3TemperatureSamplingInvalidation(39), Phase1PrechargeUnmetProtection(40), Phase2PrechargeUnmetProtection(41), + Phase3PrechargeUnmetProtection(42), UnadaptablePhaseSequenceErrorProtection(43), DSPProtection(44), Phase1GridVoltageSevereOvervoltageProtection(45),Phase1GridVoltageGeneralOvervoltageProtection(46), + Phase2GridVoltageSevereOvervoltageProtection(47), Phase2GridVoltageGeneralOvervoltageProtection(48), Phase3GridVoltageSevereOvervoltageProtection(49), Phase3GridVoltageGeneralOvervoltageProtection(50), + Phase1GridVoltageSevereUndervoltageProtection(51), Phase1GridVoltageGeneralUndervoltageProtection(52), Phase2GridVoltageSevereUndervoltageProtection(53), Phase2GridVoltageGeneralUndervoltageProtection(54), + Phase3GridVoltageSevereUndervoltageProtection(55), Phase3GridVoltageGeneralUndervoltageProtection(56), SevereOverfrequncyProtection(57), GeneralOverfrequncyProtection(58), SevereUnderfrequncyProtection(59), + GeneralsUnderfrequncyProtection(60), Phase1Gridloss(61), Phase2Gridloss(62), Phase3Gridloss(63), IslandingProtection(64), Phase1UnderVoltageRideThrough(65), Phase2UnderVoltageRideThrough(66), + Phase3UnderVoltageRideThrough(67), Phase1InverterVoltageSevereOvervoltageProtection(68), Phase1InverterVoltageGeneralOvervoltageProtection(69), Phase2InverterVoltageSevereOvervoltageProtection(70), + Phase2InverterVoltageGeneralOvervoltageProtection(71), Phase3InverterVoltageSevereOvervoltageProtection(72), Phase3InverterVoltageGeneralOvervoltageProtection(73), + InverterPeakVoltageHighProtectionCauseByACDisconnect(74); + + private final int value; + + private FaultEss(int value) { + this.value = value; + } + + @Override + public int getValue() { + return this.value; + } +} diff --git a/edge/src/io/openems/impl/device/commercial/FeneconCommercialCharger.java b/edge/src/io/openems/impl/device/commercial/FeneconCommercialCharger.java index 2df39e909df..5a5413d1cf9 100644 --- a/edge/src/io/openems/impl/device/commercial/FeneconCommercialCharger.java +++ b/edge/src/io/openems/impl/device/commercial/FeneconCommercialCharger.java @@ -33,6 +33,7 @@ import io.openems.api.doc.ThingInfo; import io.openems.api.exception.ConfigException; import io.openems.api.exception.InvalidValueException; +import io.openems.impl.protocol.modbus.ModbusBitWrappingChannel; import io.openems.impl.protocol.modbus.ModbusDeviceNature; import io.openems.impl.protocol.modbus.ModbusReadChannel; import io.openems.impl.protocol.modbus.ModbusReadLongChannel; @@ -56,11 +57,13 @@ public class FeneconCommercialCharger extends ModbusDeviceNature implements Char public FeneconCommercialCharger(String thingId, Device parent) throws ConfigException { super(thingId, parent); this.thingState = new ThingStateChannel(this); + } /* * Inherited Channels */ + private ThingStateChannel thingState; public StatusBitChannels warning; @@ -72,8 +75,6 @@ public FeneconCommercialCharger(String thingId, Device parent) throws ConfigExce private final ConfigChannel maxActualPower = new ConfigChannel("maxActualPower", this); - private ThingStateChannel thingState; - @Override public ConfigChannel maxActualPower() { return maxActualPower; @@ -219,7 +220,6 @@ public ConfigChannel maxActualPower() { */ @Override protected ModbusProtocol defineModbusProtocol() throws ConfigException { - warning = new StatusBitChannels("Warning", this); ModbusProtocol protocol = new ModbusProtocol(// new WriteableModbusRegisterRange(0x0503, new UnsignedWordElement(0x0503, pvPowerLimitCommand = new ModbusWriteLongChannel("PvPowerLimitCommand", this).multiplier(2) @@ -240,169 +240,185 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { .label(256, "Constant Voltage")// .label(512, "Boost MPPT"))), new ModbusRegisterRange(0xA100, // - new UnsignedWordElement(0xA100, - bmsDCDCSuggestiveInformation1 = warning - .channel(new StatusBitChannel("BmsDCDCSuggestiveInformation1", this)// - .label(1, "Current sampling channel abnormity on high voltage side")// - .label(2, "Current sampling channel abnormity on low voltage side")// - .label(64, "EEPROM parameters over range")// - .label(128, "Update EEPROM failed")// - .label(256, "Read EEPROM failed")// - .label(512, "Current sampling channel abnormity before inductance"))), - new UnsignedWordElement(0xA101, bmsDCDCSuggestiveInformation2 = warning - .channel(new StatusBitChannel("BmsDCDCSuggestiveInformation2", this)// - .label(1, "Reactor power decrease caused by overtemperature")// - .label(2, "IGBT power decrease caused by overtemperature")// - .label(4, "Temperature chanel3 power decrease caused by overtemperature")// - .label(8, "Temperature chanel4 power decrease caused by overtemperature")// - .label(16, "Temperature chanel5 power decrease caused by overtemperature")// - .label(32, "Temperature chanel6 power decrease caused by overtemperature")// - .label(64, "Temperature chanel7 power decrease caused by overtemperature")// - .label(128, "Temperature chanel8 power decrease caused by overtemperature")// - .label(256, "Fan 1 stop failed")// - .label(512, "Fan 2 stop failed")// - .label(1024, "Fan 3 stop failed")// - .label(2048, "Fan 4 stop failed")// - .label(4096, "Fan 1 sartup failed")// - .label(8192, "Fan 2 sartup failed")// - .label(16384, "Fan 3 sartup failed")// - .label(32768, "Fan 4 sartup failed"))), - new UnsignedWordElement(0xA102, - bmsDCDCSuggestiveInformation3 = warning - .channel(new StatusBitChannel("BmsDCDCSuggestiveInformation3", this)// - .label(1, "High voltage side overvoltage")// - .label(2, "High voltage side undervoltage")// - .label(4, "EEPROM parameters over range")// - .label(8, "High voltage side voltage change unconventionally"))), - new UnsignedWordElement(0xA103, bmsDCDCSuggestiveInformation4 = warning - .channel(new StatusBitChannel("BmsDCDCSuggestiveInformation4", this)// - .label(1, "Current abnormity before DC Converter work on high voltage side")// - .label(2, "Current abnormity before DC Converter work on low voltage side")// - .label(4, "Initial Duty Ratio abnormity before DC Converter work")// - .label(8, "Voltage abnormity before DC Converter work on high voltage side")// - .label(16, "Voltage abnormity before DC Converter work on low voltage side"))), + new UnsignedWordElement(0xA100,// + new ModbusBitWrappingChannel("BmsDCDCSuggestiveInformation1" , this, this.thingState)// + .warningBit(0, WarningCharger.CurrentSamplingChannelAbnormityOnHighVoltageSide)// + .warningBit(1, WarningCharger.CurrentSamplingChannelAbnormityOnLowVoltageSide)// + .warningBit(6, WarningCharger.EEPROMParametersOverRange)// + .warningBit(7, WarningCharger.UpdateEEPROMFailed)// + .warningBit(8, WarningCharger.ReadEEPROMFailed)// + .warningBit(9, WarningCharger.CurrentSamplingChannelAbnormityBeforeInductance)// + ),// + + new UnsignedWordElement(0xA101, // + new ModbusBitWrappingChannel("BmsDCDCSuggestiveInformation2", this, this.thingState)// + .warningBit(0, WarningCharger.ReactorPowerDecreaseCausedByOvertemperature)// + .warningBit(1, WarningCharger.IGBTPowerDecreaseCausedByOvertemperature)// + .warningBit(2, WarningCharger.TemperatureChanel3PowerDecreaseCausedByOvertemperature)// + .warningBit(3, WarningCharger.TemperatureChanel4PowerDecreaseCausedByOvertemperature)// + .warningBit(4, WarningCharger.TemperatureChanel5PowerDecreaseCausedByOvertemperature)// + .warningBit(5, WarningCharger.TemperatureChanel6PowerDecreaseCausedByOvertemperature)// + .warningBit(6, WarningCharger.TemperatureChanel7PowerDecreaseCausedByOvertemperature)// + .warningBit(7, WarningCharger.TemperatureChanel8PowerDecreaseCausedByOvertemperature)// + .warningBit(8, WarningCharger.Fan1StopFailed)// + .warningBit(9, WarningCharger.Fan2StopFailed)// + .warningBit(10,WarningCharger.Fan3StopFailed)// + .warningBit(11,WarningCharger.Fan4StopFailed)// + .warningBit(12,WarningCharger.Fan1StartupFailed)// + .warningBit(13,WarningCharger.Fan2StartupFailed)// + .warningBit(14,WarningCharger.Fan3StartupFailed)// + .warningBit(15,WarningCharger.Fan4StartupFailed)// + ),// + + new UnsignedWordElement(0xA102,// + new ModbusBitWrappingChannel("BmsDCDCSuggestiveInformation3", this, this.thingState)// + .warningBit(0, WarningCharger.HighVoltageSideOvervoltage)// + .warningBit(1, WarningCharger.HighVoltageSideUndervoltage)// + .warningBit(2, WarningCharger.HighVoltageSideVoltageChangeUnconventionally)// + ),// + + new UnsignedWordElement(0xA103, // + new ModbusBitWrappingChannel("BmsDCDCSuggestiveInformation4", this, this.thingState)// + .warningBit(0, WarningCharger.CurrentAbnormityBeforeDCConverterWorkOnHighVoltageSide) + .warningBit(1, WarningCharger.CurrentAbnormityBeforeDCConverterWorkOnLowVoltageSXide) + .warningBit(2, WarningCharger.InitialDutyRatioAbnormityBeforeDCConverterWork) + .warningBit(3, WarningCharger.VoltageAbnormityBeforeDCConverterWorkOnHighVoltageSide) + .warningBit(4, WarningCharger.VoltageAbnormityBeforeDCConverterWorkOnLowVoltageSide) + ),// + new UnsignedWordElement(0xA104, - bmsDCDCSuggestiveInformation5 = warning - .channel(new StatusBitChannel("BmsDCDCSuggestiveInformation5", this)// - .label(1, "High voltage breaker inspection abnormity")// - .label(2, "Low voltage breaker inspection abnormity")// - .label(4, "DC precharge contactor inspection abnormity")// - .label(8, "DC precharge contactor open unsuccessfully")// - .label(16, "DC main contactor inspection abnormity")// - .label(32, "DC main contactor open unsuccessfully")// - .label(64, "Output contactor close unsuccessfully")// - .label(128, "Output contactor open unsuccessfully")// - .label(256, "AC main contactor close unsuccessfully")// - .label(512, "AC main contactor open unsuccessfully")// - .label(1024, "NegContactor open unsuccessfully")// - .label(2048, "NegContactor close unsuccessfully")// - .label(4096, "NegContactor state abnormal"))), + new ModbusBitWrappingChannel("BmsDCDCSuggestiveInformation5", this, this.thingState)// + .warningBit(0, WarningCharger.HighVoltageBreakerInspectionAbnormity)// + .warningBit(1, WarningCharger.LowVoltageBreakerInspectionAbnormity)// + .warningBit(2, WarningCharger.BsmDCDC5DCPrechargeContactorInspectionAbnormity)// + .warningBit(3, WarningCharger.DCPrechargeContactorOpenUnsuccessfully)// + .warningBit(4, WarningCharger.DCMainContactorInspectionAbnormity)// + .warningBit(5, WarningCharger.DCMainContactorOpenUnsuccessfully)// + .warningBit(6, WarningCharger.OutputContactorCloseUnsuccessfully)// + .warningBit(7, WarningCharger.OutputContactorOpenUnsuccessfully)// + .warningBit(8, WarningCharger.ACMainContactorCloseUnsuccessfully)// + .warningBit(9, WarningCharger.ACMainContactorOpenUnsuccessfully)// + .warningBit(10,WarningCharger.NegContactorOpenUnsuccessfully)// + .warningBit(11,WarningCharger.NegContactorCloseUnsuccessfully)// + .warningBit(12,WarningCharger.NegContactorStateAbnormal)// + ),// + new DummyElement(0xA105, 0xA10F), - new UnsignedWordElement(0xA110, - bmsDCDCAbnormity1 = warning.channel(new StatusBitChannel("BmsDCDCAbnormity1", this)// - .label(1, "High voltage side of DC Converter undervoltage")// - .label(2, "High voltage side of DC Converter overvoltage")// - .label(4, "Low voltage side of DC Converter undervoltage")// - .label(8, "Low voltage side of DC Converter overvoltage")// - .label(16, "High voltage side of DC Converter overcurrent fault")// - .label(32, "Low voltage side of DC Converter overcurrent fault")// - .label(64, "DC Converter IGBT fault")// - .label(128, "DC Converter Precharge unmet"))), + new UnsignedWordElement(0xA110,// + new ModbusBitWrappingChannel("BmsDCDCAbnormity1", this, this.thingState)// + .faultBit(0, FaultCharger.HighVoltageSideOfDCConverterUndervoltage)// + .faultBit(1, FaultCharger.HighVoltageSideOfDCConverterOvervoltage)// + .faultBit(2, FaultCharger.LowVoltageSideOfDCConverterUndervoltage)// + .faultBit(3, FaultCharger.LowVoltageSideOfDCConverterOvervoltage)// + .faultBit(4, FaultCharger.HighVoltageSideOfDCConverterOvercurrentFault)// + .faultBit(5, FaultCharger.LowVoltageSideOfDCConverterOvercurrentFault)// + .faultBit(6, FaultCharger.DCConverterIGBTFault)// + .faultBit(7, FaultCharger.DCConverterPrechargeUnmet)// + ),// + new UnsignedWordElement(0xA111, - bmsDCDCAbnormity2 = warning.channel(new StatusBitChannel("BmsDCDCAbnormity2", this)// - .label(1, "BECU communication disconnected")// - .label(2, "DC Converter communication disconnected")// - .label(4, "Current configuration over range")// - .label(8, "The battery request stop")// - .label(32, "Overcurrent relay fault")// - .label(64, "Lightning protection device fault")// - .label(128, "DC Converter priamary contactor disconnected abnormally")// - .label(512, "DC disconnected abnormally on low voltage side of DC convetor")// - .label(4096, "DC convetor EEPROM abnormity 1")// - .label(8192, "DC convetor EEPROM abnormity 1")// - .label(16384, "EDC convetor EEPROM abnormity 1"))), - new UnsignedWordElement(0xA112, - bmsDCDCAbnormity3 = warning.channel(new StatusBitChannel("BmsDCDCAbnormity3", this)// - .label(1, "DC Convertor general overload")// - .label(2, "DC short circuit")// - .label(4, "Peak pulse current protection")// - .label(8, "DC disconnect abnormally on high voltage side of DC convetor")// - .label(16, "Effective pulse value overhigh")// - .label(32, "DC Converte severe overload")// - .label(64, - "DC breaker disconnect abnormally on high voltage side of DC convetor")// - .label(128, - "DC breaker disconnect abnormally on low voltage side of DC convetor")// - .label(256, "DC convetor precharge contactor close failed ")// - .label(512, "DC convetor main contactor close failed")// - .label(1024, "AC contactor state abnormity of DC convetor")// - .label(2048, "DC convetor emergency stop")// - .label(4096, "DC converter charging gun disconnected")// - .label(8192, "DC current abnormity before DC convetor work")// - .label(16384, "Fuse disconnected")// - .label(32768, "DC converter hardware current or voltage fault"))), - new UnsignedWordElement(0xA113, - bmsDCDCAbnormity4 = warning.channel(new StatusBitChannel("BmsDCDCAbnormity4", this)// - .label(1, "DC converter crystal oscillator circuit invalidation")// - .label(2, "DC converter reset circuit invalidation")// - .label(4, "DC converter sampling circuit invalidation")// - .label(8, "DC converter digital I/O circuit invalidation")// - .label(16, "DC converter PWM circuit invalidation")// - .label(32, "DC converter X5045 circuit invalidation")// - .label(64, "DC converter CAN circuit invalidation")// - .label(128, "DC converter software&hardware protection circuit invalidation")// - .label(256, "DC converter power circuit invalidation")// - .label(512, "DC converter CPU invalidation")// - .label(1024, "DC converter TINT0 interrupt invalidation")// - .label(2048, "DC converter ADC interrupt invalidation")// - .label(4096, "DC converter CAPITN4 interrupt invalidation")// - .label(8192, "DC converter CAPINT6 interrupt invalidation")// - .label(16384, "DC converter T3PINTinterrupt invalidation")// - .label(32768, "DC converter T4PINTinterrupt invalidation"))), - new UnsignedWordElement(0xA114, - bmsDCDCAbnormity5 = warning.channel(new StatusBitChannel("BmsDCDCAbnormity5", this)// - .label(1, "DC converter PDPINTA interrupt invalidation")// - .label(2, "DC converter T1PINT interrupt invalidation")// - .label(4, "DC converter RESV interrupt invalidation")// - .label(8, "DC converter 100us task invalidation")// - .label(16, "DC converter clock invalidation")// - .label(32, "DC converter EMS memory invalidation")// - .label(64, "DC converter exterior communication invalidation")// - .label(128, "DC converter IO Interface invalidation")// - .label(256, "DC converter Input Voltage bound fault")// - .label(512, "DC converter Outter Voltage bound fault")// - .label(1024, "DC converter Output Voltage bound fault")// - .label(2048, "DC converter Induct Current bound fault")// - .label(4096, "DC converter Input Current bound fault")// - .label(8192, "DC converter Output Current bound fault"))), - new UnsignedWordElement(0xA115, - bmsDCDCAbnormity6 = warning.channel(new StatusBitChannel("BmsDCDCAbnormity6", this)// - .label(1, "DC Reactor over temperature")// - .label(2, "DC IGBT over temperature")// - .label(4, "DC Converter chanel 3 over temperature")// - .label(8, "DC Converter chanel 4 over temperature")// - .label(16, "DC Converter chanel 5 over temperature")// - .label(32, "DC Converter chanel 6 over temperature")// - .label(64, "DC Converter chanel 7 over temperature")// - .label(128, "DC Converter chanel 8 over temperature")// - .label(256, "DC Reactor temperature sampling invalidation")// - .label(512, "DC IGBT temperature sampling invalidation")// - .label(1024, "DC Converter chanel 3 temperature sampling invalidation")// - .label(2048, "DC Converter chanel 4 temperature sampling invalidation")// - .label(4096, "DC Converter chanel 5 temperature sampling invalidation")// - .label(8192, "DC Converter chanel 6 temperature sampling invalidation")// - .label(16384, "DC Converter chanel 7 temperature sampling invalidation")// - .label(32768, "DC Converter chanel 8 temperature sampling invalidation"))), + new ModbusBitWrappingChannel("BmsDCDCAbnormity2", this, this.thingState)// + .faultBit(0, FaultCharger.BECUCommunicationDisconnected)// + .faultBit(1, FaultCharger.DCConverterCommunicationDisconnected)// + .faultBit(2, FaultCharger.CurrentConfigurationOverRange)// + .faultBit(3, FaultCharger.TheBatteryRequestStop)// + .faultBit(5, FaultCharger.OvercurrentRelayFault)// + .faultBit(6, FaultCharger.LightningProtectionDeviceFault)// + .faultBit(7, FaultCharger.DCConverterPriamaryContactorDisconnectedAbnormally)// + .faultBit(9, FaultCharger.DCDisconnectedAbnormallyOnLowVoltageSideOfDCConvetor)// + .faultBit(12,FaultCharger.DCConvetorEEPROMAbnormity1)// + .faultBit(13,FaultCharger.DCConvetorEEPROMAbnormity1Second)// + .faultBit(14,FaultCharger.EDCConvetorEEPROMAbnormity1)// + ),// + + new UnsignedWordElement(0xA112,// + new ModbusBitWrappingChannel("BmsDCDCAbnormity3", this, this.thingState)// + .faultBit(0, FaultCharger.DCConvertorGeneralOverload)// + .faultBit(1, FaultCharger.DCShortCircuit)// + .faultBit(2, FaultCharger.PeakPulseCurrentProtection)// + .faultBit(3, FaultCharger.DCDisconnectAbnormallyOnHighVoltageSideOfDCConvetor)// + .faultBit(4, FaultCharger.EffectivePulseValueOverhigh)// + .faultBit(5, FaultCharger.DCConverteSevereOverload)// + .faultBit(6, FaultCharger.DCBreakerDisconnectAbnormallyOnHighVoltageSideOfDCConvetor)// + .faultBit(7, FaultCharger.DCBreakerDisconnectAbnormallyOnLowVoltageSideOfDCConvetor)// + .faultBit(8, FaultCharger.DCConvetorPrechargeContactorCloseFailed)// + .faultBit(9, FaultCharger.DCConvetorMainContactorCloseFailed)// + .faultBit(10,FaultCharger.ACContactorStateAbnormityOfDCConvetor)// + .faultBit(11,FaultCharger.DCConvetorEmergencyStop)// + .faultBit(12,FaultCharger.DCConverterChargingGunDisconnected)// + .faultBit(13,FaultCharger.DCCurrentAbnormityBeforeDCConvetorWork)// + .faultBit(14,FaultCharger.FuSeDisconnected)// + .faultBit(15,FaultCharger.DCConverterHardwareCurrentOrVoltageFault)// + ),// + + new UnsignedWordElement(0xA113,// + new ModbusBitWrappingChannel("BmsDCDCAbnormity4", this, this.thingState)// + .faultBit(0, FaultCharger.DCConverterCrystalOscillatorCircuitInvalidation)// + .faultBit(1, FaultCharger.DCConverterResetCircuitInvalidation)// + .faultBit(2, FaultCharger.DCConverterSamplingCircuitInvalidation)// + .faultBit(3, FaultCharger.DCConverterDigitalIOCircuitInvalidation)// + .faultBit(4, FaultCharger.DCConverterPWMCircuitInvalidation)// + .faultBit(5, FaultCharger.DCConverterX5045CircuitInvalidation)// + .faultBit(6, FaultCharger.DCConverterCANCircuitInvalidation)// + .faultBit(7, FaultCharger.DCConverterSoftwareANDHardwareProtectionCircuitInvalidation)// + .faultBit(8, FaultCharger.DCConverterPowerCircuitInvalidation)// + .faultBit(9, FaultCharger.DCConverterCPUInvalidation)// + .faultBit(10,FaultCharger.DCConverterT1PINTInterruptInvalidation)// + .faultBit(11,FaultCharger.DCConverterADCInterruptInvalidation)// + .faultBit(12,FaultCharger.DCConverterCAPITN4InterruptInvalidation)// + .faultBit(13,FaultCharger.DCConverterCAPINT6InterruptInvalidation)// + .faultBit(14,FaultCharger.DCConverterT3PINTinterruptInvalidation)// + .faultBit(15,FaultCharger.DCConverterT4PINTinterruptInvalidation)// + ),// + + new UnsignedWordElement(0xA114,// + new ModbusBitWrappingChannel("BmsDCDCAbnormity5", this, this.thingState)// + .faultBit(0, FaultCharger.DCConverterPDPINTAInterruptInvalidation)// + .faultBit(1, FaultCharger.DCConverterT1PINTInterruptInvalidation)// + .faultBit(2, FaultCharger.DCConverterRESVInterruptInvalidation)// + .faultBit(3, FaultCharger.DCConverter100usTaskInvalidation)// + .faultBit(4, FaultCharger.DCConverterClockInvalidation)// + .faultBit(5, FaultCharger.DCConverterEMSMemoryInvalidation)// + .faultBit(6, FaultCharger.DCConverterExteriorCommunicationInvalidation)// + .faultBit(7, FaultCharger.DCConverterIOInterfaceInvalidation)// + .faultBit(8, FaultCharger.DCConverterInputVoltageBoundFault)// + .faultBit(9, FaultCharger.DCConverterOutterVoltageBoundFault)// + .faultBit(10,FaultCharger.DCConverterOutputVoltageBoundFault)// + .faultBit(11,FaultCharger.DCConverterInductCurrentBoundFault)// + .faultBit(12,FaultCharger.DCConverterInputCurrentBoundFault)// + .faultBit(13,FaultCharger.DCConverterOutputCurrentBoundFault)// + ),// + + new UnsignedWordElement(0xA115,// + new ModbusBitWrappingChannel("BmsDCDCAbnormity6", this, this.thingState)// + .faultBit(0, FaultCharger.DCReactorOverTemperature)// + .faultBit(1, FaultCharger.DCIGBTOverTemperature)// + .faultBit(2, FaultCharger.DCConverterChanel3OverTemperature)// + .faultBit(3, FaultCharger.DCConverterChanel4OverTemperature)// + .faultBit(4, FaultCharger.DCConverterChanel5OverTemperature)// + .faultBit(5, FaultCharger.DCConverterChanel6OverTemperature)// + .faultBit(6, FaultCharger.DCConverterChanel7OverTemperature)// + .faultBit(7, FaultCharger.DCConverterChanel8OverTemperature)// + .faultBit(8, FaultCharger.DCReactorTemperatureSamplingInvalidation)// + .faultBit(9, FaultCharger.DCIGBTTemperatureSamplingInvalidation)// + .faultBit(10,FaultCharger.DCConverterChanel3TemperatureSamplingInvalidation)// + .faultBit(11,FaultCharger.DCConverterChanel4TemperatureSamplingInvalidation)// + .faultBit(12,FaultCharger.DCConverterChanel5TemperatureSamplingInvalidation)// + .faultBit(13,FaultCharger.DCConverterChanel6TemperatureSamplingInvalidation)// + .faultBit(14,FaultCharger.DCConverterChanel7TemperatureSamplingInvalidation)// + .faultBit(15,FaultCharger.DCConverterChanel8TemperatureSamplingInvalidation)// + ),// + new UnsignedWordElement(0xA116, - bmsDCDCAbnormity7 = warning.channel(new StatusBitChannel("BmsDCDCAbnormity7", this)// - .label(32, "DC Converter inductance current sampling invalidation")// - .label(64, - "Current sampling invalidation on the low voltage sideof DC Converter")// - .label(128, - "Voltage sampling invalidation on the low voltage side of DC Converter")// - .label(256, "Insulation inspection fault")// - .label(512, "NegContactor close unsuccessly")// - .label(1024, "NegContactor cut When running"))), + new ModbusBitWrappingChannel("BmsDCDCAbnormity7", this, this.thingState)// + .faultBit(4, FaultCharger.DCConverterInductanceCurrentSamplingInvalidation)// + .faultBit(5, FaultCharger.CurrentSamplingInvalidationOnTheLowVoltageSideOfDCConverter)// + .faultBit(6, FaultCharger.VoltageSamplingInvalidationOnTheLowVoltageSideOfDCConverter)// + .faultBit(7, FaultCharger.InsulationInspectionFault)// + .faultBit(8, FaultCharger.NegContactorCloseUnsuccessly)// + .faultBit(9, FaultCharger.NegContactorCutWhenRunning)// + ),// + new DummyElement(0xA117, 0xA11F), new UnsignedWordElement(0xA120, bmsDCDCSwitchState = new StatusBitChannel("BmsDCDCSwitchState", this)// @@ -479,169 +495,192 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { .label(256, "Constant Voltage")// .label(512, "Boost MPPT"))), new ModbusRegisterRange(0xA400, // - new UnsignedWordElement(0xA400, - bmsDCDC1SuggestiveInformation1 = warning - .channel(new StatusBitChannel("BmsDCDC1SuggestiveInformation1", this)// - .label(1, "Current sampling channel abnormity on high voltage side")// - .label(2, "Current sampling channel abnormity on low voltage side")// - .label(64, "EEPROM parameters over range")// - .label(128, "Update EEPROM failed")// - .label(256, "Read EEPROM failed")// - .label(512, "Current sampling channel abnormity before inductance"))), - new UnsignedWordElement(0xA401, bmsDCDC1SuggestiveInformation2 = warning - .channel(new StatusBitChannel("BmsDCDC1SuggestiveInformation2", this)// - .label(1, "Reactor power decrease caused by overtemperature")// - .label(2, "IGBT power decrease caused by overtemperature")// - .label(4, "Temperature chanel3 power decrease caused by overtemperature")// - .label(8, "Temperature chanel4 power decrease caused by overtemperature")// - .label(16, "Temperature chanel5 power decrease caused by overtemperature")// - .label(32, "Temperature chanel6 power decrease caused by overtemperature")// - .label(64, "Temperature chanel7 power decrease caused by overtemperature")// - .label(128, "Temperature chanel8 power decrease caused by overtemperature")// - .label(256, "Fan 1 stop failed")// - .label(512, "Fan 2 stop failed")// - .label(1024, "Fan 3 stop failed")// - .label(2048, "Fan 4 stop failed")// - .label(4096, "Fan 1 sartup failed")// - .label(8192, "Fan 2 sartup failed")// - .label(16384, "Fan 3 sartup failed")// - .label(32768, "Fan 4 sartup failed"))), - new UnsignedWordElement(0xA402, - bmsDCDC1SuggestiveInformation3 = warning - .channel(new StatusBitChannel("BmsDCDC1SuggestiveInformation3", this)// - .label(1, "High voltage side overvoltage")// - .label(2, "High voltage side undervoltage")// - .label(4, "EEPROM parameters over range")// - .label(8, "High voltage side voltage change unconventionally"))), - new UnsignedWordElement(0xA403, bmsDCDC1SuggestiveInformation4 = warning - .channel(new StatusBitChannel("BmsDCDC1SuggestiveInformation4", this)// - .label(1, "Current abnormity before DC Converter work on high voltage side")// - .label(2, "Current abnormity before DC Converter work on low voltage side")// - .label(4, "Initial Duty Ratio abnormity before DC Converter work")// - .label(8, "Voltage abnormity before DC Converter work on high voltage side")// - .label(16, "Voltage abnormity before DC Converter work on low voltage side"))), - new UnsignedWordElement(0xA404, - bmsDCDC1SuggestiveInformation5 = warning - .channel(new StatusBitChannel("BmsDCDC1SuggestiveInformation5", this)// - .label(1, "High voltage breaker inspection abnormity")// - .label(2, "Low voltage breaker inspection abnormity")// - .label(4, "DC precharge contactor inspection abnormity")// - .label(8, "DC precharge contactor open unsuccessfully")// - .label(16, "DC main contactor inspection abnormity")// - .label(32, "DC main contactor open unsuccessfully")// - .label(64, "Output contactor close unsuccessfully")// - .label(128, "Output contactor open unsuccessfully")// - .label(256, "AC main contactor close unsuccessfully")// - .label(512, "AC main contactor open unsuccessfully")// - .label(1024, "NegContactor open unsuccessfully")// - .label(2048, "NegContactor close unsuccessfully")// - .label(4096, "NegContactor state abnormal"))), + new UnsignedWordElement(0xA400,// + //used BsmDCDC1 as prefix on each one if it is used before + new ModbusBitWrappingChannel("BmsDCDC1SuggestiveInformation1", this, this.thingState)// + .warningBit(0, WarningCharger.BsmDCDC1CurrentSamplingChannelAbnormityOnHighVoltageSide)// + .warningBit(1, WarningCharger.BsmDCDC1CurrentSamplingChannelAbnormityOnLowVoltageSide)// + .warningBit(6, WarningCharger.BmsDCDC1EEPROMParametersOverRange)// + .warningBit(7, WarningCharger.BsmDCDC1UpdateEEPROMFailed)// + .warningBit(8, WarningCharger.BsmDCDC1ReadEEPROMFailed)// + .warningBit(9, WarningCharger.BsmDCDC1CurrentSamplingChannelAbnormityBeforeInductance)// + ),// + + new UnsignedWordElement(0xA401, // + //Prefix = "BsmDCDC1" + new ModbusBitWrappingChannel("BmsDCDC1SuggestiveInformation2", this, this.thingState)// + .warningBit(0, WarningCharger.BsmDCDC1ReactorPowerDecreaseCausedByOvertemperature)// + .warningBit(1, WarningCharger.BsmDCDC1IGBTPowerDecreaseCausedByOvertemperature)// + .warningBit(2, WarningCharger.BsmDCDC1TemperatureChanel3PowerDecreaseCausedByOvertemperature)// + .warningBit(3, WarningCharger.BsmDCDC1TemperatureChanel4PowerDecreaseCausedByOvertemperature)// + .warningBit(4, WarningCharger.BsmDCDC1TemperatureChanel5PowerDecreaseCausedByOvertemperature)// + .warningBit(5, WarningCharger.BsmDCDC1TemperatureChanel6PowerDecreaseCausedByOvertemperature)// + .warningBit(6, WarningCharger.BsmDCDC1TemperatureChanel7PowerDecreaseCausedByOvertemperature)// + .warningBit(7, WarningCharger.BsmDCDC1TemperatureChanel8PowerDecreaseCausedByOvertemperature)// + .warningBit(8, WarningCharger.BsmDCDC1Fan1StopFailed)// + .warningBit(9, WarningCharger.BsmDCDC1Fan2StopFailed)// + .warningBit(10,WarningCharger.BsmDCDC1Fan3StopFailed)// + .warningBit(11,WarningCharger.BsmDCDC1Fan4StopFailed)// + .warningBit(12,WarningCharger.BsmDCDC1Fan1StartupFailed)// + .warningBit(13,WarningCharger.BsmDCDC1Fan2StartupFailed)// + .warningBit(14,WarningCharger.BsmDCDC1Fan3StartupFailed)// + .warningBit(15,WarningCharger.BsmDCDC1Fan4StartupFailed)// + ),// + new UnsignedWordElement(0xA402,// + //prefix = "BsmDCDC1" + new ModbusBitWrappingChannel("BmsDCDC1SuggestiveInformation3", this, this.thingState)// + .warningBit(0, WarningCharger.BsmDCDC1HighVoltageSideOvervoltage)// + .warningBit(1, WarningCharger.BsmDCDC1HighVoltageSideUndervoltage)// + .warningBit(2, WarningCharger.BsmDCDC1HighVoltageSideVoltageChangeUnconventionally)// + ),// + + new UnsignedWordElement(0xA403, // + //prefix = "BsmDCDC1" + new ModbusBitWrappingChannel("BmsDCDC1SuggestiveInformation4", this, this.thingState)// + .warningBit(0, WarningCharger.BmsDCDC1CurrentAbnormityBeforeDCConverterWorkOnHighVoltageSide) + .warningBit(1, WarningCharger.BmsDCDC1CurrentAbnormityBeforeDCConverterWorkOnLowVoltageSXide) + .warningBit(2, WarningCharger.BmsDCDC1InitialDutyRatioAbnormityBeforeDCConverterWork) + .warningBit(3, WarningCharger.BmsDCDC1VoltageAbnormityBeforeDCConverterWorkOnHighVoltageSide) + .warningBit(4, WarningCharger.BmsDCDC1VoltageAbnormityBeforeDCConverterWorkOnLowVoltageSide) + ),// + + new UnsignedWordElement(0xA404,// + // prefix = "BsmDCDC1" + new ModbusBitWrappingChannel("BmsDCDC1SuggestiveInformation5", this, this.thingState)// + .warningBit(0, WarningCharger.BmsDCDC1HighVoltageBreakerInspectionAbnormity)// + .warningBit(1, WarningCharger.BmsDCDC1LowVoltageBreakerInspectionAbnormity)// + .warningBit(2, WarningCharger.BmsDCDC1BsmDCDC5DCPrechargeContactorInspectionAbnormity)// + .warningBit(3, WarningCharger.BmsDCDC1DCPrechargeContactorOpenUnsuccessfully)// + .warningBit(4, WarningCharger.BmsDCDC1DCMainContactorInspectionAbnormity)// + .warningBit(5, WarningCharger.BmsDCDC1DCMainContactorOpenUnsuccessfully)// + .warningBit(6, WarningCharger.BmsDCDC1OutputContactorCloseUnsuccessfully)// + .warningBit(7, WarningCharger.BmsDCDC1OutputContactorOpenUnsuccessfully)// + .warningBit(8, WarningCharger.BmsDCDC1ACMainContactorCloseUnsuccessfully)// + .warningBit(9, WarningCharger.BmsDCDC1ACMainContactorOpenUnsuccessfully)// + .warningBit(10,WarningCharger.BmsDCDC1NegContactorOpenUnsuccessfully)// + .warningBit(11,WarningCharger.BmsDCDC1NegContactorCloseUnsuccessfully)// + .warningBit(12,WarningCharger.BmsDCDC1NegContactorStateAbnormal)// + ),// + new DummyElement(0xA405, 0xA40F), new UnsignedWordElement(0xA410, - bmsDCDC1Abnormity1 = warning.channel(new StatusBitChannel("BmsDCDC1Abnormity1", this)// - .label(1, "High voltage side of DC Converter undervoltage")// - .label(2, "High voltage side of DC Converter overvoltage")// - .label(4, "Low voltage side of DC Converter undervoltage")// - .label(8, "Low voltage side of DC Converter overvoltage")// - .label(16, "High voltage side of DC Converter overcurrent fault")// - .label(32, "Low voltage side of DC Converter overcurrent fault")// - .label(64, "DC Converter IGBT fault")// - .label(128, "DC Converter Precharge unmet"))), + // prefix = "BsmDCDC1" + new ModbusBitWrappingChannel("BmsDCDC1Abnormity1", this, this.thingState)// + .faultBit(0, FaultCharger.BmsDCDC1HighVoltageSideOfDCConverterUndervoltage)// + .faultBit(1, FaultCharger.BmsDCDC1HighVoltageSideOfDCConverterOvervoltage)// + .faultBit(2, FaultCharger.BmsDCDC1LowVoltageSideOfDCConverterUndervoltage)// + .faultBit(3, FaultCharger.BmsDCDC1LowVoltageSideOfDCConverterOvervoltage)// + .faultBit(4, FaultCharger.BmsDCDC1HighVoltageSideOfDCConverterOvercurrentFault)// + .faultBit(5, FaultCharger.BmsDCDC1LowVoltageSideOfDCConverterOvercurrentFault)// + .faultBit(6, FaultCharger.BmsDCDC1DCConverterIGBTFault)// + .faultBit(7, FaultCharger.BmsDCDC1DCConverterPrechargeUnmet)// + ),// + new UnsignedWordElement(0xA411, - bmsDCDC1Abnormity2 = warning.channel(new StatusBitChannel("BmsDCDC1Abnormity2", this)// - .label(1, "BECU communication disconnected")// - .label(2, "DC Converter communication disconnected")// - .label(4, "Current configuration over range")// - .label(8, "The battery request stop")// - .label(32, "Overcurrent relay fault")// - .label(64, "Lightning protection device fault")// - .label(128, "DC Converter priamary contactor disconnected abnormally")// - .label(512, "DC disconnected abnormally on low voltage side of DC convetor")// - .label(4096, "DC convetor EEPROM abnormity 1")// - .label(8192, "DC convetor EEPROM abnormity 1")// - .label(16384, "EDC convetor EEPROM abnormity 1"))), - new UnsignedWordElement(0xA412, - bmsDCDC1Abnormity3 = warning.channel(new StatusBitChannel("BmsDCDC1Abnormity3", this)// - .label(1, "DC Convertor general overload")// - .label(2, "DC short circuit")// - .label(4, "Peak pulse current protection")// - .label(8, "DC disconnect abnormally on high voltage side of DC convetor")// - .label(16, "Effective pulse value overhigh")// - .label(32, "DC Converte severe overload")// - .label(64, - "DC breaker disconnect abnormally on high voltage side of DC convetor")// - .label(128, - "DC breaker disconnect abnormally on low voltage side of DC convetor")// - .label(256, "DC convetor precharge contactor close failed ")// - .label(512, "DC convetor main contactor close failed")// - .label(1024, "AC contactor state abnormity of DC convetor")// - .label(2048, "DC convetor emergency stop")// - .label(4096, "DC converter charging gun disconnected")// - .label(8192, "DC current abnormity before DC convetor work")// - .label(16384, "Fuse disconnected")// - .label(32768, "DC converter hardware current or voltage fault"))), + // prefix = "BsmDCDC1" + new ModbusBitWrappingChannel("BmsDCDC1Abnormity2", this, this.thingState)// + .faultBit(0, FaultCharger.BmsDCDC1BECUCommunicationDisconnected)// + .faultBit(1, FaultCharger.BmsDCDC1DCConverterCommunicationDisconnected)// + .faultBit(2, FaultCharger.BmsDCDC1CurrentConfigurationOverRange)// + .faultBit(3, FaultCharger.BmsDCDC1TheBatteryRequestStop)// + .faultBit(5, FaultCharger.BmsDCDC1OvercurrentRelayFault)// + .faultBit(6, FaultCharger.BmsDCDC1LightningProtectionDeviceFault)// + .faultBit(7, FaultCharger.BmsDCDC1DCConverterPriamaryContactorDisconnectedAbnormally)// + .faultBit(9, FaultCharger.BmsDCDC1DCDisconnectedAbnormallyOnLowVoltageSideOfDCConvetor)// + .faultBit(12,FaultCharger.BmsDCDC1DCConvetorEEPROMAbnormity1)// + .faultBit(13,FaultCharger.BmsDCDC1DCConvetorEEPROMAbnormity1Second)// + .faultBit(14,FaultCharger.BmsDCDC1EDCConvetorEEPROMAbnormity1)// + ),// + + new UnsignedWordElement(0xA412,// + //prefix = "BsmDCDC1" + new ModbusBitWrappingChannel("BmsDCDC1Abnormity3", this, this.thingState)// + .faultBit(0, FaultCharger.BsmDCDC1DCConvertorGeneralOverload)// + .faultBit(1, FaultCharger.BsmDCDC1DCShortCircuit)// + .faultBit(2, FaultCharger.BsmDCDC1PeakPulseCurrentProtection)// + .faultBit(3, FaultCharger.BsmDCDC1DCDisconnectAbnormallyOnHighVoltageSideOfDCConvetor)// + .faultBit(4, FaultCharger.BsmDCDC1EffectivePulseValueOverhigh)// + .faultBit(5, FaultCharger.BsmDCDC1DCConverteSevereOverload)// + .faultBit(6, FaultCharger.BsmDCDC1DCBreakerDisconnectAbnormallyOnHighVoltageSideOfDCConvetor)// + .faultBit(7, FaultCharger.BsmDCDC1DCBreakerDisconnectAbnormallyOnLowVoltageSideOfDCConvetor)// + .faultBit(8, FaultCharger.BsmDCDC1DCConvetorPrechargeContactorCloseFailed)// + .faultBit(9, FaultCharger.BsmDCDC1DCConvetorMainContactorCloseFailed)// + .faultBit(10,FaultCharger.BsmDCDC1ACContactorStateAbnormityOfDCConvetor)// + .faultBit(11,FaultCharger.BsmDCDC1DCConvetorEmergencyStop)// + .faultBit(12,FaultCharger.BsmDCDC1DCConverterChargingGunDisconnected)// + .faultBit(13,FaultCharger.BsmDCDC1DCCurrentAbnormityBeforeDCConvetorWork)// + .faultBit(14,FaultCharger.BsmDCDC1FuSeDisconnected)// + .faultBit(15,FaultCharger.BsmDCDC1DCConverterHardwareCurrentOrVoltageFault)// + ),// + new UnsignedWordElement(0xA413, - bmsDCDC1Abnormity4 = warning.channel(new StatusBitChannel("BmsDCDC1Abnormity4", this)// - .label(1, "DC converter crystal oscillator circuit invalidation")// - .label(2, "DC converter reset circuit invalidation")// - .label(4, "DC converter sampling circuit invalidation")// - .label(8, "DC converter digital I/O circuit invalidation")// - .label(16, "DC converter PWM circuit invalidation")// - .label(32, "DC converter X5045 circuit invalidation")// - .label(64, "DC converter CAN circuit invalidation")// - .label(128, "DC converter software&hardware protection circuit invalidation")// - .label(256, "DC converter power circuit invalidation")// - .label(512, "DC converter CPU invalidation")// - .label(1024, "DC converter TINT0 interrupt invalidation")// - .label(2048, "DC converter ADC interrupt invalidation")// - .label(4096, "DC converter CAPITN4 interrupt invalidation")// - .label(8192, "DC converter CAPINT6 interrupt invalidation")// - .label(16384, "DC converter T3PINTinterrupt invalidation")// - .label(32768, "DC converter T4PINTinterrupt invalidation"))), + // prefix = "BsmDCDC1" + new ModbusBitWrappingChannel("BmsDCDC1Abnormity4", this, this.thingState)// + .faultBit(0, FaultCharger.BmsDCDC1DCConverterCrystalOscillatorCircuitInvalidation)// + .faultBit(1, FaultCharger.BmsDCDC1DCConverterResetCircuitInvalidation)// + .faultBit(2, FaultCharger.BmsDCDC1DCConverterSamplingCircuitInvalidation)// + .faultBit(3, FaultCharger.BmsDCDC1DCConverterDigitalIOCircuitInvalidation)// + .faultBit(4, FaultCharger.BmsDCDC1DCConverterPWMCircuitInvalidation)// + .faultBit(5, FaultCharger.BmsDCDC1DCConverterX5045CircuitInvalidation)// + .faultBit(6, FaultCharger.BmsDCDC1DCConverterCANCircuitInvalidation)// + .faultBit(7, FaultCharger.BmsDCDC1DCConverterSoftwareANDHardwareProtectionCircuitInvalidation)// + .faultBit(8, FaultCharger.BmsDCDC1DCConverterPowerCircuitInvalidation)// + .faultBit(9, FaultCharger.BmsDCDC1DCConverterCPUInvalidation)// + .faultBit(10,FaultCharger.BmsDCDC1DCConverterT1PINTInterruptInvalidation)// + .faultBit(11,FaultCharger.BmsDCDC1DCConverterADCInterruptInvalidation)// + .faultBit(12,FaultCharger.BmsDCDC1DCConverterCAPITN4InterruptInvalidation)// + .faultBit(13,FaultCharger.BmsDCDC1DCConverterCAPINT6InterruptInvalidation)// + .faultBit(14,FaultCharger.BmsDCDC1DCConverterT3PINTinterruptInvalidation)// + .faultBit(15,FaultCharger.BmsDCDC1DCConverterT4PINTinterruptInvalidation)// + ),// new UnsignedWordElement(0xA414, - bmsDCDC1Abnormity5 = warning.channel(new StatusBitChannel("BmsDCDC1Abnormity5", this)// - .label(1, "DC converter PDPINTA interrupt invalidation")// - .label(2, "DC converter T1PINT interrupt invalidation")// - .label(4, "DC converter RESV interrupt invalidation")// - .label(8, "DC converter 100us task invalidation")// - .label(16, "DC converter clock invalidation")// - .label(32, "DC converter EMS memory invalidation")// - .label(64, "DC converter exterior communication invalidation")// - .label(128, "DC converter IO Interface invalidation")// - .label(256, "DC converter Input Voltage bound fault")// - .label(512, "DC converter Outter Voltage bound fault")// - .label(1024, "DC converter Output Voltage bound fault")// - .label(2048, "DC converter Induct Current bound fault")// - .label(4096, "DC converter Input Current bound fault")// - .label(8192, "DC converter Output Current bound fault"))), + // prefix = "BsmDCDC1" + new ModbusBitWrappingChannel("BmsDCDC1Abnormity5", this, this.thingState)// + .faultBit(0, FaultCharger.BmsDCDC1DCConverterPDPINTAInterruptInvalidation)// + .faultBit(1, FaultCharger.BmsDCDC1DCConverterT1PINTInterruptInvalidationSecond)// + .faultBit(2, FaultCharger.BmsDCDC1DCConverterRESVInterruptInvalidation)// + .faultBit(3, FaultCharger.BmsDCDC1DCConverter100usTaskInvalidation)// + .faultBit(4, FaultCharger.BmsDCDC1DCConverterClockInvalidation)// + .faultBit(5, FaultCharger.BmsDCDC1DCConverterEMSMemoryInvalidation)// + .faultBit(6, FaultCharger.BmsDCDC1DCConverterExteriorCommunicationInvalidation)// + .faultBit(7, FaultCharger.BmsDCDC1DCConverterIOInterfaceInvalidation)// + .faultBit(8, FaultCharger.BmsDCDC1DCConverterInputVoltageBoundFault)// + .faultBit(9, FaultCharger.BmsDCDC1DCConverterOutterVoltageBoundFault)// + .faultBit(10,FaultCharger.BmsDCDC1DCConverterOutputVoltageBoundFault)// + .faultBit(11,FaultCharger.BmsDCDC1DCConverterInductCurrentBoundFault)// + .faultBit(12,FaultCharger.BmsDCDC1DCConverterInputCurrentBoundFault)// + .faultBit(13,FaultCharger.BmsDCDC1DCConverterOutputCurrentBoundFault)// + ),// new UnsignedWordElement(0xA415, - bmsDCDC1Abnormity6 = warning.channel(new StatusBitChannel("BmsDCDC1Abnormity6", this)// - .label(1, "DC Reactor over temperature")// - .label(2, "DC IGBT over temperature")// - .label(4, "DC Converter chanel 3 over temperature")// - .label(8, "DC Converter chanel 4 over temperature")// - .label(16, "DC Converter chanel 5 over temperature")// - .label(32, "DC Converter chanel 6 over temperature")// - .label(64, "DC Converter chanel 7 over temperature")// - .label(128, "DC Converter chanel 8 over temperature")// - .label(256, "DC Reactor temperature sampling invalidation")// - .label(512, "DC IGBT temperature sampling invalidation")// - .label(1024, "DC Converter chanel 3 temperature sampling invalidation")// - .label(2048, "DC Converter chanel 4 temperature sampling invalidation")// - .label(4096, "DC Converter chanel 5 temperature sampling invalidation")// - .label(8192, "DC Converter chanel 6 temperature sampling invalidation")// - .label(16384, "DC Converter chanel 7 temperature sampling invalidation")// - .label(32768, "DC Converter chanel 8 temperature sampling invalidation"))), + // prefix = "BsmDCDC1" + new ModbusBitWrappingChannel("BmsDCDC1Abnormity6", this, this.thingState)// + .faultBit(0, FaultCharger.BmsDCDC1DCReactorOverTemperature)// + .faultBit(1, FaultCharger.BmsDCDC1DCIGBTOverTemperature)// + .faultBit(2, FaultCharger.BmsDCDC1DCConverterChanel3OverTemperature)// + .faultBit(3, FaultCharger.BmsDCDC1DCConverterChanel4OverTemperature)// + .faultBit(4, FaultCharger.BmsDCDC1DCConverterChanel5OverTemperature)// + .faultBit(5, FaultCharger.BmsDCDC1DCConverterChanel6OverTemperature)// + .faultBit(6, FaultCharger.BmsDCDC1DCConverterChanel7OverTemperature)// + .faultBit(7, FaultCharger.BmsDCDC1DCConverterChanel8OverTemperature)// + .faultBit(8, FaultCharger.BmsDCDC1DCReactorTemperatureSamplingInvalidation)// + .faultBit(9, FaultCharger.BmsDCDC1DCIGBTTemperatureSamplingInvalidation)// + .faultBit(10,FaultCharger.BmsDCDC1DCConverterChanel3TemperatureSamplingInvalidation)// + .faultBit(11,FaultCharger.BmsDCDC1DCConverterChanel4TemperatureSamplingInvalidation)// + .faultBit(12,FaultCharger.BmsDCDC1DCConverterChanel5TemperatureSamplingInvalidation)// + .faultBit(13,FaultCharger.BmsDCDC1DCConverterChanel6TemperatureSamplingInvalidation)// + .faultBit(14,FaultCharger.BmsDCDC1DCConverterChanel7TemperatureSamplingInvalidation)// + .faultBit(15,FaultCharger.BmsDCDC1DCConverterChanel8TemperatureSamplingInvalidation)// + ),// new UnsignedWordElement(0xA416, - bmsDCDC1Abnormity7 = warning.channel(new StatusBitChannel("BmsDCDC1Abnormity7", this)// - .label(32, "DC Converter inductance current sampling invalidation")// - .label(64, - "Current sampling invalidation on the low voltage sideof DC Converter")// - .label(128, - "Voltage sampling invalidation on the low voltage side of DC Converter")// - .label(256, "Insulation inspection fault")// - .label(512, "NegContactor close unsuccessly")// - .label(1024, "NegContactor cut When running"))), + // prefix = "BsmDCDC1" + new ModbusBitWrappingChannel("BmsDCDC1Abnormity7", this, this.thingState)// + .faultBit(4, FaultCharger.BmsDCDC1DCConverterInductanceCurrentSamplingInvalidation)// + .faultBit(5, FaultCharger.BmsDCDC1CurrentSamplingInvalidationOnTheLowVoltageSideOfDCConverter)// + .faultBit(6, FaultCharger.BmsDCDC1VoltageSamplingInvalidationOnTheLowVoltageSideOfDCConverter)// + .faultBit(7, FaultCharger.BmsDCDC1InsulationInspectionFault)// + .faultBit(8, FaultCharger.BmsDCDC1NegContactorCloseUnsuccessly)// + .faultBit(9, FaultCharger.BmsDCDC1NegContactorCutWhenRunning)// + ),// new DummyElement(0xA417, 0xA41F), new UnsignedWordElement(0xA420, bmsDCDC1SwitchState = new StatusBitChannel("BmsDCDC1SwitchState", this)// @@ -718,169 +757,197 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { .label(256, "Constant Voltage")// .label(512, "Boost MPPT"))), new ModbusRegisterRange(0xA700, // - new UnsignedWordElement(0xA700, - pvDCDCSuggestiveInformation1 = warning - .channel(new StatusBitChannel("PvDCDCSuggestiveInformation1", this)// - .label(1, "Current sampling channel abnormity on high voltage side")// - .label(2, "Current sampling channel abnormity on low voltage side")// - .label(64, "EEPROM parameters over range")// - .label(128, "Update EEPROM failed")// - .label(256, "Read EEPROM failed")// - .label(512, "Current sampling channel abnormity before inductance"))), - new UnsignedWordElement(0xA701, pvDCDCSuggestiveInformation2 = warning - .channel(new StatusBitChannel("PvDCDCSuggestiveInformation2", this)// - .label(1, "Reactor power decrease caused by overtemperature")// - .label(2, "IGBT power decrease caused by overtemperature")// - .label(4, "Temperature chanel3 power decrease caused by overtemperature")// - .label(8, "Temperature chanel4 power decrease caused by overtemperature")// - .label(16, "Temperature chanel5 power decrease caused by overtemperature")// - .label(32, "Temperature chanel6 power decrease caused by overtemperature")// - .label(64, "Temperature chanel7 power decrease caused by overtemperature")// - .label(128, "Temperature chanel8 power decrease caused by overtemperature")// - .label(256, "Fan 1 stop failed")// - .label(512, "Fan 2 stop failed")// - .label(1024, "Fan 3 stop failed")// - .label(2048, "Fan 4 stop failed")// - .label(4096, "Fan 1 sartup failed")// - .label(8192, "Fan 2 sartup failed")// - .label(16384, "Fan 3 sartup failed")// - .label(32768, "Fan 4 sartup failed"))), - new UnsignedWordElement(0xA702, - pvDCDCSuggestiveInformation3 = warning - .channel(new StatusBitChannel("PvDCDCSuggestiveInformation3", this)// - .label(1, "High voltage side overvoltage")// - .label(2, "High voltage side undervoltage")// - .label(4, "EEPROM parameters over range")// - .label(8, "High voltage side voltage change unconventionally"))), - new UnsignedWordElement(0xA703, pvDCDCSuggestiveInformation4 = warning - .channel(new StatusBitChannel("PvDCDCSuggestiveInformation4", this)// - .label(1, "Current abnormity before DC Converter work on high voltage side")// - .label(2, "Current abnormity before DC Converter work on low voltage side")// - .label(4, "Initial Duty Ratio abnormity before DC Converter work")// - .label(8, "Voltage abnormity before DC Converter work on high voltage side")// - .label(16, "Voltage abnormity before DC Converter work on low voltage side"))), - new UnsignedWordElement(0xA704, - pvDCDCSuggestiveInformation5 = warning - .channel(new StatusBitChannel("PvDCDCSuggestiveInformation5", this)// - .label(1, "High voltage breaker inspection abnormity")// - .label(2, "Low voltage breaker inspection abnormity")// - .label(4, "DC precharge contactor inspection abnormity")// - .label(8, "DC precharge contactor open unsuccessfully")// - .label(16, "DC main contactor inspection abnormity")// - .label(32, "DC main contactor open unsuccessfully")// - .label(64, "Output contactor close unsuccessfully")// - .label(128, "Output contactor open unsuccessfully")// - .label(256, "AC main contactor close unsuccessfully")// - .label(512, "AC main contactor open unsuccessfully")// - .label(1024, "NegContactor open unsuccessfully")// - .label(2048, "NegContactor close unsuccessfully")// - .label(4096, "NegContactor state abnormal"))), + new UnsignedWordElement(0xA700,// + // prefix = "PvDCDC " + new ModbusBitWrappingChannel("PvDCDCSuggestiveInformation1" , this, this.thingState)// + .warningBit(0, WarningCharger.PvDCDCCurrentSamplingChannelAbnormityOnHighVoltageSide)// + .warningBit(1, WarningCharger.PvDCDCCurrentSamplingChannelAbnormityOnLowVoltageSide)// + .warningBit(6, WarningCharger.PvDCDCEEPROMParametersOverRange)// + .warningBit(7, WarningCharger.PvDCDCUpdateEEPROMFailed)// + .warningBit(8, WarningCharger.PvDCDCReadEEPROMFailed)// + .warningBit(9, WarningCharger.PvDCDCCurrentSamplingChannelAbnormityBeforeInductance)// + ),// + + new UnsignedWordElement(0xA701, // + //prefix = "PvDCDC " + new ModbusBitWrappingChannel("PvDCDCSuggestiveInformation2", this, this.thingState)// + .warningBit(0, WarningCharger.PvDCDCReactorPowerDecreaseCausedByOvertemperature)// + .warningBit(1, WarningCharger.PvDCDCIGBTPowerDecreaseCausedByOvertemperature)// + .warningBit(2, WarningCharger.PvDCDCTemperatureChanel3PowerDecreaseCausedByOvertemperature)// + .warningBit(3, WarningCharger.PvDCDCTemperatureChanel4PowerDecreaseCausedByOvertemperature)// + .warningBit(4, WarningCharger.PvDCDCTemperatureChanel5PowerDecreaseCausedByOvertemperature)// + .warningBit(5, WarningCharger.PvDCDCTemperatureChanel6PowerDecreaseCausedByOvertemperature)// + .warningBit(6, WarningCharger.PvDCDCTemperatureChanel7PowerDecreaseCausedByOvertemperature)// + .warningBit(7, WarningCharger.PvDCDCTemperatureChanel8PowerDecreaseCausedByOvertemperature)// + .warningBit(8, WarningCharger.PvDCDCFan1StopFailed)// + .warningBit(9, WarningCharger.PvDCDCFan2StopFailed)// + .warningBit(10,WarningCharger.PvDCDCFan3StopFailed)// + .warningBit(11,WarningCharger.PvDCDCFan4StopFailed)// + .warningBit(12,WarningCharger.PvDCDCFan1StartupFailed)// + .warningBit(13,WarningCharger.PvDCDCFan2StartupFailed)// + .warningBit(14,WarningCharger.PvDCDCFan3StartupFailed)// + .warningBit(15,WarningCharger.PvDCDCFan4StartupFailed)// + ),// + + new UnsignedWordElement(0xA702,// + // prefix = "PvDCDC" + new ModbusBitWrappingChannel("PvDCDCSuggestiveInformation3", this, this.thingState)// + .warningBit(0, WarningCharger.PvDCDCHighVoltageSideOvervoltage)// + .warningBit(1, WarningCharger.PvDCDCHighVoltageSideUndervoltage)// + .warningBit(2, WarningCharger.PvDCDCHighVoltageSideVoltageChangeUnconventionally)// + ),// + + new UnsignedWordElement(0xA703, + // prefix = "PvDCDC" + new ModbusBitWrappingChannel("PvDCDCSuggestiveInformation4", this, this.thingState)// + .warningBit(0, WarningCharger.PvDCDCCurrentAbnormityBeforeDCConverterWorkOnHighVoltageSide) + .warningBit(1, WarningCharger.PvDCDCCurrentAbnormityBeforeDCConverterWorkOnLowVoltageSXide) + .warningBit(2, WarningCharger.PvDCDCInitialDutyRatioAbnormityBeforeDCConverterWork) + .warningBit(3, WarningCharger.PvDCDCVoltageAbnormityBeforeDCConverterWorkOnHighVoltageSide) + .warningBit(4, WarningCharger.PvDCDCVoltageAbnormityBeforeDCConverterWorkOnLowVoltageSide) + ),// + + new UnsignedWordElement(0xA704,// + // prefix = "PvDCDC" + new ModbusBitWrappingChannel("PvDCDCSuggestiveInformation5", this, this.thingState)// + .warningBit(0, WarningCharger.PvDCDCHighVoltageBreakerInspectionAbnormity)// + .warningBit(1, WarningCharger.PvDCDCLowVoltageBreakerInspectionAbnormity)// + .warningBit(2, WarningCharger.PvDCDCBsmDCDC5DCPrechargeContactorInspectionAbnormity)// + .warningBit(3, WarningCharger.PvDCDCDCPrechargeContactorOpenUnsuccessfully)// + .warningBit(4, WarningCharger.PvDCDCDCMainContactorInspectionAbnormity)// + .warningBit(5, WarningCharger.PvDCDCDCMainContactorOpenUnsuccessfully)// + .warningBit(6, WarningCharger.PvDCDCOutputContactorCloseUnsuccessfully)// + .warningBit(7, WarningCharger.PvDCDCOutputContactorOpenUnsuccessfully)// + .warningBit(8, WarningCharger.PvDCDCACMainContactorCloseUnsuccessfully)// + .warningBit(9, WarningCharger.PvDCDCACMainContactorOpenUnsuccessfully)// + .warningBit(10,WarningCharger.PvDCDCNegContactorOpenUnsuccessfully)// + .warningBit(11,WarningCharger.PvDCDCNegContactorCloseUnsuccessfully)// + .warningBit(12,WarningCharger.PvDCDCNegContactorStateAbnormal)// + ),// + new DummyElement(0xA705, 0xA70F), - new UnsignedWordElement(0xA710, - pvDCDCAbnormity1 = warning.channel(new StatusBitChannel("PvDCDCAbnormity1", this)// - .label(1, "High voltage side of DC Converter undervoltage")// - .label(2, "High voltage side of DC Converter overvoltage")// - .label(4, "Low voltage side of DC Converter undervoltage")// - .label(8, "Low voltage side of DC Converter overvoltage")// - .label(16, "High voltage side of DC Converter overcurrent fault")// - .label(32, "Low voltage side of DC Converter overcurrent fault")// - .label(64, "DC Converter IGBT fault")// - .label(128, "DC Converter Precharge unmet"))), + new UnsignedWordElement(0xA710,// + // prefix = "PvDCDC" + new ModbusBitWrappingChannel("PvDCDCAbnormity1", this, this.thingState)// + .faultBit(0, FaultCharger.PvDCDCHighVoltageSideOfDCConverterUndervoltage)// + .faultBit(1, FaultCharger.PvDCDCHighVoltageSideOfDCConverterOvervoltage)// + .faultBit(2, FaultCharger.PvDCDCLowVoltageSideOfDCConverterUndervoltage)// + .faultBit(3, FaultCharger.PvDCDCLowVoltageSideOfDCConverterOvervoltage)// + .faultBit(4, FaultCharger.PvDCDCHighVoltageSideOfDCConverterOvercurrentFault)// + .faultBit(5, FaultCharger.PvDCDCLowVoltageSideOfDCConverterOvercurrentFault)// + .faultBit(6, FaultCharger.PvDCDCDCConverterIGBTFault)// + .faultBit(7, FaultCharger.PvDCDCDCConverterPrechargeUnmet)// + ),// + new UnsignedWordElement(0xA711, - pvDCDCAbnormity2 = warning.channel(new StatusBitChannel("PvDCDCAbnormity2", this)// - .label(1, "BECU communication disconnected")// - .label(2, "DC Converter communication disconnected")// - .label(4, "Current configuration over range")// - .label(8, "The battery request stop")// - .label(32, "Overcurrent relay fault")// - .label(64, "Lightning protection device fault")// - .label(128, "DC Converter priamary contactor disconnected abnormally")// - .label(512, "DC disconnected abnormally on low voltage side of DC convetor")// - .label(4096, "DC convetor EEPROM abnormity 1")// - .label(8192, "DC convetor EEPROM abnormity 1")// - .label(16384, "EDC convetor EEPROM abnormity 1"))), - new UnsignedWordElement(0xA712, - pvDCDCAbnormity3 = warning.channel(new StatusBitChannel("PvDCDCAbnormity3", this)// - .label(1, "DC Convertor general overload")// - .label(2, "DC short circuit")// - .label(4, "Peak pulse current protection")// - .label(8, "DC disconnect abnormally on high voltage side of DC convetor")// - .label(16, "Effective pulse value overhigh")// - .label(32, "DC Converte severe overload")// - .label(64, - "DC breaker disconnect abnormally on high voltage side of DC convetor")// - .label(128, - "DC breaker disconnect abnormally on low voltage side of DC convetor")// - .label(256, "DC convetor precharge contactor close failed ")// - .label(512, "DC convetor main contactor close failed")// - .label(1024, "AC contactor state abnormity of DC convetor")// - .label(2048, "DC convetor emergency stop")// - .label(4096, "DC converter charging gun disconnected")// - .label(8192, "DC current abnormity before DC convetor work")// - .label(16384, "Fuse disconnected")// - .label(32768, "DC converter hardware current or voltage fault"))), - new UnsignedWordElement(0xA713, - pvDCDCAbnormity4 = warning.channel(new StatusBitChannel("PvDCDCAbnormity4", this)// - .label(1, "DC converter crystal oscillator circuit invalidation")// - .label(2, "DC converter reset circuit invalidation")// - .label(4, "DC converter sampling circuit invalidation")// - .label(8, "DC converter digital I/O circuit invalidation")// - .label(16, "DC converter PWM circuit invalidation")// - .label(32, "DC converter X5045 circuit invalidation")// - .label(64, "DC converter CAN circuit invalidation")// - .label(128, "DC converter software&hardware protection circuit invalidation")// - .label(256, "DC converter power circuit invalidation")// - .label(512, "DC converter CPU invalidation")// - .label(1024, "DC converter TINT0 interrupt invalidation")// - .label(2048, "DC converter ADC interrupt invalidation")// - .label(4096, "DC converter CAPITN4 interrupt invalidation")// - .label(8192, "DC converter CAPINT6 interrupt invalidation")// - .label(16384, "DC converter T3PINTinterrupt invalidation")// - .label(32768, "DC converter T4PINTinterrupt invalidation"))), + // prefix = "PvDCDC" + new ModbusBitWrappingChannel("PvDCDCAbnormity2", this, this.thingState)// + .faultBit(0, FaultCharger.PvDCDCBECUCommunicationDisconnected)// + .faultBit(1, FaultCharger.PvDCDCDCConverterCommunicationDisconnected)// + .faultBit(2, FaultCharger.PvDCDCCurrentConfigurationOverRange)// + .faultBit(3, FaultCharger.PvDCDCTheBatteryRequestStop)// + .faultBit(5, FaultCharger.PvDCDCOvercurrentRelayFault)// + .faultBit(6, FaultCharger.PvDCDCLightningProtectionDeviceFault)// + .faultBit(7, FaultCharger.PvDCDCDCConverterPriamaryContactorDisconnectedAbnormally)// + .faultBit(9, FaultCharger.PvDCDCDCDisconnectedAbnormallyOnLowVoltageSideOfDCConvetor)// + .faultBit(12,FaultCharger.PvDCDCDCConvetorEEPROMAbnormity1)// + .faultBit(13,FaultCharger.PvDCDCDCConvetorEEPROMAbnormity1Second)// + .faultBit(14,FaultCharger.PvDCDCEDCConvetorEEPROMAbnormity1)// + ),// + + new UnsignedWordElement(0xA712,// + // prefix = "PvDCDC" + new ModbusBitWrappingChannel("PvDCDCAbnormity3", this, this.thingState)// + .faultBit(0, FaultCharger.PvDCDCDCConvertorGeneralOverload)// + .faultBit(1, FaultCharger.PvDCDCDCShortCircuit)// + .faultBit(2, FaultCharger.PvDCDCPeakPulseCurrentProtection)// + .faultBit(3, FaultCharger.PvDCDCDCDisconnectAbnormallyOnHighVoltageSideOfDCConvetor)// + .faultBit(4, FaultCharger.PvDCDCEffectivePulseValueOverhigh)// + .faultBit(5, FaultCharger.PvDCDCDCConverteSevereOverload)// + .faultBit(6, FaultCharger.PvDCDCDCBreakerDisconnectAbnormallyOnHighVoltageSideOfDCConvetor)// + .faultBit(7, FaultCharger.PvDCDCDCBreakerDisconnectAbnormallyOnLowVoltageSideOfDCConvetor)// + .faultBit(8, FaultCharger.PvDCDCDCConvetorPrechargeContactorCloseFailed)// + .faultBit(9, FaultCharger.PvDCDCDCConvetorMainContactorCloseFailed)// + .faultBit(10,FaultCharger.PvDCDCACContactorStateAbnormityOfDCConvetor)// + .faultBit(11,FaultCharger.PvDCDCDCConvetorEmergencyStop)// + .faultBit(12,FaultCharger.PvDCDCDCConverterChargingGunDisconnected)// + .faultBit(13,FaultCharger.PvDCDCDCCurrentAbnormityBeforeDCConvetorWork)// + .faultBit(14,FaultCharger.PvDCDCFuSeDisconnected)// + .faultBit(15,FaultCharger.PvDCDCDCConverterHardwareCurrentOrVoltageFault)// + ),// + + new UnsignedWordElement(0xA713,// + // prefix = "PvDCDC" + new ModbusBitWrappingChannel("PvDCDCAbnormity4", this, this.thingState)// + .faultBit(0, FaultCharger.PvDCConverterCrystalOscillatorCircuitInvalidation)// + .faultBit(1, FaultCharger.PvDCConverterResetCircuitInvalidation)// + .faultBit(2, FaultCharger.PvDCConverterSamplingCircuitInvalidation)// + .faultBit(3, FaultCharger.PvDCConverterDigitalIOCircuitInvalidation)// + .faultBit(4, FaultCharger.PvDCConverterPWMCircuitInvalidation)// + .faultBit(5, FaultCharger.PvDCConverterX5045CircuitInvalidation)// + .faultBit(6, FaultCharger.PvDCConverterCANCircuitInvalidation)// + .faultBit(7, FaultCharger.PvDCConverterSoftwareANDHardwareProtectionCircuitInvalidation)// + .faultBit(8, FaultCharger.PvDCConverterPowerCircuitInvalidation)// + .faultBit(9, FaultCharger.PvDCConverterCPUInvalidation)// + .faultBit(10,FaultCharger.PvDCConverterT1PINTInterruptInvalidation)// + .faultBit(11,FaultCharger.PvDCConverterADCInterruptInvalidation)// + .faultBit(12,FaultCharger.PvDCConverterCAPITN4InterruptInvalidation)// + .faultBit(13,FaultCharger.PvDCConverterCAPINT6InterruptInvalidation)// + .faultBit(14,FaultCharger.PvDCConverterT3PINTinterruptInvalidation)// + .faultBit(15,FaultCharger.PvDCConverterT4PINTinterruptInvalidation)// + ),// + new UnsignedWordElement(0xA714, - pvDCDCAbnormity5 = warning.channel(new StatusBitChannel("PvDCDCAbnormity5", this)// - .label(1, "DC converter PDPINTA interrupt invalidation")// - .label(2, "DC converter T1PINT interrupt invalidation")// - .label(4, "DC converter RESV interrupt invalidation")// - .label(8, "DC converter 100us task invalidation")// - .label(16, "DC converter clock invalidation")// - .label(32, "DC converter EMS memory invalidation")// - .label(64, "DC converter exterior communication invalidation")// - .label(128, "DC converter IO Interface invalidation")// - .label(256, "DC converter Input Voltage bound fault")// - .label(512, "DC converter Outter Voltage bound fault")// - .label(1024, "DC converter Output Voltage bound fault")// - .label(2048, "DC converter Induct Current bound fault")// - .label(4096, "DC converter Input Current bound fault")// - .label(8192, "DC converter Output Current bound fault"))), - new UnsignedWordElement(0xA715, - pvDCDCAbnormity6 = warning.channel(new StatusBitChannel("PvDCDCAbnormity6", this)// - .label(1, "DC Reactor over temperature")// - .label(2, "DC IGBT over temperature")// - .label(4, "DC Converter chanel 3 over temperature")// - .label(8, "DC Converter chanel 4 over temperature")// - .label(16, "DC Converter chanel 5 over temperature")// - .label(32, "DC Converter chanel 6 over temperature")// - .label(64, "DC Converter chanel 7 over temperature")// - .label(128, "DC Converter chanel 8 over temperature")// - .label(256, "DC Reactor temperature sampling invalidation")// - .label(512, "DC IGBT temperature sampling invalidation")// - .label(1024, "DC Converter chanel 3 temperature sampling invalidation")// - .label(2048, "DC Converter chanel 4 temperature sampling invalidation")// - .label(4096, "DC Converter chanel 5 temperature sampling invalidation")// - .label(8192, "DC Converter chanel 6 temperature sampling invalidation")// - .label(16384, "DC Converter chanel 7 temperature sampling invalidation")// - .label(32768, "DC Converter chanel 8 temperature sampling invalidation"))), - new UnsignedWordElement(0xA716, - pvDCDCAbnormity7 = warning.channel(new StatusBitChannel("PvDCDCAbnormity7", this)// - .label(32, "DC Converter inductance current sampling invalidation")// - .label(64, - "Current sampling invalidation on the low voltage sideof DC Converter")// - .label(128, - "Voltage sampling invalidation on the low voltage side of DC Converter")// - .label(256, "Insulation inspection fault")// - .label(512, "NegContactor close unsuccessly")// - .label(1024, "NegContactor cut When running"))), + // prefix = "PvDCDC" + new ModbusBitWrappingChannel("PvDCDCAbnormity5", this, this.thingState)// + .faultBit(0, FaultCharger.PvDCConverterPDPINTAInterruptInvalidation)// + .faultBit(1, FaultCharger.BvDCConverterT1PINTInterruptInvalidationSecond)// + .faultBit(2, FaultCharger.PvDCConverterRESVInterruptInvalidation)// + .faultBit(3, FaultCharger.PvDCConverter100usTaskInvalidation)// + .faultBit(4, FaultCharger.PvDCConverterClockInvalidation)// + .faultBit(5, FaultCharger.PvDCConverterEMSMemoryInvalidation)// + .faultBit(6, FaultCharger.PvDCConverterExteriorCommunicationInvalidation)// + .faultBit(7, FaultCharger.PvDCConverterIOInterfaceInvalidation)// + .faultBit(8, FaultCharger.PvDCConverterInputVoltageBoundFault)// + .faultBit(9, FaultCharger.PvDCConverterOutterVoltageBoundFault)// + .faultBit(10,FaultCharger.PvDCConverterOutputVoltageBoundFault)// + .faultBit(11,FaultCharger.PvDCConverterInductCurrentBoundFault)// + .faultBit(12,FaultCharger.PvDCConverterInputCurrentBoundFault)// + .faultBit(13,FaultCharger.PvDCConverterOutputCurrentBoundFault)// + ),// + + new UnsignedWordElement(0xA715,// + // prefix = "PvDCDC" + new ModbusBitWrappingChannel("PvDCDCAbnormity6", this, this.thingState)// + .faultBit(0, FaultCharger.PvDCDCDCReactorOverTemperature)// + .faultBit(1, FaultCharger.PvDCDCDCIGBTOverTemperature)// + .faultBit(2, FaultCharger.PvDCDCDCConverterChanel3OverTemperature)// + .faultBit(3, FaultCharger.PvDCDCDCConverterChanel4OverTemperature)// + .faultBit(4, FaultCharger.PvDCDCDCConverterChanel5OverTemperature)// + .faultBit(5, FaultCharger.PvDCDCDCConverterChanel6OverTemperature)// + .faultBit(6, FaultCharger.PvDCDCDCConverterChanel7OverTemperature)// + .faultBit(7, FaultCharger.PvDCDCDCConverterChanel8OverTemperature)// + .faultBit(8, FaultCharger.PvDCDCDCReactorTemperatureSamplingInvalidation)// + .faultBit(9, FaultCharger.PvDCDCDCIGBTTemperatureSamplingInvalidation)// + .faultBit(10,FaultCharger.PvDCDCDCConverterChanel3TemperatureSamplingInvalidation)// + .faultBit(11,FaultCharger.PvDCDCDCConverterChanel4TemperatureSamplingInvalidation)// + .faultBit(12,FaultCharger.PvDCDCDCConverterChanel5TemperatureSamplingInvalidation)// + .faultBit(13,FaultCharger.PvDCDCDCConverterChanel6TemperatureSamplingInvalidation)// + .faultBit(14,FaultCharger.PvDCDCDCConverterChanel7TemperatureSamplingInvalidation)// + .faultBit(15,FaultCharger.PvDCDCDCConverterChanel8TemperatureSamplingInvalidation)// + ),// + + new UnsignedWordElement(0xA716,// + // prefix = "PvDCDC" + new ModbusBitWrappingChannel("PvDCDCAbnormity7", this, this.thingState)// + .faultBit(4, FaultCharger.PvDCDCDCConverterInductanceCurrentSamplingInvalidation)// + .faultBit(5, FaultCharger.PvDCDCCurrentSamplingInvalidationOnTheLowVoltageSideOfDCConverter)// + .faultBit(6, FaultCharger.PvDCDCVoltageSamplingInvalidationOnTheLowVoltageSideOfDCConverter)// + .faultBit(7, FaultCharger.PvDCDCInsulationInspectionFault)// + .faultBit(8, FaultCharger.PvDCDCNegContactorCloseUnsuccessly)// + .faultBit(9, FaultCharger.PvDCDCNegContactorCutWhenRunning)// + ),// + new DummyElement(0xA717, 0xA71F), new UnsignedWordElement(0xA720, pvDCDCSwitchState = new StatusBitChannel("PvDCDCSwitchState", this)// @@ -956,169 +1023,192 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { .label(256, "Constant Voltage")// .label(512, "Boost MPPT"))), new ModbusRegisterRange(0xAA00, // - new UnsignedWordElement(0xAA00, - pvDCDC1SuggestiveInformation1 = warning - .channel(new StatusBitChannel("PvDCDC1SuggestiveInformation1", this)// - .label(1, "Current sampling channel abnormity on high voltage side")// - .label(2, "Current sampling channel abnormity on low voltage side")// - .label(64, "EEPROM parameters over range")// - .label(128, "Update EEPROM failed")// - .label(256, "Read EEPROM failed")// - .label(512, "Current sampling channel abnormity before inductance"))), - new UnsignedWordElement(0xAA01, pvDCDC1SuggestiveInformation2 = warning - .channel(new StatusBitChannel("PvDCDC1SuggestiveInformation2", this)// - .label(1, "Reactor power decrease caused by overtemperature")// - .label(2, "IGBT power decrease caused by overtemperature")// - .label(4, "Temperature chanel3 power decrease caused by overtemperature")// - .label(8, "Temperature chanel4 power decrease caused by overtemperature")// - .label(16, "Temperature chanel5 power decrease caused by overtemperature")// - .label(32, "Temperature chanel6 power decrease caused by overtemperature")// - .label(64, "Temperature chanel7 power decrease caused by overtemperature")// - .label(128, "Temperature chanel8 power decrease caused by overtemperature")// - .label(256, "Fan 1 stop failed")// - .label(512, "Fan 2 stop failed")// - .label(1024, "Fan 3 stop failed")// - .label(2048, "Fan 4 stop failed")// - .label(4096, "Fan 1 sartup failed")// - .label(8192, "Fan 2 sartup failed")// - .label(16384, "Fan 3 sartup failed")// - .label(32768, "Fan 4 sartup failed"))), - new UnsignedWordElement(0xAA02, - pvDCDC1SuggestiveInformation3 = warning - .channel(new StatusBitChannel("PvDCDC1SuggestiveInformation3", this)// - .label(1, "High voltage side overvoltage")// - .label(2, "High voltage side undervoltage")// - .label(4, "EEPROM parameters over range")// - .label(8, "High voltage side voltage change unconventionally"))), - new UnsignedWordElement(0xAA03, pvDCDC1SuggestiveInformation4 = warning - .channel(new StatusBitChannel("PvDCDC1SuggestiveInformation4", this)// - .label(1, "Current abnormity before DC Converter work on high voltage side")// - .label(2, "Current abnormity before DC Converter work on low voltage side")// - .label(4, "Initial Duty Ratio abnormity before DC Converter work")// - .label(8, "Voltage abnormity before DC Converter work on high voltage side")// - .label(16, "Voltage abnormity before DC Converter work on low voltage side"))), + new UnsignedWordElement(0xAA00,// + // Prefix = "PvDCDC1 " + new ModbusBitWrappingChannel("PvDCDC1SuggestiveInformation1", this, this.thingState)// + .warningBit(0, WarningCharger.PvDCDC1CurrentSamplingChannelAbnormityOnHighVoltageSide)// + .warningBit(1, WarningCharger.PvDCDC1CurrentSamplingChannelAbnormityOnLowVoltageSide)// + .warningBit(6, WarningCharger.PvDCDC1EEPROMParametersOverRange)// + .warningBit(7, WarningCharger.PvDCDC1UpdateEEPROMFailed)// + .warningBit(8, WarningCharger.PvDCDC1ReadEEPROMFailed)// + .warningBit(9, WarningCharger.PvDCDC1CurrentSamplingChannelAbnormityBeforeInductance)// + ),// + + new UnsignedWordElement(0xAA01, // + // Prefix = "PvDCDC1" + new ModbusBitWrappingChannel("PvDCDC1SuggestiveInformation2", this, this.thingState)// + .warningBit(0, WarningCharger.PvDCDC1ReactorPowerDecreaseCausedByOvertemperature)// + .warningBit(1, WarningCharger.PvDCDC1IGBTPowerDecreaseCausedByOvertemperature)// + .warningBit(2, WarningCharger.PvDCDC1TemperatureChanel3PowerDecreaseCausedByOvertemperature)// + .warningBit(3, WarningCharger.PvDCDC1TemperatureChanel4PowerDecreaseCausedByOvertemperature)// + .warningBit(4, WarningCharger.PvDCDC1TemperatureChanel5PowerDecreaseCausedByOvertemperature)// + .warningBit(5, WarningCharger.PvDCDC1TemperatureChanel6PowerDecreaseCausedByOvertemperature)// + .warningBit(6, WarningCharger.PvDCDC1TemperatureChanel7PowerDecreaseCausedByOvertemperature)// + .warningBit(7, WarningCharger.PvDCDC1TemperatureChanel8PowerDecreaseCausedByOvertemperature)// + .warningBit(8, WarningCharger.PvDCDC1Fan1StopFailed)// + .warningBit(9, WarningCharger.PvDCDC1Fan2StopFailed)// + .warningBit(10,WarningCharger.PvDCDC1Fan3StopFailed)// + .warningBit(11,WarningCharger.PvDCDC1Fan4StopFailed)// + .warningBit(12,WarningCharger.PvDCDC1Fan1StartupFailed)// + .warningBit(13,WarningCharger.PvDCDC1Fan2StartupFailed)// + .warningBit(14,WarningCharger.PvDCDC1Fan3StartupFailed)// + .warningBit(15,WarningCharger.PvDCDC1Fan4StartupFailed)// + ),// + + new UnsignedWordElement(0xAA02,// + // prefix = "PvDCDC1" + new ModbusBitWrappingChannel("PvDCDC1SuggestiveInformation3", this, this.thingState)// + .warningBit(0, WarningCharger.PvDCDC1HighVoltageSideOvervoltage)// + .warningBit(1, WarningCharger.PvDCDC1HighVoltageSideUndervoltage)// + .warningBit(2, WarningCharger.PvDCDC1HighVoltageSideVoltageChangeUnconventionally)// + ),// + + new UnsignedWordElement(0xAA03,// + //prefix = "PvDCDC1" + new ModbusBitWrappingChannel("PvDCDC1SuggestiveInformation4", this, this.thingState)// + .warningBit(0, WarningCharger.PvDCDC1CurrentAbnormityBeforeDCConverterWorkOnHighVoltageSide) + .warningBit(1, WarningCharger.PvDCDC1CurrentAbnormityBeforeDCConverterWorkOnLowVoltageSXide) + .warningBit(2, WarningCharger.PvDCDC1InitialDutyRatioAbnormityBeforeDCConverterWork) + .warningBit(3, WarningCharger.PvDCDC1VoltageAbnormityBeforeDCConverterWorkOnHighVoltageSide) + .warningBit(4, WarningCharger.PvDCDC1VoltageAbnormityBeforeDCConverterWorkOnLowVoltageSide) + ),// + new UnsignedWordElement(0xAA04, - pvDCDC1SuggestiveInformation5 = warning - .channel(new StatusBitChannel("PvDCDC1SuggestiveInformation5", this)// - .label(1, "High voltage breaker inspection abnormity")// - .label(2, "Low voltage breaker inspection abnormity")// - .label(4, "DC precharge contactor inspection abnormity")// - .label(8, "DC precharge contactor open unsuccessfully")// - .label(16, "DC main contactor inspection abnormity")// - .label(32, "DC main contactor open unsuccessfully")// - .label(64, "Output contactor close unsuccessfully")// - .label(128, "Output contactor open unsuccessfully")// - .label(256, "AC main contactor close unsuccessfully")// - .label(512, "AC main contactor open unsuccessfully")// - .label(1024, "NegContactor open unsuccessfully")// - .label(2048, "NegContactor close unsuccessfully")// - .label(4096, "NegContactor state abnormal"))), + //prefix = "PvDCDC1" + new ModbusBitWrappingChannel("PvDCDC1SuggestiveInformation5", this, this.thingState)// + .warningBit(0, WarningCharger.PvDCDC1HighVoltageBreakerInspectionAbnormity)// + .warningBit(1, WarningCharger.PvDCDC1LowVoltageBreakerInspectionAbnormity)// + .warningBit(2, WarningCharger.PvDCDC1BsmDCDC5DCPrechargeContactorInspectionAbnormity)// + .warningBit(3, WarningCharger.PvDCDC1DCPrechargeContactorOpenUnsuccessfully)// + .warningBit(4, WarningCharger.PvDCDC1DCMainContactorInspectionAbnormity)// + .warningBit(5, WarningCharger.PvDCDC1DCMainContactorOpenUnsuccessfully)// + .warningBit(6, WarningCharger.PvDCDC1OutputContactorCloseUnsuccessfully)// + .warningBit(7, WarningCharger.PvDCDC1OutputContactorOpenUnsuccessfully)// + .warningBit(8, WarningCharger.PvDCDC1ACMainContactorCloseUnsuccessfully)// + .warningBit(9, WarningCharger.PvDCDC1ACMainContactorOpenUnsuccessfully)// + .warningBit(10,WarningCharger.PvDCDC1NegContactorOpenUnsuccessfully)// + .warningBit(11,WarningCharger.PvDCDC1NegContactorCloseUnsuccessfully)// + .warningBit(12,WarningCharger.PvDCDC1NegContactorStateAbnormal)// + ),// + new DummyElement(0xAA05, 0xAA0F), - new UnsignedWordElement(0xAA10, - pvDCDC1Abnormity1 = warning.channel(new StatusBitChannel("PvDCDC1Abnormity1", this)// - .label(1, "High voltage side of DC Converter undervoltage")// - .label(2, "High voltage side of DC Converter overvoltage")// - .label(4, "Low voltage side of DC Converter undervoltage")// - .label(8, "Low voltage side of DC Converter overvoltage")// - .label(16, "High voltage side of DC Converter overcurrent fault")// - .label(32, "Low voltage side of DC Converter overcurrent fault")// - .label(64, "DC Converter IGBT fault")// - .label(128, "DC Converter Precharge unmet"))), - new UnsignedWordElement(0xAA11, - pvDCDC1Abnormity2 = warning.channel(new StatusBitChannel("PvDCDC1Abnormity2", this)// - .label(1, "BECU communication disconnected")// - .label(2, "DC Converter communication disconnected")// - .label(4, "Current configuration over range")// - .label(8, "The battery request stop")// - .label(32, "Overcurrent relay fault")// - .label(64, "Lightning protection device fault")// - .label(128, "DC Converter priamary contactor disconnected abnormally")// - .label(512, "DC disconnected abnormally on low voltage side of DC convetor")// - .label(4096, "DC convetor EEPROM abnormity 1")// - .label(8192, "DC convetor EEPROM abnormity 1")// - .label(16384, "EDC convetor EEPROM abnormity 1"))), + new UnsignedWordElement(0xAA10,// + // prefix = "PvDCDC1" + new ModbusBitWrappingChannel("PvDCDC1Abnormity1", this, this.thingState)// + .faultBit(0, FaultCharger.PvDCDC1HighVoltageSideOfDCConverterUndervoltage)// + .faultBit(1, FaultCharger.PvDCDC1HighVoltageSideOfDCConverterOvervoltage)// + .faultBit(2, FaultCharger.PvDCDC1LowVoltageSideOfDCConverterUndervoltage)// + .faultBit(3, FaultCharger.PvDCDC1LowVoltageSideOfDCConverterOvervoltage)// + .faultBit(4, FaultCharger.PvDCDC1HighVoltageSideOfDCConverterOvercurrentFault)// + .faultBit(5, FaultCharger.PvDCDC1LowVoltageSideOfDCConverterOvercurrentFault)// + .faultBit(6, FaultCharger.PvDCDC1DCConverterIGBTFault)// + .faultBit(7, FaultCharger.PvDCDC1DCConverterPrechargeUnmet)// + ),// + + new UnsignedWordElement(0xAA11,// + // prefix = "PvDCDC1" + new ModbusBitWrappingChannel("PvDCDC1Abnormity2", this, this.thingState)// + .faultBit(0, FaultCharger.PvDCDC1BECUCommunicationDisconnected)// + .faultBit(1, FaultCharger.PvDCDC1DCConverterCommunicationDisconnected)// + .faultBit(2, FaultCharger.PvDCDC1CurrentConfigurationOverRange)// + .faultBit(3, FaultCharger.PvDCDC1TheBatteryRequestStop)// + .faultBit(5, FaultCharger.PvDCDC1OvercurrentRelayFault)// + .faultBit(6, FaultCharger.PvDCDC1LightningProtectionDeviceFault)// + .faultBit(7, FaultCharger.PvDCDC1DCConverterPriamaryContactorDisconnectedAbnormally)// + .faultBit(9, FaultCharger.PvDCDC1DCDisconnectedAbnormallyOnLowVoltageSideOfDCConvetor)// + .faultBit(12,FaultCharger.PvDCDC1DCConvetorEEPROMAbnormity1)// + .faultBit(13,FaultCharger.PvDCDC1DCConvetorEEPROMAbnormity1Second)// + .faultBit(14,FaultCharger.PvDCDC1EDCConvetorEEPROMAbnormity1)// + ),// + new UnsignedWordElement(0xAA12, - pvDCDC1Abnormity3 = warning.channel(new StatusBitChannel("PvDCDC1Abnormity3", this)// - .label(1, "DC Convertor general overload")// - .label(2, "DC short circuit")// - .label(4, "Peak pulse current protection")// - .label(8, "DC disconnect abnormally on high voltage side of DC convetor")// - .label(16, "Effective pulse value overhigh")// - .label(32, "DC Converte severe overload")// - .label(64, - "DC breaker disconnect abnormally on high voltage side of DC convetor")// - .label(128, - "DC breaker disconnect abnormally on low voltage side of DC convetor")// - .label(256, "DC convetor precharge contactor close failed ")// - .label(512, "DC convetor main contactor close failed")// - .label(1024, "AC contactor state abnormity of DC convetor")// - .label(2048, "DC convetor emergency stop")// - .label(4096, "DC converter charging gun disconnected")// - .label(8192, "DC current abnormity before DC convetor work")// - .label(16384, "Fuse disconnected")// - .label(32768, "DC converter hardware current or voltage fault"))), + // prefix = "PvDCDC1" + new ModbusBitWrappingChannel("PvDCDC1Abnormity3", this, this.thingState)// + .faultBit(0, FaultCharger.PvDCDC1DCConvertorGeneralOverload)// + .faultBit(1, FaultCharger.PvDCDC1DCShortCircuit)// + .faultBit(2, FaultCharger.PvDCDC1PeakPulseCurrentProtection)// + .faultBit(3, FaultCharger.PvDCDC1DCDisconnectAbnormallyOnHighVoltageSideOfDCConvetor)// + .faultBit(4, FaultCharger.PvDCDC1EffectivePulseValueOverhigh)// + .faultBit(5, FaultCharger.PvDCDC1DCConverteSevereOverload)// + .faultBit(6, FaultCharger.PvDCDC1DCBreakerDisconnectAbnormallyOnHighVoltageSideOfDCConvetor)// + .faultBit(7, FaultCharger.PvDCDC1DCBreakerDisconnectAbnormallyOnLowVoltageSideOfDCConvetor)// + .faultBit(8, FaultCharger.PvDCDC1DCConvetorPrechargeContactorCloseFailed)// + .faultBit(9, FaultCharger.PvDCDC1DCConvetorMainContactorCloseFailed)// + .faultBit(10,FaultCharger.PvDCDC1ACContactorStateAbnormityOfDCConvetor)// + .faultBit(11,FaultCharger.PvDCDC1DCConvetorEmergencyStop)// + .faultBit(12,FaultCharger.PvDCDC1DCConverterChargingGunDisconnected)// + .faultBit(13,FaultCharger.PvDCDC1DCCurrentAbnormityBeforeDCConvetorWork)// + .faultBit(14,FaultCharger.PvDCDC1FuSeDisconnected)// + .faultBit(15,FaultCharger.PvDCDC1DCConverterHardwareCurrentOrVoltageFault)// + ),// new UnsignedWordElement(0xAA13, - pvDCDC1Abnormity4 = warning.channel(new StatusBitChannel("PvDCDC1Abnormity4", this)// - .label(1, "DC converter crystal oscillator circuit invalidation")// - .label(2, "DC converter reset circuit invalidation")// - .label(4, "DC converter sampling circuit invalidation")// - .label(8, "DC converter digital I/O circuit invalidation")// - .label(16, "DC converter PWM circuit invalidation")// - .label(32, "DC converter X5045 circuit invalidation")// - .label(64, "DC converter CAN circuit invalidation")// - .label(128, "DC converter software&hardware protection circuit invalidation")// - .label(256, "DC converter power circuit invalidation")// - .label(512, "DC converter CPU invalidation")// - .label(1024, "DC converter TINT0 interrupt invalidation")// - .label(2048, "DC converter ADC interrupt invalidation")// - .label(4096, "DC converter CAPITN4 interrupt invalidation")// - .label(8192, "DC converter CAPINT6 interrupt invalidation")// - .label(16384, "DC converter T3PINTinterrupt invalidation")// - .label(32768, "DC converter T4PINTinterrupt invalidation"))), + // prefix = "PvDCDC1" + new ModbusBitWrappingChannel("PvDCDC1Abnormity4", this, this.thingState)// + .faultBit(0, FaultCharger.PvDCDC1DCConverterCrystalOscillatorCircuitInvalidation)// + .faultBit(1, FaultCharger.PvDCDC1DCConverterResetCircuitInvalidation)// + .faultBit(2, FaultCharger.PvDCDC1DCConverterSamplingCircuitInvalidation)// + .faultBit(3, FaultCharger.PvDCDC1DCConverterDigitalIOCircuitInvalidation)// + .faultBit(4, FaultCharger.PvDCDC1DCConverterPWMCircuitInvalidation)// + .faultBit(5, FaultCharger.PvDCDC1DCConverterX5045CircuitInvalidation)// + .faultBit(6, FaultCharger.PvDCDC1DCConverterCANCircuitInvalidation)// + .faultBit(7, FaultCharger.PvDCDC1DCConverterSoftwareANDHardwareProtectionCircuitInvalidation)// + .faultBit(8, FaultCharger.PvDCDC1DCConverterPowerCircuitInvalidation)// + .faultBit(9, FaultCharger.PvDCDC1DCConverterCPUInvalidation)// + .faultBit(10,FaultCharger.PvDCDC1DCConverterT1PINTInterruptInvalidation)// + .faultBit(11,FaultCharger.PvDCDC1DCConverterADCInterruptInvalidation)// + .faultBit(12,FaultCharger.PvDCDC1DCConverterCAPITN4InterruptInvalidation)// + .faultBit(13,FaultCharger.PvDCDC1DCConverterCAPINT6InterruptInvalidation)// + .faultBit(14,FaultCharger.PvDCDC1DCConverterT3PINTinterruptInvalidation)// + .faultBit(15,FaultCharger.PvDCDC1DCConverterT4PINTinterruptInvalidation)// + ),// new UnsignedWordElement(0xAA14, - pvDCDC1Abnormity5 = warning.channel(new StatusBitChannel("PvDCDC1Abnormity5", this)// - .label(1, "DC converter PDPINTA interrupt invalidation")// - .label(2, "DC converter T1PINT interrupt invalidation")// - .label(4, "DC converter RESV interrupt invalidation")// - .label(8, "DC converter 100us task invalidation")// - .label(16, "DC converter clock invalidation")// - .label(32, "DC converter EMS memory invalidation")// - .label(64, "DC converter exterior communication invalidation")// - .label(128, "DC converter IO Interface invalidation")// - .label(256, "DC converter Input Voltage bound fault")// - .label(512, "DC converter Outter Voltage bound fault")// - .label(1024, "DC converter Output Voltage bound fault")// - .label(2048, "DC converter Induct Current bound fault")// - .label(4096, "DC converter Input Current bound fault")// - .label(8192, "DC converter Output Current bound fault"))), + // prefix = "PvDCDC1" + new ModbusBitWrappingChannel("PvDCDC1Abnormity5", this, this.thingState)// + .faultBit(0, FaultCharger.PvDCDC1DCConverterPDPINTAInterruptInvalidation)// + .faultBit(1, FaultCharger.PvDCDC1DCConverterT1PINTInterruptInvalidationSecond)// + .faultBit(2, FaultCharger.PvDCDC1DCConverterRESVInterruptInvalidation)// + .faultBit(3, FaultCharger.PvDCDC1DCConverter100usTaskInvalidation)// + .faultBit(4, FaultCharger.PvDCDC1DCConverterClockInvalidation)// + .faultBit(5, FaultCharger.PvDCDC1DCConverterEMSMemoryInvalidation)// + .faultBit(6, FaultCharger.PvDCDC1DCConverterExteriorCommunicationInvalidation)// + .faultBit(7, FaultCharger.PvDCDC1DCConverterIOInterfaceInvalidation)// + .faultBit(8, FaultCharger.PvDCDC1DCConverterInputVoltageBoundFault)// + .faultBit(9, FaultCharger.PvDCDC1DCConverterOutterVoltageBoundFault)// + .faultBit(10,FaultCharger.PvDCDC1DCConverterOutputVoltageBoundFault)// + .faultBit(11,FaultCharger.PvDCDC1DCConverterInductCurrentBoundFault)// + .faultBit(12,FaultCharger.PvDCDC1DCConverterInputCurrentBoundFault)// + .faultBit(13,FaultCharger.PvDCDC1DCConverterOutputCurrentBoundFault)// + ),// new UnsignedWordElement(0xAA15, - pvDCDC1Abnormity6 = warning.channel(new StatusBitChannel("PvDCDC1Abnormity6", this)// - .label(1, "DC Reactor over temperature")// - .label(2, "DC IGBT over temperature")// - .label(4, "DC Converter chanel 3 over temperature")// - .label(8, "DC Converter chanel 4 over temperature")// - .label(16, "DC Converter chanel 5 over temperature")// - .label(32, "DC Converter chanel 6 over temperature")// - .label(64, "DC Converter chanel 7 over temperature")// - .label(128, "DC Converter chanel 8 over temperature")// - .label(256, "DC Reactor temperature sampling invalidation")// - .label(512, "DC IGBT temperature sampling invalidation")// - .label(1024, "DC Converter chanel 3 temperature sampling invalidation")// - .label(2048, "DC Converter chanel 4 temperature sampling invalidation")// - .label(4096, "DC Converter chanel 5 temperature sampling invalidation")// - .label(8192, "DC Converter chanel 6 temperature sampling invalidation")// - .label(16384, "DC Converter chanel 7 temperature sampling invalidation")// - .label(32768, "DC Converter chanel 8 temperature sampling invalidation"))), + //prefix = "PvDCDC1" + new ModbusBitWrappingChannel("PvDCDC1Abnormity6", this, this.thingState)// + .faultBit(0, FaultCharger.PvDCDC1DCReactorOverTemperature)// + .faultBit(1, FaultCharger.PvDCDC1DCIGBTOverTemperature)// + .faultBit(2, FaultCharger.PvDCDC1DCConverterChanel3OverTemperature)// + .faultBit(3, FaultCharger.PvDCDC1DCConverterChanel4OverTemperature)// + .faultBit(4, FaultCharger.PvDCDC1DCConverterChanel5OverTemperature)// + .faultBit(5, FaultCharger.PvDCDC1DCConverterChanel6OverTemperature)// + .faultBit(6, FaultCharger.PvDCDC1DCConverterChanel7OverTemperature)// + .faultBit(7, FaultCharger.PvDCDC1DCConverterChanel8OverTemperature)// + .faultBit(8, FaultCharger.PvDCDC1DCReactorTemperatureSamplingInvalidation)// + .faultBit(9, FaultCharger.PvDCDC1DCIGBTTemperatureSamplingInvalidation)// + .faultBit(10,FaultCharger.PvDCDC1DCConverterChanel3TemperatureSamplingInvalidation)// + .faultBit(11,FaultCharger.PvDCDC1DCConverterChanel4TemperatureSamplingInvalidation)// + .faultBit(12,FaultCharger.PvDCDC1DCConverterChanel5TemperatureSamplingInvalidation)// + .faultBit(13,FaultCharger.PvDCDC1DCConverterChanel6TemperatureSamplingInvalidation)// + .faultBit(14,FaultCharger.PvDCDC1DCConverterChanel7TemperatureSamplingInvalidation)// + .faultBit(15,FaultCharger.PvDCDC1DCConverterChanel8TemperatureSamplingInvalidation)// + ),// new UnsignedWordElement(0xAA16, - pvDCDC1Abnormity7 = warning.channel(new StatusBitChannel("PvDCDC1Abnormity7", this)// - .label(32, "DC Converter inductance current sampling invalidation")// - .label(64, - "Current sampling invalidation on the low voltage sideof DC Converter")// - .label(128, - "Voltage sampling invalidation on the low voltage side of DC Converter")// - .label(256, "Insulation inspection fault")// - .label(512, "NegContactor close unsuccessly")// - .label(1024, "NegContactor cut When running"))), + // prefix = "PvDCDC1" + new ModbusBitWrappingChannel("PvDCDC1Abnormity7", this, this.thingState)// + .faultBit(4, FaultCharger.PvDCDC1DCConverterInductanceCurrentSamplingInvalidation)// + .faultBit(5, FaultCharger.PvDCDC1CurrentSamplingInvalidationOnTheLowVoltageSideOfDCConverter)// + .faultBit(6, FaultCharger.PvDCDC1VoltageSamplingInvalidationOnTheLowVoltageSideOfDCConverter)// + .faultBit(7, FaultCharger.PvDCDC1InsulationInspectionFault)// + .faultBit(8, FaultCharger.PvDCDC1NegContactorCloseUnsuccessly)// + .faultBit(9, FaultCharger.PvDCDC1NegContactorCutWhenRunning)// + ),// new DummyElement(0xAA17, 0xAA1F), new UnsignedWordElement(0xAA20, pvDCDC1SwitchState = new StatusBitChannel("PvDCDC1SwitchState", this)// @@ -1228,6 +1318,7 @@ public ReadChannel getInputVoltage() { @Override public ThingStateChannel getStateChannel() { + // TODO Auto-generated method stub return thingState; } diff --git a/edge/src/io/openems/impl/device/commercial/FeneconCommercialEss.java b/edge/src/io/openems/impl/device/commercial/FeneconCommercialEss.java index 4d89f253350..d8ff25891a7 100644 --- a/edge/src/io/openems/impl/device/commercial/FeneconCommercialEss.java +++ b/edge/src/io/openems/impl/device/commercial/FeneconCommercialEss.java @@ -208,6 +208,230 @@ public ReadChannel maxNominalPower() { public StatusBitChannel abnormity3; public StatusBitChannel abnormity4; public StatusBitChannel abnormity5; + public ModbusReadLongChannel batteryCell1Voltage; + public ModbusReadLongChannel batteryCell2Voltage; + public ModbusReadLongChannel batteryCell3Voltage; + public ModbusReadLongChannel batteryCell4Voltage; + public ModbusReadLongChannel batteryCell5Voltage; + public ModbusReadLongChannel batteryCell6Voltage; + public ModbusReadLongChannel batteryCell7Voltage; + public ModbusReadLongChannel batteryCell8Voltage; + public ModbusReadLongChannel batteryCell9Voltage; + public ModbusReadLongChannel batteryCell10Voltage; + public ModbusReadLongChannel batteryCell11Voltage; + public ModbusReadLongChannel batteryCell12Voltage; + public ModbusReadLongChannel batteryCell13Voltage; + public ModbusReadLongChannel batteryCell14Voltage; + public ModbusReadLongChannel batteryCell15Voltage; + public ModbusReadLongChannel batteryCell16Voltage; + public ModbusReadLongChannel batteryCell17Voltage; + public ModbusReadLongChannel batteryCell18Voltage; + public ModbusReadLongChannel batteryCell19Voltage; + public ModbusReadLongChannel batteryCell20Voltage; + public ModbusReadLongChannel batteryCell21Voltage; + public ModbusReadLongChannel batteryCell22Voltage; + public ModbusReadLongChannel batteryCell23Voltage; + public ModbusReadLongChannel batteryCell24Voltage; + public ModbusReadLongChannel batteryCell25Voltage; + public ModbusReadLongChannel batteryCell26Voltage; + public ModbusReadLongChannel batteryCell27Voltage; + public ModbusReadLongChannel batteryCell28Voltage; + public ModbusReadLongChannel batteryCell29Voltage; + public ModbusReadLongChannel batteryCell30Voltage; + public ModbusReadLongChannel batteryCell31Voltage; + public ModbusReadLongChannel batteryCell32Voltage; + public ModbusReadLongChannel batteryCell33Voltage; + public ModbusReadLongChannel batteryCell34Voltage; + public ModbusReadLongChannel batteryCell35Voltage; + public ModbusReadLongChannel batteryCell36Voltage; + public ModbusReadLongChannel batteryCell37Voltage; + public ModbusReadLongChannel batteryCell38Voltage; + public ModbusReadLongChannel batteryCell39Voltage; + public ModbusReadLongChannel batteryCell40Voltage; + public ModbusReadLongChannel batteryCell41Voltage; + public ModbusReadLongChannel batteryCell42Voltage; + public ModbusReadLongChannel batteryCell43Voltage; + public ModbusReadLongChannel batteryCell44Voltage; + public ModbusReadLongChannel batteryCell45Voltage; + public ModbusReadLongChannel batteryCell46Voltage; + public ModbusReadLongChannel batteryCell47Voltage; + public ModbusReadLongChannel batteryCell48Voltage; + public ModbusReadLongChannel batteryCell49Voltage; + public ModbusReadLongChannel batteryCell50Voltage; + public ModbusReadLongChannel batteryCell51Voltage; + public ModbusReadLongChannel batteryCell52Voltage; + public ModbusReadLongChannel batteryCell53Voltage; + public ModbusReadLongChannel batteryCell54Voltage; + public ModbusReadLongChannel batteryCell55Voltage; + public ModbusReadLongChannel batteryCell56Voltage; + public ModbusReadLongChannel batteryCell57Voltage; + public ModbusReadLongChannel batteryCell58Voltage; + public ModbusReadLongChannel batteryCell59Voltage; + public ModbusReadLongChannel batteryCell60Voltage; + public ModbusReadLongChannel batteryCell61Voltage; + public ModbusReadLongChannel batteryCell62Voltage; + public ModbusReadLongChannel batteryCell63Voltage; + public ModbusReadLongChannel batteryCell64Voltage; + public ModbusReadLongChannel batteryCell65Voltage; + public ModbusReadLongChannel batteryCell66Voltage; + public ModbusReadLongChannel batteryCell67Voltage; + public ModbusReadLongChannel batteryCell68Voltage; + public ModbusReadLongChannel batteryCell69Voltage; + public ModbusReadLongChannel batteryCell70Voltage; + public ModbusReadLongChannel batteryCell71Voltage; + public ModbusReadLongChannel batteryCell72Voltage; + public ModbusReadLongChannel batteryCell73Voltage; + public ModbusReadLongChannel batteryCell74Voltage; + public ModbusReadLongChannel batteryCell75Voltage; + public ModbusReadLongChannel batteryCell76Voltage; + public ModbusReadLongChannel batteryCell77Voltage; + public ModbusReadLongChannel batteryCell78Voltage; + public ModbusReadLongChannel batteryCell79Voltage; + public ModbusReadLongChannel batteryCell80Voltage; + public ModbusReadLongChannel batteryCell81Voltage; + public ModbusReadLongChannel batteryCell82Voltage; + public ModbusReadLongChannel batteryCell83Voltage; + public ModbusReadLongChannel batteryCell84Voltage; + public ModbusReadLongChannel batteryCell85Voltage; + public ModbusReadLongChannel batteryCell86Voltage; + public ModbusReadLongChannel batteryCell87Voltage; + public ModbusReadLongChannel batteryCell88Voltage; + public ModbusReadLongChannel batteryCell89Voltage; + public ModbusReadLongChannel batteryCell90Voltage; + public ModbusReadLongChannel batteryCell91Voltage; + public ModbusReadLongChannel batteryCell92Voltage; + public ModbusReadLongChannel batteryCell93Voltage; + public ModbusReadLongChannel batteryCell94Voltage; + public ModbusReadLongChannel batteryCell95Voltage; + public ModbusReadLongChannel batteryCell96Voltage; + public ModbusReadLongChannel batteryCell97Voltage; + public ModbusReadLongChannel batteryCell98Voltage; + public ModbusReadLongChannel batteryCell99Voltage; + public ModbusReadLongChannel batteryCell100Voltage; + public ModbusReadLongChannel batteryCell101Voltage; + public ModbusReadLongChannel batteryCell102Voltage; + public ModbusReadLongChannel batteryCell103Voltage; + public ModbusReadLongChannel batteryCell104Voltage; + public ModbusReadLongChannel batteryCell105Voltage; + public ModbusReadLongChannel batteryCell106Voltage; + public ModbusReadLongChannel batteryCell107Voltage; + public ModbusReadLongChannel batteryCell108Voltage; + public ModbusReadLongChannel batteryCell109Voltage; + public ModbusReadLongChannel batteryCell110Voltage; + public ModbusReadLongChannel batteryCell111Voltage; + public ModbusReadLongChannel batteryCell112Voltage; + public ModbusReadLongChannel batteryCell113Voltage; + public ModbusReadLongChannel batteryCell114Voltage; + public ModbusReadLongChannel batteryCell115Voltage; + public ModbusReadLongChannel batteryCell116Voltage; + public ModbusReadLongChannel batteryCell117Voltage; + public ModbusReadLongChannel batteryCell118Voltage; + public ModbusReadLongChannel batteryCell119Voltage; + public ModbusReadLongChannel batteryCell120Voltage; + public ModbusReadLongChannel batteryCell121Voltage; + public ModbusReadLongChannel batteryCell122Voltage; + public ModbusReadLongChannel batteryCell123Voltage; + public ModbusReadLongChannel batteryCell124Voltage; + public ModbusReadLongChannel batteryCell125Voltage; + public ModbusReadLongChannel batteryCell126Voltage; + public ModbusReadLongChannel batteryCell127Voltage; + public ModbusReadLongChannel batteryCell128Voltage; + public ModbusReadLongChannel batteryCell129Voltage; + public ModbusReadLongChannel batteryCell130Voltage; + public ModbusReadLongChannel batteryCell131Voltage; + public ModbusReadLongChannel batteryCell132Voltage; + public ModbusReadLongChannel batteryCell133Voltage; + public ModbusReadLongChannel batteryCell134Voltage; + public ModbusReadLongChannel batteryCell135Voltage; + public ModbusReadLongChannel batteryCell136Voltage; + public ModbusReadLongChannel batteryCell137Voltage; + public ModbusReadLongChannel batteryCell138Voltage; + public ModbusReadLongChannel batteryCell139Voltage; + public ModbusReadLongChannel batteryCell140Voltage; + public ModbusReadLongChannel batteryCell141Voltage; + public ModbusReadLongChannel batteryCell142Voltage; + public ModbusReadLongChannel batteryCell143Voltage; + public ModbusReadLongChannel batteryCell144Voltage; + public ModbusReadLongChannel batteryCell145Voltage; + public ModbusReadLongChannel batteryCell146Voltage; + public ModbusReadLongChannel batteryCell147Voltage; + public ModbusReadLongChannel batteryCell148Voltage; + public ModbusReadLongChannel batteryCell149Voltage; + public ModbusReadLongChannel batteryCell150Voltage; + public ModbusReadLongChannel batteryCell151Voltage; + public ModbusReadLongChannel batteryCell152Voltage; + public ModbusReadLongChannel batteryCell153Voltage; + public ModbusReadLongChannel batteryCell154Voltage; + public ModbusReadLongChannel batteryCell155Voltage; + public ModbusReadLongChannel batteryCell156Voltage; + public ModbusReadLongChannel batteryCell157Voltage; + public ModbusReadLongChannel batteryCell158Voltage; + public ModbusReadLongChannel batteryCell159Voltage; + public ModbusReadLongChannel batteryCell160Voltage; + public ModbusReadLongChannel batteryCell161Voltage; + public ModbusReadLongChannel batteryCell162Voltage; + public ModbusReadLongChannel batteryCell163Voltage; + public ModbusReadLongChannel batteryCell164Voltage; + public ModbusReadLongChannel batteryCell165Voltage; + public ModbusReadLongChannel batteryCell166Voltage; + public ModbusReadLongChannel batteryCell167Voltage; + public ModbusReadLongChannel batteryCell168Voltage; + public ModbusReadLongChannel batteryCell169Voltage; + public ModbusReadLongChannel batteryCell170Voltage; + public ModbusReadLongChannel batteryCell171Voltage; + public ModbusReadLongChannel batteryCell172Voltage; + public ModbusReadLongChannel batteryCell173Voltage; + public ModbusReadLongChannel batteryCell174Voltage; + public ModbusReadLongChannel batteryCell175Voltage; + public ModbusReadLongChannel batteryCell176Voltage; + public ModbusReadLongChannel batteryCell177Voltage; + public ModbusReadLongChannel batteryCell178Voltage; + public ModbusReadLongChannel batteryCell179Voltage; + public ModbusReadLongChannel batteryCell180Voltage; + public ModbusReadLongChannel batteryCell181Voltage; + public ModbusReadLongChannel batteryCell182Voltage; + public ModbusReadLongChannel batteryCell183Voltage; + public ModbusReadLongChannel batteryCell184Voltage; + public ModbusReadLongChannel batteryCell185Voltage; + public ModbusReadLongChannel batteryCell186Voltage; + public ModbusReadLongChannel batteryCell187Voltage; + public ModbusReadLongChannel batteryCell188Voltage; + public ModbusReadLongChannel batteryCell189Voltage; + public ModbusReadLongChannel batteryCell190Voltage; + public ModbusReadLongChannel batteryCell191Voltage; + public ModbusReadLongChannel batteryCell192Voltage; + public ModbusReadLongChannel batteryCell193Voltage; + public ModbusReadLongChannel batteryCell194Voltage; + public ModbusReadLongChannel batteryCell195Voltage; + public ModbusReadLongChannel batteryCell196Voltage; + public ModbusReadLongChannel batteryCell197Voltage; + public ModbusReadLongChannel batteryCell198Voltage; + public ModbusReadLongChannel batteryCell199Voltage; + public ModbusReadLongChannel batteryCell200Voltage; + public ModbusReadLongChannel batteryCell201Voltage; + public ModbusReadLongChannel batteryCell202Voltage; + public ModbusReadLongChannel batteryCell203Voltage; + public ModbusReadLongChannel batteryCell204Voltage; + public ModbusReadLongChannel batteryCell205Voltage; + public ModbusReadLongChannel batteryCell206Voltage; + public ModbusReadLongChannel batteryCell207Voltage; + public ModbusReadLongChannel batteryCell208Voltage; + public ModbusReadLongChannel batteryCell209Voltage; + public ModbusReadLongChannel batteryCell210Voltage; + public ModbusReadLongChannel batteryCell211Voltage; + public ModbusReadLongChannel batteryCell212Voltage; + public ModbusReadLongChannel batteryCell213Voltage; + public ModbusReadLongChannel batteryCell214Voltage; + public ModbusReadLongChannel batteryCell215Voltage; + public ModbusReadLongChannel batteryCell216Voltage; + public ModbusReadLongChannel batteryCell217Voltage; + public ModbusReadLongChannel batteryCell218Voltage; + public ModbusReadLongChannel batteryCell219Voltage; + public ModbusReadLongChannel batteryCell220Voltage; + public ModbusReadLongChannel batteryCell221Voltage; + public ModbusReadLongChannel batteryCell222Voltage; + public ModbusReadLongChannel batteryCell223Voltage; + public ModbusReadLongChannel batteryCell224Voltage; /* * Methods @@ -258,26 +482,35 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { .label(1, "CESS")), // new DummyElement(0x010B, 0x010F), // new UnsignedWordElement(0x0110, // - new ModbusBitWrappingChannel("SuggestiveInformation1", this,this.thingState) // - .warningBit(2, Warning.EmergencyStop) //EmergencyStop - .warningBit(6, Warning.KeyManualStop)), //KeyManualStop + new ModbusBitWrappingChannel("SuggestiveInformation1", this, this.thingState) // + .warningBit(2, WarningEss.EmergencyStop) // EmergencyStop + .warningBit(6, WarningEss.KeyManualStop)), // KeyManualStop new UnsignedWordElement(0x0111, // - new ModbusBitWrappingChannel("SuggestiveInformation2", this,this.thingState) // - .warningBit(3, Warning.TransformerPhaseBTemperatureSensorInvalidation) //Transformer phase B temperature sensor invalidation - .warningBit(12, Warning.SDMemoryCardInvalidation)), //SD memory card invalidation + new ModbusBitWrappingChannel("SuggestiveInformation2", this, this.thingState) // + .warningBit(3, WarningEss.TransformerPhaseBTemperatureSensorInvalidation) // Transformer + // phase + // B + // temperature + // sensor + // invalidation + .warningBit(12, WarningEss.SDMemoryCardInvalidation)), // SD memory card + // invalidation new DummyElement(0x0112, 0x0124), // new UnsignedWordElement(0x0125, // - suggestiveInformation3 = new StatusBitChannel("SuggestiveInformation3", this) // - .label(1, "Inverter communication abnormity") // - .label(2, "Battery stack communication abnormity") // - .label(4, "Multifunctional ammeter communication abnormity") // - .label(16, "Remote communication abnormity")// - .label(256, "PV DC1 communication abnormity")// - .label(512, "PV DC2 communication abnormity")// + new ModbusBitWrappingChannel("SuggestiveInformation3", this, this.thingState)// + .warningBit(0, WarningEss.InverterCommunicationAbnormity)// + .warningBit(1, WarningEss.BatteryStackCommunicationAbnormity)// + .warningBit(2, WarningEss.MultifunctionalAmmeterCommunicationAbnormity)// + .warningBit(4, WarningEss.RemoteCommunicationAbnormity)// + .warningBit(8, WarningEss.PVDC1CommunicationAbnormity)// + .warningBit(9, WarningEss.PVDC2CommunicationAbnormity)// ), // + new UnsignedWordElement(0x0126, // - suggestiveInformation4 = new StatusBitChannel("SuggestiveInformation4", this) // - .label(8, "Transformer severe overtemperature")), // + new ModbusBitWrappingChannel("SuggestiveInformation4", this, this.thingState)// + .warningBit(3, WarningEss.TransformerSevereOvertemperature)// + ), // + new DummyElement(0x0127, 0x014F), // new UnsignedWordElement(0x0150, // switchState = new StatusBitChannel("BatteryStringSwitchState", this) // @@ -288,136 +521,151 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { .label(16, "Middle relay"))// ), // new ModbusRegisterRange(0x0180, // - new UnsignedWordElement(0x0180, - abnormity1 = new StatusBitChannel("Abnormity1", this)// - .label(1, "DC precharge contactor close unsuccessfully") // - .label(2, "AC precharge contactor close unsuccessfully") // - .label(4, "AC main contactor close unsuccessfully") // - .label(8, "DC electrical breaker 1 close unsuccessfully") // - .label(16, "DC main contactor close unsuccessfully") // - .label(32, "AC breaker trip") // - .label(64, "AC main contactor open when running") // - .label(128, "DC main contactor open when running") // - .label(256, "AC main contactor open unsuccessfully") // - .label(512, "DC electrical breaker 1 open unsuccessfully") // - .label(1024, "DC main contactor open unsuccessfully") // - .label(2048, "Hardware PDP fault") // - .label(4096, "Master stop suddenly")), - new DummyElement(0x0181), - new UnsignedWordElement(0x0182, - abnormity2 = new StatusBitChannel("Abnormity2", this) // - .label(1, "DC short circuit protection") // - .label(2, "DC overvoltage protection") // - .label(4, "DC undervoltage protection") // - .label(8, "DC inverse/no connection protection") // - .label(16, "DC disconnection protection") // - .label(32, "Commuting voltage abnormity protection") // - .label(64, "DC overcurrent protection") // - .label(128, "Phase 1 peak current over limit protection") // - .label(256, "Phase 2 peak current over limit protection") // - .label(512, "Phase 3 peak current over limit protection") // - .label(1024, "Phase 1 grid voltage sampling invalidation") // - .label(2048, "Phase 2 virtual current over limit protection") // - .label(4096, "Phase 3 virtual current over limit protection") // - .label(8192, "Phase 1 grid voltage sampling invalidation2") // TODO same as + new UnsignedWordElement(0x0180, // + new ModbusBitWrappingChannel("Abnormity1", this, this.thingState)// + .faultBit(0, FaultEss.DCPrechargeContactorCloseUnsuccessfully)// + .faultBit(1, FaultEss.ACPrechargeContactorCloseUnsuccessfully)// + .faultBit(2, FaultEss.ACMainContactorCloseUnsuccessfully)// + .faultBit(3, FaultEss.DCElectricalBreaker1CloseUnsuccessfully)// + .faultBit(4, FaultEss.DCMainContactorCloseUnsuccessfully)// + .faultBit(5, FaultEss.ACBreakerTrip)// + .faultBit(6, FaultEss.ACMainContactorOpenWhenRunning)// + .faultBit(7, FaultEss.DCMainContactorOpenWhenRunning)// + .faultBit(8, FaultEss.ACMainContactorOpenUnsuccessfully)// + .faultBit(9, FaultEss.DCElectricalBreaker1OpenUnsuccessfully)// + .faultBit(10, FaultEss.DCMainContactorOpenUnsuccessfully)// + .faultBit(11, FaultEss.HardwarePDPFault)// + .faultBit(12, FaultEss.MasterStopSuddenly)// + ), + + new DummyElement(0x0181), new UnsignedWordElement(0x0182, // + new ModbusBitWrappingChannel("Abnormity2", this, this.thingState)// + .faultBit(0, FaultEss.DCShortCircuitProtection)// + .faultBit(1, FaultEss.DCOvervoltageProtection)// + .faultBit(2, FaultEss.DCUndervoltageProtection)// + .faultBit(3, FaultEss.DCInverseNoConnectionProtection)// + .faultBit(4, FaultEss.DCDisconnectionProtection)// + .faultBit(5, FaultEss.CommutingVoltageAbnormityProtection)// + .faultBit(6, FaultEss.DCOvercurrentProtection)// + .faultBit(7, FaultEss.Phase1PeakCurrentOverLimitProtection)// + .faultBit(8, FaultEss.Phase2PeakCurrentOverLimitProtection)// + .faultBit(9, FaultEss.Phase3PeakCurrentOverLimitProtection)// + .faultBit(10, FaultEss.Phase1GridVoltageSamplingInvalidation)// + .faultBit(11, FaultEss.Phase2VirtualCurrentOverLimitProtection)// + .faultBit(12, FaultEss.Phase3VirtualCurrentOverLimitProtection)// + .faultBit(13, FaultEss.Phase1GridVoltageSamplingInvalidation2)// TODO same as // above - .label(16384, "Phase 2 grid voltage sampling invalidation") // - .label(32768, "Phase 3 grid voltage sampling invalidation")), - new UnsignedWordElement(0x0183, - abnormity3 = new StatusBitChannel("Abnormity3", this) // - .label(1, "Phase 1 invert voltage sampling invalidation") // - .label(2, "Phase 2 invert voltage sampling invalidation") // - .label(4, "Phase 3 invert voltage sampling invalidation") // - .label(8, "AC current sampling invalidation") // - .label(16, "DC current sampling invalidation") // - .label(32, "Phase 1 overtemperature protection") // - .label(64, "Phase 2 overtemperature protection") // - .label(128, "Phase 3 overtemperature protection") // - .label(256, "Phase 1 temperature sampling invalidation") // - .label(512, "Phase 2 temperature sampling invalidation") // - .label(1024, "Phase 3 temperature sampling invalidation") // - .label(2048, "Phase 1 precharge unmet protection") // - .label(4096, "Phase 2 precharge unmet protection") // - .label(8192, "Phase 3 precharge unmet protection") // - .label(16384, "Unadaptable phase sequence error protection")// - .label(132768, "DSP protection")), - new UnsignedWordElement(0x0184, - abnormity4 = new StatusBitChannel("Abnormity4", this) // - .label(1, "Phase 1 grid voltage severe overvoltage protection") // - .label(2, "Phase 1 grid voltage general overvoltage protection") // - .label(4, "Phase 2 grid voltage severe overvoltage protection") // - .label(8, "Phase 2 grid voltage general overvoltage protection") // - .label(16, "Phase 3 grid voltage severe overvoltage protection") // - .label(32, "Phase 3 grid voltage general overvoltage protection") // - .label(64, "Phase 1 grid voltage severe undervoltage protection") // - .label(128, "Phase 1 grid voltage general undervoltage protection") // - .label(256, "Phase 2 grid voltage severe undervoltage protection") // - .label(512, "Phase 2 grid voltage general undervoltage protection") // - .label(1024, "Phase 2 Inverter voltage general overvoltage protection") // - .label(2048, "Phase 3 Inverter voltage severe overvoltage protection") // - .label(4096, "Phase 3 Inverter voltage general overvoltage protection") // - .label(8192, "Inverter peak voltage high protection cause by AC disconnect")), - new UnsignedWordElement(0x0185, - abnormity5 = new StatusBitChannel("Abnormity5", this) // - .label(1, "Phase 1 grid loss") // - .label(2, "Phase 2 grid loss") // - .label(4, "Phase 3 grid loss") // - .label(8, "Islanding protection") // - .label(16, "Phase 1 under voltage ride through") // - .label(32, "Phase 2 under voltage ride through") // - .label(64, "Phase 3 under voltage ride through ") // - .label(128, "Phase 1 Inverter voltage severe overvoltage protection") // - .label(256, "Phase 1 Inverter voltage general overvoltage protection") // - .label(512, "Phase 2 Inverter voltage severe overvoltage protection") // - .label(1024, "Phase 2 Inverter voltage general overvoltage protection") // - .label(2048, "Phase 3 Inverter voltage severe overvoltage protection") // - .label(4096, "Phase 3 Inverter voltage general overvoltage protection") // - .label(8192, "Inverter peak voltage high protection cause by AC disconnect")), - new UnsignedWordElement(0x0186, - suggestiveInformation5 = new StatusBitChannel("SuggestiveInformation5", this) // - .label(1, "DC precharge contactor inspection abnormity") // - .label(2, "DC breaker 1 inspection abnormity ") // - .label(4, "DC breaker 2 inspection abnormity ") // - .label(8, "AC precharge contactor inspection abnormity ") // - .label(16, "AC main contactor inspection abnormity ") // - .label(32, "AC breaker inspection abnormity ") // - .label(64, "DC breaker 1 close unsuccessfully") // - .label(128, "DC breaker 2 close unsuccessfully") // - .label(256, "Control signal close abnormally inspected by system") // - .label(512, "Control signal open abnormally inspected by system") // - .label(1024, "Neutral wire contactor close unsuccessfully") // - .label(2048, "Neutral wire contactor open unsuccessfully") // - .label(4096, "Work door open") // - .label(8192, "Emergency stop") // - .label(16384, "AC breaker close unsuccessfully")// - .label(132768, "Control switch stop")), - new UnsignedWordElement(0x0187, - suggestiveInformation6 = new StatusBitChannel("SuggestiveInformation6", this) // - .label(1, "General overload") // - .label(2, "Severe overload") // - .label(4, "Battery current over limit") // - .label(8, "Power decrease caused by overtemperature") // - .label(16, "Inverter general overtemperature") // - .label(32, "AC three-phase current unbalance") // - .label(64, "Rstore factory setting unsuccessfully") // - .label(128, "Pole-board invalidation") // - .label(256, "Self-inspection failed") // - .label(512, "Receive BMS fault and stop") // - .label(1024, "Refrigeration equipment invalidation") // - .label(2048, "Large temperature difference among IGBT three phases") // - .label(4096, "EEPROM parameters over range") // - .label(8192, "EEPROM parameters backup failed") // - .label(16384, "DC breaker close unsuccessfully")), - new UnsignedWordElement(0x0188, - suggestiveInformation7 = new StatusBitChannel("SuggestiveInformation7", this) // - .label(1, "Communication between inverter and BSMU disconnected") // - .label(2, "Communication between inverter and Master disconnected") // - .label(4, "Communication between inverter and UC disconnected") // - .label(8, "BMS start overtime controlled by PCS") // - .label(16, "BMS stop overtime controlled by PCS") // - .label(32, "Sync signal invalidation") // - .label(64, "Sync signal continuous caputure fault") // - .label(128, "Sync signal several times caputure fault"))), + .faultBit(14, FaultEss.Phase2ridVoltageSamplingInvalidation)// + .faultBit(15, FaultEss.Phase3GridVoltageSamplingInvalidation)// + ), // + + new UnsignedWordElement(0x0183, // + new ModbusBitWrappingChannel("Abnormity3", this, this.thingState)// + .faultBit(0, FaultEss.Phase1InvertVoltageSamplingInvalidation)// + .faultBit(1, FaultEss.Phase2InvertVoltageSamplingInvalidation)// + .faultBit(2, FaultEss.Phase3InvertVoltageSamplingInvalidation)// + .faultBit(3, FaultEss.ACCurrentSamplingInvalidation)// + .faultBit(4, FaultEss.DCCurrentSamplingInvalidation)// + .faultBit(5, FaultEss.Phase1OvertemperatureProtection)// + .faultBit(6, FaultEss.Phase2OvertemperatureProtection)// + .faultBit(7, FaultEss.Phase3OvertemperatureProtection)// + .faultBit(8, FaultEss.Phase1TemperatureSamplingInvalidation)// + .faultBit(9, FaultEss.Phase2TemperatureSamplingInvalidation)// + .faultBit(10, FaultEss.Phase3TemperatureSamplingInvalidation)// + .faultBit(11, FaultEss.Phase1PrechargeUnmetProtection)// + .faultBit(12, FaultEss.Phase2PrechargeUnmetProtection)// + .faultBit(13, FaultEss.Phase3PrechargeUnmetProtection)// + .faultBit(14, FaultEss.UnadaptablePhaseSequenceErrorProtection)// + .faultBit(15, FaultEss.DSPProtection)// + ), // + + new UnsignedWordElement(0x0184, // + new ModbusBitWrappingChannel("Abnormity4", this, this.thingState)// + .faultBit(0, FaultEss.Phase1GridVoltageSevereOvervoltageProtection)// + .faultBit(1, FaultEss.Phase1GridVoltageGeneralOvervoltageProtection)// + .faultBit(2, FaultEss.Phase2GridVoltageSevereOvervoltageProtection)// + .faultBit(3, FaultEss.Phase2GridVoltageGeneralOvervoltageProtection)// + .faultBit(4, FaultEss.Phase3GridVoltageSevereOvervoltageProtection)// + .faultBit(5, FaultEss.Phase3GridVoltageGeneralOvervoltageProtection)// + .faultBit(6, FaultEss.Phase1GridVoltageSevereUndervoltageProtection)// + .faultBit(7, FaultEss.Phase1GridVoltageGeneralUndervoltageProtection)// + .faultBit(8, FaultEss.Phase2GridVoltageSevereUndervoltageProtection)// + .faultBit(9, FaultEss.Phase2GridVoltageGeneralUndervoltageProtection)// + .faultBit(10, FaultEss.Phase3GridVoltageSevereUndervoltageProtection)// + .faultBit(11, FaultEss.Phase3GridVoltageGeneralUndervoltageProtection)// + .faultBit(12, FaultEss.SevereOverfrequncyProtection)// + .faultBit(13, FaultEss.GeneralOverfrequncyProtection)// + .faultBit(14, FaultEss.SevereUnderfrequncyProtection)// + .faultBit(15, FaultEss.GeneralsUnderfrequncyProtection)// + ), // + + new UnsignedWordElement(0x0185, // + new ModbusBitWrappingChannel("Abnormity5", this, this.thingState)// + .faultBit(0, FaultEss.Phase1Gridloss)// + .faultBit(1, FaultEss.Phase2Gridloss)// + .faultBit(2, FaultEss.Phase3Gridloss)// + .faultBit(3, FaultEss.IslandingProtection)// + .faultBit(4, FaultEss.Phase1UnderVoltageRideThrough)// + .faultBit(5, FaultEss.Phase2UnderVoltageRideThrough)// + .faultBit(6, FaultEss.Phase3UnderVoltageRideThrough)// + .faultBit(7, FaultEss.Phase1InverterVoltageSevereOvervoltageProtection)// + .faultBit(8, FaultEss.Phase1InverterVoltageGeneralOvervoltageProtection)// + .faultBit(9, FaultEss.Phase2InverterVoltageSevereOvervoltageProtection)// + .faultBit(10, FaultEss.Phase2InverterVoltageGeneralOvervoltageProtection)// + .faultBit(11, FaultEss.Phase3InverterVoltageSevereOvervoltageProtection)// + .faultBit(12, FaultEss.Phase3InverterVoltageGeneralOvervoltageProtection)// + .faultBit(13, FaultEss.InverterPeakVoltageHighProtectionCauseByACDisconnect)// + ), // + + new UnsignedWordElement(0x0186, // + new ModbusBitWrappingChannel("SuggestiveInformation5", this, this.thingState)// + .warningBit(0, WarningEss.DCPrechargeContactorInspectionAbnormity)// + .warningBit(1, WarningEss.DCBreaker1InspectionAbnormity)// + .warningBit(2, WarningEss.DCBreaker2InspectionAbnormity)// + .warningBit(3, WarningEss.ACPrechargeContactorInspectionAbnormity)// + .warningBit(4, WarningEss.ACMainontactorInspectionAbnormity)// + .warningBit(5, WarningEss.ACBreakerInspectionAbnormity)// + .warningBit(6, WarningEss.DCBreaker1CloseUnsuccessfully)// + .warningBit(7, WarningEss.DCBreaker2CloseUnsuccessfully)// + .warningBit(8, WarningEss.ControlSignalCloseAbnormallyInspectedBySystem)// + .warningBit(9, WarningEss.ControlSignalOpenAbnormallyInspectedBySystem)// + .warningBit(10, WarningEss.NeutralWireContactorCloseUnsuccessfully)// + .warningBit(11, WarningEss.NeutralWireContactorOpenUnsuccessfully)// + .warningBit(12, WarningEss.WorkDoorOpen)// + .warningBit(13, WarningEss.Emergency1Stop)// + .warningBit(14, WarningEss.ACBreakerCloseUnsuccessfully)// + .warningBit(15, WarningEss.ControlSwitchStop)// + ), // + + new UnsignedWordElement(0x0187, // + new ModbusBitWrappingChannel("SuggestiveInformation6", this, this.thingState)// + .warningBit(0, WarningEss.GeneralOverload)// + .warningBit(1, WarningEss.SevereOverload)// + .warningBit(2, WarningEss.BatteryCurrentOverLimit)// + .warningBit(3, WarningEss.PowerDecreaseCausedByOvertemperature)// + .warningBit(4, WarningEss.InverterGeneralOvertemperature)// + .warningBit(5, WarningEss.ACThreePhaseCurrentUnbalance)// + .warningBit(6, WarningEss.RestoreFactorySettingUnsuccessfully)// + .warningBit(7, WarningEss.PoleBoardInvalidation)// + .warningBit(8, WarningEss.SelfInspectionFailed)// + .warningBit(9, WarningEss.ReceiveBMSFaultAndStop)// + .warningBit(10, WarningEss.RefrigerationEquipmentinvalidation)// + .warningBit(11, WarningEss.LargeTemperatureDifferenceAmongIGBTThreePhases)// + .warningBit(12, WarningEss.EEPROMParametersOverRange)// + .warningBit(13, WarningEss.EEPROMParametersBackupFailed)// + .warningBit(14, WarningEss.DCBreakerCloseunsuccessfully)// + ), // + new UnsignedWordElement(0x0188, // + new ModbusBitWrappingChannel("SuggestiveInformation7", this, this.thingState)// + .warningBit(0, WarningEss.CommunicationBetweenInverterAndBSMUDisconnected)// + .warningBit(1, WarningEss.CommunicationBetweenInverterAndMasterDisconnected)// + .warningBit(2, WarningEss.CommunicationBetweenInverterAndUCDisconnected)// + .warningBit(3, WarningEss.BMSStartOvertimeControlledByPCS)// + .warningBit(4, WarningEss.BMSStopOvertimeControlledByPCS)// + .warningBit(5, WarningEss.SyncSignalInvalidation)// + .warningBit(6, WarningEss.SyncSignalContinuousCaputureFault)// + .warningBit(7, WarningEss.SyncSignalSeveralTimesCaputureFault))), + new ModbusRegisterRange(0x0200, // new SignedWordElement(0x0200, // batteryVoltage = new ModbusReadLongChannel("BatteryVoltage", this).unit("mV") @@ -518,8 +766,681 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { new UnsignedWordElement(0x1403, soh = new ModbusReadLongChannel("Soh", this).unit("%").interval(0, 100)), new UnsignedWordElement(0x1404, - batteryCellAverageTemperature = new ModbusReadLongChannel("BatteryCellAverageTemperature", this).unit("°C")) - )); + batteryCellAverageTemperature = new ModbusReadLongChannel( + "BatteryCellAverageTemperature", this).unit("°C"))), + new ModbusRegisterRange(0x1500, // + new UnsignedWordElement(0x1500, + batteryCell1Voltage = new ModbusReadLongChannel("Cell1Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1501, + batteryCell2Voltage = new ModbusReadLongChannel("Cell2Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1502, + batteryCell3Voltage = new ModbusReadLongChannel("Cell3Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1503, + batteryCell4Voltage = new ModbusReadLongChannel("Cell4Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1504, + batteryCell5Voltage = new ModbusReadLongChannel("Cell5Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1505, + batteryCell6Voltage = new ModbusReadLongChannel("Cell6Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1506, + batteryCell7Voltage = new ModbusReadLongChannel("Cell7Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1507, + batteryCell8Voltage = new ModbusReadLongChannel("Cell8Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1508, + batteryCell9Voltage = new ModbusReadLongChannel("Cell9Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1509, + batteryCell10Voltage = new ModbusReadLongChannel("Cel10Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x150A, + batteryCell11Voltage = new ModbusReadLongChannel("Cell11Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x150B, + batteryCell12Voltage = new ModbusReadLongChannel("Cell12Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x150C, + batteryCell13Voltage = new ModbusReadLongChannel("Cell13Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x150D, + batteryCell14Voltage = new ModbusReadLongChannel("Cell14Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x150E, + batteryCell15Voltage = new ModbusReadLongChannel("Cell15Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x150F, + batteryCell16Voltage = new ModbusReadLongChannel("Cell16Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1510, + batteryCell17Voltage = new ModbusReadLongChannel("Cell17Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1511, + batteryCell18Voltage = new ModbusReadLongChannel("Cell18Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1512, + batteryCell19Voltage = new ModbusReadLongChannel("Cell19Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1513, + batteryCell20Voltage = new ModbusReadLongChannel("Cell20Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1514, + batteryCell21Voltage = new ModbusReadLongChannel("Cell21Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1515, + batteryCell22Voltage = new ModbusReadLongChannel("Cell22Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1516, + batteryCell23Voltage = new ModbusReadLongChannel("Cell23Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1517, + batteryCell24Voltage = new ModbusReadLongChannel("Cell24Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1518, + batteryCell25Voltage = new ModbusReadLongChannel("Cell25Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1519, + batteryCell26Voltage = new ModbusReadLongChannel("Cell26Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x151A, + batteryCell27Voltage = new ModbusReadLongChannel("Cell27Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x151B, + batteryCell28Voltage = new ModbusReadLongChannel("Cell28Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x151C, + batteryCell29Voltage = new ModbusReadLongChannel("Cell29Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x151D, + batteryCell30Voltage = new ModbusReadLongChannel("Cell30Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x151E, + batteryCell31Voltage = new ModbusReadLongChannel("Cell31Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x151F, + batteryCell32Voltage = new ModbusReadLongChannel("Cell32Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1520, + batteryCell33Voltage = new ModbusReadLongChannel("Cell33Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1521, + batteryCell34Voltage = new ModbusReadLongChannel("Cell34Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1522, + batteryCell35Voltage = new ModbusReadLongChannel("Cell35Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1523, + batteryCell36Voltage = new ModbusReadLongChannel("Cell36Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1524, + batteryCell37Voltage = new ModbusReadLongChannel("Cell37Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1525, + batteryCell38Voltage = new ModbusReadLongChannel("Cell38Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1526, + batteryCell39Voltage = new ModbusReadLongChannel("Cell39Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1527, + batteryCell40Voltage = new ModbusReadLongChannel("Cell40Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1528, + batteryCell41Voltage = new ModbusReadLongChannel("Cell41Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1529, + batteryCell42Voltage = new ModbusReadLongChannel("Cell42Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x152A, + batteryCell43Voltage = new ModbusReadLongChannel("Cell43Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x152B, + batteryCell44Voltage = new ModbusReadLongChannel("Cell44Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x152C, + batteryCell45Voltage = new ModbusReadLongChannel("Cell45Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x152D, + batteryCell46Voltage = new ModbusReadLongChannel("Cell46Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x152E, + batteryCell47Voltage = new ModbusReadLongChannel("Cell47Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x152F, + batteryCell48Voltage = new ModbusReadLongChannel("Cell48Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1530, + batteryCell49Voltage = new ModbusReadLongChannel("Cell49Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1531, + batteryCell50Voltage = new ModbusReadLongChannel("Cell50Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1532, + batteryCell51Voltage = new ModbusReadLongChannel("Cell51Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1533, + batteryCell52Voltage = new ModbusReadLongChannel("Cell52Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1534, + batteryCell53Voltage = new ModbusReadLongChannel("Cell53Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1535, + batteryCell54Voltage = new ModbusReadLongChannel("Cell54Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1536, + batteryCell55Voltage = new ModbusReadLongChannel("Cell55Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1537, + batteryCell56Voltage = new ModbusReadLongChannel("Cell56Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1538, + batteryCell57Voltage = new ModbusReadLongChannel("Cell57Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1539, + batteryCell58Voltage = new ModbusReadLongChannel("Cell58Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x153A, + batteryCell59Voltage = new ModbusReadLongChannel("Cell59Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x153B, + batteryCell60Voltage = new ModbusReadLongChannel("Cell60Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x153C, + batteryCell61Voltage = new ModbusReadLongChannel("Cell61Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x153D, + batteryCell62Voltage = new ModbusReadLongChannel("Cell62Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x153E, + batteryCell63Voltage = new ModbusReadLongChannel("Cell63Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x153F, + batteryCell64Voltage = new ModbusReadLongChannel("Cell64Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1540, + batteryCell65Voltage = new ModbusReadLongChannel("Cell65Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1541, + batteryCell66Voltage = new ModbusReadLongChannel("Cell66Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1542, + batteryCell67Voltage = new ModbusReadLongChannel("Cell67Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1543, + batteryCell68Voltage = new ModbusReadLongChannel("Cell68Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1544, + batteryCell69Voltage = new ModbusReadLongChannel("Cell69Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1545, + batteryCell70Voltage = new ModbusReadLongChannel("Cell70Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1546, + batteryCell71Voltage = new ModbusReadLongChannel("Cell71Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1547, + batteryCell72Voltage = new ModbusReadLongChannel("Cell72Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1548, + batteryCell73Voltage = new ModbusReadLongChannel("Cell73Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1549, + batteryCell74Voltage = new ModbusReadLongChannel("Cell74Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x154A, + batteryCell75Voltage = new ModbusReadLongChannel("Cell75Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x154B, + batteryCell76Voltage = new ModbusReadLongChannel("Cell76Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x154C, + batteryCell77Voltage = new ModbusReadLongChannel("Cell177Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x154D, + batteryCell78Voltage = new ModbusReadLongChannel("Cell78Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x154E, + batteryCell79Voltage = new ModbusReadLongChannel("Cell79Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x154F, + batteryCell80Voltage = new ModbusReadLongChannel("Cell80Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1550, + batteryCell81Voltage = new ModbusReadLongChannel("Cell81Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1551, + batteryCell82Voltage = new ModbusReadLongChannel("Cell82Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1552, + batteryCell83Voltage = new ModbusReadLongChannel("Cell83Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1553, + batteryCell84Voltage = new ModbusReadLongChannel("Cell84Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1554, + batteryCell85Voltage = new ModbusReadLongChannel("Cell85Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1555, + batteryCell86Voltage = new ModbusReadLongChannel("Cell86Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1556, + batteryCell87Voltage = new ModbusReadLongChannel("Cell87Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1557, + batteryCell88Voltage = new ModbusReadLongChannel("Cell88Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1558, + batteryCell89Voltage = new ModbusReadLongChannel("Cell89Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1559, + batteryCell90Voltage = new ModbusReadLongChannel("Cell90Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x155A, + batteryCell91Voltage = new ModbusReadLongChannel("Cell91Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x155B, + batteryCell92Voltage = new ModbusReadLongChannel("Cell92Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x155C, + batteryCell93Voltage = new ModbusReadLongChannel("Cell93Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x155D, + batteryCell94Voltage = new ModbusReadLongChannel("Cell94Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x155E, + batteryCell95Voltage = new ModbusReadLongChannel("Cell95Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x155F, + batteryCell96Voltage = new ModbusReadLongChannel("Cell96Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1560, + batteryCell97Voltage = new ModbusReadLongChannel("Cell97Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1561, + batteryCell98Voltage = new ModbusReadLongChannel("Cell98Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1562, + batteryCell99Voltage = new ModbusReadLongChannel("Cell99Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1563, + batteryCell100Voltage = new ModbusReadLongChannel("Cell100Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1564, + batteryCell101Voltage = new ModbusReadLongChannel("Cell101Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1565, + batteryCell102Voltage = new ModbusReadLongChannel("Cell102Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1566, + batteryCell103Voltage = new ModbusReadLongChannel("Cell103Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1567, + batteryCell104Voltage = new ModbusReadLongChannel("Cell104Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1568, + batteryCell105Voltage = new ModbusReadLongChannel("Cell105Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1569, + batteryCell106Voltage = new ModbusReadLongChannel("Cell106Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x156A, + batteryCell107Voltage = new ModbusReadLongChannel("Cell107Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x156B, + batteryCell108Voltage = new ModbusReadLongChannel("Cell108Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x156C, + batteryCell109Voltage = new ModbusReadLongChannel("Cell109Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x156D, + batteryCell110Voltage = new ModbusReadLongChannel("Cell110Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x156E, + batteryCell111Voltage = new ModbusReadLongChannel("Cell111Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x156F, + batteryCell112Voltage = new ModbusReadLongChannel("Cell112Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1570, + batteryCell113Voltage = new ModbusReadLongChannel("Cell113Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1571, + batteryCell114Voltage = new ModbusReadLongChannel("Cell114Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1572, + batteryCell115Voltage = new ModbusReadLongChannel("Cell115Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1573, + batteryCell116Voltage = new ModbusReadLongChannel("Cell116Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1574, + batteryCell117Voltage = new ModbusReadLongChannel("Cell117Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1575, + batteryCell118Voltage = new ModbusReadLongChannel("Cell18Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1576, + batteryCell119Voltage = new ModbusReadLongChannel("Cell119Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1577, + batteryCell120Voltage = new ModbusReadLongChannel("Cell120Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1578, + batteryCell121Voltage = new ModbusReadLongChannel("Cell121Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1579, + batteryCell122Voltage = new ModbusReadLongChannel("Cell122Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x157A, + batteryCell123Voltage = new ModbusReadLongChannel("Cell123Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x157B, + batteryCell124Voltage = new ModbusReadLongChannel("Cell124Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x157C, + batteryCell125Voltage = new ModbusReadLongChannel("Cell125Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x157D, + batteryCell126Voltage = new ModbusReadLongChannel("Cell126Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x157E, + batteryCell127Voltage = new ModbusReadLongChannel("Cell127Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x157F, + batteryCell128Voltage = new ModbusReadLongChannel("Cell128Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1580, + batteryCell129Voltage = new ModbusReadLongChannel("Cell129Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1581, + batteryCell130Voltage = new ModbusReadLongChannel("Cell130Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1583, + batteryCell131Voltage = new ModbusReadLongChannel("Cell131Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1584, + batteryCell132Voltage = new ModbusReadLongChannel("Cell132Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1585, + batteryCell133Voltage = new ModbusReadLongChannel("Cell133Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1586, + batteryCell134Voltage = new ModbusReadLongChannel("Cell134Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1587, + batteryCell135Voltage = new ModbusReadLongChannel("Cell135Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1588, + batteryCell136Voltage = new ModbusReadLongChannel("Cell136Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1589, + batteryCell137Voltage = new ModbusReadLongChannel("Cell137Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x158A, + batteryCell138Voltage = new ModbusReadLongChannel("Cell138Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x158B, + batteryCell139Voltage = new ModbusReadLongChannel("Cell139Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x158C, + batteryCell140Voltage = new ModbusReadLongChannel("Cell140Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x158D, + batteryCell141Voltage = new ModbusReadLongChannel("Cell141Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x158E, + batteryCell142Voltage = new ModbusReadLongChannel("Cell142Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x158F, + batteryCell143Voltage = new ModbusReadLongChannel("Cell143Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1590, + batteryCell144Voltage = new ModbusReadLongChannel("Cell144Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1591, + batteryCell145Voltage = new ModbusReadLongChannel("Cell145Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1592, + batteryCell146Voltage = new ModbusReadLongChannel("Cell146Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1593, + batteryCell147Voltage = new ModbusReadLongChannel("Cell147Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1594, + batteryCell148Voltage = new ModbusReadLongChannel("Cell148Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1595, + batteryCell149Voltage = new ModbusReadLongChannel("Cell149Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1596, + batteryCell150Voltage = new ModbusReadLongChannel("Cell150Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1597, + batteryCell151Voltage = new ModbusReadLongChannel("Cell151Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1598, + batteryCell152Voltage = new ModbusReadLongChannel("Cell152Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x1599, + batteryCell153Voltage = new ModbusReadLongChannel("Cell153Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x159A, + batteryCell154Voltage = new ModbusReadLongChannel("Cell154Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x159B, + batteryCell155Voltage = new ModbusReadLongChannel("Cell155Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x159C, + batteryCell156Voltage = new ModbusReadLongChannel("Cell156Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x159D, + batteryCell157Voltage = new ModbusReadLongChannel("Cell157Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x159E, + batteryCell158Voltage = new ModbusReadLongChannel("Cell158Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x159F, + batteryCell159Voltage = new ModbusReadLongChannel("Cell159Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15A0, + batteryCell160Voltage = new ModbusReadLongChannel("Cell160Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15A1, + batteryCell161Voltage = new ModbusReadLongChannel("Cell161Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15A2, + batteryCell162Voltage = new ModbusReadLongChannel("Cell162Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15A3, + batteryCell163Voltage = new ModbusReadLongChannel("Cell163Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15A4, + batteryCell164Voltage = new ModbusReadLongChannel("Cell164Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15A5, + batteryCell165Voltage = new ModbusReadLongChannel("Cell165Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15A6, + batteryCell166Voltage = new ModbusReadLongChannel("Cell166Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15A7, + batteryCell167Voltage = new ModbusReadLongChannel("Cell167Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15A8, + batteryCell168Voltage = new ModbusReadLongChannel("Cell168Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15A9, + batteryCell169Voltage = new ModbusReadLongChannel("Cell169Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15AA, + batteryCell170Voltage = new ModbusReadLongChannel("Cell170Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15AB, + batteryCell171Voltage = new ModbusReadLongChannel("Cell171Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15AC, + batteryCell172Voltage = new ModbusReadLongChannel("Cell172Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15AD, + batteryCell173Voltage = new ModbusReadLongChannel("Cell173Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15AE, + batteryCell174Voltage = new ModbusReadLongChannel("Cell174Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15AF, + batteryCell175Voltage = new ModbusReadLongChannel("Cell175Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15B0, + batteryCell176Voltage = new ModbusReadLongChannel("Cell176Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15B1, + batteryCell177Voltage = new ModbusReadLongChannel("Cell177Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15B2, + batteryCell178Voltage = new ModbusReadLongChannel("Cell178Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15B3, + batteryCell179Voltage = new ModbusReadLongChannel("Cell179Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15B4, + batteryCell180Voltage = new ModbusReadLongChannel("Cell180Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15B5, + batteryCell181Voltage = new ModbusReadLongChannel("Cell181Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15B6, + batteryCell182Voltage = new ModbusReadLongChannel("Cell182Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15B7, + batteryCell183Voltage = new ModbusReadLongChannel("Cell183Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15B8, + batteryCell184Voltage = new ModbusReadLongChannel("Cell184Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15B9, + batteryCell185Voltage = new ModbusReadLongChannel("Cell185Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15BA, + batteryCell186Voltage = new ModbusReadLongChannel("Cell186Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15BB, + batteryCell187Voltage = new ModbusReadLongChannel("Cell187Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15BC, + batteryCell188Voltage = new ModbusReadLongChannel("Cell188Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15BD, + batteryCell189Voltage = new ModbusReadLongChannel("Cell189Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15BE, + batteryCell190Voltage = new ModbusReadLongChannel("Cell190Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15BF, + batteryCell191Voltage = new ModbusReadLongChannel("Cell191Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15C0, + batteryCell192Voltage = new ModbusReadLongChannel("Cell192Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15C1, + batteryCell193Voltage = new ModbusReadLongChannel("Cell193Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15C2, + batteryCell194Voltage = new ModbusReadLongChannel("Cell194Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15C3, + batteryCell195Voltage = new ModbusReadLongChannel("Cell195Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15C4, + batteryCell196Voltage = new ModbusReadLongChannel("Cell196Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15C5, + batteryCell197Voltage = new ModbusReadLongChannel("Cell197Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15C6, + batteryCell198Voltage = new ModbusReadLongChannel("Cell198Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15C7, + batteryCell199Voltage = new ModbusReadLongChannel("Cell199Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15C8, + batteryCell200Voltage = new ModbusReadLongChannel("Cell200Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15C9, + batteryCell201Voltage = new ModbusReadLongChannel("Cell201Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15CA, + batteryCell202Voltage = new ModbusReadLongChannel("Cell202Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15CB, + batteryCell203Voltage = new ModbusReadLongChannel("Cell203Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15CC, + batteryCell204Voltage = new ModbusReadLongChannel("Cell204Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15CD, + batteryCell205Voltage = new ModbusReadLongChannel("Cell205Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15CE, + batteryCell206Voltage = new ModbusReadLongChannel("Cell206Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15CF, + batteryCell207Voltage = new ModbusReadLongChannel("Cell207Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15D0, + batteryCell208Voltage = new ModbusReadLongChannel("Cell208Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15D1, + batteryCell209Voltage = new ModbusReadLongChannel("Cell209Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15D2, + batteryCell210Voltage = new ModbusReadLongChannel("Cell210Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15D3, + batteryCell211Voltage = new ModbusReadLongChannel("Cell211Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15D4, + batteryCell212Voltage = new ModbusReadLongChannel("Cell212Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15D5, + batteryCell213Voltage = new ModbusReadLongChannel("Cell213Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15D6, + batteryCell214Voltage = new ModbusReadLongChannel("Cell214Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15D7, + batteryCell215Voltage = new ModbusReadLongChannel("Cell215Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15D8, + batteryCell216Voltage = new ModbusReadLongChannel("Cell216Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15D9, + batteryCell217Voltage = new ModbusReadLongChannel("Cell217Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15DA, + batteryCell218Voltage = new ModbusReadLongChannel("Cell218Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15DB, + batteryCell219Voltage = new ModbusReadLongChannel("Cell219Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15DC, + batteryCell220Voltage = new ModbusReadLongChannel("Cell220Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15DD, + batteryCell221Voltage = new ModbusReadLongChannel("Cell221Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15DE, + batteryCell222Voltage = new ModbusReadLongChannel("Cell222Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15DF, + batteryCell223Voltage = new ModbusReadLongChannel("Cell223Voltage", this).unit("mV") + ),// + new UnsignedWordElement(0x15E0, + batteryCell224Voltage = new ModbusReadLongChannel("Cell224Voltage", this).unit("mV") + ))); } diff --git a/edge/src/io/openems/impl/device/commercial/Warning.java b/edge/src/io/openems/impl/device/commercial/Warning.java deleted file mode 100644 index cd2fabcd87c..00000000000 --- a/edge/src/io/openems/impl/device/commercial/Warning.java +++ /dev/null @@ -1,19 +0,0 @@ -package io.openems.impl.device.commercial; - -import io.openems.api.channel.thingstate.WarningEnum; - -public enum Warning implements WarningEnum { - EmergencyStop(0),KeyManualStop(1),TransformerPhaseBTemperatureSensorInvalidation(2),SDMemoryCardInvalidation(3); - - private final int value; - - private Warning(int value) { - this.value = value; - } - - @Override - public int getValue() { - return this.value; - } - -} diff --git a/edge/src/io/openems/impl/device/commercial/WarningCharger.java b/edge/src/io/openems/impl/device/commercial/WarningCharger.java new file mode 100644 index 00000000000..3f5cb977a56 --- /dev/null +++ b/edge/src/io/openems/impl/device/commercial/WarningCharger.java @@ -0,0 +1,57 @@ +package io.openems.impl.device.commercial; + +import io.openems.api.channel.thingstate.WarningEnum; + +public enum WarningCharger implements WarningEnum{ + CurrentSamplingChannelAbnormityOnHighVoltageSide(0), CurrentSamplingChannelAbnormityOnLowVoltageSide(1), BmsDCDC1EEPROMParametersOverRange(2),EEPROMParametersOverRange(3), UpdateEEPROMFailed(4), + ReadEEPROMFailed(5), CurrentSamplingChannelAbnormityBeforeInductance(6), ReactorPowerDecreaseCausedByOvertemperature(7), IGBTPowerDecreaseCausedByOvertemperature(8), + TemperatureChanel3PowerDecreaseCausedByOvertemperature(9), TemperatureChanel4PowerDecreaseCausedByOvertemperature(10), TemperatureChanel5PowerDecreaseCausedByOvertemperature(11), + TemperatureChanel6PowerDecreaseCausedByOvertemperature(12), TemperatureChanel7PowerDecreaseCausedByOvertemperature(13), TemperatureChanel8PowerDecreaseCausedByOvertemperature(14), + Fan1StopFailed(15), Fan2StopFailed(16), Fan3StopFailed(17), Fan4StopFailed(18), Fan1StartupFailed(19), Fan2StartupFailed(20), Fan3StartupFailed(21), Fan4StartupFailed(22), + HighVoltageSideOvervoltage(23), HighVoltageSideUndervoltage(24), HighVoltageSideVoltageChangeUnconventionally(25),CurrentAbnormityBeforeDCConverterWorkOnHighVoltageSide(26), + CurrentAbnormityBeforeDCConverterWorkOnLowVoltageSXide(27), InitialDutyRatioAbnormityBeforeDCConverterWork(28),VoltageAbnormityBeforeDCConverterWorkOnHighVoltageSide(29), + VoltageAbnormityBeforeDCConverterWorkOnLowVoltageSide(30), HighVoltageBreakerInspectionAbnormity(31),LowVoltageBreakerInspectionAbnormity(32), BsmDCDC5DCPrechargeContactorInspectionAbnormity(33), + DCPrechargeContactorOpenUnsuccessfully(34), DCMainContactorInspectionAbnormity(35),DCMainContactorOpenUnsuccessfully(36), OutputContactorCloseUnsuccessfully(37), OutputContactorOpenUnsuccessfully(38), + ACMainContactorCloseUnsuccessfully(39), ACMainContactorOpenUnsuccessfully(40),NegContactorOpenUnsuccessfully(41), NegContactorCloseUnsuccessfully(42), NegContactorStateAbnormal(43), + BsmDCDC1CurrentSamplingChannelAbnormityOnHighVoltageSide(44), BsmDCDC1CurrentSamplingChannelAbnormityOnLowVoltageSide(45), BsmDCDC1EEPROMParametersOverRange(46), BsmDCDC1UpdateEEPROMFailed(47), + BsmDCDC1ReadEEPROMFailed(48), BsmDCDC1CurrentSamplingChannelAbnormityBeforeInductance(49), BsmDCDC1ReactorPowerDecreaseCausedByOvertemperature(50), BsmDCDC1IGBTPowerDecreaseCausedByOvertemperature(51), + BsmDCDC1TemperatureChanel3PowerDecreaseCausedByOvertemperature(52), BsmDCDC1TemperatureChanel4PowerDecreaseCausedByOvertemperature(53), BsmDCDC1TemperatureChanel5PowerDecreaseCausedByOvertemperature(54), + BsmDCDC1TemperatureChanel6PowerDecreaseCausedByOvertemperature(55), BsmDCDC1TemperatureChanel7PowerDecreaseCausedByOvertemperature(56), BsmDCDC1TemperatureChanel8PowerDecreaseCausedByOvertemperature(57), + BsmDCDC1Fan1StopFailed(58), BsmDCDC1Fan2StopFailed(59), BsmDCDC1Fan3StopFailed(60), BsmDCDC1Fan4StopFailed(61), BsmDCDC1Fan1StartupFailed(62), BsmDCDC1Fan2StartupFailed(63), BsmDCDC1Fan3StartupFailed(64), + BsmDCDC1Fan4StartupFailed(65), BsmDCDC1HighVoltageSideOvervoltage(66), BsmDCDC1HighVoltageSideUndervoltage(67), BsmDCDC1HighVoltageSideVoltageChangeUnconventionally(68), BmsDCDC1CurrentAbnormityBeforeDCConverterWorkOnHighVoltageSide(69), + BmsDCDC1CurrentAbnormityBeforeDCConverterWorkOnLowVoltageSXide(70), BmsDCDC1InitialDutyRatioAbnormityBeforeDCConverterWork(71), BmsDCDC1VoltageAbnormityBeforeDCConverterWorkOnHighVoltageSide(72), + BmsDCDC1VoltageAbnormityBeforeDCConverterWorkOnLowVoltageSide(73), BmsDCDC1HighVoltageBreakerInspectionAbnormity(74), BmsDCDC1LowVoltageBreakerInspectionAbnormity(75), BmsDCDC1BsmDCDC5DCPrechargeContactorInspectionAbnormity(76), + BmsDCDC1DCPrechargeContactorOpenUnsuccessfully(77), BmsDCDC1DCMainContactorInspectionAbnormity(78), BmsDCDC1DCMainContactorOpenUnsuccessfully(79), BmsDCDC1OutputContactorCloseUnsuccessfully(80), + BmsDCDC1OutputContactorOpenUnsuccessfully(81), BmsDCDC1ACMainContactorCloseUnsuccessfully(82), BmsDCDC1ACMainContactorOpenUnsuccessfully(83), BmsDCDC1NegContactorOpenUnsuccessfully(84), + BmsDCDC1NegContactorCloseUnsuccessfully(85), BmsDCDC1NegContactorStateAbnormal(86), PvDCDCCurrentSamplingChannelAbnormityOnHighVoltageSide(87), PvDCDCCurrentSamplingChannelAbnormityOnLowVoltageSide(88), + PvDCDCEEPROMParametersOverRange(89), PvDCDCUpdateEEPROMFailed(90), PvDCDCReadEEPROMFailed(91), PvDCDCCurrentSamplingChannelAbnormityBeforeInductance(92), PvDCDCReactorPowerDecreaseCausedByOvertemperature(93), + PvDCDCIGBTPowerDecreaseCausedByOvertemperature(94), PvDCDCTemperatureChanel3PowerDecreaseCausedByOvertemperature(95), PvDCDCTemperatureChanel4PowerDecreaseCausedByOvertemperature(96), PvDCDCTemperatureChanel5PowerDecreaseCausedByOvertemperature(97), + PvDCDCTemperatureChanel6PowerDecreaseCausedByOvertemperature(98), PvDCDCTemperatureChanel7PowerDecreaseCausedByOvertemperature(99), PvDCDCTemperatureChanel8PowerDecreaseCausedByOvertemperature(100), + PvDCDCFan1StopFailed(101), PvDCDCFan2StopFailed(102), PvDCDCFan3StopFailed(103), PvDCDCFan4StopFailed(104), PvDCDCFan1StartupFailed(105), PvDCDCFan2StartupFailed(106), PvDCDCFan3StartupFailed(107), + PvDCDCFan4StartupFailed(108), PvDCDCHighVoltageSideOvervoltage(109), PvDCDCHighVoltageSideUndervoltage(110), PvDCDCHighVoltageSideVoltageChangeUnconventionally(111), PvDCDCCurrentAbnormityBeforeDCConverterWorkOnHighVoltageSide(112), + PvDCDCCurrentAbnormityBeforeDCConverterWorkOnLowVoltageSXide(113), PvDCDCInitialDutyRatioAbnormityBeforeDCConverterWork(114), PvDCDCVoltageAbnormityBeforeDCConverterWorkOnHighVoltageSide(115), + PvDCDCVoltageAbnormityBeforeDCConverterWorkOnLowVoltageSide(116), PvDCDCHighVoltageBreakerInspectionAbnormity(117), PvDCDCLowVoltageBreakerInspectionAbnormity(118), PvDCDCBsmDCDC5DCPrechargeContactorInspectionAbnormity(119), + PvDCDCDCPrechargeContactorOpenUnsuccessfully(120), PvDCDCDCMainContactorInspectionAbnormity(121), PvDCDCDCMainContactorOpenUnsuccessfully(122), PvDCDCOutputContactorCloseUnsuccessfully(123), PvDCDCOutputContactorOpenUnsuccessfully(124), + PvDCDCACMainContactorCloseUnsuccessfully(125), PvDCDCACMainContactorOpenUnsuccessfully(126), PvDCDCNegContactorOpenUnsuccessfully(127), PvDCDCNegContactorCloseUnsuccessfully(128), PvDCDCNegContactorStateAbnormal(129), + PvDCDC1CurrentSamplingChannelAbnormityOnHighVoltageSide(130), PvDCDC1CurrentSamplingChannelAbnormityOnLowVoltageSide(131), PvDCDC1EEPROMParametersOverRange(132), PvDCDC1UpdateEEPROMFailed(133), PvDCDC1ReadEEPROMFailed(134), + PvDCDC1CurrentSamplingChannelAbnormityBeforeInductance(135), PvDCDC1ReactorPowerDecreaseCausedByOvertemperature(136), PvDCDC1IGBTPowerDecreaseCausedByOvertemperature(137), PvDCDC1TemperatureChanel3PowerDecreaseCausedByOvertemperature(138), + PvDCDC1TemperatureChanel4PowerDecreaseCausedByOvertemperature(139), PvDCDC1TemperatureChanel5PowerDecreaseCausedByOvertemperature(140), PvDCDC1TemperatureChanel6PowerDecreaseCausedByOvertemperature(141), PvDCDC1TemperatureChanel7PowerDecreaseCausedByOvertemperature(142), + PvDCDC1TemperatureChanel8PowerDecreaseCausedByOvertemperature(143), PvDCDC1Fan1StopFailed(144), PvDCDC1Fan2StopFailed(145), PvDCDC1Fan3StopFailed(146), PvDCDC1Fan4StopFailed(147), PvDCDC1Fan1StartupFailed(148), PvDCDC1Fan2StartupFailed(149), + PvDCDC1Fan3StartupFailed(150), PvDCDC1Fan4StartupFailed(151), PvDCDC1HighVoltageSideOvervoltage(152), PvDCDC1HighVoltageSideUndervoltage(153), PvDCDC1HighVoltageSideVoltageChangeUnconventionally(154), PvDCDC1CurrentAbnormityBeforeDCConverterWorkOnHighVoltageSide(155), + PvDCDC1CurrentAbnormityBeforeDCConverterWorkOnLowVoltageSXide(156), PvDCDC1InitialDutyRatioAbnormityBeforeDCConverterWork(157), PvDCDC1VoltageAbnormityBeforeDCConverterWorkOnHighVoltageSide(158), PvDCDC1VoltageAbnormityBeforeDCConverterWorkOnLowVoltageSide(159), + PvDCDC1HighVoltageBreakerInspectionAbnormity(160), PvDCDC1LowVoltageBreakerInspectionAbnormity(161), PvDCDC1BsmDCDC5DCPrechargeContactorInspectionAbnormity(162), PvDCDC1DCPrechargeContactorOpenUnsuccessfully(163), PvDCDC1DCMainContactorInspectionAbnormity(164), + PvDCDC1DCMainContactorOpenUnsuccessfully(165), PvDCDC1OutputContactorCloseUnsuccessfully(166), PvDCDC1OutputContactorOpenUnsuccessfully(167), PvDCDC1ACMainContactorCloseUnsuccessfully(168), PvDCDC1ACMainContactorOpenUnsuccessfully(169), + PvDCDC1NegContactorOpenUnsuccessfully(170), PvDCDC1NegContactorCloseUnsuccessfully(171), PvDCDC1NegContactorStateAbnormal(172); + + + public final int value; + + private WarningCharger(int value) { + this.value = value; + } + + @Override + public int getValue() { + return this.value; + } +} diff --git a/edge/src/io/openems/impl/device/commercial/WarningEss.java b/edge/src/io/openems/impl/device/commercial/WarningEss.java new file mode 100644 index 00000000000..6e2d256a714 --- /dev/null +++ b/edge/src/io/openems/impl/device/commercial/WarningEss.java @@ -0,0 +1,29 @@ +package io.openems.impl.device.commercial; + +import io.openems.api.channel.thingstate.WarningEnum; + +public enum WarningEss implements WarningEnum { + EmergencyStop(0), KeyManualStop(1), TransformerPhaseBTemperatureSensorInvalidation(2), SDMemoryCardInvalidation(4), + InverterCommunicationAbnormity(5), BatteryStackCommunicationAbnormity(6), MultifunctionalAmmeterCommunicationAbnormity(7), + RemoteCommunicationAbnormity(8), PVDC1CommunicationAbnormity(9), PVDC2CommunicationAbnormity(10), TransformerSevereOvertemperature(11), + DCPrechargeContactorInspectionAbnormity(12), DCBreaker1InspectionAbnormity(13), DCBreaker2InspectionAbnormity(14), ACPrechargeContactorInspectionAbnormity(15), + ACMainontactorInspectionAbnormity(16), ACBreakerInspectionAbnormity(17), DCBreaker1CloseUnsuccessfully(18), DCBreaker2CloseUnsuccessfully(19), + ControlSignalCloseAbnormallyInspectedBySystem(20), ControlSignalOpenAbnormallyInspectedBySystem(21), NeutralWireContactorCloseUnsuccessfully(22), + NeutralWireContactorOpenUnsuccessfully(23), WorkDoorOpen(24), Emergency1Stop(25), ACBreakerCloseUnsuccessfully(26), ControlSwitchStop(27), GeneralOverload(28), + SevereOverload(29), BatteryCurrentOverLimit(30), PowerDecreaseCausedByOvertemperature(31), InverterGeneralOvertemperature(32), ACThreePhaseCurrentUnbalance(33), + RestoreFactorySettingUnsuccessfully(34), PoleBoardInvalidation(35), SelfInspectionFailed(36), ReceiveBMSFaultAndStop(37), RefrigerationEquipmentinvalidation(38), + LargeTemperatureDifferenceAmongIGBTThreePhases(39), EEPROMParametersOverRange(40), EEPROMParametersBackupFailed(41), DCBreakerCloseunsuccessfully(42), + CommunicationBetweenInverterAndBSMUDisconnected(43), CommunicationBetweenInverterAndMasterDisconnected(44), CommunicationBetweenInverterAndUCDisconnected(45), + BMSStartOvertimeControlledByPCS(46), BMSStopOvertimeControlledByPCS(47), SyncSignalInvalidation(48), SyncSignalContinuousCaputureFault(49), SyncSignalSeveralTimesCaputureFault(50); + + public final int value; + + private WarningEss(int value) { + this.value = value; + } + + @Override + public int getValue() { + return this.value; + } +} diff --git a/edge/src/io/openems/impl/device/mini/FaultEss.java b/edge/src/io/openems/impl/device/mini/FaultEss.java new file mode 100644 index 00000000000..7cb96a7ec7c --- /dev/null +++ b/edge/src/io/openems/impl/device/mini/FaultEss.java @@ -0,0 +1,28 @@ +package io.openems.impl.device.mini; + +import io.openems.api.channel.thingstate.FaultEnum; + +public enum FaultEss implements FaultEnum{ + ControlCurrentOverload100Percent(0), ControlCurrentOverload110Percent(1), ControlCurrentOverload150Percent(2), ControlCurrentOverload200Percent(3), + ControlCurrentOverload120Percent(4), ControlCurrentOverload300Percent(5), ControlTransientLoad300Percent(6), GridOverCurrent(7), LockingWaveformTooManyTimes(8), + InverterVoltageZeroDriftError(9), GridVoltageZeroDriftError(10), ControlCurrentZeroDriftError(11), InverterCurrentZeroDriftError(12), GridCurrentZeroDriftError(13), + PDPProtection(14), HardwareControlCurrentProtection(15), HardwareACVoltProtection(16), HardwareDCCurrentProtection(17), HardwareTemperatureProtection(18), + NoCapturingSignal(19), DCOvervoltage(20), DCDisconnected(21), InverterUndervoltage(22), InverterOvervoltage(23), CurrentSensorFail(24), VoltageSensorFail(25), + PowerUncontrollable(26), CurrentUncontrollable(27), FanError(28), PhaseLack(29), InverterRelayFault(30), GridRelayFault(31), ControlPanelOvertemp(32), PowerPanelOvertemp(33), + DCInputOvercurrent(34), CapacitorOvertemp(35), RadiatorOvertemp(36), TransformerOvertemp(37), CombinationCommError(38), EEPROMError(39), LoadCurrentZeroDriftError(40), + CurrentLimitRError(41), PhaseSyncError(42), ExternalPVCurrentZeroDriftError(43), ExternalGridCurrentZeroDriftError(44); + + + + + private final int value; + + private FaultEss(int value) { + this.value = value; + } + + @Override + public int getValue() { + return this.value; + } +} diff --git a/edge/src/io/openems/impl/device/mini/FeneconMiniEss.java b/edge/src/io/openems/impl/device/mini/FeneconMiniEss.java index 3a3cee72302..3a2fac68fe2 100644 --- a/edge/src/io/openems/impl/device/mini/FeneconMiniEss.java +++ b/edge/src/io/openems/impl/device/mini/FeneconMiniEss.java @@ -25,7 +25,6 @@ import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; import io.openems.api.channel.StatusBitChannel; -import io.openems.api.channel.StatusBitChannels; import io.openems.api.channel.WriteChannel; import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; @@ -36,6 +35,7 @@ import io.openems.api.exception.ConfigException; import io.openems.api.exception.InvalidValueException; import io.openems.core.utilities.ControllerUtils; +import io.openems.impl.protocol.modbus.ModbusBitWrappingChannel; import io.openems.impl.protocol.modbus.ModbusDeviceNature; import io.openems.impl.protocol.modbus.ModbusReadLongChannel; import io.openems.impl.protocol.modbus.ModbusWriteLongChannel; @@ -86,7 +86,6 @@ public ConfigChannel chargeSoc() { * Inherited Channels */ // ESS - private StatusBitChannels warning; private ModbusReadLongChannel allowedCharge; private ModbusReadLongChannel allowedDischarge; private ReadChannel gridMode; @@ -225,7 +224,6 @@ public WriteChannel rtcSecond() { */ @Override protected ModbusProtocol defineModbusProtocol() throws ConfigException { - warning = new StatusBitChannels("Warning", this); ModbusProtocol protokol = new ModbusProtocol(new ModbusRegisterRange(100, // new UnsignedWordElement(100, // @@ -263,14 +261,16 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { new SignedWordElement(112, // batteryPower = new ModbusReadLongChannel("BatteryPower", this).unit("W")), new UnsignedWordElement(113, // - batteryGroupAlarm = new ModbusReadLongChannel("BatteryGroupAlarm", this) - .label(1, "Fail, The system should be stopped") // - .label(2, "Common low voltage alarm") // - .label(4, "Common high voltage alarm") // - .label(8, "Charging over current alarm") // - .label(16, "Discharging over current alarm") // - .label(32, "Over temperature alarm")// - .label(64, "Interal communication abnormal")), + new ModbusBitWrappingChannel("BatteryGroupAlarm" , this, this.thingState)// + .warningBit(0, WarningEss.FailTheSystemShouldBeStopped )// + .warningBit(1, WarningEss.CommonLowVoltageAlarm)// + .warningBit(2, WarningEss.CommonHighVoltageAlarm)// + .warningBit(3, WarningEss.ChargingOverCurrentAlarm)// + .warningBit(4, WarningEss.DischargingOverCurrentAlarm)// + .warningBit(5, WarningEss.OverTemperatureAlarm)// + .warningBit(6, WarningEss.InteralCommunicationAbnormal)// + ),// + new UnsignedWordElement(114, // pcsOperationState = new ModbusReadLongChannel("PcsOperationState", this) .label(0, "Self-checking") // @@ -299,68 +299,82 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { new UnsignedWordElement(142, // allowedDischarge = new ModbusReadLongChannel("AllowedDischarge", this).unit("W")), new DummyElement(143, 149), - new UnsignedWordElement(150, pcsAlarm1 = warning.channel(new StatusBitChannel("PcsAlarm1", this)// - .label(1, "Grid undervoltage") // - .label(2, "Grid overvoltage") // - .label(4, "Grid under frequency") // - .label(8, "Grid over frequency") // - .label(16, "Grid power supply off") // - .label(32, "Grid condition unmeet")// - .label(64, "DC under voltage")// - .label(128, "Input over resistance")// - .label(256, "Combination error")// - .label(512, "Comm with inverter error")// - .label(1024, "Tme error")// - )), new UnsignedWordElement(151, pcsAlarm2 = warning.channel(new StatusBitChannel("PcsAlarm2", this)// - )), new UnsignedWordElement(152, warning.channel(pcsFault1 = new StatusBitChannel("PcsFault1", this)// - .label(1, "Control current overload 100%")// - .label(2, "Control current overload 110%")// - .label(4, "Control current overload 150%")// - .label(8, "Control current overload 200%")// - .label(16, "Control current overload 120%")// - .label(32, "Control current overload 300%")// - .label(64, "Control transient load 300%")// - .label(128, "Grid over current")// - .label(256, "Locking waveform too many times")// - .label(512, "Inverter voltage zero drift error")// - .label(1024, "Grid voltage zero drift error")// - .label(2048, "Control current zero drift error")// - .label(4096, "Inverter current zero drift error")// - .label(8192, "Grid current zero drift error")// - .label(16384, "PDP protection")// - .label(32768, "Hardware control current protection")// - )), new UnsignedWordElement(153, warning.channel(pcsFault2 = new StatusBitChannel("PcsFault2", this)// - .label(1, "Hardware AC volt. protection")// - .label(2, "Hardware DC curr. protection")// - .label(4, "Hardware temperature protection")// - .label(8, "No capturing signal")// - .label(16, "DC overvoltage")// - .label(32, "DC disconnected")// - .label(64, "Inverter undervoltage")// - .label(128, "Inverter overvoltage")// - .label(256, "Current sensor fail")// - .label(512, "Voltage sensor fail")// - .label(1024, "Power uncontrollable")// - .label(2048, "Current uncontrollable")// - .label(4096, "Fan error")// - .label(8192, "Phase lack")// - .label(16384, "Inverter relay fault")// - .label(32768, "Grid relay fault")// - )), new UnsignedWordElement(154, warning.channel(pcsFault3 = new StatusBitChannel("PcsFault3", this)// - .label(1, "Control panel overtemp")// - .label(2, "Power panel overtemp")// - .label(4, "DC input overcurrent")// - .label(8, "Capacitor overtemp")// - .label(16, "Radiator overtemp")// - .label(32, "Transformer overtemp")// - .label(64, "Combination comm error")// - .label(128, "EEPROM error")// - .label(256, "Load current zero drift error")// - .label(512, "Current limit-R error")// - .label(1024, "Phase sync error")// - .label(2048, "External PV current zero drift error")// - .label(4096, "External grid current zero drift error")// - ))), // + new UnsignedWordElement(150,// + new ModbusBitWrappingChannel("PcsAlarm1" , this, this.thingState)// + .warningBit(0, WarningEss.GridUndervoltage)// + .warningBit(1, WarningEss.GridOvervoltage)// + .warningBit(2, WarningEss.GridUnderFrequency)// + .warningBit(3, WarningEss.GridOverFrequency)// + .warningBit(4, WarningEss.GridPowerSupplyOff)// + .warningBit(5, WarningEss.GridConditionUnmeet)// + .warningBit(6, WarningEss.DCUnderVoltage)// + .warningBit(7, WarningEss.InputOverResistance)// + .warningBit(8, WarningEss.CombinationError)// + .warningBit(9, WarningEss.CommWithInverterError)// + .warningBit(10,WarningEss.TmeError)// + ),// + + new UnsignedWordElement(151, + new ModbusBitWrappingChannel("PcsAlarm2", this, this.thingState)// + ), // + + new UnsignedWordElement(152, + new ModbusBitWrappingChannel("PcsFault1", this, this.thingState)// + .faultBit(0, FaultEss.ControlCurrentOverload100Percent)// + .faultBit(1, FaultEss.ControlCurrentOverload110Percent)// + .faultBit(2, FaultEss.ControlCurrentOverload150Percent)// + .faultBit(3, FaultEss.ControlCurrentOverload200Percent)// + .faultBit(4, FaultEss.ControlCurrentOverload120Percent)// + .faultBit(5, FaultEss.ControlCurrentOverload300Percent)// + .faultBit(6, FaultEss.ControlTransientLoad300Percent)// + .faultBit(7, FaultEss.GridOverCurrent)// + .faultBit(8, FaultEss.LockingWaveformTooManyTimes)// + .faultBit(9, FaultEss.InverterVoltageZeroDriftError)// + .faultBit(10,FaultEss.GridVoltageZeroDriftError)// + .faultBit(11,FaultEss.ControlCurrentZeroDriftError)// + .faultBit(12,FaultEss.InverterCurrentZeroDriftError)// + .faultBit(13,FaultEss.GridCurrentZeroDriftError)// + .faultBit(14, FaultEss.PDPProtection)// + .faultBit(15, FaultEss.HardwareControlCurrentProtection)// + ),// + + new UnsignedWordElement(153, // + new ModbusBitWrappingChannel("PcsFault2" , this, this.thingState)// + .faultBit(0, FaultEss.HardwareACVoltProtection)// + .faultBit(1, FaultEss.HardwareDCCurrentProtection)// + .faultBit(2, FaultEss.HardwareTemperatureProtection)// + .faultBit(3, FaultEss.NoCapturingSignal)// + .faultBit(4, FaultEss.DCOvervoltage)// + .faultBit(5, FaultEss.DCDisconnected)// + .faultBit(6, FaultEss.InverterUndervoltage)// + .faultBit(7, FaultEss.InverterOvervoltage)// + .faultBit(8, FaultEss.CurrentSensorFail)// + .faultBit(9, FaultEss.VoltageSensorFail)// + .faultBit(10,FaultEss.PowerUncontrollable)// + .faultBit(11,FaultEss.CurrentUncontrollable)// + .faultBit(12,FaultEss.FanError)// + .faultBit(13,FaultEss.PhaseLack)// + .faultBit(14,FaultEss.InverterRelayFault)// + .faultBit(15,FaultEss.GridRelayFault)// + ),// + + new UnsignedWordElement(154, // + new ModbusBitWrappingChannel("PcsFault3", this, this.thingState)// + .faultBit(0, FaultEss.ControlPanelOvertemp)// + .faultBit(1, FaultEss.PowerPanelOvertemp)// + .faultBit(2, FaultEss.DCInputOvercurrent)// + .faultBit(3, FaultEss.CapacitorOvertemp)// + .faultBit(4, FaultEss.RadiatorOvertemp)// + .faultBit(5, FaultEss.TransformerOvertemp)// + .faultBit(6, FaultEss.CombinationCommError)// + .faultBit(7, FaultEss.EEPROMError)// + .faultBit(8, FaultEss.LoadCurrentZeroDriftError)// + .faultBit(9, FaultEss.CurrentLimitRError)// + .faultBit(10,FaultEss.PhaseSyncError)// + .faultBit(11,FaultEss.ExternalPVCurrentZeroDriftError)// + .faultBit(12,FaultEss.ExternalGridCurrentZeroDriftError)// + )),// + new WriteableModbusRegisterRange(200, // new UnsignedWordElement(200, setWorkState = new ModbusWriteLongChannel("SetWorkState", this)// .label(0, "Local control") // diff --git a/edge/src/io/openems/impl/device/mini/WarningEss.java b/edge/src/io/openems/impl/device/mini/WarningEss.java new file mode 100644 index 00000000000..acd33576da4 --- /dev/null +++ b/edge/src/io/openems/impl/device/mini/WarningEss.java @@ -0,0 +1,21 @@ +package io.openems.impl.device.mini; + +import io.openems.api.channel.thingstate.WarningEnum; + +public enum WarningEss implements WarningEnum{ + FailTheSystemShouldBeStopped(0), CommonLowVoltageAlarm(1), CommonHighVoltageAlarm(2), ChargingOverCurrentAlarm(3), + DischargingOverCurrentAlarm(4), OverTemperatureAlarm(5), InteralCommunicationAbnormal(6), GridUndervoltage(7), + GridOvervoltage(8), GridUnderFrequency(9), GridOverFrequency(10), GridPowerSupplyOff(11), GridConditionUnmeet(12), + DCUnderVoltage(13), InputOverResistance(14), CombinationError(15), CommWithInverterError(16), TmeError(17); + + public final int value; + + private WarningEss(int value) { + this.value = value; + } + + @Override + public int getValue() { + return this.value; + } +} diff --git a/edge/src/io/openems/impl/device/minireadonly/FaultEss.java b/edge/src/io/openems/impl/device/minireadonly/FaultEss.java new file mode 100644 index 00000000000..877cd7ad862 --- /dev/null +++ b/edge/src/io/openems/impl/device/minireadonly/FaultEss.java @@ -0,0 +1,27 @@ +package io.openems.impl.device.minireadonly; + +import io.openems.api.channel.thingstate.FaultEnum; + +public enum FaultEss implements FaultEnum +{ + + BECU1DischargeSevereOvercurrent(0), BECU1ChargeSevereOvercurrent(1), BECU1GeneralUndervoltage(2), BECU1SevereOvervoltage(3), BECU1GeneralOvervoltage(4), BECU1SevereUndervoltage(5), BECU1InsideCANBroken(6), + BECU1GeneralUndervoltageHighCurrentDischarge(7), BECU1BMUError(8), BECU1CurrentSamplingInvalidation(9), BECU1BatteryFail(10), BECU1TemperatureSamplingBroken(11), BECU1Contactor1TestBackIsAbnormalTurnOnAbnormity(12), + BECU1Contactor1TestBackIsAbnormalTurnOffAbnormity(13), BECU1Contactor2TestBackIsAbnormalTurnOnAbnormity(14), BECU1Contactor2TestBackIsAbnormalTurnOffAbnormity(15), BECU1SevereHighTemperatureFault(16), + BECU1HallInvalidation(17), BECU1ContactorInvalidation(18), BECU1OutsideCANBroken(19), BECU1CathodeContactorBroken(20), BECU2DischargeSevereOvercurrent(21), BECU2ChargeSevereOvercurrent(22), BECU2GeneralUndervoltage(23), + BECU2SevereOvervoltage(24), BECU2GeneralOvervoltage(25), BECU2SevereUndervoltage(26), BECU2InsideCANBroken(27), BECU2GeneralUndervoltageHighCurrentDischarge(28), BECU2BMUError(29), BECU2CurrentSamplingInvalidation(30), + BECU2BatteryFail(31), BECU2TemperatureSamplingBroken(32), BECU2Contactor1TestBackIsAbnormalTurnOnAbnormity(33), BECU2Contactor1TestBackIsAbnormalTurnOffAbnormity(34), BECU2Contactor2TestBackIsAbnormalTurnOnAbnormity(35), + BECU2Contactor2TestBackIsAbnormalTurnOffAbnormity(36), BECU2SevereHighTemperatureFault(37), BECU2HallInvalidation(38), BECU2ContactorInvalidation(39), BECU2OutsideCANBroken(40), BECU2CathodeContactorBroken(41), + NoAvailableBatteryGroup(42), StackGeneralLeakage(43), StackSevereLeakage(44), StackStartingFail(45), StackStoppingFail(46), BatteryProtection(47), StackAndGroup1CANCommunicationInterrupt(48), + StackAndGroup2CANCommunicationInterrupt(49); + private final int value; + + private FaultEss(int value) { + this.value = value; + } + + @Override + public int getValue() { + return this.value; + } +} diff --git a/edge/src/io/openems/impl/device/minireadonly/FeneconMiniEss.java b/edge/src/io/openems/impl/device/minireadonly/FeneconMiniEss.java index 5a22f4dbf41..f7b6eaedbde 100644 --- a/edge/src/io/openems/impl/device/minireadonly/FeneconMiniEss.java +++ b/edge/src/io/openems/impl/device/minireadonly/FeneconMiniEss.java @@ -23,13 +23,13 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; -import io.openems.api.channel.StatusBitChannels; import io.openems.api.channel.WriteChannel; import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; import io.openems.api.device.nature.ess.AsymmetricEssNature; import io.openems.api.doc.ThingInfo; import io.openems.api.exception.ConfigException; +import io.openems.impl.protocol.modbus.ModbusBitWrappingChannel; import io.openems.impl.protocol.modbus.ModbusDeviceNature; import io.openems.impl.protocol.modbus.ModbusReadLongChannel; import io.openems.impl.protocol.modbus.internal.DummyElement; @@ -89,8 +89,6 @@ public ConfigChannel chargeSoc() { private StaticValueChannel reactivePowerL1 = new StaticValueChannel("ReactivePowerL1", this, 0l); private StaticValueChannel reactivePowerL2 = new StaticValueChannel("ReactivePowerL2", this, 0l); private StaticValueChannel reactivePowerL3 = new StaticValueChannel("ReactivePowerL3", this, 0l); - private StatusBitChannels warning = new StatusBitChannels("Warning", this); - /* * This channels */ @@ -318,13 +316,71 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { new UnsignedWordElement(3004, // this.becu1Soc = new ModbusReadLongChannel("Becu1Soc", this)), new UnsignedWordElement(3005, // - this.becu1Alarm1 = new ModbusReadLongChannel("Becu1Alarm1", this)), + new ModbusBitWrappingChannel("BecuAlarm1" , this, this.thingState)// + .warningBit(0, WarningEss.BECU1GeneralChargeOverCurrentAlarm )// + .warningBit(1, WarningEss.BECU1GeneralDischargeOverCurrentAlarm )// + .warningBit(2, WarningEss.BECU1ChargeCurrentLimitAlarm)// + .warningBit(3, WarningEss.BECU1DischargeCurrentLimitAlarm)// + .warningBit(4, WarningEss.BECU1GeneralHighVoltageAlarm)// + .warningBit(5, WarningEss.BECU1GeneralLowVoltageAlarm)// + .warningBit(6, WarningEss.BECU1AbnormalVoltageChangeAlarm)// + .warningBit(7, WarningEss.BECU1GeneralHighTemperatureAlarm )// + .warningBit(8, WarningEss.BECU1GeneralLowTemperatureAlarm )// + .warningBit(9, WarningEss.BECU1AbnormalTemperatureChangeAlarm)// + .warningBit(10,WarningEss.BECU1SevereHighVoltageAlarm)// + .warningBit(11,WarningEss.BECU1SevereLowVoltageAlarm)// + .warningBit(12,WarningEss.BECU1SevereLowTemperatureAlarm)// + .warningBit(13,WarningEss.BECU1SeverveChargeOverCurrentAlarm )// + .warningBit(14,WarningEss.BECU1SeverveDischargeOverCurrentAlarm )// + .warningBit(15,WarningEss.BECU1AbnormalCellCapacityAlarm)// + ),// + new UnsignedWordElement(3006, // - this.becu1Alarm2 = new ModbusReadLongChannel("Becu1Alarm2", this)), + new ModbusBitWrappingChannel("BecuAlarm2" , this, this.thingState)// + .warningBit(0, WarningEss.BECU1BalancedSamplingAlarm)// + .warningBit(1, WarningEss.BECU1BalancedControlAlarm)// + .warningBit(2, WarningEss.BECU1HallSensorDoesNotWorkAccurately)// + .warningBit(4, WarningEss.BECU1Generalleakage)// + .warningBit(5, WarningEss.BECU1Severeleakage)// + .warningBit(6, WarningEss.BECU1Contactor1TurnOnAbnormity)// + .warningBit(7, WarningEss.BECU1Contactor1TurnOffAbnormity)// + .warningBit(8, WarningEss.BECU1Contactor2TurnOnAbnormity)// + .warningBit(9, WarningEss.BECU1Contactor2TurnOffAbnormity )// + .warningBit(10,WarningEss.BECU1Contactor4CheckAbnormity )// + .warningBit(11,WarningEss.BECU1ContactorCurrentUnsafe)// + .warningBit(12,WarningEss.BECU1Contactor5CheckAbnormity)// + .warningBit(13,WarningEss.BECU1HighVoltageOffset )// + .warningBit(14,WarningEss.BECU1LowVoltageOffset )// + .warningBit(15,WarningEss.BECU1HighTemperatureOffset )// + ),// + new UnsignedWordElement(3007, // - this.becu1Fault1 = new ModbusReadLongChannel("Becu1Fault1", this)), + new ModbusBitWrappingChannel("BecuFault1" , this, this.thingState)// + .faultBit(0, FaultEss.BECU1DischargeSevereOvercurrent)// + .faultBit(1, FaultEss.BECU1ChargeSevereOvercurrent)// + .faultBit(2, FaultEss.BECU1GeneralUndervoltage)// + .faultBit(3, FaultEss.BECU1SevereOvervoltage)// + .faultBit(4, FaultEss.BECU1GeneralOvervoltage)// + .faultBit(5, FaultEss.BECU1SevereUndervoltage)// + .faultBit(6, FaultEss.BECU1InsideCANBroken)// + .faultBit(7, FaultEss.BECU1GeneralUndervoltageHighCurrentDischarge)// + .faultBit(8, FaultEss.BECU1BMUError)// + .faultBit(9, FaultEss.BECU1CurrentSamplingInvalidation)// + .faultBit(10,FaultEss.BECU1BatteryFail)// + .faultBit(13,FaultEss.BECU1TemperatureSamplingBroken)// + .faultBit(14,FaultEss.BECU1Contactor1TestBackIsAbnormalTurnOnAbnormity)// + .faultBit(15,FaultEss.BECU1Contactor1TestBackIsAbnormalTurnOffAbnormity)// + ),// new UnsignedWordElement(3008, // - this.becu1Fault2 = new ModbusReadLongChannel("Becu1Fault2", this)), + new ModbusBitWrappingChannel("BecuFault2" , this, this.thingState)// + .faultBit(0, FaultEss.BECU1Contactor2TestBackIsAbnormalTurnOnAbnormity)// + .faultBit(1, FaultEss.BECU1Contactor2TestBackIsAbnormalTurnOffAbnormity)// + .faultBit(2, FaultEss.BECU1SevereHighTemperatureFault)// + .faultBit(9, FaultEss.BECU1HallInvalidation)// + .faultBit(10,FaultEss.BECU1ContactorInvalidation)// + .faultBit(12,FaultEss.BECU1OutsideCANBroken)// + .faultBit(13,FaultEss.BECU1CathodeContactorBroken)// + ),// new UnsignedWordElement(3009, // this.becu1Version = new ModbusReadLongChannel("Becu1Version", this)), new DummyElement(3010, 3011), // @@ -356,13 +412,69 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { new UnsignedWordElement(3204, // this.becu2Soc = new ModbusReadLongChannel("Becu2Soc", this)), new UnsignedWordElement(3205, // - this.becu2Alarm1 = new ModbusReadLongChannel("Becu2Alarm1", this)), + new ModbusBitWrappingChannel("Becu2Alarm1" , this, this.thingState)// + .warningBit(0, WarningEss.BECU2GeneralChargeOverCurrentAlarm )// + .warningBit(1, WarningEss.BECU2GeneralDischargeOverCurrentAlarm )// + .warningBit(2, WarningEss.BECU2ChargeCurrentLimitAlarm)// + .warningBit(3, WarningEss.BECU2DischargeCurrentLimitAlarm)// + .warningBit(4, WarningEss.BECU2GeneralHighVoltageAlarm)// + .warningBit(5, WarningEss.BECU2GeneralLowVoltageAlarm)// + .warningBit(6, WarningEss.BECU2AbnormalVoltageChangeAlarm)// + .warningBit(7, WarningEss.BECU2GeneralHighTemperatureAlarm )// + .warningBit(8, WarningEss.BECU2GeneralLowTemperatureAlarm )// + .warningBit(9, WarningEss.BECU2AbnormalTemperatureChangeAlarm)// + .warningBit(10,WarningEss.BECU2SevereHighVoltageAlarm)// + .warningBit(11,WarningEss.BECU2SevereLowVoltageAlarm)// + .warningBit(12,WarningEss.BECU2SevereLowTemperatureAlarm)// + .warningBit(13,WarningEss.BECU2SeverveChargeOverCurrentAlarm )// + .warningBit(14,WarningEss.BECU2SeverveDischargeOverCurrentAlarm )// + .warningBit(15,WarningEss.BECU2AbnormalCellCapacityAlarm)// + ),// new UnsignedWordElement(3206, // - this.becu2Alarm2 = new ModbusReadLongChannel("Becu2Alarm2", this)), + new ModbusBitWrappingChannel("Becu2Alarm2" , this, this.thingState)// + .warningBit(0, WarningEss.BECU2BalancedSamplingAlarm)// + .warningBit(1, WarningEss.BECU2BalancedControlAlarm)// + .warningBit(2, WarningEss.BECU2HallSensorDoesNotWorkAccurately)// + .warningBit(4, WarningEss.BECU2Generalleakage)// + .warningBit(5, WarningEss.BECU2Severeleakage)// + .warningBit(6, WarningEss.BECU2Contactor1TurnOnAbnormity)// + .warningBit(7, WarningEss.BECU2Contactor1TurnOffAbnormity)// + .warningBit(8, WarningEss.BECU2Contactor2TurnOnAbnormity)// + .warningBit(9, WarningEss.BECU2Contactor2TurnOffAbnormity )// + .warningBit(10,WarningEss.BECU2Contactor4CheckAbnormity )// + .warningBit(11,WarningEss.BECU2ContactorCurrentUnsafe)// + .warningBit(12,WarningEss.BECU2Contactor5CheckAbnormity)// + .warningBit(13,WarningEss.BECU2HighVoltageOffset )// + .warningBit(14,WarningEss.BECU2LowVoltageOffset )// + .warningBit(15,WarningEss.BECU2HighTemperatureOffset )// + ),// new UnsignedWordElement(3207, // - this.becu2Fault1 = new ModbusReadLongChannel("Becu2Fault1", this)), + new ModbusBitWrappingChannel("Becu2Fault1" , this, this.thingState)// + .faultBit(0, FaultEss.BECU2DischargeSevereOvercurrent)// + .faultBit(1, FaultEss.BECU2ChargeSevereOvercurrent)// + .faultBit(2, FaultEss.BECU2GeneralUndervoltage)// + .faultBit(3, FaultEss.BECU2SevereOvervoltage)// + .faultBit(4, FaultEss.BECU2GeneralOvervoltage)// + .faultBit(5, FaultEss.BECU2SevereUndervoltage)// + .faultBit(6, FaultEss.BECU2InsideCANBroken)// + .faultBit(7, FaultEss.BECU2GeneralUndervoltageHighCurrentDischarge)// + .faultBit(8, FaultEss.BECU2BMUError)// + .faultBit(9, FaultEss.BECU2CurrentSamplingInvalidation)// + .faultBit(10,FaultEss.BECU2BatteryFail)// + .faultBit(13,FaultEss.BECU2TemperatureSamplingBroken)// + .faultBit(14,FaultEss.BECU2Contactor1TestBackIsAbnormalTurnOnAbnormity)// + .faultBit(15,FaultEss.BECU2Contactor1TestBackIsAbnormalTurnOffAbnormity)// + ),// new UnsignedWordElement(3208, // - this.becu2Fault2 = new ModbusReadLongChannel("Becu2Fault2", this)), + new ModbusBitWrappingChannel("Becu2Fault2" , this, this.thingState)// + .faultBit(0, FaultEss.BECU2Contactor2TestBackIsAbnormalTurnOnAbnormity)// + .faultBit(1, FaultEss.BECU2Contactor2TestBackIsAbnormalTurnOffAbnormity)// + .faultBit(2, FaultEss.BECU2SevereHighTemperatureFault)// + .faultBit(9, FaultEss.BECU2HallInvalidation)// + .faultBit(10,FaultEss.BECU2ContactorInvalidation)// + .faultBit(12,FaultEss.BECU2OutsideCANBroken)// + .faultBit(13,FaultEss.BECU2CathodeContactorBroken)// + ),// new UnsignedWordElement(3209, // this.becu2Version = new ModbusReadLongChannel("Becu2Version", this)), new DummyElement(3210, 3211), // @@ -403,13 +515,56 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { new UnsignedWordElement(4807, // this.becuWorkState = new ModbusReadLongChannel("BecuWorkState", this)), new UnsignedWordElement(4808, // - this.becuFault1 = new ModbusReadLongChannel("BecuFault1", this)), + new ModbusBitWrappingChannel("BecuFault1", this, this.thingState)// + .faultBit(0, FaultEss.NoAvailableBatteryGroup)// + .faultBit(1, FaultEss.StackGeneralLeakage)// + .faultBit(2, FaultEss.StackSevereLeakage)// + .faultBit(3, FaultEss.StackStartingFail)// + .faultBit(4, FaultEss.StackStoppingFail)// + .faultBit(9, FaultEss.BatteryProtection)// + ),// new UnsignedWordElement(4809, // - this.becuFault2 = new ModbusReadLongChannel("BecuFault2", this)), + new ModbusBitWrappingChannel("BecuFault2" , this, this.thingState)// + .faultBit(0, FaultEss.StackAndGroup1CANCommunicationInterrupt)// + .faultBit(1, FaultEss.StackAndGroup2CANCommunicationInterrupt)// + ),// new UnsignedWordElement(4810, // - this.becuAlarm1 = new ModbusReadLongChannel("BecuAlarm1", this)), + new ModbusBitWrappingChannel("BecuAlarm2" , this, this.thingState)// + .warningBit(0, WarningEss.GeneralOvercurrentAlarmAtCellStackCharge)// + .warningBit(1, WarningEss.GeneralOvercurrentAlarmAtCellStackDischarge)// + .warningBit(2, WarningEss.CurrentLimitAlarmAtCellStackCharge)// + .warningBit(3, WarningEss.CurrentLimitAlarmAtCellStackDischarge)// + .warningBit(4, WarningEss.GeneralCellStackHighVoltageAlarm)// + .warningBit(5, WarningEss.GeneralCellStackLowVoltageAlarm)// + .warningBit(6, WarningEss.AbnormalCellStackVoltageChangeAlarm)// + .warningBit(7, WarningEss.GeneralCellStackHighTemperatureAlarm)// + .warningBit(8, WarningEss.GeneralCellStackLowTemperatureAlarm)// + .warningBit(9, WarningEss.AbnormalCellStackTemperatureChangeAlarm)// + .warningBit(10,WarningEss.SevereCellStackHighVoltageAlarm)// + .warningBit(11,WarningEss.SevereCellStackLowVoltageAlarm)// + .warningBit(12,WarningEss.SevereCellStackLowTemperatureAlarm)// + .warningBit(13,WarningEss.SeverveOverCurrentAlarmAtCellStackDharge)// + .warningBit(14,WarningEss.SeverveOverCurrentAlarmAtCellStackDischarge)// + .warningBit(15,WarningEss.AbnormalCellStackCapacityAlarm)// + ),// new UnsignedWordElement(4811, // - this.becuAlarm2 = new ModbusReadLongChannel("BecuAlarm2", this)), + new ModbusBitWrappingChannel("BecuAlarm2" , this, this.thingState)// + .warningBit(0, WarningEss.TheParameterOfEEPROMInCellStackLoseEffectiveness)// + .warningBit(1, WarningEss.IsolatingSwitchInConfluenceArkBreak)// + .warningBit(2, WarningEss.TheCommunicationBetweenCellStackAndTemperatureOfCollectorBreak)// + .warningBit(3, WarningEss.TheTemperatureOfCollectorFail)// + .warningBit(4, WarningEss.HallSensorDoNotWorkAccurately)// + .warningBit(5, WarningEss.TheCommunicationOfPCSBreak)// + .warningBit(6, WarningEss.AdvancedChargingOrMainContactorCloseAbnormally)// + .warningBit(7, WarningEss.AbnormalSampledVoltage)// + .warningBit(8, WarningEss.AbnormalAdvancedContactorOrAbnormalRS485GalleryOfPCS)// + .warningBit(9, WarningEss.AbnormalMainContactor)// + .warningBit(10,WarningEss.GeneralCellStackLeakage)// + .warningBit(11,WarningEss.SevereCellStackLeakage)// + .warningBit(12,WarningEss.SmokeAlarm)// + .warningBit(13,WarningEss.TheCommunicationWireToAmmeterBreak)// + .warningBit(14,WarningEss.TheCommunicationWireToDredBreak)// + ),// new UnsignedWordElement(4812, // this.soc = new ModbusReadLongChannel("Soc", this).unit("%")))); return protocol; diff --git a/edge/src/io/openems/impl/device/minireadonly/WarningEss.java b/edge/src/io/openems/impl/device/minireadonly/WarningEss.java new file mode 100644 index 00000000000..7031834556d --- /dev/null +++ b/edge/src/io/openems/impl/device/minireadonly/WarningEss.java @@ -0,0 +1,38 @@ +package io.openems.impl.device.minireadonly; + +import io.openems.api.channel.thingstate.WarningEnum; + +public enum WarningEss implements WarningEnum +{ + BECU1GeneralChargeOverCurrentAlarm(0), BECU1GeneralDischargeOverCurrentAlarm(1), BECU1ChargeCurrentLimitAlarm(2), BECU1DischargeCurrentLimitAlarm(3), + BECU1GeneralHighVoltageAlarm(4), BECU1GeneralLowVoltageAlarm(5), BECU1AbnormalVoltageChangeAlarm(6), BECU1GeneralHighTemperatureAlarm(7),BECU1GeneralLowTemperatureAlarm(8), + BECU1AbnormalTemperatureChangeAlarm(9), BECU1SevereHighVoltageAlarm(10), BECU1SevereLowVoltageAlarm(11),BECU1SevereLowTemperatureAlarm(12), BECU1SeverveChargeOverCurrentAlarm(13), + BECU1SeverveDischargeOverCurrentAlarm(14), BECU1AbnormalCellCapacityAlarm(15), BECU1BalancedSamplingAlarm(16), BECU1BalancedControlAlarm(17), BECU1HallSensorDoesNotWorkAccurately(18), + BECU1Generalleakage(19), BECU1Severeleakage(20), BECU1Contactor1TurnOnAbnormity(21), BECU1Contactor1TurnOffAbnormity(22), BECU1Contactor2TurnOnAbnormity(23), BECU1Contactor2TurnOffAbnormity(24), + BECU1Contactor4CheckAbnormity(25), BECU1ContactorCurrentUnsafe(26), BECU1Contactor5CheckAbnormity(27), BECU1HighVoltageOffset(28), BECU1LowVoltageOffset(29), BECU1HighTemperatureOffset(30), + BECU2GeneralChargeOverCurrentAlarm(31), BECU2GeneralDischargeOverCurrentAlarm(32), BECU2ChargeCurrentLimitAlarm(33), BECU2DischargeCurrentLimitAlarm(34), BECU2GeneralHighVoltageAlarm(35), + BECU2GeneralLowVoltageAlarm(36), BECU2AbnormalVoltageChangeAlarm(37), BECU2GeneralHighTemperatureAlarm(38), BECU2GeneralLowTemperatureAlarm(39), BECU2AbnormalTemperatureChangeAlarm(40), + BECU2SevereHighVoltageAlarm(41), BECU2SevereLowVoltageAlarm(42), BECU2SevereLowTemperatureAlarm(43), BECU2SeverveChargeOverCurrentAlarm(44), BECU2SeverveDischargeOverCurrentAlarm(45), + BECU2AbnormalCellCapacityAlarm(46), BECU2BalancedSamplingAlarm(47), BECU2BalancedControlAlarm(48), BECU2HallSensorDoesNotWorkAccurately(49), BECU2Generalleakage(50), BECU2Severeleakage(51), + BECU2Contactor1TurnOnAbnormity(52), BECU2Contactor1TurnOffAbnormity(53), BECU2Contactor2TurnOnAbnormity(54), BECU2Contactor2TurnOffAbnormity(55), BECU2Contactor4CheckAbnormity(56), + BECU2ContactorCurrentUnsafe(57), BECU2Contactor5CheckAbnormity(58), BECU2HighVoltageOffset(59), BECU2LowVoltageOffset(60), BECU2HighTemperatureOffset(61), GeneralOvercurrentAlarmAtCellStackCharge(62), + GeneralOvercurrentAlarmAtCellStackDischarge(63), CurrentLimitAlarmAtCellStackCharge(64), CurrentLimitAlarmAtCellStackDischarge(65), GeneralCellStackHighVoltageAlarm(66), GeneralCellStackLowVoltageAlarm(67), + AbnormalCellStackVoltageChangeAlarm(68), GeneralCellStackHighTemperatureAlarm(69), GeneralCellStackLowTemperatureAlarm(70), AbnormalCellStackTemperatureChangeAlarm(71), SevereCellStackHighVoltageAlarm(72), + SevereCellStackLowVoltageAlarm(73), SevereCellStackLowTemperatureAlarm(74), SeverveOverCurrentAlarmAtCellStackDharge(75), SeverveOverCurrentAlarmAtCellStackDischarge(76), AbnormalCellStackCapacityAlarm(77), + TheParameterOfEEPROMInCellStackLoseEffectiveness(78), IsolatingSwitchInConfluenceArkBreak(79), TheCommunicationBetweenCellStackAndTemperatureOfCollectorBreak(80), TheTemperatureOfCollectorFail(81), + HallSensorDoNotWorkAccurately(82), TheCommunicationOfPCSBreak(83), AdvancedChargingOrMainContactorCloseAbnormally(84), AbnormalSampledVoltage(85), AbnormalAdvancedContactorOrAbnormalRS485GalleryOfPCS(86), + AbnormalMainContactor(87), GeneralCellStackLeakage(88), SevereCellStackLeakage(89), SmokeAlarm(90), TheCommunicationWireToAmmeterBreak(91), TheCommunicationWireToDredBreak(92); + + + + public final int value; + + private WarningEss(int value) { + this.value = value; + } + + @Override + public int getValue() { + return this.value; + } +} diff --git a/edge/src/io/openems/impl/device/refu/FaultEss.java b/edge/src/io/openems/impl/device/refu/FaultEss.java new file mode 100644 index 00000000000..8628d7a0188 --- /dev/null +++ b/edge/src/io/openems/impl/device/refu/FaultEss.java @@ -0,0 +1,34 @@ +package io.openems.impl.device.refu; + +import io.openems.api.channel.thingstate.FaultEnum; + +public enum FaultEss implements FaultEnum{ + BMSInError(0), BMSInErrorSecond(1), BMSUndervoltage(2), BMSOvercurrent(3), ErrorBMSLimitsNotInitialized(4), ConnectError(5), OvervoltageWarning(6), + UndervoltageWarning(7), OvercurrentWarning(8), BMSReady(9), TREXReady(10), NoEnableBateryGroupOrUsableBatteryGroup(11), NormalLeakageOfBatteryGroup(12), + SeriousLeakageOfBatteryGroup(13), BatteryStartFailure(14), BatteryStopFailure(15), InterruptionOfCANCommunication(16),InterruptionOfCANCommunicationBetweenBatteryGroupAndController(17), + EmergencyStopAbnormalOfAuxiliaryCollector(18), LeakageSelfDetectionOnNegative(19), LeakageSelfDetectionOnPositive(20), SelfDetectionFailureOnBattery(21), + CANCommunicationInterruptionBetweenBatteryGroupAndGroup1(22),CANCommunicationInterruptionBetweenBatteryGroupAndGroup2(23), CANCommunicationInterruptionBetweenBatteryGroupAndGroup3(24), + CANCommunicationInterruptionBetweenBatteryGroupAndGroup4(25), MainContractorAbnormalInBatterySelfDetectGroup1(26), MainContractorAbnormalInBatterySelfDetectGroup2(27), + MainContractorAbnormalInBatterySelfDetectGroup3(28), MainContractorAbnormalInBatterySelfDetectGroup4(29), PreChargeContractorAbnormalOnBatterySelfDetectGroup1(30), + PreChargeContractorAbnormalOnBatterySelfDetectGroup2(31), PreChargeContractorAbnormalOnBatterySelfDetectGroup3(32), PreChargeContractorAbnormalOnBatterySelfDetectGroup4(33), + MainContactFailureOnBatteryControlGroup1(34), MainContactFailureOnBatteryControlGroup2(35), MainContactFailureOnBatteryControlGroup3(36), MainContactFailureOnBatteryControlGroup4(37), + PreChargeFailureOnBatteryControlGroup1(38), PreChargeFailureOnBatteryControlGroup2(39), PreChargeFailureOnBatteryControlGroup3(40), PreChargeFailureOnBatteryControlGroup4(41), + SamplingCircuitAbnormalForBMU(42), PowerCableDisconnectFailure(43), SamplingCircuitDisconnectFailure(44), CANDisconnectForMasterAndSlave(45), SammplingCircuitFailure(46), + SingleBatteryFailure(47), CircuitDetectionAbnormalForMainContactor(48), CircuitDetectionAbnormalForMainContactorSecond(49), CircuitDetectionAbnormalForFancontactor(50), + BMUPowerContactorCircuitDetectionAbnormal(51), CentralContactorCircuitDetectionAbnormal(52), SeriousTemperatureFault(53), CommunicationFaultForSystemController(54), + FrogAlarm(55), FuseFault(56), NormalLeakage(57), SeriousLeakage(58), CANDisconnectionBetweenBatteryGroupAndBatteryStack(59), CentralContactorCircuitOpen(60), + BMUPowerContactorOpen(61); + + + + private final int value; + + private FaultEss(int value) { + this.value = value; + } + + @Override + public int getValue() { + return this.value; + } +} diff --git a/edge/src/io/openems/impl/device/refu/RefuEss.java b/edge/src/io/openems/impl/device/refu/RefuEss.java index 44c93ca2e57..9856d1aaa2e 100644 --- a/edge/src/io/openems/impl/device/refu/RefuEss.java +++ b/edge/src/io/openems/impl/device/refu/RefuEss.java @@ -24,7 +24,6 @@ import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; import io.openems.api.channel.StatusBitChannel; -import io.openems.api.channel.StatusBitChannels; import io.openems.api.channel.WriteChannel; import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; @@ -32,6 +31,7 @@ import io.openems.api.device.nature.ess.SymmetricEssNature; import io.openems.api.doc.ThingInfo; import io.openems.api.exception.ConfigException; +import io.openems.impl.protocol.modbus.ModbusBitWrappingChannel; import io.openems.impl.protocol.modbus.ModbusDeviceNature; import io.openems.impl.protocol.modbus.ModbusReadLongChannel; import io.openems.impl.protocol.modbus.ModbusWriteLongChannel; @@ -47,8 +47,6 @@ @ThingInfo(title = "REFU battery inverter ESS") public class RefuEss extends ModbusDeviceNature implements SymmetricEssNature, AsymmetricEssNature { - private ThingStateChannel thingState; - /* * Constructors */ @@ -104,7 +102,7 @@ public ConfigChannel chargeSoc() { private StaticValueChannel maxNominalPower = new StaticValueChannel<>("maxNominalPower", this, 100000L) .unit("VA").unit("VA"); private StaticValueChannel capacity = new StaticValueChannel<>("capacity", this, 130000L).unit("Wh"); - + private ThingStateChannel thingState; /* * This Channels */ @@ -255,7 +253,6 @@ public WriteChannel setReactivePower() { @Override protected ModbusProtocol defineModbusProtocol() throws ConfigException { - StatusBitChannels warning = new StatusBitChannels("warning", this); return new ModbusProtocol( // new ModbusInputRegisterRange(0x100, // new UnsignedWordElement(0x100, // @@ -266,20 +263,21 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { .label(3, STANDBY) // .label(4, START) // .label(5, FAULT)), - new UnsignedWordElement(0x101, - systemError1 = warning.channel(new StatusBitChannel("SystemError1", this)// - .label(1, "BMS In Error")// - .label(2, "BMS Overvoltage")// - .label(4, "BMS Undervoltage")// - .label(8, "BMS Overcurrent")// - .label(16, "Error BMS Limits not initialized")// - .label(32, "Connect Error")// - .label(64, "Overvoltage warning")// - .label(128, "Undervoltage warning")// - .label(256, "Overcurrent warning")// - .label(512, "BMS Ready")// - .label(1024, "TREX Ready")// - )), + new UnsignedWordElement(0x101, // + new ModbusBitWrappingChannel("SystemError1", this, this.thingState)// + .faultBit(0, FaultEss.BMSInError)// + .faultBit(1, FaultEss.BMSInErrorSecond)// + .faultBit(2, FaultEss.BMSUndervoltage)// + .faultBit(3, FaultEss.BMSOvercurrent)// + .faultBit(4, FaultEss.ErrorBMSLimitsNotInitialized)// + .faultBit(5, FaultEss.ConnectError)// + .faultBit(6, FaultEss.OvervoltageWarning)// + .faultBit(7, FaultEss.UndervoltageWarning)// + .faultBit(8, FaultEss.OvercurrentWarning)// + .faultBit(9, FaultEss.BMSReady)// + .faultBit(10, FaultEss.TREXReady)// + ), // + new UnsignedWordElement(0x102, communicationInformations = new StatusBitChannel("CommunicationInformations", this)// .label(1, "Gateway Initialized")// @@ -397,7 +395,8 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { this).unit("kWh")).wordorder(WordOrder.LSWMSW), new SignedDoublewordElement(0x128, // batteryDischargeEnergy = new ModbusReadLongChannel( - "BatteryDischargeEnergy", this).unit("kWh")).wordorder(WordOrder.LSWMSW), + "BatteryDischargeEnergy", this) + .unit("kWh")).wordorder(WordOrder.LSWMSW), new UnsignedWordElement(0x12A, // batteryOperationStatus = new StatusBitChannel("BatteryOperationStatus", this) .label(1, "Battery group 1 operating")// @@ -418,188 +417,205 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { .unit("�C")), new UnsignedWordElement(0x12F, // batteryStopRequest = new ModbusReadLongChannel("BatteryStopRequest", this)), - new UnsignedWordElement(0x130, - batteryAlarm1 = warning.channel(new StatusBitChannel("BatteryAlarm1", this)// - .label(1, "Normal charging over-current ")// - .label(2, "Charginig current over limit")// - .label(4, "Discharging current over limit")// - .label(8, "Normal high voltage")// - .label(16, "Normal low voltage")// - .label(32, "Abnormal voltage variation")// - .label(64, "Normal high temperature")// - .label(128, "Normal low temperature")// - .label(256, "Abnormal temperature variation")// - .label(512, "Serious high voltage")// - .label(1024, "Serious low voltage")// - .label(2048, "Serious low temperature")// - .label(4096, "Charging serious over current")// - .label(8192, "Discharging serious over current")// - .label(16384, "Abnormal capacity alarm"))), - new UnsignedWordElement(0x131, - batteryAlarm2 = warning.channel(new StatusBitChannel("BatteryAlarm2", this)// - .label(1, "EEPROM parameter failure")// - .label(2, "Switch off inside combined cabinet")// - .label(32, "Should not be connected to grid due to the DC side condition")// - .label(128, "Emergency stop require from system controller"))), - new UnsignedWordElement(0x132, - batteryAlarm3 = warning.channel(new StatusBitChannel("BatteryAlarm3", this)// - .label(1, "Battery group 1 enable and not connected to grid")// - .label(2, "Battery group 2 enable and not connected to grid")// - .label(4, "Battery group 3 enable and not connected to grid")// - .label(8, "Battery group 4 enable and not connected to grid"))), - new UnsignedWordElement(0x133, - batteryAlarm4 = warning.channel(new StatusBitChannel("BatteryAlarm4", this)// - .label(1, "The isolation switch of battery group 1 open")// - .label(2, "The isolation switch of battery group 2 open")// - .label(4, "The isolation switch of battery group 3 open")// - .label(8, "The isolation switch of battery group 4 open"))), - new DummyElement(0x134), + new UnsignedWordElement(0x130, // + new ModbusBitWrappingChannel("BatteryAlarm1", this, this.thingState)// + .warningBit(0, WarningEss.NormalChargingOverCurrent)// + .warningBit(1, WarningEss.CharginigCurrentOverLimit)// + .warningBit(2, WarningEss.DischargingCurrentOverLimit)// + .warningBit(3, WarningEss.NormalHighVoltage)// + .warningBit(4, WarningEss.NormalLowVoltage)// + .warningBit(5, WarningEss.AbnormalVoltageVariation)// + .warningBit(6, WarningEss.NormalHighTemperature)// + .warningBit(7, WarningEss.NormalLowTemperature)// + .warningBit(8, WarningEss.AbnormalTemperatureVariation)// + .warningBit(9, WarningEss.SeriousHighVoltage)// + .warningBit(10, WarningEss.SeriousLowVoltage)// + .warningBit(11, WarningEss.SeriousLowTemperature)// + .warningBit(12, WarningEss.ChargingSeriousOverCurrent)// + .warningBit(13, WarningEss.DischargingSeriousOverCurrent)// + .warningBit(14, WarningEss.AbnormalCapacityAlarm)// + ), // + + new UnsignedWordElement(0x131, // + new ModbusBitWrappingChannel("BatteryAlarm2", this, this.thingState)// + .warningBit(0, WarningEss.EEPROMParameterFailure)// + .warningBit(1, WarningEss.SwitchOfInsideCombinedCabinet) + .warningBit(5, WarningEss.ShouldNotBeConnectedToGridDueToTheDCSideCondition) + .warningBit(7, WarningEss.EmergencyStopRequireFromSystemController)), // + + new UnsignedWordElement(0x132, // + new ModbusBitWrappingChannel("BatteryAlarm3", this, this.thingState)// + .warningBit(0, WarningEss.BatteryGroup1EnableAndNotConnectedToGrid)// + .warningBit(1, WarningEss.BatteryGroup2EnableAndNotConnectedToGrid)// + .warningBit(2, WarningEss.BatteryGroup3EnableAndNotConnectedToGrid)// + .warningBit(3, WarningEss.BatteryGroup4EnableAndNotConnectedToGrid)// + ), // + + new UnsignedWordElement(0x133, // + new ModbusBitWrappingChannel("BatteryAlarm4", this, this.thingState)// + .warningBit(0, WarningEss.TheIsolationSwitchOfBatteryGroup1Open) + .warningBit(1, WarningEss.TheIsolationSwitchOfBatteryGroup2Open) + .warningBit(2, WarningEss.TheIsolationSwitchOfBatteryGroup3Open) + .warningBit(3, WarningEss.TheIsolationSwitchOfBatteryGroup4Open)), // + + new DummyElement(0x134), // new UnsignedWordElement(0x135, - batteryAlarm6 = warning.channel(new StatusBitChannel("BatteryAlarm6", this)// - .label(1, "Balancing sampling failure of battery group 1")// - .label(2, "Balancing sampling failure of battery group 2")// - .label(4, "Balancing sampling failure of battery group 3")// - .label(8, "Balancing sampling failure of battery group 4"))), - new UnsignedWordElement(0x136, - batteryAlarm7 = warning.channel(new StatusBitChannel("BatteryAlarm7", this)// - .label(1, "Balancing control failure of battery group 1")// - .label(2, "Balancing control failure of battery group 2")// - .label(4, "Balancing control failure of battery group 3")// - .label(8, "Balancing control failure of battery group 4"))), - new UnsignedWordElement(0x137, - batteryFault1 = warning.channel(new StatusBitChannel("BatteryFault1", this)// - .label(1, "No enable batery group or usable battery group")// - .label(2, "Normal leakage of battery group")// - .label(4, "Serious leakage of battery group")// - .label(8, "Battery start failure")// - .label(16, "Battery stop failure")// - .label(32, - "Interruption of CAN Communication between battery group and controller")// - .label(1024, "Emergency stop abnormal of auxiliary collector")// - .label(2048, "Leakage self detection on negative")// - .label(4096, "Leakage self detection on positive")// - .label(8192, "Self detection failure on battery"))), - new UnsignedWordElement(0x138, - batteryFault2 = warning.channel(new StatusBitChannel("BatteryFault2", this)// - .label(1, "CAN Communication interruption between battery group and group 1")// - .label(2, "CAN Communication interruption between battery group and group 2")// - .label(4, "CAN Communication interruption between battery group and group 3")// - .label(8, "CAN Communication interruption between battery group and group 4"))), - new UnsignedWordElement(0x139, - batteryFault3 = warning.channel(new StatusBitChannel("BatteryFault3", this)// - .label(1, "Main contractor abnormal in battery self detect group 1")// - .label(2, "Main contractor abnormal in battery self detect group 2")// - .label(4, "Main contractor abnormal in battery self detect group 3")// - .label(8, "Main contractor abnormal in battery self detect group 4"))), - new UnsignedWordElement(0x13A, - batteryFault4 = warning.channel(new StatusBitChannel("BatteryFault4", this)// - .label(1, "Pre-charge contractor abnormal on battery self detect group 1")// - .label(2, "Pre-charge contractor abnormal on battery self detect group 2")// - .label(4, "Pre-charge contractor abnormal on battery self detect group 3")// - .label(8, "Pre-charge contractor abnormal on battery self detect group 4"))), - new UnsignedWordElement(0x13B, - batteryFault5 = warning.channel(new StatusBitChannel("BatteryFault5", this)// - .label(1, "Main contact failure on battery control group 1")// - .label(2, "Main contact failure on battery control group 2")// - .label(4, "Main contact failure on battery control group 3")// - .label(8, "Main contact failure on battery control group 4"))), - new UnsignedWordElement(0x13C, - batteryFault6 = warning.channel(new StatusBitChannel("BatteryFault6", this)// - .label(1, "Pre-charge failure on battery control group 1")// - .label(2, "Pre-charge failure on battery control group 2")// - .label(4, "Pre-charge failure on battery control group 3")// - .label(8, "Pre-charge failure on battery control group 4"))), - new UnsignedWordElement(0x13D, - batteryFault7 = warning.channel(new StatusBitChannel("BatteryFault7", this)// - )), new UnsignedWordElement(0x13E, - batteryFault8 = warning.channel(new StatusBitChannel("BatteryFault8", this)// - )), - new UnsignedWordElement(0x13F, - batteryFault9 = warning.channel(new StatusBitChannel("BatteryFault9", this)// - .label(4, "Sampling circuit abnormal for BMU")// - .label(8, "Power cable disconnect failure")// - .label(16, "Sampling circuit disconnect failure")// - .label(64, "CAN disconnect for master and slave")// - .label(512, "Sammpling circuit failure")// - .label(1024, "Single battery failure")// - .label(2048, "Circuit detection abnormal for main contactor")// - .label(4096, "Circuit detection abnormal for main contactor")// - .label(8192, "Circuit detection abnormal for Fancontactor")// - .label(16384, "BMUPower contactor circuit detection abnormal")// - .label(32768, "Central contactor circuit detection abnormal"))), - new UnsignedWordElement(0x140, - batteryFault10 = warning.channel(new StatusBitChannel("BatteryFault10", this)// - .label(4, "Serious temperature fault")// - .label(8, "Communication fault for system controller")// - .label(128, "Frog alarm")// - .label(256, "Fuse fault")// - .label(1024, "Normal leakage")// - .label(2048, "Serious leakage")// - .label(4096, "CAN disconnection between battery group and battery stack")// - .label(8192, "Central contactor circuit open")// - .label(16384, "BMU power contactor open"))), - new UnsignedWordElement(0x141, - batteryFault11 = warning.channel(new StatusBitChannel("BatteryFault11", this)// - )), new UnsignedWordElement(0x142, - batteryFault12 = warning.channel(new StatusBitChannel("BatteryFault12", this)// - )), + new ModbusBitWrappingChannel("BatteryAlarm6", this, this.thingState)// + .warningBit(0, WarningEss.BalancingSamplingFailureOfBatteryGroup1)// + .warningBit(1, WarningEss.BalancingSamplingFailureOfBatteryGroup2)// + .warningBit(2, WarningEss.BalancingSamplingFailureOfBatteryGroup3)// + .warningBit(3, WarningEss.BalancingSamplingFailureOfBatteryGroup4)// + ), // + + new UnsignedWordElement(0x136, // + new ModbusBitWrappingChannel("BatteryAlarm7", this, this.thingState)// + .warningBit(0, WarningEss.BalancingControlFailureOfBatteryGroup1)// + .warningBit(1, WarningEss.BalancingControlFailureOfBatteryGroup2)// + .warningBit(2, WarningEss.BalancingControlFailureOfBatteryGroup3)// + .warningBit(3, WarningEss.BalancingControlFailureOfBatteryGroup4)// + ), // + + new UnsignedWordElement(0x137, // + new ModbusBitWrappingChannel("BatteryFault1", this, this.thingState)// + .faultBit(0, FaultEss.NoEnableBateryGroupOrUsableBatteryGroup)// + .faultBit(1, FaultEss.NormalLeakageOfBatteryGroup)// + .faultBit(2, FaultEss.SeriousLeakageOfBatteryGroup)// + .faultBit(3, FaultEss.BatteryStartFailure)// + .faultBit(4, FaultEss.BatteryStopFailure)// + .faultBit(5, + FaultEss.InterruptionOfCANCommunicationBetweenBatteryGroupAndController)// + .faultBit(10, FaultEss.EmergencyStopAbnormalOfAuxiliaryCollector)// + .faultBit(11, FaultEss.LeakageSelfDetectionOnNegative)// + .faultBit(12, FaultEss.LeakageSelfDetectionOnPositive)// + .faultBit(13, FaultEss.SelfDetectionFailureOnBattery)// + ), // + + new UnsignedWordElement(0x138, // + new ModbusBitWrappingChannel("BatteryFault2", this, this.thingState)// + .faultBit(0, FaultEss.CANCommunicationInterruptionBetweenBatteryGroupAndGroup1)// + .faultBit(1, FaultEss.CANCommunicationInterruptionBetweenBatteryGroupAndGroup2)// + .faultBit(2, FaultEss.CANCommunicationInterruptionBetweenBatteryGroupAndGroup3)// + .faultBit(3, FaultEss.CANCommunicationInterruptionBetweenBatteryGroupAndGroup4)// + ), // + + new UnsignedWordElement(0x139, // + new ModbusBitWrappingChannel("BatteryFault3", this, this.thingState)// + .faultBit(0, FaultEss.MainContractorAbnormalInBatterySelfDetectGroup1)// + .faultBit(1, FaultEss.MainContractorAbnormalInBatterySelfDetectGroup2)// + .faultBit(2, FaultEss.MainContractorAbnormalInBatterySelfDetectGroup3)// + .faultBit(3, FaultEss.MainContractorAbnormalInBatterySelfDetectGroup4)// + ), // + + new UnsignedWordElement(0x13A, // + new ModbusBitWrappingChannel("BatteryFault4", this, this.thingState)// + .faultBit(0, FaultEss.PreChargeContractorAbnormalOnBatterySelfDetectGroup1)// + .faultBit(1, FaultEss.PreChargeContractorAbnormalOnBatterySelfDetectGroup2)// + .faultBit(2, FaultEss.PreChargeContractorAbnormalOnBatterySelfDetectGroup3)// + .faultBit(3, FaultEss.PreChargeContractorAbnormalOnBatterySelfDetectGroup4)// + ), // + + new UnsignedWordElement(0x13B, // + new ModbusBitWrappingChannel("BatteryFault5", this, this.thingState)// + .faultBit(0, FaultEss.MainContactFailureOnBatteryControlGroup1)// + .faultBit(1, FaultEss.MainContactFailureOnBatteryControlGroup2)// + .faultBit(2, FaultEss.MainContactFailureOnBatteryControlGroup3)// + .faultBit(3, FaultEss.MainContactFailureOnBatteryControlGroup4)// + ), // + + new UnsignedWordElement(0x13C, // + new ModbusBitWrappingChannel("BatteryFault6", this, this.thingState)// + .faultBit(0, FaultEss.PreChargeFailureOnBatteryControlGroup1)// + .faultBit(1, FaultEss.PreChargeFailureOnBatteryControlGroup2)// + .faultBit(2, FaultEss.PreChargeFailureOnBatteryControlGroup3)// + .faultBit(3, FaultEss.PreChargeFailureOnBatteryControlGroup4)// + ), // + + new UnsignedWordElement(0x13D, // + new ModbusBitWrappingChannel("BatteryFault7", this, this.thingState)// + // .faultBit(0, FaultEss)// + ), // + + new UnsignedWordElement(0x13E, // + new ModbusBitWrappingChannel("BatteryFault8", this, this.thingState)// + // .faultBit(0, FaultEss)// + ), // + new UnsignedWordElement(0x13F, // + new ModbusBitWrappingChannel("BatteryFault9", this, this.thingState)// + .faultBit(2, FaultEss.SamplingCircuitAbnormalForBMU)// + .faultBit(3, FaultEss.PowerCableDisconnectFailure)// + .faultBit(4, FaultEss.SamplingCircuitDisconnectFailure)// + .faultBit(6, FaultEss.CANDisconnectForMasterAndSlave)// + .faultBit(9, FaultEss.SammplingCircuitFailure)// + .faultBit(10, FaultEss.SingleBatteryFailure)// + .faultBit(11, FaultEss.CircuitDetectionAbnormalForMainContactor)// + .faultBit(12, FaultEss.CircuitDetectionAbnormalForMainContactorSecond)// + .faultBit(13, FaultEss.CircuitDetectionAbnormalForFancontactor)// + .faultBit(14, FaultEss.BMUPowerContactorCircuitDetectionAbnormal)// + .faultBit(15, FaultEss.CentralContactorCircuitDetectionAbnormal)// + ), // + + new UnsignedWordElement(0x140, // + new ModbusBitWrappingChannel("BatteryFault10", this, this.thingState)// + .faultBit(2, FaultEss.SeriousTemperatureFault)// + .faultBit(3, FaultEss.CommunicationFaultForSystemController)// + .faultBit(7, FaultEss.FrogAlarm)// + .faultBit(8, FaultEss.FuseFault)// + .faultBit(10, FaultEss.NormalLeakage)// + .faultBit(11, FaultEss.SeriousLeakage)// + .faultBit(12, FaultEss.CANDisconnectionBetweenBatteryGroupAndBatteryStack)// + .faultBit(13, FaultEss.CentralContactorCircuitOpen)// + .faultBit(14, FaultEss.BMUPowerContactorOpen)// + ), // + + new UnsignedWordElement(0x141, // + new ModbusBitWrappingChannel("BatteryFault11", this, this.thingState)// + // .faultBit(, FaultEss)// + ), // + + new UnsignedWordElement(0x142, // + new ModbusBitWrappingChannel("BatteryFault12", this, this.thingState)// + // .faultBit(, FaultEss)// + ), // + new UnsignedWordElement(0x143, - batteryFault13 = warning.channel(new StatusBitChannel("BatteryFault13", this)// - )), new UnsignedWordElement(0x144, - batteryFault14 = warning.channel(new StatusBitChannel("BatteryFault14", this)// - )), new UnsignedWordElement(0x145, batteryGroupControlStatus = warning - .channel(new StatusBitChannel("BatteryGroupControlStatus", this)// - )), new UnsignedWordElement(0x146, - errorLog1 = warning.channel(new StatusBitChannel("ErrorLog1", this)// - )), new UnsignedWordElement(0x147, - errorLog2 = warning.channel(new StatusBitChannel("ErrorLog2", this)// - )), new UnsignedWordElement(0x148, - errorLog3 = warning.channel(new StatusBitChannel("ErrorLog3", this)// - )), - new UnsignedWordElement(0x149, - errorLog4 = warning.channel(new StatusBitChannel("ErrorLog4", this)// - )), new UnsignedWordElement(0x14a, - errorLog5 = warning.channel(new StatusBitChannel("ErrorLog5", this)// - )), new UnsignedWordElement(0x14b, - errorLog6 = warning.channel(new StatusBitChannel("ErrorLog6", this)// - )), - new UnsignedWordElement(0x14c, - errorLog7 = warning.channel(new StatusBitChannel("ErrorLog7", this)// - )), new UnsignedWordElement(0x14d, - errorLog8 = warning.channel(new StatusBitChannel("ErrorLog8", this)// - )), new UnsignedWordElement(0x14e, - errorLog9 = warning.channel(new StatusBitChannel("ErrorLog9", this)// - )), - new UnsignedWordElement(0x14f, - errorLog10 = warning.channel(new StatusBitChannel("ErrorLog10", this)// - )), new UnsignedWordElement(0x150, - errorLog11 = warning.channel(new StatusBitChannel("ErrorLog11", this)// - )), new UnsignedWordElement(0x151, - errorLog12 = warning.channel(new StatusBitChannel("ErrorLog12", this)// - )), - new UnsignedWordElement(0x152, - errorLog13 = warning.channel(new StatusBitChannel("ErrorLog13", this)// - )), new UnsignedWordElement(0x153, - errorLog14 = warning.channel(new StatusBitChannel("ErrorLog14", this)// - )), new UnsignedWordElement(0x154, - errorLog15 = warning.channel(new StatusBitChannel("ErrorLog15", this)// - )), - new UnsignedWordElement(0x155, - errorLog16 = warning.channel(new StatusBitChannel("ErrorLog16", this)// - ))), new WriteableModbusRegisterRange(0x200, // - new UnsignedWordElement(0x200, // - setWorkState = new ModbusWriteLongChannel("SetWorkState", this) // - .label(0, STOP) // - .label(1, START)), - new UnsignedWordElement(0x201, // - setSystemErrorReset = new ModbusWriteLongChannel("SetSystemErrorReset", - this)// - .label(0, OFF)// - .label(1, ON)), - new UnsignedWordElement(0x202, // - setOperationMode = new ModbusWriteLongChannel("SetOperationMode", this)// - .label(0, "P/Q Set point")// - .label(1, "IAC / cosphi set point"))), + new ModbusBitWrappingChannel("BatteryFault13", this, this.thingState)// + // .faultBit(, FaultEss)// + ), // + new UnsignedWordElement(0x144, + new ModbusBitWrappingChannel("BatteryFault14", this, this.thingState)// + // .faultBit(, FaultEss)// + ), // + new UnsignedWordElement(0x145, + batteryGroupControlStatus = new StatusBitChannel("BatteryGroupControlStatus", this)// + ), new UnsignedWordElement(0x146, errorLog1 = new StatusBitChannel("ErrorLog1", this)// + ), new UnsignedWordElement(0x147, errorLog2 = new StatusBitChannel("ErrorLog2", this)// + ), new UnsignedWordElement(0x148, errorLog3 = new StatusBitChannel("ErrorLog3", this)// + ), new UnsignedWordElement(0x149, errorLog4 = new StatusBitChannel("ErrorLog4", this)// + ), new UnsignedWordElement(0x14a, errorLog5 = new StatusBitChannel("ErrorLog5", this)// + ), new UnsignedWordElement(0x14b, errorLog6 = new StatusBitChannel("ErrorLog6", this)// + ), new UnsignedWordElement(0x14c, errorLog7 = new StatusBitChannel("ErrorLog7", this)// + ), new UnsignedWordElement(0x14d, errorLog8 = new StatusBitChannel("ErrorLog8", this)// + ), new UnsignedWordElement(0x14e, errorLog9 = new StatusBitChannel("ErrorLog9", this)// + ), new UnsignedWordElement(0x14f, errorLog10 = new StatusBitChannel("ErrorLog10", this)// + ), new UnsignedWordElement(0x150, errorLog11 = new StatusBitChannel("ErrorLog11", this)// + ), new UnsignedWordElement(0x151, errorLog12 = new StatusBitChannel("ErrorLog12", this)// + ), new UnsignedWordElement(0x152, errorLog13 = new StatusBitChannel("ErrorLog13", this)// + ), new UnsignedWordElement(0x153, errorLog14 = new StatusBitChannel("ErrorLog14", this)// + ), new UnsignedWordElement(0x154, errorLog15 = new StatusBitChannel("ErrorLog15", this)// + ), new UnsignedWordElement(0x155, errorLog16 = new StatusBitChannel("ErrorLog16", this)// + )), new WriteableModbusRegisterRange(0x200, // + new UnsignedWordElement(0x200, // + setWorkState = new ModbusWriteLongChannel("SetWorkState", this) // + .label(0, STOP) // + .label(1, START)), + new UnsignedWordElement(0x201, // + setSystemErrorReset = new ModbusWriteLongChannel("SetSystemErrorReset", this)// + .label(0, OFF)// + .label(1, ON)), + new UnsignedWordElement(0x202, // + setOperationMode = new ModbusWriteLongChannel("SetOperationMode", this)// + .label(0, "P/Q Set point")// + .label(1, "IAC / cosphi set point"))), new WriteableModbusRegisterRange(0x203, new SignedWordElement(0x203, // setActivePower = new ModbusWriteLongChannel("SetActivePower", this)// .unit("W").multiplier(2))), @@ -738,7 +754,7 @@ public WriteChannel setReactivePowerL3() { @Override public ThingStateChannel getStateChannel() { - return this.thingState; + return thingState; } } diff --git a/edge/src/io/openems/impl/device/refu/WarningEss.java b/edge/src/io/openems/impl/device/refu/WarningEss.java new file mode 100644 index 00000000000..56f0bfef23b --- /dev/null +++ b/edge/src/io/openems/impl/device/refu/WarningEss.java @@ -0,0 +1,29 @@ +package io.openems.impl.device.refu; + +import io.openems.api.channel.thingstate.WarningEnum; + +public enum WarningEss implements WarningEnum +{ + NormalChargingOverCurrent(0), CharginigCurrentOverLimit(1), DischargingCurrentOverLimit(2), NormalHighVoltage(3), NormalLowVoltage(4), + AbnormalVoltageVariation(5), NormalHighTemperature(6), NormalLowTemperature(7), AbnormalTemperatureVariation(8), SeriousHighVoltage(9), + SeriousLowVoltage(10), SeriousLowTemperature(11), ChargingSeriousOverCurrent(12), DischargingSeriousOverCurrent(13), AbnormalCapacityAlarm(14), + EEPROMParameterFailure(15), SwitchOfInsideCombinedCabinet(16), ShouldNotBeConnectedToGridDueToTheDCSideCondition(17), + EmergencyStopRequireFromSystemController(18), BatteryGroup1EnableAndNotConnectedToGrid(19), BatteryGroup2EnableAndNotConnectedToGrid(20), + BatteryGroup3EnableAndNotConnectedToGrid(21), BatteryGroup4EnableAndNotConnectedToGrid(22), TheIsolationSwitchOfBatteryGroup1Open(23), + TheIsolationSwitchOfBatteryGroup2Open(24), TheIsolationSwitchOfBatteryGroup3Open(25), TheIsolationSwitchOfBatteryGroup4Open(26), + BalancingSamplingFailureOfBatteryGroup1(27), BalancingSamplingFailureOfBatteryGroup2(28), BalancingSamplingFailureOfBatteryGroup3(29), + BalancingSamplingFailureOfBatteryGroup4(30), BalancingControlFailureOfBatteryGroup1(31), BalancingControlFailureOfBatteryGroup2(32), + BalancingControlFailureOfBatteryGroup3(33), BalancingControlFailureOfBatteryGroup4(34); + + + public final int value; + + private WarningEss(int value) { + this.value = value; + } + + @Override + public int getValue() { + return this.value; + } +} From 52befa3ebc182febd32b0817c91a1d645d81b671 Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Wed, 31 Jan 2018 15:44:29 +0100 Subject: [PATCH 37/55] Fix classpath --- common/.classpath | 12 ------------ edge/.classpath | 12 ------------ 2 files changed, 24 deletions(-) diff --git a/common/.classpath b/common/.classpath index 70e13502765..a4379df1766 100644 --- a/common/.classpath +++ b/common/.classpath @@ -10,18 +10,6 @@ - - - - - - - - - - - - diff --git a/edge/.classpath b/edge/.classpath index 10569758c03..77874fed6c6 100644 --- a/edge/.classpath +++ b/edge/.classpath @@ -14,17 +14,5 @@ - - - - - - - - - - - - From 59796052fb58d9a0d50820e90dbf0b08cbfafb38 Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Wed, 31 Jan 2018 15:44:55 +0100 Subject: [PATCH 38/55] Fix "channel is returning null" detection --- edge/src/io/openems/core/ThingRepository.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/edge/src/io/openems/core/ThingRepository.java b/edge/src/io/openems/core/ThingRepository.java index 0a361cad382..aa743e4de0d 100644 --- a/edge/src/io/openems/core/ThingRepository.java +++ b/edge/src/io/openems/core/ThingRepository.java @@ -160,25 +160,33 @@ public synchronized void addThing(Thing thing) { Member member = channelDoc.getMember(); try { List channels = new ArrayList<>(); + java.util.function.Consumer addToChannels = (c) -> { + if(c == null) { + log.error( + "Channel is returning null! Thing [" + thing.id() + "], Member [" + member.getName() + "]"); + } else { + channels.add(c); + } + }; if (member instanceof Method) { if (((Method) member).getReturnType().isArray()) { Channel[] ch = (Channel[]) ((Method) member).invoke(thing); for (Channel c : ch) { - channels.add(c); + addToChannels.accept(c); } } else { // It's a Method with ReturnType Channel - channels.add((Channel) ((Method) member).invoke(thing)); + Channel c = (Channel) ((Method) member).invoke(thing); + addToChannels.accept(c); } } else if (member instanceof Field) { // It's a Field with Type Channel - channels.add((Channel) ((Field) member).get(thing)); + Channel c = (Channel) ((Field) member).get(thing); + addToChannels.accept(c); } else { continue; } if (channels.isEmpty()) { - log.error( - "Channel is returning null! Thing [" + thing.id() + "], Member [" + member.getName() + "]"); continue; } for (Channel channel : channels) { From 5f35dccc0652f91a5b1fb5faeee8ce9bbcfc9999 Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Wed, 31 Jan 2018 15:45:15 +0100 Subject: [PATCH 39/55] Uncomment wago implementation --- .../io/openems/impl/device/wago/WagoFB.java | 378 +++++++++--------- .../openems/impl/device/wago/WagoFBInput.java | 224 ++++++----- .../impl/device/wago/WagoFBOutput.java | 226 ++++++----- 3 files changed, 422 insertions(+), 406 deletions(-) diff --git a/edge/src/io/openems/impl/device/wago/WagoFB.java b/edge/src/io/openems/impl/device/wago/WagoFB.java index ae302bb8613..62219f84c3d 100644 --- a/edge/src/io/openems/impl/device/wago/WagoFB.java +++ b/edge/src/io/openems/impl/device/wago/WagoFB.java @@ -1,189 +1,189 @@ -///******************************************************************************* -// * 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.device.wago; -// -//import java.io.IOException; -//import java.io.InputStream; -//import java.net.Inet4Address; -//import java.net.URL; -//import java.net.URLConnection; -//import java.util.ArrayList; -//import java.util.HashMap; -//import java.util.HashSet; -//import java.util.List; -//import java.util.Set; -// -//import javax.xml.parsers.DocumentBuilder; -//import javax.xml.parsers.DocumentBuilderFactory; -//import javax.xml.parsers.ParserConfigurationException; -// -//import org.slf4j.LoggerFactory; -//import org.w3c.dom.Document; -//import org.w3c.dom.NamedNodeMap; -//import org.w3c.dom.Node; -//import org.xml.sax.SAXException; -// -//import io.openems.api.bridge.Bridge; -//import io.openems.api.channel.ConfigChannel; -//import io.openems.api.device.nature.DeviceNature; -//import io.openems.api.doc.ChannelInfo; -//import io.openems.api.doc.ThingInfo; -//import io.openems.api.exception.ConfigException; -//import io.openems.api.exception.OpenemsException; -//import io.openems.impl.protocol.modbus.ModbusDevice; -// -///* -// * Example config: -// * -// *
    -// * {
    -// *   "class": "io.openems.impl.protocol.modbus.ModbusTcp",
    -// *   "ip": "172.16.86.1",
    -// *   "devices": [
    -// *     {
    -// *       "class": "io.openems.impl.device.wago.WagoFB",
    -// *       "modbusUnitId": 1,
    -// *       "output": {
    -// *         "id": "output0",
    -// *         "ip": "172.16.86.1"
    -// *       },
    -// *       "input": {
    -// *         "id": "input0",
    -// *         "ip": "172.16.86.1"
    -// *       }
    -// *     }
    -// *   ]
    -// * }
    -// * 
    -// */ -// -//@ThingInfo(title = "WAGO I/O") -//public class WagoFB extends ModbusDevice { -// -// /* -// * Constructors -// */ -// public WagoFB(Bridge parent) throws OpenemsException { -// super(parent); -// } -// -// /* -// * Config -// */ -// @ChannelInfo(title = "Output", description = "Sets the output nature.", type = WagoFBOutput.class) -// public final ConfigChannel output = new ConfigChannel<>("output", this); -// -// @ChannelInfo(title = "Input", description = "Sets the input nature.", type = WagoFBInput.class) -// public final ConfigChannel input = new ConfigChannel<>("input", this); -// -// /* -// * Fields -// */ -// private static HashMap>> configCache = new HashMap<>(); -// -// /* -// * Methods -// */ -// @Override -// protected Set getDeviceNatures() { -// Set natures = new HashSet<>(); -// if (output.valueOptional().isPresent()) { -// natures.add(output.valueOptional().get()); -// } -// if (input.valueOptional().isPresent()) { -// natures.add(input.valueOptional().get()); -// } -// return natures; -// } -// -// public static HashMap> getConfig(Inet4Address ip) throws ConfigException { -// if (configCache.containsKey(ip)) { -// return configCache.get(ip); -// } else { -// HashMap> channels = new HashMap<>(); -// String username = "admin"; -// String password = "wago"; -// int ftpPort = 21; -// URL url; -// Document doc; -// try { -// url = new URL("ftp://" + username + ":" + password + "@" + ip.getHostAddress() + ":" + ftpPort -// + "/etc/EA-config.xml;type=i"); -// URLConnection urlc = url.openConnection(); -// InputStream is = urlc.getInputStream(); -// DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); -// DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); -// doc = dBuilder.parse(is); -// doc.getDocumentElement().normalize(); -// } catch (IOException | SAXException | ParserConfigurationException e) { -// throw new ConfigException(e.getMessage()); -// } -// -// Node wagoNode = doc.getElementsByTagName("WAGO").item(0); -// if (wagoNode != null) { -// HashMap moduleCounter = new HashMap(); -// Node moduleNode = wagoNode.getFirstChild(); -// while (moduleNode != null) { -// if (moduleNode.getNodeType() == Node.ELEMENT_NODE) { -// NamedNodeMap moduleAttrs = moduleNode.getAttributes(); -// // String article = moduleAttrs.getNamedItem("ARTIKELNR").getNodeValue(); -// String moduletype = moduleAttrs.getNamedItem("MODULETYPE").getNodeValue(); -// if (!moduleCounter.containsKey(moduletype)) { -// moduleCounter.put(moduletype, 0); -// } -// moduleCounter.replace(moduletype, moduleCounter.get(moduletype) + 1); -// int index = 1; -// Node channelNode = moduleNode.getFirstChild(); -// while (channelNode != null) { -// if (channelNode.getNodeType() == Node.ELEMENT_NODE) { -// NamedNodeMap channelAttrs = channelNode.getAttributes(); -// String channelType = channelAttrs.getNamedItem("CHANNELTYPE").getNodeValue(); -// if (!channels.containsKey(channelType)) { -// channels.put(channelType, new ArrayList()); -// } -// String channelName = ""; -// switch (channelType) { -// case "DO": -// channelName = "DigitalOutput_" + moduleCounter.get(channelType) + "_" + index; -// break; -// case "DI": -// channelName = "DigitalInput_" + moduleCounter.get(channelType) + "_" + index; -// break; -// default: -// LoggerFactory.getLogger(WagoFB.class) -// .debug("ChannelType: " + channelName + " nicht erkannt"); -// break; -// } -// channels.get(channelType).add(channelName); -// index++; -// } -// channelNode = channelNode.getNextSibling(); -// } -// } -// moduleNode = moduleNode.getNextSibling(); -// } -// } -// configCache.put(ip, channels); -// return channels; -// } -// } -// -//} +/******************************************************************************* + * 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.device.wago; + +import java.io.IOException; +import java.io.InputStream; +import java.net.Inet4Address; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.xml.sax.SAXException; + +import io.openems.api.bridge.Bridge; +import io.openems.api.channel.ConfigChannel; +import io.openems.api.device.nature.DeviceNature; +import io.openems.api.doc.ChannelInfo; +import io.openems.api.doc.ThingInfo; +import io.openems.api.exception.ConfigException; +import io.openems.api.exception.OpenemsException; +import io.openems.impl.protocol.modbus.ModbusDevice; + +/* + * Example config: + * + *
    + * {
    + *   "class": "io.openems.impl.protocol.modbus.ModbusTcp",
    + *   "ip": "172.16.86.1",
    + *   "devices": [
    + *     {
    + *       "class": "io.openems.impl.device.wago.WagoFB",
    + *       "modbusUnitId": 1,
    + *       "output": {
    + *         "id": "output0",
    + *         "ip": "172.16.86.1"
    + *       },
    + *       "input": {
    + *         "id": "input0",
    + *         "ip": "172.16.86.1"
    + *       }
    + *     }
    + *   ]
    + * }
    + * 
    + */ + +@ThingInfo(title = "WAGO I/O") +public class WagoFB extends ModbusDevice { + + /* + * Constructors + */ + public WagoFB(Bridge parent) throws OpenemsException { + super(parent); + } + + /* + * Config + */ + @ChannelInfo(title = "Output", description = "Sets the output nature.", type = WagoFBOutput.class) + public final ConfigChannel output = new ConfigChannel<>("output", this); + + @ChannelInfo(title = "Input", description = "Sets the input nature.", type = WagoFBInput.class) + public final ConfigChannel input = new ConfigChannel<>("input", this); + + /* + * Fields + */ + private static HashMap>> configCache = new HashMap<>(); + + /* + * Methods + */ + @Override + protected Set getDeviceNatures() { + Set natures = new HashSet<>(); + if (output.valueOptional().isPresent()) { + natures.add(output.valueOptional().get()); + } + if (input.valueOptional().isPresent()) { + natures.add(input.valueOptional().get()); + } + return natures; + } + + public static HashMap> getConfig(Inet4Address ip) throws ConfigException { + if (configCache.containsKey(ip)) { + return configCache.get(ip); + } else { + HashMap> channels = new HashMap<>(); + String username = "admin"; + String password = "wago"; + int ftpPort = 21; + URL url; + Document doc; + try { + url = new URL("ftp://" + username + ":" + password + "@" + ip.getHostAddress() + ":" + ftpPort + + "/etc/EA-config.xml;type=i"); + URLConnection urlc = url.openConnection(); + InputStream is = urlc.getInputStream(); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + doc = dBuilder.parse(is); + doc.getDocumentElement().normalize(); + } catch (IOException | SAXException | ParserConfigurationException e) { + throw new ConfigException(e.getMessage()); + } + + Node wagoNode = doc.getElementsByTagName("WAGO").item(0); + if (wagoNode != null) { + HashMap moduleCounter = new HashMap(); + Node moduleNode = wagoNode.getFirstChild(); + while (moduleNode != null) { + if (moduleNode.getNodeType() == Node.ELEMENT_NODE) { + NamedNodeMap moduleAttrs = moduleNode.getAttributes(); + // String article = moduleAttrs.getNamedItem("ARTIKELNR").getNodeValue(); + String moduletype = moduleAttrs.getNamedItem("MODULETYPE").getNodeValue(); + if (!moduleCounter.containsKey(moduletype)) { + moduleCounter.put(moduletype, 0); + } + moduleCounter.replace(moduletype, moduleCounter.get(moduletype) + 1); + int index = 1; + Node channelNode = moduleNode.getFirstChild(); + while (channelNode != null) { + if (channelNode.getNodeType() == Node.ELEMENT_NODE) { + NamedNodeMap channelAttrs = channelNode.getAttributes(); + String channelType = channelAttrs.getNamedItem("CHANNELTYPE").getNodeValue(); + if (!channels.containsKey(channelType)) { + channels.put(channelType, new ArrayList()); + } + String channelName = ""; + switch (channelType) { + case "DO": + channelName = "DigitalOutput_" + moduleCounter.get(channelType) + "_" + index; + break; + case "DI": + channelName = "DigitalInput_" + moduleCounter.get(channelType) + "_" + index; + break; + default: + LoggerFactory.getLogger(WagoFB.class) + .debug("ChannelType: " + channelName + " nicht erkannt"); + break; + } + channels.get(channelType).add(channelName); + index++; + } + channelNode = channelNode.getNextSibling(); + } + } + moduleNode = moduleNode.getNextSibling(); + } + } + configCache.put(ip, channels); + return channels; + } + } + +} diff --git a/edge/src/io/openems/impl/device/wago/WagoFBInput.java b/edge/src/io/openems/impl/device/wago/WagoFBInput.java index 297df0b5956..8ca8ded9912 100644 --- a/edge/src/io/openems/impl/device/wago/WagoFBInput.java +++ b/edge/src/io/openems/impl/device/wago/WagoFBInput.java @@ -1,108 +1,116 @@ -///******************************************************************************* -// * 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.device.wago; -// -//import java.net.Inet4Address; -//import java.util.ArrayList; -//import java.util.HashMap; -//import java.util.List; -// -//import io.openems.api.channel.ConfigChannel; -//import io.openems.api.device.Device; -//import io.openems.api.device.nature.io.InputNature; -//import io.openems.api.doc.ChannelInfo; -//import io.openems.api.doc.ThingInfo; -//import io.openems.api.exception.ConfigException; -//import io.openems.api.exception.InvalidValueException; -//import io.openems.impl.protocol.modbus.ModbusCoilReadChannel; -//import io.openems.impl.protocol.modbus.ModbusDeviceNature; -//import io.openems.impl.protocol.modbus.internal.CoilElement; -//import io.openems.impl.protocol.modbus.internal.ModbusProtocol; -//import io.openems.impl.protocol.modbus.internal.range.ModbusCoilRange; -//import io.openems.impl.protocol.modbus.internal.range.ModbusRange; -// -//@ThingInfo(title = "WAGO I/O Input") -//public class WagoFBInput extends ModbusDeviceNature implements InputNature { -// -// /* -// * Constructors -// */ -// public WagoFBInput(String thingId, Device parent) throws ConfigException { -// super(thingId, parent); -// } -// -// /* -// * Config -// */ -// @ChannelInfo(title = "IP address", description = "IP address of the WAGO device.", type = Inet4Address.class) -// public ConfigChannel ip = new ConfigChannel("ip", this); -// -// /* -// * This Channels -// */ -// private List channel = new ArrayList<>(); -// -// /* -// * Methods -// */ -// @Override -// public ModbusCoilReadChannel[] getInput() { -// return channel.toArray(new ModbusCoilReadChannel[channel.size()]); -// } -// -// @Override -// protected ModbusProtocol defineModbusProtocol() throws ConfigException { -// List ranges = new ArrayList<>(); -// HashMap> channels; -// try { -// channels = WagoFB.getConfig(ip.value()); -// for (String key : channels.keySet()) { -// switch (key) { -// case "DI": { -// List elements = new ArrayList<>(); -// int count = 0; -// for (@SuppressWarnings("unused") String channel : channels.get(key)) { -// ModbusCoilReadChannel ch = new ModbusCoilReadChannel(Integer.toString(count), this); -// this.channel.add(ch); -// elements.add(new CoilElement(count, ch)); -// count++; -// if (count % 63 == 0) { -// ranges.add(new ModbusCoilRange(elements.get(0).getAddress(), -// elements.toArray(new CoilElement[elements.size()]))); -// elements.clear(); -// } -// } -// if (this.channel.size() > 0) { -// ranges.add(new ModbusCoilRange(elements.get(0).getAddress(), -// elements.toArray(new CoilElement[elements.size()]))); -// } -// } -// break; -// } -// } -// } catch (InvalidValueException e) { -// log.error("Ip-Address is Invalid", e); -// } -// ModbusProtocol protocol = new ModbusProtocol(ranges.toArray(new ModbusRange[ranges.size()])); -// return protocol; -// } -// -//} +/******************************************************************************* + * 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.device.wago; + +import java.net.Inet4Address; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.device.Device; +import io.openems.api.device.nature.io.InputNature; +import io.openems.api.doc.ChannelInfo; +import io.openems.api.doc.ThingInfo; +import io.openems.api.exception.ConfigException; +import io.openems.api.exception.InvalidValueException; +import io.openems.impl.protocol.modbus.ModbusCoilReadChannel; +import io.openems.impl.protocol.modbus.ModbusDeviceNature; +import io.openems.impl.protocol.modbus.internal.CoilElement; +import io.openems.impl.protocol.modbus.internal.ModbusProtocol; +import io.openems.impl.protocol.modbus.internal.range.ModbusCoilRange; +import io.openems.impl.protocol.modbus.internal.range.ModbusRange; + +@ThingInfo(title = "WAGO I/O Input") +public class WagoFBInput extends ModbusDeviceNature implements InputNature { + + /* + * Constructors + */ + public WagoFBInput(String thingId, Device parent) throws ConfigException { + super(thingId, parent); + this.thingState = new ThingStateChannel(this); + } + + /* + * Config + */ + @ChannelInfo(title = "IP address", description = "IP address of the WAGO device.", type = Inet4Address.class) + public ConfigChannel ip = new ConfigChannel("ip", this); + + /* + * This Channels + */ + private List channel = new ArrayList<>(); + + private ThingStateChannel thingState; + + /* + * Methods + */ + @Override + public ModbusCoilReadChannel[] getInput() { + return channel.toArray(new ModbusCoilReadChannel[channel.size()]); + } + + @Override + protected ModbusProtocol defineModbusProtocol() throws ConfigException { + List ranges = new ArrayList<>(); + HashMap> channels; + try { + channels = WagoFB.getConfig(ip.value()); + for (String key : channels.keySet()) { + switch (key) { + case "DI": { + List elements = new ArrayList<>(); + int count = 0; + for (@SuppressWarnings("unused") String channel : channels.get(key)) { + ModbusCoilReadChannel ch = new ModbusCoilReadChannel(Integer.toString(count), this); + this.channel.add(ch); + elements.add(new CoilElement(count, ch)); + count++; + if (count % 63 == 0) { + ranges.add(new ModbusCoilRange(elements.get(0).getAddress(), + elements.toArray(new CoilElement[elements.size()]))); + elements.clear(); + } + } + if (this.channel.size() > 0) { + ranges.add(new ModbusCoilRange(elements.get(0).getAddress(), + elements.toArray(new CoilElement[elements.size()]))); + } + } + break; + } + } + } catch (InvalidValueException e) { + log.error("Ip-Address is Invalid", e); + } + ModbusProtocol protocol = new ModbusProtocol(ranges.toArray(new ModbusRange[ranges.size()])); + return protocol; + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } +} diff --git a/edge/src/io/openems/impl/device/wago/WagoFBOutput.java b/edge/src/io/openems/impl/device/wago/WagoFBOutput.java index 4534e82aa6c..c6a56e919b6 100644 --- a/edge/src/io/openems/impl/device/wago/WagoFBOutput.java +++ b/edge/src/io/openems/impl/device/wago/WagoFBOutput.java @@ -1,109 +1,117 @@ -///******************************************************************************* -// * 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.device.wago; -// -//import java.net.Inet4Address; -//import java.util.ArrayList; -//import java.util.HashMap; -//import java.util.List; -// -//import io.openems.api.channel.ConfigChannel; -//import io.openems.api.device.Device; -//import io.openems.api.device.nature.io.OutputNature; -//import io.openems.api.doc.ChannelInfo; -//import io.openems.api.doc.ThingInfo; -//import io.openems.api.exception.ConfigException; -//import io.openems.api.exception.InvalidValueException; -//import io.openems.impl.protocol.modbus.ModbusCoilWriteChannel; -//import io.openems.impl.protocol.modbus.ModbusDeviceNature; -//import io.openems.impl.protocol.modbus.internal.CoilElement; -//import io.openems.impl.protocol.modbus.internal.ModbusProtocol; -//import io.openems.impl.protocol.modbus.internal.range.ModbusCoilRange; -//import io.openems.impl.protocol.modbus.internal.range.ModbusRange; -//import io.openems.impl.protocol.modbus.internal.range.WriteableModbusCoilRange; -// -//@ThingInfo(title = "WAGO I/O Output") -//public class WagoFBOutput extends ModbusDeviceNature implements OutputNature { -// -// /* -// * Constructors -// */ -// public WagoFBOutput(String thingId, Device parent) throws ConfigException { -// super(thingId, parent); -// } -// -// /* -// * Config -// */ -// @ChannelInfo(title = "IP", description = "IP address of the WAGO device.", type = Inet4Address.class) -// public ConfigChannel ip = new ConfigChannel("ip", this); -// -// /* -// * This Channels -// */ -// private List channel = new ArrayList<>(); -// -// /* -// * Methods -// */ -// @Override -// public ModbusCoilWriteChannel[] setOutput() { -// return channel.toArray(new ModbusCoilWriteChannel[channel.size()]); -// } -// -// @Override -// protected ModbusProtocol defineModbusProtocol() throws ConfigException { -// List ranges = new ArrayList<>(); -// HashMap> channels; -// try { -// channels = WagoFB.getConfig(ip.value()); -// for (String key : channels.keySet()) { -// switch (key) { -// case "DO": { -// List elements = new ArrayList<>(); -// int count = 0; -// for (@SuppressWarnings("unused") String channel : channels.get(key)) { -// ModbusCoilWriteChannel ch = new ModbusCoilWriteChannel(Integer.toString(count), this); -// this.channel.add(ch); -// elements.add(new CoilElement(512 + count, ch)); -// count++; -// if (count % 63 == 0) { -// ranges.add(new ModbusCoilRange(elements.get(0).getAddress(), -// elements.toArray(new CoilElement[elements.size()]))); -// elements.clear(); -// } -// } -// if (this.channel.size() > 0) { -// ranges.add(new WriteableModbusCoilRange(elements.get(0).getAddress(), -// elements.toArray(new CoilElement[elements.size()]))); -// } -// } -// break; -// } -// } -// } catch (InvalidValueException e) { -// log.error("Ip-Address is Invalid", e); -// } -// ModbusProtocol protocol = new ModbusProtocol(ranges.toArray(new ModbusRange[ranges.size()])); -// return protocol; -// } -// -//} +/******************************************************************************* + * 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.device.wago; + +import java.net.Inet4Address; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.device.Device; +import io.openems.api.device.nature.io.OutputNature; +import io.openems.api.doc.ChannelInfo; +import io.openems.api.doc.ThingInfo; +import io.openems.api.exception.ConfigException; +import io.openems.api.exception.InvalidValueException; +import io.openems.impl.protocol.modbus.ModbusCoilWriteChannel; +import io.openems.impl.protocol.modbus.ModbusDeviceNature; +import io.openems.impl.protocol.modbus.internal.CoilElement; +import io.openems.impl.protocol.modbus.internal.ModbusProtocol; +import io.openems.impl.protocol.modbus.internal.range.ModbusCoilRange; +import io.openems.impl.protocol.modbus.internal.range.ModbusRange; +import io.openems.impl.protocol.modbus.internal.range.WriteableModbusCoilRange; + +@ThingInfo(title = "WAGO I/O Output") +public class WagoFBOutput extends ModbusDeviceNature implements OutputNature { + + /* + * Constructors + */ + public WagoFBOutput(String thingId, Device parent) throws ConfigException { + super(thingId, parent); + this.thingState = new ThingStateChannel(this); + } + + /* + * Config + */ + @ChannelInfo(title = "IP", description = "IP address of the WAGO device.", type = Inet4Address.class) + public ConfigChannel ip = new ConfigChannel("ip", this); + + /* + * This Channels + */ + private List channel = new ArrayList<>(); + + private ThingStateChannel thingState; + + /* + * Methods + */ + @Override + public ModbusCoilWriteChannel[] setOutput() { + return channel.toArray(new ModbusCoilWriteChannel[channel.size()]); + } + + @Override + protected ModbusProtocol defineModbusProtocol() throws ConfigException { + List ranges = new ArrayList<>(); + HashMap> channels; + try { + channels = WagoFB.getConfig(ip.value()); + for (String key : channels.keySet()) { + switch (key) { + case "DO": { + List elements = new ArrayList<>(); + int count = 0; + for (@SuppressWarnings("unused") String channel : channels.get(key)) { + ModbusCoilWriteChannel ch = new ModbusCoilWriteChannel(Integer.toString(count), this); + this.channel.add(ch); + elements.add(new CoilElement(512 + count, ch)); + count++; + if (count % 63 == 0) { + ranges.add(new ModbusCoilRange(elements.get(0).getAddress(), + elements.toArray(new CoilElement[elements.size()]))); + elements.clear(); + } + } + if (this.channel.size() > 0) { + ranges.add(new WriteableModbusCoilRange(elements.get(0).getAddress(), + elements.toArray(new CoilElement[elements.size()]))); + } + } + break; + } + } + } catch (InvalidValueException e) { + log.error("Ip-Address is Invalid", e); + } + ModbusProtocol protocol = new ModbusProtocol(ranges.toArray(new ModbusRange[ranges.size()])); + return protocol; + } + + @Override + public ThingStateChannel getStateChannel() { + return this.thingState; + } +} From 73a771fb541be01784a9052cc16dc70fe5a86f8d Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Wed, 31 Jan 2018 15:45:23 +0100 Subject: [PATCH 40/55] Fix warnings --- .../openems/common/websocket/AbstractWebsocketServer.java | 1 - edge/src/io/openems/core/utilities/BitUtils.java | 6 ++++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/common/src/io/openems/common/websocket/AbstractWebsocketServer.java b/common/src/io/openems/common/websocket/AbstractWebsocketServer.java index 07df2825e0d..b421929b02d 100644 --- a/common/src/io/openems/common/websocket/AbstractWebsocketServer.java +++ b/common/src/io/openems/common/websocket/AbstractWebsocketServer.java @@ -37,7 +37,6 @@ protected abstract void _onMessage(WebSocket websocket, JsonObject jMessage, Opt protected abstract void _onClose(WebSocket websocket, Optional sessionOpt); - @SuppressWarnings("deprecation") public AbstractWebsocketServer(int port, M sessionManager) { super(new InetSocketAddress(port), Lists.newArrayList(new Draft_6455())); this.sessionManager = sessionManager; diff --git a/edge/src/io/openems/core/utilities/BitUtils.java b/edge/src/io/openems/core/utilities/BitUtils.java index 16ed9005b20..ac662f1eba2 100644 --- a/edge/src/io/openems/core/utilities/BitUtils.java +++ b/edge/src/io/openems/core/utilities/BitUtils.java @@ -65,8 +65,11 @@ public static byte[] toBytes(Object value) throws NotImplementedException { case JSON_OBJECT: case DEVICE_NATURE: case THING_MAP: + case ENUM: // igore - no error return new byte[0]; + default: + break; } throw new NotImplementedException( "Converter to Byte for value [" + value + "] of type [" + type + "] is not implemented."); @@ -98,8 +101,11 @@ public static Object toObject(Class type, byte... value) throws NotImplemente case JSON_OBJECT: case DEVICE_NATURE: case THING_MAP: + case ENUM: throw new NotImplementedException( "Converter to Byte for value [" + value + "] of type [" + type + "] is not implemented."); + default: + break; } throw new NotImplementedException( "Converter to Byte for value [" + value + "] of type [" + type + "] is not implemented."); From 74a6c6cb4ebbff0b4b640f8b5076d49848837636 Mon Sep 17 00:00:00 2001 From: Hueseyin Sahutoglu Date: Wed, 31 Jan 2018 16:21:26 +0100 Subject: [PATCH 41/55] Correct mistakes --- .../impl/device/byd/Bem125ktla01Ess.java | 18 +- .../io/openems/impl/device/byd/Warning.java | 17 -- .../commercial/FeneconCommercialEss.java | 194 +++++++++--------- 3 files changed, 99 insertions(+), 130 deletions(-) delete mode 100644 edge/src/io/openems/impl/device/byd/Warning.java diff --git a/edge/src/io/openems/impl/device/byd/Bem125ktla01Ess.java b/edge/src/io/openems/impl/device/byd/Bem125ktla01Ess.java index 1a0f68c57cb..ff08c609caf 100644 --- a/edge/src/io/openems/impl/device/byd/Bem125ktla01Ess.java +++ b/edge/src/io/openems/impl/device/byd/Bem125ktla01Ess.java @@ -182,12 +182,7 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { .warningBit(3, WarningEss.ChargeForbidden)// .warningBit(4, WarningEss.DischargeForbidden)// ),// - // sysAlarmInfo = new ModbusReadLongChannel("SysAlarmInfo", this)// - // .label(1, "Warning State")// - // .label(2, "Protection State")// - // .label(4, "Derating State")// - // .label(8, "Charge Forbidden")// - // .label(16, "Discharge Forbidden")), + new UnsignedWordElement(0x101, // sysWorkStatus = new ModbusReadLongChannel("SysWorkStatus", this)// .label(1, "Initial") // @@ -212,22 +207,13 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { .warningBit(5, WarningEss.StatusAbnormalOfFrogDetector) // Status_abnormal_of_frog_detector .warningBit(6, WarningEss.SeriousLeakage) // Serious_leakage .warningBit(7, WarningEss.NormalLeakage)), // Normal_leakage - // .warningBit(1, Warning.Status_abnormal_of_AC_surge_protector) // Status abnormal of AC surge protector - // .warningBit(2, Warning.Close_of_control_switch) // Close of control switch - // .warningBit(3, Warning.Emergency_stop) // Emergency stop - // .warningBit(5, Warning.Status_abnormal_of_frog_detector) // Status_abnormal_of_frog_detector - // .warningBit(6, Warning.Serious_leakage) // Serious_leakage - // .warningBit(7, Warning.Normal_leakage)), // Normal_leakage new UnsignedWordElement(0x111, // new ModbusBitWrappingChannel("SysAlarmInfo2", this, thingState)// .warningBit(0, WarningEss.FailureOfTemperatureSensorInControlCabinet) // Failure of temperature sensor in control cabinet .warningBit(9, WarningEss.FailureOfHumiditySensorInControlCabinet) // Failure_of_humidity_sensor_in_control_cabinet .warningBit(12,WarningEss.FailureOfStorageDevice) // Failure_of_storage_device .warningBit(13,WarningEss.ExceedingOfHumidityInControlCabinet)) // Exceeding_of_humidity_in_control_cabinet - // .warningBit(0, Warning.Failure_of_temperature_sensor_in_control_cabinet) // Failure of temperature sensor in control cabinet - // .warningBit(9, Warning.Failure_of_humidity_sensor_in_control_cabinet) // Failure_of_humidity_sensor_in_control_cabinet - // .warningBit(12, Warning.Failure_of_storage_device) // Failure_of_storage_device - // .warningBit(13, Warning.Exceeding_of_humidity_in_control_cabinet)) // Exceeding_of_humidity_in_control_cabinet + ), new ModbusRegisterRange(0x1300, new UnsignedWordElement(0x1300, // batteryStackVoltage = new ModbusReadLongChannel("BatteryStackVoltage", this).multiplier(2) .unit("mV")), diff --git a/edge/src/io/openems/impl/device/byd/Warning.java b/edge/src/io/openems/impl/device/byd/Warning.java deleted file mode 100644 index 9565d2a4382..00000000000 --- a/edge/src/io/openems/impl/device/byd/Warning.java +++ /dev/null @@ -1,17 +0,0 @@ -package io.openems.impl.device.byd; - -import io.openems.api.channel.thingstate.WarningEnum; - -public enum Warning implements WarningEnum{ - Status_abnormal_of_AC_surge_protector(0),Close_of_control_switch(1),Emergency_stop(2),Status_abnormal_of_frog_detector(3),Serious_leakage(4),Normal_leakage(5),Failure_of_temperature_sensor_in_control_cabinet(6),Failure_of_humidity_sensor_in_control_cabinet(7),Failure_of_storage_device(8),Exceeding_of_humidity_in_control_cabinet(9); - private final int value; - - private Warning(int value) { - this.value = value; - } - - @Override - public int getValue() { - return this.value; - } -} diff --git a/edge/src/io/openems/impl/device/commercial/FeneconCommercialEss.java b/edge/src/io/openems/impl/device/commercial/FeneconCommercialEss.java index d8ff25891a7..0cb0a623e9f 100644 --- a/edge/src/io/openems/impl/device/commercial/FeneconCommercialEss.java +++ b/edge/src/io/openems/impl/device/commercial/FeneconCommercialEss.java @@ -550,7 +550,7 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { .faultBit(7, FaultEss.Phase1PeakCurrentOverLimitProtection)// .faultBit(8, FaultEss.Phase2PeakCurrentOverLimitProtection)// .faultBit(9, FaultEss.Phase3PeakCurrentOverLimitProtection)// - .faultBit(10, FaultEss.Phase1GridVoltageSamplingInvalidation)// + .faultBit(10,FaultEss.Phase1GridVoltageSamplingInvalidation)// .faultBit(11, FaultEss.Phase2VirtualCurrentOverLimitProtection)// .faultBit(12, FaultEss.Phase3VirtualCurrentOverLimitProtection)// .faultBit(13, FaultEss.Phase1GridVoltageSamplingInvalidation2)// TODO same as @@ -797,7 +797,7 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { batteryCell9Voltage = new ModbusReadLongChannel("Cell9Voltage", this).unit("mV") ),// new UnsignedWordElement(0x1509, - batteryCell10Voltage = new ModbusReadLongChannel("Cel10Voltage", this).unit("mV") + batteryCell10Voltage = new ModbusReadLongChannel("Cell10Voltage", this).unit("mV") ),// new UnsignedWordElement(0x150A, batteryCell11Voltage = new ModbusReadLongChannel("Cell11Voltage", this).unit("mV") @@ -998,7 +998,7 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { batteryCell76Voltage = new ModbusReadLongChannel("Cell76Voltage", this).unit("mV") ),// new UnsignedWordElement(0x154C, - batteryCell77Voltage = new ModbusReadLongChannel("Cell177Voltage", this).unit("mV") + batteryCell77Voltage = new ModbusReadLongChannel("Cell77Voltage", this).unit("mV") ),// new UnsignedWordElement(0x154D, batteryCell78Voltage = new ModbusReadLongChannel("Cell78Voltage", this).unit("mV") @@ -1159,286 +1159,286 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { new UnsignedWordElement(0x1581, batteryCell130Voltage = new ModbusReadLongChannel("Cell130Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x1583, + new UnsignedWordElement(0x1582, batteryCell131Voltage = new ModbusReadLongChannel("Cell131Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x1584, + new UnsignedWordElement(0x1583, batteryCell132Voltage = new ModbusReadLongChannel("Cell132Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x1585, + new UnsignedWordElement(0x1584, batteryCell133Voltage = new ModbusReadLongChannel("Cell133Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x1586, + new UnsignedWordElement(0x1585, batteryCell134Voltage = new ModbusReadLongChannel("Cell134Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x1587, + new UnsignedWordElement(0x1586, batteryCell135Voltage = new ModbusReadLongChannel("Cell135Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x1588, + new UnsignedWordElement(0x1587, batteryCell136Voltage = new ModbusReadLongChannel("Cell136Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x1589, + new UnsignedWordElement(0x1588, batteryCell137Voltage = new ModbusReadLongChannel("Cell137Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x158A, + new UnsignedWordElement(0x1589, batteryCell138Voltage = new ModbusReadLongChannel("Cell138Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x158B, + new UnsignedWordElement(0x158A, batteryCell139Voltage = new ModbusReadLongChannel("Cell139Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x158C, + new UnsignedWordElement(0x158B, batteryCell140Voltage = new ModbusReadLongChannel("Cell140Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x158D, + new UnsignedWordElement(0x158C, batteryCell141Voltage = new ModbusReadLongChannel("Cell141Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x158E, + new UnsignedWordElement(0x158D, batteryCell142Voltage = new ModbusReadLongChannel("Cell142Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x158F, + new UnsignedWordElement(0x158E, batteryCell143Voltage = new ModbusReadLongChannel("Cell143Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x1590, + new UnsignedWordElement(0x158F, batteryCell144Voltage = new ModbusReadLongChannel("Cell144Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x1591, + new UnsignedWordElement(0x1590, batteryCell145Voltage = new ModbusReadLongChannel("Cell145Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x1592, + new UnsignedWordElement(0x1591, batteryCell146Voltage = new ModbusReadLongChannel("Cell146Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x1593, + new UnsignedWordElement(0x1592, batteryCell147Voltage = new ModbusReadLongChannel("Cell147Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x1594, + new UnsignedWordElement(0x1593, batteryCell148Voltage = new ModbusReadLongChannel("Cell148Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x1595, + new UnsignedWordElement(0x1594, batteryCell149Voltage = new ModbusReadLongChannel("Cell149Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x1596, + new UnsignedWordElement(0x1595, batteryCell150Voltage = new ModbusReadLongChannel("Cell150Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x1597, + new UnsignedWordElement(0x1596, batteryCell151Voltage = new ModbusReadLongChannel("Cell151Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x1598, + new UnsignedWordElement(0x1597, batteryCell152Voltage = new ModbusReadLongChannel("Cell152Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x1599, + new UnsignedWordElement(0x1598, batteryCell153Voltage = new ModbusReadLongChannel("Cell153Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x159A, + new UnsignedWordElement(0x1599, batteryCell154Voltage = new ModbusReadLongChannel("Cell154Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x159B, + new UnsignedWordElement(0x159A, batteryCell155Voltage = new ModbusReadLongChannel("Cell155Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x159C, + new UnsignedWordElement(0x159B, batteryCell156Voltage = new ModbusReadLongChannel("Cell156Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x159D, + new UnsignedWordElement(0x159C, batteryCell157Voltage = new ModbusReadLongChannel("Cell157Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x159E, + new UnsignedWordElement(0x159D, batteryCell158Voltage = new ModbusReadLongChannel("Cell158Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x159F, + new UnsignedWordElement(0x159E, batteryCell159Voltage = new ModbusReadLongChannel("Cell159Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15A0, + new UnsignedWordElement(0x159F, batteryCell160Voltage = new ModbusReadLongChannel("Cell160Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15A1, + new UnsignedWordElement(0x15A0, batteryCell161Voltage = new ModbusReadLongChannel("Cell161Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15A2, + new UnsignedWordElement(0x15A1, batteryCell162Voltage = new ModbusReadLongChannel("Cell162Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15A3, + new UnsignedWordElement(0x15A2, batteryCell163Voltage = new ModbusReadLongChannel("Cell163Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15A4, + new UnsignedWordElement(0x15A3, batteryCell164Voltage = new ModbusReadLongChannel("Cell164Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15A5, + new UnsignedWordElement(0x15A4, batteryCell165Voltage = new ModbusReadLongChannel("Cell165Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15A6, + new UnsignedWordElement(0x15A5, batteryCell166Voltage = new ModbusReadLongChannel("Cell166Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15A7, + new UnsignedWordElement(0x15A6, batteryCell167Voltage = new ModbusReadLongChannel("Cell167Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15A8, + new UnsignedWordElement(0x15A7, batteryCell168Voltage = new ModbusReadLongChannel("Cell168Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15A9, + new UnsignedWordElement(0x15A8, batteryCell169Voltage = new ModbusReadLongChannel("Cell169Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15AA, + new UnsignedWordElement(0x15A9, batteryCell170Voltage = new ModbusReadLongChannel("Cell170Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15AB, + new UnsignedWordElement(0x15AA, batteryCell171Voltage = new ModbusReadLongChannel("Cell171Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15AC, + new UnsignedWordElement(0x15AB, batteryCell172Voltage = new ModbusReadLongChannel("Cell172Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15AD, + new UnsignedWordElement(0x15AC, batteryCell173Voltage = new ModbusReadLongChannel("Cell173Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15AE, + new UnsignedWordElement(0x15AD, batteryCell174Voltage = new ModbusReadLongChannel("Cell174Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15AF, + new UnsignedWordElement(0x15AE, batteryCell175Voltage = new ModbusReadLongChannel("Cell175Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15B0, + new UnsignedWordElement(0x15AF, batteryCell176Voltage = new ModbusReadLongChannel("Cell176Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15B1, + new UnsignedWordElement(0x15B0, batteryCell177Voltage = new ModbusReadLongChannel("Cell177Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15B2, + new UnsignedWordElement(0x15B1, batteryCell178Voltage = new ModbusReadLongChannel("Cell178Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15B3, + new UnsignedWordElement(0x15B2, batteryCell179Voltage = new ModbusReadLongChannel("Cell179Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15B4, + new UnsignedWordElement(0x15B3, batteryCell180Voltage = new ModbusReadLongChannel("Cell180Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15B5, + new UnsignedWordElement(0x15B4, batteryCell181Voltage = new ModbusReadLongChannel("Cell181Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15B6, + new UnsignedWordElement(0x15B5, batteryCell182Voltage = new ModbusReadLongChannel("Cell182Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15B7, + new UnsignedWordElement(0x15B6, batteryCell183Voltage = new ModbusReadLongChannel("Cell183Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15B8, + new UnsignedWordElement(0x15B7, batteryCell184Voltage = new ModbusReadLongChannel("Cell184Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15B9, + new UnsignedWordElement(0x15B8, batteryCell185Voltage = new ModbusReadLongChannel("Cell185Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15BA, + new UnsignedWordElement(0x15B9, batteryCell186Voltage = new ModbusReadLongChannel("Cell186Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15BB, + new UnsignedWordElement(0x15BA, batteryCell187Voltage = new ModbusReadLongChannel("Cell187Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15BC, + new UnsignedWordElement(0x15BB, batteryCell188Voltage = new ModbusReadLongChannel("Cell188Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15BD, + new UnsignedWordElement(0x15BC, batteryCell189Voltage = new ModbusReadLongChannel("Cell189Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15BE, + new UnsignedWordElement(0x15BD, batteryCell190Voltage = new ModbusReadLongChannel("Cell190Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15BF, + new UnsignedWordElement(0x15BE, batteryCell191Voltage = new ModbusReadLongChannel("Cell191Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15C0, + new UnsignedWordElement(0x15BF, batteryCell192Voltage = new ModbusReadLongChannel("Cell192Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15C1, + new UnsignedWordElement(0x15C0, batteryCell193Voltage = new ModbusReadLongChannel("Cell193Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15C2, + new UnsignedWordElement(0x15C1, batteryCell194Voltage = new ModbusReadLongChannel("Cell194Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15C3, + new UnsignedWordElement(0x15C2, batteryCell195Voltage = new ModbusReadLongChannel("Cell195Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15C4, + new UnsignedWordElement(0x15C3, batteryCell196Voltage = new ModbusReadLongChannel("Cell196Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15C5, + new UnsignedWordElement(0x15C4, batteryCell197Voltage = new ModbusReadLongChannel("Cell197Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15C6, + new UnsignedWordElement(0x15C5, batteryCell198Voltage = new ModbusReadLongChannel("Cell198Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15C7, + new UnsignedWordElement(0x15C6, batteryCell199Voltage = new ModbusReadLongChannel("Cell199Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15C8, + new UnsignedWordElement(0x15C7, batteryCell200Voltage = new ModbusReadLongChannel("Cell200Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15C9, + new UnsignedWordElement(0x15C8, batteryCell201Voltage = new ModbusReadLongChannel("Cell201Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15CA, + new UnsignedWordElement(0x15C9, batteryCell202Voltage = new ModbusReadLongChannel("Cell202Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15CB, + new UnsignedWordElement(0x15CA, batteryCell203Voltage = new ModbusReadLongChannel("Cell203Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15CC, + new UnsignedWordElement(0x15CB, batteryCell204Voltage = new ModbusReadLongChannel("Cell204Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15CD, + new UnsignedWordElement(0x15CC, batteryCell205Voltage = new ModbusReadLongChannel("Cell205Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15CE, + new UnsignedWordElement(0x15CD, batteryCell206Voltage = new ModbusReadLongChannel("Cell206Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15CF, + new UnsignedWordElement(0x15CE, batteryCell207Voltage = new ModbusReadLongChannel("Cell207Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15D0, + new UnsignedWordElement(0x15CF, batteryCell208Voltage = new ModbusReadLongChannel("Cell208Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15D1, + new UnsignedWordElement(0x15D0, batteryCell209Voltage = new ModbusReadLongChannel("Cell209Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15D2, + new UnsignedWordElement(0x15D1, batteryCell210Voltage = new ModbusReadLongChannel("Cell210Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15D3, + new UnsignedWordElement(0x15D2, batteryCell211Voltage = new ModbusReadLongChannel("Cell211Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15D4, + new UnsignedWordElement(0x15D3, batteryCell212Voltage = new ModbusReadLongChannel("Cell212Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15D5, + new UnsignedWordElement(0x15D4, batteryCell213Voltage = new ModbusReadLongChannel("Cell213Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15D6, + new UnsignedWordElement(0x15D5, batteryCell214Voltage = new ModbusReadLongChannel("Cell214Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15D7, + new UnsignedWordElement(0x15D6, batteryCell215Voltage = new ModbusReadLongChannel("Cell215Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15D8, + new UnsignedWordElement(0x15D7, batteryCell216Voltage = new ModbusReadLongChannel("Cell216Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15D9, + new UnsignedWordElement(0x15D8, batteryCell217Voltage = new ModbusReadLongChannel("Cell217Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15DA, + new UnsignedWordElement(0x15D9, batteryCell218Voltage = new ModbusReadLongChannel("Cell218Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15DB, + new UnsignedWordElement(0x15DA, batteryCell219Voltage = new ModbusReadLongChannel("Cell219Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15DC, + new UnsignedWordElement(0x15DB, batteryCell220Voltage = new ModbusReadLongChannel("Cell220Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15DD, + new UnsignedWordElement(0x15DC, batteryCell221Voltage = new ModbusReadLongChannel("Cell221Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15DE, + new UnsignedWordElement(0x15DD, batteryCell222Voltage = new ModbusReadLongChannel("Cell222Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15DF, + new UnsignedWordElement(0x15DE, batteryCell223Voltage = new ModbusReadLongChannel("Cell223Voltage", this).unit("mV") ),// - new UnsignedWordElement(0x15E0, + new UnsignedWordElement(0x15DF, batteryCell224Voltage = new ModbusReadLongChannel("Cell224Voltage", this).unit("mV") ))); From 4553bdea432f6ed11e89fdb5cfe43af901424fed Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Wed, 31 Jan 2018 16:37:40 +0100 Subject: [PATCH 42/55] Split ModbusRegisterRange in smaller parts --- .../impl/device/commercial/FeneconCommercialEss.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/edge/src/io/openems/impl/device/commercial/FeneconCommercialEss.java b/edge/src/io/openems/impl/device/commercial/FeneconCommercialEss.java index 0cb0a623e9f..89930b73b8e 100644 --- a/edge/src/io/openems/impl/device/commercial/FeneconCommercialEss.java +++ b/edge/src/io/openems/impl/device/commercial/FeneconCommercialEss.java @@ -1008,7 +1008,8 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { ),// new UnsignedWordElement(0x154F, batteryCell80Voltage = new ModbusReadLongChannel("Cell80Voltage", this).unit("mV") - ),// + )), + new ModbusRegisterRange(0x1550, // new UnsignedWordElement(0x1550, batteryCell81Voltage = new ModbusReadLongChannel("Cell81Voltage", this).unit("mV") ),// @@ -1248,7 +1249,8 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { ),// new UnsignedWordElement(0x159F, batteryCell160Voltage = new ModbusReadLongChannel("Cell160Voltage", this).unit("mV") - ),// + )),// + new ModbusRegisterRange(0x15A0, // new UnsignedWordElement(0x15A0, batteryCell161Voltage = new ModbusReadLongChannel("Cell161Voltage", this).unit("mV") ),// From 72797aa11d9fafe976d84c5eb55ea980aba05862 Mon Sep 17 00:00:00 2001 From: Hueseyin Sahutoglu Date: Mon, 5 Feb 2018 14:36:30 +0100 Subject: [PATCH 43/55] correct mistakes --- .../impl/device/commercial/FaultCharger.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/edge/src/io/openems/impl/device/commercial/FaultCharger.java b/edge/src/io/openems/impl/device/commercial/FaultCharger.java index f0f5b9aabb0..34358945692 100644 --- a/edge/src/io/openems/impl/device/commercial/FaultCharger.java +++ b/edge/src/io/openems/impl/device/commercial/FaultCharger.java @@ -30,7 +30,7 @@ public enum FaultCharger implements FaultEnum{ BsmDCDC1ACContactorStateAbnormityOfDCConvetor(116), BsmDCDC1DCConvetorEmergencyStop(117), BsmDCDC1DCConverterChargingGunDisconnected(118), BsmDCDC1DCCurrentAbnormityBeforeDCConvetorWork(119), BsmDCDC1FuSeDisconnected(120), BsmDCDC1DCConverterHardwareCurrentOrVoltageFault(121), BmsDCDC1DCConverterCrystalOscillatorCircuitInvalidation(122), BmsDCDC1DCConverterResetCircuitInvalidation(123), BmsDCDC1DCConverterSamplingCircuitInvalidation(124), BmsDCDC1DCConverterDigitalIOCircuitInvalidation(125), BmsDCDC1DCConverterPWMCircuitInvalidation(126), BmsDCDC1DCConverterX5045CircuitInvalidation(127), BmsDCDC1DCConverterCANCircuitInvalidation(128), - BmsDCDC1DCConverterSoftwareANDHardwareProtectionCircuitInvalidation(129), BmsDCDC1DCConverterPowerCircuitInvalidation(130), BmsDCDC1DCConverterCPUInvalidation(131), BmsDCDC1DCConverterT1PINTInterruptInvalidation(132), + BmsDCDC1DCConverterSoftwareANDHardwareProtectionCircuitInvalidation(129), BmsDCDC1DCConverterPowerCircuitInvalidation(130), BmsDCDC1DCConverterCPUInvalidation(131), BmsDCDC1DCConverterTINT0InterruptInvalidation(132), BmsDCDC1DCConverterADCInterruptInvalidation(133), BmsDCDC1DCConverterCAPITN4InterruptInvalidation(134), BmsDCDC1DCConverterCAPINT6InterruptInvalidation(135), BmsDCDC1DCConverterT3PINTinterruptInvalidation(136), BmsDCDC1DCConverterT4PINTinterruptInvalidation(137), BmsDCDC1DCConverterPDPINTAInterruptInvalidation(138), BmsDCDC1DCConverterT1PINTInterruptInvalidationSecond(139), BmsDCDC1DCConverterRESVInterruptInvalidation(140), BmsDCDC1DCConverter100usTaskInvalidation(141), BmsDCDC1DCConverterClockInvalidation(142), BmsDCDC1DCConverterEMSMemoryInvalidation(143), BmsDCDC1DCConverterExteriorCommunicationInvalidation(144), BmsDCDC1DCConverterIOInterfaceInvalidation(145), @@ -47,12 +47,12 @@ public enum FaultCharger implements FaultEnum{ PvDCDCDCConvertorGeneralOverload(193), PvDCDCDCShortCircuit(194), PvDCDCPeakPulseCurrentProtection(195), PvDCDCDCDisconnectAbnormallyOnHighVoltageSideOfDCConvetor(196), PvDCDCEffectivePulseValueOverhigh(197), PvDCDCDCConverteSevereOverload(198), PvDCDCDCBreakerDisconnectAbnormallyOnHighVoltageSideOfDCConvetor(199), PvDCDCDCBreakerDisconnectAbnormallyOnLowVoltageSideOfDCConvetor(200), PvDCDCDCConvetorPrechargeContactorCloseFailed(201), PvDCDCDCConvetorMainContactorCloseFailed(202), PvDCDCACContactorStateAbnormityOfDCConvetor(203), PvDCDCDCConvetorEmergencyStop(204), PvDCDCDCConverterChargingGunDisconnected(205), PvDCDCDCCurrentAbnormityBeforeDCConvetorWork(206), PvDCDCFuSeDisconnected(207), PvDCDCDCConverterHardwareCurrentOrVoltageFault(208), - PvDCConverterCrystalOscillatorCircuitInvalidation(209), PvDCConverterResetCircuitInvalidation(210), PvDCConverterSamplingCircuitInvalidation(211), PvDCConverterDigitalIOCircuitInvalidation(212), PvDCConverterPWMCircuitInvalidation(213), - PvDCConverterX5045CircuitInvalidation(214), PvDCConverterCANCircuitInvalidation(215), PvDCConverterSoftwareANDHardwareProtectionCircuitInvalidation(216), PvDCConverterPowerCircuitInvalidation(217), PvDCConverterCPUInvalidation(218), - PvDCConverterT1PINTInterruptInvalidation(219), PvDCConverterADCInterruptInvalidation(220), PvDCConverterCAPITN4InterruptInvalidation(221), PvDCConverterCAPINT6InterruptInvalidation(222), PvDCConverterT3PINTinterruptInvalidation(223), - PvDCConverterT4PINTinterruptInvalidation(224), PvDCConverterPDPINTAInterruptInvalidation(225), BvDCConverterT1PINTInterruptInvalidationSecond(226), PvDCConverterRESVInterruptInvalidation(227), PvDCConverter100usTaskInvalidation(228), - PvDCConverterClockInvalidation(229), PvDCConverterEMSMemoryInvalidation(230), PvDCConverterExteriorCommunicationInvalidation(231), PvDCConverterIOInterfaceInvalidation(232), PvDCConverterInputVoltageBoundFault(233), - PvDCConverterOutterVoltageBoundFault(234), PvDCConverterOutputVoltageBoundFault(235), PvDCConverterInductCurrentBoundFault(236), PvDCConverterInputCurrentBoundFault(237), PvDCConverterOutputCurrentBoundFault(238), PvDCDCDCReactorOverTemperature(239), + PvDCDCDCConverterCrystalOscillatorCircuitInvalidation(209), PvDCDCDCConverterResetCircuitInvalidation(210), PvDCDCDCConverterSamplingCircuitInvalidation(211), PvDCDCDCConverterDigitalIOCircuitInvalidation(212), PvDCDCDCConverterPWMCircuitInvalidation(213), + PvDCDCDCConverterX5045CircuitInvalidation(214), PvDCDCDCConverterCANCircuitInvalidation(215), PvDCDCDCConverterSoftwareANDHardwareProtectionCircuitInvalidation(216), PvDCDCDCConverterPowerCircuitInvalidation(217), PvDCDCDCConverterCPUInvalidation(218), + PvDCDCDCConverterTINT0InterruptInvalidation(219), PvDCDCDCConverterADCInterruptInvalidation(220), PvDCDCDCConverterCAPITN4InterruptInvalidation(221), PvDCDCDCConverterCAPINT6InterruptInvalidation(222), PvDCDCDCConverterT3PINTinterruptInvalidation(223), + PvDCDCDCConverterT4PINTinterruptInvalidation(224), PvDCDCConverterPDPINTAInterruptInvalidation(225), PvDCDCConverterT1PINTInterruptInvalidationSecond(226), PvDCDCConverterRESVInterruptInvalidation(227), PvDCDCConverter100usTaskInvalidation(228), + PvDCDCConverterClockInvalidation(229), PvDCDCConverterEMSMemoryInvalidation(230), PvDCDCConverterExteriorCommunicationInvalidation(231), PvDCDCConverterIOInterfaceInvalidation(232), PvDCDCConverterInputVoltageBoundFault(233), + PvDCDCConverterOutterVoltageBoundFault(234), PvDCDCConverterOutputVoltageBoundFault(235), PvDCDCConverterInductCurrentBoundFault(236), PvDCDCConverterInputCurrentBoundFault(237), PvDCDCConverterOutputCurrentBoundFault(238), PvDCDCDCReactorOverTemperature(239), PvDCDCDCIGBTOverTemperature(240), PvDCDCDCConverterChanel3OverTemperature(241), PvDCDCDCConverterChanel4OverTemperature(242), PvDCDCDCConverterChanel5OverTemperature(243), PvDCDCDCConverterChanel6OverTemperature(244), PvDCDCDCConverterChanel7OverTemperature(245), PvDCDCDCConverterChanel8OverTemperature(246), PvDCDCDCReactorTemperatureSamplingInvalidation(247), PvDCDCDCIGBTTemperatureSamplingInvalidation(248), PvDCDCDCConverterChanel3TemperatureSamplingInvalidation(249), PvDCDCDCConverterChanel4TemperatureSamplingInvalidation(250), PvDCDCDCConverterChanel5TemperatureSamplingInvalidation(251), PvDCDCDCConverterChanel6TemperatureSamplingInvalidation(252), PvDCDCDCConverterChanel7TemperatureSamplingInvalidation(253), @@ -65,7 +65,7 @@ public enum FaultCharger implements FaultEnum{ PvDCDC1DCBreakerDisconnectAbnormallyOnLowVoltageSideOfDCConvetor(287), PvDCDC1DCConvetorPrechargeContactorCloseFailed(288), PvDCDC1DCConvetorMainContactorCloseFailed(289), PvDCDC1ACContactorStateAbnormityOfDCConvetor(290), PvDCDC1DCConvetorEmergencyStop(291), PvDCDC1DCConverterChargingGunDisconnected(292), PvDCDC1DCCurrentAbnormityBeforeDCConvetorWork(293), PvDCDC1FuSeDisconnected(294), PvDCDC1DCConverterHardwareCurrentOrVoltageFault(295), PvDCDC1DCConverterCrystalOscillatorCircuitInvalidation(296), PvDCDC1DCConverterResetCircuitInvalidation(297), PvDCDC1DCConverterSamplingCircuitInvalidation(298), PvDCDC1DCConverterDigitalIOCircuitInvalidation(299), PvDCDC1DCConverterPWMCircuitInvalidation(300), PvDCDC1DCConverterX5045CircuitInvalidation(301), PvDCDC1DCConverterCANCircuitInvalidation(302), - PvDCDC1DCConverterSoftwareANDHardwareProtectionCircuitInvalidation(303), PvDCDC1DCConverterPowerCircuitInvalidation(304), PvDCDC1DCConverterCPUInvalidation(305), PvDCDC1DCConverterT1PINTInterruptInvalidation(306), PvDCDC1DCConverterADCInterruptInvalidation(307), + PvDCDC1DCConverterSoftwareANDHardwareProtectionCircuitInvalidation(303), PvDCDC1DCConverterPowerCircuitInvalidation(304), PvDCDC1DCConverterCPUInvalidation(305), PvDCDC1DCConverterTINT0InterruptInvalidation(306), PvDCDC1DCConverterADCInterruptInvalidation(307), PvDCDC1DCConverterCAPITN4InterruptInvalidation(308), PvDCDC1DCConverterCAPINT6InterruptInvalidation(309), PvDCDC1DCConverterT3PINTinterruptInvalidation(310), PvDCDC1DCConverterT4PINTinterruptInvalidation(311), PvDCDC1DCConverterPDPINTAInterruptInvalidation(312), PvDCDC1DCConverterT1PINTInterruptInvalidationSecond(313), PvDCDC1DCConverterRESVInterruptInvalidation(314), PvDCDC1DCConverter100usTaskInvalidation(315), PvDCDC1DCConverterClockInvalidation(316), PvDCDC1DCConverterEMSMemoryInvalidation(317), PvDCDC1DCConverterExteriorCommunicationInvalidation(318), PvDCDC1DCConverterIOInterfaceInvalidation(319), PvDCDC1DCConverterInputVoltageBoundFault(320), PvDCDC1DCConverterOutterVoltageBoundFault(321), PvDCDC1DCConverterOutputVoltageBoundFault(322), From eedc9657af9f3f43dcafae71b0f08130e169a5cb Mon Sep 17 00:00:00 2001 From: Hueseyin Sahutoglu Date: Mon, 5 Feb 2018 14:48:24 +0100 Subject: [PATCH 44/55] Correct mistakes --- .../commercial/FeneconCommercialCharger.java | 69 +++++++++---------- 1 file changed, 33 insertions(+), 36 deletions(-) diff --git a/edge/src/io/openems/impl/device/commercial/FeneconCommercialCharger.java b/edge/src/io/openems/impl/device/commercial/FeneconCommercialCharger.java index 5a5413d1cf9..08e0e87f2c5 100644 --- a/edge/src/io/openems/impl/device/commercial/FeneconCommercialCharger.java +++ b/edge/src/io/openems/impl/device/commercial/FeneconCommercialCharger.java @@ -25,7 +25,6 @@ import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; import io.openems.api.channel.StatusBitChannel; -import io.openems.api.channel.StatusBitChannels; import io.openems.api.channel.WriteChannel; import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.Device; @@ -65,8 +64,6 @@ public FeneconCommercialCharger(String thingId, Device parent) throws ConfigExce */ private ThingStateChannel thingState; - public StatusBitChannels warning; - public ModbusWriteChannel pvPowerLimitCommand; public ReadChannel actualPower; @@ -363,7 +360,7 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { .faultBit(7, FaultCharger.DCConverterSoftwareANDHardwareProtectionCircuitInvalidation)// .faultBit(8, FaultCharger.DCConverterPowerCircuitInvalidation)// .faultBit(9, FaultCharger.DCConverterCPUInvalidation)// - .faultBit(10,FaultCharger.DCConverterT1PINTInterruptInvalidation)// + .faultBit(10,FaultCharger.DCConverterTINT0InterruptInvalidation)// .faultBit(11,FaultCharger.DCConverterADCInterruptInvalidation)// .faultBit(12,FaultCharger.DCConverterCAPITN4InterruptInvalidation)// .faultBit(13,FaultCharger.DCConverterCAPINT6InterruptInvalidation)// @@ -626,7 +623,7 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { .faultBit(7, FaultCharger.BmsDCDC1DCConverterSoftwareANDHardwareProtectionCircuitInvalidation)// .faultBit(8, FaultCharger.BmsDCDC1DCConverterPowerCircuitInvalidation)// .faultBit(9, FaultCharger.BmsDCDC1DCConverterCPUInvalidation)// - .faultBit(10,FaultCharger.BmsDCDC1DCConverterT1PINTInterruptInvalidation)// + .faultBit(10,FaultCharger.BmsDCDC1DCConverterTINT0InterruptInvalidation)// .faultBit(11,FaultCharger.BmsDCDC1DCConverterADCInterruptInvalidation)// .faultBit(12,FaultCharger.BmsDCDC1DCConverterCAPITN4InterruptInvalidation)// .faultBit(13,FaultCharger.BmsDCDC1DCConverterCAPINT6InterruptInvalidation)// @@ -879,41 +876,41 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { new UnsignedWordElement(0xA713,// // prefix = "PvDCDC" new ModbusBitWrappingChannel("PvDCDCAbnormity4", this, this.thingState)// - .faultBit(0, FaultCharger.PvDCConverterCrystalOscillatorCircuitInvalidation)// - .faultBit(1, FaultCharger.PvDCConverterResetCircuitInvalidation)// - .faultBit(2, FaultCharger.PvDCConverterSamplingCircuitInvalidation)// - .faultBit(3, FaultCharger.PvDCConverterDigitalIOCircuitInvalidation)// - .faultBit(4, FaultCharger.PvDCConverterPWMCircuitInvalidation)// - .faultBit(5, FaultCharger.PvDCConverterX5045CircuitInvalidation)// - .faultBit(6, FaultCharger.PvDCConverterCANCircuitInvalidation)// - .faultBit(7, FaultCharger.PvDCConverterSoftwareANDHardwareProtectionCircuitInvalidation)// - .faultBit(8, FaultCharger.PvDCConverterPowerCircuitInvalidation)// - .faultBit(9, FaultCharger.PvDCConverterCPUInvalidation)// - .faultBit(10,FaultCharger.PvDCConverterT1PINTInterruptInvalidation)// - .faultBit(11,FaultCharger.PvDCConverterADCInterruptInvalidation)// - .faultBit(12,FaultCharger.PvDCConverterCAPITN4InterruptInvalidation)// - .faultBit(13,FaultCharger.PvDCConverterCAPINT6InterruptInvalidation)// - .faultBit(14,FaultCharger.PvDCConverterT3PINTinterruptInvalidation)// - .faultBit(15,FaultCharger.PvDCConverterT4PINTinterruptInvalidation)// + .faultBit(0, FaultCharger.PvDCDCDCConverterCrystalOscillatorCircuitInvalidation)// + .faultBit(1, FaultCharger.PvDCDCDCConverterResetCircuitInvalidation)// + .faultBit(2, FaultCharger.PvDCDCDCConverterSamplingCircuitInvalidation)// + .faultBit(3, FaultCharger.PvDCDCDCConverterDigitalIOCircuitInvalidation)// + .faultBit(4, FaultCharger.PvDCDCDCConverterPWMCircuitInvalidation)// + .faultBit(5, FaultCharger.PvDCDCDCConverterX5045CircuitInvalidation)// + .faultBit(6, FaultCharger.PvDCDCDCConverterCANCircuitInvalidation)// + .faultBit(7, FaultCharger.PvDCDCDCConverterSoftwareANDHardwareProtectionCircuitInvalidation)// + .faultBit(8, FaultCharger.PvDCDCDCConverterPowerCircuitInvalidation)// + .faultBit(9, FaultCharger.PvDCDCDCConverterCPUInvalidation)// + .faultBit(10,FaultCharger.PvDCDCDCConverterTINT0InterruptInvalidation)// + .faultBit(11,FaultCharger.PvDCDCDCConverterADCInterruptInvalidation)// + .faultBit(12,FaultCharger.PvDCDCDCConverterCAPITN4InterruptInvalidation)// + .faultBit(13,FaultCharger.PvDCDCDCConverterCAPINT6InterruptInvalidation)// + .faultBit(14,FaultCharger.PvDCDCDCConverterT3PINTinterruptInvalidation)// + .faultBit(15,FaultCharger.PvDCDCDCConverterT4PINTinterruptInvalidation)// ),// new UnsignedWordElement(0xA714, // prefix = "PvDCDC" new ModbusBitWrappingChannel("PvDCDCAbnormity5", this, this.thingState)// - .faultBit(0, FaultCharger.PvDCConverterPDPINTAInterruptInvalidation)// - .faultBit(1, FaultCharger.BvDCConverterT1PINTInterruptInvalidationSecond)// - .faultBit(2, FaultCharger.PvDCConverterRESVInterruptInvalidation)// - .faultBit(3, FaultCharger.PvDCConverter100usTaskInvalidation)// - .faultBit(4, FaultCharger.PvDCConverterClockInvalidation)// - .faultBit(5, FaultCharger.PvDCConverterEMSMemoryInvalidation)// - .faultBit(6, FaultCharger.PvDCConverterExteriorCommunicationInvalidation)// - .faultBit(7, FaultCharger.PvDCConverterIOInterfaceInvalidation)// - .faultBit(8, FaultCharger.PvDCConverterInputVoltageBoundFault)// - .faultBit(9, FaultCharger.PvDCConverterOutterVoltageBoundFault)// - .faultBit(10,FaultCharger.PvDCConverterOutputVoltageBoundFault)// - .faultBit(11,FaultCharger.PvDCConverterInductCurrentBoundFault)// - .faultBit(12,FaultCharger.PvDCConverterInputCurrentBoundFault)// - .faultBit(13,FaultCharger.PvDCConverterOutputCurrentBoundFault)// + .faultBit(0, FaultCharger.PvDCDCConverterPDPINTAInterruptInvalidation)// + .faultBit(1, FaultCharger.PvDCDCConverterT1PINTInterruptInvalidationSecond)// + .faultBit(2, FaultCharger.PvDCDCConverterRESVInterruptInvalidation)// + .faultBit(3, FaultCharger.PvDCDCConverter100usTaskInvalidation)// + .faultBit(4, FaultCharger.PvDCDCConverterClockInvalidation)// + .faultBit(5, FaultCharger.PvDCDCConverterEMSMemoryInvalidation)// + .faultBit(6, FaultCharger.PvDCDCConverterExteriorCommunicationInvalidation)// + .faultBit(7, FaultCharger.PvDCDCConverterIOInterfaceInvalidation)// + .faultBit(8, FaultCharger.PvDCDCConverterInputVoltageBoundFault)// + .faultBit(9, FaultCharger.PvDCDCConverterOutterVoltageBoundFault)// + .faultBit(10,FaultCharger.PvDCDCConverterOutputVoltageBoundFault)// + .faultBit(11,FaultCharger.PvDCDCConverterInductCurrentBoundFault)// + .faultBit(12,FaultCharger.PvDCDCConverterInputCurrentBoundFault)// + .faultBit(13,FaultCharger.PvDCDCConverterOutputCurrentBoundFault)// ),// new UnsignedWordElement(0xA715,// @@ -1154,7 +1151,7 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { .faultBit(7, FaultCharger.PvDCDC1DCConverterSoftwareANDHardwareProtectionCircuitInvalidation)// .faultBit(8, FaultCharger.PvDCDC1DCConverterPowerCircuitInvalidation)// .faultBit(9, FaultCharger.PvDCDC1DCConverterCPUInvalidation)// - .faultBit(10,FaultCharger.PvDCDC1DCConverterT1PINTInterruptInvalidation)// + .faultBit(10,FaultCharger.PvDCDC1DCConverterTINT0InterruptInvalidation)// .faultBit(11,FaultCharger.PvDCDC1DCConverterADCInterruptInvalidation)// .faultBit(12,FaultCharger.PvDCDC1DCConverterCAPITN4InterruptInvalidation)// .faultBit(13,FaultCharger.PvDCDC1DCConverterCAPINT6InterruptInvalidation)// From f78d97704771610c1c530d76f29ab6244d195c46 Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Tue, 6 Feb 2018 17:28:38 +0100 Subject: [PATCH 45/55] Add stateChannel dummy to AsymmetricSymmetricCombinationEss --- .../AsymmetricSymmetricCombinationEss.java | 8 -------- .../AsymmetricSymmetricCombinationEssNature.java | 5 +++-- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/edge/src/io/openems/impl/device/system/asymmetricsymmetriccombinationess/AsymmetricSymmetricCombinationEss.java b/edge/src/io/openems/impl/device/system/asymmetricsymmetriccombinationess/AsymmetricSymmetricCombinationEss.java index 9a56a5d709e..1ce4f9d9560 100644 --- a/edge/src/io/openems/impl/device/system/asymmetricsymmetriccombinationess/AsymmetricSymmetricCombinationEss.java +++ b/edge/src/io/openems/impl/device/system/asymmetricsymmetriccombinationess/AsymmetricSymmetricCombinationEss.java @@ -5,7 +5,6 @@ import io.openems.api.bridge.Bridge; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; import io.openems.api.device.nature.DeviceNature; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; @@ -31,11 +30,4 @@ protected Set getDeviceNatures() { } return natures; } - - @Override - public ThingStateChannel getStateChannel() { - // TODO Auto-generated method stub - return null; - } - } diff --git a/edge/src/io/openems/impl/device/system/asymmetricsymmetriccombinationess/AsymmetricSymmetricCombinationEssNature.java b/edge/src/io/openems/impl/device/system/asymmetricsymmetriccombinationess/AsymmetricSymmetricCombinationEssNature.java index 9fe2ba1feb8..8547efc1151 100644 --- a/edge/src/io/openems/impl/device/system/asymmetricsymmetriccombinationess/AsymmetricSymmetricCombinationEssNature.java +++ b/edge/src/io/openems/impl/device/system/asymmetricsymmetriccombinationess/AsymmetricSymmetricCombinationEssNature.java @@ -47,6 +47,8 @@ public class AsymmetricSymmetricCombinationEssNature extends SystemDeviceNature private ThingRepository repo; private List listeners; + private ThingStateChannel state = new ThingStateChannel(this); + private ProxyReadChannel gridMode = new ProxyReadChannel<>("GridMode", this); private ProxyReadChannel soc = new ProxyReadChannel<>("Soc", this); private ProxyReadChannel allowedCharge = new ProxyReadChannel("AllowedCharge", this); @@ -1479,8 +1481,7 @@ public void onBridgeInitialized() { @Override public ThingStateChannel getStateChannel() { - // TODO Auto-generated method stub - return null; + return this.state; } } From 20f7c17ce9b81a57955b5a253e8535ff658afde5 Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Thu, 15 Feb 2018 10:41:24 +0100 Subject: [PATCH 46/55] Rename ThingStateChannel to ThingStateChannels --- edge/src/io/openems/api/bridge/Bridge.java | 8 ++++---- ...StateChannel.java => ThingStateChannels.java} | 16 ++++++++-------- edge/src/io/openems/api/device/Device.java | 8 ++++---- edge/src/io/openems/api/thing/Thing.java | 8 ++++---- .../impl/controller/acisland/AcIsland.java | 6 +++--- .../api/modbustcp/ModbusTcpApiController.java | 6 +++--- .../controller/api/rest/RestApiController.java | 6 +++--- .../api/websocket/WebsocketApiController.java | 6 +++--- .../AvoidTotalChargeController.java | 6 +++--- .../AvoidTotalDischargeController.java | 6 +++--- .../balancing/BalancingController.java | 6 +++--- .../BalancingBandgapActivePowerController.java | 6 +++--- .../BalancingBandgapReactivePowerController.java | 6 +++--- .../BalancingCurrentController.java | 6 +++--- .../capacitytest/CapacityTestController.java | 6 +++--- .../fixvalue/FixValueActivePowerController.java | 6 +++--- .../FixValueReactivePowerController.java | 6 +++--- .../PhaseRectificationActivePowerController.java | 6 +++--- ...haseRectificationReactivePowerController.java | 6 +++--- .../PowerLimitationController.java | 6 +++--- ...AsymmetricSymmetricCombinationController.java | 6 +++--- .../ChannelThresholdController.java | 6 +++--- .../ChargeLimitationController.java | 6 +++--- .../clocksync/ClockSyncController.java | 6 +++--- .../controller/debuglog/DebugLogController.java | 6 +++--- .../EmergencyGeneratorController.java | 6 +++--- .../impl/controller/evcs/EvcsController.java | 6 +++--- .../FeneconProSetupController.java | 6 +++--- .../OffGridIndicationController.java | 6 +++--- .../OnGridIndicationController.java | 6 +++--- .../controller/riedmann/RiedmannController.java | 6 +++--- .../riedmann/SystemStopController.java | 6 +++--- .../SupplyBusSwitchController.java | 6 +++--- .../AvoidTotalChargeController.java | 6 +++--- .../AvoidTotalDischargeController.java | 6 +++--- ...AvoidTotalDischargeSocTimeLineController.java | 6 +++--- .../symmetric/balancing/BalancingController.java | 6 +++--- .../BalancingBandgapController.java | 6 +++--- .../BalancingCosPhiController.java | 6 +++--- .../BalancingCurrentController.java | 6 +++--- .../BalancingOffsetController.java | 6 +++--- .../BalancingSurplusController.java | 6 +++--- .../capacitytest/CapacityTestController.java | 6 +++--- .../EnergysavingController.java | 6 +++--- .../commercialworkstate/AlwaysOnController.java | 6 +++--- .../symmetric/cosphi/CosPhiController.java | 6 +++--- .../CosPhiCharacteristicController.java | 6 +++--- .../symmetric/fixvalue/FixValueController.java | 6 +++--- .../OffGridPowerStationController.java | 6 +++--- .../PowerByFrequencyController.java | 6 +++--- .../PowerLimitationController.java | 6 +++--- .../symmetric/powerramp/PowerRampController.java | 6 +++--- .../AvoidTotalDischargeController.java | 6 +++--- .../refuworkstate/WorkStateController.java | 6 +++--- .../timelinecharge/TimelineChargeController.java | 6 +++--- .../VoltageCharacteristicController.java | 6 +++--- .../testwrite/TestWriteController.java | 6 +++--- .../ThermalPowerStationController.java | 6 +++--- .../impl/device/bcontrol/BControlMeter.java | 8 ++++---- .../openems/impl/device/byd/Bem125ktla01Ess.java | 6 +++--- .../carlogavazzi/em300series/EM300Meter.java | 8 ++++---- .../commercial/FeneconCommercialCharger.java | 8 ++++---- .../device/commercial/FeneconCommercialEss.java | 8 ++++---- .../custom/riedmann/RiedmannNatureImpl.java | 8 ++++---- .../device/janitza/JanitzaUMG96RMEMeter.java | 8 ++++---- .../io/openems/impl/device/keba/KebaEvcs.java | 8 ++++---- .../device/kmtronic/KMTronicRelayOutput.java | 8 ++++---- .../device/kmtronic/KMTronicRelayOutputRev1.java | 8 ++++---- .../openems/impl/device/mini/FeneconMiniEss.java | 8 ++++---- .../FeneconMiniConsumptionMeter.java | 8 ++++---- .../impl/device/minireadonly/FeneconMiniEss.java | 8 ++++---- .../minireadonly/FeneconMiniGridMeter.java | 8 ++++---- .../minireadonly/FeneconMiniProductionMeter.java | 8 ++++---- .../impl/device/pqplus/PqPlusUMD97Meter.java | 8 ++++---- .../openems/impl/device/pro/FeneconProEss.java | 6 +++--- .../impl/device/pro/FeneconProPvMeter.java | 8 ++++---- .../src/io/openems/impl/device/refu/RefuEss.java | 8 ++++---- .../device/simulator/SimulatorAsymmetricEss.java | 8 ++++---- .../impl/device/simulator/SimulatorCharger.java | 8 ++++---- .../device/simulator/SimulatorGridMeter.java | 8 ++++---- .../impl/device/simulator/SimulatorOutput.java | 8 ++++---- .../simulator/SimulatorProductionMeter.java | 8 ++++---- .../simulator/SimulatorRiedmannNature.java | 8 ++++---- .../device/simulator/SimulatorSymmetricEss.java | 8 ++++---- .../openems/impl/device/sma/SunnyIsland6Ess.java | 8 ++++---- .../impl/device/socomec/SocomecB30Meter.java | 8 ++++---- .../impl/device/socomec/SocomecMeter.java | 8 ++++---- .../device/socomec/SocomecSinglePhaseMeter.java | 8 ++++---- .../openems/impl/device/spanner/BHKWMeter.java | 8 ++++---- .../impl/device/studer/StuderVs70Charger.java | 8 ++++---- .../openems/impl/device/system/SystemNature.java | 8 ++++---- .../AsymmetricSymmetricCombinationEssNature.java | 6 +++--- .../system/esscluster/EssClusterNature.java | 8 ++++---- .../system/metercluster/MeterClusterNature.java | 8 ++++---- .../io/openems/impl/device/wago/WagoFBInput.java | 8 ++++---- .../openems/impl/device/wago/WagoFBOutput.java | 8 ++++---- .../persistence/fenecon/FeneconPersistence.java | 8 ++++---- .../influxdb/InfluxdbPersistence.java | 8 ++++---- .../modbus/ModbusBitWrappingChannel.java | 6 +++--- .../openems/impl/scheduler/SimpleScheduler.java | 8 ++++---- .../ChannelThresholdScheduler.java | 8 ++++---- .../impl/scheduler/time/WeekTimeScheduler.java | 8 ++++---- .../test/controller/ThermalPowerStationTest.java | 4 ++-- .../test/utils/channel/UnitTestReadChannel.java | 4 ++-- .../test/utils/channel/UnitTestWriteChannel.java | 4 ++-- .../UnitTestAsymmetricEssNature.java | 4 ++-- .../UnitTestAsymmetricMeterNature.java | 4 ++-- .../UnitTestSymmetricEssNature.java | 4 ++-- .../UnitTestSymmetricMeterNature.java | 4 ++-- 109 files changed, 368 insertions(+), 368 deletions(-) rename edge/src/io/openems/api/channel/thingstate/{ThingStateChannel.java => ThingStateChannels.java} (88%) diff --git a/edge/src/io/openems/api/bridge/Bridge.java b/edge/src/io/openems/api/bridge/Bridge.java index d7a9866442d..1aa668e0009 100644 --- a/edge/src/io/openems/api/bridge/Bridge.java +++ b/edge/src/io/openems/api/bridge/Bridge.java @@ -32,7 +32,7 @@ import io.openems.api.bridge.BridgeEvent.Position; import io.openems.api.channel.DebugChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.scheduler.Scheduler; import io.openems.api.thing.Thing; @@ -56,7 +56,7 @@ public abstract class Bridge extends Thread implements Thing { private DebugChannel requiredCycleTime = new DebugChannel<>("RequiredCycleTime", this); private List eventListener = new ArrayList<>(); private DebugChannel readOtherTaskReadCount = new DebugChannel<>("ReadOtherTaskReadCount", this); - protected ThingStateChannel thingState; + protected ThingStateChannels thingState; /** * Initialize the Thread with a name @@ -66,7 +66,7 @@ public abstract class Bridge extends Thread implements Thing { public Bridge() { log = LoggerFactory.getLogger(this.getClass()); setName(THINGID_PREFIX + instanceCounter++); - thingState = new ThingStateChannel(this); + thingState = new ThingStateChannels(this); } @Override @@ -131,7 +131,7 @@ public synchronized List getDevices() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/api/channel/thingstate/ThingStateChannel.java b/edge/src/io/openems/api/channel/thingstate/ThingStateChannels.java similarity index 88% rename from edge/src/io/openems/api/channel/thingstate/ThingStateChannel.java rename to edge/src/io/openems/api/channel/thingstate/ThingStateChannels.java index 7d9357be1a8..ad0ebc9bcc8 100644 --- a/edge/src/io/openems/api/channel/thingstate/ThingStateChannel.java +++ b/edge/src/io/openems/api/channel/thingstate/ThingStateChannels.java @@ -12,14 +12,14 @@ import io.openems.api.exception.ConfigException; import io.openems.api.thing.Thing; -public class ThingStateChannel extends ReadChannel implements ChannelChangeListener { +public class ThingStateChannels extends ReadChannel implements ChannelChangeListener { private List> warningChannels; private List> faultChannels; - private List childChannels; + private List childChannels; private Set channelNames; - public ThingStateChannel(Thing parent){ + public ThingStateChannels(Thing parent){ super("State", parent); this.warningChannels = new ArrayList<>(); this.faultChannels = new ArrayList<>(); @@ -67,7 +67,7 @@ public void removeFaultChannel(ReadChannel channel) { public List> getWarningChannels() { List> warningChannels = new ArrayList<>(); warningChannels.addAll(this.warningChannels); - for(ThingStateChannel child : this.childChannels) { + for(ThingStateChannels child : this.childChannels) { warningChannels.addAll(child.getWarningChannels()); } return warningChannels; @@ -76,19 +76,19 @@ public List> getWarningChannels() { public List> getFaultChannels() { List> faultChannels = new ArrayList<>(); faultChannels.addAll(this.faultChannels); - for(ThingStateChannel child : this.childChannels) { + for(ThingStateChannels child : this.childChannels) { faultChannels.addAll(child.getFaultChannels()); } return this.faultChannels; } - public void addChildChannel(ThingStateChannel child) { + public void addChildChannel(ThingStateChannels child) { this.childChannels.add(child); child.addChangeListener(this); updateState(); } - public void removeChildChannel(ThingStateChannel child) { + public void removeChildChannel(ThingStateChannels child) { child.removeChangeListener(this); this.childChannels.add(child); updateState(); @@ -100,7 +100,7 @@ public void channelChanged(Channel channel, Optional newValue, Optional ol } private void updateState() { - for(ThingStateChannel child : this.childChannels) { + for(ThingStateChannels child : this.childChannels) { if(child.isValuePresent()) { switch(child.getValue()) { case FAULT: diff --git a/edge/src/io/openems/api/device/Device.java b/edge/src/io/openems/api/device/Device.java index d5e7b551464..55a586d2ed6 100644 --- a/edge/src/io/openems/api/device/Device.java +++ b/edge/src/io/openems/api/device/Device.java @@ -33,7 +33,7 @@ import io.openems.api.bridge.BridgeWriteTask; import io.openems.api.channel.Channel; import io.openems.api.channel.ChannelChangeListener; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.nature.DeviceNature; import io.openems.api.exception.OpenemsException; import io.openems.api.thing.Thing; @@ -44,13 +44,13 @@ public abstract class Device implements Thing, ChannelChangeListener { protected final Logger log; private Bridge bridge = null; private final String thingId; - private ThingStateChannel thingState; + private ThingStateChannels thingState; public Device(Bridge parent) throws OpenemsException { this.thingId = THINGID_PREFIX + instanceCounter++; log = LoggerFactory.getLogger(this.getClass()); this.bridge = parent; - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); this.thingState.addChildChannel(this.bridge.getStateChannel()); } @@ -121,7 +121,7 @@ public void channelChanged(Channel channel, Optional newValue, Optional ol } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } diff --git a/edge/src/io/openems/api/thing/Thing.java b/edge/src/io/openems/api/thing/Thing.java index aa07b6d6f0a..8e06b542e9e 100644 --- a/edge/src/io/openems/api/thing/Thing.java +++ b/edge/src/io/openems/api/thing/Thing.java @@ -22,7 +22,7 @@ import io.openems.api.channel.ReadChannel; import io.openems.api.channel.thingstate.ThingState; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.doc.ChannelInfo; public interface Thing { @@ -46,17 +46,17 @@ public default void init() { } @ChannelInfo(type = ThingState.class) - public ThingStateChannel getStateChannel(); + public ThingStateChannels getStateChannel(); @SuppressWarnings("unchecked") public default ReadChannel[] getFaultChannels(){ - ThingStateChannel stateChannel = getStateChannel(); + ThingStateChannels stateChannel = getStateChannel(); return stateChannel.getFaultChannels().toArray(new ReadChannel[stateChannel.getFaultChannels().size()]); } @SuppressWarnings("unchecked") public default ReadChannel[] getWarningChannels(){ - ThingStateChannel stateChannel = getStateChannel(); + ThingStateChannels stateChannel = getStateChannel(); return stateChannel.getWarningChannels().toArray(new ReadChannel[stateChannel.getWarningChannels().size()]); } diff --git a/edge/src/io/openems/impl/controller/acisland/AcIsland.java b/edge/src/io/openems/impl/controller/acisland/AcIsland.java index a45b04fa08f..3031cbcc9e9 100644 --- a/edge/src/io/openems/impl/controller/acisland/AcIsland.java +++ b/edge/src/io/openems/impl/controller/acisland/AcIsland.java @@ -25,7 +25,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.WriteChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -44,7 +44,7 @@ public class AcIsland extends Controller { private State currentState = State.UNKNOWN; private boolean isProducerDisconnected = false; private long timeProducerDisconnected; - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); private enum State { OFFGRID, ONGRID, SWITCHTOOFFGRID, SWITCHTOONGRID, UNKNOWN @@ -293,7 +293,7 @@ private void switchOutput(WriteChannel outputChannel, boolean on,boolea } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } diff --git a/edge/src/io/openems/impl/controller/api/modbustcp/ModbusTcpApiController.java b/edge/src/io/openems/impl/controller/api/modbustcp/ModbusTcpApiController.java index 4178b5ce19f..ea95d47f140 100644 --- a/edge/src/io/openems/impl/controller/api/modbustcp/ModbusTcpApiController.java +++ b/edge/src/io/openems/impl/controller/api/modbustcp/ModbusTcpApiController.java @@ -11,7 +11,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.controller.Controller; import io.openems.api.doc.ChannelDoc; import io.openems.api.doc.ChannelInfo; @@ -31,7 +31,7 @@ public class ModbusTcpApiController extends Controller { private Optional slaveOpt = Optional.empty(); private final ApiWorker apiWorker = new ApiWorker(); private final MyProcessImage processImage = new MyProcessImage(UNIT_ID, apiWorker); - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors @@ -141,7 +141,7 @@ protected void updateChannelMapping(Optional jMappingOpt) { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } \ No newline at end of file diff --git a/edge/src/io/openems/impl/controller/api/rest/RestApiController.java b/edge/src/io/openems/impl/controller/api/rest/RestApiController.java index ea4f93f2322..8b7dfbc64b9 100644 --- a/edge/src/io/openems/impl/controller/api/rest/RestApiController.java +++ b/edge/src/io/openems/impl/controller/api/rest/RestApiController.java @@ -24,7 +24,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -35,7 +35,7 @@ public class RestApiController extends Controller { private final ApiWorker apiWorker = new ApiWorker(); - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors @@ -81,7 +81,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } diff --git a/edge/src/io/openems/impl/controller/api/websocket/WebsocketApiController.java b/edge/src/io/openems/impl/controller/api/websocket/WebsocketApiController.java index 6a5f39dad96..8cdce4dc043 100644 --- a/edge/src/io/openems/impl/controller/api/websocket/WebsocketApiController.java +++ b/edge/src/io/openems/impl/controller/api/websocket/WebsocketApiController.java @@ -26,7 +26,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ChannelChangeListener; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -36,7 +36,7 @@ public class WebsocketApiController extends Controller implements ChannelChangeListener { private final ApiWorker apiWorker = new ApiWorker(); - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors @@ -117,7 +117,7 @@ public void broadcastLog(long timestamp, String level, String source, String mes } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } diff --git a/edge/src/io/openems/impl/controller/asymmetric/avoidtotalcharge/AvoidTotalChargeController.java b/edge/src/io/openems/impl/controller/asymmetric/avoidtotalcharge/AvoidTotalChargeController.java index 49ad0f71392..992ed9f1376 100644 --- a/edge/src/io/openems/impl/controller/asymmetric/avoidtotalcharge/AvoidTotalChargeController.java +++ b/edge/src/io/openems/impl/controller/asymmetric/avoidtotalcharge/AvoidTotalChargeController.java @@ -10,7 +10,7 @@ */ import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -20,7 +20,7 @@ @ThingInfo(title = "Avoid total charge of battery. (Asymmetric)", description = "Provides control over the battery's maximum state of charge at a specific time of day. For symmetric Ess.") public class AvoidTotalChargeController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Config */ @@ -172,7 +172,7 @@ private long getAsymmetricActivePower(long symmetricTotalActivePower, long gridM } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } diff --git a/edge/src/io/openems/impl/controller/asymmetric/avoidtotaldischarge/AvoidTotalDischargeController.java b/edge/src/io/openems/impl/controller/asymmetric/avoidtotaldischarge/AvoidTotalDischargeController.java index 481145845c1..24604edb661 100644 --- a/edge/src/io/openems/impl/controller/asymmetric/avoidtotaldischarge/AvoidTotalDischargeController.java +++ b/edge/src/io/openems/impl/controller/asymmetric/avoidtotaldischarge/AvoidTotalDischargeController.java @@ -24,7 +24,7 @@ import java.util.Set; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -36,7 +36,7 @@ @ThingInfo(title = "Avoid total discharge of battery (Asymmetric)", description = "Makes sure the battery is not going into critically low state of charge. For asymmetric Ess.") public class AvoidTotalDischargeController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -173,7 +173,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/asymmetric/balancing/BalancingController.java b/edge/src/io/openems/impl/controller/asymmetric/balancing/BalancingController.java index eb8bffaba96..1aed64ee9f5 100644 --- a/edge/src/io/openems/impl/controller/asymmetric/balancing/BalancingController.java +++ b/edge/src/io/openems/impl/controller/asymmetric/balancing/BalancingController.java @@ -25,7 +25,7 @@ import java.util.Optional; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -37,7 +37,7 @@ @ThingInfo(title = "Self-consumption optimization (Asymmetric)", description = "Tries to keep the grid meter on zero. For asymmetric Ess.") public class BalancingController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -328,7 +328,7 @@ private Tupel(T a, T b) { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/asymmetric/balancingBandgap/BalancingBandgapActivePowerController.java b/edge/src/io/openems/impl/controller/asymmetric/balancingBandgap/BalancingBandgapActivePowerController.java index 69899b5fa1e..998942fe526 100644 --- a/edge/src/io/openems/impl/controller/asymmetric/balancingBandgap/BalancingBandgapActivePowerController.java +++ b/edge/src/io/openems/impl/controller/asymmetric/balancingBandgap/BalancingBandgapActivePowerController.java @@ -21,7 +21,7 @@ package io.openems.impl.controller.asymmetric.balancingBandgap; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -33,7 +33,7 @@ @ThingInfo(title = "Self-consumption optimization (Asymmetric)", description = "Tries to keep the grid meter on zero. For asymmetric Ess.") public class BalancingBandgapActivePowerController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -137,7 +137,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/asymmetric/balancingBandgap/BalancingBandgapReactivePowerController.java b/edge/src/io/openems/impl/controller/asymmetric/balancingBandgap/BalancingBandgapReactivePowerController.java index 744d1ed88cf..6525959ef78 100644 --- a/edge/src/io/openems/impl/controller/asymmetric/balancingBandgap/BalancingBandgapReactivePowerController.java +++ b/edge/src/io/openems/impl/controller/asymmetric/balancingBandgap/BalancingBandgapReactivePowerController.java @@ -21,7 +21,7 @@ package io.openems.impl.controller.asymmetric.balancingBandgap; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -33,7 +33,7 @@ @ThingInfo(title = "Self-consumption optimization (Asymmetric)", description = "Tries to keep the grid meter on zero. For asymmetric Ess.") public class BalancingBandgapReactivePowerController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -137,7 +137,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/asymmetric/balancingcurrent/BalancingCurrentController.java b/edge/src/io/openems/impl/controller/asymmetric/balancingcurrent/BalancingCurrentController.java index 49f28bb83a9..8eede4592d1 100644 --- a/edge/src/io/openems/impl/controller/asymmetric/balancingcurrent/BalancingCurrentController.java +++ b/edge/src/io/openems/impl/controller/asymmetric/balancingcurrent/BalancingCurrentController.java @@ -21,7 +21,7 @@ package io.openems.impl.controller.asymmetric.balancingcurrent; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -32,7 +32,7 @@ @ThingInfo(title = "Balancing current (Asymmetric)", description = "Tries to keep the grid meter at a given current. For asymmetric Ess.") public class BalancingCurrentController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -94,7 +94,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/asymmetric/capacitytest/CapacityTestController.java b/edge/src/io/openems/impl/controller/asymmetric/capacitytest/CapacityTestController.java index 2c2e83885c7..0e26849b896 100644 --- a/edge/src/io/openems/impl/controller/asymmetric/capacitytest/CapacityTestController.java +++ b/edge/src/io/openems/impl/controller/asymmetric/capacitytest/CapacityTestController.java @@ -30,7 +30,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ChannelUpdateListener; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -41,7 +41,7 @@ @ThingInfo(title = "Battery capacity test (Asymmetric)", description = "Executes a capacity test. For asymmetric Ess.") public class CapacityTestController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -144,7 +144,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/asymmetric/fixvalue/FixValueActivePowerController.java b/edge/src/io/openems/impl/controller/asymmetric/fixvalue/FixValueActivePowerController.java index fe3d01bdf18..12b21b6d39b 100644 --- a/edge/src/io/openems/impl/controller/asymmetric/fixvalue/FixValueActivePowerController.java +++ b/edge/src/io/openems/impl/controller/asymmetric/fixvalue/FixValueActivePowerController.java @@ -23,7 +23,7 @@ import java.util.Set; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -34,7 +34,7 @@ @ThingInfo(title = "Fixed active and reactive power (Asymmetric)", description = "Charges or discharges the battery with a predefined, fixed power. For asymmetric Ess.") public class FixValueActivePowerController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -79,7 +79,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/asymmetric/fixvalue/FixValueReactivePowerController.java b/edge/src/io/openems/impl/controller/asymmetric/fixvalue/FixValueReactivePowerController.java index 46a44970b49..86bbb185470 100644 --- a/edge/src/io/openems/impl/controller/asymmetric/fixvalue/FixValueReactivePowerController.java +++ b/edge/src/io/openems/impl/controller/asymmetric/fixvalue/FixValueReactivePowerController.java @@ -23,7 +23,7 @@ import java.util.Set; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -32,7 +32,7 @@ @ThingInfo(title = "Fixed active and reactive power (Asymmetric)", description = "Charges or discharges the battery with a predefined, fixed power. For asymmetric Ess.") public class FixValueReactivePowerController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -75,7 +75,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/asymmetric/phaserectification/PhaseRectificationActivePowerController.java b/edge/src/io/openems/impl/controller/asymmetric/phaserectification/PhaseRectificationActivePowerController.java index 9cfab63736e..5a199045a99 100644 --- a/edge/src/io/openems/impl/controller/asymmetric/phaserectification/PhaseRectificationActivePowerController.java +++ b/edge/src/io/openems/impl/controller/asymmetric/phaserectification/PhaseRectificationActivePowerController.java @@ -1,7 +1,7 @@ package io.openems.impl.controller.asymmetric.phaserectification; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -13,7 +13,7 @@ @ThingInfo(title = "PhaseRectificationActivePowerController", description = "Sets the ess to the required activepower to get all three phases on the meter to the same level.") public class PhaseRectificationActivePowerController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class) public ConfigChannel ess = new ConfigChannel("ess", this); @@ -72,7 +72,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/asymmetric/phaserectification/PhaseRectificationReactivePowerController.java b/edge/src/io/openems/impl/controller/asymmetric/phaserectification/PhaseRectificationReactivePowerController.java index 7780038dc89..d32b3d4b39c 100644 --- a/edge/src/io/openems/impl/controller/asymmetric/phaserectification/PhaseRectificationReactivePowerController.java +++ b/edge/src/io/openems/impl/controller/asymmetric/phaserectification/PhaseRectificationReactivePowerController.java @@ -1,7 +1,7 @@ package io.openems.impl.controller.asymmetric.phaserectification; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -12,7 +12,7 @@ @ThingInfo(title = "PhaseRectificationReactivePowerController", description = "Sets the ess to the required reactivepower to get all three phases on the meter to the same level.") public class PhaseRectificationReactivePowerController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class) public ConfigChannel ess = new ConfigChannel("ess", this); @@ -60,7 +60,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/asymmetric/powerlimitation/PowerLimitationController.java b/edge/src/io/openems/impl/controller/asymmetric/powerlimitation/PowerLimitationController.java index fa8642a8078..eaf55ca3b7e 100644 --- a/edge/src/io/openems/impl/controller/asymmetric/powerlimitation/PowerLimitationController.java +++ b/edge/src/io/openems/impl/controller/asymmetric/powerlimitation/PowerLimitationController.java @@ -21,7 +21,7 @@ package io.openems.impl.controller.asymmetric.powerlimitation; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -31,7 +31,7 @@ @ThingInfo(title = "Power limitation (Asymmetric)", description = "Limits the active and reactive power of the Ess. For Asymmetric Ess.") public class PowerLimitationController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -157,7 +157,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/asymmetricsymmetriccombination/AsymmetricSymmetricCombinationController.java b/edge/src/io/openems/impl/controller/asymmetricsymmetriccombination/AsymmetricSymmetricCombinationController.java index dde66a7a8b6..a5384b8ac6f 100644 --- a/edge/src/io/openems/impl/controller/asymmetricsymmetriccombination/AsymmetricSymmetricCombinationController.java +++ b/edge/src/io/openems/impl/controller/asymmetricsymmetriccombination/AsymmetricSymmetricCombinationController.java @@ -1,7 +1,7 @@ package io.openems.impl.controller.asymmetricsymmetriccombination; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -11,7 +11,7 @@ @ThingInfo(title = "starts power calculation of AsymmetricSymmetricCombination Ess device") public class AsymmetricSymmetricCombinationController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); @ChannelInfo(title = "Ess", description = "Sets the Ess devices.", type = Ess.class) public final ConfigChannel ess = new ConfigChannel("ess", this); @@ -42,7 +42,7 @@ public void run() { @Override - public ThingStateChannel getStateChannel() { + 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 014b3fd10ae..35083d0abca 100644 --- a/edge/src/io/openems/impl/controller/channelthreshold/ChannelThresholdController.java +++ b/edge/src/io/openems/impl/controller/channelthreshold/ChannelThresholdController.java @@ -26,7 +26,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; import io.openems.api.channel.WriteChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -52,7 +52,7 @@ @ThingInfo(title = "Switch channel on threshold") public class ChannelThresholdController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -176,7 +176,7 @@ private void off(boolean invertOutput) throws WriteChannelException { } @Override - public ThingStateChannel getStateChannel() { + 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 7ca578f4c50..586f0c3c5cf 100644 --- a/edge/src/io/openems/impl/controller/chargerlimitation/ChargeLimitationController.java +++ b/edge/src/io/openems/impl/controller/chargerlimitation/ChargeLimitationController.java @@ -3,7 +3,7 @@ import java.util.List; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -11,7 +11,7 @@ @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 ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -67,7 +67,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/clocksync/ClockSyncController.java b/edge/src/io/openems/impl/controller/clocksync/ClockSyncController.java index b8095d4d89a..2e605e99029 100644 --- a/edge/src/io/openems/impl/controller/clocksync/ClockSyncController.java +++ b/edge/src/io/openems/impl/controller/clocksync/ClockSyncController.java @@ -25,7 +25,7 @@ import java.util.Optional; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -34,7 +34,7 @@ @ThingInfo(title = "Sychronizes system clocks", description = "Synchronizes the sytem clocks of OpenEMS and a connected real-time clock device.") public class ClockSyncController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -115,7 +115,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } diff --git a/edge/src/io/openems/impl/controller/debuglog/DebugLogController.java b/edge/src/io/openems/impl/controller/debuglog/DebugLogController.java index 5751f51fd6a..db556976f80 100644 --- a/edge/src/io/openems/impl/controller/debuglog/DebugLogController.java +++ b/edge/src/io/openems/impl/controller/debuglog/DebugLogController.java @@ -23,7 +23,7 @@ import java.util.Set; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -34,7 +34,7 @@ @ThingInfo(title = "Output debugging information on systemlog") public class DebugLogController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -97,7 +97,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/emergencygenerator/EmergencyGeneratorController.java b/edge/src/io/openems/impl/controller/emergencygenerator/EmergencyGeneratorController.java index f411f44e9b5..395aa9d82ab 100644 --- a/edge/src/io/openems/impl/controller/emergencygenerator/EmergencyGeneratorController.java +++ b/edge/src/io/openems/impl/controller/emergencygenerator/EmergencyGeneratorController.java @@ -25,7 +25,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.WriteChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -37,7 +37,7 @@ @ThingInfo(title = "External generator control", description = "Starts an external generator in case of emergency.") public class EmergencyGeneratorController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -173,7 +173,7 @@ private void stopGenerator() throws InvalidValueException, WriteChannelException } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/evcs/EvcsController.java b/edge/src/io/openems/impl/controller/evcs/EvcsController.java index d07752702f5..52baffabbcc 100644 --- a/edge/src/io/openems/impl/controller/evcs/EvcsController.java +++ b/edge/src/io/openems/impl/controller/evcs/EvcsController.java @@ -3,7 +3,7 @@ import java.util.Optional; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -27,7 +27,7 @@ public class EvcsController extends Controller { private Optional lastCurrentMilliAmp = Optional.empty(); private int lagCountdown = CONTROL_LAG; private int waitForValueSet = WAIT_FOR_VALUE_SET; - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors @@ -146,7 +146,7 @@ private void setCurrentMilliAmp(int currentMilliAmp) { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } diff --git a/edge/src/io/openems/impl/controller/feneconprosetup/FeneconProSetupController.java b/edge/src/io/openems/impl/controller/feneconprosetup/FeneconProSetupController.java index 406d101149d..35f6a5d0714 100644 --- a/edge/src/io/openems/impl/controller/feneconprosetup/FeneconProSetupController.java +++ b/edge/src/io/openems/impl/controller/feneconprosetup/FeneconProSetupController.java @@ -23,7 +23,7 @@ import java.util.List; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -34,7 +34,7 @@ @ThingInfo(title = "Initial setup for FENECON Pro", description = "Sets the correct factory settings for FENECON Pro energy storage systems.") public class FeneconProSetupController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors @@ -83,7 +83,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/offGridIndication/OffGridIndicationController.java b/edge/src/io/openems/impl/controller/offGridIndication/OffGridIndicationController.java index 557e0b54a62..2e2c474bb90 100644 --- a/edge/src/io/openems/impl/controller/offGridIndication/OffGridIndicationController.java +++ b/edge/src/io/openems/impl/controller/offGridIndication/OffGridIndicationController.java @@ -25,7 +25,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.WriteChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -43,7 +43,7 @@ public class OffGridIndicationController extends Controller { private boolean isProducerDisconnected = false; private long timeProducerDisconnected; private long startTime = System.currentTimeMillis(); - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); private enum State { OFFGRID, ONGRID, SWITCHTOOFFGRID, SWITCHTOONGRID, UNKNOWN @@ -173,7 +173,7 @@ private boolean isOff() throws InvalidValueException { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/onGridIndication/OnGridIndicationController.java b/edge/src/io/openems/impl/controller/onGridIndication/OnGridIndicationController.java index 4fb494bb973..8460ea7ecc9 100644 --- a/edge/src/io/openems/impl/controller/onGridIndication/OnGridIndicationController.java +++ b/edge/src/io/openems/impl/controller/onGridIndication/OnGridIndicationController.java @@ -25,7 +25,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.WriteChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -43,7 +43,7 @@ public class OnGridIndicationController extends Controller { private boolean isProducerDisconnected = false; private long timeProducerDisconnected; private long startTime = System.currentTimeMillis(); - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); private enum State { OFFGRID, ONGRID, SWITCHTOOFFGRID, SWITCHTOONGRID, UNKNOWN @@ -179,7 +179,7 @@ private boolean isOnGrid() throws InvalidValueException { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/riedmann/RiedmannController.java b/edge/src/io/openems/impl/controller/riedmann/RiedmannController.java index 9ef36f43159..784008cc4d4 100644 --- a/edge/src/io/openems/impl/controller/riedmann/RiedmannController.java +++ b/edge/src/io/openems/impl/controller/riedmann/RiedmannController.java @@ -5,7 +5,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ChannelChangeListener; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -17,7 +17,7 @@ @ThingInfo(title = "Sps parameter Controller") public class RiedmannController extends Controller implements ChannelChangeListener { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Config-Channel */ @@ -255,7 +255,7 @@ public void channelChanged(Channel channel, Optional newValue, Optional ol } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } diff --git a/edge/src/io/openems/impl/controller/riedmann/SystemStopController.java b/edge/src/io/openems/impl/controller/riedmann/SystemStopController.java index a9302af14c6..32a9b65203a 100644 --- a/edge/src/io/openems/impl/controller/riedmann/SystemStopController.java +++ b/edge/src/io/openems/impl/controller/riedmann/SystemStopController.java @@ -3,7 +3,7 @@ import java.util.Optional; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -14,7 +14,7 @@ @ThingInfo(title = "SystemStopController") public class SystemStopController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Config-Channel */ @@ -70,7 +70,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/supplybusswitch/SupplyBusSwitchController.java b/edge/src/io/openems/impl/controller/supplybusswitch/SupplyBusSwitchController.java index bbaa4159c69..edad337ce3a 100644 --- a/edge/src/io/openems/impl/controller/supplybusswitch/SupplyBusSwitchController.java +++ b/edge/src/io/openems/impl/controller/supplybusswitch/SupplyBusSwitchController.java @@ -32,7 +32,7 @@ import io.openems.api.channel.ChannelChangeListener; import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.WriteChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -47,7 +47,7 @@ @ThingInfo(title = "Supply Bus Switch") public class SupplyBusSwitchController extends Controller implements ChannelChangeListener { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -214,7 +214,7 @@ private Ess getEss(String essName) throws InvalidValueException { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/symmetric/avoidtotalcharge/AvoidTotalChargeController.java b/edge/src/io/openems/impl/controller/symmetric/avoidtotalcharge/AvoidTotalChargeController.java index 8a2ee99c438..0a7b028e0d9 100644 --- a/edge/src/io/openems/impl/controller/symmetric/avoidtotalcharge/AvoidTotalChargeController.java +++ b/edge/src/io/openems/impl/controller/symmetric/avoidtotalcharge/AvoidTotalChargeController.java @@ -9,7 +9,7 @@ import java.util.Set; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -19,7 +19,7 @@ @ThingInfo(title = "Avoid total charge of battery. (Symmetric)", description = "Provides control over the battery's maximum state of charge at a specific time of day. For symmetric Ess.") public class AvoidTotalChargeController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Config */ @@ -159,7 +159,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } diff --git a/edge/src/io/openems/impl/controller/symmetric/avoidtotaldischarge/AvoidTotalDischargeController.java b/edge/src/io/openems/impl/controller/symmetric/avoidtotaldischarge/AvoidTotalDischargeController.java index 7804fdb65a9..609b78fc825 100644 --- a/edge/src/io/openems/impl/controller/symmetric/avoidtotaldischarge/AvoidTotalDischargeController.java +++ b/edge/src/io/openems/impl/controller/symmetric/avoidtotaldischarge/AvoidTotalDischargeController.java @@ -24,7 +24,7 @@ import java.util.Set; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -36,7 +36,7 @@ @ThingInfo(title = "Avoid total discharge of battery (Symmetric)", description = "Makes sure the battery is not going into critically low state of charge. For symmetric Ess.") public class AvoidTotalDischargeController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -136,7 +136,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } diff --git a/edge/src/io/openems/impl/controller/symmetric/avoidtotaldischargesoctimeline/AvoidTotalDischargeSocTimeLineController.java b/edge/src/io/openems/impl/controller/symmetric/avoidtotaldischargesoctimeline/AvoidTotalDischargeSocTimeLineController.java index 2576aef1faa..1e4a8b614e4 100644 --- a/edge/src/io/openems/impl/controller/symmetric/avoidtotaldischargesoctimeline/AvoidTotalDischargeSocTimeLineController.java +++ b/edge/src/io/openems/impl/controller/symmetric/avoidtotaldischargesoctimeline/AvoidTotalDischargeSocTimeLineController.java @@ -32,7 +32,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ChannelChangeListener; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -43,7 +43,7 @@ @ThingInfo(title = "Avoid total discharge of battery (Symmetric)", description = "Makes sure the battery is not going into critically low state of charge. For symmetric Ess.") public class AvoidTotalDischargeSocTimeLineController extends Controller implements ChannelChangeListener { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -163,7 +163,7 @@ public void channelChanged(Channel channel, Optional newValue, Optional ol } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/symmetric/balancing/BalancingController.java b/edge/src/io/openems/impl/controller/symmetric/balancing/BalancingController.java index ef6a56d968f..f42bcecab36 100644 --- a/edge/src/io/openems/impl/controller/symmetric/balancing/BalancingController.java +++ b/edge/src/io/openems/impl/controller/symmetric/balancing/BalancingController.java @@ -26,7 +26,7 @@ import java.util.Optional; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -37,7 +37,7 @@ @ThingInfo(title = "Self-consumption optimization (Symmetric)", description = "Tries to keep the grid meter on zero. For symmetric Ess. Ess-Cluster is supported.") public class BalancingController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -196,7 +196,7 @@ private List getUseableEss() throws InvalidValueException { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/symmetric/balancingbandgap/BalancingBandgapController.java b/edge/src/io/openems/impl/controller/symmetric/balancingbandgap/BalancingBandgapController.java index 97b4d389171..8c808e381a6 100644 --- a/edge/src/io/openems/impl/controller/symmetric/balancingbandgap/BalancingBandgapController.java +++ b/edge/src/io/openems/impl/controller/symmetric/balancingbandgap/BalancingBandgapController.java @@ -21,7 +21,7 @@ package io.openems.impl.controller.symmetric.balancingbandgap; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -30,7 +30,7 @@ @ThingInfo(title = "Balancing bandgap (Symmetric)", description = "Tries to keep the grid meter within a bandgap. For symmetric Ess.") public class BalancingBandgapController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -117,7 +117,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/symmetric/balancingcosphi/BalancingCosPhiController.java b/edge/src/io/openems/impl/controller/symmetric/balancingcosphi/BalancingCosPhiController.java index 9e97196c96c..4ed0174200f 100644 --- a/edge/src/io/openems/impl/controller/symmetric/balancingcosphi/BalancingCosPhiController.java +++ b/edge/src/io/openems/impl/controller/symmetric/balancingcosphi/BalancingCosPhiController.java @@ -21,7 +21,7 @@ package io.openems.impl.controller.symmetric.balancingcosphi; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -30,7 +30,7 @@ @ThingInfo(title = "Balancing Cos-Phi (Symmetric)", description = "Tries to keep the grid meter at a given cos-phi. For symmetric Ess.") public class BalancingCosPhiController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -74,7 +74,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } diff --git a/edge/src/io/openems/impl/controller/symmetric/balancingcurrent/BalancingCurrentController.java b/edge/src/io/openems/impl/controller/symmetric/balancingcurrent/BalancingCurrentController.java index 8bbf5fb2a82..11b56bd014a 100644 --- a/edge/src/io/openems/impl/controller/symmetric/balancingcurrent/BalancingCurrentController.java +++ b/edge/src/io/openems/impl/controller/symmetric/balancingcurrent/BalancingCurrentController.java @@ -21,7 +21,7 @@ package io.openems.impl.controller.symmetric.balancingcurrent; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -30,7 +30,7 @@ @ThingInfo(title = "Balancing current (Symmetric)", description = "Tries to keep the grid meter at a given current. For symmetric Ess.") public class BalancingCurrentController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -91,7 +91,7 @@ private long calculatePower() throws InvalidValueException { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/symmetric/balancingoffset/BalancingOffsetController.java b/edge/src/io/openems/impl/controller/symmetric/balancingoffset/BalancingOffsetController.java index f7429b498dc..632495427b1 100644 --- a/edge/src/io/openems/impl/controller/symmetric/balancingoffset/BalancingOffsetController.java +++ b/edge/src/io/openems/impl/controller/symmetric/balancingoffset/BalancingOffsetController.java @@ -25,7 +25,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ChannelChangeListener; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -38,7 +38,7 @@ @ThingInfo(title = "Balancing offset (Symmetric)", description = "Tries to keep the grid meter within an offset. For symmetric Ess.") public class BalancingOffsetController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -138,7 +138,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/symmetric/balancingsurplus/BalancingSurplusController.java b/edge/src/io/openems/impl/controller/symmetric/balancingsurplus/BalancingSurplusController.java index dfee3cb8d6a..c34f3849558 100644 --- a/edge/src/io/openems/impl/controller/symmetric/balancingsurplus/BalancingSurplusController.java +++ b/edge/src/io/openems/impl/controller/symmetric/balancingsurplus/BalancingSurplusController.java @@ -23,7 +23,7 @@ import java.util.Set; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -33,7 +33,7 @@ @ThingInfo(title = "Self-consumption optimization with surplus feed-in (Symmetric)", description = "Tries to keep the grid meter on zero. For symmetric Ess. If ess is over the surplusMinSoc, the ess discharges with the power of the chargers. ") public class BalancingSurplusController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -124,7 +124,7 @@ private long getPvVoltage() throws InvalidValueException { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/symmetric/capacitytest/CapacityTestController.java b/edge/src/io/openems/impl/controller/symmetric/capacitytest/CapacityTestController.java index 74e8157086c..dd33456bd9d 100644 --- a/edge/src/io/openems/impl/controller/symmetric/capacitytest/CapacityTestController.java +++ b/edge/src/io/openems/impl/controller/symmetric/capacitytest/CapacityTestController.java @@ -30,7 +30,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ChannelUpdateListener; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -41,7 +41,7 @@ @ThingInfo(title = "Battery capacity test (Symmetric)", description = "Executes a capacity test. For symmetric Ess.") public class CapacityTestController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -149,7 +149,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/symmetric/commercialenergysaver/EnergysavingController.java b/edge/src/io/openems/impl/controller/symmetric/commercialenergysaver/EnergysavingController.java index 908bf41bfa9..5cae4c3f26a 100644 --- a/edge/src/io/openems/impl/controller/symmetric/commercialenergysaver/EnergysavingController.java +++ b/edge/src/io/openems/impl/controller/symmetric/commercialenergysaver/EnergysavingController.java @@ -24,7 +24,7 @@ import java.util.Set; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.SymmetricEssNature; import io.openems.api.doc.ChannelInfo; @@ -38,7 +38,7 @@ @ThingInfo(title = "Energy saving (Symmetric)", description = "Sends the Ess to Standby if no power is required for two minutes. Do not use if Off-Grid functionality is required. For symmetric Ess.") public class EnergysavingController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -116,7 +116,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/symmetric/commercialworkstate/AlwaysOnController.java b/edge/src/io/openems/impl/controller/symmetric/commercialworkstate/AlwaysOnController.java index 00ee98e8bc1..f1c77aed2ff 100644 --- a/edge/src/io/openems/impl/controller/symmetric/commercialworkstate/AlwaysOnController.java +++ b/edge/src/io/openems/impl/controller/symmetric/commercialworkstate/AlwaysOnController.java @@ -23,7 +23,7 @@ import java.util.Set; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -37,7 +37,7 @@ @ThingInfo(title = "Keep always running (Symmetric)", description = "Tries to keep the Ess always running. Use if Off-Grid functionality is required. For symmetric Ess.") public class AlwaysOnController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -74,7 +74,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } diff --git a/edge/src/io/openems/impl/controller/symmetric/cosphi/CosPhiController.java b/edge/src/io/openems/impl/controller/symmetric/cosphi/CosPhiController.java index e2852ee0aa6..766f9f5e810 100644 --- a/edge/src/io/openems/impl/controller/symmetric/cosphi/CosPhiController.java +++ b/edge/src/io/openems/impl/controller/symmetric/cosphi/CosPhiController.java @@ -21,7 +21,7 @@ package io.openems.impl.controller.symmetric.cosphi; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -31,7 +31,7 @@ @ThingInfo(title = "Ess Cos-Phi (Symmetric)", description = "Keeps the Ess at a given cos-phi. For symmetric Ess.") public class CosPhiController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -72,7 +72,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/symmetric/cosphicharacteristic/CosPhiCharacteristicController.java b/edge/src/io/openems/impl/controller/symmetric/cosphicharacteristic/CosPhiCharacteristicController.java index 4f70085a097..140dac28c67 100644 --- a/edge/src/io/openems/impl/controller/symmetric/cosphicharacteristic/CosPhiCharacteristicController.java +++ b/edge/src/io/openems/impl/controller/symmetric/cosphicharacteristic/CosPhiCharacteristicController.java @@ -24,7 +24,7 @@ import java.util.List; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -35,7 +35,7 @@ @ThingInfo(title = "Cos-Phi Characteristics (Symmetric)") public class CosPhiCharacteristicController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -97,7 +97,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/symmetric/fixvalue/FixValueController.java b/edge/src/io/openems/impl/controller/symmetric/fixvalue/FixValueController.java index d7c044f1fac..850f3a136e0 100644 --- a/edge/src/io/openems/impl/controller/symmetric/fixvalue/FixValueController.java +++ b/edge/src/io/openems/impl/controller/symmetric/fixvalue/FixValueController.java @@ -23,7 +23,7 @@ import java.util.List; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -32,7 +32,7 @@ @ThingInfo(title = "Fixed active and reactive power (Symmetric)", description = "Charges or discharges the battery with a predefined, fixed power. For symmetric Ess.") public class FixValueController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -77,7 +77,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/symmetric/offGridPowerStation/OffGridPowerStationController.java b/edge/src/io/openems/impl/controller/symmetric/offGridPowerStation/OffGridPowerStationController.java index fd817fda488..d059ad7b6cb 100644 --- a/edge/src/io/openems/impl/controller/symmetric/offGridPowerStation/OffGridPowerStationController.java +++ b/edge/src/io/openems/impl/controller/symmetric/offGridPowerStation/OffGridPowerStationController.java @@ -25,7 +25,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.WriteChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -37,7 +37,7 @@ @ThingInfo(title = "External power station control", description = "Starts an thermal power station in case of off-Grid and empty ess.") public class OffGridPowerStationController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -274,7 +274,7 @@ private boolean isOn() throws InvalidValueException { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/symmetric/powerbyfrequency/PowerByFrequencyController.java b/edge/src/io/openems/impl/controller/symmetric/powerbyfrequency/PowerByFrequencyController.java index c222a3fe01b..60d750a9e6a 100644 --- a/edge/src/io/openems/impl/controller/symmetric/powerbyfrequency/PowerByFrequencyController.java +++ b/edge/src/io/openems/impl/controller/symmetric/powerbyfrequency/PowerByFrequencyController.java @@ -21,7 +21,7 @@ package io.openems.impl.controller.symmetric.powerbyfrequency; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -30,7 +30,7 @@ @ThingInfo(title = "Power by frequency (Symmetric)", description = "Tries to keep the grid meter at a given frequency. For symmetric Ess.") public class PowerByFrequencyController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -91,7 +91,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/symmetric/powerlimitation/PowerLimitationController.java b/edge/src/io/openems/impl/controller/symmetric/powerlimitation/PowerLimitationController.java index 4a65279ec32..fd300c949d9 100644 --- a/edge/src/io/openems/impl/controller/symmetric/powerlimitation/PowerLimitationController.java +++ b/edge/src/io/openems/impl/controller/symmetric/powerlimitation/PowerLimitationController.java @@ -21,7 +21,7 @@ package io.openems.impl.controller.symmetric.powerlimitation; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -31,7 +31,7 @@ @ThingInfo(title = "Power limitation (Symmetric)", description = "Limits the active and reactive power of the Ess. For symmetric Ess.") public class PowerLimitationController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -101,7 +101,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/symmetric/powerramp/PowerRampController.java b/edge/src/io/openems/impl/controller/symmetric/powerramp/PowerRampController.java index 020689092a8..484c2bc2913 100644 --- a/edge/src/io/openems/impl/controller/symmetric/powerramp/PowerRampController.java +++ b/edge/src/io/openems/impl/controller/symmetric/powerramp/PowerRampController.java @@ -23,7 +23,7 @@ import java.util.List; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -35,7 +35,7 @@ @ThingInfo(title = "Power ramp (Symmetric)", description = "Follows a power ramp. For symmetric Ess.") public class PowerRampController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -110,7 +110,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/symmetric/refuavoidtotaldischarge/AvoidTotalDischargeController.java b/edge/src/io/openems/impl/controller/symmetric/refuavoidtotaldischarge/AvoidTotalDischargeController.java index d99ab883f5c..66b48dbbab6 100644 --- a/edge/src/io/openems/impl/controller/symmetric/refuavoidtotaldischarge/AvoidTotalDischargeController.java +++ b/edge/src/io/openems/impl/controller/symmetric/refuavoidtotaldischarge/AvoidTotalDischargeController.java @@ -25,7 +25,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ChannelChangeListener; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -36,7 +36,7 @@ @ThingInfo(title = "REFU: Avoid Total Discharge") public class AvoidTotalDischargeController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); @ChannelInfo(title = "Storage, where total discharge should be avoided. For excample to reserve load for the Off-Grid power supply.", type = Ess.class) public final ConfigChannel ess = new ConfigChannel("ess", this); @ChannelInfo(title = "Delay, to allow Power after start", type = Long.class) @@ -220,7 +220,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } diff --git a/edge/src/io/openems/impl/controller/symmetric/refuworkstate/WorkStateController.java b/edge/src/io/openems/impl/controller/symmetric/refuworkstate/WorkStateController.java index 137f14203a4..2a9715ebb43 100644 --- a/edge/src/io/openems/impl/controller/symmetric/refuworkstate/WorkStateController.java +++ b/edge/src/io/openems/impl/controller/symmetric/refuworkstate/WorkStateController.java @@ -24,7 +24,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.DebugChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -38,7 +38,7 @@ @ThingInfo(title = "REFU Workstate (Symmetric)", description = "Sends the Ess to Standby if no power is required. Do not use if Off-Grid functionality is required. For symmetric Ess.") public class WorkStateController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -216,7 +216,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/symmetric/timelinecharge/TimelineChargeController.java b/edge/src/io/openems/impl/controller/symmetric/timelinecharge/TimelineChargeController.java index d432c8746bb..ff50b6225e5 100644 --- a/edge/src/io/openems/impl/controller/symmetric/timelinecharge/TimelineChargeController.java +++ b/edge/src/io/openems/impl/controller/symmetric/timelinecharge/TimelineChargeController.java @@ -35,7 +35,7 @@ import com.google.gson.JsonObject; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -52,7 +52,7 @@ @ThingInfo(title = "Timeline charge (Symmetric)") public class TimelineChargeController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -422,7 +422,7 @@ public int getSoc() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/symmetric/voltagecharacteristic/VoltageCharacteristicController.java b/edge/src/io/openems/impl/controller/symmetric/voltagecharacteristic/VoltageCharacteristicController.java index 9c7f735083a..131bf0e270a 100644 --- a/edge/src/io/openems/impl/controller/symmetric/voltagecharacteristic/VoltageCharacteristicController.java +++ b/edge/src/io/openems/impl/controller/symmetric/voltagecharacteristic/VoltageCharacteristicController.java @@ -27,7 +27,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ChannelChangeListener; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -39,7 +39,7 @@ @ThingInfo(title = "Voltage characteristics (Symmetric)") public class VoltageCharacteristicController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors */ @@ -143,7 +143,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/testwrite/TestWriteController.java b/edge/src/io/openems/impl/controller/testwrite/TestWriteController.java index b9536fa7383..0bd38872623 100644 --- a/edge/src/io/openems/impl/controller/testwrite/TestWriteController.java +++ b/edge/src/io/openems/impl/controller/testwrite/TestWriteController.java @@ -21,7 +21,7 @@ package io.openems.impl.controller.testwrite; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -31,7 +31,7 @@ @ThingInfo(title = "Test write") public class TestWriteController extends Controller { - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Config */ @@ -67,7 +67,7 @@ public void run() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/controller/thermalpowerstation/ThermalPowerStationController.java b/edge/src/io/openems/impl/controller/thermalpowerstation/ThermalPowerStationController.java index 7d88f970fed..c86466401b8 100644 --- a/edge/src/io/openems/impl/controller/thermalpowerstation/ThermalPowerStationController.java +++ b/edge/src/io/openems/impl/controller/thermalpowerstation/ThermalPowerStationController.java @@ -26,7 +26,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.WriteChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -51,7 +51,7 @@ private enum State { private int switchOnCount = 0; private int switchOffCount = 0; private State currentState = State.UNDEFINED; - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); /* * Constructors @@ -242,7 +242,7 @@ private long getProductionPower() throws InvalidValueException { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/device/bcontrol/BControlMeter.java b/edge/src/io/openems/impl/device/bcontrol/BControlMeter.java index 66937ef915e..56eae465f9f 100644 --- a/edge/src/io/openems/impl/device/bcontrol/BControlMeter.java +++ b/edge/src/io/openems/impl/device/bcontrol/BControlMeter.java @@ -3,7 +3,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.FunctionalReadChannel; import io.openems.api.channel.ReadChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.AsymmetricMeterNature; import io.openems.api.device.nature.meter.SymmetricMeterNature; @@ -19,11 +19,11 @@ @ThingInfo(title = "B-Control Energy Meter") public class BControlMeter extends ModbusDeviceNature implements SymmetricMeterNature, AsymmetricMeterNature { - private ThingStateChannel thingState; + private ThingStateChannels thingState; public BControlMeter(String thingId, Device parent) throws ConfigException { super(thingId, parent); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* @@ -274,7 +274,7 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } diff --git a/edge/src/io/openems/impl/device/byd/Bem125ktla01Ess.java b/edge/src/io/openems/impl/device/byd/Bem125ktla01Ess.java index ff08c609caf..d0360d811ae 100644 --- a/edge/src/io/openems/impl/device/byd/Bem125ktla01Ess.java +++ b/edge/src/io/openems/impl/device/byd/Bem125ktla01Ess.java @@ -24,7 +24,7 @@ import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; import io.openems.api.channel.WriteChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.ess.SymmetricEssNature; import io.openems.api.doc.ThingInfo; @@ -69,7 +69,7 @@ public ConfigChannel chargeSoc() { /* * Inherited Channels */ - private ThingStateChannel thingState = new ThingStateChannel(this); + private ThingStateChannels thingState = new ThingStateChannels(this); private ModbusReadChannel soc; private StaticValueChannel allowedCharge = new StaticValueChannel("AllowedCharge", this, 0L); private StaticValueChannel allowedDischarge = new StaticValueChannel("AllowedDischarge", this, 0L); @@ -256,7 +256,7 @@ public StaticValueChannel capacity() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return thingState; } } diff --git a/edge/src/io/openems/impl/device/carlogavazzi/em300series/EM300Meter.java b/edge/src/io/openems/impl/device/carlogavazzi/em300series/EM300Meter.java index 2bf41d1e5a7..64a2b4456b8 100644 --- a/edge/src/io/openems/impl/device/carlogavazzi/em300series/EM300Meter.java +++ b/edge/src/io/openems/impl/device/carlogavazzi/em300series/EM300Meter.java @@ -22,7 +22,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.AsymmetricMeterNature; import io.openems.api.device.nature.meter.SymmetricMeterNature; @@ -41,14 +41,14 @@ @ThingInfo(title = "Socomec Meter") public class EM300Meter extends ModbusDeviceNature implements SymmetricMeterNature, AsymmetricMeterNature { - private ThingStateChannel thingState; + private ThingStateChannels thingState; /* * Constructors */ public EM300Meter(String thingId, Device parent) throws ConfigException { super(thingId, parent); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* @@ -252,7 +252,7 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } diff --git a/edge/src/io/openems/impl/device/commercial/FeneconCommercialCharger.java b/edge/src/io/openems/impl/device/commercial/FeneconCommercialCharger.java index 08e0e87f2c5..2a4badb246e 100644 --- a/edge/src/io/openems/impl/device/commercial/FeneconCommercialCharger.java +++ b/edge/src/io/openems/impl/device/commercial/FeneconCommercialCharger.java @@ -26,7 +26,7 @@ import io.openems.api.channel.StaticValueChannel; import io.openems.api.channel.StatusBitChannel; import io.openems.api.channel.WriteChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.charger.ChargerNature; import io.openems.api.doc.ThingInfo; @@ -55,14 +55,14 @@ public class FeneconCommercialCharger extends ModbusDeviceNature implements Char */ public FeneconCommercialCharger(String thingId, Device parent) throws ConfigException { super(thingId, parent); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* * Inherited Channels */ - private ThingStateChannel thingState; + private ThingStateChannels thingState; public ModbusWriteChannel pvPowerLimitCommand; @@ -1314,7 +1314,7 @@ public ReadChannel getInputVoltage() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { // TODO Auto-generated method stub return thingState; } diff --git a/edge/src/io/openems/impl/device/commercial/FeneconCommercialEss.java b/edge/src/io/openems/impl/device/commercial/FeneconCommercialEss.java index 89930b73b8e..9fe7fca9f18 100644 --- a/edge/src/io/openems/impl/device/commercial/FeneconCommercialEss.java +++ b/edge/src/io/openems/impl/device/commercial/FeneconCommercialEss.java @@ -24,7 +24,7 @@ import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; import io.openems.api.channel.StatusBitChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.ess.SymmetricEssNature; import io.openems.api.doc.ThingInfo; @@ -45,7 +45,7 @@ @ThingInfo(title = "FENECON Commercial ESS") public class FeneconCommercialEss extends ModbusDeviceNature implements SymmetricEssNature { - private ThingStateChannel thingState; + private ThingStateChannels thingState; /* * Constructors @@ -58,7 +58,7 @@ public FeneconCommercialEss(String thingId, Device parent) throws ConfigExceptio chargeSoc.updateValue((Integer) newValue.get() - 2, false); } }); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* @@ -1452,7 +1452,7 @@ public StaticValueChannel capacity() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return thingState; } diff --git a/edge/src/io/openems/impl/device/custom/riedmann/RiedmannNatureImpl.java b/edge/src/io/openems/impl/device/custom/riedmann/RiedmannNatureImpl.java index da00a146601..ee241701818 100644 --- a/edge/src/io/openems/impl/device/custom/riedmann/RiedmannNatureImpl.java +++ b/edge/src/io/openems/impl/device/custom/riedmann/RiedmannNatureImpl.java @@ -1,6 +1,6 @@ package io.openems.impl.device.custom.riedmann; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.doc.ThingInfo; import io.openems.api.exception.ConfigException; @@ -58,7 +58,7 @@ public class RiedmannNatureImpl extends ModbusDeviceNature implements RiedmannNa private ModbusWriteChannel setWaterLevelBorehole2Off; private ModbusWriteChannel setWaterLevelBorehole3On; private ModbusWriteChannel setWaterLevelBorehole3Off; - private ThingStateChannel thingState; + private ThingStateChannels thingState; @Override public ModbusReadChannel getWaterlevel() { @@ -262,7 +262,7 @@ public ModbusWriteChannel getSetWaterLevelBorehole3Off() { public RiedmannNatureImpl(String thingId, Device parent) throws ConfigException { super(thingId, parent); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } @Override @@ -350,7 +350,7 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/device/janitza/JanitzaUMG96RMEMeter.java b/edge/src/io/openems/impl/device/janitza/JanitzaUMG96RMEMeter.java index d52fa1a5189..74e3a9b60b2 100644 --- a/edge/src/io/openems/impl/device/janitza/JanitzaUMG96RMEMeter.java +++ b/edge/src/io/openems/impl/device/janitza/JanitzaUMG96RMEMeter.java @@ -22,7 +22,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.AsymmetricMeterNature; import io.openems.api.device.nature.meter.SymmetricMeterNature; @@ -38,14 +38,14 @@ @ThingInfo(title = "Janitza UMG96RM Meter") public class JanitzaUMG96RMEMeter extends ModbusDeviceNature implements SymmetricMeterNature, AsymmetricMeterNature { - private ThingStateChannel thingState; + private ThingStateChannels thingState; /* * Constructors */ public JanitzaUMG96RMEMeter(String thingId, Device parent) throws ConfigException { super(thingId, parent); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* @@ -238,7 +238,7 @@ public ReadChannel voltageL3() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } diff --git a/edge/src/io/openems/impl/device/keba/KebaEvcs.java b/edge/src/io/openems/impl/device/keba/KebaEvcs.java index 3729e0966b2..22cac9b8f51 100644 --- a/edge/src/io/openems/impl/device/keba/KebaEvcs.java +++ b/edge/src/io/openems/impl/device/keba/KebaEvcs.java @@ -20,7 +20,7 @@ *******************************************************************************/ package io.openems.impl.device.keba; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.nature.evcs.EvcsNature; import io.openems.api.doc.ThingInfo; import io.openems.api.exception.ConfigException; @@ -30,11 +30,11 @@ @ThingInfo(title = "KEBA KeContact EVCS") public class KebaEvcs extends KebaDeviceNature implements EvcsNature { - private ThingStateChannel thingState; + private ThingStateChannels thingState; public KebaEvcs(String thingId, KebaDevice parent) throws ConfigException { super(thingId, parent); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } @Override @@ -44,7 +44,7 @@ public String toString() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } diff --git a/edge/src/io/openems/impl/device/kmtronic/KMTronicRelayOutput.java b/edge/src/io/openems/impl/device/kmtronic/KMTronicRelayOutput.java index 5c7b93c4125..040b00017b2 100644 --- a/edge/src/io/openems/impl/device/kmtronic/KMTronicRelayOutput.java +++ b/edge/src/io/openems/impl/device/kmtronic/KMTronicRelayOutput.java @@ -20,7 +20,7 @@ *******************************************************************************/ package io.openems.impl.device.kmtronic; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.io.OutputNature; import io.openems.api.doc.ThingInfo; @@ -34,7 +34,7 @@ @ThingInfo(title = "KMTronic Relay board Output") public class KMTronicRelayOutput extends ModbusDeviceNature implements OutputNature { - private ThingStateChannel thingState; + private ThingStateChannels thingState; /* * Constructors @@ -42,7 +42,7 @@ public class KMTronicRelayOutput extends ModbusDeviceNature implements OutputNat public KMTronicRelayOutput(String thingId, Device parent) throws ConfigException { super(thingId, parent); outputs = new ModbusCoilWriteChannel[8]; - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* @@ -73,7 +73,7 @@ public ModbusCoilWriteChannel[] setOutput() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/device/kmtronic/KMTronicRelayOutputRev1.java b/edge/src/io/openems/impl/device/kmtronic/KMTronicRelayOutputRev1.java index f63b049af9e..92eff267394 100644 --- a/edge/src/io/openems/impl/device/kmtronic/KMTronicRelayOutputRev1.java +++ b/edge/src/io/openems/impl/device/kmtronic/KMTronicRelayOutputRev1.java @@ -20,7 +20,7 @@ *******************************************************************************/ package io.openems.impl.device.kmtronic; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.io.OutputNature; import io.openems.api.doc.ThingInfo; @@ -34,7 +34,7 @@ @ThingInfo(title = "KMTronic Relay board Output") public class KMTronicRelayOutputRev1 extends ModbusDeviceNature implements OutputNature { - private ThingStateChannel thingState; + private ThingStateChannels thingState; /* * Constructors @@ -42,7 +42,7 @@ public class KMTronicRelayOutputRev1 extends ModbusDeviceNature implements Outpu public KMTronicRelayOutputRev1(String thingId, Device parent) throws ConfigException { super(thingId, parent); outputs = new ModbusCoilWriteChannel[7]; - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* @@ -72,7 +72,7 @@ public ModbusCoilWriteChannel[] setOutput() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/device/mini/FeneconMiniEss.java b/edge/src/io/openems/impl/device/mini/FeneconMiniEss.java index 3a2fac68fe2..d0978c67719 100644 --- a/edge/src/io/openems/impl/device/mini/FeneconMiniEss.java +++ b/edge/src/io/openems/impl/device/mini/FeneconMiniEss.java @@ -26,7 +26,7 @@ import io.openems.api.channel.StaticValueChannel; import io.openems.api.channel.StatusBitChannel; import io.openems.api.channel.WriteChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.device.nature.ess.SymmetricEssNature; @@ -50,7 +50,7 @@ @ThingInfo(title = "FENECON Mini ESS") public class FeneconMiniEss extends ModbusDeviceNature implements SymmetricEssNature, RealTimeClockNature { - private ThingStateChannel thingState; + private ThingStateChannels thingState; /* * Constructors @@ -63,7 +63,7 @@ public FeneconMiniEss(String thingId, Device parent) throws ConfigException { chargeSoc.updateValue((Integer) newValue.get() - 2, false); } }); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* @@ -461,7 +461,7 @@ public StaticValueChannel capacity() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/device/minireadonly/FeneconMiniConsumptionMeter.java b/edge/src/io/openems/impl/device/minireadonly/FeneconMiniConsumptionMeter.java index a8504e86b31..5b1994d8e0b 100644 --- a/edge/src/io/openems/impl/device/minireadonly/FeneconMiniConsumptionMeter.java +++ b/edge/src/io/openems/impl/device/minireadonly/FeneconMiniConsumptionMeter.java @@ -3,7 +3,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.SymmetricMeterNature; import io.openems.api.doc.ThingInfo; @@ -18,14 +18,14 @@ @ThingInfo(title = "FENECON Mini Consumption-Meter") public class FeneconMiniConsumptionMeter extends ModbusDeviceNature implements SymmetricMeterNature { - private ThingStateChannel thingState; + private ThingStateChannels thingState; /* * Constructors */ public FeneconMiniConsumptionMeter(String thingId, Device parent) throws ConfigException { super(thingId, parent); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* @@ -105,7 +105,7 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/device/minireadonly/FeneconMiniEss.java b/edge/src/io/openems/impl/device/minireadonly/FeneconMiniEss.java index f7b6eaedbde..a617b2a37c3 100644 --- a/edge/src/io/openems/impl/device/minireadonly/FeneconMiniEss.java +++ b/edge/src/io/openems/impl/device/minireadonly/FeneconMiniEss.java @@ -24,7 +24,7 @@ import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; import io.openems.api.channel.WriteChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.ess.AsymmetricEssNature; import io.openems.api.doc.ThingInfo; @@ -41,7 +41,7 @@ @ThingInfo(title = "FENECON Mini ESS") public class FeneconMiniEss extends ModbusDeviceNature implements AsymmetricEssNature { - private ThingStateChannel thingState; + private ThingStateChannels thingState; /* * Constructors @@ -54,7 +54,7 @@ public FeneconMiniEss(String thingId, Device parent) throws ConfigException { chargeSoc.updateValue((Integer) newValue.get() - 2, false); } }); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* @@ -571,7 +571,7 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } diff --git a/edge/src/io/openems/impl/device/minireadonly/FeneconMiniGridMeter.java b/edge/src/io/openems/impl/device/minireadonly/FeneconMiniGridMeter.java index 085fac447b5..f40ecf25b38 100644 --- a/edge/src/io/openems/impl/device/minireadonly/FeneconMiniGridMeter.java +++ b/edge/src/io/openems/impl/device/minireadonly/FeneconMiniGridMeter.java @@ -3,7 +3,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.SymmetricMeterNature; import io.openems.api.doc.ThingInfo; @@ -18,14 +18,14 @@ @ThingInfo(title = "FENECON Mini Grid-Meter") public class FeneconMiniGridMeter extends ModbusDeviceNature implements SymmetricMeterNature { - private ThingStateChannel thingState; + private ThingStateChannels thingState; /* * Constructors */ public FeneconMiniGridMeter(String thingId, Device parent) throws ConfigException { super(thingId, parent); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* @@ -111,7 +111,7 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/device/minireadonly/FeneconMiniProductionMeter.java b/edge/src/io/openems/impl/device/minireadonly/FeneconMiniProductionMeter.java index 5f0ef09ef1e..eb310344a43 100644 --- a/edge/src/io/openems/impl/device/minireadonly/FeneconMiniProductionMeter.java +++ b/edge/src/io/openems/impl/device/minireadonly/FeneconMiniProductionMeter.java @@ -3,7 +3,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.SymmetricMeterNature; import io.openems.api.doc.ThingInfo; @@ -18,14 +18,14 @@ @ThingInfo(title = "FENECON Mini Production-Meter") public class FeneconMiniProductionMeter extends ModbusDeviceNature implements SymmetricMeterNature { - private ThingStateChannel thingState; + private ThingStateChannels thingState; /* * Constructors */ public FeneconMiniProductionMeter(String thingId, Device parent) throws ConfigException { super(thingId, parent); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* @@ -104,7 +104,7 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/device/pqplus/PqPlusUMD97Meter.java b/edge/src/io/openems/impl/device/pqplus/PqPlusUMD97Meter.java index 031655cad4e..e967d40329f 100644 --- a/edge/src/io/openems/impl/device/pqplus/PqPlusUMD97Meter.java +++ b/edge/src/io/openems/impl/device/pqplus/PqPlusUMD97Meter.java @@ -22,7 +22,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.SymmetricMeterNature; import io.openems.api.doc.ThingInfo; @@ -37,14 +37,14 @@ @ThingInfo(title = "PQ Plus UMD 97 Meter") public class PqPlusUMD97Meter extends ModbusDeviceNature implements SymmetricMeterNature { - private ThingStateChannel thingState; + private ThingStateChannels thingState; /* * Constructors */ public PqPlusUMD97Meter(String thingId, Device parent) throws ConfigException { super(thingId, parent); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* @@ -180,7 +180,7 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/device/pro/FeneconProEss.java b/edge/src/io/openems/impl/device/pro/FeneconProEss.java index 3baaee09c30..06853dea986 100644 --- a/edge/src/io/openems/impl/device/pro/FeneconProEss.java +++ b/edge/src/io/openems/impl/device/pro/FeneconProEss.java @@ -29,7 +29,7 @@ import io.openems.api.channel.StaticValueChannel; import io.openems.api.channel.ValueToBooleanChannel; import io.openems.api.channel.WriteChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.ess.AsymmetricEssNature; import io.openems.api.device.nature.ess.EssNature; @@ -72,7 +72,7 @@ public FeneconProEss(String thingId, Device parent) throws ConfigException { private ConfigChannel minSoc = new ConfigChannel("minSoc", this); private ConfigChannel chargeSoc = new ConfigChannel("chargeSoc", this); - private ThingStateChannel state = new ThingStateChannel(this); + private ThingStateChannels state = new ThingStateChannels(this); @Override public ConfigChannel minSoc() { @@ -780,7 +780,7 @@ public ReadChannel maxNominalPower() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return state; } diff --git a/edge/src/io/openems/impl/device/pro/FeneconProPvMeter.java b/edge/src/io/openems/impl/device/pro/FeneconProPvMeter.java index 343d33cb9b3..7f3726fa6a9 100644 --- a/edge/src/io/openems/impl/device/pro/FeneconProPvMeter.java +++ b/edge/src/io/openems/impl/device/pro/FeneconProPvMeter.java @@ -24,7 +24,7 @@ import io.openems.api.channel.FunctionalReadChannel; import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.AsymmetricMeterNature; import io.openems.api.device.nature.meter.SymmetricMeterNature; @@ -48,7 +48,7 @@ public class FeneconProPvMeter extends ModbusDeviceNature implements AsymmetricM */ public FeneconProPvMeter(String thingId, Device parent) throws ConfigException { super(thingId, parent); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); this.negativePowerL1 = new StaticValueChannel(WarningPvMeter.NegativePowerL1.getChannelId(), this, false); this.thingState.addWarningChannel(this.negativePowerL1); this.negativePowerL2 = new StaticValueChannel(WarningPvMeter.NegativePowerL2.getChannelId(), this, false); @@ -103,7 +103,7 @@ public ConfigChannel minActivePower() { private ModbusReadChannel orginalActivePowerL1; private ModbusReadChannel orginalActivePowerL2; private ModbusReadChannel orginalActivePowerL3; - private ThingStateChannel thingState; + private ThingStateChannels thingState; private StaticValueChannel negativePowerL1; private StaticValueChannel negativePowerL2; private StaticValueChannel negativePowerL3; @@ -296,7 +296,7 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return thingState; } } diff --git a/edge/src/io/openems/impl/device/refu/RefuEss.java b/edge/src/io/openems/impl/device/refu/RefuEss.java index 9856d1aaa2e..48e42674ff0 100644 --- a/edge/src/io/openems/impl/device/refu/RefuEss.java +++ b/edge/src/io/openems/impl/device/refu/RefuEss.java @@ -25,7 +25,7 @@ import io.openems.api.channel.StaticValueChannel; import io.openems.api.channel.StatusBitChannel; import io.openems.api.channel.WriteChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.ess.AsymmetricEssNature; import io.openems.api.device.nature.ess.SymmetricEssNature; @@ -58,7 +58,7 @@ public RefuEss(String thingId, Device parent) throws ConfigException { chargeSoc.updateValue((Integer) newValue.get() - 2, false); } }); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* @@ -102,7 +102,7 @@ public ConfigChannel chargeSoc() { private StaticValueChannel maxNominalPower = new StaticValueChannel<>("maxNominalPower", this, 100000L) .unit("VA").unit("VA"); private StaticValueChannel capacity = new StaticValueChannel<>("capacity", this, 130000L).unit("Wh"); - private ThingStateChannel thingState; + private ThingStateChannels thingState; /* * This Channels */ @@ -753,7 +753,7 @@ public WriteChannel setReactivePowerL3() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return thingState; } diff --git a/edge/src/io/openems/impl/device/simulator/SimulatorAsymmetricEss.java b/edge/src/io/openems/impl/device/simulator/SimulatorAsymmetricEss.java index 62dc40c1594..ce4f1c34a49 100644 --- a/edge/src/io/openems/impl/device/simulator/SimulatorAsymmetricEss.java +++ b/edge/src/io/openems/impl/device/simulator/SimulatorAsymmetricEss.java @@ -34,7 +34,7 @@ import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; import io.openems.api.channel.WriteChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.charger.ChargerNature; import io.openems.api.device.nature.ess.AsymmetricEssNature; @@ -59,7 +59,7 @@ public class SimulatorAsymmetricEss extends SimulatorDeviceNature private ThingRepository repo = ThingRepository.getInstance(); private LoadGenerator offGridActivePowerGenerator = new RandomLoadGenerator(); private LoadGenerator offGridReactivePowerGenerator = new RandomLoadGenerator(); - private ThingStateChannel thingState; + private ThingStateChannels thingState; /* * Constructors @@ -72,7 +72,7 @@ public SimulatorAsymmetricEss(String thingId, Device parent) throws ConfigExcept chargeSoc.updateValue((Integer) newValue.get() - 2, false); } }); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); long initialSoc = SimulatorTools.addRandomLong(90, 90, 100, 5); this.energy = capacity.valueOptional().get() / 100 * initialSoc; this.soc = new FunctionalReadChannel("Soc", this, (channels) -> { @@ -386,7 +386,7 @@ private void getCharger() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/device/simulator/SimulatorCharger.java b/edge/src/io/openems/impl/device/simulator/SimulatorCharger.java index 6eca025a4b4..27043a93c26 100644 --- a/edge/src/io/openems/impl/device/simulator/SimulatorCharger.java +++ b/edge/src/io/openems/impl/device/simulator/SimulatorCharger.java @@ -24,7 +24,7 @@ import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; import io.openems.api.channel.WriteChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.charger.ChargerNature; import io.openems.api.doc.ChannelInfo; @@ -37,14 +37,14 @@ @ThingInfo(title = "Simulator Charger") public class SimulatorCharger extends SimulatorDeviceNature implements ChargerNature { - private ThingStateChannel thingState; + private ThingStateChannels thingState; /* * Constructors */ public SimulatorCharger(String thingId, Device parent) throws ConfigException { super(thingId, parent); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* @@ -106,7 +106,7 @@ public ReadChannel getInputVoltage() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/device/simulator/SimulatorGridMeter.java b/edge/src/io/openems/impl/device/simulator/SimulatorGridMeter.java index 3094323ed69..236ade71d59 100644 --- a/edge/src/io/openems/impl/device/simulator/SimulatorGridMeter.java +++ b/edge/src/io/openems/impl/device/simulator/SimulatorGridMeter.java @@ -15,7 +15,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.FunctionalReadChannel; import io.openems.api.channel.ReadChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.ess.AsymmetricEssNature; import io.openems.api.device.nature.ess.EssNature; @@ -60,11 +60,11 @@ public class SimulatorGridMeter extends SimulatorMeter implements ChannelChangeL private List meterNatures = new ArrayList<>(); private LoadGenerator activePowerLoad; private LoadGenerator reactivePowerLoad; - private ThingStateChannel thingState; + private ThingStateChannels thingState; public SimulatorGridMeter(String thingId, Device parent) throws ConfigException { super(thingId, parent); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); repo.addThingChangedListener(new ThingsChangedListener() { @Override @@ -376,7 +376,7 @@ public ReadChannel voltageL3() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/device/simulator/SimulatorOutput.java b/edge/src/io/openems/impl/device/simulator/SimulatorOutput.java index 829f4dc6a64..e2e97e45a87 100644 --- a/edge/src/io/openems/impl/device/simulator/SimulatorOutput.java +++ b/edge/src/io/openems/impl/device/simulator/SimulatorOutput.java @@ -1,7 +1,7 @@ package io.openems.impl.device.simulator; import io.openems.api.channel.WriteChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.io.OutputNature; import io.openems.api.doc.ThingInfo; @@ -23,14 +23,14 @@ public class SimulatorOutput extends SimulatorDeviceNature implements OutputNatu private SimulatorWriteChannel do9 = new SimulatorWriteChannel<>("DO9", this, false); private SimulatorWriteChannel do10 = new SimulatorWriteChannel<>("DO10", this, false); private SimulatorWriteChannel[] array; - private ThingStateChannel thingState; + private ThingStateChannels thingState; public SimulatorOutput(String thingId, Device parent) throws ConfigException { super(thingId, parent); @SuppressWarnings("unchecked") SimulatorWriteChannel[] array = new SimulatorWriteChannel[] { do1, do2, do3, do4, do5, do6, do7, do8, do9, do10 }; this.array = array; - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } @Override @@ -44,7 +44,7 @@ protected void update() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/device/simulator/SimulatorProductionMeter.java b/edge/src/io/openems/impl/device/simulator/SimulatorProductionMeter.java index e553f8a3dad..350cef2a883 100644 --- a/edge/src/io/openems/impl/device/simulator/SimulatorProductionMeter.java +++ b/edge/src/io/openems/impl/device/simulator/SimulatorProductionMeter.java @@ -11,7 +11,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.FunctionalReadChannel; import io.openems.api.channel.ReadChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; @@ -37,7 +37,7 @@ public class SimulatorProductionMeter extends SimulatorMeter implements ChannelC private FunctionalReadChannel apparentPower; private LoadGenerator activePowerGenerator; private LoadGenerator reactivePowerGenerator; - private ThingStateChannel thingState; + private ThingStateChannels thingState; public SimulatorProductionMeter(String thingId, Device parent) throws ConfigException { super(thingId, parent); @@ -45,7 +45,7 @@ public SimulatorProductionMeter(String thingId, Device parent) throws ConfigExce return ControllerUtils.calculateApparentPower(channels[0].valueOptional().orElse(0L), channels[1].valueOptional().orElse(0L)); }, activePower, reactivePower); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } @Override @@ -129,7 +129,7 @@ private LoadGenerator getGenerator(JsonObject config) { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/device/simulator/SimulatorRiedmannNature.java b/edge/src/io/openems/impl/device/simulator/SimulatorRiedmannNature.java index 2162fa6c91c..698a4af4eb5 100644 --- a/edge/src/io/openems/impl/device/simulator/SimulatorRiedmannNature.java +++ b/edge/src/io/openems/impl/device/simulator/SimulatorRiedmannNature.java @@ -27,7 +27,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; import io.openems.api.channel.WriteChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; @@ -41,14 +41,14 @@ @ThingInfo(title = "Simulator ESS") public class SimulatorRiedmannNature extends SimulatorDeviceNature implements RiedmannNature, ChannelChangeListener { - private ThingStateChannel thingState; + private ThingStateChannels thingState; /* * Constructors */ public SimulatorRiedmannNature(String thingId, Device parent) throws ConfigException { super(thingId, parent); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* @@ -342,7 +342,7 @@ protected void update() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/device/simulator/SimulatorSymmetricEss.java b/edge/src/io/openems/impl/device/simulator/SimulatorSymmetricEss.java index feeb35452b7..8c5a495c590 100644 --- a/edge/src/io/openems/impl/device/simulator/SimulatorSymmetricEss.java +++ b/edge/src/io/openems/impl/device/simulator/SimulatorSymmetricEss.java @@ -37,7 +37,7 @@ import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; import io.openems.api.channel.WriteChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.charger.ChargerNature; import io.openems.api.device.nature.ess.EssNature; @@ -71,14 +71,14 @@ public class SimulatorSymmetricEss extends SimulatorDeviceNature implements Symm "reactivePowerGeneratorConfig", this).addChangeListener(this).addChangeListener(this); private LoadGenerator offGridActivePowerGenerator; private LoadGenerator offGridReactivePowerGenerator; - private ThingStateChannel thingState; + private ThingStateChannels thingState; /* * Constructors */ public SimulatorSymmetricEss(String thingId, Device parent) throws ConfigException { super(thingId, parent); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); minSoc.addUpdateListener((channel, newValue) -> { // If chargeSoc was not set -> set it to minSoc minus 2 if (channel == minSoc && !chargeSoc.valueOptional().isPresent()) { @@ -343,7 +343,7 @@ private void getCharger() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/device/sma/SunnyIsland6Ess.java b/edge/src/io/openems/impl/device/sma/SunnyIsland6Ess.java index 857908e92df..219b79adb53 100644 --- a/edge/src/io/openems/impl/device/sma/SunnyIsland6Ess.java +++ b/edge/src/io/openems/impl/device/sma/SunnyIsland6Ess.java @@ -4,7 +4,7 @@ import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; import io.openems.api.channel.WriteChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.ess.SymmetricEssNature; import io.openems.api.doc.ChannelInfo; @@ -23,11 +23,11 @@ @ThingInfo(title = "SMA SunnyIsland 6.0H") public class SunnyIsland6Ess extends ModbusDeviceNature implements SymmetricEssNature { - private ThingStateChannel thingState; + private ThingStateChannels thingState; public SunnyIsland6Ess(String thingId, Device parent) throws ConfigException { super(thingId, parent); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* @@ -199,7 +199,7 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/device/socomec/SocomecB30Meter.java b/edge/src/io/openems/impl/device/socomec/SocomecB30Meter.java index a9a98d7f20a..b077926fbb1 100644 --- a/edge/src/io/openems/impl/device/socomec/SocomecB30Meter.java +++ b/edge/src/io/openems/impl/device/socomec/SocomecB30Meter.java @@ -22,7 +22,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.AsymmetricMeterNature; import io.openems.api.device.nature.meter.SymmetricMeterNature; @@ -39,14 +39,14 @@ @ThingInfo(title = "Socomec B30 Meter") public class SocomecB30Meter extends ModbusDeviceNature implements SymmetricMeterNature, AsymmetricMeterNature { - private ThingStateChannel thingState; + private ThingStateChannels thingState; /* * Constructors */ public SocomecB30Meter(String thingId, Device parent) throws ConfigException { super(thingId, parent); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* @@ -247,7 +247,7 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } diff --git a/edge/src/io/openems/impl/device/socomec/SocomecMeter.java b/edge/src/io/openems/impl/device/socomec/SocomecMeter.java index 2ed69081b4f..83ca75ace23 100644 --- a/edge/src/io/openems/impl/device/socomec/SocomecMeter.java +++ b/edge/src/io/openems/impl/device/socomec/SocomecMeter.java @@ -22,7 +22,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.AsymmetricMeterNature; import io.openems.api.device.nature.meter.SymmetricMeterNature; @@ -39,14 +39,14 @@ @ThingInfo(title = "Socomec Meter") public class SocomecMeter extends ModbusDeviceNature implements SymmetricMeterNature, AsymmetricMeterNature { - private ThingStateChannel thingState; + private ThingStateChannels thingState; /* * Constructors */ public SocomecMeter(String thingId, Device parent) throws ConfigException { super(thingId, parent); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* @@ -256,7 +256,7 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } diff --git a/edge/src/io/openems/impl/device/socomec/SocomecSinglePhaseMeter.java b/edge/src/io/openems/impl/device/socomec/SocomecSinglePhaseMeter.java index 8de65f78f74..3cc6a499b6f 100644 --- a/edge/src/io/openems/impl/device/socomec/SocomecSinglePhaseMeter.java +++ b/edge/src/io/openems/impl/device/socomec/SocomecSinglePhaseMeter.java @@ -22,7 +22,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.SymmetricMeterNature; import io.openems.api.doc.ThingInfo; @@ -38,14 +38,14 @@ @ThingInfo(title = "Socomec Single Phase Meter") public class SocomecSinglePhaseMeter extends ModbusDeviceNature implements SymmetricMeterNature { - private ThingStateChannel thingState; + private ThingStateChannels thingState; /* * Constructors */ public SocomecSinglePhaseMeter(String thingId, Device parent) throws ConfigException { super(thingId, parent); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* @@ -157,7 +157,7 @@ public ReadChannel voltage() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } diff --git a/edge/src/io/openems/impl/device/spanner/BHKWMeter.java b/edge/src/io/openems/impl/device/spanner/BHKWMeter.java index 7b733ca8eae..5e27ebf68cc 100644 --- a/edge/src/io/openems/impl/device/spanner/BHKWMeter.java +++ b/edge/src/io/openems/impl/device/spanner/BHKWMeter.java @@ -24,7 +24,7 @@ import io.openems.api.channel.FunctionalReadChannel; import io.openems.api.channel.FunctionalReadChannelFunction; import io.openems.api.channel.ReadChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.AsymmetricMeterNature; import io.openems.api.device.nature.meter.SymmetricMeterNature; @@ -42,14 +42,14 @@ @ThingInfo(title = "BHKW Meter") public class BHKWMeter extends ModbusDeviceNature implements AsymmetricMeterNature, SymmetricMeterNature { - private ThingStateChannel thingState; + private ThingStateChannels thingState; /* * Constructors */ public BHKWMeter(String thingId, Device parent) throws ConfigException { super(thingId, parent); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* @@ -299,7 +299,7 @@ public ReadChannel voltage() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } diff --git a/edge/src/io/openems/impl/device/studer/StuderVs70Charger.java b/edge/src/io/openems/impl/device/studer/StuderVs70Charger.java index 22217704735..191d7ce56b9 100644 --- a/edge/src/io/openems/impl/device/studer/StuderVs70Charger.java +++ b/edge/src/io/openems/impl/device/studer/StuderVs70Charger.java @@ -3,7 +3,7 @@ import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; import io.openems.api.channel.WriteChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.doc.ThingInfo; import io.openems.api.exception.ConfigException; @@ -16,14 +16,14 @@ @ThingInfo(title = "Studer VS-70 Charger") public class StuderVs70Charger extends StuderDeviceNature { - private ThingStateChannel thingState; + private ThingStateChannels thingState; /* * Constructors */ public StuderVs70Charger(String thingId, Device parent) throws ConfigException { super(thingId, parent); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* @@ -81,7 +81,7 @@ protected StuderProtocol defineStuderProtocol() throws ConfigException { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/device/system/SystemNature.java b/edge/src/io/openems/impl/device/system/SystemNature.java index 2d613398f2c..029145e4386 100644 --- a/edge/src/io/openems/impl/device/system/SystemNature.java +++ b/edge/src/io/openems/impl/device/system/SystemNature.java @@ -32,7 +32,7 @@ import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.doc.ThingInfo; import io.openems.api.exception.ConfigException; @@ -43,7 +43,7 @@ @ThingInfo(title = "Operating system") public class SystemNature extends SystemDeviceNature implements io.openems.api.device.nature.system.SystemNature { - private ThingStateChannel thingState; + private ThingStateChannels thingState; /* * Constructors @@ -60,7 +60,7 @@ public SystemNature(String thingId, Device parent) throws ConfigException { } catch (UnknownHostException e) { throw new ConfigException("Error initializing OpenEMS Static IP: " + e.getMessage()); } - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* @@ -157,7 +157,7 @@ public void init() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } diff --git a/edge/src/io/openems/impl/device/system/asymmetricsymmetriccombinationess/AsymmetricSymmetricCombinationEssNature.java b/edge/src/io/openems/impl/device/system/asymmetricsymmetriccombinationess/AsymmetricSymmetricCombinationEssNature.java index 8547efc1151..a46086eb092 100644 --- a/edge/src/io/openems/impl/device/system/asymmetricsymmetriccombinationess/AsymmetricSymmetricCombinationEssNature.java +++ b/edge/src/io/openems/impl/device/system/asymmetricsymmetriccombinationess/AsymmetricSymmetricCombinationEssNature.java @@ -16,7 +16,7 @@ import io.openems.api.channel.ProxyReadChannel; import io.openems.api.channel.ReadChannel; import io.openems.api.channel.WriteChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.ess.AsymmetricEssNature; import io.openems.api.device.nature.ess.EssNature; @@ -47,7 +47,7 @@ public class AsymmetricSymmetricCombinationEssNature extends SystemDeviceNature private ThingRepository repo; private List listeners; - private ThingStateChannel state = new ThingStateChannel(this); + private ThingStateChannels state = new ThingStateChannels(this); private ProxyReadChannel gridMode = new ProxyReadChannel<>("GridMode", this); private ProxyReadChannel soc = new ProxyReadChannel<>("Soc", this); @@ -1480,7 +1480,7 @@ public void onBridgeInitialized() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.state; } diff --git a/edge/src/io/openems/impl/device/system/esscluster/EssClusterNature.java b/edge/src/io/openems/impl/device/system/esscluster/EssClusterNature.java index 7972166c136..2492c0e5ce2 100644 --- a/edge/src/io/openems/impl/device/system/esscluster/EssClusterNature.java +++ b/edge/src/io/openems/impl/device/system/esscluster/EssClusterNature.java @@ -20,7 +20,7 @@ import io.openems.api.channel.FunctionalWriteChannelFunction; import io.openems.api.channel.ReadChannel; import io.openems.api.channel.WriteChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.DeviceNature; import io.openems.api.device.nature.ess.EssNature; @@ -41,7 +41,7 @@ public class EssClusterNature extends SystemDeviceNature implements SymmetricEss private final Logger log = LoggerFactory.getLogger(EssClusterNature.class); private List listeners; - private ThingStateChannel thingState; + private ThingStateChannels thingState; private static ThingRepository repo = ThingRepository.getInstance(); @@ -495,7 +495,7 @@ public EssClusterNature(String id, Device parent) throws ConfigException { super(id, parent); this.listeners = new ArrayList<>(); Config.getInstance().addBridgeInitializedEventListener(this); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } @Override @@ -681,7 +681,7 @@ public void onBridgeInitialized() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/device/system/metercluster/MeterClusterNature.java b/edge/src/io/openems/impl/device/system/metercluster/MeterClusterNature.java index 4f7eba92efc..e45deb67969 100644 --- a/edge/src/io/openems/impl/device/system/metercluster/MeterClusterNature.java +++ b/edge/src/io/openems/impl/device/system/metercluster/MeterClusterNature.java @@ -14,7 +14,7 @@ import io.openems.api.channel.ChannelChangeListener; import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.AsymmetricMeterNature; import io.openems.api.device.nature.meter.SymmetricMeterNature; @@ -38,7 +38,7 @@ public class MeterClusterNature extends SimulatorDeviceNature private ThingRepository repo; private List symmetricMeterList = new ArrayList<>(); private List asymmetricMeterList = new ArrayList<>(); - private ThingStateChannel thingState; + private ThingStateChannels thingState; /* * Channels @@ -67,7 +67,7 @@ public MeterClusterNature(String thingId, Device parent) throws ConfigException this.log = LoggerFactory.getLogger(this.getClass()); this.listeners = new ArrayList<>(); this.repo = ThingRepository.getInstance(); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* @@ -440,7 +440,7 @@ public void removeListener(ThingChannelsUpdatedListener listener) { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/device/wago/WagoFBInput.java b/edge/src/io/openems/impl/device/wago/WagoFBInput.java index 8ca8ded9912..0eed423e80b 100644 --- a/edge/src/io/openems/impl/device/wago/WagoFBInput.java +++ b/edge/src/io/openems/impl/device/wago/WagoFBInput.java @@ -26,7 +26,7 @@ import java.util.List; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.io.InputNature; import io.openems.api.doc.ChannelInfo; @@ -48,7 +48,7 @@ public class WagoFBInput extends ModbusDeviceNature implements InputNature { */ public WagoFBInput(String thingId, Device parent) throws ConfigException { super(thingId, parent); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* @@ -62,7 +62,7 @@ public WagoFBInput(String thingId, Device parent) throws ConfigException { */ private List channel = new ArrayList<>(); - private ThingStateChannel thingState; + private ThingStateChannels thingState; /* * Methods @@ -110,7 +110,7 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } diff --git a/edge/src/io/openems/impl/device/wago/WagoFBOutput.java b/edge/src/io/openems/impl/device/wago/WagoFBOutput.java index c6a56e919b6..374cc902e04 100644 --- a/edge/src/io/openems/impl/device/wago/WagoFBOutput.java +++ b/edge/src/io/openems/impl/device/wago/WagoFBOutput.java @@ -26,7 +26,7 @@ import java.util.List; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.io.OutputNature; import io.openems.api.doc.ChannelInfo; @@ -49,7 +49,7 @@ public class WagoFBOutput extends ModbusDeviceNature implements OutputNature { */ public WagoFBOutput(String thingId, Device parent) throws ConfigException { super(thingId, parent); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* @@ -63,7 +63,7 @@ public WagoFBOutput(String thingId, Device parent) throws ConfigException { */ private List channel = new ArrayList<>(); - private ThingStateChannel thingState; + private ThingStateChannels thingState; /* * Methods @@ -111,7 +111,7 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } diff --git a/edge/src/io/openems/impl/persistence/fenecon/FeneconPersistence.java b/edge/src/io/openems/impl/persistence/fenecon/FeneconPersistence.java index b1f5a55eb78..77d95a570c6 100644 --- a/edge/src/io/openems/impl/persistence/fenecon/FeneconPersistence.java +++ b/edge/src/io/openems/impl/persistence/fenecon/FeneconPersistence.java @@ -40,7 +40,7 @@ import io.openems.api.channel.ChannelChangeListener; import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.controller.ThingMap; import io.openems.api.device.nature.DeviceNature; import io.openems.api.doc.ChannelInfo; @@ -68,7 +68,7 @@ @ThingInfo(title = "FENECON Persistence", description = "Establishes the connection to FENECON Cloud.") public class FeneconPersistence extends Persistence implements ChannelChangeListener { - private ThingStateChannel thingState; + private ThingStateChannels thingState; private final static String DEFAULT_CONFIG_LANGUAGE = "en"; @@ -100,7 +100,7 @@ public class FeneconPersistence extends Persistence implements ChannelChangeList */ public FeneconPersistence() { this.websocketHandler = new EdgeWebsocketHandler(); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); this.reconnectingWebsocket = new ReconnectingWebsocket(this.websocketHandler, (websocket) -> { /* * onOpen @@ -383,7 +383,7 @@ private Optional proxyInfo() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } \ No newline at end of file diff --git a/edge/src/io/openems/impl/persistence/influxdb/InfluxdbPersistence.java b/edge/src/io/openems/impl/persistence/influxdb/InfluxdbPersistence.java index aa3fb2bb2de..cebf89320a3 100644 --- a/edge/src/io/openems/impl/persistence/influxdb/InfluxdbPersistence.java +++ b/edge/src/io/openems/impl/persistence/influxdb/InfluxdbPersistence.java @@ -39,7 +39,7 @@ import io.openems.api.channel.ChannelUpdateListener; import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; import io.openems.api.exception.OpenemsException; @@ -51,7 +51,7 @@ @ThingInfo(title = "InfluxDB Persistence", description = "Persists data in an InfluxDB time-series database.") public class InfluxdbPersistence extends QueryablePersistence implements ChannelUpdateListener { - private ThingStateChannel thingState; + private ThingStateChannels thingState; /* * Config @@ -75,7 +75,7 @@ public class InfluxdbPersistence extends QueryablePersistence implements Channel public ConfigChannel cycleTime = new ConfigChannel("cycleTime", this).defaultValue(10000); public InfluxdbPersistence() { - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* @@ -224,7 +224,7 @@ protected int getCycleTime() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } \ No newline at end of file diff --git a/edge/src/io/openems/impl/protocol/modbus/ModbusBitWrappingChannel.java b/edge/src/io/openems/impl/protocol/modbus/ModbusBitWrappingChannel.java index ba2a073c79d..a8cb1fa0f26 100644 --- a/edge/src/io/openems/impl/protocol/modbus/ModbusBitWrappingChannel.java +++ b/edge/src/io/openems/impl/protocol/modbus/ModbusBitWrappingChannel.java @@ -22,16 +22,16 @@ import io.openems.api.channel.BitToBooleanChannel; import io.openems.api.channel.thingstate.FaultEnum; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.channel.thingstate.WarningEnum; import io.openems.api.device.nature.DeviceNature; import io.openems.api.exception.ConfigException; public class ModbusBitWrappingChannel extends ModbusReadChannel { - private final ThingStateChannel thingState; + private final ThingStateChannels thingState; - public ModbusBitWrappingChannel(String id, DeviceNature nature, ThingStateChannel thingStateChannel) { + public ModbusBitWrappingChannel(String id, DeviceNature nature, ThingStateChannels thingStateChannel) { super(id, nature); this.thingState = thingStateChannel; } diff --git a/edge/src/io/openems/impl/scheduler/SimpleScheduler.java b/edge/src/io/openems/impl/scheduler/SimpleScheduler.java index d89554d2d38..8b9d1c00c02 100644 --- a/edge/src/io/openems/impl/scheduler/SimpleScheduler.java +++ b/edge/src/io/openems/impl/scheduler/SimpleScheduler.java @@ -27,7 +27,7 @@ import info.faljse.SDNotify.SDNotify; import io.openems.api.bridge.Bridge; import io.openems.api.channel.WriteChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.controller.Controller; import io.openems.api.doc.ThingInfo; import io.openems.api.scheduler.Scheduler; @@ -35,13 +35,13 @@ @ThingInfo(title = "App-Planner") public class SimpleScheduler extends Scheduler { - private ThingStateChannel thingState; + private ThingStateChannels thingState; /* * Constructors */ public SimpleScheduler() { - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* @@ -75,7 +75,7 @@ protected boolean initialize() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } diff --git a/edge/src/io/openems/impl/scheduler/channelthreshold/ChannelThresholdScheduler.java b/edge/src/io/openems/impl/scheduler/channelthreshold/ChannelThresholdScheduler.java index 284bb6183ba..e6ef08130c6 100644 --- a/edge/src/io/openems/impl/scheduler/channelthreshold/ChannelThresholdScheduler.java +++ b/edge/src/io/openems/impl/scheduler/channelthreshold/ChannelThresholdScheduler.java @@ -35,7 +35,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; import io.openems.api.channel.WriteChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -48,11 +48,11 @@ @ThingInfo(title = "Channel threshold app-planer", description = "app-planer with thresholds on configured channel to run different controllers by threshold on channel.") public class ChannelThresholdScheduler extends Scheduler { - private ThingStateChannel thingState; + private ThingStateChannels thingState; public ChannelThresholdScheduler() { thingRepository = ThingRepository.getInstance(); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* @@ -302,7 +302,7 @@ public boolean isBetween(long value) { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } diff --git a/edge/src/io/openems/impl/scheduler/time/WeekTimeScheduler.java b/edge/src/io/openems/impl/scheduler/time/WeekTimeScheduler.java index 162ee4937a1..761e9fedc44 100644 --- a/edge/src/io/openems/impl/scheduler/time/WeekTimeScheduler.java +++ b/edge/src/io/openems/impl/scheduler/time/WeekTimeScheduler.java @@ -37,7 +37,7 @@ import io.openems.api.bridge.Bridge; import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.WriteChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +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; @@ -51,14 +51,14 @@ @ThingInfo(title = "Weekly App-Planner", description = "Define recurring weekly plans.") public class WeekTimeScheduler extends Scheduler { - private ThingStateChannel thingState; + private ThingStateChannels thingState; /* * Constructors */ public WeekTimeScheduler() { thingRepository = ThingRepository.getInstance(); - this.thingState = new ThingStateChannel(this); + this.thingState = new ThingStateChannels(this); } /* @@ -225,7 +225,7 @@ public synchronized void removeController(Controller controller) { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { return this.thingState; } } diff --git a/edge/src/io/openems/test/controller/ThermalPowerStationTest.java b/edge/src/io/openems/test/controller/ThermalPowerStationTest.java index 6cb1f342f13..106b3079b18 100644 --- a/edge/src/io/openems/test/controller/ThermalPowerStationTest.java +++ b/edge/src/io/openems/test/controller/ThermalPowerStationTest.java @@ -10,7 +10,7 @@ import org.junit.BeforeClass; import org.junit.Test; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.thing.Thing; import io.openems.impl.controller.thermalpowerstation.Ess; import io.openems.impl.controller.thermalpowerstation.Meter; @@ -41,7 +41,7 @@ public String id() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { // TODO Auto-generated method stub return null; } diff --git a/edge/src/io/openems/test/utils/channel/UnitTestReadChannel.java b/edge/src/io/openems/test/utils/channel/UnitTestReadChannel.java index c7f444107be..0a5c4572a01 100644 --- a/edge/src/io/openems/test/utils/channel/UnitTestReadChannel.java +++ b/edge/src/io/openems/test/utils/channel/UnitTestReadChannel.java @@ -1,6 +1,6 @@ package io.openems.test.utils.channel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.thing.Thing; public class UnitTestReadChannel extends io.openems.api.channel.ReadChannel { @@ -14,7 +14,7 @@ public String id() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { // TODO Auto-generated method stub return null; } diff --git a/edge/src/io/openems/test/utils/channel/UnitTestWriteChannel.java b/edge/src/io/openems/test/utils/channel/UnitTestWriteChannel.java index 9954ce6a1c7..9ee51e41a61 100644 --- a/edge/src/io/openems/test/utils/channel/UnitTestWriteChannel.java +++ b/edge/src/io/openems/test/utils/channel/UnitTestWriteChannel.java @@ -4,7 +4,7 @@ import io.openems.api.channel.ReadChannel; import io.openems.api.channel.WriteChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.thing.Thing; public class UnitTestWriteChannel extends WriteChannel { @@ -18,7 +18,7 @@ public String id() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { // TODO Auto-generated method stub return null; } diff --git a/edge/src/io/openems/test/utils/devicenatures/UnitTestAsymmetricEssNature.java b/edge/src/io/openems/test/utils/devicenatures/UnitTestAsymmetricEssNature.java index d543562555d..8efc1f464fd 100644 --- a/edge/src/io/openems/test/utils/devicenatures/UnitTestAsymmetricEssNature.java +++ b/edge/src/io/openems/test/utils/devicenatures/UnitTestAsymmetricEssNature.java @@ -9,7 +9,7 @@ import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; import io.openems.api.channel.WriteChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.ess.AsymmetricEssNature; import io.openems.impl.device.simulator.SimulatorTools; @@ -202,7 +202,7 @@ public List getWriteTasks() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { // TODO Auto-generated method stub return null; } diff --git a/edge/src/io/openems/test/utils/devicenatures/UnitTestAsymmetricMeterNature.java b/edge/src/io/openems/test/utils/devicenatures/UnitTestAsymmetricMeterNature.java index 30ee1c2e72c..ffaa967a7bf 100644 --- a/edge/src/io/openems/test/utils/devicenatures/UnitTestAsymmetricMeterNature.java +++ b/edge/src/io/openems/test/utils/devicenatures/UnitTestAsymmetricMeterNature.java @@ -7,7 +7,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.AsymmetricMeterNature; import io.openems.test.utils.channel.UnitTestReadChannel; @@ -147,7 +147,7 @@ public List getWriteTasks() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { // TODO Auto-generated method stub return null; } diff --git a/edge/src/io/openems/test/utils/devicenatures/UnitTestSymmetricEssNature.java b/edge/src/io/openems/test/utils/devicenatures/UnitTestSymmetricEssNature.java index 071ad40d96a..20c02d43764 100644 --- a/edge/src/io/openems/test/utils/devicenatures/UnitTestSymmetricEssNature.java +++ b/edge/src/io/openems/test/utils/devicenatures/UnitTestSymmetricEssNature.java @@ -9,7 +9,7 @@ import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; import io.openems.api.channel.WriteChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.device.nature.ess.SymmetricEssNature; @@ -159,7 +159,7 @@ public List getWriteTasks() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { // TODO Auto-generated method stub return null; } diff --git a/edge/src/io/openems/test/utils/devicenatures/UnitTestSymmetricMeterNature.java b/edge/src/io/openems/test/utils/devicenatures/UnitTestSymmetricMeterNature.java index f6b4d09176a..da69153a36b 100644 --- a/edge/src/io/openems/test/utils/devicenatures/UnitTestSymmetricMeterNature.java +++ b/edge/src/io/openems/test/utils/devicenatures/UnitTestSymmetricMeterNature.java @@ -7,7 +7,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.ReadChannel; -import io.openems.api.channel.thingstate.ThingStateChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.SymmetricMeterNature; import io.openems.test.utils.channel.UnitTestReadChannel; @@ -103,7 +103,7 @@ public List getWriteTasks() { } @Override - public ThingStateChannel getStateChannel() { + public ThingStateChannels getStateChannel() { // TODO Auto-generated method stub return null; } From 6d153ef5cbee600d93f29a1fb0595fbb596ed750 Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Thu, 15 Feb 2018 10:49:30 +0100 Subject: [PATCH 47/55] Create and use StaticThingStateChannel --- .../api/channel/BitToBooleanChannel.java | 2 +- .../api/channel/StaticThingStateChannel.java | 46 +++++++++++++++++++ .../api/channel/ThingStateChannel.java | 11 +++++ .../api/channel/ValueToBooleanChannel.java | 2 +- .../thingstate/ThingStateChannels.java | 25 +++++----- .../impl/device/pro/FeneconProPvMeter.java | 14 +++--- .../impl/protocol/modbus/ModbusRtu.java | 10 ++-- .../impl/protocol/modbus/ModbusTcp.java | 10 ++-- 8 files changed, 89 insertions(+), 31 deletions(-) create mode 100644 edge/src/io/openems/api/channel/StaticThingStateChannel.java create mode 100644 edge/src/io/openems/api/channel/ThingStateChannel.java diff --git a/edge/src/io/openems/api/channel/BitToBooleanChannel.java b/edge/src/io/openems/api/channel/BitToBooleanChannel.java index 2baa2bcbdcc..0921e86cefe 100644 --- a/edge/src/io/openems/api/channel/BitToBooleanChannel.java +++ b/edge/src/io/openems/api/channel/BitToBooleanChannel.java @@ -4,7 +4,7 @@ import io.openems.api.thing.Thing; -public class BitToBooleanChannel extends ReadChannel implements ChannelChangeListener{ +public class BitToBooleanChannel extends ThingStateChannel implements ChannelChangeListener{ private ReadChannel valueChannel; private int bitIndex; diff --git a/edge/src/io/openems/api/channel/StaticThingStateChannel.java b/edge/src/io/openems/api/channel/StaticThingStateChannel.java new file mode 100644 index 00000000000..58d4b93034b --- /dev/null +++ b/edge/src/io/openems/api/channel/StaticThingStateChannel.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * 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.api.channel; + +import io.openems.api.thing.Thing; + +public class StaticThingStateChannel extends ThingStateChannel { + + public StaticThingStateChannel(String id, Thing parent, boolean value) { + super(id, parent); + this.updateValue(value); + } + + @Override public StaticThingStateChannel addUpdateListener(ChannelUpdateListener... listeners) { + super.addUpdateListener(listeners); + return this; + } + + @Override public StaticThingStateChannel addChangeListener(ChannelChangeListener... listeners) { + super.addChangeListener(listeners); + return this; + } + + public void setValue(boolean b) { + this.updateValue(b); + } + +} diff --git a/edge/src/io/openems/api/channel/ThingStateChannel.java b/edge/src/io/openems/api/channel/ThingStateChannel.java new file mode 100644 index 00000000000..0218126501b --- /dev/null +++ b/edge/src/io/openems/api/channel/ThingStateChannel.java @@ -0,0 +1,11 @@ +package io.openems.api.channel; + +import io.openems.api.thing.Thing; + +public class ThingStateChannel extends ReadChannel { + + public ThingStateChannel(String id, Thing parent) { + super(id, parent); + } + +} diff --git a/edge/src/io/openems/api/channel/ValueToBooleanChannel.java b/edge/src/io/openems/api/channel/ValueToBooleanChannel.java index 7264b88e5e2..f2a017ce0db 100644 --- a/edge/src/io/openems/api/channel/ValueToBooleanChannel.java +++ b/edge/src/io/openems/api/channel/ValueToBooleanChannel.java @@ -4,7 +4,7 @@ import io.openems.api.thing.Thing; -public class ValueToBooleanChannel extends ReadChannel implements ChannelChangeListener{ +public class ValueToBooleanChannel extends ThingStateChannel implements ChannelChangeListener{ private ReadChannel valueChannel; private long value; diff --git a/edge/src/io/openems/api/channel/thingstate/ThingStateChannels.java b/edge/src/io/openems/api/channel/thingstate/ThingStateChannels.java index ad0ebc9bcc8..058764d5082 100644 --- a/edge/src/io/openems/api/channel/thingstate/ThingStateChannels.java +++ b/edge/src/io/openems/api/channel/thingstate/ThingStateChannels.java @@ -9,13 +9,14 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ChannelChangeListener; import io.openems.api.channel.ReadChannel; +import io.openems.api.channel.ThingStateChannel; import io.openems.api.exception.ConfigException; import io.openems.api.thing.Thing; public class ThingStateChannels extends ReadChannel implements ChannelChangeListener { - private List> warningChannels; - private List> faultChannels; + private List warningChannels; + private List faultChannels; private List childChannels; private Set channelNames; @@ -28,7 +29,7 @@ public ThingStateChannels(Thing parent){ updateState(); } - public void addWarningChannel(ReadChannel channel) throws ConfigException { + public void addWarningChannel(ThingStateChannel channel) throws ConfigException { if (!this.channelNames.contains(channel.address())) { this.warningChannels.add(channel); this.channelNames.add(channel.address()); @@ -39,14 +40,14 @@ public void addWarningChannel(ReadChannel channel) throws ConfigExcepti } } - public void removeWarningChannel(ReadChannel channel) { + public void removeWarningChannel(ThingStateChannel channel) { channel.removeChangeListener(this); this.channelNames.remove(channel.address()); this.warningChannels.remove(channel); updateState(); } - public void addFaultChannel(ReadChannel channel) throws ConfigException { + public void addFaultChannel(ThingStateChannel channel) throws ConfigException { if (!this.channelNames.contains(channel.address())) { this.faultChannels.add(channel); this.channelNames.add(channel.address()); @@ -57,15 +58,15 @@ public void addFaultChannel(ReadChannel channel) throws ConfigException } } - public void removeFaultChannel(ReadChannel channel) { + public void removeFaultChannel(ThingStateChannel channel) { channel.removeChangeListener(this); this.channelNames.remove(channel.address()); this.faultChannels.remove(channel); updateState(); } - public List> getWarningChannels() { - List> warningChannels = new ArrayList<>(); + public List getWarningChannels() { + List warningChannels = new ArrayList<>(); warningChannels.addAll(this.warningChannels); for(ThingStateChannels child : this.childChannels) { warningChannels.addAll(child.getWarningChannels()); @@ -73,8 +74,8 @@ public List> getWarningChannels() { return warningChannels; } - public List> getFaultChannels() { - List> faultChannels = new ArrayList<>(); + public List getFaultChannels() { + List faultChannels = new ArrayList<>(); faultChannels.addAll(this.faultChannels); for(ThingStateChannels child : this.childChannels) { faultChannels.addAll(child.getFaultChannels()); @@ -114,13 +115,13 @@ private void updateState() { } } } - for (ReadChannel faultChannel : faultChannels) { + for (ThingStateChannel faultChannel : faultChannels) { if (faultChannel.isValuePresent() && faultChannel.getValue()) { updateValue(ThingState.FAULT); return; } } - for (ReadChannel warningChannel : warningChannels) { + for (ThingStateChannel warningChannel : warningChannels) { if (warningChannel.isValuePresent() && warningChannel.getValue()) { updateValue(ThingState.WARNING); return; diff --git a/edge/src/io/openems/impl/device/pro/FeneconProPvMeter.java b/edge/src/io/openems/impl/device/pro/FeneconProPvMeter.java index 7f3726fa6a9..69ed31432e4 100644 --- a/edge/src/io/openems/impl/device/pro/FeneconProPvMeter.java +++ b/edge/src/io/openems/impl/device/pro/FeneconProPvMeter.java @@ -23,7 +23,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.FunctionalReadChannel; import io.openems.api.channel.ReadChannel; -import io.openems.api.channel.StaticValueChannel; +import io.openems.api.channel.StaticThingStateChannel; import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; import io.openems.api.device.nature.meter.AsymmetricMeterNature; @@ -49,11 +49,11 @@ public class FeneconProPvMeter extends ModbusDeviceNature implements AsymmetricM public FeneconProPvMeter(String thingId, Device parent) throws ConfigException { super(thingId, parent); this.thingState = new ThingStateChannels(this); - this.negativePowerL1 = new StaticValueChannel(WarningPvMeter.NegativePowerL1.getChannelId(), this, false); + this.negativePowerL1 = new StaticThingStateChannel(WarningPvMeter.NegativePowerL1.getChannelId(), this, false); this.thingState.addWarningChannel(this.negativePowerL1); - this.negativePowerL2 = new StaticValueChannel(WarningPvMeter.NegativePowerL2.getChannelId(), this, false); + this.negativePowerL2 = new StaticThingStateChannel(WarningPvMeter.NegativePowerL2.getChannelId(), this, false); this.thingState.addWarningChannel(this.negativePowerL2); - this.negativePowerL3 = new StaticValueChannel(WarningPvMeter.NegativePowerL3.getChannelId(), this, false); + this.negativePowerL3 = new StaticThingStateChannel(WarningPvMeter.NegativePowerL3.getChannelId(), this, false); this.thingState.addWarningChannel(this.negativePowerL3); } @@ -104,9 +104,9 @@ public ConfigChannel minActivePower() { private ModbusReadChannel orginalActivePowerL2; private ModbusReadChannel orginalActivePowerL3; private ThingStateChannels thingState; - private StaticValueChannel negativePowerL1; - private StaticValueChannel negativePowerL2; - private StaticValueChannel negativePowerL3; + private StaticThingStateChannel negativePowerL1; + private StaticThingStateChannel negativePowerL2; + private StaticThingStateChannel negativePowerL3; @Override public ReadChannel activePowerL1() { diff --git a/edge/src/io/openems/impl/protocol/modbus/ModbusRtu.java b/edge/src/io/openems/impl/protocol/modbus/ModbusRtu.java index fdb94ababf8..2e99b70d096 100644 --- a/edge/src/io/openems/impl/protocol/modbus/ModbusRtu.java +++ b/edge/src/io/openems/impl/protocol/modbus/ModbusRtu.java @@ -31,7 +31,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ChannelUpdateListener; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.StaticValueChannel; +import io.openems.api.channel.StaticThingStateChannel; import io.openems.api.device.Device; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; @@ -75,14 +75,14 @@ public void channelUpdated(Channel channel, Optional newValue) { * Fields */ private Optional connection = Optional.empty(); - private StaticValueChannel configurationFault; - private StaticValueChannel connectionFault; + private StaticThingStateChannel configurationFault; + private StaticThingStateChannel connectionFault; public ModbusRtu() throws ConfigException { super(); - this.configurationFault = new StaticValueChannel("Fault\0", this, false); + this.configurationFault = new StaticThingStateChannel("Fault\0", this, false); super.thingState.addFaultChannel(this.configurationFault); - this.connectionFault = new StaticValueChannel("Fault\1", this, false); + this.connectionFault = new StaticThingStateChannel("Fault\1", this, false); super.thingState.addFaultChannel(this.connectionFault); } diff --git a/edge/src/io/openems/impl/protocol/modbus/ModbusTcp.java b/edge/src/io/openems/impl/protocol/modbus/ModbusTcp.java index f1d03ff7c7b..121d7e89c18 100644 --- a/edge/src/io/openems/impl/protocol/modbus/ModbusTcp.java +++ b/edge/src/io/openems/impl/protocol/modbus/ModbusTcp.java @@ -33,7 +33,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ChannelUpdateListener; import io.openems.api.channel.ConfigChannel; -import io.openems.api.channel.StaticValueChannel; +import io.openems.api.channel.StaticThingStateChannel; import io.openems.api.device.Device; import io.openems.api.doc.ChannelInfo; import io.openems.api.doc.ThingInfo; @@ -68,14 +68,14 @@ public void channelUpdated(Channel channel, Optional newValue) { private static Logger log = LoggerFactory.getLogger(ModbusTcp.class); private Optional connection = Optional.empty(); - private StaticValueChannel configurationFault; - private StaticValueChannel connectionFault; + private StaticThingStateChannel configurationFault; + private StaticThingStateChannel connectionFault; public ModbusTcp() throws ConfigException { super(); - this.configurationFault = new StaticValueChannel("Fault\0", this, false); + this.configurationFault = new StaticThingStateChannel("Fault\0", this, false); super.thingState.addFaultChannel(this.configurationFault); - this.connectionFault = new StaticValueChannel("Fault\1", this, false); + this.connectionFault = new StaticThingStateChannel("Fault\1", this, false); super.thingState.addFaultChannel(this.connectionFault); } From 5d665b19e8f95b7d3942b797cbdd485d5c154e40 Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Thu, 15 Feb 2018 10:50:28 +0100 Subject: [PATCH 48/55] Rename ValueToBooleanChannel to ValueToBooleanThingStateChannel --- ...annel.java => ValueToBooleanThingStateChannel.java} | 4 ++-- edge/src/io/openems/impl/device/pro/FeneconProEss.java | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) rename edge/src/io/openems/api/channel/{ValueToBooleanChannel.java => ValueToBooleanThingStateChannel.java} (71%) diff --git a/edge/src/io/openems/api/channel/ValueToBooleanChannel.java b/edge/src/io/openems/api/channel/ValueToBooleanThingStateChannel.java similarity index 71% rename from edge/src/io/openems/api/channel/ValueToBooleanChannel.java rename to edge/src/io/openems/api/channel/ValueToBooleanThingStateChannel.java index f2a017ce0db..f32d1a50382 100644 --- a/edge/src/io/openems/api/channel/ValueToBooleanChannel.java +++ b/edge/src/io/openems/api/channel/ValueToBooleanThingStateChannel.java @@ -4,12 +4,12 @@ import io.openems.api.thing.Thing; -public class ValueToBooleanChannel extends ThingStateChannel implements ChannelChangeListener{ +public class ValueToBooleanThingStateChannel extends ThingStateChannel implements ChannelChangeListener{ private ReadChannel valueChannel; private long value; - public ValueToBooleanChannel(String id, Thing parent, ReadChannel channel, long value) { + public ValueToBooleanThingStateChannel(String id, Thing parent, ReadChannel channel, long value) { super(id, parent); this.valueChannel = channel; this.valueChannel.addChangeListener(this); diff --git a/edge/src/io/openems/impl/device/pro/FeneconProEss.java b/edge/src/io/openems/impl/device/pro/FeneconProEss.java index 06853dea986..70d8d16baa9 100644 --- a/edge/src/io/openems/impl/device/pro/FeneconProEss.java +++ b/edge/src/io/openems/impl/device/pro/FeneconProEss.java @@ -27,7 +27,7 @@ import io.openems.api.channel.FunctionalReadChannel; import io.openems.api.channel.ReadChannel; import io.openems.api.channel.StaticValueChannel; -import io.openems.api.channel.ValueToBooleanChannel; +import io.openems.api.channel.ValueToBooleanThingStateChannel; import io.openems.api.channel.WriteChannel; import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.device.Device; @@ -760,11 +760,11 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { }, phaseAllowedApparent); // FaultChannels - state.addFaultChannel(new ValueToBooleanChannel(FaultEss.SystemFault.getChannelId(), this, systemState, 3L)); - state.addFaultChannel(new ValueToBooleanChannel(FaultEss.BatteryFault.getChannelId(), this, batteryGroupState, 5L)); - state.addFaultChannel(new ValueToBooleanChannel(FaultEss.PCSFault.getChannelId(), this, pcsOperationState, 5L)); + state.addFaultChannel(new ValueToBooleanThingStateChannel(FaultEss.SystemFault.getChannelId(), this, systemState, 3L)); + state.addFaultChannel(new ValueToBooleanThingStateChannel(FaultEss.BatteryFault.getChannelId(), this, batteryGroupState, 5L)); + state.addFaultChannel(new ValueToBooleanThingStateChannel(FaultEss.PCSFault.getChannelId(), this, pcsOperationState, 5L)); // WarningChannels - state.addWarningChannel(new ValueToBooleanChannel(WarningEss.OFFGrid.getChannelId(), this, systemState, 1L)); + state.addWarningChannel(new ValueToBooleanThingStateChannel(WarningEss.OFFGrid.getChannelId(), this, systemState, 1L)); return protokol; } From 194def7ae16ee8272da21075aae2669e72500794 Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Thu, 15 Feb 2018 10:53:50 +0100 Subject: [PATCH 49/55] ValueToBooleanThingStateChannel requires ThingStateEnum --- .../api/channel/ValueToBooleanThingStateChannel.java | 5 +++-- .../src/io/openems/api/channel/thingstate/FaultEnum.java | 7 ++++--- .../openems/api/channel/thingstate/ThingStateEnum.java | 9 +++++++++ .../io/openems/api/channel/thingstate/WarningEnum.java | 7 ++++--- edge/src/io/openems/impl/device/pro/FeneconProEss.java | 8 ++++---- 5 files changed, 24 insertions(+), 12 deletions(-) create mode 100644 edge/src/io/openems/api/channel/thingstate/ThingStateEnum.java diff --git a/edge/src/io/openems/api/channel/ValueToBooleanThingStateChannel.java b/edge/src/io/openems/api/channel/ValueToBooleanThingStateChannel.java index f32d1a50382..d2ffce80401 100644 --- a/edge/src/io/openems/api/channel/ValueToBooleanThingStateChannel.java +++ b/edge/src/io/openems/api/channel/ValueToBooleanThingStateChannel.java @@ -2,6 +2,7 @@ import java.util.Optional; +import io.openems.api.channel.thingstate.ThingStateEnum; import io.openems.api.thing.Thing; public class ValueToBooleanThingStateChannel extends ThingStateChannel implements ChannelChangeListener{ @@ -9,8 +10,8 @@ public class ValueToBooleanThingStateChannel extends ThingStateChannel implement private ReadChannel valueChannel; private long value; - public ValueToBooleanThingStateChannel(String id, Thing parent, ReadChannel channel, long value) { - super(id, parent); + public ValueToBooleanThingStateChannel(ThingStateEnum state, Thing parent, ReadChannel channel, long value) { + super(state.getChannelId(), parent); this.valueChannel = channel; this.valueChannel.addChangeListener(this); this.value = value; diff --git a/edge/src/io/openems/api/channel/thingstate/FaultEnum.java b/edge/src/io/openems/api/channel/thingstate/FaultEnum.java index b43a5ab34f5..47d0155d0e3 100644 --- a/edge/src/io/openems/api/channel/thingstate/FaultEnum.java +++ b/edge/src/io/openems/api/channel/thingstate/FaultEnum.java @@ -1,9 +1,10 @@ package io.openems.api.channel.thingstate; -public interface FaultEnum { - int getValue(); +public interface FaultEnum extends ThingStateEnum { + @Override default String getChannelId() { - return "Fault/"+this.getValue(); + return "Fault/" + this.getValue(); } + } diff --git a/edge/src/io/openems/api/channel/thingstate/ThingStateEnum.java b/edge/src/io/openems/api/channel/thingstate/ThingStateEnum.java new file mode 100644 index 00000000000..0fdf8f6a7b1 --- /dev/null +++ b/edge/src/io/openems/api/channel/thingstate/ThingStateEnum.java @@ -0,0 +1,9 @@ +package io.openems.api.channel.thingstate; + +public interface ThingStateEnum { + + int getValue(); + + String getChannelId(); + +} diff --git a/edge/src/io/openems/api/channel/thingstate/WarningEnum.java b/edge/src/io/openems/api/channel/thingstate/WarningEnum.java index a3fedf985be..f297152412e 100644 --- a/edge/src/io/openems/api/channel/thingstate/WarningEnum.java +++ b/edge/src/io/openems/api/channel/thingstate/WarningEnum.java @@ -1,9 +1,10 @@ package io.openems.api.channel.thingstate; -public interface WarningEnum { - int getValue(); +public interface WarningEnum extends ThingStateEnum { + @Override default String getChannelId() { - return "Warning/"+this.getValue(); + return "Warning/" + this.getValue(); } + } diff --git a/edge/src/io/openems/impl/device/pro/FeneconProEss.java b/edge/src/io/openems/impl/device/pro/FeneconProEss.java index 70d8d16baa9..ac5254c46a7 100644 --- a/edge/src/io/openems/impl/device/pro/FeneconProEss.java +++ b/edge/src/io/openems/impl/device/pro/FeneconProEss.java @@ -760,11 +760,11 @@ protected ModbusProtocol defineModbusProtocol() throws ConfigException { }, phaseAllowedApparent); // FaultChannels - state.addFaultChannel(new ValueToBooleanThingStateChannel(FaultEss.SystemFault.getChannelId(), this, systemState, 3L)); - state.addFaultChannel(new ValueToBooleanThingStateChannel(FaultEss.BatteryFault.getChannelId(), this, batteryGroupState, 5L)); - state.addFaultChannel(new ValueToBooleanThingStateChannel(FaultEss.PCSFault.getChannelId(), this, pcsOperationState, 5L)); + state.addFaultChannel(new ValueToBooleanThingStateChannel(FaultEss.SystemFault, this, systemState, 3L)); + state.addFaultChannel(new ValueToBooleanThingStateChannel(FaultEss.BatteryFault, this, batteryGroupState, 5L)); + state.addFaultChannel(new ValueToBooleanThingStateChannel(FaultEss.PCSFault, this, pcsOperationState, 5L)); // WarningChannels - state.addWarningChannel(new ValueToBooleanThingStateChannel(WarningEss.OFFGrid.getChannelId(), this, systemState, 1L)); + state.addWarningChannel(new ValueToBooleanThingStateChannel(WarningEss.OFFGrid, this, systemState, 1L)); return protokol; } From a35a4295b93d6ad5d7146bef36736f55e58db5b0 Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Thu, 15 Feb 2018 10:56:35 +0100 Subject: [PATCH 50/55] BitToBooleanThingStateChannel requires ThingStateEnum --- ...annel.java => BitToBooleanThingStateChannel.java} | 7 ++++--- .../protocol/modbus/ModbusBitWrappingChannel.java | 12 +++++------- 2 files changed, 9 insertions(+), 10 deletions(-) rename edge/src/io/openems/api/channel/{BitToBooleanChannel.java => BitToBooleanThingStateChannel.java} (63%) diff --git a/edge/src/io/openems/api/channel/BitToBooleanChannel.java b/edge/src/io/openems/api/channel/BitToBooleanThingStateChannel.java similarity index 63% rename from edge/src/io/openems/api/channel/BitToBooleanChannel.java rename to edge/src/io/openems/api/channel/BitToBooleanThingStateChannel.java index 0921e86cefe..23664afc713 100644 --- a/edge/src/io/openems/api/channel/BitToBooleanChannel.java +++ b/edge/src/io/openems/api/channel/BitToBooleanThingStateChannel.java @@ -2,15 +2,16 @@ import java.util.Optional; +import io.openems.api.channel.thingstate.ThingStateEnum; import io.openems.api.thing.Thing; -public class BitToBooleanChannel extends ThingStateChannel implements ChannelChangeListener{ +public class BitToBooleanThingStateChannel extends ThingStateChannel implements ChannelChangeListener{ private ReadChannel valueChannel; private int bitIndex; - public BitToBooleanChannel(String id, Thing parent, ReadChannel channel, int bitIndex){ - super(id, parent); + public BitToBooleanThingStateChannel(ThingStateEnum state, Thing parent, ReadChannel channel, int bitIndex){ + super(state.getChannelId(), parent); this.valueChannel = channel; this.valueChannel.addChangeListener(this); this.bitIndex = bitIndex; diff --git a/edge/src/io/openems/impl/protocol/modbus/ModbusBitWrappingChannel.java b/edge/src/io/openems/impl/protocol/modbus/ModbusBitWrappingChannel.java index a8cb1fa0f26..e973cd6e74a 100644 --- a/edge/src/io/openems/impl/protocol/modbus/ModbusBitWrappingChannel.java +++ b/edge/src/io/openems/impl/protocol/modbus/ModbusBitWrappingChannel.java @@ -20,7 +20,7 @@ *******************************************************************************/ package io.openems.impl.protocol.modbus; -import io.openems.api.channel.BitToBooleanChannel; +import io.openems.api.channel.BitToBooleanThingStateChannel; import io.openems.api.channel.thingstate.FaultEnum; import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.channel.thingstate.WarningEnum; @@ -36,15 +36,13 @@ public ModbusBitWrappingChannel(String id, DeviceNature nature, ThingStateChanne this.thingState = thingStateChannel; } - public ModbusBitWrappingChannel warningBit(int bitIndex,WarningEnum warningCode) throws ConfigException { - thingState.addWarningChannel( - new BitToBooleanChannel(warningCode.getChannelId(), this.parent(), this, bitIndex)); + public ModbusBitWrappingChannel warningBit(int bitIndex, WarningEnum warningCode) throws ConfigException { + thingState.addWarningChannel(new BitToBooleanThingStateChannel(warningCode, this.parent(), this, bitIndex)); return this; } - public ModbusBitWrappingChannel faultBit( int bitIndex,FaultEnum faultCode) throws ConfigException { - thingState.addFaultChannel( - new BitToBooleanChannel(faultCode.getChannelId(), this.parent(), this, bitIndex)); + public ModbusBitWrappingChannel faultBit(int bitIndex, FaultEnum faultCode) throws ConfigException { + thingState.addFaultChannel(new BitToBooleanThingStateChannel(faultCode, this.parent(), this, bitIndex)); return this; } From 3b04fb46f0c6a2de3c6fe8d9527f19ecdbba40bf Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Thu, 15 Feb 2018 11:06:43 +0100 Subject: [PATCH 51/55] ThingStateChannel requires ThingStateEnum --- .../BitToBooleanThingStateChannel.java | 2 +- .../api/channel/StaticThingStateChannel.java | 5 +++-- .../api/channel/ThingStateChannel.java | 11 +++++++++-- .../ValueToBooleanThingStateChannel.java | 2 +- .../impl/device/pro/FeneconProPvMeter.java | 6 +++--- .../simulator/SimulatorSymmetricEss.java | 7 +++++++ .../impl/protocol/modbus/FaultModbus.java | 19 +++++++++++++++++++ .../impl/protocol/modbus/ModbusRtu.java | 4 ++-- .../impl/protocol/modbus/ModbusTcp.java | 4 ++-- 9 files changed, 47 insertions(+), 13 deletions(-) create mode 100644 edge/src/io/openems/impl/protocol/modbus/FaultModbus.java diff --git a/edge/src/io/openems/api/channel/BitToBooleanThingStateChannel.java b/edge/src/io/openems/api/channel/BitToBooleanThingStateChannel.java index 23664afc713..dc3b640b0f8 100644 --- a/edge/src/io/openems/api/channel/BitToBooleanThingStateChannel.java +++ b/edge/src/io/openems/api/channel/BitToBooleanThingStateChannel.java @@ -11,7 +11,7 @@ public class BitToBooleanThingStateChannel extends ThingStateChannel implements private int bitIndex; public BitToBooleanThingStateChannel(ThingStateEnum state, Thing parent, ReadChannel channel, int bitIndex){ - super(state.getChannelId(), parent); + super(state, parent); this.valueChannel = channel; this.valueChannel.addChangeListener(this); this.bitIndex = bitIndex; diff --git a/edge/src/io/openems/api/channel/StaticThingStateChannel.java b/edge/src/io/openems/api/channel/StaticThingStateChannel.java index 58d4b93034b..341b8b04138 100644 --- a/edge/src/io/openems/api/channel/StaticThingStateChannel.java +++ b/edge/src/io/openems/api/channel/StaticThingStateChannel.java @@ -20,12 +20,13 @@ *******************************************************************************/ package io.openems.api.channel; +import io.openems.api.channel.thingstate.ThingStateEnum; import io.openems.api.thing.Thing; public class StaticThingStateChannel extends ThingStateChannel { - public StaticThingStateChannel(String id, Thing parent, boolean value) { - super(id, parent); + public StaticThingStateChannel(ThingStateEnum state, Thing parent, boolean value) { + super(state, parent); this.updateValue(value); } diff --git a/edge/src/io/openems/api/channel/ThingStateChannel.java b/edge/src/io/openems/api/channel/ThingStateChannel.java index 0218126501b..5584efde9ea 100644 --- a/edge/src/io/openems/api/channel/ThingStateChannel.java +++ b/edge/src/io/openems/api/channel/ThingStateChannel.java @@ -1,11 +1,18 @@ package io.openems.api.channel; +import io.openems.api.channel.thingstate.ThingStateEnum; import io.openems.api.thing.Thing; public class ThingStateChannel extends ReadChannel { - public ThingStateChannel(String id, Thing parent) { - super(id, parent); + private final ThingStateEnum state; + + public ThingStateChannel(ThingStateEnum state, Thing parent) { + super(state.getChannelId(), parent); + this.state = state; } + public String name() { + return this.state.toString(); + } } diff --git a/edge/src/io/openems/api/channel/ValueToBooleanThingStateChannel.java b/edge/src/io/openems/api/channel/ValueToBooleanThingStateChannel.java index d2ffce80401..338fc7a9073 100644 --- a/edge/src/io/openems/api/channel/ValueToBooleanThingStateChannel.java +++ b/edge/src/io/openems/api/channel/ValueToBooleanThingStateChannel.java @@ -11,7 +11,7 @@ public class ValueToBooleanThingStateChannel extends ThingStateChannel implement private long value; public ValueToBooleanThingStateChannel(ThingStateEnum state, Thing parent, ReadChannel channel, long value) { - super(state.getChannelId(), parent); + super(state, parent); this.valueChannel = channel; this.valueChannel.addChangeListener(this); this.value = value; diff --git a/edge/src/io/openems/impl/device/pro/FeneconProPvMeter.java b/edge/src/io/openems/impl/device/pro/FeneconProPvMeter.java index 69ed31432e4..db2abfed4c0 100644 --- a/edge/src/io/openems/impl/device/pro/FeneconProPvMeter.java +++ b/edge/src/io/openems/impl/device/pro/FeneconProPvMeter.java @@ -49,11 +49,11 @@ public class FeneconProPvMeter extends ModbusDeviceNature implements AsymmetricM public FeneconProPvMeter(String thingId, Device parent) throws ConfigException { super(thingId, parent); this.thingState = new ThingStateChannels(this); - this.negativePowerL1 = new StaticThingStateChannel(WarningPvMeter.NegativePowerL1.getChannelId(), this, false); + this.negativePowerL1 = new StaticThingStateChannel(WarningPvMeter.NegativePowerL1, this, false); this.thingState.addWarningChannel(this.negativePowerL1); - this.negativePowerL2 = new StaticThingStateChannel(WarningPvMeter.NegativePowerL2.getChannelId(), this, false); + this.negativePowerL2 = new StaticThingStateChannel(WarningPvMeter.NegativePowerL2, this, false); this.thingState.addWarningChannel(this.negativePowerL2); - this.negativePowerL3 = new StaticThingStateChannel(WarningPvMeter.NegativePowerL3.getChannelId(), this, false); + this.negativePowerL3 = new StaticThingStateChannel(WarningPvMeter.NegativePowerL3, this, false); this.thingState.addWarningChannel(this.negativePowerL3); } diff --git a/edge/src/io/openems/impl/device/simulator/SimulatorSymmetricEss.java b/edge/src/io/openems/impl/device/simulator/SimulatorSymmetricEss.java index 8c5a495c590..37bf03422cc 100644 --- a/edge/src/io/openems/impl/device/simulator/SimulatorSymmetricEss.java +++ b/edge/src/io/openems/impl/device/simulator/SimulatorSymmetricEss.java @@ -35,6 +35,7 @@ import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.FunctionalReadChannel; import io.openems.api.channel.ReadChannel; +import io.openems.api.channel.StaticThingStateChannel; import io.openems.api.channel.StaticValueChannel; import io.openems.api.channel.WriteChannel; import io.openems.api.channel.thingstate.ThingStateChannels; @@ -50,6 +51,7 @@ import io.openems.core.ThingRepository; import io.openems.core.utilities.AvgFiFoQueue; import io.openems.core.utilities.ControllerUtils; +import io.openems.impl.protocol.modbus.FaultModbus; import io.openems.impl.protocol.modbus.ModbusWriteLongChannel; import io.openems.impl.protocol.simulator.SimulatorDeviceNature; import io.openems.impl.protocol.simulator.SimulatorReadChannel; @@ -79,6 +81,11 @@ public class SimulatorSymmetricEss extends SimulatorDeviceNature implements Symm public SimulatorSymmetricEss(String thingId, Device parent) throws ConfigException { super(thingId, parent); this.thingState = new ThingStateChannels(this); + + StaticThingStateChannel tmp = new StaticThingStateChannel(FaultModbus.ConfigurationFault, this, false); + tmp.setValue(true); + thingState.addFaultChannel(tmp); + minSoc.addUpdateListener((channel, newValue) -> { // If chargeSoc was not set -> set it to minSoc minus 2 if (channel == minSoc && !chargeSoc.valueOptional().isPresent()) { diff --git a/edge/src/io/openems/impl/protocol/modbus/FaultModbus.java b/edge/src/io/openems/impl/protocol/modbus/FaultModbus.java new file mode 100644 index 00000000000..71624781ade --- /dev/null +++ b/edge/src/io/openems/impl/protocol/modbus/FaultModbus.java @@ -0,0 +1,19 @@ +package io.openems.impl.protocol.modbus; + +import io.openems.api.channel.thingstate.FaultEnum; + +public enum FaultModbus implements FaultEnum { + ConfigurationFault(0), + ConnectionFault(1); + + private final int value; + + private FaultModbus(int value) { + this.value = value; + } + + @Override + public int getValue() { + return this.value; + } +} diff --git a/edge/src/io/openems/impl/protocol/modbus/ModbusRtu.java b/edge/src/io/openems/impl/protocol/modbus/ModbusRtu.java index 2e99b70d096..568d4500d55 100644 --- a/edge/src/io/openems/impl/protocol/modbus/ModbusRtu.java +++ b/edge/src/io/openems/impl/protocol/modbus/ModbusRtu.java @@ -80,9 +80,9 @@ public void channelUpdated(Channel channel, Optional newValue) { public ModbusRtu() throws ConfigException { super(); - this.configurationFault = new StaticThingStateChannel("Fault\0", this, false); + this.configurationFault = new StaticThingStateChannel(FaultModbus.ConfigurationFault, this, false); super.thingState.addFaultChannel(this.configurationFault); - this.connectionFault = new StaticThingStateChannel("Fault\1", this, false); + this.connectionFault = new StaticThingStateChannel(FaultModbus.ConnectionFault, this, false); super.thingState.addFaultChannel(this.connectionFault); } diff --git a/edge/src/io/openems/impl/protocol/modbus/ModbusTcp.java b/edge/src/io/openems/impl/protocol/modbus/ModbusTcp.java index 121d7e89c18..65d8b984da0 100644 --- a/edge/src/io/openems/impl/protocol/modbus/ModbusTcp.java +++ b/edge/src/io/openems/impl/protocol/modbus/ModbusTcp.java @@ -73,9 +73,9 @@ public void channelUpdated(Channel channel, Optional newValue) { public ModbusTcp() throws ConfigException { super(); - this.configurationFault = new StaticThingStateChannel("Fault\0", this, false); + this.configurationFault = new StaticThingStateChannel(FaultModbus.ConfigurationFault, this, false); super.thingState.addFaultChannel(this.configurationFault); - this.connectionFault = new StaticThingStateChannel("Fault\1", this, false); + this.connectionFault = new StaticThingStateChannel(FaultModbus.ConnectionFault, this, false); super.thingState.addFaultChannel(this.connectionFault); } From 3b71a7e629333f0785d722e5e72b819492773b56 Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Thu, 15 Feb 2018 11:11:54 +0100 Subject: [PATCH 52/55] DebugLog shows Warnings and Faults as strings --- .../openems/impl/controller/debuglog/Ess.java | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/edge/src/io/openems/impl/controller/debuglog/Ess.java b/edge/src/io/openems/impl/controller/debuglog/Ess.java index 8a85a48989e..5528f59362b 100644 --- a/edge/src/io/openems/impl/controller/debuglog/Ess.java +++ b/edge/src/io/openems/impl/controller/debuglog/Ess.java @@ -23,7 +23,7 @@ import java.util.List; import java.util.stream.Collectors; -import io.openems.api.channel.ReadChannel; +import io.openems.api.channel.ThingStateChannel; import io.openems.api.controller.IsThingMap; import io.openems.api.controller.ThingMap; import io.openems.api.device.nature.ess.AsymmetricEssNature; @@ -82,19 +82,15 @@ public Ess(EssNature ess) { "Allowed:" + ess.allowedCharge().format() + ";" + ess.allowedDischarge().format()); b.append("|" + // "GridMode:" + ess.gridMode().labelOptional().orElse("unknown")); - List> warningChannels = ess.getStateChannel().getWarningChannels().stream().filter(c -> c.isValuePresent() && c.getValue()).collect(Collectors.toList()); - List> faultChannels = ess.getStateChannel().getFaultChannels().stream().filter(c -> c.isValuePresent() && c.getValue()).collect(Collectors.toList()); + List warningChannels = ess.getStateChannel().getWarningChannels().stream().filter(c -> c.isValuePresent() && c.getValue()).collect(Collectors.toList()); + List faultChannels = ess.getStateChannel().getFaultChannels().stream().filter(c -> c.isValuePresent() && c.getValue()).collect(Collectors.toList()); if(warningChannels.size() > 0) { - b.append("|Warn: "); - for(ReadChannel warning : warningChannels) { - b.append(", "+warning.address()); - } + b.append("|Warn:"); + b.append(warningChannels.stream().map(c -> c.name()).collect(Collectors.joining())); } if(faultChannels.size() > 0) { - b.append("|Fault: "); - for(ReadChannel fault : faultChannels) { - b.append(", "+fault.address()); - } + b.append("|Fault:"); + b.append(faultChannels.stream().map(c -> c.name()).collect(Collectors.joining())); } b.append("]"); return b.toString(); From a6b208fd43625db7836ba0c86656799607beffef Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Thu, 15 Feb 2018 11:58:16 +0100 Subject: [PATCH 53/55] Add ThingStateChannels to systemstate controllers --- .../systemstate/alwayson/AlwaysOnController.java | 8 ++++++++ .../powerthreshold/ThresholdOnController.java | 9 +++++++++ .../controller/systemstate/time/TimeOnController.java | 8 ++++++++ 3 files changed, 25 insertions(+) diff --git a/edge/src/io/openems/impl/controller/systemstate/alwayson/AlwaysOnController.java b/edge/src/io/openems/impl/controller/systemstate/alwayson/AlwaysOnController.java index aa50064fc11..03f289edf9d 100644 --- a/edge/src/io/openems/impl/controller/systemstate/alwayson/AlwaysOnController.java +++ b/edge/src/io/openems/impl/controller/systemstate/alwayson/AlwaysOnController.java @@ -23,6 +23,7 @@ import java.util.Set; import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -36,6 +37,8 @@ @ThingInfo(title = "Keep always running", description = "Tries to keep the Ess always running. Use if Off-Grid functionality is required.") public class AlwaysOnController extends Controller { + private ThingStateChannels thingState = new ThingStateChannels(this); + /* * Constructors */ @@ -70,4 +73,9 @@ public void run() { log.error("No Storage Found!", e); } } + + @Override + public ThingStateChannels getStateChannel() { + return this.thingState; + } } diff --git a/edge/src/io/openems/impl/controller/systemstate/powerthreshold/ThresholdOnController.java b/edge/src/io/openems/impl/controller/systemstate/powerthreshold/ThresholdOnController.java index 1310fe90de0..8ab060903e9 100644 --- a/edge/src/io/openems/impl/controller/systemstate/powerthreshold/ThresholdOnController.java +++ b/edge/src/io/openems/impl/controller/systemstate/powerthreshold/ThresholdOnController.java @@ -25,6 +25,7 @@ import com.google.common.base.Optional; import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -39,6 +40,8 @@ @ThingInfo(title = "Stop if not useable", description = "Starts the ess if the GridFeed power is lager than a defined threshold. The ess will be stoped if the ess are empty and the GridFeed power is below a defined threshold.") public class ThresholdOnController extends Controller { + private ThingStateChannels thingState = new ThingStateChannels(this); + /* * Constructors */ @@ -77,6 +80,7 @@ public ThresholdOnController(String thingId) { /* * Methods */ + @SuppressWarnings("unlikely-arg-type") @Override public void run() { try { @@ -130,4 +134,9 @@ public void run() { log.error("No Storage Found!", e); } } + + @Override + public ThingStateChannels getStateChannel() { + return this.thingState; + } } diff --git a/edge/src/io/openems/impl/controller/systemstate/time/TimeOnController.java b/edge/src/io/openems/impl/controller/systemstate/time/TimeOnController.java index fd2ba843568..9881fbd6753 100644 --- a/edge/src/io/openems/impl/controller/systemstate/time/TimeOnController.java +++ b/edge/src/io/openems/impl/controller/systemstate/time/TimeOnController.java @@ -27,6 +27,7 @@ import io.openems.api.channel.Channel; import io.openems.api.channel.ChannelChangeListener; import io.openems.api.channel.ConfigChannel; +import io.openems.api.channel.thingstate.ThingStateChannels; import io.openems.api.controller.Controller; import io.openems.api.device.nature.ess.EssNature; import io.openems.api.doc.ChannelInfo; @@ -41,6 +42,8 @@ @ThingInfo(title = "Keep always running", description = "Tries to keep the Ess always running. Use if Off-Grid functionality is required.") public class TimeOnController extends Controller implements ChannelChangeListener { + private ThingStateChannels thingState = new ThingStateChannels(this); + /* * Constructors */ @@ -144,4 +147,9 @@ public void channelChanged(Channel channel, Optional newValue, Optional ol } } } + + @Override + public ThingStateChannels getStateChannel() { + return this.thingState; + } } From a3cf280c0467811c4b1f832fcc31c5630ef54200 Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Thu, 15 Feb 2018 13:22:41 +0100 Subject: [PATCH 54/55] Remove ResourceBundle for i18n --- edge/src/io/openems/impl/device/pro/FeneconProEss.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/edge/src/io/openems/impl/device/pro/FeneconProEss.java b/edge/src/io/openems/impl/device/pro/FeneconProEss.java index 55569e13dda..c43c7b82c39 100644 --- a/edge/src/io/openems/impl/device/pro/FeneconProEss.java +++ b/edge/src/io/openems/impl/device/pro/FeneconProEss.java @@ -20,9 +20,6 @@ *******************************************************************************/ package io.openems.impl.device.pro; -import java.util.Locale; -import java.util.ResourceBundle; - import io.openems.api.channel.ConfigChannel; import io.openems.api.channel.FunctionalReadChannel; import io.openems.api.channel.ReadChannel; @@ -63,7 +60,6 @@ public FeneconProEss(String thingId, Device parent) throws ConfigException { chargeSoc.updateValue((Integer) newValue.get() - 2, false); } }); - ResourceBundle.getBundle("Messages", Locale.GERMAN); } /* From ecb3d1c41afd79cc656dc6c592ef8db59cc07427 Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Thu, 15 Feb 2018 13:50:28 +0100 Subject: [PATCH 55/55] Push version to 2018.1 --- backend/pom.xml | 2 +- common/pom.xml | 2 +- edge/pom.xml | 2 +- ui/package-lock.json | 2 +- ui/package.json | 2 +- ui/pom.xml | 2 +- ui/src/app/about/about.component.html | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/backend/pom.xml b/backend/pom.xml index e5347760e34..2ba151c6933 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -5,7 +5,7 @@ http://openems.io io.openems edge - 1.8.0-SNAPSHOT + 2018.1 jar https://github.com/OpenEMS/openems diff --git a/common/pom.xml b/common/pom.xml index f70db0b716a..c634bbe3c82 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -5,7 +5,7 @@ http://openems.io io.openems common - 1.8.0-SNAPSHOT + 2018. jar https://github.com/OpenEMS/openems diff --git a/edge/pom.xml b/edge/pom.xml index 0f4117d0541..70345cc3340 100644 --- a/edge/pom.xml +++ b/edge/pom.xml @@ -5,7 +5,7 @@ http://openems.io io.openems edge - 1.8.0-SNAPSHOT + 2018.1 jar https://github.com/OpenEMS/openems diff --git a/ui/package-lock.json b/ui/package-lock.json index 93e0e809964..ffb13ea597d 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -1,6 +1,6 @@ { "name": "openems-ui", - "version": "1.8.0-SNAPSHOT", + "version": "2018.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/ui/package.json b/ui/package.json index bd024984051..4448a60e1d4 100644 --- a/ui/package.json +++ b/ui/package.json @@ -1,6 +1,6 @@ { "name": "openems-ui", - "version": "1.8.0-SNAPSHOT", + "version": "2018.1", "license": "AGPL", "scripts": { "ng": "ng", diff --git a/ui/pom.xml b/ui/pom.xml index e6c4ad5c1c9..b556cc90027 100644 --- a/ui/pom.xml +++ b/ui/pom.xml @@ -7,7 +7,7 @@ io.openems pom - 1.8.0-SNAPSHOT + 2018.1 edge pom diff --git a/ui/src/app/about/about.component.html b/ui/src/app/about/about.component.html index cfa0c59ecd2..eae7a2cdacf 100644 --- a/ui/src/app/about/about.component.html +++ b/ui/src/app/about/about.component.html @@ -22,7 +22,7 @@ -->
  • - About.Build: v1.8.0-SNAPSHOT + About.Build: v2018.1