Skip to content

Commit f4b72ef

Browse files
committed
refactor: simplify HA Discovery diagnostic state plumbing
Three small cleanups identified by /simplify review of v1.8.4-v1.8.5: 1. Collapse _networkDiscoveryStatus (Map) + _discoveryStatusConfigPublished (Set) into a single _networkDiscoveryEntities Map keyed on networkId with value { status, configPublished }. Same pattern as v1.8.3's collapse of the retry-state maps. Eliminates duplicate lookups and keeps the per-network lifecycle in one place. stop() now clears the map for clean hot-reload. 2. Drop the typeof === 'function' guard around haDiscovery.handleNetworkCreated in commandResponseProcessor._processSystemEvent — the tree handlers in the same file use bare `if (this._haDiscovery)`, and v1.8.3 already established that the methods are part of the class contract. The accompanying test now exercises the realistic "haDiscovery not yet initialised" null case instead of the missing-method case. 3. Add a JSDoc enum annotation on _setDiscoveryStatus so the three valid status values (discovering/ok/paused) show up in editor tooling and discourage typos at call sites. No behaviour change. Full suite 1199/1199 passing.
1 parent 72bd600 commit f4b72ef

3 files changed

Lines changed: 26 additions & 19 deletions

File tree

src/commandResponseProcessor.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ class CommandResponseProcessor {
206206
return;
207207
}
208208
const networkId = match[1];
209-
if (this._haDiscovery && typeof this._haDiscovery.handleNetworkCreated === 'function') {
209+
if (this._haDiscovery) {
210210
this._haDiscovery.handleNetworkCreated(networkId);
211211
}
212212
}

src/haDiscovery.js

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,11 @@ class HaDiscovery {
8888
this._treeRetryMaxDelayMs = 60000;
8989
this._treeRequestTimeoutMs = 8000;
9090

91-
// Tracks per-network HA Discovery health. Each entry holds the last
92-
// published state so we don't re-publish identical states. Networks for
93-
// which we've published an HA Discovery config are tracked separately
94-
// to avoid republishing the same config payload on every transition.
95-
this._networkDiscoveryStatus = new Map(); // networkId -> 'discovering' | 'ok' | 'paused'
96-
this._discoveryStatusConfigPublished = new Set();
91+
// Tracks per-network HA Discovery health. The status field is used to
92+
// de-dup repeated state publishes; configPublished gates the (one-shot)
93+
// HA Discovery config payload so we don't republish it on every
94+
// transition. networkId -> { status, configPublished }
95+
this._networkDiscoveryEntities = new Map();
9796
}
9897

9998
/**
@@ -303,23 +302,23 @@ class HaDiscovery {
303302
}
304303

305304
/**
306-
* Cancels all retry timers and watchdogs. Call on bridge shutdown.
305+
* Cancels all retry timers and watchdogs and clears per-network state.
306+
* Call on bridge shutdown.
307307
*/
308308
stop() {
309309
for (const networkId of [...this._treeRequestState.keys()]) {
310310
this._clearTreeState(networkId);
311311
}
312+
this._networkDiscoveryEntities.clear();
312313
}
313314

314315
/**
315316
* Publishes a per-network "Discovery (Network N)" diagnostic sensor to HA
316317
* via MQTT Discovery. Idempotent — only publishes the config payload once
317318
* per network for the lifetime of this instance.
318319
*/
319-
_publishDiscoveryStatusConfig(networkId) {
320-
if (!this.settings.ha_discovery_enabled) return;
321-
const networkKey = String(networkId);
322-
if (this._discoveryStatusConfigPublished.has(networkKey)) return;
320+
_publishDiscoveryStatusConfig(entry, networkKey) {
321+
if (entry.configPublished) return;
323322

324323
const uniqueId = `cgateweb_discovery_${networkKey}`;
325324
const stateTopic = `${MQTT_TOPIC_PREFIX_READ}/${networkKey}///${MQTT_TOPIC_SUFFIX_DISCOVERY_STATUS}`;
@@ -348,22 +347,30 @@ class HaDiscovery {
348347
};
349348

350349
this._publish(configTopic, JSON.stringify(payload), { retain: true, qos: 0 });
351-
this._discoveryStatusConfigPublished.add(networkKey);
350+
entry.configPublished = true;
352351
}
353352

354353
/**
355354
* Updates the per-network discovery status. Publishes the HA Discovery
356355
* config the first time a network is seen, then publishes the state to the
357356
* sensor's state topic. Skips republishes when the state hasn't changed.
357+
*
358+
* @param {string|number} networkId
359+
* @param {('discovering'|'ok'|'paused')} status
358360
*/
359361
_setDiscoveryStatus(networkId, status) {
360362
if (!this.settings.ha_discovery_enabled) return;
361363
const networkKey = String(networkId);
362-
const previous = this._networkDiscoveryStatus.get(networkKey);
363-
if (previous === status) return;
364+
let entry = this._networkDiscoveryEntities.get(networkKey);
365+
if (!entry) {
366+
entry = { status: null, configPublished: false };
367+
this._networkDiscoveryEntities.set(networkKey, entry);
368+
}
369+
if (entry.status === status) return;
364370

365-
this._publishDiscoveryStatusConfig(networkKey);
366-
this._networkDiscoveryStatus.set(networkKey, status);
371+
this._publishDiscoveryStatusConfig(entry, networkKey);
372+
const previous = entry.status;
373+
entry.status = status;
367374

368375
const stateTopic = `${MQTT_TOPIC_PREFIX_READ}/${networkKey}///${MQTT_TOPIC_SUFFIX_DISCOVERY_STATUS}`;
369376
this._publish(stateTopic, status, { retain: true, qos: 0 });

tests/commandResponseProcessor.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,8 @@ describe('CommandResponseProcessor', () => {
205205
expect(mockHaDiscovery.handleNetworkCreated).not.toHaveBeenCalled();
206206
});
207207

208-
it('should not throw when haDiscovery lacks handleNetworkCreated', () => {
209-
processor.haDiscovery = { handleTreeStart: jest.fn() };
208+
it('should not throw when haDiscovery is not yet initialized', () => {
209+
processor.haDiscovery = null;
210210
expect(() => {
211211
processor._processCommandResponse(
212212
'742',

0 commit comments

Comments
 (0)