Skip to content

Commit

Permalink
Update 01.02.2025 - 2 Fixes (#390)
Browse files Browse the repository at this point in the history
* DoorLock DoorState

* Fix Boost on Thermostat

* Other changes

* Readme
  • Loading branch information
Apollon77 authored Feb 1, 2025
1 parent 3402e46 commit ba9e8a6
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 11 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,12 @@ With the ioBroker Matter Adapter, it is possible to map the following use cases:
-->

## Changelog
### 0.4.12 (2025-02-01)

### __WORK IN PROGRESS__
* (@Apollon77) Added support for Door state feature for Devices and Controllers
* (@Apollon77) Fixed Thermostat creation with Boost state

### 0.4.12 (2025-02-01)
* (@GermanBluefox) Added the "copy to clipboard" button in the debug dialog
* (@Apollon77) Updated matter.js with performance and Memory usage optimizations (and Tasmota pairing workaround)
* (@Apollon77) Reworked Type detection in Backend and for Channel/Device detection type in UI, now multiple devicetypes are offered with most complex one pre-selected
Expand Down
4 changes: 2 additions & 2 deletions src-admin/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/lib/DeviceManagement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ class MatterAdapterDeviceManagement extends DeviceManagement<MatterAdapter> {
hasDetails: true,
actions: actions.length ? (actions as DeviceAction<'adapter'>[]) : undefined,
backgroundColor,
color: backgroundColor === 'primary' ? '#164477' : '#57BFFF',
color: '#FFFFFF',
group: {
key: 'node',
name: this.#adapter.getText('Node'),
Expand Down
10 changes: 8 additions & 2 deletions src/matter/to-iobroker/DoorLockToIoBroker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ export class DoorLockToIoBroker extends GenericElectricityDataDeviceToIoBroker {

this.#unboltingSupported =
this.appEndpoint.getClusterClient(DoorLock.Complete)?.supportedFeatures.unbolting ?? false;
// TODO: support more featuresets?
this.#ioBrokerDevice = new Lock(
{ ...ChannelDetector.getPatterns().lock, isIoBrokerDevice: false } as DetectedDevice,
adapter,
Expand Down Expand Up @@ -65,13 +64,20 @@ export class DoorLockToIoBroker extends GenericElectricityDataDeviceToIoBroker {
endpointId: this.appEndpoint.getNumber(),
clusterId: DoorLock.Cluster.id,
attributeName: 'lockState',
convertValue: value => value === DoorLock.LockState.Unlocked,
convertValue: (state: DoorLock.LockState | null) => state === DoorLock.LockState.Unlocked,
});
this.enableDeviceTypeStateForAttribute(PropertyType.Open, {
changeHandler: async () => {
await this.appEndpoint.getClusterClient(DoorLock.Complete)?.unlockDoor({});
},
});
this.enableDeviceTypeStateForAttribute(PropertyType.DoorState, {
endpointId: this.appEndpoint.getNumber(),
clusterId: DoorLock.Cluster.id,
attributeName: 'doorState',
convertValue: (state: DoorLock.DoorState | null) =>
state === DoorLock.DoorState.DoorOpen || state === DoorLock.DoorState.DoorForcedOpen,
});
return super.enableDeviceTypeStates();
}

Expand Down
4 changes: 2 additions & 2 deletions src/matter/to-iobroker/GenericDeviceToIoBroker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export interface EnabledAttributeProperty extends EnabledProperty {
attributeId?: AttributeId;
attributeName?: string;
convertValue?: (value: any) => MaybePromise<any>;
changeHandler?: (value: any) => Promise<void> | void;
changeHandler?: (value: any) => MaybePromise<void> | void;
pollAttribute?: boolean;
}

Expand Down Expand Up @@ -231,7 +231,7 @@ export abstract class GenericDeviceToIoBroker {
endpointId?: EndpointNumber;
clusterId?: ClusterId;
convertValue?: (value: any) => MaybePromise<any>;
changeHandler?: (value: any) => Promise<void> | void;
changeHandler?: (value: any) => MaybePromise<void> | void;
pollAttribute?: boolean;
} & ({ vendorSpecificAttributeId: AttributeId } | { attributeName?: string }),
): void {
Expand Down
33 changes: 30 additions & 3 deletions src/matter/to-matter/LockToMatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ const IoBrokerDoorLockDevice = DoorLockDevice.with(
);
type IoBrokerDoorLockDevice = typeof IoBrokerDoorLockDevice;

// TODO Add Latching support when "Open" is there!
//const DoorPositionDoorLockServer = EventedDoorLockServer.with(DoorLock.Feature.DoorPositionSensor);
//const UnboltingDoorLockServer = EventedDoorLockServer.with(DoorLock.Feature.Unbolting);

/** Mapping Logic to map a ioBroker Light device to a Matter OnOffLightDevice. */
export class LockToMatter extends GenericElectricityDataDeviceToMatter {
Expand All @@ -27,7 +28,18 @@ export class LockToMatter extends GenericElectricityDataDeviceToMatter {
constructor(ioBrokerDevice: Lock, name: string, uuid: string) {
super(name, uuid);

this.#matterEndpoint = new Endpoint(IoBrokerDoorLockDevice, {
this.#ioBrokerDevice = ioBrokerDevice;

const features = new Array<DoorLock.Feature>();

if (this.#ioBrokerDevice.hasOpen()) {
features.push(DoorLock.Feature.Unbolting);
}
if (this.#ioBrokerDevice.hasDoorState()) {
features.push(DoorLock.Feature.DoorPositionSensor);
}

this.#matterEndpoint = new Endpoint(IoBrokerDoorLockDevice.with(EventedDoorLockServer.with(...features)), {
id: uuid,
ioBrokerContext: {
device: ioBrokerDevice,
Expand All @@ -37,9 +49,10 @@ export class LockToMatter extends GenericElectricityDataDeviceToMatter {
lockType: DoorLock.LockType.Other,
actuatorEnabled: true,
lockState: DoorLock.LockState.Locked, // Will be corrected later
// @ts-expect-error Simplify state setting because of dynamic features
doorState: this.#ioBrokerDevice.hasDoorState() ? DoorLock.DoorState.DoorClosed : undefined,
},
});
this.#ioBrokerDevice = ioBrokerDevice;
}

get matterEndpoints(): Endpoint[] {
Expand All @@ -61,6 +74,14 @@ export class LockToMatter extends GenericElectricityDataDeviceToMatter {
: DoorLock.LockState.Locked,
},
});
if (this.#ioBrokerDevice.hasDoorState()) {
await this.#matterEndpoint.setStateOf(EventedDoorLockServer, {
// @ts-expect-error Workaround a matter.js instancing/typing error
doorState: this.#ioBrokerDevice.getDoorState()
? DoorLock.DoorState.DoorOpen
: DoorLock.DoorState.DoorClosed,
});
}

this.matterEvents.on(this.#matterEndpoint.events.ioBrokerEvents.doorLockStateControlled, async state => {
switch (state) {
Expand Down Expand Up @@ -92,6 +113,12 @@ export class LockToMatter extends GenericElectricityDataDeviceToMatter {
},
});
break;
case PropertyType.DoorState:
await this.#matterEndpoint.setStateOf(EventedDoorLockServer, {
// @ts-expect-error Workaround a matter.js instancing/typing error
doorState: event.value ? DoorLock.DoorState.DoorOpen : DoorLock.DoorState.DoorClosed,
});
break;
}
});
}
Expand Down
4 changes: 4 additions & 0 deletions src/matter/to-matter/ThermostatToMatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ export class ThermostatToMatter extends GenericDeviceToMatter {
),
{
id: `${uuid}-BoostOnOff`,
ioBrokerContext: {
device: ioBrokerDevice,
adapter: ioBrokerDevice.adapter,
},
},
);
}
Expand Down

0 comments on commit ba9e8a6

Please sign in to comment.