homebridge-tsvesync 1.1.1 → 1.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +343 -0
- package/dist/accessories/air-purifier.accessory.d.ts +1 -0
- package/dist/accessories/air-purifier.accessory.d.ts.map +1 -1
- package/dist/accessories/air-purifier.accessory.js +132 -68
- package/dist/accessories/air-purifier.accessory.js.map +1 -1
- package/dist/platform.d.ts +18 -0
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +205 -10
- package/dist/platform.js.map +1 -1
- package/dist/utils/api-proxy.d.ts +4 -1
- package/dist/utils/api-proxy.d.ts.map +1 -1
- package/dist/utils/api-proxy.js +5 -3
- package/dist/utils/api-proxy.js.map +1 -1
- package/dist/utils/session-store.d.ts +28 -0
- package/dist/utils/session-store.d.ts.map +1 -0
- package/dist/utils/session-store.js +92 -0
- package/dist/utils/session-store.js.map +1 -0
- package/package.json +2 -2
- package/src/accessories/air-purifier.accessory.ts +122 -72
- package/src/platform.ts +202 -8
- package/src/utils/api-proxy.ts +8 -2
- package/src/utils/session-store.ts +92 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,348 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.3.3 (2025-01-05)
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- **⏰ Extended Timeout Chain Fix**: Enhanced proactive token refresh system to handle very long-duration tokens
|
|
7
|
+
- **🔧 Timeout Chaining**: Implemented timeout chaining for refresh delays exceeding Node.js setTimeout maximum (~24.8 days)
|
|
8
|
+
- **🛡️ Robust Scheduling**: Prevents timer overflow errors with automatic timer chaining for extended token lifetimes
|
|
9
|
+
- **⚡ Seamless Operation**: Long-duration token refresh scheduling now works reliably without timing limitations
|
|
10
|
+
- **🎯 Precision Handling**: Maintains accurate refresh timing even for tokens with extended lifetimes
|
|
11
|
+
- **📊 Enhanced Logging**: Improved logging for chained timer operations and extended refresh scheduling
|
|
12
|
+
|
|
13
|
+
- **🔄 Session Hydration Compatibility**: Enhanced session recovery with backward compatibility
|
|
14
|
+
- **🛡️ Fallback Support**: Added backward-compatible session hydration for older tsvesync versions
|
|
15
|
+
- **⚡ Direct Field Setting**: Automatic fallback to direct field setting when hydrateSession method unavailable
|
|
16
|
+
- **🔧 Improved Reliability**: Enhanced session recovery across different tsvesync library versions
|
|
17
|
+
- **📊 Better Error Handling**: Graceful handling of version compatibility during session restoration
|
|
18
|
+
|
|
19
|
+
### Enhanced
|
|
20
|
+
- **🎯 Timer Management**: Advanced timer management system for extended timeout scenarios
|
|
21
|
+
- **🔧 MAX_DELAY Handling**: Proper handling of Node.js setTimeout maximum delay limitations (2,147,483,647 ms)
|
|
22
|
+
- **⚡ Chain Calculation**: Intelligent timer chaining with accurate remaining time calculations
|
|
23
|
+
- **🛡️ Error Prevention**: Prevents timer overflow errors and ensures reliable long-duration scheduling
|
|
24
|
+
- **📈 Performance**: Optimized timer chaining with minimal overhead for standard use cases
|
|
25
|
+
|
|
26
|
+
### Technical Details
|
|
27
|
+
- **🏗️ Timeout Architecture**: Enhanced proactive refresh system with timeout chaining support
|
|
28
|
+
- **📊 Timer Chain Logic**: Automatic detection and handling of timeouts exceeding Node.js limitations
|
|
29
|
+
- **🔧 Compatibility Layer**: Backward-compatible session hydration for various tsvesync versions
|
|
30
|
+
- **⚡ Precision Timing**: Maintains accurate refresh timing regardless of token lifetime duration
|
|
31
|
+
|
|
32
|
+
### Dependencies
|
|
33
|
+
- **📦 tsvesync**: Updated to 1.3.3 for enhanced cross-project version synchronization
|
|
34
|
+
|
|
35
|
+
### Summary of All Enhancements from v1.2.0 onwards
|
|
36
|
+
|
|
37
|
+
#### Session Management & Authentication System (v1.2.0-1.3.3)
|
|
38
|
+
- **💾 Complete Session Persistence**: Sessions survive across Homebridge restarts with enhanced validation
|
|
39
|
+
- **⏰ Advanced Proactive Token Refresh**: Intelligent refresh scheduling with extended timeout support (v1.3.0-1.3.3)
|
|
40
|
+
- **🔐 Enhanced Security**: Username validation and account isolation for multi-user environments
|
|
41
|
+
- **📊 JWT Token Mastery**: Complete lifecycle management with normalized timestamp handling
|
|
42
|
+
- **🛡️ Secure Storage**: Protected session storage with comprehensive validation and recovery
|
|
43
|
+
- **🚀 Performance Optimization**: Reduced authentication overhead with intelligent session reuse
|
|
44
|
+
- **🔄 Cross-Region Support**: Enhanced compatibility with different VeSync regional endpoints
|
|
45
|
+
- **🎯 Extended Timeout Handling**: Reliable scheduling for very long-duration token refresh scenarios (NEW in 1.3.3)
|
|
46
|
+
|
|
47
|
+
#### Speed Control & HomeKit Integration (v1.2.0-1.3.1)
|
|
48
|
+
- **🎛️ Advanced Speed Control**: Dynamic support for 3-4+ speed air purifiers with model-specific logic
|
|
49
|
+
- **🌙 Intelligent Sleep Mode**: Sleep mode integration as first notch on HomeKit slider
|
|
50
|
+
- **🎯 Precision Mapping**: Accurate percentage-to-speed conversions for different device capabilities
|
|
51
|
+
- **📱 Enhanced UX**: Improved slider positions, speed transitions, and HomeKit responsiveness
|
|
52
|
+
- **🔄 Smart Notch System**: Automatic adjustment based on device capabilities and speed ranges
|
|
53
|
+
|
|
54
|
+
Full changelog: https://github.com/mickgiles/homebridge-tsvesync/blob/main/CHANGELOG.md
|
|
55
|
+
|
|
56
|
+
## 1.3.2 (2025-01-05)
|
|
57
|
+
|
|
58
|
+
### Enhanced
|
|
59
|
+
- **🔐 Advanced Session Management**: Comprehensive improvements to session persistence and authentication reliability
|
|
60
|
+
- **👤 Enhanced Username Validation**: Session reuse now validates username to prevent cross-account authentication conflicts
|
|
61
|
+
- **🔒 Improved Account Isolation**: Persisted sessions are properly isolated and validated against configured accounts
|
|
62
|
+
- **💾 Optimized Session Persistence**: Best-effort session saving immediately after successful authentication
|
|
63
|
+
- **📝 Detailed Session Logging**: Comprehensive debug logging for session save/load operations with expiration tracking
|
|
64
|
+
- **🛡️ Robust Error Handling**: Enhanced error messages and recovery flows for session hydration failures
|
|
65
|
+
|
|
66
|
+
- **🔧 JWT Timestamp Precision Handling**: Enhanced token timestamp processing for consistent authentication
|
|
67
|
+
- **📊 Timestamp Normalization**: Automatic detection and conversion of millisecond timestamps to seconds
|
|
68
|
+
- **⚡ Improved Token Validation**: Ensures accurate token expiration calculations across different token formats
|
|
69
|
+
- **🔄 Cross-Region Compatibility**: Better handling of JWT tokens from different VeSync regional endpoints
|
|
70
|
+
- **🛡️ Edge Case Prevention**: Fixes authentication issues with tokens using inconsistent timestamp precision
|
|
71
|
+
|
|
72
|
+
### Fixed
|
|
73
|
+
- **🎛️ Session Hydration Reliability**: Improved session recovery and validation processes
|
|
74
|
+
- **🔍 Better Error Detection**: Enhanced detection of invalid or corrupted session data
|
|
75
|
+
- **📈 Startup Performance**: Optimized authentication flow to reduce unnecessary login attempts
|
|
76
|
+
- **⚡ Token Lifecycle Management**: Better coordination with tsvesync library's token refresh mechanisms
|
|
77
|
+
- **🛡️ Authentication Stability**: Reduced authentication interruptions during long-running sessions
|
|
78
|
+
|
|
79
|
+
### Technical Details
|
|
80
|
+
- **🏗️ Session Architecture**: Enhanced session store with improved persistence and validation logic
|
|
81
|
+
- **📊 Token Management**: Advanced JWT token handling with normalized timestamp precision
|
|
82
|
+
- **🔧 Error Handling**: Comprehensive error recovery flows with detailed logging and debugging
|
|
83
|
+
- **⚡ Performance**: Optimized session operations for better startup performance and reliability
|
|
84
|
+
|
|
85
|
+
### Dependencies
|
|
86
|
+
- **📦 tsvesync**: Updated to 1.3.2 for enhanced JWT timestamp handling and session management improvements
|
|
87
|
+
|
|
88
|
+
### Summary of All Enhancements from v1.2.0 onwards
|
|
89
|
+
|
|
90
|
+
#### Session Management & Authentication System (v1.2.0-1.3.2)
|
|
91
|
+
- **💾 Complete Session Persistence**: Sessions survive across Homebridge restarts with enhanced validation
|
|
92
|
+
- **⏰ Advanced Proactive Token Refresh**: Intelligent refresh scheduling prevents JWT expiration (v1.3.0)
|
|
93
|
+
- **🔐 Enhanced Security**: Username validation and account isolation for multi-user environments
|
|
94
|
+
- **📊 JWT Token Mastery**: Complete lifecycle management with normalized timestamp handling
|
|
95
|
+
- **🛡️ Secure Storage**: Protected session storage with comprehensive validation and recovery
|
|
96
|
+
- **🚀 Performance Optimization**: Reduced authentication overhead with intelligent session reuse
|
|
97
|
+
- **🔄 Cross-Region Support**: Enhanced compatibility with different VeSync regional endpoints
|
|
98
|
+
|
|
99
|
+
#### Speed Control & HomeKit Integration (v1.2.0-1.3.1)
|
|
100
|
+
- **🎛️ Advanced Speed Control**: Dynamic support for 3-4+ speed air purifiers with model-specific logic
|
|
101
|
+
- **🌙 Intelligent Sleep Mode**: Sleep mode integration as first notch on HomeKit slider
|
|
102
|
+
- **🎯 Precision Mapping**: Accurate percentage-to-speed conversions for different device capabilities
|
|
103
|
+
- **📱 Enhanced UX**: Improved slider positions, speed transitions, and HomeKit responsiveness
|
|
104
|
+
- **🔄 Smart Notch System**: Automatic adjustment based on device capabilities and speed ranges
|
|
105
|
+
|
|
106
|
+
Full changelog: https://github.com/mickgiles/homebridge-tsvesync/blob/main/CHANGELOG.md
|
|
107
|
+
|
|
108
|
+
## 1.3.1 (2025-09-04)
|
|
109
|
+
|
|
110
|
+
### Fixed
|
|
111
|
+
- **🔐 Enhanced Session Management**: Improved session persistence and authentication flow
|
|
112
|
+
- **👤 Username Validation**: Session reuse now validates username to prevent cross-account conflicts
|
|
113
|
+
- **🔒 Account Isolation**: Persisted sessions are ignored if they belong to a different configured account
|
|
114
|
+
- **⚡ Optimized Login Flow**: Authentication only occurs when necessary, relying on persisted tokens and library re-login
|
|
115
|
+
- **🛡️ Session Security**: Enhanced session storage with username tracking for better account management
|
|
116
|
+
|
|
117
|
+
- **🎛️ Core 200S Speed Control Improvements**: Enhanced air purifier speed control for Core 200S devices
|
|
118
|
+
- **🎯 Model-Specific Logic**: Core 200S now uses dedicated speed calculation method with proper 25% steps
|
|
119
|
+
- **📊 Accurate Mapping**: Improved speed-to-percentage conversion for devices with 3 manual speeds
|
|
120
|
+
- **🌙 Sleep Mode Integration**: Better sleep mode handling with model-specific speed ranges
|
|
121
|
+
- **🔄 Precise Notch Calculation**: Enhanced notch-to-speed mapping for more accurate HomeKit control
|
|
122
|
+
|
|
123
|
+
### Enhanced
|
|
124
|
+
- **📝 Improved Logging**: Better debugging information for mode changes and device operations
|
|
125
|
+
- **🔍 Mode Change Tracking**: Enhanced logging for manual, auto, and sleep mode transitions
|
|
126
|
+
- **🎛️ Speed Control Logging**: More detailed logging for speed changes and slider operations
|
|
127
|
+
- **📱 HomeKit Integration**: Better visibility into device state changes and characteristic updates
|
|
128
|
+
|
|
129
|
+
### Changed
|
|
130
|
+
- **🔄 Authentication Strategy**: Optimized authentication flow to reduce unnecessary login attempts
|
|
131
|
+
- **💾 Token Persistence**: Improved reliance on persisted tokens with library-managed re-authentication
|
|
132
|
+
- **⚡ Startup Performance**: Faster platform initialization by avoiding redundant login checks
|
|
133
|
+
- **🎯 Smart Re-login**: Authentication only triggered when API returns 401/419 status codes
|
|
134
|
+
|
|
135
|
+
### Technical Details
|
|
136
|
+
- **🏗️ Session Architecture**: Enhanced session store with username tracking and validation
|
|
137
|
+
- **🎛️ Speed Control Algorithm**: Model-specific speed calculation methods for different device types
|
|
138
|
+
- **🔧 Authentication Flow**: Streamlined login logic with better token lifecycle management
|
|
139
|
+
- **📊 Core 200S Support**: Dedicated isCore200S() method for model-specific functionality
|
|
140
|
+
|
|
141
|
+
### Dependencies
|
|
142
|
+
- **📦 tsvesync**: Updated to 1.3.1 for enhanced token expiration detection and authentication improvements
|
|
143
|
+
|
|
144
|
+
## 1.3.0 (2025-09-04)
|
|
145
|
+
|
|
146
|
+
### Added
|
|
147
|
+
- **⏰ Enhanced Proactive Token Refresh**: Advanced JWT token refresh system with intelligent scheduling
|
|
148
|
+
- **🎯 Smart Scheduling Policy**: Dynamic refresh timing based on token lifetime:
|
|
149
|
+
- >7 days remaining: refresh 5 days before expiry
|
|
150
|
+
- 1-7 days remaining: refresh 12 hours before expiry
|
|
151
|
+
- 1-24 hours remaining: refresh 1 hour before expiry
|
|
152
|
+
- <1 hour remaining: rely on 401-triggered re-login to prevent thrashing
|
|
153
|
+
- **📊 Accurate Lifetime Tracking**: Uses actual token issuance time (iat) for precise calculations
|
|
154
|
+
- **🛡️ Duplicate Prevention**: Guards against multiple timers for same token expiration
|
|
155
|
+
- **🔄 State Management**: Concurrent refresh protection with in-progress tracking
|
|
156
|
+
- **🧹 Clean Shutdown**: Proper timer cleanup on platform shutdown
|
|
157
|
+
- **⚡ Background Operation**: Seamless token refresh without service interruption
|
|
158
|
+
|
|
159
|
+
- **🔧 Advanced Session Management**: Enhanced integration with tsvesync v1.3.0
|
|
160
|
+
- **🔔 Token Change Integration**: Full utilization of tsvesync's onTokenChange callback system
|
|
161
|
+
- **📈 Reliability**: Eliminates VeSync connectivity interruptions from expired tokens
|
|
162
|
+
- **🎯 Optimal Timing**: Intelligent buffer calculation prevents both premature and late refreshes
|
|
163
|
+
- **⏰ Safety Floor**: Never schedules refresh less than 30 minutes from current time
|
|
164
|
+
|
|
165
|
+
### Enhanced
|
|
166
|
+
- **🔐 Session Persistence**: Improved session management with proactive refresh integration
|
|
167
|
+
- **💾 Complete Session Recovery**: Sessions survive across Homebridge restarts with enhanced refresh
|
|
168
|
+
- **📊 JWT Integration**: Advanced token lifecycle management with expiration tracking
|
|
169
|
+
- **🛡️ Secure Storage**: Protected session storage in tsvesync subdirectory
|
|
170
|
+
- **🚀 Faster Startup**: Reduced authentication overhead via intelligent session reuse
|
|
171
|
+
- **🔄 Seamless Recovery**: Automatic fallback when persisted sessions are invalid
|
|
172
|
+
|
|
173
|
+
### Changed
|
|
174
|
+
- **📚 Dependency Update**: Updated tsvesync dependency to 1.3.0 for enhanced session management
|
|
175
|
+
- **📝 Documentation**: Comprehensive release notes including all enhancements from 1.2.0 onwards
|
|
176
|
+
- **⚡ Performance**: Optimized token refresh logic for better performance and reliability
|
|
177
|
+
|
|
178
|
+
### Technical Details
|
|
179
|
+
- **🔧 Advanced Token Lifecycle**: Proactive refresh ensures tokens never expire during operation
|
|
180
|
+
- **🎯 Progressive Buffer Strategy**: Smart refresh timing based on token lifetime for optimal reliability
|
|
181
|
+
- **📈 Enhanced Error Handling**: Comprehensive try/finally blocks for robust operation
|
|
182
|
+
- **🔄 State Coordination**: Prevents concurrent refresh operations with proper synchronization
|
|
183
|
+
- **🛡️ Authentication Stability**: Eliminates authentication interruptions during long-running sessions
|
|
184
|
+
|
|
185
|
+
### Summary of All Features from v1.2.0 onwards
|
|
186
|
+
|
|
187
|
+
#### Session Management & Authentication (v1.2.0-1.3.0)
|
|
188
|
+
- **💾 Complete Session Persistence**: Sessions survive across Homebridge restarts
|
|
189
|
+
- **⏰ Enhanced Proactive Token Refresh**: Advanced refresh before JWT expiration (NEW in 1.3.0)
|
|
190
|
+
- **🔐 Automatic Recovery**: Seamless fallback when persisted sessions are invalid
|
|
191
|
+
- **📊 JWT Integration**: Full token lifecycle management with expiration tracking
|
|
192
|
+
- **🛡️ Secure Storage**: Protected session storage in tsvesync subdirectory
|
|
193
|
+
- **🚀 Faster Startup**: Reduced authentication overhead via session reuse
|
|
194
|
+
|
|
195
|
+
#### Speed Control & HomeKit Integration (v1.2.0)
|
|
196
|
+
- **🎛️ Advanced Speed Control**: Dynamic support for 3-4+ speed air purifiers
|
|
197
|
+
- **🌙 Sleep Mode Integration**: Sleep mode as first notch on HomeKit slider
|
|
198
|
+
- **🎯 Precision Mapping**: Accurate percentage-to-speed conversions
|
|
199
|
+
- **📱 Enhanced UX**: Improved slider positions and speed transitions
|
|
200
|
+
- **🔄 Smart Notch System**: Automatic adjustment based on device capabilities
|
|
201
|
+
|
|
202
|
+
Full changelog: https://github.com/mickgiles/homebridge-tsvesync/blob/main/CHANGELOG.md
|
|
203
|
+
|
|
204
|
+
## 1.2.2 (2025-09-04)
|
|
205
|
+
|
|
206
|
+
### Added
|
|
207
|
+
- **⏰ Proactive Token Refresh**: Intelligent JWT token refresh before expiration
|
|
208
|
+
- **🔄 Smart Scheduling**: Automatically schedules token refresh before JWT expiry
|
|
209
|
+
- **📊 Accurate Lifetime Tracking**: Uses actual token issuance time (iat) for precise calculations
|
|
210
|
+
- **🎯 Dynamic Buffer Calculation**: Refresh buffer is earlier of 5 days or 10% of token lifetime
|
|
211
|
+
- **🔔 Token Change Integration**: Leverages tsvesync's onTokenChange callback system
|
|
212
|
+
- **🧹 Clean Shutdown**: Properly clears refresh timer on platform shutdown
|
|
213
|
+
- **🛡️ Uninterrupted Service**: Prevents authentication failures during long-running sessions
|
|
214
|
+
|
|
215
|
+
### Changed
|
|
216
|
+
- **📚 Dependency Update**: Updated tsvesync dependency to 1.2.2
|
|
217
|
+
- **📝 Documentation**: Comprehensive release notes including all changes from 1.2.0 onwards
|
|
218
|
+
|
|
219
|
+
### Technical Details
|
|
220
|
+
- **🔧 Token Lifecycle**: Proactive refresh ensures tokens never expire during operation
|
|
221
|
+
- **📈 Reliability**: Eliminates VeSync connectivity interruptions from expired tokens
|
|
222
|
+
- **🎯 Buffer Strategy**: Minimum 1 day, maximum 5 days refresh buffer for optimal timing
|
|
223
|
+
- **⚡ Background Operation**: Token refresh happens seamlessly without service interruption
|
|
224
|
+
|
|
225
|
+
### Summary of All Features from v1.2.0 onwards
|
|
226
|
+
|
|
227
|
+
#### Session Management & Authentication (v1.2.0-1.2.2)
|
|
228
|
+
- **💾 Complete Session Persistence**: Sessions survive across Homebridge restarts
|
|
229
|
+
- **⏰ Proactive Token Refresh**: Automatic refresh before JWT expiration (NEW in 1.2.2)
|
|
230
|
+
- **🔐 Automatic Recovery**: Seamless fallback when persisted sessions are invalid
|
|
231
|
+
- **📊 JWT Integration**: Full token lifecycle management with expiration tracking
|
|
232
|
+
- **🛡️ Secure Storage**: Protected session storage in tsvesync subdirectory
|
|
233
|
+
- **🚀 Faster Startup**: Reduced authentication overhead via session reuse
|
|
234
|
+
|
|
235
|
+
#### Speed Control & HomeKit Integration (v1.2.0)
|
|
236
|
+
- **🎛️ Advanced Speed Control**: Dynamic support for 3-4+ speed air purifiers
|
|
237
|
+
- **🌙 Sleep Mode Integration**: Sleep mode as first notch on HomeKit slider
|
|
238
|
+
- **🎯 Precision Mapping**: Accurate percentage-to-speed conversions
|
|
239
|
+
- **📱 Enhanced UX**: Improved slider positions and speed transitions
|
|
240
|
+
- **🔄 Smart Notch System**: Automatic adjustment based on device capabilities
|
|
241
|
+
|
|
242
|
+
Full changelog: https://github.com/mickgiles/homebridge-tsvesync/blob/main/CHANGELOG.md
|
|
243
|
+
|
|
244
|
+
## 1.2.1 (2025-09-04)
|
|
245
|
+
|
|
246
|
+
### Changed
|
|
247
|
+
- **📦 Re-release**: Version 1.2.1 re-release with comprehensive release notes from 1.2.0
|
|
248
|
+
- **📝 Documentation**: Enhanced release documentation and changelog formatting
|
|
249
|
+
- **🔄 Version Alignment**: Synchronized version numbers across tsvesync and homebridge-tsvesync
|
|
250
|
+
- **📚 Dependency Update**: Updated tsvesync dependency to 1.2.1
|
|
251
|
+
|
|
252
|
+
## 1.2.0 (2025-09-04)
|
|
253
|
+
|
|
254
|
+
### Added
|
|
255
|
+
- **💾 Session Persistence**: Comprehensive session management for improved reliability
|
|
256
|
+
- **🔐 Automatic Session Recovery**: VeSync sessions now persist across Homebridge restarts
|
|
257
|
+
- **📊 Token Lifecycle Management**: JWT token expiration tracking and automatic refresh
|
|
258
|
+
- **🛡️ Secure Storage**: Sessions stored with appropriate file permissions in tsvesync subdirectory
|
|
259
|
+
- **🚀 Faster Startup**: Reduced authentication overhead on Homebridge startup via session reuse
|
|
260
|
+
- **🔄 Seamless Recovery**: Automatic fallback to fresh login when persisted sessions are invalid
|
|
261
|
+
|
|
262
|
+
- **🎛️ Advanced Speed Control**: Enhanced speed control for air purifiers with 4+ manual speeds
|
|
263
|
+
- **🌟 Multi-Speed Support**: Dynamic step calculation for devices with 4+ manual speed levels
|
|
264
|
+
- **🎯 Precision Mapping**: Better percentage-to-speed conversion for devices with varying speed counts
|
|
265
|
+
- **🔄 Smart Notch System**: Automatic adjustment of speed notches based on device capabilities
|
|
266
|
+
- **📱 Improved HomeKit UX**: More accurate slider positions and speed transitions
|
|
267
|
+
|
|
268
|
+
### Enhanced
|
|
269
|
+
- **🔧 API Integration**: Enhanced tsvesync library integration with session management
|
|
270
|
+
- **📦 Library Update**: Updated to tsvesync 1.2.0 with session persistence capabilities
|
|
271
|
+
- **🔗 Session Callbacks**: Integration with tsvesync session store for automatic persistence
|
|
272
|
+
- **⚡ Performance**: Reduced API calls through intelligent session reuse
|
|
273
|
+
- **🛡️ Reliability**: Better handling of authentication failures with automatic recovery
|
|
274
|
+
|
|
275
|
+
- **🌙 Sleep Mode Control**: Refined sleep mode speed control logic
|
|
276
|
+
- **🎛️ Dynamic Step Calculation**: Speed steps now adjust based on maximum device speeds (20% vs 25%)
|
|
277
|
+
- **🎯 Better Speed Mapping**: More accurate conversion between HomeKit percentages and device speeds
|
|
278
|
+
- **🔄 Consistent Behavior**: Unified speed control logic across all sleep-capable devices
|
|
279
|
+
- **📱 UI Responsiveness**: Improved HomeKit characteristic updates during sleep mode transitions
|
|
280
|
+
|
|
281
|
+
### Fixed
|
|
282
|
+
- **🔧 Speed Control Accuracy**: Enhanced speed control precision for various device configurations
|
|
283
|
+
- **📊 Speed Calculation**: Fixed percentage calculation for devices with 4+ manual speeds
|
|
284
|
+
- **🎛️ Notch Mapping**: Improved notch-to-speed conversion with proper boundary checking
|
|
285
|
+
- **🔄 State Synchronization**: Better synchronization between device state and HomeKit display
|
|
286
|
+
- **🛡️ Edge Case Handling**: Enhanced handling of speed edge cases and boundary conditions
|
|
287
|
+
|
|
288
|
+
### Technical Details
|
|
289
|
+
- **🏗️ Session Architecture**: Complete integration with tsvesync 1.2.0 session management system
|
|
290
|
+
- **🔧 FileSessionStore**: Dedicated session storage in ~/.homebridge/tsvesync/session.json
|
|
291
|
+
- **📊 JWT Integration**: Automatic JWT token expiration tracking and session validation
|
|
292
|
+
- **🎛️ Speed Algorithm**: Enhanced speed calculation algorithms for multi-speed device support
|
|
293
|
+
- **🔄 Promise Coordination**: Better coordination with tsvesync library's promise-based login system
|
|
294
|
+
|
|
295
|
+
### Migration Notes
|
|
296
|
+
- **🚀 Automatic Enhancement**: Session persistence activates automatically after Homebridge restart
|
|
297
|
+
- **📁 New Storage**: Session files stored in new tsvesync subdirectory under Homebridge storage path
|
|
298
|
+
- **🔄 Backward Compatible**: All existing functionality preserved with enhanced capabilities
|
|
299
|
+
- **✅ No Configuration**: No configuration changes required - enhancements work automatically
|
|
300
|
+
- **🔧 Dependency Update**: tsvesync library automatically updated to version 1.2.0
|
|
301
|
+
|
|
302
|
+
## 1.1.2 (2025-09-03)
|
|
303
|
+
|
|
304
|
+
### Enhanced
|
|
305
|
+
- **🌙 Advanced Sleep Mode Speed Control**: Significantly improved HomeKit sleep mode integration
|
|
306
|
+
- **🎯 Sleep as First Notch**: Sleep mode now appears as the first position (25%) on HomeKit speed slider for supported devices
|
|
307
|
+
- **🎛️ Better Speed Mapping**: Enhanced speed control with 25%/50%/75%/100% positions for intuitive user control
|
|
308
|
+
- **🔄 Smart Mode Transitions**: Automatic manual mode switching when adjusting speeds from sleep mode
|
|
309
|
+
- **📱 Immediate UI Feedback**: Instant HomeKit characteristic updates for responsive user experience
|
|
310
|
+
- **🛡️ Error Recovery**: Comprehensive error handling with state reversion on API failures
|
|
311
|
+
|
|
312
|
+
- **⚡ Performance Optimizations**: Streamlined speed control logic for better performance
|
|
313
|
+
- **🔧 Consolidated Code**: Refactored speed conversion methods for improved maintainability
|
|
314
|
+
- **📊 Efficient Calculations**: Optimized percentage-to-speed and speed-to-percentage conversions
|
|
315
|
+
- **🎯 Reduced Complexity**: Simplified conditional logic while maintaining full functionality
|
|
316
|
+
- **💾 Memory Efficiency**: Better resource utilization with consolidated helper methods
|
|
317
|
+
|
|
318
|
+
### Fixed
|
|
319
|
+
- **🌪️ Enhanced Speed Restoration**: Improved device speed handling across all air purifier models
|
|
320
|
+
- **🎛️ Sleep Mode Detection**: Better detection and handling of sleep mode state transitions
|
|
321
|
+
- **🔄 Mode Synchronization**: Improved synchronization between device mode and HomeKit display
|
|
322
|
+
- **📱 Slider Accuracy**: More accurate speed slider positions for devices with sleep mode support
|
|
323
|
+
- **🛡️ State Consistency**: Enhanced state management to prevent speed control conflicts
|
|
324
|
+
|
|
325
|
+
### Technical Details
|
|
326
|
+
- **🏗️ Refactored Architecture**: Consolidated speed calculation methods for better code organization
|
|
327
|
+
- **🎯 Feature Detection**: Enhanced hasFeature('sleep_mode') integration for dynamic behavior
|
|
328
|
+
- **🔧 Method Optimization**: Streamlined percentageToSpeed() and speedToPercentage() methods
|
|
329
|
+
- **📊 Improved Mapping**: Better notch-based speed mapping with rounding for discrete positions
|
|
330
|
+
- **🛡️ Enhanced Validation**: Improved input validation and boundary checking for speed values
|
|
331
|
+
|
|
332
|
+
### Affected Devices
|
|
333
|
+
- **Sleep Mode Devices**: Air purifiers with sleep mode support now have enhanced speed control
|
|
334
|
+
- **All Air Purifiers**: Benefit from optimized speed conversion logic and better performance
|
|
335
|
+
- **Core/Vital/LAP Series**: Improved HomeKit integration with consistent speed control behavior
|
|
336
|
+
|
|
337
|
+
### Migration Notes
|
|
338
|
+
- **🚀 Automatic Enhancement**: Speed control improvements activate automatically after Homebridge restart
|
|
339
|
+
- **📱 HomeKit Changes**: Supported devices will show sleep mode as first notch on speed slider
|
|
340
|
+
- **🔄 Backward Compatible**: All existing functionality preserved with enhanced capabilities
|
|
341
|
+
- **✅ No Configuration**: No configuration changes required - enhancements work automatically
|
|
342
|
+
|
|
343
|
+
### Dependencies
|
|
344
|
+
- **📦 tsvesync**: Updated to 1.1.2 for synchronized release versioning
|
|
345
|
+
|
|
3
346
|
## 1.1.1 (2025-08-30)
|
|
4
347
|
|
|
5
348
|
### Improved
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"air-purifier.accessory.d.ts","sourceRoot":"","sources":["../../src/accessories/air-purifier.accessory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,iBAAiB,EAAW,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAkC9E,qBAAa,oBAAqB,SAAQ,aAAa;IACrD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;IAClD,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IAC7C,OAAO,CAAC,iBAAiB,CAAU;IACnC,OAAO,CAAC,iBAAiB,CAAU;IACnC,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,iBAAiB,CAAa;IACtC,OAAO,CAAC,cAAc,CAAkB;gBAGtC,QAAQ,EAAE,gBAAgB,EAC1B,SAAS,EAAE,iBAAiB,EAC5B,MAAM,EAAE,iBAAiB;IAiD3B;;OAEG;IACH,OAAO,CAAC,UAAU;IAqIlB;;OAEG;IACH,OAAO,CAAC,+BAA+B;IAmBvC;;OAEG;IACH,OAAO,CAAC,cAAc;IAiCtB;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAclC;;OAEG;IACH,OAAO,CAAC,iBAAiB;
|
|
1
|
+
{"version":3,"file":"air-purifier.accessory.d.ts","sourceRoot":"","sources":["../../src/accessories/air-purifier.accessory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,iBAAiB,EAAW,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAkC9E,qBAAa,oBAAqB,SAAQ,aAAa;IACrD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;IAClD,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IAC7C,OAAO,CAAC,iBAAiB,CAAU;IACnC,OAAO,CAAC,iBAAiB,CAAU;IACnC,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,iBAAiB,CAAa;IACtC,OAAO,CAAC,cAAc,CAAkB;gBAGtC,QAAQ,EAAE,gBAAgB,EAC1B,SAAS,EAAE,iBAAiB,EAC5B,MAAM,EAAE,iBAAiB;IAiD3B;;OAEG;IACH,OAAO,CAAC,UAAU;IAqIlB;;OAEG;IACH,OAAO,CAAC,+BAA+B;IAmBvC;;OAEG;IACH,OAAO,CAAC,cAAc;IAiCtB,OAAO,CAAC,UAAU;IAIlB;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAclC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAkBzB;;;;;;;;;;;;OAYG;YACW,oCAAoC;IAoClD;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAoBzB;;OAEG;IACH,SAAS,CAAC,YAAY,IAAI,IAAI;IAqI9B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA0BzB;;OAEG;YACW,yBAAyB;IAOvC;;OAEG;YACW,kBAAkB;IAOhC;;OAEG;YACW,eAAe;IAI7B;;OAEG;IACH,SAAS,CAAC,qBAAqB,IAAI,kBAAkB;IAcrD;;OAEG;cACa,0BAA0B,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAsHvE;;OAEG;YACW,cAAc;IAY5B;;OAEG;YACW,cAAc;IA2C5B;;OAEG;YACW,gBAAgB;IA0B9B;;OAEG;YACW,gBAAgB;YAoLhB,SAAS;YAIT,SAAS;CAoExB"}
|
|
@@ -214,50 +214,49 @@ class AirPurifierAccessory extends base_accessory_1.BaseAccessory {
|
|
|
214
214
|
// Default to 3 for unknown devices
|
|
215
215
|
return 3;
|
|
216
216
|
}
|
|
217
|
+
isCore200S() {
|
|
218
|
+
return (this.device.deviceType || '').toUpperCase().includes('CORE200S');
|
|
219
|
+
}
|
|
217
220
|
/**
|
|
218
221
|
* Calculate the appropriate step size for discrete speed levels
|
|
219
222
|
*/
|
|
220
223
|
calculateRotationSpeedStep() {
|
|
221
|
-
|
|
222
|
-
//
|
|
223
|
-
if (
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
return
|
|
224
|
+
// Expose Sleep as the first notch when supported.
|
|
225
|
+
// Core 200S uses 3 manual speeds (25% step). 4-speed models use 20% step.
|
|
226
|
+
if (this.hasFeature('sleep_mode')) {
|
|
227
|
+
if (this.isCore200S())
|
|
228
|
+
return 25;
|
|
229
|
+
const max = this.getMaxFanSpeed();
|
|
230
|
+
return max >= 4 ? 20 : 25;
|
|
228
231
|
}
|
|
229
|
-
|
|
232
|
+
const maxSpeed = this.getMaxFanSpeed();
|
|
233
|
+
if (maxSpeed === 3)
|
|
234
|
+
return 33.33;
|
|
235
|
+
if (maxSpeed === 4)
|
|
236
|
+
return 25;
|
|
230
237
|
return 1;
|
|
231
238
|
}
|
|
232
239
|
/**
|
|
233
240
|
* Convert device speed to percentage
|
|
234
241
|
*/
|
|
235
242
|
speedToPercentage(speed) {
|
|
243
|
+
// Sleep as first notch: map manual speeds to notches based on model
|
|
244
|
+
if (this.hasFeature('sleep_mode')) {
|
|
245
|
+
if (typeof speed !== 'number' || speed <= 0)
|
|
246
|
+
return 0;
|
|
247
|
+
const step = this.calculateRotationSpeedStep();
|
|
248
|
+
const max = this.isCore200S() ? 3 : this.getMaxFanSpeed();
|
|
249
|
+
// Manual speeds occupy notches 2..(max+1)
|
|
250
|
+
const notch = Math.max(2, Math.min(max + 1, speed + 1));
|
|
251
|
+
return Math.min(100, notch * step);
|
|
252
|
+
}
|
|
236
253
|
const maxSpeed = this.getMaxFanSpeed();
|
|
237
|
-
|
|
238
|
-
if (maxSpeed <= 0 || typeof speed !== 'number' || speed <= 0) {
|
|
254
|
+
if (maxSpeed <= 0 || typeof speed !== 'number' || speed <= 0)
|
|
239
255
|
return 0;
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
if (maxSpeed ===
|
|
243
|
-
|
|
244
|
-
case 1: return 33.33; // Low -> 33.33%
|
|
245
|
-
case 2: return 66.67; // Medium -> 66.67%
|
|
246
|
-
case 3: return 100; // High -> 100%
|
|
247
|
-
default: return 0;
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
// For devices with 4 speed levels
|
|
251
|
-
else if (maxSpeed === 4) {
|
|
252
|
-
switch (speed) {
|
|
253
|
-
case 1: return 25; // Low -> 25%
|
|
254
|
-
case 2: return 50; // Medium-Low -> 50%
|
|
255
|
-
case 3: return 75; // Medium-High -> 75%
|
|
256
|
-
case 4: return 100; // High -> 100%
|
|
257
|
-
default: return 0;
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
// Default calculation
|
|
256
|
+
if (maxSpeed === 3)
|
|
257
|
+
return speed === 1 ? 33.33 : speed === 2 ? 66.67 : 100;
|
|
258
|
+
if (maxSpeed === 4)
|
|
259
|
+
return speed === 1 ? 25 : speed === 2 ? 50 : speed === 3 ? 75 : 100;
|
|
261
260
|
return Math.min(100, Math.max(0, Math.round((speed / maxSpeed) * 100)));
|
|
262
261
|
}
|
|
263
262
|
/**
|
|
@@ -304,41 +303,25 @@ class AirPurifierAccessory extends base_accessory_1.BaseAccessory {
|
|
|
304
303
|
* Convert percentage to device speed
|
|
305
304
|
*/
|
|
306
305
|
percentageToSpeed(percentage) {
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
306
|
+
// Sleep as first notch: round to nearest step and map notches → speeds
|
|
307
|
+
if (this.hasFeature('sleep_mode')) {
|
|
308
|
+
if (typeof percentage !== 'number')
|
|
309
|
+
return 1;
|
|
310
|
+
const step = this.calculateRotationSpeedStep();
|
|
311
|
+
const max = this.isCore200S() ? 3 : this.getMaxFanSpeed();
|
|
312
|
+
const maxNotch = max + 1; // include Sleep notch
|
|
313
|
+
const notch = Math.max(0, Math.min(maxNotch, Math.round(Math.min(100, Math.max(0, percentage)) / step)));
|
|
314
|
+
const manualNotch = Math.max(2, notch);
|
|
315
|
+
return Math.min(max, manualNotch - 1);
|
|
311
316
|
}
|
|
312
|
-
|
|
317
|
+
const maxSpeed = this.getMaxFanSpeed();
|
|
318
|
+
if (maxSpeed <= 0 || typeof percentage !== 'number')
|
|
319
|
+
return 1;
|
|
313
320
|
percentage = Math.min(100, Math.max(0, percentage));
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
}
|
|
319
|
-
else if (percentage <= 66.67) {
|
|
320
|
-
return 2; // Medium
|
|
321
|
-
}
|
|
322
|
-
else {
|
|
323
|
-
return 3; // High
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
// For devices with 4 speed levels
|
|
327
|
-
else if (maxSpeed === 4) {
|
|
328
|
-
if (percentage <= 25) {
|
|
329
|
-
return 1; // Low
|
|
330
|
-
}
|
|
331
|
-
else if (percentage <= 50) {
|
|
332
|
-
return 2; // Medium-Low
|
|
333
|
-
}
|
|
334
|
-
else if (percentage <= 75) {
|
|
335
|
-
return 3; // Medium-High
|
|
336
|
-
}
|
|
337
|
-
else {
|
|
338
|
-
return 4; // High
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
// Default calculation
|
|
321
|
+
if (maxSpeed === 3)
|
|
322
|
+
return percentage <= 33.34 ? 1 : percentage <= 66.67 ? 2 : 3;
|
|
323
|
+
if (maxSpeed === 4)
|
|
324
|
+
return percentage <= 25 ? 1 : percentage <= 50 ? 2 : percentage <= 75 ? 3 : 4;
|
|
342
325
|
return Math.max(1, Math.min(Math.round((percentage / 100) * maxSpeed), maxSpeed));
|
|
343
326
|
}
|
|
344
327
|
/**
|
|
@@ -511,8 +494,11 @@ class AirPurifierAccessory extends base_accessory_1.BaseAccessory {
|
|
|
511
494
|
*/
|
|
512
495
|
async updateDeviceSpecificStates(details) {
|
|
513
496
|
var _a, _b;
|
|
514
|
-
// Update power state
|
|
515
|
-
const
|
|
497
|
+
// Update power state (treat sleep as on for some VeSync models)
|
|
498
|
+
const extended = this.device;
|
|
499
|
+
const mode = (extended.mode || details.mode || '').toLowerCase();
|
|
500
|
+
const isSleep = mode === 'sleep';
|
|
501
|
+
const isOn = isSleep || details.enabled || details.deviceStatus === 'on';
|
|
516
502
|
this.service.updateCharacteristic(this.platform.Characteristic.Active, isOn ? 1 : 0);
|
|
517
503
|
// Update current state (INACTIVE = 0, IDLE = 1, PURIFYING_AIR = 2)
|
|
518
504
|
this.service.updateCharacteristic(this.platform.Characteristic.CurrentAirPurifierState, isOn ? 2 : 0);
|
|
@@ -531,7 +517,13 @@ class AirPurifierAccessory extends base_accessory_1.BaseAccessory {
|
|
|
531
517
|
}
|
|
532
518
|
this.service.updateCharacteristic(this.platform.Characteristic.TargetAirPurifierState, targetState);
|
|
533
519
|
// Update rotation speed
|
|
534
|
-
if (isOn &&
|
|
520
|
+
if (isOn && this.hasFeature('sleep_mode') && isSleep) {
|
|
521
|
+
const step = this.calculateRotationSpeedStep();
|
|
522
|
+
this.service.updateCharacteristic(this.platform.Characteristic.RotationSpeed, step);
|
|
523
|
+
this.lastSetSpeed = 0;
|
|
524
|
+
this.lastSetPercentage = step;
|
|
525
|
+
}
|
|
526
|
+
else if (isOn && details.speed !== undefined && details.speed !== null) {
|
|
535
527
|
// Check if we should skip this update
|
|
536
528
|
if (this.skipNextUpdate) {
|
|
537
529
|
this.platform.log.debug(`Skipping update for ${this.device.deviceName} as requested`);
|
|
@@ -611,7 +603,7 @@ class AirPurifierAccessory extends base_accessory_1.BaseAccessory {
|
|
|
611
603
|
}
|
|
612
604
|
// For all other devices, including Core300S, normal mode handling
|
|
613
605
|
const mode = targetState === 1 ? 'auto' : 'manual';
|
|
614
|
-
this.platform.log.
|
|
606
|
+
this.platform.log.info(`Changing mode to ${mode} for device: ${this.device.deviceName}`);
|
|
615
607
|
let success = false;
|
|
616
608
|
// Use the appropriate method to set the mode
|
|
617
609
|
if (targetState === 1 && typeof extendedDevice.autoMode === 'function') {
|
|
@@ -647,6 +639,11 @@ class AirPurifierAccessory extends base_accessory_1.BaseAccessory {
|
|
|
647
639
|
if (this.device.deviceStatus !== 'on' ||
|
|
648
640
|
this.device.speed === undefined ||
|
|
649
641
|
this.device.speed === null) {
|
|
642
|
+
// If in sleep mode, surface the first notch
|
|
643
|
+
const extended = this.device;
|
|
644
|
+
if (this.hasFeature('sleep_mode') && (extended.mode || '').toLowerCase() === 'sleep') {
|
|
645
|
+
return this.calculateRotationSpeedStep();
|
|
646
|
+
}
|
|
650
647
|
return 0;
|
|
651
648
|
}
|
|
652
649
|
// If we have a last set percentage, use that instead of calculating from device speed
|
|
@@ -704,6 +701,63 @@ class AirPurifierAccessory extends base_accessory_1.BaseAccessory {
|
|
|
704
701
|
// Update device state to get fresh mode information
|
|
705
702
|
await this.updateDeviceSpecificStates(this.device);
|
|
706
703
|
}
|
|
704
|
+
// When using sleep-as-first-notch, map slider notches robustly by rounding
|
|
705
|
+
if (this.hasFeature('sleep_mode')) {
|
|
706
|
+
const max = this.isCore200S() ? 3 : this.getMaxFanSpeed();
|
|
707
|
+
const step = this.calculateRotationSpeedStep();
|
|
708
|
+
const maxNotch = max + 1; // include Sleep notch
|
|
709
|
+
const notch = Math.max(0, Math.min(maxNotch, Math.round(percentage / step)));
|
|
710
|
+
if (notch <= 1) {
|
|
711
|
+
// Sleep
|
|
712
|
+
this.platform.log.info(`Changing mode to sleep for device: ${this.device.deviceName}`);
|
|
713
|
+
let ok = false;
|
|
714
|
+
if (typeof extendedDevice.sleepMode === 'function') {
|
|
715
|
+
ok = await extendedDevice.sleepMode();
|
|
716
|
+
}
|
|
717
|
+
else if (typeof extendedDevice.setMode === 'function') {
|
|
718
|
+
ok = await extendedDevice.setMode('sleep');
|
|
719
|
+
}
|
|
720
|
+
if (!ok) {
|
|
721
|
+
throw new Error('Failed to set sleep mode');
|
|
722
|
+
}
|
|
723
|
+
// Immediate UI feedback
|
|
724
|
+
this.service.updateCharacteristic(this.platform.Characteristic.RotationSpeed, step);
|
|
725
|
+
this.service.updateCharacteristic(this.platform.Characteristic.Active, 1);
|
|
726
|
+
this.service.updateCharacteristic(this.platform.Characteristic.CurrentAirPurifierState, 2);
|
|
727
|
+
this.lastSetSpeed = 0;
|
|
728
|
+
this.lastSetPercentage = step;
|
|
729
|
+
this.skipNextUpdate = true;
|
|
730
|
+
return;
|
|
731
|
+
}
|
|
732
|
+
else {
|
|
733
|
+
// Map manual notches (2..maxNotch) to speeds 1..max
|
|
734
|
+
const desiredSpeed = Math.min(max, notch - 1);
|
|
735
|
+
// Ensure manual mode before speed change if necessary
|
|
736
|
+
const modeNow = (extendedDevice.mode || '').toLowerCase();
|
|
737
|
+
if (modeNow === 'auto' || modeNow === 'sleep') {
|
|
738
|
+
this.platform.log.info(`Changing mode to manual for device: ${this.device.deviceName}`);
|
|
739
|
+
if (typeof extendedDevice.manualMode === 'function') {
|
|
740
|
+
await extendedDevice.manualMode();
|
|
741
|
+
}
|
|
742
|
+
else if (typeof extendedDevice.setMode === 'function') {
|
|
743
|
+
await extendedDevice.setMode('manual');
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
// Update UI early
|
|
747
|
+
const uiPct = Math.min(100, (desiredSpeed + 1) * step);
|
|
748
|
+
this.service.updateCharacteristic(this.platform.Characteristic.RotationSpeed, uiPct);
|
|
749
|
+
this.lastSetSpeed = desiredSpeed;
|
|
750
|
+
this.lastSetPercentage = uiPct;
|
|
751
|
+
this.skipNextUpdate = true;
|
|
752
|
+
const ok = await this.device.changeFanSpeed(desiredSpeed);
|
|
753
|
+
if (!ok) {
|
|
754
|
+
this.lastSetSpeed = 0;
|
|
755
|
+
this.lastSetPercentage = 0;
|
|
756
|
+
throw new Error(`Failed to set speed to ${desiredSpeed}`);
|
|
757
|
+
}
|
|
758
|
+
return;
|
|
759
|
+
}
|
|
760
|
+
}
|
|
707
761
|
// Check if fan speed control is supported in current mode
|
|
708
762
|
if (!this.isFeatureSupportedInCurrentMode('fan_speed')) {
|
|
709
763
|
this.platform.log.warn(`Fan speed control not supported in ${extendedDevice.mode} mode for device: ${this.device.deviceName}`);
|
|
@@ -725,6 +779,16 @@ class AirPurifierAccessory extends base_accessory_1.BaseAccessory {
|
|
|
725
779
|
}
|
|
726
780
|
}
|
|
727
781
|
}
|
|
782
|
+
// For devices without sleep notch, ensure manual mode if required
|
|
783
|
+
const modeNow = (extendedDevice.mode || '').toLowerCase();
|
|
784
|
+
if (modeNow === 'auto') {
|
|
785
|
+
if (typeof extendedDevice.manualMode === 'function') {
|
|
786
|
+
await extendedDevice.manualMode();
|
|
787
|
+
}
|
|
788
|
+
else if (typeof extendedDevice.setMode === 'function') {
|
|
789
|
+
await extendedDevice.setMode('manual');
|
|
790
|
+
}
|
|
791
|
+
}
|
|
728
792
|
// Convert percentage to device speed using our consistent conversion method
|
|
729
793
|
const speed = this.percentageToSpeed(percentage);
|
|
730
794
|
// Final validation to ensure speed is a valid number
|