-
Notifications
You must be signed in to change notification settings - Fork 17
fix: defer sensor enablement until device data is received #189
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This fixes a race-condition where we disabled sensors before we received the first device data.
WalkthroughImplements tri-state enablement for advertised components, deferring decisions until device data is available. Updates data handling to return updated paths, adds MQTT client tracking to republish discovery configs on first data receipt per path, adjusts Venus device predicates, and updates CHANGELOG. Public APIs updated accordingly. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Dev as Device
participant IDX as Index
participant DH as DataHandler
participant MQ as MqttClient
participant GD as Discovery Generator
Dev->>IDX: incoming device data (message)
IDX->>DH: handleDeviceData(device, message)
DH-->>IDX: updatedPaths: string[]
loop for each updatedPath
IDX->>MQ: onDeviceDataReceived(device, updatedPath)
alt first time for device+path
MQ->>GD: republish discovery for device
GD->>GD: evaluate enabled(state): boolean | undefined
alt enabled === true
GD-->>MQ: publish config
else enabled === false
GD-->>MQ: publish null (disable)
else enabled === undefined
GD-->>MQ: skip (defer)
end
else already seen
MQ-->>IDX: no-op
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/index.ts (1)
220-230: Wrap the switch clause body to fix the lint error
const updatedPaths = ...is declared directly in thecase 'device'clause. Without wrapping the clause in braces, the declaration is scoped to the entire switch, which violates ournoSwitchDeclarationsrule (reported by Biome) and can break compilation. Please wrap the clause in{}before declaringupdatedPaths.- switch (topicType) { - case 'device': + switch (topicType) { + case 'device': { if (topics) { mqttClient.publish(topics.availabilityTopic, 'online', { qos: 1, retain: true }); mqttClient.resetTimeoutCounter(device.deviceId); } deviceManager.clearResponseTimeout(device); const updatedPaths = dataHandler.handleDeviceData(device, message.toString()); // Re-publish discovery configs for each message path that received data for the first time updatedPaths.forEach(path => mqttClient.onDeviceDataReceived(device, path)); break; - - case 'control': + } + case 'control':
🧹 Nitpick comments (2)
src/mqttClient.ts (1)
216-235: LGTM! Clean implementation of first-data-receipt tracking.The method correctly implements the deferred sensor enablement feature by:
- Building a composite key to track device/path combinations uniquely
- Only republishing discovery configs on the first data receipt per device/path
- Logging appropriately at debug level
Optional consideration: The
devicePathsWithDataSet grows unbounded over the lifetime of the process. While the memory impact should be minimal (just string keys), in a very long-running deployment with many devices and paths, you might consider:
- Adding a method to clear stale entries if devices are removed
- Or documenting that the Set is intentionally unbounded for this use case
This is not a blocker—just a maintenance consideration for future reference.
src/generateDiscoveryConfigs.ts (1)
78-89: LGTM! Tri-state evaluation correctly implements deferred enablement.The logic correctly handles three distinct cases:
undefined(line 80-82): Defers decision by skipping publication (continue)false(line 84-87): Explicitly disables by publishing null configtrue/truthy (implicit else): Enables by proceeding to normal config publicationNote the use of strict equality (
=== false) on line 84, which means only literalfalsetriggers explicit disable—other falsy values are treated as enabled. This appears intentional and correct.Optional consideration: The
deviceStateparameter is typed asany(line 24), which means type safety is relaxed when callingfield.enabled(deviceState)on line 79. While this may be acceptable given the dynamic nature of device states in this system, you might consider:
- Adding runtime type guards in the enabled functions themselves
- Or documenting that enabled functions should handle unexpected state shapes gracefully
This is not a blocking issue—just a type safety consideration for maintainability.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
CHANGELOG.md(1 hunks)src/dataHandler.ts(1 hunks)src/device/venus.ts(2 hunks)src/deviceDefinition.ts(1 hunks)src/generateDiscoveryConfigs.ts(2 hunks)src/index.ts(1 hunks)src/mqttClient.ts(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/dataHandler.ts (2)
src/types.ts (1)
Device(212-215)src/parser.ts (1)
parseMessage(20-61)
src/mqttClient.ts (1)
src/types.ts (1)
Device(212-215)
🪛 Biome (2.1.2)
src/index.ts
[error] 227-227: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: build (linux/amd64)
- GitHub Check: build (linux/arm64)
- GitHub Check: build-addon (linux/arm64)
- GitHub Check: build-addon (linux/arm/v7)
🔇 Additional comments (2)
src/mqttClient.ts (1)
14-14: LGTM! Well-chosen data structure for tracking first-time data reception.The
Set<string>efficiently tracks which device/path combinations have received data, supporting the PR's objective to defer sensor enablement until device data arrives.src/generateDiscoveryConfigs.ts (1)
16-16: LGTM! Tri-state enablement aligns with PR objectives.Extending the return type to
boolean | undefinedenables the deferred sensor enablement feature:
true: component is enabledfalse: component is explicitly disabledundefined: defer decision until more data is availableThis change is backward compatible since
enabledis optional and existing boolean returns still work.
This fixes a race-condition where we disabled sensors before we received the first device data.
Summary by CodeRabbit
Bug Fixes
Documentation