Skip to content

Commit 7414776

Browse files
committed
[fronius] Add battery Thing type
Signed-off-by: Jimmy Tanagra <jcode@tanagra.id.au>
1 parent bcf6bb1 commit 7414776

11 files changed

Lines changed: 618 additions & 20 deletions

File tree

bundles/org.openhab.binding.fronius/README.md

Lines changed: 90 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ Inverters with integrated Solar API V1 support include:
1818
|-----------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|
1919
| `bridge` | The Bridge |
2020
| `powerinverter` | Fronius Galvo, Symo and other Fronius inverters: You can add multiple inverters that depend on the same datalogger with different device ids. (default id = 1) |
21+
| `battery` | Fronius Battery: Battery devices that map to storage controller fields (default id = 0) |
2122
| `meter` | Fronius Smart Meter: You can add multiple smart meters with different device ids. (default id = 0) |
22-
| `ohmpilot` | Fronius Ohmpilot ( default id = 0) |
23+
| `ohmpilot` | Fronius Ohmpilot (default id = 0) |
2324

2425
## Discovery
2526

@@ -44,27 +45,33 @@ The binding has no configuration options, all configuration is done at `bridge`,
4445
### Powerinverter Thing Configuration
4546

4647
| Parameter | Description |
47-
| ---------- | ------------------------------------------ |
48+
|------------|--------------------------------------------|
4849
| `deviceId` | The identifier of your device (Default: 1) |
4950

51+
### Battery Thing Configuration
52+
53+
| Parameter | Description |
54+
|------------|----------------------------------------------------|
55+
| `deviceId` | The identifier of your battery device (Default: 0) |
56+
5057
### Meter Thing Configuration
5158

5259
| Parameter | Description |
53-
| ---------- | ----------------------------------------------- |
60+
|------------|-------------------------------------------------|
5461
| `deviceId` | The identifier of your smart meter (Default: 0) |
5562

5663
### Ohmpilot Thing Configuration
5764

5865
| Parameter | Description |
59-
| ---------- | -------------------------------------------- |
66+
|------------|----------------------------------------------|
6067
| `deviceId` | The identifier of your ohmpilot (Default: 0) |
6168

6269
## Channels
6370

6471
### `powerinverter` Thing Channels
6572

6673
| Channel ID | Item Type | Description |
67-
| ------------------------------------ | ------------------------ | ----------------------------------------------------------------------------------------------------------------- |
74+
|--------------------------------------|--------------------------|-------------------------------------------------------------------------------------------------------------------|
6875
| `inverterdatachannelpac` | Number:Power | AC Power generated |
6976
| `inverterdatachannelpdc` | Number:Power | DC Power calculated from DC voltage * DC current |
7077
| `inverterdatachannelpdc2` | Number:Power | DC Power generated by MPPT tracker 2 |
@@ -94,10 +101,24 @@ The binding has no configuration options, all configuration is done at `bridge`,
94101
| `powerflowinverter1power` | Number:Power | Current power of inverter 1, null if not running (+ produce/export, - consume/import) - DEPRECATED |
95102
| `powerflowinverter1soc` | Number:Dimensionless | Current state of charge of inverter 1 in percent - DEPRECATED |
96103

104+
### `battery` Thing Channels
105+
106+
| Channel ID | Item Type | Description |
107+
|--------------------|--------------------------|----------------------------------------|
108+
| `maximumCapacity` | Number:Energy | Current maximum battery capacity in Wh |
109+
| `designedCapacity` | Number:Energy | Designed battery capacity in Wh |
110+
| `currentDc` | Number:ElectricCurrent | DC current |
111+
| `voltageDc` | Number:ElectricPotential | DC voltage |
112+
| `soc` | Number:Dimensionless | State of charge in percent |
113+
| `status` | Number | Battery cell status code |
114+
| `enable` | Number | Enable flag for the battery controller |
115+
| `temperature` | Number:Temperature | Cell temperature |
116+
| `timestamp` | DateTime | Timestamp of the last measurement |
117+
97118
### `meter` Thing Channels
98119

