Avatar

@seep

1 public val
Joined November 27, 2023

An API for mysubaru.com to enable remote start and stop.

Requires env vars (val.town secrets) named: SUBARU_USERNAME, SUBARU_PASSWORD, SUBARU_DEVICEID, SUBARU_VEHICLEKEY, SUBARU_PIN. The username, password, and PIN should match your mysubaru.com credentials. The device ID and vehicle key can be found by inspecting the request body of a login network request at mysubaru.com.

Readme
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import assert from "node:assert/strict";
import process from "node:process";
const { wrapFetch: FetchWithCookie } = await import("https://deno.land/x/another_cookiejar@v5.0.3/mod.ts");
const fetch = FetchWithCookie();
type ServiceResponse = { id: string; success: boolean };
export async function login() {
const body = new URLSearchParams({
"username": process.env.SUBARU_USERNAME,
"password": process.env.SUBARU_PASSWORD,
"deviceId": process.env.SUBARU_DEVICEID,
"lastSelectedVehicleKey": process.env.SUBARU_VEHICLEKEY,
});
const dest = "https://www.mysubaru.com/login";
const resp = await fetch(dest, { method: "POST", body });
assert(resp.status == 200, `unexpected login response status: ${resp.status}`);
}
export async function status(id: string): Promise<ServiceResponse> {
const body = new URLSearchParams({
serviceRequestId: id,
});
const url = "https://www.mysubaru.com/service/g2/remoteService/status.json";
const res = await fetch(url, { method: "POST", body });
return await parseServiceResponse(res);
}
export async function start(overrides?: Record<string, string>): Promise<ServiceResponse> {
const opts = Object.assign({
"now": `${Date.now()}`,
"pin": process.env.SUBARU_PIN,
"delay": "0",
"horn": "true",
"unlockDoorType": "ALL_DOORS_CMD",
"name": "Auto",
"runTimeMinutes": "10",
"climateZoneFrontTemp": "74",
"climateZoneFrontAirMode": "AUTO",
"climateZoneFrontAirVolume": "AUTO",
"outerAirCirculation": "auto",
"heatedRearWindowActive": "false",
"airConditionOn": "false",
"heatedSeatFrontLeft": "off",
Next