Compare commits

...
Sign in to create a new pull request.

3 commits

Author SHA1 Message Date
Matthias Alphart
0cdffeb6d6
fix wrong key for history reuse 2024-11-14 08:21:04 +01:00
farmio
ecc899b4fa tests 2024-11-13 22:33:40 +01:00
farmio
739b487109 Cache last telegram for each group address 2024-11-13 21:35:51 +01:00
5 changed files with 64 additions and 4 deletions

View file

@ -52,8 +52,8 @@ 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 = 200
TELEGRAM_LOG_MAX: Final = 5000 # ~2 MB or ~5 hours of reasonable bus load
TELEGRAM_LOG_DEFAULT: Final = 1000
TELEGRAM_LOG_MAX: Final = 25000 # ~10 MB or ~25 hours of reasonable bus load
##
# Secure constants

View file

@ -75,6 +75,7 @@ class Telegrams:
)
)
self.recent_telegrams: deque[TelegramDict] = deque(maxlen=log_size)
self.last_ga_telegrams: dict[str, TelegramDict] = {}
async def load_history(self) -> None:
"""Load history from store."""
@ -88,6 +89,9 @@ class Telegrams:
if isinstance(telegram["payload"], list):
telegram["payload"] = tuple(telegram["payload"]) # type: ignore[unreachable]
self.recent_telegrams.extend(telegrams)
self.last_ga_telegrams = {
t["destination"]: t for t in telegrams if t["payload"] is not None
}
async def save_history(self) -> None:
"""Save history to store."""
@ -98,6 +102,9 @@ class Telegrams:
"""Handle incoming and outgoing telegrams from xknx."""
telegram_dict = self.telegram_to_dict(telegram)
self.recent_telegrams.append(telegram_dict)
if telegram_dict["payload"] is not None:
# exclude GroupValueRead telegrams
self.last_ga_telegrams[telegram_dict["destination"]] = telegram_dict
async_dispatcher_send(self.hass, SIGNAL_KNX_TELEGRAM, telegram, telegram_dict)
def telegram_to_dict(self, telegram: Telegram) -> TelegramDict:

View file

@ -47,6 +47,7 @@ async def register_panel(hass: HomeAssistant) -> None:
websocket_api.async_register_command(hass, ws_project_file_process)
websocket_api.async_register_command(hass, ws_project_file_remove)
websocket_api.async_register_command(hass, ws_group_monitor_info)
websocket_api.async_register_command(hass, ws_group_telegrams)
websocket_api.async_register_command(hass, ws_subscribe_telegram)
websocket_api.async_register_command(hass, ws_get_knx_project)
websocket_api.async_register_command(hass, ws_validate_entity)
@ -287,6 +288,27 @@ def ws_group_monitor_info(
)
@websocket_api.require_admin
@websocket_api.websocket_command(
{
vol.Required("type"): "knx/group_telegrams",
}
)
@provide_knx
@callback
def ws_group_telegrams(
hass: HomeAssistant,
knx: KNXModule,
connection: websocket_api.ActiveConnection,
msg: dict,
) -> None:
"""Handle get group telegrams command."""
connection.send_result(
msg["id"],
knx.telegrams.last_ga_telegrams,
)
@websocket_api.require_admin
@websocket_api.websocket_command(
{

View file

@ -913,7 +913,7 @@ async def test_form_with_automatic_connection_handling(
CONF_KNX_ROUTE_BACK: False,
CONF_KNX_TUNNEL_ENDPOINT_IA: None,
CONF_KNX_STATE_UPDATER: True,
CONF_KNX_TELEGRAM_LOG_SIZE: 200,
CONF_KNX_TELEGRAM_LOG_SIZE: 1000,
}
knx_setup.assert_called_once()
@ -1210,7 +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: 200,
CONF_KNX_TELEGRAM_LOG_SIZE: 1000,
}

View file

@ -180,6 +180,37 @@ async def test_knx_group_monitor_info_command(
assert res["result"]["recent_telegrams"] == []
async def test_knx_group_telegrams_command(
hass: HomeAssistant, knx: KNXTestKit, hass_ws_client: WebSocketGenerator
) -> None:
"""Test knx/group_telegrams command."""
await knx.setup_integration({})
client = await hass_ws_client(hass)
await client.send_json_auto_id({"type": "knx/group_telegrams"})
res = await client.receive_json()
assert res["success"], res
assert res["result"] == {}
# # get some telegrams to populate the cache
await knx.receive_write("1/1/1", True)
await knx.receive_read("2/2/2") # read telegram shall be ignored
await knx.receive_write("3/3/3", 0x34)
await client.send_json_auto_id({"type": "knx/group_telegrams"})
res = await client.receive_json()
assert res["success"], res
assert len(res["result"]) == 2
assert "1/1/1" in res["result"]
assert res["result"]["1/1/1"]["destination"] == "1/1/1"
assert "3/3/3" in res["result"]
assert res["result"]["3/3/3"]["payload"] == 52
assert res["result"]["3/3/3"]["telegramtype"] == "GroupValueWrite"
assert res["result"]["3/3/3"]["source"] == "1.2.3"
assert res["result"]["3/3/3"]["direction"] == "Incoming"
assert res["result"]["3/3/3"]["timestamp"] is not None
async def test_knx_subscribe_telegrams_command_recent_telegrams(
hass: HomeAssistant, knx: KNXTestKit, hass_ws_client: WebSocketGenerator
) -> None: