Skip to content

Commit 3d275d9

Browse files
authored
Merge pull request #81 from RustyDust/sru_work
Fixes #78 and #80
2 parents a76943f + 857fb6b commit 3d275d9

File tree

9 files changed

+125
-15
lines changed

9 files changed

+125
-15
lines changed

README.md

Lines changed: 77 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,66 @@
1+
[![hacs_badge][hacsbadge]][hacs] [![hainstall][hainstallbadge]][hainstall]
12
# ha_sonnenbatterie
23
Homeassistant integration to show many stats of Sonnenbatterie
34
that should work with current versions of Sonnenbatterie.
45

56
[![Validate with hassfest](https://github.com/weltmeyer/ha_sonnenbatterie/actions/workflows/hassfest.yaml/badge.svg)](https://github.com/weltmeyer/ha_sonnenbatterie/actions/workflows/hassfest.yaml)
67
[![Validate with HACS](https://github.com/weltmeyer/ha_sonnenbatterie/actions/workflows/validate.yaml/badge.svg)](https://github.com/weltmeyer/ha_sonnenbatterie/actions/workflows/validate.yaml)
78

8-
## Installation
9-
Easiest way to install is to add this repository via [HACS](https://hacs.xyz).
10-
11-
## Tested working with
9+
### Tested working with
1210
* eco 8.03 9010 ND
1311
* eco 8.0 DE 9010 ND
1412
* sonnenBatterie 10 performance
1513

1614
### Won't work with older Batteries
1715
* ex. model 9.2 eco from 2014 not working
1816

17+
## Installation
18+
19+
### 1) via HACS
20+
1. Add a custom **integration** repository to HACS using this link:
21+
[https://github.com/weltmeyer/hasonnenbatterie](https://github.com/weltmeyer/hasonnenbatterie)
22+
> [!IMPORTANT]
23+
> This is a **HACS _integration_**, not a **HASS-IO _AddOn_**, so you <ins>need to have [HACS](https://hacs.xyz) installed</ins>,
24+
> and you need to add this repository as a custom **integration repository** to HACS.
25+
2. Once the repository is added, use the search bar and type `sonnenbatterie`
26+
3. Use the 3-dot menu to the right of the list entry (not the one at the top bar!) to download/install the integration.
27+
The latest release is automatically selected. Only select a different version if you've been told to do so
28+
by one of the maintainers.
29+
4. After you press download and the process has completed, you have to __Restart Home Assistant__ to install the
30+
dependencies required by the integration
31+
5. Setup the `sonnenbatterie` custom integration
32+
33+
### 2) Manual installation
34+
35+
1. Using your tool of choice open the directory (folder) where your HA configuration resides, e.g. where the
36+
`configuration.yaml` is
37+
2. If you don't have a `custom_components` directory (folder) there, create it
38+
3. In the `custom_components` directory (folder) create a new folder called `sonnenbatterie`
39+
4. Download _all_ the files from the `custom_components/sonnenbatterie/` directory (folder) from this repository
40+
5. Place the files you downloaded in the new directory (folder) `sonnenbatterie` you created
41+
6. Restart Home Assistant
42+
7. Setup the sonnenbatterie custom integration as described below (see [Adding or enabling the integration](#adding_or_enabling_the_integration))
43+
44+
## Adding or enabling the integration
45+
46+
> [!IMPORTANT]
47+
> The integration must be [installed](#installation) before you can start to add or enable it!
48+
49+
### 1) My Home Assistant
50+
51+
Just click the following Button to start the configuration automatically:
52+
53+
[![Open your Home Assistant instance and start setting up a new integration.](https://my.home-assistant.io/badges/config_flow_start.svg)][hainstall]
54+
55+
### 2) Manual
56+
57+
- Open the Home Assistant we interface
58+
- Go to `Configuration -> Integrations` and click the "Add Integration" button in the lower right corner
59+
- Search for "sonnenbatterie", select the correct entry and click on it
60+
- This starts the configuration of a new Sonnenbatterie instance. Make sure to
61+
- provide the correct IP address of your Sonnenbatterie within your network
62+
- set the update interval to a reasonable value
63+
1964
## Sensors
2065
The main focus of the integration is to provide a comprehensive set of sensors
2166
for your SonnenBatterie. Right after installation the most relevant sensors
@@ -30,6 +75,13 @@ are already activated.
3075
Since version 2025.01.01 this integration also supports actions you can use to
3176
set some variables that influence the behaviour of your SonnenBatterie.
3277

78+
> [!NOTE]
79+
> All actions require you ro provide a `device_id` to correctly identify the
80+
> Sonnenbatterie you want to talk to. To find the device id for your Sonnenbatterie
81+
> use the developer tools provided by Home Assistant. Just open the "Actions" tab
82+
> and select an action an a device. Then switch to YAML mode where instead of the
83+
> user-friendly name the device id will be displayed.
84+
3385
Currently supported actions are:
3486

3587
### <a name="set_operatingmode"></a>`set_operating_mode(mode=<mode>)`
@@ -43,6 +95,7 @@ Currently supported actions are:
4395
``` yaml
4496
action: sonnenbatterie.set_operating_mode
4597
data:
98+
device_id: "<your sb instance's device id>"
4699
mode: "automatic"
47100
```
48101
@@ -73,6 +126,7 @@ An `int` representing the mode that has been set:
73126
``` yaml
74127
action: sonnenbatterie.charge_battery
75128
data:
129+
device_id: "<your sb instance's device id>"
76130
power: 0
77131
```
78132

@@ -103,6 +157,7 @@ otherwise.
103157
``` yaml
104158
action: sonnenbatterie.discharge_battery
105159
data:
160+
device_id: "<your sb instance's device id>"
106161
power: 0
107162
```
108163

@@ -119,6 +174,7 @@ otherwise.
119174
``` yaml
120175
action: sonnenbatterie.set_battery_reserve
121176
data:
177+
device_id: "<your sb instance's device id>"
122178
value: 10
123179
```
124180

@@ -158,12 +214,13 @@ An integer representing the current value of "battery reserve"
158214
``` yaml
159215
action: sonnenbatterie.set_config_item
160216
data:
217+
device_id: "<your sb instance's device id>"
161218
item: "EM_USOC"
162219
value: "10"
163220
```
164221
##### Response
165222
``` json
166-
{'EM_USOC': '10'}
223+
{"EM_USOC": "10"}
167224
```
168225

169226
### <a name="set_tou_schedule"></a>`set_tou_schedule(schedule=<schedule_array>)`
@@ -191,13 +248,14 @@ data:
191248
``` yaml
192249
action: sonnenbatterie.set_tou_schedule_string
193250
data:
251+
device_id: "<your sb instance's device id>"
194252
schedule: '[{"start":"10:00", "stop":"10:00", "threshold_p_max": 20000}]'
195253
```
196254

197255
##### Result
198256
``` json
199257
{
200-
"schedule": '[{"start": "10:00", "stop": "10:00", "threshold_p_max": 20000}]'
258+
"schedule": [{"start": "10:00", "stop": "10:00", "threshold_p_max": 20000}]
201259
}
202260
```
203261

@@ -207,12 +265,15 @@ data:
207265
##### Code snippet
208266
``` yaml
209267
action: sonnenbatterie.get_tou_schedule
210-
data: {}
268+
data:
269+
deviceid: "<your sb instance's device id>"
211270
```
212271

213272
##### Result
214-
``` yaml
215-
schedule: "[{\"start\":\"10:00\", \"stop\":\"10:00\", \"threshold_p_max\": 20000}]"
273+
``` json
274+
{
275+
"schedule": [{"start": "10:00", "stop": "10:00", "threshold_p_max": 20000}]
276+
}
216277
```
217278

218279
## Problems and/or unused/unavailable sensors
@@ -233,3 +294,10 @@ Please put those logs along with the setting you want monitored into
233294

234295
## Screenshots :)
235296
![image](https://user-images.githubusercontent.com/1668465/78452159-ed2d7d80-7689-11ea-9e30-3a66ecc2372a.png)
297+
298+
---
299+
[hacs]: https://hacs.xyz
300+
[hacsbadge]: https://img.shields.io/badge/HACS-Custom-orange.svg?style=for-the-badge&logo=homeassistantcommunitystore&logoColor=ccc
301+
302+
[hainstall]: https://my.home-assistant.io/redirect/config_flow_start/?domain=sonnenbatterie
303+
[hainstallbadge]: https://img.shields.io/badge/dynamic/json?style=for-the-badge&logo=home-assistant&logoColor=ccc&label=usage&suffix=%20installs&cacheSeconds=15600&url=https://analytics.home-assistant.io/custom_integrations.json&query=$.sonnenbatterie.total

custom_components/sonnenbatterie/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,14 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
9393
hass.data[DOMAIN][config_entry.entry_id][CONF_COORDINATOR] = sb_coordinator
9494

9595
inverter_power = sb_coordinator.latestData['battery_system']['battery_system']['system']['inverter_capacity']
96+
LOGGER.debug(f"inverter_power: {inverter_power}")
9697

9798
# noinspection PyPep8Naming
9899
SCHEMA_CHARGE_BATTERY = vol.Schema(
99100
{
100101
**cv.ENTITY_SERVICE_FIELDS,
101-
vol.Required(CONF_CHARGE_WATT): vol.Range(min=0, max=inverter_power),
102+
# vol.Required(CONF_CHARGE_WATT): vol.Range(min=0, max=inverter_power),
103+
vol.Required(CONF_CHARGE_WATT): str,
102104
}
103105
)
104106

custom_components/sonnenbatterie/entities.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@ def __str__(self) -> str:
5656
writable=True,
5757
)
5858

59+
BATTERY_RESERVE = SelectEntry(
60+
key="battery_reserve",
61+
type=Platform.NUMBER,
62+
section="status",
63+
property="USOC",
64+
writable=True,
65+
)
66+
5967
BTN_RESET_CHARGE = SelectEntry(
6068
key="button_reset_charge",
6169
type=Platform.BUTTON,
@@ -131,7 +139,7 @@ def unique_id(self) -> str:
131139
class SonnenbatterieNumberEntityDescription(NumberEntityDescription):
132140
tag: Tag = None
133141
native_min_value = 0
134-
native_step = 100
142+
native_step = 1
135143

136144

137145
class SonnenNumberEntity(CoordinatorEntity[SonnenbatterieCoordinator], Entity):
@@ -204,6 +212,7 @@ def unique_id(self) -> str:
204212
tag=Tag.CHARGE_POWER,
205213
device_class=NumberDeviceClass.POWER,
206214
mode=NumberMode.SLIDER,
215+
native_step=100,
207216
),
208217
SonnenbatterieNumberEntityDescription(
209218
key=Tag.DISCHARGE_POWER.key,
@@ -212,6 +221,16 @@ def unique_id(self) -> str:
212221
tag=Tag.DISCHARGE_POWER,
213222
device_class=NumberDeviceClass.POWER,
214223
mode=NumberMode.SLIDER,
224+
native_step=100,
225+
),
226+
SonnenbatterieNumberEntityDescription(
227+
key=Tag.BATTERY_RESERVE.key,
228+
icon="mdi:battery-unknown",
229+
entity_category=EntityCategory.CONFIG,
230+
tag=Tag.BATTERY_RESERVE,
231+
device_class=NumberDeviceClass.BATTERY,
232+
mode=NumberMode.SLIDER,
233+
native_step=1,
215234
)
216235
]
217236

custom_components/sonnenbatterie/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@
88
"iot_class": "local_polling",
99
"issue_tracker": "https://github.com/weltmeyer/ha_sonnenbatterie/issues",
1010
"requirements": ["requests","sonnenbatterie>=0.5.2"],
11-
"version": "2025.01.02"
11+
"version": "2025.01.03"
1212
}

custom_components/sonnenbatterie/number.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@ class SonnenbatterieNumber(SonnenNumberEntity, NumberEntity):
2727

2828
def __init__(self, coordinator: SonnenbatterieCoordinator, description: SonnenbatterieNumberEntityDescription, max_power: int) -> None:
2929
super().__init__(coordinator, description)
30-
self._max_power = max_power
30+
LOGGER.debug(f"SonnenbatterieNumberEntity: {description}")
31+
if description.key == "battery_reserve":
32+
self._max_power = 100
33+
else:
34+
self._max_power = max_power
3135

3236
@property
3337
def native_max_value(self) -> int:
@@ -42,5 +46,7 @@ async def async_set_native_value(self, value):
4246
await self.coordinator.sbconn.sb2.charge_battery(int(value))
4347
case "number_discharge":
4448
await self.coordinator.sbconn.sb2.discharge_battery(int(value))
49+
case "battery_reserve":
50+
await self.coordinator.sbconn.sb2.set_battery_reserve(int(value))
4551
await self.coordinator.async_request_refresh()
4652
return None

custom_components/sonnenbatterie/service.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,10 @@ def _get_sb_connection(self, call_data: ReadOnlyDict) -> AsyncSonnenBatterie:
4949

5050
# service definitions
5151
async def charge_battery(self, call: ServiceCall) -> ServiceResponse:
52+
LOGGER.debug(f"_charge_battery: {call.data}")
5253
power = int(call.data.get(CONF_CHARGE_WATT))
54+
if power < 0:
55+
power = 0
5356
# Make sure we have an sb2 object
5457
sb_conn = self._get_sb_connection(call.data)
5558
# await sb_conn.login()
@@ -60,7 +63,10 @@ async def charge_battery(self, call: ServiceCall) -> ServiceResponse:
6063
}
6164

6265
async def discharge_battery(self, call: ServiceCall) -> ServiceResponse:
66+
LOGGER.debug(f"_discharge_battery: {call.data}")
6367
power = int(call.data.get(CONF_CHARGE_WATT))
68+
if power < 0:
69+
power = 0
6470
sb_conn = self._get_sb_connection(call.data)
6571
# await sb_conn.login()
6672
response = await sb_conn.sb2.discharge_battery(power)

custom_components/sonnenbatterie/services.yaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ charge_battery:
2222
required: true
2323
example: "1000"
2424
selector:
25-
number:
25+
text:
26+
suffix: "W"
2627
discharge_battery:
2728
fields:
2829
device_id:
@@ -34,7 +35,8 @@ discharge_battery:
3435
required: true
3536
example: "1000"
3637
selector:
37-
number:
38+
text:
39+
suffix: "W"
3840
set_battery_reserve:
3941
fields:
4042
device_id:

custom_components/sonnenbatterie/translations/de.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@
5151
},
5252
"number_discharge": {
5353
"name": "Entladen erzwingen (W)"
54+
},
55+
"battery_reserve": {
56+
"name": "Batterie-Reserve einstellen (%)"
5457
}
5558
},
5659
"select": {

custom_components/sonnenbatterie/translations/en.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,11 @@
5151
},
5252
"number_discharge": {
5353
"name": "Force discharge (W)"
54+
},
55+
"battery_reserve": {
56+
"name": "Set battery reserve (%)"
5457
}
58+
5559
},
5660
"select": {
5761
"select_operating_mode": {

0 commit comments

Comments
 (0)