Skip to content

Commit

Permalink
attempt to rework config flow to improve other phase configuration su…
Browse files Browse the repository at this point in the history
…pport and granular number entities
  • Loading branch information
Sven ten Raa committed May 9, 2023
1 parent 266ca4a commit d15abb6
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 16 deletions.
2 changes: 1 addition & 1 deletion custom_components/victron/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant

from .const import DOMAIN, CONF_HOST, CONF_PORT, SCAN_REGISTERS, CONF_INTERVAL, CONF_AC_SYSTEM_VOLTAGE, CONF_AC_CURRENT_LIMIT, CONF_DC_SYSTEM_VOLTAGE, CONF_DC_CURRENT_LIMIT
from .const import DOMAIN, CONF_HOST, CONF_PORT, SCAN_REGISTERS, CONF_INTERVAL
from .coordinator import victronEnergyDeviceUpdateCoordinator as Coordinator

PLATFORMS: list[Platform] = [Platform.SENSOR, Platform.SWITCH, Platform.NUMBER, Platform.SELECT, Platform.BINARY_SENSOR, Platform.BUTTON]
Expand Down
33 changes: 27 additions & 6 deletions custom_components/victron/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

from homeassistant.config_entries import ConfigEntry, ConfigFlow, OptionsFlow

from .const import DOMAIN, CONF_HOST, CONF_PORT, CONF_INTERVAL, RegisterInfo, SCAN_REGISTERS, CONF_ADVANCED_OPTIONS, CONF_DC_SYSTEM_VOLTAGE, CONF_AC_SYSTEM_VOLTAGE, CONF_DC_CURRENT_LIMIT, CONF_AC_CURRENT_LIMIT, DC_VOLTAGES, AC_VOLTAGES
from .const import DOMAIN, CONF_HOST, CONF_PORT, CONF_INTERVAL, RegisterInfo, SCAN_REGISTERS, CONF_ADVANCED_OPTIONS, CONF_DC_SYSTEM_VOLTAGE, CONF_AC_SYSTEM_VOLTAGE, CONF_DC_CURRENT_LIMIT, CONF_AC_CURRENT_LIMIT, CONF_NUMBER_OF_PHASES, CONF_USE_SLIDERS, DC_VOLTAGES, AC_VOLTAGES, PHASE_CONFIGURATIONS
from .hub import VictronHub

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -152,6 +152,8 @@ async def async_step_advanced(self, user_input=None):
options[CONF_PORT] = self.port
options[CONF_INTERVAL] = self.interval
options[CONF_ADVANCED_OPTIONS] = bool(self.advanced_options)
options[CONF_NUMBER_OF_PHASES] = int(user_input[CONF_NUMBER_OF_PHASES])
options[CONF_USE_SLIDERS] = bool(user_input[CONF_USE_SLIDERS])
options[CONF_AC_SYSTEM_VOLTAGE] = int(user_input[CONF_AC_SYSTEM_VOLTAGE])
options[CONF_DC_SYSTEM_VOLTAGE] = int(user_input[CONF_DC_SYSTEM_VOLTAGE])

Expand All @@ -172,14 +174,22 @@ async def async_step_advanced(self, user_input=None):
errors=errors,
data_schema=vol.Schema(
{
vol.Required(CONF_AC_SYSTEM_VOLTAGE, default=str(AC_VOLTAGES["US"])): SelectSelector(
vol.Required(CONF_AC_SYSTEM_VOLTAGE, default=str(AC_VOLTAGES["US (120)"])): SelectSelector(
SelectSelectorConfig(
options=[
SelectOptionDict(value=str(value), label=key)
for key, value in AC_VOLTAGES.items()
]
),
),
vol.Required(CONF_NUMBER_OF_PHASES, default=str(PHASE_CONFIGURATIONS["single phase"])): SelectSelector(
SelectSelectorConfig(
options=[
SelectOptionDict(value=str(value), label=key)
for key, value in PHASE_CONFIGURATIONS.items()
]
),
),
vol.Required(CONF_AC_CURRENT_LIMIT, default=0): vol.All(vol.Coerce(int, "must be a number")),
vol.Required(CONF_DC_SYSTEM_VOLTAGE, default=str(DC_VOLTAGES["lifepo4_12v"])): SelectSelector(
SelectSelectorConfig(
Expand All @@ -189,7 +199,8 @@ async def async_step_advanced(self, user_input=None):
]
),
),
vol.Required(CONF_DC_CURRENT_LIMIT, default= 0): vol.All(vol.Coerce(int, "must be a number"))
vol.Required(CONF_DC_CURRENT_LIMIT, default= 0): vol.All(vol.Coerce(int, "must be a number")),
vol.Optional(CONF_USE_SLIDERS, default=True): bool
}))


Expand Down Expand Up @@ -333,8 +344,9 @@ def init_read_form(self, errors: dict):

