mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
[fronius] Add support for Fronius Smart Meter (#9209)
* [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>
This commit is contained in:
parent
c556f49691
commit
fe5e9b85e8
@ -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 a 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" }
|
||||
```
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -12,16 +12,22 @@
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -12,26 +12,17 @@
|
||||
*/
|
||||
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
|
||||
*
|
||||
|
@ -38,6 +38,75 @@
|
||||
</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>
|
||||
@ -127,4 +196,49 @@
|
||||
<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>
|
||||
|
Loading…
Reference in New Issue
Block a user