Skip to content

Commit d15abb6

Browse files
author
Sven ten Raa
committed
attempt to rework config flow to improve other phase configuration support and granular number entities
1 parent 266ca4a commit d15abb6

File tree

6 files changed

+53
-16
lines changed

6 files changed

+53
-16
lines changed

custom_components/victron/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from homeassistant.const import Platform
66
from homeassistant.core import HomeAssistant
77

8-
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
8+
from .const import DOMAIN, CONF_HOST, CONF_PORT, SCAN_REGISTERS, CONF_INTERVAL
99
from .coordinator import victronEnergyDeviceUpdateCoordinator as Coordinator
1010

1111
PLATFORMS: list[Platform] = [Platform.SENSOR, Platform.SWITCH, Platform.NUMBER, Platform.SELECT, Platform.BINARY_SENSOR, Platform.BUTTON]

custom_components/victron/config_flow.py

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
from homeassistant.config_entries import ConfigEntry, ConfigFlow, OptionsFlow
2626

27-
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
27+
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
2828
from .hub import VictronHub
2929

3030
_LOGGER = logging.getLogger(__name__)
@@ -152,6 +152,8 @@ async def async_step_advanced(self, user_input=None):
152152
options[CONF_PORT] = self.port
153153
options[CONF_INTERVAL] = self.interval
154154
options[CONF_ADVANCED_OPTIONS] = bool(self.advanced_options)
155+
options[CONF_NUMBER_OF_PHASES] = int(user_input[CONF_NUMBER_OF_PHASES])
156+
options[CONF_USE_SLIDERS] = bool(user_input[CONF_USE_SLIDERS])
155157
options[CONF_AC_SYSTEM_VOLTAGE] = int(user_input[CONF_AC_SYSTEM_VOLTAGE])
156158
options[CONF_DC_SYSTEM_VOLTAGE] = int(user_input[CONF_DC_SYSTEM_VOLTAGE])
157159

@@ -172,14 +174,22 @@ async def async_step_advanced(self, user_input=None):
172174
errors=errors,
173175
data_schema=vol.Schema(
174176
{
175-
vol.Required(CONF_AC_SYSTEM_VOLTAGE, default=str(AC_VOLTAGES["US"])): SelectSelector(
177+
vol.Required(CONF_AC_SYSTEM_VOLTAGE, default=str(AC_VOLTAGES["US (120)"])): SelectSelector(
176178
SelectSelectorConfig(
177179
options=[
178180
SelectOptionDict(value=str(value), label=key)
179181
for key, value in AC_VOLTAGES.items()
180182
]
181183
),
182184
),
185+
vol.Required(CONF_NUMBER_OF_PHASES, default=str(PHASE_CONFIGURATIONS["single phase"])): SelectSelector(
186+
SelectSelectorConfig(
187+
options=[
188+
SelectOptionDict(value=str(value), label=key)
189+
for key, value in PHASE_CONFIGURATIONS.items()
190+
]
191+
),
192+
),
183193
vol.Required(CONF_AC_CURRENT_LIMIT, default=0): vol.All(vol.Coerce(int, "must be a number")),
184194
vol.Required(CONF_DC_SYSTEM_VOLTAGE, default=str(DC_VOLTAGES["lifepo4_12v"])): SelectSelector(
185195
SelectSelectorConfig(
@@ -189,7 +199,8 @@ async def async_step_advanced(self, user_input=None):
189199
]
190200
),
191201
),
192-
vol.Required(CONF_DC_CURRENT_LIMIT, default= 0): vol.All(vol.Coerce(int, "must be a number"))
202+
vol.Required(CONF_DC_CURRENT_LIMIT, default= 0): vol.All(vol.Coerce(int, "must be a number")),
203+
vol.Optional(CONF_USE_SLIDERS, default=True): bool
193204
}))
194205

195206

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

