diff --git a/CODEOWNERS b/CODEOWNERS
index ae0d5d1a3c958..375fc6affc81f 100755
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -114,6 +114,7 @@
/bundles/org.openhab.binding.feed/ @openhab/add-ons-maintainers
/bundles/org.openhab.binding.feican/ @Hilbrand
/bundles/org.openhab.binding.fenecon/ @nixoso
+/bundles/org.openhab.binding.ferroamp/ @basse04
/bundles/org.openhab.binding.fineoffsetweatherstation/ @Andy2003
/bundles/org.openhab.binding.flicbutton/ @pfink
/bundles/org.openhab.binding.fmiweather/ @ssalonen
diff --git a/bom/openhab-addons/pom.xml b/bom/openhab-addons/pom.xml
index 22b4e2b1f2f89..1a227395abdc1 100644
--- a/bom/openhab-addons/pom.xml
+++ b/bom/openhab-addons/pom.xml
@@ -556,6 +556,11 @@
org.openhab.binding.fenecon
${project.version}
+
+ org.openhab.addons.bundles
+ org.openhab.binding.ferroamp
+ ${project.version}
+
org.openhab.addons.bundles
org.openhab.binding.fineoffsetweatherstation
diff --git a/bundles/org.openhab.binding.ferroamp/NOTICE b/bundles/org.openhab.binding.ferroamp/NOTICE
new file mode 100644
index 0000000000000..38d625e349232
--- /dev/null
+++ b/bundles/org.openhab.binding.ferroamp/NOTICE
@@ -0,0 +1,13 @@
+This content is produced and maintained by the openHAB project.
+
+* Project home: https://www.openhab.org
+
+== Declared Project Licenses
+
+This program and the accompanying materials are made available under the terms
+of the Eclipse Public License 2.0 which is available at
+https://www.eclipse.org/legal/epl-2.0/.
+
+== Source Code
+
+https://github.com/openhab/openhab-addons
diff --git a/bundles/org.openhab.binding.ferroamp/README.md b/bundles/org.openhab.binding.ferroamp/README.md
new file mode 100644
index 0000000000000..c482bf8a2ff12
--- /dev/null
+++ b/bundles/org.openhab.binding.ferroamp/README.md
@@ -0,0 +1,240 @@
+# Ferroamp Binding
+
+The Ferroamp binding is used to get live data from Ferroamp EnergyHub
+
+The Ferroamp binding is compatible with EnergyHub Wall and EnergyHub XL, and connects to your local EnergyHub via LAN.
+Data and commands are received/sent using MQTT where the user connects to the MQTT broker residing on the EnergyHub.
+The communication with the broker might take some minute to establish, so Please just be patient. The Thing will be
+in state INITIALIZATION and UNKNOWN during this time and then change to state ONLINE once connection is established.
+
+*note* Contact Ferroamp support to enable MQTT in the EnergyHub and to get the Username and Password:
+
+
+
+Every Sso has a unique serial number which is marked on the side of the SSO unit. Ex. PS00990-A04-S20120476.
+This number is to identify the respective Sso Pv-string.
+
+## Supported Things
+
+The binding retrieves data from the different parts of the Ferroamp EnergyHub such as:
+
+- `ehub`: EnergyHub Wall and EnergyHub XL.
+- `sso` : Solar string optimizer.
+- `eso` : Bidirectional DC/DC converter for connection of battery.
+- `esm` : Energy Storage Module.
+
+## Discovery
+
+Discovery is not supported.
+
+## Thing Configuration
+
+The following configuration parameters are available.
+
+| Name | Type | Description | Default | Required | Advanced |
+|-----------------|---------|-------------------------------------------------------|---------|----------|----------|
+| hostName | text | Hostname or IP address of the device | N/A | yes | no |
+| userName | text | Username to access the device | N/A | yes | no |
+| password | text | Password to access the device | N/A | yes | no |
+| hasBattery | boolean | Has the system a battery connected? | N/A | no | yes |
+
+## Channels
+
+| Channel Type ID | Item Type | Read/Write | Label | Description |
+|--------------------------------------------------------------------|------------|------------------------------------------|------------------------------------------------------------------------------------------------------|
+| grid-frequency | Number:Frequency | R | Grid Frequency | Grid frequency |
+| ace-current-l1 | Number:ElectricCurrent | R | ACE Current L1 | Adaptive Current Equalization (ACE) equalization current set-points in Amps root mean square (Arms) |
+| ace-current-l2 | Number:ElectricCurrent | R | ACE Current L2 | Adaptive Current Equalization (ACE) equalization current set-points in Amps root mean square (Arms) |
+| ace-current-l3 | Number:ElectricCurrent | R | ACE Current L3 | Adaptive Current Equalization (ACE) equalization current set-points in Amps root mean square (Arms) |
+| grid-voltage-l1 | Number:ElectricPotential | R | Grid Voltage L1 | Grid voltage |
+| grid-voltage-l2 | Number:ElectricPotential | R | Grid Voltage L2 | Grid voltage |
+| grid-voltage-l3 | Number:ElectricPotential | R | Grid Voltage L3 | Grid voltage |
+| inverter-rms-current-l1 | Number:ElectricCurrent | R | Inverter RMS Current L1 | Inverter RMS current |
+| inverter-rms-current-l2 | Number:ElectricCurrent | R | Inverter RMS Current L2 | Inverter RMS current |
+| inverter-rms-current-l3 | Number:ElectricCurrent | R | Inverter RMS Current L3 | Inverter RMS current |
+| inverter-reactive-current-l1 | Number:ElectricCurrent | R | Inverter Reactive Current L1 | Inverter reactive current |
+| inverter-reactive-current-l2 | Number:ElectricCurrent | R | Inverter Reactive Current L2 | Inverter reactive current |
+| inverter-reactive-current-l3 | Number:ElectricCurrent | R | Inverter Reactive Current L3 | Inverter reactive current |
+| inverter-active-current-l1 | Number:ElectricCurrent | R | Inverter Active current L1 | Inverter active current |
+| inverter-active-current-l2 | Number:ElectricCurrent | R | Inverter Active current L2 | Inverter active current |
+| inverter-active-current-l3 | Number:ElectricCurrent | R | Inverter Active current L3 | Inverter active current |
+| grid-current-l1 | Number:ElectricCurrent | R | Grid Current L1 | Grid RMS current |
+| grid-current-l2 | Number:ElectricCurrent | R | Grid Current L2 | Grid RMS current |
+| grid-current-l3 | Number:ElectricCurrent | R | Grid Current L3 | Grid RMS current |
+| grid-reactive-current-l1 | Number:ElectricCurrent | R | Grid Reactive Current L1 | Grid reactive current |
+| grid-reactive-current-l2 | Number:ElectricCurrent | R | Grid Reactive Current L2 | Grid reactive current |
+| grid-reactive-current-l3 | Number:ElectricCurrent | R | Grid Reactive Current L3 | Grid reactive current |
+| grid-active-current-l1 | Number:ElectricCurrent | R | Grid Active Current L1 | Grid active current |
+| grid-active-current-l2 | Number:ElectricCurrent | R | Grid Active Current L2 | Grid active current |
+| grid-active-current-l3 | Number:ElectricCurrent | R | Grid Active Current L3 | Grid active current |
+| inverter-load-reactive-current-l1 | Number:ElectricCurrent | R | Inverter Load Reactive Current L1 | |
+| inverter-load-reactive-current-l2 | Number:ElectricCurrent | R | Inverter Load Reactive Current L2 | |
+| inverter-load-reactive-current-l3 | Number:ElectricCurrent | R | Inverter Load Reactive Current L3 | |
+| inverter-load-active-current-l1 | Number:ElectricCurrent | R | Inverter Load Active Current L1 | |
+| inverter-load-active-current-l2 | Number:ElectricCurrent | R | Inverter Load Active Current L2 | |
+| inverter-load-active-current-l3 | Number:ElectricCurrent | R | Inverter Load Active Current L3 | |
+| apparent-power | Number:Power | R | Apparent Power | Apparent power |
+| grid-power-active-l1 | Number:Power | R | Grid Power Active L1 | Grid power, active |
+| grid-power-active-l2 | Number:Power | R | Grid Power Active L2 | Grid power, active |
+| grid-power-active-l3 | Number:Power | R | Grid Power Active L3 | Grid power, active |
+| grid-power-reactive-l1 | Number:Power | R | Grid Power Reactive L1 | Grid power, reactive |
+| grid-power-reactive-l2 | Number:Power | R | Grid Power Reactive L2 | Grid power, reactive |
+| grid-power-reactive-l3 | Number:Power | R | Grid Power Reactive L3 | Grid power, reactive |
+| inverter-power-active-l1 | Number:Power | R | Inverter Power Active L1 | Inverter power, active |
+| inverter-power-active-l2 | Number:Power | R | Inverter Power Active L2 | Inverter power, active |
+| inverter-power-active-l3 | Number:Power | R | Inverter Power Active L3 | Inverter power, active |
+| inverter-power-reactive-l1 | Number:Power | R | Inverter Power Reactive L1 | Inverter power, reactive |
+| inverter-power-reactive-l1 | Number:Power | R | Inverter Power Reactive L2 | Inverter power, reactive |
+| inverter-power-reactive-l1 | Number:Power | R | Inverter Power Reactive L3 | Inverter power, reactive |
+| consumption-power-l1 | Number:Power | R | Consumption Power L1 | |
+| consumption-power-l2 | Number:Power | R | Consumption Power L2 | |
+| consumption-power-l3 | Number:Power | R | Consumption Power L3 | |
+| consumption-power-reactive-l1 | Number:Power | R | Consumption Power Reactive L1 | |
+| consumption-power-reactive-l2 | Number:Power | R | Consumption Power Reactive L2 | |
+| consumption-power-reactive-l3 | Number:Power | R | Consumption Power Reactive L3 | |
+| solar-pv | Number:Power | R | Solar Power | Only sent when system has PV |
+| positive-dc-link-voltage | Number:ElectricPotential | R | Positiv DC Link Voltage | Positiv DC link voltage |
+| negative-dc-link-voltage | Number:ElectricPotential | R | Negative DC Link Voltage | Negative DC link voltage |
+| grid-energy-produced-l1 | Number:Energy | R | Grid Energy Produced L1 | |
+| grid-energy-produced-l2 | Number:Energy | R | Grid Energy Produced L2 | |
+| grid-energy-produced-l3 | Number:Energy | R | Grid Energy Produced L3 | |
+| grid-energy-consumed-l1 | Number:Energy | R | Grid Energy Consumed L1 | |
+| grid-energy-consumed-l2 | Number:Energy | R | Grid Energy Consumed L2 | |
+| grid-energy-consumed-l3 | Number:Energy | R | Grid Energy Consumed L3 | |
+| inverter-energy-produced-l1 | Number:Energy | R | Inverter Energy Produced L1 | |
+| inverter-energy-produced-l2 | Number:Energy | R | Inverter Energy Produced L2 | |
+| inverter-energy-produced-l3 | Number:Energy | R | Inverter Energy Produced L3 | |
+| inverter-energy-consumed-l1 | Number:Energy | R | Inverter Energy Consumed L1 | |
+| inverter-energy-consumed-l2 | Number:Energy | R | Inverter Energy Consumed L2 | |
+| inverter-energy-consumed-l3 | Number:Energy | R | Inverter Energy Consumed L3 | |
+| load-energy-produced-l1 | Number:Energy | R | Load Energy Produced L1 | |
+| load-energy-produced-l2 | Number:Energy | R | Load Energy Produced L2 | |
+| load-energy-produced-l3 | Number:Energy | R | Load Energy Produced L3 | |
+| load-energy-consumed-l1 | Number:Energy | R | Load Energy Consumed L1 | |
+| load-energy-consumed-l2 | Number:Energy | R | Load Energy Consumed L2 | |
+| load-energy-consumed-l3 | Number:Energy | R | Load Energy Consumed L3 | |
+| grid-energy-produced-total | Number:Energy | R | Grid Energy Produced Total | |
+| grid-energy-consumed-total | Number:Energy | R | Grid Energy Consumed Total | |
+| inverter-energy-produced-total | Number:Energy | R | Inverter Energy Produced Total | |
+| inverter-energy-consumed-total | Number:Energy | R | Inverter Energy Consumed Total | |
+| load-energy-produced-total | Number:Energy | R | Load Energy Produced Total | |
+| load-energy-consumed-total | Number:Energy | R | Load Energy Consumed Total | |
+| total-solar-energy | Number:Energy | R | Total Solar Energy | Only sent when system has PV |
+| state | String | R | State of the System | |
+| timestamp | DateTime | R | Time Stamp | Time stamp when message was published |
+| battery-energy-produced | Number:Energy | R | Battery Energy Produced | Only sent when system has batteries |
+| battery-energy-consumed | Number:Energy | R | Battery Energy Consumed | Only sent when system has batteries |
+| soc | Number:Dimensionless | R | System State of Check | State of the system |
+| soh | Number:Dimensionless | R | System State of Health | |
+| power-battery | Number:Power | R | Battery Power | Only sent when system has batteries |
+| total-capacity-batteries | Number:Energy | R | Total Capacity Batteries | Total rated capacity of all batteries |
+
+| s1-id | String | R | S1 ID | Unique identifier of SSO-1 |
+| s1-pv-voltage | Number:ElectricPotential | R | S1 Voltage on PV String Side | Measured on PV string side |
+| s1-pv-current | Number:ElectricCurrent | R | S1 Current on PV String Side | Measured on PV string side |
+| s1-total-solar-energy | Number:Energy | R | S1 Total Solar Energy | Total energy produced by SSO-1 |
+| s1-relay-status | Contact | R | S1 Relay Status | 0 = relay closed (i.e running power), 1 = relay open/disconnected, 2 = precharge |
+| s1-temperature | Number:Temperature | R | S1 Temperature on PCB | Temperature Measured on PCB |
+| s1-fault-code | String | R | S1 FaultCode | 0x00 = OK. For all other values Please contact Ferroamp support |
+| s1-dc-link-voltage | Number:ElectricPotential | R | S1 DC Link Voltage | DC link voltage as measured by SSO-1 |
+| s1-timestamp | DateTime | R | S1 Time Stamp | Time stamp when message was published |
+
+| s2-id | String | R | S2 ID | Unique identifier of SSO-2 |
+| s2-pv-voltage | Number:ElectricPotential | R | S2 Voltage on PV String Side | Measured on PV string side |
+| s2-pv-current | Number:ElectricCurrent | R | S2 Current on PV String Side | Measured on PV string side |
+| s2-total-solar-energy | Number:Energy | R | S2 Total Solar Energy | Total energy produced by SSO-2 |
+| s2-relay-status | Contact | R | S2 Relay Status | 0 = relay closed (i.e running power), 1 = relay open/disconnected, 2 = precharge |
+| s2-temperature | Number:Temperature | R | S2 Temperature on PCB | Temperature Measured on PCB |
+| s2-fault-code | String | R | S2 FaultCode | 0x00 = OK. For all other values Please contact Ferroamp support |
+| s2-dc-link-voltage | Number:ElectricPotential | R | S2 DC Link Voltage | DC link voltage as measured by SSO-2 |
+| s2-timestamp | DateTime | R | S2 Time Stamp | Time stamp when message was published |
+
+| s3-id | String | R | S3 ID | Unique identifier of SSO-3 |
+| s3-pv-voltage | Number:ElectricPotential | R | S3 Voltage on PV String Side | Measured on PV string side |
+| s3-pv-current | Number:ElectricCurrent | R | S3 Current on PV String Side | Measured on PV string side |
+| s3-total-solar-energy | Number:Energy | R | S3 Total Solar Energy | Total energy produced by SSO-3 |
+| s3-relay-status | Contact | R | S3 Relay Status | 0 = relay closed (i.e running power), 1 = relay open/disconnected, 2 = precharge |
+| s3-temperature | Number:Temperature | R | S3 Temperature on PCB | Temperature Measured on PCB |
+| s3-fault-code | String | R | S3 FaultCode | 0x00 = OK. For all other values Please contact Ferroamp support |
+| s3-dc-link-voltage | Number:ElectricPotential | R | S3 DC Link Voltage | DC link voltage as measured by SSO-3 |
+| s3-timestamp | DateTime | R | S3 Time Stamp | Time stamp when message was published |
+
+| s4-id | String | R | S4 ID | Unique identifier of SSO-4 |
+| s4-pv-voltage | Number:ElectricPotential | R | S4 Voltage on PV String Side | Measured on PV string side |
+| s4-pv-current | Number:ElectricCurrent | R | S4 Current on PV String Side | Measured on PV string side |
+| s4-total-solar-energy | Number:Energy | R | S4 Total Solar Energy | Total energy produced by SSO-4 |
+| s4-relay-status | Contact | R | S4 Relay Status | 0 = relay closed (i.e running power), 1 = relay open/disconnected, 2 = precharge |
+| s4-temperature | Number:Temperature | R | S4 Temperature on PCB | Temperature Measured on PCB |
+| s4-fault-code | String | R | S4 FaultCode | 0x00 = OK. For all other values Please contact Ferroamp support |
+| s4-dc-link-voltage | Number:ElectricPotential | R | S4 DC Link Voltage | DC link voltage as measured by SSO-4 |
+| s4-timestamp | DateTime | R | S4 Time Stamp | Time stamp when message was published |
+
+| eso-id | String | R | Eso Unique Identifier | Unique identifier of ESO |
+| eso-voltage-battery | Number:ElectricPotential | R | Eso Voltage on Battery Side | Measured on battery side |
+| eso-current-battery | Number:ElectricCurrent | R | Eso Current on Battery Side | Measured on battery side |
+| eso-battery-energy-produced | Number:Energy | R | Eso Battery Energy Produced | Total energy produced by ESO, i.e total energy charged |
+| eso-battery-energy-consumed | Number:Energy | R | Eso Battery Energy Consumed | Total energy consumed by ESO, i.e total energy discharged |
+| eso-soc | Number:Dimensionless | R | Eso State of Charge | State of Charge for ESO |
+| eso-relay-status | Contact | R | Eso Relay Status | 0 = relay closed, 1 = relay open |
+| eso-temperature | Number:Temperature | R | Eso Temperature on PCB | Measured inside ESO |
+| eso-fault-code | String | R | Eso FaultCode | See section 4.1.3.1 in Ferroamp-External-API-specifikation |
+| eso-battery-energy-produced | Number:Energy | R | Eso Battery Energy Produced | Total energy produced by ESO, i.e total energy charged |
+| eso-dc-link-voltage | Number:ElectricPotential | R | Eso Dc Link Voltage | DC link voltage as measured by ESO |
+| eso-timestamp | DateTime | R | Eso Time Stamp | Time stamp when message was published |
+
+
+| esm-id | String | R | Esm Unique Identifier | Unique identifier of battery. If available, this will be the unique id that the battery reports |
+| esm-soh | Number:Dimensionless | R | Esm System State of Health | State of Health for ESM |
+| esm-soc | Number:Dimensionless | R | Esm System State of Charge | State of Charge for ESM |
+| esm-total-capacity | Number:Energy | R | Esm Rated Capacity | Rated capacity of all batteries |
+| esm-power-battery | Number:Power | R | Esm Rated Power of Battery | Rated power of battery |
+| esm-status | String | R | Esm Status | Dependent on battery manufacturer |
+| esm-timestamp | DateTime | R | Esm Time Stamp | Time stamp when message was published |
+
+The following channels are available for `Ferroamp` EnergyHub configuration. Please, see Ferroamp documentation for more details.
+
+| Channel Type ID | Item Type | Read/Write | Description |
+|----------------------|----------------------------|------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| request-charge | String | W | Set charge power, value in Watt |
+| request-discharge | String | W | Set discharge power, value in Watt |
+| request-auto | String | W | Set auto power. Returning control of batteries to system, value as auto
+
+# Full Example
+
+## `demo.things` Example
+
+```java
+Thing ferroamp:energyhub:myenergyhub [ hostName="energyhub-ip", userName="myUserName", password="myPassword", hasBattery=false ]
+```
+
+```java
+Thing ferroamp:energyhub:myenergyhub [ hostName="energyhub-ip", userName="myUserName", password="myPassword", hasBattery=true, eso=true ]
+```
+
+## `demo.items` Example
+
+```java
+Number:Energy Ferroamp "Load Energy Consumed L1" { channel="ferroamp:energyhub:myenergyhub:load-energy-consumed-l1" }
+String Ferroamp "RequestCharge" { channel="ferroamp:energyhub:myenergyhub:request-charge" }
+```
+
+## Rules
+
+Ex. Rule name: Set Charge Level.
+Set charging level to 5000W when item RequestCharge is updated.
+
+```yaml
+configuration: {}
+triggers:
+ - id: "1"
+ configuration:
+ itemName: EnergyHub_RequestCharge
+ type: core.ItemStateUpdateTrigger
+conditions: []
+actions:
+ - id: "2"
+ configuration:
+ itemName: EnergyHub_RequestCharge
+ command: "5000"
+ type: core.ItemCommandAction
+```
diff --git a/bundles/org.openhab.binding.ferroamp/pom.xml b/bundles/org.openhab.binding.ferroamp/pom.xml
new file mode 100644
index 0000000000000..e1c48f50acee8
--- /dev/null
+++ b/bundles/org.openhab.binding.ferroamp/pom.xml
@@ -0,0 +1,26 @@
+
+
+
+ 4.0.0
+
+
+ org.openhab.addons.bundles
+ org.openhab.addons.reactor.bundles
+ 4.3.0-SNAPSHOT
+
+
+ org.openhab.binding.ferroamp
+
+ openHAB Add-ons :: Bundles :: Ferroamp Binding
+
+
+
+ org.openhab.addons.bundles
+ org.openhab.binding.mqtt
+ ${project.version}
+ provided
+
+
+
+
diff --git a/bundles/org.openhab.binding.ferroamp/src/main/feature/feature.xml b/bundles/org.openhab.binding.ferroamp/src/main/feature/feature.xml
new file mode 100644
index 0000000000000..811b2ce24f635
--- /dev/null
+++ b/bundles/org.openhab.binding.ferroamp/src/main/feature/feature.xml
@@ -0,0 +1,13 @@
+
+
+ mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features
+
+
+ openhab-runtime-base
+ openhab-transport-mqtt
+ mvn:org.openhab.addons.bundles/org.openhab.binding.mqtt/${project.version}
+
+ mvn:org.openhab.addons.bundles/org.openhab.binding.mqtt/${project.version}
+ mvn:org.openhab.addons.bundles/org.openhab.binding.ferroamp/${project.version}
+
+
diff --git a/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/dto/GetGeneralLx.java b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/dto/GetGeneralLx.java
new file mode 100644
index 0000000000000..f7fee0bf438a7
--- /dev/null
+++ b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/dto/GetGeneralLx.java
@@ -0,0 +1,51 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+
+package org.openhab.binding.ferroamp.dto;
+
+/**
+ * The {@link GetGeneralLx} is responsible for parsing of Lx parts of received MQTT messages.
+ *
+ * @author Örjan Backsell - Initial contribution
+ *
+ */
+
+public class GetGeneralLx {
+ private String L1;
+ private String L2;
+ private String L3;
+
+ public void setL1(String L1) {
+ this.L1 = L1;
+ }
+
+ public String getL1() {
+ return L1;
+ }
+
+ public void setL2(String L2) {
+ this.L2 = L2;
+ }
+
+ public String getL2() {
+ return L2;
+ }
+
+ public void setL3(String L3) {
+ this.L3 = L3;
+ }
+
+ public String getL3() {
+ return L3;
+ }
+}
diff --git a/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/dto/GetGeneralValues.java b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/dto/GetGeneralValues.java
new file mode 100644
index 0000000000000..0b87f3d4e21a3
--- /dev/null
+++ b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/dto/GetGeneralValues.java
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+
+package org.openhab.binding.ferroamp.dto;
+
+/**
+ * The {@link GetGeneralValLx} is responsible for parsing of value parts of received MQTT messages.
+ *
+ * @author Örjan Backsell - Initial contribution
+ *
+ */
+
+public class GetGeneralValues {
+ private String name;
+ private String val;
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void setVal(String val) {
+ this.val = val;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getVal() {
+ return val;
+ }
+}
diff --git a/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/dto/GetUdc.java b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/dto/GetUdc.java
new file mode 100644
index 0000000000000..f0bdad205bb16
--- /dev/null
+++ b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/dto/GetUdc.java
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+
+package org.openhab.binding.ferroamp.dto;
+
+/**
+ * The {@link GetUdc} is responsible for parsing of Udc part of received MQTT messages.
+ *
+ * @author Örjan Backsell - Initial contribution
+ *
+ */
+
+public class GetUdc {
+ private String pos;
+ private String neg;
+
+ public void setPos(String pos) {
+ this.pos = pos;
+ }
+
+ public String getPos() {
+ return pos;
+ }
+
+ public void setNeg(String neg) {
+ this.neg = neg;
+ }
+
+ public String getNeg() {
+ return neg;
+ }
+}
diff --git a/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/EhubJsonElements.java b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/EhubJsonElements.java
new file mode 100644
index 0000000000000..8e392991d4b13
--- /dev/null
+++ b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/EhubJsonElements.java
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.ferroamp.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * The {@link EhubParameters1} is responsible for all parameters regarded to EHUB
+ *
+ * @author Örjan Backsell - Initial contribution
+ *
+ */
+
+@NonNullByDefault
+public class EhubJsonElements {
+ public String ehubJsonElements;
+
+ public EhubJsonElements(String ehubJsonElements) {
+ this.ehubJsonElements = ehubJsonElements;
+ }
+
+ public static List getJsonElementsEhub() {
+ final List jsonElementsEhub = new ArrayList<>();
+ jsonElementsEhub.add(new String("gridfreq"));
+ jsonElementsEhub.add(new String("iace"));
+ jsonElementsEhub.add(new String("ul"));
+ jsonElementsEhub.add(new String("il"));
+ jsonElementsEhub.add(new String("ild"));
+ jsonElementsEhub.add(new String("ilq"));
+ jsonElementsEhub.add(new String("iext"));
+ jsonElementsEhub.add(new String("iextd"));
+ jsonElementsEhub.add(new String("iextq"));
+ jsonElementsEhub.add(new String("iloadd"));
+ jsonElementsEhub.add(new String("iloadq"));
+ jsonElementsEhub.add(new String("sext"));
+ jsonElementsEhub.add(new String("pext"));
+ jsonElementsEhub.add(new String("pextreactive"));
+ jsonElementsEhub.add(new String("pinv"));
+ jsonElementsEhub.add(new String("pinvreactive"));
+ jsonElementsEhub.add(new String("pload"));
+ jsonElementsEhub.add(new String("ploadreactive"));
+ jsonElementsEhub.add(new String("ppv"));
+ jsonElementsEhub.add(new String("udc"));
+ jsonElementsEhub.add(new String("wextprodq"));
+ jsonElementsEhub.add(new String("wextconsq"));
+ jsonElementsEhub.add(new String("winvprodq"));
+ jsonElementsEhub.add(new String("winvconsq"));
+ jsonElementsEhub.add(new String("wloadprodq"));
+ jsonElementsEhub.add(new String("wloadconsq"));
+ jsonElementsEhub.add(new String("wextprodq_3p"));
+ jsonElementsEhub.add(new String("wextconsq_3p"));
+ jsonElementsEhub.add(new String("winvprodq_3p"));
+ jsonElementsEhub.add(new String("winvconsq_3p"));
+ jsonElementsEhub.add(new String("wloadprodq_3p"));
+ jsonElementsEhub.add(new String("wloadconsq_3p"));
+ jsonElementsEhub.add(new String("wpv"));
+ jsonElementsEhub.add(new String("state"));
+ jsonElementsEhub.add(new String("ts"));
+ jsonElementsEhub.add(new String("wbatprod"));
+ jsonElementsEhub.add(new String("wpbatcons"));
+ jsonElementsEhub.add(new String("soc"));
+ jsonElementsEhub.add(new String("soh"));
+ jsonElementsEhub.add(new String("pbat"));
+ jsonElementsEhub.add(new String("ratedcap"));
+ return jsonElementsEhub;
+ }
+}
diff --git a/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/EhubParameters.java b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/EhubParameters.java
new file mode 100644
index 0000000000000..fd9503d7c84e1
--- /dev/null
+++ b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/EhubParameters.java
@@ -0,0 +1,63 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.ferroamp.internal;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * The {@link EhubParameters} is responsible for all parameters regarded to EHUB
+ *
+ * @author Örjan Backsell - Initial contribution
+ *
+ */
+
+@NonNullByDefault
+public class EhubParameters {
+ public String jsonPostEhub;
+
+ public EhubParameters(String jsonPostEhub) {
+ this.jsonPostEhub = jsonPostEhub;
+ }
+
+ public static List getChannelParametersEhub() {
+ final List channelParametersEhub = Arrays.asList("grid-frequency", "ace-current-l1", "ace-current-l2",
+ "ace-current-l3", "external-voltage-l1", "external-voltage-l2", "external-voltage-l3",
+ "inverter-rms-current-l1", "inverter-rms-current-l2", "inverter-rms-current-l3",
+ "inverter-current-reactive-l1", "inverter-current-reactive-l2", "inverter-current-reactive-l3",
+ "inverter-current-active-l1", "inverter-current-active-l2", "inverter-current-active-l3",
+ "grid-current-l1", "grid-current-l2", "grid-current-l3", "grid-current-reactive-l1",
+ "grid-current-reactive-l2", "grid-current-reactive-l3", "grid-current-active-l1",
+ "grid-current-active-l2", "grid-current-active-l3", "inverter-load-l1", "inverter-load-l2",
+ "inverter-load-l3", "apparent-power", "grid-power-active-l1", "grid-power-active-l2",
+ "grid-power-active-l3", "grid-power-reactive-l1", "grid-power-reactive-l2", "grid-power-reactive-l3",
+ "inverter-power-active-l1", "inverter-power-active-l2", "inverter-power-active-l3",
+ "inverter-power-reactive-l1", "inverter-power-reactive-l2", "inverter-power-reactive-l3",
+ "consumption-power-l1", "consumption-power-l2", "consumption-power-l3", "consumption-power-reactive-l1",
+ "consumption-power-reactive-l2", "consumption-power-reactive-l3", "solar-pv",
+ "positive-dc-link-voltage", "negative-dc-link-voltage", "grid-energy-produced-l1",
+ "grid-energy-produced-l2", "grid-energy-produced-l3", "grid-energy-consumed-l1",
+ "grid-energy-consumed-l2", "grid-energy-consumed-l3", "inverter-energy-produced-l1",
+ "inverter-energy-produced-l2", "inverter-energy-produced-l3", "inverter-energy-consumed-l1",
+ "inverter-energy-consumed-l2", "inverter-energy-consumed-l3", "load-energy-produced-l1",
+ "load-energy-produced-l2", "load-energy-produced-l3", "load-energy-consumed-l1",
+ "load-energy-consumed-l2", "load-energy-consumed-l3", "grid-energy-produced-total",
+ "grid-energy-consumed-total", "inverter-energy-produced-total", "inverter-energy-consumed-total",
+ "load-energy-produced-3p", "load-energy-consumed-3p", "total-solar-energy", "state", "timestamp",
+ "battery-energy-produced", "battery-energy-consumed", "soc", "soh", "power-battery",
+ "total-capacity-batteries");
+ return channelParametersEhub;
+ }
+}
diff --git a/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/EsmJsonElements.java b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/EsmJsonElements.java
new file mode 100644
index 0000000000000..f74da39f04368
--- /dev/null
+++ b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/EsmJsonElements.java
@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+
+package org.openhab.binding.ferroamp.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * The {@link EhubParameters1} is responsible for all parameters regarded to EHUB
+ *
+ * @author Örjan Backsell - Initial contribution
+ *
+ */
+
+@NonNullByDefault
+public class EsmJsonElements {
+ public String esmJsonElements;
+
+ public EsmJsonElements(String esmJsonElements) {
+ this.esmJsonElements = esmJsonElements;
+ }
+
+ public static List getJsonElementsEsm() {
+ final List jsonElementsEsm = new ArrayList<>();
+ jsonElementsEsm.add(new String("id"));
+ jsonElementsEsm.add(new String("soh"));
+ jsonElementsEsm.add(new String("soc"));
+ jsonElementsEsm.add(new String("ratedcapacity"));
+ jsonElementsEsm.add(new String("ratedpower"));
+ jsonElementsEsm.add(new String("status"));
+ jsonElementsEsm.add(new String("ts"));
+ return jsonElementsEsm;
+ }
+}
diff --git a/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/EsmParameters.java b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/EsmParameters.java
new file mode 100644
index 0000000000000..3cd33a508a5dd
--- /dev/null
+++ b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/EsmParameters.java
@@ -0,0 +1,41 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+
+package org.openhab.binding.ferroamp.internal;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * The {@link EsmParameters} is responsible for all parameters regarded to ESM
+ *
+ * @author Örjan Backsell - Initial contribution
+ *
+ */
+
+@NonNullByDefault
+public class EsmParameters {
+ public String jsonPostEsm;
+
+ public EsmParameters(String jsonPostEsm) {
+ this.jsonPostEsm = jsonPostEsm;
+ }
+
+ public static List getChannelParametersEsm() {
+ final List channelParametersEsm = Arrays.asList("esm-id", "esm-soh", "esm-soc", "esm-total-capacity",
+ "esm-power-battery", "esm-status", "esm-timestamp");
+ return channelParametersEsm;
+ }
+}
diff --git a/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/EsoJsonElements.java b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/EsoJsonElements.java
new file mode 100644
index 0000000000000..d08d038c61655
--- /dev/null
+++ b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/EsoJsonElements.java
@@ -0,0 +1,51 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.ferroamp.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * The {@link EhubParameters1} is responsible for all parameters regarded to EHUB
+ *
+ * @author Örjan Backsell - Initial contribution
+ *
+ */
+
+@NonNullByDefault
+public class EsoJsonElements {
+ public String esoJsonElements;
+
+ public EsoJsonElements(String esoJsonElements) {
+ this.esoJsonElements = esoJsonElements;
+ }
+
+ public static List getJsonElementsEso() {
+ final List jsonElementsEso = new ArrayList<>();
+ jsonElementsEso.add(new String("id"));
+ jsonElementsEso.add(new String("ubat"));
+ jsonElementsEso.add(new String("ibat"));
+ jsonElementsEso.add(new String("wbatprod"));
+ jsonElementsEso.add(new String("wbatcons"));
+ jsonElementsEso.add(new String("soc"));
+ jsonElementsEso.add(new String("relaystatus"));
+ jsonElementsEso.add(new String("temp"));
+ jsonElementsEso.add(new String("faultcode"));
+ jsonElementsEso.add(new String("udc"));
+ jsonElementsEso.add(new String("ts"));
+
+ return jsonElementsEso;
+ }
+}
diff --git a/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/EsoParameters.java b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/EsoParameters.java
new file mode 100644
index 0000000000000..3f317dd1b12d3
--- /dev/null
+++ b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/EsoParameters.java
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+
+package org.openhab.binding.ferroamp.internal;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * The {@link EsoParameters} is responsible for all parameters regarded to ESO
+ *
+ * @author Örjan Backsell - Initial contribution
+ *
+ */
+
+@NonNullByDefault
+public class EsoParameters {
+ public String jsonPostEso;
+
+ public EsoParameters(String jsonPostEso) {
+ this.jsonPostEso = jsonPostEso;
+ }
+
+ public static List getChannelParametersEso() {
+ final List channelParametersEso = Arrays.asList("eso-id", "eso-voltage-battery", "eso-current-battery",
+ "eso-battery-energy-produced", "eso-battery-energy-consumed", "eso-soc", "eso-relay-status",
+ "eso-temperature", "eso-fault-code", "eso-dc-link-voltage", "eso-timestamp");
+ return channelParametersEso;
+ }
+}
diff --git a/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/FerroampBindingConstants.java b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/FerroampBindingConstants.java
new file mode 100644
index 0000000000000..9e84f3b99e912
--- /dev/null
+++ b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/FerroampBindingConstants.java
@@ -0,0 +1,207 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.ferroamp.internal;
+
+import java.util.Set;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.core.thing.ThingTypeUID;
+
+/**
+ * The {@link FerroampBindingConstants} class defines common constants, which are
+ * used across the whole binding.
+ *
+ * @author Örjan Backsell - Initial contribution
+ *
+ */
+@NonNullByDefault
+public class FerroampBindingConstants {
+
+ public static final String BINDING_ID = "ferroamp";
+
+ // Broker (energyhub) port number
+ static final int BROKER_PORT = 1883;
+
+ // Broker (energyhub) status
+ public static final String CONNECTED = "connected";
+
+ // Broker (energyhub) topics
+ public static final String EHUB_TOPIC = "extapi/data/ehub";
+ public static final String SSO_TOPIC = "extapi/data/sso";
+ public static final String ESO_TOPIC = "extapi/data/eso";
+ public static final String ESM_TOPIC = "extapi/data/esm";
+ public static final String REQUEST_TOPIC = "extapi/control/request";
+
+ // Broker (energyhub) QOS level
+ public static final String QOS = "2";
+
+ // List of all Thing Type UIDs
+ public static final ThingTypeUID THING_TYPE_ENERGYHUB = new ThingTypeUID(BINDING_ID, "energyhub");
+
+ // List of EHUB Channel ids
+ public static final String CHANNEL_GRIDFREQUENCY = "grid-frequency";
+ public static final String CHANNEL_ACECURRENTL1 = "ace-current-l1";
+ public static final String CHANNEL_ACECURRENTL2 = "ace-current-l2";
+ public static final String CHANNEL_ACECURRENTL3 = "ace-current-l3";
+ public static final String CHANNEL_GRIDVOLTAGEL1 = "grid-voltage-l1";
+ public static final String CHANNEL_GRIDVOLTAGEL2 = "grid-voltage-l2";
+ public static final String CHANNEL_GRIDVOLTAGEL3 = "grid-voltage-l3";
+ public static final String CHANNEL_INVERTERRMSCURRENTL1 = "inverter-rms-current-l1";
+ public static final String CHANNEL_INVERTERRMSCURRENTL2 = "inverter-rms-current-l2";
+ public static final String CHANNEL_INVERTERRMSCURRENTL3 = "inverter-rms-current-l3";
+ public static final String CHANNEL_INVERTERREACTIVECURRENTL1 = "inverter-reactive-current-l1";
+ public static final String CHANNEL_INVERTERREACTIVECURRENTL2 = "inverter-reactive-current-l2";
+ public static final String CHANNEL_INVERTERREACTIVECURRENTL3 = "inverter-reactive-current-l3";
+ public static final String CHANNEL_INVERTERACTIVECURRENTL1 = "inverter-active-current-l1";
+ public static final String CHANNEL_INVERTERACTIVECURRENTL2 = "inverter-active-current-l2";
+ public static final String CHANNEL_INVERTERACTIVECURRENTL3 = "inverter-active-current-l3";
+ public static final String CHANNEL_GRIDCURRENTL1 = "grid-current-l1";
+ public static final String CHANNEL_GRIDCURRENTL2 = "grid-current-l2";
+ public static final String CHANNEL_GRIDCURRENTL3 = "grid-current-l3";
+ public static final String CHANNEL_GRIDREACTIVECURRENTL1 = "grid-reactive-current-l1";
+ public static final String CHANNEL_GRIDREACTIVECURRENTL2 = "grid-reactive-current-l2";
+ public static final String CHANNEL_GRIDREACTIVECURRENTL3 = "grid-reactive-current-l3";
+ public static final String CHANNEL_GRIDACTIVECURRENTL1 = "grid-active-current-l1";
+ public static final String CHANNEL_GRIDACTIVECURRENTL2 = "grid-active-current-l2";
+ public static final String CHANNEL_GRIDACTIVECURRENTL3 = "grid-active-current-l3";
+ public static final String CHANNEL_INVERTERLOADREACTIVECURRENTL1 = "inverter-load-reactive-current-l1";
+ public static final String CHANNEL_INVERTERLOADREACTIVECURRENTL2 = "inverter-load-reactive-current-l2";
+ public static final String CHANNEL_INVERTERLOADREACTIVECURRENTL3 = "inverter-load-reactive-current-l3";
+ public static final String CHANNEL_INVERTERLOADACTIVECURRENTL1 = "inverter-load-active-current-l1";
+ public static final String CHANNEL_INVERTERLOADACTIVECURRENTL2 = "inverter-load-active-current-l2";
+ public static final String CHANNEL_INVERTERLOADACTIVECURRENTL3 = "inverter-load-active-current-l3";
+ public static final String CHANNEL_APPARENTPOWER = "apparent-power";
+ public static final String CHANNEL_GRIDPOWERACTIVEL1 = "grid-power-active-l1";
+ public static final String CHANNEL_GRIDPOWERACTIVEL2 = "grid-power-active-l2";
+ public static final String CHANNEL_GRIDPOWERACTIVEL3 = "grid-power-active-l3";
+ public static final String CHANNEL_GRIDPOWERREACTIVEL1 = "grid-power-reactive-l1";
+ public static final String CHANNEL_GRIDPOWERREACTIVEL2 = "grid-power-reactive-l2";
+ public static final String CHANNEL_GRIDPOWERREACTIVEL3 = "grid-power-reactive-l3";
+ public static final String CHANNEL_INVERTERPOWERACTIVEL1 = "inverter-power-active-l1";
+ public static final String CHANNEL_INVERTERPOWERACTIVEL2 = "inverter-power-active-l2";
+ public static final String CHANNEL_INVERTERPOWERACTIVEL3 = "inverter-power-active-l3";
+ public static final String CHANNEL_INVERTERPOWERREACTIVEL1 = "inverter-power-reactive-l1";
+ public static final String CHANNEL_INVERTERPOWERREACTIVEL2 = "inverter-power-reactive-l2";
+ public static final String CHANNEL_INVERTERPOWERREACTIVEL3 = "inverter-power-reactive-l3";
+ public static final String CHANNEL_CONSUMPTIONPOWERL1 = "consumption-power-l1";
+ public static final String CHANNEL_CONSUMPTIONPOWERL2 = "consumption-power-l2";
+ public static final String CHANNEL_CONSUMPTIONPOWERL3 = "consumption-power-l3";
+ public static final String CHANNEL_CONSUMPTIONPOWERREACTIVEL1 = "consumption-power-reactive-l1";
+ public static final String CHANNEL_CONSUMPTIONPOWERREACTIVEL2 = "consumption-power-reactive-l2";
+ public static final String CHANNEL_CONSUMPTIONPOWERREACTIVEL3 = "consumption-power-reactive-l3";
+ public static final String CHANNEL_SOLARPV = "solar-pv";
+ public static final String CHANNEL_POSITIVEDCLINKVOLTAGE = "positive-dc-link-voltage";
+ public static final String CHANNEL_NEGATIVEDCLINKVOLTAGE = "negative-dc-link-voltage";
+ public static final String CHANNEL_GRIDENERGYPRODUCEDL1 = "grid-energy-produced-l1";
+ public static final String CHANNEL_GRIDENERGYPRODUCEDL2 = "grid-energy-produced-l2";
+ public static final String CHANNEL_GRIDENERGYPRODUCEDL3 = "grid-energy-produced-l3";
+ public static final String CHANNEL_GRIDENERGYCONSUMEDL1 = "grid-energy-consumed-l1";
+ public static final String CHANNEL_GRIDENERGYCONSUMEDL2 = "grid-energy-consumed-l2";
+ public static final String CHANNEL_GRIDENERGYCONSUMEDL3 = "grid-energy-consumed-l3";
+ public static final String CHANNEL_INVERTERENERGYPRODUCEDL1 = "inverter-energy-produced-l1";
+ public static final String CHANNEL_INVERTERENERGYPRODUCEDL2 = "inverter-energy-produced-l2";
+ public static final String CHANNEL_INVERTERENERGYPRODUCEDL3 = "inverter-energy-produced-l3";
+ public static final String CHANNEL_INVERTERENERGYCONSUMEDL1 = "inverter-energy-consumed-l1";
+ public static final String CHANNEL_INVERTERENERGYCONSUMEDL2 = "inverter-energy-consumed-l2";
+ public static final String CHANNEL_INVERTERENERGYCONSUMEDL3 = "inverter-energy-consumed-l3";
+ public static final String CHANNEL_LOADENERGYPRODUCEDL1 = "load-energy-produced-l1";
+ public static final String CHANNEL_LOADENERGYPRODUCEDL2 = "load-energy-produced-l2";
+ public static final String CHANNEL_LOADENERGYPRODUCEDL3 = "load-energy-produced-l3";
+ public static final String CHANNEL_LOADENERGYCONSUMEDL1 = "load-energy-consumed-l1";
+ public static final String CHANNEL_LOADENERGYCONSUMEDL2 = "load-energy-consumed-l2";
+ public static final String CHANNEL_LOADENERGYCONSUMEDL3 = "load-energy-consumed-l3";
+ public static final String CHANNEL_GRIDENERGYPRODUCEDTOTAL = "grid-energy-produced-total";
+ public static final String CHANNEL_GRIDENERGYCONSUMEDTOTAL = "grid-energy-consumed-total";
+ public static final String CHANNEL_INVERTERENERGYPRODUCEDTOTAL = "inverter-energy-produced-total";
+ public static final String CHANNEL_INVERTERENERGYCONSUMEDTOTAL = "inverter-energy-consumed-total";
+ public static final String CHANNEL_LOADENERGYPRODUCEDTOTAL = "load-energy-produced-total";
+ public static final String CHANNEL_LOADENERGYCONSUMEDTOTAL = "load-energy-consumed-total";
+ public static final String CHANNEL_TOTALSOLARENERGY = "total-solar-energy";
+ public static final String CHANNEL_STATE = "state";
+ public static final String CHANNEL_TIMESTAMP = "timestamp";
+
+ // List of battery setup Channel ids
+ public static final String CHANNEL_BATTERYENERGYPRODUCED = "battery-energy-produced";
+ public static final String CHANNEL_BATTERYENERGYCONSUMED = "battery-energy-consumed";
+ public static final String CHANNEL_SOC = "soc";
+ public static final String CHANNEL_SOH = "soh";
+ public static final String CHANNEL_POWERBATTERY = "power-battery";
+ public static final String CHANNEL_TOTALCAPACITYBATTERIES = "total-capacity-batteries";
+
+ // List of SSO Channel ids
+ public static final String CHANNEL_S1ID = "s1-id";
+ public static final String CHANNEL_S1PVVOLTAGE = "s1-pv-voltage";
+ public static final String CHANNEL_S1PVCURRENT = "s1-pv-current";
+ public static final String CHANNEL_S1TOTALSOLARENERGY = "s1-total-solar-energy";
+ public static final String CHANNEL_S1RELAYSTATUS = "s1-relay-status";
+ public static final String CHANNEL_S1TEMPERATURE = "s1-temperature";
+ public static final String CHANNEL_S1FAULTCODE = "s1-fault-code";
+ public static final String CHANNEL_S1DCLINKVOLTAGE = "s1-dc-link-voltage";
+ public static final String CHANNEL_S1TIMESTAMP = "s1-timestamp";
+ public static final String CHANNEL_S2ID = "s2-id";
+ public static final String CHANNEL_S2PVVOLTAGE = "s2-pv-voltage";
+ public static final String CHANNEL_S2PVCURRENT = "s2-pv-current";
+ public static final String CHANNEL_S2TOTALSOLARENERGY = "s2-total-solar-energy";
+ public static final String CHANNEL_S2RELAYSTATUS = "s2-relay-status";
+ public static final String CHANNEL_S2TEMPERATURE = "s2-temperature";
+ public static final String CHANNEL_S2FAULTCODE = "s2-fault-code";
+ public static final String CHANNEL_S2DCLINKVOLTAGE = "s2-dc-link-voltage";
+ public static final String CHANNEL_S2TIMESTAMP = "s2-timestamp";
+ public static final String CHANNEL_S3ID = "s3-id";
+ public static final String CHANNEL_S3PVVOLTAGE = "s3-pv-voltage";
+ public static final String CHANNEL_S3PVCURRENT = "s3-pv-current";
+ public static final String CHANNEL_S3TOTALSOLARENERGY = "s3-total-solar-energy";
+ public static final String CHANNEL_S3RELAYSTATUS = "s3-relay-status";
+ public static final String CHANNEL_S3TEMPERATURE = "s3-temperature";
+ public static final String CHANNEL_S3FAULTCODE = "s3-fault-code";
+ public static final String CHANNEL_S3DCLINKVOLTAGE = "s3-dc-link-voltage";
+ public static final String CHANNEL_S3TIMESTAMP = "s3-timestamp";
+ public static final String CHANNEL_S4ID = "s4-id";
+ public static final String CHANNEL_S4PVVOLTAGE = "s4-pv-voltage";
+ public static final String CHANNEL_S4PVCURRENT = "s4-pv-current";
+ public static final String CHANNEL_S4TOTALSOLARENERGY = "s4-total-solar-energy";
+ public static final String CHANNEL_S4RELAYSTATUS = "s4-relay-status";
+ public static final String CHANNEL_S4TEMPERATURE = "s4-temperature";
+ public static final String CHANNEL_S4FAULTCODE = "s4-fault-code";
+ public static final String CHANNEL_S4DCLINKVOLTAGE = "s4-dc-link-voltage";
+ public static final String CHANNEL_S4TIMESTAMP = "s4-timestamp";
+
+ // List of ESO Channel ids
+ public static final String CHANNEL_ESOID = "eso-id";
+ public static final String CHANNEL_ESOVOLTAGEBATTERY = "eso-voltage-battery";
+ public static final String CHANNEL_ESOCURRENTBATTERY = "eso-current-battery";
+ public static final String CHANNEL_ESOBATTERYENERGYPRODUCED = "eso-battery-energy-produced";
+ public static final String CHANNEL_ESOBATTERYENERGYCONSUMED = "eso-battery-energy-consumed";
+ public static final String CHANNEL_ESOSOC = "eso-soc";
+ public static final String CHANNEL_ESORELAYSTATUS = "eso-relay-status";
+ public static final String CHANNEL_ESOTEMPERATURE = "eso-temperature";
+ public static final String CHANNEL_ESOFAULTCODE = "eso-fault-code";
+ public static final String CHANNEL_ESODCLINKVOLTAGE = "eso-dc-link-voltage";
+ public static final String CHANNEL_ESOTIMESTAMP = "eso-timestamp";
+
+ // List of ESM Channel ids
+ public static final String CHANNEL_ESMID = "esm-id";
+ public static final String CHANNEL_ESMSOH = "esm-soh";
+ public static final String CHANNEL_ESMSOC = "esm-soc";
+ public static final String CHANNEL_ESMTOTALCAPACITY = "esm-total-capacity";
+ public static final String CHANNEL_ESMPOWERBATTERY = "esm-power-battery";
+ public static final String CHANNEL_ESMSTATUS = "esm-status";
+ public static final String CHANNEL_ESMTIMESTAMP = "esm-timestamp";
+
+ // List of all Channel ids for configuration
+ public static final String CHANNEL_REQUESTCHARGE = "request-charge";
+ public static final String CHANNEL_REQUESTDISCHARGE = "request-discharge";
+ public static final String CHANNEL_AUTO = "request-auto";
+
+ public static final Set SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_ENERGYHUB);
+}
diff --git a/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/FerroampChannelConfiguration.java b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/FerroampChannelConfiguration.java
new file mode 100644
index 0000000000000..be87f543d18bf
--- /dev/null
+++ b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/FerroampChannelConfiguration.java
@@ -0,0 +1,365 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.ferroamp.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.measure.Unit;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.core.library.unit.Units;
+
+/**
+ * The {@link FerroampChannelConfiguration} class defines methods, which set up channel configuration for the binding.
+ *
+ * @author Örjan Backsell - Initial contribution
+ *
+ */
+
+@NonNullByDefault
+public class FerroampChannelConfiguration {
+ public String id;
+ public Unit> unit;
+
+ public FerroampChannelConfiguration(String id, Unit> unit) {
+ this.id = id;
+ this.unit = unit;
+ }
+
+ public static List getChannelConfigurationEhub() {
+ final List channelConfigurationEhub = new ArrayList<>();
+ channelConfigurationEhub
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_GRIDFREQUENCY, Units.HERTZ));
+ channelConfigurationEhub
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_ACECURRENTL1, Units.AMPERE));
+ channelConfigurationEhub
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_ACECURRENTL2, Units.AMPERE));
+ channelConfigurationEhub
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_ACECURRENTL3, Units.AMPERE));
+ channelConfigurationEhub
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_GRIDVOLTAGEL1, Units.VOLT));
+ channelConfigurationEhub
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_GRIDVOLTAGEL2, Units.VOLT));
+ channelConfigurationEhub
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_GRIDVOLTAGEL3, Units.VOLT));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_INVERTERRMSCURRENTL1, Units.AMPERE));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_INVERTERRMSCURRENTL2, Units.AMPERE));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_INVERTERRMSCURRENTL3, Units.AMPERE));
+ channelConfigurationEhub.add(new FerroampChannelConfiguration(
+ FerroampBindingConstants.CHANNEL_INVERTERREACTIVECURRENTL1, Units.AMPERE));
+ channelConfigurationEhub.add(new FerroampChannelConfiguration(
+ FerroampBindingConstants.CHANNEL_INVERTERREACTIVECURRENTL2, Units.AMPERE));
+ channelConfigurationEhub.add(new FerroampChannelConfiguration(
+ FerroampBindingConstants.CHANNEL_INVERTERREACTIVECURRENTL3, Units.AMPERE));
+ channelConfigurationEhub.add(new FerroampChannelConfiguration(
+ FerroampBindingConstants.CHANNEL_INVERTERACTIVECURRENTL1, Units.AMPERE));
+ channelConfigurationEhub.add(new FerroampChannelConfiguration(
+ FerroampBindingConstants.CHANNEL_INVERTERACTIVECURRENTL2, Units.AMPERE));
+ channelConfigurationEhub.add(new FerroampChannelConfiguration(
+ FerroampBindingConstants.CHANNEL_INVERTERACTIVECURRENTL3, Units.AMPERE));
+ channelConfigurationEhub
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_GRIDCURRENTL1, Units.AMPERE));
+ channelConfigurationEhub
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_GRIDCURRENTL2, Units.AMPERE));
+ channelConfigurationEhub
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_GRIDCURRENTL3, Units.AMPERE));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_GRIDREACTIVECURRENTL1, Units.AMPERE));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_GRIDREACTIVECURRENTL2, Units.AMPERE));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_GRIDREACTIVECURRENTL3, Units.AMPERE));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_GRIDACTIVECURRENTL1, Units.AMPERE));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_GRIDACTIVECURRENTL2, Units.AMPERE));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_GRIDACTIVECURRENTL3, Units.AMPERE));
+ channelConfigurationEhub.add(new FerroampChannelConfiguration(
+ FerroampBindingConstants.CHANNEL_INVERTERLOADREACTIVECURRENTL1, Units.AMPERE));
+ channelConfigurationEhub.add(new FerroampChannelConfiguration(
+ FerroampBindingConstants.CHANNEL_INVERTERLOADREACTIVECURRENTL2, Units.AMPERE));
+ channelConfigurationEhub.add(new FerroampChannelConfiguration(
+ FerroampBindingConstants.CHANNEL_INVERTERLOADREACTIVECURRENTL3, Units.AMPERE));
+ channelConfigurationEhub.add(new FerroampChannelConfiguration(
+ FerroampBindingConstants.CHANNEL_INVERTERLOADACTIVECURRENTL1, Units.AMPERE));
+ channelConfigurationEhub.add(new FerroampChannelConfiguration(
+ FerroampBindingConstants.CHANNEL_INVERTERLOADACTIVECURRENTL2, Units.AMPERE));
+ channelConfigurationEhub.add(new FerroampChannelConfiguration(
+ FerroampBindingConstants.CHANNEL_INVERTERLOADACTIVECURRENTL3, Units.AMPERE));
+ channelConfigurationEhub
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_APPARENTPOWER, Units.WATT));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_GRIDPOWERACTIVEL1, Units.AMPERE));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_GRIDPOWERACTIVEL2, Units.AMPERE));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_GRIDPOWERACTIVEL3, Units.AMPERE));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_GRIDPOWERREACTIVEL1, Units.WATT));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_GRIDPOWERREACTIVEL2, Units.WATT));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_GRIDPOWERREACTIVEL3, Units.WATT));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_INVERTERPOWERACTIVEL1, Units.VOLT));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_INVERTERPOWERACTIVEL2, Units.VOLT));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_INVERTERPOWERACTIVEL3, Units.VOLT));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_INVERTERPOWERREACTIVEL1, Units.VOLT));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_INVERTERPOWERREACTIVEL2, Units.VOLT));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_INVERTERPOWERREACTIVEL3, Units.VOLT));
+ channelConfigurationEhub
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_CONSUMPTIONPOWERL1, Units.WATT));
+ channelConfigurationEhub
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_CONSUMPTIONPOWERL2, Units.WATT));
+ channelConfigurationEhub
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_CONSUMPTIONPOWERL3, Units.WATT));
+ channelConfigurationEhub.add(new FerroampChannelConfiguration(
+ FerroampBindingConstants.CHANNEL_CONSUMPTIONPOWERREACTIVEL1, Units.WATT));
+ channelConfigurationEhub.add(new FerroampChannelConfiguration(
+ FerroampBindingConstants.CHANNEL_CONSUMPTIONPOWERREACTIVEL2, Units.WATT));
+ channelConfigurationEhub.add(new FerroampChannelConfiguration(
+ FerroampBindingConstants.CHANNEL_CONSUMPTIONPOWERREACTIVEL3, Units.WATT));
+ channelConfigurationEhub
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_SOLARPV, Units.WATT));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_POSITIVEDCLINKVOLTAGE, Units.VOLT));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_NEGATIVEDCLINKVOLTAGE, Units.VOLT));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_GRIDENERGYPRODUCEDL1, Units.WATT));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_GRIDENERGYPRODUCEDL2, Units.WATT));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_GRIDENERGYPRODUCEDL3, Units.WATT));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_GRIDENERGYCONSUMEDL1, Units.WATT));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_GRIDENERGYCONSUMEDL2, Units.WATT));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_GRIDENERGYCONSUMEDL3, Units.WATT));
+ channelConfigurationEhub.add(new FerroampChannelConfiguration(
+ FerroampBindingConstants.CHANNEL_INVERTERENERGYPRODUCEDL1, Units.WATT));
+ channelConfigurationEhub.add(new FerroampChannelConfiguration(
+ FerroampBindingConstants.CHANNEL_INVERTERENERGYPRODUCEDL2, Units.WATT));
+ channelConfigurationEhub.add(new FerroampChannelConfiguration(
+ FerroampBindingConstants.CHANNEL_INVERTERENERGYPRODUCEDL3, Units.WATT));
+ channelConfigurationEhub.add(new FerroampChannelConfiguration(
+ FerroampBindingConstants.CHANNEL_INVERTERENERGYCONSUMEDL1, Units.WATT));
+ channelConfigurationEhub.add(new FerroampChannelConfiguration(
+ FerroampBindingConstants.CHANNEL_INVERTERENERGYCONSUMEDL2, Units.WATT));
+ channelConfigurationEhub.add(new FerroampChannelConfiguration(
+ FerroampBindingConstants.CHANNEL_INVERTERENERGYCONSUMEDL3, Units.WATT));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_LOADENERGYPRODUCEDL1, Units.WATT));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_LOADENERGYPRODUCEDL2, Units.WATT));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_LOADENERGYPRODUCEDL3, Units.WATT));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_LOADENERGYCONSUMEDL1, Units.WATT));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_LOADENERGYCONSUMEDL2, Units.WATT));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_LOADENERGYCONSUMEDL3, Units.WATT));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_GRIDENERGYPRODUCEDTOTAL, Units.WATT));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_GRIDENERGYCONSUMEDTOTAL, Units.WATT));
+ channelConfigurationEhub.add(new FerroampChannelConfiguration(
+ FerroampBindingConstants.CHANNEL_INVERTERENERGYPRODUCEDTOTAL, Units.WATT));
+ channelConfigurationEhub.add(new FerroampChannelConfiguration(
+ FerroampBindingConstants.CHANNEL_INVERTERENERGYCONSUMEDTOTAL, Units.WATT));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_LOADENERGYPRODUCEDTOTAL, Units.WATT));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_LOADENERGYCONSUMEDTOTAL, Units.WATT));
+ channelConfigurationEhub
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_TOTALSOLARENERGY, Units.WATT));
+ channelConfigurationEhub
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_STATE, Units.ONE));
+ channelConfigurationEhub
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_TIMESTAMP, Units.ONE));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_BATTERYENERGYPRODUCED, Units.WATT));
+ channelConfigurationEhub.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_BATTERYENERGYCONSUMED, Units.WATT));
+ channelConfigurationEhub
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_SOC, Units.PERCENT));
+ channelConfigurationEhub
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_SOH, Units.PERCENT));
+ channelConfigurationEhub
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_POWERBATTERY, Units.WATT));
+ channelConfigurationEhub.add(new FerroampChannelConfiguration(
+ FerroampBindingConstants.CHANNEL_TOTALCAPACITYBATTERIES, Units.WATT_HOUR));
+ return channelConfigurationEhub;
+ }
+
+ public static List getChannelConfigurationSsoS1() {
+ final List channelConfigurationSsoS1 = new ArrayList<>();
+ channelConfigurationSsoS1
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S1ID, Units.ONE));
+ channelConfigurationSsoS1
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S1PVVOLTAGE, Units.VOLT));
+ channelConfigurationSsoS1
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S1PVCURRENT, Units.AMPERE));
+ channelConfigurationSsoS1
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S1TOTALSOLARENERGY, Units.WATT));
+ channelConfigurationSsoS1
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S1RELAYSTATUS, Units.ONE));
+ channelConfigurationSsoS1
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S1TEMPERATURE, Units.ONE));
+ channelConfigurationSsoS1
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S1FAULTCODE, Units.ONE));
+ channelConfigurationSsoS1
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S1DCLINKVOLTAGE, Units.VOLT));
+ channelConfigurationSsoS1
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S1TIMESTAMP, Units.ONE));
+ return channelConfigurationSsoS1;
+ }
+
+ public static List getChannelConfigurationSsoS2() {
+ final List channelConfigurationSsoS2 = new ArrayList<>();
+ channelConfigurationSsoS2
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S2ID, Units.ONE));
+ channelConfigurationSsoS2
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S2PVVOLTAGE, Units.VOLT));
+ channelConfigurationSsoS2
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S2PVCURRENT, Units.AMPERE));
+ channelConfigurationSsoS2
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S2TOTALSOLARENERGY, Units.WATT));
+ channelConfigurationSsoS2
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S2RELAYSTATUS, Units.ONE));
+ channelConfigurationSsoS2
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S2TEMPERATURE, Units.ONE));
+ channelConfigurationSsoS2
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S2FAULTCODE, Units.ONE));
+ channelConfigurationSsoS2
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S2DCLINKVOLTAGE, Units.VOLT));
+ channelConfigurationSsoS2
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S2TIMESTAMP, Units.ONE));
+ return channelConfigurationSsoS2;
+ }
+
+ public static List getChannelConfigurationSsoS3() {
+ final List channelConfigurationSsoS3 = new ArrayList<>();
+ channelConfigurationSsoS3
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S3ID, Units.ONE));
+ channelConfigurationSsoS3
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S3PVVOLTAGE, Units.VOLT));
+ channelConfigurationSsoS3
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S3PVCURRENT, Units.AMPERE));
+ channelConfigurationSsoS3
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S3TOTALSOLARENERGY, Units.WATT));
+ channelConfigurationSsoS3
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S3RELAYSTATUS, Units.ONE));
+ channelConfigurationSsoS3
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S3TEMPERATURE, Units.ONE));
+ channelConfigurationSsoS3
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S3FAULTCODE, Units.ONE));
+ channelConfigurationSsoS3
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S3DCLINKVOLTAGE, Units.VOLT));
+ channelConfigurationSsoS3
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S3TIMESTAMP, Units.ONE));
+ return channelConfigurationSsoS3;
+ }
+
+ public static List getChannelConfigurationSsoS4() {
+ final List channelConfigurationSsoS4 = new ArrayList<>();
+ channelConfigurationSsoS4
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S4ID, Units.ONE));
+ channelConfigurationSsoS4
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S4PVVOLTAGE, Units.VOLT));
+ channelConfigurationSsoS4
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S4PVCURRENT, Units.AMPERE));
+ channelConfigurationSsoS4
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S4TOTALSOLARENERGY, Units.WATT));
+ channelConfigurationSsoS4
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S4RELAYSTATUS, Units.ONE));
+ channelConfigurationSsoS4
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S4TEMPERATURE, Units.ONE));
+ channelConfigurationSsoS4
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S4FAULTCODE, Units.ONE));
+ channelConfigurationSsoS4
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S4DCLINKVOLTAGE, Units.VOLT));
+ channelConfigurationSsoS4
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_S4TIMESTAMP, Units.ONE));
+ return channelConfigurationSsoS4;
+ }
+
+ public static List getChannelConfigurationEso() {
+ final List channelConfigurationEso = new ArrayList<>();
+ channelConfigurationEso
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_ESOID, Units.ONE));
+ channelConfigurationEso
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_ESOVOLTAGEBATTERY, Units.VOLT));
+ channelConfigurationEso.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_ESOCURRENTBATTERY, Units.AMPERE));
+ channelConfigurationEso.add(new FerroampChannelConfiguration(
+ FerroampBindingConstants.CHANNEL_ESOBATTERYENERGYPRODUCED, Units.WATT));
+ channelConfigurationEso.add(new FerroampChannelConfiguration(
+ FerroampBindingConstants.CHANNEL_ESOBATTERYENERGYCONSUMED, Units.WATT));
+ channelConfigurationEso
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_ESOSOC, Units.PERCENT));
+ channelConfigurationEso
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_ESORELAYSTATUS, Units.ONE));
+ channelConfigurationEso
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_ESOTEMPERATURE, Units.ONE));
+ channelConfigurationEso
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_ESOFAULTCODE, Units.ONE));
+ channelConfigurationEso
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_ESODCLINKVOLTAGE, Units.VOLT));
+ channelConfigurationEso
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_ESOTIMESTAMP, Units.ONE));
+ return channelConfigurationEso;
+ }
+
+ public static List getChannelConfigurationEsm() {
+ final List channelConfigurationEsm = new ArrayList<>();
+ channelConfigurationEsm
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_ESMID, Units.ONE));
+ channelConfigurationEsm
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_ESMSOH, Units.PERCENT));
+ channelConfigurationEsm
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_ESMSOC, Units.PERCENT));
+ channelConfigurationEsm.add(
+ new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_ESMTOTALCAPACITY, Units.WATT_HOUR));
+ channelConfigurationEsm
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_ESMPOWERBATTERY, Units.WATT));
+ channelConfigurationEsm
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_ESMSTATUS, Units.ONE));
+ channelConfigurationEsm
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_ESMTIMESTAMP, Units.ONE));
+ return channelConfigurationEsm;
+ }
+
+ public static List getChannelConfigurationRequest() {
+ final List channelConfigurationRequest = new ArrayList<>();
+ channelConfigurationRequest
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_REQUESTCHARGE, Units.ONE));
+ channelConfigurationRequest
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_REQUESTDISCHARGE, Units.ONE));
+ channelConfigurationRequest
+ .add(new FerroampChannelConfiguration(FerroampBindingConstants.CHANNEL_AUTO, Units.ONE));
+ return channelConfigurationRequest;
+ }
+}
diff --git a/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/FerroampConfiguration.java b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/FerroampConfiguration.java
new file mode 100644
index 0000000000000..22bff72fa80ee
--- /dev/null
+++ b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/FerroampConfiguration.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.ferroamp.internal;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * The {@link FerroampConfiguration} class contains fields mapping thing configuration parameters.
+ *
+ * @author Örjan Backsell - Initial contribution
+ *
+ */
+
+@NonNullByDefault
+public class FerroampConfiguration {
+ public String hostName = "";
+ public String userName = "";
+ public String password = "";
+ public boolean hasBattery = false;
+}
diff --git a/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/FerroampHandler.java b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/FerroampHandler.java
new file mode 100644
index 0000000000000..82534487bec83
--- /dev/null
+++ b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/FerroampHandler.java
@@ -0,0 +1,258 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.ferroamp.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.core.io.transport.mqtt.MqttBrokerConnection;
+import org.openhab.core.io.transport.mqtt.MqttMessageSubscriber;
+import org.openhab.core.library.types.StringType;
+import org.openhab.core.thing.ChannelUID;
+import org.openhab.core.thing.Thing;
+import org.openhab.core.thing.ThingStatus;
+import org.openhab.core.thing.ThingStatusDetail;
+import org.openhab.core.thing.binding.BaseThingHandler;
+import org.openhab.core.types.Command;
+import org.openhab.core.types.State;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The {@link FerroampHandler} is responsible for handling of the values sent to and from the binding.
+ *
+ * @author Örjan Backsell - Initial contribution
+ *
+ */
+@NonNullByDefault
+public class FerroampHandler extends BaseThingHandler implements MqttMessageSubscriber {
+ private final static Logger logger = LoggerFactory.getLogger(FerroampHandler.class);
+ private @Nullable static MqttBrokerConnection ferroampConnection;
+ FerroampMqttCommunication ferroampMqttCommunication = new FerroampMqttCommunication(thing);
+ private @Nullable FerroampConfiguration ferroampConfig;
+
+ private static List channelConfigEhub = new ArrayList<>();
+ private static List channelConfigSsoS1 = new ArrayList<>();
+ private static List channelConfigSsoS2 = new ArrayList<>();
+ private static List channelConfigSsoS3 = new ArrayList<>();
+ private static List channelConfigSsoS4 = new ArrayList<>();
+ private static List channelConfigEso = new ArrayList<>();
+ private static List channelConfigEsm = new ArrayList<>();
+
+ long refreshInterval = 30;
+
+ public FerroampHandler(Thing thing) {
+ super(thing);
+ }
+
+ @Override
+ public void handleCommand(ChannelUID channelUID, Command command) {
+ String transId = UUID.randomUUID().toString();
+ String valueConfiguration = command.toString();
+ if (FerroampBindingConstants.CHANNEL_REQUESTCHARGE.equals(channelUID.getId())) {
+ String requestCmdJsonCharge = "{\"" + "transId" + "\":\"" + transId
+ + "\",\"cmd\":{\"name\":\"charge\",\"arg\":\"" + valueConfiguration + "\"}}";
+ FerroampMqttCommunication.sendPublishedTopic(requestCmdJsonCharge, ferroampConfig);
+ }
+ if (FerroampBindingConstants.CHANNEL_REQUESTDISCHARGE.equals(channelUID.getId())) {
+ String requestCmdJsonDisCharge = "{\"" + "transId" + "\":\"" + transId
+ + "\",\"cmd\":{\"name\":\"discharge\",\"arg\":\"" + valueConfiguration + "\"}}";
+ FerroampMqttCommunication.sendPublishedTopic(requestCmdJsonDisCharge, ferroampConfig);
+ }
+ if (FerroampBindingConstants.CHANNEL_AUTO.equals(channelUID.getId())) {
+ String requestCmdJsonAuto = "{\"" + "transId" + "\":\"" + transId + "\",\"cmd\":{\"name\":\"auto\"}}";
+ FerroampMqttCommunication.sendPublishedTopic(requestCmdJsonAuto, ferroampConfig);
+ }
+ }
+
+ @Override
+ public void initialize() {
+ // Set configuration parameters
+ ferroampConfig = getConfigAs(FerroampConfiguration.class);
+
+ // Set channel configuration parameters
+ channelConfigEhub = FerroampChannelConfiguration.getChannelConfigurationEhub();
+ channelConfigSsoS1 = FerroampChannelConfiguration.getChannelConfigurationSsoS1();
+ channelConfigSsoS2 = FerroampChannelConfiguration.getChannelConfigurationSsoS2();
+ channelConfigSsoS3 = FerroampChannelConfiguration.getChannelConfigurationSsoS3();
+ channelConfigSsoS4 = FerroampChannelConfiguration.getChannelConfigurationSsoS4();
+ channelConfigEso = FerroampChannelConfiguration.getChannelConfigurationEso();
+ channelConfigEsm = FerroampChannelConfiguration.getChannelConfigurationEsm();
+
+ if (ferroampConfig != null) {
+
+ FerroampConfiguration ferroampConfig = getConfigAs(FerroampConfiguration.class);
+ final MqttBrokerConnection ferroampConnection = new MqttBrokerConnection(ferroampConfig.hostName,
+ FerroampBindingConstants.BROKER_PORT, false, false, ferroampConfig.userName);
+ scheduler.scheduleWithFixedDelay(this::pollTask, 60, refreshInterval, TimeUnit.SECONDS);
+ this.setFerroampConnection(ferroampConnection);
+ updateStatus(ThingStatus.UNKNOWN);
+ } else {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR);
+ logger.debug("Configuration problems");
+ }
+ }
+
+ private void pollTask() {
+ try {
+ startMqttConnection(getConfigAs(FerroampConfiguration.class));
+ } catch (InterruptedException e) {
+ logger.debug("Not connected to the MqttBroker");
+ return;
+ }
+
+ MqttBrokerConnection ferroampConnection = FerroampHandler.ferroampConnection;
+
+ if (ferroampConnection == null || ferroampConnection.connectionState().toString().equals("DISCONNECTED")) {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
+ logger.debug("Problem connection to MqttBroker");
+ } else if (ferroampConnection.connectionState().toString().equals("CONNECTED")) {
+ updateStatus(ThingStatus.ONLINE);
+ try {
+ channelUpdate();
+ } catch (RuntimeException scheduleWithFixedDelayException) {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
+ scheduleWithFixedDelayException.getClass().getName() + ":"
+ + scheduleWithFixedDelayException.getMessage());
+ }
+ }
+ }
+
+ private void startMqttConnection(FerroampConfiguration ferroampConfig) throws InterruptedException {
+
+ MqttBrokerConnection localSubscribeConnection = FerroampHandler.getFerroampConnection();
+
+ Objects.requireNonNull(localSubscribeConnection,
+ "MqttBrokerConnection localSubscribeConnection cannot be null");
+
+ localSubscribeConnection.start();
+ localSubscribeConnection.setCredentials(ferroampConfig.userName, ferroampConfig.password);
+
+ ferroampMqttCommunication.getSubscribedTopic("ehubTopic", ferroampConfig);
+ ferroampMqttCommunication.getSubscribedTopic("ssoTopic", ferroampConfig);
+ ferroampMqttCommunication.getSubscribedTopic("esoTopic", ferroampConfig);
+ ferroampMqttCommunication.getSubscribedTopic("esmTopic", ferroampConfig);
+ }
+
+ private void channelUpdate() {
+ String[] ehubUpdateChannels;
+ ehubUpdateChannels = FerroampMqttCommunication.getEhubChannelUpdateValues();
+ int channelValuesCounterEhub = 0;
+ for (FerroampChannelConfiguration cConfig : channelConfigEhub) {
+ String ehubChannel = cConfig.id;
+ State ehubState = StringType.valueOf(ehubUpdateChannels[channelValuesCounterEhub]);
+ updateState(ehubChannel, ehubState);
+ channelValuesCounterEhub++;
+ }
+
+ String[] ssoS1UpdateChannels = new String[9];
+ ssoS1UpdateChannels = FerroampMqttCommunication.getSsoS1ChannelUpdateValues();
+ int channelValuesCounterSsoS1 = 0;
+ if (ssoS1UpdateChannels.length <= 9) {
+ for (FerroampChannelConfiguration cConfig : channelConfigSsoS1) {
+ String ssoS1Channel = cConfig.id;
+ State ssoS1State = StringType.valueOf(ssoS1UpdateChannels[channelValuesCounterSsoS1]);
+ updateState(ssoS1Channel, ssoS1State);
+ channelValuesCounterSsoS1++;
+ }
+ }
+
+ String[] ssoS2UpdateChannels = new String[9];
+ ssoS2UpdateChannels = FerroampMqttCommunication.getSsoS2ChannelUpdateValues();
+ int channelValuesCounterSsoS2 = 0;
+ if (ssoS2UpdateChannels.length <= 9) {
+ for (FerroampChannelConfiguration cConfig : channelConfigSsoS2) {
+ String ssoS2Channel = cConfig.id;
+ State ssoS2State = StringType.valueOf(ssoS2UpdateChannels[channelValuesCounterSsoS2]);
+ updateState(ssoS2Channel, ssoS2State);
+ channelValuesCounterSsoS2++;
+ }
+ }
+
+ String[] ssoS3UpdateChannels = new String[9];
+ ssoS3UpdateChannels = FerroampMqttCommunication.getSsoS3ChannelUpdateValues();
+ int channelValuesCounterSsoS3 = 0;
+ if (ssoS3UpdateChannels.length <= 9) {
+ for (FerroampChannelConfiguration cConfig : channelConfigSsoS3) {
+ String ssoS3Channel = cConfig.id;
+ State ssoS3State = StringType.valueOf(ssoS3UpdateChannels[channelValuesCounterSsoS3]);
+ updateState(ssoS3Channel, ssoS3State);
+ channelValuesCounterSsoS3++;
+ }
+ }
+
+ String[] ssoS4UpdateChannels = new String[9];
+ ssoS4UpdateChannels = FerroampMqttCommunication.getSsoS4ChannelUpdateValues();
+ int channelValuesCounterSsoS4 = 0;
+ if (ssoS4UpdateChannels.length <= 9) {
+ for (FerroampChannelConfiguration cConfig : channelConfigSsoS4) {
+ String ssoS4Channel = cConfig.id;
+ State ssoS4State = StringType.valueOf(ssoS4UpdateChannels[channelValuesCounterSsoS4]);
+ updateState(ssoS4Channel, ssoS4State);
+ channelValuesCounterSsoS4++;
+ }
+ }
+
+ String[] esoUpdateChannels = new String[11];
+ esoUpdateChannels = FerroampMqttCommunication.getEsoChannelUpdateValues();
+ if (esoUpdateChannels.length > 0) {
+ int channelValuesCounterEso = 0;
+ if (esoUpdateChannels.length <= 9) {
+ for (FerroampChannelConfiguration cConfig : channelConfigEso) {
+ String esoChannel = cConfig.id;
+ State esoState = StringType.valueOf(esoUpdateChannels[channelValuesCounterEso]);
+ updateState(esoChannel, esoState);
+ channelValuesCounterEso++;
+ }
+ }
+ }
+
+ String[] esmUpdateChannels = new String[7];
+ esmUpdateChannels = FerroampMqttCommunication.getEsmChannelUpdateValues();
+ if (esmUpdateChannels.length > 0) {
+ int channelValuesCounterEsm = 0;
+ if (esmUpdateChannels.length <= 9) {
+ for (FerroampChannelConfiguration cConfig : channelConfigEsm) {
+ String esmChannel = cConfig.id;
+ State esmState = StringType.valueOf(esmUpdateChannels[channelValuesCounterEsm]);
+ updateState(esmChannel, esmState);
+ channelValuesCounterEsm++;
+ }
+ }
+ }
+ }
+
+ // Capture actual Json-topic message
+ @Override
+ public void processMessage(String topic, byte[] payload) {
+ }
+
+ public @Nullable static MqttBrokerConnection getFerroampConnection() {
+ try {
+
+ return ferroampConnection;
+ } catch (Exception e) {
+ logger.debug("Connection to MqttBroker disturbed during startup of MqttConnection");
+ }
+ return ferroampConnection;
+ }
+
+ public void setFerroampConnection(@Nullable MqttBrokerConnection ferroampConnection) {
+ FerroampHandler.ferroampConnection = ferroampConnection;
+ }
+}
diff --git a/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/FerroampHandlerFactory.java b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/FerroampHandlerFactory.java
new file mode 100644
index 0000000000000..b317e8313d322
--- /dev/null
+++ b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/FerroampHandlerFactory.java
@@ -0,0 +1,56 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.ferroamp.internal;
+
+import static org.openhab.binding.ferroamp.internal.FerroampBindingConstants.THING_TYPE_ENERGYHUB;
+
+import java.util.Set;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.core.thing.Thing;
+import org.openhab.core.thing.ThingTypeUID;
+import org.openhab.core.thing.binding.BaseThingHandlerFactory;
+import org.openhab.core.thing.binding.ThingHandler;
+import org.openhab.core.thing.binding.ThingHandlerFactory;
+import org.osgi.service.component.annotations.Component;
+
+/**
+ * The {@link FerroampHandlerFactory} is responsible for creating things and thing
+ * handlers.
+ *
+ * @author Örjan Backsell - Initial contribution
+ *
+ */
+
+@NonNullByDefault
+@Component(configurationPid = "binding.ferroamp", service = ThingHandlerFactory.class)
+public class FerroampHandlerFactory extends BaseThingHandlerFactory {
+
+ private static final Set SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_ENERGYHUB);
+
+ @Override
+ public boolean supportsThingType(ThingTypeUID thingTypeUID) {
+ return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
+ }
+
+ @Override
+ protected @Nullable ThingHandler createHandler(Thing thing) {
+ ThingTypeUID thingTypeUID = thing.getThingTypeUID();
+
+ if (THING_TYPE_ENERGYHUB.equals(thingTypeUID)) {
+ return new FerroampHandler(thing);
+ }
+ return null;
+ }
+}
diff --git a/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/FerroampMqttCommunication.java b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/FerroampMqttCommunication.java
new file mode 100644
index 0000000000000..8b580dd6ec6ab
--- /dev/null
+++ b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/FerroampMqttCommunication.java
@@ -0,0 +1,920 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.ferroamp.internal;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Objects;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.ferroamp.dto.GetGeneralLx;
+import org.openhab.binding.ferroamp.dto.GetGeneralValues;
+import org.openhab.binding.ferroamp.dto.GetUdc;
+import org.openhab.core.io.transport.mqtt.MqttBrokerConnection;
+import org.openhab.core.io.transport.mqtt.MqttMessageSubscriber;
+import org.openhab.core.thing.Thing;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+
+/**
+ * The {@link FerroampMqttCommunication} is responsible for communication with the Ferroamp-systems Mqtt-broker.
+ *
+ * @author Örjan Backsell - Initial contribution
+ *
+ */
+
+public class FerroampMqttCommunication implements MqttMessageSubscriber {
+
+ static String[] ehubChannelsUpdateValues = new String[0];
+ static String[] ssoS1ChannelsUpdateValues = new String[0];
+ static String[] ssoS2ChannelsUpdateValues = new String[0];
+ static String[] ssoS3ChannelsUpdateValues = new String[0];
+ static String[] ssoS4ChannelsUpdateValues = new String[0];
+ static String[] esoChannelsUpdateValues = new String[0];
+ static String[] esmChannelsUpdateValues = new String[0];
+
+ static boolean isSsoChecked = false;
+ static String ssoS1IdCheck = "";
+ static String ssoS2IdCheck = "";
+ static String ssoS3IdCheck = "";
+ static String ssoS4IdCheck = "";
+
+ private final static Logger logger = LoggerFactory.getLogger(FerroampMqttCommunication.class);
+
+ public FerroampMqttCommunication(Thing thing) {
+ super();
+ }
+
+ // Handles request topic
+ static void sendPublishedTopic(String payload, FerroampConfiguration ferroampConfig) {
+
+ MqttBrokerConnection localConfigurationConnection = FerroampHandler.getFerroampConnection();
+
+ Objects.requireNonNull(localConfigurationConnection,
+ "MqttBrokerConnection localConfigurationConnection cannot be null");
+
+ localConfigurationConnection.start();
+ localConfigurationConnection.setCredentials(ferroampConfig.userName, ferroampConfig.password);
+ localConfigurationConnection.publish(FerroampBindingConstants.REQUEST_TOPIC, payload.getBytes(), 1, false);
+ }
+
+ // Handles respective topic type
+ void getSubscribedTopic(String topic, FerroampConfiguration ferroampConfig) {
+
+ MqttBrokerConnection localSubscribeConnection = FerroampHandler.getFerroampConnection();
+
+ Objects.requireNonNull(localSubscribeConnection,
+ "MqttBrokerConnection localSubscribeConnection cannot be null");
+
+ if ("ehubTopic".equals(topic)) {
+ localSubscribeConnection.subscribe(FerroampBindingConstants.EHUB_TOPIC, this);
+ }
+ if ("ssoTopic".equals(topic)) {
+ localSubscribeConnection.subscribe(FerroampBindingConstants.SSO_TOPIC, this);
+ }
+ if ("esoTopic".equals(topic)) {
+ localSubscribeConnection.subscribe(FerroampBindingConstants.ESO_TOPIC, this);
+ }
+ if ("esmTopic".equals(topic)) {
+ localSubscribeConnection.subscribe(FerroampBindingConstants.ESM_TOPIC, this);
+ }
+ }
+
+ // Capture actual Json-topic message
+ @Override
+ public void processMessage(String topic, byte[] payload) {
+ if ("extapi/data/ehub".equals(topic)) {
+ processIncomingJsonMessageEhub(topic, new String(payload, StandardCharsets.UTF_8));
+ }
+ if ("extapi/data/sso".equals(topic)) {
+ processIncomingJsonMessageSso(topic, new String(payload, StandardCharsets.UTF_8));
+ }
+ if ("extapi/data/eso".equals(topic)) {
+ processIncomingJsonMessageEso(topic, new String(payload, StandardCharsets.UTF_8));
+ }
+ if ("extapi/data/esm".equals(topic)) {
+ processIncomingJsonMessageEsm(topic, new String(payload, StandardCharsets.UTF_8));
+ }
+ }
+
+ // Prepare actual Json-topic Ehub-message and update values for channels
+ void processIncomingJsonMessageEhub(String topic, String messageJsonEhub) {
+ String[] ehubChannelPostsValue = new String[86]; // Array for EHUB (Energy Hub) Posts
+
+ JsonObject jsonElementsObject = new Gson().fromJson(new Gson().fromJson(messageJsonEhub, JsonObject.class),
+ JsonObject.class);
+
+ Objects.requireNonNull(jsonElementsObject, "JsonObject jsonElementsObject cannot be null");
+
+ String jsonElementsStringTemp = "";
+ Gson gson = new Gson();
+
+ // gridfreq
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(0)).toString();
+ GetGeneralValues gridfreq = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+
+ ehubChannelPostsValue[0] = gridfreq.getVal();
+
+ // iace
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(1)).toString();
+ GetGeneralLx iace = checkNullGeneralLx(gson.fromJson(jsonElementsStringTemp, GetGeneralLx.class));
+ ehubChannelPostsValue[1] = iace.getL1();
+ ehubChannelPostsValue[2] = iace.getL2();
+ ehubChannelPostsValue[3] = iace.getL3();
+
+ // ul
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(2)).toString();
+ GetGeneralLx ul = checkNullGeneralLx(gson.fromJson(jsonElementsStringTemp, GetGeneralLx.class));
+ ehubChannelPostsValue[4] = ul.getL1();
+ ehubChannelPostsValue[5] = ul.getL2();
+ ehubChannelPostsValue[6] = ul.getL3();
+
+ // il
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(3)).toString();
+ GetGeneralLx il = checkNullGeneralLx(gson.fromJson(jsonElementsStringTemp, GetGeneralLx.class));
+ ehubChannelPostsValue[7] = il.getL1();
+ ehubChannelPostsValue[8] = il.getL2();
+ ehubChannelPostsValue[9] = il.getL3();
+
+ // ild
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(4)).toString();
+ GetGeneralLx ild = checkNullGeneralLx(gson.fromJson(jsonElementsStringTemp, GetGeneralLx.class));
+ ehubChannelPostsValue[10] = ild.getL1();
+ ehubChannelPostsValue[11] = ild.getL2();
+ ehubChannelPostsValue[12] = ild.getL3();
+
+ // ilq
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(5)).toString();
+ GetGeneralLx ilq = checkNullGeneralLx(gson.fromJson(jsonElementsStringTemp, GetGeneralLx.class));
+ ehubChannelPostsValue[13] = ilq.getL1();
+ ehubChannelPostsValue[14] = ilq.getL2();
+ ehubChannelPostsValue[15] = ilq.getL3();
+
+ // iext
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(6)).toString();
+ GetGeneralLx iext = checkNullGeneralLx(gson.fromJson(jsonElementsStringTemp, GetGeneralLx.class));
+ ehubChannelPostsValue[16] = iext.getL1();
+ ehubChannelPostsValue[17] = iext.getL2();
+ ehubChannelPostsValue[18] = iext.getL3();
+
+ // iextd
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(7)).toString();
+ GetGeneralLx iextd = checkNullGeneralLx(gson.fromJson(jsonElementsStringTemp, GetGeneralLx.class));
+ ehubChannelPostsValue[19] = iextd.getL1();
+ ehubChannelPostsValue[20] = iextd.getL2();
+ ehubChannelPostsValue[21] = iextd.getL3();
+
+ // iextq
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(8)).toString();
+ GetGeneralLx iextq = checkNullGeneralLx(gson.fromJson(jsonElementsStringTemp, GetGeneralLx.class));
+ ehubChannelPostsValue[22] = iextq.getL1();
+ ehubChannelPostsValue[23] = iextq.getL2();
+ ehubChannelPostsValue[24] = iextq.getL3();
+
+ // iloadd
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(9)).toString();
+ GetGeneralLx iloadd = checkNullGeneralLx(gson.fromJson(jsonElementsStringTemp, GetGeneralLx.class));
+ ehubChannelPostsValue[25] = iloadd.getL1();
+ ehubChannelPostsValue[26] = iloadd.getL2();
+ ehubChannelPostsValue[27] = iloadd.getL3();
+
+ // iloadq
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(10)).toString();
+ GetGeneralLx iloadq = checkNullGeneralLx(gson.fromJson(jsonElementsStringTemp, GetGeneralLx.class));
+ ehubChannelPostsValue[28] = iloadq.getL1();
+ ehubChannelPostsValue[29] = iloadq.getL2();
+ ehubChannelPostsValue[30] = iloadq.getL3();
+
+ // sext
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(11)).toString();
+ GetGeneralValues sext = checkNullGeneralValues(gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+ ehubChannelPostsValue[31] = sext.getVal();
+
+ // pext
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(12)).toString();
+ GetGeneralLx pext = checkNullGeneralLx(gson.fromJson(jsonElementsStringTemp, GetGeneralLx.class));
+ ehubChannelPostsValue[32] = pext.getL1();
+ ehubChannelPostsValue[33] = pext.getL2();
+ ehubChannelPostsValue[34] = pext.getL3();
+
+ // pextreactive
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(13)).toString();
+ GetGeneralLx pextreactive = checkNullGeneralLx(gson.fromJson(jsonElementsStringTemp, GetGeneralLx.class));
+ ehubChannelPostsValue[35] = pextreactive.getL1();
+ ehubChannelPostsValue[36] = pextreactive.getL2();
+ ehubChannelPostsValue[37] = pextreactive.getL3();
+
+ // pinv
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(14)).toString();
+ GetGeneralLx pinv = checkNullGeneralLx(gson.fromJson(jsonElementsStringTemp, GetGeneralLx.class));
+ ehubChannelPostsValue[38] = pinv.getL1();
+ ehubChannelPostsValue[39] = pinv.getL2();
+ ehubChannelPostsValue[40] = pinv.getL3();
+
+ // pinvreactive
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(15)).toString();
+ GetGeneralLx pinvreactive = checkNullGeneralLx(gson.fromJson(jsonElementsStringTemp, GetGeneralLx.class));
+ ehubChannelPostsValue[41] = pinvreactive.getL1();
+ ehubChannelPostsValue[42] = pinvreactive.getL2();
+ ehubChannelPostsValue[43] = pinvreactive.getL3();
+
+ // pload
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(16)).toString();
+ GetGeneralLx pload = checkNullGeneralLx(gson.fromJson(jsonElementsStringTemp, GetGeneralLx.class));
+ ehubChannelPostsValue[44] = pload.getL1();
+ ehubChannelPostsValue[45] = pload.getL2();
+ ehubChannelPostsValue[46] = pload.getL3();
+
+ // ploadreactive
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(17)).toString();
+ GetGeneralLx ploadreactive = checkNullGeneralLx(gson.fromJson(jsonElementsStringTemp, GetGeneralLx.class));
+ ehubChannelPostsValue[47] = ploadreactive.getL1();
+ ehubChannelPostsValue[48] = ploadreactive.getL2();
+ ehubChannelPostsValue[49] = ploadreactive.getL3();
+
+ // ppv
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(18)).toString();
+ GetGeneralValues ppv = checkNullGeneralValues(gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(19)).toString();
+ GetUdc udc = checkNullUdc(gson.fromJson(jsonElementsStringTemp, GetUdc.class));
+ ehubChannelPostsValue[50] = ppv.getVal();
+ ehubChannelPostsValue[51] = udc.getPos();
+ ehubChannelPostsValue[52] = udc.getNeg();
+
+ // wextprodq
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(20)).toString();
+ GetGeneralLx wextprodq = checkNullGeneralLx(gson.fromJson(jsonElementsStringTemp, GetGeneralLx.class));
+ ehubChannelPostsValue[53] = mJTokWh(jsonStripEhub(wextprodq.getL1()));
+ ehubChannelPostsValue[54] = mJTokWh(jsonStripEhub(wextprodq.getL2()));
+ ehubChannelPostsValue[55] = mJTokWh(jsonStripEhub(wextprodq.getL3()));
+
+ // wextconsq
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(21)).toString();
+ GetGeneralLx wextconsq = checkNullGeneralLx(gson.fromJson(jsonElementsStringTemp, GetGeneralLx.class));
+ ehubChannelPostsValue[56] = mJTokWh(jsonStripEhub(wextconsq.getL1()));
+ ehubChannelPostsValue[57] = mJTokWh(jsonStripEhub(wextconsq.getL2()));
+ ehubChannelPostsValue[58] = mJTokWh(jsonStripEhub(wextconsq.getL3()));
+
+ // winvprodq
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(22)).toString();
+ GetGeneralLx winvprodq = checkNullGeneralLx(gson.fromJson(jsonElementsStringTemp, GetGeneralLx.class));
+ ehubChannelPostsValue[59] = mJTokWh(jsonStripEhub(winvprodq.getL1()));
+ ehubChannelPostsValue[60] = mJTokWh(jsonStripEhub(winvprodq.getL2()));
+ ehubChannelPostsValue[61] = mJTokWh(jsonStripEhub(winvprodq.getL3()));
+
+ // winvconsq
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(23)).toString();
+ GetGeneralLx winvconsq = checkNullGeneralLx(gson.fromJson(jsonElementsStringTemp, GetGeneralLx.class));
+ ehubChannelPostsValue[62] = mJTokWh(jsonStripEhub(winvconsq.getL1()));
+ ehubChannelPostsValue[63] = mJTokWh(jsonStripEhub(winvconsq.getL2()));
+ ehubChannelPostsValue[64] = mJTokWh(jsonStripEhub(winvconsq.getL3()));
+
+ // wloadprodq
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(24)).toString();
+ GetGeneralLx wloadprodq = checkNullGeneralLx(gson.fromJson(jsonElementsStringTemp, GetGeneralLx.class));
+ ehubChannelPostsValue[65] = mJTokWh(jsonStripEhub(wloadprodq.getL1()));
+ ehubChannelPostsValue[66] = mJTokWh(jsonStripEhub(wloadprodq.getL2()));
+ ehubChannelPostsValue[67] = mJTokWh(jsonStripEhub(wloadprodq.getL3()));
+
+ // wloadconsq
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(25)).toString();
+ GetGeneralLx wloadconsq = checkNullGeneralLx(gson.fromJson(jsonElementsStringTemp, GetGeneralLx.class));
+ ehubChannelPostsValue[68] = mJTokWh(jsonStripEhub(wloadconsq.getL1()));
+ ehubChannelPostsValue[69] = mJTokWh(jsonStripEhub(wloadconsq.getL2()));
+ ehubChannelPostsValue[70] = mJTokWh(jsonStripEhub(wloadconsq.getL3()));
+
+ // wextprodq_3p
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(26)).toString();
+ GetGeneralValues wextprodq_3p = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+ ehubChannelPostsValue[71] = mJTokWh(jsonStripOneLiners(wextprodq_3p.getVal()));
+
+ // wextconsq_3p
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(27)).toString();
+ GetGeneralValues wextconsq3p = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+ ehubChannelPostsValue[72] = mJTokWh(jsonStripOneLiners(wextconsq3p.getVal()));
+
+ // winvprodq_3p
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(28)).toString();
+ GetGeneralValues winvprodq3p = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+ ehubChannelPostsValue[73] = mJTokWh(jsonStripOneLiners(winvprodq3p.getVal()));
+
+ // winvconsq_3p
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(29)).toString();
+ GetGeneralValues winvconsq3p = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+ ehubChannelPostsValue[74] = mJTokWh(jsonStripOneLiners(winvconsq3p.getVal()));
+
+ // wloadprodq_3p
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(30)).toString();
+ GetGeneralValues wloadprodq3p = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+ ehubChannelPostsValue[75] = mJTokWh(jsonStripOneLiners(wloadprodq3p.getVal()));
+
+ // wloadconsq_3p
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(31)).toString();
+ GetGeneralValues wloadconsq3p = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+ ehubChannelPostsValue[76] = mJTokWh(jsonStripOneLiners(wloadconsq3p.getVal()));
+
+ // wpv
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(32)).toString();
+ GetGeneralValues wpv = checkNullGeneralValues(gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+ ehubChannelPostsValue[77] = mJTokWh(jsonStripOneLiners(wpv.getVal()));
+
+ // state
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(33)).toString();
+ GetGeneralValues state = checkNullGeneralValues(gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+ ehubChannelPostsValue[78] = jsonStripOneLiners(state.getVal());
+
+ // ts
+ jsonElementsStringTemp = jsonElementsObject.get(EhubJsonElements.getJsonElementsEhub().get(34)).toString();
+ GetGeneralValues ts = checkNullGeneralValues(gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+ ehubChannelPostsValue[79] = ts.getVal();
+
+ ehubChannelsUpdateValues = ehubChannelPostsValue;
+ }
+
+ // Prepare actual Json-topic Sso-messages and update values for channels
+ void processIncomingJsonMessageSso(String topic, String messageJsonSso) {
+ String[] ssoS1ChannelPostsValue = new String[9]; // Array for SSOS1 ( Solar String Optimizer ) Posts
+ String[] ssoS2ChannelPostsValue = new String[9]; // Array for SSOS2 ( Solar String Optimizer ) Posts
+ String[] ssoS3ChannelPostsValue = new String[9]; // Array for SSOS3 ( Solar String Optimizer ) Posts
+ String[] ssoS4ChannelPostsValue = new String[9]; // Array for SSOS4 ( Solar String Optimizer ) Posts
+
+ String jsonElementsStringTempS1 = "";
+ String jsonElementsStringTempS2 = "";
+ String jsonElementsStringTempS3 = "";
+ String jsonElementsStringTempS4 = "";
+ Gson gson = new Gson();
+
+ JsonObject jsonElementsObjectSsoS1 = new Gson().fromJson(new Gson().fromJson(messageJsonSso, JsonObject.class),
+ JsonObject.class);
+
+ Objects.requireNonNull(jsonElementsObjectSsoS1, "JsonObject jsonElementsObjectSsoS1 cannot be null");
+
+ jsonElementsStringTempS1 = jsonElementsObjectSsoS1.get(SsoJsonElements.getJsonElementsSso().get(0)).toString();
+ GetGeneralValues idS1 = checkNullGeneralValues(gson.fromJson(jsonElementsStringTempS1, GetGeneralValues.class));
+ GetGeneralValues idSso = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS1, GetGeneralValues.class));
+
+ if (isSsoChecked == false) {
+ if (ssoS1IdCheck.isEmpty() && ssoS2IdCheck.isEmpty() && ssoS3IdCheck.isEmpty() && ssoS4IdCheck.isEmpty()) {
+ ssoS1IdCheck = idSso.getVal();
+ } else {
+ if (!ssoS1IdCheck.isEmpty() && ssoS2IdCheck.isEmpty() && ssoS3IdCheck.isEmpty()
+ && ssoS4IdCheck.isEmpty()) {
+ ssoS2IdCheck = idSso.getVal();
+ // isSsoChecked = true;
+ } else {
+ if (!ssoS1IdCheck.isEmpty() && !ssoS2IdCheck.isEmpty() && ssoS3IdCheck.isEmpty()
+ && ssoS4IdCheck.isEmpty()) {
+ ssoS3IdCheck = idSso.getVal();
+ } else {
+ if (!ssoS1IdCheck.isEmpty() && !ssoS2IdCheck.isEmpty() && !ssoS3IdCheck.isEmpty()
+ && ssoS4IdCheck.isEmpty()) {
+ ssoS4IdCheck = idSso.getVal();
+ isSsoChecked = true;
+ }
+ }
+ }
+ }
+ }
+
+ if (idS1.getVal().equals(ssoS1IdCheck)) {
+ // id
+ jsonElementsStringTempS1 = jsonElementsObjectSsoS1.get(SsoJsonElements.getJsonElementsSso().get(0))
+ .toString();
+ idS1 = checkNullGeneralValues(gson.fromJson(jsonElementsStringTempS1, GetGeneralValues.class));
+ ssoS1ChannelPostsValue[0] = idS1.getVal();
+
+ // upv
+ jsonElementsStringTempS1 = jsonElementsObjectSsoS1.get(SsoJsonElements.getJsonElementsSso().get(1))
+ .toString();
+ GetGeneralValues upvS1 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS1, GetGeneralValues.class));
+ ssoS1ChannelPostsValue[1] = upvS1.getVal();
+
+ // ipv
+ jsonElementsStringTempS1 = jsonElementsObjectSsoS1.get(SsoJsonElements.getJsonElementsSso().get(2))
+ .toString();
+ GetGeneralValues ipvS1 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS1, GetGeneralValues.class));
+ ssoS1ChannelPostsValue[2] = ipvS1.getVal();
+
+ // wpv
+ jsonElementsStringTempS1 = jsonElementsObjectSsoS1.get(SsoJsonElements.getJsonElementsSso().get(3))
+ .toString();
+ GetGeneralValues wpvS1 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS1, GetGeneralValues.class));
+ ssoS1ChannelPostsValue[3] = mJTokWh(jsonStripOneLiners(wpvS1.getVal()));
+
+ // relaystatus
+ jsonElementsStringTempS1 = jsonElementsObjectSsoS1.get(SsoJsonElements.getJsonElementsSso().get(4))
+ .toString();
+ GetGeneralValues relaystatusS1 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS1, GetGeneralValues.class));
+ ssoS1ChannelPostsValue[4] = relaystatusS1.getVal();
+
+ // temp
+ jsonElementsStringTempS1 = jsonElementsObjectSsoS1.get(SsoJsonElements.getJsonElementsSso().get(5))
+ .toString();
+ GetGeneralValues tempS1 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS1, GetGeneralValues.class));
+ ssoS1ChannelPostsValue[5] = tempS1.getVal();
+
+ // faultcode
+ jsonElementsStringTempS1 = jsonElementsObjectSsoS1.get(SsoJsonElements.getJsonElementsSso().get(6))
+ .toString();
+ GetGeneralValues faultcodeS1 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS1, GetGeneralValues.class));
+ ssoS1ChannelPostsValue[6] = faultcodeS1.getVal();
+
+ // udc
+ jsonElementsStringTempS1 = jsonElementsObjectSsoS1.get(SsoJsonElements.getJsonElementsSso().get(7))
+ .toString();
+ GetGeneralValues udcS1 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS1, GetGeneralValues.class));
+ ssoS1ChannelPostsValue[7] = udcS1.getVal();
+
+ // ts
+ jsonElementsStringTempS1 = jsonElementsObjectSsoS1.get(SsoJsonElements.getJsonElementsSso().get(8))
+ .toString();
+ GetGeneralValues tsS1 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS1, GetGeneralValues.class));
+ ssoS1ChannelPostsValue[8] = tsS1.getVal();
+
+ ssoS1ChannelsUpdateValues = ssoS1ChannelPostsValue;
+ }
+
+ JsonObject jsonElementsObjectSsoS2 = new Gson().fromJson(new Gson().fromJson(messageJsonSso, JsonObject.class),
+ JsonObject.class);
+
+ Objects.requireNonNull(jsonElementsObjectSsoS2, "JsonObject jsonElementsObjectSsoS2 cannot be null");
+
+ jsonElementsStringTempS2 = jsonElementsObjectSsoS2.get(SsoJsonElements.getJsonElementsSso().get(0)).toString();
+ GetGeneralValues idS2 = checkNullGeneralValues(gson.fromJson(jsonElementsStringTempS2, GetGeneralValues.class));
+
+ if (idS2.getVal().equals(ssoS2IdCheck)) {
+ // id
+ jsonElementsStringTempS2 = jsonElementsObjectSsoS2.get(SsoJsonElements.getJsonElementsSso().get(0))
+ .toString();
+ idS2 = checkNullGeneralValues(gson.fromJson(jsonElementsStringTempS2, GetGeneralValues.class));
+ ssoS2ChannelPostsValue[0] = idS2.getVal();
+
+ // upv
+ jsonElementsStringTempS2 = jsonElementsObjectSsoS2.get(SsoJsonElements.getJsonElementsSso().get(1))
+ .toString();
+ GetGeneralValues upvS2 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS2, GetGeneralValues.class));
+ ssoS2ChannelPostsValue[1] = upvS2.getVal();
+
+ // ipv
+ jsonElementsStringTempS2 = jsonElementsObjectSsoS2.get(SsoJsonElements.getJsonElementsSso().get(2))
+ .toString();
+ GetGeneralValues ipvS2 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS2, GetGeneralValues.class));
+ ssoS2ChannelPostsValue[2] = ipvS2.getVal();
+
+ // wpv
+ jsonElementsStringTempS2 = jsonElementsObjectSsoS2.get(SsoJsonElements.getJsonElementsSso().get(3))
+ .toString();
+ GetGeneralValues wpvS2 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS2, GetGeneralValues.class));
+ ssoS2ChannelPostsValue[3] = mJTokWh(jsonStripOneLiners(wpvS2.getVal()));
+
+ // relaystatus
+ jsonElementsStringTempS2 = jsonElementsObjectSsoS2.get(SsoJsonElements.getJsonElementsSso().get(4))
+ .toString();
+ GetGeneralValues relaystatusS2 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS2, GetGeneralValues.class));
+ ssoS2ChannelPostsValue[4] = relaystatusS2.getVal();
+
+ // temp
+ jsonElementsStringTempS2 = jsonElementsObjectSsoS2.get(SsoJsonElements.getJsonElementsSso().get(5))
+ .toString();
+ GetGeneralValues tempS2 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS2, GetGeneralValues.class));
+ ssoS2ChannelPostsValue[5] = tempS2.getVal();
+
+ // faultcode
+ jsonElementsStringTempS2 = jsonElementsObjectSsoS2.get(SsoJsonElements.getJsonElementsSso().get(6))
+ .toString();
+ GetGeneralValues faultcodeS2 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS2, GetGeneralValues.class));
+ ssoS2ChannelPostsValue[6] = faultcodeS2.getVal();
+
+ // udc
+ jsonElementsStringTempS2 = jsonElementsObjectSsoS2.get(SsoJsonElements.getJsonElementsSso().get(7))
+ .toString();
+ GetGeneralValues udc = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS2, GetGeneralValues.class));
+ ssoS2ChannelPostsValue[7] = udc.getVal();
+
+ // ts
+ jsonElementsStringTempS2 = jsonElementsObjectSsoS2.get(SsoJsonElements.getJsonElementsSso().get(8))
+ .toString();
+ GetGeneralValues tsS2 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS2, GetGeneralValues.class));
+ ssoS2ChannelPostsValue[8] = tsS2.getVal();
+
+ ssoS2ChannelsUpdateValues = ssoS2ChannelPostsValue;
+ }
+
+ JsonObject jsonElementsObjectSsoS3 = new Gson().fromJson(new Gson().fromJson(messageJsonSso, JsonObject.class),
+ JsonObject.class);
+
+ Objects.requireNonNull(jsonElementsObjectSsoS3, "JsonObject jsonElementsObjectSsoS3 cannot be null");
+
+ jsonElementsStringTempS3 = jsonElementsObjectSsoS3.get(SsoJsonElements.getJsonElementsSso().get(0)).toString();
+ GetGeneralValues idS3 = checkNullGeneralValues(gson.fromJson(jsonElementsStringTempS3, GetGeneralValues.class));
+
+ if (idS3.getVal().equals(ssoS3IdCheck)) {
+ // id
+ jsonElementsStringTempS3 = jsonElementsObjectSsoS3.get(SsoJsonElements.getJsonElementsSso().get(0))
+ .toString();
+ idS3 = checkNullGeneralValues(gson.fromJson(jsonElementsStringTempS3, GetGeneralValues.class));
+ ssoS3ChannelPostsValue[0] = idS3.getVal();
+
+ // upv
+ jsonElementsStringTempS3 = jsonElementsObjectSsoS3.get(SsoJsonElements.getJsonElementsSso().get(1))
+ .toString();
+ GetGeneralValues upvS3 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS3, GetGeneralValues.class));
+ ssoS3ChannelPostsValue[1] = upvS3.getVal();
+
+ // ipv
+ jsonElementsStringTempS3 = jsonElementsObjectSsoS3.get(SsoJsonElements.getJsonElementsSso().get(2))
+ .toString();
+ GetGeneralValues ipvS3 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS3, GetGeneralValues.class));
+ ssoS3ChannelPostsValue[2] = ipvS3.getVal();
+
+ // wpv
+ jsonElementsStringTempS3 = jsonElementsObjectSsoS3.get(SsoJsonElements.getJsonElementsSso().get(3))
+ .toString();
+ GetGeneralValues wpvS3 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS3, GetGeneralValues.class));
+ ssoS3ChannelPostsValue[3] = mJTokWh(jsonStripOneLiners(wpvS3.getVal()));
+
+ // relaystatus
+ jsonElementsStringTempS3 = jsonElementsObjectSsoS3.get(SsoJsonElements.getJsonElementsSso().get(4))
+ .toString();
+ GetGeneralValues relaystatusS3 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS3, GetGeneralValues.class));
+ ssoS3ChannelPostsValue[4] = relaystatusS3.getVal();
+
+ // temp
+ jsonElementsStringTempS3 = jsonElementsObjectSsoS3.get(SsoJsonElements.getJsonElementsSso().get(5))
+ .toString();
+ GetGeneralValues tempS3 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS3, GetGeneralValues.class));
+ ssoS3ChannelPostsValue[5] = tempS3.getVal();
+
+ // faultcode
+ jsonElementsStringTempS3 = jsonElementsObjectSsoS3.get(SsoJsonElements.getJsonElementsSso().get(6))
+ .toString();
+ GetGeneralValues faultcodeS3 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS3, GetGeneralValues.class));
+ ssoS3ChannelPostsValue[6] = faultcodeS3.getVal();
+
+ // udc
+ jsonElementsStringTempS3 = jsonElementsObjectSsoS3.get(SsoJsonElements.getJsonElementsSso().get(7))
+ .toString();
+ GetGeneralValues udcS3 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS3, GetGeneralValues.class));
+ ssoS3ChannelPostsValue[7] = udcS3.getVal();
+
+ // ts
+ jsonElementsStringTempS3 = jsonElementsObjectSsoS3.get(SsoJsonElements.getJsonElementsSso().get(8))
+ .toString();
+ GetGeneralValues tsS3 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS3, GetGeneralValues.class));
+ ssoS3ChannelPostsValue[8] = tsS3.getVal();
+
+ ssoS3ChannelsUpdateValues = ssoS3ChannelPostsValue;
+ }
+
+ JsonObject jsonElementsObjectSsoS4 = new Gson().fromJson(new Gson().fromJson(messageJsonSso, JsonObject.class),
+ JsonObject.class);
+
+ Objects.requireNonNull(jsonElementsObjectSsoS4, "JsonObject jsonElementsObjectSsoS4 cannot be null");
+
+ jsonElementsStringTempS4 = jsonElementsObjectSsoS4.get(SsoJsonElements.getJsonElementsSso().get(0)).toString();
+ GetGeneralValues idS4 = checkNullGeneralValues(gson.fromJson(jsonElementsStringTempS4, GetGeneralValues.class));
+
+ if (idS4.getVal().equals(ssoS4IdCheck)) {
+ // id
+ jsonElementsStringTempS4 = jsonElementsObjectSsoS4.get(SsoJsonElements.getJsonElementsSso().get(0))
+ .toString();
+ idS4 = checkNullGeneralValues(gson.fromJson(jsonElementsStringTempS4, GetGeneralValues.class));
+ ssoS4ChannelPostsValue[0] = idS4.getVal();
+
+ // upv
+ jsonElementsStringTempS4 = jsonElementsObjectSsoS4.get(SsoJsonElements.getJsonElementsSso().get(1))
+ .toString();
+ GetGeneralValues upvS4 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS4, GetGeneralValues.class));
+ ssoS4ChannelPostsValue[1] = upvS4.getVal();
+
+ // ipv
+ jsonElementsStringTempS4 = jsonElementsObjectSsoS4.get(SsoJsonElements.getJsonElementsSso().get(2))
+ .toString();
+ GetGeneralValues ipvS4 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS4, GetGeneralValues.class));
+ ssoS4ChannelPostsValue[2] = ipvS4.getVal();
+
+ // wpv
+ jsonElementsStringTempS4 = jsonElementsObjectSsoS4.get(SsoJsonElements.getJsonElementsSso().get(3))
+ .toString();
+ GetGeneralValues wpvS4 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS4, GetGeneralValues.class));
+ ssoS4ChannelPostsValue[3] = mJTokWh(jsonStripOneLiners(wpvS4.getVal()));
+
+ // relaystatus
+ jsonElementsStringTempS4 = jsonElementsObjectSsoS4.get(SsoJsonElements.getJsonElementsSso().get(4))
+ .toString();
+ GetGeneralValues relaystatusS4 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS4, GetGeneralValues.class));
+ ssoS4ChannelPostsValue[4] = relaystatusS4.getVal();
+
+ // temp
+ jsonElementsStringTempS4 = jsonElementsObjectSsoS4.get(SsoJsonElements.getJsonElementsSso().get(5))
+ .toString();
+ GetGeneralValues tempS4 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS4, GetGeneralValues.class));
+ ssoS4ChannelPostsValue[5] = tempS4.getVal();
+
+ // faultcode
+ jsonElementsStringTempS4 = jsonElementsObjectSsoS4.get(SsoJsonElements.getJsonElementsSso().get(6))
+ .toString();
+ GetGeneralValues faultcode = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS4, GetGeneralValues.class));
+ ssoS4ChannelPostsValue[6] = faultcode.getVal();
+
+ // udc
+ jsonElementsStringTempS4 = jsonElementsObjectSsoS4.get(SsoJsonElements.getJsonElementsSso().get(7))
+ .toString();
+ GetGeneralValues udcS4 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS4, GetGeneralValues.class));
+ ssoS4ChannelPostsValue[7] = udcS4.getVal();
+
+ // ts
+ jsonElementsStringTempS4 = jsonElementsObjectSsoS4.get(SsoJsonElements.getJsonElementsSso().get(8))
+ .toString();
+ GetGeneralValues tsS4 = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTempS4, GetGeneralValues.class));
+ ssoS4ChannelPostsValue[8] = tsS4.getVal();
+
+ ssoS4ChannelsUpdateValues = ssoS4ChannelPostsValue;
+ }
+ }
+
+ // Prepare actual Json-topic Eso-message and update values for channels
+ void processIncomingJsonMessageEso(String topic, String messageJsonEso) {
+ String[] esoChannelPostsValue = new String[11]; // Array for ESO, Energy Storage Optimizer ) Posts
+ JsonObject jsonElementsObjectEso = new Gson().fromJson(new Gson().fromJson(messageJsonEso, JsonObject.class),
+ JsonObject.class);
+
+ Objects.requireNonNull(jsonElementsObjectEso, "JsonObject jsonElementsObjectEso cannot be null");
+
+ String jsonElementsStringTemp = "";
+ Gson gson = new Gson();
+
+ if (!jsonElementsObjectEso.isEmpty()) {
+ // id
+ jsonElementsStringTemp = jsonElementsObjectEso.get(EsoJsonElements.getJsonElementsEso().get(0)).toString();
+ GetGeneralValues id = checkNullGeneralValues(gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+ esoChannelPostsValue[0] = id.getVal();
+
+ // ubat
+ jsonElementsStringTemp = jsonElementsObjectEso.get(EsoJsonElements.getJsonElementsEso().get(1)).toString();
+ GetGeneralValues ubat = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+ esoChannelPostsValue[1] = ubat.getVal();
+
+ // ibat
+ jsonElementsStringTemp = jsonElementsObjectEso.get(EsoJsonElements.getJsonElementsEso().get(2)).toString();
+ GetGeneralValues ibat = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+ esoChannelPostsValue[2] = ibat.getVal();
+
+ // wbatprod
+ jsonElementsStringTemp = jsonElementsObjectEso.get(EsoJsonElements.getJsonElementsEso().get(3)).toString();
+ GetGeneralValues wbatprod = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+ esoChannelPostsValue[3] = mJTokWh(jsonStripOneLiners(wbatprod.getVal()));
+
+ // wbatcons
+ jsonElementsStringTemp = jsonElementsObjectEso.get(EsoJsonElements.getJsonElementsEso().get(4)).toString();
+ GetGeneralValues wbatcons = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+ esoChannelPostsValue[4] = mJTokWh(jsonStripOneLiners(wbatcons.getVal()));
+
+ // soc
+ jsonElementsStringTemp = jsonElementsObjectEso.get(EsoJsonElements.getJsonElementsEso().get(5)).toString();
+ GetGeneralValues soc = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+ esoChannelPostsValue[5] = soc.getVal();
+
+ // relaystatus
+ jsonElementsStringTemp = jsonElementsObjectEso.get(EsoJsonElements.getJsonElementsEso().get(6)).toString();
+ GetGeneralValues relaystatus = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+ esoChannelPostsValue[6] = relaystatus.getVal();
+
+ // temp
+ jsonElementsStringTemp = jsonElementsObjectEso.get(EsoJsonElements.getJsonElementsEso().get(7)).toString();
+ GetGeneralValues temp = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+ esoChannelPostsValue[7] = temp.getVal();
+
+ // faultcode
+ jsonElementsStringTemp = jsonElementsObjectEso.get(EsoJsonElements.getJsonElementsEso().get(8)).toString();
+ GetGeneralValues faultcode = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+ esoChannelPostsValue[8] = faultcode.getVal();
+
+ // udc
+ jsonElementsStringTemp = jsonElementsObjectEso.get(EsoJsonElements.getJsonElementsEso().get(9)).toString();
+ GetGeneralValues udc = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+ esoChannelPostsValue[9] = udc.getVal();
+
+ // ts
+ jsonElementsStringTemp = jsonElementsObjectEso.get(EsoJsonElements.getJsonElementsEso().get(10)).toString();
+ GetGeneralValues ts = checkNullGeneralValues(gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+ esoChannelPostsValue[10] = ts.getVal();
+
+ esoChannelsUpdateValues = esoChannelPostsValue;
+ } else {
+ return;
+ }
+ }
+
+ // Prepare actual Json-topic Esm-message and update values for channels
+ void processIncomingJsonMessageEsm(String topic, String messageJsonEsm) {
+ String[] esmChannelPostsValue = new String[7]; // Array for ESM, Energy Storage Module ) Posts
+ JsonObject jsonElementsObjectEsm = new Gson().fromJson(new Gson().fromJson(messageJsonEsm, JsonObject.class),
+ JsonObject.class);
+
+ Objects.requireNonNull(jsonElementsObjectEsm, "JsonObject jsonElementsObjectEsm cannot be null");
+
+ String jsonElementsStringTemp = "";
+ Gson gson = new Gson();
+
+ if (!jsonElementsObjectEsm.isEmpty()) {
+ // id
+ jsonElementsStringTemp = jsonElementsObjectEsm.get(EsmJsonElements.getJsonElementsEsm().get(0)).toString();
+ GetGeneralValues id = checkNullGeneralValues(gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+ esmChannelPostsValue[0] = id.getVal();
+
+ // soh
+ jsonElementsStringTemp = jsonElementsObjectEsm.get(EsmJsonElements.getJsonElementsEsm().get(1)).toString();
+ GetGeneralValues soh = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+ esmChannelPostsValue[1] = soh.getVal();
+
+ // soc
+ jsonElementsStringTemp = jsonElementsObjectEsm.get(EsmJsonElements.getJsonElementsEsm().get(2)).toString();
+ GetGeneralValues soc = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+ esmChannelPostsValue[2] = soc.getVal();
+
+ // ratedcapacity
+ jsonElementsStringTemp = jsonElementsObjectEsm.get(EsmJsonElements.getJsonElementsEsm().get(3)).toString();
+ GetGeneralValues ratedcapacity = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+ esmChannelPostsValue[3] = ratedcapacity.getVal();
+
+ // ratedpower
+ jsonElementsStringTemp = jsonElementsObjectEsm.get(EsmJsonElements.getJsonElementsEsm().get(4)).toString();
+ GetGeneralValues ratedpower = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+ esmChannelPostsValue[4] = ratedpower.getVal();
+
+ // status
+ jsonElementsStringTemp = jsonElementsObjectEsm.get(EsmJsonElements.getJsonElementsEsm().get(5)).toString();
+ GetGeneralValues status = checkNullGeneralValues(
+ gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+ esmChannelPostsValue[5] = status.getVal();
+
+ // ts
+ jsonElementsStringTemp = jsonElementsObjectEsm.get(EsmJsonElements.getJsonElementsEsm().get(6)).toString();
+ GetGeneralValues ts = checkNullGeneralValues(gson.fromJson(jsonElementsStringTemp, GetGeneralValues.class));
+ esmChannelPostsValue[6] = ts.getVal();
+
+ esmChannelsUpdateValues = esmChannelPostsValue;
+ } else {
+ return;
+ }
+ }
+
+ public @Nullable static String[] getEhubChannelUpdateValues() {
+ try {
+ return ehubChannelsUpdateValues;
+ } catch (Exception e) {
+ logger.debug("Failed at update of Ehub channel values");
+ }
+ return ehubChannelsUpdateValues;
+ }
+
+ public @Nullable static String[] getSsoS1ChannelUpdateValues() {
+ try {
+ return ssoS1ChannelsUpdateValues;
+ } catch (Exception e) {
+ logger.debug("Failed at update of SsoS1 channel values");
+ }
+ return ssoS1ChannelsUpdateValues;
+ }
+
+ public @Nullable static String[] getSsoS2ChannelUpdateValues() {
+ try {
+ return ssoS2ChannelsUpdateValues;
+ } catch (Exception e) {
+ logger.debug("Failed at update of SsoS2 channel values");
+ }
+ return ssoS2ChannelsUpdateValues;
+ }
+
+ public @Nullable static String[] getSsoS3ChannelUpdateValues() {
+ try {
+ return ssoS3ChannelsUpdateValues;
+ } catch (Exception e) {
+ logger.debug("Failed at update of SsoS3 channel values");
+ }
+ return ssoS3ChannelsUpdateValues;
+ }
+
+ public @Nullable static String[] getSsoS4ChannelUpdateValues() {
+ try {
+ return ssoS4ChannelsUpdateValues;
+ } catch (Exception e) {
+ logger.debug("Failed at update of SsoS4 channel values");
+ }
+ return ssoS4ChannelsUpdateValues;
+ }
+
+ public @Nullable static String[] getEsoChannelUpdateValues() {
+ try {
+ return esoChannelsUpdateValues;
+ } catch (Exception e) {
+ logger.debug("Failed at update of Eso channel values");
+ }
+ return esoChannelsUpdateValues;
+ }
+
+ public @Nullable static String[] getEsmChannelUpdateValues() {
+ try {
+ return esmChannelsUpdateValues;
+ } catch (Exception e) {
+ logger.debug("Failed at update of Esm channel values");
+ }
+ return esmChannelsUpdateValues;
+ }
+
+ public String jsonStripEhub(String jsonStringEhub) {
+ return jsonStringEhub.replaceAll("\"", "");
+ }
+
+ public String jsonStripOneLiners(String jsonStringOneLiners) {
+ return jsonStringOneLiners.replace("{", "").replace("\"", "").replace("val", "").replace(":", "").replace("}",
+ "");
+ }
+
+ public String mJTokWh(String actualmJ) {
+ Double actualkWhD = (Double.parseDouble(actualmJ) / 3600000000.0);
+ return actualkWhD.toString();
+ }
+
+ public GetGeneralValues checkNullGeneralValues(GetGeneralValues checkGeneralValues) {
+ Objects.requireNonNull(checkGeneralValues, "GeneralValues cannot be null, " + checkGeneralValues.getName());
+ return checkGeneralValues;
+ }
+
+ public GetGeneralLx checkNullGeneralLx(GetGeneralLx checkGeneralLx) {
+ Objects.requireNonNull(checkGeneralLx, "GeneralLx cannot be null, " + checkGeneralLx.getL1() + ", "
+ + checkGeneralLx.getL2() + ", " + checkGeneralLx.getL3());
+ return checkGeneralLx;
+ }
+
+ public GetUdc checkNullUdc(GetUdc checkUdc) {
+ Objects.requireNonNull(checkUdc, "Udc cannot be null, " + checkUdc.getNeg() + ", " + checkUdc.getPos());
+ return checkUdc;
+ }
+}
diff --git a/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/SsoJsonElements.java b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/SsoJsonElements.java
new file mode 100644
index 0000000000000..4c0365bf0a5aa
--- /dev/null
+++ b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/SsoJsonElements.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.ferroamp.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * The {@link EhubParameters1} is responsible for all parameters regarded to EHUB
+ *
+ * @author Örjan Backsell - Initial contribution
+ *
+ */
+
+@NonNullByDefault
+public class SsoJsonElements {
+ public String ssoJsonElements;
+
+ public SsoJsonElements(String ssoJsonElements) {
+ this.ssoJsonElements = ssoJsonElements;
+ }
+
+ public static List getJsonElementsSso() {
+ final List jsonElementsSso = new ArrayList<>();
+ jsonElementsSso.add(new String("id"));
+ jsonElementsSso.add(new String("upv"));
+ jsonElementsSso.add(new String("ipv"));
+ jsonElementsSso.add(new String("wpv"));
+ jsonElementsSso.add(new String("relaystatus"));
+ jsonElementsSso.add(new String("temp"));
+ jsonElementsSso.add(new String("faultcode"));
+ jsonElementsSso.add(new String("udc"));
+ jsonElementsSso.add(new String("ts"));
+
+ return jsonElementsSso;
+ }
+}
diff --git a/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/SsoParameters.java b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/SsoParameters.java
new file mode 100644
index 0000000000000..776402fd43fb3
--- /dev/null
+++ b/bundles/org.openhab.binding.ferroamp/src/main/java/org/openhab/binding/ferroamp/internal/SsoParameters.java
@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+
+package org.openhab.binding.ferroamp.internal;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * The {@link SsoParameters} is responsible for all parameters regarded to SSO
+ *
+ * @author Örjan Backsell - Initial contribution
+ *
+ */
+
+@NonNullByDefault
+public class SsoParameters {
+
+ public static List getChannelParametersSso() {
+ final List channelParametersSs0 = Arrays.asList("id", "pv-voltage", "pv-current", "total-solar-energy",
+ "relay-status", "temperature", "fault-code", "dc-link-voltage", "timestamp");
+ return channelParametersSs0;
+ }
+}
diff --git a/bundles/org.openhab.binding.ferroamp/src/main/resources/OH-INF/addon/addon.xml b/bundles/org.openhab.binding.ferroamp/src/main/resources/OH-INF/addon/addon.xml
new file mode 100644
index 0000000000000..2c3f658531346
--- /dev/null
+++ b/bundles/org.openhab.binding.ferroamp/src/main/resources/OH-INF/addon/addon.xml
@@ -0,0 +1,11 @@
+
+
+
+ binding
+ Ferroamp Binding
+ This is the binding for Ferroamp EnergyHub.
+ local
+
+
diff --git a/bundles/org.openhab.binding.ferroamp/src/main/resources/OH-INF/i18n/ferroamp.properties b/bundles/org.openhab.binding.ferroamp/src/main/resources/OH-INF/i18n/ferroamp.properties
new file mode 100644
index 0000000000000..006cdbf9eba97
--- /dev/null
+++ b/bundles/org.openhab.binding.ferroamp/src/main/resources/OH-INF/i18n/ferroamp.properties
@@ -0,0 +1,178 @@
+# add-on
+
+addon.ferroamp.name = Ferroamp Binding
+addon.ferroamp.description = This is the binding for Ferroamp EnergyHub.
+
+# thing types
+
+thing-type.ferroamp.energyhub.label = EnergyHub
+thing-type.ferroamp.energyhub.description = Provides information from Ferroamp EnergyHub
+thing-type.ferroamp.energyhub.channel.ace-current-l1.label = ACE Current L1
+thing-type.ferroamp.energyhub.channel.ace-current-l2.label = ACE Current L2
+thing-type.ferroamp.energyhub.channel.ace-current-l3.label = ACE Current L3
+thing-type.ferroamp.energyhub.channel.apparent-power.label = Apparent Power
+thing-type.ferroamp.energyhub.channel.battery-energy-consumed.label = Battery Energy Consumed
+thing-type.ferroamp.energyhub.channel.battery-energy-produced.label = Battery Energy Produced
+thing-type.ferroamp.energyhub.channel.consumption-power-l1.label = Consumption Power L1
+thing-type.ferroamp.energyhub.channel.consumption-power-l2.label = Consumption Power L2
+thing-type.ferroamp.energyhub.channel.consumption-power-l3.label = Consumption Power L3
+thing-type.ferroamp.energyhub.channel.consumption-power-reactive-l1.label = Consumption Power Reactive L1
+thing-type.ferroamp.energyhub.channel.consumption-power-reactive-l2.label = Consumption Power Reactive L2
+thing-type.ferroamp.energyhub.channel.consumption-power-reactive-l3.label = Consumption Power Reactive L3
+thing-type.ferroamp.energyhub.channel.esm-id.label = Esm Unique Identifier
+thing-type.ferroamp.energyhub.channel.esm-power-battery.label = Esm Rated Power of Battery
+thing-type.ferroamp.energyhub.channel.esm-soc.label = Esm System State of Charge
+thing-type.ferroamp.energyhub.channel.esm-soh.label = Esm System State of Health
+thing-type.ferroamp.energyhub.channel.esm-status.label = Esm Status
+thing-type.ferroamp.energyhub.channel.esm-timestamp.label = Esm Time Stamp When Message was Published
+thing-type.ferroamp.energyhub.channel.esm-total-capacity.label = Esm Rated Capacity
+thing-type.ferroamp.energyhub.channel.eso-battery-energy-consumed.label = Eso Battery Energy Consumed
+thing-type.ferroamp.energyhub.channel.eso-battery-energy-produced.label = Eso Battery Energy Produced
+thing-type.ferroamp.energyhub.channel.eso-current-battery.label = Eso Current on Battery Side
+thing-type.ferroamp.energyhub.channel.eso-dc-link-voltage.label = Eso DC Link Voltage
+thing-type.ferroamp.energyhub.channel.eso-fault-code.label = Eso FaultCode
+thing-type.ferroamp.energyhub.channel.eso-id.label = Eso Unique Identifier
+thing-type.ferroamp.energyhub.channel.eso-relay-status.label = Eso RelayStatus
+thing-type.ferroamp.energyhub.channel.eso-soc.label = Eso State of Charge
+thing-type.ferroamp.energyhub.channel.eso-temperature.label = ESO Temperature on PCB
+thing-type.ferroamp.energyhub.channel.eso-timestamp.label = Eso Time Stamp When Message was Published
+thing-type.ferroamp.energyhub.channel.eso-voltage-battery.label = Eso Voltage on Battery Side
+thing-type.ferroamp.energyhub.channel.grid-active-current-l1.label = Grid Active Current L1
+thing-type.ferroamp.energyhub.channel.grid-active-current-l2.label = Grid Active Current L2
+thing-type.ferroamp.energyhub.channel.grid-active-current-l3.label = Grid Active Current L3
+thing-type.ferroamp.energyhub.channel.grid-current-l1.label = Grid Current L1
+thing-type.ferroamp.energyhub.channel.grid-current-l2.label = Grid Current L2
+thing-type.ferroamp.energyhub.channel.grid-current-l3.label = Grid Current L3
+thing-type.ferroamp.energyhub.channel.grid-energy-consumed-l1.label = Grid Energy Consumed L1
+thing-type.ferroamp.energyhub.channel.grid-energy-consumed-l2.label = Grid Energy Consumed L2
+thing-type.ferroamp.energyhub.channel.grid-energy-consumed-l3.label = Grid Energy Consumed L3
+thing-type.ferroamp.energyhub.channel.grid-energy-consumed-total.label = Grid Energy Consumed Total
+thing-type.ferroamp.energyhub.channel.grid-energy-produced-l1.label = Grid Energy Produced L1
+thing-type.ferroamp.energyhub.channel.grid-energy-produced-l2.label = Grid Energy Produced L2
+thing-type.ferroamp.energyhub.channel.grid-energy-produced-l3.label = Grid Energy Produced L3
+thing-type.ferroamp.energyhub.channel.grid-energy-produced-total.label = Grid Energy Produced Total
+thing-type.ferroamp.energyhub.channel.grid-frequency.label = Grid Frequency
+thing-type.ferroamp.energyhub.channel.grid-power-active-l1.label = Grid Power Active L1
+thing-type.ferroamp.energyhub.channel.grid-power-active-l2.label = Grid Power Active L2
+thing-type.ferroamp.energyhub.channel.grid-power-active-l3.label = Grid Power Active L3
+thing-type.ferroamp.energyhub.channel.grid-power-reactive-l1.label = Grid Power Reactive L1
+thing-type.ferroamp.energyhub.channel.grid-power-reactive-l2.label = Grid Power Reactive L2
+thing-type.ferroamp.energyhub.channel.grid-power-reactive-l3.label = Grid Power Reactive L3
+thing-type.ferroamp.energyhub.channel.grid-reactive-current-l1.label = Grid Reactive Current L1
+thing-type.ferroamp.energyhub.channel.grid-reactive-current-l2.label = Grid Reactive Current L2
+thing-type.ferroamp.energyhub.channel.grid-reactive-current-l3.label = Grid Reactive Current L3
+thing-type.ferroamp.energyhub.channel.grid-voltage-l1.label = Grid Voltage L1
+thing-type.ferroamp.energyhub.channel.grid-voltage-l2.label = Grid Voltage L2
+thing-type.ferroamp.energyhub.channel.grid-voltage-l3.label = Grid Voltage L3
+thing-type.ferroamp.energyhub.channel.inverter-active-current-l1.label = Inverter Active Current L1
+thing-type.ferroamp.energyhub.channel.inverter-active-current-l2.label = Inverter Active Current L2
+thing-type.ferroamp.energyhub.channel.inverter-active-current-l3.label = Inverter Active Current L3
+thing-type.ferroamp.energyhub.channel.inverter-energy-consumed-l1.label = Inverter Energy Consumed L1
+thing-type.ferroamp.energyhub.channel.inverter-energy-consumed-l2.label = Inverter Energy Consumed L2
+thing-type.ferroamp.energyhub.channel.inverter-energy-consumed-l3.label = Inverter Energy Consumed L3
+thing-type.ferroamp.energyhub.channel.inverter-energy-consumed-total.label = Inverter Energy Consumed Total
+thing-type.ferroamp.energyhub.channel.inverter-energy-produced-l1.label = Inverter Energy Produced L1
+thing-type.ferroamp.energyhub.channel.inverter-energy-produced-l2.label = Inverter Energy Produced L2
+thing-type.ferroamp.energyhub.channel.inverter-energy-produced-l3.label = Inverter Energy Produced L3
+thing-type.ferroamp.energyhub.channel.inverter-energy-produced-total.label = Inverter Energy Produced Total
+thing-type.ferroamp.energyhub.channel.inverter-load-active-current-l1.label = Inverter Load Active Current L1
+thing-type.ferroamp.energyhub.channel.inverter-load-active-current-l2.label = Inverter Load Active Current L2
+thing-type.ferroamp.energyhub.channel.inverter-load-active-current-l3.label = Inverter Load Active Current L3
+thing-type.ferroamp.energyhub.channel.inverter-load-reactive-current-l1.label = Inverter Load Reactive Current L1
+thing-type.ferroamp.energyhub.channel.inverter-load-reactive-current-l2.label = Inverter Load Reactive Current L2
+thing-type.ferroamp.energyhub.channel.inverter-load-reactive-current-l3.label = Inverter Load Reactive Current L3
+thing-type.ferroamp.energyhub.channel.inverter-power-active-l1.label = Inverter Power Active L1
+thing-type.ferroamp.energyhub.channel.inverter-power-active-l2.label = Inverter Power Active L2
+thing-type.ferroamp.energyhub.channel.inverter-power-active-l3.label = Inverter Power Active L3
+thing-type.ferroamp.energyhub.channel.inverter-power-reactive-l1.label = Inverter Power Reactive L1
+thing-type.ferroamp.energyhub.channel.inverter-power-reactive-l2.label = Inverter Power Reactive L2
+thing-type.ferroamp.energyhub.channel.inverter-power-reactive-l3.label = Inverter Power Reactive L3
+thing-type.ferroamp.energyhub.channel.inverter-reactive-current-l1.label = Inverter Reactive Current L1
+thing-type.ferroamp.energyhub.channel.inverter-reactive-current-l2.label = Inverter Reactive Current L2
+thing-type.ferroamp.energyhub.channel.inverter-reactive-current-l3.label = Inverter Reactive Current L3
+thing-type.ferroamp.energyhub.channel.inverter-rms-current-l1.label = Inverter RMS Current L1
+thing-type.ferroamp.energyhub.channel.inverter-rms-current-l2.label = Inverter RMS Current L2
+thing-type.ferroamp.energyhub.channel.inverter-rms-current-l3.label = Inverter RMS Current L3
+thing-type.ferroamp.energyhub.channel.load-energy-consumed-l1.label = Load Energy Consumed L1
+thing-type.ferroamp.energyhub.channel.load-energy-consumed-l2.label = Load Energy Consumed L2
+thing-type.ferroamp.energyhub.channel.load-energy-consumed-l3.label = Load Energy Consumed L3
+thing-type.ferroamp.energyhub.channel.load-energy-consumed-total.label = Load Energy Consumed Total
+thing-type.ferroamp.energyhub.channel.load-energy-produced-l1.label = Load Energy Produced L1
+thing-type.ferroamp.energyhub.channel.load-energy-produced-l2.label = Load Energy Produced L2
+thing-type.ferroamp.energyhub.channel.load-energy-produced-l3.label = Load Energy Produced L3
+thing-type.ferroamp.energyhub.channel.load-energy-produced-total.label = Load Energy Produced Total
+thing-type.ferroamp.energyhub.channel.negative-dc-link-voltage.label = Negative DC Link Voltage
+thing-type.ferroamp.energyhub.channel.positive-dc-link-voltage.label = Positive DC Link Voltage
+thing-type.ferroamp.energyhub.channel.power-battery.label = Battery Power
+thing-type.ferroamp.energyhub.channel.request-auto.label = RequestAuto
+thing-type.ferroamp.energyhub.channel.request-charge.label = RequestCharge
+thing-type.ferroamp.energyhub.channel.request-discharge.label = RequestDischarge
+thing-type.ferroamp.energyhub.channel.s1-dc-link-voltage.label = S1 DC Link Voltage
+thing-type.ferroamp.energyhub.channel.s1-fault-code.label = S1 FaultCode
+thing-type.ferroamp.energyhub.channel.s1-id.label = S1 ID
+thing-type.ferroamp.energyhub.channel.s1-pv-current.label = S1 Current on PV String Side
+thing-type.ferroamp.energyhub.channel.s1-pv-voltage.label = S1 Voltage on PV String Side
+thing-type.ferroamp.energyhub.channel.s1-relay-status.label = S1 RelayStatus
+thing-type.ferroamp.energyhub.channel.s1-temperature.label = S1 Temperature on PCB
+thing-type.ferroamp.energyhub.channel.s1-timestamp.label = S1 Time Stamp When Message was Published
+thing-type.ferroamp.energyhub.channel.s1-total-solar-energy.label = S1 Total Solar Energy
+thing-type.ferroamp.energyhub.channel.s2-dc-link-voltage.label = S2 DC Link Voltage
+thing-type.ferroamp.energyhub.channel.s2-fault-code.label = S2 FaultCode
+thing-type.ferroamp.energyhub.channel.s2-id.label = S2 ID
+thing-type.ferroamp.energyhub.channel.s2-pv-current.label = S2 Current on PV String Side
+thing-type.ferroamp.energyhub.channel.s2-pv-voltage.label = S2 Voltage on PV String Side
+thing-type.ferroamp.energyhub.channel.s2-relay-status.label = S2 RelayStatus
+thing-type.ferroamp.energyhub.channel.s2-temperature.label = S2 Temperature on PCB
+thing-type.ferroamp.energyhub.channel.s2-timestamp.label = S2 Time Stamp When Message was Published
+thing-type.ferroamp.energyhub.channel.s2-total-solar-energy.label = S2 Total Solar Energy
+thing-type.ferroamp.energyhub.channel.s3-dc-link-voltage.label = S3 DC Link Voltage
+thing-type.ferroamp.energyhub.channel.s3-fault-code.label = S3 FaultCode
+thing-type.ferroamp.energyhub.channel.s3-id.label = S3 ID
+thing-type.ferroamp.energyhub.channel.s3-pv-current.label = S3 Current on PV String Side
+thing-type.ferroamp.energyhub.channel.s3-pv-voltage.label = S3 Voltage on PV String Side
+thing-type.ferroamp.energyhub.channel.s3-relay-status.label = S3 RelayStatus
+thing-type.ferroamp.energyhub.channel.s3-temperature.label = S3 Temperature on PCB
+thing-type.ferroamp.energyhub.channel.s3-timestamp.label = S3 Time Stamp When Message was Published
+thing-type.ferroamp.energyhub.channel.s3-total-solar-energy.label = S3 Total Solar Energy
+thing-type.ferroamp.energyhub.channel.s4-dc-link-voltage.label = S4 DC Link Voltage
+thing-type.ferroamp.energyhub.channel.s4-fault-code.label = S4 FaultCode
+thing-type.ferroamp.energyhub.channel.s4-id.label = S4 ID
+thing-type.ferroamp.energyhub.channel.s4-pv-current.label = S4 Current on PV String Side
+thing-type.ferroamp.energyhub.channel.s4-pv-voltage.label = S4 Voltage on PV String Side
+thing-type.ferroamp.energyhub.channel.s4-relay-status.label = S4 RelayStatus
+thing-type.ferroamp.energyhub.channel.s4-temperature.label = S4 Temperature on PCB
+thing-type.ferroamp.energyhub.channel.s4-timestamp.label = S4 Time Stamp When Message was Published
+thing-type.ferroamp.energyhub.channel.s4-total-solar-energy.label = S4 Total Solar Energy
+thing-type.ferroamp.energyhub.channel.soc.label = System State of Charge
+thing-type.ferroamp.energyhub.channel.soh.label = System State of Health
+thing-type.ferroamp.energyhub.channel.solar-pv.label = Solar Power
+thing-type.ferroamp.energyhub.channel.state.label = State of the System
+thing-type.ferroamp.energyhub.channel.timestamp.label = Time Stamp When Message was Published
+thing-type.ferroamp.energyhub.channel.total-capacity-batteries.label = Total Rated Capacity of All Batteries
+thing-type.ferroamp.energyhub.channel.total-solar-energy.label = Total Solar Energy
+
+# thing types config
+
+thing-type.config.ferroamp.energyhub.hasBattery.label = Battery Available
+thing-type.config.ferroamp.energyhub.hasBattery.description = Has the system a battery connected?
+thing-type.config.ferroamp.energyhub.hostName.label = Hostname
+thing-type.config.ferroamp.energyhub.hostName.description = Hostname or IP address of the device
+thing-type.config.ferroamp.energyhub.password.label = Password
+thing-type.config.ferroamp.energyhub.password.description = Password to access the device
+thing-type.config.ferroamp.energyhub.userName.label = Username
+thing-type.config.ferroamp.energyhub.userName.description = Username to access the device
+
+# channel types
+
+channel-type.ferroamp.date-time.label = Date Time
+channel-type.ferroamp.date-time.state.pattern = %1$tc
+channel-type.ferroamp.electric-current.label = Electric Current
+channel-type.ferroamp.electric-potential.label = Electrical Potential
+channel-type.ferroamp.energy.label = Energy
+channel-type.ferroamp.frequency.label = Frequency
+channel-type.ferroamp.percentage.label = Percentage
+channel-type.ferroamp.power.label = Power
+channel-type.ferroamp.request.label = String
+channel-type.ferroamp.request.description = Used for control of system
+channel-type.ferroamp.string.label = String
+channel-type.ferroamp.temperature.label = Temperature
diff --git a/bundles/org.openhab.binding.ferroamp/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.ferroamp/src/main/resources/OH-INF/thing/thing-types.xml
new file mode 100644
index 0000000000000..9b72e538add65
--- /dev/null
+++ b/bundles/org.openhab.binding.ferroamp/src/main/resources/OH-INF/thing/thing-types.xml
@@ -0,0 +1,538 @@
+
+
+
+
+
+ Provides information from Ferroamp EnergyHub
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ network-address
+
+ Hostname or IP address of the device
+
+
+ username
+
+ Username to access the device
+
+
+ password
+
+ Password to access the device
+
+
+
+ Has the system a battery connected?
+ false
+
+
+
+
+
+ Number:Energy
+
+ Energy
+
+
+
+
+ Number:ElectricCurrent
+
+ Energy
+
+
+
+
+ Number:Power
+
+ Energy
+
+
+
+
+ DateTime
+
+ Energy
+
+
+
+
+ Number:ElectricPotential
+
+ Energy
+
+
+
+
+ Number:Frequency
+
+ Energy
+
+
+
+
+ Number:Dimensionless
+
+ Energy
+
+
+
+
+ Number:Temperature
+
+ Energy
+
+
+
+
+ String
+
+ Energy
+
+
+
+
+ String
+
+ Used for control of system
+ Energy
+
+
+
+
diff --git a/bundles/pom.xml b/bundles/pom.xml
index f8a7c1b0e3caa..73c4d5e9775ad 100644
--- a/bundles/pom.xml
+++ b/bundles/pom.xml
@@ -1,21 +1,16 @@
-
+
-
4.0.0
-
org.openhab.addons
org.openhab.addons.reactor
4.3.0-SNAPSHOT
-
org.openhab.addons.bundles
org.openhab.addons.reactor.bundles
pom
-
openHAB Add-ons :: Bundles
-
org.openhab.automation.groovyscripting
@@ -147,6 +142,7 @@
org.openhab.binding.feed
org.openhab.binding.feican
org.openhab.binding.fenecon
+ org.openhab.binding.ferroamp
org.openhab.binding.fineoffsetweatherstation
org.openhab.binding.flicbutton
org.openhab.binding.flume
@@ -481,15 +477,11 @@
org.openhab.voice.rustpotterks
org.openhab.voice.voicerss
org.openhab.voice.voskstt
- org.openhab.voice.watsonstt
- org.openhab.voice.whisperstt
-
target/dependency
-
org.lastnpe.eea
@@ -545,7 +537,6 @@
provided
-
@@ -615,7 +606,6 @@
-
biz.aQute.bnd
@@ -681,7 +671,6 @@
-
@@ -707,5 +696,4 @@
-