Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
// For testing multi-car when you only have one car
/*
vehicles[1] = {};
vehicles[1].id_s = vehicles[0].id_s;
vehicles[1].display_name = "Tessie";
*/
session.set("vehicles", vehicles);
session.set("options", options);
return vehicles;
});
} else if (req.sessionDetails.accessToken) {
log("OAuth token passed by Alexa");
options = {authToken: req.sessionDetails.accessToken};
return tjs.vehiclesAsync(options)
.then(function(vehicles) {
log("vehicles completed.");
// ensure we have a default vehicle
options.vehicleID = vehicles[0].id_s;
session.set("vehicles", vehicles);
session.set("options", options);
return vehicles;
});
} else {
// promise fails with error response!
return new Promise(function (fulfill, reject) {
reject("No login or token found!");
});
}
}
}
return tjs.vehiclesAsync(options);
})
.then(function(vehicles) {
// ensure we have a default vehicle
options.vehicleID = vehicles[0].id_s;
session.set("vehicles", vehicles);
session.set("options", options);
return vehicles;
});
} else if (token) {
// if token found in ENV then use it
log("OAuth token found in process ENV");
options = {authToken: token};
return tjs.vehiclesAsync(options)
.then(function(vehicles) {
// ensure we have a default vehicle
options.vehicleID = vehicles[0].id_s;
// For testing multi-car when you only have one car
/*
vehicles[1] = {};
vehicles[1].id_s = vehicles[0].id_s;
vehicles[1].display_name = "Tessie";
*/
session.set("vehicles", vehicles);
session.set("options", options);
return vehicles;
});
} else if (req.sessionDetails.accessToken) {
log("OAuth token passed by Alexa");
async function triggerHomeLink(callback) {
// This is a bit more involved than it really needs to be
try {
let options = {"authToken": g_BearerToken, "vehicleID": Config.tesla.vehicleId};
// Retrieve vehicle metadata first to determine if we need to wake it up, and for tokens
let vehicle = (await Tesla.vehiclesAsync(options)).find(v => v.id_s == Config.tesla.vehicleId);
if (!vehicle) {
return callback(new Error("Cannot find vehicle"));
}
if (!vehicle.tokens || !vehicle.tokens[0]) {
return callback(new Error("No tokens found"));
}
if (['offline', 'asleep'].includes(vehicle.state)) {
// Wake up the car first
await Tesla.wakeUpAsync(options);
await new Promise(resolve => setTimeout(resolve, 5000));
}
// Get the car's drive state because we need its coordinates
let driveState = await Tesla.driveStateAsync(options);
g_BearerTokenExpiresTime = Infinity;
auth();
return;
}
if (Date.now() - g_LastPoll < 10000) {
// last poll was under 10 seconds ago
enqueueRequest();
return;
}
log("Requesting data");
let options = {"authToken": g_BearerToken, "vehicleID": Config.tesla.vehicleId};
try {
let vehicleMetadata = (await Tesla.vehiclesAsync(options)).find(v => (v.id_s || v.id) == Config.tesla.vehicleId);
if (!vehicleMetadata) {
log("Unable to retrieve metadata for vehicle: vehicle not found");
return;
}
if (['asleep', 'offline'].includes(vehicleMetadata.state)) {
// Car is asleep
log('Vehicle is asleep');
setState(VehicleState.Asleep);
if (g_CurrentState != VehicleState.Awoken && Date.now() - g_CarLastSeenAwake < (1000 * 60 * 60 * 3)) {
// Only wake it up to poll data every 3 hours
g_LastPoll = Date.now();
enqueueRequest();
return;
}
if (!vehicle) {
return callback(new Error("Cannot find vehicle"));
}
if (!vehicle.tokens || !vehicle.tokens[0]) {
return callback(new Error("No tokens found"));
}
if (['offline', 'asleep'].includes(vehicle.state)) {
// Wake up the car first
await Tesla.wakeUpAsync(options);
await new Promise(resolve => setTimeout(resolve, 5000));
}
// Get the car's drive state because we need its coordinates
let driveState = await Tesla.driveStateAsync(options);
let latitude = driveState.latitude;
let longitude = driveState.longitude;
let success = false;
let otherVehicleId = vehicle.vehicle_id;
let token = vehicle.tokens[0];
let ws = new WS13.WebSocket("wss://" + Config.tesla.email + ":" + token + "@streaming.vn.teslamotors.com/connect/" + otherVehicleId);
ws.on('connected', () => {
log("WS connected to Tesla API");
});
ws.on('disconnected', (code, reason, initiatedByUs) => {
if (initiatedByUs) {
log("Successfully disconnected from Tesla WS API");
} else {
if (['asleep', 'offline'].includes(vehicleMetadata.state)) {
// Car is asleep
log('Vehicle is asleep');
setState(VehicleState.Asleep);
if (g_CurrentState != VehicleState.Awoken && Date.now() - g_CarLastSeenAwake < (1000 * 60 * 60 * 3)) {
// Only wake it up to poll data every 3 hours
g_LastPoll = Date.now();
enqueueRequest();
return;
}
// We need to wake up the car
log('Waking vehicle...');
await Tesla.wakeUpAsync(options);
// When this request completes, the vehicle isn't already awoken. It's waking up.
// The official Tesla app then does the vehicle data request repeatedly until it works
}
let result = null;
for (let i = 1; i <= 20; i++) {
// Retry at most 20 times
try {
result = await Tesla.vehicleDataAsync(options);
break; // it worked
} catch (ex) {
log(`Error retrieving vehicle data on request ${i}: ${ex.message}`);
if (i == 20) {
throw ex; // this attempt failed
}
try {
let options = {"authToken": g_BearerToken, "vehicleID": Config.tesla.vehicleId};
// Retrieve vehicle metadata first to determine if we need to wake it up, and for tokens
let vehicle = (await Tesla.vehiclesAsync(options)).find(v => v.id_s == Config.tesla.vehicleId);
if (!vehicle) {
return callback(new Error("Cannot find vehicle"));
}
if (!vehicle.tokens || !vehicle.tokens[0]) {
return callback(new Error("No tokens found"));
}
if (['offline', 'asleep'].includes(vehicle.state)) {
// Wake up the car first
await Tesla.wakeUpAsync(options);
await new Promise(resolve => setTimeout(resolve, 5000));
}
// Get the car's drive state because we need its coordinates
let driveState = await Tesla.driveStateAsync(options);
let latitude = driveState.latitude;
let longitude = driveState.longitude;
let success = false;
let otherVehicleId = vehicle.vehicle_id;
let token = vehicle.tokens[0];
let ws = new WS13.WebSocket("wss://" + Config.tesla.email + ":" + token + "@streaming.vn.teslamotors.com/connect/" + otherVehicleId);
ws.on('connected', () => {
log("WS connected to Tesla API");
});
// if we already have vehicles and options then the promise is fulfilled
if (vehicles && options) {
log("Found existing vehicle session info");
return new Promise(function (fulfill, reject) {
fulfill(vehicles);
});
} else {
// otherwise we need to get the vehicle information
log("No existing session info found!");
// if user/pass provided then login
if (username && password) {
log("username/pwd found");
return tjs.loginAsync(username, password)
.then(function(result) {
options = {authToken: result.authToken};
return tjs.vehiclesAsync(options);
})
.then(function(vehicles) {
// ensure we have a default vehicle
options.vehicleID = vehicles[0].id_s;
session.set("vehicles", vehicles);
session.set("options", options);
return vehicles;
});
} else if (token) {
// if token found in ENV then use it
log("OAuth token found in process ENV");
options = {authToken: token};
enqueueRequest();
return;
}
// We need to wake up the car
log('Waking vehicle...');
await Tesla.wakeUpAsync(options);
// When this request completes, the vehicle isn't already awoken. It's waking up.
// The official Tesla app then does the vehicle data request repeatedly until it works
}
let result = null;
for (let i = 1; i <= 20; i++) {
// Retry at most 20 times
try {
result = await Tesla.vehicleDataAsync(options);
break; // it worked
} catch (ex) {
log(`Error retrieving vehicle data on request ${i}: ${ex.message}`);
if (i == 20) {
throw ex; // this attempt failed
}
// Wait a second and try again
await new Promise((resolve) => setTimeout(resolve, 1000));
}
}
g_LastPoll = g_CarLastSeenAwake = Date.now();
g_DataListenerSockets.forEach((socket) => {
.then( function(vehicles) {
// get options object - which must include authToken and vehicleID
var options = getOptionsFromCarName(session, carName);
tjs.chargeStateAsync(options)
.done( function(chargeState) {
var str = "";
if (options.display_name) {
str = options.display_name;
} else {
str = "The car";
}
if (chargeState.charging_state != "Disconnected") {
str += " is plugged in.";
} else {
str += " is not plugged in.";
}
res.say(str).send();
});