@shuangbing/bmw-connected-drive
Version:
This package can be used to access the BMW ConnectedDrive services.
114 lines • 6.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConnectedDrive = void 0;
const Account_1 = require("./Account");
const cross_fetch_1 = require("cross-fetch");
const Constants_1 = require("./Constants");
const RemoteServices_1 = require("./RemoteServices");
const RemoteServiceResponse_1 = require("./RemoteServiceResponse");
const ServiceStatus_1 = require("./ServiceStatus");
const VehicleStatus_1 = require("./VehicleStatus");
const RemoteServiceExecutionState_1 = require("./RemoteServiceExecutionState");
class ConnectedDrive {
constructor(username, password, region, tokenStore, logger) {
this.serviceExecutionStatusCheckInterval = 5000;
this.account = new Account_1.Account(username, password, region, tokenStore);
this.logger = logger;
}
async getVehicles() {
var _a;
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.LogInformation("Getting vehicles");
const url = `https://${Constants_1.Constants.ServerEndpoints[this.account.region]}/eadrax-vcs/v1/vehicles?apptimezone=1440.0&appDateTime=${new Date().valueOf()}&tireGuardMode=ENABLED`;
return (await this.request(url));
}
async getVehicleStatus(vin) {
var _a;
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.LogInformation("Getting vehicle status.");
let url = `https://${Constants_1.Constants.ServerEndpoints[this.account.region]}${Constants_1.Constants.getVehicleStatus}`;
url = url.replace("{vehicleVin}", vin);
return new VehicleStatus_1.VehicleStatus(await this.request(url));
}
async lockDoors(vin, waitExecution = false) {
var _a;
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.LogInformation("Locking doors");
return await this.executeService(vin, RemoteServices_1.RemoteServices.LockDoors, { "clientId": 2, "doorControl": "LOCK" }, waitExecution);
}
async unlockDoors(vin, waitExecution = false) {
var _a;
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.LogInformation("Unlocking doors");
return await this.executeService(vin, RemoteServices_1.RemoteServices.UnlockDoors, { "clientId": 2, "doorSelection": "COMPLETE" }, waitExecution);
}
async startClimateControl(vin, waitExecution = false) {
var _a;
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.LogInformation("Start Climate Control");
return await this.executeService(vin, RemoteServices_1.RemoteServices.ClimateNow, { "rcnAction": "START" }, waitExecution);
}
async stopClimateControl(vin, waitExecution = false) {
var _a;
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.LogInformation("Stop Climate Control");
return await this.executeService(vin, RemoteServices_1.RemoteServices.ClimateNow, { "rcnAction": "STOP" }, waitExecution);
}
async flashLights(vin, waitExecution = false) {
return await this.executeService(vin, RemoteServices_1.RemoteServices.FlashLight, { "number": 2, "pause": 1, "duration": 1 }, waitExecution);
}
async blowHorn(vin, waitExecution = false) {
var _a;
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.LogInformation("Blow Horn");
return await this.executeService(vin, RemoteServices_1.RemoteServices.BlowHorn, { "number": 2, "pause": 1, "duration": 1 }, waitExecution);
}
async executeService(vin, serviceType, requestBody, waitExecution) {
let url = `https://${Constants_1.Constants.LegacyServerEndpoints[this.account.region]}${Constants_1.Constants.executeRemoteServices}`;
url = url.replace("{vehicleVin}", vin);
url = url.replace("{serviceType}", serviceType);
const response = new RemoteServiceResponse_1.RemoteServiceResponse(await this.request(url, true, requestBody));
if (waitExecution) {
const timer = setInterval(async () => {
const status = await this.getServiceStatus(vin);
if (status.status === RemoteServiceExecutionState_1.RemoteServiceExecutionState.EXECUTED || status.status === RemoteServiceExecutionState_1.RemoteServiceExecutionState.CANCELLED_WITH_ERROR) {
clearInterval(timer);
}
}, this.serviceExecutionStatusCheckInterval);
}
return response;
}
async getServiceStatus(vin) {
let url = `https://${Constants_1.Constants.LegacyServerEndpoints[this.account.region]}${Constants_1.Constants.statusRemoteServices}`;
url = url.replace("{vehicleVin}", vin);
return new ServiceStatus_1.ServiceStatus(await this.request(url));
}
async sendMessage(vin, subject, message) {
var _a;
let url = `https://${Constants_1.Constants.LegacyServerEndpoints[this.account.region]}${Constants_1.Constants.sendMessage}`;
const requestBody = { "vins": [vin], "message": message, "subject": subject };
return ((_a = (await this.request(url, true, requestBody))) === null || _a === void 0 ? void 0 : _a.status) === "OK";
}
async request(url, isPost = false, requestBody) {
var _a, _b;
const httpMethod = isPost ? "POST" : "GET";
const requestBodyContent = requestBody ? JSON.stringify(requestBody) : null;
const headers = {
"accept": "application/json",
"Content-Type": "application/json;charset=UTF-8",
"Authorization": `Bearer ${(await this.account.getToken()).accessToken}`,
"x-user-agent": "android(v1.07_20200330);bmw;1.7.0(11152)"
};
if (requestBodyContent) {
headers.Accept = "application/json;charset=utf-8";
}
const response = await (0, cross_fetch_1.fetch)(url, {
method: httpMethod,
body: requestBodyContent,
headers: headers,
credentials: "same-origin"
});
const responseString = await response.text();
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.LogTrace(`Request: ${url}, Method: ${httpMethod}, Headers: ${JSON.stringify(headers)}, Body: ${requestBodyContent}`);
(_b = this.logger) === null || _b === void 0 ? void 0 : _b.LogTrace(`Response: ${response.status}, Headers: ${JSON.stringify(response.headers)}, Body: ${responseString}`);
if (!response.ok) {
throw new Error(`Error occurred while attempting '${httpMethod}' at url '${url}' with ${response.status} body (${requestBodyContent})\n${responseString}`);
}
return JSON.parse(responseString);
}
}
exports.ConnectedDrive = ConnectedDrive;
//# sourceMappingURL=ConnectedDrive.js.map