]> git.basschouten.com Git - openhab-addons.git/commitdiff
[fronius] Add support for Fronius Smart Meter (#9209)
authorjimtng <2554958+jimtng@users.noreply.github.com>
Mon, 28 Dec 2020 17:24:10 +0000 (03:24 +1000)
committerGitHub <noreply@github.com>
Mon, 28 Dec 2020 17:24:10 +0000 (09:24 -0800)
* [fronius] Add support for Fronius Smart Meter
* [fronius] Use DTO, implement UoM
* [fronius] fix README.md
* [fronius] Add mandatory label for channel-type and fix property update
* [fronius] Store meterRealtimeBodyData instead of meterRealtimeResponse

Signed-off-by: Jimmy Tanagra <jcode@tanagra.id.au>
bundles/org.openhab.binding.fronius/README.md
bundles/org.openhab.binding.fronius/src/main/java/org/openhab/binding/fronius/internal/FroniusBindingConstants.java
bundles/org.openhab.binding.fronius/src/main/java/org/openhab/binding/fronius/internal/FroniusHandlerFactory.java
bundles/org.openhab.binding.fronius/src/main/java/org/openhab/binding/fronius/internal/api/MeterRealtimeBodyDTO.java [new file with mode: 0644]
bundles/org.openhab.binding.fronius/src/main/java/org/openhab/binding/fronius/internal/api/MeterRealtimeBodyDataDTO.java [new file with mode: 0644]
bundles/org.openhab.binding.fronius/src/main/java/org/openhab/binding/fronius/internal/api/MeterRealtimeDetailsDTO.java [new file with mode: 0644]
bundles/org.openhab.binding.fronius/src/main/java/org/openhab/binding/fronius/internal/api/MeterRealtimeResponseDTO.java [new file with mode: 0644]
bundles/org.openhab.binding.fronius/src/main/java/org/openhab/binding/fronius/internal/handler/FroniusBaseThingHandler.java
bundles/org.openhab.binding.fronius/src/main/java/org/openhab/binding/fronius/internal/handler/FroniusMeterHandler.java [new file with mode: 0644]
bundles/org.openhab.binding.fronius/src/main/java/org/openhab/binding/fronius/internal/handler/FroniusSymoInverterHandler.java
bundles/org.openhab.binding.fronius/src/main/resources/OH-INF/thing/thing-types.xml

index 28d56c72c31f04ba9968ba751bcfa1bf036f868a..fba833df02d2d05ab2f5c4bbaa5fcc4f25b3ba71 100644 (file)
@@ -1,12 +1,16 @@
 # Fronius Binding
 
-This binding uses the [Fronius Solar API V1](https://www.fronius.com/en/photovoltaics/products/all-products/system-monitoring/open-interfaces/fronius-solar-api-json-) to obtain data from Fronius devices.
+This binding uses the [Fronius Solar API V1](https://www.fronius.com/en/photovoltaics/products/all-products/system-monitoring/open-interfaces/fronius-solar-api-json-) to obtain data from Fronius devices.
 
+It supports Fronius inverters and Fronius Smart Meter. Tested with a Fronius Symo 8.2-3-M and Fronius Smart Meter 63A.
 
 ## Supported Things
 
-Support Fronius Galvo, Fronius Symo inverters and other Fronius inverters in combination with the Fronius Datamanager 1.0 / 2.0 or Fronius Datalogger.
-You can add multiple inverters that depend on the same datalogger with different device ids. (Default 1)
+| Thing Type      | Description                                                                                                                                                                                                                           |
+| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `bridge`        | The Bridge                                                                                                                                                                                                                            |
+| `powerinverter` | Fronius Galvo, Symo and other Fronius inverters in combination with the Fronius Datamanager 1.0 / 2.0 or Fronius Datalogger. You can add multiple inverters that depend on the same datalogger with different device ids. (Default 1) |
+| `meter`         | Fronius Smart Meter. You can add multiple smart meters with different device ids. (The default id = 0)                                                                                                                                |
 
 ## Discovery
 
@@ -14,41 +18,83 @@ There is no discovery implemented. You have to create your things manually and s
 
 ## Binding Configuration
 
-The binding has no configuration options, all configuration is done at `bridge` or `powerinverter` level.
+The binding has no configuration options, all configuration is done at `bridge`, `powerinverter` or `meter` level.
 
 ## Thing Configuration
 
 ### Bridge Thing Configuration
 
-| Parameter       | Description                                           |
-|-----------------|------------------------------------------------------ |
-| hostname        | The hostname or IP address of your Fronius Datalogger |
-| refreshInterval | Refresh interval in seconds                           |
+| Parameter         | Description                                           |
+| ----------------- | ----------------------------------------------------- |
+| `hostname`        | The hostname or IP address of your Fronius Datalogger |
+| `refreshInterval` | Refresh interval in seconds                           |
 
 ### Powerinverter Thing Configuration
 
-| Parameter       | Description                                           |
-|-----------------|------------------------------------------------------ |
-| deviceId        | The identifier of your device (Default: 1)            |
+| Parameter  | Description                                |
+| ---------- | ------------------------------------------ |
+| `deviceId` | The identifier of your device (Default: 1) |
+
+### Meter Thing Configuration
+
+| Parameter  | Description                                     |
+| ---------- | ----------------------------------------------- |
+| `deviceId` | The identifier of your smart meter (Default: 0) |
 
 ## Channels
 
-| Channel ID | Item Type    | Description              |
-|------------|--------------|------------------------- |
-| inverterdatachanneldayenergy | Number | Energy generated on current day |
-| inverterdatachannelpac | Number | AC powery |
-| inverterdatachanneltotal | Number | Energy generated overall |
-| inverterdatachannelyear | Number | Energy generated in current year |
-| inverterdatachannelfac | Number | AC frequency |
-| inverterdatachanneliac | Number | AC current |
-| inverterdatachannelidc | Number | DC current |
-| inverterdatachanneluac | Number | AC voltage |
-| inverterdatachanneludc | Number | DC voltage |
-| inverterdatadevicestatuserrorcode | Number | Device error code |
-| inverterdatadevicestatusstatuscode | Number | Device status code<br />`0` - `6` Startup<br />`7` Running <br />`8` Standby<br />`9` Bootloading<br />`10` Error |
-| powerflowchannelpgrid | Number | Power + from grid, - to grid |
-| powerflowchannelpload | Number | Power + generator, - consumer |
-| powerflowchannelpakku | Number | Power + charge, - discharge |
+### Channels for `powerinverter` Thing
+
+| Channel ID                           | Item Type | Description                                                                                                       |
+| ------------------------------------ | --------- | ----------------------------------------------------------------------------------------------------------------- |
+| `inverterdatachanneldayenergy`       | Number    | Energy generated on current day                                                                                   |
+| `inverterdatachannelpac`             | Number    | AC power                                                                                                          |
+| `inverterdatachanneltotal`           | Number    | Energy generated overall                                                                                          |
+| `inverterdatachannelyear`            | Number    | Energy generated in current year                                                                                  |
+| `inverterdatachannelfac`             | Number    | AC frequency                                                                                                      |
+| `inverterdatachanneliac`             | Number    | AC current                                                                                                        |
+| `inverterdatachannelidc`             | Number    | DC current                                                                                                        |
+| `inverterdatachanneluac`             | Number    | AC voltage                                                                                                        |
+| `inverterdatachanneludc`             | Number    | DC voltage                                                                                                        |
+| `inverterdatadevicestatuserrorcode`  | Number    | Device error code                                                                                                 |
+| `inverterdatadevicestatusstatuscode` | Number    | Device status code<br />`0` - `6` Startup<br />`7` Running <br />`8` Standby<br />`9` Bootloading<br />`10` Error |
+| `powerflowchannelpgrid`              | Number    | Power + from grid, - to grid                                                                                      |
+| `powerflowchannelpload`              | Number    | Power + generator, - consumer                                                                                     |
+| `powerflowchannelpakku`              | Number    | Power + charge, - discharge                                                                                       |
+
+### Channels for `meter` Thing
+
+| Channel ID              | Item Type                | Description                                                                                                                                                                                                              |
+| ----------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `enable`                | Number                   | 1 = enabled, 0 = disabled                                                                                                                                                                                                |
+| `location`              | Number                   | 0 = grid interconnection point (primary meter)<br/> 1 = load (primary meter)   <br />3 = external generator (secondary meters)(multiple)<br />256-511 = subloads (secondary meters)(unique). Refer to Fronius Solar API. |
+| `currentacphase1`       | Number:ElectricCurrent   | AC Current on Phase 1                                                                                                                                                                                                    |
+| `currentacphase2`       | Number:ElectricCurrent   | AC Current on Phase 2                                                                                                                                                                                                    |
+| `currentacphase3`       | Number:ElectricCurrent   | AC Current on Phase 3                                                                                                                                                                                                    |
+| `voltageacphase1`       | Number:ElectricPotential | AC Voltage on Phase 1                                                                                                                                                                                                    |
+| `voltageacphase2`       | Number:ElectricPotential | AC Voltage on Phase 2                                                                                                                                                                                                    |
+| `voltageacphase3`       | Number:ElectricPotential | AC Voltage on Phase 3                                                                                                                                                                                                    |
+| `powerrealphase1`       | Number:Power             | Real Power on Phase 1                                                                                                                                                                                                    |
+| `powerrealphase2`       | Number:Power             | Real Power on Phase 2                                                                                                                                                                                                    |
+| `powerrealphase3`       | Number:Power             | Real Power on Phase 3                                                                                                                                                                                                    |
+| `powerfactorphase1`     | Number                   | Power Factor on Phase 1                                                                                                                                                                                                  |
+| `powerfactorphase2`     | Number                   | Power Factor on Phase 2                                                                                                                                                                                                  |
+| `powerfactorphase3`     | Number                   | Power Factor on Phase 3                                                                                                                                                                                                  |
+| `energyrealsumconsumed` | Number:Energy            | Real Energy consumed                                                                                                                                                                                                     |
+| `energyrealsumproduced` | Number:Energy            | Real Energy produced                                                                                                                                                                                                     |
+|                         |
+
+
+
+
+## Properties
+
+The `meter` thing has the following properties:
+
+| Property | Description                    |
+| -------- | ------------------------------ |
+| `model`  | The model name of the meter    |
+| `serial` | The serial number of the meter |
 
 ## Full Example
 
@@ -57,13 +103,14 @@ demo.things:
 ```
 Bridge fronius:bridge:mybridge [hostname="192.168.66.148", refreshInterval=5] {
     Thing powerinverter myinverter [deviceId=1]
+    Thing meter mymeter [deviceId=0]
 }
 ```
 
 demo.items:
 
 ```
-Number AC_Powery { channel="fronius:powerinverter:mybridge:myinverter:inverterdatachannelpac" }
+Number AC_Power { channel="fronius:powerinverter:mybridge:myinverter:inverterdatachannelpac" }
 Number Day_Energy { channel="fronius:powerinverter:mybridge:myinverter:inverterdatachanneldayenergy" }
 Number Total_Energy { channel="fronius:powerinverter:mybridge:myinverter:inverterdatachanneltotal" }
 Number Year_Energy { channel="fronius:powerinverter:mybridge:myinverter:inverterdatachannelyear" }
@@ -77,6 +124,21 @@ Number StatusCode { channel="fronius:powerinverter:mybridge:myinverter:inverterd
 Number Grid_Power { channel="fronius:powerinverter:mybridge:myinverter:powerflowchannelpgrid" }
 Number Load_Power { channel="fronius:powerinverter:mybridge:myinverter:powerflowchannelpload" }
 Number Battery_Power { channel="fronius:powerinverter:mybridge:myinverter:powerflowchannelpakku" }
-```
 
-Tested with a Fronius Symo 8.2-3-M
+Number Meter_Enable { channel="fronius:meter:mybridge:mymeter:enable" }
+Number Meter_Location { channel="fronius:meter:mybridge:mymeter:location" }
+Number:ElectricCurrent Meter_CurrentPhase1 { channel="fronius:meter:mybridge:mymeter:currentacphase1" }
+Number:ElectricCurrent Meter_CurrentPhase2 { channel="fronius:meter:mybridge:mymeter:currentacphase2" }
+Number:ElectricCurrent Meter_CurrentPhase3 { channel="fronius:meter:mybridge:mymeter:currentacphase3" }
+Number:Voltage Meter_VoltagePhase1 { channel="fronius:meter:mybridge:mymeter:voltageacphase1" }
+Number:Voltage Meter_VoltagePhase2 { channel="fronius:meter:mybridge:mymeter:voltageacphase2" }
+Number:Voltage Meter_VoltagePhase3 { channel="fronius:meter:mybridge:mymeter:voltageacphase3" }
+Number:Power Meter_PowerPhase1 { channel="fronius:meter:mybridge:mymeter:powerrealphase1" }
+Number:Power Meter_PowerPhase2 { channel="fronius:meter:mybridge:mymeter:powerrealphase2" }
+Number:Power Meter_PowerPhase3 { channel="fronius:meter:mybridge:mymeter:powerrealphase3" }
+Number Meter_PowerFactorPhase1 { channel="fronius:meter:mybridge:mymeter:powerfactorphase1" }
+Number Meter_PowerFactorPhase2 { channel="fronius:meter:mybridge:mymeter:powerfactorphase2" }
+Number Meter_PowerFactorPhase3 { channel="fronius:meter:mybridge:mymeter:powerfactorphase3" }
+Number:Energy Meter_EnergyConsumed { channel="fronius:meter:mybridge:mymeter:energyrealsumconsumed" }
+Number:Energy Meter_EnergyProduced { channel="fronius:meter:mybridge:mymeter:energyrealsumproduced" }
+```
index d71677c921bcf722f5832b1d51d27d0176323a5a..32f39fd9fdc8ff2a26b24fa6dc19c0c45bcffb0a 100644 (file)
@@ -30,6 +30,7 @@ public class FroniusBindingConstants {
     // List of all Thing Type UIDs
     public static final ThingTypeUID THING_TYPE_INVERTER = new ThingTypeUID(BINDING_ID, "powerinverter");
     public static final ThingTypeUID THING_TYPE_BRIDGE = new ThingTypeUID(BINDING_ID, "bridge");
+    public static final ThingTypeUID THING_TYPE_METER = new ThingTypeUID(BINDING_ID, "meter");
 
     // List of all Channel ids
     public static final String InverterDataChannelDayEnergy = "inverterdatachanneldayenergy";
@@ -46,8 +47,27 @@ public class FroniusBindingConstants {
     public static final String PowerFlowpGrid = "powerflowchannelpgrid";
     public static final String PowerFlowpLoad = "powerflowchannelpload";
     public static final String PowerFlowpAkku = "powerflowchannelpakku";
+    public static final String MeterModel = "model";
+    public static final String MeterSerial = "serial";
+    public static final String MeterEnable = "enable";
+    public static final String MeterLocation = "location";
+    public static final String MeterCurrentAcPhase1 = "currentacphase1";
+    public static final String MeterCurrentAcPhase2 = "currentacphase2";
+    public static final String MeterCurrentAcPhase3 = "currentacphase3";
+    public static final String MeterVoltageAcPhase1 = "voltageacphase1";
+    public static final String MeterVoltageAcPhase2 = "voltageacphase2";
+    public static final String MeterVoltageAcPhase3 = "voltageacphase3";
+    public static final String MeterPowerPhase1 = "powerrealphase1";
+    public static final String MeterPowerPhase2 = "powerrealphase2";
+    public static final String MeterPowerPhase3 = "powerrealphase3";
+    public static final String MeterPowerFactorPhase1 = "powerfactorphase1";
+    public static final String MeterPowerFactorPhase2 = "powerfactorphase2";
+    public static final String MeterPowerFactorPhase3 = "powerfactorphase3";
+    public static final String MeterEnergyRealSumConsumed = "energyrealsumconsumed";
+    public static final String MeterEnergyRealSumProduced = "energyrealsumproduced";
 
     // List of all Urls
     public static final String INVERTER_REALTIME_DATA_URL = "http://%IP%/solar_api/v1/GetInverterRealtimeData.cgi?Scope=Device&DeviceId=%DEVICEID%&DataCollection=CommonInverterData";
     public static final String POWERFLOW_REALTIME_DATA = "http://%IP%/solar_api/v1/GetPowerFlowRealtimeData.fcgi";
+    public static final String METER_REALTIME_DATA_URL = "http://%IP%/solar_api/v1/GetMeterRealtimeData.cgi?Scope=Device&DeviceId=%DEVICEID%&DataCollection=MeterRealtimeData";
 }
index ae4390473bcf84cb42be35c420fbc975be8cbf9f..adacb6eb7b670d2c2401ea1d4792cbee428da1ac 100644 (file)
@@ -18,6 +18,7 @@ import java.util.HashSet;
 import java.util.Set;
 
 import org.openhab.binding.fronius.internal.handler.FroniusBridgeHandler;
+import org.openhab.binding.fronius.internal.handler.FroniusMeterHandler;
 import org.openhab.binding.fronius.internal.handler.FroniusSymoInverterHandler;
 import org.openhab.core.thing.Bridge;
 import org.openhab.core.thing.Thing;
@@ -42,6 +43,7 @@ public class FroniusHandlerFactory extends BaseThingHandlerFactory {
         {
             add(THING_TYPE_INVERTER);
             add(THING_TYPE_BRIDGE);
+            add(THING_TYPE_METER);
         }
     };
 
@@ -58,6 +60,8 @@ public class FroniusHandlerFactory extends BaseThingHandlerFactory {
             return new FroniusSymoInverterHandler(thing);
         } else if (thingTypeUID.equals(THING_TYPE_BRIDGE)) {
             return new FroniusBridgeHandler((Bridge) thing);
+        } else if (thingTypeUID.equals(THING_TYPE_METER)) {
+            return new FroniusMeterHandler(thing);
         }
         return null;
     }
diff --git a/bundles/org.openhab.binding.fronius/src/main/java/org/openhab/binding/fronius/internal/api/MeterRealtimeBodyDTO.java b/bundles/org.openhab.binding.fronius/src/main/java/org/openhab/binding/fronius/internal/api/MeterRealtimeBodyDTO.java
new file mode 100644 (file)
index 0000000..a61476b
--- /dev/null
@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) 2010-2020 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.fronius.internal.api;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * The {@link MeterRealtimeBody} is responsible for storing
+ * the "body" node of the JSON response
+ *
+ * @author Jimmy Tanagra - Initial contribution
+ */
+public class MeterRealtimeBodyDTO {
+    @SerializedName("Data")
+    private MeterRealtimeBodyDataDTO data;
+
+    public MeterRealtimeBodyDataDTO getData() {
+        if (data == null) {
+            data = new MeterRealtimeBodyDataDTO();
+        }
+        return data;
+    }
+
+    public void setData(MeterRealtimeBodyDataDTO data) {
+        this.data = data;
+    }
+}
diff --git a/bundles/org.openhab.binding.fronius/src/main/java/org/openhab/binding/fronius/internal/api/MeterRealtimeBodyDataDTO.java b/bundles/org.openhab.binding.fronius/src/main/java/org/openhab/binding/fronius/internal/api/MeterRealtimeBodyDataDTO.java
new file mode 100644 (file)
index 0000000..71f26b7
--- /dev/null
@@ -0,0 +1,397 @@
+/**
+ * Copyright (c) 2010-2020 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.fronius.internal.api;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * The {@link MeterRealtimeBodyData} is responsible for storing
+ * the "data" node of the JSON response
+ *
+ * @author Jimmy Tanagra - Initial contribution
+ */
+public class MeterRealtimeBodyDataDTO {
+    @SerializedName("Current_AC_Phase_1")
+    private double currentACPhase1;
+    @SerializedName("Current_AC_Phase_2")
+    private double currentACPhase2;
+    @SerializedName("Current_AC_Phase_3")
+    private double currentACPhase3;
+    @SerializedName("Details")
+    private MeterRealtimeDetailsDTO details;
+    @SerializedName("Enable")
+    private int enable;
+    @SerializedName("EnergyReactive_VArAC_Sum_Consumed")
+    private int energyReactiveVArACSumConsumed;
+    @SerializedName("EnergyReactive_VArAC_Sum_Produced")
+    private int energyReactiveVArACSumProduced;
+    @SerializedName("EnergyReal_WAC_Minus_Absolute")
+    private int energyRealWACMinusAbsolute;
+    @SerializedName("EnergyReal_WAC_Plus_Absolute")
+    private int energyRealWACPlusAbsolute;
+    @SerializedName("EnergyReal_WAC_Sum_Consumed")
+    private int energyRealWACSumConsumed;
+    @SerializedName("EnergyReal_WAC_Sum_Produced")
+    private int energyRealWACSumProduced;
+    @SerializedName("Frequency_Phase_Average")
+    private double frequencyPhaseAverage;
+    @SerializedName("Meter_Location_Current")
+    private int meterLocationCurrent;
+    @SerializedName("PowerApparent_S_Phase_1")
+    private double powerApparentSPhase1;
+    @SerializedName("PowerApparent_S_Phase_2")
+    private double powerApparentSPhase2;
+    @SerializedName("PowerApparent_S_Phase_3")
+    private double powerApparentSPhase3;
+    @SerializedName("PowerApparent_S_Sum")
+    private int powerApparentSSum;
+    @SerializedName("PowerFactor_Phase_1")
+    private double powerFactorPhase1;
+    @SerializedName("PowerFactor_Phase_2")
+    private double powerFactorPhase2;
+    @SerializedName("PowerFactor_Phase_3")
+    private double powerFactorPhase3;
+    @SerializedName("PowerFactor_Sum")
+    private double powerFactorSum;
+    @SerializedName("PowerReactive_Q_Phase_1")
+    private double powerReactiveQPhase1;
+    @SerializedName("PowerReactive_Q_Phase_2")
+    private double powerReactiveQPhase2;
+    @SerializedName("PowerReactive_Q_Phase_3")
+    private double powerReactiveQPhase3;
+    @SerializedName("PowerReactive_Q_Sum")
+    private double powerReactiveQSum;
+    @SerializedName("PowerReal_P_Phase_1")
+    private double powerRealPPhase1;
+    @SerializedName("PowerReal_P_Phase_2")
+    private double powerRealPPhase2;
+    @SerializedName("PowerReal_P_Phase_3")
+    private double powerRealPPhase3;
+    @SerializedName("PowerReal_P_Sum")
+    private double powerRealPSum;
+    @SerializedName("TimeStamp")
+    private int timeStamp;
+    @SerializedName("Visible")
+    private int visible;
+    @SerializedName("Voltage_AC_PhaseToPhase_12")
+    private double voltageACPhaseToPhase12;
+    @SerializedName("Voltage_AC_PhaseToPhase_23")
+    private double voltageACPhaseToPhase23;
+    @SerializedName("Voltage_AC_PhaseToPhase_31")
+    private double voltageACPhaseToPhase31;
+    @SerializedName("Voltage_AC_Phase_1")
+    private double voltageACPhase1;
+    @SerializedName("Voltage_AC_Phase_2")
+    private double voltageACPhase2;
+    @SerializedName("Voltage_AC_Phase_3")
+    private double voltageACPhase3;
+
+    public double getCurrentACPhase1() {
+        return currentACPhase1;
+    }
+
+    public void setCurrentACPhase1(double currentACPhase1) {
+        this.currentACPhase1 = currentACPhase1;
+    }
+
+    public double getCurrentACPhase2() {
+        return currentACPhase2;
+    }
+
+    public void setCurrentACPhase2(double currentACPhase2) {
+        this.currentACPhase2 = currentACPhase2;
+    }
+
+    public double getCurrentACPhase3() {
+        return currentACPhase3;
+    }
+
+    public void setCurrentACPhase3(double currentACPhase3) {
+        this.currentACPhase3 = currentACPhase3;
+    }
+
+    public MeterRealtimeDetailsDTO getDetails() {
+        if (details == null) {
+            details = new MeterRealtimeDetailsDTO();
+        }
+        return details;
+    }
+
+    public void setDetails(MeterRealtimeDetailsDTO details) {
+        this.details = details;
+    }
+
+    public int getEnable() {
+        return enable;
+    }
+
+    public void setEnable(int enable) {
+        this.enable = enable;
+    }
+
+    public int getEnergyReactiveVArACSumConsumed() {
+        return energyReactiveVArACSumConsumed;
+    }
+
+    public void setEnergyReactiveVArACSumConsumed(int energyReactiveVArACSumConsumed) {
+        this.energyReactiveVArACSumConsumed = energyReactiveVArACSumConsumed;
+    }
+
+    public int getEnergyReactiveVArACSumProduced() {
+        return energyReactiveVArACSumProduced;
+    }
+
+    public void setEnergyReactiveVArACSumProduced(int energyReactiveVArACSumProduced) {
+        this.energyReactiveVArACSumProduced = energyReactiveVArACSumProduced;
+    }
+
+    public int getEnergyRealWACMinusAbsolute() {
+        return energyRealWACMinusAbsolute;
+    }
+
+    public void setEnergyRealWACMinusAbsolute(int energyRealWACMinusAbsolute) {
+        this.energyRealWACMinusAbsolute = energyRealWACMinusAbsolute;
+    }
+
+    public int getEnergyRealWACPlusAbsolute() {
+        return energyRealWACPlusAbsolute;
+    }
+
+    public void setEnergyRealWACPlusAbsolute(int energyRealWACPlusAbsolute) {
+        this.energyRealWACPlusAbsolute = energyRealWACPlusAbsolute;
+    }
+
+    public int getEnergyRealWACSumConsumed() {
+        return energyRealWACSumConsumed;
+    }
+
+    public void setEnergyRealWACSumConsumed(int energyRealWACSumConsumed) {
+        this.energyRealWACSumConsumed = energyRealWACSumConsumed;
+    }
+
+    public int getEnergyRealWACSumProduced() {
+        return energyRealWACSumProduced;
+    }
+
+    public void setEnergyRealWACSumProduced(int energyRealWACSumProduced) {
+        this.energyRealWACSumProduced = energyRealWACSumProduced;
+    }
+
+    public double getFrequencyPhaseAverage() {
+        return frequencyPhaseAverage;
+    }
+
+    public void setFrequencyPhaseAverage(double frequencyPhaseAverage) {
+        this.frequencyPhaseAverage = frequencyPhaseAverage;
+    }
+
+    public int getMeterLocationCurrent() {
+        return meterLocationCurrent;
+    }
+
+    public void setMeterLocationCurrent(int meterLocationCurrent) {
+        this.meterLocationCurrent = meterLocationCurrent;
+    }
+
+    public double getPowerApparentSPhase1() {
+        return powerApparentSPhase1;
+    }
+
+    public void setPowerApparentSPhase1(double powerApparentSPhase1) {
+        this.powerApparentSPhase1 = powerApparentSPhase1;
+    }
+
+    public double getPowerApparentSPhase2() {
+        return powerApparentSPhase2;
+    }
+
+    public void setPowerApparentSPhase2(double powerApparentSPhase2) {
+        this.powerApparentSPhase2 = powerApparentSPhase2;
+    }
+
+    public double getPowerApparentSPhase3() {
+        return powerApparentSPhase3;
+    }
+
+    public void setPowerApparentSPhase3(double powerApparentSPhase3) {
+        this.powerApparentSPhase3 = powerApparentSPhase3;
+    }
+
+    public int getPowerApparentSSum() {
+        return powerApparentSSum;
+    }
+
+    public void setPowerApparentSSum(int powerApparentSSum) {
+        this.powerApparentSSum = powerApparentSSum;
+    }
+
+    public double getPowerFactorPhase1() {
+        return powerFactorPhase1;
+    }
+
+    public void setPowerFactorPhase1(double powerFactorPhase1) {
+        this.powerFactorPhase1 = powerFactorPhase1;
+    }
+
+    public double getPowerFactorPhase2() {
+        return powerFactorPhase2;
+    }
+
+    public void setPowerFactorPhase2(double powerFactorPhase2) {
+        this.powerFactorPhase2 = powerFactorPhase2;
+    }
+
+    public double getPowerFactorPhase3() {
+        return powerFactorPhase3;
+    }
+
+    public void setPowerFactorPhase3(double powerFactorPhase3) {
+        this.powerFactorPhase3 = powerFactorPhase3;
+    }
+
+    public double getPowerFactorSum() {
+        return powerFactorSum;
+    }
+
+    public void setPowerFactorSum(double powerFactorSum) {
+        this.powerFactorSum = powerFactorSum;
+    }
+
+    public double getPowerReactiveQPhase1() {
+        return powerReactiveQPhase1;
+    }
+
+    public void setPowerReactiveQPhase1(double powerReactiveQPhase1) {
+        this.powerReactiveQPhase1 = powerReactiveQPhase1;
+    }
+
+    public double getPowerReactiveQPhase2() {
+        return powerReactiveQPhase2;
+    }
+
+    public void setPowerReactiveQPhase2(double powerReactiveQPhase2) {
+        this.powerReactiveQPhase2 = powerReactiveQPhase2;
+    }
+
+    public double getPowerReactiveQPhase3() {
+        return powerReactiveQPhase3;
+    }
+
+    public void setPowerReactiveQPhase3(double powerReactiveQPhase3) {
+        this.powerReactiveQPhase3 = powerReactiveQPhase3;
+    }
+
+    public double getPowerReactiveQSum() {
+        return powerReactiveQSum;
+    }
+
+    public void setPowerReactiveQSum(double powerReactiveQSum) {
+        this.powerReactiveQSum = powerReactiveQSum;
+    }
+
+    public double getPowerRealPPhase1() {
+        return powerRealPPhase1;
+    }
+
+    public void setPowerRealPPhase1(double powerRealPPhase1) {
+        this.powerRealPPhase1 = powerRealPPhase1;
+    }
+
+    public double getPowerRealPPhase2() {
+        return powerRealPPhase2;
+    }
+
+    public void setPowerRealPPhase2(double powerRealPPhase2) {
+        this.powerRealPPhase2 = powerRealPPhase2;
+    }
+
+    public double getPowerRealPPhase3() {
+        return powerRealPPhase3;
+    }
+
+    public void setPowerRealPPhase3(double powerRealPPhase3) {
+        this.powerRealPPhase3 = powerRealPPhase3;
+    }
+
+    public double getPowerRealPSum() {
+        return powerRealPSum;
+    }
+
+    public void setPowerRealPSum(double powerRealPSum) {
+        this.powerRealPSum = powerRealPSum;
+    }
+
+    public int getTimeStamp() {
+        return timeStamp;
+    }
+
+    public void setTimeStamp(int timeStamp) {
+        this.timeStamp = timeStamp;
+    }
+
+    public int getVisible() {
+        return visible;
+    }
+
+    public void setVisible(int visible) {
+        this.visible = visible;
+    }
+
+    public double getVoltageACPhaseToPhase12() {
+        return voltageACPhaseToPhase12;
+    }
+
+    public void setVoltageACPhaseToPhase12(double voltageACPhaseToPhase12) {
+        this.voltageACPhaseToPhase12 = voltageACPhaseToPhase12;
+    }
+
+    public double getVoltageACPhaseToPhase23() {
+        return voltageACPhaseToPhase23;
+    }
+
+    public void setVoltageACPhaseToPhase23(double voltageACPhaseToPhase23) {
+        this.voltageACPhaseToPhase23 = voltageACPhaseToPhase23;
+    }
+
+    public double getVoltageACPhaseToPhase31() {
+        return voltageACPhaseToPhase31;
+    }
+
+    public void setVoltageACPhaseToPhase31(double voltageACPhaseToPhase31) {
+        this.voltageACPhaseToPhase31 = voltageACPhaseToPhase31;
+    }
+
+    public double getVoltageACPhase1() {
+        return voltageACPhase1;
+    }
+
+    public void setVoltageACPhase1(double voltageACPhase1) {
+        this.voltageACPhase1 = voltageACPhase1;
+    }
+
+    public double getVoltageACPhase2() {
+        return voltageACPhase2;
+    }
+
+    public void setVoltageACPhase2(double voltageACPhase2) {
+        this.voltageACPhase2 = voltageACPhase2;
+    }
+
+    public double getVoltageACPhase3() {
+        return voltageACPhase3;
+    }
+
+    public void setVoltageACPhase3(double voltageACPhase3) {
+        this.voltageACPhase3 = voltageACPhase3;
+    }
+}
diff --git a/bundles/org.openhab.binding.fronius/src/main/java/org/openhab/binding/fronius/internal/api/MeterRealtimeDetailsDTO.java b/bundles/org.openhab.binding.fronius/src/main/java/org/openhab/binding/fronius/internal/api/MeterRealtimeDetailsDTO.java
new file mode 100644 (file)
index 0000000..6cc3dbe
--- /dev/null
@@ -0,0 +1,54 @@
+/**
+ * Copyright (c) 2010-2020 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.fronius.internal.api;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * The {@link MeterRealtimeDetails} is responsible for storing
+ * the "body" node of the JSON response
+ *
+ * @author Jimmy Tanagra - Initial contribution
+ */
+public class MeterRealtimeDetailsDTO {
+    @SerializedName("Manufacturer")
+    private String manufacturer;
+    @SerializedName("Model")
+    private String model;
+    @SerializedName("Serial")
+    private String serial;
+
+    public String getManufacturer() {
+        return manufacturer;
+    }
+
+    public void setManufacturer(String manufacturer) {
+        this.manufacturer = manufacturer;
+    }
+
+    public String getModel() {
+        return model;
+    }
+
+    public void setModel(String model) {
+        this.model = model;
+    }
+
+    public String getSerial() {
+        return serial;
+    }
+
+    public void setSerial(String serial) {
+        this.serial = serial;
+    }
+}
diff --git a/bundles/org.openhab.binding.fronius/src/main/java/org/openhab/binding/fronius/internal/api/MeterRealtimeResponseDTO.java b/bundles/org.openhab.binding.fronius/src/main/java/org/openhab/binding/fronius/internal/api/MeterRealtimeResponseDTO.java
new file mode 100644 (file)
index 0000000..765dacb
--- /dev/null
@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) 2010-2020 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.fronius.internal.api;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * The {@link MeterRealtimeResponse} is responsible for storing
+ * the response from the powerflowrealtime api
+ *
+ * @author Jimmy Tanagra - Initial contribution
+ */
+public class MeterRealtimeResponseDTO extends BaseFroniusResponse {
+    @SerializedName("Body")
+    private MeterRealtimeBodyDTO body;
+
+    public MeterRealtimeBodyDTO getBody() {
+        if (body == null) {
+            body = new MeterRealtimeBodyDTO();
+        }
+        return body;
+    }
+
+    public void setBody(MeterRealtimeBodyDTO body) {
+        this.body = body;
+    }
+}
index 9a0a620a8777f245546e87eda42fe2456f91c47d..add6097c0a73e447af050b769304ff35a71bf65a 100644 (file)
  */
 package org.openhab.binding.fronius.internal.handler;
 
+import java.io.IOException;
 import java.math.BigDecimal;
 
 import org.openhab.binding.fronius.internal.FroniusBridgeConfiguration;
+import org.openhab.binding.fronius.internal.api.BaseFroniusResponse;
 import org.openhab.binding.fronius.internal.api.ValueUnit;
+import org.openhab.core.io.net.http.HttpUtil;
 import org.openhab.core.library.types.DecimalType;
+import org.openhab.core.library.types.QuantityType;
+import org.openhab.core.library.types.StringType;
 import org.openhab.core.thing.Bridge;
 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.thing.binding.ThingHandler;
 import org.openhab.core.types.Command;
@@ -30,6 +36,9 @@ import org.openhab.core.types.State;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.gson.Gson;
+import com.google.gson.JsonSyntaxException;
+
 /**
  * Basic Handler class for all Fronius services.
  *
@@ -38,12 +47,15 @@ import org.slf4j.LoggerFactory;
  */
 public abstract class FroniusBaseThingHandler extends BaseThingHandler {
 
+    private static final int API_TIMEOUT = 5000;
     private final Logger logger = LoggerFactory.getLogger(FroniusBaseThingHandler.class);
     private final String serviceDescription;
     private FroniusBridgeHandler bridgeHandler;
+    private final Gson gson;
 
     public FroniusBaseThingHandler(Thing thing) {
         super(thing);
+        gson = new Gson();
         serviceDescription = getDescription();
     }
 
@@ -115,6 +127,10 @@ public abstract class FroniusBaseThingHandler extends BaseThingHandler {
             state = new DecimalType((double) value);
         } else if (value instanceof ValueUnit) {
             state = new DecimalType(((ValueUnit) value).getValue());
+        } else if (value instanceof String) {
+            state = new StringType((String) value);
+        } else if (value instanceof QuantityType) {
+            state = (QuantityType) value;
         } else {
             logger.warn("Update channel {}: Unsupported value type {}", channelId, value.getClass().getSimpleName());
         }
@@ -149,4 +165,53 @@ public abstract class FroniusBaseThingHandler extends BaseThingHandler {
      * @param bridgeConfiguration the connected bridge configuration
      */
     public abstract void refresh(FroniusBridgeConfiguration bridgeConfiguration);
+
+    /**
+     *
+     * @param type response class type
+     * @param url to request
+     * @return the object representation of the json response
+     */
+    protected <T extends BaseFroniusResponse> T collectDataFormUrl(Class<T> type, String url) {
+        T result = null;
+        boolean resultOk = false;
+        String errorMsg = null;
+
+        try {
+            logger.debug("URL = {}", url);
+            String response = HttpUtil.executeUrl("GET", url, API_TIMEOUT);
+
+            if (response != null) {
+                logger.debug("aqiResponse = {}", response);
+                result = gson.fromJson(response, type);
+            }
+
+            if (result == null) {
+                errorMsg = "no data returned";
+            } else {
+                if (result.getHead().getStatus().getCode() == 0) {
+                    resultOk = true;
+                } else {
+                    errorMsg = result.getHead().getStatus().getReason();
+                }
+            }
+            if (!resultOk) {
+                logger.debug("Error in fronius response: {}", errorMsg);
+            }
+        } catch (JsonSyntaxException e) {
+            errorMsg = "Invalid JSON data received";
+            logger.debug("Error running fronius request: {}", errorMsg);
+        } catch (IOException | IllegalStateException e) {
+            errorMsg = e.getMessage();
+            logger.debug("Error running fronius request: {}", errorMsg);
+        }
+
+        // Update the thing status
+        if (resultOk) {
+            updateStatus(ThingStatus.ONLINE);
+        } else {
+            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR, errorMsg);
+        }
+        return resultOk ? result : null;
+    }
 }
diff --git a/bundles/org.openhab.binding.fronius/src/main/java/org/openhab/binding/fronius/internal/handler/FroniusMeterHandler.java b/bundles/org.openhab.binding.fronius/src/main/java/org/openhab/binding/fronius/internal/handler/FroniusMeterHandler.java
new file mode 100644 (file)
index 0000000..f28ae23
--- /dev/null
@@ -0,0 +1,154 @@
+/**
+ * Copyright (c) 2010-2020 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.fronius.internal.handler;
+
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.openhab.binding.fronius.internal.FroniusBaseDeviceConfiguration;
+import org.openhab.binding.fronius.internal.FroniusBindingConstants;
+import org.openhab.binding.fronius.internal.FroniusBridgeConfiguration;
+import org.openhab.binding.fronius.internal.api.MeterRealtimeBodyDataDTO;
+import org.openhab.binding.fronius.internal.api.MeterRealtimeResponseDTO;
+import org.openhab.core.library.types.QuantityType;
+import org.openhab.core.library.unit.Units;
+import org.openhab.core.thing.Thing;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The {@link FroniusMeterHandler} is responsible for updating the data, which are
+ * sent to one of the channels.
+ *
+ * @author Jimmy Tanagra - Initial contribution
+ */
+public class FroniusMeterHandler extends FroniusBaseThingHandler {
+
+    private final Logger logger = LoggerFactory.getLogger(FroniusMeterHandler.class);
+    private MeterRealtimeBodyDataDTO meterRealtimeBodyData;
+    private FroniusBaseDeviceConfiguration config;
+
+    public FroniusMeterHandler(Thing thing) {
+        super(thing);
+    }
+
+    @Override
+    protected String getDescription() {
+        return "Fronius Smart Meter";
+    }
+
+    @Override
+    public void refresh(FroniusBridgeConfiguration bridgeConfiguration) {
+        updateData(bridgeConfiguration, config);
+        updateChannels();
+        updateProperties();
+    }
+
+    @Override
+    public void initialize() {
+        config = getConfigAs(FroniusBaseDeviceConfiguration.class);
+        super.initialize();
+    }
+
+    /**
+     * Update the channel from the last data retrieved
+     *
+     * @param channelId the id identifying the channel to be updated
+     * @return the last retrieved data
+     */
+    @Override
+    protected Object getValue(String channelId) {
+        if (meterRealtimeBodyData == null) {
+            return null;
+        }
+
+        String[] fields = StringUtils.split(channelId, "#");
+        String fieldName = fields[0];
+
+        switch (fieldName) {
+            case FroniusBindingConstants.MeterEnable:
+                return meterRealtimeBodyData.getEnable();
+            case FroniusBindingConstants.MeterLocation:
+                return meterRealtimeBodyData.getMeterLocationCurrent();
+            case FroniusBindingConstants.MeterCurrentAcPhase1:
+                return new QuantityType(meterRealtimeBodyData.getCurrentACPhase1(), Units.AMPERE);
+            case FroniusBindingConstants.MeterCurrentAcPhase2:
+                return new QuantityType(meterRealtimeBodyData.getCurrentACPhase2(), Units.AMPERE);
+            case FroniusBindingConstants.MeterCurrentAcPhase3:
+                return new QuantityType(meterRealtimeBodyData.getCurrentACPhase3(), Units.AMPERE);
+            case FroniusBindingConstants.MeterVoltageAcPhase1:
+                return new QuantityType(meterRealtimeBodyData.getVoltageACPhase1(), Units.VOLT);
+            case FroniusBindingConstants.MeterVoltageAcPhase2:
+                return new QuantityType(meterRealtimeBodyData.getVoltageACPhase2(), Units.VOLT);
+            case FroniusBindingConstants.MeterVoltageAcPhase3:
+                return new QuantityType(meterRealtimeBodyData.getVoltageACPhase3(), Units.VOLT);
+            case FroniusBindingConstants.MeterPowerPhase1:
+                return new QuantityType(meterRealtimeBodyData.getPowerRealPPhase1(), Units.WATT);
+            case FroniusBindingConstants.MeterPowerPhase2:
+                return new QuantityType(meterRealtimeBodyData.getPowerRealPPhase2(), Units.WATT);
+            case FroniusBindingConstants.MeterPowerPhase3:
+                return new QuantityType(meterRealtimeBodyData.getPowerRealPPhase3(), Units.WATT);
+            case FroniusBindingConstants.MeterPowerFactorPhase1:
+                return meterRealtimeBodyData.getPowerFactorPhase1();
+            case FroniusBindingConstants.MeterPowerFactorPhase2:
+                return meterRealtimeBodyData.getPowerFactorPhase2();
+            case FroniusBindingConstants.MeterPowerFactorPhase3:
+                return meterRealtimeBodyData.getPowerFactorPhase3();
+            case FroniusBindingConstants.MeterEnergyRealSumConsumed:
+                return new QuantityType(meterRealtimeBodyData.getEnergyRealWACSumConsumed(), Units.WATT_HOUR);
+            case FroniusBindingConstants.MeterEnergyRealSumProduced:
+                return new QuantityType(meterRealtimeBodyData.getEnergyRealWACSumProduced(), Units.WATT_HOUR);
+        }
+
+        return null;
+    }
+
+    private void updateProperties() {
+        if (meterRealtimeBodyData == null) {
+            return;
+        }
+
+        Map<String, String> properties = editProperties();
+
+        properties.put(FroniusBindingConstants.MeterModel, meterRealtimeBodyData.getDetails().getModel());
+        properties.put(FroniusBindingConstants.MeterSerial, meterRealtimeBodyData.getDetails().getSerial());
+
+        updateProperties(properties);
+    }
+
+    /**
+     * Get new data
+     */
+    private void updateData(FroniusBridgeConfiguration bridgeConfiguration, FroniusBaseDeviceConfiguration config) {
+        MeterRealtimeResponseDTO meterRealtimeResponse = getMeterRealtimeData(bridgeConfiguration.hostname,
+                config.deviceId);
+        if (meterRealtimeResponse == null) {
+            meterRealtimeBodyData = null;
+        } else {
+            meterRealtimeBodyData = meterRealtimeResponse.getBody().getData();
+        }
+    }
+
+    /**
+     * Make the MeterRealtimeData request
+     *
+     * @param ip address of the device
+     * @param deviceId of the device
+     * @return {MeterRealtimeResponse} the object representation of the json response
+     */
+    private MeterRealtimeResponseDTO getMeterRealtimeData(String ip, int deviceId) {
+        String location = FroniusBindingConstants.METER_REALTIME_DATA_URL.replace("%IP%", StringUtils.trimToEmpty(ip));
+        location = location.replace("%DEVICEID%", Integer.toString(deviceId));
+        return collectDataFormUrl(MeterRealtimeResponseDTO.class, location);
+    }
+}
index 0590b21d6bd6f34f344f785f419d049d37bea49a..a3683eb7fd54c341cf1c9a0c08964c28aa45e82b 100644 (file)
  */
 package org.openhab.binding.fronius.internal.handler;
 
-import java.io.IOException;
-
 import org.apache.commons.lang.StringUtils;
 import org.openhab.binding.fronius.internal.FroniusBaseDeviceConfiguration;
 import org.openhab.binding.fronius.internal.FroniusBindingConstants;
 import org.openhab.binding.fronius.internal.FroniusBridgeConfiguration;
-import org.openhab.binding.fronius.internal.api.BaseFroniusResponse;
 import org.openhab.binding.fronius.internal.api.InverterRealtimeResponse;
 import org.openhab.binding.fronius.internal.api.PowerFlowRealtimeResponse;
 import org.openhab.binding.fronius.internal.api.ValueUnit;
-import org.openhab.core.io.net.http.HttpUtil;
 import org.openhab.core.thing.Thing;
-import org.openhab.core.thing.ThingStatus;
-import org.openhab.core.thing.ThingStatusDetail;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.gson.Gson;
-import com.google.gson.JsonSyntaxException;
-
 /**
  * The {@link FroniusSymoInverterHandler} is responsible for updating the data, which are
  * sent to one of the channels.
@@ -41,16 +32,13 @@ import com.google.gson.JsonSyntaxException;
  */
 public class FroniusSymoInverterHandler extends FroniusBaseThingHandler {
 
-    private static final int API_TIMEOUT = 5000;
     private final Logger logger = LoggerFactory.getLogger(FroniusSymoInverterHandler.class);
     private InverterRealtimeResponse inverterRealtimeResponse;
     private PowerFlowRealtimeResponse powerFlowResponse;
     private FroniusBaseDeviceConfiguration config;
-    private final Gson gson;
 
     public FroniusSymoInverterHandler(Thing thing) {
         super(thing);
-        gson = new Gson();
     }
 
     @Override
@@ -149,54 +137,6 @@ public class FroniusSymoInverterHandler extends FroniusBaseThingHandler {
         powerFlowResponse = getPowerFlowRealtime(bridgeConfiguration.hostname);
     }
 
-    /**
-     *
-     * @param type response class type
-     * @param url to request
-     * @return the object representation of the json response
-     */
-    private <T extends BaseFroniusResponse> T collectDataFormUrl(Class<T> type, String url) {
-        T result = null;
-        boolean resultOk = false;
-        String errorMsg = null;
-
-        try {
-            logger.debug("URL = {}", url);
-            String response = HttpUtil.executeUrl("GET", url, API_TIMEOUT);
-
-            if (response != null) {
-                logger.debug("aqiResponse = {}", response);
-                result = gson.fromJson(response, type);
-            }
-
-            if (result == null) {
-                errorMsg = "no data returned";
-            } else {
-                if (result.getHead().getStatus().getCode() == 0) {
-                    resultOk = true;
-                } else {
-                    errorMsg = result.getHead().getStatus().getReason();
-                }
-            }
-            if (!resultOk) {
-                logger.debug("Error in fronius response: {}", errorMsg);
-            }
-        } catch (JsonSyntaxException e) {
-            errorMsg = "Configuration is incorrect";
-            logger.debug("Error running fronius request: {}", errorMsg);
-        } catch (IOException | IllegalStateException e) {
-            logger.debug("Error running fronius request: {}", e.getMessage());
-        }
-
-        // Update the thing status
-        if (resultOk) {
-            updateStatus(ThingStatus.ONLINE);
-        } else {
-            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR, errorMsg);
-        }
-        return resultOk ? result : null;
-    }
-
     /**
      * Make the PowerFlowRealtimeDataRequest
      *
index b110b20f71319e68a64c250f7b7f250995b356ca..d6334bdc8c8b8be5dcadf947c4c228b9b5eae208 100644 (file)
                </config-description>
        </thing-type>
 
+       <!-- Meter Thing Type -->
+       <thing-type id="meter">
+               <supported-bridge-type-refs>
+                       <bridge-type-ref id="bridge"/>
+               </supported-bridge-type-refs>
+               <label>Fronius Smart Meter</label>
+               <description>Fronius Smart Meter</description>
+
+               <channels>
+                       <channel id="enable" typeId="meter_enable"/>
+                       <channel id="location" typeId="meter_location"/>
+                       <channel id="currentacphase1" typeId="meter_ac_current">
+                               <label>AC Current Phase 1</label>
+                       </channel>
+                       <channel id="currentacphase2" typeId="meter_ac_current">
+                               <label>AC Current Phase 2</label>
+                       </channel>
+                       <channel id="currentacphase3" typeId="meter_ac_current">
+                               <label>AC Current Phase 3</label>
+                       </channel>
+                       <channel id="voltageacphase1" typeId="meter_ac_voltage">
+                               <label>AC Voltage Phase 1</label>
+                       </channel>
+                       <channel id="voltageacphase2" typeId="meter_ac_voltage">
+                               <label>AC Voltage Phase 2</label>
+                       </channel>
+                       <channel id="voltageacphase3" typeId="meter_ac_voltage">
+                               <label>AC Voltage Phase 3</label>
+                       </channel>
+                       <channel id="powerrealphase1" typeId="meter_powerreal">
+                               <label>Real Power Phase 1</label>
+                       </channel>
+                       <channel id="powerrealphase2" typeId="meter_powerreal">
+                               <label>Real Power Phase 2</label>
+                       </channel>
+                       <channel id="powerrealphase3" typeId="meter_powerreal">
+                               <label>Real Power Phase 3</label>
+                       </channel>
+                       <channel id="powerfactorphase1" typeId="meter_powerfactor">
+                               <label>Power Factor Phase 1</label>
+                       </channel>
+                       <channel id="powerfactorphase2" typeId="meter_powerfactor">
+                               <label>Power Factor Phase 2</label>
+                       </channel>
+                       <channel id="powerfactorphase3" typeId="meter_powerfactor">
+                               <label>Power Factor Phase 3</label>
+                       </channel>
+                       <channel id="energyrealsumconsumed" typeId="meter_energy">
+                               <label>Real Energy Consumed</label>
+                       </channel>
+                       <channel id="energyrealsumproduced" typeId="meter_energy">
+                               <label>Real Energy Produced</label>
+                       </channel>
+               </channels>
+
+               <properties>
+                       <property name="model"/>
+                       <property name="serial"/>
+               </properties>
+
+               <config-description>
+                       <parameter name="deviceId" type="integer">
+                               <label>Device ID</label>
+                               <description>Specific device identifier</description>
+                               <default>0</default>
+                       </parameter>
+               </config-description>
+       </thing-type>
+
        <channel-type id="day_energy">
                <item-type>Number</item-type>
                <label>Day Energy</label>
                <description>Battery Power ( + charge, - discharge )</description>
                <state pattern="%.2f W" readOnly="true"></state>
        </channel-type>
+
+
+       <channel-type id="meter_enable" advanced="true">
+               <item-type>Number</item-type>
+               <label>Enabled</label>
+               <description>Enabled</description>
+               <state readOnly="true"></state>
+       </channel-type>
+       <channel-type id="meter_location" advanced="true">
+               <item-type>Number</item-type>
+               <label>Location</label>
+               <description>Meter location code</description>
+               <state readOnly="true"></state>
+       </channel-type>
+       <channel-type id="meter_ac_current">
+               <item-type>Number:ElectricCurrent</item-type>
+               <label>AC Current</label>
+               <description></description>
+               <state pattern="%.2f %unit%" readOnly="true"></state>
+       </channel-type>
+       <channel-type id="meter_ac_voltage">
+               <item-type>Number:ElectricPotential</item-type>
+               <label>AC Voltage</label>
+               <description></description>
+               <state pattern="%.2f %unit%" readOnly="true"></state>
+       </channel-type>
+       <channel-type id="meter_powerreal">
+               <item-type>Number:Power</item-type>
+               <label>Power</label>
+               <description></description>
+               <state pattern="%.2f %unit%" readOnly="true"></state>
+       </channel-type>
+       <channel-type id="meter_powerfactor">
+               <item-type>Number</item-type>
+               <label>Power Factor</label>
+               <description></description>
+               <state pattern="%.2f" readOnly="true"></state>
+       </channel-type>
+       <channel-type id="meter_energy">
+               <item-type>Number:Energy</item-type>
+               <label>Energy</label>
+               <description></description>
+               <state pattern="%.2f %unit%" readOnly="true"></state>
+       </channel-type>
+
 </thing:thing-descriptions>