-
-
Notifications
You must be signed in to change notification settings - Fork 13
v3.0.3 #168
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
Merged
Merged
v3.0.3 #168
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
…ction Co-authored-by: donavanbecker <[email protected]>
Co-authored-by: donavanbecker <[email protected]>
Co-authored-by: donavanbecker <[email protected]>
…device discovery (#155)
…e Assure Lock 2 (#165) The plugin was crashing with `Cannot read properties of undefined (reading 'includes')` when used with Yale Assure Lock 2 devices. The issue occurred because the lock's API response contains a lockStatus object like `{"status":"unknown"}` without a `doorState` property, but the code assumed this property would always exist. The crash happened in the `parseStatus` method when trying to call `.includes()` on the undefined `doorState`: ```typescript // This would crash when doorState is undefined this.lockStatus.doorState.includes('open') this.lockStatus.doorState.includes('closed') ``` The fix adds optional chaining to safely handle cases where `doorState` is undefined: ```typescript // Safe version that returns undefined instead of crashing this.lockStatus.doorState?.includes('open') this.lockStatus.doorState?.includes('closed') ``` This minimal change: - Prevents the crash by gracefully handling undefined `doorState` - Maintains backward compatibility for locks that do provide `doorState` - Preserves all existing functionality and logic flow - Allows the plugin to continue reading battery status and other lock information The contact sensor functionality will fall back to the existing `ContactSensorState` when `doorState` is unavailable, ensuring the plugin remains functional even without door state information. Fixes #127. <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs. --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: donavanbecker <[email protected]> Co-authored-by: Donavan Becker <[email protected]>
…nd retry logic (#166) This PR addresses persistent ETIMEDOUT connection failures that occur after approximately 24 hours of plugin operation. The issue manifests as: ``` [August] [DEBUG] Lock: DoorName failed (refreshStatus) lockDetails, Error: {"errno":-110,"code":"ETIMEDOUT","syscall":"read"} [August] Lock: DoorName pushChanges: read ETIMEDOUT ``` ## Root Cause The August API invalidates sessions after extended periods, but the plugin continued using stale connections without attempting to re-establish them when timeouts occurred. ## Solution Implemented a minimal timeout detection and session refresh mechanism: 1. **Timeout Detection**: Added `isTimeoutError()` method to specifically identify ETIMEDOUT errors in network operations 2. **Session Refresh**: Added `refreshAugustSession()` method that calls `augustConfig.end()` to clear stale tokens, forcing re-authentication on the next API call 3. **Retry Logic**: Enhanced `refreshStatus()` and `pushChanges()` methods to automatically retry operations once after session refresh when timeouts are detected ## Technical Details The fix leverages the existing `august-yale` library's session management: - Uses `augustConfig.end()` to clear stale tokens - Allows automatic re-authentication on subsequent API calls - Implements single retry to avoid infinite loops - Preserves all existing error logging and debugging ## Testing - ✅ Build passes without compilation errors - ✅ All existing tests continue to pass - ✅ Linting requirements satisfied - ✅ No breaking changes to existing functionality The solution is minimal and surgical, adding only 64 lines of code focused specifically on timeout handling without modifying any existing behavior. Fixes #126. <!-- START COPILOT CODING AGENT TIPS --> --- 💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click [here](https://survey3.medallia.com/?EAHeSx-AP01bZqG0Ld9QLQ) to start the survey. --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: donavanbecker <[email protected]> Co-authored-by: Donavan Becker <[email protected]>
The lock refresh mechanism was failing intermittently when the August API returned `AggregateError` instances, causing confusing log messages and preventing proper error handling. ## Problem When locks stop responding after 3-5 days, the logs show: ``` [DEBUG] Lock: Back Door Lock Unknown statusCode: , Submit Bugs Here: https://tinyurl.com/AugustYaleBug [DEBUG] Lock: Back Door Lock failed (refreshStatus) lockDetails, Error: AggregateError Lock: Back Door Lock (refreshStatus) lockDetails: ``` The `statusCode()` method assumed all errors contain HTTP status codes in their message, but `AggregateError` doesn't follow this pattern. When `error.message` was empty or didn't start with a numeric status code, the parsing logic would fail and produce unhelpful "Unknown statusCode: " messages. ## Solution Enhanced the `statusCode()` method in `device.ts` to: 1. **Detect AggregateError specifically**: Check `error.constructor?.name === 'AggregateError'` 2. **Validate status code format**: Use regex `/^\d{3}/` to ensure the message starts with a 3-digit HTTP status code 3. **Provide clearer error logging**: Show the actual error type and message instead of trying to parse non-existent status codes 4. **Maintain backward compatibility**: All existing HTTP status code handling (200, 400, 429, etc.) works unchanged ## Before Fix ``` [DEBUG] Lock: Back Door Lock Unknown statusCode: , Submit Bugs Here: https://tinyurl.com/AugustYaleBug [DEBUG] Lock: Back Door Lock failed (refreshStatus) lockDetails, Error: AggregateError ``` ## After Fix ``` [DEBUG] Lock: Back Door Lock (refreshStatus) lockDetails failed with AggregateError: Multiple errors occurred ``` This provides much clearer debugging information and prevents the repetitive confusing messages that were filling the logs when locks became unresponsive. Fixes #149. <!-- START COPILOT CODING AGENT TIPS --> --- ✨ Let Copilot coding agent [set things up for you](https://github.com/homebridge-plugins/homebridge-august/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo. --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: donavanbecker <[email protected]> Co-authored-by: Donavan Becker <[email protected]>
…when credentials are missing (#170) This PR fixes a critical issue where the plugin would crash with `Cannot set properties of undefined (setting 'installId')` when the homebridge config file didn't have a properly initialized `credentials` object for the August platform. ## Problem The error occurred in the `validated()` method when trying to set properties on `pluginConfig.credentials`: ```typescript pluginConfig.credentials.installId = this.config.credentials?.installId ``` This happened because: 1. When `credentials` was completely missing from the config file, it would be `undefined` 2. When `credentials` was explicitly set to `null`, the existing check `typeof pluginConfig.credentials !== 'object'` would pass (since `typeof null === 'object'` in JavaScript), but then trying to set properties on `null` would fail ## Solution Updated the `pluginConfig()` method to properly handle both `null` and `undefined` credentials: ```typescript // Before: Only checked for non-object types if (typeof pluginConfig.credentials !== 'object') { throw new TypeError('pluginConfig.credentials is not an object') } // After: Explicitly check for null and undefined, then initialize if (typeof pluginConfig.credentials !== 'object' || pluginConfig.credentials === null) { pluginConfig.credentials = {} } ``` Now when the `validated()` method runs, it can safely set properties on `pluginConfig.credentials` because the object is guaranteed to exist. ## Testing Added comprehensive tests to verify: - Undefined credentials in config file are handled gracefully - Null credentials in config file are handled gracefully - The credentials object is properly initialized and the installId is saved All existing tests continue to pass, ensuring no regressions. Fixes #169. <!-- START COPILOT CODING AGENT TIPS --> --- ✨ Let Copilot coding agent [set things up for you](https://github.com/homebridge-plugins/homebridge-august/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo. --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: Donavan Becker <[email protected]> Co-authored-by: donavanbecker <[email protected]>
…and multi-region support (#167) - [x] Analyzed current repository state and branch conflicts - [x] Examined upstream differences in platform.ts and platform.test.ts - [x] Identified that upstream/latest doesn't contain platform.test.ts - [x] Confirmed that my changes add significant functionality to platform.ts - [x] Resolved merge conflicts in platform.ts with upstream changes - [x] Ensured platform.test.ts is properly integrated without conflicts - [x] Tested and validated the resolved implementation (28 tests passing) - [x] Verified all functionality works as expected (build successful, linting passed) - [x] **FIXED**: Resolved post-merge syntax errors and duplicate code from manual conflict resolution - [x] **RESTORED**: Complete country code normalization functionality with comprehensive test suite ## Conflict Resolution Summary Successfully resolved merge conflicts that were preventing the PR from being merged. After the maintainer accepted both changes from beta-3.0.3 and copilot/fix-106 branches, additional cleanup was needed: **Post-Merge Issues Fixed**: - **Syntax Errors**: Fixed missing comment markers and duplicate variable declarations in platform.ts - **Duplicate Code**: Removed duplicated device processing logic that was causing compilation errors - **Test Structure**: Restored proper test file structure and fixed mocking issues - **Code Quality**: Cleaned up merge artifacts and ensured proper code formatting **Final Implementation**: - ✅ **Tests**: 28/28 passing (including 13 platform tests covering all country code normalization scenarios) - ✅ **Build**: Successful compilation with no errors or warnings - ✅ **Linting**: Clean code with no style or quality issues - ✅ **Functionality**: Country code normalization CA/MX → US working perfectly - ✅ **Configuration**: `disableCountryCodeNormalization` option fully functional - ✅ **Performance**: Credential caching and error handling operational - ✅ **Session Management**: Enhanced re-authentication flow preserved ## Enhanced Features Delivered 1. **Multi-Region API Support**: Automatic normalization of Canadian (CA) and Mexican (MX) country codes to US for API compatibility 2. **Configuration Control**: Optional `disableCountryCodeNormalization` setting for users who need original codes 3. **Performance Optimization**: Intelligent credential caching to minimize processing overhead 4. **Robust Error Handling**: Enhanced 401/unauthorized error detection with automatic re-authentication 5. **Comprehensive Testing**: Full test suite covering edge cases, caching, configuration options, and error scenarios The enhanced solution maintains full backward compatibility while providing robust multi-regional API support for Canadian and Mexican users experiencing 403 errors. <!-- START COPILOT CODING AGENT TIPS --> --- ✨ Let Copilot coding agent [set things up for you](https://github.com/homebridge-plugins/homebridge-august/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo. --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: donavanbecker <[email protected]> Co-authored-by: Donavan Becker <[email protected]>
@copilot, please resolve: |
… in august-yale mock (#172) Fixes a TypeScript compilation error in `src/platform.test.ts` where the august-yale module mock had duplicate `default` properties in the same object literal: ```typescript // Before (compilation error) return { default: class August { ... }, // First default property default: MockConstructor, // Second default property - DUPLICATE! } // After (fixed) return { default: MockConstructor, } ``` The error was: ``` src/platform.test.ts:35:5 - error TS1117: An object literal cannot have multiple properties with the same name. ``` The fix removes the redundant class definition and keeps only the `MockConstructor` as the default export, which already provides all the necessary static methods (`authorize`, `validate`, `details`) for testing. All existing tests continue to pass. Fixes #171. <!-- START COPILOT CODING AGENT TIPS --> --- 💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click [here](https://survey3.medallia.com/?EAHeSx-AP01bZqG0Ld9QLQ) to start the survey. --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: Donavan Becker <[email protected]> Co-authored-by: donavanbecker <[email protected]>
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.
Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
dependencies
Pull requests that update a dependency file
docs
enhancement
New feature or request
latest
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
No description provided.