diff --git a/CODEOWNERS b/CODEOWNERS
index 41e5ecba6..122c66404 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -147,6 +147,7 @@
/bundles/org.openhab.binding.mail/ @openhab/add-ons-maintainers
/bundles/org.openhab.binding.max/ @marcelrv
/bundles/org.openhab.binding.mcp23017/ @aogorek
+/bundles/org.openhab.binding.mecmeter/ @kaikreuzer
/bundles/org.openhab.binding.melcloud/ @lucacalcaterra @paulianttila @thewiep
/bundles/org.openhab.binding.meteoalerte/ @clinique
/bundles/org.openhab.binding.meteoblue/ @9037568
diff --git a/bom/openhab-addons/pom.xml b/bom/openhab-addons/pom.xml
index 1b0f7a7af..4eaa9f9be 100644
--- a/bom/openhab-addons/pom.xml
+++ b/bom/openhab-addons/pom.xml
@@ -721,6 +721,11 @@
org.openhab.binding.mcp23017
${project.version}
+
+ org.openhab.addons.bundles
+ org.openhab.binding.mecmeter
+ ${project.version}
+
org.openhab.addons.bundles
org.openhab.binding.melcloud
diff --git a/bundles/org.openhab.binding.mecmeter/NOTICE b/bundles/org.openhab.binding.mecmeter/NOTICE
new file mode 100644
index 000000000..38d625e34
--- /dev/null
+++ b/bundles/org.openhab.binding.mecmeter/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.mecmeter/README.MD b/bundles/org.openhab.binding.mecmeter/README.MD
new file mode 100644
index 000000000..aa8f2f8fb
--- /dev/null
+++ b/bundles/org.openhab.binding.mecmeter/README.MD
@@ -0,0 +1,247 @@
+# MecMeter Binding
+
+This binding reads data from MEC power meter for providing electrical information for the electric circuit.
+
+To use this binding the meter must be installed, initialized and connected to the same network as openHAB.
+
+## Supported Things
+
+The mecMeter is supported with firmware version starting from 2.0.0.
+There is exactly one supported thing type `meter`, which represents the electric meter.
+Its unique ID is the serial number.
+
+## Discovery
+
+MecMeters are automatically discovered via mDNS.
+The IP of the Power Meter is automatically set and can be changed manually if needed.
+The default update interval is set to 5 seconds. Intervals from 1 to 300 seconds can be set manually.
+
+## Thing Configuration
+
+The thing has a few configuration parameters:
+
+| Parameter | Description |
+|-----------------|-----------------------------------------------------------------------|
+| password | User-defined password during initializing the Power Meter. Mandatory. |
+| ip | The IP address of the meter. Mandatory. |
+| refreshInterval | Refresh interval in second. Optional, the default value is 5 seconds. |
+
+
+## Channels
+
+The meter has the following channels:
+
+| Channel Type ID | Item Type | Label | Description |
+|--------------------------------------------------------------|--------------------------|-----------------------------------|------------------------------------------|
+| general_group#frequency | Number:Frequency | Main Frequency | Frequency in Hertz |
+| general_group#temperature | Number:Temperature | Internal Temperature | Internal Temperature of the energy meter |
+| general_group#op_time | Number:Time | Time in Operation | Time in Operation |
+| voltage_group#voltage_phase1 | Number:ElectricPotential | Voltage P1 | Voltage in Volt |
+| voltage_group#voltage_phase2 | Number:ElectricPotential | Voltage P2 | Voltage in Volt |
+| voltage_group#voltage_phase3 | Number:ElectricPotential | Voltage P3 | Voltage in Volt |
+| voltage_group#avg_phase_phase_voltage | Number:ElectricPotential | Average Phase – Phase Voltage | Average Phase – Phase Voltage in Volt |
+| voltage_group#avg_neutral_phase_voltage | Number:ElectricPotential | Average Voltage | Average N – Phase Voltage in Volt |
+| current_group#current_allphase | Number:ElectricCurrent | Current | Current in Ampere |
+| current_group#current_phase1 | Number:ElectricCurrent | Current P1 | Current in Ampere |
+| current_group#current_phase2 | Number:ElectricCurrent | Current P2 | Current in Ampere |
+| current_group#current_phase3 | Number:ElectricCurrent | Current P3 | Current in Ampere |
+| angle_group#phase_angle_currvolt_phase1 | Number:Angle | Current P1 | Angle Current to Voltage in Degree |
+| angle_group#phase_angle_currvolt_phase2 | Number:Angle | Current P2 | Angle Current to Voltage in Degree |
+| angle_group#phase_angle_currvolt_phase3 | Number:Angle | Current P3 | Angle Current to Voltage in Degree |
+| angle_group#phase_angle_phase1-3 | Number:Angle | Angle Voltage to Voltage | Angle Voltage to Voltage in Degree |
+| angle_group#phase_angle_phase2-3 | Number:Angle | Angle Voltage to Voltage | Angle Voltage to Voltage in Degree |
+| activepower_group#activepower_allphase | Number:Power | Active Power | Active power consumed |
+| activepower_group#activepower_phase1 | Number:Power | Active Power P1 | Active power consumed |
+| activepower_group#activepower_phase2 | Number:Power | Active Power P2 | Active power consumed |
+| activepower_group#activepower_phase3 | Number:Power | Active Power P3 | Active power consumed |
+| activefundpower_group#activefundpower_allphase | Number:Power | Active Fundamental Power | Active fundamental power |
+| activefundpower_group#activefundpower_phase1 | Number:Power | Active Fund Power P1 | Active fundamental power |
+| activefundpower_group#activefundpower_phase2 | Number:Power | Active Fund Power P2 | Active fundamental power |
+| activefundpower_group#activefundpower_phase3 | Number:Power | Active Fund Power P3 | Active fundamental power |
+| activeharmpower_group#activeharmpower_allphase | Number:Power | Active Harmonic Power | Active harmonic power |
+| activeharmpower_group#activeharmpower_phase1 | Number:Power | Active Harm Power P1 | Active harmonic power |
+| activeharmpower_group#activeharmpower_phase2 | Number:Power | Active Harm Power P2 | Active harmonic power |
+| activeharmpower_group#activeharmpower_phase3 | Number:Power | Active Harm Power P3 | Active harmonic power |
+| reactivepower_group#reactivepower_allphase | Number:Power | Reactive Power | Reactive power consumed |
+| reactivepower_group#reactivepower_phase1 | Number:Power | Reactive Power P1 | Reactive power consumed |
+| reactivepower_group#reactivepower_phase2 | Number:Power | Reactive Power P2 | Reactive power consumed |
+| reactivepower_group#reactivepower_phase3 | Number:Power | Reactive Power P3 | Reactive power consumed |
+| powerfactor_group#powerFactor_allphase | Number:Dimensionless | Power Factor | Power Factor |
+| powerfactor_group#powerFactor_phase1 | Number:Dimensionless | Power Factor P1 | Power Factor |
+| powerfactor_group#powerFactor_phase2 | Number:Dimensionless | Power Factor P2 | Power Factor |
+| powerfactor_group#powerFactor_phase3 | Number:Dimensionless | Power Factor P3 | Power Factor |
+| apppower_group#apppower_allphase | Number:Power | Apparent Power | Apparent power consumed |
+| apppower_group#apppower_phase1 | Number:Power | Apparent Power P1 | Apparent power consumed |
+| apppower_group#apppower_phase2 | Number:Power | Apparent Power P2 | Apparent power consumed |
+| apppower_group#apppower_phase3 | Number:Power | Apparent Power P3 | Apparent power consumed |
+| fwd_active_energy_group#fwd_active_energy_allphase | Number:Energy | Forward Active Energy | Forward Active Energy in kWh |
+| fwd_active_energy_group#fwd_active_energy_phase1 | Number:Energy | Fwd Active Energy P1 | Forward Active Energy in kWh |
+| fwd_active_energy_group#fwd_active_energy_phase2 | Number:Energy | Fwd Active Energy P2 | Forward Active Energy in kWh |
+| fwd_active_energy_group#fwd_active_energy_phase3 | Number:Energy | Fwd Active Energy P3 | Forward Active Energy in kWh |
+| fwd_active_fund_energy_group#fwd_active_fund_energy_allphase | Number:Energy | Forward Active Fundamental Energy | Forward Active Fundamental Energy in kWh |
+| fwd_active_fund_energy_group#fwd_active_fund_energy_phase1 | Number:Energy | Fwd Active Fund Energy P1 | Forward Active Fundamental Energy in kWh |
+| fwd_active_fund_energy_group#fwd_active_fund_energy_phase2 | Number:Energy | Fwd Active Fund Energy P2 | Forward Active Fundamental Energy in kWh |
+| fwd_active_fund_energy_group#fwd_active_fund_energy_phase3 | Number:Energy | Fwd Active Fund Energy P3 | Forward Active Fundamental Energy in kWh |
+| fwd_active_harm_energy_group#fwd_active_harm_energy_allphase | Number:Energy | Forward Active Harmonic Energy | Forward Active Harmonic Energy in kWh |
+| fwd_active_harm_energy_group#fwd_active_harm_energy_phase1 | Number:Energy | Fwd Active Harm Energy P1 | Forward Active Harmonic Energy in kWh |
+| fwd_active_harm_energy_group#fwd_active_harm_energy_phase2 | Number:Energy | Fwd Active Harm Energy P2 | Forward Active Harmonic Energy in kWh |
+| fwd_active_harm_energy_group#fwd_active_harm_energy_phase3 | Number:Energy | Fwd Active Harm Energy P3 | Forward Active Harmonic Energy in kWh |
+| fwd_reactive_energy_group#fwd_reactive_energy_allphase | Number:Energy | Forward Reactive Energy | Forward Reactive Energy in VArh |
+| fwd_reactive_energy_group#fwd_reactive_energy_phase1 | Number:Energy | Fwd Reactive Energy P1 | Forward Reactive Energy in VArh |
+| fwd_reactive_energy_group#fwd_reactive_energy_phase2 | Number:Energy | Fwd Reactive Energy P2 | Forward Reactive Energy in VArh |
+| fwd_reactive_energy_group#fwd_reactive_energy_phase3 | Number:Energy | Fwd Reactive Energy P3 | Forward Reactive Energy in VArh |
+| rev_active_energy_group#rev_active_energy_allphase | Number:Energy | Reverse Active Energy | Reverse Active Energy in kWh |
+| rev_active_energy_group#rev_active_energy_phase1 | Number:Energy | Rev Active Energy P1 | Reverse Active Energy in kWh |
+| rev_active_energy_group#rev_active_energy_phase2 | Number:Energy | Rev Active Energy P2 | Reverse Active Energy in kWh |
+| rev_active_energy_group#rev_active_energy_phase3 | Number:Energy | Rev Active Energy P3 | Reverse Active Energy in kWh |
+| rev_active_fund_energy_group#rev_active_fund_energy_allphase | Number:Energy | Reverse Active Fundamental Energy | Reverse Active Fundamental Energy in kWh |
+| rev_active_fund_energy_group#rev_active_fund_energy_phase1 | Number:Energy | Rev Active Fund Energy P1 | Reverse Active Fundamental Energy in kWh |
+| rev_active_fund_energy_group#rev_active_fund_energy_phase2 | Number:Energy | Rev Active Fund Energy P2 | Reverse Active Fundamental Energy in kWh |
+| rev_active_fund_energy_group#rev_active_fund_energy_phase3 | Number:Energy | Rev Active Fund Energy P3 | Reverse Active Fundamental Energy in kWh |
+| rev_active_harm_energy_group#rev_active_harm_energy_allphase | Number:Energy | Reverse Active Harmonic Energy | Reverse Active Harmonic Energy in kWh |
+| rev_active_harm_energy_group#rev_active_harm_energy_phase1 | Number:Energy | Rev Active Harm Energy P1 | Reverse Active Harmonic Energy in kWh |
+| rev_active_harm_energy_group#rev_active_harm_energy_phase2 | Number:Energy | Rev Active Harm Energy P2 | Reverse Active Harmonic Energy in kWh |
+| rev_active_harm_energy_group#rev_active_harm_energy_phase3 | Number:Energy | Rev Active Harm Energy P3 | Reverse Active Harmonic Energy in kWh |
+| rev_reactive_energy_group#rev_reactive_energy_allphase | Number:Energy | Reverse Reactive Energy | Reverse Reactive Energy in VArh |
+| rev_reactive_energy_group#rev_reactive_energy_phase1 | Number:Energy | Rev Reactive Energy P1 | Reverse Reactive Energy in VArh |
+| rev_reactive_energy_group#rev_reactive_energy_phase2 | Number:Energy | Rev Reactive Energy P2 | Reverse Reactive Energy in VArh |
+| rev_reactive_energy_group#rev_reactive_energy_phase3 | Number:Energy | Rev Reactive Energy P3 | Reverse Reactive Energy in VArh |
+| app_energy_group#appenergy_consumption_allphase | Number:Energy | Apparent Energy Consumption | Apparent Energy Consumption in VArh |
+| app_energy_group#appenergy_consumption_phase1 | Number:Energy | Apparent Energy P1 | Apparent Energy Consumption in VArh |
+| app_energy_group#appenergy_consumption_phase2 | Number:Energy | Apparent Energy P2 | Apparent Energy Consumption in VArh |
+| app_energy_group#appenergy_consumption_phase3 | Number:Energy | Apparent Energy P3 | Apparent Energy Consumption in VArh |
+
+## Full Example
+
+### mecmeter.things
+
+```
+mecmeter:meter:1 [ password="Test1234", ip="192.168.1.16", refreshInterval="10" ]
+```
+
+### mecmeter.items
+
+```
+Number:Frequency MainFrequency { channel="mecmeter:meter:1:general_group#frequency" }
+Number:Temperature InternalTemperature { channel="mecmeter:meter:1:general_group#temperature" }
+Number:Time TimeinOperation { channel="mecmeter:meter:1:general_group#op_time" }
+
+Number:Power ActivePower { channel="mecmeter:meter:1:activepower_group#activepower_allphase" }
+Number:Power ActivePowerP1 { channel="mecmeter:meter:1:activepower_group#activepower_phase1" }
+Number:Power ActivePowerP2 { channel="mecmeter:meter:1:activepower_group#activepower_phase2" }
+Number:Power ActivePowerP3 { channel="mecmeter:meter:1:activepower_group#activepower_phase3" }
+
+Number:ElectricPotential VoltageP1 { channel="mecmeter:meter:1:voltage_group#voltage_phase1" }
+Number:ElectricPotential VoltageP2 { channel="mecmeter:meter:1:voltage_group#voltage_phase2" }
+Number:ElectricPotential VoltageP3 { channel="mecmeter:meter:1:voltage_group#voltage_phase3" }
+Number:ElectricPotential AveragePhasePhaseVoltage { channel="mecmeter:meter:1:voltage_group#avg_phase_phase_voltage" }
+Number:ElectricPotential AverageVoltage { channel="mecmeter:meter:1:voltage_group#avg_neutral_phase_voltage" }
+
+Number:ElectricCurrent Current { channel="mecmeter:meter:1:current_group#current_allphase" }
+Number:ElectricCurrent Current_Group_Current_Phase1 { channel="mecmeter:meter:1:current_group#current_phase1" }
+Number:ElectricCurrent Current_Group_Current_Phase2 { channel="mecmeter:meter:1:current_group#current_phase2" }
+Number:ElectricCurrent Current_Group_Current_Phase3 { channel="mecmeter:meter:1:current_group#current_phase3" }
+
+Number:Power ActiveFundamentalPower { channel="mecmeter:meter:1:activefundpower_group#activefundpower_allphase" }
+Number:Power ActiveFundPowerP1 { channel="mecmeter:meter:1:activefundpower_group#activefundpower_phase1" }
+Number:Power ActiveFundPowerP2 { channel="mecmeter:meter:1:activefundpower_group#activefundpower_phase2" }
+Number:Power ActiveFundPowerP3 { channel="mecmeter:meter:1:activefundpower_group#activefundpower_phase3" }
+
+Number:Power ActiveHarmonicPower { channel="mecmeter:meter:1:activeharmpower_group#activeharmpower_allphase" }
+Number:Power ActiveHarmPowerP1 { channel="mecmeter:meter:1:activeharmpower_group#activeharmpower_phase1" }
+Number:Power ActiveHarmPowerP2 { channel="mecmeter:meter:1:activeharmpower_group#activeharmpower_phase2" }
+Number:Power ActiveHarmPowerP3 { channel="mecmeter:meter:1:activeharmpower_group#activeharmpower_phase3" }
+
+Number:Angle Angle_Group_Phase_Angle_Currvolt_Phase1 { channel="mecmeter:meter:1:angle_group#phase_angle_currvolt_phase1" }
+Number:Angle Angle_Group_Phase_Angle_Currvolt_Phase2 { channel="mecmeter:meter:1:angle_group#phase_angle_currvolt_phase2" }
+Number:Angle Angle_Group_Phase_Angle_Currvolt_Phase3 { channel="mecmeter:meter:1:angle_group#phase_angle_currvolt_phase3" }
+Number:Angle Angle_Group_Phase_Angle_Phase13 { channel="mecmeter:meter:1:angle_group#phase_angle_phase1-3" }
+Number:Angle Angle_Group_Phase_Angle_Phase23 { channel="mecmeter:meter:1:angle_group#phase_angle_phase2-3" }
+
+Number:Energy ApparentEnergyConsumption { channel="mecmeter:meter:1:app_energy_group#appenergy_consumption_allphase" }
+Number:Energy ApparentEnergyP1 { channel="mecmeter:meter:1:app_energy_group#appenergy_consumption_phase1" }
+Number:Energy ApparentEnergyP2 { channel="mecmeter:meter:1:app_energy_group#appenergy_consumption_phase2" }
+Number:Energy ApparentEnergyP3 { channel="mecmeter:meter:1:app_energy_group#appenergy_consumption_phase3" }
+
+Number:Power ApparentPower { channel="mecmeter:meter:1:apppower_group#apppower_allphase" }
+Number:Power ApparentPowerP1 { channel="mecmeter:meter:1:apppower_group#apppower_phase1" }
+Number:Power ApparentPowerP2 { channel="mecmeter:meter:1:apppower_group#apppower_phase2" }
+Number:Power ApparentPowerP3 { channel="mecmeter:meter:1:apppower_group#apppower_phase3" }
+
+Number:Energy ForwardActiveEnergy { channel="mecmeter:meter:1:fwd_active_energy_group#fwd_active_energy_allphase" }
+Number:Energy ForwardActiveFundamentalEnergy { channel="mecmeter:meter:1:fwd_active_fund_energy_group#fwd_active_fund_energy_allphase" }
+Number:Energy ForwardActiveHarmonicEnergy { channel="mecmeter:meter:1:fwd_active_harm_energy_group#fwd_active_harm_energy_allphase" }
+Number:Energy ForwardReactiveEnergy { channel="mecmeter:meter:1:fwd_reactive_energy_group#fwd_reactive_energy_allphase" }
+
+Number:Energy FwdActiveEnergyP1 { channel="mecmeter:meter:1:fwd_active_energy_group#fwd_active_energy_phase1" }
+Number:Energy FwdActiveEnergyP2 { channel="mecmeter:meter:1:fwd_active_energy_group#fwd_active_energy_phase2" }
+Number:Energy FwdActiveEnergyP3 { channel="mecmeter:meter:1:fwd_active_energy_group#fwd_active_energy_phase3" }
+
+Number:Energy FwdActiveFundEnergyP1 { channel="mecmeter:meter:1:fwd_active_fund_energy_group#fwd_active_fund_energy_phase1" }
+Number:Energy FwdActiveFundEnergyP2 { channel="mecmeter:meter:1:fwd_active_fund_energy_group#fwd_active_fund_energy_phase2" }
+Number:Energy FwdActiveFundEnergyP3 { channel="mecmeter:meter:1:fwd_active_fund_energy_group#fwd_active_fund_energy_phase3" }
+
+Number:Energy FwdActiveHarmEnergyP1 { channel="mecmeter:meter:1:fwd_active_harm_energy_group#fwd_active_harm_energy_phase1" }
+Number:Energy FwdActiveHarmEnergyP2 { channel="mecmeter:meter:1:fwd_active_harm_energy_group#fwd_active_harm_energy_phase2" }
+Number:Energy FwdActiveHarmEnergyP3 { channel="mecmeter:meter:1:fwd_active_harm_energy_group#fwd_active_harm_energy_phase3" }
+
+Number:Energy FwdReactiveEnergyP1 { channel="mecmeter:meter:1:fwd_reactive_energy_group#fwd_reactive_energy_phase1" }
+Number:Energy FwdReactiveEnergyP2 { channel="mecmeter:meter:1:fwd_reactive_energy_group#fwd_reactive_energy_phase2" }
+Number:Energy FwdReactiveEnergyP3 { channel="mecmeter:meter:1:fwd_reactive_energy_group#fwd_reactive_energy_phase3" }
+
+Number:Energy PowerFactor { channel="mecmeter:meter:1:powerfactor_group#powerFactor_allphase" }
+Number:Energy PowerFactorP1 { channel="mecmeter:meter:1:powerfactor_group#powerFactor_phase1" }
+Number:Energy PowerFactorP2 { channel="mecmeter:meter:1:powerfactor_group#powerFactor_phase2" }
+Number:Energy PowerFactorP3 { channel="mecmeter:meter:1:powerfactor_group#powerFactor_phase3" }
+
+Number:Power ReactivePower { channel="mecmeter:meter:1:reactivepower_group#reactivepower_allphase" }
+Number:Power ReactivePowerP1 { channel="mecmeter:meter:1:reactivepower_group#reactivepower_phase1" }
+Number:Power ReactivePowerP2 { channel="mecmeter:meter:1:reactivepower_group#reactivepower_phase2" }
+Number:Power ReactivePowerP3 { channel="mecmeter:meter:1:reactivepower_group#reactivepower_phase3" }
+
+Number:Energy ReverseActiveEnergy { channel="mecmeter:meter:1:rev_active_energy_group#rev_active_energy_allphase" }
+Number:Energy RevActiveEnergyP1 { channel="mecmeter:meter:1:rev_active_energy_group#rev_active_energy_phase1" }
+Number:Energy RevActiveEnergyP2 { channel="mecmeter:meter:1:rev_active_energy_group#rev_active_energy_phase2" }
+Number:Energy RevActiveEnergyP3 { channel="mecmeter:meter:1:rev_active_energy_group#rev_active_energy_phase3" }
+
+Number:Energy ReverseActiveFundamentalEnergy { channel="mecmeter:meter:1:rev_active_fund_energy_group#rev_active_fund_energy_allphase" }
+Number:Energy RevActiveFundEnergyP1 { channel="mecmeter:meter:1:rev_active_fund_energy_group#rev_active_fund_energy_phase1" }
+Number:Energy RevActiveFundEnergyP2 { channel="mecmeter:meter:1:rev_active_fund_energy_group#rev_active_fund_energy_phase2" }
+Number:Energy RevActiveFundEnergyP3 { channel="mecmeter:meter:1:rev_active_fund_energy_group#rev_active_fund_energy_phase3" }
+
+Number:Energy ReverseActiveHarmonicEnergy { channel="mecmeter:meter:1:rev_active_harm_energy_group#rev_active_harm_energy_allphase" }
+Number:Energy RevActiveHarmEnergyP1 { channel="mecmeter:meter:1:rev_active_harm_energy_group#rev_active_harm_energy_phase1" }
+Number:Energy RevActiveHarmEnergyP2 { channel="mecmeter:meter:1:rev_active_harm_energy_group#rev_active_harm_energy_phase2" }
+Number:Energy RevActiveHarmEnergyP3 { channel="mecmeter:meter:1:rev_active_harm_energy_group#rev_active_harm_energy_phase3" }
+
+Number:Energy ReverseReactiveEnergy { channel="mecmeter:meter:1:rev_reactive_energy_group#rev_reactive_energy_allphase" }
+Number:Energy RevReactiveEnergyP1 { channel="mecmeter:meter:1:rev_reactive_energy_group#rev_reactive_energy_phase1" }
+Number:Energy RevReactiveEnergyP2 { channel="mecmeter:meter:1:rev_reactive_energy_group#rev_reactive_energy_phase2" }
+Number:Energy RevReactiveEnergyP3 { channel="mecmeter:meter:1:rev_reactive_energy_group#rev_reactive_energy_phase3" }
+```
+
+### mecmeter.sitemap
+
+```
+sitemap mecmeter label="MecMeter"
+{
+ Frame label="General" {
+ Text item=MainFrequency
+ Text item=InternalTemperature
+ }
+
+ Frame label="Power" {
+ Text item=ActivePower
+ Text item=ActivePowerP1
+ Text item=ActivePowerP2
+ Text item=ActivePowerP3
+ }
+
+ Frame label="Electric Potential" {
+ Text item=VoltageP1
+ Text item=VoltageP2
+ Text item=VoltageP3
+ }
+
+}
+```
diff --git a/bundles/org.openhab.binding.mecmeter/pom.xml b/bundles/org.openhab.binding.mecmeter/pom.xml
new file mode 100644
index 000000000..3f454bac7
--- /dev/null
+++ b/bundles/org.openhab.binding.mecmeter/pom.xml
@@ -0,0 +1,17 @@
+
+
+
+ 4.0.0
+
+
+ org.openhab.addons.bundles
+ org.openhab.addons.reactor.bundles
+ 3.1.0-SNAPSHOT
+
+
+ org.openhab.binding.mecmeter
+
+ openHAB Add-ons :: Bundles :: mecMeter Binding
+
+
diff --git a/bundles/org.openhab.binding.mecmeter/src/main/feature/feature.xml b/bundles/org.openhab.binding.mecmeter/src/main/feature/feature.xml
new file mode 100644
index 000000000..2ddad66bd
--- /dev/null
+++ b/bundles/org.openhab.binding.mecmeter/src/main/feature/feature.xml
@@ -0,0 +1,9 @@
+
+
+ mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features
+
+
+ openhab-runtime-base
+ mvn:org.openhab.addons.bundles/org.openhab.binding.mecmeter/${project.version}
+
+
diff --git a/bundles/org.openhab.binding.mecmeter/src/main/java/org/openhab/binding/mecmeter/MecMeterBindingConstants.java b/bundles/org.openhab.binding.mecmeter/src/main/java/org/openhab/binding/mecmeter/MecMeterBindingConstants.java
new file mode 100644
index 000000000..b594cf4e3
--- /dev/null
+++ b/bundles/org.openhab.binding.mecmeter/src/main/java/org/openhab/binding/mecmeter/MecMeterBindingConstants.java
@@ -0,0 +1,210 @@
+/**
+ * Copyright (c) 2010-2021 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.mecmeter;
+
+import java.util.Set;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.core.thing.ThingTypeUID;
+
+/**
+ * The {@link MecMeterBindingConstants} class defines common constants, which are
+ * used across the whole binding.
+ *
+ * @author Florian Pazour - Initial contribution
+ * @author Klaus Berger - Initial contribution
+ */
+@NonNullByDefault
+public class MecMeterBindingConstants {
+
+ private static final String BINDING_ID = "mecmeter";
+
+ // List of all Thing Type UIDs
+ public static final ThingTypeUID THING_TYPE_METER = new ThingTypeUID(BINDING_ID, "meter");
+
+ public static final Set SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_METER);
+
+ /*
+ * List of all Groups
+ */
+ public static final String GENERAL_GROUP = "general_group";
+ public static final String VOLTAGE_GROUP = "voltage_group";
+ public static final String CURRENT_GROUP = "current_group";
+ public static final String ANGLE_GROUP = "angle_group";
+
+ public static final String ACTIVE_POWER_GROUP = "activepower_group";
+ public static final String ACTIVE_FUND_POWER_GROUP = "activefundpower_group";
+ public static final String POWER_FACTOR_GROUP = "powerfactor_group";
+ public static final String ACTIVE_HARM_POWER_GROUP = "activeharmpower_group";
+ public static final String REACTIVE_POWER_GROUP = "reactivepower_group";
+
+ public static final String APP_POWER_GROUP = "apppower_group";
+
+ public static final String FWD_ACTIVE_ENERGY_GROUP = "fwd_active_energy_group";
+ public static final String FWD_ACTIVE_FUND_ENERGY_GROUP = "fwd_active_fund_energy_group";
+ public static final String FWD_ACTIVE_HARM_ENERGY_GROUP = "fwd_active_harm_energy_group";
+ public static final String FWD_REACTIVE_ENERGY_GROUP = "fwd_reactive_energy_group";
+
+ public static final String REV_ACTIVE_ENERGY_GROUP = "rev_active_energy_group";
+ public static final String REV_ACTIVE_FUND_ENERGY_GROUP = "rev_active_fund_energy_group";
+ public static final String REV_ACTIVE_HARM_ENERGY_GROUP = "rev_active_harm_energy_group";
+ public static final String REV_REACTIVE_ENERGY_GROUP = "rev_reactive_energy_group";
+
+ public static final String APP_ENERGY_GROUP = "app_energy_group";
+
+ /*
+ * List of all Channels
+ */
+ // General Channels
+ public static final String FREQUENCY = GENERAL_GROUP + "#" + "frequency";
+ public static final String TEMPERATURE = GENERAL_GROUP + "#" + "temperature";
+ public static final String OPERATIONAL_TIME = GENERAL_GROUP + "#" + "op_time";
+
+ // Voltage Channels
+ public static final String VOLTAGE_PHASE_1 = VOLTAGE_GROUP + "#" + "voltage_phase1";
+ public static final String VOLTAGE_PHASE_2 = VOLTAGE_GROUP + "#" + "voltage_phase2";
+ public static final String VOLTAGE_PHASE_3 = VOLTAGE_GROUP + "#" + "voltage_phase3";
+
+ public static final String VOLTAGE_PHASE_3_TO_PHASE_2 = VOLTAGE_GROUP + "#" + "voltage_phase3-2";
+ public static final String VOLTAGE_PHASE_2_TO_PHASE_1 = VOLTAGE_GROUP + "#" + "voltage_phase2-1";
+ public static final String VOLTAGE_PHASE_1_TO_PHASE_3 = VOLTAGE_GROUP + "#" + "voltage_phase1-3";
+
+ public static final String AVERAGE_VOLTAGE_PHASE_2_PHASE = VOLTAGE_GROUP + "#" + "avg_phase_phase_voltage";
+ public static final String AVERAGE_VOLTAGE_NEUTRAL_2_PHASE = VOLTAGE_GROUP + "#" + "avg_neutral_phase_voltage";
+
+ // Current Channels
+ public static final String CURRENT_PHASE_1 = CURRENT_GROUP + "#" + "current_phase1";
+ public static final String CURRENT_PHASE_2 = CURRENT_GROUP + "#" + "current_phase2";
+ public static final String CURRENT_PHASE_3 = CURRENT_GROUP + "#" + "current_phase3";
+ public static final String CURRENT_SUM = CURRENT_GROUP + "#" + "current_allphase";
+
+ // Angle Channels
+ public static final String PHASE_ANGLE_TO_CURRENT_PHASE_1 = ANGLE_GROUP + "#" + "phase_angle_currvolt_phase1";
+ public static final String PHASE_ANGLE_TO_CURRENT_PHASE_2 = ANGLE_GROUP + "#" + "phase_angle_currvolt_phase2";
+ public static final String PHASE_ANGLE_TO_CURRENT_PHASE_3 = ANGLE_GROUP + "#" + "phase_angle_currvolt_phase3";
+
+ public static final String PHASE_ANGLE_PHASE_1_3 = ANGLE_GROUP + "#" + "phase_angle_phase1-3";
+ public static final String PHASE_ANGLE_PHASE_2_3 = ANGLE_GROUP + "#" + "phase_angle_phase2-3";
+
+ // Power Channels
+ public static final String ACTIVE_POWER_PHASE_1 = ACTIVE_POWER_GROUP + "#" + "activepower_phase1";
+ public static final String ACTIVE_POWER_PHASE_2 = ACTIVE_POWER_GROUP + "#" + "activepower_phase2";
+ public static final String ACTIVE_POWER_PHASE_3 = ACTIVE_POWER_GROUP + "#" + "activepower_phase3";
+ public static final String ACTIVE_POWER_SUM = ACTIVE_POWER_GROUP + "#" + "activepower_allphase";
+
+ public static final String ACTIVE_FUND_POWER_PHASE_1 = ACTIVE_FUND_POWER_GROUP + "#" + "activefundpower_phase1";
+ public static final String ACTIVE_FUND_POWER_PHASE_2 = ACTIVE_FUND_POWER_GROUP + "#" + "activefundpower_phase2";
+ public static final String ACTIVE_FUND_POWER_PHASE_3 = ACTIVE_FUND_POWER_GROUP + "#" + "activefundpower_phase3";
+ public static final String ACTIVE_FUND_POWER_ALL = ACTIVE_FUND_POWER_GROUP + "#" + "activefundpower_allphase";
+
+ public static final String POWER_FACTOR_PHASE_1 = POWER_FACTOR_GROUP + "#" + "powerFactor_phase1";
+ public static final String POWER_FACTOR_PHASE_2 = POWER_FACTOR_GROUP + "#" + "powerFactor_phase2";
+ public static final String POWER_FACTOR_PHASE_3 = POWER_FACTOR_GROUP + "#" + "powerFactor_phase3";
+ public static final String POWER_FACTOR_ALL = POWER_FACTOR_GROUP + "#" + "powerFactor_allphase";
+
+ public static final String ACTIVE_HARM_POWER_PHASE_1 = ACTIVE_HARM_POWER_GROUP + "#" + "activeharmpower_phase1";
+ public static final String ACTIVE_HARM_POWER_PHASE_2 = ACTIVE_HARM_POWER_GROUP + "#" + "activeharmpower_phase2";
+ public static final String ACTIVE_HARM_POWER_PHASE_3 = ACTIVE_HARM_POWER_GROUP + "#" + "activeharmpower_phase3";
+ public static final String ACTIVE_HARM_POWER_ALL = ACTIVE_HARM_POWER_GROUP + "#" + "activeharmpower_allphase";
+
+ public static final String REACTIVE_POWER_PHASE_1 = REACTIVE_POWER_GROUP + "#" + "reactivepower_phase1";
+ public static final String REACTIVE_POWER_PHASE_2 = REACTIVE_POWER_GROUP + "#" + "reactivepower_phase2";
+ public static final String REACTIVE_POWER_PHASE_3 = REACTIVE_POWER_GROUP + "#" + "reactivepower_phase3";
+ public static final String REACTIVE_POWER_ALL = REACTIVE_POWER_GROUP + "#" + "reactivepower_allphase";
+
+ public static final String APP_POWER_PHASE_1 = APP_POWER_GROUP + "#" + "apppower_phase1";
+ public static final String APP_POWER_PHASE_2 = APP_POWER_GROUP + "#" + "apppower_phase2";
+ public static final String APP_POWER_PHASE_3 = APP_POWER_GROUP + "#" + "apppower_phase3";
+ public static final String APP_POWER_ALL = APP_POWER_GROUP + "#" + "apppower_allphase";
+
+ // Forward Energy Channels
+ public static final String FORWARD_ACTIVE_ENERGY_PHASE_1 = FWD_ACTIVE_ENERGY_GROUP + "#"
+ + "fwd_active_energy_phase1";
+ public static final String FORWARD_ACTIVE_ENERGY_PHASE_2 = FWD_ACTIVE_ENERGY_GROUP + "#"
+ + "fwd_active_energy_phase2";
+ public static final String FORWARD_ACTIVE_ENERGY_PHASE_3 = FWD_ACTIVE_ENERGY_GROUP + "#"
+ + "fwd_active_energy_phase3";
+ public static final String FORWARD_ACTIVE_ENERGY_ALL = FWD_ACTIVE_ENERGY_GROUP + "#" + "fwd_active_energy_allphase";
+
+ public static final String FORWARD_ACTIVE_FUND_ENERGY_PHASE_1 = FWD_ACTIVE_FUND_ENERGY_GROUP + "#"
+ + "fwd_active_fund_energy_phase1";
+ public static final String FORWARD_ACTIVE_FUND_ENERGY_PHASE_2 = FWD_ACTIVE_FUND_ENERGY_GROUP + "#"
+ + "fwd_active_fund_energy_phase2";
+ public static final String FORWARD_ACTIVE_FUND_ENERGY_PHASE_3 = FWD_ACTIVE_FUND_ENERGY_GROUP + "#"
+ + "fwd_active_fund_energy_phase3";
+ public static final String FORWARD_ACTIVE_FUND_ENERGY_ALL = FWD_ACTIVE_FUND_ENERGY_GROUP + "#"
+ + "fwd_active_fund_energy_allphase";
+
+ public static final String FORWARD_ACTIVE_HARM_ENERGY_PHASE_1 = FWD_ACTIVE_HARM_ENERGY_GROUP + "#"
+ + "fwd_active_harm_energy_phase1";
+ public static final String FORWARD_ACTIVE_HARM_ENERGY_PHASE_2 = FWD_ACTIVE_HARM_ENERGY_GROUP + "#"
+ + "fwd_active_harm_energy_phase2";
+ public static final String FORWARD_ACTIVE_HARM_ENERGY_PHASE_3 = FWD_ACTIVE_HARM_ENERGY_GROUP + "#"
+ + "fwd_active_harm_energy_phase3";
+ public static final String FORWARD_ACTIVE_HARM_ENERGY_ALL = FWD_ACTIVE_HARM_ENERGY_GROUP + "#"
+ + "fwd_active_harm_energy_allphase";
+
+ public static final String FORWARD_REACTIVE_ENERGY_PHASE_1 = FWD_REACTIVE_ENERGY_GROUP + "#"
+ + "fwd_reactive_energy_phase1";
+ public static final String FORWARD_REACTIVE_ENERGY_PHASE_2 = FWD_REACTIVE_ENERGY_GROUP + "#"
+ + "fwd_reactive_energy_phase2";
+ public static final String FORWARD_REACTIVE_ENERGY_PHASE_3 = FWD_REACTIVE_ENERGY_GROUP + "#"
+ + "fwd_reactive_energy_phase3";
+ public static final String FORWARD_REACTIVE_ENERGY_ALL = FWD_REACTIVE_ENERGY_GROUP + "#"
+ + "fwd_reactive_energy_allphase";
+
+ // Reverse Energy Channels
+ public static final String REVERSE_ACTIVE_ENERGY_PHASE_1 = REV_ACTIVE_ENERGY_GROUP + "#"
+ + "rev_active_energy_phase1";
+ public static final String REVERSE_ACTIVE_ENERGY_PHASE_2 = REV_ACTIVE_ENERGY_GROUP + "#"
+ + "rev_active_energy_phase2";
+ public static final String REVERSE_ACTIVE_ENERGY_PHASE_3 = REV_ACTIVE_ENERGY_GROUP + "#"
+ + "rev_active_energy_phase3";
+ public static final String REVERSE_ACTIVE_ENERGY_ALL = REV_ACTIVE_ENERGY_GROUP + "#" + "rev_active_energy_allphase";
+
+ public static final String REVERSE_ACTIVE_FUND_ENERGY_PHASE_1 = REV_ACTIVE_FUND_ENERGY_GROUP + "#"
+ + "rev_active_fund_energy_phase1";
+ public static final String REVERSE_ACTIVE_FUND_ENERGY_PHASE_2 = REV_ACTIVE_FUND_ENERGY_GROUP + "#"
+ + "rev_active_fund_energy_phase2";
+ public static final String REVERSE_ACTIVE_FUND_ENERGY_PHASE_3 = REV_ACTIVE_FUND_ENERGY_GROUP + "#"
+ + "rev_active_fund_energy_phase3";
+ public static final String REVERSE_ACTIVE_FUND_ENERGY_ALL = REV_ACTIVE_FUND_ENERGY_GROUP + "#"
+ + "rev_active_fund_energy_allphase";
+
+ public static final String REVERSE_ACTIVE_HARM_ENERGY_PHASE_1 = REV_ACTIVE_HARM_ENERGY_GROUP + "#"
+ + "rev_active_harm_energy_phase1";
+ public static final String REVERSE_ACTIVE_HARM_ENERGY_PHASE_2 = REV_ACTIVE_HARM_ENERGY_GROUP + "#"
+ + "rev_active_harm_energy_phase2";
+ public static final String REVERSE_ACTIVE_HARM_ENERGY_PHASE_3 = REV_ACTIVE_HARM_ENERGY_GROUP + "#"
+ + "rev_active_harm_energy_phase3";
+ public static final String REVERSE_ACTIVE_HARM_ENERGY_ALL = REV_ACTIVE_HARM_ENERGY_GROUP + "#"
+ + "rev_active_harm_energy_allphase";
+
+ public static final String REVERSE_REACTIVE_ENERGY_PHASE_1 = REV_REACTIVE_ENERGY_GROUP + "#"
+ + "rev_reactive_energy_phase1";
+ public static final String REVERSE_REACTIVE_ENERGY_PHASE_2 = REV_REACTIVE_ENERGY_GROUP + "#"
+ + "rev_reactive_energy_phase2";
+ public static final String REVERSE_REACTIVE_ENERGY_PHASE_3 = REV_REACTIVE_ENERGY_GROUP + "#"
+ + "rev_reactive_energy_phase3";
+ public static final String REVERSE_REACTIVE_ENERGY_ALL = REV_REACTIVE_ENERGY_GROUP + "#"
+ + "rev_reactive_energy_allphase";
+
+ // Apparent Energy Channels
+ public static final String APP_ENERGY_PHASE_1 = APP_ENERGY_GROUP + "#" + "appenergy_consumption_phase1";
+ public static final String APP_ENERGY_PHASE_2 = APP_ENERGY_GROUP + "#" + "appenergy_consumption_phase2";
+ public static final String APP_ENERGY_PHASE_3 = APP_ENERGY_GROUP + "#" + "appenergy_consumption_phase3";
+ public static final String APP_ENERGY_ALL = APP_ENERGY_GROUP + "#" + "appenergy_consumption_allphase";
+
+ // list of all URLs
+ public static final String POWERMETER_DATA_URL = "http://%IP%/wizard/public/api/measurements";
+}
diff --git a/bundles/org.openhab.binding.mecmeter/src/main/java/org/openhab/binding/mecmeter/MecMeterDeviceConfiguration.java b/bundles/org.openhab.binding.mecmeter/src/main/java/org/openhab/binding/mecmeter/MecMeterDeviceConfiguration.java
new file mode 100644
index 000000000..605a1678c
--- /dev/null
+++ b/bundles/org.openhab.binding.mecmeter/src/main/java/org/openhab/binding/mecmeter/MecMeterDeviceConfiguration.java
@@ -0,0 +1,64 @@
+/**
+ * Copyright (c) 2010-2021 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.mecmeter;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * The {@link MecMeterDeviceConfiguration} is the class used to match the
+ * thing configuration.
+ *
+ * @author Florian Pazour - Initial contribution
+ * @author Klaus Berger - Initial contribution
+ */
+@NonNullByDefault
+public class MecMeterDeviceConfiguration {
+ public String ip = "";
+ public String password = "12345";
+ public int refreshInterval = 5;
+
+ public String getIp() {
+ return ip;
+ }
+
+ public void setIp(String inetaddress) {
+ ip = inetaddress;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String pw) {
+ password = pw;
+ }
+
+ public int getRefreshInterval() {
+ return refreshInterval;
+ }
+
+ public void setRefreshInterval(int ri) {
+ refreshInterval = ri;
+ }
+
+ public @Nullable String isValid() {
+ if (ip.isBlank()) {
+ return "Missing IP";
+ }
+ if (password.isBlank()) {
+ return "Password is missing";
+ }
+ return null;
+ }
+}
diff --git a/bundles/org.openhab.binding.mecmeter/src/main/java/org/openhab/binding/mecmeter/handler/MecMeterHandler.java b/bundles/org.openhab.binding.mecmeter/src/main/java/org/openhab/binding/mecmeter/handler/MecMeterHandler.java
new file mode 100644
index 000000000..c66aa9851
--- /dev/null
+++ b/bundles/org.openhab.binding.mecmeter/src/main/java/org/openhab/binding/mecmeter/handler/MecMeterHandler.java
@@ -0,0 +1,408 @@
+/**
+ * Copyright (c) 2010-2021 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.mecmeter.handler;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.client.api.ContentResponse;
+import org.eclipse.jetty.http.HttpHeader;
+import org.eclipse.jetty.http.HttpMethod;
+import org.openhab.binding.mecmeter.MecMeterBindingConstants;
+import org.openhab.binding.mecmeter.MecMeterDeviceConfiguration;
+import org.openhab.binding.mecmeter.internal.dto.MecMeterResponse;
+import org.openhab.core.library.types.QuantityType;
+import org.openhab.core.library.unit.SIUnits;
+import org.openhab.core.library.unit.Units;
+import org.openhab.core.thing.Channel;
+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.RefreshType;
+import org.openhab.core.types.State;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonSyntaxException;
+
+/**
+ * The {@link MecMeterHandler} is responsible for handling commands, which are
+ * sent to one of the channels.
+ *
+ * @author Florian Pazour - Initial contribution
+ * @author Klaus Berger - Initial contribution
+ * @author Kai Kreuzer - Refactoring for openHAB 3
+ */
+@NonNullByDefault
+public class MecMeterHandler extends BaseThingHandler {
+
+ private static final int API_TIMEOUT = 5000; // set on 5000ms - not specified in datasheet
+
+ private static final String USERNAME = "admin";
+
+ private final Logger logger = LoggerFactory.getLogger(MecMeterHandler.class);
+
+ private Gson gson = new Gson();
+
+ private final HttpClient httpClient;
+
+ private @Nullable ScheduledFuture> pollFuture;
+
+ private @Nullable MecMeterResponse powerMeterResponse;
+
+ public MecMeterHandler(Thing thing, HttpClient httpClient) {
+ super(thing);
+ this.httpClient = httpClient;
+ }
+
+ @Override
+ public void handleCommand(ChannelUID channelUID, Command command) {
+ if (command instanceof RefreshType) {
+ updateChannel(channelUID.getId());
+ } else {
+ logger.debug("Received unsupported command {}.", command);
+ }
+ }
+
+ /**
+ * function which is called to refresh the data
+ */
+ public void refresh() {
+ updateData();
+ updateChannels();
+ }
+
+ @Override
+ public void dispose() {
+ super.dispose();
+ logger.debug("removing thing..");
+ if (pollFuture != null) {
+ pollFuture.cancel(true);
+ }
+ }
+
+ @Override
+ public void initialize() {
+ MecMeterDeviceConfiguration config = getConfig().as(MecMeterDeviceConfiguration.class);
+ String configCheck = config.isValid();
+
+ if (configCheck != null) {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, configCheck);
+ return;
+ }
+ updateStatus(ThingStatus.UNKNOWN);
+
+ if (pollFuture != null) {
+ pollFuture.cancel(false);
+ }
+ pollFuture = scheduler.scheduleWithFixedDelay(() -> {
+ refresh();
+ }, 0, config.refreshInterval, TimeUnit.SECONDS);
+ }
+
+ /**
+ * Get new data
+ * Function to save Response of the powermeter
+ */
+ private void updateData() {
+ powerMeterResponse = getRealtimeData();
+ }
+
+ /**
+ * Get new realtime data over the network
+ *
+ * @return MecMeterResponse class where json values "are saved"
+ */
+ private @Nullable MecMeterResponse getRealtimeData() {
+ MecMeterResponse result = null;
+ boolean resultOk = false;
+ String errorMsg = null;
+
+ MecMeterDeviceConfiguration config = getConfig().as(MecMeterDeviceConfiguration.class);
+
+ try {
+ String basicAuthentication = "Basic " + Base64.getEncoder()
+ .encodeToString(new String(USERNAME + ":" + config.password).getBytes(StandardCharsets.ISO_8859_1));
+
+ String location = MecMeterBindingConstants.POWERMETER_DATA_URL.replace("%IP%", config.ip.strip());
+
+ ContentResponse response = httpClient.newRequest(location).method(HttpMethod.GET)
+ .header(HttpHeader.AUTHORIZATION, basicAuthentication).timeout(API_TIMEOUT, TimeUnit.MILLISECONDS)
+ .send();
+ if (response.getStatus() != 200) {
+ errorMsg = "Reading meter did not succeed: " + response.getReason();
+ logger.error("Request to meter failed: HTTP {}: {}", response.getStatus(), response.getReason());
+ } else {
+ result = gson.fromJson(response.getContentAsString(), MecMeterResponse.class);
+ if (result == null) {
+ errorMsg = "no data returned";
+ logger.error("no data returned from meter at {}", location);
+ } else {
+ resultOk = true;
+ }
+ }
+ } catch (JsonSyntaxException e) {
+ errorMsg = "Configuration is incorrect";
+ logger.error("Error running power meter request: {}", e.getMessage());
+ } catch (IllegalStateException e) {
+ errorMsg = "Connection failed";
+ logger.error("Error running powermeter request: {}", e.getMessage());
+ } catch (InterruptedException e) {
+ logger.debug("Http request has been interrupted: {}", e.getMessage());
+ } catch (TimeoutException e) {
+ logger.debug("Http request ran into a timeout: {}", e.getMessage());
+ errorMsg = "Connection to power meter timed out.";
+ } catch (ExecutionException e) {
+ logger.debug("Http request did not succeed: {}", e.getMessage());
+ errorMsg = "Connection problem: " + e.getMessage();
+ }
+
+ // Update the thing status
+ if (resultOk) {
+ updateStatus(ThingStatus.ONLINE);
+ } else {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR, errorMsg);
+ }
+
+ return resultOk ? result : null;
+ }
+
+ /**
+ * Update all Channels
+ */
+ protected void updateChannels() {
+ for (Channel channel : getThing().getChannels()) {
+ updateChannel(channel.getUID().getId());
+ }
+ }
+
+ /**
+ * Update the channel state
+ *
+ * @param channelId the id identifying the channel to be updated
+ */
+ protected void updateChannel(String channelId) {
+ if (!isLinked(channelId)) {
+ return;
+ }
+ State state = getState(channelId);
+ if (state != null) {
+ updateState(channelId, state);
+ }
+ }
+
+ /**
+ * Get the state of a given channel
+ *
+ * @param channelId the id identifying the channel to be updated
+ * @return state of the channel
+ */
+ protected @Nullable State getState(String channelId) {
+ MecMeterResponse response = powerMeterResponse;
+ if (response == null) {
+ return null;
+ } else {
+ switch (channelId) {
+ /* General */
+ case MecMeterBindingConstants.FREQUENCY:
+ return new QuantityType<>(response.getFrequency(), Units.HERTZ);
+ case MecMeterBindingConstants.TEMPERATURE:
+ return new QuantityType<>(response.getTemperature(), SIUnits.CELSIUS);
+ case MecMeterBindingConstants.OPERATIONAL_TIME:
+ return new QuantityType<>(response.getOperationalTime() / 1000, Units.SECOND);
+
+ /* Voltage */
+ case MecMeterBindingConstants.VOLTAGE_PHASE_1:
+ return new QuantityType<>(response.getVoltagePhase1(), Units.VOLT);
+ case MecMeterBindingConstants.VOLTAGE_PHASE_2:
+ return new QuantityType<>(response.getVoltagePhase2(), Units.VOLT);
+ case MecMeterBindingConstants.VOLTAGE_PHASE_3:
+ return new QuantityType<>(response.getVoltagePhase3(), Units.VOLT);
+ case MecMeterBindingConstants.VOLTAGE_PHASE_3_TO_PHASE_2:
+ return new QuantityType<>(response.getVoltagePhase3ToPhase2(), Units.VOLT);
+ case MecMeterBindingConstants.VOLTAGE_PHASE_2_TO_PHASE_1:
+ return new QuantityType<>(response.getVoltagePhase2ToPhase1(), Units.VOLT);
+ case MecMeterBindingConstants.VOLTAGE_PHASE_1_TO_PHASE_3:
+ return new QuantityType<>(response.getVoltagePhase1ToPhase3(), Units.VOLT);
+ case MecMeterBindingConstants.AVERAGE_VOLTAGE_PHASE_2_PHASE:
+ return new QuantityType<>(response.getAverageVoltagePhaseToPhase(), Units.VOLT);
+ case MecMeterBindingConstants.AVERAGE_VOLTAGE_NEUTRAL_2_PHASE:
+ return new QuantityType<>(response.getAverageVoltageNeutralToPhase(), Units.VOLT);
+
+ /* Current */
+ case MecMeterBindingConstants.CURRENT_PHASE_1:
+ return new QuantityType<>(response.getCurrentPhase1(), Units.AMPERE);
+ case MecMeterBindingConstants.CURRENT_PHASE_2:
+ return new QuantityType<>(response.getCurrentPhase2(), Units.AMPERE);
+ case MecMeterBindingConstants.CURRENT_PHASE_3:
+ return new QuantityType<>(response.getCurrentPhase3(), Units.AMPERE);
+ case MecMeterBindingConstants.CURRENT_SUM:
+ return new QuantityType<>(response.getCurrentSum(), Units.AMPERE);
+
+ /* Angles */
+ case MecMeterBindingConstants.PHASE_ANGLE_TO_CURRENT_PHASE_1:
+ return new QuantityType<>(response.getPhaseAngleCurrentToVoltagePhase1(), Units.DEGREE_ANGLE);
+ case MecMeterBindingConstants.PHASE_ANGLE_TO_CURRENT_PHASE_2:
+ return new QuantityType<>(response.getPhaseAngleCurrentToVoltagePhase2(), Units.DEGREE_ANGLE);
+ case MecMeterBindingConstants.PHASE_ANGLE_TO_CURRENT_PHASE_3:
+ return new QuantityType<>(response.getPhaseAngleCurrentToVoltagePhase3(), Units.DEGREE_ANGLE);
+ case MecMeterBindingConstants.PHASE_ANGLE_PHASE_1_3:
+ return new QuantityType<>(response.getPhaseAnglePhase1To3(), Units.DEGREE_ANGLE);
+ case MecMeterBindingConstants.PHASE_ANGLE_PHASE_2_3:
+ return new QuantityType<>(response.getPhaseAnglePhase2To3(), Units.DEGREE_ANGLE);
+
+ /* Power */
+ case MecMeterBindingConstants.ACTIVE_POWER_PHASE_1:
+ return new QuantityType<>(response.getActivePowerPhase1(), Units.WATT);
+ case MecMeterBindingConstants.ACTIVE_POWER_PHASE_2:
+ return new QuantityType<>(response.getActivePowerPhase2(), Units.WATT);
+ case MecMeterBindingConstants.ACTIVE_POWER_PHASE_3:
+ return new QuantityType<>(response.getActivePowerPhase3(), Units.WATT);
+ case MecMeterBindingConstants.ACTIVE_POWER_SUM:
+ return new QuantityType<>(response.getActivePowerSum(), Units.WATT);
+ case MecMeterBindingConstants.ACTIVE_FUND_POWER_PHASE_1:
+ return new QuantityType<>(response.getActiveFundamentalPowerPhase1(), Units.WATT);
+ case MecMeterBindingConstants.ACTIVE_FUND_POWER_PHASE_2:
+ return new QuantityType<>(response.getActiveFundamentalPowerPhase2(), Units.WATT);
+ case MecMeterBindingConstants.ACTIVE_FUND_POWER_PHASE_3:
+ return new QuantityType<>(response.getActiveFundamentalPowerPhase3(), Units.WATT);
+ case MecMeterBindingConstants.ACTIVE_FUND_POWER_ALL:
+ return new QuantityType<>(response.getActiveFundamentalPowerSum(), Units.WATT);
+ case MecMeterBindingConstants.ACTIVE_HARM_POWER_PHASE_1:
+ return new QuantityType<>(response.getActiveHarmonicPowerPhase1(), Units.WATT);
+ case MecMeterBindingConstants.ACTIVE_HARM_POWER_PHASE_2:
+ return new QuantityType<>(response.getActiveHarmonicPowerPhase2(), Units.WATT);
+ case MecMeterBindingConstants.ACTIVE_HARM_POWER_PHASE_3:
+ return new QuantityType<>(response.getActiveHarmonicPowerPhase3(), Units.WATT);
+ case MecMeterBindingConstants.ACTIVE_HARM_POWER_ALL:
+ return new QuantityType<>(response.getActiveHarmonicPowerSum(), Units.WATT);
+ case MecMeterBindingConstants.REACTIVE_POWER_PHASE_1:
+ return new QuantityType<>(response.getReactivePowerPhase1(), Units.VAR);
+ case MecMeterBindingConstants.REACTIVE_POWER_PHASE_2:
+ return new QuantityType<>(response.getReactivePowerPhase2(), Units.VAR);
+ case MecMeterBindingConstants.REACTIVE_POWER_PHASE_3:
+ return new QuantityType<>(response.getReactivePowerPhase3(), Units.VAR);
+ case MecMeterBindingConstants.REACTIVE_POWER_ALL:
+ return new QuantityType<>(response.getReactivePowerSum(), Units.VAR);
+ case MecMeterBindingConstants.APP_POWER_PHASE_1:
+ return new QuantityType<>(response.getApparentPowerPhase1(), Units.VOLT_AMPERE);
+ case MecMeterBindingConstants.APP_POWER_PHASE_2:
+ return new QuantityType<>(response.getApparentPowerPhase2(), Units.VOLT_AMPERE);
+ case MecMeterBindingConstants.APP_POWER_PHASE_3:
+ return new QuantityType<>(response.getApparentPowerPhase3(), Units.VOLT_AMPERE);
+ case MecMeterBindingConstants.APP_POWER_ALL:
+ return new QuantityType<>(response.getApparentPowerSum(), Units.VOLT_AMPERE);
+
+ /* Forward Energy */
+ case MecMeterBindingConstants.FORWARD_ACTIVE_ENERGY_PHASE_1:
+ return new QuantityType<>(response.getForwardActiveEnergyPhase1(), Units.KILOWATT_HOUR);
+ case MecMeterBindingConstants.FORWARD_ACTIVE_ENERGY_PHASE_2:
+ return new QuantityType<>(response.getForwardActiveEnergyPhase2(), Units.KILOWATT_HOUR);
+ case MecMeterBindingConstants.FORWARD_ACTIVE_ENERGY_PHASE_3:
+ return new QuantityType<>(response.getForwardActiveEnergyPhase3(), Units.KILOWATT_HOUR);
+ case MecMeterBindingConstants.FORWARD_ACTIVE_ENERGY_ALL:
+ return new QuantityType<>(response.getForwardActiveEnergySum(), Units.KILOWATT_HOUR);
+ case MecMeterBindingConstants.FORWARD_ACTIVE_FUND_ENERGY_PHASE_1:
+ return new QuantityType<>(response.getForwardActiveFundamentalEnergyPhase1(), Units.KILOWATT_HOUR);
+ case MecMeterBindingConstants.FORWARD_ACTIVE_FUND_ENERGY_PHASE_2:
+ return new QuantityType<>(response.getForwardActiveFundamentalEnergyPhase2(), Units.KILOWATT_HOUR);
+ case MecMeterBindingConstants.FORWARD_ACTIVE_FUND_ENERGY_PHASE_3:
+ return new QuantityType<>(response.getForwardActiveFundamentalEnergyPhase3(), Units.KILOWATT_HOUR);
+ case MecMeterBindingConstants.FORWARD_ACTIVE_FUND_ENERGY_ALL:
+ return new QuantityType<>(response.getForwardActiveFundamentalEnergySum(), Units.KILOWATT_HOUR);
+ case MecMeterBindingConstants.FORWARD_ACTIVE_HARM_ENERGY_PHASE_1:
+ return new QuantityType<>(response.getForwardActiveHarmonicEnergyPhase1(), Units.KILOWATT_HOUR);
+ case MecMeterBindingConstants.FORWARD_ACTIVE_HARM_ENERGY_PHASE_2:
+ return new QuantityType<>(response.getForwardActiveHarmonicEnergyPhase2(), Units.KILOWATT_HOUR);
+ case MecMeterBindingConstants.FORWARD_ACTIVE_HARM_ENERGY_PHASE_3:
+ return new QuantityType<>(response.getForwardActiveHarmonicEnergyPhase3(), Units.KILOWATT_HOUR);
+ case MecMeterBindingConstants.FORWARD_ACTIVE_HARM_ENERGY_ALL:
+ return new QuantityType<>(response.getForwardActiveHarmonicEnergySum(), Units.KILOWATT_HOUR);
+ case MecMeterBindingConstants.FORWARD_REACTIVE_ENERGY_PHASE_1:
+ return new QuantityType<>(response.getForwardReactiveEnergyPhase1(), Units.VAR_HOUR);
+ case MecMeterBindingConstants.FORWARD_REACTIVE_ENERGY_PHASE_2:
+ return new QuantityType<>(response.getForwardReactiveEnergyPhase2(), Units.VAR_HOUR);
+ case MecMeterBindingConstants.FORWARD_REACTIVE_ENERGY_PHASE_3:
+ return new QuantityType<>(response.getForwardReactiveEnergyPhase3(), Units.VAR_HOUR);
+ case MecMeterBindingConstants.FORWARD_REACTIVE_ENERGY_ALL:
+ return new QuantityType<>(response.getForwardReactiveEnergySum(), Units.VAR_HOUR);
+
+ /* Reverse Energy */
+ case MecMeterBindingConstants.REVERSE_ACTIVE_ENERGY_PHASE_1:
+ return new QuantityType<>(response.getReverseActiveEnergyPhase1(), Units.KILOWATT_HOUR);
+ case MecMeterBindingConstants.REVERSE_ACTIVE_ENERGY_PHASE_2:
+ return new QuantityType<>(response.getReverseActiveEnergyPhase2(), Units.KILOWATT_HOUR);
+ case MecMeterBindingConstants.REVERSE_ACTIVE_ENERGY_PHASE_3:
+ return new QuantityType<>(response.getReverseActiveEnergyPhase3(), Units.KILOWATT_HOUR);
+ case MecMeterBindingConstants.REVERSE_ACTIVE_ENERGY_ALL:
+ return new QuantityType<>(response.getReverseActiveEnergySum(), Units.KILOWATT_HOUR);
+ case MecMeterBindingConstants.REVERSE_ACTIVE_FUND_ENERGY_PHASE_1:
+ return new QuantityType<>(response.getReverseActiveFundamentalEnergyPhase1(), Units.KILOWATT_HOUR);
+ case MecMeterBindingConstants.REVERSE_ACTIVE_FUND_ENERGY_PHASE_2:
+ return new QuantityType<>(response.getReverseActiveFundamentalEnergyPhase2(), Units.KILOWATT_HOUR);
+ case MecMeterBindingConstants.REVERSE_ACTIVE_FUND_ENERGY_PHASE_3:
+ return new QuantityType<>(response.getReverseActiveFundamentalEnergyPhase3(), Units.KILOWATT_HOUR);
+ case MecMeterBindingConstants.REVERSE_ACTIVE_FUND_ENERGY_ALL:
+ return new QuantityType<>(response.getReverseActiveFundamentalEnergySum(), Units.KILOWATT_HOUR);
+ case MecMeterBindingConstants.REVERSE_ACTIVE_HARM_ENERGY_PHASE_1:
+ return new QuantityType<>(response.getReverseActiveHarmonicEnergyPhase1(), Units.KILOWATT_HOUR);
+ case MecMeterBindingConstants.REVERSE_ACTIVE_HARM_ENERGY_PHASE_2:
+ return new QuantityType<>(response.getReverseActiveHarmonicEnergyPhase2(), Units.KILOWATT_HOUR);
+ case MecMeterBindingConstants.REVERSE_ACTIVE_HARM_ENERGY_PHASE_3:
+ return new QuantityType<>(response.getReverseActiveHarmonicEnergyPhase3(), Units.KILOWATT_HOUR);
+ case MecMeterBindingConstants.REVERSE_ACTIVE_HARM_ENERGY_ALL:
+ return new QuantityType<>(response.getReverseActiveHarmonicEnergySum(), Units.KILOWATT_HOUR);
+ case MecMeterBindingConstants.REVERSE_REACTIVE_ENERGY_PHASE_1:
+ return new QuantityType<>(response.getReverseReactiveEnergyPhase1(), Units.VAR_HOUR);
+ case MecMeterBindingConstants.REVERSE_REACTIVE_ENERGY_PHASE_2:
+ return new QuantityType<>(response.getReverseReactiveEnergyPhase2(), Units.VAR_HOUR);
+ case MecMeterBindingConstants.REVERSE_REACTIVE_ENERGY_PHASE_3:
+ return new QuantityType<>(response.getReverseReactiveEnergyPhase3(), Units.VAR_HOUR);
+ case MecMeterBindingConstants.REVERSE_REACTIVE_ENERGY_ALL:
+ return new QuantityType<>(response.getReverseReactiveEnergySum(), Units.VAR_HOUR);
+
+ /* Apparent Energy */
+ case MecMeterBindingConstants.APP_ENERGY_PHASE_1:
+ return new QuantityType<>(response.getApparentEnergyConsumptionPhase1(), Units.VOLT_AMPERE_HOUR);
+ case MecMeterBindingConstants.APP_ENERGY_PHASE_2:
+ return new QuantityType<>(response.getApparentEnergyConsumptionPhase2(), Units.VOLT_AMPERE_HOUR);
+ case MecMeterBindingConstants.APP_ENERGY_PHASE_3:
+ return new QuantityType<>(response.getApparentEnergyConsumptionPhase3(), Units.VOLT_AMPERE_HOUR);
+ case MecMeterBindingConstants.APP_ENERGY_ALL:
+ return new QuantityType<>(response.getApparentEnergyConsumptionSum(), Units.VOLT_AMPERE_HOUR);
+
+ /* Power Factor */
+ case MecMeterBindingConstants.POWER_FACTOR_PHASE_1:
+ return new QuantityType<>(response.getPowerFactorPhase1(), Units.ONE);
+ case MecMeterBindingConstants.POWER_FACTOR_PHASE_2:
+ return new QuantityType<>(response.getPowerFactorPhase2(), Units.ONE);
+ case MecMeterBindingConstants.POWER_FACTOR_PHASE_3:
+ return new QuantityType<>(response.getPowerFactorPhase3(), Units.ONE);
+ case MecMeterBindingConstants.POWER_FACTOR_ALL:
+ return new QuantityType<>(response.getPowerFactorSum(), Units.ONE);
+ }
+ }
+ return null;
+ }
+}
diff --git a/bundles/org.openhab.binding.mecmeter/src/main/java/org/openhab/binding/mecmeter/internal/MecMeterHandlerFactory.java b/bundles/org.openhab.binding.mecmeter/src/main/java/org/openhab/binding/mecmeter/internal/MecMeterHandlerFactory.java
new file mode 100644
index 000000000..f26fca199
--- /dev/null
+++ b/bundles/org.openhab.binding.mecmeter/src/main/java/org/openhab/binding/mecmeter/internal/MecMeterHandlerFactory.java
@@ -0,0 +1,65 @@
+/**
+ * Copyright (c) 2010-2021 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.mecmeter.internal;
+
+import static org.openhab.binding.mecmeter.MecMeterBindingConstants.THING_TYPE_METER;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.jetty.client.HttpClient;
+import org.openhab.binding.mecmeter.MecMeterBindingConstants;
+import org.openhab.binding.mecmeter.handler.MecMeterHandler;
+import org.openhab.core.io.net.http.HttpClientFactory;
+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.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+
+/**
+ * The {@link MecMeterHandlerFactory} is responsible for creating things and thing
+ * handlers.
+ *
+ * @author Florian Pazour - Initial contribution
+ * @author Klaus Berger - Initial contribution
+ * @author Kai Kreuzer - Refactoring for openHAB 3
+ */
+@NonNullByDefault
+@Component(service = ThingHandlerFactory.class, configurationPid = "binding.mecmeter")
+public class MecMeterHandlerFactory extends BaseThingHandlerFactory {
+
+ private final HttpClient httpClient;
+
+ @Activate
+ public MecMeterHandlerFactory(@Reference HttpClientFactory httpClientFactory) {
+ httpClient = httpClientFactory.getCommonHttpClient();
+ }
+
+ @Override
+ public boolean supportsThingType(ThingTypeUID thingTypeUID) {
+ return MecMeterBindingConstants.SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
+ }
+
+ @Override
+ protected @Nullable ThingHandler createHandler(Thing thing) {
+ ThingTypeUID thingTypeUID = thing.getThingTypeUID();
+
+ if (thingTypeUID.equals(THING_TYPE_METER)) {
+ return new MecMeterHandler(thing, httpClient);
+ }
+ return null;
+ }
+}
diff --git a/bundles/org.openhab.binding.mecmeter/src/main/java/org/openhab/binding/mecmeter/internal/discovery/MecMeterDiscoveryParticipant.java b/bundles/org.openhab.binding.mecmeter/src/main/java/org/openhab/binding/mecmeter/internal/discovery/MecMeterDiscoveryParticipant.java
new file mode 100644
index 000000000..b6b6762d3
--- /dev/null
+++ b/bundles/org.openhab.binding.mecmeter/src/main/java/org/openhab/binding/mecmeter/internal/discovery/MecMeterDiscoveryParticipant.java
@@ -0,0 +1,119 @@
+/**
+ * Copyright (c) 2010-2021 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.mecmeter.internal.discovery;
+
+import static org.openhab.binding.mecmeter.MecMeterBindingConstants.THING_TYPE_METER;
+
+import java.net.InetAddress;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.jmdns.ServiceInfo;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.mecmeter.MecMeterBindingConstants;
+import org.openhab.core.config.discovery.DiscoveryResult;
+import org.openhab.core.config.discovery.DiscoveryResultBuilder;
+import org.openhab.core.config.discovery.mdns.MDNSDiscoveryParticipant;
+import org.openhab.core.thing.Thing;
+import org.openhab.core.thing.ThingTypeUID;
+import org.openhab.core.thing.ThingUID;
+import org.osgi.service.component.annotations.Component;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The {@link MecMeterDiscoveryParticipant} is responsible for discovering devices, which are
+ * sent to inbox.
+ *
+ * @author Florian Pazour - Initial contribution
+ * @author Klaus Berger - Initial contribution
+ * @author Kai Kreuzer - Refactoring for openHAB 3
+ */
+@NonNullByDefault
+@Component(service = MDNSDiscoveryParticipant.class)
+public class MecMeterDiscoveryParticipant implements MDNSDiscoveryParticipant {
+
+ private Logger logger = LoggerFactory.getLogger(MecMeterDiscoveryParticipant.class);
+ private static final String SERVICE_TYPE = "_http._tcp.local.";
+
+ /**
+ * Match the serial number, vendor and model of the discovered PowerMeter.
+ * Input is like "vpmAA11BB33CC55"
+ */
+ private static final Pattern MECMETER_PATTERN = Pattern
+ .compile("^(vpm|mec)[A-F0-9]{12}\\._http\\._tcp\\.local\\.$");
+
+ @Override
+ public Set getSupportedThingTypeUIDs() {
+ return MecMeterBindingConstants.SUPPORTED_THING_TYPES_UIDS;
+ }
+
+ @Override
+ public String getServiceType() {
+ return SERVICE_TYPE;
+ }
+
+ @Override
+ public @Nullable DiscoveryResult createResult(ServiceInfo service) {
+ String qualifiedName = service.getQualifiedName();
+ logger.debug("Device found: {}", qualifiedName);
+ ThingUID uid = getThingUID(service);
+ if (uid == null) {
+ return null;
+ }
+
+ String serial = qualifiedName.substring(3, 15);
+ String vendor = "MEC";
+
+ InetAddress ip = getIpAddress(service);
+ if (ip == null) {
+ return null;
+ }
+ String inetAddress = ip.toString().substring(1);
+
+ Map properties = new HashMap<>(3);
+ properties.put(Thing.PROPERTY_SERIAL_NUMBER, serial);
+ properties.put(Thing.PROPERTY_VENDOR, vendor);
+ properties.put("ip", inetAddress);
+
+ String label = "MEC Power Meter";
+ return DiscoveryResultBuilder.create(uid).withProperties(properties).withLabel(label)
+ .withRepresentationProperty(Thing.PROPERTY_SERIAL_NUMBER).build();
+ }
+
+ private @Nullable InetAddress getIpAddress(ServiceInfo service) {
+ if (service.getInet4Addresses().length > 0) {
+ return service.getInet4Addresses()[0];
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public @Nullable ThingUID getThingUID(ServiceInfo service) {
+ Matcher matcher = MECMETER_PATTERN.matcher(service.getQualifiedName());
+ if (matcher.matches()) {
+ String serial = service.getQualifiedName().substring(3, 15); // Qualified Name like "mecABCDEF123456", we
+ // want "ABCDEF123456"
+ return new ThingUID(THING_TYPE_METER, serial);
+ } else {
+ logger.debug("The discovered device is not supported, ignoring it.");
+ }
+ return null;
+ }
+}
diff --git a/bundles/org.openhab.binding.mecmeter/src/main/java/org/openhab/binding/mecmeter/internal/dto/MecMeterResponse.java b/bundles/org.openhab.binding.mecmeter/src/main/java/org/openhab/binding/mecmeter/internal/dto/MecMeterResponse.java
new file mode 100644
index 000000000..bcd042707
--- /dev/null
+++ b/bundles/org.openhab.binding.mecmeter/src/main/java/org/openhab/binding/mecmeter/internal/dto/MecMeterResponse.java
@@ -0,0 +1,856 @@
+/**
+ * Copyright (c) 2010-2021 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.mecmeter.internal.dto;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * The {@link MecMeterResponse} is responsible for storing
+ * the "data" node of the JSON response
+ *
+ * @author Florian Pazour - Initial contribution
+ * @author Klaus Berger - Initial contribution
+ * @author Kai Kreuzer - Refactoring for openHAB 3
+ */
+public class MecMeterResponse {
+ /* General */
+ @SerializedName("F")
+ private float frequency;
+ @SerializedName("T")
+ private float temperature;
+ @SerializedName("TIME")
+ private long operationalTime;
+
+ /* Voltage */
+ @SerializedName("VA")
+ private float voltagePhase1;
+ @SerializedName("VB")
+ private float voltagePhase2;
+ @SerializedName("VC")
+ private float voltagePhase3;
+ @SerializedName("VCB")
+ private float voltagePhase3ToPhase2;
+ @SerializedName("VBA")
+ private float voltagePhase2ToPhase1;
+ @SerializedName("VAC")
+ private float voltagePhase1ToPhase3;
+ @SerializedName("VPT")
+ private float averageVoltagePhaseToPhase;
+ @SerializedName("VT")
+ private float averageVoltageNeutralToPhase;
+
+ /* Current */
+ @SerializedName("IA")
+ private float currentPhase1;
+ @SerializedName("IB")
+ private float currentPhase2;
+ @SerializedName("IC")
+ private float currentPhase3;
+ @SerializedName("IN")
+ private float currentSum;
+
+ /* Angles */
+ @SerializedName("IAA")
+ private float phaseAngleCurrentToVoltagePhase1;
+ @SerializedName("IAB")
+ private float phaseAngleCurrentToVoltagePhase2;
+ @SerializedName("IAC")
+ private float phaseAngleCurrentToVoltagePhase3;
+ @SerializedName("UAA")
+ private float phaseAnglePhase1To3;
+ @SerializedName("UAB")
+ private float phaseAnglePhase2To3;
+
+ /* Power */
+ @SerializedName("PA")
+ private float activePowerPhase1;
+ @SerializedName("PB")
+ private float activePowerPhase2;
+ @SerializedName("PC")
+ private float activePowerPhase3;
+ @SerializedName("PT")
+ private float activePowerSum;
+
+ @SerializedName("PAF")
+ private float activeFundamentalPowerPhase1;
+ @SerializedName("PBF")
+ private float activeFundamentalPowerPhase2;
+ @SerializedName("PCF")
+ private float activeFundamentalPowerPhase3;
+ @SerializedName("PTF")
+ private float activeFundamentalPowerSum;
+
+ @SerializedName("PFA")
+ private float powerFactorPhase1;
+ @SerializedName("PFB")
+ private float powerFactorPhase2;
+ @SerializedName("PFC")
+ private float powerFactorPhase3;
+ @SerializedName("PFT")
+ private float powerFactorSum;
+
+ @SerializedName("PAH")
+ private float activeHarmonicPowerPhase1;
+ @SerializedName("PBH")
+ private float activeHarmonicPowerPhase2;
+ @SerializedName("PCH")
+ private float activeHarmonicPowerPhase3;
+ @SerializedName("PTH")
+ private float activeHarmonicPowerSum;
+
+ @SerializedName("QA")
+ private float reactivePowerPhase1;
+ @SerializedName("QB")
+ private float reactivePowerPhase2;
+ @SerializedName("QC")
+ private float reactivePowerPhase3;
+ @SerializedName("QT")
+ private float reactivePowerSum;
+
+ @SerializedName("SA")
+ private float apparentPowerPhase1;
+ @SerializedName("SB")
+ private float apparentPowerPhase2;
+ @SerializedName("SC")
+ private float apparentPowerPhase3;
+ @SerializedName("ST")
+ private float apparentPowerSum;
+
+ /* Forward Energy */
+ @SerializedName("EFAA")
+ private float forwardActiveEnergyPhase1;
+ @SerializedName("EFAB")
+ private float forwardActiveEnergyPhase2;
+ @SerializedName("EFAC")
+ private float forwardActiveEnergyPhase3;
+ @SerializedName("EFAT")
+ private float forwardActiveEnergySum;
+
+ @SerializedName("EFAF")
+ private float forwardActiveFundamentalEnergyPhase1;
+ @SerializedName("EFBF")
+ private float forwardActiveFundamentalEnergyPhase2;
+ @SerializedName("EFCF")
+ private float forwardActiveFundamentalEnergyPhase3;
+ @SerializedName("EFTF")
+ private float forwardActiveFundamentalEnergySum;
+
+ @SerializedName("EFAH")
+ private float forwardActiveHarmonicEnergyPhase1;
+ @SerializedName("EFBH")
+ private float forwardActiveHarmonicEnergyPhase2;
+ @SerializedName("EFCH")
+ private float forwardActiveHarmonicEnergyPhase3;
+ @SerializedName("EFTH")
+ private float forwardActiveHarmonicEnergySum;
+
+ @SerializedName("EFRA")
+ private float forwardReactiveEnergyPhase1;
+ @SerializedName("EFRB")
+ private float forwardReactiveEnergyPhase2;
+ @SerializedName("EFRC")
+ private float forwardReactiveEnergyPhase3;
+ @SerializedName("EFRT")
+ private float forwardReactiveEnergySum;
+
+ /* Reverse Energy */
+ @SerializedName("ERAA")
+ private float reverseActiveEnergyPhase1;
+ @SerializedName("ERAB")
+ private float reverseActiveEnergyPhase2;
+ @SerializedName("ERAC")
+ private float reverseActiveEnergyPhase3;
+ @SerializedName("ERAT")
+ private float reverseActiveEnergySum;
+
+ @SerializedName("ERAF")
+ private float reverseActiveFundamentalEnergyPhase1;
+ @SerializedName("ERBF")
+ private float reverseActiveFundamentalEnergyPhase2;
+ @SerializedName("ERCF")
+ private float reverseActiveFundamentalEnergyPhase3;
+ @SerializedName("ERTF")
+ private float reverseActiveFundamentalEnergySum;
+
+ @SerializedName("ERAH")
+ private float reverseActiveHarmonicEnergyPhase1;
+ @SerializedName("ERBH")
+ private float reverseActiveHarmonicEnergyPhase2;
+ @SerializedName("ERCH")
+ private float reverseActiveHarmonicEnergyPhase3;
+ @SerializedName("ERTH")
+ private float reverseActiveHarmonicEnergySum;
+
+ @SerializedName("ERRA")
+ private float reverseReactiveEnergyPhase1;
+ @SerializedName("ERRB")
+ private float reverseReactiveEnergyPhase2;
+ @SerializedName("ERRC")
+ private float reverseReactiveEnergyPhase3;
+ @SerializedName("ERRT")
+ private float reverseReactiveEnergySum;
+
+ /* apparent Energy */
+ @SerializedName("ESA")
+ private float apparentEnergyConsumptionPhase1;
+ @SerializedName("ESB")
+ private float apparentEnergyConsumptionPhase2;
+ @SerializedName("ESC")
+ private float apparentEnergyConsumptionPhase3;
+ @SerializedName("EST")
+ private float apparentEnergyConsumptionSum;
+
+ /* Constants */
+ private static final int KILO = 1000;
+
+ /* Getters and Setters */
+ public float getFrequency() {
+ return frequency;
+ }
+
+ public void setFrequency(float frequency) {
+ this.frequency = frequency;
+ }
+
+ public float getTemperature() {
+ return temperature;
+ }
+
+ public void setTemperature(float temperature) {
+ this.temperature = temperature;
+ }
+
+ public long getOperationalTime() {
+ return operationalTime;
+ }
+
+ public void setOperationalTime(long operationalTime) {
+ this.operationalTime = operationalTime;
+ }
+
+ public float getVoltagePhase1() {
+ return voltagePhase1;
+ }
+
+ public void setVoltagePhase1(float voltagePhase1) {
+ this.voltagePhase1 = voltagePhase1;
+ }
+
+ public float getVoltagePhase2() {
+ return voltagePhase2;
+ }
+
+ public void setVoltagePhase2(float voltagePhase2) {
+ this.voltagePhase2 = voltagePhase2;
+ }
+
+ public float getVoltagePhase3() {
+ return voltagePhase3;
+ }
+
+ public void setVoltagePhase3(float voltagePhase3) {
+ this.voltagePhase3 = voltagePhase3;
+ }
+
+ public float getVoltagePhase3ToPhase2() {
+ return voltagePhase3ToPhase2;
+ }
+
+ public void setVoltagePhase3ToPhase2(float voltagePhase3ToPhase2) {
+ this.voltagePhase3ToPhase2 = voltagePhase3ToPhase2;
+ }
+
+ public float getVoltagePhase2ToPhase1() {
+ return voltagePhase2ToPhase1;
+ }
+
+ public void setVoltagePhase2ToPhase1(float voltagePhase2ToPhase1) {
+ this.voltagePhase2ToPhase1 = voltagePhase2ToPhase1;
+ }
+
+ public float getVoltagePhase1ToPhase3() {
+ return voltagePhase1ToPhase3;
+ }
+
+ public void setVoltagePhase1ToPhase3(float voltagePhase1ToPhase3) {
+ this.voltagePhase1ToPhase3 = voltagePhase1ToPhase3;
+ }
+
+ public float getAverageVoltagePhaseToPhase() {
+ return averageVoltagePhaseToPhase;
+ }
+
+ public void setAverageVoltagePhaseToPhase(float averageVoltagePhaseToPhase) {
+ this.averageVoltagePhaseToPhase = averageVoltagePhaseToPhase;
+ }
+
+ public float getAverageVoltageNeutralToPhase() {
+ return averageVoltageNeutralToPhase;
+ }
+
+ public void setAverageVoltageNeutralToPhase(float averageVoltageNeutralToPhase) {
+ this.averageVoltageNeutralToPhase = averageVoltageNeutralToPhase;
+ }
+
+ public float getCurrentPhase1() {
+ return currentPhase1;
+ }
+
+ public void setCurrentPhase1(float currentPhase1) {
+ this.currentPhase1 = currentPhase1;
+ }
+
+ public float getCurrentPhase2() {
+ return currentPhase2;
+ }
+
+ public void setCurrentPhase2(float currentPhase2) {
+ this.currentPhase2 = currentPhase2;
+ }
+
+ public float getCurrentPhase3() {
+ return currentPhase3;
+ }
+
+ public void setCurrentPhase3(float currentPhase3) {
+ this.currentPhase3 = currentPhase3;
+ }
+
+ public float getCurrentSum() {
+ return currentSum;
+ }
+
+ public void setCurrentSum(float currentSum) {
+ this.currentSum = currentSum;
+ }
+
+ public float getPhaseAngleCurrentToVoltagePhase1() {
+ return phaseAngleCurrentToVoltagePhase1;
+ }
+
+ public void setPhaseAngleCurrentToVoltagePhase1(float phaseAngleCurrentToVoltagePhase1) {
+ this.phaseAngleCurrentToVoltagePhase1 = phaseAngleCurrentToVoltagePhase1;
+ }
+
+ public float getPhaseAngleCurrentToVoltagePhase2() {
+ return phaseAngleCurrentToVoltagePhase2;
+ }
+
+ public void setPhaseAngleCurrentToVoltagePhase2(float phaseAngleCurrentToVoltagePhase2) {
+ this.phaseAngleCurrentToVoltagePhase2 = phaseAngleCurrentToVoltagePhase2;
+ }
+
+ public float getPhaseAngleCurrentToVoltagePhase3() {
+ return phaseAngleCurrentToVoltagePhase3;
+ }
+
+ public void setPhaseAngleCurrentToVoltagePhase3(float phaseAngleCurrentToVoltagePhase3) {
+ this.phaseAngleCurrentToVoltagePhase3 = phaseAngleCurrentToVoltagePhase3;
+ }
+
+ public float getPhaseAnglePhase1To3() {
+ return phaseAnglePhase1To3;
+ }
+
+ public void setPhaseAnglePhase1To3(float phaseAnglePhase1To3) {
+ this.phaseAnglePhase1To3 = phaseAnglePhase1To3;
+ }
+
+ public float getPhaseAnglePhase2To3() {
+ return phaseAnglePhase2To3;
+ }
+
+ public void setPhaseAnglePhase2To3(float phaseAnglePhase2To3) {
+ this.phaseAnglePhase2To3 = phaseAnglePhase2To3;
+ }
+
+ public float getActivePowerPhase1() {
+ return activePowerPhase1;
+ }
+
+ public void setActivePowerPhase1(float activePowerPhase1) {
+ this.activePowerPhase1 = activePowerPhase1;
+ }
+
+ public float getActivePowerPhase2() {
+ return activePowerPhase2;
+ }
+
+ public void setActivePowerPhase2(float activePowerPhase2) {
+ this.activePowerPhase2 = activePowerPhase2;
+ }
+
+ public float getActivePowerPhase3() {
+ return activePowerPhase3;
+ }
+
+ public void setActivePowerPhase3(float activePowerPhase3) {
+ this.activePowerPhase3 = activePowerPhase3;
+ }
+
+ public float getActivePowerSum() {
+ return activePowerSum;
+ }
+
+ public void setActivePowerSum(float activePowerSum) {
+ this.activePowerSum = activePowerSum;
+ }
+
+ public float getActiveFundamentalPowerPhase1() {
+ return activeFundamentalPowerPhase1;
+ }
+
+ public void setActiveFundamentalPowerPhase1(float activeFundamentalPowerPhase1) {
+ this.activeFundamentalPowerPhase1 = activeFundamentalPowerPhase1;
+ }
+
+ public float getPowerFactorPhase1() {
+ return powerFactorPhase1;
+ }
+
+ public void setPowerFactorPhase1(float powerFactorPhase1) {
+ this.powerFactorPhase1 = powerFactorPhase1;
+ }
+
+ public float getPowerFactorPhase2() {
+ return powerFactorPhase2;
+ }
+
+ public void setPowerFactorPhase2(float powerFactorPhase2) {
+ this.powerFactorPhase2 = powerFactorPhase2;
+ }
+
+ public float getPowerFactorPhase3() {
+ return powerFactorPhase3;
+ }
+
+ public void setPowerFactorPhase3(float powerFactorPhase3) {
+ this.powerFactorPhase3 = powerFactorPhase3;
+ }
+
+ public float getPowerFactorSum() {
+ return powerFactorSum;
+ }
+
+ public void setPowerFactorSum(float powerFactorSum) {
+ this.powerFactorSum = powerFactorSum;
+ }
+
+ public float getActiveFundamentalPowerPhase2() {
+ return activeFundamentalPowerPhase2;
+ }
+
+ public void setActiveFundamentalPowerPhase2(float activeFundamentalPowerPhase2) {
+ this.activeFundamentalPowerPhase2 = activeFundamentalPowerPhase2;
+ }
+
+ public float getActiveFundamentalPowerPhase3() {
+ return activeFundamentalPowerPhase3;
+ }
+
+ public void setActiveFundamentalPowerPhase3(float activeFundamentalPowerPhase3) {
+ this.activeFundamentalPowerPhase3 = activeFundamentalPowerPhase3;
+ }
+
+ public float getActiveFundamentalPowerSum() {
+ return activeFundamentalPowerSum;
+ }
+
+ public void setActiveFundamentalPowerSum(float activeFundamentalPowerSum) {
+ this.activeFundamentalPowerSum = activeFundamentalPowerSum;
+ }
+
+ public float getActiveHarmonicPowerPhase1() {
+ return activeHarmonicPowerPhase1;
+ }
+
+ public void setActiveHarmonicPowerPhase1(float activeHarmonicPowerPhase1) {
+ this.activeHarmonicPowerPhase1 = activeHarmonicPowerPhase1;
+ }
+
+ public float getActiveHarmonicPowerPhase2() {
+ return activeHarmonicPowerPhase2;
+ }
+
+ public void setActiveHarmonicPowerPhase2(float activeHarmonicPowerPhase2) {
+ this.activeHarmonicPowerPhase2 = activeHarmonicPowerPhase2;
+ }
+
+ public float getActiveHarmonicPowerPhase3() {
+ return activeHarmonicPowerPhase3;
+ }
+
+ public void setActiveHarmonicPowerPhase3(float activeHarmonicPowerPhase3) {
+ this.activeHarmonicPowerPhase3 = activeHarmonicPowerPhase3;
+ }
+
+ public float getActiveHarmonicPowerSum() {
+ return activeHarmonicPowerSum;
+ }
+
+ public void setActiveHarmonicPowerSum(float activeHarmonicPowerSum) {
+ this.activeHarmonicPowerSum = activeHarmonicPowerSum;
+ }
+
+ public float getReactivePowerPhase1() {
+ return reactivePowerPhase1;
+ }
+
+ public void setReactivePowerPhase1(float reactivePowerPhase1) {
+ this.reactivePowerPhase1 = reactivePowerPhase1;
+ }
+
+ public float getReactivePowerPhase2() {
+ return reactivePowerPhase2;
+ }
+
+ public void setReactivePowerPhase2(float reactivePowerPhase2) {
+ this.reactivePowerPhase2 = reactivePowerPhase2;
+ }
+
+ public float getReactivePowerPhase3() {
+ return reactivePowerPhase3;
+ }
+
+ public void setReactivePowerPhase3(float reactivePowerPhase3) {
+ this.reactivePowerPhase3 = reactivePowerPhase3;
+ }
+
+ public float getReactivePowerSum() {
+ return reactivePowerSum;
+ }
+
+ public void setReactivePowerSum(float reactivePowerSum) {
+ this.reactivePowerSum = reactivePowerSum;
+ }
+
+ public float getApparentPowerPhase1() {
+ return apparentPowerPhase1;
+ }
+
+ public void setApparentPowerPhase1(float apparentPowerPhase1) {
+ this.apparentPowerPhase1 = apparentPowerPhase1;
+ }
+
+ public float getApparentPowerPhase2() {
+ return apparentPowerPhase2;
+ }
+
+ public void setApparentPowerPhase2(float apparentPowerPhase2) {
+ this.apparentPowerPhase2 = apparentPowerPhase2;
+ }
+
+ public float getApparentPowerPhase3() {
+ return apparentPowerPhase3;
+ }
+
+ public void setApparentPowerPhase3(float apparentPowerPhase3) {
+ this.apparentPowerPhase3 = apparentPowerPhase3;
+ }
+
+ public float getApparentPowerSum() {
+ return apparentPowerSum;
+ }
+
+ public void setApparentPowerSum(float apparentPowerSum) {
+ this.apparentPowerSum = apparentPowerSum;
+ }
+
+ public float getForwardActiveEnergyPhase1() {
+ return forwardActiveEnergyPhase1 / KILO;
+ }
+
+ public void setForwardActiveEnergyPhase1(float forwardActiveEnergyPhase1) {
+ this.forwardActiveEnergyPhase1 = forwardActiveEnergyPhase1;
+ }
+
+ public float getForwardActiveEnergyPhase2() {
+ return forwardActiveEnergyPhase2 / KILO;
+ }
+
+ public void setForwardActiveEnergyPhase2(float forwardActiveEnergyPhase2) {
+ this.forwardActiveEnergyPhase2 = forwardActiveEnergyPhase2;
+ }
+
+ public float getForwardActiveEnergyPhase3() {
+ return forwardActiveEnergyPhase3 / KILO;
+ }
+
+ public void setForwardActiveEnergyPhase3(float forwardActiveEnergyPhase3) {
+ this.forwardActiveEnergyPhase3 = forwardActiveEnergyPhase3;
+ }
+
+ public float getForwardActiveEnergySum() {
+ return forwardActiveEnergySum / KILO;
+ }
+
+ public void setForwardActiveEnergySum(float forwardActiveEnergySum) {
+ this.forwardActiveEnergySum = forwardActiveEnergySum;
+ }
+
+ public float getForwardActiveFundamentalEnergyPhase1() {
+ return forwardActiveFundamentalEnergyPhase1 / KILO;
+ }
+
+ public void setForwardActiveFundamentalEnergyPhase1(float forwardActiveFundamentalEnergyPhase1) {
+ this.forwardActiveFundamentalEnergyPhase1 = forwardActiveFundamentalEnergyPhase1;
+ }
+
+ public float getForwardActiveFundamentalEnergyPhase2() {
+ return forwardActiveFundamentalEnergyPhase2 / KILO;
+ }
+
+ public void setForwardActiveFundamentalEnergyPhase2(float forwardActiveFundamentalEnergyPhase2) {
+ this.forwardActiveFundamentalEnergyPhase2 = forwardActiveFundamentalEnergyPhase2;
+ }
+
+ public float getForwardActiveFundamentalEnergyPhase3() {
+ return forwardActiveFundamentalEnergyPhase3 / KILO;
+ }
+
+ public void setForwardActiveFundamentalEnergyPhase3(float forwardActiveFundamentalEnergyPhase3) {
+ this.forwardActiveFundamentalEnergyPhase3 = forwardActiveFundamentalEnergyPhase3;
+ }
+
+ public float getForwardActiveFundamentalEnergySum() {
+ return forwardActiveFundamentalEnergySum / KILO;
+ }
+
+ public void setForwardActiveFundamentalEnergySum(float forwardActiveFundamentalEnergySum) {
+ this.forwardActiveFundamentalEnergySum = forwardActiveFundamentalEnergySum;
+ }
+
+ public float getForwardActiveHarmonicEnergyPhase1() {
+ return forwardActiveHarmonicEnergyPhase1 / KILO;
+ }
+
+ public void setForwardActiveHarmonicEnergyPhase1(float forwardActiveHarmonicEnergyPhase1) {
+ this.forwardActiveHarmonicEnergyPhase1 = forwardActiveHarmonicEnergyPhase1;
+ }
+
+ public float getForwardActiveHarmonicEnergyPhase2() {
+ return forwardActiveHarmonicEnergyPhase2 / KILO;
+ }
+
+ public void setForwardActiveHarmonicEnergyPhase2(float forwardActiveHarmonicEnergyPhase2) {
+ this.forwardActiveHarmonicEnergyPhase2 = forwardActiveHarmonicEnergyPhase2;
+ }
+
+ public float getForwardActiveHarmonicEnergyPhase3() {
+ return forwardActiveHarmonicEnergyPhase3 / KILO;
+ }
+
+ public void setForwardActiveHarmonicEnergyPhase3(float forwardActiveHarmonicEnergyPhase3) {
+ this.forwardActiveHarmonicEnergyPhase3 = forwardActiveHarmonicEnergyPhase3;
+ }
+
+ public float getForwardActiveHarmonicEnergySum() {
+ return forwardActiveHarmonicEnergySum / KILO;
+ }
+
+ public void setForwardActiveHarmonicEnergySum(float forwardActiveHarmonicEnergySum) {
+ this.forwardActiveHarmonicEnergySum = forwardActiveHarmonicEnergySum;
+ }
+
+ public float getForwardReactiveEnergyPhase1() {
+ return forwardReactiveEnergyPhase1;
+ }
+
+ public void setForwardReactiveEnergyPhase1(float forwardReactiveEnergyPhase1) {
+ this.forwardReactiveEnergyPhase1 = forwardReactiveEnergyPhase1;
+ }
+
+ public float getForwardReactiveEnergyPhase2() {
+ return forwardReactiveEnergyPhase2;
+ }
+
+ public void setForwardReactiveEnergyPhase2(float forwardReactiveEnergyPhase2) {
+ this.forwardReactiveEnergyPhase2 = forwardReactiveEnergyPhase2;
+ }
+
+ public float getForwardReactiveEnergyPhase3() {
+ return forwardReactiveEnergyPhase3;
+ }
+
+ public void setForwardReactiveEnergyPhase3(float forwardReactiveEnergyPhase3) {
+ this.forwardReactiveEnergyPhase3 = forwardReactiveEnergyPhase3;
+ }
+
+ public float getForwardReactiveEnergySum() {
+ return forwardReactiveEnergySum;
+ }
+
+ public void setForwardReactiveEnergySum(float forwardReactiveEnergySum) {
+ this.forwardReactiveEnergySum = forwardReactiveEnergySum;
+ }
+
+ public float getReverseActiveEnergyPhase1() {
+ return reverseActiveEnergyPhase1 / KILO;
+ }
+
+ public void setReverseActiveEnergyPhase1(float reverseActiveEnergyPhase1) {
+ this.reverseActiveEnergyPhase1 = reverseActiveEnergyPhase1;
+ }
+
+ public float getReverseActiveEnergyPhase2() {
+ return reverseActiveEnergyPhase2 / KILO;
+ }
+
+ public void setReverseActiveEnergyPhase2(float reverseActiveEnergyPhase2) {
+ this.reverseActiveEnergyPhase2 = reverseActiveEnergyPhase2;
+ }
+
+ public float getReverseActiveEnergyPhase3() {
+ return reverseActiveEnergyPhase3 / KILO;
+ }
+
+ public void setReverseActiveEnergyPhase3(float reverseActiveEnergyPhase3) {
+ this.reverseActiveEnergyPhase3 = reverseActiveEnergyPhase3;
+ }
+
+ public float getReverseActiveEnergySum() {
+ return reverseActiveEnergySum / KILO;
+ }
+
+ public void setReverseActiveEnergySum(float reverseActiveEnergySum) {
+ this.reverseActiveEnergySum = reverseActiveEnergySum;
+ }
+
+ public float getReverseActiveFundamentalEnergyPhase1() {
+ return reverseActiveFundamentalEnergyPhase1 / KILO;
+ }
+
+ public void setReverseActiveFundamentalEnergyPhase1(float reverseActiveFundamentalEnergyPhase1) {
+ this.reverseActiveFundamentalEnergyPhase1 = reverseActiveFundamentalEnergyPhase1;
+ }
+
+ public float getReverseActiveFundamentalEnergyPhase2() {
+ return reverseActiveFundamentalEnergyPhase2 / KILO;
+ }
+
+ public void setReverseActiveFundamentalEnergyPhase2(float reverseActiveFundamentalEnergyPhase2) {
+ this.reverseActiveFundamentalEnergyPhase2 = reverseActiveFundamentalEnergyPhase2;
+ }
+
+ public float getReverseActiveFundamentalEnergyPhase3() {
+ return reverseActiveFundamentalEnergyPhase3 / KILO;
+ }
+
+ public void setReverseActiveFundamentalEnergyPhase3(float reverseActiveFundamentalEnergyPhase3) {
+ this.reverseActiveFundamentalEnergyPhase3 = reverseActiveFundamentalEnergyPhase3;
+ }
+
+ public float getReverseActiveFundamentalEnergySum() {
+ return reverseActiveFundamentalEnergySum / KILO;
+ }
+
+ public void setReverseActiveFundamentalEnergySum(float reverseActiveFundamentalEnergySum) {
+ this.reverseActiveFundamentalEnergySum = reverseActiveFundamentalEnergySum;
+ }
+
+ public float getReverseActiveHarmonicEnergyPhase1() {
+ return reverseActiveHarmonicEnergyPhase1 / KILO;
+ }
+
+ public void setReverseActiveHarmonicEnergyPhase1(float reverseActiveHarmonicEnergyPhase1) {
+ this.reverseActiveHarmonicEnergyPhase1 = reverseActiveHarmonicEnergyPhase1;
+ }
+
+ public float getReverseActiveHarmonicEnergyPhase2() {
+ return reverseActiveHarmonicEnergyPhase2 / KILO;
+ }
+
+ public void setReverseActiveHarmonicEnergyPhase2(float reverseActiveHarmonicEnergyPhase2) {
+ this.reverseActiveHarmonicEnergyPhase2 = reverseActiveHarmonicEnergyPhase2;
+ }
+
+ public float getReverseActiveHarmonicEnergyPhase3() {
+ return reverseActiveHarmonicEnergyPhase3 / KILO;
+ }
+
+ public void setReverseActiveHarmonicEnergyPhase3(float reverseActiveHarmonicEnergyPhase3) {
+ this.reverseActiveHarmonicEnergyPhase3 = reverseActiveHarmonicEnergyPhase3;
+ }
+
+ public float getReverseActiveHarmonicEnergySum() {
+ return reverseActiveHarmonicEnergySum / KILO;
+ }
+
+ public void setReverseActiveHarmonicEnergySum(float reverseActiveHarmonicEnergySum) {
+ this.reverseActiveHarmonicEnergySum = reverseActiveHarmonicEnergySum;
+ }
+
+ public float getReverseReactiveEnergyPhase1() {
+ return reverseReactiveEnergyPhase1;
+ }
+
+ public void setReverseReactiveEnergyPhase1(float reverseReactiveEnergyPhase1) {
+ this.reverseReactiveEnergyPhase1 = reverseReactiveEnergyPhase1;
+ }
+
+ public float getReverseReactiveEnergyPhase2() {
+ return reverseReactiveEnergyPhase2;
+ }
+
+ public void setReverseReactiveEnergyPhase2(float reverseReactiveEnergyPhase2) {
+ this.reverseReactiveEnergyPhase2 = reverseReactiveEnergyPhase2;
+ }
+
+ public float getReverseReactiveEnergyPhase3() {
+ return reverseReactiveEnergyPhase3;
+ }
+
+ public void setReverseReactiveEnergyPhase3(float reverseReactiveEnergyPhase3) {
+ this.reverseReactiveEnergyPhase3 = reverseReactiveEnergyPhase3;
+ }
+
+ public float getReverseReactiveEnergySum() {
+ return reverseReactiveEnergySum;
+ }
+
+ public void setReverseReactiveEnergySum(float reverseReactiveEnergySum) {
+ this.reverseReactiveEnergySum = reverseReactiveEnergySum;
+ }
+
+ public float getApparentEnergyConsumptionPhase1() {
+ return apparentEnergyConsumptionPhase1;
+ }
+
+ public void setApparentEnergyConsumptionPhase1(float apparentEnergyConsumptionPhase1) {
+ this.apparentEnergyConsumptionPhase1 = apparentEnergyConsumptionPhase1;
+ }
+
+ public float getApparentEnergyConsumptionPhase2() {
+ return apparentEnergyConsumptionPhase2;
+ }
+
+ public void setApparentEnergyConsumptionPhase2(float apparentEnergyConsumptionPhase2) {
+ this.apparentEnergyConsumptionPhase2 = apparentEnergyConsumptionPhase2;
+ }
+
+ public float getApparentEnergyConsumptionPhase3() {
+ return apparentEnergyConsumptionPhase3;
+ }
+
+ public void setApparentEnergyConsumptionPhase3(float apparentEnergyConsumptionPhase3) {
+ this.apparentEnergyConsumptionPhase3 = apparentEnergyConsumptionPhase3;
+ }
+
+ public float getApparentEnergyConsumptionSum() {
+ return apparentEnergyConsumptionSum;
+ }
+
+ public void setApparentEnergyConsumptionSum(float apparentEnergyConsumptionSum) {
+ this.apparentEnergyConsumptionSum = apparentEnergyConsumptionSum;
+ }
+}
diff --git a/bundles/org.openhab.binding.mecmeter/src/main/resources/OH-INF/binding/binding.xml b/bundles/org.openhab.binding.mecmeter/src/main/resources/OH-INF/binding/binding.xml
new file mode 100644
index 000000000..b55da2275
--- /dev/null
+++ b/bundles/org.openhab.binding.mecmeter/src/main/resources/OH-INF/binding/binding.xml
@@ -0,0 +1,9 @@
+
+
+
+ mecMeter Binding
+ This is the binding for the din-rail power meter from MEC.
+
+
diff --git a/bundles/org.openhab.binding.mecmeter/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.mecmeter/src/main/resources/OH-INF/thing/thing-types.xml
new file mode 100644
index 000000000..064ee8a5a
--- /dev/null
+++ b/bundles/org.openhab.binding.mecmeter/src/main/resources/OH-INF/thing/thing-types.xml
@@ -0,0 +1,561 @@
+
+
+
+
+
+ Power Meter from MEC
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Enter the password
+ password
+
+
+
+ The IP address of the mecMeter
+ network-address
+
+
+
+ 5
+ Refresh interval in seconds, default 5 seconds, range 1 to 300 seconds
+
+
+
+
+
+
+
+ General Channels
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Number:Frequency
+
+ Frequency in Hertz
+
+
+
+ Number:Temperature
+
+ Internal Temperature of the energy meter
+
+
+
+ Number:Time
+
+ Time in Operation
+
+
+
+
+
+ Number:ElectricPotential
+
+ Average N – Phase Voltage in Volt
+
+
+
+ Number:ElectricPotential
+
+ Voltage in Volt
+
+
+
+ Number:ElectricPotential
+
+ Average Phase – Phase Voltage in Volt
+
+
+
+
+
+ Number:ElectricCurrent
+
+ Current in Ampere
+
+
+
+
+
+ Number:Angle
+
+ Angle Current to Voltage in Degree
+
+
+
+
+ Number:Angle
+
+ Angle Voltage to Voltage in Degree
+
+
+
+
+
+ Number:Power
+
+ Active power consumed
+
+
+
+
+ Number:Power
+
+ Active fundamental power
+
+
+
+
+ Number:Power
+
+ Active harmonic power
+
+
+
+
+ Number:Power
+
+ Reactive power consumed
+
+
+
+
+ Number:Power
+
+ Apparent power consumed
+
+
+
+
+
+ Number:Energy
+
+ Forward Active Energy in kWh
+ Energy
+
+
+
+ Number:Energy
+
+ Forward Active Energy in kWh
+ Energy
+
+
+
+ Number:Energy
+
+ Forward Active Energy all phase in kWh
+ Energy
+
+
+
+
+ Number:Energy
+
+ Forward Active Fundamental Energy in kWh
+ Energy
+
+
+
+
+ Number:Energy
+
+ Forward Active Harmonic Energy in kWh
+ Energy
+
+
+
+
+ Number:Energy
+
+ Forward Reactive Energy in VArh
+ Energy
+
+
+
+
+
+ Number:Energy
+
+ Reverse Active Energy in kWh
+ Energy
+
+
+
+ Number:Energy
+
+ Reverse Active Energy in kWh
+ Energy
+
+
+
+
+ Number:Energy
+
+ Reverse Active Fundamental Energy in kWh
+ Energy
+
+
+
+
+ Number:Energy
+
+ Reverse Active Harmonic Energy in kWh
+ Energy
+
+
+
+
+ Number:Energy
+
+ Reverse Reactive Energy in VArh
+ Energy
+
+
+
+
+
+ Number:Energy
+
+ Apparent Energy Consumption in VArh
+
+
+
+
+
+ Number:Dimensionless
+
+ Power Factor
+
+
+
diff --git a/bundles/pom.xml b/bundles/pom.xml
index 3c6b37c48..aef3e7d41 100644
--- a/bundles/pom.xml
+++ b/bundles/pom.xml
@@ -178,6 +178,7 @@
org.openhab.binding.mail
org.openhab.binding.max
org.openhab.binding.mcp23017
+ org.openhab.binding.mecmeter
org.openhab.binding.melcloud
org.openhab.binding.meteoalerte
org.openhab.binding.meteoblue