@switchbot/homebridge-switchbot 5.0.0-beta.64 → 5.0.0-beta.66
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/config.schema.json +9 -4
- package/dist/devices-matter/RoboticVacuumAccessory.d.ts.map +1 -1
- package/dist/devices-matter/RoboticVacuumAccessory.js +19 -4
- package/dist/devices-matter/RoboticVacuumAccessory.js.map +1 -1
- package/dist/devices-matter/VenetianBlindAccessory.d.ts +6 -6
- package/dist/devices-matter/VenetianBlindAccessory.d.ts.map +1 -1
- package/dist/devices-matter/VenetianBlindAccessory.js.map +1 -1
- package/dist/devices-matter/WindowBlindAccessory.d.ts +5 -5
- package/dist/devices-matter/WindowBlindAccessory.d.ts.map +1 -1
- package/dist/devices-matter/WindowBlindAccessory.js +57 -6
- package/dist/devices-matter/WindowBlindAccessory.js.map +1 -1
- package/dist/platform-matter.d.ts.map +1 -1
- package/dist/platform-matter.js +20 -2
- package/dist/platform-matter.js.map +1 -1
- package/dist/settings.d.ts +17 -0
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js.map +1 -1
- package/docs/variables/default.html +1 -1
- package/package.json +1 -1
- package/src/devices-matter/RoboticVacuumAccessory.ts +17 -4
- package/src/devices-matter/VenetianBlindAccessory.ts +5 -5
- package/src/devices-matter/WindowBlindAccessory.ts +53 -10
- package/src/platform-matter.ts +20 -2
- package/src/settings.ts +17 -1
|
@@ -270,13 +270,18 @@ export class RoboticVacuumAccessory extends BaseMatterAccessory {
|
|
|
270
270
|
stop: async () => this.handleStop(),
|
|
271
271
|
start: async () => this.handleStart(),
|
|
272
272
|
goHome: async () => this.handleGoHome(),
|
|
273
|
+
// Always register resume handler, log warning if not supported
|
|
274
|
+
resume: async () => {
|
|
275
|
+
if (capabilities.resume) {
|
|
276
|
+
await this.handleResume()
|
|
277
|
+
} else {
|
|
278
|
+
this.logWarn(`Resume operation is not supported for model: ${this.model}`)
|
|
279
|
+
}
|
|
280
|
+
},
|
|
273
281
|
}
|
|
274
282
|
if (capabilities.pause) {
|
|
275
283
|
opHandlers.pause = async () => this.handlePause()
|
|
276
284
|
}
|
|
277
|
-
if (capabilities.resume) {
|
|
278
|
-
opHandlers.resume = async () => this.handleResume()
|
|
279
|
-
}
|
|
280
285
|
return {
|
|
281
286
|
rvcRunMode: { changeToMode: async (request: MatterRequests.ChangeToMode) => this.handleChangeRunMode(request) },
|
|
282
287
|
rvcCleanMode: { changeToMode: async (request: MatterRequests.ChangeToMode) => this.handleChangeCleanMode(request) },
|
|
@@ -456,7 +461,15 @@ export class RoboticVacuumAccessory extends BaseMatterAccessory {
|
|
|
456
461
|
|
|
457
462
|
private async handleResume(): Promise<void> {
|
|
458
463
|
this.logInfo('resume requested.')
|
|
459
|
-
|
|
464
|
+
try {
|
|
465
|
+
this.logInfo(`[OpenAPI] Sending resume command`)
|
|
466
|
+
await this.sendOpenAPICommand('resume')
|
|
467
|
+
this.logInfo(`[OpenAPI] resume command sent`)
|
|
468
|
+
} catch (e: any) {
|
|
469
|
+
this.logWarn(`OpenAPI resume failed: ${String(e?.message ?? e)}`)
|
|
470
|
+
}
|
|
471
|
+
this.updateRunMode(1)
|
|
472
|
+
this.updateOperationalState(1)
|
|
460
473
|
}
|
|
461
474
|
|
|
462
475
|
private async handleGoHome(): Promise<void> {
|
|
@@ -58,7 +58,7 @@ export class VenetianBlindAccessory extends BaseMatterAccessory {
|
|
|
58
58
|
this.logInfo('initialized.')
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
public async handleGoToLift(request: MatterRequests.GoToLiftPercentage): Promise<void> {
|
|
62
62
|
this.logInfo(`GoToLiftPercentage request: ${JSON.stringify(request)}`)
|
|
63
63
|
|
|
64
64
|
// Matter uses 0=open, 10000=closed, so invert to get open percentage
|
|
@@ -68,7 +68,7 @@ export class VenetianBlindAccessory extends BaseMatterAccessory {
|
|
|
68
68
|
// TODO: await myBlindAPI.setPosition(openPercent)
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
public async handleGoToTilt(request: MatterRequests.GoToTiltPercentage): Promise<void> {
|
|
72
72
|
this.logInfo(`GoToTiltPercentage request: ${JSON.stringify(request)}`)
|
|
73
73
|
|
|
74
74
|
// Matter tilt: 0=horizontal/open (0deg), 10000=vertical/closed (90deg)
|
|
@@ -77,17 +77,17 @@ export class VenetianBlindAccessory extends BaseMatterAccessory {
|
|
|
77
77
|
// TODO: await myBlindAPI.setTiltAngle(degrees)
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
|
|
80
|
+
public async handleUpOrOpen(): Promise<void> {
|
|
81
81
|
this.logInfo('opened blind.')
|
|
82
82
|
// TODO: await myBlindAPI.open()
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
public async handleDownOrClose(): Promise<void> {
|
|
86
86
|
this.logInfo('closed blind.')
|
|
87
87
|
// TODO: await myBlindAPI.close()
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
public async handleStop(): Promise<void> {
|
|
91
91
|
this.logInfo('stopped blind.')
|
|
92
92
|
// TODO: await myBlindAPI.stop()
|
|
93
93
|
}
|
|
@@ -55,28 +55,71 @@ export class WindowBlindAccessory extends BaseMatterAccessory {
|
|
|
55
55
|
this.logInfo('initialized.')
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
public async handleGoToLift(request: MatterRequests.GoToLiftPercentage): Promise<void> {
|
|
59
59
|
this.logInfo(`GoToLiftPercentage request: ${JSON.stringify(request)}`)
|
|
60
60
|
// Matter uses 0=open, 10000=closed, so invert to get open percentage
|
|
61
61
|
const closedPercent = request.liftPercent100thsValue / 100
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
//
|
|
62
|
+
// SwitchBot API expects position: 0=open, 100=closed
|
|
63
|
+
const position = Math.max(0, Math.min(100, closedPercent))
|
|
64
|
+
// Default to performance mode (ff), index is always 0
|
|
65
|
+
const mode = 'ff' // or '01' for silent mode if needed
|
|
66
|
+
const parameter = `0,${mode},${position}`
|
|
67
|
+
this.logInfo(`Sending setPosition to OpenAPI: parameter=${parameter}`)
|
|
68
|
+
try {
|
|
69
|
+
if (this.context?.sendOpenAPI) {
|
|
70
|
+
await this.sendOpenAPICommand('setPosition', parameter)
|
|
71
|
+
this.logInfo('OpenAPI setPosition command sent.')
|
|
72
|
+
} else {
|
|
73
|
+
this.logWarn('OpenAPI sender not available in context.')
|
|
74
|
+
}
|
|
75
|
+
} catch (e: any) {
|
|
76
|
+
this.logWarn(`OpenAPI setPosition failed: ${String(e?.message ?? e)}`)
|
|
77
|
+
}
|
|
65
78
|
}
|
|
66
79
|
|
|
67
|
-
|
|
80
|
+
public async handleUpOrOpen(): Promise<void> {
|
|
68
81
|
this.logInfo('opened blind.')
|
|
69
|
-
|
|
82
|
+
try {
|
|
83
|
+
// Send open command to SwitchBot OpenAPI
|
|
84
|
+
if (this.context?.sendOpenAPI) {
|
|
85
|
+
await this.sendOpenAPICommand('turnOn')
|
|
86
|
+
this.logInfo('OpenAPI open command sent.')
|
|
87
|
+
} else {
|
|
88
|
+
this.logWarn('OpenAPI sender not available in context.')
|
|
89
|
+
}
|
|
90
|
+
} catch (e: any) {
|
|
91
|
+
this.logWarn(`OpenAPI open failed: ${String(e?.message ?? e)}`)
|
|
92
|
+
}
|
|
70
93
|
}
|
|
71
94
|
|
|
72
|
-
|
|
95
|
+
public async handleDownOrClose(): Promise<void> {
|
|
73
96
|
this.logInfo('closed blind.')
|
|
74
|
-
|
|
97
|
+
try {
|
|
98
|
+
// Send close command to SwitchBot OpenAPI
|
|
99
|
+
if (this.context?.sendOpenAPI) {
|
|
100
|
+
await this.sendOpenAPICommand('turnOff')
|
|
101
|
+
this.logInfo('OpenAPI close command sent.')
|
|
102
|
+
} else {
|
|
103
|
+
this.logWarn('OpenAPI sender not available in context.')
|
|
104
|
+
}
|
|
105
|
+
} catch (e: any) {
|
|
106
|
+
this.logWarn(`OpenAPI close failed: ${String(e?.message ?? e)}`)
|
|
107
|
+
}
|
|
75
108
|
}
|
|
76
109
|
|
|
77
|
-
|
|
110
|
+
public async handleStop(): Promise<void> {
|
|
78
111
|
this.logInfo('stopped blind.')
|
|
79
|
-
|
|
112
|
+
try {
|
|
113
|
+
// Send pause command to SwitchBot OpenAPI
|
|
114
|
+
if (this.context?.sendOpenAPI) {
|
|
115
|
+
await this.sendOpenAPICommand('pause')
|
|
116
|
+
this.logInfo('OpenAPI pause command sent.')
|
|
117
|
+
} else {
|
|
118
|
+
this.logWarn('OpenAPI sender not available in context.')
|
|
119
|
+
}
|
|
120
|
+
} catch (e: any) {
|
|
121
|
+
this.logWarn(`OpenAPI pause failed: ${String(e?.message ?? e)}`)
|
|
122
|
+
}
|
|
80
123
|
}
|
|
81
124
|
|
|
82
125
|
public updateLiftPosition(openPercent: number): void {
|
package/src/platform-matter.ts
CHANGED
|
@@ -2344,13 +2344,31 @@ export class SwitchBotMatterPlatform implements DynamicPlatformPlugin {
|
|
|
2344
2344
|
|
|
2345
2345
|
// Window Blind
|
|
2346
2346
|
if (this.config.enableWindowBlind !== false) {
|
|
2347
|
-
const device = new WindowBlindAccessory(this.api, this.log
|
|
2347
|
+
const device = new WindowBlindAccessory(this.api, this.log, {
|
|
2348
|
+
handlers: {
|
|
2349
|
+
windowCovering: {
|
|
2350
|
+
goToLiftPercentage: async request => device?.handleGoToLift?.(request),
|
|
2351
|
+
upOrOpen: async () => device?.handleUpOrOpen?.(),
|
|
2352
|
+
downOrClose: async () => device?.handleDownOrClose?.(),
|
|
2353
|
+
stopMotion: async () => device?.handleStop?.(),
|
|
2354
|
+
},
|
|
2355
|
+
},
|
|
2356
|
+
})
|
|
2348
2357
|
accessories.push(device.toAccessory())
|
|
2349
2358
|
}
|
|
2350
2359
|
|
|
2351
2360
|
// Venetian Blind
|
|
2352
2361
|
if (this.config.enableVenetianBlind !== false) {
|
|
2353
|
-
const device = new VenetianBlindAccessory(this.api, this.log
|
|
2362
|
+
const device = new VenetianBlindAccessory(this.api, this.log, {
|
|
2363
|
+
handlers: {
|
|
2364
|
+
windowCovering: {
|
|
2365
|
+
goToLiftPercentage: async request => device?.handleGoToLift?.(request),
|
|
2366
|
+
upOrOpen: async () => device?.handleUpOrOpen?.(),
|
|
2367
|
+
downOrClose: async () => device?.handleDownOrClose?.(),
|
|
2368
|
+
stopMotion: async () => device?.handleStop?.(),
|
|
2369
|
+
},
|
|
2370
|
+
},
|
|
2371
|
+
})
|
|
2354
2372
|
accessories.push(device.toAccessory())
|
|
2355
2373
|
}
|
|
2356
2374
|
|
package/src/settings.ts
CHANGED
|
@@ -88,11 +88,27 @@ export interface options {
|
|
|
88
88
|
* When false (default), reset at UTC midnight. Default: false.
|
|
89
89
|
*/
|
|
90
90
|
dailyApiResetAtLocalMidnight?: boolean
|
|
91
|
-
|
|
91
|
+
/**
|
|
92
|
+
* When true, resets the daily API request counter to zero. This is useful for testing purposes.
|
|
93
|
+
*/
|
|
94
|
+
resetDailyApiCounter?: boolean
|
|
95
|
+
/**
|
|
96
|
+
* When set, configures the batch refresh rate (in milliseconds) for Matter devices. Default: 5000 ms.
|
|
97
|
+
*/
|
|
92
98
|
matterBatchRefreshRate?: number
|
|
99
|
+
/**
|
|
100
|
+
* When true, enables batch processing for Matter devices. Default: false.
|
|
101
|
+
*/
|
|
93
102
|
matterBatchConcurrency?: number
|
|
103
|
+
/**
|
|
104
|
+
* When true, enables batch processing for Matter devices. Default: false.
|
|
105
|
+
*/
|
|
94
106
|
matterBatchEnabled?: boolean
|
|
107
|
+
/**
|
|
108
|
+
* When set, adds a random delay (jitter) to batch requests to avoid thundering herd problems.
|
|
109
|
+
*/
|
|
95
110
|
matterBatchJitter?: number
|
|
111
|
+
newFeatureEnabled?: boolean
|
|
96
112
|
};
|
|
97
113
|
|
|
98
114
|
export type devicesConfig = botConfig | relaySwitch1Config | relaySwitch1PMConfig | meterConfig | meterProConfig | indoorOutdoorSensorConfig | humidifierConfig | curtainConfig | blindTiltConfig | contactConfig | motionConfig | waterDetectorConfig | plugConfig | colorBulbConfig | stripLightConfig | ceilingLightConfig | lockConfig | hubConfig
|