]> git.basschouten.com Git - openhab-addons.git/commitdiff
[solax] Add support for Solax X3MIC / G2 inverter and workmode channel (#16248)
authorHenrik Tóth <realthk@gmail.com>
Sat, 10 Feb 2024 14:17:43 +0000 (15:17 +0100)
committerGitHub <noreply@github.com>
Sat, 10 Feb 2024 14:17:43 +0000 (15:17 +0100)
* Support for Solax X3MIC / G2 inverter, and workmode channel for the existing X1, X3 also
* Add update instructions and make raise the target version to 1
* Refactor the workmode to be enum instead of string constants

Signed-off-by: Henrik Tóth <realthk@gmail.com>
Signed-off-by: Konstantin Polihronov <polychronov@gmail.com>
Signed-off-by: Leo Siepel <leosiepel@gmail.com>
17 files changed:
bundles/org.openhab.binding.solax/src/main/java/org/openhab/binding/solax/internal/SolaxBindingConstants.java
bundles/org.openhab.binding.solax/src/main/java/org/openhab/binding/solax/internal/SolaxLocalAccessHandler.java
bundles/org.openhab.binding.solax/src/main/java/org/openhab/binding/solax/internal/model/InverterData.java
bundles/org.openhab.binding.solax/src/main/java/org/openhab/binding/solax/internal/model/InverterType.java
bundles/org.openhab.binding.solax/src/main/java/org/openhab/binding/solax/internal/model/impl/X1HybridG4InverterData.java
bundles/org.openhab.binding.solax/src/main/java/org/openhab/binding/solax/internal/model/impl/X3HybridG4InverterData.java
bundles/org.openhab.binding.solax/src/main/java/org/openhab/binding/solax/internal/model/impl/X3MicOrProG2InverterData.java [new file with mode: 0644]
bundles/org.openhab.binding.solax/src/main/java/org/openhab/binding/solax/internal/model/parsers/X1HybridG4DataParser.java
bundles/org.openhab.binding.solax/src/main/java/org/openhab/binding/solax/internal/model/parsers/X3HybridG4DataParser.java
bundles/org.openhab.binding.solax/src/main/java/org/openhab/binding/solax/internal/model/parsers/X3MicOrProG2DataParser.java [new file with mode: 0644]
bundles/org.openhab.binding.solax/src/main/resources/OH-INF/i18n/solax.properties
bundles/org.openhab.binding.solax/src/main/resources/OH-INF/thing/channel_types.xml
bundles/org.openhab.binding.solax/src/main/resources/OH-INF/thing/localConnectInverter.xml
bundles/org.openhab.binding.solax/src/main/resources/OH-INF/update/local_connect_inverter_type_update.xml
bundles/org.openhab.binding.solax/src/test/java/org/openhab/binding/solax/internal/TestX1HybridG4Parser.java
bundles/org.openhab.binding.solax/src/test/java/org/openhab/binding/solax/internal/TestX3HybridG4Parser.java
bundles/org.openhab.binding.solax/src/test/java/org/openhab/binding/solax/internal/TestX3MicOrProG2Parser.java [new file with mode: 0644]

index e04633e377b899a48a3c577bb3387bad1458824f..39d0b3ba6eb67b72ff9fa9a1a7c550c382c2d6c3 100644 (file)
@@ -61,6 +61,9 @@ public class SolaxBindingConstants {
     public static final String CHANNEL_INVERTER_OUTPUT_FREQUENCY_PHASE1 = "inverter-frequency-phase1";
     public static final String CHANNEL_INVERTER_OUTPUT_FREQUENCY_PHASE2 = "inverter-frequency-phase2";
     public static final String CHANNEL_INVERTER_OUTPUT_FREQUENCY_PHASE3 = "inverter-frequency-phase3";
+    public static final String CHANNEL_INVERTER_TEMPERATURE1 = "inverter-temperature1";
+    public static final String CHANNEL_INVERTER_TEMPERATURE2 = "inverter-temperature2";
+    public static final String CHANNEL_INVERTER_WORKMODE = "inverter-workmode";
 
     // Generic
     public static final String CHANNEL_INVERTER_PV1_POWER = "pv1-power";
index 94b418f3651b8e1c40cecbde9c98e016a8f3204f..dd17e7bc27b365ec59820a41ddc6c12fb43a64b9 100644 (file)
@@ -190,12 +190,18 @@ public class SolaxLocalAccessHandler extends BaseThingHandler {
                 supportedChannels);
         updateChannel(SolaxBindingConstants.CHANNEL_BATTERY_TEMPERATURE, inverterData.getBatteryTemperature(),
                 SIUnits.CELSIUS, supportedChannels);
+        updateChannel(SolaxBindingConstants.CHANNEL_INVERTER_TEMPERATURE1, inverterData.getInverterTemperature1(),
+                SIUnits.CELSIUS, supportedChannels);
+        updateChannel(SolaxBindingConstants.CHANNEL_INVERTER_TEMPERATURE2, inverterData.getInverterTemperature2(),
+                SIUnits.CELSIUS, supportedChannels);
         updateChannel(SolaxBindingConstants.CHANNEL_BATTERY_STATE_OF_CHARGE, inverterData.getBatteryLevel(),
                 Units.PERCENT, supportedChannels);
         updateChannel(SolaxBindingConstants.CHANNEL_FEED_IN_POWER, inverterData.getFeedInPower(), Units.WATT,
                 supportedChannels);
         updateChannel(SolaxBindingConstants.CHANNEL_POWER_USAGE, inverterData.getPowerUsage(), Units.WATT,
                 supportedChannels);
+        updateState(SolaxBindingConstants.CHANNEL_INVERTER_WORKMODE,
+                new StringType(inverterData.getInverterWorkMode()));
 
         // Totals
         updateChannel(SolaxBindingConstants.CHANNEL_TOTAL_ENERGY, inverterData.getTotalEnergy(), Units.KILOWATT_HOUR,
index 04c60aed7b4a0b01f6bfdbf8ca5d0518cf31833c..429e3367819320b114280da4c7169dd900cf7936 100644 (file)
@@ -82,6 +82,22 @@ public interface InverterData {
         return Short.MIN_VALUE;
     }
 
+    default short getInverterTemperature1() {
+        return Short.MIN_VALUE;
+    }
+
+    default short getInverterTemperature2() {
+        return Short.MIN_VALUE;
+    }
+
+    default short getInverterWorkModeCode() {
+        return Short.MIN_VALUE;
+    }
+
+    default String getInverterWorkMode() {
+        return String.valueOf(getInverterWorkModeCode());
+    }
+
     default short getBatteryLevel() {
         return Short.MIN_VALUE;
     }
index 072a0e9abbdcc694ac1325193d7eadca18e3224e..9d87543dfe7213de2f1730b9ca9df8d5b3251511 100644 (file)
@@ -21,6 +21,7 @@ import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.solax.internal.model.parsers.RawDataParser;
 import org.openhab.binding.solax.internal.model.parsers.X1HybridG4DataParser;
 import org.openhab.binding.solax.internal.model.parsers.X3HybridG4DataParser;
+import org.openhab.binding.solax.internal.model.parsers.X3MicOrProG2DataParser;
 
 /**
  * The {@link InverterType} class is enum representing the different inverter types with a simple logic to convert from
@@ -46,7 +47,7 @@ public enum InverterType {
     J1_ESS(13),
     X3_HYBRID_G4(14, new X3HybridG4DataParser()),
     X1_HYBRID_G4(15, new X1HybridG4DataParser()),
-    X3_MIC_OR_PRO_G2(16),
+    X3_MIC_OR_PRO_G2(16, new X3MicOrProG2DataParser()),
     X1_SPT(17),
     X1_BOOST_OR_MINI_G4(18),
     A1_HYB_G2(19),
index 238176b047269359b475b60511c7e61ad82f20b5..ead4e05302402742eef893bd355da0a8e4f7d4fb 100644 (file)
@@ -83,6 +83,11 @@ public class X1HybridG4InverterData extends CommonInverterData {
         return getData(9);
     }
 
+    @Override
+    public short getInverterWorkModeCode() {
+        return getData(10);
+    }
+
     @Override
     public double getBatteryVoltage() {
         return ((double) getData(14)) / 100;
index 92f57373f1c1f6ec9e49dfbc50bf2bfb324ae2d9..48ec4b707bd1f558d4ddbe90f3dd34c1dd9496d7 100644 (file)
@@ -125,6 +125,11 @@ public class X3HybridG4InverterData extends CommonInverterData {
         return ((double) getData(18)) / 100;
     }
 
+    @Override
+    public short getInverterWorkModeCode() {
+        return getData(19);
+    }
+
     // Battery
 
     @Override
diff --git a/bundles/org.openhab.binding.solax/src/main/java/org/openhab/binding/solax/internal/model/impl/X3MicOrProG2InverterData.java b/bundles/org.openhab.binding.solax/src/main/java/org/openhab/binding/solax/internal/model/impl/X3MicOrProG2InverterData.java
new file mode 100644 (file)
index 0000000..ddf6fb3
--- /dev/null
@@ -0,0 +1,153 @@
+/**
+ * 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.solax.internal.model.impl;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.solax.internal.connectivity.rawdata.LocalConnectRawDataBean;
+
+/**
+ * The {@link X3HybridG4InverterData} is responsible for handling commands, which are
+ * sent to one of the channels.
+ *
+ * @author Henrik Tóth - Initial contribution
+ *         (based on X1/X3 G4 parser from Konstantin Polihronov)
+ */
+@NonNullByDefault
+public class X3MicOrProG2InverterData extends CommonInverterData {
+
+    public X3MicOrProG2InverterData(LocalConnectRawDataBean data) {
+        super(data);
+    }
+
+    // Inverter data
+
+    @Override
+    public double getVoltagePhase1() {
+        return ((double) getData(0)) / 10;
+    }
+
+    @Override
+    public double getVoltagePhase2() {
+        return ((double) getData(1)) / 10;
+    }
+
+    @Override
+    public double getVoltagePhase3() {
+        return ((double) getData(2)) / 10;
+    }
+
+    @Override
+    public double getCurrentPhase1() {
+        return ((double) getData(3)) / 10;
+    }
+
+    @Override
+    public double getCurrentPhase2() {
+        return ((double) getData(4)) / 10;
+    }
+
+    @Override
+    public double getCurrentPhase3() {
+        return ((double) getData(5)) / 10;
+    }
+
+    @Override
+    public short getOutputPowerPhase1() {
+        return getData(6);
+    }
+
+    @Override
+    public short getOutputPowerPhase2() {
+        return getData(7);
+    }
+
+    @Override
+    public short getOutputPowerPhase3() {
+        return getData(8);
+    }
+
+    @Override
+    public double getPV1Voltage() {
+        return ((double) getData(9)) / 10;
+    }
+
+    @Override
+    public double getPV2Voltage() {
+        return ((double) getData(10)) / 10;
+    }
+
+    @Override
+    public double getPV1Current() {
+        return ((double) getData(12)) / 10;
+    }
+
+    @Override
+    public double getPV2Current() {
+        return ((double) getData(13)) / 10;
+    }
+
+    @Override
+    public short getPV1Power() {
+        return getData(15);
+    }
+
+    @Override
+    public short getPV2Power() {
+        return getData(16);
+    }
+
+    @Override
+    public double getFrequencyPhase1() {
+        return ((double) getData(18)) / 100;
+    }
+
+    @Override
+    public double getFrequencyPhase2() {
+        return ((double) getData(19)) / 100;
+    }
+
+    @Override
+    public double getFrequencyPhase3() {
+        return ((double) getData(20)) / 100;
+    }
+
+    @Override
+    public short getInverterWorkModeCode() {
+        return getData(21);
+    }
+
+    @Override
+    public double getTotalEnergy() {
+        return ((double) getData(22)) / 10;
+    }
+
+    @Override
+    public double getTodayEnergy() {
+        return ((double) getData(24)) / 10;
+    }
+
+    @Override
+    public short getInverterTemperature1() {
+        return getData(26);
+    }
+
+    @Override
+    public short getInverterTemperature2() {
+        return getData(27);
+    }
+
+    @Override
+    public short getTotalOutputPower() {
+        return getData(78);
+    }
+}
index fd68cf15e3289149f6096cf779485dac626abe56..538e937231f6a4b943ab6f0149aedd53ff8fb28b 100644 (file)
@@ -36,7 +36,7 @@ public class X1HybridG4DataParser implements RawDataParser {
             CHANNEL_INVERTER_PV_TOTAL_CURRENT, CHANNEL_BATTERY_POWER, CHANNEL_BATTERY_VOLTAGE, CHANNEL_BATTERY_CURRENT,
             CHANNEL_BATTERY_TEMPERATURE, CHANNEL_BATTERY_STATE_OF_CHARGE, CHANNEL_FEED_IN_POWER, CHANNEL_TIMESTAMP,
             CHANNEL_RAW_DATA, CHANNEL_INVERTER_OUTPUT_POWER, CHANNEL_INVERTER_OUTPUT_CURRENT,
-            CHANNEL_INVERTER_OUTPUT_VOLTAGE, CHANNEL_INVERTER_OUTPUT_FREQUENCY);
+            CHANNEL_INVERTER_OUTPUT_VOLTAGE, CHANNEL_INVERTER_OUTPUT_FREQUENCY, CHANNEL_INVERTER_WORKMODE);
 
     @Override
     public InverterData getData(LocalConnectRawDataBean rawData) {
index 4c814feade27300420e796e1d9105b67d3a0694c..7f0680aa489eaae6fb500c54a4a5c03568967b69 100644 (file)
@@ -44,7 +44,7 @@ public class X3HybridG4DataParser implements RawDataParser {
             CHANNEL_INVERTER_OUTPUT_FREQUENCY_PHASE3, CHANNEL_POWER_USAGE, CHANNEL_TOTAL_ENERGY,
             CHANNEL_TOTAL_BATTERY_CHARGE_ENERGY, CHANNEL_TOTAL_PV_ENERGY, CHANNEL_TOTAL_CONSUMPTION,
             CHANNEL_TODAY_ENERGY, CHANNEL_TODAY_FEED_IN_ENERGY, CHANNEL_TODAY_CONSUMPTION,
-            CHANNEL_TODAY_BATTERY_CHARGE_ENERGY, CHANNEL_TODAY_BATTERY_DISCHARGE_ENERGY);
+            CHANNEL_TODAY_BATTERY_CHARGE_ENERGY, CHANNEL_TODAY_BATTERY_DISCHARGE_ENERGY, CHANNEL_INVERTER_WORKMODE);
 
     @Override
     public InverterData getData(LocalConnectRawDataBean rawData) {
diff --git a/bundles/org.openhab.binding.solax/src/main/java/org/openhab/binding/solax/internal/model/parsers/X3MicOrProG2DataParser.java b/bundles/org.openhab.binding.solax/src/main/java/org/openhab/binding/solax/internal/model/parsers/X3MicOrProG2DataParser.java
new file mode 100644 (file)
index 0000000..6a1660b
--- /dev/null
@@ -0,0 +1,55 @@
+/**
+ * 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.solax.internal.model.parsers;
+
+import static org.openhab.binding.solax.internal.SolaxBindingConstants.*;
+
+import java.util.Set;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.solax.internal.connectivity.rawdata.LocalConnectRawDataBean;
+import org.openhab.binding.solax.internal.model.InverterData;
+import org.openhab.binding.solax.internal.model.impl.X3MicOrProG2InverterData;
+
+/**
+ * The {@link X3MicOrProG2DataParser} is the implementation that parses raw data into a SinglePhaseInverterData for the
+ * X3 Mic / Pro G2 inverter.
+ *
+ * @author Henrik Tóth - Initial contribution
+ *         (based on X1/X3 G4 parser from Konstantin Polihronov)
+ */
+@NonNullByDefault
+public class X3MicOrProG2DataParser implements RawDataParser {
+
+    private static final Set<String> X3_MIC_OR_PRO_G2_SUPPORTED_CHANNELS = Set.of(
+            CHANNEL_INVERTER_OUTPUT_VOLTAGE_PHASE1, CHANNEL_INVERTER_OUTPUT_FREQUENCY_PHASE2,
+            CHANNEL_INVERTER_OUTPUT_VOLTAGE_PHASE3, CHANNEL_INVERTER_OUTPUT_CURRENT_PHASE1,
+            CHANNEL_INVERTER_OUTPUT_CURRENT_PHASE2, CHANNEL_INVERTER_OUTPUT_CURRENT_PHASE3,
+            CHANNEL_INVERTER_OUTPUT_POWER_PHASE1, CHANNEL_INVERTER_OUTPUT_POWER_PHASE2,
+            CHANNEL_INVERTER_OUTPUT_POWER_PHASE3, CHANNEL_INVERTER_PV1_VOLTAGE, CHANNEL_INVERTER_PV2_VOLTAGE,
+            CHANNEL_INVERTER_PV1_CURRENT, CHANNEL_INVERTER_PV2_CURRENT, CHANNEL_INVERTER_PV1_POWER,
+            CHANNEL_INVERTER_PV2_POWER, CHANNEL_INVERTER_OUTPUT_FREQUENCY_PHASE1,
+            CHANNEL_INVERTER_OUTPUT_VOLTAGE_PHASE2, CHANNEL_INVERTER_OUTPUT_FREQUENCY_PHASE3, CHANNEL_TOTAL_ENERGY,
+            CHANNEL_TODAY_ENERGY, CHANNEL_INVERTER_TOTAL_OUTPUT_POWER, CHANNEL_INVERTER_TEMPERATURE1,
+            CHANNEL_INVERTER_TEMPERATURE2, CHANNEL_INVERTER_WORKMODE, CHANNEL_RAW_DATA);
+
+    @Override
+    public InverterData getData(LocalConnectRawDataBean rawData) {
+        return new X3MicOrProG2InverterData(rawData);
+    }
+
+    @Override
+    public Set<String> getSupportedChannels() {
+        return X3_MIC_OR_PRO_G2_SUPPORTED_CHANNELS;
+    }
+}
index 518f83a8399beec3c27b677d9eaa41f17ba45700..7344060f39424d34f8f6ba6032ebc04bcf536dba 100644 (file)
@@ -27,12 +27,12 @@ thing-type.solax.local-connect-inverter.channel.inverter-current-phase2.label =
 thing-type.solax.local-connect-inverter.channel.inverter-current-phase2.description = Current to/from the inverter phase 2
 thing-type.solax.local-connect-inverter.channel.inverter-current-phase3.label = Inverter Input/Output Current Phase 3
 thing-type.solax.local-connect-inverter.channel.inverter-current-phase3.description = Current to/from the inverter phase 3
-thing-type.solax.local-connect-inverter.channel.inverter-frequency-phase1.label = Inverter Voltage Phase 3
-thing-type.solax.local-connect-inverter.channel.inverter-frequency-phase1.description = Voltage of the inverter's phase 3
-thing-type.solax.local-connect-inverter.channel.inverter-frequency-phase2.label = Inverter Voltage Phase 2
-thing-type.solax.local-connect-inverter.channel.inverter-frequency-phase2.description = Voltage of the inverter's phase 3
-thing-type.solax.local-connect-inverter.channel.inverter-frequency-phase3.label = Inverter Voltage Phase 3
-thing-type.solax.local-connect-inverter.channel.inverter-frequency-phase3.description = Voltage of the inverter's phase 3
+thing-type.solax.local-connect-inverter.channel.inverter-frequency-phase1.label = Inverter Frequency Phase 1
+thing-type.solax.local-connect-inverter.channel.inverter-frequency-phase1.description = Frequency of the inverter's phase 1
+thing-type.solax.local-connect-inverter.channel.inverter-frequency-phase2.label = Inverter Frequency Phase 2
+thing-type.solax.local-connect-inverter.channel.inverter-frequency-phase2.description = Frequency of the inverter's phase 2
+thing-type.solax.local-connect-inverter.channel.inverter-frequency-phase3.label = Inverter Frequency Phase 3
+thing-type.solax.local-connect-inverter.channel.inverter-frequency-phase3.description = Frequency of the inverter's phase 3
 thing-type.solax.local-connect-inverter.channel.inverter-output-power.label = Inverter Input/Output Power
 thing-type.solax.local-connect-inverter.channel.inverter-output-power.description = Power to/from the inverter
 thing-type.solax.local-connect-inverter.channel.inverter-output-power-phase1.label = Inverter Input/Output Power Phase 1
@@ -41,6 +41,10 @@ thing-type.solax.local-connect-inverter.channel.inverter-output-power-phase2.lab
 thing-type.solax.local-connect-inverter.channel.inverter-output-power-phase2.description = Power to/from the inverter phase 2
 thing-type.solax.local-connect-inverter.channel.inverter-output-power-phase3.label = Inverter Input/Output Power Phase 3
 thing-type.solax.local-connect-inverter.channel.inverter-output-power-phase3.description = Power to/from the inverter phase 3
+thing-type.solax.local-connect-inverter.channel.inverter-temperature1.label = Inverter Temperature 1
+thing-type.solax.local-connect-inverter.channel.inverter-temperature1.description = Temperature 1 of the inverter
+thing-type.solax.local-connect-inverter.channel.inverter-temperature2.label = Inverter Temperature 2
+thing-type.solax.local-connect-inverter.channel.inverter-temperature2.description = Temperature 2 of the inverter
 thing-type.solax.local-connect-inverter.channel.inverter-total-output-power.label = Inverter Input/Output Total Power
 thing-type.solax.local-connect-inverter.channel.inverter-total-output-power.description = Power to/from the inverter on all phases
 thing-type.solax.local-connect-inverter.channel.inverter-voltage.label = Inverter Voltage
@@ -51,6 +55,8 @@ thing-type.solax.local-connect-inverter.channel.inverter-voltage-phase2.label =
 thing-type.solax.local-connect-inverter.channel.inverter-voltage-phase2.description = Voltage of the inverter's phase 2
 thing-type.solax.local-connect-inverter.channel.inverter-voltage-phase3.label = Inverter Voltage Phase 3
 thing-type.solax.local-connect-inverter.channel.inverter-voltage-phase3.description = Voltage of the inverter's phase 3
+thing-type.solax.local-connect-inverter.channel.inverter-workmode.label = Inverter Workmode
+thing-type.solax.local-connect-inverter.channel.inverter-workmode.description = Inverter Workmode
 thing-type.solax.local-connect-inverter.channel.power-usage.label = Power Usage
 thing-type.solax.local-connect-inverter.channel.power-usage.description = Current power consumption of the building
 thing-type.solax.local-connect-inverter.channel.pv-total-current.label = PV Total Current
@@ -107,6 +113,24 @@ channel-type.solax.battery-temperature.label = Battery Temperature
 channel-type.solax.battery-temperature.description = Battery Temperature
 channel-type.solax.frequency.label = Electric Frequency
 channel-type.solax.frequency.description = Frequency of the electricity to/from the inverter
+channel-type.solax.inverter-temperature.label = Inverter Temperature
+channel-type.solax.inverter-temperature.description = Inverter Temperature
+channel-type.solax.inverter-workmode.label = Inverter Workmode
+channel-type.solax.inverter-workmode.description = Inverter Workmode
+channel-type.solax.inverter-workmode.state.option.0 = Waiting
+channel-type.solax.inverter-workmode.state.option.1 = Checking
+channel-type.solax.inverter-workmode.state.option.2 = Normal
+channel-type.solax.inverter-workmode.state.option.3 = Fault
+channel-type.solax.inverter-workmode.state.option.4 = Permanent Fault
+channel-type.solax.inverter-workmode.state.option.5 = Updating
+channel-type.solax.inverter-workmode.state.option.6 = EPS Check
+channel-type.solax.inverter-workmode.state.option.7 = EPS Normal
+channel-type.solax.inverter-workmode.state.option.8 = Self Test
+channel-type.solax.inverter-workmode.state.option.9 = Idle
+channel-type.solax.inverter-workmode.state.option.10 = Standby
+channel-type.solax.inverter-workmode.state.option.11 = PV Wake-up Battery
+channel-type.solax.inverter-workmode.state.option.12 = GEN Check
+channel-type.solax.inverter-workmode.state.option.13 = GEN Run
 channel-type.solax.last-retrieve-time-stamp.label = Last Retrieve Time Stamp
 channel-type.solax.last-retrieve-time-stamp.description = Last time with a successful retrieval of data
 channel-type.solax.raw-data-type.label = Raw Data
index a1a814436d56e18f3f9960651baf8a0ea145a091..472c9eea76d003bae02a3919840d64573c1ac69e 100644 (file)
                </tags>
                <state pattern="%d %unit%" readOnly="true"/>
        </channel-type>
+       <channel-type id="inverter-temperature">
+               <item-type>Number:Temperature</item-type>
+               <label>Inverter Temperature</label>
+               <description>Inverter Temperature</description>
+               <tags>
+                       <tag>Measurement</tag>
+                       <tag>Temperature</tag>
+               </tags>
+               <state pattern="%d %unit%" readOnly="true"/>
+       </channel-type>
+       <channel-type id="inverter-workmode">
+               <item-type>String</item-type>
+               <label>Inverter Workmode</label>
+               <description>Inverter Workmode</description>
+               <state pattern="%s" readOnly="true">
+                       <options>
+                               <option value="0">Waiting</option>
+                               <option value="1">Checking</option>
+                               <option value="2">Normal</option>
+                               <option value="3">Fault</option>
+                               <option value="4">Permanent Fault</option>
+                               <option value="5">Updating</option>
+                               <option value="6">EPS Check</option>
+                               <option value="7">EPS Normal</option>
+                               <option value="8">Self Test</option>
+                               <option value="9">Idle</option>
+                               <option value="10">Standby</option>
+                               <option value="11">PV Wake-up Battery</option>
+                               <option value="12">GEN Check</option>
+                               <option value="13">GEN Run</option>
+                       </options>
+               </state>
+       </channel-type>
        <channel-type id="last-retrieve-time-stamp">
                <item-type>DateTime</item-type>
                <label>Last Retrieve Time Stamp</label>
index 67e4b20f18ad679c26afe1fb739d94e8de5af595..f3f10681598f2234cc43c9440f4a5b82253f02a4 100644 (file)
                                <description>Voltage of the inverter's phase 3</description>
                        </channel>
                        <channel id="inverter-frequency-phase1" typeId="frequency">
-                               <label>Inverter Voltage Phase 3</label>
-                               <description>Voltage of the inverter's phase 3</description>
+                               <label>Inverter Frequency Phase 1</label>
+                               <description>Frequency of the inverter's phase 1</description>
                        </channel>
                        <channel id="inverter-frequency-phase2" typeId="frequency">
-                               <label>Inverter Voltage Phase 2</label>
-                               <description>Voltage of the inverter's phase 3</description>
+                               <label>Inverter Frequency Phase 2</label>
+                               <description>Frequency of the inverter's phase 2</description>
                        </channel>
                        <channel id="inverter-frequency-phase3" typeId="frequency">
-                               <label>Inverter Voltage Phase 3</label>
-                               <description>Voltage of the inverter's phase 3</description>
+                               <label>Inverter Frequency Phase 3</label>
+                               <description>Frequency of the inverter's phase 3</description>
                        </channel>
 
                        <!-- Generic channels -->
                                <description>The sum of PV currents from all strings</description>
                        </channel>
 
+                       <channel id="inverter-temperature1" typeId="inverter-temperature">
+                               <label>Inverter Temperature 1</label>
+                               <description>Temperature 1 of the inverter</description>
+                       </channel>
+                       <channel id="inverter-temperature2" typeId="inverter-temperature">
+                               <label>Inverter Temperature 2</label>
+                               <description>Temperature 2 of the inverter</description>
+                       </channel>
+                       <channel id="inverter-workmode" typeId="inverter-workmode">
+                               <label>Inverter Workmode</label>
+                               <description>Inverter Workmode</description>
+                       </channel>
+
                        <channel id="battery-power" typeId="system.electric-power">
                                <label>Battery Power</label>
                                <description>Power to/from the battery</description>
                </channels>
 
                <properties>
-                       <property name="thingTypeVersion">1</property>
+                       <property name="thingTypeVersion">2</property>
                </properties>
 
                <config-description>
index 1a1e54416d1fb8680d4f2fca410faad526a19b3e..dc79f7bebfd2c27797557dd55d172be3147af36d 100644 (file)
                                <description>Energy consumed for the day</description>
                        </add-channel>
                </instruction-set>
+
+               <instruction-set targetVersion="2">
+
+                       <add-channel id="inverter-temperature1">
+                               <type>solax:inverter-temperature</type>
+                               <label>Inverter Temperature 1</label>
+                               <description>Temperature 1 of the inverter</description>
+                       </add-channel>
+                       <add-channel id="inverter-temperature2">
+                               <type>solax:inverter-temperature</type>
+                               <label>Inverter Temperature 2</label>
+                               <description>Temperature 2 of the inverter</description>
+                       </add-channel>
+                       <add-channel id="inverter-workmode">
+                               <type>solax:inverter-workmode</type>
+                               <label>Inverter Workmode</label>
+                               <description>Inverter Workmode</description>
+                       </add-channel>
+               </instruction-set>
        </thing-type>
 </update:update-descriptions>
index 08def71318e17ef51c4ce5b0ef11a95e48ce3380..c8c8c3ac97489ffdb22fd076343db5346fa222c8 100644 (file)
@@ -69,6 +69,9 @@ public class TestX1HybridG4Parser {
         assertEquals(487, data.getPV1Power()); // [8]
         assertEquals(65, data.getPV2Power()); // [9]
 
+        assertEquals(2, data.getInverterWorkModeCode()); // [10]
+        assertEquals("2", data.getInverterWorkMode()); // [10]
+
         assertEquals(121.8, data.getBatteryVoltage()); // [14]
         assertEquals(5, data.getBatteryCurrent()); // [15]
         assertEquals(605, data.getBatteryPower()); // [16]
index 7bb4e972c5c2addab2387b59fa4ebe8aed3cc681..8c02197c80f403f1fc4e94cb77a1d2dc5aed15e1 100644 (file)
@@ -89,6 +89,9 @@ public class TestX3HybridG4Parser {
         assertEquals(49.96, data.getFrequencyPhase2()); // [17]
         assertEquals(49.96, data.getFrequencyPhase3()); // [18]
 
+        assertEquals(2, data.getInverterWorkModeCode()); // [19]
+        assertEquals("2", data.getInverterWorkMode()); // [19]
+
         assertEquals(-41, data.getFeedInPower()); // [34] - [35]
 
         assertEquals(313.3, data.getBatteryVoltage()); // [39]
diff --git a/bundles/org.openhab.binding.solax/src/test/java/org/openhab/binding/solax/internal/TestX3MicOrProG2Parser.java b/bundles/org.openhab.binding.solax/src/test/java/org/openhab/binding/solax/internal/TestX3MicOrProG2Parser.java
new file mode 100644 (file)
index 0000000..c3d353d
--- /dev/null
@@ -0,0 +1,97 @@
+/**
+ * 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.solax.internal;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.junit.jupiter.api.Test;
+import org.openhab.binding.solax.internal.connectivity.rawdata.LocalConnectRawDataBean;
+import org.openhab.binding.solax.internal.model.InverterData;
+import org.openhab.binding.solax.internal.model.InverterType;
+import org.openhab.binding.solax.internal.model.parsers.RawDataParser;
+
+/**
+ * The {@link TestX3HybridG4Parser} simple test that tests for proper parsing against a real data from the inverter
+ *
+ * @author Konstantin Polihronov - Initial contribution
+ */
+@NonNullByDefault
+public class TestX3MicOrProG2Parser {
+
+    String rawData = """
+            {
+                sn:XYZ,
+                ver:3.003.02,
+                type:16,Data:[
+                    2515,2449,2484,5,5,9,54,44,20,4080,4340,
+                    0,1,2,0,67,102,0,4999,4999,4999,2,19035,
+                    0,50,8000,5,9,
+                    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+                    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
+                    0,0,0,0,0,0,0,0,120,40,1,6,5,0,6772,0,0,0,
+                    0,0,0,0,0,0,0,0,0,0,0,0
+                    ],
+                Information:[8.000,16,XY,8,1.15,0.00,1.11,1.01,0.00,1]
+             }
+            """;
+
+    @Test
+    public void testParser() {
+        LocalConnectRawDataBean bean = LocalConnectRawDataBean.fromJson(rawData);
+        int type = bean.getType();
+        InverterType inverterType = InverterType.fromIndex(type);
+        assertEquals(InverterType.X3_MIC_OR_PRO_G2, inverterType, "Inverter type not recognized properly");
+
+        RawDataParser parser = inverterType.getParser();
+        assertNotNull(parser);
+
+        InverterData data = parser.getData(bean);
+        assertEquals("XYZ", data.getWifiSerial());
+        assertEquals("3.003.02", data.getWifiVersion());
+
+        assertEquals(251.5, data.getVoltagePhase1()); // [0]
+        assertEquals(244.9, data.getVoltagePhase2()); // [1]
+        assertEquals(248.4, data.getVoltagePhase3()); // [2]
+
+        assertEquals(0.5, data.getCurrentPhase1()); // [3]
+        assertEquals(0.5, data.getCurrentPhase2()); // [4]
+        assertEquals(0.9, data.getCurrentPhase3()); // [5]
+
+        assertEquals(54, data.getOutputPowerPhase1()); // [6]
+        assertEquals(44, data.getOutputPowerPhase2()); // [7]
+        assertEquals(20, data.getOutputPowerPhase3()); // [8]
+
+        assertEquals(408, data.getPV1Voltage()); // [9]
+        assertEquals(434, data.getPV2Voltage()); // [10]
+        assertEquals(0.1, data.getPV1Current()); // [12]
+        assertEquals(0.2, data.getPV2Current()); // [13]
+        assertEquals(67, data.getPV1Power()); // [15]
+        assertEquals(102, data.getPV2Power()); // [16]
+
+        assertEquals(49.99, data.getFrequencyPhase1()); // [18]
+        assertEquals(49.99, data.getFrequencyPhase2()); // [19]
+        assertEquals(49.99, data.getFrequencyPhase3()); // [20]
+
+        assertEquals(2, data.getInverterWorkModeCode()); // [21]
+        assertEquals("2", data.getInverterWorkMode()); // [21]
+
+        assertEquals(5, data.getInverterTemperature1()); // [26]
+        assertEquals(9, data.getInverterTemperature2()); // [27]
+
+        assertEquals(120, data.getTotalOutputPower()); // [78]
+
+        assertEquals(1903.5, data.getTotalEnergy()); // [22]
+        assertEquals(5.0, data.getTodayEnergy()); // [24]
+    }
+}