@matterbridge/core 3.10.8-dev-20260903-4ab4a0f → 3.10.8-dev-20260903-014e30e
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/dist/behaviors/export.d.ts +1 -0
- package/dist/behaviors/export.js +1 -0
- package/dist/behaviors/temperatureAlarmServer.d.ts +26 -0
- package/dist/behaviors/temperatureAlarmServer.js +96 -0
- package/dist/behaviors/windowCoveringServer.js +2 -1
- package/dist/chipTests.js +0 -8
- package/dist/demoDevices.js +4 -0
- package/dist/devices/dishwasher.d.ts +14 -2
- package/dist/devices/dishwasher.js +93 -3
- package/dist/devices/refrigerator.d.ts +2 -0
- package/dist/devices/refrigerator.js +8 -0
- package/dist/export.d.ts +1 -0
- package/dist/export.js +1 -0
- package/dist/frontend.js +2 -0
- package/dist/matterbridgeDeviceTypes.js +1 -0
- package/dist/matterbridgeEndpoint.d.ts +6 -4
- package/dist/matterbridgeEndpoint.js +26 -4
- package/dist/matterbridgeEndpointCommandHandler.d.ts +30 -0
- package/dist/matterbridgeEndpointHelpers.d.ts +1 -1
- package/dist/matterbridgeEndpointHelpers.js +10 -1
- package/package.json +5 -5
|
@@ -19,6 +19,7 @@ export * from './pumpConfigurationAndControlServer.js';
|
|
|
19
19
|
export * from './serviceAreaServer.js';
|
|
20
20
|
export * from './smokeCoAlarmServer.js';
|
|
21
21
|
export * from './switchServer.js';
|
|
22
|
+
export * from './temperatureAlarmServer.js';
|
|
22
23
|
export * from './thermostatServer.js';
|
|
23
24
|
export * from './valveConfigurationAndControlServer.js';
|
|
24
25
|
export * from './waterTankLevelMonitoringServer.js';
|
package/dist/behaviors/export.js
CHANGED
|
@@ -19,6 +19,7 @@ export * from './pumpConfigurationAndControlServer.js';
|
|
|
19
19
|
export * from './serviceAreaServer.js';
|
|
20
20
|
export * from './smokeCoAlarmServer.js';
|
|
21
21
|
export * from './switchServer.js';
|
|
22
|
+
export * from './temperatureAlarmServer.js';
|
|
22
23
|
export * from './thermostatServer.js';
|
|
23
24
|
export * from './valveConfigurationAndControlServer.js';
|
|
24
25
|
export * from './waterTankLevelMonitoringServer.js';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { MaybePromise } from '@matter/general';
|
|
2
|
+
import { TemperatureAlarmServer } from '@matter/node/behaviors/temperature-alarm';
|
|
3
|
+
import { TemperatureAlarm } from '@matter/types/clusters/temperature-alarm';
|
|
4
|
+
declare class TemperatureAlarmBaseServer extends TemperatureAlarmServer {
|
|
5
|
+
static readonly schema: import("@matter/model").ClusterModel;
|
|
6
|
+
}
|
|
7
|
+
declare const MatterbridgeTemperatureAlarmServer_base: import("@matter/node").ClusterBehavior.Type<typeof TemperatureAlarmBaseServer, import("@matter/types").ClusterType.WithSupportedFeatures<TemperatureAlarm, {
|
|
8
|
+
majorThreshold: false;
|
|
9
|
+
minorThreshold: false;
|
|
10
|
+
overCriticalAdjustable: false;
|
|
11
|
+
overMajorAdjustable: false;
|
|
12
|
+
overMinorAdjustable: false;
|
|
13
|
+
overTemperature: true;
|
|
14
|
+
reset: true;
|
|
15
|
+
underCriticalAdjustable: false;
|
|
16
|
+
underMajorAdjustable: false;
|
|
17
|
+
underMinorAdjustable: false;
|
|
18
|
+
underTemperature: true;
|
|
19
|
+
}>, import("@matter/types").ClusterType.Concrete, new () => {}, "temperatureAlarm">;
|
|
20
|
+
export declare class MatterbridgeTemperatureAlarmServer extends MatterbridgeTemperatureAlarmServer_base {
|
|
21
|
+
#private;
|
|
22
|
+
initialize(): MaybePromise;
|
|
23
|
+
reset(request: TemperatureAlarm.ResetRequest): Promise<void>;
|
|
24
|
+
modifyEnabledAlarms(request: TemperatureAlarm.ModifyEnabledAlarmsRequest): Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { AttributeElement, CommandElement, EventElement, FieldElement } from '@matter/model';
|
|
2
|
+
import { TemperatureAlarmServer } from '@matter/node/behaviors/temperature-alarm';
|
|
3
|
+
import { Status, StatusResponseError } from '@matter/types';
|
|
4
|
+
import { TemperatureAlarm } from '@matter/types/clusters/temperature-alarm';
|
|
5
|
+
import { debugStringify, nf } from 'node-ansi-logger';
|
|
6
|
+
import { MatterbridgeServer } from './matterbridgeServer.js';
|
|
7
|
+
const MatterbridgeTemperatureAlarmSchema = TemperatureAlarmServer.schema.extend({}, AttributeElement({ name: 'Mask', id: 0x0000, type: 'AlarmBitmap', access: 'R V', conformance: 'M' }), AttributeElement({ name: 'Latch', id: 0x0001, type: 'AlarmBitmap', access: 'R V', conformance: 'RESET', quality: 'F' }), AttributeElement({ name: 'State', id: 0x0002, type: 'AlarmBitmap', access: 'R V', conformance: 'M' }), AttributeElement({ name: 'Supported', id: 0x0003, type: 'AlarmBitmap', access: 'R V', conformance: 'M', quality: 'F' }), CommandElement({ name: 'Reset', id: 0x0000, access: 'O', conformance: 'RESET', direction: 'request', response: 'status' }, FieldElement({ name: 'Alarms', id: 0x0000, type: 'AlarmBitmap', conformance: 'M' })), CommandElement({ name: 'ModifyEnabledAlarms', id: 0x0001, access: 'O', conformance: 'O', direction: 'request', response: 'status' }, FieldElement({ name: 'Mask', id: 0x0000, type: 'AlarmBitmap', conformance: 'M' })), EventElement({ name: 'Notify', id: 0x0000, access: 'V', conformance: 'M', priority: 'info' }, FieldElement({ name: 'Active', id: 0x0000, type: 'AlarmBitmap', conformance: 'M' }), FieldElement({ name: 'Inactive', id: 0x0001, type: 'AlarmBitmap', conformance: 'M' }), FieldElement({ name: 'State', id: 0x0002, type: 'AlarmBitmap', conformance: 'M' }), FieldElement({ name: 'Mask', id: 0x0003, type: 'AlarmBitmap', conformance: 'M' })));
|
|
8
|
+
class TemperatureAlarmBaseServer extends TemperatureAlarmServer {
|
|
9
|
+
static schema = MatterbridgeTemperatureAlarmSchema;
|
|
10
|
+
}
|
|
11
|
+
export class MatterbridgeTemperatureAlarmServer extends TemperatureAlarmBaseServer.with(TemperatureAlarm.Feature.Reset, TemperatureAlarm.Feature.OverTemperature, TemperatureAlarm.Feature.UnderTemperature) {
|
|
12
|
+
initialize() {
|
|
13
|
+
this.reactTo(this.events.state$Changed, this.#emitNotify);
|
|
14
|
+
}
|
|
15
|
+
#emitNotify(state, oldState) {
|
|
16
|
+
const active = {
|
|
17
|
+
criticalOverTemperatureAlarm: Boolean(state.criticalOverTemperatureAlarm && !oldState.criticalOverTemperatureAlarm),
|
|
18
|
+
majorOverTemperatureAlarm: Boolean(state.majorOverTemperatureAlarm && !oldState.majorOverTemperatureAlarm),
|
|
19
|
+
minorOverTemperatureAlarm: Boolean(state.minorOverTemperatureAlarm && !oldState.minorOverTemperatureAlarm),
|
|
20
|
+
minorUnderTemperatureAlarm: Boolean(state.minorUnderTemperatureAlarm && !oldState.minorUnderTemperatureAlarm),
|
|
21
|
+
majorUnderTemperatureAlarm: Boolean(state.majorUnderTemperatureAlarm && !oldState.majorUnderTemperatureAlarm),
|
|
22
|
+
criticalUnderTemperatureAlarm: Boolean(state.criticalUnderTemperatureAlarm && !oldState.criticalUnderTemperatureAlarm),
|
|
23
|
+
};
|
|
24
|
+
const inactive = {
|
|
25
|
+
criticalOverTemperatureAlarm: Boolean(!state.criticalOverTemperatureAlarm && oldState.criticalOverTemperatureAlarm),
|
|
26
|
+
majorOverTemperatureAlarm: Boolean(!state.majorOverTemperatureAlarm && oldState.majorOverTemperatureAlarm),
|
|
27
|
+
minorOverTemperatureAlarm: Boolean(!state.minorOverTemperatureAlarm && oldState.minorOverTemperatureAlarm),
|
|
28
|
+
minorUnderTemperatureAlarm: Boolean(!state.minorUnderTemperatureAlarm && oldState.minorUnderTemperatureAlarm),
|
|
29
|
+
majorUnderTemperatureAlarm: Boolean(!state.majorUnderTemperatureAlarm && oldState.majorUnderTemperatureAlarm),
|
|
30
|
+
criticalUnderTemperatureAlarm: Boolean(!state.criticalUnderTemperatureAlarm && oldState.criticalUnderTemperatureAlarm),
|
|
31
|
+
};
|
|
32
|
+
this.events.notify.emit({ active, inactive, state, mask: this.state.mask }, this.context);
|
|
33
|
+
}
|
|
34
|
+
#assertAlarmsSupported(alarms, status) {
|
|
35
|
+
const unsupported = {
|
|
36
|
+
criticalOverTemperatureAlarm: Boolean(alarms.criticalOverTemperatureAlarm && !this.state.supported.criticalOverTemperatureAlarm),
|
|
37
|
+
majorOverTemperatureAlarm: Boolean(alarms.majorOverTemperatureAlarm && !this.state.supported.majorOverTemperatureAlarm),
|
|
38
|
+
minorOverTemperatureAlarm: Boolean(alarms.minorOverTemperatureAlarm && !this.state.supported.minorOverTemperatureAlarm),
|
|
39
|
+
minorUnderTemperatureAlarm: Boolean(alarms.minorUnderTemperatureAlarm && !this.state.supported.minorUnderTemperatureAlarm),
|
|
40
|
+
majorUnderTemperatureAlarm: Boolean(alarms.majorUnderTemperatureAlarm && !this.state.supported.majorUnderTemperatureAlarm),
|
|
41
|
+
criticalUnderTemperatureAlarm: Boolean(alarms.criticalUnderTemperatureAlarm && !this.state.supported.criticalUnderTemperatureAlarm),
|
|
42
|
+
};
|
|
43
|
+
if (Object.values(unsupported).some(Boolean)) {
|
|
44
|
+
throw new StatusResponseError(`MatterbridgeTemperatureAlarmServer: requested alarm is not supported (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`, status);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
#clearAlarms(alarms) {
|
|
48
|
+
return {
|
|
49
|
+
criticalOverTemperatureAlarm: Boolean(this.state.state.criticalOverTemperatureAlarm && !alarms.criticalOverTemperatureAlarm),
|
|
50
|
+
majorOverTemperatureAlarm: Boolean(this.state.state.majorOverTemperatureAlarm && !alarms.majorOverTemperatureAlarm),
|
|
51
|
+
minorOverTemperatureAlarm: Boolean(this.state.state.minorOverTemperatureAlarm && !alarms.minorOverTemperatureAlarm),
|
|
52
|
+
minorUnderTemperatureAlarm: Boolean(this.state.state.minorUnderTemperatureAlarm && !alarms.minorUnderTemperatureAlarm),
|
|
53
|
+
majorUnderTemperatureAlarm: Boolean(this.state.state.majorUnderTemperatureAlarm && !alarms.majorUnderTemperatureAlarm),
|
|
54
|
+
criticalUnderTemperatureAlarm: Boolean(this.state.state.criticalUnderTemperatureAlarm && !alarms.criticalUnderTemperatureAlarm),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
#applyMaskToState(mask) {
|
|
58
|
+
return {
|
|
59
|
+
criticalOverTemperatureAlarm: Boolean(this.state.state.criticalOverTemperatureAlarm && mask.criticalOverTemperatureAlarm),
|
|
60
|
+
majorOverTemperatureAlarm: Boolean(this.state.state.majorOverTemperatureAlarm && mask.majorOverTemperatureAlarm),
|
|
61
|
+
minorOverTemperatureAlarm: Boolean(this.state.state.minorOverTemperatureAlarm && mask.minorOverTemperatureAlarm),
|
|
62
|
+
minorUnderTemperatureAlarm: Boolean(this.state.state.minorUnderTemperatureAlarm && mask.minorUnderTemperatureAlarm),
|
|
63
|
+
majorUnderTemperatureAlarm: Boolean(this.state.state.majorUnderTemperatureAlarm && mask.majorUnderTemperatureAlarm),
|
|
64
|
+
criticalUnderTemperatureAlarm: Boolean(this.state.state.criticalUnderTemperatureAlarm && mask.criticalUnderTemperatureAlarm),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
async reset(request) {
|
|
68
|
+
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
69
|
+
device.log.info(`MatterbridgeTemperatureAlarmServer: resetting alarms ${debugStringify(request.alarms)}${nf} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
70
|
+
await device.commandHandler.executeHandler('TemperatureAlarm.reset', {
|
|
71
|
+
command: 'reset',
|
|
72
|
+
request,
|
|
73
|
+
cluster: MatterbridgeTemperatureAlarmServer.id,
|
|
74
|
+
attributes: this.state,
|
|
75
|
+
endpoint: this.endpoint,
|
|
76
|
+
context: this.context,
|
|
77
|
+
});
|
|
78
|
+
this.#assertAlarmsSupported(request.alarms, Status.Failure);
|
|
79
|
+
this.state.state = this.#clearAlarms(request.alarms);
|
|
80
|
+
}
|
|
81
|
+
async modifyEnabledAlarms(request) {
|
|
82
|
+
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
83
|
+
device.log.info(`MatterbridgeTemperatureAlarmServer: modifying enabled alarms ${debugStringify(request.mask)}${nf} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
84
|
+
await device.commandHandler.executeHandler('TemperatureAlarm.modifyEnabledAlarms', {
|
|
85
|
+
command: 'modifyEnabledAlarms',
|
|
86
|
+
request,
|
|
87
|
+
cluster: MatterbridgeTemperatureAlarmServer.id,
|
|
88
|
+
attributes: this.state,
|
|
89
|
+
endpoint: this.endpoint,
|
|
90
|
+
context: this.context,
|
|
91
|
+
});
|
|
92
|
+
this.#assertAlarmsSupported(request.mask, Status.InvalidCommand);
|
|
93
|
+
this.state.mask = request.mask;
|
|
94
|
+
this.state.state = this.#applyMaskToState(request.mask);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -32,7 +32,8 @@ export class MatterbridgeWindowCoveringServer extends WindowCoveringServer.with(
|
|
|
32
32
|
return current < target ? WindowCovering.MovementStatus.Closing : WindowCovering.MovementStatus.Opening;
|
|
33
33
|
}
|
|
34
34
|
#updateGlobalOperationalStatus() {
|
|
35
|
-
const
|
|
35
|
+
const lift = this.state.operationalStatus.lift ?? WindowCovering.MovementStatus.Stopped;
|
|
36
|
+
const tilt = this.state.operationalStatus.tilt ?? WindowCovering.MovementStatus.Stopped;
|
|
36
37
|
this.state.operationalStatus.global = lift === WindowCovering.MovementStatus.Stopped ? tilt : lift;
|
|
37
38
|
}
|
|
38
39
|
#startLiftMovement(targetPercent100ths) {
|
package/dist/chipTests.js
CHANGED
|
@@ -24,7 +24,6 @@ import { SmokeCoAlarm } from '@matter/types/clusters/smoke-co-alarm';
|
|
|
24
24
|
import { TariffPriceType, TariffUnit } from '@matter/types/globals';
|
|
25
25
|
import { MatterbridgeOccupancySensingServer } from './behaviors/occupancySensingServer.js';
|
|
26
26
|
import { cliEmitter } from './cliEmitter.js';
|
|
27
|
-
import { MatterbridgeRefrigeratorAlarmServer } from './devices/refrigerator.js';
|
|
28
27
|
import { MatterbridgeRvcOperationalStateServer, MatterbridgeRvcRunModeServer } from './devices/roboticVacuumCleaner.js';
|
|
29
28
|
import { MatterbridgeEndpoint } from './matterbridgeEndpoint.js';
|
|
30
29
|
const chipTestAppPipePath = '/tmp/matterbridge-chip-test-app-pipe';
|
|
@@ -1019,14 +1018,7 @@ async function handleChipTestAppPipeCommand(matterbridge, command) {
|
|
|
1019
1018
|
return;
|
|
1020
1019
|
case 'SetRefrigeratorDoorStatus': {
|
|
1021
1020
|
const doorOpen = Boolean(command.DoorOpen);
|
|
1022
|
-
const wasDoorOpen = Boolean(endpoint.stateOf(MatterbridgeRefrigeratorAlarmServer).state.doorOpen);
|
|
1023
1021
|
await endpoint.setCluster(RefrigeratorAlarm, { state: { doorOpen } }, matterbridge.log);
|
|
1024
|
-
await endpoint.triggerEvent('RefrigeratorAlarm', 'notify', {
|
|
1025
|
-
active: { doorOpen: doorOpen && !wasDoorOpen },
|
|
1026
|
-
inactive: { doorOpen: !doorOpen && wasDoorOpen },
|
|
1027
|
-
state: { doorOpen },
|
|
1028
|
-
mask: endpoint.stateOf(MatterbridgeRefrigeratorAlarmServer).mask,
|
|
1029
|
-
}, matterbridge.log);
|
|
1030
1022
|
matterbridge.log.info(`CHIP test app pipe set RefrigeratorAlarm.State.DoorOpen to ${doorOpen} on endpoint ${endpointId}`);
|
|
1031
1023
|
return;
|
|
1032
1024
|
}
|
package/dist/demoDevices.js
CHANGED
|
@@ -372,6 +372,10 @@ export async function createDemoDevices(matterbridge) {
|
|
|
372
372
|
ep.createDefaultPowerSourceBatteryClusterServer();
|
|
373
373
|
ep.createUserPinDoorLockClusterServer(DoorLock.LockState.Locked, DoorLock.LockType.DeadBolt, 0, 4, 10, 2, 3, 4);
|
|
374
374
|
await registerDevice(ep, 'Door Lock User PIN Schedules', 'ENTRY-08-01-2');
|
|
375
|
+
ep = new MatterbridgeEndpoint([getSupportedDeviceType('DoorLock'), bridgedNode, powerSource], { id: 'DoorLockUserPinExpiring', number: EndpointNumber(8_01_3) });
|
|
376
|
+
ep.createDefaultPowerSourceBatteryClusterServer();
|
|
377
|
+
ep.createUserPinDoorLockClusterServer(DoorLock.LockState.Locked, DoorLock.LockType.DeadBolt, 0, 4, 10, undefined, undefined, undefined, 10);
|
|
378
|
+
await registerDevice(ep, 'Door Lock User PIN Expiring', 'ENTRY-08-01-3');
|
|
375
379
|
ep = new MatterbridgeEndpoint([getSupportedDeviceType('DoorLockController'), bridgedNode, powerSource], { id: 'DoorLockController', number: EndpointNumber(8_02) });
|
|
376
380
|
await registerDevice(ep, 'Door Lock Controller', 'ENTRY-08-02');
|
|
377
381
|
ep = new MatterbridgeEndpoint([getSupportedDeviceType('WindowCovering'), bridgedNode, powerSource], { id: 'WindowCoveringLift', number: EndpointNumber(8_03) });
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import type { MaybePromise } from '@matter/general';
|
|
1
2
|
import { DishwasherAlarmServer } from '@matter/node/behaviors/dishwasher-alarm';
|
|
2
3
|
import { DishwasherModeServer } from '@matter/node/behaviors/dishwasher-mode';
|
|
3
|
-
import type
|
|
4
|
+
import { type EndpointNumber } from '@matter/types';
|
|
5
|
+
import { DishwasherAlarm } from '@matter/types/clusters/dishwasher-alarm';
|
|
4
6
|
import { DishwasherMode } from '@matter/types/clusters/dishwasher-mode';
|
|
5
7
|
import { ModeBase } from '@matter/types/clusters/mode-base';
|
|
6
8
|
import type { OperationalState } from '@matter/types/clusters/operational-state';
|
|
@@ -32,6 +34,16 @@ export declare class MatterbridgeDishwasherModeServer extends DishwasherModeServ
|
|
|
32
34
|
protected handleOnOffChange(onOff: boolean): void;
|
|
33
35
|
changeToMode(request: ModeBase.ChangeToModeRequest): Promise<ModeBase.ChangeToModeResponse>;
|
|
34
36
|
}
|
|
35
|
-
|
|
37
|
+
declare class DishwasherAlarmBaseServer extends DishwasherAlarmServer {
|
|
36
38
|
static readonly schema: import("@matter/model").ClusterModel;
|
|
37
39
|
}
|
|
40
|
+
declare const MatterbridgeDishwasherAlarmServer_base: import("@matter/node").ClusterBehavior.Type<typeof DishwasherAlarmBaseServer, import("@matter/types").ClusterType.WithSupportedFeatures<DishwasherAlarm, {
|
|
41
|
+
reset: true;
|
|
42
|
+
}>, import("@matter/types").ClusterType.Concrete, new () => {}, "dishwasherAlarm">;
|
|
43
|
+
export declare class MatterbridgeDishwasherAlarmServer extends MatterbridgeDishwasherAlarmServer_base {
|
|
44
|
+
#private;
|
|
45
|
+
initialize(): MaybePromise;
|
|
46
|
+
reset(request: DishwasherAlarm.ResetRequest): Promise<void>;
|
|
47
|
+
modifyEnabledAlarms(request: DishwasherAlarm.ModifyEnabledAlarmsRequest): Promise<void>;
|
|
48
|
+
}
|
|
49
|
+
export {};
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import { AttributeElement, EventElement, FieldElement } from '@matter/model';
|
|
1
|
+
import { AttributeElement, CommandElement, EventElement, FieldElement } from '@matter/model';
|
|
2
2
|
import { DishwasherAlarmServer } from '@matter/node/behaviors/dishwasher-alarm';
|
|
3
3
|
import { DishwasherModeServer } from '@matter/node/behaviors/dishwasher-mode';
|
|
4
|
+
import { Status, StatusResponseError } from '@matter/types';
|
|
5
|
+
import { DishwasherAlarm } from '@matter/types/clusters/dishwasher-alarm';
|
|
4
6
|
import { DishwasherMode } from '@matter/types/clusters/dishwasher-mode';
|
|
5
7
|
import { ModeBase } from '@matter/types/clusters/mode-base';
|
|
6
8
|
import { OnOff } from '@matter/types/clusters/on-off';
|
|
9
|
+
import { debugStringify, nf } from 'node-ansi-logger';
|
|
7
10
|
import { MatterbridgeServer } from '../behaviors/matterbridgeServer.js';
|
|
8
11
|
import { MatterbridgeOnOffServer } from '../behaviors/onOffServer.js';
|
|
9
12
|
import { dishwasher, powerSource } from '../matterbridgeDeviceTypes.js';
|
|
@@ -56,6 +59,7 @@ export class Dishwasher extends MatterbridgeEndpoint {
|
|
|
56
59
|
createDefaultDishwasherAlarmClusterServer() {
|
|
57
60
|
this.behaviors.require(MatterbridgeDishwasherAlarmServer, {
|
|
58
61
|
mask: { inflowError: false, drainError: false, doorError: true, tempTooLow: false, tempTooHigh: false, waterLevelError: false },
|
|
62
|
+
latch: { inflowError: false, drainError: false, doorError: false, tempTooLow: false, tempTooHigh: false, waterLevelError: false },
|
|
59
63
|
state: { inflowError: false, drainError: false, doorError: false, tempTooLow: false, tempTooHigh: false, waterLevelError: false },
|
|
60
64
|
supported: { inflowError: false, drainError: false, doorError: true, tempTooLow: false, tempTooHigh: false, waterLevelError: false },
|
|
61
65
|
});
|
|
@@ -98,7 +102,93 @@ export class MatterbridgeDishwasherModeServer extends DishwasherModeServer {
|
|
|
98
102
|
}
|
|
99
103
|
}
|
|
100
104
|
}
|
|
101
|
-
const MatterbridgeDishwasherAlarmSchema = DishwasherAlarmServer.schema.extend({}, AttributeElement({ name: 'Mask', id: 0x0000, type: 'AlarmBitmap', access: 'R V', conformance: 'M' }), AttributeElement({ name: 'State', id: 0x0002, type: 'AlarmBitmap', access: 'R V', conformance: 'M' }), AttributeElement({ name: 'Supported', id: 0x0003, type: 'AlarmBitmap', access: 'R V', conformance: 'M', quality: 'F' }), EventElement({ name: 'Notify', id: 0x0000, access: 'V', conformance: 'M', priority: 'info' }, FieldElement({ name: 'Active', id: 0x0000, type: 'AlarmBitmap', conformance: 'M' }), FieldElement({ name: 'Inactive', id: 0x0001, type: 'AlarmBitmap', conformance: 'M' }), FieldElement({ name: 'State', id: 0x0002, type: 'AlarmBitmap', conformance: 'M' }), FieldElement({ name: 'Mask', id: 0x0003, type: 'AlarmBitmap', conformance: 'M' })));
|
|
102
|
-
|
|
105
|
+
const MatterbridgeDishwasherAlarmSchema = DishwasherAlarmServer.schema.extend({}, AttributeElement({ name: 'Mask', id: 0x0000, type: 'AlarmBitmap', access: 'R V', conformance: 'M' }), AttributeElement({ name: 'Latch', id: 0x0001, type: 'AlarmBitmap', access: 'R V', conformance: 'RESET', quality: 'F' }), AttributeElement({ name: 'State', id: 0x0002, type: 'AlarmBitmap', access: 'R V', conformance: 'M' }), AttributeElement({ name: 'Supported', id: 0x0003, type: 'AlarmBitmap', access: 'R V', conformance: 'M', quality: 'F' }), CommandElement({ name: 'Reset', id: 0x0000, access: 'O', conformance: 'RESET', direction: 'request', response: 'status' }, FieldElement({ name: 'Alarms', id: 0x0000, type: 'AlarmBitmap', conformance: 'M' })), CommandElement({ name: 'ModifyEnabledAlarms', id: 0x0001, access: 'O', conformance: 'O', direction: 'request', response: 'status' }, FieldElement({ name: 'Mask', id: 0x0000, type: 'AlarmBitmap', conformance: 'M' })), EventElement({ name: 'Notify', id: 0x0000, access: 'V', conformance: 'M', priority: 'info' }, FieldElement({ name: 'Active', id: 0x0000, type: 'AlarmBitmap', conformance: 'M' }), FieldElement({ name: 'Inactive', id: 0x0001, type: 'AlarmBitmap', conformance: 'M' }), FieldElement({ name: 'State', id: 0x0002, type: 'AlarmBitmap', conformance: 'M' }), FieldElement({ name: 'Mask', id: 0x0003, type: 'AlarmBitmap', conformance: 'M' })));
|
|
106
|
+
class DishwasherAlarmBaseServer extends DishwasherAlarmServer {
|
|
103
107
|
static schema = MatterbridgeDishwasherAlarmSchema;
|
|
104
108
|
}
|
|
109
|
+
export class MatterbridgeDishwasherAlarmServer extends DishwasherAlarmBaseServer.with(DishwasherAlarm.Feature.Reset) {
|
|
110
|
+
initialize() {
|
|
111
|
+
this.reactTo(this.events.state$Changed, this.#emitNotify);
|
|
112
|
+
}
|
|
113
|
+
#emitNotify(state, oldState) {
|
|
114
|
+
const active = {
|
|
115
|
+
inflowError: Boolean(state.inflowError && !oldState.inflowError),
|
|
116
|
+
drainError: Boolean(state.drainError && !oldState.drainError),
|
|
117
|
+
doorError: Boolean(state.doorError && !oldState.doorError),
|
|
118
|
+
tempTooLow: Boolean(state.tempTooLow && !oldState.tempTooLow),
|
|
119
|
+
tempTooHigh: Boolean(state.tempTooHigh && !oldState.tempTooHigh),
|
|
120
|
+
waterLevelError: Boolean(state.waterLevelError && !oldState.waterLevelError),
|
|
121
|
+
};
|
|
122
|
+
const inactive = {
|
|
123
|
+
inflowError: Boolean(!state.inflowError && oldState.inflowError),
|
|
124
|
+
drainError: Boolean(!state.drainError && oldState.drainError),
|
|
125
|
+
doorError: Boolean(!state.doorError && oldState.doorError),
|
|
126
|
+
tempTooLow: Boolean(!state.tempTooLow && oldState.tempTooLow),
|
|
127
|
+
tempTooHigh: Boolean(!state.tempTooHigh && oldState.tempTooHigh),
|
|
128
|
+
waterLevelError: Boolean(!state.waterLevelError && oldState.waterLevelError),
|
|
129
|
+
};
|
|
130
|
+
this.events.notify.emit({ active, inactive, state, mask: this.state.mask }, this.context);
|
|
131
|
+
}
|
|
132
|
+
#assertAlarmsSupported(alarms, status) {
|
|
133
|
+
const unsupported = {
|
|
134
|
+
inflowError: Boolean(alarms.inflowError && !this.state.supported.inflowError),
|
|
135
|
+
drainError: Boolean(alarms.drainError && !this.state.supported.drainError),
|
|
136
|
+
doorError: Boolean(alarms.doorError && !this.state.supported.doorError),
|
|
137
|
+
tempTooLow: Boolean(alarms.tempTooLow && !this.state.supported.tempTooLow),
|
|
138
|
+
tempTooHigh: Boolean(alarms.tempTooHigh && !this.state.supported.tempTooHigh),
|
|
139
|
+
waterLevelError: Boolean(alarms.waterLevelError && !this.state.supported.waterLevelError),
|
|
140
|
+
};
|
|
141
|
+
if (Object.values(unsupported).some(Boolean)) {
|
|
142
|
+
throw new StatusResponseError(`MatterbridgeDishwasherAlarmServer: requested alarm is not supported (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`, status);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
#clearAlarms(alarms) {
|
|
146
|
+
return {
|
|
147
|
+
inflowError: Boolean(this.state.state.inflowError && !alarms.inflowError),
|
|
148
|
+
drainError: Boolean(this.state.state.drainError && !alarms.drainError),
|
|
149
|
+
doorError: Boolean(this.state.state.doorError && !alarms.doorError),
|
|
150
|
+
tempTooLow: Boolean(this.state.state.tempTooLow && !alarms.tempTooLow),
|
|
151
|
+
tempTooHigh: Boolean(this.state.state.tempTooHigh && !alarms.tempTooHigh),
|
|
152
|
+
waterLevelError: Boolean(this.state.state.waterLevelError && !alarms.waterLevelError),
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
#applyMaskToState(mask) {
|
|
156
|
+
return {
|
|
157
|
+
inflowError: Boolean(this.state.state.inflowError && mask.inflowError),
|
|
158
|
+
drainError: Boolean(this.state.state.drainError && mask.drainError),
|
|
159
|
+
doorError: Boolean(this.state.state.doorError && mask.doorError),
|
|
160
|
+
tempTooLow: Boolean(this.state.state.tempTooLow && mask.tempTooLow),
|
|
161
|
+
tempTooHigh: Boolean(this.state.state.tempTooHigh && mask.tempTooHigh),
|
|
162
|
+
waterLevelError: Boolean(this.state.state.waterLevelError && mask.waterLevelError),
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
async reset(request) {
|
|
166
|
+
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
167
|
+
device.log.info(`MatterbridgeDishwasherAlarmServer: resetting alarms ${debugStringify(request.alarms)}${nf} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
168
|
+
await device.commandHandler.executeHandler('DishwasherAlarm.reset', {
|
|
169
|
+
command: 'reset',
|
|
170
|
+
request,
|
|
171
|
+
cluster: MatterbridgeDishwasherAlarmServer.id,
|
|
172
|
+
attributes: this.state,
|
|
173
|
+
endpoint: this.endpoint,
|
|
174
|
+
context: this.context,
|
|
175
|
+
});
|
|
176
|
+
this.#assertAlarmsSupported(request.alarms, Status.Failure);
|
|
177
|
+
this.state.state = this.#clearAlarms(request.alarms);
|
|
178
|
+
}
|
|
179
|
+
async modifyEnabledAlarms(request) {
|
|
180
|
+
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
181
|
+
device.log.info(`MatterbridgeDishwasherAlarmServer: modifying enabled alarms ${debugStringify(request.mask)}${nf} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
182
|
+
await device.commandHandler.executeHandler('DishwasherAlarm.modifyEnabledAlarms', {
|
|
183
|
+
command: 'modifyEnabledAlarms',
|
|
184
|
+
request,
|
|
185
|
+
cluster: MatterbridgeDishwasherAlarmServer.id,
|
|
186
|
+
attributes: this.state,
|
|
187
|
+
endpoint: this.endpoint,
|
|
188
|
+
context: this.context,
|
|
189
|
+
});
|
|
190
|
+
this.#assertAlarmsSupported(request.mask, Status.InvalidCommand);
|
|
191
|
+
this.state.mask = request.mask;
|
|
192
|
+
this.state.state = this.#applyMaskToState(request.mask);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
@@ -38,5 +38,7 @@ export declare class MatterbridgeRefrigeratorAndTemperatureControlledCabinetMode
|
|
|
38
38
|
changeToMode(request: ModeBase.ChangeToModeRequest): MaybePromise<ModeBase.ChangeToModeResponse>;
|
|
39
39
|
}
|
|
40
40
|
export declare class MatterbridgeRefrigeratorAlarmServer extends RefrigeratorAlarmServer {
|
|
41
|
+
#private;
|
|
41
42
|
static readonly schema: import("@matter/model").ClusterModel;
|
|
43
|
+
initialize(): MaybePromise;
|
|
42
44
|
}
|
|
@@ -100,4 +100,12 @@ export class MatterbridgeRefrigeratorAndTemperatureControlledCabinetModeServer e
|
|
|
100
100
|
const MatterbridgeRefrigeratorAlarmSchema = RefrigeratorAlarmServer.schema.extend({}, AttributeElement({ name: 'Mask', id: 0x0000, type: 'AlarmBitmap', access: 'R V', conformance: 'M' }), AttributeElement({ name: 'State', id: 0x0002, type: 'AlarmBitmap', access: 'R V', conformance: 'M' }), AttributeElement({ name: 'Supported', id: 0x0003, type: 'AlarmBitmap', access: 'R V', conformance: 'M', quality: 'F' }), EventElement({ name: 'Notify', id: 0x0000, access: 'V', conformance: 'M', priority: 'info' }, FieldElement({ name: 'Active', id: 0x0000, type: 'AlarmBitmap', conformance: 'M' }), FieldElement({ name: 'Inactive', id: 0x0001, type: 'AlarmBitmap', conformance: 'M' }), FieldElement({ name: 'State', id: 0x0002, type: 'AlarmBitmap', conformance: 'M' }), FieldElement({ name: 'Mask', id: 0x0003, type: 'AlarmBitmap', conformance: 'M' })));
|
|
101
101
|
export class MatterbridgeRefrigeratorAlarmServer extends RefrigeratorAlarmServer {
|
|
102
102
|
static schema = MatterbridgeRefrigeratorAlarmSchema;
|
|
103
|
+
initialize() {
|
|
104
|
+
this.reactTo(this.events.state$Changed, this.#emitNotify);
|
|
105
|
+
}
|
|
106
|
+
#emitNotify(state, oldState) {
|
|
107
|
+
const active = { doorOpen: Boolean(state.doorOpen && !oldState.doorOpen) };
|
|
108
|
+
const inactive = { doorOpen: Boolean(!state.doorOpen && oldState.doorOpen) };
|
|
109
|
+
this.events.notify.emit({ active, inactive, state, mask: this.state.mask }, this.context);
|
|
110
|
+
}
|
|
103
111
|
}
|
package/dist/export.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ export * from './behaviors/smokeCoAlarmServer.js';
|
|
|
19
19
|
export * from './behaviors/switchServer.js';
|
|
20
20
|
export * from './behaviors/thermostatServer.js';
|
|
21
21
|
export * from './behaviors/valveConfigurationAndControlServer.js';
|
|
22
|
+
export * from './behaviors/temperatureAlarmServer.js';
|
|
22
23
|
export * from './behaviors/waterTankLevelMonitoringServer.js';
|
|
23
24
|
export * from './behaviors/windowCoveringServer.js';
|
|
24
25
|
export { addVirtualDevice } from './helpers.js';
|
package/dist/export.js
CHANGED
|
@@ -21,6 +21,7 @@ export * from './behaviors/smokeCoAlarmServer.js';
|
|
|
21
21
|
export * from './behaviors/switchServer.js';
|
|
22
22
|
export * from './behaviors/thermostatServer.js';
|
|
23
23
|
export * from './behaviors/valveConfigurationAndControlServer.js';
|
|
24
|
+
export * from './behaviors/temperatureAlarmServer.js';
|
|
24
25
|
export * from './behaviors/waterTankLevelMonitoringServer.js';
|
|
25
26
|
export * from './behaviors/windowCoveringServer.js';
|
|
26
27
|
export { addVirtualDevice } from './helpers.js';
|
package/dist/frontend.js
CHANGED
|
@@ -1202,6 +1202,8 @@ export class Frontend extends EventEmitter {
|
|
|
1202
1202
|
attributes += `Carbon filter: ${attributeValue}% `;
|
|
1203
1203
|
if (clusterName === 'waterTankLevelMonitoring' && attributeName === 'condition')
|
|
1204
1204
|
attributes += `Water tank: ${attributeValue}% `;
|
|
1205
|
+
if (clusterName === 'temperatureAlarm' && attributeName === 'state' && isValidObject(attributeValue))
|
|
1206
|
+
attributes += `Temp alarm: ${stringify(attributeValue)} `;
|
|
1205
1207
|
if (clusterName === 'occupancySensing' && attributeName === 'occupancy' && isValidObject(attributeValue, 1))
|
|
1206
1208
|
attributes += `Occupancy: ${attributeValue.occupied} `;
|
|
1207
1209
|
if (clusterName === 'illuminanceMeasurement' && attributeName === 'measuredValue') {
|
|
@@ -18,6 +18,7 @@ import { PowerTopology } from '@matter/types/clusters/power-topology';
|
|
|
18
18
|
import { PumpConfigurationAndControl } from '@matter/types/clusters/pump-configuration-and-control';
|
|
19
19
|
import { ResourceMonitoring } from '@matter/types/clusters/resource-monitoring';
|
|
20
20
|
import { SmokeCoAlarm } from '@matter/types/clusters/smoke-co-alarm';
|
|
21
|
+
import type { TemperatureAlarm } from '@matter/types/clusters/temperature-alarm';
|
|
21
22
|
import { Thermostat } from '@matter/types/clusters/thermostat';
|
|
22
23
|
import { ThermostatUserInterfaceConfiguration } from '@matter/types/clusters/thermostat-user-interface-configuration';
|
|
23
24
|
import { ValveConfigurationAndControl } from '@matter/types/clusters/valve-configuration-and-control';
|
|
@@ -119,9 +120,9 @@ export declare class MatterbridgeEndpoint extends Endpoint {
|
|
|
119
120
|
addCommandHandler<C extends CommandHandlers>(command: C, handler: CommandHandlerFunction<C>): this;
|
|
120
121
|
removeCommandHandler<C extends CommandHandlers>(command: C, handler: CommandHandlerFunction<C>): this;
|
|
121
122
|
executeCommandHandler<C extends CommandHandlers>(command: C, request: CommandHandlerData<C>['request'], cluster: CommandHandlerData<C>['cluster'], attributes: CommandHandlerData<C>['attributes'], endpoint: CommandHandlerData<C>['endpoint']): Promise<CommandHandlerExecutionResult<C>>;
|
|
122
|
-
invokeBehaviorCommand<T extends Behavior.Type, C extends BehaviorCommandName<T>>(cluster: T, command: C, params?: BehaviorCommandParams<T, C
|
|
123
|
-
invokeBehaviorCommand<T extends ClusterType, C extends ClusterCommandName<T>>(cluster: T, command: C, params?: ClusterCommandParams<T, C
|
|
124
|
-
invokeBehaviorCommand(cluster: ClusterId | string, command: CommandHandlers, params?: Record<string, boolean | number | bigint | string | object | null
|
|
123
|
+
invokeBehaviorCommand<T extends Behavior.Type, C extends BehaviorCommandName<T>>(cluster: T, command: C, params?: BehaviorCommandParams<T, C>, waiterCondition?: () => boolean): Promise<void>;
|
|
124
|
+
invokeBehaviorCommand<T extends ClusterType, C extends ClusterCommandName<T>>(cluster: T, command: C, params?: ClusterCommandParams<T, C>, waiterCondition?: () => boolean): Promise<void>;
|
|
125
|
+
invokeBehaviorCommand(cluster: ClusterId | string, command: CommandHandlers, params?: Record<string, boolean | number | bigint | string | object | null>, waiterCondition?: () => boolean): Promise<void>;
|
|
125
126
|
addRequiredClusters(): MatterbridgeEndpoint;
|
|
126
127
|
addRequiredClusterServers(): MatterbridgeEndpoint;
|
|
127
128
|
addOptionalClusterServers(): MatterbridgeEndpoint;
|
|
@@ -207,9 +208,10 @@ export declare class MatterbridgeEndpoint extends Endpoint {
|
|
|
207
208
|
}, airflowDirection?: FanControl.AirflowDirection): this;
|
|
208
209
|
createDefaultHepaFilterMonitoringClusterServer(condition?: number, changeIndication?: ResourceMonitoring.ChangeIndication, inPlaceIndicator?: boolean | undefined, lastChangedTime?: number | null | undefined, replacementProductList?: ResourceMonitoring.ReplacementProduct[]): this;
|
|
209
210
|
createDefaultActivatedCarbonFilterMonitoringClusterServer(condition?: number, changeIndication?: ResourceMonitoring.ChangeIndication, inPlaceIndicator?: boolean | undefined, lastChangedTime?: number | null | undefined, replacementProductList?: ResourceMonitoring.ReplacementProduct[]): this;
|
|
211
|
+
createDefaultTemperatureAlarmClusterServer(criticalOverTemperatureThreshold?: number, criticalUnderTemperatureThreshold?: number, supported?: TemperatureAlarm.Alarm, mask?: TemperatureAlarm.Alarm, latch?: TemperatureAlarm.Alarm, state?: TemperatureAlarm.Alarm): this;
|
|
210
212
|
createDefaultWaterTankLevelMonitoringClusterServer(condition?: number, changeIndication?: ResourceMonitoring.ChangeIndication, inPlaceIndicator?: boolean | undefined, lastChangedTime?: number | null | undefined, replacementProductList?: ResourceMonitoring.ReplacementProduct[]): this;
|
|
211
213
|
createDefaultDoorLockClusterServer(lockState?: DoorLock.LockState, lockType?: DoorLock.LockType, autoRelockTime?: number, numberOfWeekDaySchedulesSupportedPerUser?: number, numberOfYearDaySchedulesSupportedPerUser?: number, numberOfHolidaySchedulesSupported?: number): this;
|
|
212
|
-
createUserPinDoorLockClusterServer(lockState?: DoorLock.LockState, lockType?: DoorLock.LockType, autoRelockTime?: number, minPinCodeLength?: number, maxPinCodeLength?: number, numberOfWeekDaySchedulesSupportedPerUser?: number, numberOfYearDaySchedulesSupportedPerUser?: number, numberOfHolidaySchedulesSupported?: number): this;
|
|
214
|
+
createUserPinDoorLockClusterServer(lockState?: DoorLock.LockState, lockType?: DoorLock.LockType, autoRelockTime?: number, minPinCodeLength?: number, maxPinCodeLength?: number, numberOfWeekDaySchedulesSupportedPerUser?: number, numberOfYearDaySchedulesSupportedPerUser?: number, numberOfHolidaySchedulesSupported?: number, expiringUserTimeout?: number, numberOfRfidUsersSupported?: number, minRfidCodeLength?: number, maxRfidCodeLength?: number): this;
|
|
213
215
|
createDefaultModeSelectClusterServer(description: string, supportedModes: ModeSelect.ModeOption[], currentMode?: number, startUpMode?: number): this;
|
|
214
216
|
createDefaultValveConfigurationAndControlClusterServer(valveState?: ValveConfigurationAndControl.ValveState, valveLevel?: number, movementDuration?: number, autoClose?: boolean): this;
|
|
215
217
|
createDefaultPumpConfigurationAndControlClusterServer(pumpMode?: PumpConfigurationAndControl.OperationMode, maxPressure?: number | null, maxSpeed?: number | null, maxFlow?: number | null, minConstSpeed?: number | null, maxConstSpeed?: number | null, speed?: number | null): this;
|
|
@@ -79,6 +79,7 @@ import { MatterbridgePowerSourceServer } from './behaviors/powerSourceServer.js'
|
|
|
79
79
|
import { MatterbridgePumpConfigurationAndControlServer } from './behaviors/pumpConfigurationAndControlServer.js';
|
|
80
80
|
import { MatterbridgeSmokeCoAlarmServer } from './behaviors/smokeCoAlarmServer.js';
|
|
81
81
|
import { MatterbridgeSwitchServer } from './behaviors/switchServer.js';
|
|
82
|
+
import { MatterbridgeTemperatureAlarmServer } from './behaviors/temperatureAlarmServer.js';
|
|
82
83
|
import { MatterbridgeThermostatServer } from './behaviors/thermostatServer.js';
|
|
83
84
|
import { MatterbridgeValveConfigurationAndControlServer } from './behaviors/valveConfigurationAndControlServer.js';
|
|
84
85
|
import { MatterbridgeWaterTankLevelMonitoringServer } from './behaviors/waterTankLevelMonitoringServer.js';
|
|
@@ -278,8 +279,8 @@ export class MatterbridgeEndpoint extends Endpoint {
|
|
|
278
279
|
async executeCommandHandler(command, request, cluster, attributes, endpoint) {
|
|
279
280
|
return this.commandHandler.executeHandler(command, { command, request, cluster, attributes, endpoint });
|
|
280
281
|
}
|
|
281
|
-
async invokeBehaviorCommand(cluster, command, params) {
|
|
282
|
-
await invokeBehaviorCommand(this, cluster, command, params);
|
|
282
|
+
async invokeBehaviorCommand(cluster, command, params, waiterCondition) {
|
|
283
|
+
await invokeBehaviorCommand(this, cluster, command, params, waiterCondition);
|
|
283
284
|
}
|
|
284
285
|
addRequiredClusters() {
|
|
285
286
|
addRequiredClusterServers(this);
|
|
@@ -1285,6 +1286,25 @@ export class MatterbridgeEndpoint extends Endpoint {
|
|
|
1285
1286
|
});
|
|
1286
1287
|
return this;
|
|
1287
1288
|
}
|
|
1289
|
+
createDefaultTemperatureAlarmClusterServer(criticalOverTemperatureThreshold = 60 * 100, criticalUnderTemperatureThreshold = -10 * 100, supported = { criticalOverTemperatureAlarm: true, criticalUnderTemperatureAlarm: true }, mask = supported, latch = {}, state = {}) {
|
|
1290
|
+
const bitmap = (alarm) => ({
|
|
1291
|
+
criticalOverTemperatureAlarm: Boolean(alarm.criticalOverTemperatureAlarm),
|
|
1292
|
+
majorOverTemperatureAlarm: false,
|
|
1293
|
+
minorOverTemperatureAlarm: false,
|
|
1294
|
+
minorUnderTemperatureAlarm: false,
|
|
1295
|
+
majorUnderTemperatureAlarm: false,
|
|
1296
|
+
criticalUnderTemperatureAlarm: Boolean(alarm.criticalUnderTemperatureAlarm),
|
|
1297
|
+
});
|
|
1298
|
+
this.behaviors.require(MatterbridgeTemperatureAlarmServer, {
|
|
1299
|
+
criticalOverTemperatureThreshold,
|
|
1300
|
+
criticalUnderTemperatureThreshold,
|
|
1301
|
+
latch: bitmap(latch),
|
|
1302
|
+
supported: bitmap(supported),
|
|
1303
|
+
mask: bitmap(mask),
|
|
1304
|
+
state: bitmap(state),
|
|
1305
|
+
});
|
|
1306
|
+
return this;
|
|
1307
|
+
}
|
|
1288
1308
|
createDefaultWaterTankLevelMonitoringClusterServer(condition = 100, changeIndication = ResourceMonitoring.ChangeIndication.Ok, inPlaceIndicator = true, lastChangedTime = null, replacementProductList = []) {
|
|
1289
1309
|
this.behaviors.require(MatterbridgeWaterTankLevelMonitoringServer.with(ResourceMonitoring.Feature.Condition, ResourceMonitoring.Feature.Warning, ResourceMonitoring.Feature.ReplacementProductList), {
|
|
1290
1310
|
condition,
|
|
@@ -1313,8 +1333,8 @@ export class MatterbridgeEndpoint extends Endpoint {
|
|
|
1313
1333
|
});
|
|
1314
1334
|
return this;
|
|
1315
1335
|
}
|
|
1316
|
-
createUserPinDoorLockClusterServer(lockState = DoorLock.LockState.Locked, lockType = DoorLock.LockType.DeadBolt, autoRelockTime = 0, minPinCodeLength = 4, maxPinCodeLength = 10, numberOfWeekDaySchedulesSupportedPerUser, numberOfYearDaySchedulesSupportedPerUser, numberOfHolidaySchedulesSupported) {
|
|
1317
|
-
this.behaviors.require(MatterbridgeDoorLockServer.with(DoorLock.Feature.User, DoorLock.Feature.PinCredential, ...(numberOfWeekDaySchedulesSupportedPerUser !== undefined ? [DoorLock.Feature.WeekDayAccessSchedules] : []), ...(numberOfYearDaySchedulesSupportedPerUser !== undefined ? [DoorLock.Feature.YearDayAccessSchedules] : []), ...(numberOfHolidaySchedulesSupported !== undefined ? [DoorLock.Feature.HolidaySchedules] : [])).enable({
|
|
1336
|
+
createUserPinDoorLockClusterServer(lockState = DoorLock.LockState.Locked, lockType = DoorLock.LockType.DeadBolt, autoRelockTime = 0, minPinCodeLength = 4, maxPinCodeLength = 10, numberOfWeekDaySchedulesSupportedPerUser, numberOfYearDaySchedulesSupportedPerUser, numberOfHolidaySchedulesSupported, expiringUserTimeout, numberOfRfidUsersSupported, minRfidCodeLength = 8, maxRfidCodeLength = 20) {
|
|
1337
|
+
this.behaviors.require(MatterbridgeDoorLockServer.with(DoorLock.Feature.User, DoorLock.Feature.PinCredential, ...(numberOfWeekDaySchedulesSupportedPerUser !== undefined ? [DoorLock.Feature.WeekDayAccessSchedules] : []), ...(numberOfYearDaySchedulesSupportedPerUser !== undefined ? [DoorLock.Feature.YearDayAccessSchedules] : []), ...(numberOfHolidaySchedulesSupported !== undefined ? [DoorLock.Feature.HolidaySchedules] : []), ...(numberOfRfidUsersSupported !== undefined ? [DoorLock.Feature.RfidCredential] : [])).enable({
|
|
1318
1338
|
events: { doorLockAlarm: true, lockOperation: true, lockOperationError: true },
|
|
1319
1339
|
commands: { lockDoor: true, unlockDoor: true, unlockWithTimeout: true },
|
|
1320
1340
|
}), {
|
|
@@ -1332,9 +1352,11 @@ export class MatterbridgeEndpoint extends Endpoint {
|
|
|
1332
1352
|
numberOfTotalUsersSupported: 10,
|
|
1333
1353
|
credentialRulesSupport: { single: true },
|
|
1334
1354
|
numberOfCredentialsSupportedPerUser: 10,
|
|
1355
|
+
...(expiringUserTimeout !== undefined ? { expiringUserTimeout } : {}),
|
|
1335
1356
|
...(numberOfWeekDaySchedulesSupportedPerUser !== undefined ? { numberOfWeekDaySchedulesSupportedPerUser } : {}),
|
|
1336
1357
|
...(numberOfYearDaySchedulesSupportedPerUser !== undefined ? { numberOfYearDaySchedulesSupportedPerUser } : {}),
|
|
1337
1358
|
...(numberOfHolidaySchedulesSupported !== undefined ? { numberOfHolidaySchedulesSupported } : {}),
|
|
1359
|
+
...(numberOfRfidUsersSupported !== undefined ? { numberOfRfidUsersSupported, minRfidCodeLength, maxRfidCodeLength } : {}),
|
|
1338
1360
|
});
|
|
1339
1361
|
return this;
|
|
1340
1362
|
}
|
|
@@ -8,6 +8,7 @@ import type { CommodityPrice } from '@matter/types/clusters/commodity-price';
|
|
|
8
8
|
import type { CommodityTariff } from '@matter/types/clusters/commodity-tariff';
|
|
9
9
|
import type { DeviceEnergyManagement } from '@matter/types/clusters/device-energy-management';
|
|
10
10
|
import type { DeviceEnergyManagementMode } from '@matter/types/clusters/device-energy-management-mode';
|
|
11
|
+
import type { DishwasherAlarm } from '@matter/types/clusters/dishwasher-alarm';
|
|
11
12
|
import type { DishwasherMode } from '@matter/types/clusters/dishwasher-mode';
|
|
12
13
|
import type { DoorLock } from '@matter/types/clusters/door-lock';
|
|
13
14
|
import type { EnergyEvse } from '@matter/types/clusters/energy-evse';
|
|
@@ -30,6 +31,7 @@ import type { RvcOperationalState } from '@matter/types/clusters/rvc-operational
|
|
|
30
31
|
import type { RvcRunMode } from '@matter/types/clusters/rvc-run-mode';
|
|
31
32
|
import type { ServiceArea } from '@matter/types/clusters/service-area';
|
|
32
33
|
import type { SmokeCoAlarm } from '@matter/types/clusters/smoke-co-alarm';
|
|
34
|
+
import type { TemperatureAlarm } from '@matter/types/clusters/temperature-alarm';
|
|
33
35
|
import type { TemperatureControl } from '@matter/types/clusters/temperature-control';
|
|
34
36
|
import type { Thermostat } from '@matter/types/clusters/thermostat';
|
|
35
37
|
import type { ThreadNetworkDiagnostics } from '@matter/types/clusters/thread-network-diagnostics';
|
|
@@ -674,6 +676,34 @@ export type CommandHandlerDataMap = {
|
|
|
674
676
|
attributes: ClusterAttributeValues<(typeof SmokeCoAlarm)['attributes']>;
|
|
675
677
|
endpoint: MatterbridgeEndpoint;
|
|
676
678
|
};
|
|
679
|
+
'DishwasherAlarm.reset': {
|
|
680
|
+
command: 'reset';
|
|
681
|
+
request: DishwasherAlarm.ResetRequest;
|
|
682
|
+
cluster: 'dishwasherAlarm';
|
|
683
|
+
attributes: ClusterAttributeValues<(typeof DishwasherAlarm)['attributes']>;
|
|
684
|
+
endpoint: MatterbridgeEndpoint;
|
|
685
|
+
};
|
|
686
|
+
'DishwasherAlarm.modifyEnabledAlarms': {
|
|
687
|
+
command: 'modifyEnabledAlarms';
|
|
688
|
+
request: DishwasherAlarm.ModifyEnabledAlarmsRequest;
|
|
689
|
+
cluster: 'dishwasherAlarm';
|
|
690
|
+
attributes: ClusterAttributeValues<(typeof DishwasherAlarm)['attributes']>;
|
|
691
|
+
endpoint: MatterbridgeEndpoint;
|
|
692
|
+
};
|
|
693
|
+
'TemperatureAlarm.reset': {
|
|
694
|
+
command: 'reset';
|
|
695
|
+
request: TemperatureAlarm.ResetRequest;
|
|
696
|
+
cluster: 'temperatureAlarm';
|
|
697
|
+
attributes: ClusterAttributeValues<(typeof TemperatureAlarm)['attributes']>;
|
|
698
|
+
endpoint: MatterbridgeEndpoint;
|
|
699
|
+
};
|
|
700
|
+
'TemperatureAlarm.modifyEnabledAlarms': {
|
|
701
|
+
command: 'modifyEnabledAlarms';
|
|
702
|
+
request: TemperatureAlarm.ModifyEnabledAlarmsRequest;
|
|
703
|
+
cluster: 'temperatureAlarm';
|
|
704
|
+
attributes: ClusterAttributeValues<(typeof TemperatureAlarm)['attributes']>;
|
|
705
|
+
endpoint: MatterbridgeEndpoint;
|
|
706
|
+
};
|
|
677
707
|
'resetCounts': CommandHandlerData<'ThreadNetworkDiagnostics.resetCounts'>;
|
|
678
708
|
'ThreadNetworkDiagnostics.resetCounts': {
|
|
679
709
|
command: 'resetCounts';
|
|
@@ -41,7 +41,7 @@ export declare function getBehaviourTypesFromClusterClientIds(clusterClientList:
|
|
|
41
41
|
export declare function getBehaviourTypeFromClusterServerId(clusterId: ClusterId): Behavior.Type | undefined;
|
|
42
42
|
export declare function getBehaviourTypeFromClusterClientId(clusterId: ClusterId): ClusterBehavior.Type | undefined;
|
|
43
43
|
export declare function getBehavior(endpoint: MatterbridgeEndpoint, cluster: Behavior.Type | ClusterType | ClusterId | string): Behavior.Type | undefined;
|
|
44
|
-
export declare function invokeBehaviorCommand(endpoint: MatterbridgeEndpoint, cluster: Behavior.Type | ClusterType | ClusterId | string, command: CommandHandlers, params?: Record<string, boolean | number | bigint | string | object | null
|
|
44
|
+
export declare function invokeBehaviorCommand(endpoint: MatterbridgeEndpoint, cluster: Behavior.Type | ClusterType | ClusterId | string, command: CommandHandlers, params?: Record<string, boolean | number | bigint | string | object | null>, waiterCondition?: () => boolean): Promise<boolean>;
|
|
45
45
|
export declare function invokeSubscribeHandler(endpoint: MatterbridgeEndpoint, cluster: Behavior.Type | ClusterType | ClusterId | string, attribute: string, newValue: unknown, oldValue: unknown): Promise<boolean>;
|
|
46
46
|
export declare function addRequiredClusterServers(endpoint: MatterbridgeEndpoint): void;
|
|
47
47
|
export declare function addOptionalClusterServers(endpoint: MatterbridgeEndpoint): void;
|
|
@@ -99,6 +99,7 @@ import { ScenesManagement } from '@matter/types/clusters/scenes-management';
|
|
|
99
99
|
import { SmokeCoAlarm } from '@matter/types/clusters/smoke-co-alarm';
|
|
100
100
|
import { SoilMeasurement } from '@matter/types/clusters/soil-measurement';
|
|
101
101
|
import { Switch } from '@matter/types/clusters/switch';
|
|
102
|
+
import { TemperatureAlarm } from '@matter/types/clusters/temperature-alarm';
|
|
102
103
|
import { TemperatureMeasurement } from '@matter/types/clusters/temperature-measurement';
|
|
103
104
|
import { Thermostat } from '@matter/types/clusters/thermostat';
|
|
104
105
|
import { ThermostatUserInterfaceConfiguration } from '@matter/types/clusters/thermostat-user-interface-configuration';
|
|
@@ -112,6 +113,7 @@ import { MeasurementType } from '@matter/types/globals';
|
|
|
112
113
|
import { deepEqual } from '@matterbridge/utils/deep-equal';
|
|
113
114
|
import { logModuleLoaded } from '@matterbridge/utils/loader';
|
|
114
115
|
import { isValidArray } from '@matterbridge/utils/validate';
|
|
116
|
+
import { waiter } from '@matterbridge/utils/wait';
|
|
115
117
|
import { BLUE, CYAN, db, debugStringify, er, hk, nf, or, wr, YELLOW, zb } from 'node-ansi-logger';
|
|
116
118
|
import { MatterbridgeBindingServer } from './behaviors/bindingServer.js';
|
|
117
119
|
import { MatterbridgeBooleanStateConfigurationServer } from './behaviors/booleanStateConfigurationServer.js';
|
|
@@ -129,6 +131,7 @@ import { MatterbridgeOperationalStateServer } from './behaviors/operationalState
|
|
|
129
131
|
import { MatterbridgePowerSourceServer } from './behaviors/powerSourceServer.js';
|
|
130
132
|
import { MatterbridgePumpConfigurationAndControlServer } from './behaviors/pumpConfigurationAndControlServer.js';
|
|
131
133
|
import { MatterbridgeSmokeCoAlarmServer } from './behaviors/smokeCoAlarmServer.js';
|
|
134
|
+
import { MatterbridgeTemperatureAlarmServer } from './behaviors/temperatureAlarmServer.js';
|
|
132
135
|
import { MatterbridgeThermostatServer } from './behaviors/thermostatServer.js';
|
|
133
136
|
import { MatterbridgeValveConfigurationAndControlServer } from './behaviors/valveConfigurationAndControlServer.js';
|
|
134
137
|
import { MatterbridgeWindowCoveringServer } from './behaviors/windowCoveringServer.js';
|
|
@@ -307,6 +310,8 @@ export function getBehaviourTypeFromClusterServerId(clusterId) {
|
|
|
307
310
|
return BooleanStateServer.enable({ events: { stateChange: true } });
|
|
308
311
|
if (clusterId === BooleanStateConfiguration.id)
|
|
309
312
|
return MatterbridgeBooleanStateConfigurationServer;
|
|
313
|
+
if (clusterId === TemperatureAlarm.id)
|
|
314
|
+
return MatterbridgeTemperatureAlarmServer;
|
|
310
315
|
if (clusterId === PowerTopology.id)
|
|
311
316
|
return PowerTopologyServer.with('TreeTopology');
|
|
312
317
|
if (clusterId === ElectricalPowerMeasurement.id)
|
|
@@ -426,7 +431,7 @@ export function getBehavior(endpoint, cluster) {
|
|
|
426
431
|
}
|
|
427
432
|
return behavior;
|
|
428
433
|
}
|
|
429
|
-
export async function invokeBehaviorCommand(endpoint, cluster, command, params) {
|
|
434
|
+
export async function invokeBehaviorCommand(endpoint, cluster, command, params, waiterCondition) {
|
|
430
435
|
const behaviorId = getBehavior(endpoint, cluster)?.id;
|
|
431
436
|
if (!behaviorId) {
|
|
432
437
|
endpoint.log?.error(`invokeBehaviorCommand error: command ${hk}${command}${er} not found on endpoint ${or}${endpoint.maybeId}${er}:${or}${endpoint.maybeNumber}${er}`);
|
|
@@ -459,6 +464,8 @@ export async function invokeBehaviorCommand(endpoint, cluster, command, params)
|
|
|
459
464
|
delete behavior.context;
|
|
460
465
|
}
|
|
461
466
|
});
|
|
467
|
+
if (invoked && waiterCondition)
|
|
468
|
+
return await waiter(`invokeBehaviorCommand ${command}`, waiterCondition, false, 1000, 50);
|
|
462
469
|
return invoked;
|
|
463
470
|
}
|
|
464
471
|
export async function invokeSubscribeHandler(endpoint, cluster, attribute, newValue, oldValue) {
|
|
@@ -547,6 +554,8 @@ export function addClusterServers(endpoint, serverList) {
|
|
|
547
554
|
endpoint.createDefaultBooleanStateClusterServer();
|
|
548
555
|
if (serverList.includes(BooleanStateConfiguration.id))
|
|
549
556
|
endpoint.createDefaultBooleanStateConfigurationClusterServer();
|
|
557
|
+
if (serverList.includes(TemperatureAlarm.id))
|
|
558
|
+
endpoint.createDefaultTemperatureAlarmClusterServer();
|
|
550
559
|
if (serverList.includes(PowerTopology.id))
|
|
551
560
|
endpoint.createDefaultPowerTopologyClusterServer();
|
|
552
561
|
if (serverList.includes(ElectricalPowerMeasurement.id))
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matterbridge/core",
|
|
3
|
-
"version": "3.10.8-dev-20260903-
|
|
3
|
+
"version": "3.10.8-dev-20260903-014e30e",
|
|
4
4
|
"description": "Matterbridge core library",
|
|
5
5
|
"author": "https://github.com/Luligu",
|
|
6
6
|
"homepage": "https://matterbridge.io/",
|
|
@@ -132,10 +132,10 @@
|
|
|
132
132
|
},
|
|
133
133
|
"dependencies": {
|
|
134
134
|
"@matter/main": "0.17.9",
|
|
135
|
-
"@matterbridge/dgram": "3.10.8-dev-20260903-
|
|
136
|
-
"@matterbridge/thread": "3.10.8-dev-20260903-
|
|
137
|
-
"@matterbridge/types": "3.10.8-dev-20260903-
|
|
138
|
-
"@matterbridge/utils": "3.10.8-dev-20260903-
|
|
135
|
+
"@matterbridge/dgram": "3.10.8-dev-20260903-014e30e",
|
|
136
|
+
"@matterbridge/thread": "3.10.8-dev-20260903-014e30e",
|
|
137
|
+
"@matterbridge/types": "3.10.8-dev-20260903-014e30e",
|
|
138
|
+
"@matterbridge/utils": "3.10.8-dev-20260903-014e30e",
|
|
139
139
|
"escape-html": "1.0.3",
|
|
140
140
|
"express": "5.2.1",
|
|
141
141
|
"express-rate-limit": "8.7.0",
|