334345
def init_write_form(self, errors: dict):
335346
config = dict(self.config_entry.options)
336-
system_ac_voltage_default = self.config_entry.options.get(CONF_AC_SYSTEM_VOLTAGE, AC_VOLTAGES["US"])
347+
system_ac_voltage_default = self.config_entry.options.get(CONF_AC_SYSTEM_VOLTAGE, AC_VOLTAGES["US (120)"])
337348
system_dc_voltage_default = self.config_entry.options.get(CONF_DC_SYSTEM_VOLTAGE, DC_VOLTAGES["lifepo4_12v"])
349+
system_number_of_phases_default = self.config_entry.options.get(CONF_NUMBER_OF_PHASES, PHASE_CONFIGURATIONS["single phase"])
338350
errors = {}
339351
return self.async_show_form(
340352
step_id="init_write",
@@ -352,7 +364,15 @@ def init_write_form(self, errors: dict):
352364
]
353365
),
354366
),
355-
vol.Required(CONF_AC_CURRENT_LIMIT, default=config.get(CONF_AC_CURRENT_LIMIT, 0)): vol.All(vol.Coerce(int, "must be a number")),
367+
vol.Required(CONF_NUMBER_OF_PHASES, default=str(system_number_of_phases_default)): SelectSelector(
368+
SelectSelectorConfig(
369+
options=[
370+
SelectOptionDict(value=str(value), label=key)
371+
for key, value in PHASE_CONFIGURATIONS.items()
372+
]
373+
),
374+
),
375+
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")),
356376
vol.Required(CONF_DC_SYSTEM_VOLTAGE, default=str(system_dc_voltage_default)): SelectSelector(
357377
SelectSelectorConfig(
358378
options=[
@@ -361,7 +381,8 @@ def init_write_form(self, errors: dict):
361381
]
362382
),
363383
),
364-
vol.Required(CONF_DC_CURRENT_LIMIT, default=config.get(CONF_DC_CURRENT_LIMIT,1)): vol.All(vol.Coerce(int, "must be a number")),
384+
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")),
385+
vol.Optional(CONF_USE_SLIDERS, default=config.get(CONF_USE_SLIDERS, config.get(CONF_USE_SLIDERS, True))): bool,
365386
vol.Optional(CONF_RESCAN, default=False): bool,
366387
vol.Optional(CONF_ADVANCED_OPTIONS, default=True): bool
367388
},

custom_components/victron/const.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,12 @@ class DeviceType(Enum):
3737
CONF_DC_CURRENT_LIMIT = "dc_current"
3838
CONF_DC_SYSTEM_VOLTAGE = "dc_voltage"
3939
CONF_AC_SYSTEM_VOLTAGE = "ac_voltage"
40+
CONF_NUMBER_OF_PHASES = "number_of_phases"
41+
CONF_USE_SLIDERS = "use_sliders"
4042

41-
AC_VOLTAGES = { "US": 120, "EU": 230 } # For now only most common voltages supported
43+
AC_VOLTAGES = { "US (120)": 120, "EU (230)": 230 } # For now only most common voltages supported
4244
DC_VOLTAGES = { "lifepo4_12v": 12, "lifepo4_24v": 24, "lifepo4_48v": 48 } #only 3 volt nominal 4s, 8s and 16s lifepo4 configurations currently supported
43-
45+
PHASE_CONFIGURATIONS = { "single phase": 1, "split phase": 2, "three phase": 3 }
4446

4547
class STRING():
4648
def __init__(self, length=1, read_length=None):

custom_components/victron/number.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
UINT16_MAX,
3434
CONF_DC_SYSTEM_VOLTAGE,
3535
CONF_DC_CURRENT_LIMIT,
36+
CONF_NUMBER_OF_PHASES,
37+
CONF_USE_SLIDERS,
3638
CONF_AC_SYSTEM_VOLTAGE,
3739
CONF_AC_CURRENT_LIMIT)
3840

