From 1d8b0df4a7d89c51e4e21d5beab257430e68bf42 Mon Sep 17 00:00:00 2001 From: Kai Kreuzer Date: Sun, 28 Mar 2021 11:20:21 +0200 Subject: [PATCH] [mecmeter] Initial contribution of mecmeter binding (#9075) * Initial contribution of mecmeter binding Also-by: Klaus Berger Also-by: Florian Pazour Signed-off-by: Kai Kreuzer * addressed review feedback Signed-off-by: Kai Kreuzer * added codeowners entry Signed-off-by: Kai Kreuzer * addressed review comments Signed-off-by: Kai Kreuzer --- CODEOWNERS | 1 + bom/openhab-addons/pom.xml | 5 + bundles/org.openhab.binding.mecmeter/NOTICE | 13 + .../org.openhab.binding.mecmeter/README.MD | 247 +++++ bundles/org.openhab.binding.mecmeter/pom.xml | 17 + .../src/main/feature/feature.xml | 9 + .../mecmeter/MecMeterBindingConstants.java | 210 +++++ .../mecmeter/MecMeterDeviceConfiguration.java | 64 ++ .../mecmeter/handler/MecMeterHandler.java | 408 +++++++++ .../internal/MecMeterHandlerFactory.java | 65 ++ .../MecMeterDiscoveryParticipant.java | 119 +++ .../internal/dto/MecMeterResponse.java | 856 ++++++++++++++++++ .../main/resources/OH-INF/binding/binding.xml | 9 + .../resources/OH-INF/thing/thing-types.xml | 561 ++++++++++++ bundles/pom.xml | 1 + 15 files changed, 2585 insertions(+) create mode 100644 bundles/org.openhab.binding.mecmeter/NOTICE create mode 100644 bundles/org.openhab.binding.mecmeter/README.MD create mode 100644 bundles/org.openhab.binding.mecmeter/pom.xml create mode 100644 bundles/org.openhab.binding.mecmeter/src/main/feature/feature.xml create mode 100644 bundles/org.openhab.binding.mecmeter/src/main/java/org/openhab/binding/mecmeter/MecMeterBindingConstants.java create mode 100644 bundles/org.openhab.binding.mecmeter/src/main/java/org/openhab/binding/mecmeter/MecMeterDeviceConfiguration.java create mode 100644 bundles/org.openhab.binding.mecmeter/src/main/java/org/openhab/binding/mecmeter/handler/MecMeterHandler.java create mode 100644 bundles/org.openhab.binding.mecmeter/src/main/java/org/openhab/binding/mecmeter/internal/MecMeterHandlerFactory.java create mode 100644 bundles/org.openhab.binding.mecmeter/src/main/java/org/openhab/binding/mecmeter/internal/discovery/MecMeterDiscoveryParticipant.java create mode 100644 bundles/org.openhab.binding.mecmeter/src/main/java/org/openhab/binding/mecmeter/internal/dto/MecMeterResponse.java create mode 100644 bundles/org.openhab.binding.mecmeter/src/main/resources/OH-INF/binding/binding.xml create mode 100644 bundles/org.openhab.binding.mecmeter/src/main/resources/OH-INF/thing/thing-types.xml diff --git a/CODEOWNERS b/CODEOWNERS index 41e5ecba69f28..122c664046cb4 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 1b0f7a7afa26e..4eaa9f9befd40 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 0000000000000..38d625e349232 --- /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 0000000000000..aa8f2f8fbdcf7 --- /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 0000000000000..3f454bac78ba7 --- /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 0000000000000..2ddad66bd474a --- /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 0000000000000..b594cf4e39e96 --- /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 0000000000000..605a1678cd513 --- /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 0000000000000..c66aa985123d5 --- /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 0000000000000..f26fca199601f --- /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 0000000000000..b6b6762d3eca9 --- /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 0000000000000..bcd042707684d --- /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 0000000000000..b55da22752445 --- /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 0000000000000..064ee8a5a0a4e --- /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 3c6b37c4875a2..aef3e7d41dcd3 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