Skip to content

Commit

Permalink
autodetect supported measurands (#968)
Browse files Browse the repository at this point in the history
* autodetect supported measurands

* fix ConfigurationStatus check

* remove measurands from config flow
  • Loading branch information
lbbrhzn authored Nov 10, 2023
1 parent e067eee commit 64dab6e
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 80 deletions.
23 changes: 22 additions & 1 deletion custom_components/ocpp/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,10 +430,31 @@ async def handle_data_transfer(call):
resp = await self.get_configuration(ckey.number_of_connectors.value)
self._metrics[cdet.connectors.value].value = resp
await self.get_configuration(ckey.heartbeat_interval.value)

all_measurands = self.entry.data.get(
CONF_MONITORED_VARIABLES, DEFAULT_MEASURAND
)

accepted_measurands = []
key = ckey.meter_values_sampled_data.value

for measurand in all_measurands.split(","):
_LOGGER.debug(f"'{self.id}' trying measurand '{measurand}'")
req = call.ChangeConfigurationPayload(key=key, value=measurand)
resp = await self.call(req)
if resp.status == ConfigurationStatus.accepted:
_LOGGER.debug(f"'{self.id}' adding measurand '{measurand}'")
accepted_measurands.append(measurand)

accepted_measurands = ",".join(accepted_measurands)

_LOGGER.debug(f"'{self.id}' allowed measurands '{accepted_measurands}'")

await self.configure(
ckey.meter_values_sampled_data.value,
self.entry.data.get(CONF_MONITORED_VARIABLES, DEFAULT_MEASURAND),
accepted_measurands,
)

await self.configure(
ckey.meter_value_sample_interval.value,
str(self.entry.data.get(CONF_METER_INTERVAL, DEFAULT_METER_INTERVAL)),
Expand Down
34 changes: 6 additions & 28 deletions custom_components/ocpp/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
DEFAULT_HOST,
DEFAULT_IDLE_INTERVAL,
DEFAULT_MAX_CURRENT,
DEFAULT_MEASURAND,
DEFAULT_METER_INTERVAL,
DEFAULT_MONITORED_VARIABLES,
DEFAULT_PORT,
DEFAULT_SKIP_SCHEMA_VALIDATION,
DEFAULT_SSL,
Expand All @@ -38,7 +38,6 @@
DEFAULT_WEBSOCKET_PING_TIMEOUT,
DEFAULT_WEBSOCKET_PING_TRIES,
DOMAIN,
MEASURANDS,
)

STEP_USER_DATA_SCHEMA = vol.Schema(
Expand All @@ -51,6 +50,9 @@
vol.Required(CONF_CSID, default=DEFAULT_CSID): str,
vol.Required(CONF_CPID, default=DEFAULT_CPID): str,
vol.Required(CONF_MAX_CURRENT, default=DEFAULT_MAX_CURRENT): int,
vol.Required(
CONF_MONITORED_VARIABLES, default=DEFAULT_MONITORED_VARIABLES
): str,
vol.Required(CONF_METER_INTERVAL, default=DEFAULT_METER_INTERVAL): int,
vol.Required(CONF_IDLE_INTERVAL, default=DEFAULT_IDLE_INTERVAL): int,
vol.Required(
Expand All @@ -73,12 +75,6 @@
): bool,
}
)
STEP_USER_MEASURANDS_SCHEMA = vol.Schema(
{
vol.Required(m, default=(True if m == DEFAULT_MEASURAND else False)): bool
for m in MEASURANDS
}
)


class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
Expand All @@ -98,27 +94,9 @@ async def async_step_user(self, user_input=None):
if user_input is not None:
# Todo: validate the user input
self._data = user_input
return await self.async_step_measurands()
self._data[CONF_MONITORED_VARIABLES] = DEFAULT_MONITORED_VARIABLES
return self.async_create_entry(title=self._data[CONF_CSID], data=self._data)

return self.async_show_form(
step_id="user", data_schema=STEP_USER_DATA_SCHEMA, errors=errors
)

async def async_step_measurands(self, user_input=None):
"""Select the measurands to be shown."""

errors: dict[str, str] = {}
if user_input is not None:
selected_measurands = [m for m, value in user_input.items() if value]
if set(selected_measurands).issubset(set(MEASURANDS)):
self._data[CONF_MONITORED_VARIABLES] = ",".join(selected_measurands)
return self.async_create_entry(
title=self._data[CONF_CSID], data=self._data
)
else:
errors["base"] = "measurand"
return self.async_show_form(
step_id="measurands",
data_schema=STEP_USER_MEASURANDS_SCHEMA,
errors=errors,
)
30 changes: 15 additions & 15 deletions custom_components/ocpp/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,28 +70,28 @@

