@matterbridge/core 3.10.5-dev-20260809-ffe76d7 → 3.10.5-dev-20260809-30130bb
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.
|
@@ -10,11 +10,13 @@ declare const MatterbridgeThermostatServer_base: import("@matter/node").ClusterB
|
|
|
10
10
|
occupancy: false;
|
|
11
11
|
presets: true;
|
|
12
12
|
setback: false;
|
|
13
|
-
thermostatSuggestions:
|
|
13
|
+
thermostatSuggestions: true;
|
|
14
14
|
}>, import("@matter/types").ClusterType.Concrete, typeof import("@matter/node/behaviors/thermostat").ThermostatBaseServer.Internal, "thermostat">;
|
|
15
15
|
export declare class MatterbridgeThermostatServer extends MatterbridgeThermostatServer_base {
|
|
16
16
|
setpointRaiseLower(request: Thermostat.SetpointRaiseLowerRequest): Promise<void>;
|
|
17
17
|
setActivePresetRequest(request: Thermostat.SetActivePresetRequest): Promise<void>;
|
|
18
18
|
setActiveScheduleRequest(request: Thermostat.SetActiveScheduleRequest): Promise<void>;
|
|
19
|
+
addThermostatSuggestion(request: Thermostat.AddThermostatSuggestionRequest): Promise<Thermostat.AddThermostatSuggestionResponse>;
|
|
20
|
+
removeThermostatSuggestion(request: Thermostat.RemoveThermostatSuggestionRequest): Promise<void>;
|
|
19
21
|
}
|
|
20
22
|
export {};
|
|
@@ -3,7 +3,7 @@ import { ThermostatServer } from '@matter/node/behaviors/thermostat';
|
|
|
3
3
|
import { StatusResponse } from '@matter/types';
|
|
4
4
|
import { Thermostat } from '@matter/types/clusters/thermostat';
|
|
5
5
|
import { MatterbridgeServer } from './matterbridgeServer.js';
|
|
6
|
-
export class MatterbridgeThermostatServer extends ThermostatServer.with(Thermostat.Feature.Cooling, Thermostat.Feature.Heating, Thermostat.Feature.AutoMode, Thermostat.Feature.Presets, Thermostat.Feature.MatterScheduleConfiguration) {
|
|
6
|
+
export class MatterbridgeThermostatServer extends ThermostatServer.with(Thermostat.Feature.Cooling, Thermostat.Feature.Heating, Thermostat.Feature.AutoMode, Thermostat.Feature.Presets, Thermostat.Feature.MatterScheduleConfiguration, Thermostat.Feature.ThermostatSuggestions) {
|
|
7
7
|
async setpointRaiseLower(request) {
|
|
8
8
|
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
9
9
|
device.log.info(`Setting setpoint by ${request.amount} in mode ${request.mode} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
@@ -55,4 +55,63 @@ export class MatterbridgeThermostatServer extends ThermostatServer.with(Thermost
|
|
|
55
55
|
this.state.activeScheduleHandle = Uint8Array.from(request.scheduleHandle);
|
|
56
56
|
device.log.debug(`MatterbridgeThermostatServer: setActiveScheduleRequest completed with activeScheduleHandle: ${scheduleHandle}`);
|
|
57
57
|
}
|
|
58
|
+
async addThermostatSuggestion(request) {
|
|
59
|
+
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
60
|
+
const presetHandle = `0x${Buffer.from(request.presetHandle).toString('hex')}`;
|
|
61
|
+
device.log.info(`Adding thermostat suggestion for preset ${presetHandle} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
62
|
+
await device.commandHandler.executeHandler('Thermostat.addThermostatSuggestion', {
|
|
63
|
+
command: 'addThermostatSuggestion',
|
|
64
|
+
request,
|
|
65
|
+
cluster: ThermostatServer.id,
|
|
66
|
+
attributes: this.state,
|
|
67
|
+
endpoint: this.endpoint,
|
|
68
|
+
context: this.context,
|
|
69
|
+
});
|
|
70
|
+
if (this.state.presets.find((p) => p.presetHandle !== null && Bytes.areEqual(p.presetHandle, request.presetHandle)) === undefined) {
|
|
71
|
+
throw new StatusResponse.NotFoundError('Requested PresetHandle not found');
|
|
72
|
+
}
|
|
73
|
+
if (this.state.thermostatSuggestions.length >= this.state.maxThermostatSuggestions) {
|
|
74
|
+
throw new StatusResponse.ResourceExhaustedError('Maximum number of thermostat suggestions reached');
|
|
75
|
+
}
|
|
76
|
+
const currentTime = Math.floor(Date.now() / 1000);
|
|
77
|
+
const effectiveTime = request.effectiveTime ?? currentTime;
|
|
78
|
+
if (effectiveTime > currentTime + 24 * 60 * 60) {
|
|
79
|
+
throw new StatusResponse.InvalidCommandError('EffectiveTime cannot be more than 24 hours in the future');
|
|
80
|
+
}
|
|
81
|
+
const usedUniqueIds = new Set(this.state.thermostatSuggestions.map((s) => s.uniqueId));
|
|
82
|
+
let uniqueId = 0;
|
|
83
|
+
while (usedUniqueIds.has(uniqueId))
|
|
84
|
+
uniqueId++;
|
|
85
|
+
const suggestion = {
|
|
86
|
+
uniqueId,
|
|
87
|
+
presetHandle: Uint8Array.from(request.presetHandle),
|
|
88
|
+
effectiveTime,
|
|
89
|
+
expirationTime: effectiveTime + request.expirationInMinutes * 60,
|
|
90
|
+
};
|
|
91
|
+
this.state.thermostatSuggestions = [...this.state.thermostatSuggestions, suggestion];
|
|
92
|
+
device.log.debug(`MatterbridgeThermostatServer: addThermostatSuggestion completed with uniqueId: ${uniqueId}`);
|
|
93
|
+
return { uniqueId };
|
|
94
|
+
}
|
|
95
|
+
async removeThermostatSuggestion(request) {
|
|
96
|
+
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
97
|
+
device.log.info(`Removing thermostat suggestion ${request.uniqueId} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
98
|
+
await device.commandHandler.executeHandler('Thermostat.removeThermostatSuggestion', {
|
|
99
|
+
command: 'removeThermostatSuggestion',
|
|
100
|
+
request,
|
|
101
|
+
cluster: ThermostatServer.id,
|
|
102
|
+
attributes: this.state,
|
|
103
|
+
endpoint: this.endpoint,
|
|
104
|
+
context: this.context,
|
|
105
|
+
});
|
|
106
|
+
const suggestion = this.state.thermostatSuggestions.find((s) => s.uniqueId === request.uniqueId);
|
|
107
|
+
if (suggestion === undefined) {
|
|
108
|
+
throw new StatusResponse.NotFoundError('Requested UniqueID not found');
|
|
109
|
+
}
|
|
110
|
+
this.state.thermostatSuggestions = this.state.thermostatSuggestions.filter((s) => s.uniqueId !== request.uniqueId);
|
|
111
|
+
if (this.state.currentThermostatSuggestion?.uniqueId === request.uniqueId) {
|
|
112
|
+
this.state.currentThermostatSuggestion = null;
|
|
113
|
+
this.state.thermostatSuggestionNotFollowingReason = null;
|
|
114
|
+
}
|
|
115
|
+
device.log.debug(`MatterbridgeThermostatServer: removeThermostatSuggestion completed for uniqueId: ${request.uniqueId}`);
|
|
116
|
+
}
|
|
58
117
|
}
|
|
@@ -174,8 +174,9 @@ export declare class MatterbridgeEndpoint extends Endpoint {
|
|
|
174
174
|
setWindowCoveringTargetAndCurrentPosition(liftPosition: number, tiltPosition?: number): Promise<void>;
|
|
175
175
|
createDefaultThermostatClusterServer(localTemperature?: number, occupiedHeatingSetpoint?: number, occupiedCoolingSetpoint?: number, minSetpointDeadBand?: number, minHeatSetpointLimit?: number, maxHeatSetpointLimit?: number, minCoolSetpointLimit?: number, maxCoolSetpointLimit?: number, unoccupiedHeatingSetpoint?: number, unoccupiedCoolingSetpoint?: number, occupied?: boolean, outdoorTemperature?: number | null): this;
|
|
176
176
|
createDefaultHeatingThermostatClusterServer(localTemperature?: number, occupiedHeatingSetpoint?: number, minHeatSetpointLimit?: number, maxHeatSetpointLimit?: number, unoccupiedHeatingSetpoint?: number, occupied?: boolean, outdoorTemperature?: number | null): this;
|
|
177
|
-
createDefaultPresetsThermostatClusterServer(localTemperature?: number, occupiedHeatingSetpoint?: number, occupiedCoolingSetpoint?: number, minSetpointDeadBand?: number, minHeatSetpointLimit?: number, maxHeatSetpointLimit?: number, minCoolSetpointLimit?: number, maxCoolSetpointLimit?: number, unoccupiedHeatingSetpoint?: number, unoccupiedCoolingSetpoint?: number, occupied?: boolean, outdoorTemperature?: number | null, activePresetHandle?: Uint8Array | null, presets?: Thermostat.Preset[], presetTypes?: Thermostat.PresetType[]): this;
|
|
177
|
+
createDefaultPresetsThermostatClusterServer(localTemperature?: number, occupiedHeatingSetpoint?: number, occupiedCoolingSetpoint?: number, minSetpointDeadBand?: number, minHeatSetpointLimit?: number, maxHeatSetpointLimit?: number, minCoolSetpointLimit?: number, maxCoolSetpointLimit?: number, unoccupiedHeatingSetpoint?: number, unoccupiedCoolingSetpoint?: number, occupied?: boolean, outdoorTemperature?: number | null, activePresetHandle?: Uint8Array | null, presets?: Thermostat.Preset[], presetTypes?: Thermostat.PresetType[] | null): this;
|
|
178
178
|
createDefaultSchedulesThermostatClusterServer(localTemperature?: number, occupiedHeatingSetpoint?: number, occupiedCoolingSetpoint?: number, minSetpointDeadBand?: number, minHeatSetpointLimit?: number, maxHeatSetpointLimit?: number, minCoolSetpointLimit?: number, maxCoolSetpointLimit?: number, unoccupiedHeatingSetpoint?: number, unoccupiedCoolingSetpoint?: number, occupied?: boolean, outdoorTemperature?: number | null, activeScheduleHandle?: Uint8Array | null, schedules?: Thermostat.Schedule[], scheduleTypes?: Thermostat.ScheduleType[], numberOfScheduleTransitions?: number, numberOfScheduleTransitionPerDay?: number | null): this;
|
|
179
|
+
createDefaultThermostatSuggestionsClusterServer(localTemperature?: number, occupiedHeatingSetpoint?: number, occupiedCoolingSetpoint?: number, minSetpointDeadBand?: number, minHeatSetpointLimit?: number, maxHeatSetpointLimit?: number, minCoolSetpointLimit?: number, maxCoolSetpointLimit?: number, unoccupiedHeatingSetpoint?: number, unoccupiedCoolingSetpoint?: number, occupied?: boolean, outdoorTemperature?: number | null, activePresetHandle?: Uint8Array | null, presets?: Thermostat.Preset[], presetTypes?: Thermostat.PresetType[] | null, thermostatSuggestions?: Thermostat.ThermostatSuggestion[], currentThermostatSuggestion?: Thermostat.ThermostatSuggestion | null, thermostatSuggestionNotFollowingReason?: Thermostat.ThermostatSuggestionNotFollowingReason | null): this;
|
|
179
180
|
createDefaultCoolingThermostatClusterServer(localTemperature?: number, occupiedCoolingSetpoint?: number, minCoolSetpointLimit?: number, maxCoolSetpointLimit?: number, unoccupiedCoolingSetpoint?: number, occupied?: boolean, outdoorTemperature?: number | null): this;
|
|
180
181
|
createDefaultThermostatUserInterfaceConfigurationClusterServer(temperatureDisplayMode?: ThermostatUserInterfaceConfiguration.TemperatureDisplayMode, keypadLockout?: ThermostatUserInterfaceConfiguration.KeypadLockout, scheduleProgrammingVisibility?: ThermostatUserInterfaceConfiguration.ScheduleProgrammingVisibility): this;
|
|
181
182
|
createDefaultFanControlClusterServer(fanMode?: FanControl.FanMode, fanModeSequence?: FanControl.FanModeSequence, percentSetting?: number, percentCurrent?: number): this;
|
|
@@ -1059,6 +1059,66 @@ export class MatterbridgeEndpoint extends Endpoint {
|
|
|
1059
1059
|
});
|
|
1060
1060
|
return this;
|
|
1061
1061
|
}
|
|
1062
|
+
createDefaultThermostatSuggestionsClusterServer(localTemperature = 23, occupiedHeatingSetpoint = 21, occupiedCoolingSetpoint = 25, minSetpointDeadBand = 0, minHeatSetpointLimit = 0, maxHeatSetpointLimit = 50, minCoolSetpointLimit = 0, maxCoolSetpointLimit = 50, unoccupiedHeatingSetpoint, unoccupiedCoolingSetpoint, occupied, outdoorTemperature, activePresetHandle = null, presets = [], presetTypes = [
|
|
1063
|
+
{ presetScenario: Thermostat.PresetScenario.Occupied, numberOfPresets: 2, presetTypeFeatures: { automatic: false, supportsNames: true } },
|
|
1064
|
+
{ presetScenario: Thermostat.PresetScenario.Unoccupied, numberOfPresets: 2, presetTypeFeatures: { automatic: false, supportsNames: true } },
|
|
1065
|
+
], thermostatSuggestions = [], currentThermostatSuggestion = null, thermostatSuggestionNotFollowingReason = null) {
|
|
1066
|
+
this.behaviors.require(MatterbridgeThermostatServer.with(Thermostat.Feature.Heating, Thermostat.Feature.Cooling, Thermostat.Feature.AutoMode, ...(occupied !== undefined ? [Thermostat.Feature.Occupancy] : []), Thermostat.Feature.Presets, Thermostat.Feature.ThermostatSuggestions), {
|
|
1067
|
+
localTemperature: localTemperature * 100,
|
|
1068
|
+
externalMeasuredIndoorTemperature: localTemperature * 100,
|
|
1069
|
+
...(outdoorTemperature !== undefined ? { outdoorTemperature: outdoorTemperature !== null ? outdoorTemperature * 100 : outdoorTemperature } : {}),
|
|
1070
|
+
systemMode: Thermostat.SystemMode.Auto,
|
|
1071
|
+
controlSequenceOfOperation: Thermostat.ControlSequenceOfOperation.CoolingAndHeating,
|
|
1072
|
+
occupiedHeatingSetpoint: occupiedHeatingSetpoint * 100,
|
|
1073
|
+
minHeatSetpointLimit: minHeatSetpointLimit * 100,
|
|
1074
|
+
maxHeatSetpointLimit: maxHeatSetpointLimit * 100,
|
|
1075
|
+
absMinHeatSetpointLimit: minHeatSetpointLimit * 100,
|
|
1076
|
+
absMaxHeatSetpointLimit: maxHeatSetpointLimit * 100,
|
|
1077
|
+
occupiedCoolingSetpoint: occupiedCoolingSetpoint * 100,
|
|
1078
|
+
minCoolSetpointLimit: minCoolSetpointLimit * 100,
|
|
1079
|
+
maxCoolSetpointLimit: maxCoolSetpointLimit * 100,
|
|
1080
|
+
absMinCoolSetpointLimit: minCoolSetpointLimit * 100,
|
|
1081
|
+
absMaxCoolSetpointLimit: maxCoolSetpointLimit * 100,
|
|
1082
|
+
minSetpointDeadBand: minSetpointDeadBand * 10,
|
|
1083
|
+
thermostatRunningMode: Thermostat.ThermostatRunningMode.Off,
|
|
1084
|
+
...(occupied !== undefined ? { unoccupiedHeatingSetpoint: unoccupiedHeatingSetpoint !== undefined ? unoccupiedHeatingSetpoint * 100 : 1900 } : {}),
|
|
1085
|
+
...(occupied !== undefined ? { unoccupiedCoolingSetpoint: unoccupiedCoolingSetpoint !== undefined ? unoccupiedCoolingSetpoint * 100 : 2700 } : {}),
|
|
1086
|
+
...(occupied !== undefined ? { occupancy: { occupied } } : {}),
|
|
1087
|
+
...(occupied !== undefined ? { externallyMeasuredOccupancy: true } : {}),
|
|
1088
|
+
numberOfPresets: Math.max(Array.isArray(presets) ? presets.length : 0, Array.isArray(presetTypes) ? Math.max(0, ...presetTypes.map((pt) => pt.numberOfPresets ?? 0)) : 0, 1),
|
|
1089
|
+
activePresetHandle: activePresetHandle ? Uint8Array.from(activePresetHandle) : null,
|
|
1090
|
+
presets: (presets ?? []).map((p) => ({
|
|
1091
|
+
presetHandle: p.presetHandle ? Uint8Array.from(p.presetHandle) : null,
|
|
1092
|
+
presetScenario: p.presetScenario,
|
|
1093
|
+
name: p.name,
|
|
1094
|
+
coolingSetpoint: p.coolingSetpoint,
|
|
1095
|
+
heatingSetpoint: p.heatingSetpoint,
|
|
1096
|
+
builtIn: p.builtIn ?? true,
|
|
1097
|
+
})),
|
|
1098
|
+
presetTypes: (presetTypes ?? []).map((pt) => ({
|
|
1099
|
+
...pt,
|
|
1100
|
+
numberOfPresets: pt.numberOfPresets ?? 0,
|
|
1101
|
+
presetTypeFeatures: pt.presetTypeFeatures ?? { automatic: false, supportsNames: true },
|
|
1102
|
+
})),
|
|
1103
|
+
maxThermostatSuggestions: Math.max(Array.isArray(thermostatSuggestions) ? thermostatSuggestions.length : 0, 5),
|
|
1104
|
+
thermostatSuggestions: (thermostatSuggestions ?? []).map((s) => ({
|
|
1105
|
+
uniqueId: s.uniqueId,
|
|
1106
|
+
presetHandle: Uint8Array.from(s.presetHandle),
|
|
1107
|
+
effectiveTime: s.effectiveTime,
|
|
1108
|
+
expirationTime: s.expirationTime,
|
|
1109
|
+
})),
|
|
1110
|
+
currentThermostatSuggestion: currentThermostatSuggestion
|
|
1111
|
+
? {
|
|
1112
|
+
uniqueId: currentThermostatSuggestion.uniqueId,
|
|
1113
|
+
presetHandle: Uint8Array.from(currentThermostatSuggestion.presetHandle),
|
|
1114
|
+
effectiveTime: currentThermostatSuggestion.effectiveTime,
|
|
1115
|
+
expirationTime: currentThermostatSuggestion.expirationTime,
|
|
1116
|
+
}
|
|
1117
|
+
: null,
|
|
1118
|
+
thermostatSuggestionNotFollowingReason: thermostatSuggestionNotFollowingReason ?? null,
|
|
1119
|
+
});
|
|
1120
|
+
return this;
|
|
1121
|
+
}
|
|
1062
1122
|
createDefaultCoolingThermostatClusterServer(localTemperature = 23, occupiedCoolingSetpoint = 25, minCoolSetpointLimit = 0, maxCoolSetpointLimit = 50, unoccupiedCoolingSetpoint, occupied, outdoorTemperature) {
|
|
1063
1123
|
this.behaviors.require(MatterbridgeThermostatServer.with(Thermostat.Feature.Cooling, ...(occupied !== undefined ? [Thermostat.Feature.Occupancy] : [])), {
|
|
1064
1124
|
localTemperature: localTemperature * 100,
|
|
@@ -458,6 +458,8 @@ export type CommandHandlerDataMap = {
|
|
|
458
458
|
'setpointRaiseLower': CommandHandlerData<'Thermostat.setpointRaiseLower'>;
|
|
459
459
|
'setActivePresetRequest': CommandHandlerData<'Thermostat.setActivePresetRequest'>;
|
|
460
460
|
'setActiveScheduleRequest': CommandHandlerData<'Thermostat.setActiveScheduleRequest'>;
|
|
461
|
+
'addThermostatSuggestion': CommandHandlerData<'Thermostat.addThermostatSuggestion'>;
|
|
462
|
+
'removeThermostatSuggestion': CommandHandlerData<'Thermostat.removeThermostatSuggestion'>;
|
|
461
463
|
'Thermostat.setpointRaiseLower': {
|
|
462
464
|
command: 'setpointRaiseLower';
|
|
463
465
|
request: Thermostat.SetpointRaiseLowerRequest;
|
|
@@ -479,6 +481,20 @@ export type CommandHandlerDataMap = {
|
|
|
479
481
|
attributes: ClusterAttributeValues<(typeof Thermostat)['attributes']>;
|
|
480
482
|
endpoint: MatterbridgeEndpoint;
|
|
481
483
|
};
|
|
484
|
+
'Thermostat.addThermostatSuggestion': {
|
|
485
|
+
command: 'addThermostatSuggestion';
|
|
486
|
+
request: Thermostat.AddThermostatSuggestionRequest;
|
|
487
|
+
cluster: 'thermostat';
|
|
488
|
+
attributes: ClusterAttributeValues<(typeof Thermostat)['attributes']>;
|
|
489
|
+
endpoint: MatterbridgeEndpoint;
|
|
490
|
+
};
|
|
491
|
+
'Thermostat.removeThermostatSuggestion': {
|
|
492
|
+
command: 'removeThermostatSuggestion';
|
|
493
|
+
request: Thermostat.RemoveThermostatSuggestionRequest;
|
|
494
|
+
cluster: 'thermostat';
|
|
495
|
+
attributes: ClusterAttributeValues<(typeof Thermostat)['attributes']>;
|
|
496
|
+
endpoint: MatterbridgeEndpoint;
|
|
497
|
+
};
|
|
482
498
|
'step': CommandHandlerData<'FanControl.step'>;
|
|
483
499
|
'FanControl.step': {
|
|
484
500
|
command: 'step';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matterbridge/core",
|
|
3
|
-
"version": "3.10.5-dev-20260809-
|
|
3
|
+
"version": "3.10.5-dev-20260809-30130bb",
|
|
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.5-dev-20260809-
|
|
136
|
-
"@matterbridge/thread": "3.10.5-dev-20260809-
|
|
137
|
-
"@matterbridge/types": "3.10.5-dev-20260809-
|
|
138
|
-
"@matterbridge/utils": "3.10.5-dev-20260809-
|
|
135
|
+
"@matterbridge/dgram": "3.10.5-dev-20260809-30130bb",
|
|
136
|
+
"@matterbridge/thread": "3.10.5-dev-20260809-30130bb",
|
|
137
|
+
"@matterbridge/types": "3.10.5-dev-20260809-30130bb",
|
|
138
|
+
"@matterbridge/utils": "3.10.5-dev-20260809-30130bb",
|
|
139
139
|
"escape-html": "1.0.3",
|
|
140
140
|
"express": "5.2.1",
|
|
141
141
|
"express-rate-limit": "8.6.2",
|