matterbridge-example-dynamic-platform 1.1.9 → 1.2.0-edge.11

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/robot.js ADDED
@@ -0,0 +1,215 @@
1
+ import { Matterbridge, MatterbridgeServer, MatterbridgeEndpoint, roboticVacuumCleaner, dishwasher } from 'matterbridge';
2
+ import { LogLevel as MatterLogLevel, LogFormat as MatterLogFormat, EndpointServer, logEndpoint, DeviceTypeId, VendorId, } from 'matterbridge/matter';
3
+ import { ModeBase, OperationalState, PowerSource, RvcRunMode, RvcCleanMode, RvcOperationalState, ServiceArea } from 'matterbridge/matter/clusters';
4
+ import { ActionsServer, RvcCleanModeBehavior, RvcOperationalStateBehavior, RvcRunModeBehavior, ServiceAreaBehavior } from 'matterbridge/matter/behaviors';
5
+ import { AnsiLogger } from 'matterbridge/logger';
6
+ import { Appliances } from './appliances.js';
7
+ export class Robot extends MatterbridgeEndpoint {
8
+ constructor(name, serial) {
9
+ super(roboticVacuumCleaner, { uniqueStorageKey: `${name}-${serial}` }, true);
10
+ this.createDefaultIdentifyClusterServer()
11
+ .createDefaultBasicInformationClusterServer(name, serial, 0xfff1, 'Matterbridge', 0x8000, 'Matterbridge Robot Vacuum Cleaner')
12
+ .createDefaultRvcRunModeClusterServer()
13
+ .createDefaultRvcOperationalStateClusterServer()
14
+ .createDefaultRvcCleanModeClusterServer()
15
+ .createDefaultServiceAreaClusterServer()
16
+ .createDefaultPowerSourceRechargeableBatteryClusterServer(80, PowerSource.BatChargeLevel.Ok, 5900);
17
+ }
18
+ createDefaultRvcRunModeClusterServer(currentMode, supportedModes) {
19
+ this.behaviors.require(MatterbridgeRvcRunModeServer, {
20
+ supportedModes: supportedModes ?? [
21
+ { label: 'Idle', mode: 1, modeTags: [{ value: RvcRunMode.ModeTag.Idle }] },
22
+ { label: 'Cleaning', mode: 2, modeTags: [{ value: RvcRunMode.ModeTag.Cleaning }] },
23
+ { label: 'Mapping', mode: 3, modeTags: [{ value: RvcRunMode.ModeTag.Mapping }] },
24
+ { label: 'SpotCleaning', mode: 4, modeTags: [{ value: RvcRunMode.ModeTag.Cleaning }, { value: RvcRunMode.ModeTag.Max }] },
25
+ ],
26
+ currentMode: currentMode ?? 1,
27
+ });
28
+ return this;
29
+ }
30
+ createDefaultRvcCleanModeClusterServer(currentMode, supportedModes) {
31
+ this.behaviors.require(MatterbridgeRvcCleanModeServer, {
32
+ supportedModes: supportedModes ?? [
33
+ { label: 'Vacuum', mode: 1, modeTags: [{ value: RvcCleanMode.ModeTag.Vacuum }] },
34
+ { label: 'Mop', mode: 2, modeTags: [{ value: RvcCleanMode.ModeTag.Mop }] },
35
+ { label: 'Clean', mode: 3, modeTags: [{ value: RvcCleanMode.ModeTag.DeepClean }] },
36
+ ],
37
+ currentMode: currentMode ?? 1,
38
+ });
39
+ return this;
40
+ }
41
+ createDefaultServiceAreaClusterServer(supportedAreas, selectedAreas) {
42
+ this.behaviors.require(MatterbridgeServiceAreaServer, {
43
+ supportedAreas: supportedAreas ?? [
44
+ {
45
+ areaId: 1,
46
+ mapId: null,
47
+ areaInfo: { locationInfo: { locationName: 'Living', floorNumber: null, areaType: null }, landmarkInfo: null },
48
+ },
49
+ {
50
+ areaId: 2,
51
+ mapId: null,
52
+ areaInfo: { locationInfo: { locationName: 'Kitchen', floorNumber: null, areaType: null }, landmarkInfo: null },
53
+ },
54
+ {
55
+ areaId: 3,
56
+ mapId: null,
57
+ areaInfo: { locationInfo: { locationName: 'Bedroom', floorNumber: null, areaType: null }, landmarkInfo: null },
58
+ },
59
+ {
60
+ areaId: 4,
61
+ mapId: null,
62
+ areaInfo: { locationInfo: { locationName: 'Bathroom', floorNumber: null, areaType: null }, landmarkInfo: null },
63
+ },
64
+ ],
65
+ selectedAreas: selectedAreas ?? [],
66
+ currentArea: 1,
67
+ estimatedEndTime: null,
68
+ });
69
+ return this;
70
+ }
71
+ createDefaultRvcOperationalStateClusterServer(phaseList = null, currentPhase = null, operationalStateList, operationalState, operationalError) {
72
+ this.behaviors.require(MatterbridgeRvcOperationalStateServer, {
73
+ phaseList,
74
+ currentPhase,
75
+ operationalStateList: operationalStateList ?? [
76
+ { operationalStateId: RvcOperationalState.OperationalState.Stopped, operationalStateLabel: 'Stopped' },
77
+ { operationalStateId: RvcOperationalState.OperationalState.Running, operationalStateLabel: 'Running' },
78
+ { operationalStateId: RvcOperationalState.OperationalState.Paused, operationalStateLabel: 'Paused' },
79
+ { operationalStateId: RvcOperationalState.OperationalState.Error, operationalStateLabel: 'Error' },
80
+ { operationalStateId: RvcOperationalState.OperationalState.SeekingCharger, operationalStateLabel: 'SeekingCharger' },
81
+ { operationalStateId: RvcOperationalState.OperationalState.Charging, operationalStateLabel: 'Charging' },
82
+ { operationalStateId: RvcOperationalState.OperationalState.Docked, operationalStateLabel: 'Docked' },
83
+ ],
84
+ operationalState: operationalState ?? RvcOperationalState.OperationalState.Docked,
85
+ operationalError: operationalError ?? { errorStateId: RvcOperationalState.ErrorState.NoError, errorStateLabel: 'No Error', errorStateDetails: 'Fully operational' },
86
+ });
87
+ return this;
88
+ }
89
+ }
90
+ export class MatterbridgeServiceAreaServer extends ServiceAreaBehavior {
91
+ initialize() {
92
+ }
93
+ selectAreas({ newAreas }) {
94
+ const device = this.endpoint.stateOf(MatterbridgeServer).deviceCommand;
95
+ for (const area of newAreas) {
96
+ const supportedArea = this.state.supportedAreas.find((supportedArea) => supportedArea.areaId === area);
97
+ if (!supportedArea) {
98
+ device.log.error('MatterbridgeServiceAreaServer selectAreas called with unsupported area:', area);
99
+ return { status: ServiceArea.SelectAreasStatus.UnsupportedArea, statusText: 'Unsupported areas' };
100
+ }
101
+ }
102
+ this.state.selectedAreas = newAreas;
103
+ this.state.currentArea = newAreas[0];
104
+ device.log.info(`***MatterbridgeServiceAreaServer selectAreas called with: ${newAreas.map((area) => area.toString()).join(', ')}`);
105
+ return { status: ServiceArea.SelectAreasStatus.Success, statusText: 'Succesfully selected new areas' };
106
+ }
107
+ }
108
+ export class MatterbridgeRvcRunModeServer extends RvcRunModeBehavior {
109
+ initialize() {
110
+ this.state.currentMode = 1;
111
+ }
112
+ changeToMode({ newMode }) {
113
+ const device = this.endpoint.stateOf(MatterbridgeServer).deviceCommand;
114
+ const changedMode = this.state.supportedModes.find((mode) => mode.mode === newMode);
115
+ if (!changedMode) {
116
+ device.log.error('MatterbridgeRvcRunModeServer changeToMode called with unsupported newMode:', newMode);
117
+ return { status: ModeBase.ModeChangeStatus.InvalidInMode, statusText: 'Invalid mode' };
118
+ }
119
+ device.changeToMode({ newMode });
120
+ this.state.currentMode = newMode;
121
+ if (changedMode.modeTags.find((tag) => tag.value === RvcRunMode.ModeTag.Cleaning)) {
122
+ device.log.info('***MatterbridgeRvcRunModeServer changeToMode called with newMode Cleaning => Running');
123
+ this.agent.get(MatterbridgeRvcOperationalStateServer).state.operationalState = RvcOperationalState.OperationalState.Running;
124
+ return { status: ModeBase.ModeChangeStatus.Success, statusText: 'Running' };
125
+ }
126
+ else if (changedMode.modeTags.find((tag) => tag.value === RvcRunMode.ModeTag.Idle)) {
127
+ device.log.info('***MatterbridgeRvcRunModeServer changeToMode called with newMode Idle => Docked');
128
+ this.agent.get(MatterbridgeRvcOperationalStateServer).state.operationalState = RvcOperationalState.OperationalState.Docked;
129
+ return { status: ModeBase.ModeChangeStatus.Success, statusText: 'Docked' };
130
+ }
131
+ device.log.info(`***MatterbridgeRvcRunModeServer changeToMode called with newMode ${newMode} => ${changedMode.label}`);
132
+ this.agent.get(MatterbridgeRvcOperationalStateServer).state.operationalState = RvcOperationalState.OperationalState.Running;
133
+ return { status: ModeBase.ModeChangeStatus.Success, statusText: 'Success' };
134
+ }
135
+ }
136
+ export class MatterbridgeRvcCleanModeServer extends RvcCleanModeBehavior {
137
+ initialize() {
138
+ this.state.currentMode = 1;
139
+ }
140
+ changeToMode({ newMode }) {
141
+ const device = this.endpoint.stateOf(MatterbridgeServer).deviceCommand;
142
+ const supported = this.state.supportedModes.find((mode) => mode.mode === newMode);
143
+ if (!supported) {
144
+ device.log.error('***MatterbridgeRvcCleanModeServer changeToMode called with unsupported newMode:', newMode);
145
+ return { status: ModeBase.ModeChangeStatus.InvalidInMode, statusText: 'Invalid mode' };
146
+ }
147
+ device.changeToMode({ newMode });
148
+ this.state.currentMode = newMode;
149
+ device.log.info(`***MatterbridgeRvcCleanModeServer changeToMode called with newMode ${newMode} => ${supported.label}`);
150
+ return { status: ModeBase.ModeChangeStatus.Success, statusText: 'Success' };
151
+ }
152
+ }
153
+ export class MatterbridgeRvcOperationalStateServer extends RvcOperationalStateBehavior {
154
+ initialize() {
155
+ const device = this.endpoint.stateOf(MatterbridgeServer).deviceCommand;
156
+ device.log.info('***MatterbridgeRvcOperationalStateServer initialized: setting operational state to Docked');
157
+ this.state.operationalState = RvcOperationalState.OperationalState.Docked;
158
+ this.state.operationalError = { errorStateId: RvcOperationalState.ErrorState.NoError, errorStateLabel: 'No Error', errorStateDetails: 'Fully operational' };
159
+ }
160
+ pause() {
161
+ const device = this.endpoint.stateOf(MatterbridgeServer).deviceCommand;
162
+ device.log.info('MatterbridgeRvcOperationalStateServer: pause called setting operational state to Paused and currentMode to Idle');
163
+ this.agent.get(MatterbridgeRvcRunModeServer).state.currentMode = 1;
164
+ this.state.operationalState = RvcOperationalState.OperationalState.Paused;
165
+ this.state.operationalError = { errorStateId: RvcOperationalState.ErrorState.NoError, errorStateLabel: 'No Error', errorStateDetails: 'Fully operational' };
166
+ return {
167
+ commandResponseState: { errorStateId: OperationalState.ErrorState.NoError, errorStateLabel: 'No error', errorStateDetails: 'Fully operational' },
168
+ };
169
+ }
170
+ resume() {
171
+ const device = this.endpoint.stateOf(MatterbridgeServer).deviceCommand;
172
+ device.log.info('MatterbridgeRvcOperationalStateServer: resume called setting operational state to Running and currentMode to Cleaning');
173
+ this.agent.get(MatterbridgeRvcRunModeServer).state.currentMode = 2;
174
+ this.state.operationalState = RvcOperationalState.OperationalState.Running;
175
+ this.state.operationalError = { errorStateId: RvcOperationalState.ErrorState.NoError, errorStateLabel: 'No Error', errorStateDetails: 'Fully operational' };
176
+ return {
177
+ commandResponseState: { errorStateId: OperationalState.ErrorState.NoError, errorStateLabel: 'No error', errorStateDetails: 'Fully operational' },
178
+ };
179
+ }
180
+ goHome() {
181
+ const device = this.endpoint.stateOf(MatterbridgeServer).deviceCommand;
182
+ device.log.info('MatterbridgeRvcOperationalStateServer: goHome called setting operational state to Docked and currentMode to Idle');
183
+ this.agent.get(MatterbridgeRvcRunModeServer).state.currentMode = 1;
184
+ this.state.operationalState = RvcOperationalState.OperationalState.Docked;
185
+ this.state.operationalError = { errorStateId: RvcOperationalState.ErrorState.NoError, errorStateLabel: 'No Error', errorStateDetails: 'Fully operational' };
186
+ return {
187
+ commandResponseState: { errorStateId: OperationalState.ErrorState.NoError, errorStateLabel: 'No error', errorStateDetails: 'Fully operational' },
188
+ };
189
+ }
190
+ }
191
+ function createEndpointActionsClusterServer(endpoint, endpointLists) {
192
+ endpoint.behaviors.require(ActionsServer, {
193
+ actionList: [],
194
+ endpointLists,
195
+ });
196
+ return endpoint;
197
+ }
198
+ if (process.argv.includes('-testRobot')) {
199
+ const matterbridge = await Matterbridge.loadInstance(false);
200
+ matterbridge.log = new AnsiLogger({ logName: 'Matterbridge', logTimestampFormat: 4, logLevel: "debug" });
201
+ matterbridge.environment.vars.set('log.level', MatterLogLevel.DEBUG);
202
+ matterbridge.environment.vars.set('log.format', MatterLogFormat.ANSI);
203
+ matterbridge.environment.vars.set('path.root', 'matterstorage');
204
+ matterbridge.environment.vars.set('runtime.signals', true);
205
+ matterbridge.environment.vars.set('runtime.exitcode', true);
206
+ matterbridge.environment.vars.set('mdns.networkInterface', 'Wi-Fi');
207
+ await matterbridge.startMatterStorage();
208
+ const deviceType = dishwasher;
209
+ const context = await matterbridge.createServerNodeContext('Matterbridge', deviceType.name, DeviceTypeId(deviceType.code), VendorId(0xfff1), 'Matterbridge', 0x8000, 'Matterbridge device');
210
+ const server = (await matterbridge.createServerNode(context));
211
+ const device = new Appliances(deviceType, 'Dish Washer', '97754248654');
212
+ await server.add(device);
213
+ await matterbridge.startServerNode(server);
214
+ logEndpoint(EndpointServer.forEndpoint(server));
215
+ }
@@ -40,7 +40,7 @@
40
40
  "default": true
41
41
  },
42
42
  "enableConcentrationMeasurements": {
43
- "description": "Enable the ConcentrationMeasurements in the Air Quality device and SmokeCoSensor devices (Apple Home 18.4 will discard these devices when enabled)",
43
+ "description": "Enable the ConcentrationMeasurements in the Air Quality device and SmokeCoSensor device (Apple Home 18.4 will discard these devices when enabled)",
44
44
  "type": "boolean",
45
45
  "default": true
46
46
  },
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "matterbridge-example-dynamic-platform",
3
- "version": "1.1.9",
3
+ "version": "1.2.0-edge.11",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "matterbridge-example-dynamic-platform",
9
- "version": "1.1.9",
9
+ "version": "1.2.0-edge.11",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "node-ansi-logger": "3.0.1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "matterbridge-example-dynamic-platform",
3
- "version": "1.1.9",
3
+ "version": "1.2.0-edge.11",
4
4
  "description": "Matterbridge dynamic plugin",
5
5
  "author": "https://github.com/Luligu",
6
6
  "license": "MIT",
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ // enable isolatedModules just for ts-jest
5
+ "isolatedModules": true
6
+ },
7
+ "include": ["**/*.spec.ts", "**/*.test.ts", "**/__test__/*"]
8
+ }