# Ocpp supported measurands
MEASURANDS = [
Measurand.energy_active_import_register.value,
Measurand.energy_reactive_import_register.value,
Measurand.current_export.value,
Measurand.current_import.value,
Measurand.current_offered.value,
Measurand.energy_active_export_interval.value,
Measurand.energy_active_export_register.value,
Measurand.energy_active_import_interval.value,
Measurand.energy_active_import_register.value,
Measurand.energy_reactive_export_interval.value,
Measurand.energy_reactive_export_register.value,
Measurand.energy_reactive_import_interval.value,
Measurand.energy_reactive_import_register.value,
Measurand.frequency.value,
Measurand.power_active_export.value,
Measurand.power_active_import.value,
Measurand.power_reactive_import.value,
Measurand.power_offered.value,
Measurand.power_factor.value,
Measurand.current_import.value,
Measurand.current_offered.value,
Measurand.voltage.value,
Measurand.frequency.value,
Measurand.power_offered.value,
Measurand.power_reactive_export.value,
Measurand.power_reactive_import.value,
Measurand.rpm.value,
Measurand.soc.value,
Measurand.temperature.value,
Measurand.current_export.value,
Measurand.energy_active_export_register.value,
Measurand.energy_reactive_export_register.value,
Measurand.energy_active_export_interval.value,
Measurand.energy_reactive_export_interval.value,
Measurand.power_active_export.value,
Measurand.power_reactive_export.value,
Measurand.voltage.value,
]
DEFAULT_MEASURAND = Measurand.energy_active_import_register.value
DEFAULT_MONITORED_VARIABLES = ",".join(MEASURANDS)
Expand Down
30 changes: 4 additions & 26 deletions tests/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
CONF_WEBSOCKET_PING_INTERVAL,
CONF_WEBSOCKET_PING_TIMEOUT,
CONF_WEBSOCKET_PING_TRIES,
DEFAULT_MONITORED_VARIABLES,
)
from ocpp.v16.enums import Measurand

MOCK_CONFIG = {
CONF_HOST: "127.0.0.1",
Expand All @@ -31,37 +31,15 @@
CONF_IDLE_INTERVAL: 900,
CONF_MAX_CURRENT: 32,
CONF_METER_INTERVAL: 60,
CONF_MONITORED_VARIABLES: DEFAULT_MONITORED_VARIABLES,
CONF_SKIP_SCHEMA_VALIDATION: False,
CONF_FORCE_SMART_CHARGING: True,
CONF_WEBSOCKET_CLOSE_TIMEOUT: 1,
CONF_WEBSOCKET_PING_TRIES: 0,
CONF_WEBSOCKET_PING_INTERVAL: 1,
CONF_WEBSOCKET_PING_TIMEOUT: 1,
}
MOCK_CONFIG_2 = {
Measurand.current_export.value: True,
Measurand.current_import.value: True,
Measurand.current_offered.value: True,
Measurand.energy_active_export_register.value: True,
Measurand.energy_active_import_register.value: True,
Measurand.energy_reactive_export_register.value: True,
Measurand.energy_reactive_import_register.value: True,
Measurand.energy_active_export_interval.value: True,
Measurand.energy_active_import_interval.value: True,
Measurand.energy_reactive_export_interval.value: True,
Measurand.energy_reactive_import_interval.value: True,
Measurand.frequency.value: True,
Measurand.power_active_export.value: True,
Measurand.power_active_import.value: True,
Measurand.power_factor.value: True,
Measurand.power_offered.value: True,
Measurand.power_reactive_export.value: True,
Measurand.power_reactive_import.value: True,
Measurand.rpm.value: True,
Measurand.soc.value: True,
Measurand.temperature.value: True,
Measurand.voltage.value: True,
}

MOCK_CONFIG_DATA = {
CONF_HOST: "127.0.0.1",
CONF_PORT: 9000,
Expand All @@ -70,7 +48,7 @@
CONF_IDLE_INTERVAL: 900,
CONF_MAX_CURRENT: 32,
CONF_METER_INTERVAL: 60,
CONF_MONITORED_VARIABLES: "Current.Export,Current.Import,Current.Offered,Energy.Active.Export.Register,Energy.Active.Import.Register,Energy.Reactive.Export.Register,Energy.Reactive.Import.Register,Energy.Active.Export.Interval,Energy.Active.Import.Interval,Energy.Reactive.Export.Interval,Energy.Reactive.Import.Interval,Frequency,Power.Active.Export,Power.Active.Import,Power.Factor,Power.Offered,Power.Reactive.Export,Power.Reactive.Import,RPM,SoC,Temperature,Voltage",
CONF_MONITORED_VARIABLES: DEFAULT_MONITORED_VARIABLES,
CONF_SKIP_SCHEMA_VALIDATION: False,
CONF_FORCE_SMART_CHARGING: True,
CONF_SSL: False,
Expand Down
11 changes: 1 addition & 10 deletions tests/test_config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
DOMAIN,
)

from .const import MOCK_CONFIG, MOCK_CONFIG_2, MOCK_CONFIG_DATA
from .const import MOCK_CONFIG, MOCK_CONFIG_DATA

# from pytest_homeassistant_custom_component.common import MockConfigEntry

Expand Down Expand Up @@ -49,15 +49,6 @@ async def test_successful_config_flow(hass, bypass_get_data):
result["flow_id"], user_input=MOCK_CONFIG
)

# Check that the config flow shows the user form as the first step
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["step_id"] == "measurands"

# Call again for step_id == "measurands" with default measurand
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input=MOCK_CONFIG_2
)

# Check that the config flow is complete and a new entry is created with
# the input data
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
Expand Down

0 comments on commit 64dab6e

Please sign in to comment.