99120
| Channel ID | Item Type | Description |
100-
| ----------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
121+
|-------------------------|--------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
101122
| `enable` | Number | 1 = enabled, 0 = disabled |
102123
| `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. |
103124
| `currentacphase1` | Number:ElectricCurrent | AC Current on Phase 1 |
@@ -119,7 +140,7 @@ The binding has no configuration options, all configuration is done at `bridge`,
119140
### `ohmpilot` Thing Channels
120141

121142
| Channel ID | Item Type | Description |
122-
| ----------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
143+
|-------------------------|--------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
123144
| `energyrealsumconsumed` | Number:Energy | Real Energy consumed |
124145
| `powerrealsum` | Number:Power | Real Power |
125146
| `temperaturechannel1` | Number:Temperature | Temperature |
@@ -128,17 +149,24 @@ The binding has no configuration options, all configuration is done at `bridge`,
128149

129150
## Properties
130151

152+
### `battery` Thing Properties
153+
154+
| Property | Description |
155+
|----------------|-----------------------------------|
156+
| `modelId` | The model name of the battery |
157+
| `serialNumber` | The serial number of the battery |
158+
131159
### `meter` Thing Properties
132160

133161
| Property | Description |
134-
| -------------- | ------------------------------ |
162+
|----------------|--------------------------------|
135163
| `modelId` | The model name of the meter |
136164
| `serialNumber` | The serial number of the meter |
137165

138166
### `ohmpilot` Thing Properties
139167

140168
| Property | Description |
141-
| -------------- | --------------------------------- |
169+
|----------------|-----------------------------------|
142170
| `modelId` | The model name of the ohmpilot |
143171
| `serialNumber` | The serial number of the ohmpilot |
144172

@@ -172,6 +200,19 @@ var froniusInverterActions = actions.thingActions('fronius', 'fronius:powerinver
172200

173201
:::
174202

203+
::: tab JRuby
204+
205+
In JRuby, the action methods are attached to the the Thing object.
206+
207+
```rb
208+
my_inverter = things["fronius:powerinverter:mybridge:myinverter"]
209+
210+
# call some actions
211+
my_inverter.prevent_battery_charging
212+
```
213+
214+
:::
215+
175216
::::
176217

177218
Where the first parameter must always be `fronius` and the second must be the full Thing UID of the inverter.
@@ -212,6 +253,10 @@ All methods return a boolean value indicating whether the action was successful.
212253

213254
### Examples
214255

256+
:::: tabs
257+
258+
::: tab JS
259+
215260
```javascript
216261
var froniusInverterActions = actions.thingActions('fronius', 'fronius:powerinverter:mybridge:myinverter');
217262

