Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #78 and #80 #81

Merged
merged 7 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading