node-chargepoint 0.3.2 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +25 -11
- package/dist/index.cjs +25 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +25 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -335,7 +335,12 @@ var ChargingSession = class _ChargingSession {
|
|
|
335
335
|
}
|
|
336
336
|
static async start(deviceId, client) {
|
|
337
337
|
await sendCommand(client, "start", deviceId);
|
|
338
|
-
const
|
|
338
|
+
const deadline = Date.now() + 15e3;
|
|
339
|
+
let status = await client.getUserChargingStatus();
|
|
340
|
+
while (!status && Date.now() < deadline) {
|
|
341
|
+
await sleep(2e3);
|
|
342
|
+
status = await client.getUserChargingStatus();
|
|
343
|
+
}
|
|
339
344
|
if (!status) {
|
|
340
345
|
throw new APIError("No active charging session found after start command.");
|
|
341
346
|
}
|
|
@@ -377,7 +382,7 @@ var ChargePoint = class _ChargePoint {
|
|
|
377
382
|
return client;
|
|
378
383
|
}
|
|
379
384
|
_setToken(token, region) {
|
|
380
|
-
this._coulombToken = token;
|
|
385
|
+
this._coulombToken = decodeURIComponent(token);
|
|
381
386
|
this._region = region;
|
|
382
387
|
}
|
|
383
388
|
/** @internal Used by session.ts and tests. */
|
|
@@ -398,7 +403,7 @@ var ChargePoint = class _ChargePoint {
|
|
|
398
403
|
for (const cookie of setCookies) {
|
|
399
404
|
const match = /^coulomb_sess=([^;]+)/.exec(cookie);
|
|
400
405
|
if (match) {
|
|
401
|
-
this._coulombToken = match[1] ??
|
|
406
|
+
this._coulombToken = decodeURIComponent(match[1] ?? "");
|
|
402
407
|
break;
|
|
403
408
|
}
|
|
404
409
|
}
|
|
@@ -418,6 +423,13 @@ var ChargePoint = class _ChargePoint {
|
|
|
418
423
|
}
|
|
419
424
|
return response;
|
|
420
425
|
}
|
|
426
|
+
async _errorBody(response) {
|
|
427
|
+
try {
|
|
428
|
+
return await response.clone().text();
|
|
429
|
+
} catch {
|
|
430
|
+
return "";
|
|
431
|
+
}
|
|
432
|
+
}
|
|
421
433
|
// ---------------------------------------------------------------------------
|
|
422
434
|
// Authentication
|
|
423
435
|
// ---------------------------------------------------------------------------
|
|
@@ -624,8 +636,7 @@ var ChargePoint = class _ChargePoint {
|
|
|
624
636
|
const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;
|
|
625
637
|
const response = await this._request("PUT", url, {
|
|
626
638
|
body: JSON.stringify({
|
|
627
|
-
|
|
628
|
-
userSchedule: {
|
|
639
|
+
schedule: {
|
|
629
640
|
weekdays: { startTime: weekdayStart, endTime: weekdayEnd },
|
|
630
641
|
weekends: { startTime: weekendStart, endTime: weekendEnd }
|
|
631
642
|
}
|
|
@@ -633,14 +644,15 @@ var ChargePoint = class _ChargePoint {
|
|
|
633
644
|
headers: { "Content-Type": "application/json" }
|
|
634
645
|
});
|
|
635
646
|
if (!response.ok) {
|
|
636
|
-
|
|
647
|
+
const body = await this._errorBody(response);
|
|
648
|
+
throw new CommunicationError(response.status, `Failed to set home charger schedule. HTTP ${response.status}: ${body}`);
|
|
637
649
|
}
|
|
638
650
|
return await response.json();
|
|
639
651
|
}
|
|
640
652
|
async disableHomeChargerSchedule(chargerId) {
|
|
641
653
|
const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;
|
|
642
654
|
const response = await this._request("PUT", url, {
|
|
643
|
-
body: JSON.stringify({
|
|
655
|
+
body: JSON.stringify({}),
|
|
644
656
|
headers: { "Content-Type": "application/json" }
|
|
645
657
|
});
|
|
646
658
|
if (!response.ok) {
|
|
@@ -651,22 +663,24 @@ var ChargePoint = class _ChargePoint {
|
|
|
651
663
|
async setAmperageLimit(chargerId, amperageLimit) {
|
|
652
664
|
const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/chargers/${chargerId}/charge-amperage-limit`;
|
|
653
665
|
const response = await this._request("PUT", url, {
|
|
654
|
-
body: JSON.stringify({ amperageLimit }),
|
|
666
|
+
body: JSON.stringify({ chargeAmperageLimit: amperageLimit }),
|
|
655
667
|
headers: { "Content-Type": "application/json" }
|
|
656
668
|
});
|
|
657
669
|
if (!response.ok) {
|
|
658
|
-
|
|
670
|
+
const body = await this._errorBody(response);
|
|
671
|
+
throw new CommunicationError(response.status, `Failed to set amperage limit. HTTP ${response.status}: ${body}`);
|
|
659
672
|
}
|
|
660
673
|
await response.text();
|
|
661
674
|
}
|
|
662
675
|
async setLedBrightness(chargerId, level) {
|
|
663
676
|
const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/chargers/${chargerId}/led-brightness`;
|
|
664
677
|
const response = await this._request("PUT", url, {
|
|
665
|
-
body: JSON.stringify({ level }),
|
|
678
|
+
body: JSON.stringify({ ledBrightnessLevel: level }),
|
|
666
679
|
headers: { "Content-Type": "application/json" }
|
|
667
680
|
});
|
|
668
681
|
if (!response.ok) {
|
|
669
|
-
|
|
682
|
+
const body = await this._errorBody(response);
|
|
683
|
+
throw new CommunicationError(response.status, `Failed to set LED brightness. HTTP ${response.status}: ${body}`);
|
|
670
684
|
}
|
|
671
685
|
await response.text();
|
|
672
686
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -312,7 +312,12 @@ var ChargingSession = class _ChargingSession {
|
|
|
312
312
|
}
|
|
313
313
|
static async start(deviceId, client) {
|
|
314
314
|
await sendCommand(client, "start", deviceId);
|
|
315
|
-
const
|
|
315
|
+
const deadline = Date.now() + 15e3;
|
|
316
|
+
let status = await client.getUserChargingStatus();
|
|
317
|
+
while (!status && Date.now() < deadline) {
|
|
318
|
+
await sleep(2e3);
|
|
319
|
+
status = await client.getUserChargingStatus();
|
|
320
|
+
}
|
|
316
321
|
if (!status) {
|
|
317
322
|
throw new APIError("No active charging session found after start command.");
|
|
318
323
|
}
|
|
@@ -354,7 +359,7 @@ var ChargePoint = class _ChargePoint {
|
|
|
354
359
|
return client;
|
|
355
360
|
}
|
|
356
361
|
_setToken(token, region) {
|
|
357
|
-
this._coulombToken = token;
|
|
362
|
+
this._coulombToken = decodeURIComponent(token);
|
|
358
363
|
this._region = region;
|
|
359
364
|
}
|
|
360
365
|
/** @internal Used by session.ts and tests. */
|
|
@@ -375,7 +380,7 @@ var ChargePoint = class _ChargePoint {
|
|
|
375
380
|
for (const cookie of setCookies) {
|
|
376
381
|
const match = /^coulomb_sess=([^;]+)/.exec(cookie);
|
|
377
382
|
if (match) {
|
|
378
|
-
this._coulombToken = match[1] ??
|
|
383
|
+
this._coulombToken = decodeURIComponent(match[1] ?? "");
|
|
379
384
|
break;
|
|
380
385
|
}
|
|
381
386
|
}
|
|
@@ -395,6 +400,13 @@ var ChargePoint = class _ChargePoint {
|
|
|
395
400
|
}
|
|
396
401
|
return response;
|
|
397
402
|
}
|
|
403
|
+
async _errorBody(response) {
|
|
404
|
+
try {
|
|
405
|
+
return await response.clone().text();
|
|
406
|
+
} catch {
|
|
407
|
+
return "";
|
|
408
|
+
}
|
|
409
|
+
}
|
|
398
410
|
// ---------------------------------------------------------------------------
|
|
399
411
|
// Authentication
|
|
400
412
|
// ---------------------------------------------------------------------------
|
|
@@ -601,8 +613,7 @@ var ChargePoint = class _ChargePoint {
|
|
|
601
613
|
const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;
|
|
602
614
|
const response = await this._request("PUT", url, {
|
|
603
615
|
body: JSON.stringify({
|
|
604
|
-
|
|
605
|
-
userSchedule: {
|
|
616
|
+
schedule: {
|
|
606
617
|
weekdays: { startTime: weekdayStart, endTime: weekdayEnd },
|
|
607
618
|
weekends: { startTime: weekendStart, endTime: weekendEnd }
|
|
608
619
|
}
|
|
@@ -610,14 +621,15 @@ var ChargePoint = class _ChargePoint {
|
|
|
610
621
|
headers: { "Content-Type": "application/json" }
|
|
611
622
|
});
|
|
612
623
|
if (!response.ok) {
|
|
613
|
-
|
|
624
|
+
const body = await this._errorBody(response);
|
|
625
|
+
throw new CommunicationError(response.status, `Failed to set home charger schedule. HTTP ${response.status}: ${body}`);
|
|
614
626
|
}
|
|
615
627
|
return await response.json();
|
|
616
628
|
}
|
|
617
629
|
async disableHomeChargerSchedule(chargerId) {
|
|
618
630
|
const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;
|
|
619
631
|
const response = await this._request("PUT", url, {
|
|
620
|
-
body: JSON.stringify({
|
|
632
|
+
body: JSON.stringify({}),
|
|
621
633
|
headers: { "Content-Type": "application/json" }
|
|
622
634
|
});
|
|
623
635
|
if (!response.ok) {
|
|
@@ -628,22 +640,24 @@ var ChargePoint = class _ChargePoint {
|
|
|
628
640
|
async setAmperageLimit(chargerId, amperageLimit) {
|
|
629
641
|
const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/chargers/${chargerId}/charge-amperage-limit`;
|
|
630
642
|
const response = await this._request("PUT", url, {
|
|
631
|
-
body: JSON.stringify({ amperageLimit }),
|
|
643
|
+
body: JSON.stringify({ chargeAmperageLimit: amperageLimit }),
|
|
632
644
|
headers: { "Content-Type": "application/json" }
|
|
633
645
|
});
|
|
634
646
|
if (!response.ok) {
|
|
635
|
-
|
|
647
|
+
const body = await this._errorBody(response);
|
|
648
|
+
throw new CommunicationError(response.status, `Failed to set amperage limit. HTTP ${response.status}: ${body}`);
|
|
636
649
|
}
|
|
637
650
|
await response.text();
|
|
638
651
|
}
|
|
639
652
|
async setLedBrightness(chargerId, level) {
|
|
640
653
|
const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/chargers/${chargerId}/led-brightness`;
|
|
641
654
|
const response = await this._request("PUT", url, {
|
|
642
|
-
body: JSON.stringify({ level }),
|
|
655
|
+
body: JSON.stringify({ ledBrightnessLevel: level }),
|
|
643
656
|
headers: { "Content-Type": "application/json" }
|
|
644
657
|
});
|
|
645
658
|
if (!response.ok) {
|
|
646
|
-
|
|
659
|
+
const body = await this._errorBody(response);
|
|
660
|
+
throw new CommunicationError(response.status, `Failed to set LED brightness. HTTP ${response.status}: ${body}`);
|
|
647
661
|
}
|
|
648
662
|
await response.text();
|
|
649
663
|
}
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants.ts","../src/exceptions.ts","../src/global-config.ts","../src/session.ts","../src/client.ts"],"names":["https","parseMsTimestamp"],"mappings":"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","file":"index.cjs","sourcesContent":["export const DISCOVERY_API =\n 'https://discovery.chargepoint.com/discovery/v3/globalconfig';\n\nexport const VERSION = '0.0.1-alpha.0';\nexport const USER_AGENT = `node-chargepoint/${VERSION}`;\n","export class APIError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'APIError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class CommunicationError extends APIError {\n constructor(\n public readonly statusCode: number,\n message: string,\n public readonly body?: unknown,\n ) {\n super(message);\n this.name = 'CommunicationError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class LoginError extends CommunicationError {\n constructor(statusCode: number, message: string, body?: unknown) {\n super(statusCode, message, body);\n this.name = 'LoginError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class InvalidSession extends CommunicationError {\n constructor(statusCode = 401, message = 'ChargePoint session expired. Please log in again.', body?: unknown) {\n super(statusCode, message, body);\n this.name = 'InvalidSession';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class DatadomeCaptcha extends APIError {\n constructor(\n public readonly captchaUrl: string,\n message = 'Datadome captcha protection triggered.',\n ) {\n super(message);\n this.name = 'DatadomeCaptcha';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","import https from 'node:https';\nimport { DISCOVERY_API, USER_AGENT } from './constants.js';\nimport { CommunicationError } from './exceptions.js';\nimport type { APIEndpoints, GlobalConfiguration } from './types.js';\n\ntype RawValue = Record<string, unknown>;\n\n// Node 24's built-in fetch automatically adds `Sec-Fetch-Mode: cors`, which\n// causes the ChargePoint discovery endpoint to return HTTP 500. Using node:https\n// directly avoids that header. Default import (not named) is required so that\n// MSW's runtime patch of https.request is visible at call time in unit tests.\nasync function postJson(url: string, body: string): Promise<{ status: number; data: RawValue }> {\n return new Promise((resolve, reject) => {\n const bodyBuf = Buffer.from(body, 'utf-8');\n const req = https.request(\n url,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Content-Length': bodyBuf.byteLength,\n 'User-Agent': USER_AGENT,\n },\n },\n (res) => {\n const chunks: Buffer[] = [];\n res.on('data', (chunk: Buffer) => chunks.push(chunk));\n res.on('end', () => {\n const statusCode = res.statusCode ?? 0;\n if (statusCode < 200 || statusCode >= 300) {\n reject(new CommunicationError(statusCode, 'Failed to fetch global configuration.'));\n return;\n }\n try {\n resolve({ status: statusCode, data: JSON.parse(Buffer.concat(chunks).toString('utf-8')) as RawValue });\n } catch {\n reject(new CommunicationError(statusCode, 'Failed to parse global configuration response.'));\n }\n });\n },\n );\n req.on('error', (err: Error) => {\n reject(new CommunicationError(0, `Failed to reach ChargePoint discovery API: ${err.message}`));\n });\n req.write(bodyBuf);\n req.end();\n });\n}\n\nfunction endpointStr(v: unknown): string {\n const raw =\n v !== null && typeof v === 'object' && 'value' in v\n ? String((v as RawValue).value ?? '')\n : typeof v === 'string'\n ? v\n : '';\n return raw.replace(/\\/+$/, ''); // strip trailing slashes so callers can always do `${url}/path`\n}\n\nfunction parseEndpoints(raw: RawValue): APIEndpoints {\n // Support both camelCase and snake_case keys from the discovery API\n const get = (camel: string, snake: string): string =>\n endpointStr(raw[camel] ?? raw[snake] ?? '');\n\n return {\n accountsEndpoint: get('accountsEndpoint', 'accounts_endpoint'),\n internalApiGatewayEndpoint: get('internalApiGatewayEndpoint', 'internal_api_gateway_endpoint'),\n mapcacheEndpoint: get('mapcacheEndpoint', 'mapcache_endpoint'),\n pandaWebsocketEndpoint: get('pandaWebsocketEndpoint', 'panda_websocket_endpoint'),\n paymentJavaEndpoint: get('paymentJavaEndpoint', 'payment_java_endpoint'),\n paymentPhpEndpoint: get('paymentPhpEndpoint', 'payment_php_endpoint'),\n portalDomainEndpoint: get('portalDomainEndpoint', 'portal_domain_endpoint'),\n portalSubdomain:\n typeof raw.portalSubdomain === 'string'\n ? raw.portalSubdomain\n : typeof raw.portal_subdomain === 'string'\n ? raw.portal_subdomain\n : '',\n ssoEndpoint: get('ssoEndpoint', 'sso_endpoint'),\n webservicesEndpoint: get('webservicesEndpoint', 'webservices_endpoint'),\n websocketEndpoint: get('websocketEndpoint', 'websocket_endpoint'),\n hcpoHcmEndpoint: get('hcpoHcmEndpoint', 'hcpo_hcm_endpoint'),\n };\n}\n\nexport async function fetchGlobalConfig(region = 'NA'): Promise<GlobalConfiguration> {\n const { data } = await postJson(DISCOVERY_API, JSON.stringify({ regionCode: region }));\n\n // The API may return the config directly or nested under \"globalConfiguration\"\n const raw = (typeof data.globalConfiguration === 'object' && data.globalConfiguration !== null\n ? data.globalConfiguration\n : data) as RawValue;\n\n const endpointsRaw = (raw.endPoints ?? raw.endpoints ?? {}) as RawValue;\n\n return {\n region: typeof raw.region === 'string' ? raw.region : region,\n defaultCountry: (raw.defaultCountry ?? {}) as GlobalConfiguration['defaultCountry'],\n supportedCountries: Array.isArray(raw.supportedCountries)\n ? (raw.supportedCountries as GlobalConfiguration['supportedCountries'])\n : [],\n defaultCurrency: (raw.currency ?? raw.defaultCurrency ?? {}) as GlobalConfiguration['defaultCurrency'],\n supportedCurrencies: Array.isArray(raw.supportedCurrencies)\n ? (raw.supportedCurrencies as GlobalConfiguration['supportedCurrencies'])\n : [],\n endpoints: parseEndpoints(endpointsRaw),\n };\n}\n","import type { ChargePoint } from './client.js';\nimport { APIError, CommunicationError } from './exceptions.js';\nimport type { ChargingSessionUpdate, PowerUtility, VehicleInfo } from './types.js';\n\nconst sleep = (ms: number): Promise<void> =>\n new Promise((resolve) => setTimeout(resolve, ms));\n\ntype RawObj = Record<string, unknown>;\n\nexport async function sendCommand(\n client: ChargePoint,\n action: 'start' | 'stop',\n deviceId: number,\n portNumber = 1,\n sessionId = 0,\n): Promise<void> {\n const actionPath = action === 'start' ? 'startsession' : 'stopSession';\n const body: RawObj = { deviceId };\n\n if (action === 'stop') {\n body.portNumber = portNumber;\n body.sessionId = sessionId;\n }\n\n const url = `${client.globalConfig.endpoints.accountsEndpoint}/v1/driver/station/${actionPath}`;\n const response = await client._request('POST', url, {\n body: JSON.stringify(body),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new CommunicationError(\n response.status,\n `Failed to ${action} ChargePoint session: ${text}`,\n );\n }\n\n const actionStatus = (await response.json()) as RawObj;\n const ackId = actionStatus.ackId;\n\n const ackUrl = `${client.globalConfig.endpoints.accountsEndpoint}/v1/driver/station/session/ack`;\n\n let lastStatus = 0;\n let errorMessage = `Session failed to ${action}.`;\n let errorBody: unknown;\n\n for (let attempt = 1; attempt <= 20; attempt++) {\n const ackResponse = await client._request('POST', ackUrl, {\n body: JSON.stringify({ ackId, action: `${action}_session` }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n lastStatus = ackResponse.status;\n\n if (ackResponse.status === 200) {\n return;\n }\n\n try {\n errorBody = await ackResponse.json();\n const msg = (errorBody as RawObj).errorMessage;\n if (typeof msg === 'string') errorMessage = msg;\n } catch {\n errorBody = undefined;\n }\n\n if (attempt < 20) {\n await sleep(3000);\n }\n }\n\n throw new CommunicationError(lastStatus, errorMessage, errorBody);\n}\n\nfunction parseMsTimestamp(v: unknown): Date {\n if (typeof v === 'number') return new Date(v);\n if (typeof v === 'string') return new Date(Number(v));\n return new Date(0);\n}\n\nfunction parseSessionUpdates(raw: unknown): ChargingSessionUpdate[] {\n if (!Array.isArray(raw)) return [];\n return raw.map((u: unknown) => {\n const item = u as RawObj;\n return {\n energyKwh: typeof item.energy_kwh === 'number' ? item.energy_kwh : 0,\n powerKw: typeof item.power_kw === 'number' ? item.power_kw : 0,\n timestamp: parseMsTimestamp(item.timestamp),\n };\n });\n}\n\nexport class ChargingSession {\n sessionId: number;\n deviceId = 0;\n deviceName = '';\n chargingState = '';\n chargingTime = 0;\n energyKwh = 0;\n milesAdded = 0;\n milesAddedPerHour = 0;\n outletNumber = 0;\n portLevel = 0;\n powerKw = 0;\n purpose = '';\n currencyIsoCode = '';\n paymentCompleted = false;\n paymentType = '';\n pricingSpecId = 0;\n totalAmount = 0;\n apiFlag = false;\n enableStopCharging = false;\n hasChargingReceipt = false;\n hasUtilityInfo = false;\n isHomeCharger = false;\n isPurposeFinalized = false;\n stopChargeSupported = false;\n companyId = 0;\n companyName = '';\n latitude = 0;\n longitude = 0;\n address = '';\n city = '';\n stateName = '';\n country = '';\n zipcode = '';\n updatePeriod = 0;\n startTime: Date | null = null;\n lastUpdateDataTimestamp: Date | null = null;\n updateData: ChargingSessionUpdate[] | null = null;\n utility: PowerUtility | null = null;\n vehicleInfo: VehicleInfo | null = null;\n\n private _client: ChargePoint | null = null;\n\n constructor(sessionId: number) {\n this.sessionId = sessionId;\n }\n\n /** @internal */\n _setClient(client: ChargePoint): void {\n this._client = client;\n }\n\n /** @internal Apply raw session data from the driver-bff API (snake_case keys). */\n _apply(data: RawObj): void {\n if (data.device_id !== undefined) this.deviceId = data.device_id as number;\n if (data.device_name !== undefined) this.deviceName = data.device_name as string;\n if (data.current_charging !== undefined) this.chargingState = data.current_charging as string;\n if (data.charging_time !== undefined) this.chargingTime = data.charging_time as number;\n if (data.energy_kwh !== undefined) this.energyKwh = data.energy_kwh as number;\n if (data.miles_added !== undefined) this.milesAdded = data.miles_added as number;\n if (data.miles_added_per_hour !== undefined) this.milesAddedPerHour = data.miles_added_per_hour as number;\n if (data.outlet_number !== undefined) this.outletNumber = data.outlet_number as number;\n if (data.port_level !== undefined) this.portLevel = data.port_level as number;\n if (data.power_kw !== undefined) this.powerKw = data.power_kw as number;\n if (data.purpose !== undefined) this.purpose = data.purpose as string;\n if (data.currency_iso_code !== undefined) this.currencyIsoCode = String(data.currency_iso_code);\n if (data.payment_completed !== undefined) this.paymentCompleted = data.payment_completed as boolean;\n if (data.payment_type !== undefined) this.paymentType = data.payment_type as string;\n if (data.pricing_spec_id !== undefined) this.pricingSpecId = data.pricing_spec_id as number;\n if (data.total_amount !== undefined) this.totalAmount = data.total_amount as number;\n if (data.api_flag !== undefined) this.apiFlag = data.api_flag as boolean;\n if (data.enable_stop_charging !== undefined) this.enableStopCharging = data.enable_stop_charging as boolean;\n if (data.has_charging_receipt !== undefined) this.hasChargingReceipt = data.has_charging_receipt as boolean;\n if (data.has_utility_info !== undefined) this.hasUtilityInfo = data.has_utility_info as boolean;\n if (data.is_home_charger !== undefined) this.isHomeCharger = data.is_home_charger as boolean;\n if (data.is_purpose_finalized !== undefined) this.isPurposeFinalized = data.is_purpose_finalized as boolean;\n if (data.stop_charge_supported !== undefined) this.stopChargeSupported = data.stop_charge_supported as boolean;\n if (data.company_id !== undefined) this.companyId = data.company_id as number;\n if (data.company_name !== undefined) this.companyName = data.company_name as string;\n if (data.lat !== undefined) this.latitude = data.lat as number;\n if (data.lon !== undefined) this.longitude = data.lon as number;\n if (data.address1 !== undefined) this.address = data.address1 as string;\n if (data.city !== undefined) this.city = data.city as string;\n if (data.state_name !== undefined) this.stateName = data.state_name as string;\n if (data.country !== undefined) this.country = data.country as string;\n if (data.zipcode !== undefined) this.zipcode = data.zipcode as string;\n if (data.update_period !== undefined) this.updatePeriod = data.update_period as number;\n if (data.start_time !== undefined) this.startTime = parseMsTimestamp(data.start_time);\n if (data.last_update_data_timestamp !== undefined) {\n this.lastUpdateDataTimestamp = parseMsTimestamp(data.last_update_data_timestamp);\n }\n if (data.update_data !== undefined) this.updateData = parseSessionUpdates(data.update_data);\n if (data.utility !== undefined) this.utility = (data.utility as PowerUtility) ?? null;\n if (data.vehicle_info !== undefined) this.vehicleInfo = (data.vehicle_info as VehicleInfo) ?? null;\n }\n\n async refresh(): Promise<void> {\n if (!this._client) throw new Error('ChargingSession client not set.');\n\n const url = `${this._client.globalConfig.endpoints.internalApiGatewayEndpoint}/driver-bff/v1/sessions/${this.sessionId}`;\n const response = await this._client._request('POST', url, {\n body: JSON.stringify({\n charging_status: { session_id: this.sessionId, mfhs: [] },\n }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get charging session data.');\n }\n\n const json = (await response.json()) as RawObj;\n const status = json.charging_status as RawObj | undefined;\n\n if (!status || 'error_message' in status || 'error' in status) {\n throw new CommunicationError(response.status, 'Failed to get charging session data.');\n }\n\n this._apply(status);\n }\n\n async stop(): Promise<void> {\n if (!this._client) throw new Error('ChargingSession client not set.');\n await sendCommand(\n this._client,\n 'stop',\n this.deviceId,\n this.outletNumber,\n this.sessionId,\n );\n }\n\n static async start(deviceId: number, client: ChargePoint): Promise<ChargingSession> {\n await sendCommand(client, 'start', deviceId);\n // The sessionId returned by the start endpoint is not the real session ID;\n // fetch it from the status API instead.\n const status = await client.getUserChargingStatus();\n if (!status) {\n throw new APIError('No active charging session found after start command.');\n }\n const session = new ChargingSession(status.sessionId);\n session._setClient(client);\n await session.refresh();\n return session;\n }\n}\n","import { USER_AGENT } from './constants.js';\nimport { CommunicationError, DatadomeCaptcha, InvalidSession, LoginError } from './exceptions.js';\nimport { fetchGlobalConfig } from './global-config.js';\nimport { ChargingSession } from './session.js';\nimport type {\n Account,\n ElectricVehicle,\n GlobalConfiguration,\n HomeChargerConfiguration,\n HomeChargerSchedule,\n HomeChargerStatus,\n HomeChargerTechnicalInfo,\n MapFilter,\n MapStation,\n Station,\n StationInfo,\n UserChargingStatus,\n ZoomBounds,\n} from './types.js';\n\ntype RawObj = Record<string, unknown>;\n\nexport interface ChargePointOptions {\n coulombToken?: string;\n region?: string;\n}\n\nfunction parseMsTimestamp(v: unknown): Date {\n if (typeof v === 'number') return new Date(v);\n if (typeof v === 'string') return new Date(Number(v));\n return new Date(0);\n}\n\nexport class ChargePoint {\n public globalConfig: GlobalConfiguration;\n private _username: string;\n private _coulombToken: string | null = null;\n private _region: string;\n private _userId: number | null = null;\n\n /** The current session token. Save this after login to avoid re-authenticating. */\n get coulombToken(): string | null {\n return this._coulombToken;\n }\n\n private constructor(username: string, globalConfig: GlobalConfiguration, region: string) {\n this._username = username;\n this.globalConfig = globalConfig;\n this._region = region;\n }\n\n static async create(username: string, options: ChargePointOptions = {}): Promise<ChargePoint> {\n const region = options.region ?? 'NA';\n const config = await fetchGlobalConfig(region);\n const client = new ChargePoint(username, config, region);\n\n if (options.coulombToken) {\n client._setToken(options.coulombToken, region);\n }\n\n return client;\n }\n\n private _setToken(token: string, region: string): void {\n this._coulombToken = token;\n this._region = region;\n }\n\n /** @internal Used by session.ts and tests. */\n async _request(method: string, url: string, init: RequestInit = {}): Promise<Response> {\n const headers = new Headers(init.headers as string[][] | Record<string, string> | Headers);\n headers.set('user-agent', USER_AGENT);\n\n if (!headers.has('content-type') && method !== 'GET') {\n headers.set('content-type', 'application/json');\n }\n\n if (this._coulombToken) {\n headers.set('cookie', `coulomb_sess=${this._coulombToken}`);\n headers.set('cp-session-type', 'CP_SESSION_TOKEN');\n headers.set('cp-session-token', this._coulombToken);\n headers.set('cp-region', this._region);\n }\n\n const response = await fetch(url, { ...init, method, headers });\n\n // Refresh coulomb_sess from Set-Cookie response header\n const setCookies: string[] =\n typeof (response.headers as unknown as { getSetCookie?: () => string[] }).getSetCookie ===\n 'function'\n ? (response.headers as unknown as { getSetCookie: () => string[] }).getSetCookie()\n : [response.headers.get('set-cookie') ?? ''].filter(Boolean);\n\n for (const cookie of setCookies) {\n const match = /^coulomb_sess=([^;]+)/.exec(cookie);\n if (match) {\n this._coulombToken = match[1] ?? null;\n break;\n }\n }\n\n if (response.status === 401) {\n throw new InvalidSession(401, 'ChargePoint session expired. Please log in again.');\n }\n\n if (response.status === 403) {\n let body: unknown;\n try {\n body = await response.clone().json();\n } catch {\n // not JSON\n }\n const captchaUrl = (body as RawObj)?.url;\n if (typeof captchaUrl === 'string' && captchaUrl.includes('datadome')) {\n throw new DatadomeCaptcha(captchaUrl);\n }\n }\n\n return response;\n }\n\n // ---------------------------------------------------------------------------\n // Authentication\n // ---------------------------------------------------------------------------\n\n async loginWithPassword(password: string): Promise<void> {\n const url = `${this.globalConfig.endpoints.ssoEndpoint}/v1/user/login`;\n const response = await this._request('POST', url, {\n body: JSON.stringify({ user_name: this._username, password }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n let body: unknown;\n try { body = await response.json(); } catch { /* ignore */ }\n throw new LoginError(response.status, 'Failed to login with password.', body);\n }\n\n // The coulomb_sess cookie is set by the SSO endpoint on success;\n // _request() already extracted it from Set-Cookie above.\n await response.text(); // drain body\n\n if (!this._coulombToken) {\n throw new LoginError(response.status, 'Login succeeded but no session token was returned.');\n }\n }\n\n async loginWithSsoSession(ssoJwt: string): Promise<void> {\n // Exchange an SSO JWT for a coulomb_sess cookie via the portal endpoint.\n const url = `${this.globalConfig.endpoints.portalDomainEndpoint}/index.php/nghelper/getSession`;\n const response = await this._request('GET', url, {\n headers: {\n cookie: `auth-session=${ssoJwt}`,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n let body: unknown;\n try { body = await response.json(); } catch { /* ignore */ }\n throw new LoginError(response.status, 'Failed to login with SSO session.', body);\n }\n\n await response.text();\n }\n\n async logout(): Promise<void> {\n const url = `${this.globalConfig.endpoints.ssoEndpoint}/v1/user/logout`;\n try {\n await this._request('POST', url);\n } finally {\n this._coulombToken = null;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Account\n // ---------------------------------------------------------------------------\n\n async getAccount(): Promise<Account> {\n const url = `${this.globalConfig.endpoints.accountsEndpoint}/v1/driver/profile/user`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get account information.');\n }\n\n const data = (await response.json()) as Account;\n if (data.user?.userId) {\n this._userId = data.user.userId;\n }\n return data;\n }\n\n async getVehicles(): Promise<ElectricVehicle[]> {\n const url = `${this.globalConfig.endpoints.accountsEndpoint}/v1/driver/vehicle`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get vehicles.');\n }\n\n const data = (await response.json()) as RawObj;\n return (Array.isArray(data.vehicles) ? data.vehicles : []) as ElectricVehicle[];\n }\n\n async getUserChargingStatus(): Promise<UserChargingStatus | null> {\n const url = `${this.globalConfig.endpoints.mapcacheEndpoint}/v2`;\n const response = await this._request('POST', url, {\n body: JSON.stringify({ user_status: { timestamp: Date.now() } }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get user charging status.');\n }\n\n const data = (await response.json()) as RawObj;\n const userStatus = data.user_status as RawObj | null | undefined;\n\n if (!userStatus) return null;\n\n const charging = userStatus.charging_status as RawObj | null | undefined;\n if (!charging) return null;\n\n const stations: Station[] = Array.isArray(charging.stations)\n ? (charging.stations as RawObj[]).map((s) => ({\n id: s.id as number,\n name: typeof s.name === 'string' ? s.name : '',\n latitude: typeof s.lat === 'number' ? s.lat : (s.latitude as number ?? 0),\n longitude: typeof s.lon === 'number' ? s.lon : (s.longitude as number ?? 0),\n }))\n : [];\n\n return {\n sessionId: charging.session_id as number,\n startTime: parseMsTimestamp(charging.start_time),\n state: typeof charging.current_charging === 'string' ? charging.current_charging : '',\n stations,\n };\n }\n\n // ---------------------------------------------------------------------------\n // Home charger helpers\n // ---------------------------------------------------------------------------\n\n private async ensureUserId(): Promise<number> {\n if (this._userId !== null) return this._userId;\n const account = await this.getAccount();\n return account.user.userId;\n }\n\n async getHomeChargers(): Promise<number[]> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n let body: unknown;\n try { body = await response.json(); } catch { /* ignore */ }\n throw new CommunicationError(response.status, 'Failed to get home chargers.', body);\n }\n\n const data = (await response.json()) as RawObj;\n // API returns { data: [...] }; older shape used { chargers: [...] }\n const arr = Array.isArray(data.data)\n ? (data.data as RawObj[])\n : Array.isArray(data.chargers)\n ? (data.chargers as RawObj[])\n : [];\n return arr.map((c) => {\n // API uses \"id\" (string); older shape used chargerId / charger_id (number)\n const id = c.id ?? c.chargerId ?? c.charger_id;\n return typeof id === 'number' ? id : Number(id);\n });\n }\n\n async getHomeChargerStatus(chargerId: number): Promise<HomeChargerStatus> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/status`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger status.');\n }\n\n const data = (await response.json()) as RawObj;\n // Real API nests amperage info under chargeAmperageSettings; fall back to flat fields for older shapes\n const amp = (data.chargeAmperageSettings ?? {}) as RawObj;\n return {\n chargerId, // not echoed by the API; inject from parameter\n brand: String(data.brand ?? ''),\n model: String(data.model ?? ''),\n macAddress: String(data.macAddress ?? ''),\n chargingStatus: String(data.chargingStatus ?? ''),\n isPluggedIn: Boolean(data.isPluggedIn),\n isConnected: Boolean(data.isConnected),\n isReminderEnabled: Boolean(data.isReminderEnabled),\n plugInReminderTime: String(data.plugInReminderTime ?? ''),\n hasUtilityInfo: Boolean(data.hasUtilityInfo),\n isDuringScheduledTime: Boolean(data.isDuringScheduledTime),\n amperageLimit: Number(amp.chargeLimit ?? data.amperageLimit ?? 0),\n possibleAmperageLimits: ((amp.possibleChargeLimit ?? data.possibleAmperageLimits ?? []) as number[]).map(Number),\n };\n }\n\n async getHomeChargerTechnicalInfo(chargerId: number): Promise<HomeChargerTechnicalInfo> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/technical-info`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger technical info.');\n }\n\n return (await response.json()) as HomeChargerTechnicalInfo;\n }\n\n async getHomeChargerConfig(chargerId: number): Promise<HomeChargerConfiguration> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/configurations`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger configuration.');\n }\n\n const data = (await response.json()) as RawObj;\n // Real API wraps all fields under \"settings\"; fall back to flat shape for older responses\n const s = (data.settings ?? data) as RawObj;\n // LED brightness: real API uses settings.led.brightness with string-typed level/supportedLevels\n const rawLed = ((s.led as RawObj | undefined)?.brightness ?? s.ledBrightness ?? {}) as RawObj;\n const level =\n typeof rawLed.level === 'string'\n ? Number(rawLed.level)\n : Number(rawLed.level ?? rawLed.currentBrightnessSettings ?? 0);\n const supportedLevels = Array.isArray(rawLed.supportedLevels)\n ? (rawLed.supportedLevels as (string | number)[]).map(Number)\n : [];\n return {\n serialNumber: String(s.serialNumber ?? ''),\n macAddress: String(s.macAddress ?? ''),\n stationNickname: String(s.stationNickname ?? ''),\n streetAddress: String(s.streetAddress ?? ''),\n hasUtilityInfo: Boolean(s.hasUtilityInfo),\n utility: (s.utility ?? null) as HomeChargerConfiguration['utility'],\n // API may return boolean true/false or string \"ON\"/\"OFF\"\n indicatorLightEcoMode: s.indicatorLightEcoMode === true || s.indicatorLightEcoMode === 'ON',\n flashlightReset: Boolean(s.flashlightReset),\n worksWithNest: Boolean(s.worksWithNest),\n isPairedWithNest: Boolean(s.isPairedWithNest),\n isInstalledByInstaller: Boolean(s.isInstalledByInstaller),\n ledBrightness: {\n level,\n inProgress: Boolean(rawLed.inProgress),\n supportedLevels,\n isEnabled: rawLed.isEnabled !== false,\n },\n };\n }\n\n async getHomeChargerSchedule(chargerId: number): Promise<HomeChargerSchedule> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger schedule.');\n }\n\n return (await response.json()) as HomeChargerSchedule;\n }\n\n async setHomeChargerSchedule(\n chargerId: number,\n weekdayStart: string,\n weekdayEnd: string,\n weekendStart: string,\n weekendEnd: string,\n ): Promise<HomeChargerSchedule> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({\n scheduleEnabled: true,\n userSchedule: {\n weekdays: { startTime: weekdayStart, endTime: weekdayEnd },\n weekends: { startTime: weekendStart, endTime: weekendEnd },\n },\n }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to set home charger schedule.');\n }\n\n return (await response.json()) as HomeChargerSchedule;\n }\n\n async disableHomeChargerSchedule(chargerId: number): Promise<void> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({ scheduleEnabled: false }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to disable home charger schedule.');\n }\n\n await response.text();\n }\n\n async setAmperageLimit(chargerId: number, amperageLimit: number): Promise<void> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/chargers/${chargerId}/charge-amperage-limit`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({ amperageLimit }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to set amperage limit.');\n }\n\n await response.text();\n }\n\n async setLedBrightness(chargerId: number, level: number): Promise<void> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/chargers/${chargerId}/led-brightness`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({ level }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to set LED brightness.');\n }\n\n await response.text();\n }\n\n async restartHomeCharger(chargerId: number): Promise<void> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/restart`;\n const response = await this._request('POST', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to restart home charger.');\n }\n\n await response.text();\n }\n\n // ---------------------------------------------------------------------------\n // Charging sessions\n // ---------------------------------------------------------------------------\n\n async getChargingSession(sessionId: number): Promise<ChargingSession> {\n const session = new ChargingSession(sessionId);\n session._setClient(this);\n await session.refresh();\n return session;\n }\n\n async startChargingSession(deviceId: number): Promise<ChargingSession> {\n return ChargingSession.start(deviceId, this);\n }\n\n // ---------------------------------------------------------------------------\n // Stations\n // ---------------------------------------------------------------------------\n\n async getStation(deviceId: number): Promise<StationInfo> {\n const url = `${this.globalConfig.endpoints.mapcacheEndpoint}/v3/station/info?deviceId=${deviceId}&use_cache=false`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get station info.');\n }\n\n return (await response.json()) as StationInfo;\n }\n\n async getNearbyStations(bounds: ZoomBounds, filter: MapFilter = {}): Promise<MapStation[]> {\n const url = `${this.globalConfig.endpoints.mapcacheEndpoint}/v2`;\n const stationList: RawObj = {\n ne_lat: bounds.neLat,\n ne_lon: bounds.neLon,\n sw_lat: bounds.swLat,\n sw_lon: bounds.swLon,\n ...filter,\n };\n\n const response = await this._request('POST', url, {\n body: JSON.stringify({ station_list: stationList }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get nearby stations.');\n }\n\n const data = (await response.json()) as RawObj;\n const list = data.station_list as RawObj | undefined;\n return Array.isArray(list?.stations) ? (list.stations as MapStation[]) : [];\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/exceptions.ts","../src/global-config.ts","../src/session.ts","../src/client.ts"],"names":["https","parseMsTimestamp"],"mappings":"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","file":"index.cjs","sourcesContent":["export const DISCOVERY_API =\n 'https://discovery.chargepoint.com/discovery/v3/globalconfig';\n\nexport const VERSION = '0.0.1-alpha.0';\nexport const USER_AGENT = `node-chargepoint/${VERSION}`;\n","export class APIError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'APIError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class CommunicationError extends APIError {\n constructor(\n public readonly statusCode: number,\n message: string,\n public readonly body?: unknown,\n ) {\n super(message);\n this.name = 'CommunicationError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class LoginError extends CommunicationError {\n constructor(statusCode: number, message: string, body?: unknown) {\n super(statusCode, message, body);\n this.name = 'LoginError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class InvalidSession extends CommunicationError {\n constructor(statusCode = 401, message = 'ChargePoint session expired. Please log in again.', body?: unknown) {\n super(statusCode, message, body);\n this.name = 'InvalidSession';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class DatadomeCaptcha extends APIError {\n constructor(\n public readonly captchaUrl: string,\n message = 'Datadome captcha protection triggered.',\n ) {\n super(message);\n this.name = 'DatadomeCaptcha';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","import https from 'node:https';\nimport { DISCOVERY_API, USER_AGENT } from './constants.js';\nimport { CommunicationError } from './exceptions.js';\nimport type { APIEndpoints, GlobalConfiguration } from './types.js';\n\ntype RawValue = Record<string, unknown>;\n\n// Node 24's built-in fetch automatically adds `Sec-Fetch-Mode: cors`, which\n// causes the ChargePoint discovery endpoint to return HTTP 500. Using node:https\n// directly avoids that header. Default import (not named) is required so that\n// MSW's runtime patch of https.request is visible at call time in unit tests.\nasync function postJson(url: string, body: string): Promise<{ status: number; data: RawValue }> {\n return new Promise((resolve, reject) => {\n const bodyBuf = Buffer.from(body, 'utf-8');\n const req = https.request(\n url,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Content-Length': bodyBuf.byteLength,\n 'User-Agent': USER_AGENT,\n },\n },\n (res) => {\n const chunks: Buffer[] = [];\n res.on('data', (chunk: Buffer) => chunks.push(chunk));\n res.on('end', () => {\n const statusCode = res.statusCode ?? 0;\n if (statusCode < 200 || statusCode >= 300) {\n reject(new CommunicationError(statusCode, 'Failed to fetch global configuration.'));\n return;\n }\n try {\n resolve({ status: statusCode, data: JSON.parse(Buffer.concat(chunks).toString('utf-8')) as RawValue });\n } catch {\n reject(new CommunicationError(statusCode, 'Failed to parse global configuration response.'));\n }\n });\n },\n );\n req.on('error', (err: Error) => {\n reject(new CommunicationError(0, `Failed to reach ChargePoint discovery API: ${err.message}`));\n });\n req.write(bodyBuf);\n req.end();\n });\n}\n\nfunction endpointStr(v: unknown): string {\n const raw =\n v !== null && typeof v === 'object' && 'value' in v\n ? String((v as RawValue).value ?? '')\n : typeof v === 'string'\n ? v\n : '';\n return raw.replace(/\\/+$/, ''); // strip trailing slashes so callers can always do `${url}/path`\n}\n\nfunction parseEndpoints(raw: RawValue): APIEndpoints {\n // Support both camelCase and snake_case keys from the discovery API\n const get = (camel: string, snake: string): string =>\n endpointStr(raw[camel] ?? raw[snake] ?? '');\n\n return {\n accountsEndpoint: get('accountsEndpoint', 'accounts_endpoint'),\n internalApiGatewayEndpoint: get('internalApiGatewayEndpoint', 'internal_api_gateway_endpoint'),\n mapcacheEndpoint: get('mapcacheEndpoint', 'mapcache_endpoint'),\n pandaWebsocketEndpoint: get('pandaWebsocketEndpoint', 'panda_websocket_endpoint'),\n paymentJavaEndpoint: get('paymentJavaEndpoint', 'payment_java_endpoint'),\n paymentPhpEndpoint: get('paymentPhpEndpoint', 'payment_php_endpoint'),\n portalDomainEndpoint: get('portalDomainEndpoint', 'portal_domain_endpoint'),\n portalSubdomain:\n typeof raw.portalSubdomain === 'string'\n ? raw.portalSubdomain\n : typeof raw.portal_subdomain === 'string'\n ? raw.portal_subdomain\n : '',\n ssoEndpoint: get('ssoEndpoint', 'sso_endpoint'),\n webservicesEndpoint: get('webservicesEndpoint', 'webservices_endpoint'),\n websocketEndpoint: get('websocketEndpoint', 'websocket_endpoint'),\n hcpoHcmEndpoint: get('hcpoHcmEndpoint', 'hcpo_hcm_endpoint'),\n };\n}\n\nexport async function fetchGlobalConfig(region = 'NA'): Promise<GlobalConfiguration> {\n const { data } = await postJson(DISCOVERY_API, JSON.stringify({ regionCode: region }));\n\n // The API may return the config directly or nested under \"globalConfiguration\"\n const raw = (typeof data.globalConfiguration === 'object' && data.globalConfiguration !== null\n ? data.globalConfiguration\n : data) as RawValue;\n\n const endpointsRaw = (raw.endPoints ?? raw.endpoints ?? {}) as RawValue;\n\n return {\n region: typeof raw.region === 'string' ? raw.region : region,\n defaultCountry: (raw.defaultCountry ?? {}) as GlobalConfiguration['defaultCountry'],\n supportedCountries: Array.isArray(raw.supportedCountries)\n ? (raw.supportedCountries as GlobalConfiguration['supportedCountries'])\n : [],\n defaultCurrency: (raw.currency ?? raw.defaultCurrency ?? {}) as GlobalConfiguration['defaultCurrency'],\n supportedCurrencies: Array.isArray(raw.supportedCurrencies)\n ? (raw.supportedCurrencies as GlobalConfiguration['supportedCurrencies'])\n : [],\n endpoints: parseEndpoints(endpointsRaw),\n };\n}\n","import type { ChargePoint } from './client.js';\nimport { APIError, CommunicationError } from './exceptions.js';\nimport type { ChargingSessionUpdate, PowerUtility, VehicleInfo } from './types.js';\n\nconst sleep = (ms: number): Promise<void> =>\n new Promise((resolve) => setTimeout(resolve, ms));\n\ntype RawObj = Record<string, unknown>;\n\nexport async function sendCommand(\n client: ChargePoint,\n action: 'start' | 'stop',\n deviceId: number,\n portNumber = 1,\n sessionId = 0,\n): Promise<void> {\n const actionPath = action === 'start' ? 'startsession' : 'stopSession';\n const body: RawObj = { deviceId };\n\n if (action === 'stop') {\n body.portNumber = portNumber;\n body.sessionId = sessionId;\n }\n\n const url = `${client.globalConfig.endpoints.accountsEndpoint}/v1/driver/station/${actionPath}`;\n const response = await client._request('POST', url, {\n body: JSON.stringify(body),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new CommunicationError(\n response.status,\n `Failed to ${action} ChargePoint session: ${text}`,\n );\n }\n\n const actionStatus = (await response.json()) as RawObj;\n const ackId = actionStatus.ackId;\n\n const ackUrl = `${client.globalConfig.endpoints.accountsEndpoint}/v1/driver/station/session/ack`;\n\n let lastStatus = 0;\n let errorMessage = `Session failed to ${action}.`;\n let errorBody: unknown;\n\n for (let attempt = 1; attempt <= 20; attempt++) {\n const ackResponse = await client._request('POST', ackUrl, {\n body: JSON.stringify({ ackId, action: `${action}_session` }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n lastStatus = ackResponse.status;\n\n if (ackResponse.status === 200) {\n return;\n }\n\n try {\n errorBody = await ackResponse.json();\n const msg = (errorBody as RawObj).errorMessage;\n if (typeof msg === 'string') errorMessage = msg;\n } catch {\n errorBody = undefined;\n }\n\n if (attempt < 20) {\n await sleep(3000);\n }\n }\n\n throw new CommunicationError(lastStatus, errorMessage, errorBody);\n}\n\nfunction parseMsTimestamp(v: unknown): Date {\n if (typeof v === 'number') return new Date(v);\n if (typeof v === 'string') return new Date(Number(v));\n return new Date(0);\n}\n\nfunction parseSessionUpdates(raw: unknown): ChargingSessionUpdate[] {\n if (!Array.isArray(raw)) return [];\n return raw.map((u: unknown) => {\n const item = u as RawObj;\n return {\n energyKwh: typeof item.energy_kwh === 'number' ? item.energy_kwh : 0,\n powerKw: typeof item.power_kw === 'number' ? item.power_kw : 0,\n timestamp: parseMsTimestamp(item.timestamp),\n };\n });\n}\n\nexport class ChargingSession {\n sessionId: number;\n deviceId = 0;\n deviceName = '';\n chargingState = '';\n chargingTime = 0;\n energyKwh = 0;\n milesAdded = 0;\n milesAddedPerHour = 0;\n outletNumber = 0;\n portLevel = 0;\n powerKw = 0;\n purpose = '';\n currencyIsoCode = '';\n paymentCompleted = false;\n paymentType = '';\n pricingSpecId = 0;\n totalAmount = 0;\n apiFlag = false;\n enableStopCharging = false;\n hasChargingReceipt = false;\n hasUtilityInfo = false;\n isHomeCharger = false;\n isPurposeFinalized = false;\n stopChargeSupported = false;\n companyId = 0;\n companyName = '';\n latitude = 0;\n longitude = 0;\n address = '';\n city = '';\n stateName = '';\n country = '';\n zipcode = '';\n updatePeriod = 0;\n startTime: Date | null = null;\n lastUpdateDataTimestamp: Date | null = null;\n updateData: ChargingSessionUpdate[] | null = null;\n utility: PowerUtility | null = null;\n vehicleInfo: VehicleInfo | null = null;\n\n private _client: ChargePoint | null = null;\n\n constructor(sessionId: number) {\n this.sessionId = sessionId;\n }\n\n /** @internal */\n _setClient(client: ChargePoint): void {\n this._client = client;\n }\n\n /** @internal Apply raw session data from the driver-bff API (snake_case keys). */\n _apply(data: RawObj): void {\n if (data.device_id !== undefined) this.deviceId = data.device_id as number;\n if (data.device_name !== undefined) this.deviceName = data.device_name as string;\n if (data.current_charging !== undefined) this.chargingState = data.current_charging as string;\n if (data.charging_time !== undefined) this.chargingTime = data.charging_time as number;\n if (data.energy_kwh !== undefined) this.energyKwh = data.energy_kwh as number;\n if (data.miles_added !== undefined) this.milesAdded = data.miles_added as number;\n if (data.miles_added_per_hour !== undefined) this.milesAddedPerHour = data.miles_added_per_hour as number;\n if (data.outlet_number !== undefined) this.outletNumber = data.outlet_number as number;\n if (data.port_level !== undefined) this.portLevel = data.port_level as number;\n if (data.power_kw !== undefined) this.powerKw = data.power_kw as number;\n if (data.purpose !== undefined) this.purpose = data.purpose as string;\n if (data.currency_iso_code !== undefined) this.currencyIsoCode = String(data.currency_iso_code);\n if (data.payment_completed !== undefined) this.paymentCompleted = data.payment_completed as boolean;\n if (data.payment_type !== undefined) this.paymentType = data.payment_type as string;\n if (data.pricing_spec_id !== undefined) this.pricingSpecId = data.pricing_spec_id as number;\n if (data.total_amount !== undefined) this.totalAmount = data.total_amount as number;\n if (data.api_flag !== undefined) this.apiFlag = data.api_flag as boolean;\n if (data.enable_stop_charging !== undefined) this.enableStopCharging = data.enable_stop_charging as boolean;\n if (data.has_charging_receipt !== undefined) this.hasChargingReceipt = data.has_charging_receipt as boolean;\n if (data.has_utility_info !== undefined) this.hasUtilityInfo = data.has_utility_info as boolean;\n if (data.is_home_charger !== undefined) this.isHomeCharger = data.is_home_charger as boolean;\n if (data.is_purpose_finalized !== undefined) this.isPurposeFinalized = data.is_purpose_finalized as boolean;\n if (data.stop_charge_supported !== undefined) this.stopChargeSupported = data.stop_charge_supported as boolean;\n if (data.company_id !== undefined) this.companyId = data.company_id as number;\n if (data.company_name !== undefined) this.companyName = data.company_name as string;\n if (data.lat !== undefined) this.latitude = data.lat as number;\n if (data.lon !== undefined) this.longitude = data.lon as number;\n if (data.address1 !== undefined) this.address = data.address1 as string;\n if (data.city !== undefined) this.city = data.city as string;\n if (data.state_name !== undefined) this.stateName = data.state_name as string;\n if (data.country !== undefined) this.country = data.country as string;\n if (data.zipcode !== undefined) this.zipcode = data.zipcode as string;\n if (data.update_period !== undefined) this.updatePeriod = data.update_period as number;\n if (data.start_time !== undefined) this.startTime = parseMsTimestamp(data.start_time);\n if (data.last_update_data_timestamp !== undefined) {\n this.lastUpdateDataTimestamp = parseMsTimestamp(data.last_update_data_timestamp);\n }\n if (data.update_data !== undefined) this.updateData = parseSessionUpdates(data.update_data);\n if (data.utility !== undefined) this.utility = (data.utility as PowerUtility) ?? null;\n if (data.vehicle_info !== undefined) this.vehicleInfo = (data.vehicle_info as VehicleInfo) ?? null;\n }\n\n async refresh(): Promise<void> {\n if (!this._client) throw new Error('ChargingSession client not set.');\n\n const url = `${this._client.globalConfig.endpoints.internalApiGatewayEndpoint}/driver-bff/v1/sessions/${this.sessionId}`;\n const response = await this._client._request('POST', url, {\n body: JSON.stringify({\n charging_status: { session_id: this.sessionId, mfhs: [] },\n }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get charging session data.');\n }\n\n const json = (await response.json()) as RawObj;\n const status = json.charging_status as RawObj | undefined;\n\n if (!status || 'error_message' in status || 'error' in status) {\n throw new CommunicationError(response.status, 'Failed to get charging session data.');\n }\n\n this._apply(status);\n }\n\n async stop(): Promise<void> {\n if (!this._client) throw new Error('ChargingSession client not set.');\n await sendCommand(\n this._client,\n 'stop',\n this.deviceId,\n this.outletNumber,\n this.sessionId,\n );\n }\n\n static async start(deviceId: number, client: ChargePoint): Promise<ChargingSession> {\n await sendCommand(client, 'start', deviceId);\n\n // The start ack confirms the cloud received the command, but the session\n // may take a moment to appear in the status API (same async IoT pattern\n // as amperage/LED changes). Poll until it shows up.\n const deadline = Date.now() + 15_000;\n let status = await client.getUserChargingStatus();\n while (!status && Date.now() < deadline) {\n await sleep(2000);\n status = await client.getUserChargingStatus();\n }\n\n if (!status) {\n throw new APIError('No active charging session found after start command.');\n }\n const session = new ChargingSession(status.sessionId);\n session._setClient(client);\n await session.refresh();\n return session;\n }\n}\n","import { USER_AGENT } from './constants.js';\nimport { CommunicationError, DatadomeCaptcha, InvalidSession, LoginError } from './exceptions.js';\nimport { fetchGlobalConfig } from './global-config.js';\nimport { ChargingSession } from './session.js';\nimport type {\n Account,\n ElectricVehicle,\n GlobalConfiguration,\n HomeChargerConfiguration,\n HomeChargerSchedule,\n HomeChargerStatus,\n HomeChargerTechnicalInfo,\n MapFilter,\n MapStation,\n Station,\n StationInfo,\n UserChargingStatus,\n ZoomBounds,\n} from './types.js';\n\ntype RawObj = Record<string, unknown>;\n\nexport interface ChargePointOptions {\n coulombToken?: string;\n region?: string;\n}\n\nfunction parseMsTimestamp(v: unknown): Date {\n if (typeof v === 'number') return new Date(v);\n if (typeof v === 'string') return new Date(Number(v));\n return new Date(0);\n}\n\nexport class ChargePoint {\n public globalConfig: GlobalConfiguration;\n private _username: string;\n private _coulombToken: string | null = null;\n private _region: string;\n private _userId: number | null = null;\n\n /** The current session token. Save this after login to avoid re-authenticating. */\n get coulombToken(): string | null {\n return this._coulombToken;\n }\n\n private constructor(username: string, globalConfig: GlobalConfiguration, region: string) {\n this._username = username;\n this.globalConfig = globalConfig;\n this._region = region;\n }\n\n static async create(username: string, options: ChargePointOptions = {}): Promise<ChargePoint> {\n const region = options.region ?? 'NA';\n const config = await fetchGlobalConfig(region);\n const client = new ChargePoint(username, config, region);\n\n if (options.coulombToken) {\n client._setToken(options.coulombToken, region);\n }\n\n return client;\n }\n\n private _setToken(token: string, region: string): void {\n this._coulombToken = decodeURIComponent(token);\n this._region = region;\n }\n\n /** @internal Used by session.ts and tests. */\n async _request(method: string, url: string, init: RequestInit = {}): Promise<Response> {\n const headers = new Headers(init.headers as string[][] | Record<string, string> | Headers);\n headers.set('user-agent', USER_AGENT);\n\n if (!headers.has('content-type') && method !== 'GET') {\n headers.set('content-type', 'application/json');\n }\n\n if (this._coulombToken) {\n headers.set('cookie', `coulomb_sess=${this._coulombToken}`);\n headers.set('cp-session-type', 'CP_SESSION_TOKEN');\n headers.set('cp-session-token', this._coulombToken);\n headers.set('cp-region', this._region);\n }\n\n const response = await fetch(url, { ...init, method, headers });\n\n // Refresh coulomb_sess from Set-Cookie response header\n const setCookies: string[] =\n typeof (response.headers as unknown as { getSetCookie?: () => string[] }).getSetCookie ===\n 'function'\n ? (response.headers as unknown as { getSetCookie: () => string[] }).getSetCookie()\n : [response.headers.get('set-cookie') ?? ''].filter(Boolean);\n\n for (const cookie of setCookies) {\n const match = /^coulomb_sess=([^;]+)/.exec(cookie);\n if (match) {\n this._coulombToken = decodeURIComponent(match[1] ?? '');\n break;\n }\n }\n\n if (response.status === 401) {\n throw new InvalidSession(401, 'ChargePoint session expired. Please log in again.');\n }\n\n if (response.status === 403) {\n let body: unknown;\n try {\n body = await response.clone().json();\n } catch {\n // not JSON\n }\n const captchaUrl = (body as RawObj)?.url;\n if (typeof captchaUrl === 'string' && captchaUrl.includes('datadome')) {\n throw new DatadomeCaptcha(captchaUrl);\n }\n }\n\n return response;\n }\n\n private async _errorBody(response: Response): Promise<string> {\n try {\n return await response.clone().text();\n } catch {\n return '';\n }\n }\n\n // ---------------------------------------------------------------------------\n // Authentication\n // ---------------------------------------------------------------------------\n\n async loginWithPassword(password: string): Promise<void> {\n const url = `${this.globalConfig.endpoints.ssoEndpoint}/v1/user/login`;\n const response = await this._request('POST', url, {\n body: JSON.stringify({ user_name: this._username, password }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n let body: unknown;\n try { body = await response.json(); } catch { /* ignore */ }\n throw new LoginError(response.status, 'Failed to login with password.', body);\n }\n\n // The coulomb_sess cookie is set by the SSO endpoint on success;\n // _request() already extracted it from Set-Cookie above.\n await response.text(); // drain body\n\n if (!this._coulombToken) {\n throw new LoginError(response.status, 'Login succeeded but no session token was returned.');\n }\n }\n\n async loginWithSsoSession(ssoJwt: string): Promise<void> {\n // Exchange an SSO JWT for a coulomb_sess cookie via the portal endpoint.\n const url = `${this.globalConfig.endpoints.portalDomainEndpoint}/index.php/nghelper/getSession`;\n const response = await this._request('GET', url, {\n headers: {\n cookie: `auth-session=${ssoJwt}`,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n let body: unknown;\n try { body = await response.json(); } catch { /* ignore */ }\n throw new LoginError(response.status, 'Failed to login with SSO session.', body);\n }\n\n await response.text();\n }\n\n async logout(): Promise<void> {\n const url = `${this.globalConfig.endpoints.ssoEndpoint}/v1/user/logout`;\n try {\n await this._request('POST', url);\n } finally {\n this._coulombToken = null;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Account\n // ---------------------------------------------------------------------------\n\n async getAccount(): Promise<Account> {\n const url = `${this.globalConfig.endpoints.accountsEndpoint}/v1/driver/profile/user`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get account information.');\n }\n\n const data = (await response.json()) as Account;\n if (data.user?.userId) {\n this._userId = data.user.userId;\n }\n return data;\n }\n\n async getVehicles(): Promise<ElectricVehicle[]> {\n const url = `${this.globalConfig.endpoints.accountsEndpoint}/v1/driver/vehicle`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get vehicles.');\n }\n\n const data = (await response.json()) as RawObj;\n return (Array.isArray(data.vehicles) ? data.vehicles : []) as ElectricVehicle[];\n }\n\n async getUserChargingStatus(): Promise<UserChargingStatus | null> {\n const url = `${this.globalConfig.endpoints.mapcacheEndpoint}/v2`;\n const response = await this._request('POST', url, {\n body: JSON.stringify({ user_status: { timestamp: Date.now() } }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get user charging status.');\n }\n\n const data = (await response.json()) as RawObj;\n const userStatus = data.user_status as RawObj | null | undefined;\n\n if (!userStatus) return null;\n\n const charging = userStatus.charging_status as RawObj | null | undefined;\n if (!charging) return null;\n\n const stations: Station[] = Array.isArray(charging.stations)\n ? (charging.stations as RawObj[]).map((s) => ({\n id: s.id as number,\n name: typeof s.name === 'string' ? s.name : '',\n latitude: typeof s.lat === 'number' ? s.lat : (s.latitude as number ?? 0),\n longitude: typeof s.lon === 'number' ? s.lon : (s.longitude as number ?? 0),\n }))\n : [];\n\n return {\n sessionId: charging.session_id as number,\n startTime: parseMsTimestamp(charging.start_time),\n state: typeof charging.current_charging === 'string' ? charging.current_charging : '',\n stations,\n };\n }\n\n // ---------------------------------------------------------------------------\n // Home charger helpers\n // ---------------------------------------------------------------------------\n\n private async ensureUserId(): Promise<number> {\n if (this._userId !== null) return this._userId;\n const account = await this.getAccount();\n return account.user.userId;\n }\n\n async getHomeChargers(): Promise<number[]> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n let body: unknown;\n try { body = await response.json(); } catch { /* ignore */ }\n throw new CommunicationError(response.status, 'Failed to get home chargers.', body);\n }\n\n const data = (await response.json()) as RawObj;\n // API returns { data: [...] }; older shape used { chargers: [...] }\n const arr = Array.isArray(data.data)\n ? (data.data as RawObj[])\n : Array.isArray(data.chargers)\n ? (data.chargers as RawObj[])\n : [];\n return arr.map((c) => {\n // API uses \"id\" (string); older shape used chargerId / charger_id (number)\n const id = c.id ?? c.chargerId ?? c.charger_id;\n return typeof id === 'number' ? id : Number(id);\n });\n }\n\n async getHomeChargerStatus(chargerId: number): Promise<HomeChargerStatus> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/status`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger status.');\n }\n\n const data = (await response.json()) as RawObj;\n // Real API nests amperage info under chargeAmperageSettings; fall back to flat fields for older shapes\n const amp = (data.chargeAmperageSettings ?? {}) as RawObj;\n return {\n chargerId, // not echoed by the API; inject from parameter\n brand: String(data.brand ?? ''),\n model: String(data.model ?? ''),\n macAddress: String(data.macAddress ?? ''),\n chargingStatus: String(data.chargingStatus ?? ''),\n isPluggedIn: Boolean(data.isPluggedIn),\n isConnected: Boolean(data.isConnected),\n isReminderEnabled: Boolean(data.isReminderEnabled),\n plugInReminderTime: String(data.plugInReminderTime ?? ''),\n hasUtilityInfo: Boolean(data.hasUtilityInfo),\n isDuringScheduledTime: Boolean(data.isDuringScheduledTime),\n amperageLimit: Number(amp.chargeLimit ?? data.amperageLimit ?? 0),\n possibleAmperageLimits: ((amp.possibleChargeLimit ?? data.possibleAmperageLimits ?? []) as number[]).map(Number),\n };\n }\n\n async getHomeChargerTechnicalInfo(chargerId: number): Promise<HomeChargerTechnicalInfo> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/technical-info`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger technical info.');\n }\n\n return (await response.json()) as HomeChargerTechnicalInfo;\n }\n\n async getHomeChargerConfig(chargerId: number): Promise<HomeChargerConfiguration> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/configurations`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger configuration.');\n }\n\n const data = (await response.json()) as RawObj;\n // Real API wraps all fields under \"settings\"; fall back to flat shape for older responses\n const s = (data.settings ?? data) as RawObj;\n // LED brightness: real API uses settings.led.brightness with string-typed level/supportedLevels\n const rawLed = ((s.led as RawObj | undefined)?.brightness ?? s.ledBrightness ?? {}) as RawObj;\n const level =\n typeof rawLed.level === 'string'\n ? Number(rawLed.level)\n : Number(rawLed.level ?? rawLed.currentBrightnessSettings ?? 0);\n const supportedLevels = Array.isArray(rawLed.supportedLevels)\n ? (rawLed.supportedLevels as (string | number)[]).map(Number)\n : [];\n return {\n serialNumber: String(s.serialNumber ?? ''),\n macAddress: String(s.macAddress ?? ''),\n stationNickname: String(s.stationNickname ?? ''),\n streetAddress: String(s.streetAddress ?? ''),\n hasUtilityInfo: Boolean(s.hasUtilityInfo),\n utility: (s.utility ?? null) as HomeChargerConfiguration['utility'],\n // API may return boolean true/false or string \"ON\"/\"OFF\"\n indicatorLightEcoMode: s.indicatorLightEcoMode === true || s.indicatorLightEcoMode === 'ON',\n flashlightReset: Boolean(s.flashlightReset),\n worksWithNest: Boolean(s.worksWithNest),\n isPairedWithNest: Boolean(s.isPairedWithNest),\n isInstalledByInstaller: Boolean(s.isInstalledByInstaller),\n ledBrightness: {\n level,\n inProgress: Boolean(rawLed.inProgress),\n supportedLevels,\n isEnabled: rawLed.isEnabled !== false,\n },\n };\n }\n\n async getHomeChargerSchedule(chargerId: number): Promise<HomeChargerSchedule> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger schedule.');\n }\n\n return (await response.json()) as HomeChargerSchedule;\n }\n\n async setHomeChargerSchedule(\n chargerId: number,\n weekdayStart: string,\n weekdayEnd: string,\n weekendStart: string,\n weekendEnd: string,\n ): Promise<HomeChargerSchedule> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({\n schedule: {\n weekdays: { startTime: weekdayStart, endTime: weekdayEnd },\n weekends: { startTime: weekendStart, endTime: weekendEnd },\n },\n }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n const body = await this._errorBody(response);\n throw new CommunicationError(response.status, `Failed to set home charger schedule. HTTP ${response.status}: ${body}`);\n }\n\n return (await response.json()) as HomeChargerSchedule;\n }\n\n async disableHomeChargerSchedule(chargerId: number): Promise<void> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({}),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to disable home charger schedule.');\n }\n\n await response.text();\n }\n\n async setAmperageLimit(chargerId: number, amperageLimit: number): Promise<void> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/chargers/${chargerId}/charge-amperage-limit`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({ chargeAmperageLimit: amperageLimit }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n const body = await this._errorBody(response);\n throw new CommunicationError(response.status, `Failed to set amperage limit. HTTP ${response.status}: ${body}`);\n }\n\n await response.text();\n }\n\n async setLedBrightness(chargerId: number, level: number): Promise<void> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/chargers/${chargerId}/led-brightness`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({ ledBrightnessLevel: level }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n const body = await this._errorBody(response);\n throw new CommunicationError(response.status, `Failed to set LED brightness. HTTP ${response.status}: ${body}`);\n }\n\n await response.text();\n }\n\n async restartHomeCharger(chargerId: number): Promise<void> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/restart`;\n const response = await this._request('POST', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to restart home charger.');\n }\n\n await response.text();\n }\n\n // ---------------------------------------------------------------------------\n // Charging sessions\n // ---------------------------------------------------------------------------\n\n async getChargingSession(sessionId: number): Promise<ChargingSession> {\n const session = new ChargingSession(sessionId);\n session._setClient(this);\n await session.refresh();\n return session;\n }\n\n async startChargingSession(deviceId: number): Promise<ChargingSession> {\n return ChargingSession.start(deviceId, this);\n }\n\n // ---------------------------------------------------------------------------\n // Stations\n // ---------------------------------------------------------------------------\n\n async getStation(deviceId: number): Promise<StationInfo> {\n const url = `${this.globalConfig.endpoints.mapcacheEndpoint}/v3/station/info?deviceId=${deviceId}&use_cache=false`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get station info.');\n }\n\n return (await response.json()) as StationInfo;\n }\n\n async getNearbyStations(bounds: ZoomBounds, filter: MapFilter = {}): Promise<MapStation[]> {\n const url = `${this.globalConfig.endpoints.mapcacheEndpoint}/v2`;\n const stationList: RawObj = {\n ne_lat: bounds.neLat,\n ne_lon: bounds.neLon,\n sw_lat: bounds.swLat,\n sw_lon: bounds.swLon,\n ...filter,\n };\n\n const response = await this._request('POST', url, {\n body: JSON.stringify({ station_list: stationList }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get nearby stations.');\n }\n\n const data = (await response.json()) as RawObj;\n const list = data.station_list as RawObj | undefined;\n return Array.isArray(list?.stations) ? (list.stations as MapStation[]) : [];\n }\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -149,8 +149,8 @@ interface HomeChargerSchedule {
|
|
|
149
149
|
hasUtilityInfo: boolean;
|
|
150
150
|
basedOnUtility: PowerUtility | null;
|
|
151
151
|
defaultSchedule: ChargeSchedule;
|
|
152
|
-
userSchedule
|
|
153
|
-
utilitySchedule
|
|
152
|
+
userSchedule?: ChargeSchedule;
|
|
153
|
+
utilitySchedule?: ChargeSchedule | null;
|
|
154
154
|
}
|
|
155
155
|
interface ChargingSessionUpdate {
|
|
156
156
|
energyKwh: number;
|
|
@@ -393,6 +393,7 @@ declare class ChargePoint {
|
|
|
393
393
|
private _setToken;
|
|
394
394
|
/** @internal Used by session.ts and tests. */
|
|
395
395
|
_request(method: string, url: string, init?: RequestInit): Promise<Response>;
|
|
396
|
+
private _errorBody;
|
|
396
397
|
loginWithPassword(password: string): Promise<void>;
|
|
397
398
|
loginWithSsoSession(ssoJwt: string): Promise<void>;
|
|
398
399
|
logout(): Promise<void>;
|
package/dist/index.d.ts
CHANGED
|
@@ -149,8 +149,8 @@ interface HomeChargerSchedule {
|
|
|
149
149
|
hasUtilityInfo: boolean;
|
|
150
150
|
basedOnUtility: PowerUtility | null;
|
|
151
151
|
defaultSchedule: ChargeSchedule;
|
|
152
|
-
userSchedule
|
|
153
|
-
utilitySchedule
|
|
152
|
+
userSchedule?: ChargeSchedule;
|
|
153
|
+
utilitySchedule?: ChargeSchedule | null;
|
|
154
154
|
}
|
|
155
155
|
interface ChargingSessionUpdate {
|
|
156
156
|
energyKwh: number;
|
|
@@ -393,6 +393,7 @@ declare class ChargePoint {
|
|
|
393
393
|
private _setToken;
|
|
394
394
|
/** @internal Used by session.ts and tests. */
|
|
395
395
|
_request(method: string, url: string, init?: RequestInit): Promise<Response>;
|
|
396
|
+
private _errorBody;
|
|
396
397
|
loginWithPassword(password: string): Promise<void>;
|
|
397
398
|
loginWithSsoSession(ssoJwt: string): Promise<void>;
|
|
398
399
|
logout(): Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -306,7 +306,12 @@ var ChargingSession = class _ChargingSession {
|
|
|
306
306
|
}
|
|
307
307
|
static async start(deviceId, client) {
|
|
308
308
|
await sendCommand(client, "start", deviceId);
|
|
309
|
-
const
|
|
309
|
+
const deadline = Date.now() + 15e3;
|
|
310
|
+
let status = await client.getUserChargingStatus();
|
|
311
|
+
while (!status && Date.now() < deadline) {
|
|
312
|
+
await sleep(2e3);
|
|
313
|
+
status = await client.getUserChargingStatus();
|
|
314
|
+
}
|
|
310
315
|
if (!status) {
|
|
311
316
|
throw new APIError("No active charging session found after start command.");
|
|
312
317
|
}
|
|
@@ -348,7 +353,7 @@ var ChargePoint = class _ChargePoint {
|
|
|
348
353
|
return client;
|
|
349
354
|
}
|
|
350
355
|
_setToken(token, region) {
|
|
351
|
-
this._coulombToken = token;
|
|
356
|
+
this._coulombToken = decodeURIComponent(token);
|
|
352
357
|
this._region = region;
|
|
353
358
|
}
|
|
354
359
|
/** @internal Used by session.ts and tests. */
|
|
@@ -369,7 +374,7 @@ var ChargePoint = class _ChargePoint {
|
|
|
369
374
|
for (const cookie of setCookies) {
|
|
370
375
|
const match = /^coulomb_sess=([^;]+)/.exec(cookie);
|
|
371
376
|
if (match) {
|
|
372
|
-
this._coulombToken = match[1] ??
|
|
377
|
+
this._coulombToken = decodeURIComponent(match[1] ?? "");
|
|
373
378
|
break;
|
|
374
379
|
}
|
|
375
380
|
}
|
|
@@ -389,6 +394,13 @@ var ChargePoint = class _ChargePoint {
|
|
|
389
394
|
}
|
|
390
395
|
return response;
|
|
391
396
|
}
|
|
397
|
+
async _errorBody(response) {
|
|
398
|
+
try {
|
|
399
|
+
return await response.clone().text();
|
|
400
|
+
} catch {
|
|
401
|
+
return "";
|
|
402
|
+
}
|
|
403
|
+
}
|
|
392
404
|
// ---------------------------------------------------------------------------
|
|
393
405
|
// Authentication
|
|
394
406
|
// ---------------------------------------------------------------------------
|
|
@@ -595,8 +607,7 @@ var ChargePoint = class _ChargePoint {
|
|
|
595
607
|
const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;
|
|
596
608
|
const response = await this._request("PUT", url, {
|
|
597
609
|
body: JSON.stringify({
|
|
598
|
-
|
|
599
|
-
userSchedule: {
|
|
610
|
+
schedule: {
|
|
600
611
|
weekdays: { startTime: weekdayStart, endTime: weekdayEnd },
|
|
601
612
|
weekends: { startTime: weekendStart, endTime: weekendEnd }
|
|
602
613
|
}
|
|
@@ -604,14 +615,15 @@ var ChargePoint = class _ChargePoint {
|
|
|
604
615
|
headers: { "Content-Type": "application/json" }
|
|
605
616
|
});
|
|
606
617
|
if (!response.ok) {
|
|
607
|
-
|
|
618
|
+
const body = await this._errorBody(response);
|
|
619
|
+
throw new CommunicationError(response.status, `Failed to set home charger schedule. HTTP ${response.status}: ${body}`);
|
|
608
620
|
}
|
|
609
621
|
return await response.json();
|
|
610
622
|
}
|
|
611
623
|
async disableHomeChargerSchedule(chargerId) {
|
|
612
624
|
const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;
|
|
613
625
|
const response = await this._request("PUT", url, {
|
|
614
|
-
body: JSON.stringify({
|
|
626
|
+
body: JSON.stringify({}),
|
|
615
627
|
headers: { "Content-Type": "application/json" }
|
|
616
628
|
});
|
|
617
629
|
if (!response.ok) {
|
|
@@ -622,22 +634,24 @@ var ChargePoint = class _ChargePoint {
|
|
|
622
634
|
async setAmperageLimit(chargerId, amperageLimit) {
|
|
623
635
|
const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/chargers/${chargerId}/charge-amperage-limit`;
|
|
624
636
|
const response = await this._request("PUT", url, {
|
|
625
|
-
body: JSON.stringify({ amperageLimit }),
|
|
637
|
+
body: JSON.stringify({ chargeAmperageLimit: amperageLimit }),
|
|
626
638
|
headers: { "Content-Type": "application/json" }
|
|
627
639
|
});
|
|
628
640
|
if (!response.ok) {
|
|
629
|
-
|
|
641
|
+
const body = await this._errorBody(response);
|
|
642
|
+
throw new CommunicationError(response.status, `Failed to set amperage limit. HTTP ${response.status}: ${body}`);
|
|
630
643
|
}
|
|
631
644
|
await response.text();
|
|
632
645
|
}
|
|
633
646
|
async setLedBrightness(chargerId, level) {
|
|
634
647
|
const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/chargers/${chargerId}/led-brightness`;
|
|
635
648
|
const response = await this._request("PUT", url, {
|
|
636
|
-
body: JSON.stringify({ level }),
|
|
649
|
+
body: JSON.stringify({ ledBrightnessLevel: level }),
|
|
637
650
|
headers: { "Content-Type": "application/json" }
|
|
638
651
|
});
|
|
639
652
|
if (!response.ok) {
|
|
640
|
-
|
|
653
|
+
const body = await this._errorBody(response);
|
|
654
|
+
throw new CommunicationError(response.status, `Failed to set LED brightness. HTTP ${response.status}: ${body}`);
|
|
641
655
|
}
|
|
642
656
|
await response.text();
|
|
643
657
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants.ts","../src/exceptions.ts","../src/global-config.ts","../src/session.ts","../src/client.ts"],"names":["parseMsTimestamp"],"mappings":"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","file":"index.js","sourcesContent":["export const DISCOVERY_API =\n 'https://discovery.chargepoint.com/discovery/v3/globalconfig';\n\nexport const VERSION = '0.0.1-alpha.0';\nexport const USER_AGENT = `node-chargepoint/${VERSION}`;\n","export class APIError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'APIError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class CommunicationError extends APIError {\n constructor(\n public readonly statusCode: number,\n message: string,\n public readonly body?: unknown,\n ) {\n super(message);\n this.name = 'CommunicationError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class LoginError extends CommunicationError {\n constructor(statusCode: number, message: string, body?: unknown) {\n super(statusCode, message, body);\n this.name = 'LoginError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class InvalidSession extends CommunicationError {\n constructor(statusCode = 401, message = 'ChargePoint session expired. Please log in again.', body?: unknown) {\n super(statusCode, message, body);\n this.name = 'InvalidSession';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class DatadomeCaptcha extends APIError {\n constructor(\n public readonly captchaUrl: string,\n message = 'Datadome captcha protection triggered.',\n ) {\n super(message);\n this.name = 'DatadomeCaptcha';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","import https from 'node:https';\nimport { DISCOVERY_API, USER_AGENT } from './constants.js';\nimport { CommunicationError } from './exceptions.js';\nimport type { APIEndpoints, GlobalConfiguration } from './types.js';\n\ntype RawValue = Record<string, unknown>;\n\n// Node 24's built-in fetch automatically adds `Sec-Fetch-Mode: cors`, which\n// causes the ChargePoint discovery endpoint to return HTTP 500. Using node:https\n// directly avoids that header. Default import (not named) is required so that\n// MSW's runtime patch of https.request is visible at call time in unit tests.\nasync function postJson(url: string, body: string): Promise<{ status: number; data: RawValue }> {\n return new Promise((resolve, reject) => {\n const bodyBuf = Buffer.from(body, 'utf-8');\n const req = https.request(\n url,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Content-Length': bodyBuf.byteLength,\n 'User-Agent': USER_AGENT,\n },\n },\n (res) => {\n const chunks: Buffer[] = [];\n res.on('data', (chunk: Buffer) => chunks.push(chunk));\n res.on('end', () => {\n const statusCode = res.statusCode ?? 0;\n if (statusCode < 200 || statusCode >= 300) {\n reject(new CommunicationError(statusCode, 'Failed to fetch global configuration.'));\n return;\n }\n try {\n resolve({ status: statusCode, data: JSON.parse(Buffer.concat(chunks).toString('utf-8')) as RawValue });\n } catch {\n reject(new CommunicationError(statusCode, 'Failed to parse global configuration response.'));\n }\n });\n },\n );\n req.on('error', (err: Error) => {\n reject(new CommunicationError(0, `Failed to reach ChargePoint discovery API: ${err.message}`));\n });\n req.write(bodyBuf);\n req.end();\n });\n}\n\nfunction endpointStr(v: unknown): string {\n const raw =\n v !== null && typeof v === 'object' && 'value' in v\n ? String((v as RawValue).value ?? '')\n : typeof v === 'string'\n ? v\n : '';\n return raw.replace(/\\/+$/, ''); // strip trailing slashes so callers can always do `${url}/path`\n}\n\nfunction parseEndpoints(raw: RawValue): APIEndpoints {\n // Support both camelCase and snake_case keys from the discovery API\n const get = (camel: string, snake: string): string =>\n endpointStr(raw[camel] ?? raw[snake] ?? '');\n\n return {\n accountsEndpoint: get('accountsEndpoint', 'accounts_endpoint'),\n internalApiGatewayEndpoint: get('internalApiGatewayEndpoint', 'internal_api_gateway_endpoint'),\n mapcacheEndpoint: get('mapcacheEndpoint', 'mapcache_endpoint'),\n pandaWebsocketEndpoint: get('pandaWebsocketEndpoint', 'panda_websocket_endpoint'),\n paymentJavaEndpoint: get('paymentJavaEndpoint', 'payment_java_endpoint'),\n paymentPhpEndpoint: get('paymentPhpEndpoint', 'payment_php_endpoint'),\n portalDomainEndpoint: get('portalDomainEndpoint', 'portal_domain_endpoint'),\n portalSubdomain:\n typeof raw.portalSubdomain === 'string'\n ? raw.portalSubdomain\n : typeof raw.portal_subdomain === 'string'\n ? raw.portal_subdomain\n : '',\n ssoEndpoint: get('ssoEndpoint', 'sso_endpoint'),\n webservicesEndpoint: get('webservicesEndpoint', 'webservices_endpoint'),\n websocketEndpoint: get('websocketEndpoint', 'websocket_endpoint'),\n hcpoHcmEndpoint: get('hcpoHcmEndpoint', 'hcpo_hcm_endpoint'),\n };\n}\n\nexport async function fetchGlobalConfig(region = 'NA'): Promise<GlobalConfiguration> {\n const { data } = await postJson(DISCOVERY_API, JSON.stringify({ regionCode: region }));\n\n // The API may return the config directly or nested under \"globalConfiguration\"\n const raw = (typeof data.globalConfiguration === 'object' && data.globalConfiguration !== null\n ? data.globalConfiguration\n : data) as RawValue;\n\n const endpointsRaw = (raw.endPoints ?? raw.endpoints ?? {}) as RawValue;\n\n return {\n region: typeof raw.region === 'string' ? raw.region : region,\n defaultCountry: (raw.defaultCountry ?? {}) as GlobalConfiguration['defaultCountry'],\n supportedCountries: Array.isArray(raw.supportedCountries)\n ? (raw.supportedCountries as GlobalConfiguration['supportedCountries'])\n : [],\n defaultCurrency: (raw.currency ?? raw.defaultCurrency ?? {}) as GlobalConfiguration['defaultCurrency'],\n supportedCurrencies: Array.isArray(raw.supportedCurrencies)\n ? (raw.supportedCurrencies as GlobalConfiguration['supportedCurrencies'])\n : [],\n endpoints: parseEndpoints(endpointsRaw),\n };\n}\n","import type { ChargePoint } from './client.js';\nimport { APIError, CommunicationError } from './exceptions.js';\nimport type { ChargingSessionUpdate, PowerUtility, VehicleInfo } from './types.js';\n\nconst sleep = (ms: number): Promise<void> =>\n new Promise((resolve) => setTimeout(resolve, ms));\n\ntype RawObj = Record<string, unknown>;\n\nexport async function sendCommand(\n client: ChargePoint,\n action: 'start' | 'stop',\n deviceId: number,\n portNumber = 1,\n sessionId = 0,\n): Promise<void> {\n const actionPath = action === 'start' ? 'startsession' : 'stopSession';\n const body: RawObj = { deviceId };\n\n if (action === 'stop') {\n body.portNumber = portNumber;\n body.sessionId = sessionId;\n }\n\n const url = `${client.globalConfig.endpoints.accountsEndpoint}/v1/driver/station/${actionPath}`;\n const response = await client._request('POST', url, {\n body: JSON.stringify(body),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new CommunicationError(\n response.status,\n `Failed to ${action} ChargePoint session: ${text}`,\n );\n }\n\n const actionStatus = (await response.json()) as RawObj;\n const ackId = actionStatus.ackId;\n\n const ackUrl = `${client.globalConfig.endpoints.accountsEndpoint}/v1/driver/station/session/ack`;\n\n let lastStatus = 0;\n let errorMessage = `Session failed to ${action}.`;\n let errorBody: unknown;\n\n for (let attempt = 1; attempt <= 20; attempt++) {\n const ackResponse = await client._request('POST', ackUrl, {\n body: JSON.stringify({ ackId, action: `${action}_session` }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n lastStatus = ackResponse.status;\n\n if (ackResponse.status === 200) {\n return;\n }\n\n try {\n errorBody = await ackResponse.json();\n const msg = (errorBody as RawObj).errorMessage;\n if (typeof msg === 'string') errorMessage = msg;\n } catch {\n errorBody = undefined;\n }\n\n if (attempt < 20) {\n await sleep(3000);\n }\n }\n\n throw new CommunicationError(lastStatus, errorMessage, errorBody);\n}\n\nfunction parseMsTimestamp(v: unknown): Date {\n if (typeof v === 'number') return new Date(v);\n if (typeof v === 'string') return new Date(Number(v));\n return new Date(0);\n}\n\nfunction parseSessionUpdates(raw: unknown): ChargingSessionUpdate[] {\n if (!Array.isArray(raw)) return [];\n return raw.map((u: unknown) => {\n const item = u as RawObj;\n return {\n energyKwh: typeof item.energy_kwh === 'number' ? item.energy_kwh : 0,\n powerKw: typeof item.power_kw === 'number' ? item.power_kw : 0,\n timestamp: parseMsTimestamp(item.timestamp),\n };\n });\n}\n\nexport class ChargingSession {\n sessionId: number;\n deviceId = 0;\n deviceName = '';\n chargingState = '';\n chargingTime = 0;\n energyKwh = 0;\n milesAdded = 0;\n milesAddedPerHour = 0;\n outletNumber = 0;\n portLevel = 0;\n powerKw = 0;\n purpose = '';\n currencyIsoCode = '';\n paymentCompleted = false;\n paymentType = '';\n pricingSpecId = 0;\n totalAmount = 0;\n apiFlag = false;\n enableStopCharging = false;\n hasChargingReceipt = false;\n hasUtilityInfo = false;\n isHomeCharger = false;\n isPurposeFinalized = false;\n stopChargeSupported = false;\n companyId = 0;\n companyName = '';\n latitude = 0;\n longitude = 0;\n address = '';\n city = '';\n stateName = '';\n country = '';\n zipcode = '';\n updatePeriod = 0;\n startTime: Date | null = null;\n lastUpdateDataTimestamp: Date | null = null;\n updateData: ChargingSessionUpdate[] | null = null;\n utility: PowerUtility | null = null;\n vehicleInfo: VehicleInfo | null = null;\n\n private _client: ChargePoint | null = null;\n\n constructor(sessionId: number) {\n this.sessionId = sessionId;\n }\n\n /** @internal */\n _setClient(client: ChargePoint): void {\n this._client = client;\n }\n\n /** @internal Apply raw session data from the driver-bff API (snake_case keys). */\n _apply(data: RawObj): void {\n if (data.device_id !== undefined) this.deviceId = data.device_id as number;\n if (data.device_name !== undefined) this.deviceName = data.device_name as string;\n if (data.current_charging !== undefined) this.chargingState = data.current_charging as string;\n if (data.charging_time !== undefined) this.chargingTime = data.charging_time as number;\n if (data.energy_kwh !== undefined) this.energyKwh = data.energy_kwh as number;\n if (data.miles_added !== undefined) this.milesAdded = data.miles_added as number;\n if (data.miles_added_per_hour !== undefined) this.milesAddedPerHour = data.miles_added_per_hour as number;\n if (data.outlet_number !== undefined) this.outletNumber = data.outlet_number as number;\n if (data.port_level !== undefined) this.portLevel = data.port_level as number;\n if (data.power_kw !== undefined) this.powerKw = data.power_kw as number;\n if (data.purpose !== undefined) this.purpose = data.purpose as string;\n if (data.currency_iso_code !== undefined) this.currencyIsoCode = String(data.currency_iso_code);\n if (data.payment_completed !== undefined) this.paymentCompleted = data.payment_completed as boolean;\n if (data.payment_type !== undefined) this.paymentType = data.payment_type as string;\n if (data.pricing_spec_id !== undefined) this.pricingSpecId = data.pricing_spec_id as number;\n if (data.total_amount !== undefined) this.totalAmount = data.total_amount as number;\n if (data.api_flag !== undefined) this.apiFlag = data.api_flag as boolean;\n if (data.enable_stop_charging !== undefined) this.enableStopCharging = data.enable_stop_charging as boolean;\n if (data.has_charging_receipt !== undefined) this.hasChargingReceipt = data.has_charging_receipt as boolean;\n if (data.has_utility_info !== undefined) this.hasUtilityInfo = data.has_utility_info as boolean;\n if (data.is_home_charger !== undefined) this.isHomeCharger = data.is_home_charger as boolean;\n if (data.is_purpose_finalized !== undefined) this.isPurposeFinalized = data.is_purpose_finalized as boolean;\n if (data.stop_charge_supported !== undefined) this.stopChargeSupported = data.stop_charge_supported as boolean;\n if (data.company_id !== undefined) this.companyId = data.company_id as number;\n if (data.company_name !== undefined) this.companyName = data.company_name as string;\n if (data.lat !== undefined) this.latitude = data.lat as number;\n if (data.lon !== undefined) this.longitude = data.lon as number;\n if (data.address1 !== undefined) this.address = data.address1 as string;\n if (data.city !== undefined) this.city = data.city as string;\n if (data.state_name !== undefined) this.stateName = data.state_name as string;\n if (data.country !== undefined) this.country = data.country as string;\n if (data.zipcode !== undefined) this.zipcode = data.zipcode as string;\n if (data.update_period !== undefined) this.updatePeriod = data.update_period as number;\n if (data.start_time !== undefined) this.startTime = parseMsTimestamp(data.start_time);\n if (data.last_update_data_timestamp !== undefined) {\n this.lastUpdateDataTimestamp = parseMsTimestamp(data.last_update_data_timestamp);\n }\n if (data.update_data !== undefined) this.updateData = parseSessionUpdates(data.update_data);\n if (data.utility !== undefined) this.utility = (data.utility as PowerUtility) ?? null;\n if (data.vehicle_info !== undefined) this.vehicleInfo = (data.vehicle_info as VehicleInfo) ?? null;\n }\n\n async refresh(): Promise<void> {\n if (!this._client) throw new Error('ChargingSession client not set.');\n\n const url = `${this._client.globalConfig.endpoints.internalApiGatewayEndpoint}/driver-bff/v1/sessions/${this.sessionId}`;\n const response = await this._client._request('POST', url, {\n body: JSON.stringify({\n charging_status: { session_id: this.sessionId, mfhs: [] },\n }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get charging session data.');\n }\n\n const json = (await response.json()) as RawObj;\n const status = json.charging_status as RawObj | undefined;\n\n if (!status || 'error_message' in status || 'error' in status) {\n throw new CommunicationError(response.status, 'Failed to get charging session data.');\n }\n\n this._apply(status);\n }\n\n async stop(): Promise<void> {\n if (!this._client) throw new Error('ChargingSession client not set.');\n await sendCommand(\n this._client,\n 'stop',\n this.deviceId,\n this.outletNumber,\n this.sessionId,\n );\n }\n\n static async start(deviceId: number, client: ChargePoint): Promise<ChargingSession> {\n await sendCommand(client, 'start', deviceId);\n // The sessionId returned by the start endpoint is not the real session ID;\n // fetch it from the status API instead.\n const status = await client.getUserChargingStatus();\n if (!status) {\n throw new APIError('No active charging session found after start command.');\n }\n const session = new ChargingSession(status.sessionId);\n session._setClient(client);\n await session.refresh();\n return session;\n }\n}\n","import { USER_AGENT } from './constants.js';\nimport { CommunicationError, DatadomeCaptcha, InvalidSession, LoginError } from './exceptions.js';\nimport { fetchGlobalConfig } from './global-config.js';\nimport { ChargingSession } from './session.js';\nimport type {\n Account,\n ElectricVehicle,\n GlobalConfiguration,\n HomeChargerConfiguration,\n HomeChargerSchedule,\n HomeChargerStatus,\n HomeChargerTechnicalInfo,\n MapFilter,\n MapStation,\n Station,\n StationInfo,\n UserChargingStatus,\n ZoomBounds,\n} from './types.js';\n\ntype RawObj = Record<string, unknown>;\n\nexport interface ChargePointOptions {\n coulombToken?: string;\n region?: string;\n}\n\nfunction parseMsTimestamp(v: unknown): Date {\n if (typeof v === 'number') return new Date(v);\n if (typeof v === 'string') return new Date(Number(v));\n return new Date(0);\n}\n\nexport class ChargePoint {\n public globalConfig: GlobalConfiguration;\n private _username: string;\n private _coulombToken: string | null = null;\n private _region: string;\n private _userId: number | null = null;\n\n /** The current session token. Save this after login to avoid re-authenticating. */\n get coulombToken(): string | null {\n return this._coulombToken;\n }\n\n private constructor(username: string, globalConfig: GlobalConfiguration, region: string) {\n this._username = username;\n this.globalConfig = globalConfig;\n this._region = region;\n }\n\n static async create(username: string, options: ChargePointOptions = {}): Promise<ChargePoint> {\n const region = options.region ?? 'NA';\n const config = await fetchGlobalConfig(region);\n const client = new ChargePoint(username, config, region);\n\n if (options.coulombToken) {\n client._setToken(options.coulombToken, region);\n }\n\n return client;\n }\n\n private _setToken(token: string, region: string): void {\n this._coulombToken = token;\n this._region = region;\n }\n\n /** @internal Used by session.ts and tests. */\n async _request(method: string, url: string, init: RequestInit = {}): Promise<Response> {\n const headers = new Headers(init.headers as string[][] | Record<string, string> | Headers);\n headers.set('user-agent', USER_AGENT);\n\n if (!headers.has('content-type') && method !== 'GET') {\n headers.set('content-type', 'application/json');\n }\n\n if (this._coulombToken) {\n headers.set('cookie', `coulomb_sess=${this._coulombToken}`);\n headers.set('cp-session-type', 'CP_SESSION_TOKEN');\n headers.set('cp-session-token', this._coulombToken);\n headers.set('cp-region', this._region);\n }\n\n const response = await fetch(url, { ...init, method, headers });\n\n // Refresh coulomb_sess from Set-Cookie response header\n const setCookies: string[] =\n typeof (response.headers as unknown as { getSetCookie?: () => string[] }).getSetCookie ===\n 'function'\n ? (response.headers as unknown as { getSetCookie: () => string[] }).getSetCookie()\n : [response.headers.get('set-cookie') ?? ''].filter(Boolean);\n\n for (const cookie of setCookies) {\n const match = /^coulomb_sess=([^;]+)/.exec(cookie);\n if (match) {\n this._coulombToken = match[1] ?? null;\n break;\n }\n }\n\n if (response.status === 401) {\n throw new InvalidSession(401, 'ChargePoint session expired. Please log in again.');\n }\n\n if (response.status === 403) {\n let body: unknown;\n try {\n body = await response.clone().json();\n } catch {\n // not JSON\n }\n const captchaUrl = (body as RawObj)?.url;\n if (typeof captchaUrl === 'string' && captchaUrl.includes('datadome')) {\n throw new DatadomeCaptcha(captchaUrl);\n }\n }\n\n return response;\n }\n\n // ---------------------------------------------------------------------------\n // Authentication\n // ---------------------------------------------------------------------------\n\n async loginWithPassword(password: string): Promise<void> {\n const url = `${this.globalConfig.endpoints.ssoEndpoint}/v1/user/login`;\n const response = await this._request('POST', url, {\n body: JSON.stringify({ user_name: this._username, password }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n let body: unknown;\n try { body = await response.json(); } catch { /* ignore */ }\n throw new LoginError(response.status, 'Failed to login with password.', body);\n }\n\n // The coulomb_sess cookie is set by the SSO endpoint on success;\n // _request() already extracted it from Set-Cookie above.\n await response.text(); // drain body\n\n if (!this._coulombToken) {\n throw new LoginError(response.status, 'Login succeeded but no session token was returned.');\n }\n }\n\n async loginWithSsoSession(ssoJwt: string): Promise<void> {\n // Exchange an SSO JWT for a coulomb_sess cookie via the portal endpoint.\n const url = `${this.globalConfig.endpoints.portalDomainEndpoint}/index.php/nghelper/getSession`;\n const response = await this._request('GET', url, {\n headers: {\n cookie: `auth-session=${ssoJwt}`,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n let body: unknown;\n try { body = await response.json(); } catch { /* ignore */ }\n throw new LoginError(response.status, 'Failed to login with SSO session.', body);\n }\n\n await response.text();\n }\n\n async logout(): Promise<void> {\n const url = `${this.globalConfig.endpoints.ssoEndpoint}/v1/user/logout`;\n try {\n await this._request('POST', url);\n } finally {\n this._coulombToken = null;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Account\n // ---------------------------------------------------------------------------\n\n async getAccount(): Promise<Account> {\n const url = `${this.globalConfig.endpoints.accountsEndpoint}/v1/driver/profile/user`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get account information.');\n }\n\n const data = (await response.json()) as Account;\n if (data.user?.userId) {\n this._userId = data.user.userId;\n }\n return data;\n }\n\n async getVehicles(): Promise<ElectricVehicle[]> {\n const url = `${this.globalConfig.endpoints.accountsEndpoint}/v1/driver/vehicle`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get vehicles.');\n }\n\n const data = (await response.json()) as RawObj;\n return (Array.isArray(data.vehicles) ? data.vehicles : []) as ElectricVehicle[];\n }\n\n async getUserChargingStatus(): Promise<UserChargingStatus | null> {\n const url = `${this.globalConfig.endpoints.mapcacheEndpoint}/v2`;\n const response = await this._request('POST', url, {\n body: JSON.stringify({ user_status: { timestamp: Date.now() } }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get user charging status.');\n }\n\n const data = (await response.json()) as RawObj;\n const userStatus = data.user_status as RawObj | null | undefined;\n\n if (!userStatus) return null;\n\n const charging = userStatus.charging_status as RawObj | null | undefined;\n if (!charging) return null;\n\n const stations: Station[] = Array.isArray(charging.stations)\n ? (charging.stations as RawObj[]).map((s) => ({\n id: s.id as number,\n name: typeof s.name === 'string' ? s.name : '',\n latitude: typeof s.lat === 'number' ? s.lat : (s.latitude as number ?? 0),\n longitude: typeof s.lon === 'number' ? s.lon : (s.longitude as number ?? 0),\n }))\n : [];\n\n return {\n sessionId: charging.session_id as number,\n startTime: parseMsTimestamp(charging.start_time),\n state: typeof charging.current_charging === 'string' ? charging.current_charging : '',\n stations,\n };\n }\n\n // ---------------------------------------------------------------------------\n // Home charger helpers\n // ---------------------------------------------------------------------------\n\n private async ensureUserId(): Promise<number> {\n if (this._userId !== null) return this._userId;\n const account = await this.getAccount();\n return account.user.userId;\n }\n\n async getHomeChargers(): Promise<number[]> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n let body: unknown;\n try { body = await response.json(); } catch { /* ignore */ }\n throw new CommunicationError(response.status, 'Failed to get home chargers.', body);\n }\n\n const data = (await response.json()) as RawObj;\n // API returns { data: [...] }; older shape used { chargers: [...] }\n const arr = Array.isArray(data.data)\n ? (data.data as RawObj[])\n : Array.isArray(data.chargers)\n ? (data.chargers as RawObj[])\n : [];\n return arr.map((c) => {\n // API uses \"id\" (string); older shape used chargerId / charger_id (number)\n const id = c.id ?? c.chargerId ?? c.charger_id;\n return typeof id === 'number' ? id : Number(id);\n });\n }\n\n async getHomeChargerStatus(chargerId: number): Promise<HomeChargerStatus> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/status`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger status.');\n }\n\n const data = (await response.json()) as RawObj;\n // Real API nests amperage info under chargeAmperageSettings; fall back to flat fields for older shapes\n const amp = (data.chargeAmperageSettings ?? {}) as RawObj;\n return {\n chargerId, // not echoed by the API; inject from parameter\n brand: String(data.brand ?? ''),\n model: String(data.model ?? ''),\n macAddress: String(data.macAddress ?? ''),\n chargingStatus: String(data.chargingStatus ?? ''),\n isPluggedIn: Boolean(data.isPluggedIn),\n isConnected: Boolean(data.isConnected),\n isReminderEnabled: Boolean(data.isReminderEnabled),\n plugInReminderTime: String(data.plugInReminderTime ?? ''),\n hasUtilityInfo: Boolean(data.hasUtilityInfo),\n isDuringScheduledTime: Boolean(data.isDuringScheduledTime),\n amperageLimit: Number(amp.chargeLimit ?? data.amperageLimit ?? 0),\n possibleAmperageLimits: ((amp.possibleChargeLimit ?? data.possibleAmperageLimits ?? []) as number[]).map(Number),\n };\n }\n\n async getHomeChargerTechnicalInfo(chargerId: number): Promise<HomeChargerTechnicalInfo> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/technical-info`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger technical info.');\n }\n\n return (await response.json()) as HomeChargerTechnicalInfo;\n }\n\n async getHomeChargerConfig(chargerId: number): Promise<HomeChargerConfiguration> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/configurations`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger configuration.');\n }\n\n const data = (await response.json()) as RawObj;\n // Real API wraps all fields under \"settings\"; fall back to flat shape for older responses\n const s = (data.settings ?? data) as RawObj;\n // LED brightness: real API uses settings.led.brightness with string-typed level/supportedLevels\n const rawLed = ((s.led as RawObj | undefined)?.brightness ?? s.ledBrightness ?? {}) as RawObj;\n const level =\n typeof rawLed.level === 'string'\n ? Number(rawLed.level)\n : Number(rawLed.level ?? rawLed.currentBrightnessSettings ?? 0);\n const supportedLevels = Array.isArray(rawLed.supportedLevels)\n ? (rawLed.supportedLevels as (string | number)[]).map(Number)\n : [];\n return {\n serialNumber: String(s.serialNumber ?? ''),\n macAddress: String(s.macAddress ?? ''),\n stationNickname: String(s.stationNickname ?? ''),\n streetAddress: String(s.streetAddress ?? ''),\n hasUtilityInfo: Boolean(s.hasUtilityInfo),\n utility: (s.utility ?? null) as HomeChargerConfiguration['utility'],\n // API may return boolean true/false or string \"ON\"/\"OFF\"\n indicatorLightEcoMode: s.indicatorLightEcoMode === true || s.indicatorLightEcoMode === 'ON',\n flashlightReset: Boolean(s.flashlightReset),\n worksWithNest: Boolean(s.worksWithNest),\n isPairedWithNest: Boolean(s.isPairedWithNest),\n isInstalledByInstaller: Boolean(s.isInstalledByInstaller),\n ledBrightness: {\n level,\n inProgress: Boolean(rawLed.inProgress),\n supportedLevels,\n isEnabled: rawLed.isEnabled !== false,\n },\n };\n }\n\n async getHomeChargerSchedule(chargerId: number): Promise<HomeChargerSchedule> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger schedule.');\n }\n\n return (await response.json()) as HomeChargerSchedule;\n }\n\n async setHomeChargerSchedule(\n chargerId: number,\n weekdayStart: string,\n weekdayEnd: string,\n weekendStart: string,\n weekendEnd: string,\n ): Promise<HomeChargerSchedule> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({\n scheduleEnabled: true,\n userSchedule: {\n weekdays: { startTime: weekdayStart, endTime: weekdayEnd },\n weekends: { startTime: weekendStart, endTime: weekendEnd },\n },\n }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to set home charger schedule.');\n }\n\n return (await response.json()) as HomeChargerSchedule;\n }\n\n async disableHomeChargerSchedule(chargerId: number): Promise<void> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({ scheduleEnabled: false }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to disable home charger schedule.');\n }\n\n await response.text();\n }\n\n async setAmperageLimit(chargerId: number, amperageLimit: number): Promise<void> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/chargers/${chargerId}/charge-amperage-limit`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({ amperageLimit }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to set amperage limit.');\n }\n\n await response.text();\n }\n\n async setLedBrightness(chargerId: number, level: number): Promise<void> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/chargers/${chargerId}/led-brightness`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({ level }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to set LED brightness.');\n }\n\n await response.text();\n }\n\n async restartHomeCharger(chargerId: number): Promise<void> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/restart`;\n const response = await this._request('POST', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to restart home charger.');\n }\n\n await response.text();\n }\n\n // ---------------------------------------------------------------------------\n // Charging sessions\n // ---------------------------------------------------------------------------\n\n async getChargingSession(sessionId: number): Promise<ChargingSession> {\n const session = new ChargingSession(sessionId);\n session._setClient(this);\n await session.refresh();\n return session;\n }\n\n async startChargingSession(deviceId: number): Promise<ChargingSession> {\n return ChargingSession.start(deviceId, this);\n }\n\n // ---------------------------------------------------------------------------\n // Stations\n // ---------------------------------------------------------------------------\n\n async getStation(deviceId: number): Promise<StationInfo> {\n const url = `${this.globalConfig.endpoints.mapcacheEndpoint}/v3/station/info?deviceId=${deviceId}&use_cache=false`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get station info.');\n }\n\n return (await response.json()) as StationInfo;\n }\n\n async getNearbyStations(bounds: ZoomBounds, filter: MapFilter = {}): Promise<MapStation[]> {\n const url = `${this.globalConfig.endpoints.mapcacheEndpoint}/v2`;\n const stationList: RawObj = {\n ne_lat: bounds.neLat,\n ne_lon: bounds.neLon,\n sw_lat: bounds.swLat,\n sw_lon: bounds.swLon,\n ...filter,\n };\n\n const response = await this._request('POST', url, {\n body: JSON.stringify({ station_list: stationList }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get nearby stations.');\n }\n\n const data = (await response.json()) as RawObj;\n const list = data.station_list as RawObj | undefined;\n return Array.isArray(list?.stations) ? (list.stations as MapStation[]) : [];\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/exceptions.ts","../src/global-config.ts","../src/session.ts","../src/client.ts"],"names":["parseMsTimestamp"],"mappings":"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","file":"index.js","sourcesContent":["export const DISCOVERY_API =\n 'https://discovery.chargepoint.com/discovery/v3/globalconfig';\n\nexport const VERSION = '0.0.1-alpha.0';\nexport const USER_AGENT = `node-chargepoint/${VERSION}`;\n","export class APIError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'APIError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class CommunicationError extends APIError {\n constructor(\n public readonly statusCode: number,\n message: string,\n public readonly body?: unknown,\n ) {\n super(message);\n this.name = 'CommunicationError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class LoginError extends CommunicationError {\n constructor(statusCode: number, message: string, body?: unknown) {\n super(statusCode, message, body);\n this.name = 'LoginError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class InvalidSession extends CommunicationError {\n constructor(statusCode = 401, message = 'ChargePoint session expired. Please log in again.', body?: unknown) {\n super(statusCode, message, body);\n this.name = 'InvalidSession';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class DatadomeCaptcha extends APIError {\n constructor(\n public readonly captchaUrl: string,\n message = 'Datadome captcha protection triggered.',\n ) {\n super(message);\n this.name = 'DatadomeCaptcha';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","import https from 'node:https';\nimport { DISCOVERY_API, USER_AGENT } from './constants.js';\nimport { CommunicationError } from './exceptions.js';\nimport type { APIEndpoints, GlobalConfiguration } from './types.js';\n\ntype RawValue = Record<string, unknown>;\n\n// Node 24's built-in fetch automatically adds `Sec-Fetch-Mode: cors`, which\n// causes the ChargePoint discovery endpoint to return HTTP 500. Using node:https\n// directly avoids that header. Default import (not named) is required so that\n// MSW's runtime patch of https.request is visible at call time in unit tests.\nasync function postJson(url: string, body: string): Promise<{ status: number; data: RawValue }> {\n return new Promise((resolve, reject) => {\n const bodyBuf = Buffer.from(body, 'utf-8');\n const req = https.request(\n url,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Content-Length': bodyBuf.byteLength,\n 'User-Agent': USER_AGENT,\n },\n },\n (res) => {\n const chunks: Buffer[] = [];\n res.on('data', (chunk: Buffer) => chunks.push(chunk));\n res.on('end', () => {\n const statusCode = res.statusCode ?? 0;\n if (statusCode < 200 || statusCode >= 300) {\n reject(new CommunicationError(statusCode, 'Failed to fetch global configuration.'));\n return;\n }\n try {\n resolve({ status: statusCode, data: JSON.parse(Buffer.concat(chunks).toString('utf-8')) as RawValue });\n } catch {\n reject(new CommunicationError(statusCode, 'Failed to parse global configuration response.'));\n }\n });\n },\n );\n req.on('error', (err: Error) => {\n reject(new CommunicationError(0, `Failed to reach ChargePoint discovery API: ${err.message}`));\n });\n req.write(bodyBuf);\n req.end();\n });\n}\n\nfunction endpointStr(v: unknown): string {\n const raw =\n v !== null && typeof v === 'object' && 'value' in v\n ? String((v as RawValue).value ?? '')\n : typeof v === 'string'\n ? v\n : '';\n return raw.replace(/\\/+$/, ''); // strip trailing slashes so callers can always do `${url}/path`\n}\n\nfunction parseEndpoints(raw: RawValue): APIEndpoints {\n // Support both camelCase and snake_case keys from the discovery API\n const get = (camel: string, snake: string): string =>\n endpointStr(raw[camel] ?? raw[snake] ?? '');\n\n return {\n accountsEndpoint: get('accountsEndpoint', 'accounts_endpoint'),\n internalApiGatewayEndpoint: get('internalApiGatewayEndpoint', 'internal_api_gateway_endpoint'),\n mapcacheEndpoint: get('mapcacheEndpoint', 'mapcache_endpoint'),\n pandaWebsocketEndpoint: get('pandaWebsocketEndpoint', 'panda_websocket_endpoint'),\n paymentJavaEndpoint: get('paymentJavaEndpoint', 'payment_java_endpoint'),\n paymentPhpEndpoint: get('paymentPhpEndpoint', 'payment_php_endpoint'),\n portalDomainEndpoint: get('portalDomainEndpoint', 'portal_domain_endpoint'),\n portalSubdomain:\n typeof raw.portalSubdomain === 'string'\n ? raw.portalSubdomain\n : typeof raw.portal_subdomain === 'string'\n ? raw.portal_subdomain\n : '',\n ssoEndpoint: get('ssoEndpoint', 'sso_endpoint'),\n webservicesEndpoint: get('webservicesEndpoint', 'webservices_endpoint'),\n websocketEndpoint: get('websocketEndpoint', 'websocket_endpoint'),\n hcpoHcmEndpoint: get('hcpoHcmEndpoint', 'hcpo_hcm_endpoint'),\n };\n}\n\nexport async function fetchGlobalConfig(region = 'NA'): Promise<GlobalConfiguration> {\n const { data } = await postJson(DISCOVERY_API, JSON.stringify({ regionCode: region }));\n\n // The API may return the config directly or nested under \"globalConfiguration\"\n const raw = (typeof data.globalConfiguration === 'object' && data.globalConfiguration !== null\n ? data.globalConfiguration\n : data) as RawValue;\n\n const endpointsRaw = (raw.endPoints ?? raw.endpoints ?? {}) as RawValue;\n\n return {\n region: typeof raw.region === 'string' ? raw.region : region,\n defaultCountry: (raw.defaultCountry ?? {}) as GlobalConfiguration['defaultCountry'],\n supportedCountries: Array.isArray(raw.supportedCountries)\n ? (raw.supportedCountries as GlobalConfiguration['supportedCountries'])\n : [],\n defaultCurrency: (raw.currency ?? raw.defaultCurrency ?? {}) as GlobalConfiguration['defaultCurrency'],\n supportedCurrencies: Array.isArray(raw.supportedCurrencies)\n ? (raw.supportedCurrencies as GlobalConfiguration['supportedCurrencies'])\n : [],\n endpoints: parseEndpoints(endpointsRaw),\n };\n}\n","import type { ChargePoint } from './client.js';\nimport { APIError, CommunicationError } from './exceptions.js';\nimport type { ChargingSessionUpdate, PowerUtility, VehicleInfo } from './types.js';\n\nconst sleep = (ms: number): Promise<void> =>\n new Promise((resolve) => setTimeout(resolve, ms));\n\ntype RawObj = Record<string, unknown>;\n\nexport async function sendCommand(\n client: ChargePoint,\n action: 'start' | 'stop',\n deviceId: number,\n portNumber = 1,\n sessionId = 0,\n): Promise<void> {\n const actionPath = action === 'start' ? 'startsession' : 'stopSession';\n const body: RawObj = { deviceId };\n\n if (action === 'stop') {\n body.portNumber = portNumber;\n body.sessionId = sessionId;\n }\n\n const url = `${client.globalConfig.endpoints.accountsEndpoint}/v1/driver/station/${actionPath}`;\n const response = await client._request('POST', url, {\n body: JSON.stringify(body),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new CommunicationError(\n response.status,\n `Failed to ${action} ChargePoint session: ${text}`,\n );\n }\n\n const actionStatus = (await response.json()) as RawObj;\n const ackId = actionStatus.ackId;\n\n const ackUrl = `${client.globalConfig.endpoints.accountsEndpoint}/v1/driver/station/session/ack`;\n\n let lastStatus = 0;\n let errorMessage = `Session failed to ${action}.`;\n let errorBody: unknown;\n\n for (let attempt = 1; attempt <= 20; attempt++) {\n const ackResponse = await client._request('POST', ackUrl, {\n body: JSON.stringify({ ackId, action: `${action}_session` }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n lastStatus = ackResponse.status;\n\n if (ackResponse.status === 200) {\n return;\n }\n\n try {\n errorBody = await ackResponse.json();\n const msg = (errorBody as RawObj).errorMessage;\n if (typeof msg === 'string') errorMessage = msg;\n } catch {\n errorBody = undefined;\n }\n\n if (attempt < 20) {\n await sleep(3000);\n }\n }\n\n throw new CommunicationError(lastStatus, errorMessage, errorBody);\n}\n\nfunction parseMsTimestamp(v: unknown): Date {\n if (typeof v === 'number') return new Date(v);\n if (typeof v === 'string') return new Date(Number(v));\n return new Date(0);\n}\n\nfunction parseSessionUpdates(raw: unknown): ChargingSessionUpdate[] {\n if (!Array.isArray(raw)) return [];\n return raw.map((u: unknown) => {\n const item = u as RawObj;\n return {\n energyKwh: typeof item.energy_kwh === 'number' ? item.energy_kwh : 0,\n powerKw: typeof item.power_kw === 'number' ? item.power_kw : 0,\n timestamp: parseMsTimestamp(item.timestamp),\n };\n });\n}\n\nexport class ChargingSession {\n sessionId: number;\n deviceId = 0;\n deviceName = '';\n chargingState = '';\n chargingTime = 0;\n energyKwh = 0;\n milesAdded = 0;\n milesAddedPerHour = 0;\n outletNumber = 0;\n portLevel = 0;\n powerKw = 0;\n purpose = '';\n currencyIsoCode = '';\n paymentCompleted = false;\n paymentType = '';\n pricingSpecId = 0;\n totalAmount = 0;\n apiFlag = false;\n enableStopCharging = false;\n hasChargingReceipt = false;\n hasUtilityInfo = false;\n isHomeCharger = false;\n isPurposeFinalized = false;\n stopChargeSupported = false;\n companyId = 0;\n companyName = '';\n latitude = 0;\n longitude = 0;\n address = '';\n city = '';\n stateName = '';\n country = '';\n zipcode = '';\n updatePeriod = 0;\n startTime: Date | null = null;\n lastUpdateDataTimestamp: Date | null = null;\n updateData: ChargingSessionUpdate[] | null = null;\n utility: PowerUtility | null = null;\n vehicleInfo: VehicleInfo | null = null;\n\n private _client: ChargePoint | null = null;\n\n constructor(sessionId: number) {\n this.sessionId = sessionId;\n }\n\n /** @internal */\n _setClient(client: ChargePoint): void {\n this._client = client;\n }\n\n /** @internal Apply raw session data from the driver-bff API (snake_case keys). */\n _apply(data: RawObj): void {\n if (data.device_id !== undefined) this.deviceId = data.device_id as number;\n if (data.device_name !== undefined) this.deviceName = data.device_name as string;\n if (data.current_charging !== undefined) this.chargingState = data.current_charging as string;\n if (data.charging_time !== undefined) this.chargingTime = data.charging_time as number;\n if (data.energy_kwh !== undefined) this.energyKwh = data.energy_kwh as number;\n if (data.miles_added !== undefined) this.milesAdded = data.miles_added as number;\n if (data.miles_added_per_hour !== undefined) this.milesAddedPerHour = data.miles_added_per_hour as number;\n if (data.outlet_number !== undefined) this.outletNumber = data.outlet_number as number;\n if (data.port_level !== undefined) this.portLevel = data.port_level as number;\n if (data.power_kw !== undefined) this.powerKw = data.power_kw as number;\n if (data.purpose !== undefined) this.purpose = data.purpose as string;\n if (data.currency_iso_code !== undefined) this.currencyIsoCode = String(data.currency_iso_code);\n if (data.payment_completed !== undefined) this.paymentCompleted = data.payment_completed as boolean;\n if (data.payment_type !== undefined) this.paymentType = data.payment_type as string;\n if (data.pricing_spec_id !== undefined) this.pricingSpecId = data.pricing_spec_id as number;\n if (data.total_amount !== undefined) this.totalAmount = data.total_amount as number;\n if (data.api_flag !== undefined) this.apiFlag = data.api_flag as boolean;\n if (data.enable_stop_charging !== undefined) this.enableStopCharging = data.enable_stop_charging as boolean;\n if (data.has_charging_receipt !== undefined) this.hasChargingReceipt = data.has_charging_receipt as boolean;\n if (data.has_utility_info !== undefined) this.hasUtilityInfo = data.has_utility_info as boolean;\n if (data.is_home_charger !== undefined) this.isHomeCharger = data.is_home_charger as boolean;\n if (data.is_purpose_finalized !== undefined) this.isPurposeFinalized = data.is_purpose_finalized as boolean;\n if (data.stop_charge_supported !== undefined) this.stopChargeSupported = data.stop_charge_supported as boolean;\n if (data.company_id !== undefined) this.companyId = data.company_id as number;\n if (data.company_name !== undefined) this.companyName = data.company_name as string;\n if (data.lat !== undefined) this.latitude = data.lat as number;\n if (data.lon !== undefined) this.longitude = data.lon as number;\n if (data.address1 !== undefined) this.address = data.address1 as string;\n if (data.city !== undefined) this.city = data.city as string;\n if (data.state_name !== undefined) this.stateName = data.state_name as string;\n if (data.country !== undefined) this.country = data.country as string;\n if (data.zipcode !== undefined) this.zipcode = data.zipcode as string;\n if (data.update_period !== undefined) this.updatePeriod = data.update_period as number;\n if (data.start_time !== undefined) this.startTime = parseMsTimestamp(data.start_time);\n if (data.last_update_data_timestamp !== undefined) {\n this.lastUpdateDataTimestamp = parseMsTimestamp(data.last_update_data_timestamp);\n }\n if (data.update_data !== undefined) this.updateData = parseSessionUpdates(data.update_data);\n if (data.utility !== undefined) this.utility = (data.utility as PowerUtility) ?? null;\n if (data.vehicle_info !== undefined) this.vehicleInfo = (data.vehicle_info as VehicleInfo) ?? null;\n }\n\n async refresh(): Promise<void> {\n if (!this._client) throw new Error('ChargingSession client not set.');\n\n const url = `${this._client.globalConfig.endpoints.internalApiGatewayEndpoint}/driver-bff/v1/sessions/${this.sessionId}`;\n const response = await this._client._request('POST', url, {\n body: JSON.stringify({\n charging_status: { session_id: this.sessionId, mfhs: [] },\n }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get charging session data.');\n }\n\n const json = (await response.json()) as RawObj;\n const status = json.charging_status as RawObj | undefined;\n\n if (!status || 'error_message' in status || 'error' in status) {\n throw new CommunicationError(response.status, 'Failed to get charging session data.');\n }\n\n this._apply(status);\n }\n\n async stop(): Promise<void> {\n if (!this._client) throw new Error('ChargingSession client not set.');\n await sendCommand(\n this._client,\n 'stop',\n this.deviceId,\n this.outletNumber,\n this.sessionId,\n );\n }\n\n static async start(deviceId: number, client: ChargePoint): Promise<ChargingSession> {\n await sendCommand(client, 'start', deviceId);\n\n // The start ack confirms the cloud received the command, but the session\n // may take a moment to appear in the status API (same async IoT pattern\n // as amperage/LED changes). Poll until it shows up.\n const deadline = Date.now() + 15_000;\n let status = await client.getUserChargingStatus();\n while (!status && Date.now() < deadline) {\n await sleep(2000);\n status = await client.getUserChargingStatus();\n }\n\n if (!status) {\n throw new APIError('No active charging session found after start command.');\n }\n const session = new ChargingSession(status.sessionId);\n session._setClient(client);\n await session.refresh();\n return session;\n }\n}\n","import { USER_AGENT } from './constants.js';\nimport { CommunicationError, DatadomeCaptcha, InvalidSession, LoginError } from './exceptions.js';\nimport { fetchGlobalConfig } from './global-config.js';\nimport { ChargingSession } from './session.js';\nimport type {\n Account,\n ElectricVehicle,\n GlobalConfiguration,\n HomeChargerConfiguration,\n HomeChargerSchedule,\n HomeChargerStatus,\n HomeChargerTechnicalInfo,\n MapFilter,\n MapStation,\n Station,\n StationInfo,\n UserChargingStatus,\n ZoomBounds,\n} from './types.js';\n\ntype RawObj = Record<string, unknown>;\n\nexport interface ChargePointOptions {\n coulombToken?: string;\n region?: string;\n}\n\nfunction parseMsTimestamp(v: unknown): Date {\n if (typeof v === 'number') return new Date(v);\n if (typeof v === 'string') return new Date(Number(v));\n return new Date(0);\n}\n\nexport class ChargePoint {\n public globalConfig: GlobalConfiguration;\n private _username: string;\n private _coulombToken: string | null = null;\n private _region: string;\n private _userId: number | null = null;\n\n /** The current session token. Save this after login to avoid re-authenticating. */\n get coulombToken(): string | null {\n return this._coulombToken;\n }\n\n private constructor(username: string, globalConfig: GlobalConfiguration, region: string) {\n this._username = username;\n this.globalConfig = globalConfig;\n this._region = region;\n }\n\n static async create(username: string, options: ChargePointOptions = {}): Promise<ChargePoint> {\n const region = options.region ?? 'NA';\n const config = await fetchGlobalConfig(region);\n const client = new ChargePoint(username, config, region);\n\n if (options.coulombToken) {\n client._setToken(options.coulombToken, region);\n }\n\n return client;\n }\n\n private _setToken(token: string, region: string): void {\n this._coulombToken = decodeURIComponent(token);\n this._region = region;\n }\n\n /** @internal Used by session.ts and tests. */\n async _request(method: string, url: string, init: RequestInit = {}): Promise<Response> {\n const headers = new Headers(init.headers as string[][] | Record<string, string> | Headers);\n headers.set('user-agent', USER_AGENT);\n\n if (!headers.has('content-type') && method !== 'GET') {\n headers.set('content-type', 'application/json');\n }\n\n if (this._coulombToken) {\n headers.set('cookie', `coulomb_sess=${this._coulombToken}`);\n headers.set('cp-session-type', 'CP_SESSION_TOKEN');\n headers.set('cp-session-token', this._coulombToken);\n headers.set('cp-region', this._region);\n }\n\n const response = await fetch(url, { ...init, method, headers });\n\n // Refresh coulomb_sess from Set-Cookie response header\n const setCookies: string[] =\n typeof (response.headers as unknown as { getSetCookie?: () => string[] }).getSetCookie ===\n 'function'\n ? (response.headers as unknown as { getSetCookie: () => string[] }).getSetCookie()\n : [response.headers.get('set-cookie') ?? ''].filter(Boolean);\n\n for (const cookie of setCookies) {\n const match = /^coulomb_sess=([^;]+)/.exec(cookie);\n if (match) {\n this._coulombToken = decodeURIComponent(match[1] ?? '');\n break;\n }\n }\n\n if (response.status === 401) {\n throw new InvalidSession(401, 'ChargePoint session expired. Please log in again.');\n }\n\n if (response.status === 403) {\n let body: unknown;\n try {\n body = await response.clone().json();\n } catch {\n // not JSON\n }\n const captchaUrl = (body as RawObj)?.url;\n if (typeof captchaUrl === 'string' && captchaUrl.includes('datadome')) {\n throw new DatadomeCaptcha(captchaUrl);\n }\n }\n\n return response;\n }\n\n private async _errorBody(response: Response): Promise<string> {\n try {\n return await response.clone().text();\n } catch {\n return '';\n }\n }\n\n // ---------------------------------------------------------------------------\n // Authentication\n // ---------------------------------------------------------------------------\n\n async loginWithPassword(password: string): Promise<void> {\n const url = `${this.globalConfig.endpoints.ssoEndpoint}/v1/user/login`;\n const response = await this._request('POST', url, {\n body: JSON.stringify({ user_name: this._username, password }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n let body: unknown;\n try { body = await response.json(); } catch { /* ignore */ }\n throw new LoginError(response.status, 'Failed to login with password.', body);\n }\n\n // The coulomb_sess cookie is set by the SSO endpoint on success;\n // _request() already extracted it from Set-Cookie above.\n await response.text(); // drain body\n\n if (!this._coulombToken) {\n throw new LoginError(response.status, 'Login succeeded but no session token was returned.');\n }\n }\n\n async loginWithSsoSession(ssoJwt: string): Promise<void> {\n // Exchange an SSO JWT for a coulomb_sess cookie via the portal endpoint.\n const url = `${this.globalConfig.endpoints.portalDomainEndpoint}/index.php/nghelper/getSession`;\n const response = await this._request('GET', url, {\n headers: {\n cookie: `auth-session=${ssoJwt}`,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n let body: unknown;\n try { body = await response.json(); } catch { /* ignore */ }\n throw new LoginError(response.status, 'Failed to login with SSO session.', body);\n }\n\n await response.text();\n }\n\n async logout(): Promise<void> {\n const url = `${this.globalConfig.endpoints.ssoEndpoint}/v1/user/logout`;\n try {\n await this._request('POST', url);\n } finally {\n this._coulombToken = null;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Account\n // ---------------------------------------------------------------------------\n\n async getAccount(): Promise<Account> {\n const url = `${this.globalConfig.endpoints.accountsEndpoint}/v1/driver/profile/user`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get account information.');\n }\n\n const data = (await response.json()) as Account;\n if (data.user?.userId) {\n this._userId = data.user.userId;\n }\n return data;\n }\n\n async getVehicles(): Promise<ElectricVehicle[]> {\n const url = `${this.globalConfig.endpoints.accountsEndpoint}/v1/driver/vehicle`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get vehicles.');\n }\n\n const data = (await response.json()) as RawObj;\n return (Array.isArray(data.vehicles) ? data.vehicles : []) as ElectricVehicle[];\n }\n\n async getUserChargingStatus(): Promise<UserChargingStatus | null> {\n const url = `${this.globalConfig.endpoints.mapcacheEndpoint}/v2`;\n const response = await this._request('POST', url, {\n body: JSON.stringify({ user_status: { timestamp: Date.now() } }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get user charging status.');\n }\n\n const data = (await response.json()) as RawObj;\n const userStatus = data.user_status as RawObj | null | undefined;\n\n if (!userStatus) return null;\n\n const charging = userStatus.charging_status as RawObj | null | undefined;\n if (!charging) return null;\n\n const stations: Station[] = Array.isArray(charging.stations)\n ? (charging.stations as RawObj[]).map((s) => ({\n id: s.id as number,\n name: typeof s.name === 'string' ? s.name : '',\n latitude: typeof s.lat === 'number' ? s.lat : (s.latitude as number ?? 0),\n longitude: typeof s.lon === 'number' ? s.lon : (s.longitude as number ?? 0),\n }))\n : [];\n\n return {\n sessionId: charging.session_id as number,\n startTime: parseMsTimestamp(charging.start_time),\n state: typeof charging.current_charging === 'string' ? charging.current_charging : '',\n stations,\n };\n }\n\n // ---------------------------------------------------------------------------\n // Home charger helpers\n // ---------------------------------------------------------------------------\n\n private async ensureUserId(): Promise<number> {\n if (this._userId !== null) return this._userId;\n const account = await this.getAccount();\n return account.user.userId;\n }\n\n async getHomeChargers(): Promise<number[]> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n let body: unknown;\n try { body = await response.json(); } catch { /* ignore */ }\n throw new CommunicationError(response.status, 'Failed to get home chargers.', body);\n }\n\n const data = (await response.json()) as RawObj;\n // API returns { data: [...] }; older shape used { chargers: [...] }\n const arr = Array.isArray(data.data)\n ? (data.data as RawObj[])\n : Array.isArray(data.chargers)\n ? (data.chargers as RawObj[])\n : [];\n return arr.map((c) => {\n // API uses \"id\" (string); older shape used chargerId / charger_id (number)\n const id = c.id ?? c.chargerId ?? c.charger_id;\n return typeof id === 'number' ? id : Number(id);\n });\n }\n\n async getHomeChargerStatus(chargerId: number): Promise<HomeChargerStatus> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/status`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger status.');\n }\n\n const data = (await response.json()) as RawObj;\n // Real API nests amperage info under chargeAmperageSettings; fall back to flat fields for older shapes\n const amp = (data.chargeAmperageSettings ?? {}) as RawObj;\n return {\n chargerId, // not echoed by the API; inject from parameter\n brand: String(data.brand ?? ''),\n model: String(data.model ?? ''),\n macAddress: String(data.macAddress ?? ''),\n chargingStatus: String(data.chargingStatus ?? ''),\n isPluggedIn: Boolean(data.isPluggedIn),\n isConnected: Boolean(data.isConnected),\n isReminderEnabled: Boolean(data.isReminderEnabled),\n plugInReminderTime: String(data.plugInReminderTime ?? ''),\n hasUtilityInfo: Boolean(data.hasUtilityInfo),\n isDuringScheduledTime: Boolean(data.isDuringScheduledTime),\n amperageLimit: Number(amp.chargeLimit ?? data.amperageLimit ?? 0),\n possibleAmperageLimits: ((amp.possibleChargeLimit ?? data.possibleAmperageLimits ?? []) as number[]).map(Number),\n };\n }\n\n async getHomeChargerTechnicalInfo(chargerId: number): Promise<HomeChargerTechnicalInfo> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/technical-info`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger technical info.');\n }\n\n return (await response.json()) as HomeChargerTechnicalInfo;\n }\n\n async getHomeChargerConfig(chargerId: number): Promise<HomeChargerConfiguration> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/configurations`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger configuration.');\n }\n\n const data = (await response.json()) as RawObj;\n // Real API wraps all fields under \"settings\"; fall back to flat shape for older responses\n const s = (data.settings ?? data) as RawObj;\n // LED brightness: real API uses settings.led.brightness with string-typed level/supportedLevels\n const rawLed = ((s.led as RawObj | undefined)?.brightness ?? s.ledBrightness ?? {}) as RawObj;\n const level =\n typeof rawLed.level === 'string'\n ? Number(rawLed.level)\n : Number(rawLed.level ?? rawLed.currentBrightnessSettings ?? 0);\n const supportedLevels = Array.isArray(rawLed.supportedLevels)\n ? (rawLed.supportedLevels as (string | number)[]).map(Number)\n : [];\n return {\n serialNumber: String(s.serialNumber ?? ''),\n macAddress: String(s.macAddress ?? ''),\n stationNickname: String(s.stationNickname ?? ''),\n streetAddress: String(s.streetAddress ?? ''),\n hasUtilityInfo: Boolean(s.hasUtilityInfo),\n utility: (s.utility ?? null) as HomeChargerConfiguration['utility'],\n // API may return boolean true/false or string \"ON\"/\"OFF\"\n indicatorLightEcoMode: s.indicatorLightEcoMode === true || s.indicatorLightEcoMode === 'ON',\n flashlightReset: Boolean(s.flashlightReset),\n worksWithNest: Boolean(s.worksWithNest),\n isPairedWithNest: Boolean(s.isPairedWithNest),\n isInstalledByInstaller: Boolean(s.isInstalledByInstaller),\n ledBrightness: {\n level,\n inProgress: Boolean(rawLed.inProgress),\n supportedLevels,\n isEnabled: rawLed.isEnabled !== false,\n },\n };\n }\n\n async getHomeChargerSchedule(chargerId: number): Promise<HomeChargerSchedule> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger schedule.');\n }\n\n return (await response.json()) as HomeChargerSchedule;\n }\n\n async setHomeChargerSchedule(\n chargerId: number,\n weekdayStart: string,\n weekdayEnd: string,\n weekendStart: string,\n weekendEnd: string,\n ): Promise<HomeChargerSchedule> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({\n schedule: {\n weekdays: { startTime: weekdayStart, endTime: weekdayEnd },\n weekends: { startTime: weekendStart, endTime: weekendEnd },\n },\n }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n const body = await this._errorBody(response);\n throw new CommunicationError(response.status, `Failed to set home charger schedule. HTTP ${response.status}: ${body}`);\n }\n\n return (await response.json()) as HomeChargerSchedule;\n }\n\n async disableHomeChargerSchedule(chargerId: number): Promise<void> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({}),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to disable home charger schedule.');\n }\n\n await response.text();\n }\n\n async setAmperageLimit(chargerId: number, amperageLimit: number): Promise<void> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/chargers/${chargerId}/charge-amperage-limit`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({ chargeAmperageLimit: amperageLimit }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n const body = await this._errorBody(response);\n throw new CommunicationError(response.status, `Failed to set amperage limit. HTTP ${response.status}: ${body}`);\n }\n\n await response.text();\n }\n\n async setLedBrightness(chargerId: number, level: number): Promise<void> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/chargers/${chargerId}/led-brightness`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({ ledBrightnessLevel: level }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n const body = await this._errorBody(response);\n throw new CommunicationError(response.status, `Failed to set LED brightness. HTTP ${response.status}: ${body}`);\n }\n\n await response.text();\n }\n\n async restartHomeCharger(chargerId: number): Promise<void> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/restart`;\n const response = await this._request('POST', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to restart home charger.');\n }\n\n await response.text();\n }\n\n // ---------------------------------------------------------------------------\n // Charging sessions\n // ---------------------------------------------------------------------------\n\n async getChargingSession(sessionId: number): Promise<ChargingSession> {\n const session = new ChargingSession(sessionId);\n session._setClient(this);\n await session.refresh();\n return session;\n }\n\n async startChargingSession(deviceId: number): Promise<ChargingSession> {\n return ChargingSession.start(deviceId, this);\n }\n\n // ---------------------------------------------------------------------------\n // Stations\n // ---------------------------------------------------------------------------\n\n async getStation(deviceId: number): Promise<StationInfo> {\n const url = `${this.globalConfig.endpoints.mapcacheEndpoint}/v3/station/info?deviceId=${deviceId}&use_cache=false`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get station info.');\n }\n\n return (await response.json()) as StationInfo;\n }\n\n async getNearbyStations(bounds: ZoomBounds, filter: MapFilter = {}): Promise<MapStation[]> {\n const url = `${this.globalConfig.endpoints.mapcacheEndpoint}/v2`;\n const stationList: RawObj = {\n ne_lat: bounds.neLat,\n ne_lon: bounds.neLon,\n sw_lat: bounds.swLat,\n sw_lon: bounds.swLon,\n ...filter,\n };\n\n const response = await this._request('POST', url, {\n body: JSON.stringify({ station_list: stationList }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get nearby stations.');\n }\n\n const data = (await response.json()) as RawObj;\n const list = data.station_list as RawObj | undefined;\n return Array.isArray(list?.stations) ? (list.stations as MapStation[]) : [];\n }\n}\n"]}
|
package/package.json
CHANGED