feat: CoAP inter-request pacing to prevent RT-OCF rate limit drops
Samsung appliances silently drop CoAP requests when hit faster than their firmware ceiling (~8–14 req/s measured; dishwasher unknown). Multi-block Block2 fetches on LAN hit ~100 req/s instantaneously, causing the observed burst timeouts on block 4 and block 10 of /device/0. Adds rate_limit_rps (default 5 req/s / 200 ms) to DtlsCoapSession with a pace() method that enforces the inter-block delay via _stop.wait() so session teardown interrupts the sleep cleanly. Coordinator calls pace() between hrefs in _poll_hrefs_blocking. Also adds device IP to all GET log lines for easier per-device filtering.
This commit is contained in:
1 parent
9ea4ddd3a3
commit
022a192bca
7 files changed
+130
-36
No files matched your search
@@ -8,7 +8,7 @@ import pytest
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from custom_components.localthings.const import (
|
||||
ACTIVE_INTERVAL_S, DOMAIN, IDLE_INTERVAL_S,
|
||||
DOMAIN, SUMMARY_INTERVAL_S,
|
||||
)
|
||||
from custom_components.localthings.coordinator import LocalThingsCoordinator
|
||||
|
||||
@@ -42,15 +42,15 @@ async def test_device_info_populated(
|
||||
)
|
||||
|
||||
|
||||
async def test_idle_interval_by_default(
|
||||
async def test_summary_interval(
|
||||
hass: HomeAssistant, mock_entry, mock_coordinator_session
|
||||
) -> None:
|
||||
"""Interval defaults to idle when no active_when fires."""
|
||||
"""Summary poll interval is always SUMMARY_INTERVAL_S."""
|
||||
await hass.config_entries.async_setup(mock_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
coordinator: LocalThingsCoordinator = hass.data[DOMAIN][mock_entry.entry_id]
|
||||
assert coordinator.update_interval == timedelta(seconds=IDLE_INTERVAL_S)
|
||||
assert coordinator.update_interval == timedelta(seconds=SUMMARY_INTERVAL_S)
|
||||
|
||||
|
||||
async def test_update_failed_on_persistent_poll_error(
|
||||
|
||||
@@ -5,7 +5,7 @@ from custom_components.localthings.ocf.registry.entities import BinarySensorDesc
|
||||
def test_capability_defaults():
|
||||
c = Capability(href='/kidslock/vs/0',
|
||||
entities=(BinarySensorDesc(key='child_lock', field='x.com.samsung.da.kidsLock'),))
|
||||
assert c.poll_tier == 'warm'
|
||||
assert c.poll_tier == 'cold'
|
||||
assert c.active_when is None
|
||||
assert len(c.entities) == 1
|
||||
|
||||
|
||||
Reference in new issue
Block a user