Skip to content

Commit

Permalink
Merge pull request #81 from RustyDust/sru_work
Browse files Browse the repository at this point in the history
Fixes #78 and #80
  • Loading branch information
RustyDust authored Jan 24, 2025
2 parents a76943f + 857fb6b commit 3d275d9
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 15 deletions.
86 changes: 77 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,66 @@
[![hacs_badge][hacsbadge]][hacs] [![hainstall][hainstallbadge]][hainstall]
# ha_sonnenbatterie
Homeassistant integration to show many stats of Sonnenbatterie
that should work with current versions of Sonnenbatterie.

[![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)
[![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)

## Installation
Easiest way to install is to add this repository via [HACS](https://hacs.xyz).

## Tested working with
### Tested working with
* eco 8.03 9010 ND
* eco 8.0 DE 9010 ND
* sonnenBatterie 10 performance

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

## Installation

### 1) via HACS
1. Add a custom **integration** repository to HACS using this link:
[https://github.com/weltmeyer/hasonnenbatterie](https://github.com/weltmeyer/hasonnenbatterie)
> [!IMPORTANT]
> This is a **HACS _integration_**, not a **HASS-IO _AddOn_**, so you <ins>need to have [HACS](https://hacs.xyz) installed</ins>,
> and you need to add this repository as a custom **integration repository** to HACS.
2. Once the repository is added, use the search bar and type `sonnenbatterie`
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.
The latest release is automatically selected. Only select a different version if you've been told to do so
by one of the maintainers.
4. After you press download and the process has completed, you have to __Restart Home Assistant__ to install the
dependencies required by the integration
5. Setup the `sonnenbatterie` custom integration

### 2) Manual installation

1. Using your tool of choice open the directory (folder) where your HA configuration resides, e.g. where the
`configuration.yaml` is
2. If you don't have a `custom_components` directory (folder) there, create it
3. In the `custom_components` directory (folder) create a new folder called `sonnenbatterie`
4. Download _all_ the files from the `custom_components/sonnenbatterie/` directory (folder) from this repository
5. Place the files you downloaded in the new directory (folder) `sonnenbatterie` you created
6. Restart Home Assistant
7. Setup the sonnenbatterie custom integration as described below (see [Adding or enabling the integration](#adding_or_enabling_the_integration))

## Adding or enabling the integration

> [!IMPORTANT]
> The integration must be [installed](#installation) before you can start to add or enable it!
### 1) My Home Assistant

Just click the following Button to start the configuration automatically:

[![Open your Home Assistant instance and start setting up a new integration.](https://my.home-assistant.io/badges/config_flow_start.svg)][hainstall]

### 2) Manual

- Open the Home Assistant we interface
- Go to `Configuration -> Integrations` and click the "Add Integration" button in the lower right corner
- Search for "sonnenbatterie", select the correct entry and click on it
- This starts the configuration of a new Sonnenbatterie instance. Make sure to
- provide the correct IP address of your Sonnenbatterie within your network
- set the update interval to a reasonable value

## Sensors
The main focus of the integration is to provide a comprehensive set of sensors
for your SonnenBatterie. Right after installation the most relevant sensors
Expand All @@ -30,6 +75,13 @@ are already activated.
Since version 2025.01.01 this integration also supports actions you can use to
set some variables that influence the behaviour of your SonnenBatterie.

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

### <a name="set_operatingmode"></a>`set_operating_mode(mode=<mode>)`
Expand All @@ -43,6 +95,7 @@ Currently supported actions are:
``` yaml
action: sonnenbatterie.set_operating_mode
data:
device_id: "<your sb instance's device id>"
mode: "automatic"
```
Expand Down Expand Up @@ -73,6 +126,7 @@ An `int` representing the mode that has been set:
``` yaml
action: sonnenbatterie.charge_battery
data:
device_id: "<your sb instance's device id>"
power: 0
```

Expand Down Expand Up @@ -103,6 +157,7 @@ otherwise.
``` yaml
action: sonnenbatterie.discharge_battery
data:
device_id: "<your sb instance's device id>"
power: 0
```

Expand All @@ -119,6 +174,7 @@ otherwise.
``` yaml
action: sonnenbatterie.set_battery_reserve
data:
device_id: "<your sb instance's device id>"
value: 10
```

Expand Down Expand Up @@ -158,12 +214,13 @@ An integer representing the current value of "battery reserve"
``` yaml
action: sonnenbatterie.set_config_item
data:
device_id: "<your sb instance's device id>"
item: "EM_USOC"
value: "10"
```
##### Response
``` json
{'EM_USOC': '10'}
{"EM_USOC": "10"}
```

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

##### Result
``` json
{
"schedule": '[{"start": "10:00", "stop": "10:00", "threshold_p_max": 20000}]'
"schedule": [{"start": "10:00", "stop": "10:00", "threshold_p_max": 20000}]
}
```

Expand All @@ -207,12 +265,15 @@ data:
##### Code snippet
``` yaml
action: sonnenbatterie.get_tou_schedule
data: {}
data:
deviceid: "<your sb instance's device id>"
```

##### Result
``` yaml
schedule: "[{\"start\":\"10:00\", \"stop\":\"10:00\", \"threshold_p_max\": 20000}]"
``` json
{
"schedule": [{"start": "10:00", "stop": "10:00", "threshold_p_max": 20000}]
}
```

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

## Screenshots :)
![image](https://user-images.githubusercontent.com/1668465/78452159-ed2d7d80-7689-11ea-9e30-3a66ecc2372a.png)

---
[hacs]: https://hacs.xyz
[hacsbadge]: https://img.shields.io/badge/HACS-Custom-orange.svg?style=for-the-badge&logo=homeassistantcommunitystore&logoColor=ccc

[hainstall]: https://my.home-assistant.io/redirect/config_flow_start/?domain=sonnenbatterie
[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
4 changes: 3 additions & 1 deletion custom_components/sonnenbatterie/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,14 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
hass.data[DOMAIN][config_entry.entry_id][CONF_COORDINATOR] = sb_coordinator

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

# noinspection PyPep8Naming
SCHEMA_CHARGE_BATTERY = vol.Schema(
{
**cv.ENTITY_SERVICE_FIELDS,
vol.Required(CONF_CHARGE_WATT): vol.Range(min=0, max=inverter_power),
# vol.Required(CONF_CHARGE_WATT): vol.Range(min=0, max=inverter_power),
vol.Required(CONF_CHARGE_WATT): str,
}
)

Expand Down
21 changes: 20 additions & 1 deletion custom_components/sonnenbatterie/entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ def __str__(self) -> str:
writable=True,
)

BATTERY_RESERVE = SelectEntry(
key="battery_reserve",
type=Platform.NUMBER,
section="status",
property="USOC",
writable=True,
)

BTN_RESET_CHARGE = SelectEntry(
key="button_reset_charge",
type=Platform.BUTTON,
Expand Down Expand Up @@ -131,7 +139,7 @@ def unique_id(self) -> str:
class SonnenbatterieNumberEntityDescription(NumberEntityDescription):
tag: Tag = None
native_min_value = 0
native_step = 100
native_step = 1


class SonnenNumberEntity(CoordinatorEntity[SonnenbatterieCoordinator], Entity):
Expand Down Expand Up @@ -204,6 +212,7 @@ def unique_id(self) -> str:
tag=Tag.CHARGE_POWER,
device_class=NumberDeviceClass.POWER,
mode=NumberMode.SLIDER,
native_step=100,
),
SonnenbatterieNumberEntityDescription(
key=Tag.DISCHARGE_POWER.key,
Expand All @@ -212,6 +221,16 @@ def unique_id(self) -> str:
tag=Tag.DISCHARGE_POWER,
device_class=NumberDeviceClass.POWER,
mode=NumberMode.SLIDER,
native_step=100,
),
SonnenbatterieNumberEntityDescription(
key=Tag.BATTERY_RESERVE.key,
icon="mdi:battery-unknown",
entity_category=EntityCategory.CONFIG,
tag=Tag.BATTERY_RESERVE,
device_class=NumberDeviceClass.BATTERY,
mode=NumberMode.SLIDER,
native_step=1,
)
]

Expand Down
2 changes: 1 addition & 1 deletion custom_components/sonnenbatterie/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
"iot_class": "local_polling",
"issue_tracker": "https://github.com/weltmeyer/ha_sonnenbatterie/issues",
"requirements": ["requests","sonnenbatterie>=0.5.2"],
"version": "2025.01.02"
"version": "2025.01.03"
}
8 changes: 7 additions & 1 deletion custom_components/sonnenbatterie/number.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ class SonnenbatterieNumber(SonnenNumberEntity, NumberEntity):

def __init__(self, coordinator: SonnenbatterieCoordinator, description: SonnenbatterieNumberEntityDescription, max_power: int) -> None:
super().__init__(coordinator, description)
self._max_power = max_power
LOGGER.debug(f"SonnenbatterieNumberEntity: {description}")
if description.key == "battery_reserve":
self._max_power = 100
else:
self._max_power = max_power

@property
def native_max_value(self) -> int:
Expand All @@ -42,5 +46,7 @@ async def async_set_native_value(self, value):
await self.coordinator.sbconn.sb2.charge_battery(int(value))
case "number_discharge":
await self.coordinator.sbconn.sb2.discharge_battery(int(value))
case "battery_reserve":
await self.coordinator.sbconn.sb2.set_battery_reserve(int(value))
await self.coordinator.async_request_refresh()
return None
6 changes: 6 additions & 0 deletions custom_components/sonnenbatterie/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ def _get_sb_connection(self, call_data: ReadOnlyDict) -> AsyncSonnenBatterie:

# service definitions
async def charge_battery(self, call: ServiceCall) -> ServiceResponse:
LOGGER.debug(f"_charge_battery: {call.data}")
power = int(call.data.get(CONF_CHARGE_WATT))
if power < 0:
power = 0
# Make sure we have an sb2 object
sb_conn = self._get_sb_connection(call.data)
# await sb_conn.login()
Expand All @@ -60,7 +63,10 @@ async def charge_battery(self, call: ServiceCall) -> ServiceResponse:
}

async def discharge_battery(self, call: ServiceCall) -> ServiceResponse:
LOGGER.debug(f"_discharge_battery: {call.data}")
power = int(call.data.get(CONF_CHARGE_WATT))
if power < 0:
power = 0
sb_conn = self._get_sb_connection(call.data)
# await sb_conn.login()
response = await sb_conn.sb2.discharge_battery(power)
Expand Down
6 changes: 4 additions & 2 deletions custom_components/sonnenbatterie/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ charge_battery:
required: true
example: "1000"
selector:
number:
text:
suffix: "W"
discharge_battery:
fields:
device_id:
Expand All @@ -34,7 +35,8 @@ discharge_battery:
required: true
example: "1000"
selector:
number:
text:
suffix: "W"
set_battery_reserve:
fields:
device_id:
Expand Down
3 changes: 3 additions & 0 deletions custom_components/sonnenbatterie/translations/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@
},
"number_discharge": {
"name": "Entladen erzwingen (W)"
},
"battery_reserve": {
"name": "Batterie-Reserve einstellen (%)"
}
},
"select": {
Expand Down
4 changes: 4 additions & 0 deletions custom_components/sonnenbatterie/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,11 @@
},
"number_discharge": {
"name": "Force discharge (W)"
},
"battery_reserve": {
"name": "Set battery reserve (%)"
}

},
"select": {
"select_operating_mode": {
Expand Down

0 comments on commit 3d275d9

Please sign in to comment.