Skip to content

Commit d88c0bf

Browse files
committed
Update PicoRemote.ts
1 parent ba30999 commit d88c0bf

1 file changed

Lines changed: 29 additions & 12 deletions

File tree

src/PicoRemote.ts

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ export class PicoRemote {
403403
const buttonNumber = this.hrefToButtonNumber.get(buttonHref)
404404
const alias = this.hrefToAlias.get(buttonHref)
405405

406-
// GenericSwitch path (Homebridge PR #3924): update switch position on button press.
406+
// Composed OnOffSwitch path: pulse onOff for the pressed part.
407407
if (
408408
this.matterApi
409409
&& buttonNumber !== undefined
@@ -415,17 +415,35 @@ export class PicoRemote {
415415

416416
if (hasComposedParts) {
417417
void this.matterApi
418-
.updateAccessoryState(this.accessory.UUID, 'switch', { currentPosition: 1 }, partId)
418+
.updateAccessoryState(this.accessory.UUID, 'onOff', { onOff: true }, partId)
419419
.catch((error: unknown) => {
420-
this.platform.log.debug(`[Matter] Failed to update composed switch part ${partId} for ${this.accessory.displayName}: ${String(error)}`)
420+
this.platform.log.debug(`[Matter] Failed to update composed onOff part ${partId} for ${this.accessory.displayName}: ${String(error)}`)
421421
})
422-
} else if ((this.accessory as any).clusters?.switch) {
422+
} else if ((this.accessory as any).clusters?.onOff) {
423423
void this.matterApi
424-
.updateAccessoryState(this.accessory.UUID, 'switch', { currentPosition: alias.index })
424+
.updateAccessoryState(this.accessory.UUID, 'onOff', { onOff: true })
425425
.catch((error: unknown) => {
426-
this.platform.log.debug(`[Matter] Failed to update switch position for ${this.accessory.displayName}: ${String(error)}`)
426+
this.platform.log.debug(`[Matter] Failed to update onOff state for ${this.accessory.displayName}: ${String(error)}`)
427427
})
428428
}
429+
430+
// Stateless behavior: clear the pressed state after a short pulse so the
431+
// button can be triggered repeatedly.
432+
setTimeout(() => {
433+
if (hasComposedParts) {
434+
void this.matterApi
435+
.updateAccessoryState(this.accessory.UUID, 'onOff', { onOff: false }, partId)
436+
.catch((error: unknown) => {
437+
this.platform.log.debug(`[Matter] Failed to clear composed onOff part ${partId} for ${this.accessory.displayName}: ${String(error)}`)
438+
})
439+
} else if ((this.accessory as any).clusters?.onOff) {
440+
void this.matterApi
441+
.updateAccessoryState(this.accessory.UUID, 'onOff', { onOff: false })
442+
.catch((error: unknown) => {
443+
this.platform.log.debug(`[Matter] Failed to clear onOff state for ${this.accessory.displayName}: ${String(error)}`)
444+
})
445+
}
446+
}, 250)
429447
}
430448
const fullName = this.accessory.context.device.FullyQualifiedName.join(' ')
431449
// Raw Press/Release event from the bridge — fires twice per physical
@@ -462,12 +480,12 @@ export class PicoRemote {
462480
return {}
463481
}
464482

465-
// Expose Pico remotes as composed Matter endpoints: one GenericSwitch-like
483+
// Expose Pico remotes as composed Matter endpoints: one OnOffSwitch-like
466484
// part per physical button. This aligns better with Home's separate button
467485
// presentation than a single multi-position switch endpoint.
468-
const partDeviceType = this.matterApi?.deviceTypes?.GenericSwitch
486+
const partDeviceType = this.matterApi?.deviceTypes?.OnOffSwitch
469487
if (!partDeviceType) {
470-
this.platform.log.warn(`[Matter] GenericSwitch deviceType is unavailable for '${type}', returning empty clusters.`)
488+
this.platform.log.warn(`[Matter] OnOffSwitch deviceType is unavailable for '${type}', returning empty clusters.`)
471489
return {}
472490
}
473491

@@ -479,9 +497,8 @@ export class PicoRemote {
479497
displayName: alias.label,
480498
deviceType: partDeviceType,
481499
clusters: {
482-
switch: {
483-
currentPosition: 0,
484-
numberOfPositions: 1,
500+
onOff: {
501+
onOff: false,
485502
},
486503
},
487504
}

0 commit comments

Comments
 (0)