lib-maestro-dmx 1.0.0
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/LICENSE +21 -0
- package/README.md +729 -0
- package/dist/control/osc-control.d.ts +156 -0
- package/dist/control/osc-control.js +312 -0
- package/dist/control.d.ts +96 -0
- package/dist/control.js +259 -0
- package/dist/http.d.ts +10 -0
- package/dist/http.js +46 -0
- package/dist/index.d.ts +98 -0
- package/dist/index.js +90 -0
- package/dist/internal/normalize.d.ts +10 -0
- package/dist/internal/normalize.js +25 -0
- package/dist/live.d.ts +42 -0
- package/dist/live.js +44 -0
- package/dist/normalize.d.ts +5 -0
- package/dist/normalize.js +20 -0
- package/dist/osc.d.ts +45 -0
- package/dist/osc.js +279 -0
- package/dist/patterns.d.ts +35 -0
- package/dist/patterns.js +69 -0
- package/dist/read/brightness.d.ts +17 -0
- package/dist/read/brightness.js +18 -0
- package/dist/read/color-palettes.d.ts +46 -0
- package/dist/read/color-palettes.js +86 -0
- package/dist/read/fixture-groups.d.ts +31 -0
- package/dist/read/fixture-groups.js +56 -0
- package/dist/read/fx-palettes.d.ts +28 -0
- package/dist/read/fx-palettes.js +38 -0
- package/dist/read/live.d.ts +37 -0
- package/dist/read/live.js +40 -0
- package/dist/read/lookup.d.ts +71 -0
- package/dist/read/lookup.js +91 -0
- package/dist/read/palette-assignments.d.ts +31 -0
- package/dist/read/palette-assignments.js +47 -0
- package/dist/read/patterns-available.d.ts +19 -0
- package/dist/read/patterns-available.js +21 -0
- package/dist/read/patterns.d.ts +48 -0
- package/dist/read/patterns.js +95 -0
- package/dist/read/read-api.d.ts +20 -0
- package/dist/read/read-api.js +30 -0
- package/dist/read/shared.d.ts +45 -0
- package/dist/read/shared.js +65 -0
- package/dist/read/show-state.d.ts +35 -0
- package/dist/read/show-state.js +38 -0
- package/dist/read/show.d.ts +51 -0
- package/dist/read/show.js +62 -0
- package/dist/read/system-info.d.ts +39 -0
- package/dist/read/system-info.js +29 -0
- package/dist/read-api.d.ts +10 -0
- package/dist/read-api.js +18 -0
- package/dist/transport/http.d.ts +19 -0
- package/dist/transport/http.js +86 -0
- package/dist/transport/osc.d.ts +73 -0
- package/dist/transport/osc.js +301 -0
- package/package.json +58 -0
package/dist/control.js
ADDED
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import { oscFloat, OscClient } from "./osc.js";
|
|
2
|
+
function assertLiveGroup(group) {
|
|
3
|
+
if (!Number.isInteger(group) || group < 1 || group > 4) {
|
|
4
|
+
throw new RangeError("Live group must be an integer between 1 and 4.");
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
function assertUnitInterval(name, value) {
|
|
8
|
+
if (!Number.isFinite(value) || value < 0 || value > 1) {
|
|
9
|
+
throw new RangeError(`${name} must be a finite number between 0 and 1.`);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function assertInteger(name, value, minimum = 0) {
|
|
13
|
+
if (!Number.isInteger(value) || value < minimum) {
|
|
14
|
+
throw new RangeError(`${name} must be an integer greater than or equal to ${minimum}.`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function assertString(name, value) {
|
|
18
|
+
if (value.trim().length === 0) {
|
|
19
|
+
throw new RangeError(`${name} must not be empty.`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
class GlobalControlApi {
|
|
23
|
+
oscClient;
|
|
24
|
+
constructor(oscClient) {
|
|
25
|
+
this.oscClient = oscClient;
|
|
26
|
+
}
|
|
27
|
+
async setBrightness(value) {
|
|
28
|
+
assertUnitInterval("Global brightness", value);
|
|
29
|
+
await this.oscClient.sendThrottled("/global/brightness", { intervalMs: 300 }, oscFloat(value));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
class AudioControlApi {
|
|
33
|
+
oscClient;
|
|
34
|
+
constructor(oscClient) {
|
|
35
|
+
this.oscClient = oscClient;
|
|
36
|
+
}
|
|
37
|
+
async setInput(name) {
|
|
38
|
+
assertString("Audio input name", name);
|
|
39
|
+
await this.oscClient.send("/audio/input", name);
|
|
40
|
+
}
|
|
41
|
+
async nextInput() {
|
|
42
|
+
await this.oscClient.send("/audio/input/next");
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
class LiveControlApi {
|
|
46
|
+
oscClient;
|
|
47
|
+
constructor(oscClient) {
|
|
48
|
+
this.oscClient = oscClient;
|
|
49
|
+
}
|
|
50
|
+
async pause() {
|
|
51
|
+
await this.oscClient.send("/live/pause");
|
|
52
|
+
}
|
|
53
|
+
async resume() {
|
|
54
|
+
await this.oscClient.send("/live/resume");
|
|
55
|
+
}
|
|
56
|
+
async stop() {
|
|
57
|
+
await this.oscClient.send("/live/stop");
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
class LiveGroupControlApi {
|
|
61
|
+
oscClient;
|
|
62
|
+
group;
|
|
63
|
+
constructor(oscClient, group) {
|
|
64
|
+
assertLiveGroup(group);
|
|
65
|
+
this.oscClient = oscClient;
|
|
66
|
+
this.group = group;
|
|
67
|
+
}
|
|
68
|
+
async setPattern(name) {
|
|
69
|
+
assertString("Pattern name", name);
|
|
70
|
+
await this.oscClient.send(this.address("pattern"), name);
|
|
71
|
+
}
|
|
72
|
+
async setPatternIndex(index) {
|
|
73
|
+
assertInteger("Pattern index", index);
|
|
74
|
+
await this.oscClient.send(this.address("pattern/index"), index);
|
|
75
|
+
}
|
|
76
|
+
async setPalette(id) {
|
|
77
|
+
assertInteger("Palette id", id);
|
|
78
|
+
await this.oscClient.send(this.address("palette"), id);
|
|
79
|
+
}
|
|
80
|
+
async setPaletteIndex(index) {
|
|
81
|
+
assertInteger("Palette index", index);
|
|
82
|
+
await this.oscClient.send(this.address("palette/index"), index);
|
|
83
|
+
}
|
|
84
|
+
async setFxPaletteIndex(index) {
|
|
85
|
+
assertInteger("FX palette index", index);
|
|
86
|
+
await this.oscClient.send(this.address("fx/index"), index);
|
|
87
|
+
}
|
|
88
|
+
async setBrightness(value) {
|
|
89
|
+
assertUnitInterval("Brightness", value);
|
|
90
|
+
await this.oscClient.sendThrottled(this.address("brightness"), { intervalMs: 500 }, oscFloat(value));
|
|
91
|
+
}
|
|
92
|
+
async setExcitement(value) {
|
|
93
|
+
assertUnitInterval("Excitement", value);
|
|
94
|
+
await this.oscClient.sendThrottled(this.address("excitement"), oscFloat(value));
|
|
95
|
+
}
|
|
96
|
+
async setBackground(value) {
|
|
97
|
+
assertUnitInterval("Background", value);
|
|
98
|
+
await this.oscClient.sendThrottled(this.address("background"), oscFloat(value));
|
|
99
|
+
}
|
|
100
|
+
async setMotionRange(value) {
|
|
101
|
+
assertUnitInterval("Motion range", value);
|
|
102
|
+
await this.oscClient.sendThrottled(this.address("motion/range"), oscFloat(value));
|
|
103
|
+
}
|
|
104
|
+
async setMotionSpeed(value) {
|
|
105
|
+
assertUnitInterval("Motion speed", value);
|
|
106
|
+
await this.oscClient.sendThrottled(this.address("motion/speed"), oscFloat(value));
|
|
107
|
+
}
|
|
108
|
+
async setSpeed(value) {
|
|
109
|
+
assertUnitInterval("Speed", value);
|
|
110
|
+
await this.oscClient.sendThrottled(this.address("speed"), oscFloat(value));
|
|
111
|
+
}
|
|
112
|
+
async setEnergy(value) {
|
|
113
|
+
assertUnitInterval("Energy", value);
|
|
114
|
+
await this.oscClient.sendThrottled(this.address("energy"), oscFloat(value));
|
|
115
|
+
}
|
|
116
|
+
async setVariance(value) {
|
|
117
|
+
assertUnitInterval("Variance", value);
|
|
118
|
+
await this.oscClient.sendThrottled(this.address("variance"), oscFloat(value));
|
|
119
|
+
}
|
|
120
|
+
async setDecay(value) {
|
|
121
|
+
assertUnitInterval("Decay", value);
|
|
122
|
+
await this.oscClient.sendThrottled(this.address("decay"), oscFloat(value));
|
|
123
|
+
}
|
|
124
|
+
async setAttack(value) {
|
|
125
|
+
assertUnitInterval("Attack", value);
|
|
126
|
+
await this.oscClient.sendThrottled(this.address("attack"), oscFloat(value));
|
|
127
|
+
}
|
|
128
|
+
async setShape(value) {
|
|
129
|
+
if (!Number.isInteger(value) || value < 0 || value > 15) {
|
|
130
|
+
throw new RangeError("Shape must be an integer between 0 and 15.");
|
|
131
|
+
}
|
|
132
|
+
await this.oscClient.send(this.address("shape"), value);
|
|
133
|
+
}
|
|
134
|
+
address(suffix) {
|
|
135
|
+
return `/live/${this.group}/${suffix}`;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
class ShowControlApi {
|
|
139
|
+
oscClient;
|
|
140
|
+
constructor(oscClient) {
|
|
141
|
+
this.oscClient = oscClient;
|
|
142
|
+
}
|
|
143
|
+
async loadByName(name) {
|
|
144
|
+
assertString("Show name", name);
|
|
145
|
+
await this.oscClient.send("/show/name", name);
|
|
146
|
+
}
|
|
147
|
+
async next() {
|
|
148
|
+
await this.oscClient.send("/show/next");
|
|
149
|
+
}
|
|
150
|
+
async previous() {
|
|
151
|
+
await this.oscClient.send("/show/previous");
|
|
152
|
+
}
|
|
153
|
+
async loadByIndex(index) {
|
|
154
|
+
assertInteger("Show index", index);
|
|
155
|
+
await this.oscClient.send("/show/index", index);
|
|
156
|
+
}
|
|
157
|
+
async loadCueByIndex(index) {
|
|
158
|
+
assertInteger("Cue index", index, 1);
|
|
159
|
+
await this.oscClient.send("/show/cue/index", index);
|
|
160
|
+
}
|
|
161
|
+
async nextCue() {
|
|
162
|
+
await this.oscClient.send("/show/cue/next");
|
|
163
|
+
}
|
|
164
|
+
async previousCue() {
|
|
165
|
+
await this.oscClient.send("/show/cue/previous");
|
|
166
|
+
}
|
|
167
|
+
async playPause() {
|
|
168
|
+
await this.oscClient.send("/show/play_pause");
|
|
169
|
+
}
|
|
170
|
+
async play() {
|
|
171
|
+
await this.oscClient.send("/show/play");
|
|
172
|
+
}
|
|
173
|
+
async stop() {
|
|
174
|
+
await this.oscClient.send("/show/stop");
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
class TriggerControlApi {
|
|
178
|
+
oscClient;
|
|
179
|
+
constructor(oscClient) {
|
|
180
|
+
this.oscClient = oscClient;
|
|
181
|
+
}
|
|
182
|
+
async setStrobe(enabled) {
|
|
183
|
+
await this.oscClient.send("/triggers/strobe", enabled);
|
|
184
|
+
}
|
|
185
|
+
async toggleStrobe() {
|
|
186
|
+
await this.oscClient.send("/triggers/strobe/toggle");
|
|
187
|
+
}
|
|
188
|
+
async setStrobeBrightness(value) {
|
|
189
|
+
assertUnitInterval("Strobe brightness", value);
|
|
190
|
+
await this.oscClient.send("/triggers/strobe/brightness", oscFloat(value));
|
|
191
|
+
}
|
|
192
|
+
async setStrobeRate(value) {
|
|
193
|
+
assertUnitInterval("Strobe rate", value);
|
|
194
|
+
await this.oscClient.send("/triggers/strobe/rate", oscFloat(value));
|
|
195
|
+
}
|
|
196
|
+
async setBlinder(enabled) {
|
|
197
|
+
await this.oscClient.send("/triggers/blinder", enabled);
|
|
198
|
+
}
|
|
199
|
+
async toggleBlinder() {
|
|
200
|
+
await this.oscClient.send("/triggers/blinder/toggle");
|
|
201
|
+
}
|
|
202
|
+
async setBlinderBrightness(value) {
|
|
203
|
+
assertUnitInterval("Blinder brightness", value);
|
|
204
|
+
await this.oscClient.send("/triggers/blinder/brightness", oscFloat(value));
|
|
205
|
+
}
|
|
206
|
+
async setBlackout(enabled) {
|
|
207
|
+
await this.oscClient.send("/triggers/blackout", enabled);
|
|
208
|
+
}
|
|
209
|
+
async toggleBlackout() {
|
|
210
|
+
await this.oscClient.send("/triggers/blackout/toggle");
|
|
211
|
+
}
|
|
212
|
+
async setFog(enabled) {
|
|
213
|
+
await this.oscClient.send("/triggers/fog", enabled);
|
|
214
|
+
}
|
|
215
|
+
async toggleFog() {
|
|
216
|
+
await this.oscClient.send("/triggers/fog/toggle");
|
|
217
|
+
}
|
|
218
|
+
async setFogInterval(value) {
|
|
219
|
+
assertUnitInterval("Fog interval", value);
|
|
220
|
+
await this.oscClient.send("/triggers/fog/interval", oscFloat(value));
|
|
221
|
+
}
|
|
222
|
+
async setFogDuration(value) {
|
|
223
|
+
assertUnitInterval("Fog duration", value);
|
|
224
|
+
await this.oscClient.send("/triggers/fog/duration", oscFloat(value));
|
|
225
|
+
}
|
|
226
|
+
async setFogVolume(value) {
|
|
227
|
+
assertUnitInterval("Fog volume", value);
|
|
228
|
+
await this.oscClient.send("/triggers/fog/volume", oscFloat(value));
|
|
229
|
+
}
|
|
230
|
+
async setFogSpeed(value) {
|
|
231
|
+
assertUnitInterval("Fog speed", value);
|
|
232
|
+
await this.oscClient.send("/triggers/fog/speed", oscFloat(value));
|
|
233
|
+
}
|
|
234
|
+
async setEffect(enabled) {
|
|
235
|
+
await this.oscClient.send("/triggers/effect", enabled);
|
|
236
|
+
}
|
|
237
|
+
async toggleEffect() {
|
|
238
|
+
await this.oscClient.send("/triggers/effect/toggle");
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
export class MaestroOscControlApiImpl {
|
|
242
|
+
global;
|
|
243
|
+
audio;
|
|
244
|
+
live;
|
|
245
|
+
show;
|
|
246
|
+
triggers;
|
|
247
|
+
oscClient;
|
|
248
|
+
constructor(oscClient) {
|
|
249
|
+
this.oscClient = oscClient;
|
|
250
|
+
this.global = new GlobalControlApi(oscClient);
|
|
251
|
+
this.audio = new AudioControlApi(oscClient);
|
|
252
|
+
this.live = new LiveControlApi(oscClient);
|
|
253
|
+
this.show = new ShowControlApi(oscClient);
|
|
254
|
+
this.triggers = new TriggerControlApi(oscClient);
|
|
255
|
+
}
|
|
256
|
+
group(group) {
|
|
257
|
+
return new LiveGroupControlApi(this.oscClient, group);
|
|
258
|
+
}
|
|
259
|
+
}
|
package/dist/http.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface HttpClientOptions {
|
|
2
|
+
host: string;
|
|
3
|
+
protocol?: "http" | "https";
|
|
4
|
+
}
|
|
5
|
+
export declare class HttpClient {
|
|
6
|
+
private readonly host;
|
|
7
|
+
private readonly protocol;
|
|
8
|
+
constructor(options: HttpClientOptions);
|
|
9
|
+
getJson<T>(path: string): Promise<T>;
|
|
10
|
+
}
|
package/dist/http.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import http from "node:http";
|
|
2
|
+
import https from "node:https";
|
|
3
|
+
export class HttpClient {
|
|
4
|
+
host;
|
|
5
|
+
protocol;
|
|
6
|
+
constructor(options) {
|
|
7
|
+
this.host = options.host;
|
|
8
|
+
this.protocol = options.protocol ?? "http";
|
|
9
|
+
}
|
|
10
|
+
async getJson(path) {
|
|
11
|
+
const transport = this.protocol === "https" ? https : http;
|
|
12
|
+
return new Promise((resolve, reject) => {
|
|
13
|
+
const request = transport.get({
|
|
14
|
+
host: this.host,
|
|
15
|
+
path,
|
|
16
|
+
headers: {
|
|
17
|
+
Accept: "application/json"
|
|
18
|
+
}
|
|
19
|
+
}, (response) => {
|
|
20
|
+
if (!response.statusCode) {
|
|
21
|
+
reject(new Error(`HTTP request to "${path}" returned no status code.`));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (response.statusCode < 200 || response.statusCode >= 300) {
|
|
25
|
+
response.resume();
|
|
26
|
+
reject(new Error(`HTTP request to "${path}" failed with status ${response.statusCode}.`));
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const chunks = [];
|
|
30
|
+
response.on("data", (chunk) => {
|
|
31
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
32
|
+
});
|
|
33
|
+
response.on("end", () => {
|
|
34
|
+
try {
|
|
35
|
+
const body = Buffer.concat(chunks).toString("utf8");
|
|
36
|
+
resolve(JSON.parse(body));
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
reject(error);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
request.on("error", reject);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { BrightnessApi } from "./read/brightness.js";
|
|
2
|
+
import { ColorPalettesApi } from "./read/color-palettes.js";
|
|
3
|
+
import { FixtureGroupsApi } from "./read/fixture-groups.js";
|
|
4
|
+
import { FxPalettesApi } from "./read/fx-palettes.js";
|
|
5
|
+
import type { MaestroOscControlApi } from "./control/osc-control.js";
|
|
6
|
+
import { LiveApi } from "./read/live.js";
|
|
7
|
+
import { PaletteAssignmentsApi } from "./read/palette-assignments.js";
|
|
8
|
+
import { PatternsApi } from "./read/patterns.js";
|
|
9
|
+
import { PatternsAvailableApi } from "./read/patterns-available.js";
|
|
10
|
+
import { MaestroLookupApi } from "./read/lookup.js";
|
|
11
|
+
import { OscClient } from "./transport/osc.js";
|
|
12
|
+
import { ShowApi } from "./read/show.js";
|
|
13
|
+
import { ShowStateApi } from "./read/show-state.js";
|
|
14
|
+
import { SystemInfoApi } from "./read/system-info.js";
|
|
15
|
+
export type { LiveGroup, MaestroOscControlApi } from "./control/osc-control.js";
|
|
16
|
+
export type { LiveSlotState, LiveState } from "./read/live.js";
|
|
17
|
+
export type { BrightnessState } from "./read/brightness.js";
|
|
18
|
+
export type { ColorPalette, ColorPalettesState, PaletteColor } from "./read/color-palettes.js";
|
|
19
|
+
export type { FixtureGroup, FixtureGroupsState } from "./read/fixture-groups.js";
|
|
20
|
+
export type { FxPalette, FxPalettesState } from "./read/fx-palettes.js";
|
|
21
|
+
export type { PaletteAssignment, PaletteAssignmentsState } from "./read/palette-assignments.js";
|
|
22
|
+
export type { PatternDefinition, PatternManifest, PatternParameter, PatternsState } from "./read/patterns.js";
|
|
23
|
+
export type { PatternsAvailableState } from "./read/patterns-available.js";
|
|
24
|
+
export type { CueGroupContext, CurrentCueGroupContext, LiveGroupContext } from "./read/lookup.js";
|
|
25
|
+
export type { ShowCue, ShowState } from "./read/show.js";
|
|
26
|
+
export type { ShowPlaybackState } from "./read/show-state.js";
|
|
27
|
+
export type { ParamGroup, SlotState } from "./read/shared.js";
|
|
28
|
+
export type { SystemInfoState } from "./read/system-info.js";
|
|
29
|
+
export type { HttpClientOptions } from "./transport/http.js";
|
|
30
|
+
export type { OscArgument, OscClientOptions, OscMessage, OscResponse } from "./transport/osc.js";
|
|
31
|
+
export { BrightnessApi } from "./read/brightness.js";
|
|
32
|
+
export { ColorPalettesApi } from "./read/color-palettes.js";
|
|
33
|
+
export { FixtureGroupsApi } from "./read/fixture-groups.js";
|
|
34
|
+
export { FxPalettesApi } from "./read/fx-palettes.js";
|
|
35
|
+
export { MaestroOscControlApiImpl } from "./control/osc-control.js";
|
|
36
|
+
export { LiveApi } from "./read/live.js";
|
|
37
|
+
export { MaestroLookupApi } from "./read/lookup.js";
|
|
38
|
+
export { PaletteAssignmentsApi } from "./read/palette-assignments.js";
|
|
39
|
+
export { PatternsApi } from "./read/patterns.js";
|
|
40
|
+
export { PatternsAvailableApi } from "./read/patterns-available.js";
|
|
41
|
+
export { ShowApi } from "./read/show.js";
|
|
42
|
+
export { ShowStateApi } from "./read/show-state.js";
|
|
43
|
+
export { SystemInfoApi } from "./read/system-info.js";
|
|
44
|
+
export { HttpClient } from "./transport/http.js";
|
|
45
|
+
export { OscClient, decodeOscMessage, encodeOscMessage, oscFloat } from "./transport/osc.js";
|
|
46
|
+
/**
|
|
47
|
+
* Connection options for creating a MaestroDMX client.
|
|
48
|
+
*/
|
|
49
|
+
export interface MaestroDmxClientOptions {
|
|
50
|
+
/** Hostname or IP address of the MaestroDMX device. */
|
|
51
|
+
host: string;
|
|
52
|
+
/** HTTP protocol used for Web API reads. Defaults to `http`. */
|
|
53
|
+
protocol?: "http" | "https";
|
|
54
|
+
/** Optional local UDP port to bind the OSC socket to. */
|
|
55
|
+
localOscPort?: number;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Main high-level client for MaestroDMX.
|
|
59
|
+
*
|
|
60
|
+
* It combines OSC writes, typed Web API readers, and snapshot-based lookup
|
|
61
|
+
* helpers for common show-automation workflows.
|
|
62
|
+
*/
|
|
63
|
+
export interface MaestroDmxClient {
|
|
64
|
+
/** Hostname or IP address of the connected MaestroDMX device. */
|
|
65
|
+
host: string;
|
|
66
|
+
/** Low-level OSC transport for raw OSC access. */
|
|
67
|
+
osc: OscClient;
|
|
68
|
+
/** Typed MaestroDMX OSC control surface. */
|
|
69
|
+
control: MaestroOscControlApi;
|
|
70
|
+
/** Device and software metadata reader. */
|
|
71
|
+
systemInfo: SystemInfoApi;
|
|
72
|
+
/** Global stage brightness reader. */
|
|
73
|
+
brightness: BrightnessApi;
|
|
74
|
+
/** Current live state reader for all four fixture groups. */
|
|
75
|
+
live: LiveApi;
|
|
76
|
+
/** Full pattern catalog reader. */
|
|
77
|
+
patterns: PatternsApi;
|
|
78
|
+
/** Flattened list of available pattern ids. */
|
|
79
|
+
patternsAvailable: PatternsAvailableApi;
|
|
80
|
+
/** Active palette assignments per fixture group. */
|
|
81
|
+
paletteAssignments: PaletteAssignmentsApi;
|
|
82
|
+
/** Color palette catalog reader. */
|
|
83
|
+
colorPalettes: ColorPalettesApi;
|
|
84
|
+
/** FX palette / snapshot catalog reader. */
|
|
85
|
+
fxPalettes: FxPalettesApi;
|
|
86
|
+
/** Loaded show definition reader. */
|
|
87
|
+
show: ShowApi;
|
|
88
|
+
/** Runtime show playback-state reader. */
|
|
89
|
+
showState: ShowStateApi;
|
|
90
|
+
/** Fixture-group topology reader. */
|
|
91
|
+
fixtureGroups: FixtureGroupsApi;
|
|
92
|
+
/** High-level snapshot resolver across multiple readers. */
|
|
93
|
+
lookup: MaestroLookupApi;
|
|
94
|
+
/** Closes the underlying OSC socket and related timers. */
|
|
95
|
+
close(): Promise<void>;
|
|
96
|
+
}
|
|
97
|
+
/** Creates a fully wired MaestroDMX client instance. */
|
|
98
|
+
export declare function createClient(options: MaestroDmxClientOptions): MaestroDmxClient;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { BrightnessApi } from "./read/brightness.js";
|
|
2
|
+
import { ColorPalettesApi } from "./read/color-palettes.js";
|
|
3
|
+
import { FixtureGroupsApi } from "./read/fixture-groups.js";
|
|
4
|
+
import { FxPalettesApi } from "./read/fx-palettes.js";
|
|
5
|
+
import { MaestroOscControlApiImpl } from "./control/osc-control.js";
|
|
6
|
+
import { LiveApi } from "./read/live.js";
|
|
7
|
+
import { PaletteAssignmentsApi } from "./read/palette-assignments.js";
|
|
8
|
+
import { PatternsApi } from "./read/patterns.js";
|
|
9
|
+
import { PatternsAvailableApi } from "./read/patterns-available.js";
|
|
10
|
+
import { MaestroLookupApi } from "./read/lookup.js";
|
|
11
|
+
import { HttpClient } from "./transport/http.js";
|
|
12
|
+
import { OscClient } from "./transport/osc.js";
|
|
13
|
+
import { ShowApi } from "./read/show.js";
|
|
14
|
+
import { ShowStateApi } from "./read/show-state.js";
|
|
15
|
+
import { SystemInfoApi } from "./read/system-info.js";
|
|
16
|
+
const DEFAULT_OSC_PORT = 7672;
|
|
17
|
+
export { BrightnessApi } from "./read/brightness.js";
|
|
18
|
+
export { ColorPalettesApi } from "./read/color-palettes.js";
|
|
19
|
+
export { FixtureGroupsApi } from "./read/fixture-groups.js";
|
|
20
|
+
export { FxPalettesApi } from "./read/fx-palettes.js";
|
|
21
|
+
export { MaestroOscControlApiImpl } from "./control/osc-control.js";
|
|
22
|
+
export { LiveApi } from "./read/live.js";
|
|
23
|
+
export { MaestroLookupApi } from "./read/lookup.js";
|
|
24
|
+
export { PaletteAssignmentsApi } from "./read/palette-assignments.js";
|
|
25
|
+
export { PatternsApi } from "./read/patterns.js";
|
|
26
|
+
export { PatternsAvailableApi } from "./read/patterns-available.js";
|
|
27
|
+
export { ShowApi } from "./read/show.js";
|
|
28
|
+
export { ShowStateApi } from "./read/show-state.js";
|
|
29
|
+
export { SystemInfoApi } from "./read/system-info.js";
|
|
30
|
+
export { HttpClient } from "./transport/http.js";
|
|
31
|
+
export { OscClient, decodeOscMessage, encodeOscMessage, oscFloat } from "./transport/osc.js";
|
|
32
|
+
class MaestroDmxClientImpl {
|
|
33
|
+
host;
|
|
34
|
+
osc;
|
|
35
|
+
control;
|
|
36
|
+
systemInfo;
|
|
37
|
+
brightness;
|
|
38
|
+
live;
|
|
39
|
+
patterns;
|
|
40
|
+
patternsAvailable;
|
|
41
|
+
paletteAssignments;
|
|
42
|
+
colorPalettes;
|
|
43
|
+
fxPalettes;
|
|
44
|
+
show;
|
|
45
|
+
showState;
|
|
46
|
+
fixtureGroups;
|
|
47
|
+
lookup;
|
|
48
|
+
constructor(options) {
|
|
49
|
+
this.host = options.host;
|
|
50
|
+
this.osc = new OscClient({
|
|
51
|
+
host: options.host,
|
|
52
|
+
port: DEFAULT_OSC_PORT,
|
|
53
|
+
localPort: options.localOscPort
|
|
54
|
+
});
|
|
55
|
+
this.control = new MaestroOscControlApiImpl(this.osc);
|
|
56
|
+
const httpClient = new HttpClient({
|
|
57
|
+
host: options.host,
|
|
58
|
+
protocol: options.protocol
|
|
59
|
+
});
|
|
60
|
+
this.systemInfo = new SystemInfoApi(httpClient);
|
|
61
|
+
this.brightness = new BrightnessApi(httpClient);
|
|
62
|
+
this.live = new LiveApi(httpClient);
|
|
63
|
+
this.patterns = new PatternsApi(httpClient);
|
|
64
|
+
this.patternsAvailable = new PatternsAvailableApi(httpClient);
|
|
65
|
+
this.paletteAssignments = new PaletteAssignmentsApi(httpClient);
|
|
66
|
+
this.colorPalettes = new ColorPalettesApi(httpClient);
|
|
67
|
+
this.fxPalettes = new FxPalettesApi(httpClient);
|
|
68
|
+
this.show = new ShowApi(httpClient);
|
|
69
|
+
this.showState = new ShowStateApi(httpClient);
|
|
70
|
+
this.fixtureGroups = new FixtureGroupsApi(httpClient);
|
|
71
|
+
this.lookup = new MaestroLookupApi({
|
|
72
|
+
live: this.live,
|
|
73
|
+
patterns: this.patterns,
|
|
74
|
+
patternsAvailable: this.patternsAvailable,
|
|
75
|
+
paletteAssignments: this.paletteAssignments,
|
|
76
|
+
colorPalettes: this.colorPalettes,
|
|
77
|
+
fxPalettes: this.fxPalettes,
|
|
78
|
+
show: this.show,
|
|
79
|
+
showState: this.showState,
|
|
80
|
+
fixtureGroups: this.fixtureGroups
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
async close() {
|
|
84
|
+
await this.osc.close();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/** Creates a fully wired MaestroDMX client instance. */
|
|
88
|
+
export function createClient(options) {
|
|
89
|
+
return new MaestroDmxClientImpl(options);
|
|
90
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Returns `true` when the input is a non-null object that is not an array. */
|
|
2
|
+
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
3
|
+
/** Normalizes a value to an optional string. */
|
|
4
|
+
export declare function toOptionalString(value: unknown): string | undefined;
|
|
5
|
+
/** Normalizes a value to an optional finite number. */
|
|
6
|
+
export declare function toOptionalNumber(value: unknown): number | undefined;
|
|
7
|
+
/** Normalizes a value to an optional boolean. */
|
|
8
|
+
export declare function toOptionalBoolean(value: unknown): boolean | undefined;
|
|
9
|
+
/** Normalizes an unknown value to an array of validated entries. */
|
|
10
|
+
export declare function normalizeArray<T>(value: unknown, normalizeEntry: (entry: unknown) => T | undefined): T[];
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** Returns `true` when the input is a non-null object that is not an array. */
|
|
2
|
+
export function isRecord(value) {
|
|
3
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4
|
+
}
|
|
5
|
+
/** Normalizes a value to an optional string. */
|
|
6
|
+
export function toOptionalString(value) {
|
|
7
|
+
return typeof value === "string" ? value : undefined;
|
|
8
|
+
}
|
|
9
|
+
/** Normalizes a value to an optional finite number. */
|
|
10
|
+
export function toOptionalNumber(value) {
|
|
11
|
+
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
12
|
+
}
|
|
13
|
+
/** Normalizes a value to an optional boolean. */
|
|
14
|
+
export function toOptionalBoolean(value) {
|
|
15
|
+
return typeof value === "boolean" ? value : undefined;
|
|
16
|
+
}
|
|
17
|
+
/** Normalizes an unknown value to an array of validated entries. */
|
|
18
|
+
export function normalizeArray(value, normalizeEntry) {
|
|
19
|
+
if (!Array.isArray(value)) {
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
return value
|
|
23
|
+
.map((entry) => normalizeEntry(entry))
|
|
24
|
+
.filter((entry) => entry !== undefined);
|
|
25
|
+
}
|
package/dist/live.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { HttpClient } from "./http.js";
|
|
2
|
+
import { ReadApi } from "./read-api.js";
|
|
3
|
+
export interface LiveSlotState {
|
|
4
|
+
patternId?: string;
|
|
5
|
+
paletteId?: string;
|
|
6
|
+
brightness?: number;
|
|
7
|
+
excitement?: number;
|
|
8
|
+
background?: number;
|
|
9
|
+
intensity?: number;
|
|
10
|
+
motion?: number;
|
|
11
|
+
speed?: number;
|
|
12
|
+
energy?: number;
|
|
13
|
+
variance?: number;
|
|
14
|
+
attack?: number;
|
|
15
|
+
decay?: number;
|
|
16
|
+
motionSpeed?: number;
|
|
17
|
+
blackout?: boolean;
|
|
18
|
+
blackoutOnSilence?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface LiveState {
|
|
21
|
+
mode: string;
|
|
22
|
+
transition: Record<string, unknown>;
|
|
23
|
+
primary: LiveSlotState;
|
|
24
|
+
secondary: LiveSlotState;
|
|
25
|
+
tertiary: LiveSlotState;
|
|
26
|
+
quaternary: LiveSlotState;
|
|
27
|
+
fetchedAt: Date;
|
|
28
|
+
}
|
|
29
|
+
interface LiveApiResponse {
|
|
30
|
+
type?: unknown;
|
|
31
|
+
transition?: unknown;
|
|
32
|
+
params?: unknown;
|
|
33
|
+
secondaryParams?: unknown;
|
|
34
|
+
tertiaryParams?: unknown;
|
|
35
|
+
quaternaryParams?: unknown;
|
|
36
|
+
}
|
|
37
|
+
export declare class LiveApi extends ReadApi<LiveState, LiveApiResponse> {
|
|
38
|
+
constructor(httpClient: HttpClient);
|
|
39
|
+
protected getPath(): string;
|
|
40
|
+
protected normalizeResponse(response: LiveApiResponse, fetchedAt: Date): LiveState;
|
|
41
|
+
}
|
|
42
|
+
export {};
|
package/dist/live.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { HttpClient } from "./http.js";
|
|
2
|
+
import { isRecord, toOptionalBoolean, toOptionalNumber, toOptionalString } from "./normalize.js";
|
|
3
|
+
import { ReadApi } from "./read-api.js";
|
|
4
|
+
function normalizeSlotState(value) {
|
|
5
|
+
if (!isRecord(value)) {
|
|
6
|
+
return {};
|
|
7
|
+
}
|
|
8
|
+
return {
|
|
9
|
+
patternId: toOptionalString(value.patternId),
|
|
10
|
+
paletteId: toOptionalString(value.paletteId),
|
|
11
|
+
brightness: toOptionalNumber(value.brightness),
|
|
12
|
+
excitement: toOptionalNumber(value.excitement) ?? toOptionalNumber(value.intensity),
|
|
13
|
+
background: toOptionalNumber(value.background),
|
|
14
|
+
intensity: toOptionalNumber(value.intensity),
|
|
15
|
+
motion: toOptionalNumber(value.motion),
|
|
16
|
+
speed: toOptionalNumber(value.speed),
|
|
17
|
+
energy: toOptionalNumber(value.energy),
|
|
18
|
+
variance: toOptionalNumber(value.variance),
|
|
19
|
+
attack: toOptionalNumber(value.attack),
|
|
20
|
+
decay: toOptionalNumber(value.decay),
|
|
21
|
+
motionSpeed: toOptionalNumber(value.motionSpeed),
|
|
22
|
+
blackout: toOptionalBoolean(value.blackout),
|
|
23
|
+
blackoutOnSilence: toOptionalBoolean(value.blackoutOnSilence)
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export class LiveApi extends ReadApi {
|
|
27
|
+
constructor(httpClient) {
|
|
28
|
+
super(httpClient);
|
|
29
|
+
}
|
|
30
|
+
getPath() {
|
|
31
|
+
return "/api/v1/live";
|
|
32
|
+
}
|
|
33
|
+
normalizeResponse(response, fetchedAt) {
|
|
34
|
+
return {
|
|
35
|
+
mode: typeof response.type === "string" ? response.type : "UNKNOWN",
|
|
36
|
+
transition: isRecord(response.transition) ? response.transition : {},
|
|
37
|
+
primary: normalizeSlotState(response.params),
|
|
38
|
+
secondary: normalizeSlotState(response.secondaryParams),
|
|
39
|
+
tertiary: normalizeSlotState(response.tertiaryParams),
|
|
40
|
+
quaternary: normalizeSlotState(response.quaternaryParams),
|
|
41
|
+
fetchedAt
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
2
|
+
export declare function toOptionalString(value: unknown): string | undefined;
|
|
3
|
+
export declare function toOptionalNumber(value: unknown): number | undefined;
|
|
4
|
+
export declare function toOptionalBoolean(value: unknown): boolean | undefined;
|
|
5
|
+
export declare function normalizeArray<T>(value: unknown, normalizeEntry: (entry: unknown) => T | undefined): T[];
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function isRecord(value) {
|
|
2
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3
|
+
}
|
|
4
|
+
export function toOptionalString(value) {
|
|
5
|
+
return typeof value === "string" ? value : undefined;
|
|
6
|
+
}
|
|
7
|
+
export function toOptionalNumber(value) {
|
|
8
|
+
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
9
|
+
}
|
|
10
|
+
export function toOptionalBoolean(value) {
|
|
11
|
+
return typeof value === "boolean" ? value : undefined;
|
|
12
|
+
}
|
|
13
|
+
export function normalizeArray(value, normalizeEntry) {
|
|
14
|
+
if (!Array.isArray(value)) {
|
|
15
|
+
return [];
|
|
16
|
+
}
|
|
17
|
+
return value
|
|
18
|
+
.map((entry) => normalizeEntry(entry))
|
|
19
|
+
.filter((entry) => entry !== undefined);
|
|
20
|
+
}
|