@matterbridge/core 3.10.6-dev-20260820-36b52be → 3.10.6-dev-20260821-16f33ac
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/demoDevices.js +45 -0
- package/dist/devices/basicVideoPlayer.d.ts +5 -20
- package/dist/devices/basicVideoPlayer.js +9 -140
- package/dist/devices/castingVideoClient.d.ts +11 -0
- package/dist/devices/castingVideoClient.js +19 -0
- package/dist/devices/castingVideoPlayer.d.ts +5 -7
- package/dist/devices/castingVideoPlayer.js +10 -29
- package/dist/devices/contentApp.d.ts +19 -0
- package/dist/devices/contentApp.js +19 -0
- package/dist/devices/export.d.ts +4 -0
- package/dist/devices/export.js +4 -0
- package/dist/devices/mediaHelpers.d.ts +46 -0
- package/dist/devices/mediaHelpers.js +281 -0
- package/dist/devices/speaker.d.ts +10 -1
- package/dist/devices/speaker.js +10 -3
- package/dist/devices/videoRemoteControl.d.ts +11 -0
- package/dist/devices/videoRemoteControl.js +18 -0
- package/dist/frontend.js +2 -0
- package/dist/matterbridgeEndpointCommandHandler.d.ts +22 -0
- package/package.json +5 -5
package/dist/demoDevices.js
CHANGED
|
@@ -3,8 +3,14 @@ import { AirQuality } from '@matter/types/clusters/air-quality';
|
|
|
3
3
|
import { FanControl } from '@matter/types/clusters/fan-control';
|
|
4
4
|
import { PowerSource } from '@matter/types/clusters/power-source';
|
|
5
5
|
import { EndpointNumber } from '@matter/types/datatype';
|
|
6
|
+
import { BasicVideoPlayer } from './devices/basicVideoPlayer.js';
|
|
7
|
+
import { CastingVideoClient } from './devices/castingVideoClient.js';
|
|
8
|
+
import { CastingVideoPlayer } from './devices/castingVideoPlayer.js';
|
|
6
9
|
import { Closure } from './devices/closure.js';
|
|
10
|
+
import { ContentApp } from './devices/contentApp.js';
|
|
7
11
|
import { IrrigationSystem } from './devices/irrigationSystem.js';
|
|
12
|
+
import { Speaker } from './devices/speaker.js';
|
|
13
|
+
import { VideoRemoteControl } from './devices/videoRemoteControl.js';
|
|
8
14
|
import { getSupportedDeviceType } from './matterbridgeDeviceTypes.js';
|
|
9
15
|
import { MatterbridgeEndpoint } from './matterbridgeEndpoint.js';
|
|
10
16
|
import { getSemtag } from './matterbridgeEndpointHelpers.js';
|
|
@@ -251,4 +257,43 @@ export async function createDemoDevices(matterbridge) {
|
|
|
251
257
|
await registerDevice(ep, 'Air Purifier', 'HVAC-09-03');
|
|
252
258
|
ep = new MatterbridgeEndpoint([getSupportedDeviceType('ThermostatController'), bridgedNode, powerSource], { id: 'ThermostatController', number: EndpointNumber(9_04) });
|
|
253
259
|
await registerDevice(ep, 'Thermostat Controller', 'HVAC-09-04');
|
|
260
|
+
ep = new BasicVideoPlayer('Basic Video Player', 'MEDIA-10-02', { id: 'BasicVideoPlayer', number: EndpointNumber(10_02) });
|
|
261
|
+
await registerDevice(ep, 'Basic Video Player', 'MEDIA-10-02');
|
|
262
|
+
ep = new CastingVideoPlayer('Casting Video Player', 'MEDIA-10-03', { id: 'CastingVideoPlayer', number: EndpointNumber(10_03) });
|
|
263
|
+
await registerDevice(ep, 'Casting Video Player', 'MEDIA-10-03');
|
|
264
|
+
ep = new Speaker('Speaker', 'MEDIA-10-04', { id: 'Speaker', number: EndpointNumber(10_04) });
|
|
265
|
+
await registerDevice(ep, 'Speaker', 'MEDIA-10-04');
|
|
266
|
+
ep = new ContentApp('Content App', 'MEDIA-10-05', { id: 'ContentApp', number: EndpointNumber(10_05) });
|
|
267
|
+
await registerDevice(ep, 'Content App', 'MEDIA-10-05');
|
|
268
|
+
ep = new CastingVideoClient('Casting Video Client', 'MEDIA-10-06', { id: 'CastingVideoClient', number: EndpointNumber(10_06) });
|
|
269
|
+
await registerDevice(ep, 'Casting Video Client', 'MEDIA-10-06');
|
|
270
|
+
ep = new VideoRemoteControl('Video Remote Control', 'MEDIA-10-07', { id: 'VideoRemoteControl', number: EndpointNumber(10_07) });
|
|
271
|
+
await registerDevice(ep, 'Video Remote Control', 'MEDIA-10-07');
|
|
272
|
+
ep = new MatterbridgeEndpoint([getSupportedDeviceType('ModeSelect'), bridgedNode, powerSource], { id: 'ModeSelect', number: EndpointNumber(11_01) });
|
|
273
|
+
ep.createDefaultPowerSourceWiredClusterServer();
|
|
274
|
+
ep.createDefaultModeSelectClusterServer('Mode', [
|
|
275
|
+
{ label: 'Mode 1', mode: 0, semanticTags: [] },
|
|
276
|
+
{ label: 'Mode 2', mode: 1, semanticTags: [] },
|
|
277
|
+
]);
|
|
278
|
+
await registerDevice(ep, 'Mode Select', 'GENERIC-11-01');
|
|
279
|
+
ep = new MatterbridgeEndpoint([getSupportedDeviceType('Aggregator'), bridgedNode, powerSource], { id: 'Aggregator', number: EndpointNumber(11_02) });
|
|
280
|
+
ep.createDefaultPowerSourceWiredClusterServer();
|
|
281
|
+
await ep.addFixedLabel('composed', 'Aggregator');
|
|
282
|
+
ep.addChildDeviceType('Plug1', getSupportedDeviceType('OnOffPlugInUnit'), {
|
|
283
|
+
number: EndpointNumber(11_02_1),
|
|
284
|
+
tagList: [getSemtag(CommonNumberTag.One)],
|
|
285
|
+
}).addRequiredClusters();
|
|
286
|
+
ep.addChildDeviceType('Plug2', getSupportedDeviceType('OnOffPlugInUnit'), {
|
|
287
|
+
number: EndpointNumber(11_02_2),
|
|
288
|
+
tagList: [getSemtag(CommonNumberTag.Two)],
|
|
289
|
+
}).addRequiredClusters();
|
|
290
|
+
ep.addChildDeviceType('Plug3', getSupportedDeviceType('OnOffPlugInUnit'), {
|
|
291
|
+
number: EndpointNumber(11_02_3),
|
|
292
|
+
tagList: [getSemtag(CommonNumberTag.Three)],
|
|
293
|
+
}).addRequiredClusters();
|
|
294
|
+
ep.addChildDeviceType('Plug4', getSupportedDeviceType('OnOffPlugInUnit'), {
|
|
295
|
+
number: EndpointNumber(11_02_4),
|
|
296
|
+
tagList: [getSemtag(CommonNumberTag.Four)],
|
|
297
|
+
}).addRequiredClusters();
|
|
298
|
+
await registerDevice(ep, 'Aggregator', 'GENERIC-11-02');
|
|
254
299
|
}
|
|
@@ -1,29 +1,14 @@
|
|
|
1
|
-
import { KeypadInputServer } from '@matter/node/behaviors/keypad-input';
|
|
2
|
-
import { MediaPlaybackServer } from '@matter/node/behaviors/media-playback';
|
|
3
|
-
import { KeypadInput } from '@matter/types/clusters/keypad-input';
|
|
4
1
|
import { MediaPlayback } from '@matter/types/clusters/media-playback';
|
|
2
|
+
import type { EndpointNumber } from '@matter/types/datatype';
|
|
5
3
|
import { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
|
|
4
|
+
import { type MediaPowerSourceType } from './mediaHelpers.js';
|
|
6
5
|
export interface BasicVideoPlayerOptions {
|
|
7
6
|
onOff?: boolean;
|
|
8
7
|
playbackState?: MediaPlayback.PlaybackState;
|
|
8
|
+
powerSourceType?: MediaPowerSourceType;
|
|
9
|
+
id?: string;
|
|
10
|
+
number?: EndpointNumber;
|
|
9
11
|
}
|
|
10
12
|
export declare class BasicVideoPlayer extends MatterbridgeEndpoint {
|
|
11
13
|
constructor(name: string, serial: string, options?: BasicVideoPlayerOptions);
|
|
12
|
-
createDefaultMediaPlaybackClusterServer(currentState: MediaPlayback.PlaybackState): this;
|
|
13
|
-
createDefaultKeypadInputClusterServer(): this;
|
|
14
|
-
}
|
|
15
|
-
export declare class MatterbridgeMediaPlaybackServer extends MediaPlaybackServer {
|
|
16
|
-
initialize(): void;
|
|
17
|
-
protected handleOnOffChange(_onOff: boolean): void;
|
|
18
|
-
play(): Promise<MediaPlayback.PlaybackResponse>;
|
|
19
|
-
pause(): Promise<MediaPlayback.PlaybackResponse>;
|
|
20
|
-
stop(): Promise<MediaPlayback.PlaybackResponse>;
|
|
21
|
-
previous(): Promise<MediaPlayback.PlaybackResponse>;
|
|
22
|
-
next(): Promise<MediaPlayback.PlaybackResponse>;
|
|
23
|
-
skipForward(request: MediaPlayback.SkipForwardRequest): Promise<MediaPlayback.PlaybackResponse>;
|
|
24
|
-
skipBackward(request: MediaPlayback.SkipBackwardRequest): Promise<MediaPlayback.PlaybackResponse>;
|
|
25
|
-
}
|
|
26
|
-
export declare class MatterbridgeKeypadInputServer extends KeypadInputServer {
|
|
27
|
-
initialize(): void;
|
|
28
|
-
sendKey(request: KeypadInput.SendKeyRequest): Promise<KeypadInput.SendKeyResponse>;
|
|
29
14
|
}
|
|
@@ -1,149 +1,18 @@
|
|
|
1
|
-
import { KeypadInputServer } from '@matter/node/behaviors/keypad-input';
|
|
2
|
-
import { MediaPlaybackServer } from '@matter/node/behaviors/media-playback';
|
|
3
|
-
import { KeypadInput } from '@matter/types/clusters/keypad-input';
|
|
4
1
|
import { MediaPlayback } from '@matter/types/clusters/media-playback';
|
|
5
|
-
import { MatterbridgeServer } from '../behaviors/matterbridgeServer.js';
|
|
6
|
-
import { MatterbridgeOnOffServer } from '../behaviors/onOffServer.js';
|
|
7
2
|
import { basicVideoPlayer, powerSource } from '../matterbridgeDeviceTypes.js';
|
|
8
3
|
import { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
|
|
4
|
+
import { createDefaultKeypadInputClusterServer, createDefaultMediaPlaybackClusterServer, createDefaultMediaPowerSourceClusterServer, } from './mediaHelpers.js';
|
|
9
5
|
export class BasicVideoPlayer extends MatterbridgeEndpoint {
|
|
10
6
|
constructor(name, serial, options = {}) {
|
|
11
|
-
const { onOff = false, playbackState = MediaPlayback.PlaybackState.NotPlaying } = options;
|
|
12
|
-
super([basicVideoPlayer
|
|
7
|
+
const { onOff = false, playbackState = MediaPlayback.PlaybackState.NotPlaying, powerSourceType = 'Wired' } = options;
|
|
8
|
+
super(powerSourceType === 'None' ? [basicVideoPlayer] : [basicVideoPlayer, powerSource], {
|
|
9
|
+
id: options.id ?? `${name.replaceAll(' ', '')}-${serial.replaceAll(' ', '')}`,
|
|
10
|
+
number: options.number,
|
|
11
|
+
});
|
|
13
12
|
this.createDefaultBasicInformationClusterServer(name, serial, 0xfff1, 'Matterbridge', 0x8000, 'Matterbridge Basic Video Player');
|
|
14
|
-
this
|
|
13
|
+
createDefaultMediaPowerSourceClusterServer(this, powerSourceType);
|
|
15
14
|
this.createOnOffClusterServer(onOff);
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
createDefaultMediaPlaybackClusterServer(currentState) {
|
|
20
|
-
this.behaviors.require(MatterbridgeMediaPlaybackServer.enable({
|
|
21
|
-
commands: { next: true, previous: true, skipForward: true, skipBackward: true },
|
|
22
|
-
}), {
|
|
23
|
-
currentState,
|
|
24
|
-
});
|
|
25
|
-
return this;
|
|
26
|
-
}
|
|
27
|
-
createDefaultKeypadInputClusterServer() {
|
|
28
|
-
this.behaviors.require(MatterbridgeKeypadInputServer, {});
|
|
29
|
-
return this;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
export class MatterbridgeMediaPlaybackServer extends MediaPlaybackServer {
|
|
33
|
-
initialize() {
|
|
34
|
-
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
35
|
-
device.log.info(`MatterbridgeMediaPlaybackServer initialized: currentState is ${this.state.currentState}`);
|
|
36
|
-
this.reactTo(this.agent.get(MatterbridgeOnOffServer.with()).events.onOff$Changed, this.handleOnOffChange);
|
|
37
|
-
}
|
|
38
|
-
handleOnOffChange(_onOff) {
|
|
39
|
-
this.state.currentState = MediaPlayback.PlaybackState.NotPlaying;
|
|
40
|
-
}
|
|
41
|
-
async play() {
|
|
42
|
-
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
43
|
-
device.log.info(`Play (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
44
|
-
await device.commandHandler.executeHandler('MediaPlayback.play', {
|
|
45
|
-
command: 'play',
|
|
46
|
-
request: {},
|
|
47
|
-
cluster: MediaPlaybackServer.id,
|
|
48
|
-
attributes: this.state,
|
|
49
|
-
endpoint: this.endpoint,
|
|
50
|
-
});
|
|
51
|
-
if (this.endpoint.stateOf(MatterbridgeOnOffServer.with()).onOff)
|
|
52
|
-
this.state.currentState = MediaPlayback.PlaybackState.Playing;
|
|
53
|
-
return { status: MediaPlayback.Status.Success };
|
|
54
|
-
}
|
|
55
|
-
async pause() {
|
|
56
|
-
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
57
|
-
device.log.info(`Pause (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
58
|
-
await device.commandHandler.executeHandler('MediaPlayback.pause', {
|
|
59
|
-
command: 'pause',
|
|
60
|
-
request: {},
|
|
61
|
-
cluster: MediaPlaybackServer.id,
|
|
62
|
-
attributes: this.state,
|
|
63
|
-
endpoint: this.endpoint,
|
|
64
|
-
});
|
|
65
|
-
if (this.endpoint.stateOf(MatterbridgeOnOffServer.with()).onOff)
|
|
66
|
-
this.state.currentState = MediaPlayback.PlaybackState.Paused;
|
|
67
|
-
return { status: MediaPlayback.Status.Success };
|
|
68
|
-
}
|
|
69
|
-
async stop() {
|
|
70
|
-
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
71
|
-
device.log.info(`Stop (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
72
|
-
await device.commandHandler.executeHandler('MediaPlayback.stop', {
|
|
73
|
-
command: 'stop',
|
|
74
|
-
request: {},
|
|
75
|
-
cluster: MediaPlaybackServer.id,
|
|
76
|
-
attributes: this.state,
|
|
77
|
-
endpoint: this.endpoint,
|
|
78
|
-
});
|
|
79
|
-
if (this.endpoint.stateOf(MatterbridgeOnOffServer.with()).onOff)
|
|
80
|
-
this.state.currentState = MediaPlayback.PlaybackState.NotPlaying;
|
|
81
|
-
return { status: MediaPlayback.Status.Success };
|
|
82
|
-
}
|
|
83
|
-
async previous() {
|
|
84
|
-
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
85
|
-
device.log.info(`Previous (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
86
|
-
await device.commandHandler.executeHandler('MediaPlayback.previous', {
|
|
87
|
-
command: 'previous',
|
|
88
|
-
request: {},
|
|
89
|
-
cluster: MediaPlaybackServer.id,
|
|
90
|
-
attributes: this.state,
|
|
91
|
-
endpoint: this.endpoint,
|
|
92
|
-
});
|
|
93
|
-
return { status: MediaPlayback.Status.Success };
|
|
94
|
-
}
|
|
95
|
-
async next() {
|
|
96
|
-
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
97
|
-
device.log.info(`Next (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
98
|
-
await device.commandHandler.executeHandler('MediaPlayback.next', {
|
|
99
|
-
command: 'next',
|
|
100
|
-
request: {},
|
|
101
|
-
cluster: MediaPlaybackServer.id,
|
|
102
|
-
attributes: this.state,
|
|
103
|
-
endpoint: this.endpoint,
|
|
104
|
-
});
|
|
105
|
-
return { status: MediaPlayback.Status.Success };
|
|
106
|
-
}
|
|
107
|
-
async skipForward(request) {
|
|
108
|
-
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
109
|
-
device.log.info(`SkipForward (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
110
|
-
await device.commandHandler.executeHandler('MediaPlayback.skipForward', {
|
|
111
|
-
command: 'skipForward',
|
|
112
|
-
request,
|
|
113
|
-
cluster: MediaPlaybackServer.id,
|
|
114
|
-
attributes: this.state,
|
|
115
|
-
endpoint: this.endpoint,
|
|
116
|
-
});
|
|
117
|
-
return { status: MediaPlayback.Status.Success };
|
|
118
|
-
}
|
|
119
|
-
async skipBackward(request) {
|
|
120
|
-
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
121
|
-
device.log.info(`SkipBackward (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
122
|
-
await device.commandHandler.executeHandler('MediaPlayback.skipBackward', {
|
|
123
|
-
command: 'skipBackward',
|
|
124
|
-
request,
|
|
125
|
-
cluster: MediaPlaybackServer.id,
|
|
126
|
-
attributes: this.state,
|
|
127
|
-
endpoint: this.endpoint,
|
|
128
|
-
});
|
|
129
|
-
return { status: MediaPlayback.Status.Success };
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
export class MatterbridgeKeypadInputServer extends KeypadInputServer {
|
|
133
|
-
initialize() {
|
|
134
|
-
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
135
|
-
device.log.info(`MatterbridgeKeypadInputServer initialized`);
|
|
136
|
-
}
|
|
137
|
-
async sendKey(request) {
|
|
138
|
-
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
139
|
-
device.log.info(`SendKey keyCode ${request.keyCode} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
140
|
-
await device.commandHandler.executeHandler('KeypadInput.sendKey', {
|
|
141
|
-
command: 'sendKey',
|
|
142
|
-
request,
|
|
143
|
-
cluster: KeypadInputServer.id,
|
|
144
|
-
attributes: {},
|
|
145
|
-
endpoint: this.endpoint,
|
|
146
|
-
});
|
|
147
|
-
return { status: KeypadInput.Status.Success };
|
|
15
|
+
createDefaultMediaPlaybackClusterServer(this, playbackState, true);
|
|
16
|
+
createDefaultKeypadInputClusterServer(this);
|
|
148
17
|
}
|
|
149
18
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { EndpointNumber } from '@matter/types/datatype';
|
|
2
|
+
import { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
|
|
3
|
+
import { type MediaPowerSourceType } from './mediaHelpers.js';
|
|
4
|
+
export interface CastingVideoClientOptions {
|
|
5
|
+
powerSourceType?: MediaPowerSourceType;
|
|
6
|
+
id?: string;
|
|
7
|
+
number?: EndpointNumber;
|
|
8
|
+
}
|
|
9
|
+
export declare class CastingVideoClient extends MatterbridgeEndpoint {
|
|
10
|
+
constructor(name: string, serial: string, options?: CastingVideoClientOptions);
|
|
11
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ApplicationBasic } from '@matter/types/clusters/application-basic';
|
|
2
|
+
import { ContentLauncher } from '@matter/types/clusters/content-launcher';
|
|
3
|
+
import { KeypadInput } from '@matter/types/clusters/keypad-input';
|
|
4
|
+
import { OnOff } from '@matter/types/clusters/on-off';
|
|
5
|
+
import { castingVideoClient, powerSource } from '../matterbridgeDeviceTypes.js';
|
|
6
|
+
import { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
|
|
7
|
+
import { createDefaultMediaBindingClusterServer, createDefaultMediaPowerSourceClusterServer } from './mediaHelpers.js';
|
|
8
|
+
export class CastingVideoClient extends MatterbridgeEndpoint {
|
|
9
|
+
constructor(name, serial, options = {}) {
|
|
10
|
+
const { powerSourceType = 'Wired' } = options;
|
|
11
|
+
super(powerSourceType === 'None' ? [castingVideoClient] : [castingVideoClient, powerSource], {
|
|
12
|
+
id: options.id ?? `${name.replaceAll(' ', '')}-${serial.replaceAll(' ', '')}`,
|
|
13
|
+
number: options.number,
|
|
14
|
+
});
|
|
15
|
+
this.createDefaultBasicInformationClusterServer(name, serial, 0xfff1, 'Matterbridge', 0x8000, 'Matterbridge Casting Video Client');
|
|
16
|
+
createDefaultMediaPowerSourceClusterServer(this, powerSourceType);
|
|
17
|
+
createDefaultMediaBindingClusterServer(this, [OnOff.id, KeypadInput.id, ContentLauncher.id, ApplicationBasic.id]);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
import { ContentLauncherServer } from '@matter/node/behaviors/content-launcher';
|
|
2
1
|
import { MediaPlayback } from '@matter/types/clusters/media-playback';
|
|
2
|
+
import type { EndpointNumber } from '@matter/types/datatype';
|
|
3
3
|
import { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
|
|
4
|
+
import { type MediaPowerSourceType } from './mediaHelpers.js';
|
|
4
5
|
export interface CastingVideoPlayerOptions {
|
|
5
6
|
onOff?: boolean;
|
|
6
7
|
playbackState?: MediaPlayback.PlaybackState;
|
|
8
|
+
powerSourceType?: MediaPowerSourceType;
|
|
9
|
+
id?: string;
|
|
10
|
+
number?: EndpointNumber;
|
|
7
11
|
}
|
|
8
12
|
export declare class CastingVideoPlayer extends MatterbridgeEndpoint {
|
|
9
13
|
constructor(name: string, serial: string, options?: CastingVideoPlayerOptions);
|
|
10
|
-
createDefaultMediaPlaybackClusterServer(currentState: MediaPlayback.PlaybackState): this;
|
|
11
|
-
createDefaultKeypadInputClusterServer(): this;
|
|
12
|
-
createDefaultContentLauncherClusterServer(): this;
|
|
13
|
-
}
|
|
14
|
-
export declare class MatterbridgeContentLauncherServer extends ContentLauncherServer {
|
|
15
|
-
initialize(): void;
|
|
16
14
|
}
|
|
@@ -1,38 +1,19 @@
|
|
|
1
|
-
import { ContentLauncherServer } from '@matter/node/behaviors/content-launcher';
|
|
2
1
|
import { MediaPlayback } from '@matter/types/clusters/media-playback';
|
|
3
|
-
import { MatterbridgeServer } from '../behaviors/matterbridgeServer.js';
|
|
4
2
|
import { castingVideoPlayer, powerSource } from '../matterbridgeDeviceTypes.js';
|
|
5
3
|
import { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
|
|
6
|
-
import {
|
|
4
|
+
import { createDefaultContentLauncherClusterServer, createDefaultKeypadInputClusterServer, createDefaultMediaPlaybackClusterServer, createDefaultMediaPowerSourceClusterServer, } from './mediaHelpers.js';
|
|
7
5
|
export class CastingVideoPlayer extends MatterbridgeEndpoint {
|
|
8
6
|
constructor(name, serial, options = {}) {
|
|
9
|
-
const { onOff = false, playbackState = MediaPlayback.PlaybackState.NotPlaying } = options;
|
|
10
|
-
super([castingVideoPlayer
|
|
7
|
+
const { onOff = false, playbackState = MediaPlayback.PlaybackState.NotPlaying, powerSourceType = 'Wired' } = options;
|
|
8
|
+
super(powerSourceType === 'None' ? [castingVideoPlayer] : [castingVideoPlayer, powerSource], {
|
|
9
|
+
id: options.id ?? `${name.replaceAll(' ', '')}-${serial.replaceAll(' ', '')}`,
|
|
10
|
+
number: options.number,
|
|
11
|
+
});
|
|
11
12
|
this.createDefaultBasicInformationClusterServer(name, serial, 0xfff1, 'Matterbridge', 0x8000, 'Matterbridge Casting Video Player');
|
|
12
|
-
this
|
|
13
|
+
createDefaultMediaPowerSourceClusterServer(this, powerSourceType);
|
|
13
14
|
this.createOnOffClusterServer(onOff);
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
createDefaultMediaPlaybackClusterServer(currentState) {
|
|
19
|
-
this.behaviors.require(MatterbridgeMediaPlaybackServer, {
|
|
20
|
-
currentState,
|
|
21
|
-
});
|
|
22
|
-
return this;
|
|
23
|
-
}
|
|
24
|
-
createDefaultKeypadInputClusterServer() {
|
|
25
|
-
this.behaviors.require(MatterbridgeKeypadInputServer, {});
|
|
26
|
-
return this;
|
|
27
|
-
}
|
|
28
|
-
createDefaultContentLauncherClusterServer() {
|
|
29
|
-
this.behaviors.require(MatterbridgeContentLauncherServer, {});
|
|
30
|
-
return this;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
export class MatterbridgeContentLauncherServer extends ContentLauncherServer {
|
|
34
|
-
initialize() {
|
|
35
|
-
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
36
|
-
device.log.info(`MatterbridgeContentLauncherServer initialized`);
|
|
15
|
+
createDefaultMediaPlaybackClusterServer(this, playbackState);
|
|
16
|
+
createDefaultKeypadInputClusterServer(this);
|
|
17
|
+
createDefaultContentLauncherClusterServer(this);
|
|
37
18
|
}
|
|
38
19
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ApplicationBasic } from '@matter/types/clusters/application-basic';
|
|
2
|
+
import { VendorId } from '@matter/types/datatype';
|
|
3
|
+
import type { EndpointNumber } from '@matter/types/datatype';
|
|
4
|
+
import { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
|
|
5
|
+
import { type MediaPowerSourceType } from './mediaHelpers.js';
|
|
6
|
+
export interface ContentAppOptions {
|
|
7
|
+
applicationName?: string;
|
|
8
|
+
catalogVendorId?: number;
|
|
9
|
+
applicationId?: string;
|
|
10
|
+
status?: ApplicationBasic.ApplicationStatus;
|
|
11
|
+
applicationVersion?: string;
|
|
12
|
+
allowedVendorList?: VendorId[];
|
|
13
|
+
powerSourceType?: MediaPowerSourceType;
|
|
14
|
+
id?: string;
|
|
15
|
+
number?: EndpointNumber;
|
|
16
|
+
}
|
|
17
|
+
export declare class ContentApp extends MatterbridgeEndpoint {
|
|
18
|
+
constructor(name: string, serial: string, options?: ContentAppOptions);
|
|
19
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ApplicationBasic } from '@matter/types/clusters/application-basic';
|
|
2
|
+
import { VendorId } from '@matter/types/datatype';
|
|
3
|
+
import { contentApp, powerSource } from '../matterbridgeDeviceTypes.js';
|
|
4
|
+
import { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
|
|
5
|
+
import { createDefaultApplicationBasicClusterServer, createDefaultApplicationLauncherClusterServer, createDefaultKeypadInputClusterServer, createDefaultMediaPowerSourceClusterServer, } from './mediaHelpers.js';
|
|
6
|
+
export class ContentApp extends MatterbridgeEndpoint {
|
|
7
|
+
constructor(name, serial, options = {}) {
|
|
8
|
+
const { applicationName = name, catalogVendorId = 0xfff1, applicationId = 'matterbridge-content-app', status = ApplicationBasic.ApplicationStatus.ActiveVisibleFocus, applicationVersion = '1.0.0', allowedVendorList = [VendorId(0xfff1)], powerSourceType = 'Wired', } = options;
|
|
9
|
+
super(powerSourceType === 'None' ? [contentApp] : [contentApp, powerSource], {
|
|
10
|
+
id: options.id ?? `${name.replaceAll(' ', '')}-${serial.replaceAll(' ', '')}`,
|
|
11
|
+
number: options.number,
|
|
12
|
+
});
|
|
13
|
+
this.createDefaultBasicInformationClusterServer(name, serial, 0xfff1, 'Matterbridge', 0x8000, 'Matterbridge Content App');
|
|
14
|
+
createDefaultMediaPowerSourceClusterServer(this, powerSourceType);
|
|
15
|
+
createDefaultKeypadInputClusterServer(this);
|
|
16
|
+
createDefaultApplicationLauncherClusterServer(this);
|
|
17
|
+
createDefaultApplicationBasicClusterServer(this, applicationName, catalogVendorId, applicationId, status, applicationVersion, allowedVendorList);
|
|
18
|
+
}
|
|
19
|
+
}
|
package/dist/devices/export.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export * from './basicVideoPlayer.js';
|
|
2
|
+
export * from './castingVideoClient.js';
|
|
2
3
|
export * from './castingVideoPlayer.js';
|
|
4
|
+
export * from './contentApp.js';
|
|
5
|
+
export * from './mediaHelpers.js';
|
|
3
6
|
export * from './speaker.js';
|
|
7
|
+
export * from './videoRemoteControl.js';
|
|
4
8
|
export * from './closure.js';
|
|
5
9
|
export * from './closurePanel.js';
|
|
6
10
|
export * from './irrigationSystem.js';
|
package/dist/devices/export.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export * from './basicVideoPlayer.js';
|
|
2
|
+
export * from './castingVideoClient.js';
|
|
2
3
|
export * from './castingVideoPlayer.js';
|
|
4
|
+
export * from './contentApp.js';
|
|
5
|
+
export * from './mediaHelpers.js';
|
|
3
6
|
export * from './speaker.js';
|
|
7
|
+
export * from './videoRemoteControl.js';
|
|
4
8
|
export * from './closure.js';
|
|
5
9
|
export * from './closurePanel.js';
|
|
6
10
|
export * from './irrigationSystem.js';
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { ApplicationBasicServer } from '@matter/node/behaviors/application-basic';
|
|
2
|
+
import { ApplicationLauncherServer } from '@matter/node/behaviors/application-launcher';
|
|
3
|
+
import { ContentLauncherServer } from '@matter/node/behaviors/content-launcher';
|
|
4
|
+
import { KeypadInputServer } from '@matter/node/behaviors/keypad-input';
|
|
5
|
+
import { MediaPlaybackServer } from '@matter/node/behaviors/media-playback';
|
|
6
|
+
import { ApplicationBasic } from '@matter/types/clusters/application-basic';
|
|
7
|
+
import { ApplicationLauncher } from '@matter/types/clusters/application-launcher';
|
|
8
|
+
import { KeypadInput } from '@matter/types/clusters/keypad-input';
|
|
9
|
+
import { MediaPlayback } from '@matter/types/clusters/media-playback';
|
|
10
|
+
import type { ClusterId, VendorId } from '@matter/types/datatype';
|
|
11
|
+
import type { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
|
|
12
|
+
export declare class MatterbridgeMediaPlaybackServer extends MediaPlaybackServer {
|
|
13
|
+
initialize(): void;
|
|
14
|
+
protected handleOnOffChange(_onOff: boolean): void;
|
|
15
|
+
play(): Promise<MediaPlayback.PlaybackResponse>;
|
|
16
|
+
pause(): Promise<MediaPlayback.PlaybackResponse>;
|
|
17
|
+
stop(): Promise<MediaPlayback.PlaybackResponse>;
|
|
18
|
+
previous(): Promise<MediaPlayback.PlaybackResponse>;
|
|
19
|
+
next(): Promise<MediaPlayback.PlaybackResponse>;
|
|
20
|
+
skipForward(request: MediaPlayback.SkipForwardRequest): Promise<MediaPlayback.PlaybackResponse>;
|
|
21
|
+
skipBackward(request: MediaPlayback.SkipBackwardRequest): Promise<MediaPlayback.PlaybackResponse>;
|
|
22
|
+
}
|
|
23
|
+
export declare class MatterbridgeKeypadInputServer extends KeypadInputServer {
|
|
24
|
+
initialize(): void;
|
|
25
|
+
sendKey(request: KeypadInput.SendKeyRequest): Promise<KeypadInput.SendKeyResponse>;
|
|
26
|
+
}
|
|
27
|
+
export declare class MatterbridgeContentLauncherServer extends ContentLauncherServer {
|
|
28
|
+
initialize(): void;
|
|
29
|
+
}
|
|
30
|
+
export declare class MatterbridgeApplicationBasicServer extends ApplicationBasicServer {
|
|
31
|
+
initialize(): void;
|
|
32
|
+
}
|
|
33
|
+
export declare class MatterbridgeApplicationLauncherServer extends ApplicationLauncherServer {
|
|
34
|
+
initialize(): void;
|
|
35
|
+
launchApp(request: ApplicationLauncher.LaunchAppRequest): Promise<ApplicationLauncher.LauncherResponse>;
|
|
36
|
+
stopApp(request: ApplicationLauncher.StopAppRequest): Promise<ApplicationLauncher.LauncherResponse>;
|
|
37
|
+
hideApp(request: ApplicationLauncher.HideAppRequest): Promise<ApplicationLauncher.LauncherResponse>;
|
|
38
|
+
}
|
|
39
|
+
export declare function createDefaultMediaPlaybackClusterServer(endpoint: MatterbridgeEndpoint, currentState: MediaPlayback.PlaybackState, extendedCommands?: boolean): void;
|
|
40
|
+
export declare function createDefaultKeypadInputClusterServer(endpoint: MatterbridgeEndpoint): void;
|
|
41
|
+
export declare function createDefaultContentLauncherClusterServer(endpoint: MatterbridgeEndpoint): void;
|
|
42
|
+
export declare function createDefaultApplicationLauncherClusterServer(endpoint: MatterbridgeEndpoint): void;
|
|
43
|
+
export declare function createDefaultApplicationBasicClusterServer(endpoint: MatterbridgeEndpoint, applicationName: string, catalogVendorId: number, applicationId: string, status: ApplicationBasic.ApplicationStatus, applicationVersion: string, allowedVendorList: VendorId[]): void;
|
|
44
|
+
export declare function createDefaultMediaBindingClusterServer(endpoint: MatterbridgeEndpoint, clientList: ClusterId[]): void;
|
|
45
|
+
export type MediaPowerSourceType = 'Rechargeable' | 'Replaceable' | 'Battery' | 'Wired' | 'None';
|
|
46
|
+
export declare function createDefaultMediaPowerSourceClusterServer(endpoint: MatterbridgeEndpoint, powerSourceType: MediaPowerSourceType): void;
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { AccountLoginClient } from '@matter/node/behaviors/account-login';
|
|
2
|
+
import { ApplicationBasicClient, ApplicationBasicServer } from '@matter/node/behaviors/application-basic';
|
|
3
|
+
import { ApplicationLauncherClient, ApplicationLauncherServer } from '@matter/node/behaviors/application-launcher';
|
|
4
|
+
import { AudioOutputClient } from '@matter/node/behaviors/audio-output';
|
|
5
|
+
import { ChannelClient } from '@matter/node/behaviors/channel';
|
|
6
|
+
import { ContentAppObserverClient } from '@matter/node/behaviors/content-app-observer';
|
|
7
|
+
import { ContentControlClient } from '@matter/node/behaviors/content-control';
|
|
8
|
+
import { ContentLauncherClient, ContentLauncherServer } from '@matter/node/behaviors/content-launcher';
|
|
9
|
+
import { KeypadInputClient, KeypadInputServer } from '@matter/node/behaviors/keypad-input';
|
|
10
|
+
import { LevelControlClient } from '@matter/node/behaviors/level-control';
|
|
11
|
+
import { LowPowerClient } from '@matter/node/behaviors/low-power';
|
|
12
|
+
import { MediaInputClient } from '@matter/node/behaviors/media-input';
|
|
13
|
+
import { MediaPlaybackClient, MediaPlaybackServer } from '@matter/node/behaviors/media-playback';
|
|
14
|
+
import { MessagesClient } from '@matter/node/behaviors/messages';
|
|
15
|
+
import { OnOffClient } from '@matter/node/behaviors/on-off';
|
|
16
|
+
import { TargetNavigatorClient } from '@matter/node/behaviors/target-navigator';
|
|
17
|
+
import { WakeOnLanClient } from '@matter/node/behaviors/wake-on-lan';
|
|
18
|
+
import { getClusterNameById } from '@matter/types/cluster';
|
|
19
|
+
import { AccountLogin } from '@matter/types/clusters/account-login';
|
|
20
|
+
import { ApplicationBasic } from '@matter/types/clusters/application-basic';
|
|
21
|
+
import { ApplicationLauncher } from '@matter/types/clusters/application-launcher';
|
|
22
|
+
import { AudioOutput } from '@matter/types/clusters/audio-output';
|
|
23
|
+
import { Channel } from '@matter/types/clusters/channel';
|
|
24
|
+
import { ContentAppObserver } from '@matter/types/clusters/content-app-observer';
|
|
25
|
+
import { ContentControl } from '@matter/types/clusters/content-control';
|
|
26
|
+
import { ContentLauncher } from '@matter/types/clusters/content-launcher';
|
|
27
|
+
import { KeypadInput } from '@matter/types/clusters/keypad-input';
|
|
28
|
+
import { LevelControl } from '@matter/types/clusters/level-control';
|
|
29
|
+
import { LowPower } from '@matter/types/clusters/low-power';
|
|
30
|
+
import { MediaInput } from '@matter/types/clusters/media-input';
|
|
31
|
+
import { MediaPlayback } from '@matter/types/clusters/media-playback';
|
|
32
|
+
import { Messages } from '@matter/types/clusters/messages';
|
|
33
|
+
import { OnOff } from '@matter/types/clusters/on-off';
|
|
34
|
+
import { TargetNavigator } from '@matter/types/clusters/target-navigator';
|
|
35
|
+
import { WakeOnLan } from '@matter/types/clusters/wake-on-lan';
|
|
36
|
+
import { MatterbridgeBindingServer } from '../behaviors/bindingServer.js';
|
|
37
|
+
import { MatterbridgeServer } from '../behaviors/matterbridgeServer.js';
|
|
38
|
+
import { MatterbridgeOnOffServer } from '../behaviors/onOffServer.js';
|
|
39
|
+
import { lowercaseFirstLetter } from '../matterbridgeEndpointHelpers.js';
|
|
40
|
+
export class MatterbridgeMediaPlaybackServer extends MediaPlaybackServer {
|
|
41
|
+
initialize() {
|
|
42
|
+
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
43
|
+
device.log.info(`MatterbridgeMediaPlaybackServer initialized: currentState is ${this.state.currentState}`);
|
|
44
|
+
this.reactTo(this.agent.get(MatterbridgeOnOffServer.with()).events.onOff$Changed, this.handleOnOffChange);
|
|
45
|
+
}
|
|
46
|
+
handleOnOffChange(_onOff) {
|
|
47
|
+
this.state.currentState = MediaPlayback.PlaybackState.NotPlaying;
|
|
48
|
+
}
|
|
49
|
+
async play() {
|
|
50
|
+
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
51
|
+
device.log.info(`Play (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
52
|
+
await device.commandHandler.executeHandler('MediaPlayback.play', {
|
|
53
|
+
command: 'play',
|
|
54
|
+
request: {},
|
|
55
|
+
cluster: MediaPlaybackServer.id,
|
|
56
|
+
attributes: this.state,
|
|
57
|
+
endpoint: this.endpoint,
|
|
58
|
+
});
|
|
59
|
+
if (this.endpoint.stateOf(MatterbridgeOnOffServer.with()).onOff)
|
|
60
|
+
this.state.currentState = MediaPlayback.PlaybackState.Playing;
|
|
61
|
+
return { status: MediaPlayback.Status.Success };
|
|
62
|
+
}
|
|
63
|
+
async pause() {
|
|
64
|
+
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
65
|
+
device.log.info(`Pause (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
66
|
+
await device.commandHandler.executeHandler('MediaPlayback.pause', {
|
|
67
|
+
command: 'pause',
|
|
68
|
+
request: {},
|
|
69
|
+
cluster: MediaPlaybackServer.id,
|
|
70
|
+
attributes: this.state,
|
|
71
|
+
endpoint: this.endpoint,
|
|
72
|
+
});
|
|
73
|
+
if (this.endpoint.stateOf(MatterbridgeOnOffServer.with()).onOff)
|
|
74
|
+
this.state.currentState = MediaPlayback.PlaybackState.Paused;
|
|
75
|
+
return { status: MediaPlayback.Status.Success };
|
|
76
|
+
}
|
|
77
|
+
async stop() {
|
|
78
|
+
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
79
|
+
device.log.info(`Stop (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
80
|
+
await device.commandHandler.executeHandler('MediaPlayback.stop', {
|
|
81
|
+
command: 'stop',
|
|
82
|
+
request: {},
|
|
83
|
+
cluster: MediaPlaybackServer.id,
|
|
84
|
+
attributes: this.state,
|
|
85
|
+
endpoint: this.endpoint,
|
|
86
|
+
});
|
|
87
|
+
if (this.endpoint.stateOf(MatterbridgeOnOffServer.with()).onOff)
|
|
88
|
+
this.state.currentState = MediaPlayback.PlaybackState.NotPlaying;
|
|
89
|
+
return { status: MediaPlayback.Status.Success };
|
|
90
|
+
}
|
|
91
|
+
async previous() {
|
|
92
|
+
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
93
|
+
device.log.info(`Previous (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
94
|
+
await device.commandHandler.executeHandler('MediaPlayback.previous', {
|
|
95
|
+
command: 'previous',
|
|
96
|
+
request: {},
|
|
97
|
+
cluster: MediaPlaybackServer.id,
|
|
98
|
+
attributes: this.state,
|
|
99
|
+
endpoint: this.endpoint,
|
|
100
|
+
});
|
|
101
|
+
return { status: MediaPlayback.Status.Success };
|
|
102
|
+
}
|
|
103
|
+
async next() {
|
|
104
|
+
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
105
|
+
device.log.info(`Next (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
106
|
+
await device.commandHandler.executeHandler('MediaPlayback.next', {
|
|
107
|
+
command: 'next',
|
|
108
|
+
request: {},
|
|
109
|
+
cluster: MediaPlaybackServer.id,
|
|
110
|
+
attributes: this.state,
|
|
111
|
+
endpoint: this.endpoint,
|
|
112
|
+
});
|
|
113
|
+
return { status: MediaPlayback.Status.Success };
|
|
114
|
+
}
|
|
115
|
+
async skipForward(request) {
|
|
116
|
+
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
117
|
+
device.log.info(`SkipForward (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
118
|
+
await device.commandHandler.executeHandler('MediaPlayback.skipForward', {
|
|
119
|
+
command: 'skipForward',
|
|
120
|
+
request,
|
|
121
|
+
cluster: MediaPlaybackServer.id,
|
|
122
|
+
attributes: this.state,
|
|
123
|
+
endpoint: this.endpoint,
|
|
124
|
+
});
|
|
125
|
+
return { status: MediaPlayback.Status.Success };
|
|
126
|
+
}
|
|
127
|
+
async skipBackward(request) {
|
|
128
|
+
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
129
|
+
device.log.info(`SkipBackward (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
130
|
+
await device.commandHandler.executeHandler('MediaPlayback.skipBackward', {
|
|
131
|
+
command: 'skipBackward',
|
|
132
|
+
request,
|
|
133
|
+
cluster: MediaPlaybackServer.id,
|
|
134
|
+
attributes: this.state,
|
|
135
|
+
endpoint: this.endpoint,
|
|
136
|
+
});
|
|
137
|
+
return { status: MediaPlayback.Status.Success };
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
export class MatterbridgeKeypadInputServer extends KeypadInputServer {
|
|
141
|
+
initialize() {
|
|
142
|
+
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
143
|
+
device.log.info(`MatterbridgeKeypadInputServer initialized`);
|
|
144
|
+
}
|
|
145
|
+
async sendKey(request) {
|
|
146
|
+
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
147
|
+
device.log.info(`SendKey keyCode ${request.keyCode} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
148
|
+
await device.commandHandler.executeHandler('KeypadInput.sendKey', {
|
|
149
|
+
command: 'sendKey',
|
|
150
|
+
request,
|
|
151
|
+
cluster: KeypadInputServer.id,
|
|
152
|
+
attributes: {},
|
|
153
|
+
endpoint: this.endpoint,
|
|
154
|
+
});
|
|
155
|
+
return { status: KeypadInput.Status.Success };
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
export class MatterbridgeContentLauncherServer extends ContentLauncherServer {
|
|
159
|
+
initialize() {
|
|
160
|
+
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
161
|
+
device.log.info(`MatterbridgeContentLauncherServer initialized`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
export class MatterbridgeApplicationBasicServer extends ApplicationBasicServer {
|
|
165
|
+
initialize() {
|
|
166
|
+
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
167
|
+
device.log.info(`MatterbridgeApplicationBasicServer initialized`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
export class MatterbridgeApplicationLauncherServer extends ApplicationLauncherServer {
|
|
171
|
+
initialize() {
|
|
172
|
+
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
173
|
+
device.log.info(`MatterbridgeApplicationLauncherServer initialized`);
|
|
174
|
+
}
|
|
175
|
+
async launchApp(request) {
|
|
176
|
+
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
177
|
+
device.log.info(`LaunchApp (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
178
|
+
await device.commandHandler.executeHandler('ApplicationLauncher.launchApp', {
|
|
179
|
+
command: 'launchApp',
|
|
180
|
+
request,
|
|
181
|
+
cluster: ApplicationLauncherServer.id,
|
|
182
|
+
attributes: this.state,
|
|
183
|
+
endpoint: this.endpoint,
|
|
184
|
+
});
|
|
185
|
+
return { status: ApplicationLauncher.Status.Success };
|
|
186
|
+
}
|
|
187
|
+
async stopApp(request) {
|
|
188
|
+
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
189
|
+
device.log.info(`StopApp (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
190
|
+
await device.commandHandler.executeHandler('ApplicationLauncher.stopApp', {
|
|
191
|
+
command: 'stopApp',
|
|
192
|
+
request,
|
|
193
|
+
cluster: ApplicationLauncherServer.id,
|
|
194
|
+
attributes: this.state,
|
|
195
|
+
endpoint: this.endpoint,
|
|
196
|
+
});
|
|
197
|
+
return { status: ApplicationLauncher.Status.Success };
|
|
198
|
+
}
|
|
199
|
+
async hideApp(request) {
|
|
200
|
+
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
201
|
+
device.log.info(`HideApp (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
202
|
+
await device.commandHandler.executeHandler('ApplicationLauncher.hideApp', {
|
|
203
|
+
command: 'hideApp',
|
|
204
|
+
request,
|
|
205
|
+
cluster: ApplicationLauncherServer.id,
|
|
206
|
+
attributes: this.state,
|
|
207
|
+
endpoint: this.endpoint,
|
|
208
|
+
});
|
|
209
|
+
return { status: ApplicationLauncher.Status.Success };
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
export function createDefaultMediaPlaybackClusterServer(endpoint, currentState, extendedCommands = false) {
|
|
213
|
+
endpoint.behaviors.require(extendedCommands
|
|
214
|
+
? MatterbridgeMediaPlaybackServer.enable({ commands: { next: true, previous: true, skipForward: true, skipBackward: true } })
|
|
215
|
+
: MatterbridgeMediaPlaybackServer, { currentState });
|
|
216
|
+
}
|
|
217
|
+
export function createDefaultKeypadInputClusterServer(endpoint) {
|
|
218
|
+
endpoint.behaviors.require(MatterbridgeKeypadInputServer, {});
|
|
219
|
+
}
|
|
220
|
+
export function createDefaultContentLauncherClusterServer(endpoint) {
|
|
221
|
+
endpoint.behaviors.require(MatterbridgeContentLauncherServer, {});
|
|
222
|
+
}
|
|
223
|
+
export function createDefaultApplicationLauncherClusterServer(endpoint) {
|
|
224
|
+
endpoint.behaviors.require(MatterbridgeApplicationLauncherServer, {
|
|
225
|
+
currentApp: null,
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
export function createDefaultApplicationBasicClusterServer(endpoint, applicationName, catalogVendorId, applicationId, status, applicationVersion, allowedVendorList) {
|
|
229
|
+
endpoint.behaviors.require(MatterbridgeApplicationBasicServer, {
|
|
230
|
+
applicationName,
|
|
231
|
+
application: new ApplicationBasic.Application({ catalogVendorId, applicationId }),
|
|
232
|
+
status,
|
|
233
|
+
applicationVersion,
|
|
234
|
+
allowedVendorList,
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
const mediaClientBehaviors = new Map([
|
|
238
|
+
[OnOff.id, OnOffClient],
|
|
239
|
+
[KeypadInput.id, KeypadInputClient],
|
|
240
|
+
[MediaPlayback.id, MediaPlaybackClient],
|
|
241
|
+
[ContentLauncher.id, ContentLauncherClient],
|
|
242
|
+
[ApplicationBasic.id, ApplicationBasicClient],
|
|
243
|
+
[LevelControl.id, LevelControlClient],
|
|
244
|
+
[Messages.id, MessagesClient],
|
|
245
|
+
[WakeOnLan.id, WakeOnLanClient],
|
|
246
|
+
[Channel.id, ChannelClient],
|
|
247
|
+
[TargetNavigator.id, TargetNavigatorClient],
|
|
248
|
+
[MediaInput.id, MediaInputClient],
|
|
249
|
+
[LowPower.id, LowPowerClient],
|
|
250
|
+
[AudioOutput.id, AudioOutputClient],
|
|
251
|
+
[ApplicationLauncher.id, ApplicationLauncherClient],
|
|
252
|
+
[AccountLogin.id, AccountLoginClient],
|
|
253
|
+
[ContentControl.id, ContentControlClient],
|
|
254
|
+
[ContentAppObserver.id, ContentAppObserverClient],
|
|
255
|
+
]);
|
|
256
|
+
export function createDefaultMediaBindingClusterServer(endpoint, clientList) {
|
|
257
|
+
endpoint.behaviors.require(MatterbridgeBindingServer, { clientList });
|
|
258
|
+
for (const clusterId of clientList) {
|
|
259
|
+
const client = mediaClientBehaviors.get(clusterId);
|
|
260
|
+
if (client)
|
|
261
|
+
endpoint.type.clientClusters[lowercaseFirstLetter(getClusterNameById(clusterId))] ??= client;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
export function createDefaultMediaPowerSourceClusterServer(endpoint, powerSourceType) {
|
|
265
|
+
switch (powerSourceType) {
|
|
266
|
+
case 'Rechargeable':
|
|
267
|
+
endpoint.createDefaultPowerSourceRechargeableBatteryClusterServer();
|
|
268
|
+
break;
|
|
269
|
+
case 'Replaceable':
|
|
270
|
+
endpoint.createDefaultPowerSourceReplaceableBatteryClusterServer();
|
|
271
|
+
break;
|
|
272
|
+
case 'Battery':
|
|
273
|
+
endpoint.createDefaultPowerSourceBatteryClusterServer();
|
|
274
|
+
break;
|
|
275
|
+
case 'Wired':
|
|
276
|
+
endpoint.createDefaultPowerSourceWiredClusterServer();
|
|
277
|
+
break;
|
|
278
|
+
case 'None':
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
@@ -1,6 +1,15 @@
|
|
|
1
|
+
import type { EndpointNumber } from '@matter/types/datatype';
|
|
1
2
|
import { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
|
|
3
|
+
import { type MediaPowerSourceType } from './mediaHelpers.js';
|
|
4
|
+
export interface SpeakerOptions {
|
|
5
|
+
muted?: boolean;
|
|
6
|
+
volume?: number;
|
|
7
|
+
powerSourceType?: MediaPowerSourceType;
|
|
8
|
+
id?: string;
|
|
9
|
+
number?: EndpointNumber;
|
|
10
|
+
}
|
|
2
11
|
export declare class Speaker extends MatterbridgeEndpoint {
|
|
3
|
-
constructor(name: string, serial: string,
|
|
12
|
+
constructor(name: string, serial: string, options?: SpeakerOptions);
|
|
4
13
|
setMuted(muted: boolean): Promise<void>;
|
|
5
14
|
isMuted(): boolean;
|
|
6
15
|
setVolume(level: number): Promise<void>;
|
package/dist/devices/speaker.js
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
import { LevelControl } from '@matter/types/clusters/level-control';
|
|
2
2
|
import { OnOff } from '@matter/types/clusters/on-off';
|
|
3
|
-
import { speaker } from '../matterbridgeDeviceTypes.js';
|
|
3
|
+
import { powerSource, speaker } from '../matterbridgeDeviceTypes.js';
|
|
4
4
|
import { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
|
|
5
|
+
import { createDefaultMediaPowerSourceClusterServer } from './mediaHelpers.js';
|
|
5
6
|
export class Speaker extends MatterbridgeEndpoint {
|
|
6
|
-
constructor(name, serial,
|
|
7
|
+
constructor(name, serial, options = {}) {
|
|
8
|
+
const { muted = false, powerSourceType = 'Wired' } = options;
|
|
9
|
+
let { volume = 128 } = options;
|
|
7
10
|
if (!Number.isFinite(volume))
|
|
8
11
|
volume = 128;
|
|
9
12
|
if (volume < 1)
|
|
10
13
|
volume = 1;
|
|
11
14
|
if (volume > 254)
|
|
12
15
|
volume = 254;
|
|
13
|
-
super([speaker]
|
|
16
|
+
super(powerSourceType === 'None' ? [speaker] : [speaker, powerSource], {
|
|
17
|
+
id: options.id ?? `${name.replaceAll(' ', '')}-${serial.replaceAll(' ', '')}`,
|
|
18
|
+
number: options.number,
|
|
19
|
+
});
|
|
14
20
|
this.createDefaultBasicInformationClusterServer(name, serial, 0xfff1, 'Matterbridge', 0x8000, 'Matterbridge Speaker');
|
|
21
|
+
createDefaultMediaPowerSourceClusterServer(this, powerSourceType);
|
|
15
22
|
this.createOnOffClusterServer(!muted);
|
|
16
23
|
this.createLevelControlClusterServer(volume);
|
|
17
24
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { EndpointNumber } from '@matter/types/datatype';
|
|
2
|
+
import { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
|
|
3
|
+
import { type MediaPowerSourceType } from './mediaHelpers.js';
|
|
4
|
+
export interface VideoRemoteControlOptions {
|
|
5
|
+
powerSourceType?: MediaPowerSourceType;
|
|
6
|
+
id?: string;
|
|
7
|
+
number?: EndpointNumber;
|
|
8
|
+
}
|
|
9
|
+
export declare class VideoRemoteControl extends MatterbridgeEndpoint {
|
|
10
|
+
constructor(name: string, serial: string, options?: VideoRemoteControlOptions);
|
|
11
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { KeypadInput } from '@matter/types/clusters/keypad-input';
|
|
2
|
+
import { MediaPlayback } from '@matter/types/clusters/media-playback';
|
|
3
|
+
import { OnOff } from '@matter/types/clusters/on-off';
|
|
4
|
+
import { powerSource, videoRemoteControl } from '../matterbridgeDeviceTypes.js';
|
|
5
|
+
import { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
|
|
6
|
+
import { createDefaultMediaBindingClusterServer, createDefaultMediaPowerSourceClusterServer } from './mediaHelpers.js';
|
|
7
|
+
export class VideoRemoteControl extends MatterbridgeEndpoint {
|
|
8
|
+
constructor(name, serial, options = {}) {
|
|
9
|
+
const { powerSourceType = 'Battery' } = options;
|
|
10
|
+
super(powerSourceType === 'None' ? [videoRemoteControl] : [videoRemoteControl, powerSource], {
|
|
11
|
+
id: options.id ?? `${name.replaceAll(' ', '')}-${serial.replaceAll(' ', '')}`,
|
|
12
|
+
number: options.number,
|
|
13
|
+
});
|
|
14
|
+
this.createDefaultBasicInformationClusterServer(name, serial, 0xfff1, 'Matterbridge', 0x8000, 'Matterbridge Video Remote Control');
|
|
15
|
+
createDefaultMediaPowerSourceClusterServer(this, powerSourceType);
|
|
16
|
+
createDefaultMediaBindingClusterServer(this, [OnOff.id, MediaPlayback.id, KeypadInput.id]);
|
|
17
|
+
}
|
|
18
|
+
}
|
package/dist/frontend.js
CHANGED
|
@@ -1158,6 +1158,8 @@ export class Frontend extends EventEmitter {
|
|
|
1158
1158
|
attributes += `State: ${getEnumDescription(ValveConfigurationAndControl.ValveState, attributeValue, { fallback: 'unknown' })} `;
|
|
1159
1159
|
if (clusterName === 'levelControl' && attributeName === 'currentLevel')
|
|
1160
1160
|
attributes += `Level: ${attributeValue} `;
|
|
1161
|
+
if (clusterName === 'applicationBasic' && attributeName === 'applicationName')
|
|
1162
|
+
attributes += `App: ${attributeValue} `;
|
|
1161
1163
|
if (clusterName === 'colorControl' && attributeName === 'colorMode' && isValidNumber(attributeValue, 0, 2))
|
|
1162
1164
|
attributes += `Mode: ${['HS', 'XY', 'CT'][attributeValue]} `;
|
|
1163
1165
|
if (clusterName === 'colorControl' && getAttribute(device, 'colorControl', 'colorMode') === 0 && attributeName === 'currentHue' && isValidNumber(attributeValue))
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ActionContext } from '@matter/main';
|
|
2
2
|
import type { ClusterType } from '@matter/types/cluster';
|
|
3
3
|
import type { ActivatedCarbonFilterMonitoring } from '@matter/types/clusters/activated-carbon-filter-monitoring';
|
|
4
|
+
import type { ApplicationLauncher } from '@matter/types/clusters/application-launcher';
|
|
4
5
|
import type { BooleanStateConfiguration } from '@matter/types/clusters/boolean-state-configuration';
|
|
5
6
|
import type { ColorControl } from '@matter/types/clusters/color-control';
|
|
6
7
|
import type { DeviceEnergyManagement } from '@matter/types/clusters/device-energy-management';
|
|
@@ -868,6 +869,27 @@ export type CommandHandlerDataMap = {
|
|
|
868
869
|
attributes: {};
|
|
869
870
|
endpoint: MatterbridgeEndpoint;
|
|
870
871
|
};
|
|
872
|
+
'ApplicationLauncher.launchApp': {
|
|
873
|
+
command: 'launchApp';
|
|
874
|
+
request: ApplicationLauncher.LaunchAppRequest;
|
|
875
|
+
cluster: 'applicationLauncher';
|
|
876
|
+
attributes: ClusterAttributeValues<(typeof ApplicationLauncher)['attributes']>;
|
|
877
|
+
endpoint: MatterbridgeEndpoint;
|
|
878
|
+
};
|
|
879
|
+
'ApplicationLauncher.stopApp': {
|
|
880
|
+
command: 'stopApp';
|
|
881
|
+
request: ApplicationLauncher.StopAppRequest;
|
|
882
|
+
cluster: 'applicationLauncher';
|
|
883
|
+
attributes: ClusterAttributeValues<(typeof ApplicationLauncher)['attributes']>;
|
|
884
|
+
endpoint: MatterbridgeEndpoint;
|
|
885
|
+
};
|
|
886
|
+
'ApplicationLauncher.hideApp': {
|
|
887
|
+
command: 'hideApp';
|
|
888
|
+
request: ApplicationLauncher.HideAppRequest;
|
|
889
|
+
cluster: 'applicationLauncher';
|
|
890
|
+
attributes: ClusterAttributeValues<(typeof ApplicationLauncher)['attributes']>;
|
|
891
|
+
endpoint: MatterbridgeEndpoint;
|
|
892
|
+
};
|
|
871
893
|
'resetCondition': CommandHandlerData<'ResourceMonitoring.resetCondition'>;
|
|
872
894
|
'ResourceMonitoring.resetCondition': {
|
|
873
895
|
command: 'resetCondition';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matterbridge/core",
|
|
3
|
-
"version": "3.10.6-dev-
|
|
3
|
+
"version": "3.10.6-dev-20260821-16f33ac",
|
|
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.6-dev-
|
|
136
|
-
"@matterbridge/thread": "3.10.6-dev-
|
|
137
|
-
"@matterbridge/types": "3.10.6-dev-
|
|
138
|
-
"@matterbridge/utils": "3.10.6-dev-
|
|
135
|
+
"@matterbridge/dgram": "3.10.6-dev-20260821-16f33ac",
|
|
136
|
+
"@matterbridge/thread": "3.10.6-dev-20260821-16f33ac",
|
|
137
|
+
"@matterbridge/types": "3.10.6-dev-20260821-16f33ac",
|
|
138
|
+
"@matterbridge/utils": "3.10.6-dev-20260821-16f33ac",
|
|
139
139
|
"escape-html": "1.0.3",
|
|
140
140
|
"express": "5.2.1",
|
|
141
141
|
"express-rate-limit": "8.6.2",
|