homebridge-midea-platform 0.1.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/LICENSE +176 -0
- package/README.md +9 -0
- package/config.schema.json +137 -0
- package/dist/accessory/AccessoryFactory.d.ts +8 -0
- package/dist/accessory/AccessoryFactory.d.ts.map +1 -0
- package/dist/accessory/AccessoryFactory.js +17 -0
- package/dist/accessory/AccessoryFactory.js.map +1 -0
- package/dist/accessory/AirConditionerAccessory.d.ts +25 -0
- package/dist/accessory/AirConditionerAccessory.d.ts.map +1 -0
- package/dist/accessory/AirConditionerAccessory.js +182 -0
- package/dist/accessory/AirConditionerAccessory.js.map +1 -0
- package/dist/accessory/BaseAccessory.d.ts +9 -0
- package/dist/accessory/BaseAccessory.d.ts.map +1 -0
- package/dist/accessory/BaseAccessory.js +29 -0
- package/dist/accessory/BaseAccessory.js.map +1 -0
- package/dist/core/MideaCloud.d.ts +32 -0
- package/dist/core/MideaCloud.d.ts.map +1 -0
- package/dist/core/MideaCloud.js +152 -0
- package/dist/core/MideaCloud.js.map +1 -0
- package/dist/core/MideaConstants.d.ts +41 -0
- package/dist/core/MideaConstants.d.ts.map +1 -0
- package/dist/core/MideaConstants.js +56 -0
- package/dist/core/MideaConstants.js.map +1 -0
- package/dist/core/MideaDevice.d.ts +58 -0
- package/dist/core/MideaDevice.d.ts.map +1 -0
- package/dist/core/MideaDevice.js +263 -0
- package/dist/core/MideaDevice.js.map +1 -0
- package/dist/core/MideaDiscover.d.ts +17 -0
- package/dist/core/MideaDiscover.d.ts.map +1 -0
- package/dist/core/MideaDiscover.js +129 -0
- package/dist/core/MideaDiscover.js.map +1 -0
- package/dist/core/MideaMessage.d.ts +76 -0
- package/dist/core/MideaMessage.d.ts.map +1 -0
- package/dist/core/MideaMessage.js +186 -0
- package/dist/core/MideaMessage.js.map +1 -0
- package/dist/core/MideaPacketBuilder.d.ts +11 -0
- package/dist/core/MideaPacketBuilder.d.ts.map +1 -0
- package/dist/core/MideaPacketBuilder.js +60 -0
- package/dist/core/MideaPacketBuilder.js.map +1 -0
- package/dist/core/MideaSecurity.d.ts +35 -0
- package/dist/core/MideaSecurity.d.ts.map +1 -0
- package/dist/core/MideaSecurity.js +168 -0
- package/dist/core/MideaSecurity.js.map +1 -0
- package/dist/core/MideaUtils.d.ts +18 -0
- package/dist/core/MideaUtils.d.ts.map +1 -0
- package/dist/core/MideaUtils.js +187 -0
- package/dist/core/MideaUtils.js.map +1 -0
- package/dist/devices/DeviceFactory.d.ts +8 -0
- package/dist/devices/DeviceFactory.d.ts.map +1 -0
- package/dist/devices/DeviceFactory.js +17 -0
- package/dist/devices/DeviceFactory.js.map +1 -0
- package/dist/devices/ac/MideaACDevice.d.ts +80 -0
- package/dist/devices/ac/MideaACDevice.d.ts.map +1 -0
- package/dist/devices/ac/MideaACDevice.js +271 -0
- package/dist/devices/ac/MideaACDevice.js.map +1 -0
- package/dist/devices/ac/MideaACMessage.d.ts +90 -0
- package/dist/devices/ac/MideaACMessage.d.ts.map +1 -0
- package/dist/devices/ac/MideaACMessage.js +528 -0
- package/dist/devices/ac/MideaACMessage.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/platform.d.ts +20 -0
- package/dist/platform.d.ts.map +1 -0
- package/dist/platform.js +110 -0
- package/dist/platform.js.map +1 -0
- package/dist/settings.d.ts +9 -0
- package/dist/settings.d.ts.map +1 -0
- package/dist/settings.js +12 -0
- package/dist/settings.js.map +1 -0
- package/package.json +45 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { Logger } from 'homebridge';
|
|
3
|
+
import { Endianness } from './MideaConstants';
|
|
4
|
+
export default class Cloud {
|
|
5
|
+
private readonly account;
|
|
6
|
+
private readonly password;
|
|
7
|
+
private readonly logger;
|
|
8
|
+
private readonly CLIENT_TYPE;
|
|
9
|
+
private readonly FORMAT;
|
|
10
|
+
private readonly LANGUAGE;
|
|
11
|
+
private readonly APP_ID;
|
|
12
|
+
private readonly SRC;
|
|
13
|
+
private readonly DEVICE_ID;
|
|
14
|
+
BASE_URL: string;
|
|
15
|
+
BASE_URL_CHINA: string;
|
|
16
|
+
RETRIES: number;
|
|
17
|
+
private loginId?;
|
|
18
|
+
private accessToken;
|
|
19
|
+
private session?;
|
|
20
|
+
private base_url;
|
|
21
|
+
private security;
|
|
22
|
+
constructor(account: string, password: string, use_china_server: boolean | undefined, logger: Logger);
|
|
23
|
+
private timestamp;
|
|
24
|
+
private parseResponse;
|
|
25
|
+
private request;
|
|
26
|
+
private apiRequest;
|
|
27
|
+
private buildRequestBody;
|
|
28
|
+
private getLoginId;
|
|
29
|
+
login(force?: boolean): Promise<void>;
|
|
30
|
+
getToken(device_id: number, endianess: Endianness): Promise<[Buffer, Buffer]>;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=MideaCloud.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MideaCloud.d.ts","sourceRoot":"","sources":["../../src/core/MideaCloud.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAOpC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,MAAM,CAAC,OAAO,OAAO,KAAK;IA2BtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAEzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IA3BzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAK;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAK;IAC5B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;IACjC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAU;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkC;IAG5D,QAAQ,SAAgC;IACxC,cAAc,SAAoC;IAGlD,OAAO,SAAK;IAGZ,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,OAAO,CAAC,CAAS;IAEzB,OAAO,CAAC,QAAQ,CAAS;IAEzB,OAAO,CAAC,QAAQ,CAAgB;gBAGb,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EACjC,gBAAgB,qBAAQ,EACP,MAAM,EAAE,MAAM;IAgBjC,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,aAAa;YAUP,OAAO;YAmBP,UAAU;IAoBxB,OAAO,CAAC,gBAAgB;YAeV,UAAU;IAYX,KAAK,CAAC,KAAK,UAAQ;IAuCnB,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAoB3F"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const crypto_1 = require("crypto");
|
|
7
|
+
const luxon_1 = require("luxon");
|
|
8
|
+
const axios_1 = __importDefault(require("axios"));
|
|
9
|
+
const MideaSecurity_1 = require("./MideaSecurity");
|
|
10
|
+
const MideaUtils_1 = require("./MideaUtils");
|
|
11
|
+
class Cloud {
|
|
12
|
+
constructor(account, password, use_china_server = false, logger) {
|
|
13
|
+
this.account = account;
|
|
14
|
+
this.password = password;
|
|
15
|
+
this.logger = logger;
|
|
16
|
+
// Misc constants for the API
|
|
17
|
+
this.CLIENT_TYPE = 1;
|
|
18
|
+
this.FORMAT = 2;
|
|
19
|
+
this.LANGUAGE = 'en_US';
|
|
20
|
+
this.APP_ID = '1010';
|
|
21
|
+
this.SRC = '1010';
|
|
22
|
+
this.DEVICE_ID = (0, crypto_1.randomBytes)(8).toString('hex');
|
|
23
|
+
// Base URLs
|
|
24
|
+
this.BASE_URL = 'https://mp-prod.appsmb.com';
|
|
25
|
+
this.BASE_URL_CHINA = 'https://mp-prod.smartmidea.net';
|
|
26
|
+
// Default number of request retries
|
|
27
|
+
this.RETRIES = 3;
|
|
28
|
+
this.accessToken = '';
|
|
29
|
+
this.security = new MideaSecurity_1.CloudSecurity(use_china_server);
|
|
30
|
+
if (use_china_server) {
|
|
31
|
+
this.base_url = this.BASE_URL_CHINA;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
this.base_url = this.BASE_URL;
|
|
35
|
+
}
|
|
36
|
+
this.logger.debug(`Using Midea cloud server: ${this.base_url} (China: ${use_china_server}).`);
|
|
37
|
+
}
|
|
38
|
+
timestamp() {
|
|
39
|
+
return luxon_1.DateTime.utc().toFormat('yyyyMMddHHmmss');
|
|
40
|
+
}
|
|
41
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
42
|
+
parseResponse(response) {
|
|
43
|
+
this.logger.debug(`Parsing response: ${JSON.stringify(response)}`);
|
|
44
|
+
if (response.code === '0' || response.code === 0) {
|
|
45
|
+
return response.data;
|
|
46
|
+
}
|
|
47
|
+
throw new Error(`Error response from Midea cloud: ${response.msg}`);
|
|
48
|
+
}
|
|
49
|
+
async request(url, headers, data, retries = this.RETRIES) {
|
|
50
|
+
this.logger.debug(`Sending request to ${url} with data: ${JSON.stringify(data)}`);
|
|
51
|
+
try {
|
|
52
|
+
const response = await axios_1.default.post(url, data, { headers: headers });
|
|
53
|
+
return this.parseResponse(response.data);
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
this.logger.error(`Error while sending request to ${url}: ${error}`);
|
|
57
|
+
if (retries > 0) {
|
|
58
|
+
this.logger.debug(`Retrying request to ${url} (${retries} retries left).`);
|
|
59
|
+
return this.request(url, headers, data, retries - 1);
|
|
60
|
+
}
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
async apiRequest(endpoint, body) {
|
|
65
|
+
const data = JSON.stringify(body);
|
|
66
|
+
const random = (0, crypto_1.randomBytes)(16).toString('hex');
|
|
67
|
+
const sign = this.security.sign(data, random);
|
|
68
|
+
const headers = {
|
|
69
|
+
'Content-Type': 'application/json',
|
|
70
|
+
'secretVersion': '1',
|
|
71
|
+
'sign': sign,
|
|
72
|
+
'random': random,
|
|
73
|
+
'accessToken': this.accessToken,
|
|
74
|
+
};
|
|
75
|
+
const url = `${this.base_url}/mas/v5/app/proxy?alias=${endpoint}`;
|
|
76
|
+
return await this.request(url, headers, body);
|
|
77
|
+
}
|
|
78
|
+
buildRequestBody(data) {
|
|
79
|
+
const body = {
|
|
80
|
+
'appId': this.APP_ID,
|
|
81
|
+
'format': this.FORMAT,
|
|
82
|
+
'clientType': this.CLIENT_TYPE,
|
|
83
|
+
'language': this.LANGUAGE,
|
|
84
|
+
'src': this.SRC,
|
|
85
|
+
'stamp': this.timestamp(),
|
|
86
|
+
'deviceId': this.DEVICE_ID,
|
|
87
|
+
'reqId': (0, crypto_1.randomBytes)(16).toString('hex'),
|
|
88
|
+
};
|
|
89
|
+
return Object.assign(body, data);
|
|
90
|
+
}
|
|
91
|
+
async getLoginId() {
|
|
92
|
+
const response = await this.apiRequest('/v1/user/login/id/get', this.buildRequestBody({
|
|
93
|
+
'loginAccount': this.account,
|
|
94
|
+
}));
|
|
95
|
+
if (response) {
|
|
96
|
+
return response['loginId'];
|
|
97
|
+
}
|
|
98
|
+
throw new Error('Failed to get login ID.');
|
|
99
|
+
}
|
|
100
|
+
async login(force = false) {
|
|
101
|
+
if (this.session && !force) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (this.loginId === undefined) {
|
|
105
|
+
this.loginId = await this.getLoginId();
|
|
106
|
+
this.logger.debug(`Got login ID: ${this.loginId}`);
|
|
107
|
+
}
|
|
108
|
+
const body = {
|
|
109
|
+
'data': {
|
|
110
|
+
'platform': this.FORMAT,
|
|
111
|
+
'deviceId': this.DEVICE_ID,
|
|
112
|
+
},
|
|
113
|
+
'iotData': {
|
|
114
|
+
'appId': this.APP_ID,
|
|
115
|
+
'clientType': this.CLIENT_TYPE,
|
|
116
|
+
'iampwd': this.security.encrpytIAMPassword(this.loginId, this.password),
|
|
117
|
+
'loginAccount': this.account,
|
|
118
|
+
'password': this.security.encrpytPassword(this.loginId, this.password),
|
|
119
|
+
'pushToken': (0, crypto_1.randomBytes)(20).toString('base64url'),
|
|
120
|
+
'reqId': (0, crypto_1.randomBytes)(16).toString('hex'),
|
|
121
|
+
'src': this.SRC,
|
|
122
|
+
'stamp': this.timestamp(),
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
const response = await this.apiRequest('/mj/user/login', body);
|
|
126
|
+
if (response) {
|
|
127
|
+
this.accessToken = response['mdata']['accessToken'];
|
|
128
|
+
this.session = response;
|
|
129
|
+
this.logger.debug(`Logged in with access token: ${this.accessToken}`);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
throw new Error('Failed to login.');
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
async getToken(device_id, endianess) {
|
|
136
|
+
const udpid = MideaSecurity_1.CloudSecurity.getUDPID((0, MideaUtils_1.numberToUint8Array)(device_id, 6, endianess));
|
|
137
|
+
const response = await this.apiRequest('/v1/iot/secure/getToken', this.buildRequestBody({ 'udpid': udpid }));
|
|
138
|
+
if (response) {
|
|
139
|
+
for (const token of response['tokenlist']) {
|
|
140
|
+
if (token['udpId'] === udpid) {
|
|
141
|
+
return [Buffer.from(token['token'], 'hex'), Buffer.from(token['key'], 'hex')];
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
throw new Error('Failed to get token.');
|
|
147
|
+
}
|
|
148
|
+
throw new Error(`No token/key found for udpid ${udpid}.`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
exports.default = Cloud;
|
|
152
|
+
//# sourceMappingURL=MideaCloud.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MideaCloud.js","sourceRoot":"","sources":["../../src/core/MideaCloud.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export declare const DISCOVERY_MESSAGE: Int8Array;
|
|
2
|
+
export declare const DEVICE_INFO_MESSAGE: Int8Array;
|
|
3
|
+
export declare enum DeviceType {
|
|
4
|
+
AIR_CONDITIONER = 172
|
|
5
|
+
}
|
|
6
|
+
export declare enum ParseMessageResult {
|
|
7
|
+
SUCCESS = 0,
|
|
8
|
+
PADDING = 1,
|
|
9
|
+
ERROR = 99
|
|
10
|
+
}
|
|
11
|
+
export type DeviceInfo = {
|
|
12
|
+
ip: string;
|
|
13
|
+
port: number;
|
|
14
|
+
id: number;
|
|
15
|
+
model: string;
|
|
16
|
+
sn: string;
|
|
17
|
+
name: string;
|
|
18
|
+
type: number;
|
|
19
|
+
version: number;
|
|
20
|
+
};
|
|
21
|
+
export declare enum FrameType {
|
|
22
|
+
UNKNOWN = 0,
|
|
23
|
+
SET = 2,
|
|
24
|
+
REQUEST = 3,
|
|
25
|
+
RESPONSE = 4,
|
|
26
|
+
ABNORMAL_REPORT = 6
|
|
27
|
+
}
|
|
28
|
+
export declare enum TCPMessageType {
|
|
29
|
+
HANDSHAKE_REQUEST = 0,
|
|
30
|
+
HANDSHAKE_RESPONSE = 1,
|
|
31
|
+
ENCRYPTED_RESPONSE = 3,
|
|
32
|
+
ENCRYPTED_REQUEST = 6
|
|
33
|
+
}
|
|
34
|
+
export declare enum ProtocolVersion {
|
|
35
|
+
UNKNOWN = 0,
|
|
36
|
+
V1 = 1,
|
|
37
|
+
V2 = 2,
|
|
38
|
+
V3 = 3
|
|
39
|
+
}
|
|
40
|
+
export type Endianness = 'little' | 'big';
|
|
41
|
+
//# sourceMappingURL=MideaConstants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MideaConstants.d.ts","sourceRoot":"","sources":["../../src/core/MideaConstants.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,iBAAiB,WAU5B,CAAC;AAEH,eAAO,MAAM,mBAAmB,WAQ9B,CAAC;AAEH,oBAAY,UAAU;IACpB,eAAe,MAAO;CACvB;AAED,oBAAY,kBAAkB;IAC5B,OAAO,IAAI;IACX,OAAO,IAAI;IACX,KAAK,KAAK;CACX;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,oBAAY,SAAS;IACnB,OAAO,IAAI;IACX,GAAG,IAAO;IACV,OAAO,IAAO;IACd,QAAQ,IAAO;IACf,eAAe,IAAO;CACvB;AAED,oBAAY,cAAc;IACxB,iBAAiB,IAAM;IACvB,kBAAkB,IAAM;IACxB,kBAAkB,IAAM;IACxB,iBAAiB,IAAM;CACxB;AAED,oBAAY,eAAe;IACzB,OAAO,IAAI;IACX,EAAE,IAAA;IACF,EAAE,IAAA;IACF,EAAE,IAAA;CACH;AAED,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,KAAK,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ProtocolVersion = exports.TCPMessageType = exports.FrameType = exports.ParseMessageResult = exports.DeviceType = exports.DEVICE_INFO_MESSAGE = exports.DISCOVERY_MESSAGE = void 0;
|
|
4
|
+
exports.DISCOVERY_MESSAGE = new Int8Array([
|
|
5
|
+
0x5a, 0x5a, 0x01, 0x11, 0x48, 0x00, 0x92, 0x00,
|
|
6
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
7
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
8
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
9
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
10
|
+
0x7f, 0x75, 0xbd, 0x6b, 0x3e, 0x4f, 0x8b, 0x76,
|
|
11
|
+
0x2e, 0x84, 0x9c, 0x6e, 0x57, 0x8d, 0x65, 0x90,
|
|
12
|
+
0x03, 0x6e, 0x9d, 0x43, 0x42, 0xa5, 0x0f, 0x1f,
|
|
13
|
+
0x56, 0x9e, 0xb8, 0xec, 0x91, 0x8e, 0x92, 0xe5,
|
|
14
|
+
]);
|
|
15
|
+
exports.DEVICE_INFO_MESSAGE = new Int8Array([
|
|
16
|
+
0x5a, 0x5a, 0x15, 0x00, 0x00, 0x38, 0x00, 0x04,
|
|
17
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x33, 0x05,
|
|
18
|
+
0x13, 0x06, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00,
|
|
19
|
+
0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x00,
|
|
20
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
21
|
+
0xca, 0x8d, 0x9b, 0xf9, 0xa0, 0x30, 0x1a, 0xe3,
|
|
22
|
+
0xb7, 0xe4, 0x2d, 0x53, 0x49, 0x47, 0x62, 0xbe,
|
|
23
|
+
]);
|
|
24
|
+
var DeviceType;
|
|
25
|
+
(function (DeviceType) {
|
|
26
|
+
DeviceType[DeviceType["AIR_CONDITIONER"] = 172] = "AIR_CONDITIONER";
|
|
27
|
+
})(DeviceType = exports.DeviceType || (exports.DeviceType = {}));
|
|
28
|
+
var ParseMessageResult;
|
|
29
|
+
(function (ParseMessageResult) {
|
|
30
|
+
ParseMessageResult[ParseMessageResult["SUCCESS"] = 0] = "SUCCESS";
|
|
31
|
+
ParseMessageResult[ParseMessageResult["PADDING"] = 1] = "PADDING";
|
|
32
|
+
ParseMessageResult[ParseMessageResult["ERROR"] = 99] = "ERROR";
|
|
33
|
+
})(ParseMessageResult = exports.ParseMessageResult || (exports.ParseMessageResult = {}));
|
|
34
|
+
var FrameType;
|
|
35
|
+
(function (FrameType) {
|
|
36
|
+
FrameType[FrameType["UNKNOWN"] = 0] = "UNKNOWN";
|
|
37
|
+
FrameType[FrameType["SET"] = 2] = "SET";
|
|
38
|
+
FrameType[FrameType["REQUEST"] = 3] = "REQUEST";
|
|
39
|
+
FrameType[FrameType["RESPONSE"] = 4] = "RESPONSE";
|
|
40
|
+
FrameType[FrameType["ABNORMAL_REPORT"] = 6] = "ABNORMAL_REPORT";
|
|
41
|
+
})(FrameType = exports.FrameType || (exports.FrameType = {}));
|
|
42
|
+
var TCPMessageType;
|
|
43
|
+
(function (TCPMessageType) {
|
|
44
|
+
TCPMessageType[TCPMessageType["HANDSHAKE_REQUEST"] = 0] = "HANDSHAKE_REQUEST";
|
|
45
|
+
TCPMessageType[TCPMessageType["HANDSHAKE_RESPONSE"] = 1] = "HANDSHAKE_RESPONSE";
|
|
46
|
+
TCPMessageType[TCPMessageType["ENCRYPTED_RESPONSE"] = 3] = "ENCRYPTED_RESPONSE";
|
|
47
|
+
TCPMessageType[TCPMessageType["ENCRYPTED_REQUEST"] = 6] = "ENCRYPTED_REQUEST";
|
|
48
|
+
})(TCPMessageType = exports.TCPMessageType || (exports.TCPMessageType = {}));
|
|
49
|
+
var ProtocolVersion;
|
|
50
|
+
(function (ProtocolVersion) {
|
|
51
|
+
ProtocolVersion[ProtocolVersion["UNKNOWN"] = 0] = "UNKNOWN";
|
|
52
|
+
ProtocolVersion[ProtocolVersion["V1"] = 1] = "V1";
|
|
53
|
+
ProtocolVersion[ProtocolVersion["V2"] = 2] = "V2";
|
|
54
|
+
ProtocolVersion[ProtocolVersion["V3"] = 3] = "V3";
|
|
55
|
+
})(ProtocolVersion = exports.ProtocolVersion || (exports.ProtocolVersion = {}));
|
|
56
|
+
//# sourceMappingURL=MideaConstants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MideaConstants.js","sourceRoot":"","sources":["../../src/core/MideaConstants.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
import { Logger } from 'homebridge';
|
|
4
|
+
import { KeyToken, LocalSecurity } from './MideaSecurity';
|
|
5
|
+
import { DeviceInfo, DeviceType, ProtocolVersion, ParseMessageResult } from './MideaConstants';
|
|
6
|
+
import { Socket } from 'net';
|
|
7
|
+
import { MessageRequest, MessageType } from './MideaMessage';
|
|
8
|
+
import { PromiseSocket } from './MideaUtils';
|
|
9
|
+
export type DeviceAttributesBase = {
|
|
10
|
+
[key: string]: string | number | boolean | undefined;
|
|
11
|
+
};
|
|
12
|
+
export default abstract class MideaDevice {
|
|
13
|
+
protected readonly logger: Logger;
|
|
14
|
+
private readonly SOCKET_TIMEOUT;
|
|
15
|
+
protected readonly ip: string;
|
|
16
|
+
protected readonly port: number;
|
|
17
|
+
readonly id: number;
|
|
18
|
+
readonly model: string;
|
|
19
|
+
readonly sn: string;
|
|
20
|
+
readonly name: string;
|
|
21
|
+
readonly type: DeviceType;
|
|
22
|
+
protected readonly version: ProtocolVersion;
|
|
23
|
+
protected is_running: boolean;
|
|
24
|
+
protected available: boolean;
|
|
25
|
+
private unsupported_protocol;
|
|
26
|
+
protected device_protocol_version: number;
|
|
27
|
+
protected refresh_interval: number;
|
|
28
|
+
protected heartbeat_interval: number;
|
|
29
|
+
protected default_refresh_interval: number;
|
|
30
|
+
private _sub_type?;
|
|
31
|
+
token: KeyToken;
|
|
32
|
+
key: KeyToken;
|
|
33
|
+
protected readonly security: LocalSecurity;
|
|
34
|
+
private buffer;
|
|
35
|
+
protected socket: Socket;
|
|
36
|
+
promiseSocket: PromiseSocket;
|
|
37
|
+
abstract attributes: DeviceAttributesBase;
|
|
38
|
+
protected abstract build_query(): MessageRequest[];
|
|
39
|
+
protected abstract process_message(message: Buffer): void;
|
|
40
|
+
protected abstract set_subtype(): void;
|
|
41
|
+
abstract set_attribute(status: DeviceAttributesBase): Promise<void>;
|
|
42
|
+
constructor(logger: Logger, device_info: DeviceInfo, token: KeyToken, key: KeyToken);
|
|
43
|
+
get sub_type(): number;
|
|
44
|
+
fetch_v2_message(message: Buffer): [Buffer[], Buffer];
|
|
45
|
+
connect(refresh_status?: boolean): Promise<boolean>;
|
|
46
|
+
private authenticate;
|
|
47
|
+
send_message(data: Buffer): Promise<void>;
|
|
48
|
+
private createSocket;
|
|
49
|
+
private send_message_v2;
|
|
50
|
+
private send_message_v3;
|
|
51
|
+
build_send(command: MessageRequest): Promise<void>;
|
|
52
|
+
refresh_status(wait_response?: boolean, ignore_unsupported?: boolean): Promise<boolean>;
|
|
53
|
+
preprocess_message(message: Buffer): boolean;
|
|
54
|
+
parse_message(message: Buffer): ParseMessageResult;
|
|
55
|
+
send_command(command_type: MessageType, command_body: Buffer): Promise<void>;
|
|
56
|
+
send_heartbeat(): Promise<void>;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=MideaDevice.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MideaDevice.d.ts","sourceRoot":"","sources":["../../src/core/MideaDevice.ts"],"names":[],"mappings":";;AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,UAAU,EAAkB,eAAe,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC/G,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAA2C,cAAc,EAA0B,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE9H,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,MAAM,oBAAoB,GAAG;IACjC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;CACtD,CAAC;AAEF,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,WAAW;IA4CrC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM;IA1CnC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAQ;IAEvC,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAC9B,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEhC,SAAgB,EAAE,EAAE,MAAM,CAAC;IAC3B,SAAgB,KAAK,EAAE,MAAM,CAAC;IAC9B,SAAgB,EAAE,EAAE,MAAM,CAAC;IAC3B,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,SAAgB,IAAI,EAAE,UAAU,CAAC;IACjC,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAE5C,SAAS,CAAC,UAAU,UAAS;IAC7B,SAAS,CAAC,SAAS,UAAS;IAE5B,OAAO,CAAC,oBAAoB,CAAgB;IAC5C,SAAS,CAAC,uBAAuB,SAAK;IAEtC,SAAS,CAAC,gBAAgB,SAAS;IACnC,SAAS,CAAC,kBAAkB,SAAS;IACrC,SAAS,CAAC,wBAAwB,SAAS;IAE3C,OAAO,CAAC,SAAS,CAAC,CAAS;IAEpB,KAAK,EAAE,QAAQ,CAAC;IAChB,GAAG,EAAE,QAAQ,CAAC;IAErB,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IAC3C,OAAO,CAAC,MAAM,CAAS;IAEvB,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,aAAa,CAAC;IAEpC,SAAgB,UAAU,EAAE,oBAAoB,CAAC;IAGjD,SAAS,CAAC,QAAQ,CAAC,WAAW,IAAI,cAAc,EAAE;IAClD,SAAS,CAAC,QAAQ,CAAC,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IACzD,SAAS,CAAC,QAAQ,CAAC,WAAW,IAAI,IAAI;aACtB,aAAa,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;gBAGrD,MAAM,EAAE,MAAM,EACjC,WAAW,EAAE,UAAU,EACvB,KAAK,EAAE,QAAQ,EACf,GAAG,EAAE,QAAQ;IAwBf,IAAI,QAAQ,IAAI,MAAM,CAErB;IAEM,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,CAAE,MAAM,EAAE,EAAE,MAAM,CAAE;IAkBjD,OAAO,CAAC,cAAc,UAAO;YAyB5B,YAAY;IAqBb,YAAY,CAAC,IAAI,EAAE,MAAM;IAQtC,OAAO,CAAC,YAAY;YAYN,eAAe;YAkBf,eAAe;IAKhB,UAAU,CAAC,OAAO,EAAE,cAAc;IAMlC,cAAc,CAAC,aAAa,UAAQ,EAAE,kBAAkB,UAAQ;IA4CtE,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAY5C,aAAa,CAAC,OAAO,EAAE,MAAM;IAoCvB,YAAY,CAAC,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM;IAW5D,cAAc;CAI5B"}
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const MideaSecurity_1 = require("./MideaSecurity");
|
|
7
|
+
const MideaConstants_1 = require("./MideaConstants");
|
|
8
|
+
const net_1 = require("net");
|
|
9
|
+
const MideaMessage_1 = require("./MideaMessage");
|
|
10
|
+
const MideaPacketBuilder_1 = __importDefault(require("./MideaPacketBuilder"));
|
|
11
|
+
const MideaUtils_1 = require("./MideaUtils");
|
|
12
|
+
class MideaDevice {
|
|
13
|
+
constructor(logger, device_info, token, key) {
|
|
14
|
+
this.logger = logger;
|
|
15
|
+
this.SOCKET_TIMEOUT = 3000;
|
|
16
|
+
this.is_running = false;
|
|
17
|
+
this.available = false;
|
|
18
|
+
this.unsupported_protocol = [];
|
|
19
|
+
this.device_protocol_version = 0;
|
|
20
|
+
this.refresh_interval = 30000;
|
|
21
|
+
this.heartbeat_interval = 10000;
|
|
22
|
+
this.default_refresh_interval = 30000;
|
|
23
|
+
this.ip = device_info.ip;
|
|
24
|
+
this.port = device_info.port;
|
|
25
|
+
this.id = device_info.id;
|
|
26
|
+
this.model = device_info.model;
|
|
27
|
+
this.sn = device_info.sn;
|
|
28
|
+
this.name = device_info.name;
|
|
29
|
+
this.type = device_info.type;
|
|
30
|
+
this.version = device_info.version;
|
|
31
|
+
this.token = token;
|
|
32
|
+
this.key = key;
|
|
33
|
+
this.security = new MideaSecurity_1.LocalSecurity();
|
|
34
|
+
this.buffer = Buffer.alloc(0);
|
|
35
|
+
this.socket = new net_1.Socket();
|
|
36
|
+
this.promiseSocket = new MideaUtils_1.PromiseSocket(this.socket, this.logger);
|
|
37
|
+
this.createSocket();
|
|
38
|
+
}
|
|
39
|
+
get sub_type() {
|
|
40
|
+
return this._sub_type || 0;
|
|
41
|
+
}
|
|
42
|
+
fetch_v2_message(message) {
|
|
43
|
+
const result = [];
|
|
44
|
+
while (message.length > 0) {
|
|
45
|
+
const length = message.length;
|
|
46
|
+
if (length < 6) {
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
const alleged_length = message[4] + (message[5] << 8);
|
|
50
|
+
if (length >= alleged_length) {
|
|
51
|
+
result.push(message.subarray(0, alleged_length));
|
|
52
|
+
message = message.subarray(alleged_length, length);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return [result, message];
|
|
59
|
+
}
|
|
60
|
+
async connect(refresh_status = true) {
|
|
61
|
+
try {
|
|
62
|
+
await this.promiseSocket.connect(this.port, this.ip);
|
|
63
|
+
this.logger.debug(`Connecting to device ${this.name} (${this.ip}:${this.port})...`);
|
|
64
|
+
if (this.version === MideaConstants_1.ProtocolVersion.V3) {
|
|
65
|
+
await this.authenticate();
|
|
66
|
+
}
|
|
67
|
+
let retries = 0;
|
|
68
|
+
if (refresh_status) {
|
|
69
|
+
let success = await this.refresh_status(true);
|
|
70
|
+
while (!success && retries++ < 3) {
|
|
71
|
+
success = await this.refresh_status(true, true);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (retries > 3) {
|
|
75
|
+
this.logger.debug(`[${this.name}] Error when connecting to device ${this.name} (${this.ip}:${this.port}): Refresh status failed.`);
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
this.logger.debug(`[${this.name}] Error when connecting to device ${this.name} (${this.ip}:${this.port}): ${err}`);
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async authenticate() {
|
|
86
|
+
if (!(this.token && this.key)) {
|
|
87
|
+
throw new Error('Token or key is missing!');
|
|
88
|
+
}
|
|
89
|
+
const request = this.security.encode_8370(this.token, MideaConstants_1.TCPMessageType.HANDSHAKE_REQUEST);
|
|
90
|
+
await this.promiseSocket.write(request);
|
|
91
|
+
const response = await this.promiseSocket.read(512);
|
|
92
|
+
if (response) {
|
|
93
|
+
if (response.length < 20) {
|
|
94
|
+
throw Error(`Authenticate error when receiving data from ${this.ip}:${this.port}. (Data length mismatch)`);
|
|
95
|
+
}
|
|
96
|
+
const resp = response.subarray(8, 72);
|
|
97
|
+
this.security.tcp_key_from_resp(resp, this.key);
|
|
98
|
+
this.logger.debug(`[${this.name}] Authentication success.`);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
throw Error(`Authenticate error when receiving data from ${this.ip}:${this.port}.`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async send_message(data) {
|
|
105
|
+
if (this.version === MideaConstants_1.ProtocolVersion.V3) {
|
|
106
|
+
await this.send_message_v3(data);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
await this.send_message_v2(data);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
createSocket() {
|
|
113
|
+
this.socket = new net_1.Socket();
|
|
114
|
+
this.socket.setTimeout(this.SOCKET_TIMEOUT);
|
|
115
|
+
this.socket.on('error', (err) => {
|
|
116
|
+
this.logger.debug(`[${this.name}] Socket error: ${err}`);
|
|
117
|
+
});
|
|
118
|
+
this.socket.on('close', async () => {
|
|
119
|
+
this.socket.destroy();
|
|
120
|
+
});
|
|
121
|
+
this.promiseSocket = new MideaUtils_1.PromiseSocket(this.socket, this.logger);
|
|
122
|
+
}
|
|
123
|
+
async send_message_v2(data, retries = 3, force_reinit = false) {
|
|
124
|
+
if (retries === 0) {
|
|
125
|
+
throw new Error(`[${this.name} | send_message] Error when sending data to device.`);
|
|
126
|
+
}
|
|
127
|
+
if (force_reinit || !this.socket || !this.socket.writable || this.socket.destroyed) {
|
|
128
|
+
this.createSocket();
|
|
129
|
+
let connected = await this.connect(false);
|
|
130
|
+
while (!connected) {
|
|
131
|
+
connected = await this.connect(false);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
try {
|
|
135
|
+
await this.promiseSocket.write(data);
|
|
136
|
+
}
|
|
137
|
+
catch (_a) {
|
|
138
|
+
await this.send_message_v2(data, retries - 1, true);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
async send_message_v3(data, message_type = MideaConstants_1.TCPMessageType.ENCRYPTED_REQUEST) {
|
|
142
|
+
const encrypted_data = this.security.encode_8370(data, message_type);
|
|
143
|
+
await this.send_message_v2(encrypted_data);
|
|
144
|
+
}
|
|
145
|
+
async build_send(command) {
|
|
146
|
+
const data = command.serialize();
|
|
147
|
+
const message = new MideaPacketBuilder_1.default(this.id, data).finalize();
|
|
148
|
+
await this.send_message(message);
|
|
149
|
+
}
|
|
150
|
+
async refresh_status(wait_response = false, ignore_unsupported = false) {
|
|
151
|
+
this.logger.debug(`[${this.name}] Refreshing status...`);
|
|
152
|
+
const commands = this.build_query();
|
|
153
|
+
if (this._sub_type === undefined) {
|
|
154
|
+
commands.unshift(new MideaMessage_1.MessageQuerySubtype(this.type));
|
|
155
|
+
}
|
|
156
|
+
let error_cnt = 0;
|
|
157
|
+
for (const cmd of commands) {
|
|
158
|
+
if (ignore_unsupported || !this.unsupported_protocol.includes(cmd.constructor.name)) {
|
|
159
|
+
await this.build_send(cmd);
|
|
160
|
+
if (wait_response) {
|
|
161
|
+
try {
|
|
162
|
+
// eslint-disable-next-line no-constant-condition
|
|
163
|
+
while (true) {
|
|
164
|
+
const message = await this.promiseSocket.read(512);
|
|
165
|
+
if (message.length === 0) {
|
|
166
|
+
throw new Error(`[${this.name} | refresh_status] Error when receiving data from device.`);
|
|
167
|
+
}
|
|
168
|
+
const result = this.parse_message(message);
|
|
169
|
+
if (result === MideaConstants_1.ParseMessageResult.SUCCESS) {
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
else if (result === MideaConstants_1.ParseMessageResult.PADDING) {
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
throw new Error(`[${this.name} | refresh_status] Error when parsing message.`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
catch (err) {
|
|
181
|
+
error_cnt++;
|
|
182
|
+
this.unsupported_protocol.push(cmd.constructor.name);
|
|
183
|
+
this.logger.error(`[${this.name}] Does not supports the protocol ${cmd.constructor.name}, ignored, error: ${err}`);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
error_cnt++;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (error_cnt === commands.length) {
|
|
192
|
+
this.logger.error(`[${this.name}] Refresh failed.`);
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
return true;
|
|
196
|
+
}
|
|
197
|
+
preprocess_message(message) {
|
|
198
|
+
if (message[9] === MideaMessage_1.MessageType.QUERY_SUBTYPE) {
|
|
199
|
+
const msg = new MideaMessage_1.MessageSubtypeResponse(message);
|
|
200
|
+
this._sub_type = msg.sub_type;
|
|
201
|
+
this.set_subtype();
|
|
202
|
+
this.device_protocol_version = msg.device_protocol_version;
|
|
203
|
+
this.logger.debug(`[${this.name}] Subtype: ${this._sub_type}, device protocol version: ${this.device_protocol_version}`);
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
return true;
|
|
207
|
+
}
|
|
208
|
+
parse_message(message) {
|
|
209
|
+
let messages;
|
|
210
|
+
if (this.version === MideaConstants_1.ProtocolVersion.V3) {
|
|
211
|
+
[messages, this.buffer] = this.security.decode_8370(Buffer.concat([this.buffer, message]));
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
[messages, this.buffer] = this.fetch_v2_message(Buffer.concat([this.buffer, message]));
|
|
215
|
+
}
|
|
216
|
+
if (message.length === 0) {
|
|
217
|
+
return MideaConstants_1.ParseMessageResult.PADDING;
|
|
218
|
+
}
|
|
219
|
+
for (const msg of messages) {
|
|
220
|
+
if (msg.toString('utf8') === 'ERROR') {
|
|
221
|
+
return MideaConstants_1.ParseMessageResult.ERROR;
|
|
222
|
+
}
|
|
223
|
+
const payload_length = msg[4] + (msg[5] << 8) - 56;
|
|
224
|
+
const payload_type = msg[2] + (msg[3] << 8);
|
|
225
|
+
if ([0x1001, 0x0001].includes(payload_type)) {
|
|
226
|
+
// Heartbeat
|
|
227
|
+
}
|
|
228
|
+
else if (msg.length > 56) {
|
|
229
|
+
const cryptographic = msg.subarray(40, -16);
|
|
230
|
+
if (payload_length % 16 === 0) {
|
|
231
|
+
const decrypted = this.security.aes_decrypt(cryptographic);
|
|
232
|
+
if (this.preprocess_message(decrypted)) {
|
|
233
|
+
this.process_message(decrypted);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
this.logger.warn(`[${this.name}] Invalid payload length: ${payload_length}`);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
this.logger.warn(`[${this.name}] Illegal message.`);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return MideaConstants_1.ParseMessageResult.SUCCESS;
|
|
245
|
+
}
|
|
246
|
+
async send_command(command_type, command_body) {
|
|
247
|
+
const cmd = new MideaMessage_1.MessageQuestCustom(this.type, command_type, command_body);
|
|
248
|
+
try {
|
|
249
|
+
await this.build_send(cmd);
|
|
250
|
+
}
|
|
251
|
+
catch (e) {
|
|
252
|
+
this.logger.debug(`[${this.name}] Interface send_command failure: ${e},
|
|
253
|
+
cmd_type: ${command_type},
|
|
254
|
+
cmd_body: ${command_body.toString('hex')}`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
async send_heartbeat() {
|
|
258
|
+
const message = new MideaPacketBuilder_1.default(this.id, Buffer.alloc(0)).finalize(0);
|
|
259
|
+
await this.send_message(message);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
exports.default = MideaDevice;
|
|
263
|
+
//# sourceMappingURL=MideaDevice.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MideaDevice.js","sourceRoot":"","sources":["../../src/core/MideaDevice.ts"],"names":[],"mappings":"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"}
|