amaran-light-cli 1.1.2 → 1.3.6
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/CHANGELOG.md +44 -5
- package/README.md +94 -70
- package/dist/__tests__/autoCct.test.js +89 -20
- package/dist/__tests__/autoCct.test.js.map +1 -1
- package/dist/__tests__/autostart.test.js +87 -41
- package/dist/__tests__/autostart.test.js.map +1 -1
- package/dist/__tests__/cctUtil.test.js +26 -27
- package/dist/__tests__/cctUtil.test.js.map +1 -1
- package/dist/__tests__/cli.smoke.test.js +18 -13
- package/dist/__tests__/cli.smoke.test.js.map +1 -1
- package/dist/__tests__/intensityApi.test.js +4 -9
- package/dist/__tests__/intensityApi.test.js.map +1 -1
- package/dist/__tests__/lightControl.test.js +79 -68
- package/dist/__tests__/lightControl.test.js.map +1 -1
- package/dist/__tests__/setupTests.js +9 -8
- package/dist/__tests__/setupTests.js.map +1 -1
- package/dist/__tests__/simulateSchedule.test.d.ts +2 -0
- package/dist/__tests__/simulateSchedule.test.d.ts.map +1 -0
- package/dist/__tests__/simulateSchedule.test.js +87 -0
- package/dist/__tests__/simulateSchedule.test.js.map +1 -0
- package/dist/autostart.js +19 -60
- package/dist/autostart.js.map +1 -1
- package/dist/cctUtil.d.ts.map +1 -1
- package/dist/cctUtil.js +16 -21
- package/dist/cctUtil.js.map +1 -1
- package/dist/cli.d.ts +2 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +52 -231
- package/dist/cli.js.map +1 -1
- package/dist/commands/__tests__/integration.test.d.ts +2 -0
- package/dist/commands/__tests__/integration.test.d.ts.map +1 -0
- package/dist/commands/__tests__/integration.test.js +279 -0
- package/dist/commands/__tests__/integration.test.js.map +1 -0
- package/dist/commands/autoCct.d.ts +1 -1
- package/dist/commands/autoCct.d.ts.map +1 -1
- package/dist/commands/autoCct.js +90 -76
- package/dist/commands/autoCct.js.map +1 -1
- package/dist/commands/cct.d.ts +1 -1
- package/dist/commands/cct.d.ts.map +1 -1
- package/dist/commands/cct.js +17 -23
- package/dist/commands/cct.js.map +1 -1
- package/dist/commands/color.d.ts +1 -1
- package/dist/commands/color.d.ts.map +1 -1
- package/dist/commands/color.js +9 -15
- package/dist/commands/color.js.map +1 -1
- package/dist/commands/config.d.ts +4 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +219 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/discover.d.ts +1 -1
- package/dist/commands/discover.d.ts.map +1 -1
- package/dist/commands/discover.js +8 -14
- package/dist/commands/discover.js.map +1 -1
- package/dist/commands/hsi.d.ts +1 -1
- package/dist/commands/hsi.d.ts.map +1 -1
- package/dist/commands/hsi.js +11 -17
- package/dist/commands/hsi.js.map +1 -1
- package/dist/commands/intensity.d.ts +1 -1
- package/dist/commands/intensity.d.ts.map +1 -1
- package/dist/commands/intensity.js +9 -15
- package/dist/commands/intensity.js.map +1 -1
- package/dist/commands/list.d.ts +1 -1
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/list.js +6 -12
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/power.d.ts +1 -1
- package/dist/commands/power.d.ts.map +1 -1
- package/dist/commands/power.js +18 -24
- package/dist/commands/power.js.map +1 -1
- package/dist/commands/printSchedule.d.ts +5 -0
- package/dist/commands/printSchedule.d.ts.map +1 -0
- package/dist/commands/{schedule.js → printSchedule.js} +92 -84
- package/dist/commands/printSchedule.js.map +1 -0
- package/dist/commands/service.d.ts +1 -1
- package/dist/commands/service.d.ts.map +1 -1
- package/dist/commands/service.js +54 -88
- package/dist/commands/service.js.map +1 -1
- package/dist/commands/simulateSchedule.d.ts +1 -1
- package/dist/commands/simulateSchedule.d.ts.map +1 -1
- package/dist/commands/simulateSchedule.js +50 -70
- package/dist/commands/simulateSchedule.js.map +1 -1
- package/dist/commands/status.d.ts +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +8 -14
- package/dist/commands/status.js.map +1 -1
- package/dist/commands.d.ts +1 -1
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +56 -33
- package/dist/commands.js.map +1 -1
- package/dist/constants.d.ts +13 -14
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +21 -27
- package/dist/constants.js.map +1 -1
- package/dist/discovery.js +8 -15
- package/dist/discovery.js.map +1 -1
- package/dist/geoipUtil.js +3 -9
- package/dist/geoipUtil.js.map +1 -1
- package/dist/lightControl.js +18 -20
- package/dist/lightControl.js.map +1 -1
- package/dist/test/MockLightServer.d.ts +13 -0
- package/dist/test/MockLightServer.d.ts.map +1 -0
- package/dist/test/MockLightServer.js +140 -0
- package/dist/test/MockLightServer.js.map +1 -0
- package/dist/types.d.ts +4 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -2
- package/package.json +16 -15
- package/scripts/release.js +112 -0
- package/scripts/test.sh +2 -5
- package/dist/commands/schedule.d.ts +0 -5
- package/dist/commands/schedule.d.ts.map +0 -1
- package/dist/commands/schedule.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,51 @@
|
|
|
1
|
-
|
|
1
|
+
## [1.3.6] - 2025-12-14
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
- **Fix**: Updated workflow to use latest `npm` version for better OIDC support.
|
|
4
4
|
|
|
5
|
-
## [1.
|
|
5
|
+
## [1.3.5] - 2025-12-14
|
|
6
|
+
|
|
7
|
+
- **Fix**: Re-applied `registry-url` configuration fix (previous attempt in v1.3.4 failed to update workflow).
|
|
8
|
+
|
|
9
|
+
## [1.3.4] - 2025-12-14
|
|
10
|
+
|
|
11
|
+
- **Fix**: Restored `registry-url` configuration (required for OIDC `ENEEDAUTH` fix).
|
|
12
|
+
|
|
13
|
+
## [1.3.3] - 2025-12-14
|
|
14
|
+
|
|
15
|
+
- **Fix**: Removed conflicting `registry-url` configuration to enable OIDC authentication.
|
|
16
|
+
|
|
17
|
+
## [1.3.2] - 2025-12-14
|
|
18
|
+
|
|
19
|
+
- **Fix**: Updated release workflow to use NPM Trusted Publishing (OIDC) instead of auth tokens.
|
|
20
|
+
|
|
21
|
+
## [1.3.1] - 2025-12-14
|
|
22
|
+
|
|
23
|
+
- **Fix**: Resolved timezone issue in integration tests causing CI failures.
|
|
24
|
+
|
|
25
|
+
## [1.3.0] - 2025-12-14
|
|
26
|
+
|
|
27
|
+
- **Breaking**: Migrated project to ESM (`type: module`).
|
|
28
|
+
- **Breaking**: Migrated testing framework from Jest to Vitest.
|
|
29
|
+
- **Feature**: Added `intensityMultiplier` support to `auto-cct`.
|
|
30
|
+
- **Feature**: `auto-cct` command now accepts a device argument (defaults to 'all').
|
|
31
|
+
- **Refactor**: Renamed `schedule` command to `print-schedule`.
|
|
32
|
+
- **Fix**: Resolved `suncalc` import issues.
|
|
33
|
+
- **Fix**: Improved CLI output styling for light mode terminals.
|
|
34
|
+
- **Chore**: Comprehensive linting and formatting fixes.
|
|
35
|
+
|
|
36
|
+
## [1.1.4] - 2025-11-02
|
|
37
|
+
|
|
38
|
+
- test token config
|
|
39
|
+
|
|
40
|
+
## [1.1.3] - 2025-11-02
|
|
41
|
+
|
|
42
|
+
- curve config and refactors
|
|
43
|
+
|
|
44
|
+
## [1.1.2] - 2025-11-01
|
|
6
45
|
|
|
7
46
|
- Enhanced CLI help output and documentation
|
|
8
47
|
|
|
9
|
-
## [1.1.0] -
|
|
48
|
+
## [1.1.0] - 2025-10-31
|
|
10
49
|
|
|
11
50
|
- Added more curves for auto-cct
|
|
12
51
|
- Improved schedule table display with all curves
|
|
@@ -16,7 +55,7 @@ All notable changes to this project will be documented in this file.
|
|
|
16
55
|
- Added more special times in schedule (e.g., Nautical Dawn)
|
|
17
56
|
- Various tests and refactoring
|
|
18
57
|
|
|
19
|
-
## [1.0.3] -
|
|
58
|
+
## [1.0.3] - 2025-10-30
|
|
20
59
|
|
|
21
60
|
- Initial stable release with full CLI functionality
|
|
22
61
|
- WebSocket control for Aputure Amaran lights
|
package/README.md
CHANGED
|
@@ -10,14 +10,19 @@ Written with AI mostly, including this documentation. Thanks to [Zac for his co
|
|
|
10
10
|
|
|
11
11
|
1. Clone this repository or download the files
|
|
12
12
|
2. Install dependencies:
|
|
13
|
+
|
|
13
14
|
```bash
|
|
14
15
|
npm install
|
|
15
16
|
```
|
|
17
|
+
|
|
16
18
|
3. Build the project:
|
|
19
|
+
|
|
17
20
|
```bash
|
|
18
21
|
npm run build
|
|
19
22
|
```
|
|
23
|
+
|
|
20
24
|
4. Optionally, install globally:
|
|
25
|
+
|
|
21
26
|
```bash
|
|
22
27
|
npm install -g .
|
|
23
28
|
```
|
|
@@ -64,9 +69,17 @@ amaran-cli discover -d
|
|
|
64
69
|
|
|
65
70
|
This command uses `lsof` to find the WebSocket port that the Amaran Desktop application is listening on, then saves it to your configuration file for future use.
|
|
66
71
|
|
|
72
|
+
## Device Identification
|
|
73
|
+
|
|
74
|
+
Devices can be identified by:
|
|
75
|
+
|
|
76
|
+
- **Device name**: Case-insensitive partial matching (e.g., "key" matches "Key Light")
|
|
77
|
+
- **Node ID**: Exact match of the device's node_id
|
|
78
|
+
|
|
67
79
|
## Usage
|
|
68
80
|
|
|
69
81
|
### List all available lights
|
|
82
|
+
|
|
70
83
|
```bash
|
|
71
84
|
amaran-cli list
|
|
72
85
|
# or
|
|
@@ -74,6 +87,7 @@ amaran-cli ls
|
|
|
74
87
|
```
|
|
75
88
|
|
|
76
89
|
### Control lights
|
|
90
|
+
|
|
77
91
|
```bash
|
|
78
92
|
# Turn light on
|
|
79
93
|
amaran-cli on "Light Name"
|
|
@@ -96,6 +110,7 @@ amaran-cli toggle
|
|
|
96
110
|
```
|
|
97
111
|
|
|
98
112
|
### Set light properties
|
|
113
|
+
|
|
99
114
|
```bash
|
|
100
115
|
# Set intensity (0-100%)
|
|
101
116
|
amaran-cli intensity 75 "Light Name"
|
|
@@ -135,6 +150,7 @@ amaran-cli color blue -i 50
|
|
|
135
150
|
**Note:** For all commands that support device names, you can omit the device name or use `all` to apply the command to all lights. Commands are throttled with 250ms delay between each device to prevent overwhelming the server.
|
|
136
151
|
|
|
137
152
|
### Auto CCT (Circadian Lighting)
|
|
153
|
+
|
|
138
154
|
```bash
|
|
139
155
|
# Set CCT for all lights based on current time and location (auto-detected via geoip)
|
|
140
156
|
amaran-cli auto-cct
|
|
@@ -156,18 +172,21 @@ amaran-cli auto-cct -d
|
|
|
156
172
|
```
|
|
157
173
|
|
|
158
174
|
The `auto-cct` command automatically adjusts color temperature based on sunrise/sunset times for your location. By default, it maps the circadian curve to:
|
|
175
|
+
|
|
159
176
|
- **Before sunrise / After sunset**: 2000K at 5% intensity (warm, dim night lighting)
|
|
160
177
|
- **Solar noon**: 6500K at 100% intensity (cool, bright daylight)
|
|
161
178
|
- **Between sunrise and sunset**: Smooth bell curve transition from 2000K/5% → 6500K/100% → 2000K/5%
|
|
162
179
|
|
|
163
180
|
This mimics natural daylight changes throughout the day for more comfortable, circadian-friendly lighting. Both color temperature and brightness follow the same curve, providing natural dimming at dawn/dusk.
|
|
164
181
|
|
|
165
|
-
|
|
182
|
+
#### Location Priority
|
|
183
|
+
|
|
166
184
|
1. Command-line `--lat` and `--lon` arguments (highest priority)
|
|
167
185
|
2. Config file defaults (set with `amaran-cli config --lat <lat> --lon <lon>`)
|
|
168
186
|
3. GeoIP lookup based on public IP address (fallback)
|
|
169
187
|
|
|
170
|
-
|
|
188
|
+
#### Bounds (optional)
|
|
189
|
+
|
|
171
190
|
You can constrain the auto-cct curve to your preferred ranges via config:
|
|
172
191
|
|
|
173
192
|
```bash
|
|
@@ -180,6 +199,7 @@ amaran-cli config --intensity-min 10 --intensity-max 80
|
|
|
180
199
|
# Show the saved configuration
|
|
181
200
|
amaran-cli config --show
|
|
182
201
|
```
|
|
202
|
+
|
|
183
203
|
If a bound is not set, the default is used. When both min and max are set, min must be <= max.
|
|
184
204
|
|
|
185
205
|
### Running Auto-CCT as a Circadian Lighting Service
|
|
@@ -218,22 +238,25 @@ amaran-cli circadian-service start
|
|
|
218
238
|
amaran-cli circadian-service uninstall
|
|
219
239
|
```
|
|
220
240
|
|
|
221
|
-
|
|
241
|
+
#### Backward Compatibility
|
|
242
|
+
|
|
222
243
|
The `service` command is still available as an alias to `circadian-service`:
|
|
244
|
+
|
|
223
245
|
```bash
|
|
224
246
|
# These commands work the same way
|
|
225
247
|
amaran-cli service install
|
|
226
248
|
amaran-cli circadian-service install
|
|
227
249
|
```
|
|
228
250
|
|
|
229
|
-
|
|
251
|
+
#### Installation Detection
|
|
252
|
+
|
|
230
253
|
- The service automatically detects if amaran-cli is installed globally (via `npm install -g`) or running from a local development build
|
|
231
254
|
- Global installations run the executable directly for better performance
|
|
232
255
|
- Local development builds use Node.js to run the built JavaScript files
|
|
233
256
|
|
|
234
257
|
The service uses macOS launchd and will automatically start on login. Logs are stored in `~/Library/Logs/amaran-circadian-service.log`.
|
|
235
258
|
|
|
236
|
-
|
|
259
|
+
#### Alternative: Using Cron
|
|
237
260
|
|
|
238
261
|
If you prefer using cron instead of launchd, the included script handles both global and local installations:
|
|
239
262
|
|
|
@@ -250,7 +273,7 @@ crontab -e
|
|
|
250
273
|
tail -f ~/.amaran-circadian-service.log
|
|
251
274
|
```
|
|
252
275
|
|
|
253
|
-
|
|
276
|
+
#### Manual launchd Setup
|
|
254
277
|
|
|
255
278
|
For advanced users who want to create the service manually:
|
|
256
279
|
|
|
@@ -265,87 +288,86 @@ View how color temperature and intensity will change throughout the day:
|
|
|
265
288
|
|
|
266
289
|
```console
|
|
267
290
|
# Preview schedule for today at your current location
|
|
268
|
-
$ amaran-cli schedule
|
|
291
|
+
$ amaran-cli print-schedule
|
|
269
292
|
|
|
270
293
|
═══════════════════════════════════════════════════════════
|
|
271
294
|
Auto-CCT Schedule Preview
|
|
272
295
|
═══════════════════════════════════════════════════════════
|
|
273
296
|
|
|
274
|
-
Location:
|
|
275
|
-
Date:
|
|
297
|
+
Location: 38.XXXX°, -122.XXXX° (geoip (XXX.XXX.XXX.157))
|
|
298
|
+
Date: Sunday, November 2, 2025
|
|
276
299
|
Interval: Every 30 minutes
|
|
277
300
|
Curve: All available curves
|
|
278
301
|
|
|
279
|
-
NE Night End :
|
|
280
|
-
DN Nautical Dawn :
|
|
281
|
-
DA Dawn :
|
|
282
|
-
SR Sunrise :
|
|
283
|
-
SE Sunrise End :
|
|
284
|
-
GE Golden Hour End :
|
|
285
|
-
SN Solar Noon :
|
|
302
|
+
NE Night End : 05:08 AM GH Golden Hour : 04:34 PM
|
|
303
|
+
DN Nautical Dawn : 05:39 AM SB Sunset Start : 05:08 PM
|
|
304
|
+
DA Dawn : 06:10 AM SS Sunset : 05:11 PM
|
|
305
|
+
SR Sunrise : 06:37 AM ND Nautical Dusk : 06:09 PM
|
|
306
|
+
SE Sunrise End : 06:40 AM DU Dusk : 05:38 PM
|
|
307
|
+
GE Golden Hour End : 07:14 AM NI Night : 06:40 PM
|
|
308
|
+
SN Solar Noon : 11:54 AM NA Nadir : 12:54 AM
|
|
286
309
|
|
|
287
310
|
|
|
288
311
|
─────────────────────────────────────────────────────────────────────────────────────────────────
|
|
289
|
-
Time HANN WM_SMALL WM_MEDIUM WM_LARGE CIE SUN_ALT PEREZ
|
|
312
|
+
Time HANN WM_SMALL WM_MEDIUM WM_LARGE CIE SUN_ALT PEREZ
|
|
290
313
|
─────────────────────────────────────────────────────────────────────────────────────────────────
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
08
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
06:
|
|
327
|
-
06:
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
07:
|
|
331
|
-
07:41 PM NI 1700K/5% 1700K/5% 1700K/5% 1700K/5% 1700K/5% 1700K/5% 1700K/5%
|
|
332
|
-
08:07 PM 1700K/5% 1700K/5% 1700K/5% 1700K/5% 1700K/5% 1700K/5% 1700K/5%
|
|
314
|
+
04:38 AM 1700K/5% 1700K/5% 1700K/5% 1700K/5% 1700K/5% 1700K/5% 1700K/5%
|
|
315
|
+
05:08 AM NE 1700K/5% 1700K/5% 1700K/5% 1700K/5% 1700K/5% 1700K/5% 1700K/5%
|
|
316
|
+
05:38 AM 1764K/6% 2493K/21% 3074K/32% 4333K/57% 1700K/5% 1700K/5% 1700K/5%
|
|
317
|
+
05:39 AM DN 1767K/6% 2509K/21% 3102K/33% 4382K/58% 1700K/5% 1700K/5% 1700K/5%
|
|
318
|
+
06:08 AM 1954K/10% 3264K/36% 4333K/57% 6103K/92% 1700K/5% 1700K/5% 1700K/5%
|
|
319
|
+
06:10 AM DA 1968K/10% 3305K/37% 4398K/58% 6163K/93% 3627K/5% 3175K/5% 3382K/5%
|
|
320
|
+
06:37 AM SR 2247K/16% 3966K/50% 5339K/77% 6500K/100% 4435K/7% 4001K/9% 4345K/6%
|
|
321
|
+
06:38 AM 2259K/16% 3991K/50% 5372K/78% 6500K/100% 4482K/7% 4033K/9% 4419K/6%
|
|
322
|
+
06:40 AM SE 2281K/17% 4032K/51% 5424K/79% 6500K/100% 4559K/8% 4086K/10% 4545K/6%
|
|
323
|
+
07:08 AM 2663K/24% 4656K/64% 6103K/92% 6500K/100% 4335K/9% 4346K/17% 4457K/13%
|
|
324
|
+
07:14 AM GE 2754K/26% 4781K/66% 6207K/94% 6500K/100% 4290K/9% 4398K/19% 4453K/15%
|
|
325
|
+
07:38 AM 3144K/34% 5240K/75% 6466K/99% 6500K/100% 4153K/9% 4602K/25% 4492K/21%
|
|
326
|
+
08:08 AM 3677K/44% 5727K/85% 6500K/100% 6500K/100% 4134K/33% 4846K/35% 4818K/26%
|
|
327
|
+
08:38 AM 4232K/55% 6103K/92% 6500K/100% 6500K/100% 4440K/66% 5075K/44% 5358K/45%
|
|
328
|
+
09:08 AM 4780K/66% 6358K/97% 6500K/100% 6500K/100% 4720K/87% 5285K/52% 5838K/79%
|
|
329
|
+
09:38 AM 5291K/76% 6485K/100% 6500K/100% 6500K/100% 4969K/97% 5472K/59% 5437K/97%
|
|
330
|
+
10:08 AM 5739K/85% 6500K/100% 6500K/100% 6500K/100% 5180K/100% 5600K/100% 5564K/100%
|
|
331
|
+
10:38 AM 6098K/92% 6500K/100% 6500K/100% 6500K/100% 5347K/100% 5684K/100% 5664K/100%
|
|
332
|
+
11:08 AM 6351K/97% 6500K/100% 6500K/100% 6500K/100% 5463K/100% 5742K/100% 5734K/100%
|
|
333
|
+
11:38 AM 6482K/100% 6500K/100% 6500K/100% 6500K/100% 5522K/100% 5771K/100% 5769K/100%
|
|
334
|
+
11:54 AM SN 6500K/100% 6500K/100% 6500K/100% 6500K/100% 5529K/100% 5775K/100% 5774K/100%
|
|
335
|
+
12:08 PM 6486K/100% 6500K/100% 6500K/100% 6500K/100% 5522K/100% 5771K/100% 5769K/100%
|
|
336
|
+
12:38 PM 6361K/97% 6500K/100% 6500K/100% 6500K/100% 5461K/100% 5741K/100% 5733K/100%
|
|
337
|
+
01:08 PM 6115K/92% 6500K/100% 6500K/100% 6500K/100% 5344K/100% 5682K/100% 5663K/100%
|
|
338
|
+
01:38 PM 5761K/85% 6500K/100% 6500K/100% 6500K/100% 5177K/100% 5598K/100% 5562K/100%
|
|
339
|
+
02:08 PM 5317K/77% 6489K/100% 6500K/100% 6500K/100% 4964K/97% 5468K/59% 5434K/97%
|
|
340
|
+
02:38 PM 4808K/67% 6368K/97% 6500K/100% 6500K/100% 4714K/87% 5281K/52% 5830K/79%
|
|
341
|
+
03:08 PM 4262K/56% 6120K/93% 6500K/100% 6500K/100% 4434K/66% 5070K/43% 5347K/45%
|
|
342
|
+
03:38 PM 3706K/45% 5750K/85% 6500K/100% 6500K/100% 4128K/32% 4841K/34% 4809K/25%
|
|
343
|
+
04:08 PM 3172K/34% 5269K/76% 6474K/100% 6500K/100% 4156K/9% 4597K/25% 4489K/21%
|
|
344
|
+
04:34 PM GH 2754K/26% 4781K/66% 6207K/94% 6500K/100% 4306K/9% 4378K/18% 4454K/14%
|
|
345
|
+
04:38 PM 2687K/25% 4690K/64% 6132K/93% 6500K/100% 4340K/9% 4340K/17% 4458K/13%
|
|
346
|
+
05:08 PM SB 2281K/17% 4032K/51% 5424K/79% 6500K/100% 4461K/7% 4019K/9% 4385K/6%
|
|
347
|
+
05:11 PM SS 2247K/16% 3966K/50% 5339K/77% 6500K/100% 4341K/7% 3933K/8% 4199K/6%
|
|
348
|
+
05:38 PM DU 1968K/10% 3305K/37% 4398K/58% 6163K/93% 1700K/5% 1700K/5% 1700K/5%
|
|
349
|
+
06:08 PM 1772K/6% 2535K/22% 3145K/34% 4457K/60% 1700K/5% 1700K/5% 1700K/5%
|
|
350
|
+
06:09 PM ND 1767K/6% 2509K/21% 3102K/33% 4382K/58% 1700K/5% 1700K/5% 1700K/5%
|
|
351
|
+
06:38 PM 1700K/5% 1743K/6% 1775K/7% 1849K/8% 1700K/5% 1700K/5% 1700K/5%
|
|
352
|
+
06:40 PM NI 1700K/5% 1700K/5% 1700K/5% 1700K/5% 1700K/5% 1700K/5% 1700K/5%
|
|
353
|
+
07:08 PM 1700K/5% 1700K/5% 1700K/5% 1700K/5% 1700K/5% 1700K/5% 1700K/5%
|
|
333
354
|
─────────────────────────────────────────────────────────────────────────────────────────────────
|
|
334
355
|
|
|
335
356
|
# Preview with manual location
|
|
336
|
-
amaran-cli schedule --lat 40.7128 --lon -74.0060
|
|
357
|
+
amaran-cli print-schedule --lat 40.7128 --lon -74.0060
|
|
337
358
|
|
|
338
359
|
# Preview for a specific date
|
|
339
|
-
amaran-cli schedule --date 2025-12-21
|
|
360
|
+
amaran-cli print-schedule --date 2025-12-21
|
|
340
361
|
|
|
341
362
|
# Change time interval (default: 30 minutes)
|
|
342
|
-
amaran-cli schedule --interval 15
|
|
363
|
+
amaran-cli print-schedule --interval 15
|
|
343
364
|
|
|
344
365
|
# Combine options
|
|
345
|
-
amaran-cli schedule --lat 51.5074 --lon -0.1278 --date 2025-06-21 --interval 60
|
|
366
|
+
amaran-cli print-schedule --lat 51.5074 --lon -0.1278 --date 2025-06-21 --interval 60
|
|
346
367
|
```
|
|
347
368
|
|
|
348
369
|
The schedule shows CCT and intensity values from 30 minutes before sunrise to 30 minutes after sunset, with special highlighting for:
|
|
370
|
+
|
|
349
371
|
- **Sunrise** (yellow)
|
|
350
372
|
- **Solar Noon** (green, bold)
|
|
351
373
|
- **Sunset** (magenta)
|
|
@@ -355,22 +377,26 @@ This helps you visualize and plan your automated lighting schedule before implem
|
|
|
355
377
|
Note: The schedule respects any configured bounds set via `amaran-cli config --cct-min/--cct-max` and `--intensity-min/--intensity-max`. If no bounds are set, it uses the default curve from `calculateCCT`.
|
|
356
378
|
|
|
357
379
|
### Get light status
|
|
380
|
+
|
|
358
381
|
```bash
|
|
359
382
|
amaran-cli status "Light Name"
|
|
360
383
|
```
|
|
361
384
|
|
|
362
385
|
### Global options
|
|
386
|
+
|
|
363
387
|
All commands support these options:
|
|
388
|
+
|
|
364
389
|
- `-u, --url <url>`: Override WebSocket URL
|
|
365
390
|
- `-c, --client-id <id>`: Override client ID
|
|
366
391
|
- `-d, --debug`: Enable debug mode
|
|
367
392
|
|
|
368
393
|
Example:
|
|
394
|
+
|
|
369
395
|
```bash
|
|
370
396
|
amaran-cli list -u ws://192.168.1.100:60124 -d
|
|
371
397
|
```
|
|
372
398
|
|
|
373
|
-
## Examples
|
|
399
|
+
## Usage Examples
|
|
374
400
|
|
|
375
401
|
```bash
|
|
376
402
|
# Configure for remote Amaran Desktop
|
|
@@ -409,6 +435,10 @@ amaran-cli off
|
|
|
409
435
|
|
|
410
436
|
## Development
|
|
411
437
|
|
|
438
|
+
The localhost amaran desktop websocket API looks like to be near identical or identical to the Open API Sidus has published at <https://tools.sidus.link/openapi/docs/usage> . So if `lightControl.ts` is missing any functionality you can probably use the OpenAPI spec to implement the new functionality fairly quickly. This cli would probably work with the Sidus desktop apps as well, as well as Windows verisons of the Amaran desktop app but I haven't tested it. If you want to submit PRs for it, feel free!
|
|
439
|
+
|
|
440
|
+
Extending command line tool to work with their networked Open API would probably be fairly simple to do since the local Websocket API is very similar to the Open API.
|
|
441
|
+
|
|
412
442
|
```bash
|
|
413
443
|
# Run in development mode
|
|
414
444
|
npm run dev
|
|
@@ -419,9 +449,3 @@ npm run build
|
|
|
419
449
|
# Clean build artifacts
|
|
420
450
|
npm run clean
|
|
421
451
|
```
|
|
422
|
-
|
|
423
|
-
## Device Identification
|
|
424
|
-
|
|
425
|
-
Devices can be identified by:
|
|
426
|
-
- **Device name**: Case-insensitive partial matching (e.g., "key" matches "Key Light")
|
|
427
|
-
- **Node ID**: Exact match of the device's node_id
|
|
@@ -1,17 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const globals_1 = require("@jest/globals");
|
|
7
|
-
const commander_1 = require("commander");
|
|
8
|
-
const commands_1 = __importDefault(require("../commands"));
|
|
9
|
-
globals_1.jest.mock('../geoipUtil', () => ({
|
|
10
|
-
getLocationFromIP: globals_1.jest.fn(() => ({ ll: [37.7749, -122.4194] })),
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { vi } from 'vitest';
|
|
3
|
+
import registerCommands from '../commands.js';
|
|
4
|
+
vi.mock('../geoipUtil', () => ({
|
|
5
|
+
getLocationFromIP: vi.fn(() => ({ ll: [37.7749, -122.4194] })),
|
|
11
6
|
}));
|
|
12
|
-
|
|
13
|
-
calculateCCT:
|
|
14
|
-
parseCurveType:
|
|
7
|
+
vi.mock('../cctUtil', () => ({
|
|
8
|
+
calculateCCT: vi.fn(() => ({ cct: 5600, intensity: 500 })),
|
|
9
|
+
parseCurveType: vi.fn(() => 'HANN'),
|
|
15
10
|
CurveType: {
|
|
16
11
|
HANN: 'hann',
|
|
17
12
|
WIDER_MIDDLE_SMALL: 'wider-middle-small',
|
|
@@ -24,7 +19,7 @@ globals_1.jest.mock('../cctUtil', () => ({
|
|
|
24
19
|
}));
|
|
25
20
|
describe('auto-cct command', () => {
|
|
26
21
|
const originalFetch = global.fetch;
|
|
27
|
-
const mockFetch =
|
|
22
|
+
const mockFetch = vi.fn();
|
|
28
23
|
beforeAll(() => {
|
|
29
24
|
mockFetch.mockImplementation(async () => ({
|
|
30
25
|
json: async () => ({ ip: '1.2.3.4' }),
|
|
@@ -38,18 +33,18 @@ describe('auto-cct command', () => {
|
|
|
38
33
|
global.fetch = originalFetch;
|
|
39
34
|
});
|
|
40
35
|
test('skips sleeping lights when running auto-cct', async () => {
|
|
41
|
-
const setCCT =
|
|
42
|
-
const disconnect =
|
|
36
|
+
const setCCT = vi.fn();
|
|
37
|
+
const disconnect = vi.fn(async () => Promise.resolve());
|
|
43
38
|
const sleepState = {
|
|
44
39
|
'400J5-F2C008': false,
|
|
45
40
|
'400J5-F2C009': true,
|
|
46
41
|
};
|
|
47
42
|
const controllerStub = {
|
|
48
|
-
getDevices:
|
|
43
|
+
getDevices: vi.fn(() => [
|
|
49
44
|
{ node_id: '400J5-F2C008', device_name: 'On Light' },
|
|
50
45
|
{ node_id: '400J5-F2C009', device_name: 'Off Light' },
|
|
51
46
|
]),
|
|
52
|
-
getLightSleepStatus:
|
|
47
|
+
getLightSleepStatus: vi.fn((nodeId, cb) => {
|
|
53
48
|
setImmediate(() => cb(true, 'ok', { sleep: sleepState[nodeId] }));
|
|
54
49
|
}),
|
|
55
50
|
setCCT,
|
|
@@ -62,14 +57,88 @@ describe('auto-cct command', () => {
|
|
|
62
57
|
loadConfig: () => ({}),
|
|
63
58
|
saveWsUrl: undefined,
|
|
64
59
|
};
|
|
65
|
-
const program = new
|
|
60
|
+
const program = new Command();
|
|
66
61
|
program.exitOverride();
|
|
67
|
-
(
|
|
62
|
+
registerCommands(program, deps);
|
|
68
63
|
await program.parseAsync(['node', 'test', 'auto-cct']);
|
|
69
64
|
expect(setCCT).toHaveBeenCalledTimes(1);
|
|
70
65
|
// auto-cct should pass through calculateCCT result
|
|
71
66
|
expect(setCCT).toHaveBeenCalledWith('400J5-F2C008', 5600, 500);
|
|
72
67
|
expect(disconnect).toHaveBeenCalledTimes(1);
|
|
73
68
|
});
|
|
69
|
+
test('applies intensity multiplier from config', async () => {
|
|
70
|
+
const setCCT = vi.fn();
|
|
71
|
+
const disconnect = vi.fn(async () => Promise.resolve());
|
|
72
|
+
const controllerStub = {
|
|
73
|
+
getDevices: vi.fn(() => [
|
|
74
|
+
{ node_id: '400J5-F2C008', device_name: 'Key Light' },
|
|
75
|
+
{ node_id: '400J5-F2C009', device_name: 'Fill Light' },
|
|
76
|
+
]),
|
|
77
|
+
getLightSleepStatus: vi.fn((_nodeId, cb) => {
|
|
78
|
+
setImmediate(() => cb(true, 'ok', { sleep: false }));
|
|
79
|
+
}),
|
|
80
|
+
setCCT,
|
|
81
|
+
disconnect,
|
|
82
|
+
};
|
|
83
|
+
const deps = {
|
|
84
|
+
createController: async () => controllerStub,
|
|
85
|
+
findDevice: (_controller, _deviceQuery) => null,
|
|
86
|
+
asyncCommand: (fn) => (...args) => fn(...args),
|
|
87
|
+
loadConfig: () => ({
|
|
88
|
+
intensityMultiplier: {
|
|
89
|
+
'400J5-F2C008': 0.5, // 50% multiplier
|
|
90
|
+
// 400J5-F2C009 has no multiplier, defaults to 1.0
|
|
91
|
+
},
|
|
92
|
+
}),
|
|
93
|
+
saveWsUrl: undefined,
|
|
94
|
+
};
|
|
95
|
+
const program = new Command();
|
|
96
|
+
program.exitOverride();
|
|
97
|
+
registerCommands(program, deps);
|
|
98
|
+
await program.parseAsync(['node', 'test', 'auto-cct']);
|
|
99
|
+
expect(setCCT).toHaveBeenCalledTimes(2);
|
|
100
|
+
// 5600K at 50% intensity (base 500 * 0.5 = 250)
|
|
101
|
+
// Note: The logic in autoCct computes percent first, then multiplies.
|
|
102
|
+
// Base intensity 500 -> 50%. 50% * 0.5 = 25%.
|
|
103
|
+
// Then it converts back to raw intensity: 500 * (25 / 50) = 250.
|
|
104
|
+
expect(setCCT).toHaveBeenCalledWith('400J5-F2C008', 5600, 250);
|
|
105
|
+
// Normal intensity for the other light
|
|
106
|
+
expect(setCCT).toHaveBeenCalledWith('400J5-F2C009', 5600, 500);
|
|
107
|
+
expect(disconnect).toHaveBeenCalledTimes(1);
|
|
108
|
+
});
|
|
109
|
+
test('targets specific device when argument is provided', async () => {
|
|
110
|
+
const setCCT = vi.fn();
|
|
111
|
+
const disconnect = vi.fn(async () => Promise.resolve());
|
|
112
|
+
const targetDevice = { node_id: '400J5-F2C008', device_name: 'Target Light' };
|
|
113
|
+
const otherDevice = { node_id: '400J5-F2C009', device_name: 'Other Light' };
|
|
114
|
+
const controllerStub = {
|
|
115
|
+
getDevices: vi.fn(() => [targetDevice, otherDevice]),
|
|
116
|
+
getLightSleepStatus: vi.fn((_nodeId, cb) => {
|
|
117
|
+
setImmediate(() => cb(true, 'ok', { sleep: false }));
|
|
118
|
+
}),
|
|
119
|
+
setCCT,
|
|
120
|
+
disconnect,
|
|
121
|
+
};
|
|
122
|
+
const findDeviceMock = vi.fn((_controller, query) => {
|
|
123
|
+
if (query === 'Target')
|
|
124
|
+
return targetDevice;
|
|
125
|
+
return null;
|
|
126
|
+
});
|
|
127
|
+
const deps = {
|
|
128
|
+
createController: async () => controllerStub,
|
|
129
|
+
findDevice: findDeviceMock,
|
|
130
|
+
asyncCommand: (fn) => (...args) => fn(...args),
|
|
131
|
+
loadConfig: () => ({}),
|
|
132
|
+
saveWsUrl: undefined,
|
|
133
|
+
};
|
|
134
|
+
const program = new Command();
|
|
135
|
+
program.exitOverride();
|
|
136
|
+
registerCommands(program, deps);
|
|
137
|
+
await program.parseAsync(['node', 'test', 'auto-cct', 'Target']);
|
|
138
|
+
expect(findDeviceMock).toHaveBeenCalledWith(controllerStub, 'Target');
|
|
139
|
+
expect(setCCT).toHaveBeenCalledTimes(1);
|
|
140
|
+
expect(setCCT).toHaveBeenCalledWith('400J5-F2C008', 5600, 500);
|
|
141
|
+
expect(disconnect).toHaveBeenCalledTimes(1);
|
|
142
|
+
});
|
|
74
143
|
});
|
|
75
144
|
//# sourceMappingURL=autoCct.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"autoCct.test.js","sourceRoot":"","sources":["../../src/__tests__/autoCct.test.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"autoCct.test.js","sourceRoot":"","sources":["../../src/__tests__/autoCct.test.ts"],"names":[],"mappings":"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"}
|