homebridge-kasa-python 1.0.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -6
- package/config.schema.json +2 -33
- package/dist/accessoryInformation.d.ts +1 -1
- package/dist/accessoryInformation.js +14 -18
- package/dist/accessoryInformation.js.map +1 -1
- package/dist/categoriesParse.d.ts +8 -0
- package/dist/categoriesParse.js +44 -0
- package/dist/categoriesParse.js.map +1 -0
- package/dist/config.d.ts +12 -155
- package/dist/config.js +52 -100
- package/dist/config.js.map +1 -1
- package/dist/devices/create.d.ts +3 -9
- package/dist/devices/create.js +6 -7
- package/dist/devices/create.js.map +1 -1
- package/dist/devices/deviceManager.d.ts +6 -8
- package/dist/devices/deviceManager.js +47 -126
- package/dist/devices/deviceManager.js.map +1 -1
- package/dist/devices/homekitPlug.d.ts +10 -16
- package/dist/devices/homekitPlug.js +93 -74
- package/dist/devices/homekitPlug.js.map +1 -1
- package/dist/devices/homekitPowerstrip.d.ts +11 -17
- package/dist/devices/homekitPowerstrip.js +106 -73
- package/dist/devices/homekitPowerstrip.js.map +1 -1
- package/dist/devices/index.d.ts +12 -19
- package/dist/devices/index.js +44 -71
- package/dist/devices/index.js.map +1 -1
- package/dist/devices/kasaDevices.d.ts +4 -5
- package/dist/platform.d.ts +22 -29
- package/dist/platform.js +127 -131
- package/dist/platform.js.map +1 -1
- package/dist/python/kasaApi.py +109 -0
- package/dist/python/pythonChecker.d.ts +2 -2
- package/dist/python/pythonChecker.js +24 -89
- package/dist/python/pythonChecker.js.map +1 -1
- package/dist/utils.d.ts +3 -18
- package/dist/utils.js +72 -116
- package/dist/utils.js.map +1 -1
- package/package.json +20 -19
- package/requirements.txt +4 -1
- package/dist/python/discover.py +0 -38
- package/dist/python/getSysInfo.py +0 -39
- package/dist/python/turnOff.py +0 -20
- package/dist/python/turnOffChild.py +0 -22
- package/dist/python/turnOn.py +0 -20
- package/dist/python/turnOnChild.py +0 -22
|
@@ -1,16 +1,10 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import { fileURLToPath } from 'url';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
6
5
|
import { delay, prefixLogger, runCommand } from '../utils.js';
|
|
7
6
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
8
|
-
const SUPPORTED_PYTHON_VERSIONS = [
|
|
9
|
-
'3.9',
|
|
10
|
-
'3.10',
|
|
11
|
-
'3.11',
|
|
12
|
-
'3.12',
|
|
13
|
-
];
|
|
7
|
+
const SUPPORTED_PYTHON_VERSIONS = ['3.9', '3.10', '3.11', '3.12'];
|
|
14
8
|
class PythonChecker {
|
|
15
9
|
log;
|
|
16
10
|
platform;
|
|
@@ -21,130 +15,79 @@ class PythonChecker {
|
|
|
21
15
|
venvPythonExecutable;
|
|
22
16
|
venvConfigPath;
|
|
23
17
|
requirementsPath = path.join(__dirname, '..', '..', 'requirements.txt');
|
|
24
|
-
constructor(platform
|
|
18
|
+
constructor(platform) {
|
|
25
19
|
this.platform = platform;
|
|
26
|
-
this.log = prefixLogger(this.platform.log,
|
|
27
|
-
this.pythonExecutable = pythonExecutable || 'python3';
|
|
28
|
-
this.
|
|
29
|
-
this.pluginDirPath = path.join(storagePath, 'kasa-python');
|
|
20
|
+
this.log = prefixLogger(this.platform.log, '[Python Check]');
|
|
21
|
+
this.pythonExecutable = this.platform.config.pythonExecutable || 'python3';
|
|
22
|
+
this.pluginDirPath = path.join(this.platform.storagePath, 'kasa-python');
|
|
30
23
|
this.venvPath = path.join(this.pluginDirPath, '.venv');
|
|
31
24
|
this.venvPythonExecutable = path.join(this.venvPath, 'bin', 'python3');
|
|
32
25
|
this.venvPipExecutable = path.join(this.venvPath, 'bin', 'pip3');
|
|
33
26
|
this.venvConfigPath = path.join(this.venvPath, 'pyvenv.cfg');
|
|
34
27
|
}
|
|
35
|
-
async allInOne(
|
|
36
|
-
this.log.
|
|
28
|
+
async allInOne() {
|
|
29
|
+
this.log.debug('Starting python environment check...');
|
|
37
30
|
this.ensurePluginDir();
|
|
38
31
|
await this.ensurePythonVersion();
|
|
39
|
-
await this.ensureVenvCreated(forceVenvRecreate);
|
|
32
|
+
await this.ensureVenvCreated(this.platform.config.forceVenvRecreate);
|
|
40
33
|
await this.ensureVenvUsesCorrectPythonHome();
|
|
41
34
|
await this.ensureVenvPipUpToDate();
|
|
42
35
|
await this.ensureVenvRequirementsSatisfied();
|
|
43
|
-
this.log.
|
|
36
|
+
this.log.debug('Finished python environment check.');
|
|
44
37
|
}
|
|
45
38
|
ensurePluginDir() {
|
|
46
|
-
this.log.debug('Checking if plugin directory exists...');
|
|
47
39
|
if (!fs.existsSync(this.pluginDirPath)) {
|
|
48
|
-
this.log.debug('Plugin directory does not exist, Creating plugin dir...');
|
|
49
40
|
fs.mkdirSync(this.pluginDirPath);
|
|
50
|
-
this.log.debug('Plugin directory created. Continuing...');
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
this.log.debug('Plugin directory already exists. Continuing...');
|
|
54
41
|
}
|
|
55
42
|
}
|
|
56
43
|
async ensurePythonVersion() {
|
|
57
|
-
this.log.debug('Getting python version...');
|
|
58
44
|
const version = await this.getSystemPythonVersion();
|
|
59
45
|
if (SUPPORTED_PYTHON_VERSIONS.findIndex((e) => version.includes(e)) === -1) {
|
|
60
46
|
while (true) {
|
|
61
|
-
this.log.error(`Python ${version} is installed. However, only Python
|
|
62
|
-
${SUPPORTED_PYTHON_VERSIONS[0]} to ${SUPPORTED_PYTHON_VERSIONS[SUPPORTED_PYTHON_VERSIONS.length - 1]} is supported.`);
|
|
47
|
+
this.log.error(`Python ${version} is installed. However, only Python ${SUPPORTED_PYTHON_VERSIONS.join(', ')} is supported.`);
|
|
63
48
|
await delay(300000);
|
|
64
49
|
}
|
|
65
50
|
}
|
|
66
|
-
else {
|
|
67
|
-
this.log.debug(`Python ${version} is installed and supported by the plugin. Continuing...`);
|
|
68
|
-
}
|
|
69
51
|
}
|
|
70
52
|
async ensureVenvCreated(forceVenvRecreate) {
|
|
71
|
-
|
|
72
|
-
if (forceVenvRecreate) {
|
|
73
|
-
this.log.warn('Python virtual environment is being force recreated...');
|
|
74
|
-
await this.createVenv();
|
|
75
|
-
}
|
|
76
|
-
else if (this.isVenvCreated() === false) {
|
|
77
|
-
this.log.info('Python virtual environment does not exist. Creating now...');
|
|
53
|
+
if (forceVenvRecreate || !this.isVenvCreated()) {
|
|
78
54
|
await this.createVenv();
|
|
79
55
|
}
|
|
80
|
-
else {
|
|
81
|
-
this.log.info('Python virtual environment already exists. Continuing...');
|
|
82
|
-
}
|
|
83
56
|
}
|
|
84
57
|
isVenvCreated() {
|
|
85
|
-
return fs.existsSync(this.venvPipExecutable) &&
|
|
86
|
-
fs.existsSync(this.venvConfigPath) &&
|
|
87
|
-
fs.existsSync(this.venvPythonExecutable);
|
|
58
|
+
return fs.existsSync(this.venvPipExecutable) && fs.existsSync(this.venvConfigPath) && fs.existsSync(this.venvPythonExecutable);
|
|
88
59
|
}
|
|
89
60
|
async createVenv() {
|
|
90
61
|
const [stdout] = await runCommand(this.log, this.pythonExecutable, ['-m', 'venv', this.venvPath, '--clear'], undefined, true);
|
|
91
62
|
if (stdout.includes('not created successfully') || !this.isVenvCreated()) {
|
|
92
63
|
while (true) {
|
|
93
|
-
this.log.error('virtualenv python module is not installed.
|
|
94
|
-
update the homebridge apt package to 1.1.4 or above (this applies for installations based on the Raspberry Pi OS iamge as well). \
|
|
95
|
-
When using the official docker image, update the image to version 2023-11-28 or above. Otherwise install the python virtualenv \
|
|
96
|
-
module manually.');
|
|
64
|
+
this.log.error('virtualenv python module is not installed.');
|
|
97
65
|
await delay(300000);
|
|
98
66
|
}
|
|
99
67
|
}
|
|
100
|
-
else if (stdout.trim() !== '') {
|
|
101
|
-
this.log.warn(stdout);
|
|
102
|
-
}
|
|
103
|
-
this.log.debug('Python virtual environment (re)created. Continuing...');
|
|
104
68
|
}
|
|
105
69
|
async ensureVenvUsesCorrectPythonHome() {
|
|
106
|
-
this.log.debug('Checking if python virtual environment uses the python system environment...');
|
|
107
|
-
this.log.debug('Getting python home for python virtual environment...');
|
|
108
70
|
const venvPythonHome = await this.getPythonHome(this.venvPythonExecutable);
|
|
109
|
-
this.log.debug('Getting python home for python system environment...');
|
|
110
71
|
const pythonHome = await this.getPythonHome(this.pythonExecutable);
|
|
111
72
|
if (venvPythonHome !== pythonHome) {
|
|
112
|
-
this.log.warn('Python virtual environment does not use the python system environment.\
|
|
113
|
-
Recreating virtual environment...');
|
|
114
|
-
this.log.debug(`Python System Environment: ${pythonHome}; Python Virtual Environment: ${venvPythonHome}`);
|
|
115
73
|
await this.createVenv();
|
|
116
74
|
}
|
|
117
|
-
else {
|
|
118
|
-
this.log.debug('Python virtual environment is using the python system environment. Continuing ...');
|
|
119
|
-
}
|
|
120
75
|
}
|
|
121
76
|
async getPythonHome(executable) {
|
|
122
77
|
const [venvPythonHome] = await runCommand(this.log, executable, [path.join(__dirname, 'pythonHome.py')], undefined, true);
|
|
123
78
|
return venvPythonHome.trim();
|
|
124
79
|
}
|
|
125
80
|
async ensureVenvPipUpToDate() {
|
|
126
|
-
this.log.debug('Checking if python virtual environment pip is up-to-date...');
|
|
127
81
|
const venvPipVersion = await this.getVenvPipVersion();
|
|
128
|
-
|
|
129
|
-
this.log.debug('Checking if there is an update for python virtual environment pip...');
|
|
130
|
-
if (venvPipVersion === await this.getMostRecentPipVersion()) {
|
|
131
|
-
this.log.debug('Python virtual environment pip is up-to-date. Continuing...');
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
this.log.warn('Python virtual environment pip is outdated. Updating now...');
|
|
82
|
+
if (venvPipVersion !== await this.getMostRecentPipVersion()) {
|
|
135
83
|
await this.updatePip();
|
|
136
|
-
this.log.debug('Python virtual environment pip updated. Continuing...');
|
|
137
84
|
}
|
|
138
85
|
}
|
|
139
86
|
async updatePip() {
|
|
140
87
|
await runCommand(this.log, this.venvPipExecutable, ['install', '--upgrade', 'pip'], undefined, true);
|
|
141
88
|
}
|
|
142
89
|
async ensureVenvRequirementsSatisfied() {
|
|
143
|
-
if (await this.areRequirementsSatisfied()) {
|
|
144
|
-
this.log.debug('Python requirements are satisfied. Continuing...');
|
|
145
|
-
}
|
|
146
|
-
else {
|
|
147
|
-
this.log.warn('Python requirements are not satisfied. Installing them now...');
|
|
90
|
+
if (!await this.areRequirementsSatisfied()) {
|
|
148
91
|
await this.installRequirements();
|
|
149
92
|
}
|
|
150
93
|
}
|
|
@@ -152,25 +95,17 @@ class PythonChecker {
|
|
|
152
95
|
const [freezeStdout] = await runCommand(this.log, this.venvPipExecutable, ['freeze'], undefined, true);
|
|
153
96
|
const freeze = this.freezeStringToObject(freezeStdout);
|
|
154
97
|
const requirements = this.freezeStringToObject(fs.readFileSync(this.requirementsPath).toString());
|
|
155
|
-
|
|
156
|
-
if (freeze[pkg] !== requirements[pkg]) {
|
|
157
|
-
return false;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
return true;
|
|
98
|
+
return Object.keys(requirements).every(pkg => freeze[pkg] === requirements[pkg]);
|
|
161
99
|
}
|
|
162
100
|
freezeStringToObject(value) {
|
|
163
|
-
|
|
164
|
-
const packages = {};
|
|
165
|
-
for (const line of lines) {
|
|
101
|
+
return value.trim().split('\n').reduce((acc, line) => {
|
|
166
102
|
const [pkg, version] = line.split('==');
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
103
|
+
acc[pkg.replaceAll('_', '-')] = version;
|
|
104
|
+
return acc;
|
|
105
|
+
}, {});
|
|
170
106
|
}
|
|
171
107
|
async installRequirements() {
|
|
172
108
|
await runCommand(this.log, this.venvPipExecutable, ['install', '-r', this.requirementsPath], undefined, true);
|
|
173
|
-
this.log.debug('Python requirements installed. Continuing...');
|
|
174
109
|
}
|
|
175
110
|
async getSystemPythonVersion() {
|
|
176
111
|
const [version] = await runCommand(this.log, this.pythonExecutable, ['--version'], undefined, true);
|
|
@@ -178,7 +113,7 @@ class PythonChecker {
|
|
|
178
113
|
}
|
|
179
114
|
async getVenvPipVersion() {
|
|
180
115
|
const [version] = await runCommand(this.log, this.venvPipExecutable, ['--version'], undefined, true);
|
|
181
|
-
return version.trim().
|
|
116
|
+
return version.trim().split(' ')[1];
|
|
182
117
|
}
|
|
183
118
|
async getMostRecentPipVersion() {
|
|
184
119
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pythonChecker.js","sourceRoot":"","sources":["../../src/python/pythonChecker.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pythonChecker.js","sourceRoot":"","sources":["../../src/python/pythonChecker.ts"],"names":[],"mappings":"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"}
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,30 +1,15 @@
|
|
|
1
1
|
import type { Characteristic, Logger, Logging, Service, WithUUID } from 'homebridge';
|
|
2
|
-
import { SpawnOptionsWithoutStdio } from 'child_process';
|
|
3
|
-
import type { Plug, Powerstrip } from './devices/kasaDevices.js';
|
|
4
|
-
export type KasaDevice = Plug | Powerstrip;
|
|
5
|
-
export declare function isObjectLike(candidate: unknown): candidate is Record<string, unknown>;
|
|
6
|
-
/**
|
|
7
|
-
* Creates a function that will "batch" calls that are within the `timeout`
|
|
8
|
-
*
|
|
9
|
-
* The first time the function that is created is called, it will wait the `timeout` for additional calls.
|
|
10
|
-
* After the `timeout` expires the result of one execution of `fn` will be resolved to all calls during the `timeout`.
|
|
11
|
-
*
|
|
12
|
-
* If `runNowFn` is specified it will be run synchronously without a timeout. Useful for functions that are used to set rather than get.
|
|
13
|
-
*
|
|
14
|
-
* @param {() => Promise<T>} fn
|
|
15
|
-
* @param {number} timeout (ms)
|
|
16
|
-
* @param {(arg: U) => void} [runNowFn]
|
|
17
|
-
* @returns {(arg?: U) => Promise<T>}
|
|
18
|
-
*/
|
|
2
|
+
import { ChildProcessWithoutNullStreams, SpawnOptionsWithoutStdio } from 'node:child_process';
|
|
19
3
|
export declare function deferAndCombine<T, U>(fn: (requestCount: number) => Promise<T>, timeout: number, runNowFn?: (arg: U) => void): (arg?: U) => Promise<T>;
|
|
20
4
|
export declare function delay(ms: number): Promise<void>;
|
|
21
5
|
export declare function getOrAddCharacteristic(service: Service, characteristic: WithUUID<new () => Characteristic>): Characteristic;
|
|
22
6
|
export declare function hasCharacteristic(characteristics: Array<Characteristic>, characteristic: WithUUID<{
|
|
23
7
|
new (): Characteristic;
|
|
24
8
|
}>): boolean;
|
|
9
|
+
export declare function isObjectLike(candidate: unknown): candidate is Record<string, unknown>;
|
|
25
10
|
export declare function kelvinToMired(kelvin: number): number;
|
|
26
11
|
export declare function lookup<T>(object: unknown, compareFn: undefined | ((objectProp: unknown, search: T) => boolean), value: T): string | undefined;
|
|
27
12
|
export declare function lookupCharacteristicNameByUUID(characteristic: typeof Characteristic, uuid: string): string | undefined;
|
|
28
13
|
export declare function miredToKelvin(mired: number): number;
|
|
29
|
-
export declare function runCommand(logger: Logger, command: string, args?: readonly string[], options?: SpawnOptionsWithoutStdio, hideStdout?: boolean, hideStderr?: boolean): Promise<[string, string, number | null]>;
|
|
30
14
|
export declare function prefixLogger(logger: Logger, prefix: string | (() => string)): Logging;
|
|
15
|
+
export declare function runCommand(logger: Logger, command: string, args?: readonly string[], options?: SpawnOptionsWithoutStdio, hideStdout?: boolean, hideStderr?: boolean, returnProcess?: boolean): Promise<[string, string, number | null, (ChildProcessWithoutNullStreams | null)?]>;
|
package/dist/utils.js
CHANGED
|
@@ -1,49 +1,25 @@
|
|
|
1
|
-
import { spawn } from 'child_process';
|
|
2
|
-
import { writeFile } from 'fs/promises';
|
|
3
|
-
export function isObjectLike(candidate) {
|
|
4
|
-
return ((typeof candidate === 'object' && candidate !== null) ||
|
|
5
|
-
typeof candidate === 'function');
|
|
6
|
-
}
|
|
7
|
-
/**
|
|
8
|
-
* Creates a function that will "batch" calls that are within the `timeout`
|
|
9
|
-
*
|
|
10
|
-
* The first time the function that is created is called, it will wait the `timeout` for additional calls.
|
|
11
|
-
* After the `timeout` expires the result of one execution of `fn` will be resolved to all calls during the `timeout`.
|
|
12
|
-
*
|
|
13
|
-
* If `runNowFn` is specified it will be run synchronously without a timeout. Useful for functions that are used to set rather than get.
|
|
14
|
-
*
|
|
15
|
-
* @param {() => Promise<T>} fn
|
|
16
|
-
* @param {number} timeout (ms)
|
|
17
|
-
* @param {(arg: U) => void} [runNowFn]
|
|
18
|
-
* @returns {(arg?: U) => Promise<T>}
|
|
19
|
-
*/
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { writeFile } from 'node:fs/promises';
|
|
20
3
|
export function deferAndCombine(fn, timeout, runNowFn) {
|
|
21
|
-
|
|
22
|
-
let
|
|
4
|
+
let requests = [];
|
|
5
|
+
let timer = null;
|
|
6
|
+
const processRequests = () => {
|
|
7
|
+
const currentRequests = requests;
|
|
8
|
+
requests = [];
|
|
9
|
+
fn(currentRequests.length)
|
|
10
|
+
.then(value => currentRequests.forEach(req => req.resolve(value)))
|
|
11
|
+
.catch(error => currentRequests.forEach(req => req.reject(error)))
|
|
12
|
+
.finally(() => timer = null);
|
|
13
|
+
};
|
|
23
14
|
return (arg) => {
|
|
24
|
-
if (runNowFn
|
|
15
|
+
if (runNowFn && arg !== undefined) {
|
|
25
16
|
runNowFn(arg);
|
|
26
17
|
}
|
|
27
18
|
return new Promise((resolve, reject) => {
|
|
28
19
|
requests.push({ resolve, reject });
|
|
29
|
-
if (
|
|
30
|
-
|
|
20
|
+
if (!timer) {
|
|
21
|
+
timer = setTimeout(processRequests, timeout);
|
|
31
22
|
}
|
|
32
|
-
isWaiting = true;
|
|
33
|
-
setTimeout(() => {
|
|
34
|
-
isWaiting = false;
|
|
35
|
-
fn(requests.length)
|
|
36
|
-
.then((value) => {
|
|
37
|
-
for (const d of requests) {
|
|
38
|
-
d.resolve(value);
|
|
39
|
-
}
|
|
40
|
-
})
|
|
41
|
-
.catch((error) => {
|
|
42
|
-
for (const d of requests) {
|
|
43
|
-
d.reject(error);
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
}, timeout);
|
|
47
23
|
});
|
|
48
24
|
};
|
|
49
25
|
}
|
|
@@ -53,120 +29,100 @@ export function delay(ms) {
|
|
|
53
29
|
});
|
|
54
30
|
}
|
|
55
31
|
export function getOrAddCharacteristic(service, characteristic) {
|
|
56
|
-
|
|
57
|
-
|
|
32
|
+
const allCharacteristics = service.characteristics.concat(service.optionalCharacteristics);
|
|
33
|
+
if (!hasCharacteristic(allCharacteristics, characteristic)) {
|
|
58
34
|
service.addOptionalCharacteristic(characteristic);
|
|
59
35
|
}
|
|
60
|
-
return
|
|
61
|
-
service.addCharacteristic(characteristic));
|
|
36
|
+
return service.getCharacteristic(characteristic) || service.addCharacteristic(characteristic);
|
|
62
37
|
}
|
|
63
38
|
export function hasCharacteristic(characteristics, characteristic) {
|
|
64
|
-
return
|
|
65
|
-
|
|
66
|
-
|
|
39
|
+
return characteristics.some((char) => char instanceof characteristic ||
|
|
40
|
+
char.UUID === characteristic.UUID);
|
|
41
|
+
}
|
|
42
|
+
export function isObjectLike(candidate) {
|
|
43
|
+
return typeof candidate === 'object' && candidate !== null || typeof candidate === 'function';
|
|
67
44
|
}
|
|
68
45
|
export function kelvinToMired(kelvin) {
|
|
69
46
|
return 1e6 / kelvin;
|
|
70
47
|
}
|
|
71
48
|
export function lookup(object, compareFn, value) {
|
|
72
|
-
const compare = compareFn ??
|
|
73
|
-
((objectProp, search) => objectProp === search);
|
|
49
|
+
const compare = compareFn ?? ((objectProp, search) => objectProp === search);
|
|
74
50
|
if (isObjectLike(object)) {
|
|
75
|
-
|
|
76
|
-
for (let i = 0; i < keys.length; i += 1) {
|
|
77
|
-
if (compare(object[keys[i]], value)) {
|
|
78
|
-
return keys[i];
|
|
79
|
-
}
|
|
80
|
-
}
|
|
51
|
+
return Object.keys(object).find(key => compare(object[key], value));
|
|
81
52
|
}
|
|
82
53
|
return undefined;
|
|
83
54
|
}
|
|
84
55
|
export function lookupCharacteristicNameByUUID(characteristic, uuid) {
|
|
85
|
-
|
|
86
|
-
for (let i = 0; i < keys.length; i += 1) {
|
|
87
|
-
const key = keys[i];
|
|
88
|
-
// @ts-expect-error: not sure how to make this correct in typescript
|
|
89
|
-
const c = characteristic[key];
|
|
90
|
-
if ('UUID' in c && c.UUID === uuid) {
|
|
91
|
-
return key;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
return undefined;
|
|
56
|
+
return Object.keys(characteristic).find(key => (characteristic[key].UUID === uuid));
|
|
95
57
|
}
|
|
96
58
|
export function miredToKelvin(mired) {
|
|
97
59
|
return 1e6 / mired;
|
|
98
60
|
}
|
|
99
|
-
export
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
if (arg.startsWith('>')) {
|
|
108
|
-
redirectOutputToFile = true;
|
|
109
|
-
outputFile = arg.substring(1).trim();
|
|
110
|
-
break;
|
|
61
|
+
export function prefixLogger(logger, prefix) {
|
|
62
|
+
const methods = ['info', 'warn', 'error', 'debug', 'log'];
|
|
63
|
+
const clonedLogger = methods.reduce((acc, method) => {
|
|
64
|
+
acc[method] = (...args) => {
|
|
65
|
+
const prefixString = typeof prefix === 'function' ? prefix() : prefix;
|
|
66
|
+
if (method === 'log') {
|
|
67
|
+
const [level, message, ...parameters] = args;
|
|
68
|
+
logger[method](level, `${prefixString} ${message}`, ...parameters);
|
|
111
69
|
}
|
|
112
70
|
else {
|
|
113
|
-
|
|
71
|
+
const [message, ...parameters] = args;
|
|
72
|
+
logger[method](`${prefixString} ${message}`, ...parameters);
|
|
114
73
|
}
|
|
74
|
+
};
|
|
75
|
+
return acc;
|
|
76
|
+
}, {});
|
|
77
|
+
clonedLogger.prefix = typeof logger.prefix === 'string' ? `${prefix} ${logger.prefix}` : prefix;
|
|
78
|
+
return clonedLogger;
|
|
79
|
+
}
|
|
80
|
+
export async function runCommand(logger, command, args = [], options, hideStdout = false, hideStderr = false, returnProcess = false) {
|
|
81
|
+
let stdout = '';
|
|
82
|
+
let stderr = '';
|
|
83
|
+
let outputFile = null;
|
|
84
|
+
const filteredArgs = args.filter(arg => {
|
|
85
|
+
if (arg.startsWith('>')) {
|
|
86
|
+
outputFile = arg.substring(1).trim();
|
|
87
|
+
return false;
|
|
115
88
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
logger.debug(`Running command: ${command} ${args?.join(' ')}`);
|
|
121
|
-
const p = spawn(command, args, options);
|
|
89
|
+
return true;
|
|
90
|
+
});
|
|
91
|
+
logger.debug(`Running command: ${command} ${filteredArgs.join(' ')}`);
|
|
92
|
+
const p = spawn(command, filteredArgs, options);
|
|
122
93
|
logger.debug(`Command PID: ${p.pid}`);
|
|
123
|
-
p.stdout.setEncoding('utf8')
|
|
124
|
-
p.stdout.on('data', (data) => {
|
|
94
|
+
p.stdout.setEncoding('utf8').on('data', data => {
|
|
125
95
|
stdout += data;
|
|
126
96
|
if (!hideStdout) {
|
|
127
97
|
logger.info(data.trim());
|
|
128
98
|
}
|
|
129
99
|
});
|
|
130
|
-
p.stderr.setEncoding('utf8')
|
|
131
|
-
p.stderr.on('data', (data) => {
|
|
100
|
+
p.stderr.setEncoding('utf8').on('data', data => {
|
|
132
101
|
stderr += data;
|
|
133
102
|
if (!hideStderr) {
|
|
134
|
-
|
|
135
|
-
logger.warn(data.trim());
|
|
136
|
-
}
|
|
137
|
-
else {
|
|
138
|
-
logger.error(data.trim());
|
|
139
|
-
}
|
|
103
|
+
logger[data.startsWith('WARNING') ? 'warn' : 'error'](data.trim());
|
|
140
104
|
}
|
|
141
105
|
});
|
|
106
|
+
if (returnProcess) {
|
|
107
|
+
logger.debug('Command started.');
|
|
108
|
+
const stderrReady = new Promise((resolve) => {
|
|
109
|
+
p.stderr.once('data', () => {
|
|
110
|
+
resolve();
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
await stderrReady;
|
|
114
|
+
return [stdout, stderr, null, p];
|
|
115
|
+
}
|
|
142
116
|
const exitCode = await new Promise((resolve, reject) => {
|
|
143
|
-
p.on('close', resolve);
|
|
144
|
-
p.on('error', reject);
|
|
117
|
+
p.on('close', resolve).on('error', reject);
|
|
145
118
|
});
|
|
146
|
-
|
|
119
|
+
p.stdout.destroy();
|
|
120
|
+
p.stderr.destroy();
|
|
121
|
+
p.kill();
|
|
122
|
+
if (outputFile) {
|
|
147
123
|
await writeFile(outputFile, stdout);
|
|
148
124
|
}
|
|
149
125
|
logger.debug('Command finished.');
|
|
150
126
|
return [stdout, stderr, exitCode];
|
|
151
127
|
}
|
|
152
|
-
function cloneLogger(logger) {
|
|
153
|
-
// @ts-expect-error this doesn't work on function types
|
|
154
|
-
const clonedLogger = logger.info.bind(logger);
|
|
155
|
-
clonedLogger.info = logger.info;
|
|
156
|
-
clonedLogger.warn = logger.warn;
|
|
157
|
-
clonedLogger.error = logger.error;
|
|
158
|
-
clonedLogger.debug = logger.debug;
|
|
159
|
-
clonedLogger.log = logger.log;
|
|
160
|
-
clonedLogger.prefix = logger.prefix;
|
|
161
|
-
return clonedLogger;
|
|
162
|
-
}
|
|
163
|
-
export function prefixLogger(logger, prefix) {
|
|
164
|
-
const newLogger = cloneLogger(logger);
|
|
165
|
-
const origLog = logger.log.bind(newLogger);
|
|
166
|
-
newLogger.log = function log(level, message, ...parameters) {
|
|
167
|
-
const prefixEval = prefix instanceof Function ? prefix() : prefix;
|
|
168
|
-
origLog(level, `${prefixEval} ${message}`, ...parameters);
|
|
169
|
-
};
|
|
170
|
-
return newLogger;
|
|
171
|
-
}
|
|
172
128
|
//# sourceMappingURL=utils.js.map
|
package/dist/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AASA,OAAO,EAAkC,KAAK,EAA4B,MAAM,
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"displayName": "Homebridge Kasa Python",
|
|
3
3
|
"name": "homebridge-kasa-python",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "2.0.0",
|
|
5
5
|
"description": "Plugin that uses Python-Kasa API to communicate with Kasa Devices.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"type": "module",
|
|
@@ -13,15 +13,15 @@
|
|
|
13
13
|
"url": "https://github.com/ZeliardM/homebridge-kasa-python/issues"
|
|
14
14
|
},
|
|
15
15
|
"engines": {
|
|
16
|
-
"node": "^18.
|
|
17
|
-
"homebridge": "^1.8.0",
|
|
16
|
+
"node": "^18.20.4 || ^20.16.0 || ^22.6.0",
|
|
17
|
+
"homebridge": "^1.8.0 || ^2.0.0-beta.0",
|
|
18
18
|
"python": "^3.9.0"
|
|
19
19
|
},
|
|
20
20
|
"main": "dist/index.js",
|
|
21
21
|
"scripts": {
|
|
22
22
|
"lint": "eslint src/**/*.ts --max-warnings=0",
|
|
23
23
|
"watch": "npm run build && npm link && nodemon",
|
|
24
|
-
"build": "npm ci && rimraf -I ./dist && npm run lint && tsc && cp ./src/python/*.py ./dist/python",
|
|
24
|
+
"build": "npm ci && rimraf -I ./dist && npm run lint && tsc && shx cp ./src/python/*.py ./dist/python",
|
|
25
25
|
"prepublishOnly": "npm run lint && npm run build"
|
|
26
26
|
},
|
|
27
27
|
"keywords": [
|
|
@@ -46,17 +46,22 @@
|
|
|
46
46
|
"requirements.txt"
|
|
47
47
|
],
|
|
48
48
|
"devDependencies": {
|
|
49
|
+
"@eslint/eslintrc": "^3.1.0",
|
|
50
|
+
"@eslint/js": "^9.9.0",
|
|
51
|
+
"@stylistic/eslint-plugin": "^2.6.2",
|
|
49
52
|
"@types/lodash.defaults": "^4.2.9",
|
|
50
|
-
"@types/node": "^
|
|
53
|
+
"@types/node": "^22.2.0",
|
|
51
54
|
"@types/semver": "^7.5.8",
|
|
52
|
-
"@typescript-eslint/
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"homebridge": "^
|
|
56
|
-
"nodemon": "^3.1.
|
|
57
|
-
"rimraf": "^
|
|
55
|
+
"@typescript-eslint/parser": "^8.0.1",
|
|
56
|
+
"eslint": "^9.9.0",
|
|
57
|
+
"globals": "^15.9.0",
|
|
58
|
+
"homebridge": "^2.0.0-beta.11",
|
|
59
|
+
"nodemon": "^3.1.4",
|
|
60
|
+
"rimraf": "^6.0.1",
|
|
61
|
+
"shx": "^0.3.4",
|
|
58
62
|
"ts-node": "^10.9.2",
|
|
59
|
-
"typescript": "^5.4
|
|
63
|
+
"typescript": "^5.5.4",
|
|
64
|
+
"typescript-eslint": "^8.0.1"
|
|
60
65
|
},
|
|
61
66
|
"homepage": "https://github.com/ZeliardM/homebridge-kasa-python#readme",
|
|
62
67
|
"funding": [
|
|
@@ -70,17 +75,13 @@
|
|
|
70
75
|
}
|
|
71
76
|
],
|
|
72
77
|
"dependencies": {
|
|
73
|
-
"ajv": "^8.
|
|
78
|
+
"ajv": "^8.17.1",
|
|
74
79
|
"ajv-formats": "^3.0.1",
|
|
75
|
-
"axios": "^1.7.
|
|
76
|
-
"
|
|
77
|
-
"child_process": "^1.0.2",
|
|
78
|
-
"fs": "^0.0.1-security",
|
|
80
|
+
"axios": "^1.7.3",
|
|
81
|
+
"get-port": "^7.1.0",
|
|
79
82
|
"lodash.defaults": "^4.2.0",
|
|
80
|
-
"path": "^0.12.7",
|
|
81
83
|
"semver": "^7.6.3",
|
|
82
84
|
"ts-essentials": "^10.0.1",
|
|
83
|
-
"url": "^0.11.3",
|
|
84
85
|
"util": "^0.12.5"
|
|
85
86
|
}
|
|
86
87
|
}
|