Skip to content

Commit f3dab8b

Browse files
authored
fix: skip active discovery when retained messages already provide enough metrics
When MQTT broker has retained messages from a running OVMS module, those messages arrive immediately after SUBACK, often before the connection loop completes. In beta4, the metric_topics_before count was taken AFTER those retained messages arrived, causing the 'new metrics' count to be 0. This fix adds an early check: if we already have >= 50 metric topics from retained messages, skip both active discovery AND legacy wait entirely. This returns discovery to ~instant completion for users with retained msgs. Timeline issue (from debug logs): - 05:23:54.300: SUBACK received - 05:23:54.316-586: 172 retained metric messages arrive - 05:24:04.735: new_metric_topics = 0 → 'No metric topics' → legacy fallback - 05:24:54.816: Discovery complete (60s total, 50s wasted) With this fix: - Check metric_topics_before FIRST - If >= GOOD_DISCOVERY_TOPICS (50), skip active/legacy phases - Discovery completes in ~1s instead of 60s
1 parent c61342d commit f3dab8b

File tree

1 file changed

+49
-34
lines changed

1 file changed

+49
-34
lines changed

custom_components/ovms/config_flow/topic_discovery.py

Lines changed: 49 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -366,8 +366,9 @@ def on_connect_v311(client, userdata, flags, rc):
366366
}
367367

368368
# Hybrid discovery strategy:
369-
# 1. First try active metric request (OVMS edge firmware) with short timeout
370-
# 2. If no/few topics found, fall back to legacy passive discovery
369+
# 1. If retained messages already provided enough metrics, skip active/legacy
370+
# 2. Otherwise try active metric request (OVMS edge firmware) with short timeout
371+
# 3. If no/few topics found, fall back to legacy passive discovery
371372

372373
# Helper to count only metric topics (excludes /client/ command/response topics)
373374
def count_metric_topics(topics):
@@ -379,41 +380,55 @@ def count_metric_topics(topics):
379380
# Count only metric topics, not /client/ echoes (Issue 1 fix)
380381
metric_topics_before = count_metric_topics(discovered_topics)
381382

382-
# Phase 1: Try active metric request (OVMS edge firmware)
383-
_LOGGER.debug(
384-
"%s - Attempting active metric request (OVMS edge firmware)", log_prefix
385-
)
386-
try:
387-
if request_all_metrics(mqttc, config, client_id, config.get(CONF_QOS, 1)):
388-
# Wait for active discovery timeout
389-
_LOGGER.debug(
390-
"%s - Waiting %d seconds for active discovery response",
391-
log_prefix,
392-
ACTIVE_DISCOVERY_TIMEOUT,
393-
)
394-
await asyncio.sleep(ACTIVE_DISCOVERY_TIMEOUT)
395-
396-
# Count only metric topics to avoid false success from echoed requests
397-
metric_topics_after = count_metric_topics(discovered_topics)
398-
new_metric_topics = metric_topics_after - metric_topics_before
399-
400-
if new_metric_topics > 0:
401-
_LOGGER.info(
402-
"%s - Active discovery succeeded: received %d new metric topics",
403-
log_prefix,
404-
new_metric_topics,
405-
)
406-
active_discovery_succeeded = True
407-
debug_info["discovery_method"] = "active"
408-
debug_info["active_discovery_topics"] = new_metric_topics
409-
else:
383+
# Check if retained messages already gave us enough metrics
384+
# This happens when broker has retained messages from a running OVMS module
385+
if metric_topics_before >= GOOD_DISCOVERY_TOPICS:
386+
_LOGGER.info(
387+
"%s - Already received %d metric topics from retained messages, skipping active discovery",
388+
log_prefix,
389+
metric_topics_before,
390+
)
391+
active_discovery_succeeded = True
392+
debug_info["discovery_method"] = "retained"
393+
debug_info["retained_metric_topics"] = metric_topics_before
394+
else:
395+
# Phase 1: Try active metric request (OVMS edge firmware)
396+
_LOGGER.debug(
397+
"%s - Attempting active metric request (OVMS edge firmware)", log_prefix
398+
)
399+
try:
400+
if request_all_metrics(
401+
mqttc, config, client_id, config.get(CONF_QOS, 1)
402+
):
403+
# Wait for active discovery timeout
410404
_LOGGER.debug(
411-
"%s - No metric topics from active request (got %d total topics, may be echoes), firmware may be older",
405+
"%s - Waiting %d seconds for active discovery response",
412406
log_prefix,
413-
len(discovered_topics) - metric_topics_before,
407+
ACTIVE_DISCOVERY_TIMEOUT,
414408
)
415-
except Exception as ex: # pylint: disable=broad-except
416-
_LOGGER.debug("%s - Active metric request failed: %s", log_prefix, ex)
409+
await asyncio.sleep(ACTIVE_DISCOVERY_TIMEOUT)
410+
411+
# Count only metric topics to avoid false success from echoed requests
412+
metric_topics_after = count_metric_topics(discovered_topics)
413+
new_metric_topics = metric_topics_after - metric_topics_before
414+
415+
if new_metric_topics > 0:
416+
_LOGGER.info(
417+
"%s - Active discovery succeeded: received %d new metric topics",
418+
log_prefix,
419+
new_metric_topics,
420+
)
421+
active_discovery_succeeded = True
422+
debug_info["discovery_method"] = "active"
423+
debug_info["active_discovery_topics"] = new_metric_topics
424+
else:
425+
_LOGGER.debug(
426+
"%s - No metric topics from active request (got %d total topics, may be echoes), firmware may be older",
427+
log_prefix,
428+
len(discovered_topics) - metric_topics_before,
429+
)
430+
except Exception as ex: # pylint: disable=broad-except
431+
_LOGGER.debug("%s - Active metric request failed: %s", log_prefix, ex)
417432

418433
# Phase 2: Legacy discovery (wait for passive messages or send stat command)
419434
if not active_discovery_succeeded:

0 commit comments

Comments
 (0)