homebridge-connectlife-ac
Version:
Control your ConnectLife air conditioner with Homebridge
121 lines • 5.49 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConnectLifeApi = void 0;
const axios_1 = __importDefault(require("axios"));
const node_cache_1 = __importDefault(require("node-cache"));
axios_1.default.defaults.headers['User-Agent'] = 'connectlife-api-connector 2.1.11';
const cache = new node_cache_1.default();
class ConnectLifeApi {
loginID;
password;
options;
constructor(loginID, password, options = {}) {
this.loginID = loginID;
this.password = password;
this.options = options;
}
async getAccessToken() {
const cachedToken = cache.get('access_token');
if (cachedToken) {
return cachedToken;
}
// no wonder, this is always the same (tested with multiple accounts - reverse engine with mitmproxy)
const apiKey = '4_yhTWQmHFpZkQZDSV1uV-_A';
const gmid =
// eslint-disable-next-line
'gmid.ver4.AtLt3mZAMA.C8m5VqSTEQDrTRrkYYDgOaJWcyQ-XHow5nzQSXJF3EO3TnqTJ8tKUmQaaQ6z8p0s.zcTbHe6Ax6lHfvTN7JUj7VgO4x8Vl-vk1u0kZcrkKmKWw8K9r0shyut_at5Q0ri6zTewnAv2g1Dc8dauuyd-Sw.sc3';
const clientId = '5065059336212';
const loginParams = new URLSearchParams();
loginParams.append('loginID', this.loginID);
loginParams.append('password', this.password);
loginParams.append('APIKey', apiKey);
loginParams.append('gmid', gmid);
const loginResponse = (await axios_1.default.post('https://accounts.eu1.gigya.com/accounts.login', loginParams)).data;
const token = loginResponse.sessionInfo.cookieValue ?? null;
if (!token) {
throw new Error('Login failed');
}
const uid = loginResponse.UID;
const jwtParams = new URLSearchParams();
jwtParams.append('APIKey', apiKey);
jwtParams.append('gmid', gmid);
jwtParams.append('login_token', token);
const jwtResponse = (await axios_1.default.post('https://accounts.eu1.gigya.com/accounts.getJWT', jwtParams)).data;
const authorizeResponse = (await axios_1.default.post('https://oauth.hijuconn.com/oauth/authorize', {
client_id: clientId,
idToken: jwtResponse.id_token,
response_type: 'code',
redirect_uri: 'https://api.connectlife.io/swagger/oauth2-redirect.html',
thirdType: 'CDC',
thirdClientId: uid,
})).data;
const tokenParams = new URLSearchParams();
tokenParams.append('client_id', clientId);
tokenParams.append('code', authorizeResponse.code);
tokenParams.append('grant_type', 'authorization_code');
tokenParams.append('client_secret', '07swfKgvJhC3ydOUS9YV_SwVz0i4LKqlOLGNUukYHVMsJRF1b-iWeUGcNlXyYCeK');
tokenParams.append('redirect_uri', 'https://api.connectlife.io/swagger/oauth2-redirect.html');
const tokenResponse = (await axios_1.default.post('https://oauth.hijuconn.com/oauth/token', tokenParams)).data;
cache.set('access_token', tokenResponse.access_token, 60 * 60);
return tokenResponse.access_token;
}
async getDeviceIdByNickName(deviceNickName) {
const deviceIdCache = cache.get(`device_id_${deviceNickName}`);
if (deviceIdCache) {
return deviceIdCache;
}
const deviceId = axios_1.default
.get('https://connectlife.bapi.ovh/appliances', {
headers: {
'X-Token': await this.getAccessToken(),
},
})
.then(({ data }) => data.find(({ deviceNickName: nickname }) => nickname?.toLocaleLowerCase() === deviceNickName.toLowerCase())?.puid);
cache.set(`device_id_${deviceNickName}`, deviceId);
return deviceId;
}
async changeDeviceProperties(deviceNickname, properties) {
axios_1.default.post('https://connectlife.bapi.ovh/appliances', {
puid: await this.getDeviceIdByNickName(deviceNickname),
properties,
}, {
headers: {
'X-Token': await this.getAccessToken(),
},
});
}
async getDeviceProperties(deviceNickname, properties) {
const result = await axios_1.default
.get('https://connectlife.bapi.ovh/appliances', {
headers: {
'X-Token': await this.getAccessToken(),
},
})
.then(({ data }) => Object.entries(data?.find?.(async ({ puid }) => puid === (await this.getDeviceIdByNickName(deviceNickname)))?.statusList || {}).reduce((acc, [key, value]) => {
const format = properties[key];
if (!format) {
return acc;
}
acc[key] =
format === 'integer' ? parseInt(value) : `${value}`;
return acc;
// eslint-disable-next-line
}, {}))
.catch(() => ({
// fallback to some defaults values in case of any error
...Object.fromEntries(Object.entries(properties).map(([key, type]) => [
key,
type === 'integer' ? 0 : '',
])),
}));
if (this.options.debugMode) {
this.options.log?.info('getDeviceProperties', result);
}
return result;
}
}
exports.ConnectLifeApi = ConnectLifeApi;
//# sourceMappingURL=ConnectLifeApi.js.map