Configurable KNX Telegram history size (#93248)
* Configurable KNX Telegram history size * Add maximum value to description
This commit is contained in:
parent
3bf9eaffdf
commit
b10e73e2d4
6 changed files with 83 additions and 25 deletions
|
@ -60,6 +60,7 @@ from .const import (
|
|||
CONF_KNX_SECURE_USER_ID,
|
||||
CONF_KNX_SECURE_USER_PASSWORD,
|
||||
CONF_KNX_STATE_UPDATER,
|
||||
CONF_KNX_TELEGRAM_LOG_SIZE,
|
||||
CONF_KNX_TUNNELING,
|
||||
CONF_KNX_TUNNELING_TCP,
|
||||
CONF_KNX_TUNNELING_TCP_SECURE,
|
||||
|
@ -68,6 +69,7 @@ from .const import (
|
|||
DOMAIN,
|
||||
KNX_ADDRESS,
|
||||
SUPPORTED_PLATFORMS,
|
||||
TELEGRAM_LOG_DEFAULT,
|
||||
)
|
||||
from .device import KNXInterfaceDevice
|
||||
from .expose import KNXExposeSensor, KNXExposeTime, create_knx_exposure
|
||||
|
@ -384,7 +386,12 @@ class KNXModule:
|
|||
self.xknx.connection_manager.register_connection_state_changed_cb(
|
||||
self.connection_state_changed_cb
|
||||
)
|
||||
self.telegrams = Telegrams(hass, self.xknx, self.project)
|
||||
self.telegrams = Telegrams(
|
||||
hass=hass,
|
||||
xknx=self.xknx,
|
||||
project=self.project,
|
||||
log_size=entry.data.get(CONF_KNX_TELEGRAM_LOG_SIZE, TELEGRAM_LOG_DEFAULT),
|
||||
)
|
||||
self.interface_device = KNXInterfaceDevice(
|
||||
hass=hass, entry=entry, xknx=self.xknx
|
||||
)
|
||||
|
|
|
@ -49,12 +49,15 @@ from .const import (
|
|||
CONF_KNX_SECURE_USER_ID,
|
||||
CONF_KNX_SECURE_USER_PASSWORD,
|
||||
CONF_KNX_STATE_UPDATER,
|
||||
CONF_KNX_TELEGRAM_LOG_SIZE,
|
||||
CONF_KNX_TUNNEL_ENDPOINT_IA,
|
||||
CONF_KNX_TUNNELING,
|
||||
CONF_KNX_TUNNELING_TCP,
|
||||
CONF_KNX_TUNNELING_TCP_SECURE,
|
||||
DEFAULT_ROUTING_IA,
|
||||
DOMAIN,
|
||||
TELEGRAM_LOG_DEFAULT,
|
||||
TELEGRAM_LOG_MAX,
|
||||
KNXConfigEntryData,
|
||||
)
|
||||
from .schema import ia_validator, ip_v4_validator
|
||||
|
@ -70,6 +73,7 @@ DEFAULT_ENTRY_DATA = KNXConfigEntryData(
|
|||
rate_limit=CONF_KNX_DEFAULT_RATE_LIMIT,
|
||||
route_back=False,
|
||||
state_updater=CONF_KNX_DEFAULT_STATE_UPDATER,
|
||||
telegram_log_size=TELEGRAM_LOG_DEFAULT,
|
||||
)
|
||||
|
||||
CONF_KEYRING_FILE: Final = "knxkeys_file"
|
||||
|
@ -203,7 +207,11 @@ class KNXCommonFlow(ABC, FlowHandler):
|
|||
)
|
||||
|
||||
async def async_step_tunnel(self, user_input: dict | None = None) -> FlowResult:
|
||||
"""Select a tunnel from a list. Will be skipped if the gateway scan was unsuccessful or if only one gateway was found."""
|
||||
"""Select a tunnel from a list.
|
||||
|
||||
Will be skipped if the gateway scan was unsuccessful
|
||||
or if only one gateway was found.
|
||||
"""
|
||||
if user_input is not None:
|
||||
if user_input[CONF_KNX_GATEWAY] == OPTION_MANUAL_TUNNEL:
|
||||
if self._found_tunnels:
|
||||
|
@ -804,6 +812,7 @@ class KNXOptionsFlow(KNXCommonFlow, OptionsFlow):
|
|||
self.new_entry_data = KNXConfigEntryData(
|
||||
state_updater=user_input[CONF_KNX_STATE_UPDATER],
|
||||
rate_limit=user_input[CONF_KNX_RATE_LIMIT],
|
||||
telegram_log_size=user_input[CONF_KNX_TELEGRAM_LOG_SIZE],
|
||||
)
|
||||
return self.finish_flow()
|
||||
|
||||
|
@ -811,15 +820,13 @@ class KNXOptionsFlow(KNXCommonFlow, OptionsFlow):
|
|||
vol.Required(
|
||||
CONF_KNX_STATE_UPDATER,
|
||||
default=self.initial_data.get(
|
||||
CONF_KNX_STATE_UPDATER,
|
||||
CONF_KNX_DEFAULT_STATE_UPDATER,
|
||||
CONF_KNX_STATE_UPDATER, CONF_KNX_DEFAULT_STATE_UPDATER
|
||||
),
|
||||
): selector.BooleanSelector(),
|
||||
vol.Required(
|
||||
CONF_KNX_RATE_LIMIT,
|
||||
default=self.initial_data.get(
|
||||
CONF_KNX_RATE_LIMIT,
|
||||
CONF_KNX_DEFAULT_RATE_LIMIT,
|
||||
CONF_KNX_RATE_LIMIT, CONF_KNX_DEFAULT_RATE_LIMIT
|
||||
),
|
||||
): vol.All(
|
||||
selector.NumberSelector(
|
||||
|
@ -831,9 +838,27 @@ class KNXOptionsFlow(KNXCommonFlow, OptionsFlow):
|
|||
),
|
||||
vol.Coerce(int),
|
||||
),
|
||||
vol.Required(
|
||||
CONF_KNX_TELEGRAM_LOG_SIZE,
|
||||
default=self.initial_data.get(
|
||||
CONF_KNX_TELEGRAM_LOG_SIZE, TELEGRAM_LOG_DEFAULT
|
||||
),
|
||||
): vol.All(
|
||||
selector.NumberSelector(
|
||||
selector.NumberSelectorConfig(
|
||||
min=0,
|
||||
max=TELEGRAM_LOG_MAX,
|
||||
mode=selector.NumberSelectorMode.BOX,
|
||||
),
|
||||
),
|
||||
vol.Coerce(int),
|
||||
),
|
||||
}
|
||||
return self.async_show_form(
|
||||
step_id="communication_settings",
|
||||
data_schema=vol.Schema(data_schema),
|
||||
last_step=True,
|
||||
description_placeholders={
|
||||
"telegram_log_size_max": f"{TELEGRAM_LOG_MAX}",
|
||||
},
|
||||
)
|
||||
|
|
|
@ -52,6 +52,10 @@ CONF_KNX_DEFAULT_RATE_LIMIT: Final = 0
|
|||
|
||||
DEFAULT_ROUTING_IA: Final = "0.0.240"
|
||||
|
||||
CONF_KNX_TELEGRAM_LOG_SIZE: Final = "telegram_log_size"
|
||||
TELEGRAM_LOG_DEFAULT: Final = 50
|
||||
TELEGRAM_LOG_MAX: Final = 5000 # ~2 MB or ~5 hours of reasonable bus load
|
||||
|
||||
##
|
||||
# Secure constants
|
||||
##
|
||||
|
@ -88,23 +92,26 @@ class KNXConfigEntryData(TypedDict, total=False):
|
|||
|
||||
connection_type: str
|
||||
individual_address: str
|
||||
local_ip: str | None
|
||||
local_ip: str | None # not required
|
||||
multicast_group: str
|
||||
multicast_port: int
|
||||
route_back: bool
|
||||
route_back: bool # not required
|
||||
host: str # only required for tunnelling
|
||||
port: int # only required for tunnelling
|
||||
tunnel_endpoint_ia: str | None
|
||||
# KNX secure
|
||||
user_id: int | None # not required
|
||||
user_password: str | None # not required
|
||||
device_authentication: str | None # not required
|
||||
knxkeys_filename: str # not required
|
||||
knxkeys_password: str # not required
|
||||
backbone_key: str | None # not required
|
||||
sync_latency_tolerance: int | None # not required
|
||||
# OptionsFlow only
|
||||
state_updater: bool
|
||||
rate_limit: int
|
||||
host: str
|
||||
port: int
|
||||
tunnel_endpoint_ia: str | None
|
||||
|
||||
user_id: int | None
|
||||
user_password: str | None
|
||||
device_authentication: str | None
|
||||
knxkeys_filename: str
|
||||
knxkeys_password: str
|
||||
backbone_key: str | None
|
||||
sync_latency_tolerance: int | None
|
||||
# Integration only (not forwarded to xknx)
|
||||
telegram_log_size: int # not required
|
||||
|
||||
|
||||
class KNXBusMonitorMessage(TypedDict):
|
||||
|
|
|
@ -133,11 +133,13 @@
|
|||
"title": "Communication settings",
|
||||
"data": {
|
||||
"state_updater": "State updater",
|
||||
"rate_limit": "Rate limit"
|
||||
"rate_limit": "Rate limit",
|
||||
"telegram_log_size": "Telegram history limit"
|
||||
},
|
||||
"data_description": {
|
||||
"state_updater": "Set default for reading states from the KNX Bus. When disabled, Home Assistant will not actively retrieve entity states from the KNX Bus. Can be overridden by `sync_state` entity options.",
|
||||
"rate_limit": "Maximum outgoing telegrams per second.\n`0` to disable limit. Recommended: 0 or 20 to 40"
|
||||
"rate_limit": "Maximum outgoing telegrams per second.\n`0` to disable limit. Recommended: 0 or 20 to 40",
|
||||
"telegram_log_size": "Telegrams to keep in memory for KNX panel group monitor. Maximum: {telegram_log_size_max}"
|
||||
}
|
||||
},
|
||||
"connection_type": {
|
||||
|
|
|
@ -35,7 +35,13 @@ class TelegramDict(TypedDict):
|
|||
class Telegrams:
|
||||
"""Class to handle KNX telegrams."""
|
||||
|
||||
def __init__(self, hass: HomeAssistant, xknx: XKNX, project: KNXProject) -> None:
|
||||
def __init__(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
xknx: XKNX,
|
||||
project: KNXProject,
|
||||
log_size: int,
|
||||
) -> None:
|
||||
"""Initialize Telegrams class."""
|
||||
self.hass = hass
|
||||
self.project = project
|
||||
|
@ -46,7 +52,7 @@ class Telegrams:
|
|||
match_for_outgoing=True,
|
||||
)
|
||||
)
|
||||
self.recent_telegrams: deque[TelegramDict] = deque(maxlen=50)
|
||||
self.recent_telegrams: deque[TelegramDict] = deque(maxlen=log_size)
|
||||
|
||||
async def _xknx_telegram_cb(self, telegram: Telegram) -> None:
|
||||
"""Handle incoming and outgoing telegrams from xknx."""
|
||||
|
|
|
@ -37,6 +37,7 @@ from homeassistant.components.knx.const import (
|
|||
CONF_KNX_SECURE_USER_ID,
|
||||
CONF_KNX_SECURE_USER_PASSWORD,
|
||||
CONF_KNX_STATE_UPDATER,
|
||||
CONF_KNX_TELEGRAM_LOG_SIZE,
|
||||
CONF_KNX_TUNNEL_ENDPOINT_IA,
|
||||
CONF_KNX_TUNNELING,
|
||||
CONF_KNX_TUNNELING_TCP,
|
||||
|
@ -820,7 +821,6 @@ async def test_tunneling_setup_for_multiple_found_gateways(
|
|||
CONF_PORT: 3675,
|
||||
CONF_KNX_INDIVIDUAL_ADDRESS: "0.0.240",
|
||||
CONF_KNX_ROUTE_BACK: False,
|
||||
CONF_KNX_LOCAL_IP: None,
|
||||
CONF_KNX_TUNNEL_ENDPOINT_IA: None,
|
||||
CONF_KNX_SECURE_DEVICE_AUTHENTICATION: None,
|
||||
CONF_KNX_SECURE_USER_ID: None,
|
||||
|
@ -900,9 +900,17 @@ async def test_form_with_automatic_connection_handling(
|
|||
assert result2["type"] == FlowResultType.CREATE_ENTRY
|
||||
assert result2["title"] == CONF_KNX_AUTOMATIC.capitalize()
|
||||
assert result2["data"] == {
|
||||
**DEFAULT_ENTRY_DATA,
|
||||
# don't use **DEFAULT_ENTRY_DATA here to check for correct usage of defaults
|
||||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_AUTOMATIC,
|
||||
CONF_KNX_INDIVIDUAL_ADDRESS: "0.0.240",
|
||||
CONF_KNX_LOCAL_IP: None,
|
||||
CONF_KNX_MCAST_PORT: DEFAULT_MCAST_PORT,
|
||||
CONF_KNX_MCAST_GRP: DEFAULT_MCAST_GRP,
|
||||
CONF_KNX_RATE_LIMIT: 0,
|
||||
CONF_KNX_ROUTE_BACK: False,
|
||||
CONF_KNX_TUNNEL_ENDPOINT_IA: None,
|
||||
CONF_KNX_STATE_UPDATER: True,
|
||||
CONF_KNX_TELEGRAM_LOG_SIZE: 50,
|
||||
}
|
||||
knx_setup.assert_called_once()
|
||||
|
||||
|
@ -1202,6 +1210,7 @@ async def test_options_flow_connection_type(
|
|||
CONF_KNX_SECURE_DEVICE_AUTHENTICATION: None,
|
||||
CONF_KNX_SECURE_USER_ID: None,
|
||||
CONF_KNX_SECURE_USER_PASSWORD: None,
|
||||
CONF_KNX_TELEGRAM_LOG_SIZE: 50,
|
||||
}
|
||||
|
||||
|
||||
|
@ -1331,6 +1340,7 @@ async def test_options_communication_settings(
|
|||
user_input={
|
||||
CONF_KNX_STATE_UPDATER: False,
|
||||
CONF_KNX_RATE_LIMIT: 40,
|
||||
CONF_KNX_TELEGRAM_LOG_SIZE: 3000,
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
@ -1341,6 +1351,7 @@ async def test_options_communication_settings(
|
|||
CONF_KNX_CONNECTION_TYPE: CONF_KNX_AUTOMATIC,
|
||||
CONF_KNX_STATE_UPDATER: False,
|
||||
CONF_KNX_RATE_LIMIT: 40,
|
||||
CONF_KNX_TELEGRAM_LOG_SIZE: 3000,
|
||||
}
|
||||
knx_setup.assert_called_once()
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue