amaran-light-cli 1.1.4 → 1.4.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/CHANGELOG.md +44 -9
- package/README.md +32 -5
- 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 +106 -107
- 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 -247
- 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 +74 -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 +1 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +64 -66
- package/dist/commands/config.js.map +1 -1
- 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/graphSchedule.d.ts +5 -0
- package/dist/commands/graphSchedule.d.ts.map +1 -0
- package/dist/commands/graphSchedule.js +293 -0
- package/dist/commands/graphSchedule.js.map +1 -0
- 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} +113 -116
- 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 +52 -54
- 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 +2 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -2
- package/package.json +17 -15
- package/scripts/release.js +8 -4
- package/scripts/test.sh +2 -2
- 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
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
1
|
// Setup test environment before running tests
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
import { mkdirSync } from 'node:fs';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { LocalStorage } from 'node-localstorage';
|
|
6
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
+
const __dirname = dirname(__filename);
|
|
7
8
|
// Create a temporary directory for test local storage
|
|
8
|
-
const TEST_STORAGE_DIR =
|
|
9
|
+
const TEST_STORAGE_DIR = join(__dirname, '.test-storage');
|
|
9
10
|
try {
|
|
10
11
|
// Ensure the test storage directory exists
|
|
11
|
-
|
|
12
|
+
mkdirSync(TEST_STORAGE_DIR, { recursive: true });
|
|
12
13
|
// Set up global localStorage for tests
|
|
13
|
-
global.localStorage = new
|
|
14
|
+
global.localStorage = new LocalStorage(TEST_STORAGE_DIR);
|
|
14
15
|
}
|
|
15
16
|
catch (error) {
|
|
16
17
|
console.error('Failed to set up test storage:', error);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setupTests.js","sourceRoot":"","sources":["../../src/__tests__/setupTests.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"setupTests.js","sourceRoot":"","sources":["../../src/__tests__/setupTests.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAE9C,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC,sDAAsD;AACtD,MAAM,gBAAgB,GAAG,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;AAE1D,IAAI,CAAC;IACH,2CAA2C;IAC3C,SAAS,CAAC,gBAAgB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEjD,uCAAuC;IACvC,MAAM,CAAC,YAAY,GAAG,IAAI,YAAY,CAAC,gBAAgB,CAAC,CAAC;AAC3D,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IACf,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAC;IACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,0CAA0C;AAC1C,OAAO,CAAC,GAAG,CAAC,QAAQ,GAAG,MAAM,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simulateSchedule.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/simulateSchedule.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,87 @@
|
|
|
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('../geoipUtil', () => ({
|
|
6
|
+
getLocationFromIP: vi.fn(() => ({ ll: [37.7749, -122.4194] })),
|
|
7
|
+
}));
|
|
8
|
+
// Mock cctUtil to return predictable values
|
|
9
|
+
vi.mock('../cctUtil', () => ({
|
|
10
|
+
calculateCCT: vi.fn(() => ({ cct: 5600, intensity: 500 })), // 500 = 50%
|
|
11
|
+
parseCurveType: vi.fn(() => 'HANN'),
|
|
12
|
+
CurveType: {
|
|
13
|
+
HANN: 'hann',
|
|
14
|
+
},
|
|
15
|
+
}));
|
|
16
|
+
// Mock constants to speed up simulation for tests
|
|
17
|
+
vi.mock('../constants', async (importOriginal) => {
|
|
18
|
+
const actual = await importOriginal();
|
|
19
|
+
return {
|
|
20
|
+
...actual,
|
|
21
|
+
DEVICE_DEFAULTS: {
|
|
22
|
+
updateInterval: 200, // 5 updates per second
|
|
23
|
+
statusCheckDelay: 0,
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
describe('simulate-schedule command', () => {
|
|
28
|
+
const originalFetch = global.fetch;
|
|
29
|
+
const mockFetch = vi.fn();
|
|
30
|
+
beforeAll(() => {
|
|
31
|
+
mockFetch.mockImplementation(async () => ({
|
|
32
|
+
json: async () => ({ ip: '1.2.3.4' }),
|
|
33
|
+
}));
|
|
34
|
+
global.fetch = mockFetch;
|
|
35
|
+
});
|
|
36
|
+
afterEach(() => {
|
|
37
|
+
mockFetch.mockClear();
|
|
38
|
+
vi.clearAllMocks();
|
|
39
|
+
});
|
|
40
|
+
afterAll(() => {
|
|
41
|
+
global.fetch = originalFetch;
|
|
42
|
+
});
|
|
43
|
+
test('applies intensity multiplier during simulation', async () => {
|
|
44
|
+
const setCCT = vi.fn();
|
|
45
|
+
const disconnect = vi.fn(async () => Promise.resolve());
|
|
46
|
+
const controllerStub = {
|
|
47
|
+
getDevices: vi.fn(() => [{ node_id: '400J5-F2C008', device_name: 'Key Light' }]),
|
|
48
|
+
getLightSleepStatus: vi.fn(),
|
|
49
|
+
setCCT,
|
|
50
|
+
disconnect,
|
|
51
|
+
};
|
|
52
|
+
const deps = {
|
|
53
|
+
createController: async () => controllerStub,
|
|
54
|
+
findDevice: (_controller, _deviceQuery) => ({
|
|
55
|
+
node_id: '400J5-F2C008',
|
|
56
|
+
device_name: 'Key Light',
|
|
57
|
+
}),
|
|
58
|
+
asyncCommand: (fn) => (...args) => fn(...args),
|
|
59
|
+
loadConfig: () => ({
|
|
60
|
+
intensityMultiplier: {
|
|
61
|
+
'400J5-F2C008': 0.5, // 50% multiplier
|
|
62
|
+
},
|
|
63
|
+
}),
|
|
64
|
+
saveWsUrl: undefined,
|
|
65
|
+
};
|
|
66
|
+
const program = new Command();
|
|
67
|
+
program.exitOverride();
|
|
68
|
+
registerCommands(program, deps);
|
|
69
|
+
// Run simulation for 1 second with 200ms interval = 5 updates (plus one initial?)
|
|
70
|
+
await program.parseAsync(['node', 'test', 'simulate-schedule', 'Key Light', '--duration', '1']);
|
|
71
|
+
// Check that setCCT was called
|
|
72
|
+
expect(setCCT).toHaveBeenCalled();
|
|
73
|
+
// Verify the intensity was scaled
|
|
74
|
+
// Base intensity is 500 (50%). Multiplier is 0.5.
|
|
75
|
+
// Target percent = 25%.
|
|
76
|
+
// Raw intensity = 500 * (25/50) = 250.
|
|
77
|
+
const calls = setCCT.mock.calls;
|
|
78
|
+
expect(calls.length).toBeGreaterThan(0);
|
|
79
|
+
// Check key parameters of the first call
|
|
80
|
+
const [nodeId, cct, intensity] = calls[0];
|
|
81
|
+
expect(nodeId).toBe('400J5-F2C008');
|
|
82
|
+
expect(cct).toBe(5600);
|
|
83
|
+
expect(intensity).toBe(250); // 500 * 0.5
|
|
84
|
+
expect(disconnect).toHaveBeenCalled();
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
//# sourceMappingURL=simulateSchedule.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simulateSchedule.test.js","sourceRoot":"","sources":["../../src/__tests__/simulateSchedule.test.ts"],"names":[],"mappings":"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"}
|
package/dist/autostart.js
CHANGED
|
@@ -1,48 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
-
};
|
|
38
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.isAmaranAppRunning = isAmaranAppRunning;
|
|
40
|
-
exports.startAmaranApp = startAmaranApp;
|
|
41
|
-
exports.handleAutostart = handleAutostart;
|
|
42
|
-
const node_child_process_1 = require("node:child_process");
|
|
43
|
-
const fs = __importStar(require("node:fs"));
|
|
44
|
-
const path = __importStar(require("node:path"));
|
|
45
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
1
|
+
import { exec } from 'node:child_process';
|
|
2
|
+
import * as fs from 'node:fs';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import chalk from 'chalk';
|
|
46
5
|
const configPath = path.join(process.env.HOME || '', '.amaran-cli.json');
|
|
47
6
|
function loadConfig() {
|
|
48
7
|
try {
|
|
@@ -53,7 +12,7 @@ function loadConfig() {
|
|
|
53
12
|
return null;
|
|
54
13
|
}
|
|
55
14
|
catch (_error) {
|
|
56
|
-
console.warn(
|
|
15
|
+
console.warn(chalk.yellow('Warning: Could not load config file'));
|
|
57
16
|
return null;
|
|
58
17
|
}
|
|
59
18
|
}
|
|
@@ -61,7 +20,7 @@ function logAutostart(message, debug = false) {
|
|
|
61
20
|
const timestamp = new Date().toISOString();
|
|
62
21
|
const logMessage = `[${timestamp}] [AUTOSTART] ${message}`;
|
|
63
22
|
if (debug) {
|
|
64
|
-
console.log(
|
|
23
|
+
console.log(chalk.gray(logMessage));
|
|
65
24
|
}
|
|
66
25
|
// Also log to a file for persistence
|
|
67
26
|
try {
|
|
@@ -76,9 +35,9 @@ function logAutostart(message, debug = false) {
|
|
|
76
35
|
* Check if the Amaran desktop app is running by looking for processes
|
|
77
36
|
* that contain "amaran desktop" (case-insensitive)
|
|
78
37
|
*/
|
|
79
|
-
async function isAmaranAppRunning(debug = false) {
|
|
38
|
+
export async function isAmaranAppRunning(debug = false) {
|
|
80
39
|
return new Promise((resolve) => {
|
|
81
|
-
|
|
40
|
+
exec('ps aux | grep -i "amaran desktop" | grep -v grep', (error, stdout) => {
|
|
82
41
|
if (error) {
|
|
83
42
|
if (debug) {
|
|
84
43
|
logAutostart(`Failed to check if app is running: ${error.message}`, debug);
|
|
@@ -90,7 +49,7 @@ async function isAmaranAppRunning(debug = false) {
|
|
|
90
49
|
if (debug) {
|
|
91
50
|
logAutostart(`App running check: ${isRunning ? 'FOUND' : 'NOT FOUND'}`, debug);
|
|
92
51
|
if (isRunning) {
|
|
93
|
-
console.log(
|
|
52
|
+
console.log(chalk.gray(`[AUTOSTART] Found Amaran Desktop processes:\n${stdout}`));
|
|
94
53
|
}
|
|
95
54
|
}
|
|
96
55
|
resolve(isRunning);
|
|
@@ -101,7 +60,7 @@ async function isAmaranAppRunning(debug = false) {
|
|
|
101
60
|
* Attempt to start the Amaran desktop app
|
|
102
61
|
* This implementation tries common locations and methods for macOS
|
|
103
62
|
*/
|
|
104
|
-
async function startAmaranApp(debug = false) {
|
|
63
|
+
export async function startAmaranApp(debug = false) {
|
|
105
64
|
const config = loadConfig();
|
|
106
65
|
// Check if autostart is disabled in config
|
|
107
66
|
if (config?.autoStartApp === false) {
|
|
@@ -124,17 +83,17 @@ async function startAmaranApp(debug = false) {
|
|
|
124
83
|
if (methodIndex >= startMethods.length) {
|
|
125
84
|
logAutostart('Failed to start app - tried all known methods', debug);
|
|
126
85
|
if (debug) {
|
|
127
|
-
console.log(
|
|
86
|
+
console.log(chalk.yellow('[AUTOSTART] Could not find or start Amaran app. Tried:'));
|
|
128
87
|
startMethods.forEach((method) => {
|
|
129
|
-
console.log(
|
|
88
|
+
console.log(chalk.gray(` - ${method}`));
|
|
130
89
|
});
|
|
131
|
-
console.log(
|
|
90
|
+
console.log(chalk.yellow('Make sure the Amaran desktop app is installed in /Applications or available via "open -a"'));
|
|
132
91
|
}
|
|
133
92
|
resolve(false);
|
|
134
93
|
return;
|
|
135
94
|
}
|
|
136
95
|
const method = startMethods[methodIndex];
|
|
137
|
-
|
|
96
|
+
exec(method, (error) => {
|
|
138
97
|
if (error) {
|
|
139
98
|
// Try the next method
|
|
140
99
|
methodIndex++;
|
|
@@ -143,7 +102,7 @@ async function startAmaranApp(debug = false) {
|
|
|
143
102
|
}
|
|
144
103
|
logAutostart(`Successfully started app using: ${method}`, debug);
|
|
145
104
|
if (debug) {
|
|
146
|
-
console.log(
|
|
105
|
+
console.log(chalk.green(`[AUTOSTART] Started Amaran app using: ${method}`));
|
|
147
106
|
}
|
|
148
107
|
// Give the app a moment to start up
|
|
149
108
|
setTimeout(() => {
|
|
@@ -158,7 +117,7 @@ async function startAmaranApp(debug = false) {
|
|
|
158
117
|
* Main function to handle autostart logic
|
|
159
118
|
* Checks if app is running, and if not, attempts to start it (unless disabled)
|
|
160
119
|
*/
|
|
161
|
-
async function handleAutostart(debug = false) {
|
|
120
|
+
export async function handleAutostart(debug = false) {
|
|
162
121
|
const config = loadConfig();
|
|
163
122
|
// Log the autostart setting
|
|
164
123
|
const autoStartEnabled = config?.autoStartApp !== false; // Default to true
|
|
@@ -166,7 +125,7 @@ async function handleAutostart(debug = false) {
|
|
|
166
125
|
if (!autoStartEnabled) {
|
|
167
126
|
logAutostart('Autostart is blocked by configuration setting', debug);
|
|
168
127
|
if (debug) {
|
|
169
|
-
console.log(
|
|
128
|
+
console.log(chalk.yellow('[AUTOSTART] Autostart is disabled. Use "amaran config --auto-start-app true" to enable.'));
|
|
170
129
|
}
|
|
171
130
|
return false;
|
|
172
131
|
}
|
|
@@ -180,13 +139,13 @@ async function handleAutostart(debug = false) {
|
|
|
180
139
|
if (started) {
|
|
181
140
|
logAutostart('Successfully started Amaran desktop app', debug);
|
|
182
141
|
if (debug) {
|
|
183
|
-
console.log(
|
|
142
|
+
console.log(chalk.green('[AUTOSTART] Amaran desktop app started successfully'));
|
|
184
143
|
}
|
|
185
144
|
}
|
|
186
145
|
else {
|
|
187
146
|
logAutostart('Failed to start Amaran desktop app', debug);
|
|
188
147
|
if (debug) {
|
|
189
|
-
console.log(
|
|
148
|
+
console.log(chalk.red('[AUTOSTART] Failed to start Amaran desktop app'));
|
|
190
149
|
}
|
|
191
150
|
}
|
|
192
151
|
return started;
|
package/dist/autostart.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"autostart.js","sourceRoot":"","sources":["../src/autostart.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"autostart.js","sourceRoot":"","sources":["../src/autostart.ts"],"names":[],"mappings":"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"}
|
package/dist/cctUtil.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cctUtil.d.ts","sourceRoot":"","sources":["../src/cctUtil.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cctUtil.d.ts","sourceRoot":"","sources":["../src/cctUtil.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,oBAAY,SAAS;IACnB,IAAI,SAAS;IACb,kBAAkB,uBAAuB;IACzC,mBAAmB,wBAAwB;IAC3C,kBAAkB,uBAAuB;IACzC,YAAY,iBAAiB;IAC7B,YAAY,iBAAiB;IAC7B,cAAc,mBAAmB;CAClC;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,OAAO,SAAS,CAuBpE;AAED,wBAAgB,kBAAkB,IAAI,MAAM,EAAE,CAE7C;AAwbD,wBAAgB,YAAY,CAC1B,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,IAAI,GAAE,IAAiB,EACvB,IAAI,CAAC,EAAE,UAAU,EACjB,SAAS,GAAE,SAA0B,GACpC,SAAS,CAgBX"}
|
package/dist/cctUtil.js
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
exports.getAvailableCurves = getAvailableCurves;
|
|
6
|
-
exports.calculateCCT = calculateCCT;
|
|
7
|
-
const suncalc_1 = require("suncalc");
|
|
8
|
-
const constants_1 = require("./constants");
|
|
9
|
-
var CurveType;
|
|
1
|
+
import SunCalc from 'suncalc';
|
|
2
|
+
const { getPosition, getTimes } = SunCalc;
|
|
3
|
+
import { CCT_DEFAULTS } from './constants.js';
|
|
4
|
+
export var CurveType;
|
|
10
5
|
(function (CurveType) {
|
|
11
6
|
CurveType["HANN"] = "hann";
|
|
12
7
|
CurveType["WIDER_MIDDLE_SMALL"] = "wider-middle-small";
|
|
@@ -15,8 +10,8 @@ var CurveType;
|
|
|
15
10
|
CurveType["CIE_DAYLIGHT"] = "cie-daylight";
|
|
16
11
|
CurveType["SUN_ALTITUDE"] = "sun-altitude";
|
|
17
12
|
CurveType["PEREZ_DAYLIGHT"] = "perez-daylight";
|
|
18
|
-
})(CurveType || (
|
|
19
|
-
function parseCurveType(curve) {
|
|
13
|
+
})(CurveType || (CurveType = {}));
|
|
14
|
+
export function parseCurveType(curve) {
|
|
20
15
|
const normalizedCurve = curve.toLowerCase();
|
|
21
16
|
if (normalizedCurve === 'hann') {
|
|
22
17
|
return 'HANN';
|
|
@@ -46,7 +41,7 @@ function parseCurveType(curve) {
|
|
|
46
41
|
throw new Error('Invalid curve type. Use "hann", "wider-middle-small", "wider-middle-medium", "wider-middle-large", "cie-daylight", "sun-altitude", or "perez-daylight"');
|
|
47
42
|
}
|
|
48
43
|
}
|
|
49
|
-
function getAvailableCurves() {
|
|
44
|
+
export function getAvailableCurves() {
|
|
50
45
|
return Object.values(CurveType);
|
|
51
46
|
}
|
|
52
47
|
const CURVE_FUNCTIONS = {
|
|
@@ -109,32 +104,29 @@ function calculateRealisticSunAltitude(altitude, maxAltitude) {
|
|
|
109
104
|
// Very high sun: 6500-7500K
|
|
110
105
|
cctFactor = 1.0;
|
|
111
106
|
}
|
|
112
|
-
//
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
//
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
// Maintain peak at maximum intensity
|
|
136
|
-
intensityFactor = 1.0;
|
|
137
|
-
}
|
|
107
|
+
// Calculate raw intensity factor based on absolute altitude
|
|
108
|
+
const calculateIntensity = (altDeg) => {
|
|
109
|
+
if (altDeg < -6)
|
|
110
|
+
return 0;
|
|
111
|
+
if (altDeg < 0)
|
|
112
|
+
return ((altDeg + 6) / 6) ** 2 * 0.05;
|
|
113
|
+
if (altDeg < 10)
|
|
114
|
+
return 0.05 + (altDeg / 10) * 0.15;
|
|
115
|
+
if (altDeg < 30)
|
|
116
|
+
return 0.2 + ((altDeg - 10) / 20) * 0.4;
|
|
117
|
+
// For higher altitudes, use a standard curve that would reach 1.0 at 90 degrees
|
|
118
|
+
// This serves as our "raw" value before normalization
|
|
119
|
+
return 0.6 + ((altDeg - 30) / 60) * 0.4;
|
|
120
|
+
};
|
|
121
|
+
const rawIntensity = calculateIntensity(altitudeDeg);
|
|
122
|
+
// Calculate the maximum possible intensity for this day (at solar noon)
|
|
123
|
+
// This ensures that even on winter days with low max altitude, we can reach 100%
|
|
124
|
+
const maxDailyIntensity = calculateIntensity(maxAltitudeDeg);
|
|
125
|
+
// Normalize: Scale the current intensity so that at maxAltitude it reaches 1.0
|
|
126
|
+
// Avoid division by zero if maxDailyIntensity is very small (e.g. polar night)
|
|
127
|
+
let intensityFactor = maxDailyIntensity > 0.01 ? rawIntensity / maxDailyIntensity : 0;
|
|
128
|
+
// Cap at 1.0 just in case
|
|
129
|
+
intensityFactor = Math.min(1.0, intensityFactor);
|
|
138
130
|
return [Math.max(0, Math.min(1, cctFactor)), Math.max(0, Math.min(1, intensityFactor))];
|
|
139
131
|
}
|
|
140
132
|
function calculateRealisticCIEDaylight(altitude, maxAltitude) {
|
|
@@ -162,35 +154,41 @@ function calculateRealisticCIEDaylight(altitude, maxAltitude) {
|
|
|
162
154
|
// High sun: maximum blue
|
|
163
155
|
cctFactor = 0.9 + Math.min(0.1, ((altitudeDeg - 45) / 45) * 0.1); // 0.9 to 1.0
|
|
164
156
|
}
|
|
165
|
-
//
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
//
|
|
192
|
-
|
|
193
|
-
|
|
157
|
+
// Calculate raw intensity based on absolute altitude (0-90 degrees)
|
|
158
|
+
const calculateRawIntensity = (altDeg) => {
|
|
159
|
+
if (altDeg < -6)
|
|
160
|
+
return 0;
|
|
161
|
+
if (altDeg < 0)
|
|
162
|
+
return ((altDeg + 6) / 6) ** 3 * 0.03; // Very low start
|
|
163
|
+
if (altDeg < 15) {
|
|
164
|
+
// Atmospheric path length effect - gradual start
|
|
165
|
+
// Fix: Use radians directly for sin() since altitude was originally radians,
|
|
166
|
+
// but here we are working with degrees, so convert back or just use the degree value logic?
|
|
167
|
+
// Actually airMass formula: 1 / sin(elevation). elevation in radians.
|
|
168
|
+
// We have altDeg. Convert to radians: altDeg * PI / 180.
|
|
169
|
+
const altRad = Math.max(0.01, (altDeg * Math.PI) / 180);
|
|
170
|
+
const airMass = 1 / Math.sin(altRad);
|
|
171
|
+
return Math.min(0.25, 1 / airMass ** 0.7);
|
|
172
|
+
}
|
|
173
|
+
if (altDeg < 40) {
|
|
174
|
+
// Mid-morning increase
|
|
175
|
+
// Map 15..40 to 0.25..0.80
|
|
176
|
+
return 0.25 + ((altDeg - 15) / 25) * 0.55;
|
|
177
|
+
}
|
|
178
|
+
if (altDeg < 70) {
|
|
179
|
+
// Approach peak
|
|
180
|
+
// Map 40..70 to 0.80..0.95
|
|
181
|
+
return 0.8 + ((altDeg - 40) / 30) * 0.15;
|
|
182
|
+
}
|
|
183
|
+
// High sun > 70
|
|
184
|
+
// Map 70..90 to 0.95..1.0
|
|
185
|
+
return 0.95 + ((altDeg - 70) / 20) * 0.05;
|
|
186
|
+
};
|
|
187
|
+
const rawIntensity = calculateRawIntensity(altitudeDeg);
|
|
188
|
+
// Calculate max possible intensity for this day (normalization factor)
|
|
189
|
+
const maxDailyIntensity = calculateRawIntensity(maxAltitudeDeg);
|
|
190
|
+
// Normalize
|
|
191
|
+
const intensityFactor = maxDailyIntensity > 0.001 ? rawIntensity / maxDailyIntensity : 0;
|
|
194
192
|
return [Math.max(0, Math.min(1, cctFactor)), Math.max(0, Math.min(1, intensityFactor))];
|
|
195
193
|
}
|
|
196
194
|
function calculateRealisticPerezDaylight(altitude, maxAltitude) {
|
|
@@ -219,37 +217,38 @@ function calculateRealisticPerezDaylight(altitude, maxAltitude) {
|
|
|
219
217
|
// Slight cooling at very high angles
|
|
220
218
|
cctFactor = Math.min(1.0, 0.95 + ((altitudeDeg - 50) / 40) * 0.05); // 0.95 to 1.0
|
|
221
219
|
}
|
|
222
|
-
//
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
0.9 +
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
220
|
+
// Calculate raw intensity based on absolute altitude (0-90 degrees)
|
|
221
|
+
const calculateRawIntensity = (altDeg) => {
|
|
222
|
+
if (altDeg < -6)
|
|
223
|
+
return 0;
|
|
224
|
+
if (altDeg < 5) {
|
|
225
|
+
// Very low light near horizon
|
|
226
|
+
return (Math.max(0, altDeg + 6) / 11) ** 4 * 0.15;
|
|
227
|
+
}
|
|
228
|
+
if (altDeg < 20) {
|
|
229
|
+
// Morning increase with atmospheric effects
|
|
230
|
+
const zenithAngle = Math.max(0.01, ((90 - altDeg) * Math.PI) / 180);
|
|
231
|
+
const relativeLuminance = Math.exp(-0.2 / Math.max(0.01, Math.cos(zenithAngle)));
|
|
232
|
+
return Math.min(0.4, relativeLuminance * 0.35 + 0.05);
|
|
233
|
+
}
|
|
234
|
+
if (altDeg < 45) {
|
|
235
|
+
// Strong increase to midday
|
|
236
|
+
// Map 20..45 to 0.25..0.9
|
|
237
|
+
return 0.25 + ((altDeg - 20) / 25) * 0.65;
|
|
238
|
+
}
|
|
239
|
+
if (altDeg < 80) {
|
|
240
|
+
// Peak approach
|
|
241
|
+
// Map 45..80 to 0.9..1.0
|
|
242
|
+
return 0.9 + ((altDeg - 45) / 35) * 0.1;
|
|
243
|
+
}
|
|
244
|
+
// High sun > 80
|
|
245
|
+
return 1.0;
|
|
246
|
+
};
|
|
247
|
+
const rawIntensity = calculateRawIntensity(altitudeDeg);
|
|
248
|
+
// Calculate max possible intensity for this day (normalization factor)
|
|
249
|
+
const maxDailyIntensity = calculateRawIntensity(maxAltitudeDeg);
|
|
250
|
+
// Normalize
|
|
251
|
+
const intensityFactor = maxDailyIntensity > 0.001 ? rawIntensity / maxDailyIntensity : 0;
|
|
253
252
|
return [Math.max(0, Math.min(1, cctFactor)), Math.max(0, Math.min(1, intensityFactor))];
|
|
254
253
|
}
|
|
255
254
|
function cieDaylightCurve(x) {
|
|
@@ -285,7 +284,7 @@ function isValidSunTimes(sunrise, sunset, solarNoon) {
|
|
|
285
284
|
}
|
|
286
285
|
function calculateCCTCore(lat, lon, date, minK, maxK, minIntensity, maxIntensity, curveType) {
|
|
287
286
|
const curve = CURVE_FUNCTIONS[curveType];
|
|
288
|
-
const times =
|
|
287
|
+
const times = getTimes(date, lat, lon);
|
|
289
288
|
const sunrise = times.sunrise;
|
|
290
289
|
const sunset = times.sunset;
|
|
291
290
|
const _solarNoon = times.solarNoon;
|
|
@@ -322,10 +321,10 @@ function calculateCCTCore(lat, lon, date, minK, maxK, minIntensity, maxIntensity
|
|
|
322
321
|
return { cct: minK, intensity: minIntensity };
|
|
323
322
|
}
|
|
324
323
|
}
|
|
325
|
-
const pos =
|
|
324
|
+
const pos = getPosition(date, lat, lon);
|
|
326
325
|
const altitude = pos.altitude;
|
|
327
326
|
// Get maximum altitude for normalization (at solar noon on this day)
|
|
328
|
-
const noonPos =
|
|
327
|
+
const noonPos = getPosition(_solarNoon, lat, lon);
|
|
329
328
|
const maxAltitude = noonPos.altitude;
|
|
330
329
|
if (curveType === CurveType.SUN_ALTITUDE) {
|
|
331
330
|
// Realistic sun altitude-based calculations
|
|
@@ -403,7 +402,7 @@ function calculateCCTCore(lat, lon, date, minK, maxK, minIntensity, maxIntensity
|
|
|
403
402
|
}
|
|
404
403
|
// Fallback for empirical curves when night times are not available
|
|
405
404
|
try {
|
|
406
|
-
const pos =
|
|
405
|
+
const pos = getPosition(date, lat, lon);
|
|
407
406
|
const altitude = pos.altitude;
|
|
408
407
|
if (altitude <= 0)
|
|
409
408
|
return { cct: minK, intensity: minIntensity };
|
|
@@ -419,14 +418,14 @@ function calculateCCTCore(lat, lon, date, minK, maxK, minIntensity, maxIntensity
|
|
|
419
418
|
return { cct: minK, intensity: minIntensity };
|
|
420
419
|
}
|
|
421
420
|
}
|
|
422
|
-
function calculateCCT(lat, lon, date = new Date(), opts, curveType = CurveType.HANN) {
|
|
421
|
+
export function calculateCCT(lat, lon, date = new Date(), opts, curveType = CurveType.HANN) {
|
|
423
422
|
const clamp = (v, lo, hi) => Math.min(hi, Math.max(lo, v));
|
|
424
|
-
const cctMinK = clamp(opts?.cctMinK ??
|
|
425
|
-
const cctMaxK = clamp(opts?.cctMaxK ??
|
|
423
|
+
const cctMinK = clamp(opts?.cctMinK ?? CCT_DEFAULTS.cctMinK, 1000, 20000);
|
|
424
|
+
const cctMaxK = clamp(opts?.cctMaxK ?? CCT_DEFAULTS.cctMaxK, 1000, 20000);
|
|
426
425
|
const minK = Math.min(cctMinK, cctMaxK);
|
|
427
426
|
const maxK = Math.max(cctMinK, cctMaxK);
|
|
428
|
-
const intensityMinPct = clamp(opts?.intensityMinPct ??
|
|
429
|
-
const intensityMaxPct = clamp(opts?.intensityMaxPct ??
|
|
427
|
+
const intensityMinPct = clamp(opts?.intensityMinPct ?? CCT_DEFAULTS.intensityMinPct, 0, 100);
|
|
428
|
+
const intensityMaxPct = clamp(opts?.intensityMaxPct ?? CCT_DEFAULTS.intensityMaxPct, 0, 100);
|
|
430
429
|
const minPct = Math.min(intensityMinPct, intensityMaxPct);
|
|
431
430
|
const maxPct = Math.max(intensityMinPct, intensityMaxPct);
|
|
432
431
|
const minIntensity = Math.round(minPct * 10);
|