def init_write_form(self, errors: dict):
config = dict(self.config_entry.options)
system_ac_voltage_default = self.config_entry.options.get(CONF_AC_SYSTEM_VOLTAGE, AC_VOLTAGES["US"])
system_ac_voltage_default = self.config_entry.options.get(CONF_AC_SYSTEM_VOLTAGE, AC_VOLTAGES["US (120)"])
system_dc_voltage_default = self.config_entry.options.get(CONF_DC_SYSTEM_VOLTAGE, DC_VOLTAGES["lifepo4_12v"])
system_number_of_phases_default = self.config_entry.options.get(CONF_NUMBER_OF_PHASES, PHASE_CONFIGURATIONS["single phase"])
errors = {}
return self.async_show_form(
step_id="init_write",
Expand All @@ -352,7 +364,15 @@ def init_write_form(self, errors: dict):
]
),
),
vol.Required(CONF_AC_CURRENT_LIMIT, default=config.get(CONF_AC_CURRENT_LIMIT, 0)): vol.All(vol.Coerce(int, "must be a number")),
vol.Required(CONF_NUMBER_OF_PHASES, default=str(system_number_of_phases_default)): SelectSelector(
SelectSelectorConfig(
options=[
SelectOptionDict(value=str(value), label=key)
for key, value in PHASE_CONFIGURATIONS.items()
]
),
),
vol.Required(CONF_AC_CURRENT_LIMIT, default=config.get(CONF_AC_CURRENT_LIMIT, 1)): vol.All(vol.Coerce(int, "must be the max current of a single phase as a number")),
vol.Required(CONF_DC_SYSTEM_VOLTAGE, default=str(system_dc_voltage_default)): SelectSelector(
SelectSelectorConfig(
options=[
Expand All @@ -361,7 +381,8 @@ def init_write_form(self, errors: dict):
]
),
),
vol.Required(CONF_DC_CURRENT_LIMIT, default=config.get(CONF_DC_CURRENT_LIMIT,1)): vol.All(vol.Coerce(int, "must be a number")),
vol.Required(CONF_DC_CURRENT_LIMIT, default=config.get(CONF_DC_CURRENT_LIMIT,1)): vol.All(vol.Coerce(int, "must be the total DC current for the system as a number")),
vol.Optional(CONF_USE_SLIDERS, default=config.get(CONF_USE_SLIDERS, config.get(CONF_USE_SLIDERS, True))): bool,
vol.Optional(CONF_RESCAN, default=False): bool,
vol.Optional(CONF_ADVANCED_OPTIONS, default=True): bool
},
Expand Down
6 changes: 4 additions & 2 deletions custom_components/victron/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@ class DeviceType(Enum):
CONF_DC_CURRENT_LIMIT = "dc_current"
CONF_DC_SYSTEM_VOLTAGE = "dc_voltage"
CONF_AC_SYSTEM_VOLTAGE = "ac_voltage"
CONF_NUMBER_OF_PHASES = "number_of_phases"
CONF_USE_SLIDERS = "use_sliders"

AC_VOLTAGES = { "US": 120, "EU": 230 } # For now only most common voltages supported
AC_VOLTAGES = { "US (120)": 120, "EU (230)": 230 } # For now only most common voltages supported
DC_VOLTAGES = { "lifepo4_12v": 12, "lifepo4_24v": 24, "lifepo4_48v": 48 } #only 3 volt nominal 4s, 8s and 16s lifepo4 configurations currently supported

PHASE_CONFIGURATIONS = { "single phase": 1, "split phase": 2, "three phase": 3 }

class STRING():
def __init__(self, length=1, read_length=None):
Expand Down
12 changes: 9 additions & 3 deletions custom_components/victron/number.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
UINT16_MAX,
CONF_DC_SYSTEM_VOLTAGE,
CONF_DC_CURRENT_LIMIT,
CONF_NUMBER_OF_PHASES,
CONF_USE_SLIDERS,
CONF_AC_SYSTEM_VOLTAGE,
CONF_AC_CURRENT_LIMIT)

