Skip to content

Commit

Permalink
Merge pull request #94 from nathanmarlor/feature/auto-energy
Browse files Browse the repository at this point in the history
Automatically configure energy dashboard through config flow
  • Loading branch information
nathanmarlor authored Mar 30, 2023
2 parents 465d4a0 + 895e07e commit 137329b
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 4 deletions.
1 change: 1 addition & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"request": "attach",
"port": 5678,
"host": "localhost",
"justMyCode": false,
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
Expand Down
93 changes: 90 additions & 3 deletions custom_components/foxess_modbus/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
import voluptuous as vol
from custom_components.foxess_modbus import ModbusClient
from homeassistant import config_entries
from homeassistant.components.energy import data
from homeassistant.components.energy.data import BatterySourceType
from homeassistant.components.energy.data import EnergyPreferencesUpdate
from homeassistant.components.energy.data import FlowFromGridSourceType
from homeassistant.components.energy.data import FlowToGridSourceType
from homeassistant.components.energy.data import GridSourceType
from homeassistant.components.energy.data import SolarSourceType
from homeassistant.core import callback
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.selector import selector
Expand All @@ -16,6 +23,7 @@
from .const import ADD_ANOTHER
from .const import CONFIG_SAVE_TIME
from .const import DOMAIN
from .const import ENERGY_DASHBOARD
from .const import FRIENDLY_NAME
from .const import INVERTER_BASE
from .const import INVERTER_CONN
Expand Down Expand Up @@ -57,7 +65,7 @@ def __init__(self, config=None) -> None:
{
vol.Required(INVERTER_TYPE, default="TCP"): selector(
{"select": {"options": ["TCP", "SERIAL"]}}
)
),
}
)

Expand Down Expand Up @@ -92,6 +100,12 @@ def __init__(self, config=None) -> None:
}
)

self._energy_dash = vol.Schema(
{
vol.Required(ENERGY_DASHBOARD, default=False): bool,
}
)

async def async_step_init(self, user_input: dict[str, Any] = None):
"""Handle a flow initialized by the user."""
self._errors = {}
Expand Down Expand Up @@ -126,7 +140,7 @@ async def async_step_tcp(self, user_input: dict[str, Any] = None):
errors=self._errors,
)
elif result:
return self.async_create_entry(title=_TITLE, data=self._data)
return await self.async_step_energy()

return self.async_show_form(
step_id="tcp", data_schema=self._modbus_tcp_schema, errors=self._errors
Expand All @@ -148,14 +162,27 @@ async def async_step_serial(self, user_input: dict[str, Any] = None):
errors=self._errors,
)
elif result:
return self.async_create_entry(title=_TITLE, data=self._data)
return await self.async_step_energy()

return self.async_show_form(
step_id="serial",
data_schema=self._modbus_serial_schema,
errors=self._errors,
)

async def async_step_energy(self, user_input: dict[str, Any] = None):
"""Handle a flow initialized by the user."""
if user_input is not None:
if user_input[ENERGY_DASHBOARD]:
await self._setup_energy_dashboard()
return self.async_create_entry(title=_TITLE, data=self._data)

return self.async_show_form(
step_id="energy",
data_schema=self._energy_dash,
errors=self._errors,
)

def detect_duplicate(self, inv_type, host, friendly_name):
"""Detect duplicates"""
if host in self._data[inv_type]:
Expand Down Expand Up @@ -211,6 +238,66 @@ async def _autodetect_modbus(self, inv_type, host, slave):
self._errors["base"] = "modbus_error"
return False, None

async def _setup_energy_dashboard(self):
"""Setup Energy Dashboard"""
manager = await data.async_get_manager(self.hass)

friendly_names = self._get_friendly_names(self._data)

def _prefix_name(name):
if name != "":
return f"sensor.{name}_"
else:
return "sensor."

energy_prefs = EnergyPreferencesUpdate(energy_sources=[])
for name in friendly_names:
name_prefix = _prefix_name(name)
energy_prefs["energy_sources"].extend(
[
SolarSourceType(
type="solar", stat_energy_from=f"{name_prefix}pv1_energy_total"
),
SolarSourceType(
type="solar", stat_energy_from=f"{name_prefix}pv2_energy_total"
),
BatterySourceType(
type="battery",
stat_energy_to=f"{name_prefix}battery_charge_total",
stat_energy_from=f"{name_prefix}battery_discharge_total",
),
]
)

grid_source = GridSourceType(
type="grid", flow_from=[], flow_to=[], cost_adjustment_day=0
)
for name in friendly_names:
name_prefix = _prefix_name(name)
grid_source["flow_from"].append(
FlowFromGridSourceType(
stat_energy_from=f"{name_prefix}grid_consumption_energy_total"
)
)
grid_source["flow_to"].append(
FlowToGridSourceType(
stat_energy_to=f"{name_prefix}feed_in_energy_total"
)
)
energy_prefs["energy_sources"].append(grid_source)

await manager.async_update(energy_prefs)

def _get_friendly_names(self, data_dict):
"""Return all friendly names"""
names = []
inverters = {k: v for k, v in data_dict.items() if k in (TCP, SERIAL)}
for _, host_dict in inverters.items():
for _, name_dict in host_dict.items():
names.extend(list(name_dict.keys()))

return names

@staticmethod
@callback
def async_get_options_flow(config_entry):
Expand Down
2 changes: 2 additions & 0 deletions custom_components/foxess_modbus/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
CONNECTION = "connection"
MODBUS = "modbus"

ENERGY_DASHBOARD = "energy_dashboard"

# Defaults
DEFAULT_NAME = DOMAIN

Expand Down
2 changes: 1 addition & 1 deletion custom_components/foxess_modbus/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "FoxESS - Modbus",
"codeowners": ["@nathanmarlor"],
"config_flow": true,
"dependencies": ["integration"],
"dependencies": ["energy", "integration"],
"documentation": "https://github.com/nathanmarlor/foxess_modbus",
"integration_type": "service",
"iot_class": "local_push",
Expand Down
6 changes: 6 additions & 0 deletions custom_components/foxess_modbus/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@
"modbus_slave": "Modbus Slave",
"add_another": "Add another device"
}
},
"energy": {
"description": "Warning: this will overwrite any existing settings. \nWe recommend checking the configuration at (https://your-ha.com/config/energy)",
"data": {
"energy_dashboard": "Automatically configure the Energy Dashboard"
}
}
},
"error": {
Expand Down

0 comments on commit 137329b

Please sign in to comment.