amaran-light-cli 1.6.0 → 1.7.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.
Files changed (60) hide show
  1. package/README.md +52 -0
  2. package/dist/__tests__/autoCctMaxLux.test.d.ts +2 -0
  3. package/dist/__tests__/autoCctMaxLux.test.d.ts.map +1 -0
  4. package/dist/__tests__/autoCctMaxLux.test.js +153 -0
  5. package/dist/__tests__/autoCctMaxLux.test.js.map +1 -0
  6. package/dist/__tests__/cctUtil.test.js +45 -0
  7. package/dist/__tests__/cctUtil.test.js.map +1 -1
  8. package/dist/__tests__/configMaxLux.test.d.ts +2 -0
  9. package/dist/__tests__/configMaxLux.test.d.ts.map +1 -0
  10. package/dist/__tests__/configMaxLux.test.js +43 -0
  11. package/dist/__tests__/configMaxLux.test.js.map +1 -0
  12. package/dist/__tests__/maxLuxInterpolation.test.d.ts +2 -0
  13. package/dist/__tests__/maxLuxInterpolation.test.d.ts.map +1 -0
  14. package/dist/__tests__/maxLuxInterpolation.test.js +96 -0
  15. package/dist/__tests__/maxLuxInterpolation.test.js.map +1 -0
  16. package/dist/__tests__/weatherPhysics.test.d.ts +2 -0
  17. package/dist/__tests__/weatherPhysics.test.d.ts.map +1 -0
  18. package/dist/__tests__/weatherPhysics.test.js +72 -0
  19. package/dist/__tests__/weatherPhysics.test.js.map +1 -0
  20. package/dist/commands/daylightSimulation/autoCct.d.ts.map +1 -1
  21. package/dist/commands/daylightSimulation/autoCct.js +66 -4
  22. package/dist/commands/daylightSimulation/autoCct.js.map +1 -1
  23. package/dist/commands/daylightSimulation/graphSchedule.d.ts.map +1 -1
  24. package/dist/commands/daylightSimulation/graphSchedule.js +6 -1
  25. package/dist/commands/daylightSimulation/graphSchedule.js.map +1 -1
  26. package/dist/commands/daylightSimulation/printSchedule.d.ts.map +1 -1
  27. package/dist/commands/daylightSimulation/printSchedule.js +6 -1
  28. package/dist/commands/daylightSimulation/printSchedule.js.map +1 -1
  29. package/dist/commands/daylightSimulation/simulateSchedule.d.ts.map +1 -1
  30. package/dist/commands/daylightSimulation/simulateSchedule.js +6 -1
  31. package/dist/commands/daylightSimulation/simulateSchedule.js.map +1 -1
  32. package/dist/commands/deviceControl/config.d.ts.map +1 -1
  33. package/dist/commands/deviceControl/config.js +27 -0
  34. package/dist/commands/deviceControl/config.js.map +1 -1
  35. package/dist/daylightSimulation/cctUtil.d.ts +2 -2
  36. package/dist/daylightSimulation/cctUtil.d.ts.map +1 -1
  37. package/dist/daylightSimulation/cctUtil.js +47 -5
  38. package/dist/daylightSimulation/cctUtil.js.map +1 -1
  39. package/dist/daylightSimulation/constants.d.ts +2 -1
  40. package/dist/daylightSimulation/constants.d.ts.map +1 -1
  41. package/dist/daylightSimulation/constants.js +2 -1
  42. package/dist/daylightSimulation/constants.js.map +1 -1
  43. package/dist/daylightSimulation/curves/realistic.d.ts +2 -1
  44. package/dist/daylightSimulation/curves/realistic.d.ts.map +1 -1
  45. package/dist/daylightSimulation/curves/realistic.js +36 -12
  46. package/dist/daylightSimulation/curves/realistic.js.map +1 -1
  47. package/dist/daylightSimulation/mathUtil.d.ts +13 -0
  48. package/dist/daylightSimulation/mathUtil.d.ts.map +1 -0
  49. package/dist/daylightSimulation/mathUtil.js +54 -0
  50. package/dist/daylightSimulation/mathUtil.js.map +1 -0
  51. package/dist/daylightSimulation/scheduleMaker.d.ts +2 -0
  52. package/dist/daylightSimulation/scheduleMaker.d.ts.map +1 -1
  53. package/dist/daylightSimulation/scheduleMaker.js +8 -0
  54. package/dist/daylightSimulation/scheduleMaker.js.map +1 -1
  55. package/dist/daylightSimulation/types.d.ts +5 -0
  56. package/dist/daylightSimulation/types.d.ts.map +1 -1
  57. package/dist/daylightSimulation/types.js.map +1 -1
  58. package/dist/deviceControl/types.d.ts +1 -0
  59. package/dist/deviceControl/types.d.ts.map +1 -1
  60. package/package.json +1 -1