@@ -231,13 +276,41 @@ froniusInverterActions.addSchedule(time.toZDT('10:00'), time.toZDT('11:00'), 'DI
231276
froniusInverterActions.setBackupReservedBatteryCapacity(50);
232277
```
233278

279+
:::
280+
281+
::: JRuby
282+
283+
```rb
284+
inverter = things["fronius:powerinverter:mybridge:myinverter"]
285+
286+
inverter.reset_battery_control
287+
inverter.hold_battery_charge
288+
inverter.force_battery_charging(5 | "kW")
289+
290+
inverter.reset_battery_control
291+
inverter.add_hold_battery_charge_schedule(LocalTime.parse("18:00"), LocalTime.parse("22:00"))
292+
inverter.add_forced_battery_charging_schedule(LocalTime.parse("22:00"), LocalTime.parse("23:59"), 5 | "kW")
293+
inverter.add_forced_battery_charging_schedule(LocalTime.parse("00:00"), LocalTime.parse("06:00"), 5 | "kW")
294+
inverter.add_forced_battery_discharging_schedule(LocalTime.parse("07:00"), LocalTime.parse("09:00"))
295+
inverter.add_prevent_battery_charging_schedule(LocalTime.parse("09:00"), LocalTime.parse("12:00"))
296+
297+
inverter.add_schedule(LocalTime.parse("10:00"), LocalTime.parse("11:00"), 'DISCHARGE_MAX', 500 | "W")
298+
299+
inverter.set_backup_reserved_battery_capacity(50)
300+
```
301+
302+
:::
303+
304+
::::
305+
234306
## Full Example
235307

236308
demo.things:
237309

238310
```java
239311
Bridge fronius:bridge:mybridge [hostname="192.168.66.148", refreshInterval=5, username="customer", password="someSecretPassword", scheme="http"] {
240312
Thing powerinverter myinverter [deviceId=1]
313+
Thing battery mybattery [deviceId=0]
241314
Thing meter mymeter [deviceId=0]
242315
Thing ohmpilot myohmpilot [deviceId=0]
243316
}
@@ -291,6 +364,14 @@ Number:Power Ohmpilot_PowerSum { channel="fronius:ohmpilot:mybridge:myohmpilot:p
291364
Number:Temperature Ohmpilot_Temperature { channel="fronius:ohmpilot:mybridge:myohmpilot:temperaturechannel1" }
292365
Number Ohmpilot_State { channel="fronius:ohmpilot:mybridge:myohmpilot:statecode" }
293366
Number Ohmpilot_Errorcode { channel="fronius:ohmpilot:mybridge:myohmpilot:errorcode" }
367+
368+
Number:Energy Battery_MaxCapacity { channel="fronius:battery:mybridge:mybattery:maximumCapacity" }
369+
Number:Energy Battery_DesignedCapacity { channel="fronius:battery:mybridge:mybattery:designedCapacity" }
370+
Number:ElectricCurrent Battery_CurrentDC { channel="fronius:battery:mybridge:mybattery:currentDc" }
371+
Number:ElectricPotential Battery_VoltageDC { channel="fronius:battery:mybridge:mybattery:voltageDc" }
372+
Number:Dimensionless Battery_SOC { channel="fronius:battery:mybridge:mybattery:soc" }
373+
Number:Temperature Battery_Temperature { channel="fronius:battery:mybridge:mybattery:temperature" }
374+
DateTime Battery_Timestamp { channel="fronius:battery:mybridge:mybattery:timestamp" }
294375
```
295376

296377
Note: Make sure to turn on the **Night Mode** in the Display Settings on the Fronius inverter to keep it from going offline at night.

bundles/org.openhab.binding.fronius/src/main/java/org/openhab/binding/fronius/internal/FroniusBindingConstants.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public class FroniusBindingConstants {
3535
public static final ThingTypeUID THING_TYPE_INVERTER = new ThingTypeUID(BINDING_ID, "powerinverter");
3636
public static final ThingTypeUID THING_TYPE_METER = new ThingTypeUID(BINDING_ID, "meter");
3737
public static final ThingTypeUID THING_TYPE_OHMPILOT = new ThingTypeUID(BINDING_ID, "ohmpilot");
38+
public static final ThingTypeUID THING_TYPE_BATTERY = new ThingTypeUID(BINDING_ID, "battery");
3839

3940
// Inverter channels
4041
public static final String INVERTER_DATA_CHANNEL_DAY_ENERGY = "inverterdatachanneldayenergy";
@@ -97,12 +98,24 @@ public class FroniusBindingConstants {
9798
public static final String OHMPILOT_ERROR_CODE = "errorcode";
9899
public static final String OHMPILOT_STATE_CODE = "statecode";
99100

101+
// Battery channels (map to Storage Controller fields)
102+
public static final String BATTERY_CAPACITY_MAXIMUM = "maximumCapacity";
103+
public static final String BATTERY_DESIGNED_CAPACITY = "designedCapacity";
104+
public static final String BATTERY_CURRENT_DC = "currentDc";
105+
public static final String BATTERY_VOLTAGE_DC = "voltageDc";
106+
public static final String BATTERY_STATE_OF_CHARGE = "soc";
107+
public static final String BATTERY_STATUS_BATTERY_CELL = "status";
108+
public static final String BATTERY_ENABLE = "enable";
109+
public static final String BATTERY_TEMPERATURE_CELL = "temperature";
110+
public static final String BATTERY_TIMESTAMP = "timestamp";
111+
100112
// List of all Urls
101113
public static final String INVERTER_REALTIME_DATA_URL = "%SCHEME%://%IP%/solar_api/v1/GetInverterRealtimeData.cgi?Scope=Device&DeviceId=%DEVICEID%&DataCollection=CommonInverterData";
102114
public static final String INVERTER_INFO_URL = "%SCHEME%://%IP%/solar_api/v1/GetInverterInfo.cgi";
103115
public static final String POWERFLOW_REALTIME_DATA_URL = "%SCHEME%://%IP%/solar_api/v1/GetPowerFlowRealtimeData.fcgi";
104116
public static final String METER_REALTIME_DATA_URL = "%SCHEME%://%IP%/solar_api/v1/GetMeterRealtimeData.cgi?Scope=Device&DeviceId=%DEVICEID%&DataCollection=MeterRealtimeData";
105117
public static final String OHMPILOT_REALTIME_DATA_URL = "%SCHEME%://%IP%/solar_api/v1/GetOhmPilotRealtimeData.cgi?Scope=Device&DeviceId=%DEVICEID%";
118+
public static final String BATTERY_REALTIME_DATA_URL = "%SCHEME%://%IP%/solar_api/v1/GetStorageRealtimeData.cgi?Scope=Device&DeviceId=%DEVICEID%&DataCollection=StorageRealtimeData";
106119

107120
public static final int API_TIMEOUT = 5000;
108121
public static final int DEFAULT_REFRESH_PERIOD = 10;
@@ -127,6 +140,10 @@ public static String getOhmPilotDataUrl(String scheme, String ip, int deviceId)
127140
return parseUrl(OHMPILOT_REALTIME_DATA_URL, scheme, ip, deviceId);
128141
}
129142

143+
public static String getBatteryDataUrl(String scheme, String ip, int deviceId) {
144+
return parseUrl(BATTERY_REALTIME_DATA_URL, scheme, ip, deviceId);
145+
}
146+
130147
public static String parseUrl(String url, String scheme, String ip) {
131148
return url.replace("%SCHEME%", scheme).replace("%IP%", ip.trim());
132149
}

bundles/org.openhab.binding.fronius/src/main/java/org/openhab/binding/fronius/internal/FroniusHandlerFactory.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import org.eclipse.jdt.annotation.NonNullByDefault;
2121
import org.eclipse.jdt.annotation.Nullable;
22+
import org.openhab.binding.fronius.internal.handler.FroniusBatteryHandler;
2223
import org.openhab.binding.fronius.internal.handler.FroniusBridgeHandler;
2324
import org.openhab.binding.fronius.internal.handler.FroniusMeterHandler;
2425
import org.openhab.binding.fronius.internal.handler.FroniusOhmpilotHandler;
@@ -39,7 +40,9 @@
3940
* handlers.
4041
*
4142
* @author Thomas Rokohl - Initial contribution
43+
* @author Jimmy Tanagra - Added meter
4244
* @author Hannes Spenger - Added ohmpilot
45+
* @author Jimmy Tanagra - Added battery
4346
*/
4447
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.fronius")
4548
@NonNullByDefault
@@ -54,6 +57,7 @@ public class FroniusHandlerFactory extends BaseThingHandlerFactory {
5457
add(THING_TYPE_BRIDGE);
5558
add(THING_TYPE_METER);
5659
add(THING_TYPE_OHMPILOT);
60+
add(THING_TYPE_BATTERY);
5761
}
5862
};
5963

@@ -81,6 +85,8 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) {
8185
return new FroniusMeterHandler(thing);
8286
} else if (thingTypeUID.equals(THING_TYPE_OHMPILOT)) {
8387
return new FroniusOhmpilotHandler(thing);
88+
} else if (thingTypeUID.equals(THING_TYPE_BATTERY)) {
89+
return new FroniusBatteryHandler(thing);
8490
}
8591
return null;
8692
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
* Copyright (c) 2010-2026 Contributors to the openHAB project
3+
*
4+
* See the NOTICE file(s) distributed with this work for additional
5+
* information.
6+
*
7+
* This program and the accompanying materials are made available under the
8+
* terms of the Eclipse Public License 2.0 which is available at
9+
* http://www.eclipse.org/legal/epl-2.0
10+
*
11+
* SPDX-License-Identifier: EPL-2.0
12+
*/
13+
package org.openhab.binding.fronius.internal.api.dto.storage;
14+
15+
import com.google.gson.annotations.SerializedName;
16+
17+
/**
18+
* The {@link StorageController} is responsible for storing the "Controller" node
19+
* of the {@link StorageRealtimeResponse}.
20+
*
21+
* @author Jimmy Tanagra - Initial contribution
22+
*/
23+
public class StorageController {
24+
@SerializedName("Capacity_Maximum")
25+
private double capacityMaximum;
26+
27+
@SerializedName("Current_DC")
28+
private double currentDC;
29+
30+
@SerializedName("DesignedCapacity")
31+
private double designedCapacity;
32+
33+
@SerializedName("Details")
34+
private StorageDetails details;
35+
36+
@SerializedName("Enable")
37+
private int enable;
38+
39+
@SerializedName("StateOfCharge_Relative")
40+
private int stateOfChargeRelative;
41+
42+
@SerializedName("Status_BatteryCell")
43+
private int statusBatteryCell;
44+
45+
@SerializedName("Temperature_Cell")
46+
private double temperatureCell;
47+
48+
@SerializedName("TimeStamp")
49+
private int timeStamp;
50+
51+
@SerializedName("Voltage_DC")
52+
private double voltageDC;
53+
54+
public double getCapacityMaximum() {
55+
return capacityMaximum;
56+
}
57+
58+
public double getCurrentDC() {
59+
return currentDC;
60+
}
61+
62+
public double getDesignedCapacity() {
63+
return designedCapacity;
64+
}
65+
66+
public StorageDetails getDetails() {
67+
if (details == null) {
68+
details = new StorageDetails();
69+
}
70+
return details;
71+
}
72+
73+
public int getEnable() {
74+
return enable;
75+
}
76+
77+
public int getStateOfChargeRelative() {
78+
return stateOfChargeRelative;
79+
}
80+
81+
public int getStatusBatteryCell() {
82+
return statusBatteryCell;
83+
}
84+
85+
public double getTemperatureCell() {
86+
return temperatureCell;
87+
}
88+
89+
public int getTimeStamp() {
90+
return timeStamp;
91+
}
92+
93+
public double getVoltageDC() {
94+
return voltageDC;
95+
}
96+
}

0 commit comments

Comments
 (0)