@@ -71,6 +73,7 @@ async def async_setup_entry(
7173
native_unit_of_measurement=registerInfo.unit,
7274
# native_min_value=registerInfo.writeType.lowerLimit,
7375
# native_max_value=registerInfo.writeType.upperLimit,
76+
mode=NumberMode.SLIDER if config_entry.options[CONF_USE_SLIDERS] else NumberMode.BOX,
7477
native_min_value=determine_min_value(registerInfo.unit, config_entry.options, registerInfo.entityType.powerType, registerInfo.entityType.negative),
7578
native_max_value=determine_max_value(registerInfo.unit, config_entry.options, registerInfo.entityType.powerType),
7679
entity_category=EntityCategory.CONFIG,
@@ -102,7 +105,7 @@ def determine_min_value(unit, config_entry: config_entries.ConfigEntry, powerTyp
102105
return min_value
103106
elif unit == UnitOfPower.WATT:
104107
if negative:
105-
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])
108+
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])
106109
rounded_min = -round(min_value/100)*100
107110
_LOGGER.debug(rounded_min)
108111
return rounded_min
@@ -127,7 +130,7 @@ def determine_max_value(unit, config_entry:config_entries.ConfigEntry, powerType
127130
max_value = series_type * 3.65 #statically based on lifepo4 cells
128131
return max_value
129132
elif unit == UnitOfPower.WATT:
130-
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])
133+
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])
131134
rounded_max = round(max_value/100)*100
132135
return rounded_max
133136
elif unit == ELECTRIC_CURRENT_AMPERE:
@@ -143,6 +146,7 @@ def determine_max_value(unit, config_entry:config_entries.ConfigEntry, powerType
143146
class VictronNumberMixin:
144147
"""A class that describes number entities."""
145148
scale: int
149+
mode: bool
146150

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

181-
self._attr_mode = NumberMode.SLIDER
185+
self._attr_mode = self.description.mode
182186

183187

184188

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

202206
@property
203207
def native_step(self) -> float | None:
208+
if not self.description.mode == NumberMode.SLIDER: # allow users to skip stepping in case of box mode
209+
return None
204210
if self.description.step > 0:
205211
return self.description.step
206212
max = self.native_max_value

custom_components/victron/strings.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
},
1212
"advanced": {
1313
"data": {
14+
"use_sliders": "[%key:common::config_flow::data::use_sliders%]",
15+
"number_of_phases": "[%key:common::config_flow::data::number_of_phases%]",
1416
"ac_voltage": "[%key:common::config_flow::data::ac_voltage%]",
1517
"dc_voltage": "[%key:common::config_flow::data::dc_voltage%]",
1618
"dc_current": "[%key:common::config_flow::data::ac_current%]",

custom_components/victron/translations/en.json

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@
2121
"advanced": {
2222
"data": {
2323
"ac_voltage": "The AC voltage of your grid in V",
24-
"ac_current": "The AC current limit of your grid in A",
24+
"ac_current": "The AC (per phase) current limit of your grid in A",
2525
"dc_voltage": "The DC voltage of your battery in V",
26-
"dc_current": "The DC current limit of your battery in A"
26+
"dc_current": "The DC current limit of your battery in A",
27+
"number_of_phases": "The phase configuration of your system",
28+
"use_sliders": "Use stepped sliders for writeable number entities"
2729
}
2830
}
2931
}
@@ -35,9 +37,11 @@
3537
"rescan": "Rescan available devices. This will rescan all available devices",
3638
"interval": "Update interval in (s)",
3739
"ac_voltage": "The AC voltage of your grid in V",
38-
"ac_current": "The AC current limit of your grid in A",
40+
"ac_current": "The AC (per phase) current limit of your grid in A",
3941
"dc_voltage": "The DC voltage of your battery in V",
4042
"dc_current": "The DC current limit of your battery in A",
43+
"number_of_phases": "The phase configuration of your system",
44+
"use_sliders": "Use stepped sliders for writeable number entities",
4145
"advanced": "switch to read only mode if unchecked (when submitted)"
4246
}
4347
},
@@ -53,7 +57,9 @@
5357
"ac_voltage": "The AC voltage of your grid in V",
5458
"ac_current": "The AC current limit of your grid in A",
5559
"dc_voltage": "The DC voltage of your battery in V",
56-
"dc_current": "The DC current limit of your battery in A"
60+
"dc_current": "The DC current limit of your battery in A",
61+
"number_of_phases": "The phase configuration of your system",
62+
"use_sliders": "Use stepped sliders for writeable number entities"
5763
}
5864
}
5965
}

0 commit comments

Comments
 (0)