package/README.md CHANGED
@@ -204,6 +204,58 @@ amaran-cli config --show
204
204
 
205
205
  If a bound is not set, the default is used. When both min and max are set, min must be <= max.
206
206
 
207
+ #### Max Lux Output (Advanced)
208
+
209
+ #### Max Lux Output (Advanced)
210
+
211
+ If you have measured the maximum lux output of your lighting setup, you can provide this value to `auto-cct` to enable more accurate intensity scaling.
212
+
213
+ By default, `auto-cct` maps the daylight curve's `lightOutput` directly to intensity percentage (e.g. max curve value = 100% intensity). With Max Lux mode, it uses your specific setup's capability as the reference.
214
+
215
+ You can provide:
216
+ 1. **A Single Number**: If your setup has a constant max lux.
217
+ 2. **A CCT Map**: If max lux varies by color temperature (common with bi-color lights).
218
+
219
+ ```bash
220
+ # Option 1: Constant Max Lux (e.g. 10000 lux)
221
+ amaran-cli auto-cct --max-lux 10000
222
+
223
+ # Option 2: CCT to Lux Map (2700K=8000lux, 5600K=10000lux)
224
+ # The system linearly interpolates for values in between.
225
+ amaran-cli auto-cct --max-lux "2700:8000, 5600:10000, 6500:9000"
226
+
227
+ # Configure permanently
228
+ amaran-cli config --max-lux "2700:8000, 5600:10000"
229
+ ```
230
+
231
+ **How it works:**
232
+ 1. The system determines the effective max lux for the current target CCT (interpolating if necessary).
233
+ 2. It calculates intensity as: `(Target Lux / Effective Max Lux) * 100`.
234
+ 3. If the target lux exceeds the capability, lights are clamped to 100%.
235
+
236
+ #### Weather Modifiers (Advanced)
237
+
238
+ You can simulate weather conditions to adjust the calculated CCT and intensity. This is useful if you want your lights to reflect the current outdoor weather (or simulate a specific mood).
239
+
240
+ - **Cloud Cover**: Reduces intensity and shifts CCT towards neutral daylight (6500K).
241
+ - **Precipitation**: Further reduces intensity and slightly cools the CCT (rain/snow).
242
+
243
+ ```bash
244
+ # Simulate 50% cloud cover
245
+ amaran-cli auto-cct --cloud-cover 0.5
246
+
247
+ # Simulate overcast (100% clouds)
248
+ amaran-cli auto-cct --cloud-cover 1
249
+
250
+ # Simulate rain (reduces intensity further)
251
+ amaran-cli auto-cct --precipitation rain
252
+
253
+ # Simulate snow
254
+ amaran-cli auto-cct --precipitation snow
255
+ ```
256
+
257
+ These options also work with `simulate-schedule`, `print-schedule`, and `graph-schedule`.
258
+
207
259
  ### Running Auto-CCT as a Circadian Lighting Service
