UNPKG

homebridge-connect-my-pool

Version:
318 lines 17.2 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.AstralGatewayAPI = void 0; const events_1 = __importDefault(require("events")); const request_promise_1 = __importDefault(require("request-promise")); const cheerio_1 = __importDefault(require("cheerio")); const tough_cookie_1 = require("tough-cookie"); const constants_1 = require("./constants"); const ajaxResponse_1 = require("./ajaxResponse"); const BASE_URL = 'https://connectmypool.com.au'; class AstralGatewayAPI extends events_1.default { constructor(config, logger) { super(); this.log = logger; this.username = config.username || 'email'; this.password = config.password || 'password'; this.cookieJar = request_promise_1.default.jar(); } get ConfiguredZones() { return [ { name: 'Pool Pumps', type: "pool_and_spa" /* POOL_AND_SPA */ }, { name: 'Pool Lighting', type: "lighting" /* LIGHTING */ }, { name: 'Pool Heater', type: "heating" /* HEATING */ }, { name: 'Pool Solar Heater', type: "solar" /* SOLAR */ } ]; } request(url, method = 'GET', formData, headers) { return new Promise((success, fail) => { var baseUrl = BASE_URL; var options = { method: method, resolveWithFullResponse: true, simple: false, uri: baseUrl + url }; if (headers) options.headers = headers; if (!(method === 'GET' && url === constants_1.URLS.login_url)) options.jar = this.cookieJar; if (formData) options.form = formData; request_promise_1.default(options) .then(async (response) => { var body = response.body; var resp = new ajaxResponse_1.AjaxResponse(response.statusCode, body, response.headers); if (response.statusCode === 200) { //success! const $ = cheerio_1.default.load(body); if ($('#ucLogin1$txtUserName').length > 0) { await this.login(); return this.request(url, method, formData, headers); } else { var p = $("input"); //var inputs : InputField[] = []; p.each((index, e) => { var i = e; resp.inputs.push(new ajaxResponse_1.InputField(i.attribs.name, i.attribs.value, i.attribs.id)); }); } } else { // if ('location' in response.headers) { // resp.url = response.headers.location; // } } if (response.headers['set-cookie']) { var cookies; if (response.headers['set-cookie'] instanceof Array) cookies = response.headers['set-cookie'].map(c => tough_cookie_1.Cookie.parse(c)); else { var cookie = tough_cookie_1.Cookie.parse(response.headers['set-cookie']); if (cookie) cookies = [cookie]; } if (cookies) { cookies.forEach(c => { if (c) this.cookieJar.setCookie(c, baseUrl); }); } } resp.cookies = this.cookieJar; success(resp); }) .catch(function (err) { fail(err); //handle error }); }); } async getFavourites(inputs) { var response = await this.request(constants_1.URLS.favourites_url); var favourites = new ajaxResponse_1.ZoneResponse("favourites" /* FAVOURITES */, response.inputs); this.emit("ZONE" /* ZONE */, favourites); return favourites; } async getPoolSpa(inputs) { var _a, _b; var response = await this.request(constants_1.URLS.pool_spa_url); const $ = cheerio_1.default.load(response.body); var poolSpaMode = $(constants_1.COMMANDS.POOL_SPA.id_pump_mode_pool); var modePoolSpa = null; if (poolSpaMode.length > 0) { modePoolSpa = poolSpaMode[0].attribs.class === 'btn_blue' ? "POOL" /* POOL */ : "SPA" /* SPA */; } var poolPumpMode = $(constants_1.COMMANDS.POOL_SPA.id_pool_filter); var poolPumpModeState = null; if (poolPumpMode.length > 0) { poolPumpModeState = $(poolPumpMode[0]).text(); } var spaJetMode = $(constants_1.COMMANDS.POOL_SPA.id_spa_jets); var spaJetsModeState = null; if (spaJetMode.length > 0) { spaJetsModeState = $(spaJetMode[0]).text(); } var spaBlowerMode = $(constants_1.COMMANDS.POOL_SPA.id_spa_blower); var spaBlowerModeState = null; if (spaBlowerMode.length > 0) { spaBlowerModeState = $(spaBlowerMode[0]).text(); } var isPoolPumpRunning = $(constants_1.COMMANDS.POOL_SPA.id_pool_filter_is_running).length > 0; var isSpaJetsRunning = $(constants_1.COMMANDS.POOL_SPA.id_spa_jets_is_running).length > 0; var isSpaBlowerRunning = $(constants_1.COMMANDS.POOL_SPA.id_spa_blower_is_running).length > 0; var poolSpa = new ajaxResponse_1.PoolSpaResponse("pool_and_spa" /* POOL_AND_SPA */, modePoolSpa, poolPumpModeState, isPoolPumpRunning, spaJetsModeState, isSpaJetsRunning, spaBlowerModeState, isSpaBlowerRunning, response.inputs); if (inputs && !modePoolSpa) { (_a = this.log) === null || _a === void 0 ? void 0 : _a.info('PoolSpaResponse No Status', response.body); } else (_b = this.log) === null || _b === void 0 ? void 0 : _b.info('PoolSpaResponse', inputs ? 'With Inputs' : 'No Inputs', poolSpa.poolSpaMode, poolSpa.poolFilterMode, poolSpa.isPoolFilterRunning, poolSpa.spaJetsMode, poolSpa.isSpaJetsRunning, poolSpa.spaBlowerMode, poolSpa.isSpaBlowerRunning); this.emit("ZONE" /* ZONE */, poolSpa); return poolSpa; } async getLighting(inputs) { var response = await this.request(constants_1.URLS.lighting_url); var lighting = new ajaxResponse_1.ZoneResponse("lighting" /* LIGHTING */, response.inputs); this.emit("ZONE" /* ZONE */, lighting); return lighting; } async getHeating(inputs) { var _a, _b; var response; // if (inputs) { // var formData: FormData = {}; // formData['ctl00$ScriptManager2'] = 'ctl00$ScriptManager2|ctl00$cpPageContent$tmrAutoPost'; // inputs.forEach(i => { // if (i.name.includes('$hdn') || i.name.startsWith('__')) // formData[i.name] = i.value ? i.value : ''; // }) // formData['__EVENTTARGET'] = 'ctl00$cpPageContent$tmrAutoPost'; // formData['__EVENTARGUMENT'] = null; // formData['__LASTFOCUS'] = null; // formData['ctl00$ddlPool'] = this.poolId // formData['__ASYNCPOST'] = true; // var headers: {key: string, value: string}[] = []; // headers.push({key: "content-type", value: "application/x-www-form-urlencoded; charset=UTF-8"}); // headers.push({key: 'user-agent', value:'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Safari/537.36'}); // headers.push({key: 'x-microsoftajax', value:'Delta=true'}); // headers.push({ key: 'x-requested-with', value: 'XMLHttpRequest' }); // headers.push({ key: 'origin', value: BASE_URL}); // headers.push({ key: 'referer', value: BASE_URL + URLS.heating_url}); // headers.push({ key: 'accept', value: '*.*'}); // response = await this.request(URLS.heating_url, 'POST', formData, headers) // if (response.body.includes('ScriptManager.SupportsPartialRendering')) // { // this.log?.error('getHeating', 'Partial Rendering error', headers) // response = await this.request(URLS.heating_url); // } // } // else response = await this.request(constants_1.URLS.heating_url); const $ = cheerio_1.default.load(response.body); var currentTemp = $(constants_1.COMMANDS.HEATING.id_current_temp); var status = response.inputs.find(i => i.id === constants_1.COMMANDS.HEATING.status); var heatingMode = response.inputs.find(i => i.id === constants_1.COMMANDS.HEATING.mode_pool_spa); var modePoolSpa = heatingMode ? heatingMode.value === '1' ? "POOL" /* POOL */ : "SPA" /* SPA */ : null; var statusOnOff = status ? status.value === '1' ? "ON" /* ON */ : "OFF" /* OFF */ : null; var isRunning = $(constants_1.COMMANDS.HEATING.id_is_running).length > 0; var currentId = constants_1.COMMANDS.HEATING.pool_temp; if (modePoolSpa === "SPA" /* SPA */) currentId = constants_1.COMMANDS.HEATING.spa_temp; var currentValue = response.inputs.find(i => i.id === currentId); var heating = new ajaxResponse_1.HeatingResponse("heating" /* HEATING */, statusOnOff, isRunning, currentTemp ? Number(currentTemp.text()) : null, currentValue ? Number(currentValue.value) : null, modePoolSpa, response.inputs); if (inputs && !status) { (_a = this.log) === null || _a === void 0 ? void 0 : _a.info('HeatingResponse No Status', response.body); } else (_b = this.log) === null || _b === void 0 ? void 0 : _b.info('HeatingResponse', inputs ? 'With Inputs' : 'No Inputs', heating.status, heating.isRunning, heating.heatingMode, heating.currentTemp, heating.targetTemp); this.emit("ZONE" /* ZONE */, heating); return heating; } async getSolar(inputs) { var _a, _b; var response = await this.request(constants_1.URLS.solar_url); const $ = cheerio_1.default.load(response.body); var currentTemp = $(constants_1.COMMANDS.SOLAR.id_current_temp); var status = response.inputs.find(i => i.id === constants_1.COMMANDS.SOLAR.status); var rooftemp = $(constants_1.COMMANDS.SOLAR.id_roof_temp); var statusOnOffAuto = status ? status.value === '2' ? "ON" /* ON */ : status.value === '1' ? "AUTO" /* AUTO */ : "OFF" /* OFF */ : null; var running = $(constants_1.COMMANDS.SOLAR.id_is_running); var isRunning = running.length > 0; var currentId = constants_1.COMMANDS.SOLAR.pool_temp; var currentValue = response.inputs.find(i => i.id === currentId); var solar = new ajaxResponse_1.SolarResponse("solar" /* SOLAR */, statusOnOffAuto, isRunning, currentTemp ? Number(currentTemp.text()) : null, currentValue ? Number(currentValue.value) : null, rooftemp ? Number(rooftemp.text()) : null, response.inputs); if (inputs && !status) { (_a = this.log) === null || _a === void 0 ? void 0 : _a.info('SolarResponse No Status', response.body); } else (_b = this.log) === null || _b === void 0 ? void 0 : _b.info('SolarResponse', inputs ? 'With Inputs' : 'No Inputs', solar.status, solar.isRunning, solar.currentTemp, solar.roofTemp, solar.targetTemp); this.emit("ZONE" /* ZONE */, solar); return solar; } async getChemistry(inputs) { var response = await this.request(constants_1.URLS.chemistry_url); var chemistry = new ajaxResponse_1.ZoneResponse("chemistry" /* CHEMISTRY */, response.inputs); this.emit("ZONE" /* ZONE */, chemistry); return chemistry; } getFormData(inputs, target, targetArgument) { var _a, _b, _c, _d, _e, _f; var viewstate = null; var viewstategenerator = null; var eventvalidation = null; if (inputs) { viewstate = (_b = (_a = inputs.find(s => s.name === '__VIEWSTATE')) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : null; viewstategenerator = (_d = (_c = inputs.find(s => s.name === '__VIEWSTATEGENERATOR')) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : null; eventvalidation = (_f = (_e = inputs.find(s => s.name === '__EVENTVALIDATION')) === null || _e === void 0 ? void 0 : _e.value) !== null && _f !== void 0 ? _f : null; } return { ['__LASTFOCUS']: null, ['__EVENTTARGET']: target !== null && target !== void 0 ? target : null, ['__EVENTARGUMENT']: targetArgument !== null && targetArgument !== void 0 ? targetArgument : null, ['__VIEWSTATE']: viewstate, ['__VIEWSTATEGENERATOR']: viewstategenerator, ['__EVENTVALIDATION']: eventvalidation, }; } getPoolId(html) { const $ = cheerio_1.default.load(html); return parseInt($('#ddlPool option:selected').val(), 10); } async login() { var response = await this.request(constants_1.URLS.login_url); var formData = this.getFormData(response.inputs); formData['ucLogin1$txtUserName'] = this.username; formData['ucLogin1$txtPassword'] = this.password; formData['ucLogin1$btnLogin'] = 'Login'; response = await this.request(constants_1.URLS.login_url, 'POST', formData); if (response.statusCode === 302) { response = await this.request(constants_1.URLS.home_url); this.poolId = this.getPoolId(response.body); formData = this.getFormData(response.inputs, 'ctl00$ddlPool'); formData['ctl00$ddlPool'] = this.poolId; response = await this.request(constants_1.URLS.home_url, 'POST', formData); return response; } else throw new Error("Unable to Login"); } getSystemStatus(status) { var self = this; return new Promise((success, fail) => { var _a, _b, _c, _d, _e, _f, _g; var Promises = []; Promises.push(self.getFavourites((_a = status === null || status === void 0 ? void 0 : status.favourites) === null || _a === void 0 ? void 0 : _a.inputs)); Promises.push(self.getPoolSpa((_b = status === null || status === void 0 ? void 0 : status.poolSpa) === null || _b === void 0 ? void 0 : _b.inputs)); Promises.push(self.getLighting((_c = status === null || status === void 0 ? void 0 : status.lighting) === null || _c === void 0 ? void 0 : _c.inputs)); Promises.push(self.getHeating((_d = status === null || status === void 0 ? void 0 : status.heating) === null || _d === void 0 ? void 0 : _d.inputs)); Promises.push(self.getSolar((_e = status === null || status === void 0 ? void 0 : status.solar) === null || _e === void 0 ? void 0 : _e.inputs)); Promises.push(self.getChemistry((_f = status === null || status === void 0 ? void 0 : status.chemistry) === null || _f === void 0 ? void 0 : _f.inputs)); (_g = this.log) === null || _g === void 0 ? void 0 : _g.debug("Getting System Status"); Promise.all(Promises).then((responses) => { //this.log?.debug('Responses', responses); var status = { favourites: responses[0], poolSpa: responses[1], lighting: responses[2], heating: responses[3], solar: responses[4], chemistry: responses[5], }; self.emit("SYSTEM_STATUS" /* SYSTEM_STATUS */, status); success(status); }).catch((error) => { fail("Error in Getting System Status " + error); }); }); } async connect() { return new Promise((success, fail) => { this.login().then(() => { success(this.getSystemStatus()); }).catch((error) => { fail('Unable to login ' + error); }); }); } async close() { this.emit("close" /* CLOSE */); } } exports.AstralGatewayAPI = AstralGatewayAPI; //# sourceMappingURL=astralGatewayAPI.js.map