Skip to content

Commit

Permalink
Add phase awareness to slider entities
Browse files Browse the repository at this point in the history
Limits the single phase entities to the maximum power rating for the single phase
This change might result in int min/max outliers due to the min/max of the slider shifting and possibly being out of bounds before the shift.
  • Loading branch information
sfstar committed Feb 25, 2024
1 parent 05c57ed commit ae64cbb
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 22 deletions.
21 changes: 11 additions & 10 deletions custom_components/victron/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,11 @@ def __init__(self) -> None:
super().__init__(entityTypeName="switch")

class SliderWriteType(EntityType):
def __init__(self, powerType="", negative: bool=False) -> None:
def __init__(self, powerType="", negative: bool=False, phaseApplicability: int = 0) -> None:
super().__init__(entityTypeName="slider")
self.powerType = powerType
self.negative = negative
self.phaseApplicability = phaseApplicability

class SelectWriteType(EntityType):
def __init__(self, optionsEnum: Enum) -> None:
Expand Down Expand Up @@ -210,7 +211,7 @@ class vebus_error(Enum):
"vebus_out_L2_current": RegisterInfo(19, INT16, UnitOfElectricCurrent.AMPERE, 10),
"vebus_out_L3_current": RegisterInfo(20, INT16, UnitOfElectricCurrent.AMPERE, 10),
"vebus_out_L1_frequency": RegisterInfo(21, INT16, UnitOfFrequency.HERTZ, 100),
"vebus_activein_currentlimit": RegisterInfo(22, INT16, UnitOfElectricCurrent.AMPERE, 10, SliderWriteType("AC", True)),
"vebus_activein_currentlimit": RegisterInfo(22, INT16, UnitOfElectricCurrent.AMPERE, 10, SliderWriteType("AC", True, 1)),
"vebus_out_L1_power": RegisterInfo(23, INT16, UnitOfPower.WATT, 0.1),
"vebus_out_L2_power": RegisterInfo(24, INT16, UnitOfPower.WATT, 0.1),
"vebus_out_L3_power": RegisterInfo(25, INT16, UnitOfPower.WATT, 0.1),
Expand All @@ -225,11 +226,11 @@ class vebus_error(Enum):
"vebus_alarm_hightemperature": RegisterInfo(register=34, dataType=UINT16, entityType=TextReadEntityType(generic_alarm_ledger)), #This has no unit of measurement
"vebus_alarm_lowbattery": RegisterInfo(register=35, dataType=UINT16, entityType=TextReadEntityType(generic_alarm_ledger)), #This has no unit of measurement
"vebus_alarm_overload": RegisterInfo(register=36,dataType=UINT16, entityType=TextReadEntityType(generic_alarm_ledger)), #This has no unit of measurement
"vebus_L1_acpowersetpoint": RegisterInfo(register=37, dataType=INT16, unit=UnitOfPower.WATT, entityType=SliderWriteType("AC", True)),
"vebus_L1_acpowersetpoint": RegisterInfo(register=37, dataType=INT16, unit=UnitOfPower.WATT, entityType=SliderWriteType("AC", True, 1)),
"vebus_disablecharge": RegisterInfo(register=38, dataType=UINT16, entityType=SwitchWriteType()), #This has no unit of measurement
"vebus_disablefeedin": RegisterInfo(39, UINT16, entityType=SwitchWriteType()), #This has no unit of measurement
"vebus_L2_acpowersetpoint": RegisterInfo(register=40, dataType=INT16, unit=UnitOfPower.WATT, entityType=SliderWriteType("AC", True)),
"vebus_L3_acpowersetpoint": RegisterInfo(register=41, dataType=INT16, unit=UnitOfPower.WATT, entityType=SliderWriteType("AC", True)),
"vebus_L2_acpowersetpoint": RegisterInfo(register=40, dataType=INT16, unit=UnitOfPower.WATT, entityType=SliderWriteType("AC", True, 1)),
"vebus_L3_acpowersetpoint": RegisterInfo(register=41, dataType=INT16, unit=UnitOfPower.WATT, entityType=SliderWriteType("AC", True, 1)),
"vebus_alarm_temperaturesensor": RegisterInfo(register=42, dataType=UINT16, entityType=TextReadEntityType(generic_alarm_ledger)), #This has no unit of measurement
"vebus_alarm_voltagesensor": RegisterInfo(register=43, dataType=UINT16, entityType=TextReadEntityType(generic_alarm_ledger)), #This has no unit of measurement
"vebus_alarm_L1_higtemperature": RegisterInfo(register=44, dataType=UINT16, entityType=TextReadEntityType(generic_alarm_ledger)), #This has no unit of measurement
Expand All @@ -254,9 +255,9 @@ class vebus_error(Enum):
"vebus_alarm_phaserotation": RegisterInfo(register=63, dataType=UINT16, entityType=TextReadEntityType(generic_alarm_ledger)), #This has no unit of measurement
"vebus_alarm_gridlost": RegisterInfo(register=64, dataType=UINT16, entityType=TextReadEntityType(generic_alarm_ledger)), #This has no unit of measurement
"vebus_donotfeedinovervoltage": RegisterInfo(register=65, dataType=UINT16, entityType=SwitchWriteType()), #This has no unit of measurement
"vebus_L1_maxfeedinpower": RegisterInfo(66, UINT16, UnitOfPower.WATT, 0.01, SliderWriteType("AC", False)),
"vebus_L2_maxfeedinpower": RegisterInfo(67, UINT16, UnitOfPower.WATT, 0.01, SliderWriteType("AC", False)),
"vebus_L3_maxfeedinpower": RegisterInfo(68, UINT16, UnitOfPower.WATT, 0.01, SliderWriteType("AC", False)),
"vebus_L1_maxfeedinpower": RegisterInfo(66, UINT16, UnitOfPower.WATT, 0.01, SliderWriteType("AC", False, 1)),
"vebus_L2_maxfeedinpower": RegisterInfo(67, UINT16, UnitOfPower.WATT, 0.01, SliderWriteType("AC", False, 1)),
"vebus_L3_maxfeedinpower": RegisterInfo(68, UINT16, UnitOfPower.WATT, 0.01, SliderWriteType("AC", False, 1)),
"vebus_state_ignoreacin1": RegisterInfo(register=69, dataType=UINT16, entityType=BoolReadEntityType()), #This has no unit of measurement
"vebus_state_ignoreacin2": RegisterInfo(register=70, dataType=UINT16, entityType=BoolReadEntityType()), #This has no unit of measurement
"vebus_targetpowerismaxfeedin": RegisterInfo(register=71, dataType=UINT16, entityType=SwitchWriteType()), #This has no unit of measurement
Expand Down Expand Up @@ -1198,8 +1199,8 @@ class multi_input_type(Enum):
"multi_output_L1_frequency": RegisterInfo(4519, UINT16, UnitOfFrequency.HERTZ, 100),
"multi_input_1_type": RegisterInfo(register=4520, dataType=UINT16, entityType=TextReadEntityType(multi_input_type)),
"multi_input_2_type": RegisterInfo(register=4521, dataType=UINT16, entityType=TextReadEntityType(multi_input_type)),
"multi_input_1_currentlimit": RegisterInfo(4522, UINT16, UnitOfElectricCurrent.AMPERE, 10, SliderWriteType("AC", False)),
"multi_input_2_currentlimit": RegisterInfo(4523, UINT16, UnitOfElectricCurrent.AMPERE, 10, SliderWriteType("AC", False)),
"multi_input_1_currentlimit": RegisterInfo(4522, UINT16, UnitOfElectricCurrent.AMPERE, 10, SliderWriteType("AC", False, 1)),
"multi_input_2_currentlimit": RegisterInfo(4523, UINT16, UnitOfElectricCurrent.AMPERE, 10, SliderWriteType("AC", False, 1)),
"multi_numberofphases": RegisterInfo(4524, UINT16),
"multi_activein_activeinput": RegisterInfo(register=4525, dataType=UINT16, entityType=TextReadEntityType(generic_activeinput)),
"multi_battery_voltage": RegisterInfo(4526, UINT16, UnitOfElectricPotential.VOLT, 100),
Expand Down
20 changes: 8 additions & 12 deletions custom_components/victron/number.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,19 +61,15 @@ async def async_setup_entry(
for slave, registerLedger in register_set.items():
for name in registerLedger:
for register_name, registerInfo in register_info_dict[name].items():
# _LOGGER.debug("unit == " + str(slave) + " registerLedger == " + str(registerLedger) + " registerInfo ")
# _LOGGER.debug(str(registerInfo.slave))
# _LOGGER.debug("register_name")
# _LOGGER.debug(register_name)
if isinstance(registerInfo.entityType, SliderWriteType):
descriptions.append(VictronEntityDescription(
key=register_name,
name=register_name.replace('_', ' '),
slave=slave,
native_unit_of_measurement=registerInfo.unit,
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),
native_min_value=determine_min_value(registerInfo.unit, config_entry.options, registerInfo.entityType.powerType, registerInfo.entityType.negative, registerInfo.entityType.phaseApplicability),
native_max_value=determine_max_value(registerInfo.unit, config_entry.options, registerInfo.entityType.powerType, registerInfo.entityType.phaseApplicability),
entity_category=EntityCategory.CONFIG,
address=registerInfo.register,
scale = registerInfo.scale,
Expand All @@ -91,10 +87,8 @@ async def async_setup_entry(
))
_LOGGER.debug("adding number")
async_add_entities(entities)
_LOGGER.debug("adding numbering")


def determine_min_value(unit, config_entry: config_entries.ConfigEntry, powerType, negative: bool) -> int:
def determine_min_value(unit, config_entry: config_entries.ConfigEntry, powerType, negative: bool, phaseApplicability: int) -> int:
if unit == PERCENTAGE:
return 0
elif unit == UnitOfElectricPotential.VOLT:
Expand All @@ -103,7 +97,8 @@ 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]) * 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])
number_of_phases = phaseApplicability if phaseApplicability > 0 else int(config_entry[CONF_NUMBER_OF_PHASES])
min_value = (int(config_entry[CONF_AC_SYSTEM_VOLTAGE]) * 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 @@ -120,15 +115,16 @@ def determine_min_value(unit, config_entry: config_entries.ConfigEntry, powerTyp
else:
return 0

def determine_max_value(unit, config_entry:config_entries.ConfigEntry, powerType) -> int:
def determine_max_value(unit, config_entry:config_entries.ConfigEntry, powerType, phaseApplicability) -> int:
if unit == PERCENTAGE:
return 100
elif unit == UnitOfElectricPotential.VOLT:
series_type = int(config_entry[CONF_DC_SYSTEM_VOLTAGE]) / 3 #statically based on lifepo4 cells
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]) * 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])
number_of_phases = phaseApplicability if phaseApplicability > 0 else int(config_entry[CONF_NUMBER_OF_PHASES])
max_value = (int(config_entry[CONF_AC_SYSTEM_VOLTAGE]) * 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 == UnitOfElectricCurrent.AMPERE:
Expand Down

0 comments on commit ae64cbb

Please sign in to comment.