Expand Down Expand Up @@ -71,6 +73,7 @@ async def async_setup_entry(
native_unit_of_measurement=registerInfo.unit,
# native_min_value=registerInfo.writeType.lowerLimit,
# native_max_value=registerInfo.writeType.upperLimit,
mode=NumberMode.SLIDER if config_entry.options[CONF_USE_SLIDERS] else NumberMode.BOX,
native_min_value=determine_min_value(registerInfo.unit, config_entry.options, registerInfo.entityType.powerType, registerInfo.entityType.negative),
native_max_value=determine_max_value(registerInfo.unit, config_entry.options, registerInfo.entityType.powerType),
entity_category=EntityCategory.CONFIG,
Expand Down Expand Up @@ -102,7 +105,7 @@ def determine_min_value(unit, config_entry: config_entries.ConfigEntry, powerTyp
return min_value
elif unit == UnitOfPower.WATT:
if negative:
min_value = (int(config_entry[CONF_AC_SYSTEM_VOLTAGE]) * config_entry[CONF_AC_CURRENT_LIMIT]) if powerType == "AC" else (int(config_entry[CONF_DC_SYSTEM_VOLTAGE].dc_voltage) * config_entry[CONF_DC_CURRENT_LIMIT])
min_value = (int(config_entry[CONF_AC_SYSTEM_VOLTAGE]) * int(config_entry[CONF_NUMBER_OF_PHASES]) * config_entry[CONF_AC_CURRENT_LIMIT]) if powerType == "AC" else (int(config_entry[CONF_DC_SYSTEM_VOLTAGE].dc_voltage) * config_entry[CONF_DC_CURRENT_LIMIT])
rounded_min = -round(min_value/100)*100
_LOGGER.debug(rounded_min)
return rounded_min
Expand All @@ -127,7 +130,7 @@ def determine_max_value(unit, config_entry:config_entries.ConfigEntry, powerType
max_value = series_type * 3.65 #statically based on lifepo4 cells
return max_value
elif unit == UnitOfPower.WATT:
max_value = (int(config_entry[CONF_AC_SYSTEM_VOLTAGE]) * config_entry[CONF_AC_CURRENT_LIMIT]) if powerType == "AC" else (int(config_entry[CONF_DC_SYSTEM_VOLTAGE]) * config_entry[CONF_DC_CURRENT_LIMIT])
max_value = (int(config_entry[CONF_AC_SYSTEM_VOLTAGE]) * int(config_entry[CONF_NUMBER_OF_PHASES]) * config_entry[CONF_AC_CURRENT_LIMIT]) if powerType == "AC" else (int(config_entry[CONF_DC_SYSTEM_VOLTAGE]) * config_entry[CONF_DC_CURRENT_LIMIT])
rounded_max = round(max_value/100)*100
return rounded_max
elif unit == ELECTRIC_CURRENT_AMPERE:
Expand All @@ -143,6 +146,7 @@ def determine_max_value(unit, config_entry:config_entries.ConfigEntry, powerType
class VictronNumberMixin:
"""A class that describes number entities."""
scale: int
mode: bool

class VictronNumberStep:
step: float = 0
Expand Down Expand Up @@ -178,7 +182,7 @@ def __init__(self, coordinator: victronEnergyDeviceUpdateCoordinator, descriptio
else:
self.entity_id = f"{NUMBER_DOMAIN}.{DOMAIN}_{self.description.key}"

self._attr_mode = NumberMode.SLIDER
self._attr_mode = self.description.mode



Expand All @@ -201,6 +205,8 @@ def native_value(self) -> float:

@property
def native_step(self) -> float | None:
if not self.description.mode == NumberMode.SLIDER: # allow users to skip stepping in case of box mode
return None
if self.description.step > 0:
return self.description.step
max = self.native_max_value
Expand Down
2 changes: 2 additions & 0 deletions custom_components/victron/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
},
"advanced": {
"data": {
"use_sliders": "[%key:common::config_flow::data::use_sliders%]",
"number_of_phases": "[%key:common::config_flow::data::number_of_phases%]",
"ac_voltage": "[%key:common::config_flow::data::ac_voltage%]",
"dc_voltage": "[%key:common::config_flow::data::dc_voltage%]",
"dc_current": "[%key:common::config_flow::data::ac_current%]",
Expand Down
14 changes: 10 additions & 4 deletions custom_components/victron/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@
"advanced": {
"data": {
"ac_voltage": "The AC voltage of your grid in V",
"ac_current": "The AC current limit of your grid in A",
"ac_current": "The AC (per phase) current limit of your grid in A",
"dc_voltage": "The DC voltage of your battery in V",
"dc_current": "The DC current limit of your battery in A"
"dc_current": "The DC current limit of your battery in A",
"number_of_phases": "The phase configuration of your system",
"use_sliders": "Use stepped sliders for writeable number entities"
}
}
}
Expand All @@ -35,9 +37,11 @@
"rescan": "Rescan available devices. This will rescan all available devices",
"interval": "Update interval in (s)",
"ac_voltage": "The AC voltage of your grid in V",
"ac_current": "The AC current limit of your grid in A",
"ac_current": "The AC (per phase) current limit of your grid in A",
"dc_voltage": "The DC voltage of your battery in V",
"dc_current": "The DC current limit of your battery in A",
"number_of_phases": "The phase configuration of your system",
"use_sliders": "Use stepped sliders for writeable number entities",
"advanced": "switch to read only mode if unchecked (when submitted)"
}
},
Expand All @@ -53,7 +57,9 @@
"ac_voltage": "The AC voltage of your grid in V",
"ac_current": "The AC current limit of your grid in A",
"dc_voltage": "The DC voltage of your battery in V",
"dc_current": "The DC current limit of your battery in A"
"dc_current": "The DC current limit of your battery in A",
"number_of_phases": "The phase configuration of your system",
"use_sliders": "Use stepped sliders for writeable number entities"
}
}
}
Expand Down

0 comments on commit d15abb6

Please sign in to comment.