amaran-light-cli 1.0.2
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 +22 -0
- package/README.md +374 -0
- package/dist/__tests__/autoCct.test.d.ts +2 -0
- package/dist/__tests__/autoCct.test.d.ts.map +1 -0
- package/dist/__tests__/autoCct.test.js +65 -0
- package/dist/__tests__/autoCct.test.js.map +1 -0
- package/dist/__tests__/cctUtil.test.d.ts +2 -0
- package/dist/__tests__/cctUtil.test.d.ts.map +1 -0
- package/dist/__tests__/cctUtil.test.js +195 -0
- package/dist/__tests__/cctUtil.test.js.map +1 -0
- package/dist/__tests__/cli.smoke.test.d.ts +2 -0
- package/dist/__tests__/cli.smoke.test.d.ts.map +1 -0
- package/dist/__tests__/cli.smoke.test.js +18 -0
- package/dist/__tests__/cli.smoke.test.js.map +1 -0
- package/dist/__tests__/intensityApi.test.d.ts +2 -0
- package/dist/__tests__/intensityApi.test.d.ts.map +1 -0
- package/dist/__tests__/intensityApi.test.js +105 -0
- package/dist/__tests__/intensityApi.test.js.map +1 -0
- package/dist/__tests__/lightControl.test.d.ts +2 -0
- package/dist/__tests__/lightControl.test.d.ts.map +1 -0
- package/dist/__tests__/lightControl.test.js +185 -0
- package/dist/__tests__/lightControl.test.js.map +1 -0
- package/dist/cctUtil.d.ts +26 -0
- package/dist/cctUtil.d.ts.map +1 -0
- package/dist/cctUtil.js +93 -0
- package/dist/cctUtil.js.map +1 -0
- package/dist/cli.d.ts +10 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +274 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/autoCct.d.ts +5 -0
- package/dist/commands/autoCct.d.ts.map +1 -0
- package/dist/commands/autoCct.js +270 -0
- package/dist/commands/autoCct.js.map +1 -0
- package/dist/commands/cct.d.ts +5 -0
- package/dist/commands/cct.d.ts.map +1 -0
- package/dist/commands/cct.js +68 -0
- package/dist/commands/cct.js.map +1 -0
- package/dist/commands/color.d.ts +5 -0
- package/dist/commands/color.d.ts.map +1 -0
- package/dist/commands/color.js +63 -0
- package/dist/commands/color.js.map +1 -0
- package/dist/commands/discover.d.ts +5 -0
- package/dist/commands/discover.d.ts.map +1 -0
- package/dist/commands/discover.js +30 -0
- package/dist/commands/discover.js.map +1 -0
- package/dist/commands/hsi.d.ts +5 -0
- package/dist/commands/hsi.d.ts.map +1 -0
- package/dist/commands/hsi.js +65 -0
- package/dist/commands/hsi.js.map +1 -0
- package/dist/commands/intensity.d.ts +5 -0
- package/dist/commands/intensity.d.ts.map +1 -0
- package/dist/commands/intensity.js +56 -0
- package/dist/commands/intensity.js.map +1 -0
- package/dist/commands/list.d.ts +5 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +36 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/power.d.ts +5 -0
- package/dist/commands/power.d.ts.map +1 -0
- package/dist/commands/power.js +126 -0
- package/dist/commands/power.js.map +1 -0
- package/dist/commands/schedule.d.ts +5 -0
- package/dist/commands/schedule.d.ts.map +1 -0
- package/dist/commands/schedule.js +188 -0
- package/dist/commands/schedule.js.map +1 -0
- package/dist/commands/service.d.ts +5 -0
- package/dist/commands/service.d.ts.map +1 -0
- package/dist/commands/service.js +350 -0
- package/dist/commands/service.js.map +1 -0
- package/dist/commands/status.d.ts +5 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +54 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands.d.ts +5 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +31 -0
- package/dist/commands.js.map +1 -0
- package/dist/discovery.d.ts +13 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +130 -0
- package/dist/discovery.js.map +1 -0
- package/dist/geoipUtil.d.ts +8 -0
- package/dist/geoipUtil.d.ts.map +1 -0
- package/dist/geoipUtil.js +26 -0
- package/dist/geoipUtil.js.map +1 -0
- package/dist/lightControl.d.ts +114 -0
- package/dist/lightControl.d.ts.map +1 -0
- package/dist/lightControl.js +385 -0
- package/dist/lightControl.js.map +1 -0
- package/dist/types.d.ts +37 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +75 -0
- package/scripts/create-launchd-service.sh +114 -0
- package/scripts/run-auto-cct.sh +43 -0
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
MIT License
|
|
4
|
+
Copyright (c) 2024 S. Zachariah Sprackett <zac@sprackett.com>
|
|
5
|
+
Copyright (c) 2025 Mahyar McDonald <github@hmmfn.com>
|
|
6
|
+
|
|
7
|
+
Control Aputure Amaran Lights via websocket to the amaran Desktop application.
|
|
8
|
+
|
|
9
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
10
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
11
|
+
in the Software without restriction, including without limitation the rights
|
|
12
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
13
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
14
|
+
furnished to do so, subject to the following conditions:
|
|
15
|
+
The above copyright notice and this permission notice shall be included in all
|
|
16
|
+
copies or substantial portions of the Software.
|
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
SOFTWARE.
|
|
24
|
+
|
|
25
|
+
Downloaded from: https://gist.github.com/zsprackett/29334b9be1e2bd90c1737bd0ba0eaf5c
|
|
26
|
+
*/
|
|
27
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
28
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
29
|
+
};
|
|
30
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
|
+
const ws_1 = __importDefault(require("ws"));
|
|
32
|
+
class LightController {
|
|
33
|
+
/**
|
|
34
|
+
* Apply a command to all light devices with throttling.
|
|
35
|
+
* Only targets devices with node_ids matching the light pattern (e.g., '400J5-F2C008').
|
|
36
|
+
* Throttles commands with 250ms delay between each to avoid overwhelming the server.
|
|
37
|
+
*
|
|
38
|
+
* @param commandFn - Function that takes (nodeId, callback) and executes the command
|
|
39
|
+
* @param commandName - Display name for the command (for logging)
|
|
40
|
+
* @param getDisplayArgs - Optional function to get display arguments for logging
|
|
41
|
+
*/
|
|
42
|
+
async applyToAllLights(commandFn, commandName, getDisplayArgs) {
|
|
43
|
+
if (!this.deviceList)
|
|
44
|
+
return;
|
|
45
|
+
// Filter devices: only those with node_id matching the light pattern
|
|
46
|
+
const lightDevices = this.deviceList.filter((device) => {
|
|
47
|
+
return device?.node_id && this.isLightNodeId(device.node_id);
|
|
48
|
+
});
|
|
49
|
+
if (lightDevices.length === 0) {
|
|
50
|
+
this.log(`No light devices found for ${commandName}`);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
this.log(`${commandName} for ${lightDevices.length} light(s)`);
|
|
54
|
+
const waitTimeMs = 250;
|
|
55
|
+
// Send commands with waitTimeMs throttling between each
|
|
56
|
+
for (let i = 0; i < lightDevices.length; i++) {
|
|
57
|
+
const device = lightDevices[i];
|
|
58
|
+
const displayName = device.device_name || device.name || device.node_id || 'Unknown';
|
|
59
|
+
const displayArgs = getDisplayArgs ? getDisplayArgs(device) : '';
|
|
60
|
+
console.log(` ${commandName} ${displayName} (${device.node_id})${displayArgs}`);
|
|
61
|
+
if (device.node_id) {
|
|
62
|
+
commandFn(device.node_id);
|
|
63
|
+
}
|
|
64
|
+
// Wait waitTimeMs before sending next command (skip delay after last one)
|
|
65
|
+
if (i < lightDevices.length - 1) {
|
|
66
|
+
await this.sleep(waitTimeMs);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Set CCT & Intensity for all lights in deviceList.
|
|
72
|
+
* Only targets devices with node_ids matching the light pattern (e.g., '400J5-F2C008').
|
|
73
|
+
* Throttles commands with 250ms delay between each to avoid overwhelming the server.
|
|
74
|
+
*/
|
|
75
|
+
async setCCTAndIntensityForAllLights(cct, intensity, callback) {
|
|
76
|
+
await this.applyToAllLights((nodeId) => this.setCCT(nodeId, cct, intensity, callback), 'Setting CCT', () => ` to ${cct}K${intensity !== undefined ? ` at ${intensity / 10}%` : ''}`);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Turn on all lights.
|
|
80
|
+
*/
|
|
81
|
+
async turnOnAllLights(callback) {
|
|
82
|
+
await this.applyToAllLights((nodeId) => this.turnLightOn(nodeId, callback), 'Turning on');
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Turn off all lights.
|
|
86
|
+
*/
|
|
87
|
+
async turnOffAllLights(callback) {
|
|
88
|
+
await this.applyToAllLights((nodeId) => this.turnLightOff(nodeId, callback), 'Turning off');
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Toggle all lights.
|
|
92
|
+
*/
|
|
93
|
+
async toggleAllLights(callback) {
|
|
94
|
+
await this.applyToAllLights((nodeId) => this.toggleLight(nodeId, callback), 'Toggling');
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Set intensity for all lights.
|
|
98
|
+
*/
|
|
99
|
+
async setIntensityForAllLights(intensity, callback) {
|
|
100
|
+
await this.applyToAllLights((nodeId) => this.setIntensity(nodeId, intensity, callback), 'Setting intensity', () => ` to ${intensity / 10}%`);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Increment intensity for all lights.
|
|
104
|
+
*/
|
|
105
|
+
async incrementIntensityForAllLights(delta, callback) {
|
|
106
|
+
await this.applyToAllLights((nodeId) => this.incrementIntensity(nodeId, delta, callback), 'Incrementing intensity', () => ` by ${delta > 0 ? '+' : ''}${delta / 10}%`);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Increment CCT for all lights.
|
|
110
|
+
*/
|
|
111
|
+
async incrementCCTForAllLights(delta, intensity, callback) {
|
|
112
|
+
await this.applyToAllLights((nodeId) => this.incrementCCT(nodeId, delta, intensity, callback), 'Incrementing CCT', () => ` by ${delta > 0 ? '+' : ''}${delta}K${intensity !== undefined ? ` at ${intensity / 10}%` : ''}`);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Set HSI color for all lights.
|
|
116
|
+
*/
|
|
117
|
+
async setHSIForAllLights(hue, sat, intensity, cct, gm, callback) {
|
|
118
|
+
await this.applyToAllLights((nodeId) => this.setHSI(nodeId, hue, sat, intensity, cct, gm, callback), 'Setting HSI', () => ` to H:${hue} S:${sat} I:${intensity / 10}%`);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Set color for all lights.
|
|
122
|
+
*/
|
|
123
|
+
async setColorForAllLights(color, intensity, callback) {
|
|
124
|
+
await this.applyToAllLights((nodeId) => this.setColor(nodeId, color, intensity, callback), 'Setting color', () => ` to ${color}${intensity !== undefined ? ` at ${intensity / 10}%` : ''}`);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Set system effect for all lights.
|
|
128
|
+
*/
|
|
129
|
+
async setSystemEffectForAllLights(effectType, intensity, callback) {
|
|
130
|
+
await this.applyToAllLights((nodeId) => this.setSystemEffect(nodeId, effectType, intensity, callback), 'Setting effect', () => ` to ${effectType}${intensity !== undefined ? ` at ${intensity / 10}%` : ''}`);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Check if a node_id looks like a light device (not a group or other entity).
|
|
134
|
+
* Light node_ids typically follow pattern like '400J5-F2C008' (alphanumeric with dash).
|
|
135
|
+
*/
|
|
136
|
+
isLightNodeId(nodeId) {
|
|
137
|
+
// Pattern: contains at least one dash and alphanumeric characters
|
|
138
|
+
// Excludes things like 'all', 'group1', etc.
|
|
139
|
+
const lightPattern = /^[A-Z0-9]+-[A-Z0-9]+$/i;
|
|
140
|
+
return lightPattern.test(nodeId);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Sleep utility for throttling commands
|
|
144
|
+
*/
|
|
145
|
+
sleep(ms) {
|
|
146
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
147
|
+
}
|
|
148
|
+
constructor(wsUrl, clientId, onInitialized, debug = false) {
|
|
149
|
+
this.clientId = 'unknown_client';
|
|
150
|
+
this.deviceList = [];
|
|
151
|
+
this.sceneList = [];
|
|
152
|
+
this.nodeConfigs = new Map();
|
|
153
|
+
this.commandCallbacks = new Map();
|
|
154
|
+
this.pendingQueue = [];
|
|
155
|
+
this.ws = new ws_1.default(wsUrl);
|
|
156
|
+
if (clientId) {
|
|
157
|
+
this.clientId = clientId;
|
|
158
|
+
}
|
|
159
|
+
this.debug = debug;
|
|
160
|
+
if (onInitialized) {
|
|
161
|
+
this.onInitializedCallback = onInitialized;
|
|
162
|
+
}
|
|
163
|
+
this.ws.on('open', () => {
|
|
164
|
+
this.log('Connected to WebSocket server');
|
|
165
|
+
// Flush any queued commands that were issued before the socket was open
|
|
166
|
+
this.flushPending();
|
|
167
|
+
this.onConnectionOpen();
|
|
168
|
+
});
|
|
169
|
+
this.ws.on('message', (data) => {
|
|
170
|
+
try {
|
|
171
|
+
const parsedData = JSON.parse(data.toString());
|
|
172
|
+
this.log('Received message from server:', parsedData);
|
|
173
|
+
const requestId = parsedData.request?.type;
|
|
174
|
+
if (parsedData.code !== 0) {
|
|
175
|
+
console.error('Error from server:', parsedData.message);
|
|
176
|
+
if (requestId && this.commandCallbacks.has(requestId)) {
|
|
177
|
+
this.commandCallbacks.get(requestId)?.(false, parsedData.message);
|
|
178
|
+
this.commandCallbacks.delete(requestId);
|
|
179
|
+
}
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
if (requestId && this.commandCallbacks.has(requestId)) {
|
|
183
|
+
this.commandCallbacks.get(requestId)?.(true, parsedData.message, parsedData.data);
|
|
184
|
+
this.commandCallbacks.delete(requestId);
|
|
185
|
+
}
|
|
186
|
+
if (parsedData.request?.type) {
|
|
187
|
+
switch (parsedData.request.type) {
|
|
188
|
+
case 'get_device_list':
|
|
189
|
+
this.handleDeviceList(parsedData.data);
|
|
190
|
+
break;
|
|
191
|
+
case 'get_scene_list':
|
|
192
|
+
this.handleSceneList(parsedData.data);
|
|
193
|
+
break;
|
|
194
|
+
case 'get_node_config':
|
|
195
|
+
this.handleNodeConfig(parsedData.data);
|
|
196
|
+
break;
|
|
197
|
+
default:
|
|
198
|
+
this.log('Unknown response type');
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
console.error('Error parsing message:', error);
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
this.ws.on('error', (error) => {
|
|
207
|
+
console.error('WebSocket error:', error);
|
|
208
|
+
});
|
|
209
|
+
this.ws.on('close', () => {
|
|
210
|
+
this.log('Disconnected from WebSocket server');
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
setClientId(clientId) {
|
|
214
|
+
this.clientId = clientId;
|
|
215
|
+
}
|
|
216
|
+
onConnectionOpen() {
|
|
217
|
+
this.getDeviceList();
|
|
218
|
+
}
|
|
219
|
+
sendCommand(nodeId, type, args, callback) {
|
|
220
|
+
if (this.ws.readyState === ws_1.default.OPEN) {
|
|
221
|
+
const command = {
|
|
222
|
+
version: 1,
|
|
223
|
+
client_id: this.clientId,
|
|
224
|
+
type,
|
|
225
|
+
node_id: nodeId,
|
|
226
|
+
args,
|
|
227
|
+
};
|
|
228
|
+
if (callback) {
|
|
229
|
+
this.commandCallbacks.set(type, callback);
|
|
230
|
+
}
|
|
231
|
+
this.ws.send(JSON.stringify(command));
|
|
232
|
+
this.log(`Sent command: ${type}`);
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
// Queue the command to be sent when the socket opens
|
|
236
|
+
this.pendingQueue.push({ nodeId, type, args, callback });
|
|
237
|
+
this.log(`Queued command (socket not open yet): ${type}`);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
handleDeviceList(data) {
|
|
241
|
+
this.deviceList = data.data;
|
|
242
|
+
this.log('Device List:', JSON.stringify(this.deviceList, null, 2));
|
|
243
|
+
this.getSceneList();
|
|
244
|
+
}
|
|
245
|
+
handleSceneList(data) {
|
|
246
|
+
this.sceneList = data.data;
|
|
247
|
+
this.log('Scene List:', JSON.stringify(this.sceneList, null, 2));
|
|
248
|
+
this.getNodeConfigs();
|
|
249
|
+
}
|
|
250
|
+
handleNodeConfig(data) {
|
|
251
|
+
const nodeId = data.node_id;
|
|
252
|
+
if (nodeId) {
|
|
253
|
+
this.nodeConfigs.set(nodeId, data.data);
|
|
254
|
+
this.log('Node Config:', JSON.stringify(data.data, null, 2));
|
|
255
|
+
if (this.nodeConfigs.size === this.deviceList.length) {
|
|
256
|
+
this.log('All node configurations have been gathered');
|
|
257
|
+
if (this.onInitializedCallback) {
|
|
258
|
+
this.onInitializedCallback();
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
getNodeConfigs() {
|
|
264
|
+
this.deviceList.forEach((device) => {
|
|
265
|
+
if (device.node_id) {
|
|
266
|
+
this.getNodeConfig(device.node_id);
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
getDeviceList(callback) {
|
|
271
|
+
this.sendCommand(undefined, 'get_device_list', {}, callback);
|
|
272
|
+
}
|
|
273
|
+
getSceneList(callback) {
|
|
274
|
+
this.sendCommand(undefined, 'get_scene_list', {}, callback);
|
|
275
|
+
}
|
|
276
|
+
getNodeConfig(nodeId, callback) {
|
|
277
|
+
this.sendCommand(nodeId, 'get_node_config', {}, callback);
|
|
278
|
+
}
|
|
279
|
+
turnLightOn(nodeId, callback) {
|
|
280
|
+
this.sendCommand(nodeId, 'set_sleep', { sleep: false }, callback);
|
|
281
|
+
}
|
|
282
|
+
turnLightOff(nodeId, callback) {
|
|
283
|
+
this.sendCommand(nodeId, 'set_sleep', { sleep: true }, callback);
|
|
284
|
+
}
|
|
285
|
+
getLightSleepStatus(nodeId, callback) {
|
|
286
|
+
this.sendCommand(nodeId, 'get_sleep', {}, callback);
|
|
287
|
+
}
|
|
288
|
+
toggleLight(nodeId, callback) {
|
|
289
|
+
this.sendCommand(nodeId, 'toggle_sleep', undefined, callback);
|
|
290
|
+
}
|
|
291
|
+
setIntensity(nodeId, intensity, callback) {
|
|
292
|
+
this.sendCommand(nodeId, 'set_intensity', { intensity }, callback);
|
|
293
|
+
}
|
|
294
|
+
incrementIntensity(nodeId, delta, callback) {
|
|
295
|
+
this.sendCommand(nodeId, 'increment_intensity', { delta }, callback);
|
|
296
|
+
}
|
|
297
|
+
setCCT(nodeId, cct, intensity, callback) {
|
|
298
|
+
const args = { cct };
|
|
299
|
+
if (intensity !== undefined) {
|
|
300
|
+
args.intensity = intensity;
|
|
301
|
+
}
|
|
302
|
+
this.sendCommand(nodeId, 'set_cct', args, callback);
|
|
303
|
+
}
|
|
304
|
+
incrementCCT(nodeId, delta, intensity, callback) {
|
|
305
|
+
const args = { delta };
|
|
306
|
+
if (intensity !== undefined) {
|
|
307
|
+
args.intensity = intensity;
|
|
308
|
+
}
|
|
309
|
+
this.sendCommand(nodeId, 'increment_cct', args, callback);
|
|
310
|
+
}
|
|
311
|
+
setHSI(nodeId, hue, sat, intensity, cct, gm, callback) {
|
|
312
|
+
const args = { hue, sat, intensity };
|
|
313
|
+
if (cct !== undefined) {
|
|
314
|
+
args.cct = cct;
|
|
315
|
+
}
|
|
316
|
+
if (gm !== undefined) {
|
|
317
|
+
args.gm = gm;
|
|
318
|
+
}
|
|
319
|
+
this.sendCommand(nodeId, 'set_hsi', args, callback);
|
|
320
|
+
}
|
|
321
|
+
setColor(nodeId, color, intensity, callback) {
|
|
322
|
+
const args = { color };
|
|
323
|
+
if (intensity !== undefined) {
|
|
324
|
+
args.intensity = intensity;
|
|
325
|
+
}
|
|
326
|
+
this.sendCommand(nodeId, 'set_color', args, callback);
|
|
327
|
+
}
|
|
328
|
+
setSystemEffect(nodeId, effectType, intensity, callback) {
|
|
329
|
+
const args = { effect_type: effectType };
|
|
330
|
+
if (intensity !== undefined) {
|
|
331
|
+
args.intensity = intensity;
|
|
332
|
+
}
|
|
333
|
+
this.sendCommand(nodeId, 'set_system_effect', args, callback);
|
|
334
|
+
}
|
|
335
|
+
async disconnect() {
|
|
336
|
+
if (this.ws.readyState === ws_1.default.OPEN) {
|
|
337
|
+
await this.waitForPendingCommands(5000);
|
|
338
|
+
this.ws.close();
|
|
339
|
+
this.log('WebSocket connection closed');
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
console.error('WebSocket is not open or already closed');
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
waitForPendingCommands(timeout) {
|
|
346
|
+
return new Promise((resolve) => {
|
|
347
|
+
const start = Date.now();
|
|
348
|
+
const checkPendingCommands = () => {
|
|
349
|
+
if (this.commandCallbacks.size === 0 || Date.now() - start >= timeout) {
|
|
350
|
+
resolve();
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
setTimeout(checkPendingCommands, 100);
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
checkPendingCommands();
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
// Getters
|
|
360
|
+
getDevices() {
|
|
361
|
+
return this.deviceList;
|
|
362
|
+
}
|
|
363
|
+
getScenes() {
|
|
364
|
+
return this.sceneList;
|
|
365
|
+
}
|
|
366
|
+
getNode(nodeId) {
|
|
367
|
+
return this.nodeConfigs.get(nodeId);
|
|
368
|
+
}
|
|
369
|
+
log(...args) {
|
|
370
|
+
if (this.debug) {
|
|
371
|
+
console.log(...args);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
flushPending() {
|
|
375
|
+
if (this.pendingQueue.length === 0)
|
|
376
|
+
return;
|
|
377
|
+
const pending = [...this.pendingQueue];
|
|
378
|
+
this.pendingQueue.length = 0;
|
|
379
|
+
for (const p of pending) {
|
|
380
|
+
this.sendCommand(p.nodeId, p.type, p.args, p.callback);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
exports.default = LightController;
|
|
385
|
+
//# sourceMappingURL=lightControl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lightControl.js","sourceRoot":"","sources":["../src/lightControl.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type LightController from './lightControl';
|
|
2
|
+
export type { LightController };
|
|
3
|
+
export interface Device {
|
|
4
|
+
node_id?: string;
|
|
5
|
+
device_name?: string;
|
|
6
|
+
name?: string;
|
|
7
|
+
id?: string;
|
|
8
|
+
[key: string]: unknown;
|
|
9
|
+
}
|
|
10
|
+
export type CommandCallback = (success: boolean, message: string, data?: unknown) => void;
|
|
11
|
+
export interface Config {
|
|
12
|
+
wsUrl?: string;
|
|
13
|
+
latitude?: number;
|
|
14
|
+
longitude?: number;
|
|
15
|
+
[key: string]: unknown;
|
|
16
|
+
}
|
|
17
|
+
export interface CommandDeps {
|
|
18
|
+
createController: (wsUrl?: string, clientId?: string, debug?: boolean) => Promise<LightController>;
|
|
19
|
+
findDevice: (controller: LightController, deviceQuery: string) => Device | null;
|
|
20
|
+
asyncCommand: <T extends unknown[]>(fn: (...args: T) => Promise<void>) => (...args: T) => Promise<void>;
|
|
21
|
+
saveWsUrl?: (url: string) => void;
|
|
22
|
+
loadConfig?: () => Config | null;
|
|
23
|
+
}
|
|
24
|
+
export interface CommandOptions {
|
|
25
|
+
url?: string;
|
|
26
|
+
clientId?: string;
|
|
27
|
+
debug?: boolean;
|
|
28
|
+
intensity?: string;
|
|
29
|
+
interval?: string;
|
|
30
|
+
follow?: boolean;
|
|
31
|
+
errors?: boolean;
|
|
32
|
+
lat?: string;
|
|
33
|
+
lon?: string;
|
|
34
|
+
date?: string;
|
|
35
|
+
[key: string]: unknown;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,eAAe,MAAM,gBAAgB,CAAC;AAElD,YAAY,EAAE,eAAe,EAAE,CAAC;AAEhC,MAAM,WAAW,MAAM;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;AAE1F,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,gBAAgB,EAAE,CAChB,KAAK,CAAC,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,OAAO,KACZ,OAAO,CAAC,eAAe,CAAC,CAAC;IAC9B,UAAU,EAAE,CAAC,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAChF,YAAY,EAAE,CAAC,CAAC,SAAS,OAAO,EAAE,EAChC,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,KAC9B,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "amaran-light-cli",
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "Command line tool for controlling Aputure Amaran lights via WebSocket to a local Amaran desktop app.",
|
|
5
|
+
"main": "dist/lightControl.js",
|
|
6
|
+
"types": "dist/lightControl.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"amaran-cli": "dist/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"start": "node dist/cli.js",
|
|
13
|
+
"dev": "ts-node src/cli.ts",
|
|
14
|
+
"test": "jest",
|
|
15
|
+
"test:watch": "jest --watch",
|
|
16
|
+
"test:coverage": "jest --coverage",
|
|
17
|
+
"clean": "rm -rf dist",
|
|
18
|
+
"prepublishOnly": "npm run clean && npm run build",
|
|
19
|
+
"lint": "biome lint src/",
|
|
20
|
+
"lint:fix": "biome lint --apply src/",
|
|
21
|
+
"format": "biome format --write src/",
|
|
22
|
+
"format:check": "biome format src/",
|
|
23
|
+
"check": "biome check src/",
|
|
24
|
+
"check:fix": "biome check --apply src/"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"scripts",
|
|
29
|
+
"README.md",
|
|
30
|
+
"LICENSE",
|
|
31
|
+
"CHANGELOG.md"
|
|
32
|
+
],
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "https://github.com/theontho/amaran-cli.git"
|
|
36
|
+
},
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/theontho/amaran-cli/issues"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://github.com/theontho/amaran-cli#readme",
|
|
41
|
+
"keywords": [
|
|
42
|
+
"amaran",
|
|
43
|
+
"aputure",
|
|
44
|
+
"lighting",
|
|
45
|
+
"cli",
|
|
46
|
+
"websocket",
|
|
47
|
+
"smart-home",
|
|
48
|
+
"home-automation",
|
|
49
|
+
"circadian"
|
|
50
|
+
],
|
|
51
|
+
"author": "Mahyar McDonald <github@hmmfn.com>",
|
|
52
|
+
"license": "MIT",
|
|
53
|
+
"engines": {
|
|
54
|
+
"node": ">=14.0.0"
|
|
55
|
+
},
|
|
56
|
+
"dependencies": {
|
|
57
|
+
"chalk": "^4.1.2",
|
|
58
|
+
"commander": "^11.1.0",
|
|
59
|
+
"geoip-lite": "^1.4.10",
|
|
60
|
+
"suncalc": "^1.9.0",
|
|
61
|
+
"ws": "^8.14.2"
|
|
62
|
+
},
|
|
63
|
+
"devDependencies": {
|
|
64
|
+
"@biomejs/biome": "^2.3.1",
|
|
65
|
+
"@types/geoip-lite": "^1.4.4",
|
|
66
|
+
"@types/jest": "^30.0.0",
|
|
67
|
+
"@types/node": "^20.8.0",
|
|
68
|
+
"@types/suncalc": "^1.9.0",
|
|
69
|
+
"@types/ws": "^8.5.8",
|
|
70
|
+
"jest": "^30.2.0",
|
|
71
|
+
"ts-jest": "^29.4.5",
|
|
72
|
+
"ts-node": "^10.9.1",
|
|
73
|
+
"typescript": "^5.2.2"
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Script to create a launchd service for auto-cct
|
|
4
|
+
# Usage: ./scripts/create-launchd-service.sh
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
# Check if amaran-cli is globally installed first
|
|
9
|
+
if command -v amaran-cli >/dev/null 2>&1; then
|
|
10
|
+
AMARAN_CLI=$(which amaran-cli)
|
|
11
|
+
IS_GLOBAL=true
|
|
12
|
+
echo "Found global installation: $AMARAN_CLI"
|
|
13
|
+
else
|
|
14
|
+
# Fall back to local development build
|
|
15
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
16
|
+
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
|
17
|
+
AMARAN_CLI="$PROJECT_DIR/dist/cli.js"
|
|
18
|
+
IS_GLOBAL=false
|
|
19
|
+
|
|
20
|
+
# Check if the CLI is built
|
|
21
|
+
if [ ! -f "$AMARAN_CLI" ]; then
|
|
22
|
+
echo "Error: amaran-cli not found at $AMARAN_CLI"
|
|
23
|
+
echo "Please either:"
|
|
24
|
+
echo " 1. Install globally: npm install -g ."
|
|
25
|
+
echo " 2. Or build locally: npm run build"
|
|
26
|
+
exit 1
|
|
27
|
+
fi
|
|
28
|
+
echo "Using local development build: $AMARAN_CLI"
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# Plist file path
|
|
32
|
+
PLIST_NAME="com.hmmfn.amaran.circadian-service"
|
|
33
|
+
PLIST_PATH="$HOME/Library/LaunchAgents/$PLIST_NAME.plist"
|
|
34
|
+
|
|
35
|
+
# Create the plist content
|
|
36
|
+
if [ "$IS_GLOBAL" = true ]; then
|
|
37
|
+
# For global installation, use the executable directly
|
|
38
|
+
cat > "$PLIST_PATH" << EOF
|
|
39
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
40
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
41
|
+
<plist version="1.0">
|
|
42
|
+
<dict>
|
|
43
|
+
<key>Label</key>
|
|
44
|
+
<string>$PLIST_NAME</string>
|
|
45
|
+
<key>ProgramArguments</key>
|
|
46
|
+
<array>
|
|
47
|
+
<string>$AMARAN_CLI</string>
|
|
48
|
+
<string>auto-cct</string>
|
|
49
|
+
</array>
|
|
50
|
+
<key>StartInterval</key>
|
|
51
|
+
<integer>60</integer>
|
|
52
|
+
<key>RunAtLoad</key>
|
|
53
|
+
<true/>
|
|
54
|
+
<key>KeepAlive</key>
|
|
55
|
+
<false/>
|
|
56
|
+
<key>StandardOutPath</key>
|
|
57
|
+
<string>$HOME/Library/Logs/amaran-circadian-service.log</string>
|
|
58
|
+
<key>StandardErrorPath</key>
|
|
59
|
+
<string>$HOME/Library/Logs/amaran-circadian-service-error.log</string>
|
|
60
|
+
</dict>
|
|
61
|
+
</plist>
|
|
62
|
+
EOF
|
|
63
|
+
else
|
|
64
|
+
# For local development, use node to run the script
|
|
65
|
+
cat > "$PLIST_PATH" << EOF
|
|
66
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
67
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
68
|
+
<plist version="1.0">
|
|
69
|
+
<dict>
|
|
70
|
+
<key>Label</key>
|
|
71
|
+
<string>$PLIST_NAME</string>
|
|
72
|
+
<key>ProgramArguments</key>
|
|
73
|
+
<array>
|
|
74
|
+
<string>/usr/local/bin/node</string>
|
|
75
|
+
<string>$AMARAN_CLI</string>
|
|
76
|
+
<string>auto-cct</string>
|
|
77
|
+
</array>
|
|
78
|
+
<key>StartInterval</key>
|
|
79
|
+
<integer>60</integer>
|
|
80
|
+
<key>RunAtLoad</key>
|
|
81
|
+
<true/>
|
|
82
|
+
<key>KeepAlive</key>
|
|
83
|
+
<false/>
|
|
84
|
+
<key>StandardOutPath</key>
|
|
85
|
+
<string>$HOME/Library/Logs/amaran-circadian-service.log</string>
|
|
86
|
+
<key>StandardErrorPath</key>
|
|
87
|
+
<string>$HOME/Library/Logs/amaran-circadian-service-error.log</string>
|
|
88
|
+
<key>WorkingDirectory</key>
|
|
89
|
+
<string>$PROJECT_DIR</string>
|
|
90
|
+
</dict>
|
|
91
|
+
</plist>
|
|
92
|
+
EOF
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
echo "Created launchd plist at: $PLIST_PATH"
|
|
96
|
+
echo "Installation type: $([ "$IS_GLOBAL" = true ] && echo "Global" || echo "Local development")"
|
|
97
|
+
echo "CLI path: $AMARAN_CLI"
|
|
98
|
+
|
|
99
|
+
# Load the service
|
|
100
|
+
launchctl load "$PLIST_PATH"
|
|
101
|
+
echo "Loaded launchd circadian lighting service: $PLIST_NAME"
|
|
102
|
+
|
|
103
|
+
echo ""
|
|
104
|
+
echo "Circadian lighting service commands:"
|
|
105
|
+
echo " Start: launchctl start $PLIST_NAME"
|
|
106
|
+
echo " Stop: launchctl stop $PLIST_NAME"
|
|
107
|
+
echo " Unload: launchctl unload $PLIST_PATH"
|
|
108
|
+
echo " Status: launchctl list | grep $PLIST_NAME"
|
|
109
|
+
echo ""
|
|
110
|
+
echo "Logs:"
|
|
111
|
+
echo " Output: tail -f $HOME/Library/Logs/amaran-circadian-service.log"
|
|
112
|
+
echo " Errors: tail -f $HOME/Library/Logs/amaran-circadian-service-error.log"
|
|
113
|
+
|
|
114
|
+
chmod +x /Users/mac/Documents/src/amaran-cli/scripts/create-launchd-service.sh
|