@mp-consulting/homebridge-lg-thinq 1.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/.claude/settings.local.json +15 -0
- package/CHANGELOG.md +98 -0
- package/LICENSE +176 -0
- package/README.md +114 -0
- package/config.schema.json +399 -0
- package/dist/__tests__/baseDevice.spec.d.ts +1 -0
- package/dist/__tests__/baseDevice.spec.js +96 -0
- package/dist/__tests__/baseDevice.spec.js.map +1 -0
- package/dist/__tests__/deviceControl.coercion.spec.d.ts +1 -0
- package/dist/__tests__/deviceControl.coercion.spec.js +53 -0
- package/dist/__tests__/deviceControl.coercion.spec.js.map +1 -0
- package/dist/__tests__/helper.spec.d.ts +1 -0
- package/dist/__tests__/helper.spec.js +74 -0
- package/dist/__tests__/helper.spec.js.map +1 -0
- package/dist/baseDevice.d.ts +40 -0
- package/dist/baseDevice.js +85 -0
- package/dist/baseDevice.js.map +1 -0
- package/dist/baseDevice.spec.d.ts +1 -0
- package/dist/baseDevice.spec.js +107 -0
- package/dist/baseDevice.spec.js.map +1 -0
- package/dist/characteristics/TotalConsumption.d.ts +2 -0
- package/dist/characteristics/TotalConsumption.js +17 -0
- package/dist/characteristics/TotalConsumption.js.map +1 -0
- package/dist/characteristics/index.d.ts +2 -0
- package/dist/characteristics/index.js +7 -0
- package/dist/characteristics/index.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +89 -0
- package/dist/cli.js.map +1 -0
- package/dist/devices/AeroTower.d.ts +24 -0
- package/dist/devices/AeroTower.js +113 -0
- package/dist/devices/AeroTower.js.map +1 -0
- package/dist/devices/AirConditioner.d.ts +425 -0
- package/dist/devices/AirConditioner.js +1253 -0
- package/dist/devices/AirConditioner.js.map +1 -0
- package/dist/devices/AirPurifier.d.ts +50 -0
- package/dist/devices/AirPurifier.js +281 -0
- package/dist/devices/AirPurifier.js.map +1 -0
- package/dist/devices/Dehumidifier.d.ts +28 -0
- package/dist/devices/Dehumidifier.js +175 -0
- package/dist/devices/Dehumidifier.js.map +1 -0
- package/dist/devices/Dishwasher.d.ts +64 -0
- package/dist/devices/Dishwasher.js +740 -0
- package/dist/devices/Dishwasher.js.map +1 -0
- package/dist/devices/Microwave.d.ts +128 -0
- package/dist/devices/Microwave.js +1939 -0
- package/dist/devices/Microwave.js.map +1 -0
- package/dist/devices/Oven.d.ts +148 -0
- package/dist/devices/Oven.js +1850 -0
- package/dist/devices/Oven.js.map +1 -0
- package/dist/devices/RangeHood.d.ts +16 -0
- package/dist/devices/RangeHood.js +99 -0
- package/dist/devices/RangeHood.js.map +1 -0
- package/dist/devices/Refrigerator.d.ts +50 -0
- package/dist/devices/Refrigerator.js +325 -0
- package/dist/devices/Refrigerator.js.map +1 -0
- package/dist/devices/Styler.d.ts +27 -0
- package/dist/devices/Styler.js +76 -0
- package/dist/devices/Styler.js.map +1 -0
- package/dist/devices/WasherDryer.d.ts +39 -0
- package/dist/devices/WasherDryer.js +170 -0
- package/dist/devices/WasherDryer.js.map +1 -0
- package/dist/devices/WasherDryer2.d.ts +9 -0
- package/dist/devices/WasherDryer2.js +16 -0
- package/dist/devices/WasherDryer2.js.map +1 -0
- package/dist/errors/AuthenticationError.d.ts +2 -0
- package/dist/errors/AuthenticationError.js +3 -0
- package/dist/errors/AuthenticationError.js.map +1 -0
- package/dist/errors/ManualProcessNeeded.d.ts +3 -0
- package/dist/errors/ManualProcessNeeded.js +4 -0
- package/dist/errors/ManualProcessNeeded.js.map +1 -0
- package/dist/errors/MonitorError.d.ts +2 -0
- package/dist/errors/MonitorError.js +3 -0
- package/dist/errors/MonitorError.js.map +1 -0
- package/dist/errors/NotConnectedError.d.ts +3 -0
- package/dist/errors/NotConnectedError.js +4 -0
- package/dist/errors/NotConnectedError.js.map +1 -0
- package/dist/errors/TokenError.d.ts +2 -0
- package/dist/errors/TokenError.js +3 -0
- package/dist/errors/TokenError.js.map +1 -0
- package/dist/errors/TokenExpiredError.d.ts +3 -0
- package/dist/errors/TokenExpiredError.js +4 -0
- package/dist/errors/TokenExpiredError.js.map +1 -0
- package/dist/errors/index.d.ts +6 -0
- package/dist/errors/index.js +7 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/helper.d.ts +24 -0
- package/dist/helper.js +66 -0
- package/dist/helper.js.map +1 -0
- package/dist/helper.spec.d.ts +1 -0
- package/dist/helper.spec.js +74 -0
- package/dist/helper.spec.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/API.d.ts +141 -0
- package/dist/lib/API.js +362 -0
- package/dist/lib/API.js.map +1 -0
- package/dist/lib/API.spec.d.ts +1 -0
- package/dist/lib/API.spec.js +55 -0
- package/dist/lib/API.spec.js.map +1 -0
- package/dist/lib/Auth.d.ts +99 -0
- package/dist/lib/Auth.js +348 -0
- package/dist/lib/Auth.js.map +1 -0
- package/dist/lib/Auth.spec.d.ts +1 -0
- package/dist/lib/Auth.spec.js +111 -0
- package/dist/lib/Auth.spec.js.map +1 -0
- package/dist/lib/Device.d.ts +88 -0
- package/dist/lib/Device.js +95 -0
- package/dist/lib/Device.js.map +1 -0
- package/dist/lib/Device.spec.d.ts +1 -0
- package/dist/lib/Device.spec.js +53 -0
- package/dist/lib/Device.spec.js.map +1 -0
- package/dist/lib/DeviceModel.d.ts +164 -0
- package/dist/lib/DeviceModel.js +321 -0
- package/dist/lib/DeviceModel.js.map +1 -0
- package/dist/lib/DeviceModel.spec.d.ts +1 -0
- package/dist/lib/DeviceModel.spec.js +90 -0
- package/dist/lib/DeviceModel.spec.js.map +1 -0
- package/dist/lib/Gateway.d.ts +18 -0
- package/dist/lib/Gateway.js +25 -0
- package/dist/lib/Gateway.js.map +1 -0
- package/dist/lib/Gateway.spec.d.ts +1 -0
- package/dist/lib/Gateway.spec.js +35 -0
- package/dist/lib/Gateway.spec.js.map +1 -0
- package/dist/lib/Persist.d.ts +101 -0
- package/dist/lib/Persist.js +245 -0
- package/dist/lib/Persist.js.map +1 -0
- package/dist/lib/Persist.spec.d.ts +1 -0
- package/dist/lib/Persist.spec.js +90 -0
- package/dist/lib/Persist.spec.js.map +1 -0
- package/dist/lib/Session.d.ts +80 -0
- package/dist/lib/Session.js +100 -0
- package/dist/lib/Session.js.map +1 -0
- package/dist/lib/Session.spec.d.ts +1 -0
- package/dist/lib/Session.spec.js +43 -0
- package/dist/lib/Session.spec.js.map +1 -0
- package/dist/lib/ThinQ.d.ts +28 -0
- package/dist/lib/ThinQ.js +373 -0
- package/dist/lib/ThinQ.js.map +1 -0
- package/dist/lib/__tests__/API.spec.d.ts +1 -0
- package/dist/lib/__tests__/API.spec.js +55 -0
- package/dist/lib/__tests__/API.spec.js.map +1 -0
- package/dist/lib/__tests__/Auth.spec.d.ts +1 -0
- package/dist/lib/__tests__/Auth.spec.js +110 -0
- package/dist/lib/__tests__/Auth.spec.js.map +1 -0
- package/dist/lib/__tests__/Device.spec.d.ts +1 -0
- package/dist/lib/__tests__/Device.spec.js +53 -0
- package/dist/lib/__tests__/Device.spec.js.map +1 -0
- package/dist/lib/__tests__/DeviceModel.spec.d.ts +1 -0
- package/dist/lib/__tests__/DeviceModel.spec.js +90 -0
- package/dist/lib/__tests__/DeviceModel.spec.js.map +1 -0
- package/dist/lib/__tests__/Gateway.spec.d.ts +1 -0
- package/dist/lib/__tests__/Gateway.spec.js +35 -0
- package/dist/lib/__tests__/Gateway.spec.js.map +1 -0
- package/dist/lib/__tests__/Persist.spec.d.ts +1 -0
- package/dist/lib/__tests__/Persist.spec.js +90 -0
- package/dist/lib/__tests__/Persist.spec.js.map +1 -0
- package/dist/lib/__tests__/Session.spec.d.ts +1 -0
- package/dist/lib/__tests__/Session.spec.js +43 -0
- package/dist/lib/__tests__/Session.spec.js.map +1 -0
- package/dist/lib/constants.d.ts +95 -0
- package/dist/lib/constants.js +106 -0
- package/dist/lib/constants.js.map +1 -0
- package/dist/lib/request.d.ts +2 -0
- package/dist/lib/request.js +66 -0
- package/dist/lib/request.js.map +1 -0
- package/dist/platform.d.ts +41 -0
- package/dist/platform.js +229 -0
- package/dist/platform.js.map +1 -0
- package/dist/settings.d.ts +8 -0
- package/dist/settings.js +9 -0
- package/dist/settings.js.map +1 -0
- package/dist/status/BaseStatus.d.ts +48 -0
- package/dist/status/BaseStatus.js +59 -0
- package/dist/status/BaseStatus.js.map +1 -0
- package/dist/types/snapshots.d.ts +142 -0
- package/dist/types/snapshots.js +6 -0
- package/dist/types/snapshots.js.map +1 -0
- package/dist/utils/__tests__/normalize.spec.d.ts +1 -0
- package/dist/utils/__tests__/normalize.spec.js +95 -0
- package/dist/utils/__tests__/normalize.spec.js.map +1 -0
- package/dist/utils/normalize.d.ts +22 -0
- package/dist/utils/normalize.js +51 -0
- package/dist/utils/normalize.js.map +1 -0
- package/dist/v1/__tests__/prepareControlData.spec.d.ts +1 -0
- package/dist/v1/__tests__/prepareControlData.spec.js +48 -0
- package/dist/v1/__tests__/prepareControlData.spec.js.map +1 -0
- package/dist/v1/devices/AC.d.ts +13 -0
- package/dist/v1/devices/AC.js +112 -0
- package/dist/v1/devices/AC.js.map +1 -0
- package/dist/v1/devices/AirPurifier.d.ts +15 -0
- package/dist/v1/devices/AirPurifier.js +57 -0
- package/dist/v1/devices/AirPurifier.js.map +1 -0
- package/dist/v1/devices/RangeHood.d.ts +6 -0
- package/dist/v1/devices/RangeHood.js +12 -0
- package/dist/v1/devices/RangeHood.js.map +1 -0
- package/dist/v1/devices/Refrigerator.d.ts +17 -0
- package/dist/v1/devices/Refrigerator.js +69 -0
- package/dist/v1/devices/Refrigerator.js.map +1 -0
- package/dist/v1/devices/Washer.d.ts +10 -0
- package/dist/v1/devices/Washer.js +23 -0
- package/dist/v1/devices/Washer.js.map +1 -0
- package/dist/v1/devices/index.d.ts +6 -0
- package/dist/v1/devices/index.js +7 -0
- package/dist/v1/devices/index.js.map +1 -0
- package/dist/v1/helper.d.ts +14 -0
- package/dist/v1/helper.js +111 -0
- package/dist/v1/helper.js.map +1 -0
- package/dist/v1/transforms/AirPurifierState.d.ts +2 -0
- package/dist/v1/transforms/AirPurifierState.js +9 -0
- package/dist/v1/transforms/AirPurifierState.js.map +1 -0
- package/dist/v1/transforms/AirState.d.ts +9 -0
- package/dist/v1/transforms/AirState.js +55 -0
- package/dist/v1/transforms/AirState.js.map +1 -0
- package/dist/v1/transforms/HoodState.d.ts +17 -0
- package/dist/v1/transforms/HoodState.js +20 -0
- package/dist/v1/transforms/HoodState.js.map +1 -0
- package/dist/v1/transforms/RefState.d.ts +6 -0
- package/dist/v1/transforms/RefState.js +29 -0
- package/dist/v1/transforms/RefState.js.map +1 -0
- package/dist/v1/transforms/WasherDryer.d.ts +49 -0
- package/dist/v1/transforms/WasherDryer.js +56 -0
- package/dist/v1/transforms/WasherDryer.js.map +1 -0
- package/docs/authorization.md +40 -0
- package/docs/device-configuration.md +68 -0
- package/homebridge-ui/public/index.html +120 -0
- package/homebridge-ui/public/js/app.js +300 -0
- package/homebridge-ui/public/js/countries.js +233 -0
- package/homebridge-ui/public/styles.css +185 -0
- package/homebridge-ui/server.js +103 -0
- package/jest.config.ts +39 -0
- package/package.json +83 -0
- package/sample/README.md +10 -0
- package/sample/airconditioner-model.json +3080 -0
- package/sample/airconditioner-snapshot.json +49 -0
- package/sample/airconditioner.json +157 -0
- package/sample/dishwasher-model.json +869 -0
- package/sample/dishwasher.json +125 -0
- package/sample/washer_dryer-model.json +1294 -0
- package/sample/washer_dryer.json +126 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { LGThinQHomebridgePlatform } from './platform.js';
|
|
2
|
+
import { Logger, PlatformAccessory, Service, WithUUID } from 'homebridge';
|
|
3
|
+
import { Device } from './lib/Device.js';
|
|
4
|
+
import { EventEmitter } from 'events';
|
|
5
|
+
type ServiceConstructor = WithUUID<typeof Service>;
|
|
6
|
+
export interface DeviceControlPayload {
|
|
7
|
+
dataKey: string | null;
|
|
8
|
+
dataValue: unknown;
|
|
9
|
+
dataSetList?: Record<string, unknown> | null;
|
|
10
|
+
dataGetList?: Record<string, unknown> | null;
|
|
11
|
+
}
|
|
12
|
+
export type AccessoryContext = {
|
|
13
|
+
device: Device;
|
|
14
|
+
};
|
|
15
|
+
export declare class BaseDevice extends EventEmitter {
|
|
16
|
+
readonly platform: LGThinQHomebridgePlatform;
|
|
17
|
+
readonly accessory: PlatformAccessory<AccessoryContext>;
|
|
18
|
+
protected readonly logger: Logger;
|
|
19
|
+
constructor(platform: LGThinQHomebridgePlatform, accessory: PlatformAccessory<AccessoryContext>, logger: Logger);
|
|
20
|
+
updateAccessoryCharacteristic(device: Device): void;
|
|
21
|
+
update(snapshot: any): void;
|
|
22
|
+
get config(): Record<string, any>;
|
|
23
|
+
/**
|
|
24
|
+
* Helper method to safely control a device with error handling.
|
|
25
|
+
* Wraps ThinQ deviceControl with try/catch and returns success/failure.
|
|
26
|
+
*/
|
|
27
|
+
protected controlDevice(payload: DeviceControlPayload, onSuccess?: () => void): Promise<boolean>;
|
|
28
|
+
/**
|
|
29
|
+
* Get or create a service with the given type and name.
|
|
30
|
+
* Automatically adds ConfiguredName characteristic.
|
|
31
|
+
*/
|
|
32
|
+
protected getOrCreateService(serviceType: ServiceConstructor, name: string, subType?: string): Service;
|
|
33
|
+
/**
|
|
34
|
+
* Conditionally create or remove a service based on a boolean flag.
|
|
35
|
+
* Returns the service if enabled, undefined if disabled.
|
|
36
|
+
*/
|
|
37
|
+
protected ensureService(serviceType: ServiceConstructor, name: string, enabled: boolean, subType?: string): Service | undefined;
|
|
38
|
+
static model(): string;
|
|
39
|
+
}
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
export class BaseDevice extends EventEmitter {
|
|
3
|
+
platform;
|
|
4
|
+
accessory;
|
|
5
|
+
logger;
|
|
6
|
+
constructor(platform, accessory, logger) {
|
|
7
|
+
super();
|
|
8
|
+
this.platform = platform;
|
|
9
|
+
this.accessory = accessory;
|
|
10
|
+
this.logger = logger;
|
|
11
|
+
const device = accessory.context.device;
|
|
12
|
+
const { AccessoryInformation } = this.platform.Service;
|
|
13
|
+
const serviceAccessoryInformation = accessory.getService(AccessoryInformation) || accessory.addService(AccessoryInformation);
|
|
14
|
+
// set accessory information
|
|
15
|
+
serviceAccessoryInformation
|
|
16
|
+
.setCharacteristic(this.platform.Characteristic.Manufacturer, 'LG')
|
|
17
|
+
.setCharacteristic(this.platform.Characteristic.Model, device.salesModel || device.model || 'Unknown')
|
|
18
|
+
.setCharacteristic(this.platform.Characteristic.SerialNumber, this.config.serial_number || device.serialNumber || 'Unknown');
|
|
19
|
+
}
|
|
20
|
+
updateAccessoryCharacteristic(device) {
|
|
21
|
+
this.accessory.context.device = device;
|
|
22
|
+
}
|
|
23
|
+
update(snapshot) {
|
|
24
|
+
this.platform.log.debug('[' + this.accessory.context.device.name + '] Received snapshot: ', JSON.stringify(snapshot));
|
|
25
|
+
this.accessory.context.device.data.snapshot = { ...this.accessory.context.device.snapshot, ...snapshot };
|
|
26
|
+
this.updateAccessoryCharacteristic(this.accessory.context.device);
|
|
27
|
+
}
|
|
28
|
+
get config() {
|
|
29
|
+
return this.platform.config.devices.find((enabled) => enabled.id === this.accessory.context.device.id) || {};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Helper method to safely control a device with error handling.
|
|
33
|
+
* Wraps ThinQ deviceControl with try/catch and returns success/failure.
|
|
34
|
+
*/
|
|
35
|
+
async controlDevice(payload, onSuccess) {
|
|
36
|
+
const device = this.accessory.context.device;
|
|
37
|
+
try {
|
|
38
|
+
const result = await this.platform.ThinQ?.deviceControl(device.id, payload);
|
|
39
|
+
if (result && onSuccess) {
|
|
40
|
+
onSuccess();
|
|
41
|
+
}
|
|
42
|
+
return !!result;
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
this.logger.error(`[${device.name}] Device control failed:`, error);
|
|
46
|
+
throw new this.platform.api.hap.HapStatusError(-70402 /* HAPStatus.SERVICE_COMMUNICATION_FAILURE */);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Get or create a service with the given type and name.
|
|
51
|
+
* Automatically adds ConfiguredName characteristic.
|
|
52
|
+
*/
|
|
53
|
+
getOrCreateService(serviceType, name, subType) {
|
|
54
|
+
const effectiveSubType = subType || name;
|
|
55
|
+
const service = this.accessory.getService(effectiveSubType)
|
|
56
|
+
|| this.accessory.addService(serviceType, name, effectiveSubType);
|
|
57
|
+
// Add ConfiguredName for better HomeKit display
|
|
58
|
+
service.addOptionalCharacteristic(this.platform.Characteristic.ConfiguredName);
|
|
59
|
+
service.updateCharacteristic(this.platform.Characteristic.ConfiguredName, name);
|
|
60
|
+
return service;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Conditionally create or remove a service based on a boolean flag.
|
|
64
|
+
* Returns the service if enabled, undefined if disabled.
|
|
65
|
+
*/
|
|
66
|
+
ensureService(serviceType, name, enabled, subType) {
|
|
67
|
+
const existingService = subType
|
|
68
|
+
? this.accessory.getService(subType)
|
|
69
|
+
: this.accessory.getService(serviceType);
|
|
70
|
+
if (enabled) {
|
|
71
|
+
if (!existingService) {
|
|
72
|
+
return this.getOrCreateService(serviceType, name, subType);
|
|
73
|
+
}
|
|
74
|
+
return existingService;
|
|
75
|
+
}
|
|
76
|
+
else if (existingService) {
|
|
77
|
+
this.accessory.removeService(existingService);
|
|
78
|
+
}
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
static model() {
|
|
82
|
+
return '';
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=baseDevice.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseDevice.js","sourceRoot":"","sources":["../src/baseDevice.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { BaseDevice } from './baseDevice.js';
|
|
2
|
+
import { Device } from './lib/Device.js';
|
|
3
|
+
import { describe, expect, it, jest, beforeEach } from '@jest/globals';
|
|
4
|
+
// Mock dependencies
|
|
5
|
+
jest.mock('./platform.js');
|
|
6
|
+
jest.mock('./lib/Device');
|
|
7
|
+
// Test suite for BaseDevice class
|
|
8
|
+
describe('BaseDevice', () => {
|
|
9
|
+
let platform;
|
|
10
|
+
let accessory;
|
|
11
|
+
let logger;
|
|
12
|
+
let device;
|
|
13
|
+
let baseDevice;
|
|
14
|
+
const mockDeviceData = {
|
|
15
|
+
deviceId: '12345',
|
|
16
|
+
alias: 'Smart Fridge',
|
|
17
|
+
deviceType: 101,
|
|
18
|
+
modelName: 'FR123-US',
|
|
19
|
+
modelJsonUri: 'https://example.com/model.json',
|
|
20
|
+
manufacture: {
|
|
21
|
+
macAddress: '00:1A:2B:3C:4D:5E',
|
|
22
|
+
salesModel: 'FR123',
|
|
23
|
+
serialNo: 'SN123456789',
|
|
24
|
+
manufactureModel: 'FR123-M',
|
|
25
|
+
},
|
|
26
|
+
online: true,
|
|
27
|
+
modemInfo: {
|
|
28
|
+
appVersion: '1.0.0',
|
|
29
|
+
modelName: 'FR123-MODEM',
|
|
30
|
+
},
|
|
31
|
+
snapshot: {
|
|
32
|
+
online: true,
|
|
33
|
+
},
|
|
34
|
+
platformType: 'ThinQ2',
|
|
35
|
+
};
|
|
36
|
+
beforeEach(() => {
|
|
37
|
+
logger = {
|
|
38
|
+
debug: jest.fn(),
|
|
39
|
+
info: jest.fn(),
|
|
40
|
+
warn: jest.fn(),
|
|
41
|
+
error: jest.fn(),
|
|
42
|
+
};
|
|
43
|
+
platform = {
|
|
44
|
+
Service: {
|
|
45
|
+
AccessoryInformation: function AccessoryInformation() { },
|
|
46
|
+
},
|
|
47
|
+
Characteristic: {
|
|
48
|
+
Manufacturer: 'Manufacturer',
|
|
49
|
+
Model: 'Model',
|
|
50
|
+
SerialNumber: 'SerialNumber',
|
|
51
|
+
},
|
|
52
|
+
config: {
|
|
53
|
+
devices: [
|
|
54
|
+
{ id: '12345', customConfig: true },
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
log: logger,
|
|
58
|
+
};
|
|
59
|
+
accessory = {
|
|
60
|
+
context: {
|
|
61
|
+
device: new Device(mockDeviceData),
|
|
62
|
+
},
|
|
63
|
+
getService: jest.fn().mockReturnValue(null),
|
|
64
|
+
addService: jest.fn().mockImplementation(() => ({
|
|
65
|
+
setCharacteristic: jest.fn().mockReturnThis(),
|
|
66
|
+
})),
|
|
67
|
+
};
|
|
68
|
+
device = accessory.context.device;
|
|
69
|
+
});
|
|
70
|
+
it('should set accessory information on initialization', () => {
|
|
71
|
+
baseDevice = new BaseDevice(platform, accessory, logger);
|
|
72
|
+
expect(accessory.addService).toHaveBeenCalled();
|
|
73
|
+
const calledArg = accessory.addService.mock.calls[0][0];
|
|
74
|
+
if (typeof calledArg === 'function') {
|
|
75
|
+
expect(calledArg.name).toBe('AccessoryInformation');
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
expect(calledArg.displayName).toBe('AccessoryInformation');
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
it('should update accessory characteristics', () => {
|
|
82
|
+
baseDevice = new BaseDevice(platform, accessory, logger);
|
|
83
|
+
const newDevice = { ...device, name: 'Updated Device' };
|
|
84
|
+
baseDevice.updateAccessoryCharacteristic(newDevice);
|
|
85
|
+
expect(accessory.context.device).toEqual(newDevice);
|
|
86
|
+
});
|
|
87
|
+
// it('should update device snapshot and accessory characteristics', () => {
|
|
88
|
+
// baseDevice = new BaseDevice(platform, accessory, logger);
|
|
89
|
+
// const snapshot = { key: 'value' };
|
|
90
|
+
// baseDevice.update(snapshot);
|
|
91
|
+
// expect(device.data.snapshot).toEqual({ key: 'value' });
|
|
92
|
+
// expect(accessory.context.device).toEqual(device);
|
|
93
|
+
// });
|
|
94
|
+
// it('should return the correct configuration for the device', () => {
|
|
95
|
+
// baseDevice = new BaseDevice(platform, accessory, logger);
|
|
96
|
+
// expect(baseDevice.config).toEqual({ id: '12345', customConfig: true });
|
|
97
|
+
// });
|
|
98
|
+
it('should return an empty object if no configuration is found for the device', () => {
|
|
99
|
+
baseDevice = new BaseDevice(platform, accessory, logger);
|
|
100
|
+
platform.config.devices = [];
|
|
101
|
+
expect(baseDevice.config).toEqual({});
|
|
102
|
+
});
|
|
103
|
+
it('should return an empty string for the static model method', () => {
|
|
104
|
+
expect(BaseDevice.model()).toBe('');
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
//# sourceMappingURL=baseDevice.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseDevice.spec.js","sourceRoot":"","sources":["../src/baseDevice.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export default function TotalConsumption(DefaultCharacteristic) {
|
|
2
|
+
return class TotalConsumption extends DefaultCharacteristic {
|
|
3
|
+
// Eve Energy - Total consumption
|
|
4
|
+
static UUID = 'E863F10C-079E-48FF-8F27-9C2605A29F52';
|
|
5
|
+
constructor() {
|
|
6
|
+
super('Total Consumption', TotalConsumption.UUID, {
|
|
7
|
+
format: "float" /* Formats.FLOAT */,
|
|
8
|
+
unit: 'kWh',
|
|
9
|
+
minValue: 0,
|
|
10
|
+
maxValue: 1000000,
|
|
11
|
+
minStep: 0.01,
|
|
12
|
+
perms: ["pr" /* Perms.PAIRED_READ */, "ev" /* Perms.NOTIFY */],
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=TotalConsumption.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TotalConsumption.js","sourceRoot":"","sources":["../../src/characteristics/TotalConsumption.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,OAAO,UAAU,gBAAgB,CACtC,qBAA4C;IAE5C,OAAO,MAAM,gBAAiB,SAAQ,qBAAqB;QACzD,iCAAiC;QACjC,MAAM,CAAU,IAAI,GAAG,sCAAsC,CAAC;QAE9D;YACE,KAAK,CAAC,mBAAmB,EAAE,gBAAgB,CAAC,IAAI,EAAE;gBAChD,MAAM,6BAAe;gBACrB,IAAI,EAAE,KAAK;gBACX,QAAQ,EAAE,CAAC;gBACX,QAAQ,EAAE,OAAO;gBACjB,OAAO,EAAE,IAAI;gBACb,KAAK,EAAE,uDAAiC;aACzC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/characteristics/index.ts"],"names":[],"mappings":"AAKA,OAAO,gBAAgB,MAAM,uBAAuB,CAAC;AAErD,MAAM,CAAC,OAAO,UAAU,cAAc,CACpC,cAAyC;IAMzC,OAAO;QACL,gBAAgB,EAAE,gBAAgB,CAAC,cAAc,CAAC;KACnD,CAAC;AACJ,CAAC"}
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { API } from './lib/API.js';
|
|
4
|
+
import { Auth } from './lib/Auth.js';
|
|
5
|
+
import { URL } from 'url';
|
|
6
|
+
import * as readline from 'readline';
|
|
7
|
+
const makeLogger = () => console;
|
|
8
|
+
const input = (question) => new Promise((resolve) => {
|
|
9
|
+
const rl = readline.createInterface(process.stdin, process.stdout);
|
|
10
|
+
rl.question(question, (answer) => resolve(answer));
|
|
11
|
+
});
|
|
12
|
+
const program = new Command();
|
|
13
|
+
const options = {
|
|
14
|
+
country: 'US',
|
|
15
|
+
language: 'en-US',
|
|
16
|
+
};
|
|
17
|
+
program
|
|
18
|
+
.option('-c, --country <type>', 'Country code for account', options.country)
|
|
19
|
+
.on('option:country', (value) => options.country = value)
|
|
20
|
+
.option('-l, --language <type>', 'Language code for account', options.language)
|
|
21
|
+
.on('option:language', (value) => options.language = value);
|
|
22
|
+
program
|
|
23
|
+
.command('login')
|
|
24
|
+
.description('Obtain refresh_token from LG account')
|
|
25
|
+
.argument('<username>', 'LG username')
|
|
26
|
+
.argument('<password>', 'LG password')
|
|
27
|
+
.action(async (username, password) => {
|
|
28
|
+
console.info('Start login: username =', username, ', password =', password, ', country =', options.country, ', language =', options.language);
|
|
29
|
+
const logger = makeLogger();
|
|
30
|
+
try {
|
|
31
|
+
const api = new API(options.country, options.language, logger);
|
|
32
|
+
const gateway = await api.gateway();
|
|
33
|
+
const auth = new Auth(gateway, logger);
|
|
34
|
+
const session = await auth.login(username, password);
|
|
35
|
+
console.info('Your refresh_token:', session.refreshToken);
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
console.error(err);
|
|
39
|
+
}
|
|
40
|
+
process.exit(0);
|
|
41
|
+
});
|
|
42
|
+
program
|
|
43
|
+
.command('auth')
|
|
44
|
+
.description('Obtain refresh_token from account logged by Google Account, Apple ID')
|
|
45
|
+
.action(async () => {
|
|
46
|
+
const logger = makeLogger();
|
|
47
|
+
const api = new API(options.country, options.language, logger);
|
|
48
|
+
const gateway = await api.gateway();
|
|
49
|
+
const auth = new Auth(gateway, logger);
|
|
50
|
+
const loginUrl = new URL(await auth.getLoginUrl());
|
|
51
|
+
const origin = loginUrl.origin;
|
|
52
|
+
loginUrl.host = 'us.m.lgaccount.com';
|
|
53
|
+
loginUrl.searchParams.set('division', 'ha'); // enable Apple ID
|
|
54
|
+
loginUrl.searchParams.set('redirect_uri', origin + '/login/iabClose');
|
|
55
|
+
loginUrl.searchParams.set('callback_url', origin + '/login/iabClose');
|
|
56
|
+
console.info('Log in here:', loginUrl.href);
|
|
57
|
+
const callbackUrl = await input('Then paste the URL where the browser is redirected: ');
|
|
58
|
+
const url = new URL(callbackUrl);
|
|
59
|
+
const refresh_token = url.searchParams.get('refresh_token');
|
|
60
|
+
if (refresh_token) {
|
|
61
|
+
console.info('Your refresh_token:', refresh_token);
|
|
62
|
+
process.exit(0);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const username = url.searchParams.get('user_id'), thirdparty_token = url.searchParams.get('user_thirdparty_token'), id_type = url.searchParams.get('user_id_type') || '';
|
|
66
|
+
const thirdparty = {
|
|
67
|
+
APPL: 'apple',
|
|
68
|
+
FBK: 'facebook',
|
|
69
|
+
GGL: 'google',
|
|
70
|
+
AMZ: 'amazon',
|
|
71
|
+
};
|
|
72
|
+
if (!username || !thirdparty_token || typeof thirdparty[id_type] === 'undefined') {
|
|
73
|
+
console.error('redirected url not valid, please try again or use LG account method');
|
|
74
|
+
process.exit(0);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
try {
|
|
78
|
+
const session = await auth.loginStep2(username, thirdparty_token, {
|
|
79
|
+
third_party: thirdparty[id_type],
|
|
80
|
+
});
|
|
81
|
+
console.info('Your refresh_token:', session.refreshToken);
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
console.error(err);
|
|
85
|
+
}
|
|
86
|
+
process.exit(0);
|
|
87
|
+
});
|
|
88
|
+
program.parse(process.argv);
|
|
89
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import AirPurifier from './AirPurifier.js';
|
|
2
|
+
import { LGThinQHomebridgePlatform } from '../platform.js';
|
|
3
|
+
import { CharacteristicValue, Logger, PlatformAccessory, Service } from 'homebridge';
|
|
4
|
+
import { Device } from '../lib/Device.js';
|
|
5
|
+
import { AccessoryContext } from '../baseDevice.js';
|
|
6
|
+
export declare enum LightBrightness {
|
|
7
|
+
OFF = 0,
|
|
8
|
+
ON = 1,
|
|
9
|
+
LEVEL_1 = 8,
|
|
10
|
+
LEVEL_2 = 9,
|
|
11
|
+
LEVEL_3 = 10
|
|
12
|
+
}
|
|
13
|
+
export default class AeroTower extends AirPurifier {
|
|
14
|
+
readonly platform: LGThinQHomebridgePlatform;
|
|
15
|
+
readonly accessory: PlatformAccessory<AccessoryContext>;
|
|
16
|
+
protected serviceTemperatureSensor: Service;
|
|
17
|
+
protected serviceHumiditySensor: Service;
|
|
18
|
+
protected serviceUVNano: Service;
|
|
19
|
+
constructor(platform: LGThinQHomebridgePlatform, accessory: PlatformAccessory<AccessoryContext>, logger: Logger);
|
|
20
|
+
setLight(value: CharacteristicValue): Promise<void>;
|
|
21
|
+
protected setUVMode(value: CharacteristicValue): Promise<void>;
|
|
22
|
+
protected setLightBrightness(value: CharacteristicValue): Promise<void>;
|
|
23
|
+
updateAccessoryCharacteristic(device: Device): void;
|
|
24
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import AirPurifier from './AirPurifier.js';
|
|
2
|
+
import { normalizeNumber } from '../helper.js';
|
|
3
|
+
export var LightBrightness;
|
|
4
|
+
(function (LightBrightness) {
|
|
5
|
+
LightBrightness[LightBrightness["OFF"] = 0] = "OFF";
|
|
6
|
+
LightBrightness[LightBrightness["ON"] = 1] = "ON";
|
|
7
|
+
LightBrightness[LightBrightness["LEVEL_1"] = 8] = "LEVEL_1";
|
|
8
|
+
LightBrightness[LightBrightness["LEVEL_2"] = 9] = "LEVEL_2";
|
|
9
|
+
LightBrightness[LightBrightness["LEVEL_3"] = 10] = "LEVEL_3";
|
|
10
|
+
})(LightBrightness || (LightBrightness = {}));
|
|
11
|
+
export default class AeroTower extends AirPurifier {
|
|
12
|
+
platform;
|
|
13
|
+
accessory;
|
|
14
|
+
serviceTemperatureSensor;
|
|
15
|
+
serviceHumiditySensor;
|
|
16
|
+
serviceUVNano;
|
|
17
|
+
constructor(platform, accessory, logger) {
|
|
18
|
+
super(platform, accessory, logger);
|
|
19
|
+
this.platform = platform;
|
|
20
|
+
this.accessory = accessory;
|
|
21
|
+
const { Service: { TemperatureSensor, HumiditySensor, Switch, }, Characteristic, } = this.platform;
|
|
22
|
+
this.serviceTemperatureSensor = this.getOrCreateService(TemperatureSensor, 'Temperature Sensor');
|
|
23
|
+
this.serviceHumiditySensor = this.getOrCreateService(HumiditySensor, 'Humidity Sensor');
|
|
24
|
+
this.serviceLight?.getCharacteristic(Characteristic.Brightness)
|
|
25
|
+
.setProps({
|
|
26
|
+
maxValue: 3, // 3 level of light
|
|
27
|
+
})
|
|
28
|
+
.onSet(this.setLightBrightness.bind(this));
|
|
29
|
+
this.serviceUVNano = this.getOrCreateService(Switch, 'UV Purifier', 'UV Purifier');
|
|
30
|
+
this.serviceUVNano.getCharacteristic(Characteristic.On).onSet(this.setUVMode.bind(this));
|
|
31
|
+
}
|
|
32
|
+
async setLight(value) {
|
|
33
|
+
if (!this.Status.isPowerOn) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const device = this.accessory.context.device;
|
|
37
|
+
const isLightOn = value ? 1 : 0;
|
|
38
|
+
try {
|
|
39
|
+
const result = await this.platform.ThinQ?.deviceControl(device.id, {
|
|
40
|
+
dataKey: 'airState.lightingState.displayControl',
|
|
41
|
+
dataValue: isLightOn,
|
|
42
|
+
});
|
|
43
|
+
if (result) {
|
|
44
|
+
device.data.snapshot['airState.lightingState.displayControl'] = isLightOn;
|
|
45
|
+
this.updateAccessoryCharacteristic(device);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
this.logger.error('Error setting light state:', error);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async setUVMode(value) {
|
|
53
|
+
const device = this.accessory.context.device;
|
|
54
|
+
const uvModeValue = value ? 1 : 0;
|
|
55
|
+
try {
|
|
56
|
+
const result = await this.platform.ThinQ?.deviceControl(device.id, {
|
|
57
|
+
dataKey: 'airState.miscFuncState.Uvnano',
|
|
58
|
+
dataValue: uvModeValue,
|
|
59
|
+
});
|
|
60
|
+
if (result) {
|
|
61
|
+
device.data.snapshot['airState.miscFuncState.Uvnano'] = uvModeValue;
|
|
62
|
+
this.updateAccessoryCharacteristic(device);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
this.logger.error('Error setting UV mode:', error);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async setLightBrightness(value) {
|
|
70
|
+
const vNum = normalizeNumber(value);
|
|
71
|
+
if (vNum === null) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const device = this.accessory.context.device;
|
|
75
|
+
const brightnessValue = vNum - 1;
|
|
76
|
+
const values = [LightBrightness.LEVEL_1, LightBrightness.LEVEL_2, LightBrightness.LEVEL_3];
|
|
77
|
+
if (typeof values[brightnessValue] !== 'undefined') {
|
|
78
|
+
try {
|
|
79
|
+
const result = await this.platform.ThinQ?.deviceControl(device.id, {
|
|
80
|
+
dataKey: 'airState.lightingState.displayControl',
|
|
81
|
+
dataValue: values[brightnessValue],
|
|
82
|
+
});
|
|
83
|
+
if (result) {
|
|
84
|
+
device.data.snapshot['airState.lightingState.displayControl'] = values[brightnessValue];
|
|
85
|
+
this.updateAccessoryCharacteristic(device);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
this.logger.error('Error setting light brightness:', error);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
updateAccessoryCharacteristic(device) {
|
|
94
|
+
super.updateAccessoryCharacteristic(device);
|
|
95
|
+
const { Characteristic, } = this.platform;
|
|
96
|
+
const snapshot = device.data.snapshot;
|
|
97
|
+
// light brightness
|
|
98
|
+
const values = [LightBrightness.LEVEL_1, LightBrightness.LEVEL_2, LightBrightness.LEVEL_3];
|
|
99
|
+
const brightnessValue = values.indexOf(snapshot['airState.lightingState.displayControl'] || 0);
|
|
100
|
+
if (brightnessValue !== -1) {
|
|
101
|
+
this.serviceLight?.updateCharacteristic(Characteristic.Brightness, brightnessValue + 1);
|
|
102
|
+
}
|
|
103
|
+
if (typeof snapshot['airState.tempState.current'] !== 'undefined') {
|
|
104
|
+
this.serviceTemperatureSensor.updateCharacteristic(Characteristic.CurrentTemperature, snapshot['airState.tempState.current']);
|
|
105
|
+
}
|
|
106
|
+
if (typeof snapshot['airState.humidity.current'] !== 'undefined') {
|
|
107
|
+
this.serviceHumiditySensor.updateCharacteristic(Characteristic.CurrentRelativeHumidity, snapshot['airState.humidity.current']);
|
|
108
|
+
}
|
|
109
|
+
// uv mode
|
|
110
|
+
this.serviceUVNano.updateCharacteristic(Characteristic.On, !!(snapshot['airState.miscFuncState.Uvnano'] || 0));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=AeroTower.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AeroTower.js","sourceRoot":"","sources":["../../src/devices/AeroTower.ts"],"names":[],"mappings":"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"}
|