208
260
 
209
261
  You can set up auto-cct to run automatically every minute as a circadian lighting background service. The service works with both global and local installations:
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=autoCctMaxLux.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autoCctMaxLux.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/autoCctMaxLux.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,153 @@
1
+ import { Command } from 'commander';
2
+ import { afterAll, afterEach, beforeAll, describe, expect, test, vi } from 'vitest';
3
+ import registerCommands from '../commands.js';
4
+ // Mock dependencies
5
+ vi.mock('../daylightSimulation/geoipUtil', () => ({
6
+ getLocationFromIP: vi.fn(() => ({ ll: [37.7749, -122.4194] })),
7
+ }));
8
+ // We will mock cctUtil's return value individually in tests if needed,
9
+ // but here is a default mock factory
10
+ const mockCalculateCCT = vi.fn();
11
+ vi.mock('../daylightSimulation/cctUtil', () => ({
12
+ calculateCCT: (...args) => mockCalculateCCT(...args),
13
+ parseCurveType: vi.fn(() => 'HANN'),
14
+ CurveType: {
15
+ HANN: 'hann',
16
+ },
17
+ }));
18
+ describe('auto-cct max-lux logic', () => {
19
+ const originalFetch = global.fetch;
20
+ const mockFetch = vi.fn();
21
+ // Common stub setups
22
+ const setCCT = vi.fn();
23
+ const disconnect = vi.fn(async () => Promise.resolve());
24
+ const controllerStub = {
25
+ getDevices: vi.fn(() => [{ node_id: '400J5-F2C008', device_name: 'Test Light' }]),
26
+ getLightSleepStatus: vi.fn((_nodeId, cb) => {
27
+ setImmediate(() => cb(true, 'ok', { sleep: false }));
28
+ }),
29
+ setCCT,
30
+ disconnect,
31
+ };
32
+ const createController = async () => controllerStub;
33
+ const findDevice = (_controller, _deviceQuery) => null;
34
+ const asyncCommand = (fn) => (...args) => fn(...args);
35
+ beforeAll(() => {
36
+ mockFetch.mockImplementation(async () => ({
37
+ json: async () => ({ ip: '1.2.3.4' }),
38
+ }));
39
+ global.fetch = mockFetch;
40
+ });
41
+ afterEach(() => {
42
+ mockFetch.mockClear();
43
+ setCCT.mockClear();
44
+ disconnect.mockClear();
45
+ mockCalculateCCT.mockReset();
46
+ });
47
+ afterAll(() => {
48
+ global.fetch = originalFetch;
49
+ });
50
+ test('uses standard intensity when no max-lux provided', async () => {
51
+ mockCalculateCCT.mockReturnValue({ cct: 5600, intensity: 500, lightOutput: 5000 }); // 50% intensity
52
+ const deps = {
53
+ createController,
54
+ findDevice,
55
+ asyncCommand,
56
+ loadConfig: () => ({}),
57
+ saveWsUrl: undefined,
58
+ };
59
+ const program = new Command();
60
+ program.exitOverride();
61
+ registerCommands(program, deps);
62
+ await program.parseAsync(['node', 'test', 'auto-cct']);
63
+ // Should use raw intensity: 500 (50.0%)
64
+ expect(setCCT).toHaveBeenCalledWith('400J5-F2C008', 5600, 500);
65
+ });
66
+ test('uses max-lux scaling when CLI option provided', async () => {
67
+ // lightOutput 5000 lux. maxLux 10000. Should be 50% -> 500 raw.
68
+ mockCalculateCCT.mockReturnValue({ cct: 5600, intensity: 800, lightOutput: 5000 });
69
+ // Note: intensity 800 (80%) is ignored in favor of lux scaling
70
+ const deps = {
71
+ createController,
72
+ findDevice,
73
+ asyncCommand,
74
+ loadConfig: () => ({}),
75
+ saveWsUrl: undefined,
76
+ };
77
+ const program = new Command();
78
+ program.exitOverride();
79
+ registerCommands(program, deps);
80
+ // --max-lux 10000
81
+ await program.parseAsync(['node', 'test', 'auto-cct', '--max-lux', '10000']);
82
+ // 5000 / 10000 = 0.5 = 50% = 500 raw
83
+ expect(setCCT).toHaveBeenCalledWith('400J5-F2C008', 5600, 500);
84
+ });
85
+ test('uses max-lux scaling from config', async () => {
86
+ // lightOutput 2000 lux. maxLux 10000. Should be 20% -> 200 raw.
87
+ mockCalculateCCT.mockReturnValue({ cct: 5600, intensity: 800, lightOutput: 2000 });
88
+ const deps = {
89
+ createController,
90
+ findDevice,
91
+ asyncCommand,
92
+ loadConfig: () => ({ maxLux: 10000 }),
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).toHaveBeenCalledWith('400J5-F2C008', 5600, 200);
100
+ });
101
+ test('CLI option overrides config for max-lux', async () => {
102
+ // Config: 10000 maxLux. CLI: 5000 maxLux. LightOutput: 2500.
103
+ // Config would yield 25%. CLI should yield 50%.
104
+ mockCalculateCCT.mockReturnValue({ cct: 5600, intensity: 800, lightOutput: 2500 });
105
+ const deps = {
106
+ createController,
107
+ findDevice,
108
+ asyncCommand,
109
+ loadConfig: () => ({ maxLux: 10000 }),
110
+ saveWsUrl: undefined,
111
+ };
112
+ const program = new Command();
113
+ program.exitOverride();
114
+ registerCommands(program, deps);
115
+ await program.parseAsync(['node', 'test', 'auto-cct', '--max-lux', '5000']);
116
+ // 2500 / 5000 = 0.5 = 50% = 500 raw
117
+ expect(setCCT).toHaveBeenCalledWith('400J5-F2C008', 5600, 500);
118
+ });
119
+ test('falls back to intensity curve if lightOutput is missing', async () => {
120
+ // No lightOutput in result
121
+ mockCalculateCCT.mockReturnValue({ cct: 5600, intensity: 300 }); // 30%
122
+ const deps = {
123
+ createController,
124
+ findDevice,
125
+ asyncCommand,
126
+ loadConfig: () => ({}),
127
+ saveWsUrl: undefined,
128
+ };
129
+ const program = new Command();
130
+ program.exitOverride();
131
+ registerCommands(program, deps);
132
+ await program.parseAsync(['node', 'test', 'auto-cct', '--max-lux', '10000']);
133
+ // Should use the 30% intensity since lightOutput is missing
134
+ expect(setCCT).toHaveBeenCalledWith('400J5-F2C008', 5600, 300);
135
+ });
136
+ test('clamps intensity to 100% if lux exceeds max-lux', async () => {
137
+ // Output 15000, Max 10000 -> 150% -> clamped to 100%
138
+ mockCalculateCCT.mockReturnValue({ cct: 5600, intensity: 800, lightOutput: 15000 });
139
+ const deps = {
140
+ createController,
141
+ findDevice,
142
+ asyncCommand,
143
+ loadConfig: () => ({}),
144
+ saveWsUrl: undefined,
145
+ };
146
+ const program = new Command();
147
+ program.exitOverride();
148
+ registerCommands(program, deps);
149
+ await program.parseAsync(['node', 'test', 'auto-cct', '--max-lux', '10000']);
150
+ expect(setCCT).toHaveBeenCalledWith('400J5-F2C008', 5600, 1000); // 100%
151
+ });
152
+ });
153
+ //# sourceMappingURL=autoCctMaxLux.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autoCctMaxLux.test.js","sourceRoot":"","sources":["../../src/__tests__/autoCctMaxLux.test.ts"],"names":[],"mappings":"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"}
@@ -220,5 +220,50 @@ describe('calculateCCT', () => {
220
220
  expect(result.lightOutput).toBe(0);
221
221
  });
