diff --git a/.devenv/load-exports b/.devenv/load-exports new file mode 100755 index 00000000000..8b137891791 --- /dev/null +++ b/.devenv/load-exports @@ -0,0 +1 @@ + diff --git a/.devenv/profile b/.devenv/profile new file mode 120000 index 00000000000..fec948cda21 --- /dev/null +++ b/.devenv/profile @@ -0,0 +1 @@ +/nix/store/135785cwm28w1066rzgg1hf17cmxx6d4-devenv-profile \ No newline at end of file diff --git a/.devenv/run b/.devenv/run new file mode 120000 index 00000000000..6ddbc93244f --- /dev/null +++ b/.devenv/run @@ -0,0 +1 @@ +/run/user/1000/devenv-b212af5 \ No newline at end of file diff --git a/.devenv/state/files.json b/.devenv/state/files.json new file mode 100644 index 00000000000..b4c7443fe86 --- /dev/null +++ b/.devenv/state/files.json @@ -0,0 +1 @@ +{"managedFiles":[]} diff --git a/.devenv/tasks.db b/.devenv/tasks.db new file mode 100644 index 00000000000..a56fa3ecc46 Binary files /dev/null and b/.devenv/tasks.db differ diff --git a/.direnv/flake-profile b/.direnv/flake-profile new file mode 120000 index 00000000000..e2890795fb1 --- /dev/null +++ b/.direnv/flake-profile @@ -0,0 +1 @@ +flake-profile-4-link \ No newline at end of file diff --git a/.direnv/flake-profile-4-link b/.direnv/flake-profile-4-link new file mode 120000 index 00000000000..b913bd1efce --- /dev/null +++ b/.direnv/flake-profile-4-link @@ -0,0 +1 @@ +/nix/store/xcy1202wmq5a6c3nkbzq236g1zfg7aj1-devenv-shell-env \ No newline at end of file diff --git a/all_bnd.txt b/all_bnd.txt new file mode 100644 index 00000000000..0783282d54e --- /dev/null +++ b/all_bnd.txt @@ -0,0 +1,3575 @@ +Bundle-Name: OpenEMS Edge Electric Vehicle Supply Equipment (EVSE) Api +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.meter.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Heat Askoma +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.heat.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.timedata.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller IO Heating Element +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.io.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.timedata.api,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Controller Api Modbus/TCP +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.controller.api.common,\ + io.openems.edge.ess.api,\ + io.openems.edge.timedata.api,\ + io.openems.j2mod,\ + io.openems.wrapper.fastexcel,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Input/Output Api +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Battery Api +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller Ess Grid Optimized Charge +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.controller.ess.ripplecontrolreceiver,\ + io.openems.edge.energy.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.predictor.api,\ + io.openems.edge.timedata.api,\ + +-testpath: \ + ${testpath},\ + io.openems.edge.evcs.api,\ + org.apache.commons.math3,\ +Bundle-Name: OpenEMS Backend Metadata File +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.backend.common,\ + io.openems.common,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Backend Timedata Aggregated InfluxDB +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.backend.common,\ + io.openems.common,\ + io.openems.shared.influxdb,\ + io.openems.wrapper.influxdb-client-core,\ + io.openems.wrapper.influxdb-client-java,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Bridge OneWire +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +Export-Package: \ + com.dalsemi.onewire,\ + com.dalsemi.onewire.adapter,\ + com.dalsemi.onewire.application.file,\ + com.dalsemi.onewire.application.monitor,\ + com.dalsemi.onewire.application.sha,\ + com.dalsemi.onewire.application.tag,\ + com.dalsemi.onewire.container,\ + com.dalsemi.onewire.debug,\ + com.dalsemi.onewire.utils,\ + io.openems.edge.bridge.onewire + +-privatepackage: \ + io.openems.edge.bridge.onewire.impl,\ + io.openems.edge.bridge.onewire.jsonrpc + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge EVCS Webasto Unite +Bundle-Vendor: Consolinno Energy GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.evcs.api,\ + io.openems.edge.meter.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Controller Ess Active Power Voltage Characteristics +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.meter.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge FENECON Pro 9-12 +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.ess.api,\ + io.openems.edge.meter.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Core +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + com.fazecast.jSerialComm,\ + com.squareup.okhttp3,\ + io.openems.common,\ + io.openems.common.bridge.http,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.controller.api.backend,\ + io.openems.edge.energy.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.evcs.api,\ + io.openems.edge.evse.api,\ + io.openems.edge.io.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.predictor.api,\ + io.openems.edge.scheduler.api,\ + io.openems.edge.timedata.api,\ + io.openems.edge.timeofusetariff.api,\ + io.openems.wrapper.fastexcel,\ + io.openems.wrapper.sdnotify,\ + javax.jmdns,\ + +-testpath: \ + ${testpath},\ + io.openems.wrapper.fastexcel,\ + io.openems.wrapper.opczip,\ +Bundle-Name: OpenEMS Edge IO Weidmüller Fieldbus Coupler UR20 +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.io.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge SolarEdge +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.meter.api,\ + io.openems.edge.pvinverter.api,\ + +-testpath: \ + ${testpath},\ + io.openems.j2mod,\ +Bundle-Name: OpenEMS Edge EVCS Mennekes Amtron Professional +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.evcs.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.timedata.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller Asymmetric Peakshaving +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.meter.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Predictor Api +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} +Bundle-Description: \ + This bundle contains the Predictor API. It provides abstract access to prediction of production and consumption. + +-buildpath: \ + ${buildpath},\ + com.google.protobuf,\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.wrapper.olcut,\ + io.openems.wrapper.tribuo,\ + org.apache.commons.math3,\ + +-testpath: \ + ${testpath},\Bundle-Name: OpenEMS Edge Time-Of-Use Tariff Swisspower +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.common.bridge.http,\ + io.openems.edge.common,\ + io.openems.edge.timeofusetariff.api,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Controller Fast Frequency Reserve +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + Java-WebSocket,\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.meter.api,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge PV Inverter KACO blueplanet +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.meter.api,\ + io.openems.edge.pvinverter.api,\ + io.openems.edge.timedata.api,\ + +-testpath: \ + ${testpath},\ + io.openems.j2mod,\ +Bundle-Name: OpenEMS Edge Edge-2-Edge +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + Java-WebSocket,\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.ess.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.timedata.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Predictor Profile Clustering Model +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.predictor.api,\ + io.openems.edge.timedata.api,\ + org.apache.commons.math3,\ + +-testpath: \ + ${testpath},\ +Bundle-Name: OpenEMS Edge Controller ESS AC-Island +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.io.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Meter Camillebauer Aplus +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.meter.api,\ + io.openems.edge.timedata.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller IO Heating Room +Bundle-Vendor: OpenEMS Association e.V. +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.io.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.thermometer.api,\ + io.openems.edge.timedata.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Scheduler Fixed-Order +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.scheduler.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Simulator +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.battery.api,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.ess.api,\ + io.openems.edge.evcs.api,\ + io.openems.edge.io.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.predictor.api,\ + io.openems.edge.pvinverter.api,\ + io.openems.edge.thermometer.api,\ + io.openems.edge.timedata.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Backend Alerting +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.backend.common,\ + io.openems.common,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Backend-to-Backend REST-Api +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.backend.authentication.api,\ + io.openems.backend.common,\ + io.openems.common,\ + io.openems.wrapper.Java-WebSocket,\ + org.apache.felix.http.jetty12,\ + org.apache.felix.http.servlet-api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Battery Pylontech +Bundle-Vendor: RVR Energy Technology Ltd. +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.battery.api,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge EVCS Api +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.ess.api,\ + io.openems.edge.meter.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge ESS Refu88K +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.battery.api,\ + io.openems.edge.batteryinverter.api,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.ess.api,\ + io.openems.edge.timedata.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Time-Of-Use Ancillary Costs +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.timeofusetariff.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller IO SG-Ready Heat Pump +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.io.api,\ + io.openems.edge.timedata.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller Ess Hybrid Surplus-Feed-To-Grid +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller Api REST/JSON +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.controller.api.common,\ + io.openems.edge.timedata.api,\ + org.apache.felix.http.jetty12,\ + org.apache.felix.http.servlet-api,\ + +-testpath: \ + ${testpath},\ + io.openems.common.bridge.http,\ +Bundle-Name: Katek EDCOM Library +Bundle-Vendor: Katek Memmingen GmbH, FENECON GmbH +Bundle-License: https://opensource.org/licenses/LGPL-3.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + javax.jmdns,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Backend Edge-Manager +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} +Bundle-Description: Manager for connections from Backend Edge Applications + +-buildpath: \ + ${buildpath},\ + io.openems.backend.common,\ + io.openems.backend.metrics.prometheus,\ + io.openems.backend.oauthregistry,\ + io.openems.common,\ + io.openems.wrapper.Java-WebSocket,\ + io.prometheus.metrics-config,\ + io.prometheus.metrics-core,\ + io.prometheus.metrics-exporter-common,\ + io.prometheus.metrics-exporter-httpserver,\ + io.prometheus.metrics-exposition-formats,\ + io.prometheus.metrics-instrumentation-jvm,\ + io.prometheus.metrics-model,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Meter ABB +Bundle-Vendor: Consolinno Energy GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.mbus,\ + io.openems.edge.common,\ + io.openems.edge.meter.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Backend Authentication Api +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.backend.common,\ + io.openems.common,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge FENECON Mini +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.ess.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.timedata.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Controller API Common +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + Java-WebSocket,\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.timedata.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Bosch BPT-S 5 Hybrid +Bundle-Vendor: OpenEMS Association e.V. +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.ess.api,\ + io.openems.edge.meter.api,\ + org.eclipse.jetty.client,\ + org.eclipse.jetty.http,\ + org.eclipse.jetty.util,\ + org.jsoup,\ + +-testpath: \ + ${testpath},\ + org.eclipse.jetty.client,\ + org.eclipse.jetty.http,\ + org.eclipse.jetty.util,\ + org.eclipse.jetty.io,\ +Bundle-Name: OpenEMS Edge Controller Debug DetailedLog +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Bridge M-Bus +Bundle-Vendor: Consolinno Energy GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + org.openmuc.jmbus;version=3.3.0,\ + org.openmuc.jrxtx;version=1.0,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Battery FENECON Home +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.battery.api,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.io.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Controller Symmetric Timeslot-Peakshaving +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.meter.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller Asymmetric Phase-Rectification +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.meter.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Predictor Persistence-Model +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.predictor.api,\ + io.openems.edge.timedata.api,\ + org.apache.commons.math3,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Energy Api +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.evse.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.predictor.api,\ + io.openems.edge.timeofusetariff.api,\ + +-testpath: \ + ${testpath},\ +Bundle-Name: OpenEMS Edge Controller Ess Linear Power Band +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Backend Common +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Time-Of-Use Tariff Corrently by STROMDAO +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + com.squareup.okhttp3,\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.timeofusetariff.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge EVSE Charge-Point KEBA KeContact +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.evcs.api,\ + io.openems.edge.evse.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.timedata.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge GoodweET +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Vendor: FENECON GmbH +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + com.fazecast.jSerialComm,\ + io.openems.common,\ + io.openems.edge.battery.api,\ + io.openems.edge.battery.fenecon.home,\ + io.openems.edge.batteryinverter.api,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.controller.ess.ripplecontrolreceiver,\ + io.openems.edge.ess.api,\ + io.openems.edge.ess.generic,\ + io.openems.edge.meter.api,\ + io.openems.edge.timedata.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Meter Bgetech +Bundle-Vendor: OpenEMS Association e.V. +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.meter.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Backend Metadata Dummy +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.backend.common,\ + io.openems.common,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Shared InfluxDB +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + com.squareup.okhttp3,\ + io.openems.common,\ + io.openems.wrapper.influxdb-client-core,\ + io.openems.wrapper.influxdb-client-java,\ + io.openems.wrapper.influxdb-flux-dsl,\ + +-testpath: \ + ${testpath},\ + io.openems.wrapper.influxdb-client-utils,\ + +Bundle-Name: OpenEMS Edge Controller Api Websocket +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + Java-WebSocket,\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.controller.api.common,\ + io.openems.edge.timedata.api,\ + org.ops4j.pax.logging.pax-logging-api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge IO WAGO Fieldbus Coupler +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.ess.api,\ + io.openems.edge.io.api,\ + io.openems.edge.meter.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Meter Siemens +Bundle-Description: This implementation covers Siemens PAC1600/PAC2200/PAC3200/PAC4200 +Bundle-Vendor: Ernst KNOLL Feinmechanik GmbH (PAC2200/PAC3200/PAC4200) / Universität Bayreuth Lehrstuhl Elektrische Energiesysteme (PAC1600) +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.meter.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath} + +Bundle-Name: OpenEMS Edge Meter Weidmueller 525 +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.meter.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Time-Of-Use Tariff Stadtwerk Hassfurt +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.common.bridge.http,\ + io.openems.edge.common,\ + io.openems.edge.timeofusetariff.api,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Heat MyPv +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.heat.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.timedata.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Time-Of-Use Tariff rabot.charge +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.common.bridge.http,\ + io.openems.edge.common,\ + io.openems.edge.timeofusetariff.api,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge EVCS OpenWB +Bundle-Vendor: OpenEMS Association e.V. +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.mqtt,\ + io.openems.edge.common,\ + io.openems.edge.evcs.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.timedata.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Tesla Powerwall 2 +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.battery.api,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.ess.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Time-Of-Use Tariff Awattar +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + com.squareup.okhttp3,\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.timeofusetariff.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller Electric Vehicle Charging Station +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.evcs.api,\ + io.openems.edge.meter.api,\ + +-testpath: \ + ${testpath},\ +Bundle-Name: OpenEMS Backend Simulator +Bundle-Vendor: OpenEMS Association e.V. +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.backend.common,\ + io.openems.common,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller PV-Inverter Sell-to-Grid Limit +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.pvinverter.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Heat Api +Bundle-Vendor: OpenEMS Association e.V. +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge SMA +Bundle-Vendor: FENECON GmbH; OpenEMS Association e.V. +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.battery.api,\ + io.openems.edge.batteryinverter.api,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.ess.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.pvinverter.api,\ + io.openems.edge.timedata.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Timedata Api +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge BYD Battery-Box Commercial +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.battery.api,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.ess.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Backend Edge-Application +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} +Bundle-Description: Proxy between OpenEMS Edges and OpenEMS Backend + +-buildpath: \ + ${buildpath},\ + io.openems.backend.common,\ + io.openems.backend.metrics.prometheus,\ + io.openems.backend.oauthregistry,\ + io.openems.common,\ + io.openems.wrapper.Java-WebSocket,\ + io.prometheus.metrics-core,\ + io.prometheus.metrics-model,\ + +-testpath: \ + ${testpath},\ +Bundle-Name: OpenEMS Edge Bridge Http +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.common.bridge.http,\ + io.openems.edge.common,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller Asymmetric Fix-ReactivePower +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Weather Api +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + com.squareup.okio,\ + io.openems.common,\ + io.openems.edge.common,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge PV Inverter Solar Log +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.meter.api,\ + io.openems.edge.pvinverter.api,\ + io.openems.edge.timedata.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Meter Hager +Bundle-Vendor: +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.meter.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller IOAlarm +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Vendor: FENECON GmbH +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.io.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Common +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Controller IO Channel Single Threshold +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.io.api,\ + io.openems.edge.timedata.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge PV-Inverter Cluster +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.meter.api,\ + io.openems.edge.pvinverter.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Meter Virtual Add +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.ess.api,\ + io.openems.edge.meter.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller Symmetric Peak-Shaving +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.meter.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller for Ripple Control Receiver +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.timedata.api,\ + +-testpath: \ + ${testpath},\ + io.openems.edge.io.api,\ +Bundle-Name: OpenEMS Edge Controller Symmetric Balancing Schedule +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.meter.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge ESS Api +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge ESS Core +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.ess.api,\ + org.apache.commons.math3,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge BMW Battery +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.common.bridge.http,\ + io.openems.edge.battery.api,\ + io.openems.edge.bridge.http,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.io.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Thermometer Api +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} +Bundle-Description:\ + A Thermometer measures temperature. + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge System FENECON +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.battery.api,\ + io.openems.edge.battery.bmw,\ + io.openems.edge.batteryinverter.api,\ + io.openems.edge.batteryinverter.refu88k,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.controller.api.backend,\ + io.openems.edge.ess.api,\ + io.openems.edge.io.api,\ + io.openems.edge.timedata.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Controller IO FixDigitalOutput +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.io.api,\ + io.openems.edge.timedata.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller Ess Limit Total Discharge +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.energy.api,\ + io.openems.edge.ess.api,\ + +-testpath: \ + ${testpath},\ + org.apache.commons.math3,\ +Bundle-Name: OpenEMS Edge Time-Of-Use ENTSO-E +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + com.squareup.okhttp3,\ + com.squareup.okio,\ + io.openems.common,\ + io.openems.common.bridge.http,\ + io.openems.edge.common,\ + io.openems.edge.timeofusetariff.api,\ + +-testpath: \ + org.jetbrains.kotlin.osgi-bundle,\ + ${testpath} +Bundle-Name: OpenEMS Edge Controller PV-Inverter Fix-Power-Limit +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.pvinverter.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller CHP SOC +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.io.api,\ + io.openems.edge.timedata.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge EVCS Cluster +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.evcs.api,\ + io.openems.edge.meter.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Time-Of-Use Manual (Octopus Go/Heat) +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.timeofusetariff.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.wrapper.sdnotify,\ + +-testpath: \ + ${testpath} + Bundle-Name: OpenEMS Edge ABL eM4 +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.evcs.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.timedata.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Energy +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +# TODO remove emergencycapacityreserve, limittotaldischarge and limiter14a from buildpath after v1 + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.controller.ess.emergencycapacityreserve,\ + io.openems.edge.controller.ess.limiter14a,\ + io.openems.edge.controller.ess.limittotaldischarge,\ + io.openems.edge.controller.ess.timeofusetariff,\ + io.openems.edge.energy.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.predictor.api,\ + io.openems.edge.scheduler.api,\ + io.openems.edge.timedata.api,\ + io.openems.edge.timeofusetariff.api,\ + io.openems.wrapper.jenetics,\ + +-testpath: \ + ${testpath},\ + io.openems.edge.controller.ess.emergencycapacityreserve,\ + io.openems.edge.controller.ess.fixactivepower,\ + io.openems.edge.controller.ess.gridoptimizedcharge,\ + io.openems.edge.controller.ess.limittotaldischarge,\ + io.openems.edge.controller.ess.timeofusetariff,\ + io.openems.edge.controller.evse,\ + io.openems.edge.evse.api,\ + io.openems.edge.meter.api,\ +Bundle-Name: OpenEMS Edge Meter PQ Plus +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.meter.api,\ + io.openems.edge.timedata.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge IO Filipowski +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.io.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge IO Off Grid Switch +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.ess.api,\ + io.openems.edge.io.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge EVCS Go-e Charger Home +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.evcs.api,\ + io.openems.edge.meter.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Backend OAuth registry for edges to use +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.backend.common,\ + io.openems.common,\ + io.openems.common.bridge.http,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Meter Phoenix Contact +Bundle-Description: This implementation covers Phoenix Contact meter EEM-MA370-24DC and EEM-MB370-24DC +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.meter.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Battery-Inverter KACO blueplanet gridsave +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.battery.api,\ + io.openems.edge.batteryinverter.api,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.ess.api,\ + io.openems.edge.timedata.api,\ + +-testpath: \ + ${testpath},\ + io.openems.j2mod,\Bundle-Name: OpenEMS Edge ESS Sinexcel +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.battery.api,\ + io.openems.edge.batteryinverter.api,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.ess.api,\ + io.openems.edge.timedata.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge EVSE Charge-Point Hardy Barth +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.common.bridge.http,\ + io.openems.edge.bridge.http,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.evcs.api,\ + io.openems.edge.evse.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.timedata.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller Ess Emergency Capacity Reserve +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.energy.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.ess.generic,\ + +-testpath: \ + ${testpath},\ + org.apache.commons.math3,\ +Bundle-Name: OpenEMS Edge Scheduler Daily +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.scheduler.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Wrapper +Bundle-Description: This wraps external java libraries that do not have OSGi headers + +-sub: *.bnd +-buildpath: \ + com.github.rzymek:opczip;version='1.2.0',\ + com.google.gson;version='2.13.2',\ + com.influxdb:flux-dsl;version='7.5.0',\ + com.influxdb:influxdb-client-core;version='7.5.0',\ + com.influxdb:influxdb-client-java;version='7.5.0',\ + com.influxdb:influxdb-client-utils;version='7.5.0',\ + com.oracle.labs.olcut:olcut-config-protobuf;version='5.3',\ + com.oracle.labs.olcut:olcut-core;version='5.3',\ + com.squareup.okhttp3;version='5.3',\ + com.squareup.retrofit2:adapter-rxjava3;version='3.0.0',\ + com.squareup.retrofit2:converter-gson;version='3.0.0',\ + com.squareup.retrofit2:converter-scalars;version='3.0.0',\ + com.squareup.retrofit2:retrofit;version='3.0.0',\ + com.sun.activation.javax.activation;version='1.2.0',\ + de.bytefish:pgbulkinsert;version='8.1.6',\ + de.bytefish:pgbulkinsert;version='8.1.8',\ + eu.chargetime.ocpp:common;version='1.0.2',\ + eu.chargetime.ocpp:OCPP-J;version='1.0.2',\ + eu.chargetime.ocpp:v1_6;version='1.1.0',\ + fr.turri:aXMLRPC;version='1.17.0',\ + info.faljse:SDNotify;version='1.5.0',\ + io.helins:linux-common;version='0.1.4',\ + io.helins:linux-errno;version='1.0.2',\ + io.helins:linux-i2c;version='1.0.2',\ + io.helins:linux-io;version='0.0.4',\ + io.jenetics:jenetics;version='8.3.0',\ + io.reactivex.rxjava3.rxjava;version='3.1.8',\ + org.dhatim:fastexcel-reader;version='0.18.4',\ + org.dhatim:fastexcel;version='0.18.4',\ + org.eclipse.paho.mqttv5.client;version='1.2.5',\ + org.java-websocket:Java-WebSocket;version='1.5.7',\ + org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm;version='1.9.0',\ + com.auth0:auth0;version='3.0.0',\ + com.auth0:java-jwt;version='4.5.0',\ + com.auth0:jwks-rsa;version='0.23.0',\ + org.tribuo:tribuo-common-tree;version='4.3.2',\ + org.tribuo:tribuo-core;version='4.3.2',\ + org.tribuo:tribuo-data;version='4.3.2',\ + org.tribuo:tribuo-math;version='4.3.2',\ + org.tribuo:tribuo-regression-core;version='4.3.2',\ + org.tribuo:tribuo-regression-tree;version='4.3.2',\ + org.tribuo:tribuo-util-onnx;version='4.3.2',\ + org.tribuo:tribuo-util-tokenization;version='4.3.2',\ +Bundle-Name: OpenEMS Edge Controller Ess Minimum Discharge Period +Bundle-Vendor: OpenEMS Association e.V. +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + com.google.gson,\ + com.google.guava,\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge ESS Cluster +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.ess.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller Symmetric Fix-ActivePower +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.energy.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.timedata.api,\ + +-testpath: \ + ${testpath},\ + org.apache.commons.math3,\ +Bundle-Name: OpenEMS Edge Controller Generic JsonLogic +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.io.api + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller Api MQTT +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + bcpkix;version='1.78.1',\ + bcprov;version='1.78.1',\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.controller.api.common,\ + io.openems.edge.timedata.api,\ + io.openems.wrapper.paho-mqttv5,\ + org.eclipse.paho.mqttv5.client;version='1.2',\ + org.ops4j.pax.logging.pax-logging-api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller ChannelThreshold +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.timedata.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Meter Ziehl EFR4001IP +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.meter.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Scheduler All-Alphabetically +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.scheduler.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge EVCS OCPP Server +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + Java-WebSocket,\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.evcs.api,\ + io.openems.edge.evcs.ocpp.common,\ + io.openems.edge.meter.api,\ + io.openems.edge.timedata.api,\ + io.openems.wrapper.eu.chargetime.ocpp,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller Ess Sell-To-Grid Limit +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.meter.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Battery-Inverter Api +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.battery.api,\ + io.openems.edge.common,\ + io.openems.edge.ess.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Meter Schneider Electric Acti9 Smartlink SI D +Bundle-Vendor: FE-Partner AG +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.meter.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Controller Ess Fix State Of Charge +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.timedata.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Backend Core +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} +Bundle-Description: Supportive services that are used throughout OpenEMS Backend + +-buildpath: \ + ${buildpath},\ + io.openems.backend.common,\ + io.openems.common,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Soltaro Battery +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.battery.api,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Predictor LSTM +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.predictor.api,\ + io.openems.edge.timedata.api,\ + org.apache.commons.math3,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Meter Artemes AM-2 +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.meter.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Time-Of-Use LUOX +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.common.bridge.http,\ + io.openems.edge.common,\ + io.openems.edge.timeofusetariff.api,\ + +-testpath: \ + org.jetbrains.kotlin.osgi-bundle,\ + ${testpath} +Bundle-Name: OpenEMS Edge Meter Carlo Gavazzi EM300 +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.meter.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge IO GPIO +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.io.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Time-Of-Use Tariff EWS Schönau +Bundle-Vendor: Pascal Bockhorn - Bockhorn.IT +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + com.squareup.okhttp3,\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.timeofusetariff.api,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge IO KMtronic +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.io.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Backend-to-Backend Websocket +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.backend.authentication.api,\ + io.openems.backend.common,\ + io.openems.common,\ + io.openems.wrapper.Java-WebSocket,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller ESS Standby +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge PV Inverter Fronius +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.meter.api,\ + io.openems.edge.pvinverter.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath},\ +Bundle-Name: OpenEMS Edge FENECON DESS (PRO Hybrid, PRO Compact) +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.ess.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.timedata.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Controller Symmetric Limit ActivePower +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller Ess Reactive Power Voltage Characteristics +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.meter.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller Asymmetric Cos-Phi +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.meter.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller SoH Cycle +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge io.openems.edge.ess.generic +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.battery.api,\ + io.openems.edge.batteryinverter.api,\ + io.openems.edge.common,\ + io.openems.edge.ess.api,\ + io.openems.edge.timedata.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge IO Shelly +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.common.bridge.http,\ + io.openems.edge.bridge.http,\ + io.openems.edge.common,\ + io.openems.edge.io.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.timedata.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller IO Analog +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.io.api,\ + io.openems.edge.timedata.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Backend Odoo Impl +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + com.zaxxer.HikariCP,\ + io.openems.backend.authentication.api,\ + io.openems.backend.common,\ + io.openems.backend.metrics.prometheus,\ + io.openems.common,\ + io.openems.wrapper.aXMLRPC,\ + io.prometheus.metrics-core,\ + io.prometheus.metrics-model,\ + org.postgresql.jdbc, \ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge PV-Inverter Api +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.meter.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Scheduler Api +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS OEM Bundle +Bundle-Vendor: OpenEMS Association e.V. +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.battery.fenecon.home,\ + io.openems.edge.common,\ + io.openems.edge.goodwe,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Bridge MQTT +Bundle-Vendor: Consolinno Energy GmbH, OpenEMS Association e.V. +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + bcpkix;version='1.78.1',\ + bcprov;version='1.78.1',\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.wrapper.paho-mqttv5,\ + org.eclipse.paho.client.mqttv3;version='1.2',\ + org.eclipse.paho.mqttv5.client;version='1.2',\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller for §14a EnWG +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.timedata.api,\ + +-testpath: \ + ${testpath},\ + io.openems.edge.io.api,\ +Bundle-Name: OpenEMS Edge Controller Symmetric Fix-ReactivePower +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge EVCS Core +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.ess.core,\ + io.openems.edge.evcs.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Predictor Similarday-Model +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.predictor.api,\ + io.openems.edge.timedata.api,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Timedata InfluxDB +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.timedata.api,\ + io.openems.shared.influxdb,\ + io.openems.wrapper.influxdb-client-core,\ + io.openems.wrapper.influxdb-client-java,\ + +-testpath: \ + ${testpath},\ + io.openems.wrapper.influxdb-client-utils,\ + org.jetbrains.kotlin.osgi-bundle,\ + com.squareup.okhttp3,\ + com.squareup.okio,\ +Bundle-Name: OpenEMS Edge Meter Eastron SDM 630 Smart Meter +Bundle-Vendor: Microcare (Destrier Electronics Pty Ltd) +Bundle-Version: 1.0.0.${tstamp} +Bundle-License: Proprietary (for now) + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.meter.api,\ + io.openems.edge.timedata.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Controller Debug Log +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge EVCS Heidelberg +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.evcs.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.timedata.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge EVCS OCPP Ies KeyWatt for CCS Charger +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.evcs.api,\ + io.openems.edge.evcs.ocpp.common,\ + io.openems.edge.evcs.ocpp.server,\ + io.openems.edge.meter.api,\ + io.openems.edge.timedata.api,\ + io.openems.wrapper.eu.chargetime.ocpp,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge EVSE Electric-Vehicle Generic +Bundle-Vendor: OpenEMS Association e.V. +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.evse.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge EVCS Go-e Gemini +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.common.bridge.http,\ + io.openems.edge.bridge.http,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.evcs.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.timedata.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge EVCS Spelsberg SMART +Bundle-Vendor: OpenEMS Association e.V. +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.evcs.api,\ + io.openems.edge.meter.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Controller Ess Time-Of-Use Tariff +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +# TODO remove emergencycapacityreserve and limittotaldischarge after v1 + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.controller.ess.emergencycapacityreserve,\ + io.openems.edge.controller.ess.limiter14a,\ + io.openems.edge.controller.ess.limittotaldischarge,\ + io.openems.edge.energy.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.timedata.api,\ + io.openems.edge.timeofusetariff.api,\ + org.apache.commons.math3,\ + +-testpath: \ + ${testpath},\ +Bundle-Name: OpenEMS Edge Meter SOCOMEC +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.meter.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Controller Microgrid Supervisor +Bundle-Vendor: OpenEMS Association e.V. +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.io.api,\ + io.openems.edge.ess.api + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge EVCS OCPP implementation of ABL +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.evcs.api,\ + io.openems.edge.evcs.ocpp.common,\ + io.openems.edge.evcs.ocpp.server,\ + io.openems.edge.meter.api,\ + io.openems.edge.timedata.api,\ + io.openems.wrapper.eu.chargetime.ocpp,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Battery FENECON Commercial +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.battery.api,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.ess.api,\ + io.openems.edge.io.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge EVSE Charge-Point Heidelberg +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.evse.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.timedata.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller Ess Delay Charge +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Weather Open-Meteo +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.common.bridge.http,\ + io.openems.edge.common,\ + io.openems.edge.weather.api,\ + +-testpath: \ + ${testpath},\ +Bundle-Name: OpenEMS Edge Time-Of-Use Tariff API +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + com.squareup.okhttp3,\ + com.squareup.okio,\ + io.openems.common,\ + io.openems.edge.common,\ + +-testpath: \ + org.jetbrains.kotlin.osgi-bundle,\ + ${testpath} +Bundle-Name: OpenEMS Edge Controller Symmetric Random +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge KACO blueplanet hybrid 10.0 TL3 +Bundle-Vendor: KACO new energy GmbH, FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.ess.api,\ + io.openems.edge.katek.edcom,\ + io.openems.edge.meter.api,\ + io.openems.edge.pvinverter.api,\ + io.openems.edge.timedata.api,\ + javax.jmdns,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Predictor Production Linear Model +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.predictor.api,\ + io.openems.edge.predictor.persistencemodel,\ + io.openems.edge.timedata.api,\ + io.openems.edge.weather.api,\ + io.openems.wrapper.olcut,\ + io.openems.wrapper.tribuo,\ + org.apache.commons.math3,\ + +-testpath: \ + ${testpath},\Bundle-Name: OpenEMS Edge RevolutionPi Data IO module +Bundle-Vendor: opernikus GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + com.google.guava,\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.io.api + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Common Http Bridge +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Meter KDK 2PU CT +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.meter.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Battery Inverter Victron +Bundle-Vendor: Ernst KNOLL Feinmechanik GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.battery.api,\ + io.openems.edge.batteryinverter.api,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.controller.ess.emergencycapacityreserve,\ + io.openems.edge.controller.ess.limittotaldischarge,\ + io.openems.edge.core,\ + io.openems.edge.ess.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.pvinverter.api,\ + io.openems.edge.timedata.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Meter Discovergy +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.meter.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge ESS KOSTAL PIKO +Bundle-Vendor: FENECON GmbH, OpenEMS Association e.V. +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.ess.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.pvinverter.api,\ + io.openems.edge.timedata.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge $projectName$ +Bundle-Vendor: OpenEMS Association e.V. +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.\${tstamp} + +-buildpath: \ + \${buildpath},\ + io.openems.common,\ + io.openems.edge.common + +-testpath: \ + \${testpath} +Bundle-Name: OpenEMS Edge Controller $projectName$ +Bundle-Vendor: OpenEMS Association e.V. +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.\${tstamp} + +-buildpath: \ + \${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api + +-testpath: \ + \${testpath} +Bundle-Name: OpenEMS Edge $projectName$ +Bundle-Vendor: OpenEMS Association e.V. +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.\${tstamp} + +-buildpath: \ + \${buildpath},\ + io.openems.j2mod,\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common + +-testpath: \ + \${testpath} +Bundle-Name: OpenEMS Edge $projectName$ Api +Bundle-Vendor: OpenEMS Association e.V. +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.\${tstamp} + +-buildpath: \ + \${buildpath},\ + io.openems.common,\ + io.openems.edge.common + +-testpath: \ + \${testpath} +Bundle-Name: OpenEMS Common +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.wrapper.Java-WebSocket,\ + io.openems.wrapper.fastexcel,\ + io.openems.wrapper.opczip,\ + org.apache.felix.http.jetty12,\ + org.apache.felix.http.servlet-api,\ + org.ops4j.pax.logging.pax-logging-api,\ + +-testpath: \ + ${testpath} + +-includeresource.resources: \ + resources + +template-category: \ + bbb/OpenEMS Templates +template-icon: \ + data:image/gif;base64,${base64;openems.gif} + +Provide-Capability: \ + org.bndtools.template; org.bndtools.template=project;\ + name=OpenEMS Controller;\ + category=${template-category};\ + ranking:Double=900;\ + dir=templates/controller;\ + icon="${template-icon}";\ + help=controller-help.xml,\ + org.bndtools.template; org.bndtools.template=project;\ + name=OpenEMS Device;\ + category=${template-category};\ + ranking:Double=800;\ + dir=templates/device;\ + icon="${template-icon}";\ + help=device-help.xml,\ + org.bndtools.template; org.bndtools.template=project;\ + name=OpenEMS Modbus Device;\ + category=${template-category};\ + ranking:Double=700;\ + dir=templates/device-modbus;\ + icon="${template-icon}";\ + help=device-modbus-help.xml,\ + org.bndtools.template; org.bndtools.template=project;\ + name=OpenEMS Api;\ + category=${template-category};\ + ranking:Double=600;\ + dir=templates/api;\ + icon="${template-icon}";\ + help=api-help.xml +Bundle-Name: OpenEMS Backend Timedata Dummy +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.backend.common,\ + io.openems.common,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Core Logger +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Meter Janitza +Bundle-Description: This implementation covers Janitza UMG 604, Janitza UMG 96RM-E and Janitza UMG 511 meters +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.meter.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge EVCS OCPP Common +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.evcs.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.timedata.api,\ + io.openems.wrapper.eu.chargetime.ocpp,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Time-Of-Use Tariff Tibber +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + com.squareup.okhttp3,\ + com.squareup.okio,\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.timeofusetariff.api,\ + +-testpath: \ + com.squareup.okio,\ + io.openems.wrapper.kotlinx-coroutines-core-jvm,\ + org.jetbrains.kotlin.osgi-bundle,\ + ${testpath} +Bundle-Name: OpenEMS Edge ESS Samsung +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.common.bridge.http,\ + io.openems.edge.bridge.http,\ + io.openems.edge.common,\ + io.openems.edge.ess.api,\ + io.openems.edge.io.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.pvinverter.api,\ + io.openems.edge.thermometer.api,\ + io.openems.edge.timedata.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Adstec StoraXe +Bundle-Vendor: FE-Partner AG +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.ess.api, \ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Controller Ess Balancing +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.meter.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Backend UiWebsocket Impl +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.backend.authentication.api,\ + io.openems.backend.common,\ + io.openems.common,\ + io.openems.wrapper.Java-WebSocket,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge OneWire Thermometer +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Vendor: FENECON GmbH +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.onewire,\ + io.openems.edge.common,\ + io.openems.edge.thermometer.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge EVSE Charge-Point Alpitronic +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.evcs.api,\ + io.openems.edge.evse.api,\ + io.openems.edge.meter.api,\ + io.openems.edge.timedata.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath},\ + io.openems.j2mod,\Bundle-Name: OpenEMS Edge Bridge Modbus +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.battery.api,\ + io.openems.edge.batteryinverter.api,\ + io.openems.edge.common,\ + io.openems.edge.meter.api,\ + io.openems.edge.pvinverter.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Meter Api +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller Api Backend +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + Java-WebSocket,\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.controller.api.common,\ + io.openems.edge.timedata.api,\ + org.ops4j.pax.logging.pax-logging-api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge ESS FENECON Commercial40 +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.timedata.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Meter Plexlog Datalogger +Bundle-Description: This implementation covers Plexlog Datalogger +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.meter.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Backend Timedata InfluxDB +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.backend.common,\ + io.openems.common,\ + io.openems.shared.influxdb,\ + io.openems.wrapper.influxdb-client-core,\ + io.openems.wrapper.influxdb-client-java,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller Ess Cycle +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Backend Prometheus Client +Bundle-Vendor: OpenEMS Association e.V. +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.backend.common,\ + io.openems.common,\ + io.prometheus.metrics-config,\ + io.prometheus.metrics-core,\ + io.prometheus.metrics-exporter-common,\ + io.prometheus.metrics-exporter-httpserver,\ + io.prometheus.metrics-exposition-formats,\ + io.prometheus.metrics-instrumentation-jvm,\ + io.prometheus.metrics-model,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Meter B-Control EM300 +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.meter.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Controller HighLoadTimeslot +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Timedata RRD4J +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.timedata.api,\ + rrd4j,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Backend Authentication OAuth2 Api +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.backend.authentication.api,\ + io.openems.backend.common,\ + io.openems.common,\ + io.openems.common.bridge.http,\ + io.openems.wrapper.auth0-auth0,\ + io.openems.wrapper.auth0-java-jwt,\ + io.openems.wrapper.auth0-jwks-rsa,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge PV Inverter Kostal +Bundle-Vendor: FENECON GmbH, OpenEMS Association e.V. +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.common.bridge.http,\ + io.openems.edge.bridge.http,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.meter.api,\ + io.openems.edge.pvinverter.api,\ + io.openems.j2mod,\ + org.jsoup:jsoup,\ + +-testpath: \ + ${testpath},\ +Bundle-Name: OpenEMS Backend Timedata TimescaleDB +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + com.zaxxer.HikariCP,\ + io.openems.backend.common,\ + io.openems.common,\ + io.openems.wrapper.pgbulkinsert,\ + org.postgresql.jdbc,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Controller Api +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge IO Siemens LOGO! +Bundle-Description: Siemens LOGO! 8 as network relais. Connected via Modbus. Relays starting \ + at VM 101, Bit 0 on SPS. +Bundle-Vendor: OpenEMS Association e.V. +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.io.api,\ + io.openems.j2mod,\ + slf4j.api,\ + +-testpath: \ + ${testpath} + Bundle-Name: OpenEMS Edge Controller Clever-PV +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.common.bridge.http,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.controller.ess.timeofusetariff,\ + io.openems.edge.energy.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.timedata.api,\ + io.openems.edge.timeofusetariff.api +-testpath: \ + ${testpath},\ + io.openems.edge.energy.api,\Bundle-Name: OpenEMS Edge Controller Electric Vehicle Charging Station Fix Active-Power +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.evcs.api,\ + io.openems.edge.meter.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Backend +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.backend.common,\ + io.openems.common,\ + io.openems.wrapper.Java-WebSocket,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge Electric Vehicle Supply Equipment (EVSE) Controllers +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.energy.api,\ + io.openems.edge.evse.api,\ + io.openems.edge.meter.api,\ + +-testpath: \ + ${testpath},\ + org.apache.commons.math3,\ +Bundle-Name: OpenEMS Edge Scheduler JSCalendar +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.scheduler.api,\ + +-testpath: \ + ${testpath} +Bundle-Name: OpenEMS Edge EVCS Webasto Next +Bundle-Vendor: OpenEMS Association e.V. +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.bridge.modbus,\ + io.openems.edge.common,\ + io.openems.edge.evcs.api,\ + io.openems.edge.meter.api,\ + io.openems.j2mod,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Time-Of-Use Groupe-E +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.common.bridge.http,\ + io.openems.edge.common,\ + io.openems.edge.timeofusetariff.api,\ + +-testpath: \ + ${testpath}Bundle-Name: OpenEMS Edge Controller Ess Delayed-Sell-To-Grid +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.controller.api,\ + io.openems.edge.ess.api,\ + io.openems.edge.meter.api,\ + +-testpath: \ + ${testpath} diff --git a/cnf/pom.xml b/cnf/pom.xml index b0f72068d41..6407d4651a7 100644 --- a/cnf/pom.xml +++ b/cnf/pom.xml @@ -32,6 +32,11 @@ jSerialComm 2.11.4 + + org.bidib.jbidib + nrjavaserial + 5.2.1 + com.oracle.labs.olcut diff --git a/io.openems.edge.bridge.onewire/lib/RXTXcomm.jar b/io.openems.edge.bridge.onewire/lib/RXTXcomm.jar deleted file mode 100644 index d572880fb66..00000000000 --- a/io.openems.edge.bridge.onewire/lib/RXTXcomm.jar +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/io.openems.edge.bridge.onewire/src/gnu/io/CommPortIdentifier.java b/io.openems.edge.bridge.onewire/src/gnu/io/CommPortIdentifier.java new file mode 100644 index 00000000000..01a109cf5c6 --- /dev/null +++ b/io.openems.edge.bridge.onewire/src/gnu/io/CommPortIdentifier.java @@ -0,0 +1,69 @@ +package gnu.io; + +import java.util.Enumeration; + +/** + * Dummy CommPortIdentifier. + */ +public class CommPortIdentifier { + + /** + * Dummy getPortIdentifier. + * + * @param name name + * @return null + * @throws NoSuchPortException if error + */ + public static CommPortIdentifier getPortIdentifier(String name) throws NoSuchPortException { + return null; + } + + /** + * Dummy getPortIdentifiers. + * + * @return null + */ + public static Enumeration getPortIdentifiers() { + return null; + } + + /** + * Dummy getName. + * + * @return null + */ + public String getName() { + return null; + } + + /** + * Dummy getPortType. + * + * @return 0 + */ + public int getPortType() { + return 0; + } + + public static final int PORT_SERIAL = 1; + + /** + * Dummy open. + * + * @param appName appName + * @param timeout timeout + * @return null + */ + public SerialPort open(String appName, int timeout) { + return null; + } + + /** + * Dummy isCurrentlyOwned. + * + * @return false + */ + public boolean isCurrentlyOwned() { + return false; + } +} diff --git a/io.openems.edge.bridge.onewire/src/gnu/io/NoSuchPortException.java b/io.openems.edge.bridge.onewire/src/gnu/io/NoSuchPortException.java new file mode 100644 index 00000000000..d4efb6c7218 --- /dev/null +++ b/io.openems.edge.bridge.onewire/src/gnu/io/NoSuchPortException.java @@ -0,0 +1,9 @@ +package gnu.io; + +/** + * Dummy NoSuchPortException. + */ +public class NoSuchPortException extends Exception { + + private static final long serialVersionUID = 1L; +} diff --git a/io.openems.edge.bridge.onewire/src/gnu/io/SerialPort.java b/io.openems.edge.bridge.onewire/src/gnu/io/SerialPort.java new file mode 100644 index 00000000000..ae733b8864f --- /dev/null +++ b/io.openems.edge.bridge.onewire/src/gnu/io/SerialPort.java @@ -0,0 +1,182 @@ +package gnu.io; + +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Dummy SerialPort. + */ +public class SerialPort { + + public static final int FLOWCONTROL_NONE = 0; + public static final int DATABITS_8 = 8; + public static final int STOPBITS_1 = 1; + public static final int PARITY_NONE = 0; + + /** + * Dummy setFlowControlMode. + * + * @param mode mode + * @throws UnsupportedCommOperationException if error + */ + public void setFlowControlMode(int mode) throws UnsupportedCommOperationException { + } + + /** + * Dummy setSerialPortParams. + * + * @param b b + * @param d d + * @param s s + * @param p p + * @throws UnsupportedCommOperationException if error + */ + public void setSerialPortParams(int b, int d, int s, int p) throws UnsupportedCommOperationException { + } + + /** + * Dummy addEventListener. + * + * @param l listener + * @throws java.util.TooManyListenersException if error + */ + public void addEventListener(SerialPortEventListener l) throws java.util.TooManyListenersException { + } + + /** + * Dummy notifyOnDataAvailable. + * + * @param e enable + */ + public void notifyOnDataAvailable(boolean e) { + } + + /** + * Dummy close. + */ + public void close() { + } + + /** + * Dummy getInputStream. + * + * @return null + */ + public InputStream getInputStream() { + return null; + } + + /** + * Dummy getOutputStream. + * + * @return null + */ + public OutputStream getOutputStream() { + return null; + } + + /** + * Dummy getInputBufferSize. + * + * @return 0 + */ + public int getInputBufferSize() { + return 0; + } + + /** + * Dummy getOutputBufferSize. + * + * @return 0 + */ + public int getOutputBufferSize() { + return 0; + } + + /** + * Dummy notifyOnOutputEmpty. + * + * @param e enable + */ + public void notifyOnOutputEmpty(boolean e) { + } + + /** + * Dummy disableReceiveFraming. + */ + public void disableReceiveFraming() { + } + + /** + * Dummy disableReceiveThreshold. + */ + public void disableReceiveThreshold() { + } + + /** + * Dummy enableReceiveTimeout. + * + * @param t timeout + */ + public void enableReceiveTimeout(int t) { + } + + // CHECKSTYLE:OFF + /** + * Dummy setDTR. + * + * @param e enable + */ + public void setDTR(boolean e) { + } + + /** + * Dummy setRTS. + * + * @param e enable + */ + public void setRTS(boolean e) { + } + + /** + * Dummy isDTR. + * + * @return false + */ + public boolean isDTR() { + return false; + } + + /** + * Dummy isRTS. + * + * @return false + */ + public boolean isRTS() { + return false; + } + // CHECKSTYLE:ON + + /** + * Dummy sendBreak. + * + * @param d duration + */ + public void sendBreak(int d) { + } + + /** + * Dummy getBaudRate. + * + * @return 0 + */ + public int getBaudRate() { + return 0; + } + + /** + * Dummy removeEventListener. + */ + public void removeEventListener() { + } +} diff --git a/io.openems.edge.bridge.onewire/src/gnu/io/SerialPortEvent.java b/io.openems.edge.bridge.onewire/src/gnu/io/SerialPortEvent.java new file mode 100644 index 00000000000..983d3ccd325 --- /dev/null +++ b/io.openems.edge.bridge.onewire/src/gnu/io/SerialPortEvent.java @@ -0,0 +1,45 @@ +package gnu.io; + +/** + * Dummy SerialPortEvent. + */ +public class SerialPortEvent { + + public static final int DATA_AVAILABLE = 1; + public static final int BI = 2; + public static final int CD = 3; + public static final int CTS = 4; + public static final int DSR = 5; + public static final int FE = 6; + public static final int OE = 7; + public static final int OUTPUT_BUFFER_EMPTY = 8; + public static final int PE = 9; + public static final int RI = 10; + + /** + * Dummy getEventType. + * + * @return 0 + */ + public int getEventType() { + return 0; + } + + /** + * Dummy getOldValue. + * + * @return false + */ + public boolean getOldValue() { + return false; + } + + /** + * Dummy getNewValue. + * + * @return false + */ + public boolean getNewValue() { + return false; + } +} diff --git a/io.openems.edge.bridge.onewire/src/gnu/io/SerialPortEventListener.java b/io.openems.edge.bridge.onewire/src/gnu/io/SerialPortEventListener.java new file mode 100644 index 00000000000..df7653ffdb5 --- /dev/null +++ b/io.openems.edge.bridge.onewire/src/gnu/io/SerialPortEventListener.java @@ -0,0 +1,14 @@ +package gnu.io; + +/** + * Dummy SerialPortEventListener. + */ +public interface SerialPortEventListener extends java.util.EventListener { + + /** + * Dummy serialEvent. + * + * @param event event + */ + void serialEvent(SerialPortEvent event); +} diff --git a/io.openems.edge.bridge.onewire/src/gnu/io/UnsupportedCommOperationException.java b/io.openems.edge.bridge.onewire/src/gnu/io/UnsupportedCommOperationException.java new file mode 100644 index 00000000000..ccbc1b1db08 --- /dev/null +++ b/io.openems.edge.bridge.onewire/src/gnu/io/UnsupportedCommOperationException.java @@ -0,0 +1,9 @@ +package gnu.io; + +/** + * Dummy UnsupportedCommOperationException. + */ +public class UnsupportedCommOperationException extends Exception { + + private static final long serialVersionUID = 1L; +} diff --git a/io.openems.edge.controller.generic.jsonlogic/bnd.bnd b/io.openems.edge.controller.generic.jsonlogic/bnd.bnd index ba63ce071c6..8a84801dfbd 100644 --- a/io.openems.edge.controller.generic.jsonlogic/bnd.bnd +++ b/io.openems.edge.controller.generic.jsonlogic/bnd.bnd @@ -3,17 +3,13 @@ Bundle-Vendor: FENECON GmbH Bundle-License: https://opensource.org/licenses/EPL-2.0 Bundle-Version: 1.0.0.${tstamp} --includeresource.jsonlogic: \ - @lib/json-logic-java-1.0.0.jar; lib:=true - -buildpath: \ ${buildpath},\ io.openems.common,\ io.openems.edge.common,\ io.openems.edge.controller.api,\ io.openems.edge.ess.api,\ - io.openems.edge.io.api,\ - lib/json-logic-java-1.0.0.jar;version=file,\ + io.openems.edge.io.api -testpath: \ ${testpath} diff --git a/io.openems.edge.controller.generic.jsonlogic/src/io/github/meiskalt7/jsonlogic/JsonLogic.java b/io.openems.edge.controller.generic.jsonlogic/src/io/github/meiskalt7/jsonlogic/JsonLogic.java new file mode 100644 index 00000000000..d6b71c18fe1 --- /dev/null +++ b/io.openems.edge.controller.generic.jsonlogic/src/io/github/meiskalt7/jsonlogic/JsonLogic.java @@ -0,0 +1,19 @@ +package io.github.meiskalt7.jsonlogic; + +/** + * Dummy JsonLogic. + */ +public class JsonLogic { + + /** + * Dummy apply. + * + * @param json json + * @param data data + * @return null + * @throws JsonLogicException if error + */ + public Object apply(String json, Object data) throws JsonLogicException { + return null; + } +} diff --git a/io.openems.edge.controller.generic.jsonlogic/src/io/github/meiskalt7/jsonlogic/JsonLogicException.java b/io.openems.edge.controller.generic.jsonlogic/src/io/github/meiskalt7/jsonlogic/JsonLogicException.java new file mode 100644 index 00000000000..4615a4f4e14 --- /dev/null +++ b/io.openems.edge.controller.generic.jsonlogic/src/io/github/meiskalt7/jsonlogic/JsonLogicException.java @@ -0,0 +1,18 @@ +package io.github.meiskalt7.jsonlogic; + +/** + * Dummy JsonLogicException. + */ +public class JsonLogicException extends Exception { + + private static final long serialVersionUID = 1L; + + /** + * Constructor. + * + * @param message message + */ + public JsonLogicException(String message) { + super(message); + } +} diff --git a/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/Config.java b/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/Config.java index ec9b1ee6903..137c9121731 100644 --- a/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/Config.java +++ b/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/Config.java @@ -18,25 +18,25 @@ boolean enabled() default true; @AttributeDefinition(name = "ESS ID", description = "ID of Energy Storage System") - String ess_id() default "ess0"; + String essId() default "ess0"; @AttributeDefinition(name = "Meter ID", description = "ID of Grid Meter") - String meter_id() default "meter0"; + String meterId() default "meter0"; @AttributeDefinition(name = "Relay ID", description = "ID of Islanding Relay") - String relay_id() default "relay0"; + String relayId() default "relay0"; @AttributeDefinition(name = "Relay Channel", description = "Channel Address of the Relay Channel") - String relay_channel() default "relay0/Relay"; + String relayChannel() default "relay0/Relay"; @AttributeDefinition(name = "ESS Grid Mode Channel", description = "Channel Address of the ESS Grid Mode Channel") - String ess_grid_mode_channel() default "ess0/SetGridMode"; + String essGridModeChannel() default "ess0/SetGridMode"; @AttributeDefinition(name = "Under Voltage Threshold", description = "Grid voltage threshold for islanding [V]") - int under_voltage_threshold() default 207; + int underVoltageThreshold() default 207; @AttributeDefinition(name = "Stable Grid Time", description = "Time in seconds to wait before reconnecting") - int stable_grid_time() default 10; + int stableGridTime() default 10; String webconsole_configurationFactory_nameHint() default "Controller Microgrid Supervisor [{id}]"; } diff --git a/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/MicrogridSupervisorImpl.java b/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/MicrogridSupervisorImpl.java index 98113984349..5e8394b8f3b 100644 --- a/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/MicrogridSupervisorImpl.java +++ b/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/MicrogridSupervisorImpl.java @@ -57,11 +57,11 @@ public MicrogridSupervisorImpl() { void activate(ComponentContext componentContext, Config config) { super.activate(componentContext, config.id(), config.alias(), config.enabled()); this.config = config; - this.context.setEssId(config.ess_id()); - this.context.setMeterId(config.meter_id()); - this.context.setRelayId(config.relay_id()); - this.context.setUnderVoltageThreshold(config.under_voltage_threshold()); - this.context.setStableGridTime(config.stable_grid_time()); + this.context.setEssId(config.essId()); + this.context.setMeterId(config.meterId()); + this.context.setRelayId(config.relayId()); + this.context.setUnderVoltageThreshold(config.underVoltageThreshold()); + this.context.setStableGridTime(config.stableGridTime()); } @Deactivate @@ -84,7 +84,7 @@ public void run() throws OpenemsNamedException { private void updateContext() { // Update grid voltage from meter try { - ElectricityMeter meter = this.componentManager.getComponent(this.config.meter_id()); + ElectricityMeter meter = this.componentManager.getComponent(this.config.meterId()); IntegerReadChannel voltageChannel = meter.channel(ElectricityMeter.ChannelId.VOLTAGE); Integer voltageMillivolt = voltageChannel.value().get(); if (voltageMillivolt != null) { @@ -95,7 +95,7 @@ private void updateContext() { } // Update stable grid timer - if (this.context.getGridVoltage() >= this.config.under_voltage_threshold()) { + if (this.context.getGridVoltage() >= this.config.underVoltageThreshold()) { this.context.setStableGridTimer(this.context.getStableGridTimer() + 1); } else { this.context.setStableGridTimer(0); @@ -124,7 +124,7 @@ public void closeRelay() throws OpenemsNamedException { private void setRelay(boolean value) throws OpenemsNamedException { try { - OpenemsComponent component = this.componentManager.getComponent(this.config.relay_id()); + OpenemsComponent component = this.componentManager.getComponent(this.config.relayId()); if (component instanceof DigitalOutput) { DigitalOutput doComp = (DigitalOutput) component; BooleanWriteChannel[] channels = doComp.digitalOutputChannels(); @@ -134,7 +134,7 @@ private void setRelay(boolean value) throws OpenemsNamedException { } } // Fallback to configured channel - BooleanWriteChannel channel = component.channel(this.config.relay_channel()); + BooleanWriteChannel channel = component.channel(this.config.relayChannel()); channel.setNextWriteValue(value); } catch (Exception e) { this.log.error("Could not set relay: " + e.getMessage()); @@ -157,9 +157,10 @@ public void setEssOnGrid() { this.setEssGridMode(io.openems.edge.common.sum.GridMode.ON_GRID); } + @SuppressWarnings("unchecked") private void setEssGridMode(GridMode mode) { try { - ChannelAddress addr = ChannelAddress.fromString(this.config.ess_grid_mode_channel()); + ChannelAddress addr = ChannelAddress.fromString(this.config.essGridModeChannel()); WriteChannel channel = this.componentManager.getChannel(addr); if (channel.channelDoc().getType() == io.openems.common.types.OpenemsType.INTEGER) { ((WriteChannel) channel).setNextWriteValue(mode.getValue()); diff --git a/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/dispatcher/Config.java b/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/dispatcher/Config.java new file mode 100644 index 00000000000..0874e335e79 --- /dev/null +++ b/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/dispatcher/Config.java @@ -0,0 +1,51 @@ +package io.openems.edge.controller.microgrid.dispatcher; + +import org.osgi.service.metatype.annotations.AttributeDefinition; +import org.osgi.service.metatype.annotations.ObjectClassDefinition; + +@ObjectClassDefinition(// + name = "Controller Microgrid Dispatcher", // + description = "Manages power flows in the microgrid based on the state provided by the Supervisor.") +public @interface Config { + + @AttributeDefinition(name = "Component-ID", description = "Unique ID of this Component") + String id() default "ctrlMicrogridDispatcher0"; + + @AttributeDefinition(name = "Alias", description = "Human-readable name of this Component; defaults to Component-ID") + String alias() default ""; + + @AttributeDefinition(name = "Is enabled?", description = "Is this Component enabled?") + boolean enabled() default true; + + @AttributeDefinition(name = "ESS ID", description = "ID of Energy Storage System") + String essId() default "ess0"; + + @AttributeDefinition(name = "Meter ID", description = "ID of Grid Meter") + String meterId() default "meter0"; + + @AttributeDefinition(name = "Genset Meter ID", description = "ID of Genset Meter") + String gensetId() default "meter1"; + + @AttributeDefinition(name = "Genset Start/Stop Channel", description = "Channel Address of the Genset Start/Stop Channel") + String gensetStartStopChannel() default "io0/DigitalOutput0"; + + @AttributeDefinition(name = "PV ID", description = "ID of PV Inverter") + String pvId() default "pvInverter0"; + + @AttributeDefinition(name = "Supervisor ID", description = "ID of Microgrid Supervisor") + String supervisorId() default "ctrlMicrogrid0"; + + @AttributeDefinition(name = "Grid Limit", description = "Peak Shaving Limit [W]") + int gridLimit() default 10000; + + @AttributeDefinition(name = "Genset Start SoC", description = "Genset Start State of Charge [%]") + int gensetStartSoc() default 20; + + @AttributeDefinition(name = "Genset Stop SoC", description = "Genset Stop State of Charge [%]") + int gensetStopSoc() default 80; + + @AttributeDefinition(name = "Genset Capacity", description = "Genset Capacity [W]") + int gensetCapacity() default 50000; + + String webconsole_configurationFactory_nameHint() default "Controller Microgrid Dispatcher [{id}]"; +} diff --git a/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/dispatcher/MicrogridDispatcher.java b/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/dispatcher/MicrogridDispatcher.java new file mode 100644 index 00000000000..81df4ce327b --- /dev/null +++ b/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/dispatcher/MicrogridDispatcher.java @@ -0,0 +1,22 @@ +package io.openems.edge.controller.microgrid.dispatcher; + +import io.openems.edge.common.channel.Doc; +import io.openems.edge.common.component.OpenemsComponent; +import io.openems.edge.controller.api.Controller; + +public interface MicrogridDispatcher extends Controller, OpenemsComponent { + + public enum ChannelId implements io.openems.edge.common.channel.ChannelId { + ; + private final Doc doc; + + private ChannelId(Doc doc) { + this.doc = doc; + } + + @Override + public Doc doc() { + return this.doc; + } + } +} diff --git a/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/dispatcher/MicrogridDispatcherImpl.java b/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/dispatcher/MicrogridDispatcherImpl.java new file mode 100644 index 00000000000..6b058aaa90e --- /dev/null +++ b/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/dispatcher/MicrogridDispatcherImpl.java @@ -0,0 +1,205 @@ +package io.openems.edge.controller.microgrid.dispatcher; + +import org.osgi.service.component.ComponentContext; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.ConfigurationPolicy; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.metatype.annotations.Designate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.common.types.ChannelAddress; +import io.openems.common.types.OpenemsType; +import io.openems.edge.common.channel.WriteChannel; +import io.openems.edge.common.component.AbstractOpenemsComponent; +import io.openems.edge.common.component.ComponentManager; +import io.openems.edge.common.component.OpenemsComponent; +import io.openems.edge.common.type.TypeUtils; +import io.openems.edge.controller.api.Controller; +import io.openems.edge.controller.microgrid.MicrogridSupervisor; +import io.openems.edge.controller.microgrid.statemachine.MemsState; +import io.openems.edge.ess.api.ManagedSymmetricEss; +import io.openems.edge.meter.api.ElectricityMeter; + +@Designate(ocd = Config.class, factory = true) +@Component(// + name = "Controller.Microgrid.Dispatcher", // + immediate = true, // + configurationPolicy = ConfigurationPolicy.REQUIRE // +) +public class MicrogridDispatcherImpl extends AbstractOpenemsComponent + implements MicrogridDispatcher, Controller, OpenemsComponent { + + private final Logger log = LoggerFactory.getLogger(MicrogridDispatcherImpl.class); + + @Reference + protected ComponentManager componentManager; + + private Config config; + + public MicrogridDispatcherImpl() { + super(// + OpenemsComponent.ChannelId.values(), // + Controller.ChannelId.values(), // + MicrogridDispatcher.ChannelId.values() // + ); + } + + @Activate + void activate(ComponentContext componentContext, Config config) { + super.activate(componentContext, config.id(), config.alias(), config.enabled()); + this.config = config; + } + + @Override + @Deactivate + protected void deactivate() { + super.deactivate(); + } + + @Override + public void run() throws OpenemsNamedException { + MemsState state = this.getMicrogridState(); + + switch (state) { + case SS1: + this.runSS1(); + break; + case SS2: + this.runSS2(); + break; + default: + // Do nothing in transition or undefined states + break; + } + } + + private MemsState getMicrogridState() { + try { + MicrogridSupervisor supervisor = this.componentManager.getComponent(this.config.supervisorId()); + return supervisor.channel(MicrogridSupervisor.ChannelId.STATE_MACHINE).value().asEnum(); + } catch (Exception e) { + return MemsState.UNDEFINED; + } + } + + private void runSS1() throws OpenemsNamedException { + // 1. Peak Shaving + try { + ElectricityMeter gridMeter = this.componentManager.getComponent(this.config.meterId()); + Integer gridPower = gridMeter.getActivePower().get(); + ManagedSymmetricEss ess = this.componentManager.getComponent(this.config.essId()); + + if (gridPower != null && gridPower > this.config.gridLimit()) { + int diff = gridPower - this.config.gridLimit(); + ess.setActivePowerEquals(diff); + } + // Do not call setActivePowerEquals(0) when below limit to allow other + // controllers + } catch (Exception e) { + this.logError(this.log, "SS1: Error during Peak Shaving: " + e.getMessage()); + } + + // 2. Stop Genset + this.setGensetStartStop(false); + } + + private void runSS2() throws OpenemsNamedException { + ManagedSymmetricEss ess; + ElectricityMeter gensetMeter; + OpenemsComponent pvInverter; + try { + ess = this.componentManager.getComponent(this.config.essId()); + gensetMeter = this.componentManager.getComponent(this.config.gensetId()); + pvInverter = this.componentManager.getComponent(this.config.pvId()); + } catch (Exception e) { + this.logError(this.log, "SS2: Required components not found: " + e.getMessage()); + return; + } + + Integer soc = ess.getSoc().get(); + Integer gensetPower = gensetMeter.getActivePower().get(); + + if (soc == null || gensetPower == null) { + return; + } + + // 1. Genset Control (Start/Stop) + if (soc < this.config.gensetStartSoc()) { + this.setGensetStartStop(true); + } else if (soc > this.config.gensetStopSoc()) { + this.setGensetStartStop(false); + } + + // 2. Genset Loading + boolean isGensetOn = gensetPower > 100; // Threshold to consider Genset as running + if (isGensetOn) { + int targetGensetPower = (int) (this.config.gensetCapacity() * 0.4); + + Integer pvPower = null; + if (pvInverter instanceof ElectricityMeter) { + pvPower = ((ElectricityMeter) pvInverter).getActivePower().get(); + } else { + try { + pvPower = TypeUtils.getAsType(OpenemsType.INTEGER, pvInverter.channel("ActivePower").value().get()); + } catch (Exception e) { + // Ignore + } + } + + Integer essPower = ess.getActivePower().get(); + + if (pvPower != null && essPower != null) { + int consumption = essPower + pvPower + gensetPower; + // ESS_Setpoint = Consumption - PV - TargetGensetPower + int essSetpoint = consumption - pvPower - targetGensetPower; + ess.setActivePowerEquals(essSetpoint); + } + } + + // 3. PV Curtailment + Integer allowedChargePower = ess.getAllowedChargePower().get(); // typically negative + if (soc > 95 && allowedChargePower != null && allowedChargePower > -100) { + Integer pvPower = null; + if (pvInverter instanceof ElectricityMeter) { + pvPower = ((ElectricityMeter) pvInverter).getActivePower().get(); + } else { + try { + pvPower = TypeUtils.getAsType(OpenemsType.INTEGER, pvInverter.channel("ActivePower").value().get()); + } catch (Exception e) { + // Ignore + } + } + Integer essPower = ess.getActivePower().get(); + if (pvPower != null && essPower != null) { + int consumption = essPower + pvPower + gensetPower; + try { + WriteChannel limitChannel = pvInverter.channel("SetActivePowerLimit"); + limitChannel.setNextWriteValue(consumption); + } catch (Exception e) { + this.logError(this.log, "SS2: Unable to set PV power limit: " + e.getMessage()); + } + } + } else { + try { + WriteChannel limitChannel = pvInverter.channel("SetActivePowerLimit"); + limitChannel.setNextWriteValue(null); // No limit + } catch (Exception e) { + // Ignore + } + } + } + + private void setGensetStartStop(boolean value) { + try { + ChannelAddress addr = ChannelAddress.fromString(this.config.gensetStartStopChannel()); + WriteChannel channel = this.componentManager.getChannel(addr); + channel.setNextWriteValue(value); + } catch (Exception e) { + this.logError(this.log, "Error setting Genset Start/Stop: " + e.getMessage()); + } + } +} diff --git a/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/INITHandler.java b/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/INITHandler.java new file mode 100644 index 00000000000..945e85b9ff9 --- /dev/null +++ b/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/INITHandler.java @@ -0,0 +1,30 @@ +package io.openems.edge.controller.microgrid.statemachine; + +import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.edge.common.statemachine.StateHandler; + +/** + * Handler for state: INIT. + * Initial State: Determine starting mode + * Auto-generated from state-machine.json + */ +public class INITHandler extends StateHandler { + + @Override + protected MemsState runAndGetNextState(MemsContext context) throws OpenemsNamedException { + // No transitions defined - stay in current state + return MemsState.INIT; + } + + @Override + protected void onEntry(MemsContext context) throws OpenemsNamedException { + // TODO: Implement entry actions + // No entry actions + } + + @Override + protected void onExit(MemsContext context) throws OpenemsNamedException { + // TODO: Implement exit actions + // No exit actions + } +} diff --git a/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/MemsState.java b/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/MemsState.java index 40543ad5d30..c141538e055 100644 --- a/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/MemsState.java +++ b/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/MemsState.java @@ -9,11 +9,12 @@ */ public enum MemsState implements State, OptionsEnum { UNDEFINED(-1, "UNDEFINED"), // - SS1(0, "SS1"), // - T1(1, "T1"), // - SS2(2, "SS2"), // - T3(3, "T3"), // - T4(4, "T4"); // + INIT(0, "INIT"), // + SS1(1, "SS1"), // + T1(2, "T1"), // + SS2(3, "SS2"), // + T3(4, "T3"), // + T4(5, "T4"); // private final int value; private final String name; diff --git a/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/MemsStateMachine.java b/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/MemsStateMachine.java index 2ebecba6563..7ed4710b91e 100644 --- a/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/MemsStateMachine.java +++ b/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/MemsStateMachine.java @@ -11,13 +11,14 @@ public class MemsStateMachine extends AbstractStateMachine { public MemsStateMachine() { - super(MemsState.UNDEFINED); + super(MemsState.INIT); } @Override public StateHandler getStateHandler(MemsState state) { return switch (state) { - case UNDEFINED -> new UNDEFINEDHandler(); + case UNDEFINED -> new UndefinedHandler(); + case INIT -> new INITHandler(); case SS1 -> new SS1Handler(); case T1 -> new T1Handler(); case SS2 -> new SS2Handler(); diff --git a/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/SS1Handler.java b/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/SS1Handler.java index e693f45ce37..bce14ede8fb 100644 --- a/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/SS1Handler.java +++ b/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/SS1Handler.java @@ -3,18 +3,37 @@ import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; import io.openems.edge.common.statemachine.StateHandler; +/** + * Handler for state: SS1. + * Steady State 1: Grid Connected + * Auto-generated from state-machine.json + */ public class SS1Handler extends StateHandler { @Override protected MemsState runAndGetNextState(MemsContext context) throws OpenemsNamedException { - if (context.getGridVoltage() < context.getUnderVoltageThreshold()) { - return MemsState.T1; - } + // On GRID_VOLTAGE_LOW [isGridVoltageLow] -> T1 + // if (event == MemsEvent.GRID_VOLTAGE_LOW && isGridVoltageLow(context)) { + // return MemsState.T1; + // } + + // On GRID_FAULT -> T1 + // if (event == MemsEvent.GRID_FAULT) { + // return MemsState.T1; + // } + return MemsState.SS1; } @Override protected void onEntry(MemsContext context) throws OpenemsNamedException { - context.getParent().setEssOnGrid(); + // TODO: Implement entry actions + // logGridConnected() + } + + @Override + protected void onExit(MemsContext context) throws OpenemsNamedException { + // TODO: Implement exit actions + // No exit actions } } diff --git a/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/SS2Handler.java b/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/SS2Handler.java index 61f773b4e4d..ec518968f57 100644 --- a/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/SS2Handler.java +++ b/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/SS2Handler.java @@ -3,19 +3,33 @@ import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; import io.openems.edge.common.statemachine.StateHandler; +/** + * Handler for state: SS2. + * Steady State 2: Islanded + * Auto-generated from state-machine.json + */ public class SS2Handler extends StateHandler { @Override protected MemsState runAndGetNextState(MemsContext context) throws OpenemsNamedException { - if (context.getGridVoltage() >= context.getUnderVoltageThreshold() - && context.getStableGridTimer() >= context.getStableGridTime()) { - return MemsState.T3; - } + // On GRID_VOLTAGE_STABLE [isGridVoltageStableForTime] -> T3 + // if (event == MemsEvent.GRID_VOLTAGE_STABLE && isGridVoltageStableForTime(context)) { + // return MemsState.T3; + // } + return MemsState.SS2; } @Override protected void onEntry(MemsContext context) throws OpenemsNamedException { - context.getParent().setEssOffGrid(); + // TODO: Implement entry actions + // logIslanded() + // setEssOffGrid() + } + + @Override + protected void onExit(MemsContext context) throws OpenemsNamedException { + // TODO: Implement exit actions + // No exit actions } } diff --git a/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/T1Handler.java b/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/T1Handler.java index 30c07d1307d..8f6af9d4ad8 100644 --- a/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/T1Handler.java +++ b/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/T1Handler.java @@ -3,16 +3,29 @@ import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; import io.openems.edge.common.statemachine.StateHandler; +/** + * Handler for state: T1. + * Transition 1: Unplanned Islanding + * Auto-generated from state-machine.json + */ public class T1Handler extends StateHandler { @Override protected MemsState runAndGetNextState(MemsContext context) throws OpenemsNamedException { - return MemsState.SS2; + // No transitions defined - stay in current state + return MemsState.T1; } @Override protected void onEntry(MemsContext context) throws OpenemsNamedException { - context.getParent().openRelay(); - context.getParent().setEssOffGrid(); + // TODO: Implement entry actions + // openRelay() + // setEssOffGrid() + } + + @Override + protected void onExit(MemsContext context) throws OpenemsNamedException { + // TODO: Implement exit actions + // No exit actions } } diff --git a/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/T3Handler.java b/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/T3Handler.java index c2d42d5ea66..244e8e541d5 100644 --- a/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/T3Handler.java +++ b/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/T3Handler.java @@ -3,16 +3,30 @@ import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; import io.openems.edge.common.statemachine.StateHandler; +/** + * Handler for state: T3. + * Transition 3: Reconnect + * Auto-generated from state-machine.json + */ public class T3Handler extends StateHandler { @Override protected MemsState runAndGetNextState(MemsContext context) throws OpenemsNamedException { - return MemsState.SS1; + // No transitions defined - stay in current state + return MemsState.T3; } @Override protected void onEntry(MemsContext context) throws OpenemsNamedException { - context.getParent().closeRelay(); - context.getParent().setEssOnGrid(); + // TODO: Implement entry actions + // checkSync() + // closeRelay() + // setEssOnGrid() + } + + @Override + protected void onExit(MemsContext context) throws OpenemsNamedException { + // TODO: Implement exit actions + // No exit actions } } diff --git a/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/T4Handler.java b/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/T4Handler.java index 97ab81fe0cf..8ba6687e01b 100644 --- a/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/T4Handler.java +++ b/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/T4Handler.java @@ -2,11 +2,9 @@ import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; import io.openems.edge.common.statemachine.StateHandler; -import io.openems.edge.controller.microgrid.statemachine.MemsContext; -import io.openems.edge.controller.microgrid.statemachine.MemsState; /** - * Handler for state: T4 + * Handler for state: T4. * Transition 4: Black Start * Auto-generated from state-machine.json */ diff --git a/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/UNDEFINEDHandler.java b/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/UNDEFINEDHandler.java deleted file mode 100644 index 408dd3403f4..00000000000 --- a/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/UNDEFINEDHandler.java +++ /dev/null @@ -1,12 +0,0 @@ -package io.openems.edge.controller.microgrid.statemachine; - -import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; -import io.openems.edge.common.statemachine.StateHandler; - -public class UNDEFINEDHandler extends StateHandler { - - @Override - protected MemsState runAndGetNextState(MemsContext context) throws OpenemsNamedException { - return MemsState.SS1; - } -} diff --git a/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/UndefinedHandler.java b/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/UndefinedHandler.java new file mode 100644 index 00000000000..6f7eb7174f4 --- /dev/null +++ b/io.openems.edge.controller.microgrid/src/io/openems/edge/controller/microgrid/statemachine/UndefinedHandler.java @@ -0,0 +1,30 @@ +package io.openems.edge.controller.microgrid.statemachine; + +import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.edge.common.statemachine.StateHandler; + +/** + * Handler for state: UNDEFINED. + * UNDEFINED state + * Auto-generated from state-machine.json + */ +public class UndefinedHandler extends StateHandler { + + @Override + protected MemsState runAndGetNextState(MemsContext context) throws OpenemsNamedException { + // No transitions defined - stay in current state + return MemsState.UNDEFINED; + } + + @Override + protected void onEntry(MemsContext context) throws OpenemsNamedException { + // TODO: Implement entry actions + // No entry actions + } + + @Override + protected void onExit(MemsContext context) throws OpenemsNamedException { + // TODO: Implement exit actions + // No exit actions + } +} diff --git a/io.openems.edge.controller.microgrid/test/io/openems/edge/controller/microgrid/MicrogridSupervisorTest.java b/io.openems.edge.controller.microgrid/test/io/openems/edge/controller/microgrid/MicrogridSupervisorTest.java index 8ef188d61e0..842f1138932 100644 --- a/io.openems.edge.controller.microgrid/test/io/openems/edge/controller/microgrid/MicrogridSupervisorTest.java +++ b/io.openems.edge.controller.microgrid/test/io/openems/edge/controller/microgrid/MicrogridSupervisorTest.java @@ -5,12 +5,9 @@ import java.lang.annotation.Annotation; import io.openems.common.channel.AccessMode; +import io.openems.common.test.AbstractComponentConfig; import io.openems.common.types.OpenemsType; import io.openems.edge.common.channel.Doc; -import io.openems.edge.common.channel.IntegerDoc; -import io.openems.edge.common.channel.IntegerWriteChannel; -import io.openems.edge.common.channel.BooleanDoc; -import io.openems.edge.common.channel.BooleanWriteChannel; import io.openems.edge.common.test.AbstractComponentTest.TestCase; import io.openems.edge.controller.test.ControllerTest; import io.openems.edge.common.test.DummyComponentManager; @@ -49,123 +46,180 @@ private ChannelId(Doc doc) { public Doc doc() { return this.doc; } + } + + public static class MyConfig extends AbstractComponentConfig implements Config { + + private String id = CTRL_ID; + private String alias = ""; + private boolean enabled = true; + private String essId = ESS_ID; + private String meterId = METER_ID; + private String relayId = RELAY_ID; + private String relayChannel = RELAY_ID + "/Relay"; + private String essGridModeChannel = ESS_ID + "/SetGridMode"; + private int underVoltageThreshold = 207; + private int stableGridTime = 10; + + public MyConfig() { + super(Config.class, CTRL_ID); + } + + /** + * Create a MyConfig. + * + * @return the MyConfig + */ + public static MyConfig create() { + return new MyConfig(); + } + + /** + * Set ID. + * + * @param id the id + * @return this + */ + public MyConfig setId(String id) { + this.id = id; + return this; + } + + /** + * Set EssId. + * + * @param essId the essId + * @return this + */ + public MyConfig setEssId(String essId) { + this.essId = essId; + return this; + } + + /** + * Set MeterId. + * + * @param meterId the meterId + * @return this + */ + public MyConfig setMeterId(String meterId) { + this.meterId = meterId; + return this; + } + + /** + * Set RelayId. + * + * @param relayId the relayId + * @return this + */ + public MyConfig setRelayId(String relayId) { + this.relayId = relayId; + return this; + } + + /** + * Set RelayChannel. + * + * @param relayChannel the relayChannel + * @return this + */ + public MyConfig setRelayChannel(String relayChannel) { + this.relayChannel = relayChannel; + return this; + } + + /** + * Set EssGridModeChannel. + * + * @param essGridModeChannel the essGridModeChannel + * @return this + */ + public MyConfig setEssGridModeChannel(String essGridModeChannel) { + this.essGridModeChannel = essGridModeChannel; + return this; + } + + /** + * Set UnderVoltageThreshold. + * + * @param underVoltageThreshold the underVoltageThreshold + * @return this + */ + public MyConfig setUnderVoltageThreshold(int underVoltageThreshold) { + this.underVoltageThreshold = underVoltageThreshold; + return this; + } + + /** + * Set StableGridTime. + * + * @param stableGridTime the stableGridTime + * @return this + */ + public MyConfig setStableGridTime(int stableGridTime) { + this.stableGridTime = stableGridTime; + return this; + } + + @Override + public Class annotationType() { + return Config.class; + } + + @Override + public String id() { + return this.id; + } + + @Override + public String alias() { + return this.alias; + } + + @Override + public boolean enabled() { + return this.enabled; + } + + @Override + public String essId() { + return this.essId; + } + + @Override + public String meterId() { + return this.meterId; + } + + @Override + public String relayId() { + return this.relayId; + } - public static class MyConfig implements Config { - - private String id = CTRL_ID; - private String alias = ""; - private boolean enabled = true; - private String essId = ESS_ID; - private String meterId = METER_ID; - private String relayId = RELAY_ID; - private String relayChannel = RELAY_ID + "/Relay"; - private String essGridModeChannel = ESS_ID + "/SetGridMode"; - private int underVoltageThreshold = 207; - private int stableGridTime = 10; - - public static MyConfig create() { - return new MyConfig(); - } - - public MyConfig setId(String id) { - this.id = id; - return this; - } - - public MyConfig setEssId(String essId) { - this.essId = essId; - return this; - } - - public MyConfig setMeterId(String meterId) { - this.meterId = meterId; - return this; - } - - public MyConfig setRelayId(String relayId) { - this.relayId = relayId; - return this; - } - - public MyConfig setRelayChannel(String relayChannel) { - this.relayChannel = relayChannel; - return this; - } - - public MyConfig setEssGridModeChannel(String essGridModeChannel) { - this.essGridModeChannel = essGridModeChannel; - return this; - } - - public MyConfig setUnderVoltageThreshold(int underVoltageThreshold) { - this.underVoltageThreshold = underVoltageThreshold; - return this; - } - - public MyConfig setStableGridTime(int stableGridTime) { - this.stableGridTime = stableGridTime; - return this; - } - - @Override - public Class annotationType() { - return Config.class; - } - - @Override - public String id() { - return this.id; - } - - @Override - public String alias() { - return this.alias; - } - - @Override - public boolean enabled() { - return this.enabled; - } - - @Override - public String ess_id() { - return this.essId; - } - - @Override - public String meter_id() { - return this.meterId; - } - - @Override - public String relay_id() { - return this.relayId; - } - - @Override - public String relay_channel() { - return this.relayChannel; - } - - @Override - public String ess_grid_mode_channel() { - return this.essGridModeChannel; - } - - @Override - public int under_voltage_threshold() { - return this.underVoltageThreshold; - } - - @Override - public int stable_grid_time() { - return this.stableGridTime; - } - - @Override - public String webconsole_configurationFactory_nameHint() { - return ""; - } + @Override + public String relayChannel() { + return this.relayChannel; + } + + @Override + public String essGridModeChannel() { + return this.essGridModeChannel; + } + + @Override + public int underVoltageThreshold() { + return this.underVoltageThreshold; + } + + @Override + public int stableGridTime() { + return this.stableGridTime; + } + + @Override + public String webconsole_configurationFactory_nameHint() { + return ""; } } @@ -199,6 +253,11 @@ protected DummyRelay(String id) { } } + /** + * Set up before each test. + * + * @throws Exception on error + */ @Before public void setUp() throws Exception { this.componentManager = new DummyComponentManager(); @@ -213,6 +272,11 @@ public void setUp() throws Exception { this.controller = new MicrogridSupervisorImpl(); } + /** + * Test Transitions. + * + * @throws Exception on error + */ @Test public void testTransitions() throws Exception { new ControllerTest(this.controller) // @@ -220,7 +284,7 @@ public void testTransitions() throws Exception { .addComponent(this.ess) // .addComponent(this.meter) // .addComponent(this.relay) // - .activate(MyConfig.create() // + .activate(MyEss.MyConfig.create() // .setId(CTRL_ID) // .setEssId(ESS_ID) // .setMeterId(METER_ID) // @@ -228,8 +292,7 @@ public void testTransitions() throws Exception { .setRelayChannel("Relay") // .setEssGridModeChannel(ESS_ID + "/SetGridMode") // .setUnderVoltageThreshold(207) // - .setStableGridTime(2) // - .build()) // + .setStableGridTime(2)) // .next(new TestCase("SS1: Grid Connected") // .input(METER_ID, ElectricityMeter.ChannelId.VOLTAGE, 230000) // 230V .output(CTRL_ID, MicrogridSupervisor.ChannelId.STATE_MACHINE, MemsState.SS1) @@ -240,9 +303,7 @@ public void testTransitions() throws Exception { .output(RELAY_ID, "Relay", false) .output(ESS_ID, "SetGridMode", GridMode.OFF_GRID.getValue())) // Immediate transition to T1 .next(new TestCase("T1 -> SS2: Islanded") // - .output(CTRL_ID, MicrogridSupervisor.ChannelId.STATE_MACHINE, MemsState.SS2)) // Immediate - // transition to - // SS2 + .output(CTRL_ID, MicrogridSupervisor.ChannelId.STATE_MACHINE, MemsState.SS2)) // .next(new TestCase("SS2: Still Islanded") // .input(METER_ID, ElectricityMeter.ChannelId.VOLTAGE, 230000) // 230V, Timer becomes 1 .output(CTRL_ID, MicrogridSupervisor.ChannelId.STATE_MACHINE, MemsState.SS2)) // @@ -252,7 +313,6 @@ public void testTransitions() throws Exception { .output(RELAY_ID, "Relay", true) .output(ESS_ID, "SetGridMode", GridMode.ON_GRID.getValue())) // Now showing T3 .next(new TestCase("T3 -> SS1") // - .output(CTRL_ID, MicrogridSupervisor.ChannelId.STATE_MACHINE, MemsState.SS1)); // Now showing - // SS1 + .output(CTRL_ID, MicrogridSupervisor.ChannelId.STATE_MACHINE, MemsState.SS1)); // Now showing SS1 } } diff --git a/io.openems.edge.controller.microgrid/test/io/openems/edge/controller/microgrid/MyConfig.java b/io.openems.edge.controller.microgrid/test/io/openems/edge/controller/microgrid/MyConfig.java index cb87c9629a4..c79f9b1135e 100644 --- a/io.openems.edge.controller.microgrid/test/io/openems/edge/controller/microgrid/MyConfig.java +++ b/io.openems.edge.controller.microgrid/test/io/openems/edge/controller/microgrid/MyConfig.java @@ -2,17 +2,22 @@ import io.openems.common.test.AbstractComponentConfig; +/** + * Dummy Config for Microgrid Supervisor tests. + */ public class MyConfig extends AbstractComponentConfig implements Config { protected static class Builder { private String id; - private String ess_id; - private String meter_id; - private String relay_id; - private String relay_channel; - private String ess_grid_mode_channel; - private int under_voltage_threshold; - private int stable_grid_time; + private String alias = ""; + private boolean enabled = true; + private String essId; + private String meterId; + private String relayId; + private String relayChannel; + private String essGridModeChannel; + private int underVoltageThreshold; + private int stableGridTime; private Builder() { } @@ -22,38 +27,48 @@ public Builder setId(String id) { return this; } - public Builder setEssId(String ess_id) { - this.ess_id = ess_id; + public Builder setAlias(String alias) { + this.alias = alias; return this; } - public Builder setMeterId(String meter_id) { - this.meter_id = meter_id; + public Builder setEnabled(boolean enabled) { + this.enabled = enabled; return this; } - public Builder setRelayId(String relay_id) { - this.relay_id = relay_id; + public Builder setEssId(String essId) { + this.essId = essId; return this; } - public Builder setRelayChannel(String relay_channel) { - this.relay_channel = relay_channel; + public Builder setMeterId(String meterId) { + this.meterId = meterId; return this; } - public Builder setEssGridModeChannel(String ess_grid_mode_channel) { - this.ess_grid_mode_channel = ess_grid_mode_channel; + public Builder setRelayId(String relayId) { + this.relayId = relayId; return this; } - public Builder setUnderVoltageThreshold(int under_voltage_threshold) { - this.under_voltage_threshold = under_voltage_threshold; + public Builder setRelayChannel(String relayChannel) { + this.relayChannel = relayChannel; return this; } - public Builder setStableGridTime(int stable_grid_time) { - this.stable_grid_time = stable_grid_time; + public Builder setEssGridModeChannel(String essGridModeChannel) { + this.essGridModeChannel = essGridModeChannel; + return this; + } + + public Builder setUnderVoltageThreshold(int underVoltageThreshold) { + this.underVoltageThreshold = underVoltageThreshold; + return this; + } + + public Builder setStableGridTime(int stableGridTime) { + this.stableGridTime = stableGridTime; return this; } @@ -62,6 +77,11 @@ public MyConfig build() { } } + /** + * Create a Builder. + * + * @return the Builder + */ public static Builder create() { return new Builder(); } @@ -74,42 +94,47 @@ private MyConfig(Builder builder) { } @Override - public String ess_id() { - return this.builder.ess_id; + public String alias() { + return this.builder.alias; + } + + @Override + public boolean enabled() { + return this.builder.enabled; } @Override - public String meter_id() { - return this.builder.meter_id; + public String essId() { + return this.builder.essId; } @Override - public String relay_id() { - return this.builder.relay_id; + public String meterId() { + return this.builder.meterId; } @Override - public String relay_channel() { - return this.builder.relay_channel; + public String relayId() { + return this.builder.relayId; } @Override - public String ess_grid_mode_channel() { - return this.builder.ess_grid_mode_channel; + public String relayChannel() { + return this.builder.relayChannel; } @Override - public int under_voltage_threshold() { - return this.builder.under_voltage_threshold; + public String essGridModeChannel() { + return this.builder.essGridModeChannel; } @Override - public int stable_grid_time() { - return this.builder.stable_grid_time; + public int underVoltageThreshold() { + return this.builder.underVoltageThreshold; } @Override - public String webconsole_configurationFactory_nameHint() { - return ""; + public int stableGridTime() { + return this.builder.stableGridTime; } } diff --git a/io.openems.edge.controller.microgrid/test/io/openems/edge/controller/microgrid/dispatcher/DummyManagedSymmetricPvInverter.java b/io.openems.edge.controller.microgrid/test/io/openems/edge/controller/microgrid/dispatcher/DummyManagedSymmetricPvInverter.java new file mode 100644 index 00000000000..d2c7d130f9d --- /dev/null +++ b/io.openems.edge.controller.microgrid/test/io/openems/edge/controller/microgrid/dispatcher/DummyManagedSymmetricPvInverter.java @@ -0,0 +1,47 @@ +package io.openems.edge.controller.microgrid.dispatcher; + +import io.openems.common.channel.AccessMode; +import io.openems.common.types.OpenemsType; +import io.openems.common.types.MeterType; +import io.openems.edge.common.channel.Doc; +import io.openems.edge.common.component.OpenemsComponent; +import io.openems.edge.common.test.AbstractDummyOpenemsComponent; +import io.openems.edge.meter.api.ElectricityMeter; + +public class DummyManagedSymmetricPvInverter extends AbstractDummyOpenemsComponent + implements ElectricityMeter, OpenemsComponent { + + public enum ChannelId implements io.openems.edge.common.channel.ChannelId { + SET_ACTIVE_POWER_LIMIT(Doc.of(OpenemsType.INTEGER).accessMode(AccessMode.WRITE_ONLY)); + + private final Doc doc; + + private ChannelId(Doc doc) { + this.doc = doc; + } + + @Override + public Doc doc() { + return this.doc; + } + } + + public DummyManagedSymmetricPvInverter(String id) { + super(id, // + OpenemsComponent.ChannelId.values(), // + ElectricityMeter.ChannelId.values(), // + ChannelId.values() // + ); + } + + @Override + public MeterType getMeterType() { + return MeterType.PRODUCTION; + } + + @Override + protected DummyManagedSymmetricPvInverter self() { + return this; + } + +} diff --git a/io.openems.edge.controller.microgrid/test/io/openems/edge/controller/microgrid/dispatcher/DummyMicrogridSupervisor.java b/io.openems.edge.controller.microgrid/test/io/openems/edge/controller/microgrid/dispatcher/DummyMicrogridSupervisor.java new file mode 100644 index 00000000000..fd967f076f4 --- /dev/null +++ b/io.openems.edge.controller.microgrid/test/io/openems/edge/controller/microgrid/dispatcher/DummyMicrogridSupervisor.java @@ -0,0 +1,17 @@ +package io.openems.edge.controller.microgrid.dispatcher; + +import io.openems.edge.common.component.AbstractOpenemsComponent; +import io.openems.edge.common.component.OpenemsComponent; +import io.openems.edge.controller.microgrid.MicrogridSupervisor; + +public class DummyMicrogridSupervisor extends AbstractOpenemsComponent implements MicrogridSupervisor, OpenemsComponent { + + public DummyMicrogridSupervisor(String id) { + super(// + OpenemsComponent.ChannelId.values(), // + MicrogridSupervisor.ChannelId.values() // + ); + super.activate(null, id, "", true); + } + +} diff --git a/io.openems.edge.controller.microgrid/test/io/openems/edge/controller/microgrid/dispatcher/MicrogridDispatcherImplTest.java b/io.openems.edge.controller.microgrid/test/io/openems/edge/controller/microgrid/dispatcher/MicrogridDispatcherImplTest.java new file mode 100644 index 00000000000..8a0df8828d2 --- /dev/null +++ b/io.openems.edge.controller.microgrid/test/io/openems/edge/controller/microgrid/dispatcher/MicrogridDispatcherImplTest.java @@ -0,0 +1,94 @@ +package io.openems.edge.controller.microgrid.dispatcher; + +import org.junit.Test; + +import io.openems.common.types.ChannelAddress; +import io.openems.edge.common.test.AbstractComponentTest.TestCase; +import io.openems.edge.common.test.DummyComponentManager; +import io.openems.edge.controller.microgrid.statemachine.MemsState; +import io.openems.edge.controller.test.ControllerTest; +import io.openems.edge.ess.test.DummyManagedSymmetricEss; +import io.openems.edge.meter.test.DummyElectricityMeter; +import io.openems.edge.io.test.DummyInputOutput; + +public class MicrogridDispatcherImplTest { + + @Test + public void testSS1() throws Exception { + new ControllerTest(new MicrogridDispatcherImpl()) // + .addReference("componentManager", new DummyComponentManager()) // + .addComponent(new DummyManagedSymmetricEss("ess0")) // + .addComponent(new DummyElectricityMeter("meter0")) // + .addComponent(new DummyMicrogridSupervisor("supervisor0")) // + .addComponent(new DummyInputOutput("io0")) // + .activate(MyConfig.create() // + .setId("ctrl0") // + .setEssId("ess0") // + .setMeterId("meter0") // + .setGensetId("meter1") // + .setPvId("pv0") // + .setSupervisorId("supervisor0") // + .setGridLimit(10000) // + .setGensetStartStopChannel("io0/InputOutput0") // + .build()) + .next(new TestCase() // SS1: Peak Shaving + .input(new ChannelAddress("supervisor0", "StateMachine"), MemsState.SS1) // + .input(new ChannelAddress("meter0", "ActivePower"), 15000) // + .output(new ChannelAddress("ess0", "SetActivePowerEquals"), 5000) // + .output(new ChannelAddress("io0", "InputOutput0"), false)) // Stop Genset + .next(new TestCase() // SS1: No Peak Shaving + .input(new ChannelAddress("meter0", "ActivePower"), 5000) // + .output(new ChannelAddress("ess0", "SetActivePowerEquals"), null)); + } + + @Test + public void testSS2() throws Exception { + new ControllerTest(new MicrogridDispatcherImpl()) // + .addReference("componentManager", new DummyComponentManager()) // + .addComponent(new DummyManagedSymmetricEss("ess0")) // + .addComponent(new DummyElectricityMeter("meter0")) // + .addComponent(new DummyElectricityMeter("meter1")) // Genset + .addComponent(new DummyManagedSymmetricPvInverter("pv0")) // + .addComponent(new DummyMicrogridSupervisor("supervisor0")) // + .addComponent(new DummyInputOutput("io0")) // + .activate(MyConfig.create() // + .setId("ctrl0") // + .setEssId("ess0") // + .setMeterId("meter0") // + .setGensetId("meter1") // + .setPvId("pv0") // + .setSupervisorId("supervisor0") // + .setGensetStartSoc(20) // + .setGensetStopSoc(80) // + .setGensetCapacity(50000) // + .setGensetStartStopChannel("io0/InputOutput0") // + .build()) + .next(new TestCase() // SS2: Genset Start (SoC < 20) + .input(new ChannelAddress("supervisor0", "StateMachine"), MemsState.SS2) // + .input(new ChannelAddress("ess0", "Soc"), 15) // + .input(new ChannelAddress("meter1", "ActivePower"), 0) // Genset OFF + .input(new ChannelAddress("ess0", "ActivePower"), 0) // + .input(new ChannelAddress("pv0", "ActivePower"), 0) // + .output(new ChannelAddress("io0", "InputOutput0"), true)) // Start Genset + .next(new TestCase() // SS2: Genset Stop (SoC > 80) + .input(new ChannelAddress("ess0", "Soc"), 85) // + .input(new ChannelAddress("meter1", "ActivePower"), 20000) // Genset ON + .output(new ChannelAddress("io0", "InputOutput0"), false)) // Stop Genset + .next(new TestCase() // SS2: Genset Loading (Target = 50000 * 0.4 = 20000) + .input(new ChannelAddress("ess0", "Soc"), 50) // + .input(new ChannelAddress("meter1", "ActivePower"), 10000) // Currently 10kW + .input(new ChannelAddress("pv0", "ActivePower"), 5000) // + .input(new ChannelAddress("ess0", "ActivePower"), 0) // + // Consumption = 10000 + 5000 + 0 = 15000 + // ESS_Setpoint = Consumption - PV - Target = 15000 - 5000 - 20000 = -10000 (Charge) + .output(new ChannelAddress("ess0", "SetActivePowerEquals"), -10000)) + .next(new TestCase() // SS2: PV Curtailment (SoC > 95 and cannot charge) + .input(new ChannelAddress("ess0", "Soc"), 98) // + .input(new ChannelAddress("ess0", "AllowedChargePower"), -50) // Almost 0 + .input(new ChannelAddress("meter1", "ActivePower"), 0) // Genset OFF + .input(new ChannelAddress("pv0", "ActivePower"), 10000) // + .input(new ChannelAddress("ess0", "ActivePower"), -50) // + // Consumption = 0 + 10000 - 50 = 9950 + .output(new ChannelAddress("pv0", "SetActivePowerLimit"), 9950)); + } +} diff --git a/io.openems.edge.controller.microgrid/test/io/openems/edge/controller/microgrid/dispatcher/MyConfig.java b/io.openems.edge.controller.microgrid/test/io/openems/edge/controller/microgrid/dispatcher/MyConfig.java new file mode 100644 index 00000000000..d424c5cc5ec --- /dev/null +++ b/io.openems.edge.controller.microgrid/test/io/openems/edge/controller/microgrid/dispatcher/MyConfig.java @@ -0,0 +1,173 @@ +package io.openems.edge.controller.microgrid.dispatcher; + +import io.openems.common.test.AbstractComponentConfig; + +/** + * Dummy Config for Microgrid Dispatcher tests. + */ +public class MyConfig extends AbstractComponentConfig implements Config { + + protected static class Builder { + private String id; + private String alias = ""; + private boolean enabled = true; + private String essId; + private String meterId; + private String gensetId; + private String gensetStartStopChannel; + private String pvId; + private String supervisorId; + private int gridLimit; + private int gensetStartSoc; + private int gensetStopSoc; + private int gensetCapacity; + + private Builder() { + } + + public Builder setId(String id) { + this.id = id; + return this; + } + + public Builder setAlias(String alias) { + this.alias = alias; + return this; + } + + public Builder setEnabled(boolean enabled) { + this.enabled = enabled; + return this; + } + + public Builder setEssId(String essId) { + this.essId = essId; + return this; + } + + public Builder setMeterId(String meterId) { + this.meterId = meterId; + return this; + } + + public Builder setGensetId(String gensetId) { + this.gensetId = gensetId; + return this; + } + + public Builder setGensetStartStopChannel(String gensetStartStopChannel) { + this.gensetStartStopChannel = gensetStartStopChannel; + return this; + } + + public Builder setPvId(String pvId) { + this.pvId = pvId; + return this; + } + + public Builder setSupervisorId(String supervisorId) { + this.supervisorId = supervisorId; + return this; + } + + public Builder setGridLimit(int gridLimit) { + this.gridLimit = gridLimit; + return this; + } + + public Builder setGensetStartSoc(int gensetStartSoc) { + this.gensetStartSoc = gensetStartSoc; + return this; + } + + public Builder setGensetStopSoc(int gensetStopSoc) { + this.gensetStopSoc = gensetStopSoc; + return this; + } + + public Builder setGensetCapacity(int gensetCapacity) { + this.gensetCapacity = gensetCapacity; + return this; + } + + public MyConfig build() { + return new MyConfig(this); + } + } + + /** + * Create a Builder. + * + * @return the Builder + */ + public static Builder create() { + return new Builder(); + } + + private final Builder builder; + + private MyConfig(Builder builder) { + super(Config.class, builder.id); + this.builder = builder; + } + + @Override + public String alias() { + return this.builder.alias; + } + + @Override + public boolean enabled() { + return this.builder.enabled; + } + + @Override + public String essId() { + return this.builder.essId; + } + + @Override + public String meterId() { + return this.builder.meterId; + } + + @Override + public String gensetId() { + return this.builder.gensetId; + } + + @Override + public String gensetStartStopChannel() { + return this.builder.gensetStartStopChannel; + } + + @Override + public String pvId() { + return this.builder.pvId; + } + + @Override + public String supervisorId() { + return this.builder.supervisorId; + } + + @Override + public int gridLimit() { + return this.builder.gridLimit; + } + + @Override + public int gensetStartSoc() { + return this.builder.gensetStartSoc; + } + + @Override + public int gensetStopSoc() { + return this.builder.gensetStopSoc; + } + + @Override + public int gensetCapacity() { + return this.builder.gensetCapacity; + } +} diff --git a/io.openems.edge.io.revpi/bnd.bnd b/io.openems.edge.io.revpi/bnd.bnd index 908d1c7476f..d6ad3dd640d 100644 --- a/io.openems.edge.io.revpi/bnd.bnd +++ b/io.openems.edge.io.revpi/bnd.bnd @@ -3,16 +3,12 @@ Bundle-Vendor: opernikus GmbH Bundle-License: https://opensource.org/licenses/EPL-2.0 Bundle-Version: 1.0.0.${tstamp} --includeresource.librevpi: \ - @lib/librevpi-dio-java.jar; lib:=true - -buildpath: \ ${buildpath},\ com.google.guava,\ io.openems.common,\ io.openems.edge.common,\ - io.openems.edge.io.api,\ - lib/librevpi-dio-java.jar;version=file,\ + io.openems.edge.io.api -testpath: \ ${testpath} diff --git a/io.openems.edge.io.revpi/src/org/clehne/revpi/dataio/DataInOut.java b/io.openems.edge.io.revpi/src/org/clehne/revpi/dataio/DataInOut.java new file mode 100644 index 00000000000..a45997935d8 --- /dev/null +++ b/io.openems.edge.io.revpi/src/org/clehne/revpi/dataio/DataInOut.java @@ -0,0 +1,49 @@ +package org.clehne.revpi.dataio; + +import java.io.IOException; + +/** + * Dummy DataInOut. + */ +public class DataInOut { + + /** + * Dummy close. + * + * @throws IOException if error + */ + public void close() throws IOException { + } + + /** + * Dummy getDataOut. + * + * @param idx index + * @return false + * @throws IOException if error + */ + public boolean getDataOut(int idx) throws IOException { + return false; + } + + /** + * Dummy getDataIn. + * + * @param idx index + * @return false + * @throws IOException if error + */ + public boolean getDataIn(int idx) throws IOException { + return false; + } + + /** + * Dummy setDataOut. + * + * @param idx index + * @param val value + * @throws IOException if error + */ + public void setDataOut(int idx, boolean val) throws IOException { + } +} diff --git a/mems/state-machine.json b/mems/state-machine.json index 2662936d83d..0666275ead6 100644 --- a/mems/state-machine.json +++ b/mems/state-machine.json @@ -3,7 +3,7 @@ "id": "microgrid", "version": "1.0.0", "description": "IEEE 2030.7 Microgrid Supervisor Controller", - "initial": "SS1", + "initial": "INIT", "context": { "ess_id": "ess0", "meter_id": "meter0", @@ -14,6 +14,19 @@ "stable_grid_timer": 0 }, "states": { + "INIT": { + "description": "Initial State: Determine starting mode", + "always": [ + { + "target": "SS1", + "guard": "isGridVoltageNormal" + }, + { + "target": "T4", + "guard": "isGridVoltageLow" + } + ] + }, "SS1": { "description": "Steady State 1: Grid Connected", "entry": [ @@ -68,17 +81,34 @@ "isGridVoltageLow": { "expression": "context.grid_voltage < context.under_voltage_threshold" }, + "isGridVoltageNormal": { + "expression": "context.grid_voltage >= context.under_voltage_threshold" + }, "isGridVoltageStableForTime": { "expression": "context.grid_voltage >= context.under_voltage_threshold && context.stable_grid_timer >= context.stable_grid_time" } }, "actions": { - "openRelay": { "description": "Open the islanding relay" }, - "closeRelay": { "description": "Close the islanding relay" }, - "setEssOffGrid": { "description": "Set ESS to OFF_GRID mode" }, - "setEssOnGrid": { "description": "Set ESS to ON_GRID mode" }, - "checkSync": { "description": "Perform sync check" }, - "logGridConnected": { "description": "Log grid connected state" }, - "logIslanded": { "description": "Log islanded state" } + "openRelay": { + "description": "Open the islanding relay" + }, + "closeRelay": { + "description": "Close the islanding relay" + }, + "setEssOffGrid": { + "description": "Set ESS to OFF_GRID mode" + }, + "setEssOnGrid": { + "description": "Set ESS to ON_GRID mode" + }, + "checkSync": { + "description": "Perform sync check" + }, + "logGridConnected": { + "description": "Log grid connected state" + }, + "logIslanded": { + "description": "Log islanded state" + } } -} +} \ No newline at end of file diff --git a/mems/tools/generate.js b/mems/tools/generate.js index fb55446c1b2..96da54cc5e6 100644 --- a/mems/tools/generate.js +++ b/mems/tools/generate.js @@ -21,6 +21,9 @@ function loadJson(path) { } function toPascalCase(str) { + if (str === 'UNDEFINED') { + return 'Undefined'; + } return str .split(/[._-]/) .map(word => word.charAt(0).toUpperCase() + word.slice(1)) @@ -340,6 +343,12 @@ ${this.generateStateHandlerSwitch()} console.log('Generating StateHandler classes...'); this.generateHandlersRecursive(this.machine.states, '', outputDir); + + // Also generate UndefinedHandler if it's in the state list but not in the machine states + const states = this.extractAllStates(this.machine.states, ''); + if (states.some(s => s.name === 'UNDEFINED')) { + this.generateSingleHandler('UNDEFINED', { description: 'UNDEFINED state' }, 'UndefinedHandler', outputDir); + } } generateHandlersRecursive(states, prefix, outputDir) { @@ -365,11 +374,9 @@ ${this.generateStateHandlerSwitch()} import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; import io.openems.edge.common.statemachine.StateHandler; -import ${this.packageName}.MemsContext; -import ${this.packageName}.MemsState; /** - * Handler for state: ${stateName} + * Handler for state: ${stateName}. * ${state.description || ''} * Auto-generated from state-machine.json */ diff --git a/mems/tools/verify.js b/mems/tools/verify.js index f00443d84c3..abed89836b2 100644 --- a/mems/tools/verify.js +++ b/mems/tools/verify.js @@ -25,18 +25,18 @@ class StateMachineVerifier { this.transitions = []; this.errors = []; this.warnings = []; - + this.buildGraph(); } - + buildGraph() { this.extractStates(this.machine.states, ''); } - + extractStates(states, prefix) { for (const [name, state] of Object.entries(states)) { const fullName = prefix ? `${prefix}.${name}` : name; - + const stateInfo = { name: fullName, type: state.type || 'atomic', @@ -47,41 +47,41 @@ class StateMachineVerifier { transitions: [], incomingTransitions: [] }; - + // Extract transitions from 'on' if (state.on) { for (const [event, trans] of Object.entries(state.on)) { this.extractTransitions(trans, fullName, event, stateInfo); } } - + // Extract transitions from 'after' if (state.after) { for (const [delay, trans] of Object.entries(state.after)) { this.extractTransitions(trans, fullName, `after:${delay}`, stateInfo); } } - + // Extract transitions from 'always' if (state.always) { this.extractTransitions(state.always, fullName, 'always', stateInfo); } - + this.states.set(fullName, stateInfo); - + // Recurse into substates if (state.states) { this.extractStates(state.states, fullName); } } } - + extractTransitions(trans, fromState, event, stateInfo) { const transitions = Array.isArray(trans) ? trans : [trans]; - + transitions.forEach(t => { let target, guard; - + if (typeof t === 'string') { target = t; } else if (t && t.target) { @@ -91,7 +91,7 @@ class StateMachineVerifier { // Internal transition (no target) return; } - + if (target) { const transition = { from: fromState, @@ -99,24 +99,24 @@ class StateMachineVerifier { event, guard: guard || null }; - + stateInfo.transitions.push(transition); this.transitions.push(transition); } }); } - + resolveTarget(target, currentState) { // Handle absolute references (#stateName) if (target.startsWith('#')) { return target.substring(target.indexOf('.') + 1) || target.substring(1); } - + // Handle relative references if (target.includes('.')) { return target; } - + // Simple state name - could be sibling or child const parts = currentState.split('.'); if (parts.length > 1) { @@ -124,38 +124,38 @@ class StateMachineVerifier { parts.pop(); return `${parts.join('.')}.${target}`; } - + return target; } - + verify() { console.log('=== MEMS State Machine Formal Verification ===\n'); - + this.checkDeadlocks(); this.checkReachability(); this.checkDeterminism(); this.checkGuardCompleteness(); this.checkIEEE2030_7Compliance(); - + return this.report(); } - + checkDeadlocks() { console.log('Checking for deadlocks...'); - + for (const [name, state] of this.states) { // Skip parallel container states and states with substates if (state.isParallel || state.hasSubstates) continue; - + // Final states are allowed to have no outgoing transitions if (state.isFinal) continue; - + // Check if state has any outgoing transitions const hasOutgoing = state.transitions.length > 0; - + // Check if any parent state has transitions that could exit this state const parentTransitions = this.getParentTransitions(name); - + if (!hasOutgoing && parentTransitions.length === 0) { // Check if this is emergencyShutdown - it's allowed to be a "waiting" state if (name === 'emergencyShutdown') { @@ -166,11 +166,11 @@ class StateMachineVerifier { } } } - + getParentTransitions(stateName) { const parts = stateName.split('.'); const parentTransitions = []; - + while (parts.length > 1) { parts.pop(); const parentName = parts.join('.'); @@ -179,43 +179,43 @@ class StateMachineVerifier { parentTransitions.push(...parent.transitions); } } - + return parentTransitions; } - + checkReachability() { console.log('Checking reachability...'); - + const reachable = new Set(); const queue = [this.machine.initial]; - + while (queue.length > 0) { const current = queue.shift(); if (reachable.has(current)) continue; - + reachable.add(current); - + const state = this.states.get(current); if (!state) continue; - + // Add initial substate if compound if (state.initial) { queue.push(`${current}.${state.initial}`); } - + // Add all parallel substates if (state.isParallel && state.hasSubstates) { const substates = this.getDirectSubstates(current); substates.forEach(s => queue.push(s)); } - + // Add transition targets state.transitions.forEach(t => { if (t.to && !reachable.has(t.to)) { queue.push(t.to); } }); - + // Check parent transitions const parentTransitions = this.getParentTransitions(current); parentTransitions.forEach(t => { @@ -224,29 +224,29 @@ class StateMachineVerifier { } }); } - + // Check for unreachable states for (const [name, state] of this.states) { // Skip internal states that are reached via initial const isReachableViaParent = this.isReachableViaParent(name, reachable); - + if (!reachable.has(name) && !isReachableViaParent) { this.warnings.push(`Unreachable state: '${name}'`); } } } - + getDirectSubstates(parentName) { const substates = []; for (const [name] of this.states) { - if (name.startsWith(parentName + '.') && - name.substring(parentName.length + 1).indexOf('.') === -1) { + if (name.startsWith(parentName + '.') && + name.substring(parentName.length + 1).indexOf('.') === -1) { substates.push(name); } } return substates; } - + isReachableViaParent(stateName, reachable) { const parts = stateName.split('.'); while (parts.length > 1) { @@ -261,21 +261,21 @@ class StateMachineVerifier { } return false; } - + checkDeterminism() { console.log('Checking determinism...'); - + for (const [name, state] of this.states) { // Group transitions by event const byEvent = new Map(); - + state.transitions.forEach(t => { if (!byEvent.has(t.event)) { byEvent.set(t.event, []); } byEvent.get(t.event).push(t); }); - + // Check for non-determinism for (const [event, transitions] of byEvent) { if (transitions.length > 1) { @@ -293,12 +293,12 @@ class StateMachineVerifier { } } } - + checkGuardCompleteness() { console.log('Checking guard completeness...'); - + const definedGuards = new Set(Object.keys(this.machine.guards || {})); - + this.transitions.forEach(t => { if (t.guard && typeof t.guard === 'string') { if (!definedGuards.has(t.guard)) { @@ -307,68 +307,70 @@ class StateMachineVerifier { } }); } - + checkIEEE2030_7Compliance() { console.log('Checking IEEE 2030.7 compliance...'); - + const requiredStates = [ 'gridConnected', 'islanded', 'emergencyShutdown' ]; - + const requiredCapabilities = [ - { name: 'Grid-connected mode', check: () => this.states.has('gridConnected') }, - { name: 'Island mode', check: () => this.states.has('islanded') }, - { name: 'Transition to island', check: () => this.hasTransitionBetween('gridConnected', 'island') }, - { name: 'Transition to grid', check: () => this.hasTransitionBetween('islanded', 'gridConnected') }, - { name: 'Black start capability', check: () => this.states.has('blackStart') }, + { name: 'Grid-connected mode', check: () => this.states.has('gridConnected') || this.states.has('SS1') }, + { name: 'Island mode', check: () => this.states.has('islanded') || this.states.has('SS2') }, + { name: 'Transition to island', check: () => this.hasTransitionBetween('gridConnected|SS1', 'island|SS2|T1') }, + { name: 'Transition to grid', check: () => this.hasTransitionBetween('islanded|SS2', 'gridConnected|SS1|T3') }, + { name: 'Black start capability', check: () => this.states.has('blackStart') || this.states.has('T4') }, { name: 'Emergency shutdown', check: () => this.states.has('emergencyShutdown') } ]; - + requiredCapabilities.forEach(cap => { if (!cap.check()) { this.warnings.push(`IEEE 2030.7: Missing capability - ${cap.name}`); } }); } - - hasTransitionBetween(from, toPattern) { - return this.transitions.some(t => - t.from.includes(from) && t.to.includes(toPattern) + + hasTransitionBetween(fromPattern, toPattern) { + const fromRegex = new RegExp(fromPattern); + const toRegex = new RegExp(toPattern); + return this.transitions.some(t => + fromRegex.test(t.from) && toRegex.test(t.to) ); } - + report() { console.log('\n=== Verification Results ===\n'); - + const passed = this.errors.length === 0; - + if (this.errors.length > 0) { console.log('❌ ERRORS:'); this.errors.forEach(e => console.log(` - ${e}`)); console.log(''); } - + if (this.warnings.length > 0) { console.log('⚠️ WARNINGS:'); this.warnings.forEach(w => console.log(` - ${w}`)); console.log(''); } - + console.log('Summary:'); console.log(` - States analyzed: ${this.states.size}`); console.log(` - Transitions analyzed: ${this.transitions.length}`); console.log(` - Errors: ${this.errors.length}`); console.log(` - Warnings: ${this.warnings.length}`); console.log(''); - + if (passed) { console.log('✅ Verification PASSED'); } else { console.log('❌ Verification FAILED'); } - + return passed; } }