222
222
  });
223
+ describe('Weather Modifiers', () => {
224
+ const noon = new Date('2024-06-21T16:00:00Z'); // Approx solar noon NYC
225
+ it('should reduce intensity and lightOutput with cloudCover', () => {
226
+ const clearResult = calculateCCT(NYC_LAT, NYC_LON, noon, {
227
+ weather: { cloudCover: 0 },
228
+ });
229
+ const cloudyResult = calculateCCT(NYC_LAT, NYC_LON, noon, {
230
+ weather: { cloudCover: 0.5 },
231
+ });
232
+ const overcastResult = calculateCCT(NYC_LAT, NYC_LON, noon, {
233
+ weather: { cloudCover: 1.0 },
234
+ });
235
+ expect(cloudyResult.intensity).toBeLessThan(clearResult.intensity);
236
+ expect(overcastResult.intensity).toBeLessThan(cloudyResult.intensity);
237
+ expect(cloudyResult.lightOutput).toBeLessThan(clearResult.lightOutput || 0);
238
+ expect(overcastResult.lightOutput).toBeLessThan(cloudyResult.lightOutput || 0);
239
+ });
240
+ it('should shift CCT towards 6500K with cloudCover', () => {
241
+ // Assuming clear sky noon is usually cooler (>5500K) or warmer depending on curve,
242
+ // but let's check relative shift.
243
+ const clearResult = calculateCCT(NYC_LAT, NYC_LON, noon, {
244
+ weather: { cloudCover: 0 },
245
+ }, CurveType.PHYSICS);
246
+ const overcastResult = calculateCCT(NYC_LAT, NYC_LON, noon, {
247
+ weather: { cloudCover: 1.0 },
248
+ }, CurveType.PHYSICS);
249
+ // Physics curve at noon is usually blueish (>6500K) or whitish.
250
+ // If we force a very warm time (morning), clouds should cool it.
251
+ // If we force a very cool time (noon blue sky), clouds should warm it (neutralize it).
252
+ // Let's just check it moves towards 6500.
253
+ const target = 6500;
254
+ const clearDiff = Math.abs(clearResult.cct - target);
255
+ const overcastDiff = Math.abs(overcastResult.cct - target);
256
+ expect(overcastDiff).toBeLessThan(clearDiff);
257
+ });
258
+ it('should reduce intensity further with precipitation', () => {
259
+ const cloudyResult = calculateCCT(NYC_LAT, NYC_LON, noon, {
260
+ weather: { cloudCover: 0.5, precipitation: 'none' },
261
+ });
262
+ const rainyResult = calculateCCT(NYC_LAT, NYC_LON, noon, {
263
+ weather: { cloudCover: 0.5, precipitation: 'rain' },
264
+ });
265
+ expect(rainyResult.intensity).toBeLessThan(cloudyResult.intensity);
266
+ });
267
+ });
223
268
  });
224
269
  //# sourceMappingURL=cctUtil.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cctUtil.test.js","sourceRoot":"","sources":["../../src/__tests__/cctUtil.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cctUtil.test.js","sourceRoot":"","sources":["../../src/__tests__/cctUtil.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=configMaxLux.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configMaxLux.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/configMaxLux.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,43 @@
1
+ import { Command } from 'commander';
2
+ import { describe, expect, it, vi } from 'vitest';
3
+ import registerConfig from '../commands/deviceControl/config.js';
4
+ describe('config command max-lux', () => {
5
+ it('should save max-lux when valid number provided', async () => {
6
+ const program = new Command();
7
+ program.exitOverride();
8
+ const saveConfig = vi.fn();
9
+ const deps = {
10
+ asyncCommand: (fn) => (...args) => fn(...args),
11
+ loadConfig: () => ({}),
12
+ saveConfig,
13
+ };
14
+ registerConfig(program, deps);
15
+ await program.parseAsync(['node', 'test', 'config', '--max-lux', '10000']);
16
+ expect(saveConfig).toHaveBeenCalledWith(expect.objectContaining({ maxLux: 10000 }), expect.arrayContaining([expect.stringContaining('Max Lux: 10000')]));
17
+ });
18
+ it('should error when max-lux is not a positive number', async () => {
19
+ const program = new Command();
20
+ program.exitOverride();
21
+ const saveConfig = vi.fn();
22
+ const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {
23
+ /* no-op */
24
+ });
25
+ const exitSpy = vi.spyOn(process, 'exit').mockImplementation(((code) => {
26
+ throw new Error(`Process exit: ${code}`);
27
+ }));
28
+ const deps = {
29
+ asyncCommand: (fn) => (...args) => fn(...args),
30
+ loadConfig: () => ({}),
31
+ saveConfig,
32
+ };
33
+ registerConfig(program, deps);
34
+ // Test non-number
35
+ await expect(program.parseAsync(['node', 'test', 'config', '--max-lux', 'invalid'])).rejects.toThrow();
36
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('max-lux must be a positive number'));
37
+ // Test negative number
38
+ await expect(program.parseAsync(['node', 'test', 'config', '--max-lux', '-100'])).rejects.toThrow();
39
+ consoleSpy.mockRestore();
40
+ exitSpy.mockRestore();
41
+ });
42
+ });
43
+ //# sourceMappingURL=configMaxLux.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configMaxLux.test.js","sourceRoot":"","sources":["../../src/__tests__/configMaxLux.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=maxLuxInterpolation.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"maxLuxInterpolation.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/maxLuxInterpolation.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,96 @@
1
+ import { Command } from 'commander';
2
+ import { describe, expect, it, vi } from 'vitest';
3
+ import registerAutoCct from '../commands/daylightSimulation/autoCct.js';
4
+ import registerConfig from '../commands/deviceControl/config.js';
5
+ import { interpolateMaxLux, parseMaxLuxMap } from '../daylightSimulation/mathUtil.js';
6
+ describe('Max Lux Map Feature', () => {
7
+ describe('Math Utils', () => {
8
+ const map = {
9
+ 2700: 8000,
10
+ 5600: 10000,
11
+ 6500: 9000,
12
+ };
13
+ it('parses valid map string', () => {
14
+ const result = parseMaxLuxMap('2700:8000, 5600:10000, 6500:9000');
15
+ expect(result).toEqual(map);
16
+ });
17
+ it('returns null for invalid string', () => {
18
+ expect(parseMaxLuxMap('invalid')).toBeNull();
19
+ expect(parseMaxLuxMap('2700:abc')).toBeNull();
20
+ });
21
+ it('interpolates correctly within range', () => {
22
+ // 4150 is exactly half way between 2700 and 5600.
23
+ // 2700->8000, 5600->10000. Diff = 2000. Half = 1000. Result 9000.
24
+ expect(interpolateMaxLux(4150, map)).toBeCloseTo(9000);
25
+ });
26
+ it('clamps to lower bound', () => {
27
+ expect(interpolateMaxLux(2000, map)).toBe(8000);
28
+ });
29
+ it('clamps to upper bound', () => {
30
+ expect(interpolateMaxLux(7000, map)).toBe(9000);
31
+ });
32
+ it('handles exact match', () => {
33
+ expect(interpolateMaxLux(5600, map)).toBe(10000);
34
+ });
35
+ });
36
+ describe('Config Command Integration', () => {
37
+ it('saves parsed map to config', async () => {
38
+ const program = new Command();
39
+ program.exitOverride();
40
+ const saveConfig = vi.fn();
41
+ const deps = {
42
+ asyncCommand: (fn) => (...args) => fn(...args),
43
+ loadConfig: () => ({}),
44
+ saveConfig,
45
+ };
46
+ registerConfig(program, deps);
47
+ await program.parseAsync(['node', 'test', 'config', '--max-lux', '2700:8000,5600:10000']);
48
+ expect(saveConfig).toHaveBeenCalledWith(expect.objectContaining({
49
+ maxLux: { 2700: 8000, 5600: 10000 },
50
+ }), expect.anything());
51
+ });
52
+ });
53
+ describe('AutoCCT Integration', () => {
54
+ // Mock cctUtil to control the "current" CCT
55
+ vi.mock('../daylightSimulation/cctUtil', () => ({
56
+ calculateCCT: vi.fn(() => ({ cct: 4150, intensity: 500, lightOutput: 4500 })), // 4500 lux target
57
+ parseCurveType: vi.fn(() => 'HANN'),
58
+ CurveType: { HANN: 'hann' },
59
+ }));
60
+ vi.mock('../daylightSimulation/geoipUtil', () => ({
61
+ getLocationFromIP: vi.fn(() => ({ ll: [0, 0] })),
62
+ }));
63
+ it('uses interpolated max lux for intensity calculation', async () => {
64
+ const setCCT = vi.fn();
65
+ const disconnect = vi.fn(async () => Promise.resolve());
66
+ const controllerStub = {
67
+ getDevices: () => [{ node_id: 'AAA-111' }],
68
+ getLightSleepStatus: (_id, cb) => cb(true, 'ok', { sleep: false }),
69
+ setCCT,
70
+ disconnect,
71
+ on: vi.fn(),
72
+ off: vi.fn(),
73
+ };
74
+ const _actionSpy = vi.fn();
75
+ // Mock dependencies
76
+ const deps = {
77
+ createController: async () => controllerStub,
78
+ findDevice: () => ({ node_id: 'AAA-111' }),
79
+ asyncCommand: ((fn) => (...args) => fn(...args)),
80
+ loadConfig: () => ({}),
81
+ };
82
+ const program = new Command();
83
+ program.exitOverride();
84
+ registerAutoCct(program, deps);
85
+ // Max Lux Map: 2700:8000, 5600:10000.
86
+ // Target CCT from mock is 4150.
87
+ // Interpolated Max Lux should be 9000 (midpoint).
88
+ // Target Output is 4500.
89
+ // Intensity should be 4500 / 9000 = 0.5 = 50%.
90
+ // 50% * 10 = 500 raw intensity.
91
+ await program.parseAsync(['node', 'test', 'auto-cct', '--max-lux', '2700:8000,5600:10000']);
92
+ expect(setCCT).toHaveBeenCalledWith('AAA-111', 4150, 500);
93
+ });
94
+ });
95
+ });
96
+ //# sourceMappingURL=maxLuxInterpolation.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"maxLuxInterpolation.test.js","sourceRoot":"","sources":["../../src/__tests__/maxLuxInterpolation.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=weatherPhysics.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"weatherPhysics.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/weatherPhysics.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,72 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { calculateCCT } from '../daylightSimulation/cctUtil.js';
3
+ import { CurveType } from '../daylightSimulation/types.js';
4
+ describe('Weather-Aware Physics Curve', () => {
5
+ // Use a fixed date and location for reproducible sun position
6
+ // Noon at Equator on Equinox = Zenith
7
+ const lat = 0;
8
+ const lon = 0;
9
+ const dateNoon = new Date('2024-03-21T12:00:00Z');
10
+ const dateMorning = new Date('2024-03-21T08:00:00Z'); // Moderate altitude
11
+ it('should match baseline for clear sky (no weather)', () => {
12
+ const result = calculateCCT(lat, lon, dateNoon, {
13
+ cctMinK: 2700,
14
+ cctMaxK: 6500,
15
+ }, CurveType.PHYSICS);
16
+ expect(result.cct).toBeGreaterThan(6000); // Near max at zenith
17
+ expect(result.intensity).toBeGreaterThan(90); // Near max at zenith
18
+ });
19
+ it('should flatten CCT curve with 100% cloud cover', () => {
20
+ // Clear sky morning
21
+ const clearResult = calculateCCT(lat, lon, dateMorning, {
22
+ cctMinK: 2000,
23
+ cctMaxK: 6500,
24
+ weather: { cloudCover: 0 },
25
+ }, CurveType.PHYSICS);
26
+ // Overcast sky morning
27
+ const cloudyResult = calculateCCT(lat, lon, dateMorning, {
28
+ cctMinK: 2000,
29
+ cctMaxK: 6500,
30
+ weather: { cloudCover: 1 },
31
+ }, CurveType.PHYSICS);
32
+ // In clear sky, morning CCT should be significantly lower than max
33
+ // In overcast sky, CCT should be closer to neutral/max (uniform diffusion)
34
+ // Actually, our logic: cctFactor blends towards 1.0 (maxK).
35
+ // So cloudy CCT should be higher than clear CCT at lower altitudes (where clear is warm).
36
+ expect(cloudyResult.cct).toBeGreaterThan(clearResult.cct);
37
+ // Also, cloudy result should be close to maxK (factor ~ 1.0)
38
+ expect(cloudyResult.cct).toBeCloseTo(6500, -2); // +/- 100K tolerance
39
+ });
40
+ it('should reduce max intensity with cloud cover (via applyWeatherModifiers)', () => {
41
+ // Even though realistic.ts normalizes intensity shape, calculateCCT applies applyWeatherModifiers
42
+ // which reduces the absolute intensity.
43
+ const clearResult = calculateCCT(lat, lon, dateNoon, {
44
+ weather: { cloudCover: 0 },
45
+ }, CurveType.PHYSICS);
46
+ const cloudyResult = calculateCCT(lat, lon, dateNoon, {
47
+ weather: { cloudCover: 1 },
48
+ }, CurveType.PHYSICS);
49
+ expect(cloudyResult.intensity).toBeLessThan(clearResult.intensity);
50
+ expect(cloudyResult.lightOutput).toBeLessThan(clearResult.lightOutput ?? Infinity);
51
+ });
52
+ it('should blend shapes partially with 50% cloud cover', () => {
53
+ const halfCloudyResult = calculateCCT(lat, lon, dateMorning, {
54
+ cctMinK: 2000,
55
+ cctMaxK: 6500,
56
+ weather: { cloudCover: 0.5 },
57
+ }, CurveType.PHYSICS);
58
+ const clearResult = calculateCCT(lat, lon, dateMorning, {
59
+ cctMinK: 2000,
60
+ cctMaxK: 6500,
61
+ weather: { cloudCover: 0 },
62
+ }, CurveType.PHYSICS);
63
+ const fullCloudyResult = calculateCCT(lat, lon, dateMorning, {
64
+ cctMinK: 2000,
65
+ cctMaxK: 6500,
66
+ weather: { cloudCover: 1 },
67
+ }, CurveType.PHYSICS);
68
+ expect(halfCloudyResult.cct).toBeGreaterThan(clearResult.cct);
69
+ expect(halfCloudyResult.cct).toBeLessThan(fullCloudyResult.cct);
70
+ });
71
+ });
72
+ //# sourceMappingURL=weatherPhysics.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"weatherPhysics.test.js","sourceRoot":"","sources":["../../src/__tests__/weatherPhysics.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"autoCct.d.ts","sourceRoot":"","sources":["../../../src/commands/daylightSimulation/autoCct.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAEhE,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,QAoBlE;AA+VD,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"autoCct.d.ts","sourceRoot":"","sources":["../../../src/commands/daylightSimulation/autoCct.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAEhE,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,QAmBlE;AA4ZD,eAAe,eAAe,CAAC"}