iobroker.mg-saic 0.0.2 → 0.0.3
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/README.md +12 -1
- package/build/main.js +152 -10
- package/build/main.js.map +2 -2
- package/build/runtime-translations.js +103 -0
- package/build/runtime-translations.js.map +2 -2
- package/build/saic-client.js +147 -26
- package/build/saic-client.js.map +3 -3
- package/build/status-metadata.js +88 -2
- package/build/status-metadata.js.map +2 -2
- package/io-package.json +14 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# ioBroker MG/SAIC
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/iobroker.mg-saic)
|
|
4
|
+
[](https://www.npmjs.com/package/iobroker.mg-saic)
|
|
5
|
+
|
|
3
6
|
<img src="MG.png" alt="MG" width="314">
|
|
4
7
|
|
|
5
8
|
The adapter is intended for connecting MG and SAIC vehicles to ioBroker through the iSmart cloud service. It is not affiliated with or endorsed by MG, SAIC, or iSmart.
|
|
@@ -29,9 +32,17 @@ The adapter is intended for connecting MG and SAIC vehicles to ioBroker through
|
|
|
29
32
|
|
|
30
33
|
## Installation
|
|
31
34
|
|
|
32
|
-
The adapter is
|
|
35
|
+
The adapter is published on npm but has not yet been added to the ioBroker adapter catalog.
|
|
33
36
|
|
|
34
37
|
## Changelog
|
|
38
|
+
### 0.0.3 (2026-10-21)
|
|
39
|
+
|
|
40
|
+
- (Voodoo2man) Improved release automation, updated Node.js release checks, and removed unpublished version metadata.
|
|
41
|
+
- (Voodoo2man) Added charging data
|
|
42
|
+
- (Voodoo2man) Fixed vehicle datapoint units and roles
|
|
43
|
+
|
|
44
|
+
Older changelog entries are available in [CHANGELOG_OLD.md](CHANGELOG_OLD.md).
|
|
45
|
+
|
|
35
46
|
### 0.0.2 (2026-10-20)
|
|
36
47
|
|
|
37
48
|
- (Voodoo2man) Added regional iSmart account setup, vehicle status, and supported remote controls.
|
package/build/main.js
CHANGED
|
@@ -28,6 +28,10 @@ var import_regions = require("./regions");
|
|
|
28
28
|
var import_refresh_command = require("./refresh-command");
|
|
29
29
|
var import_status_metadata = require("./status-metadata");
|
|
30
30
|
var import_runtime_translations = require("./runtime-translations");
|
|
31
|
+
const chargingGroups = [
|
|
32
|
+
{ source: "chrgMgmtData", id: "session", name: "chargingManagement" },
|
|
33
|
+
{ source: "rvsChargeStatus", id: "statistics", name: "chargeStatus" }
|
|
34
|
+
];
|
|
31
35
|
const vehicleCommands = [
|
|
32
36
|
{ id: "lock" },
|
|
33
37
|
{ id: "unlock" },
|
|
@@ -68,16 +72,16 @@ const settingGroups = {
|
|
|
68
72
|
climateTemperature: "climate",
|
|
69
73
|
chargeTargetSoc: "charging",
|
|
70
74
|
chargingCurrentLimit: "charging",
|
|
71
|
-
chargingScheduleStart: "
|
|
72
|
-
chargingScheduleEnd: "
|
|
73
|
-
chargingScheduleMode: "
|
|
75
|
+
chargingScheduleStart: "charging",
|
|
76
|
+
chargingScheduleEnd: "charging",
|
|
77
|
+
chargingScheduleMode: "charging",
|
|
74
78
|
batteryHeatingScheduleEnabled: "schedules",
|
|
75
79
|
batteryHeatingScheduleStart: "schedules"
|
|
76
80
|
};
|
|
77
81
|
const actionGroups = {
|
|
78
82
|
climateTemperatureApply: "climate",
|
|
79
83
|
chargingSettingsApply: "charging",
|
|
80
|
-
chargingScheduleApply: "
|
|
84
|
+
chargingScheduleApply: "charging",
|
|
81
85
|
batteryHeatingScheduleApply: "schedules"
|
|
82
86
|
};
|
|
83
87
|
function vehicleCommandPath(vin, id) {
|
|
@@ -128,6 +132,16 @@ class MgSaic extends utils.Adapter {
|
|
|
128
132
|
await this.extendObjectAsync("info.backend", { common: { name: (0, import_runtime_translations.getRuntimeName)("backend") } });
|
|
129
133
|
await this.extendObjectAsync("info.connection", { common: { name: (0, import_runtime_translations.getRuntimeName)("connection") } });
|
|
130
134
|
await this.extendObjectAsync("info.lastError", { common: { name: (0, import_runtime_translations.getRuntimeName)("lastError") } });
|
|
135
|
+
await this.setObjectNotExistsAsync("commands", {
|
|
136
|
+
type: "channel",
|
|
137
|
+
common: { name: (0, import_runtime_translations.getRuntimeName)("commands") },
|
|
138
|
+
native: {}
|
|
139
|
+
});
|
|
140
|
+
await this.setObjectAsync("vehicles", {
|
|
141
|
+
type: "folder",
|
|
142
|
+
common: { name: "Vehicles" },
|
|
143
|
+
native: {}
|
|
144
|
+
});
|
|
131
145
|
await this.setObjectNotExistsAsync("commands.refresh", {
|
|
132
146
|
type: "state",
|
|
133
147
|
common: {
|
|
@@ -287,6 +301,22 @@ class MgSaic extends utils.Adapter {
|
|
|
287
301
|
break;
|
|
288
302
|
}
|
|
289
303
|
}
|
|
304
|
+
try {
|
|
305
|
+
const charging = await this.client.getVehicleChargingStatus(
|
|
306
|
+
this.loginOptions,
|
|
307
|
+
this.accessToken,
|
|
308
|
+
vehicle.vin,
|
|
309
|
+
this.abortController.signal
|
|
310
|
+
);
|
|
311
|
+
await this.createVehicleChargingObjects(vehicle.vin, charging);
|
|
312
|
+
} catch (error) {
|
|
313
|
+
if (this.stopping) {
|
|
314
|
+
break;
|
|
315
|
+
}
|
|
316
|
+
const details = error instanceof Error ? error.message : "Unknown charging data error";
|
|
317
|
+
statusErrors.push(`Charging data request failed for ${vehicle.vin}: ${details}`);
|
|
318
|
+
this.log.warn(`Could not retrieve charging data for vehicle ${vehicle.vin}: ${details}`);
|
|
319
|
+
}
|
|
290
320
|
let status;
|
|
291
321
|
try {
|
|
292
322
|
this.log.debug(`Refreshing live status for ${vehicle.vin}`);
|
|
@@ -372,6 +402,33 @@ class MgSaic extends utils.Adapter {
|
|
|
372
402
|
statusErrors.push(`Ignored older live status for ${vehicle.vin}`);
|
|
373
403
|
continue;
|
|
374
404
|
}
|
|
405
|
+
if (status.basicVehicleStatus.mileage === void 0) {
|
|
406
|
+
try {
|
|
407
|
+
const cachedStatus = await this.client.getCachedVehicleStatus(
|
|
408
|
+
this.loginOptions,
|
|
409
|
+
this.accessToken,
|
|
410
|
+
vehicle.vin,
|
|
411
|
+
this.abortController.signal
|
|
412
|
+
);
|
|
413
|
+
const cachedMileage = cachedStatus.basicVehicleStatus.mileage;
|
|
414
|
+
const mileage = (0, import_status_metadata.resolveOdometerValue)(void 0, cachedMileage);
|
|
415
|
+
if (mileage !== void 0) {
|
|
416
|
+
status = {
|
|
417
|
+
...status,
|
|
418
|
+
basicVehicleStatus: { ...status.basicVehicleStatus, mileage }
|
|
419
|
+
};
|
|
420
|
+
this.log.debug(
|
|
421
|
+
`Used cached odometer for ${vehicle.vin} because live status omitted mileage`
|
|
422
|
+
);
|
|
423
|
+
}
|
|
424
|
+
} catch (cacheError) {
|
|
425
|
+
if (this.stopping) {
|
|
426
|
+
break;
|
|
427
|
+
}
|
|
428
|
+
const details = cacheError instanceof Error ? cacheError.message : "Unknown cache error";
|
|
429
|
+
this.log.debug(`Could not retrieve cached odometer for ${vehicle.vin}: ${details}`);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
375
432
|
try {
|
|
376
433
|
this.log.debug(
|
|
377
434
|
`Received live status for ${vehicle.vin}: ${Object.keys(status.basicVehicleStatus).length} basic fields, statusTime ${(_a = status.statusTime) != null ? _a : "missing"}`
|
|
@@ -651,6 +708,18 @@ class MgSaic extends utils.Adapter {
|
|
|
651
708
|
}
|
|
652
709
|
const group = (0, import_status_metadata.getVehicleStatusGroup)(key);
|
|
653
710
|
const groupId = `${statusId}.${group}`;
|
|
711
|
+
const stateId = `${groupId}.${key}`;
|
|
712
|
+
if (value === void 0) {
|
|
713
|
+
if ((0, import_status_metadata.shouldDeleteUnavailableStatusValue)(key)) {
|
|
714
|
+
await this.delObjectAsync(stateId);
|
|
715
|
+
} else {
|
|
716
|
+
const previousState = await this.getStateAsync(stateId);
|
|
717
|
+
if ((previousState == null ? void 0 : previousState.val) === null) {
|
|
718
|
+
await this.delObjectAsync(stateId);
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
continue;
|
|
722
|
+
}
|
|
654
723
|
await this.setObjectNotExistsAsync(groupId, {
|
|
655
724
|
type: "channel",
|
|
656
725
|
common: { name: (0, import_runtime_translations.getRuntimeName)(group) },
|
|
@@ -661,7 +730,6 @@ class MgSaic extends utils.Adapter {
|
|
|
661
730
|
return;
|
|
662
731
|
}
|
|
663
732
|
const metadata = (0, import_status_metadata.getVehicleStatusMetadata)(key);
|
|
664
|
-
const stateId = `${groupId}.${key}`;
|
|
665
733
|
const common = {
|
|
666
734
|
name: metadata.name,
|
|
667
735
|
type: metadata.type,
|
|
@@ -693,6 +761,67 @@ class MgSaic extends utils.Adapter {
|
|
|
693
761
|
await this.delObjectAsync(`${statusId}.${key}`);
|
|
694
762
|
}
|
|
695
763
|
}
|
|
764
|
+
async createVehicleChargingObjects(vin, charging) {
|
|
765
|
+
await this.ensureVehicleChargingGroups(vin);
|
|
766
|
+
const rootId = `vehicles.${vin}.status.charging`;
|
|
767
|
+
for (const { source, id } of chargingGroups) {
|
|
768
|
+
const groupId = `${rootId}.${id}`;
|
|
769
|
+
for (const [field, value] of Object.entries(charging[source])) {
|
|
770
|
+
if (this.stopping) {
|
|
771
|
+
return;
|
|
772
|
+
}
|
|
773
|
+
const stateId = `${groupId}.${field}`;
|
|
774
|
+
if (value === void 0) {
|
|
775
|
+
await this.delObjectAsync(stateId);
|
|
776
|
+
continue;
|
|
777
|
+
}
|
|
778
|
+
const metadata = (0, import_status_metadata.getChargingFieldMetadata)(field);
|
|
779
|
+
const common = {
|
|
780
|
+
name: (0, import_runtime_translations.getChargingFieldName)(field),
|
|
781
|
+
type: metadata.type === "boolean" ? "boolean" : typeof value === "string" ? "string" : "number",
|
|
782
|
+
role: typeof value === "string" ? "text" : metadata.role,
|
|
783
|
+
read: true,
|
|
784
|
+
write: false
|
|
785
|
+
};
|
|
786
|
+
if (metadata.unit) {
|
|
787
|
+
common.unit = metadata.unit;
|
|
788
|
+
}
|
|
789
|
+
await this.setObjectNotExistsAsync(stateId, { type: "state", common, native: {} });
|
|
790
|
+
await this.extendObjectAsync(stateId, { common });
|
|
791
|
+
await this.setStateAsync(stateId, {
|
|
792
|
+
val: (0, import_status_metadata.normalizeChargingValue)(field, value),
|
|
793
|
+
ack: true
|
|
794
|
+
});
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
await this.delObjectAsync(`vehicles.${vin}.charging`, { recursive: true });
|
|
798
|
+
}
|
|
799
|
+
async ensureVehicleChargingGroups(vin) {
|
|
800
|
+
const statusId = `vehicles.${vin}.status`;
|
|
801
|
+
const rootId = `${statusId}.charging`;
|
|
802
|
+
await this.setObjectNotExistsAsync(statusId, {
|
|
803
|
+
type: "channel",
|
|
804
|
+
common: { name: (0, import_runtime_translations.getRuntimeName)("currentStatus") },
|
|
805
|
+
native: {}
|
|
806
|
+
});
|
|
807
|
+
await this.setObjectNotExistsAsync(rootId, {
|
|
808
|
+
type: "channel",
|
|
809
|
+
common: { name: (0, import_runtime_translations.getRuntimeName)("commandGroup_charging") },
|
|
810
|
+
native: {}
|
|
811
|
+
});
|
|
812
|
+
await this.extendObjectAsync(rootId, { common: { name: (0, import_runtime_translations.getRuntimeName)("commandGroup_charging") } });
|
|
813
|
+
for (const { source, id, name } of chargingGroups) {
|
|
814
|
+
const groupId = `${rootId}.${id}`;
|
|
815
|
+
const groupName = (0, import_runtime_translations.getRuntimeName)(name);
|
|
816
|
+
await this.setObjectNotExistsAsync(groupId, {
|
|
817
|
+
type: "channel",
|
|
818
|
+
common: { name: groupName },
|
|
819
|
+
native: {}
|
|
820
|
+
});
|
|
821
|
+
await this.extendObjectAsync(groupId, { common: { name: groupName } });
|
|
822
|
+
await this.delObjectAsync(`${rootId}.${source}`, { recursive: true });
|
|
823
|
+
}
|
|
824
|
+
}
|
|
696
825
|
async createCanonicalVehicleStatusObjects(vin, status, source) {
|
|
697
826
|
if (this.stopping || !(0, import_saic_client.isVehicleStatusNotOlder)(status.statusTime, this.lastCanonicalStatusTimes.get(vin))) {
|
|
698
827
|
return;
|
|
@@ -733,7 +862,7 @@ class MgSaic extends utils.Adapter {
|
|
|
733
862
|
}
|
|
734
863
|
}
|
|
735
864
|
async createVehicleObjects(vehicle) {
|
|
736
|
-
var _a;
|
|
865
|
+
var _a, _b;
|
|
737
866
|
if (this.stopping) {
|
|
738
867
|
return;
|
|
739
868
|
}
|
|
@@ -757,6 +886,7 @@ class MgSaic extends utils.Adapter {
|
|
|
757
886
|
if (this.stopping) {
|
|
758
887
|
return;
|
|
759
888
|
}
|
|
889
|
+
await this.ensureVehicleChargingGroups(vehicle.vin);
|
|
760
890
|
const commandsId = `${deviceId}.commands`;
|
|
761
891
|
await this.setObjectNotExistsAsync(commandsId, {
|
|
762
892
|
type: "channel",
|
|
@@ -843,13 +973,13 @@ class MgSaic extends utils.Adapter {
|
|
|
843
973
|
{
|
|
844
974
|
id: "chargingScheduleStart",
|
|
845
975
|
type: "string",
|
|
846
|
-
role: "
|
|
976
|
+
role: "text",
|
|
847
977
|
def: "00:00"
|
|
848
978
|
},
|
|
849
979
|
{
|
|
850
980
|
id: "chargingScheduleEnd",
|
|
851
981
|
type: "string",
|
|
852
|
-
role: "
|
|
982
|
+
role: "text",
|
|
853
983
|
def: "06:00"
|
|
854
984
|
},
|
|
855
985
|
{
|
|
@@ -870,7 +1000,7 @@ class MgSaic extends utils.Adapter {
|
|
|
870
1000
|
{
|
|
871
1001
|
id: "batteryHeatingScheduleStart",
|
|
872
1002
|
type: "string",
|
|
873
|
-
role: "
|
|
1003
|
+
role: "text",
|
|
874
1004
|
def: "00:00"
|
|
875
1005
|
}
|
|
876
1006
|
];
|
|
@@ -879,6 +1009,7 @@ class MgSaic extends utils.Adapter {
|
|
|
879
1009
|
const legacyStateId = `${commandsId}.${setting.id}`;
|
|
880
1010
|
const stateObject = await this.getObjectAsync(stateId);
|
|
881
1011
|
const legacyState = await this.getStateAsync(legacyStateId);
|
|
1012
|
+
const previousScheduleState = setting.id.startsWith("chargingSchedule") ? await this.getStateAsync(`${commandsId}.schedules.${setting.id}`) : null;
|
|
882
1013
|
await this.setObjectNotExistsAsync(stateId, {
|
|
883
1014
|
type: "state",
|
|
884
1015
|
common: {
|
|
@@ -898,7 +1029,10 @@ class MgSaic extends utils.Adapter {
|
|
|
898
1029
|
});
|
|
899
1030
|
const currentState = await this.getStateAsync(stateId);
|
|
900
1031
|
if (!currentState || currentState.val === null) {
|
|
901
|
-
await this.setStateAsync(stateId, {
|
|
1032
|
+
await this.setStateAsync(stateId, {
|
|
1033
|
+
val: (_b = (_a = legacyState == null ? void 0 : legacyState.val) != null ? _a : previousScheduleState == null ? void 0 : previousScheduleState.val) != null ? _b : setting.def,
|
|
1034
|
+
ack: true
|
|
1035
|
+
});
|
|
902
1036
|
} else if (typeof currentState.val === "number" && (stateObject == null ? void 0 : stateObject.common.unit) !== setting.unit) {
|
|
903
1037
|
if (setting.id === "chargeTargetSoc" && currentState.val >= 1 && currentState.val <= 7) {
|
|
904
1038
|
await this.setStateAsync(stateId, { val: (currentState.val + 3) * 10, ack: true });
|
|
@@ -934,6 +1068,14 @@ class MgSaic extends utils.Adapter {
|
|
|
934
1068
|
await this.setStateAsync(actionId, { val: false, ack: true });
|
|
935
1069
|
await this.delObjectAsync(`${commandsId}.${action.id}`);
|
|
936
1070
|
}
|
|
1071
|
+
for (const id of [
|
|
1072
|
+
"chargingScheduleStart",
|
|
1073
|
+
"chargingScheduleEnd",
|
|
1074
|
+
"chargingScheduleMode",
|
|
1075
|
+
"chargingScheduleApply"
|
|
1076
|
+
]) {
|
|
1077
|
+
await this.delObjectAsync(`${commandsId}.schedules.${id}`);
|
|
1078
|
+
}
|
|
937
1079
|
for (const command of vehicleCommands) {
|
|
938
1080
|
await this.delObjectAsync(`${commandsId}.${command.id}`);
|
|
939
1081
|
}
|
package/build/main.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/main.ts"],
|
|
4
|
-
"sourcesContent": ["import * as utils from '@iobroker/adapter-core';\nimport { DEFAULT_POLL_INTERVAL_SECONDS, validateConfig, type MgSaicConfig } from './config';\nimport {\n\tSaicApiClient,\n\tSaicHttpError,\n\tSaicRemoteInstructionError,\n\tclimateTemperatureToIndex,\n\tgetClimateTemperatureRange,\n\tisVehicleStatusNotOlder,\n\ttargetSocPercentToCode,\n\ttype SaicVehicleSetting,\n\ttype SaicVehicleCommand,\n\ttype SaicVehicle,\n\ttype SaicVehicleStatus,\n} from './saic-client';\nimport { resolveSaicRegion } from './regions';\nimport { isRefreshCommand } from './refresh-command';\nimport { getVehicleStatusGroup, getVehicleStatusMetadata, normalizeVehicleStatusValue } from './status-metadata';\nimport { getRuntimeName } from './runtime-translations';\n\nconst vehicleCommands: Array<{ id: SaicVehicleCommand }> = [\n\t{ id: 'lock' },\n\t{ id: 'unlock' },\n\t{ id: 'openBoot' },\n\t{ id: 'climateStart' },\n\t{ id: 'climateStop' },\n\t{ id: 'frontDefrost' },\n\t{ id: 'rearWindowHeatStart' },\n\t{ id: 'rearWindowHeatStop' },\n\t{ id: 'batteryHeatStart' },\n\t{ id: 'batteryHeatStop' },\n\t{ id: 'chargingStart' },\n\t{ id: 'chargingStop' },\n\t{ id: 'chargingPortLock' },\n\t{ id: 'chargingPortUnlock' },\n\t{ id: 'findMyCar' },\n];\n\nconst commandGroups: Partial<Record<SaicVehicleCommand, string>> = {\n\tlock: 'access',\n\tunlock: 'access',\n\topenBoot: 'access',\n\tclimateStart: 'climate',\n\tclimateStop: 'climate',\n\tfrontDefrost: 'climate',\n\trearWindowHeatStart: 'heating',\n\trearWindowHeatStop: 'heating',\n\tbatteryHeatStart: 'heating',\n\tbatteryHeatStop: 'heating',\n\tchargingStart: 'charging',\n\tchargingStop: 'charging',\n\tchargingPortLock: 'charging',\n\tchargingPortUnlock: 'charging',\n\tfindMyCar: 'vehicle',\n};\n\nconst settingGroups: Record<string, string> = {\n\tdriverSeatHeatLevel: 'heating',\n\tpassengerSeatHeatLevel: 'heating',\n\tclimateTemperature: 'climate',\n\tchargeTargetSoc: 'charging',\n\tchargingCurrentLimit: 'charging',\n\tchargingScheduleStart: 'schedules',\n\tchargingScheduleEnd: 'schedules',\n\tchargingScheduleMode: 'schedules',\n\tbatteryHeatingScheduleEnabled: 'schedules',\n\tbatteryHeatingScheduleStart: 'schedules',\n};\n\nconst actionGroups: Record<SettingAction, string> = {\n\tclimateTemperatureApply: 'climate',\n\tchargingSettingsApply: 'charging',\n\tchargingScheduleApply: 'schedules',\n\tbatteryHeatingScheduleApply: 'schedules',\n};\n\nfunction vehicleCommandPath(vin: string, id: string): string {\n\tconst group =\n\t\tid in commandGroups\n\t\t\t? commandGroups[id as SaicVehicleCommand]\n\t\t\t: id in settingGroups\n\t\t\t\t? settingGroups[id]\n\t\t\t\t: actionGroups[id as SettingAction];\n\tif (!group) {\n\t\tthrow new Error(`Missing command group for ${id}`);\n\t}\n\treturn `vehicles.${vin}.commands.${group}.${id}`;\n}\n\nconst settingActions = [\n\t{ id: 'climateTemperatureApply' },\n\t{ id: 'chargingSettingsApply' },\n\t{ id: 'chargingScheduleApply' },\n\t{ id: 'batteryHeatingScheduleApply' },\n] as const;\n\ntype SettingAction = (typeof settingActions)[number]['id'];\n\nconst EXPOSE_SOURCE_STATUS_DATAPOINTS = false;\n\nclass MgSaic extends utils.Adapter {\n\tpublic constructor(options: Partial<utils.AdapterOptions> = {}) {\n\t\tsuper({\n\t\t\t...options,\n\t\t\tname: 'mg-saic',\n\t\t});\n\t\tthis.on('ready', this.onReady.bind(this));\n\t\tthis.on('stateChange', this.onStateChange.bind(this));\n\t\tthis.on('unload', this.onUnload.bind(this));\n\t}\n\n\tprivate pollTimer?: ioBroker.Interval;\n\tprivate pollInProgress = false;\n\tprivate refreshQueued = false;\n\tprivate stopping = false;\n\tprivate unloadCallbackCalled = false;\n\tprivate readonly abortController = new AbortController();\n\tprivate client?: SaicApiClient;\n\tprivate loginOptions?: {\n\t\tbaseUrl: string;\n\t\tregionCode: string;\n\t\ttenantId: string;\n\t\taccountType: 'email' | 'phone';\n\t\taccountIdentifier: string;\n\t\tphoneCountryCode?: string;\n\t\tpassword: string;\n\t};\n\tprivate accessToken?: string;\n\tprivate accessTokenExpiresAt = 0;\n\tprivate vehicles: SaicVehicle[] = [];\n\tprivate readonly lastStatusTimes = new Map<string, number>();\n\tprivate readonly lastCanonicalStatusTimes = new Map<string, number>();\n\tprivate readonly vehicleCommandsInProgress = new Set<string>();\n\n\tprivate async onReady(): Promise<void> {\n\t\tif (this.stopping) {\n\t\t\treturn;\n\t\t}\n\t\tconst config = this.config as unknown as MgSaicConfig;\n\t\tawait this.extendObjectAsync('info', { common: { name: getRuntimeName('info') } });\n\t\tawait this.extendObjectAsync('info.backend', { common: { name: getRuntimeName('backend') } });\n\t\tawait this.extendObjectAsync('info.connection', { common: { name: getRuntimeName('connection') } });\n\t\tawait this.extendObjectAsync('info.lastError', { common: { name: getRuntimeName('lastError') } });\n\t\tawait this.setObjectNotExistsAsync('commands.refresh', {\n\t\t\ttype: 'state',\n\t\t\tcommon: {\n\t\t\t\tname: getRuntimeName('refresh'),\n\t\t\t\ttype: 'boolean',\n\t\t\t\trole: 'button',\n\t\t\t\tread: false,\n\t\t\t\twrite: true,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\t\tawait this.extendObjectAsync('commands.refresh', { common: { name: getRuntimeName('refresh') } });\n\t\tif (this.stopping) {\n\t\t\treturn;\n\t\t}\n\t\tawait this.setStateAsync('commands.refresh', { val: false, ack: true });\n\t\tif (this.stopping) {\n\t\t\treturn;\n\t\t}\n\t\tthis.subscribeStates('commands.refresh');\n\t\tawait this.setState('info.connection', false, true);\n\t\tawait this.setState('info.backend', config.region?.trim() || 'not configured', true);\n\t\tconst errors = validateConfig(config);\n\t\tawait this.setState('info.lastError', errors.join('; '), true);\n\t\tif (errors.length) {\n\t\t\tthis.log.warn(`Configuration is incomplete: ${errors.join('; ')}`);\n\t\t\treturn;\n\t\t}\n\n\t\tconst region = resolveSaicRegion(config.region ?? '');\n\t\tif (!region) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tthis.client = new SaicApiClient(\n\t\t\t\tundefined,\n\t\t\t\tDate.now,\n\t\t\t\tundefined,\n\t\t\t\tmessage => this.log.debug(message),\n\t\t\t\tundefined,\n\t\t\t\t{\n\t\t\t\t\tsetTimeout: (callback, milliseconds) => {\n\t\t\t\t\t\tconst timer = this.setTimeout(callback, milliseconds);\n\t\t\t\t\t\treturn () => {\n\t\t\t\t\t\t\tif (timer !== undefined) {\n\t\t\t\t\t\t\t\tthis.clearTimeout(timer);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t\tthis.loginOptions = {\n\t\t\t\t...region,\n\t\t\t\taccountType: config.accountType as 'email' | 'phone',\n\t\t\t\taccountIdentifier: config.accountIdentifier ?? '',\n\t\t\t\tphoneCountryCode: config.phoneCountryCode,\n\t\t\t\tpassword: config.password ?? '',\n\t\t\t};\n\t\t\tawait this.authenticate();\n\t\t\tif (this.stopping) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.vehicles = await this.client.listVehicles(\n\t\t\t\tthis.loginOptions,\n\t\t\t\tthis.accessToken!,\n\t\t\t\tthis.abortController.signal,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tif (this.stopping) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst details = error instanceof Error ? error.message : 'Unknown initialization error';\n\t\t\tconst message = `SAIC initialization failed: ${details}`;\n\t\t\tawait this.setState('info.connection', false, true);\n\t\t\tawait this.setState('info.lastError', message, true);\n\t\t\tthis.log.warn(message);\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tfor (const vehicle of this.vehicles) {\n\t\t\t\tif (this.stopping) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tawait this.createVehicleObjects(vehicle);\n\t\t\t\tif (!EXPOSE_SOURCE_STATUS_DATAPOINTS) {\n\t\t\t\t\tawait this.delObjectAsync(`vehicles.${vehicle.vin}.cachedStatus`, { recursive: true });\n\t\t\t\t}\n\t\t\t\tawait this.delObjectAsync(`vehicles.${vehicle.vin}.canonicalStatus`, { recursive: true });\n\t\t\t}\n\t\t\tawait this.setState('info.connection', true, true);\n\t\t\tthis.log.info(`SAIC account authenticated; discovered ${this.vehicles.length} vehicle(s).`);\n\t\t\tif (this.vehicles.length === 0) {\n\t\t\t\tawait this.setState('info.lastError', 'No vehicles are linked to this SAIC account', true);\n\t\t\t\tthis.log.warn('No vehicles are linked to this SAIC account.');\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tawait this.refreshVehicleStatuses();\n\t\t\tconst intervalSeconds = config.pollIntervalSeconds ?? DEFAULT_POLL_INTERVAL_SECONDS;\n\t\t\tif (!this.stopping) {\n\t\t\t\tthis.pollTimer = this.setInterval(() => this.triggerRefresh(), intervalSeconds * 1000);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (this.stopping) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst details = error instanceof Error ? error.message : 'Unknown local adapter error';\n\t\t\tawait this.setState('info.lastError', `Could not initialize vehicle objects: ${details}`, true);\n\t\t\tthis.log.error(`Could not initialize vehicle objects: ${details}`);\n\t\t}\n\t}\n\n\tprivate async authenticate(): Promise<void> {\n\t\tif (!this.client || !this.loginOptions || this.stopping) {\n\t\t\tthrow new Error('Adapter is stopping or not initialized');\n\t\t}\n\t\tconst login = await this.client.login(this.loginOptions, this.abortController.signal);\n\t\tif (this.stopping) {\n\t\t\treturn;\n\t\t}\n\t\tthis.accessToken = login.accessToken;\n\t\tthis.accessTokenExpiresAt = Date.now() + login.expiresIn * 1000;\n\t\tawait this.setState('info.connection', true, true);\n\t}\n\n\tprivate triggerRefresh(): void {\n\t\tvoid this.refreshVehicleStatuses().catch(error => {\n\t\t\tconst details = error instanceof Error ? error.message : 'Unknown refresh error';\n\t\t\tthis.log.error(`Vehicle status refresh failed: ${details}`);\n\t\t});\n\t}\n\n\tprivate async refreshVehicleStatuses(): Promise<void> {\n\t\tif (this.stopping || !this.client || !this.loginOptions || !this.accessToken) {\n\t\t\treturn;\n\t\t}\n\t\tif (this.pollInProgress) {\n\t\t\tthis.refreshQueued = true;\n\t\t\treturn;\n\t\t}\n\t\tthis.pollInProgress = true;\n\t\tconst statusErrors: string[] = [];\n\t\tlet followUpUsed = false;\n\t\ttry {\n\t\t\tdo {\n\t\t\t\tthis.refreshQueued = false;\n\t\t\t\tfor (const vehicle of this.vehicles) {\n\t\t\t\t\tif (this.stopping) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tif (Date.now() >= this.accessTokenExpiresAt - 60_000) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tawait this.authenticate();\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tif (this.stopping) {\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst details = error instanceof Error ? error.message : 'Unknown authentication error';\n\t\t\t\t\t\t\tstatusErrors.push(`SAIC re-authentication failed: ${details}`);\n\t\t\t\t\t\t\tawait this.setState('info.connection', false, true);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tlet status: SaicVehicleStatus;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.log.debug(`Refreshing live status for ${vehicle.vin}`);\n\t\t\t\t\t\tstatus = await this.client.getVehicleStatus(\n\t\t\t\t\t\t\tthis.loginOptions,\n\t\t\t\t\t\t\tthis.accessToken,\n\t\t\t\t\t\t\tvehicle.vin,\n\t\t\t\t\t\t\tthis.abortController.signal,\n\t\t\t\t\t\t);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tif (this.stopping) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (error instanceof SaicHttpError && (error.status === 401 || error.status === 403)) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tawait this.authenticate();\n\t\t\t\t\t\t\t\tstatus = await this.client.getVehicleStatus(\n\t\t\t\t\t\t\t\t\tthis.loginOptions,\n\t\t\t\t\t\t\t\t\tthis.accessToken,\n\t\t\t\t\t\t\t\t\tvehicle.vin,\n\t\t\t\t\t\t\t\t\tthis.abortController.signal,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} catch (reauthError) {\n\t\t\t\t\t\t\t\tif (this.stopping) {\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tconst details =\n\t\t\t\t\t\t\t\t\treauthError instanceof Error ? reauthError.message : 'Unknown authentication error';\n\t\t\t\t\t\t\t\tstatusErrors.push(`SAIC re-authentication failed for ${vehicle.vin}: ${details}`);\n\t\t\t\t\t\t\t\tawait this.setState('info.connection', false, true);\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconst details = error instanceof Error ? error.message : 'Unknown error';\n\t\t\t\t\t\t\tconst diagnostic =\n\t\t\t\t\t\t\t\terror instanceof SaicRemoteInstructionError\n\t\t\t\t\t\t\t\t\t? `SAIC/MG returned remote instruction code 4 for ${vehicle.vin}; this is a response from the MG/SAIC service or vehicle, not an adapter parsing/processing error. SAIC message: ${details}`\n\t\t\t\t\t\t\t\t\t: details;\n\t\t\t\t\t\t\tstatusErrors.push(`Vehicle status request failed for ${vehicle.vin}: ${diagnostic}`);\n\t\t\t\t\t\t\tthis.log.warn(\n\t\t\t\t\t\t\t\t`Could not retrieve current status for vehicle ${vehicle.vin}: ${diagnostic}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tlet cachedStatus: SaicVehicleStatus;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tthis.log.debug(`Refreshing cached status as fallback for ${vehicle.vin}`);\n\t\t\t\t\t\t\t\tcachedStatus = await this.client.getCachedVehicleStatus(\n\t\t\t\t\t\t\t\t\tthis.loginOptions,\n\t\t\t\t\t\t\t\t\tthis.accessToken,\n\t\t\t\t\t\t\t\t\tvehicle.vin,\n\t\t\t\t\t\t\t\t\tthis.abortController.signal,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} catch (cacheError) {\n\t\t\t\t\t\t\t\tif (this.stopping) {\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tconst cacheDetails = cacheError instanceof Error ? cacheError.message : 'Unknown error';\n\t\t\t\t\t\t\t\tstatusErrors.push(\n\t\t\t\t\t\t\t\t\t`Cached vehicle status request failed for ${vehicle.vin}: ${cacheDetails}`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tthis.log.warn(\n\t\t\t\t\t\t\t\t\t`Could not retrieve cached status for vehicle ${vehicle.vin}: ${cacheDetails}`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tif (EXPOSE_SOURCE_STATUS_DATAPOINTS) {\n\t\t\t\t\t\t\t\t\tawait this.createVehicleStatusObjects(\n\t\t\t\t\t\t\t\t\t\tvehicle.vin,\n\t\t\t\t\t\t\t\t\t\tcachedStatus,\n\t\t\t\t\t\t\t\t\t\t'cachedStatus',\n\t\t\t\t\t\t\t\t\t\t'cachedStatus',\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tawait this.createCanonicalVehicleStatusObjects(vehicle.vin, cachedStatus, 'cached');\n\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\tconst writeDetails =\n\t\t\t\t\t\t\t\t\terror instanceof Error ? error.message : 'Unknown state write error';\n\t\t\t\t\t\t\t\tstatusErrors.push(`Could not write cached status for ${vehicle.vin}: ${writeDetails}`);\n\t\t\t\t\t\t\t\tthis.log.error(`Could not write cached status for ${vehicle.vin}: ${writeDetails}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (this.stopping) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tif (!isVehicleStatusNotOlder(status.statusTime, this.lastStatusTimes.get(vehicle.vin))) {\n\t\t\t\t\t\tstatusErrors.push(`Ignored older live status for ${vehicle.vin}`);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.log.debug(\n\t\t\t\t\t\t\t`Received live status for ${vehicle.vin}: ${Object.keys(status.basicVehicleStatus).length} basic fields, statusTime ${status.statusTime ?? 'missing'}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (EXPOSE_SOURCE_STATUS_DATAPOINTS) {\n\t\t\t\t\t\t\tawait this.createVehicleStatusObjects(vehicle.vin, status, 'liveStatus', 'liveStatus');\n\t\t\t\t\t\t}\n\t\t\t\t\t\tawait this.createCanonicalVehicleStatusObjects(vehicle.vin, status, 'live');\n\t\t\t\t\t\tif (!this.stopping && status.statusTime !== undefined) {\n\t\t\t\t\t\t\tthis.lastStatusTimes.set(vehicle.vin, status.statusTime);\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tisVehicleStatusNotOlder(\n\t\t\t\t\t\t\t\t\tstatus.statusTime,\n\t\t\t\t\t\t\t\t\tthis.lastCanonicalStatusTimes.get(vehicle.vin),\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tthis.lastCanonicalStatusTimes.set(vehicle.vin, status.statusTime);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.log.debug(`Created/updated live status objects for ${vehicle.vin}`);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tconst details = error instanceof Error ? error.message : 'Unknown state write error';\n\t\t\t\t\t\tstatusErrors.push(`Could not write live status for ${vehicle.vin}: ${details}`);\n\t\t\t\t\t\tthis.log.error(`Could not write live status for ${vehicle.vin}: ${details}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (this.refreshQueued && followUpUsed) {\n\t\t\t\t\tthis.refreshQueued = false;\n\t\t\t\t} else if (this.refreshQueued) {\n\t\t\t\t\tfollowUpUsed = true;\n\t\t\t\t}\n\t\t\t} while (this.refreshQueued && !this.stopping);\n\t\t\tif (!this.stopping) {\n\t\t\t\tawait this.setState('info.lastError', statusErrors.join('; '), true);\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.pollInProgress = false;\n\t\t}\n\t}\n\n\tprivate onStateChange(id: string, state: ioBroker.State | null | undefined): void {\n\t\tif (this.stopping) {\n\t\t\treturn;\n\t\t}\n\t\tif (isRefreshCommand(id, this.namespace, state)) {\n\t\t\tvoid this.setStateAsync('commands.refresh', { val: false, ack: true }).catch(error => {\n\t\t\t\tconst details = error instanceof Error ? error.message : 'Unknown state error';\n\t\t\t\tthis.log.error(`Could not acknowledge refresh command: ${details}`);\n\t\t\t});\n\t\t\tthis.triggerRefresh();\n\t\t\treturn;\n\t\t}\n\t\tif (!state || state.ack) {\n\t\t\treturn;\n\t\t}\n\t\tconst settingAction = settingActions.find(({ id: actionId }) =>\n\t\t\tthis.vehicles.some(({ vin }) => id === `${this.namespace}.${vehicleCommandPath(vin, actionId)}`),\n\t\t);\n\t\tconst settingVehicle = this.vehicles.find(\n\t\t\t({ vin }) => settingAction && id === `${this.namespace}.${vehicleCommandPath(vin, settingAction.id)}`,\n\t\t);\n\t\tif (settingAction && settingVehicle) {\n\t\t\tvoid this.executeVehicleSetting(settingVehicle.vin, settingAction.id);\n\t\t\treturn;\n\t\t}\n\t\tconst settingInput = this.vehicles\n\t\t\t.flatMap(({ vin }) =>\n\t\t\t\tObject.keys(settingGroups)\n\t\t\t\t\t.filter(stateId => stateId !== 'driverSeatHeatLevel' && stateId !== 'passengerSeatHeatLevel')\n\t\t\t\t\t.map(stateId => ({ vin, stateId })),\n\t\t\t)\n\t\t\t.find(({ vin, stateId }) => id === `${this.namespace}.${vehicleCommandPath(vin, stateId)}`);\n\t\tif (settingInput) {\n\t\t\tvoid this.setStateAsync(vehicleCommandPath(settingInput.vin, settingInput.stateId), {\n\t\t\t\tval: state.val,\n\t\t\t\tack: true,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tconst seatHeating = this.vehicles\n\t\t\t.flatMap(({ vin }) =>\n\t\t\t\t(['driverSeatHeatLevel', 'passengerSeatHeatLevel'] as const).map(stateId => ({ vin, stateId })),\n\t\t\t)\n\t\t\t.find(({ vin, stateId }) => id === `${this.namespace}.${vehicleCommandPath(vin, stateId)}`);\n\t\tif (seatHeating) {\n\t\t\tconst seat = seatHeating.stateId === 'driverSeatHeatLevel' ? 'driver' : 'passenger';\n\t\t\tvoid this.executeSeatHeating(seatHeating.vin, seat, state.val);\n\t\t\treturn;\n\t\t}\n\t\tif (state.val !== true) {\n\t\t\treturn;\n\t\t}\n\t\tconst commandEntry = vehicleCommands.find(({ id: commandId }) =>\n\t\t\tthis.vehicles.some(({ vin }) => id === `${this.namespace}.${vehicleCommandPath(vin, commandId)}`),\n\t\t);\n\t\tconst vehicle = this.vehicles.find(\n\t\t\t({ vin }) => commandEntry && id === `${this.namespace}.${vehicleCommandPath(vin, commandEntry.id)}`,\n\t\t);\n\t\tif (!commandEntry || !vehicle) {\n\t\t\treturn;\n\t\t}\n\t\tvoid this.executeVehicleCommand(vehicle.vin, commandEntry.id);\n\t}\n\n\tprivate async executeSeatHeating(\n\t\tvin: string,\n\t\tseat: 'driver' | 'passenger',\n\t\tvalue: ioBroker.StateValue,\n\t): Promise<void> {\n\t\tconst stateId = vehicleCommandPath(vin, `${seat}SeatHeatLevel`);\n\t\tif (typeof value !== 'number' || !Number.isInteger(value) || value < 0 || value > 3) {\n\t\t\tawait this.setStateAsync(stateId, { ack: true });\n\t\t\tthis.log.warn(`Ignored ${seat} seat heating level for ${vin}: expected an integer from 0 to 3`);\n\t\t\treturn;\n\t\t}\n\t\tif (this.vehicleCommandsInProgress.has(vin)) {\n\t\t\tawait this.setStateAsync(stateId, { ack: true });\n\t\t\tthis.log.warn(`Ignored ${seat} seat heating for ${vin}: another vehicle command is still running`);\n\t\t\treturn;\n\t\t}\n\t\tthis.vehicleCommandsInProgress.add(vin);\n\t\ttry {\n\t\t\tif (!this.client || !this.loginOptions) {\n\t\t\t\tthrow new Error('SAIC client is not initialized');\n\t\t\t}\n\t\t\tif (!this.accessToken || this.accessTokenExpiresAt <= Date.now() + 30_000) {\n\t\t\t\tawait this.authenticate();\n\t\t\t}\n\t\t\tawait this.client.sendVehicleSeatHeating(\n\t\t\t\tthis.loginOptions,\n\t\t\t\tthis.accessToken!,\n\t\t\t\tvin,\n\t\t\t\tseat,\n\t\t\t\tvalue,\n\t\t\t\tthis.abortController.signal,\n\t\t\t);\n\t\t\tawait this.setStateAsync(stateId, { val: value, ack: true });\n\t\t\tthis.log.info(`SAIC ${seat} seat heating level ${value} completed for ${vin}`);\n\t\t} catch (error) {\n\t\t\tif (!this.stopping) {\n\t\t\t\tawait this.setStateAsync(stateId, { val: value, ack: true });\n\t\t\t\tconst details = error instanceof Error ? error.message : 'Unknown command error';\n\t\t\t\tthis.log.warn(`SAIC ${seat} seat heating failed for ${vin}: ${details}`);\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.vehicleCommandsInProgress.delete(vin);\n\t\t}\n\t}\n\n\tprivate async executeVehicleSetting(vin: string, action: SettingAction): Promise<void> {\n\t\tconst stateId = vehicleCommandPath(vin, action);\n\t\tif (this.vehicleCommandsInProgress.has(vin)) {\n\t\t\tawait this.setStateAsync(stateId, { val: false, ack: true });\n\t\t\tthis.log.warn(`Ignored ${action} for ${vin}: another vehicle command is still running`);\n\t\t\treturn;\n\t\t}\n\t\tthis.vehicleCommandsInProgress.add(vin);\n\t\ttry {\n\t\t\tawait this.setStateAsync(stateId, { val: false, ack: true });\n\t\t\tif (!this.client || !this.loginOptions) {\n\t\t\t\tthrow new Error('SAIC client is not initialized');\n\t\t\t}\n\t\t\tconst setting = await this.readVehicleSetting(vin, action);\n\t\t\tif (!this.accessToken || this.accessTokenExpiresAt <= Date.now() + 30_000) {\n\t\t\t\tawait this.authenticate();\n\t\t\t}\n\t\t\tawait this.client.sendVehicleSetting(\n\t\t\t\tthis.loginOptions,\n\t\t\t\tthis.accessToken!,\n\t\t\t\tvin,\n\t\t\t\tsetting,\n\t\t\t\tthis.abortController.signal,\n\t\t\t);\n\t\t\tthis.log.info(`SAIC ${action} completed for ${vin}`);\n\t\t} catch (error) {\n\t\t\tif (!this.stopping) {\n\t\t\t\tconst details = error instanceof Error ? error.message : 'Unknown settings error';\n\t\t\t\tthis.log.warn(`SAIC ${action} failed for ${vin}: ${details}`);\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.vehicleCommandsInProgress.delete(vin);\n\t\t}\n\t}\n\n\tprivate async readVehicleSetting(vin: string, action: SettingAction): Promise<SaicVehicleSetting> {\n\t\tconst readNumber = async (id: string): Promise<number> => {\n\t\t\tconst state = await this.getStateAsync(vehicleCommandPath(vin, id));\n\t\t\tif (!state || typeof state.val !== 'number' || !Number.isFinite(state.val)) {\n\t\t\t\tthrow new Error(`Setting ${id} must contain a finite number`);\n\t\t\t}\n\t\t\treturn state.val;\n\t\t};\n\t\tconst readString = async (id: string): Promise<string> => {\n\t\t\tconst state = await this.getStateAsync(vehicleCommandPath(vin, id));\n\t\t\tif (!state || typeof state.val !== 'string') {\n\t\t\t\tthrow new Error(`Setting ${id} must contain a time in HH:MM format`);\n\t\t\t}\n\t\t\treturn state.val;\n\t\t};\n\t\tif (action === 'climateTemperatureApply') {\n\t\t\tconst vehicle = this.vehicles.find(item => item.vin === vin);\n\t\t\treturn {\n\t\t\t\ttype: 'climateTemperature',\n\t\t\t\tvalue: climateTemperatureToIndex(await readNumber('climateTemperature'), vehicle?.series),\n\t\t\t};\n\t\t}\n\t\tif (action === 'chargingSettingsApply') {\n\t\t\treturn {\n\t\t\t\ttype: 'chargingSettings',\n\t\t\t\ttargetSoc: targetSocPercentToCode(await readNumber('chargeTargetSoc')),\n\t\t\t\tcurrentLimit: await readNumber('chargingCurrentLimit'),\n\t\t\t};\n\t\t}\n\t\tif (action === 'chargingScheduleApply') {\n\t\t\treturn {\n\t\t\t\ttype: 'chargingSchedule',\n\t\t\t\tstart: await readString('chargingScheduleStart'),\n\t\t\t\tend: await readString('chargingScheduleEnd'),\n\t\t\t\tmode: await readNumber('chargingScheduleMode'),\n\t\t\t};\n\t\t}\n\t\tconst enabled = await this.getStateAsync(vehicleCommandPath(vin, 'batteryHeatingScheduleEnabled'));\n\t\tif (!enabled || typeof enabled.val !== 'boolean') {\n\t\t\tthrow new Error('Battery heating schedule enabled must be boolean');\n\t\t}\n\t\treturn {\n\t\t\ttype: 'batteryHeatingSchedule',\n\t\t\tenabled: enabled.val,\n\t\t\tstart: await readString('batteryHeatingScheduleStart'),\n\t\t};\n\t}\n\n\tprivate async executeVehicleCommand(vin: string, command: SaicVehicleCommand): Promise<void> {\n\t\tconst stateId = vehicleCommandPath(vin, command);\n\t\tif (this.vehicleCommandsInProgress.has(vin)) {\n\t\t\tawait this.setStateAsync(stateId, { val: false, ack: true });\n\t\t\tthis.log.warn(`Ignored ${command} command for ${vin}: another vehicle command is still running`);\n\t\t\treturn;\n\t\t}\n\t\tthis.vehicleCommandsInProgress.add(vin);\n\t\ttry {\n\t\t\tawait this.setStateAsync(stateId, { val: false, ack: true });\n\t\t\tif (!this.client || !this.loginOptions) {\n\t\t\t\tthrow new Error('SAIC client is not initialized');\n\t\t\t}\n\t\t\tif (!this.accessToken || this.accessTokenExpiresAt <= Date.now() + 30_000) {\n\t\t\t\tawait this.authenticate();\n\t\t\t}\n\t\t\tawait this.client.sendVehicleCommand(\n\t\t\t\tthis.loginOptions,\n\t\t\t\tthis.accessToken!,\n\t\t\t\tvin,\n\t\t\t\tcommand,\n\t\t\t\tthis.abortController.signal,\n\t\t\t);\n\t\t\tthis.log.info(`SAIC ${command} command completed for ${vin}`);\n\t\t} catch (error) {\n\t\t\tif (!this.stopping) {\n\t\t\t\tconst details = error instanceof Error ? error.message : 'Unknown command error';\n\t\t\t\tthis.log.warn(`SAIC ${command} command failed for ${vin}: ${details}`);\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.vehicleCommandsInProgress.delete(vin);\n\t\t}\n\t}\n\n\tprivate async createVehicleStatusObjects(\n\t\tvin: string,\n\t\tstatus: SaicVehicleStatus,\n\t\tchannel = 'status',\n\t\tchannelName = 'currentStatus',\n\t): Promise<void> {\n\t\tif (this.stopping) {\n\t\t\treturn;\n\t\t}\n\t\tif (!EXPOSE_SOURCE_STATUS_DATAPOINTS && (channel === 'liveStatus' || channel === 'cachedStatus')) {\n\t\t\treturn;\n\t\t}\n\t\tconst statusId = `vehicles.${vin}.${channel}`;\n\t\tawait this.setObjectNotExistsAsync(statusId, {\n\t\t\ttype: 'channel',\n\t\t\tcommon: { name: getRuntimeName(channelName) },\n\t\t\tnative: {},\n\t\t});\n\t\tawait this.extendObjectAsync(statusId, { common: { name: getRuntimeName(channelName) } });\n\t\tif (this.stopping) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst values: Record<string, number> = { ...status.basicVehicleStatus };\n\t\tif (status.statusTime !== undefined) {\n\t\t\tvalues.statusTime = status.statusTime;\n\t\t}\n\t\tif (status.onlineStatus !== undefined) {\n\t\t\tvalues.onlineStatus = status.onlineStatus;\n\t\t}\n\t\tthis.log.debug(`Writing ${Object.keys(values).length} values under ${statusId}`);\n\t\tfor (const [key, value] of Object.entries(values)) {\n\t\t\tif (this.stopping) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst group = getVehicleStatusGroup(key);\n\t\t\tconst groupId = `${statusId}.${group}`;\n\t\t\tawait this.setObjectNotExistsAsync(groupId, {\n\t\t\t\ttype: 'channel',\n\t\t\t\tcommon: { name: getRuntimeName(group) },\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tawait this.extendObjectAsync(groupId, { common: { name: getRuntimeName(group) } });\n\t\t\tif (this.stopping) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst metadata = getVehicleStatusMetadata(key);\n\t\t\tconst stateId = `${groupId}.${key}`;\n\t\t\tconst common = {\n\t\t\t\tname: metadata.name,\n\t\t\t\ttype: metadata.type,\n\t\t\t\trole: metadata.role,\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t\t...(metadata.unit ? { unit: metadata.unit } : {}),\n\t\t\t};\n\t\t\tawait this.setObjectNotExistsAsync(stateId, {\n\t\t\t\ttype: 'state',\n\t\t\t\tcommon,\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tif (this.stopping) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait this.extendObjectAsync(stateId, {\n\t\t\t\ttype: 'state',\n\t\t\t\tcommon,\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tif (this.stopping) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait this.setStateAsync(stateId, { val: normalizeVehicleStatusValue(key, value), ack: true });\n\t\t\tif (this.stopping) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait this.delObjectAsync(`${statusId}.${key}`);\n\t\t}\n\t}\n\n\tprivate async createCanonicalVehicleStatusObjects(\n\t\tvin: string,\n\t\tstatus: SaicVehicleStatus,\n\t\tsource: 'live' | 'cached',\n\t): Promise<void> {\n\t\tif (this.stopping || !isVehicleStatusNotOlder(status.statusTime, this.lastCanonicalStatusTimes.get(vin))) {\n\t\t\treturn;\n\t\t}\n\t\tawait this.createVehicleStatusObjects(vin, status);\n\t\tif (this.stopping) {\n\t\t\treturn;\n\t\t}\n\t\tconst sourceId = `vehicles.${vin}.status.source`;\n\t\tawait this.setObjectNotExistsAsync(sourceId, {\n\t\t\ttype: 'state',\n\t\t\tcommon: { name: getRuntimeName('statusSource'), type: 'string', role: 'text', read: true, write: false },\n\t\t\tnative: {},\n\t\t});\n\t\tawait this.extendObjectAsync(sourceId, { common: { name: getRuntimeName('statusSource') } });\n\t\tif (this.stopping) {\n\t\t\treturn;\n\t\t}\n\t\tawait this.setStateAsync(sourceId, { val: source, ack: true });\n\t\tif (status.statusTime !== undefined) {\n\t\t\tconst sourceTimestampId = `vehicles.${vin}.status.sourceTimestamp`;\n\t\t\tawait this.setObjectNotExistsAsync(sourceTimestampId, {\n\t\t\t\ttype: 'state',\n\t\t\t\tcommon: {\n\t\t\t\t\tname: getRuntimeName('statusSourceTimestamp'),\n\t\t\t\t\ttype: 'number',\n\t\t\t\t\trole: 'date',\n\t\t\t\t\tread: true,\n\t\t\t\t\twrite: false,\n\t\t\t\t},\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tawait this.extendObjectAsync(sourceTimestampId, {\n\t\t\t\tcommon: { name: getRuntimeName('statusSourceTimestamp') },\n\t\t\t});\n\t\t\tawait this.setStateAsync(sourceTimestampId, { val: status.statusTime * 1000, ack: true });\n\t\t\tthis.lastCanonicalStatusTimes.set(vin, status.statusTime);\n\t\t}\n\t}\n\n\tprivate async createVehicleObjects(vehicle: SaicVehicle): Promise<void> {\n\t\tif (this.stopping) {\n\t\t\treturn;\n\t\t}\n\t\tconst deviceId = `vehicles.${vehicle.vin}`;\n\t\tconst values: Record<string, string | boolean | undefined> = {\n\t\t\tvin: vehicle.vin,\n\t\t\tname: vehicle.name,\n\t\t\tbrandName: vehicle.brandName,\n\t\t\tmodelName: vehicle.modelName,\n\t\t\tseries: vehicle.series,\n\t\t\tmodelYear: vehicle.modelYear,\n\t\t\tcolorName: vehicle.colorName,\n\t\t\tisCurrentVehicle: vehicle.isCurrentVehicle,\n\t\t\tisSubaccount: vehicle.isSubaccount,\n\t\t};\n\n\t\tawait this.setObjectNotExistsAsync(deviceId, {\n\t\t\ttype: 'device',\n\t\t\tcommon: { name: vehicle.name || vehicle.modelName || vehicle.vin },\n\t\t\tnative: {},\n\t\t});\n\t\tif (this.stopping) {\n\t\t\treturn;\n\t\t}\n\t\tconst commandsId = `${deviceId}.commands`;\n\t\tawait this.setObjectNotExistsAsync(commandsId, {\n\t\t\ttype: 'channel',\n\t\t\tcommon: { name: getRuntimeName('commands') },\n\t\t\tnative: {},\n\t\t});\n\t\tawait this.extendObjectAsync(commandsId, { common: { name: getRuntimeName('commands') } });\n\t\tfor (const group of ['access', 'climate', 'heating', 'charging', 'schedules', 'vehicle']) {\n\t\t\tconst groupId = `${commandsId}.${group}`;\n\t\t\tconst groupName = getRuntimeName(`commandGroup_${group}`);\n\t\t\tawait this.setObjectNotExistsAsync(groupId, {\n\t\t\t\ttype: 'channel',\n\t\t\t\tcommon: { name: groupName },\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tawait this.extendObjectAsync(groupId, { common: { name: groupName } });\n\t\t}\n\t\tfor (const command of vehicleCommands) {\n\t\t\tconst commandId = vehicleCommandPath(vehicle.vin, command.id);\n\t\t\tawait this.setObjectNotExistsAsync(commandId, {\n\t\t\t\ttype: 'state',\n\t\t\t\tcommon: {\n\t\t\t\t\tname: getRuntimeName(command.id),\n\t\t\t\t\ttype: 'boolean',\n\t\t\t\t\trole: 'button',\n\t\t\t\t\tread: false,\n\t\t\t\t\twrite: true,\n\t\t\t\t},\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tawait this.extendObjectAsync(commandId, {\n\t\t\t\tcommon: { name: getRuntimeName(command.id) },\n\t\t\t});\n\t\t\tawait this.setStateAsync(commandId, { val: false, ack: true });\n\t\t}\n\t\tconst settingStates: Array<{\n\t\t\tid: string;\n\t\t\ttype: 'number' | 'string' | 'boolean';\n\t\t\trole: string;\n\t\t\tdef: number | string | boolean;\n\t\t\tmin?: number;\n\t\t\tmax?: number;\n\t\t\tstep?: number;\n\t\t\tunit?: string;\n\t\t\tstates?: Record<string, string>;\n\t\t}> = [\n\t\t\t{\n\t\t\t\tid: 'driverSeatHeatLevel',\n\t\t\t\ttype: 'number',\n\t\t\t\trole: 'level',\n\t\t\t\tdef: 0,\n\t\t\t\tmin: 0,\n\t\t\t\tmax: 3,\n\t\t\t\tstates: { 0: 'Off', 1: 'Low', 2: 'Medium', 3: 'High' },\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'passengerSeatHeatLevel',\n\t\t\t\ttype: 'number',\n\t\t\t\trole: 'level',\n\t\t\t\tdef: 0,\n\t\t\t\tmin: 0,\n\t\t\t\tmax: 3,\n\t\t\t\tstates: { 0: 'Off', 1: 'Low', 2: 'Medium', 3: 'High' },\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'climateTemperature',\n\t\t\t\ttype: 'number',\n\t\t\t\trole: 'level.temperature',\n\t\t\t\tdef: 22,\n\t\t\t\tmin: getClimateTemperatureRange(vehicle.series).min,\n\t\t\t\tmax: getClimateTemperatureRange(vehicle.series).max,\n\t\t\t\tunit: '\u00B0C',\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'chargeTargetSoc',\n\t\t\t\ttype: 'number',\n\t\t\t\trole: 'level',\n\t\t\t\tdef: 80,\n\t\t\t\tmin: 40,\n\t\t\t\tmax: 100,\n\t\t\t\tstep: 10,\n\t\t\t\tunit: '%',\n\t\t\t\tstates: { 40: '40%', 50: '50%', 60: '60%', 70: '70%', 80: '80%', 90: '90%', 100: '100%' },\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'chargingCurrentLimit',\n\t\t\t\ttype: 'number',\n\t\t\t\trole: 'level',\n\t\t\t\tdef: 4,\n\t\t\t\tmin: 1,\n\t\t\t\tmax: 4,\n\t\t\t\tstates: { 1: '6 A', 2: '8 A', 3: '16 A', 4: 'Maximum' },\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'chargingScheduleStart',\n\t\t\t\ttype: 'string',\n\t\t\t\trole: 'value.time',\n\t\t\t\tdef: '00:00',\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'chargingScheduleEnd',\n\t\t\t\ttype: 'string',\n\t\t\t\trole: 'value.time',\n\t\t\t\tdef: '06:00',\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'chargingScheduleMode',\n\t\t\t\ttype: 'number',\n\t\t\t\trole: 'level',\n\t\t\t\tdef: 2,\n\t\t\t\tmin: 1,\n\t\t\t\tmax: 3,\n\t\t\t\tstates: { 1: 'Until configured time', 2: 'Disabled', 3: 'Until configured SOC' },\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'batteryHeatingScheduleEnabled',\n\t\t\t\ttype: 'boolean',\n\t\t\t\trole: 'switch',\n\t\t\t\tdef: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'batteryHeatingScheduleStart',\n\t\t\t\ttype: 'string',\n\t\t\t\trole: 'value.time',\n\t\t\t\tdef: '00:00',\n\t\t\t},\n\t\t];\n\t\tfor (const setting of settingStates) {\n\t\t\tconst stateId = vehicleCommandPath(vehicle.vin, setting.id);\n\t\t\tconst legacyStateId = `${commandsId}.${setting.id}`;\n\t\t\tconst stateObject = await this.getObjectAsync(stateId);\n\t\t\tconst legacyState = await this.getStateAsync(legacyStateId);\n\t\t\tawait this.setObjectNotExistsAsync(stateId, {\n\t\t\t\ttype: 'state',\n\t\t\t\tcommon: {\n\t\t\t\t\tname: getRuntimeName(setting.id),\n\t\t\t\t\ttype: setting.type,\n\t\t\t\t\trole: setting.role,\n\t\t\t\t\tread: true,\n\t\t\t\t\twrite: true,\n\t\t\t\t\tdef: setting.def,\n\t\t\t\t\t...(setting.min === undefined ? {} : { min: setting.min }),\n\t\t\t\t\t...(setting.max === undefined ? {} : { max: setting.max }),\n\t\t\t\t\t...(setting.step === undefined ? {} : { step: setting.step }),\n\t\t\t\t\t...(setting.unit === undefined ? {} : { unit: setting.unit }),\n\t\t\t\t\t...(setting.states ? { states: setting.states } : {}),\n\t\t\t\t},\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tconst currentState = await this.getStateAsync(stateId);\n\t\t\tif (!currentState || currentState.val === null) {\n\t\t\t\tawait this.setStateAsync(stateId, { val: legacyState?.val ?? setting.def, ack: true });\n\t\t\t} else if (typeof currentState.val === 'number' && stateObject?.common.unit !== setting.unit) {\n\t\t\t\tif (setting.id === 'chargeTargetSoc' && currentState.val >= 1 && currentState.val <= 7) {\n\t\t\t\t\tawait this.setStateAsync(stateId, { val: (currentState.val + 3) * 10, ack: true });\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait this.extendObjectAsync(stateId, {\n\t\t\t\tcommon: {\n\t\t\t\t\tname: getRuntimeName(setting.id),\n\t\t\t\t\ttype: setting.type,\n\t\t\t\t\trole: setting.role,\n\t\t\t\t\tread: true,\n\t\t\t\t\twrite: true,\n\t\t\t\t\tdef: setting.def,\n\t\t\t\t\t...(setting.min === undefined ? {} : { min: setting.min }),\n\t\t\t\t\t...(setting.max === undefined ? {} : { max: setting.max }),\n\t\t\t\t\t...(setting.step === undefined ? {} : { step: setting.step }),\n\t\t\t\t\t...(setting.unit === undefined ? {} : { unit: setting.unit }),\n\t\t\t\t\t...(setting.states ? { states: setting.states } : {}),\n\t\t\t\t},\n\t\t\t});\n\t\t\tawait this.delObjectAsync(legacyStateId);\n\t\t}\n\t\tfor (const action of settingActions) {\n\t\t\tconst actionId = vehicleCommandPath(vehicle.vin, action.id);\n\t\t\tawait this.setObjectNotExistsAsync(actionId, {\n\t\t\t\ttype: 'state',\n\t\t\t\tcommon: { name: getRuntimeName(action.id), type: 'boolean', role: 'button', read: false, write: true },\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tawait this.extendObjectAsync(actionId, {\n\t\t\t\tcommon: { name: getRuntimeName(action.id) },\n\t\t\t});\n\t\t\tawait this.setStateAsync(actionId, { val: false, ack: true });\n\t\t\tawait this.delObjectAsync(`${commandsId}.${action.id}`);\n\t\t}\n\t\tfor (const command of vehicleCommands) {\n\t\t\tawait this.delObjectAsync(`${commandsId}.${command.id}`);\n\t\t}\n\t\tthis.subscribeStates(`${commandsId}.*`);\n\t\tif (this.stopping) {\n\t\t\treturn;\n\t\t}\n\t\tfor (const [key, value] of Object.entries(values)) {\n\t\t\tif (this.stopping) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (value === undefined) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst isBoolean = typeof value === 'boolean';\n\t\t\tconst name = getRuntimeName(key);\n\t\t\tawait this.setObjectNotExistsAsync(`${deviceId}.${key}`, {\n\t\t\t\ttype: 'state',\n\t\t\t\tcommon: {\n\t\t\t\t\tname,\n\t\t\t\t\ttype: isBoolean ? 'boolean' : 'string',\n\t\t\t\t\trole: isBoolean ? 'indicator' : key === 'vin' ? 'text' : 'info.name',\n\t\t\t\t\tread: true,\n\t\t\t\t\twrite: false,\n\t\t\t\t},\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tawait this.extendObjectAsync(`${deviceId}.${key}`, { common: { name } });\n\t\t\tif (this.stopping) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait this.setStateAsync(`${deviceId}.${key}`, { val: value, ack: true });\n\t\t}\n\t}\n\n\tprivate onUnload(callback: () => void): void {\n\t\tif (this.unloadCallbackCalled) {\n\t\t\treturn;\n\t\t}\n\t\tthis.unloadCallbackCalled = true;\n\t\tthis.stopping = true;\n\t\tthis.abortController.abort(new DOMException('Adapter is stopping', 'AbortError'));\n\t\tthis.refreshQueued = false;\n\t\tif (this.pollTimer) {\n\t\t\tthis.clearInterval(this.pollTimer);\n\t\t}\n\t\tcallback();\n\t}\n}\nif (require.main !== module) {\n\t// Export the constructor in compact mode\n\tmodule.exports = (options: Partial<utils.AdapterOptions> | undefined) => new MgSaic(options);\n} else {\n\t// otherwise start the instance directly\n\t(() => new MgSaic())();\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import * as utils from '@iobroker/adapter-core';\nimport { DEFAULT_POLL_INTERVAL_SECONDS, validateConfig, type MgSaicConfig } from './config';\nimport {\n\tSaicApiClient,\n\tSaicHttpError,\n\tSaicRemoteInstructionError,\n\tclimateTemperatureToIndex,\n\tgetClimateTemperatureRange,\n\tisVehicleStatusNotOlder,\n\ttargetSocPercentToCode,\n\ttype SaicVehicleSetting,\n\ttype SaicVehicleCommand,\n\ttype SaicVehicle,\n\ttype SaicVehicleStatus,\n\ttype SaicChargingStatus,\n} from './saic-client';\nimport { resolveSaicRegion } from './regions';\nimport { isRefreshCommand } from './refresh-command';\nimport {\n\tgetVehicleStatusGroup,\n\tgetVehicleStatusMetadata,\n\tgetChargingFieldMetadata,\n\tnormalizeChargingValue,\n\tnormalizeVehicleStatusValue,\n\tresolveOdometerValue,\n\tshouldDeleteUnavailableStatusValue,\n} from './status-metadata';\nimport { getChargingFieldName, getRuntimeName } from './runtime-translations';\n\nconst chargingGroups = [\n\t{ source: 'chrgMgmtData', id: 'session', name: 'chargingManagement' },\n\t{ source: 'rvsChargeStatus', id: 'statistics', name: 'chargeStatus' },\n] as const;\n\nconst vehicleCommands: Array<{ id: SaicVehicleCommand }> = [\n\t{ id: 'lock' },\n\t{ id: 'unlock' },\n\t{ id: 'openBoot' },\n\t{ id: 'climateStart' },\n\t{ id: 'climateStop' },\n\t{ id: 'frontDefrost' },\n\t{ id: 'rearWindowHeatStart' },\n\t{ id: 'rearWindowHeatStop' },\n\t{ id: 'batteryHeatStart' },\n\t{ id: 'batteryHeatStop' },\n\t{ id: 'chargingStart' },\n\t{ id: 'chargingStop' },\n\t{ id: 'chargingPortLock' },\n\t{ id: 'chargingPortUnlock' },\n\t{ id: 'findMyCar' },\n];\n\nconst commandGroups: Partial<Record<SaicVehicleCommand, string>> = {\n\tlock: 'access',\n\tunlock: 'access',\n\topenBoot: 'access',\n\tclimateStart: 'climate',\n\tclimateStop: 'climate',\n\tfrontDefrost: 'climate',\n\trearWindowHeatStart: 'heating',\n\trearWindowHeatStop: 'heating',\n\tbatteryHeatStart: 'heating',\n\tbatteryHeatStop: 'heating',\n\tchargingStart: 'charging',\n\tchargingStop: 'charging',\n\tchargingPortLock: 'charging',\n\tchargingPortUnlock: 'charging',\n\tfindMyCar: 'vehicle',\n};\n\nconst settingGroups: Record<string, string> = {\n\tdriverSeatHeatLevel: 'heating',\n\tpassengerSeatHeatLevel: 'heating',\n\tclimateTemperature: 'climate',\n\tchargeTargetSoc: 'charging',\n\tchargingCurrentLimit: 'charging',\n\tchargingScheduleStart: 'charging',\n\tchargingScheduleEnd: 'charging',\n\tchargingScheduleMode: 'charging',\n\tbatteryHeatingScheduleEnabled: 'schedules',\n\tbatteryHeatingScheduleStart: 'schedules',\n};\n\nconst actionGroups: Record<SettingAction, string> = {\n\tclimateTemperatureApply: 'climate',\n\tchargingSettingsApply: 'charging',\n\tchargingScheduleApply: 'charging',\n\tbatteryHeatingScheduleApply: 'schedules',\n};\n\nfunction vehicleCommandPath(vin: string, id: string): string {\n\tconst group =\n\t\tid in commandGroups\n\t\t\t? commandGroups[id as SaicVehicleCommand]\n\t\t\t: id in settingGroups\n\t\t\t\t? settingGroups[id]\n\t\t\t\t: actionGroups[id as SettingAction];\n\tif (!group) {\n\t\tthrow new Error(`Missing command group for ${id}`);\n\t}\n\treturn `vehicles.${vin}.commands.${group}.${id}`;\n}\n\nconst settingActions = [\n\t{ id: 'climateTemperatureApply' },\n\t{ id: 'chargingSettingsApply' },\n\t{ id: 'chargingScheduleApply' },\n\t{ id: 'batteryHeatingScheduleApply' },\n] as const;\n\ntype SettingAction = (typeof settingActions)[number]['id'];\n\nconst EXPOSE_SOURCE_STATUS_DATAPOINTS = false;\n\nclass MgSaic extends utils.Adapter {\n\tpublic constructor(options: Partial<utils.AdapterOptions> = {}) {\n\t\tsuper({\n\t\t\t...options,\n\t\t\tname: 'mg-saic',\n\t\t});\n\t\tthis.on('ready', this.onReady.bind(this));\n\t\tthis.on('stateChange', this.onStateChange.bind(this));\n\t\tthis.on('unload', this.onUnload.bind(this));\n\t}\n\n\tprivate pollTimer?: ioBroker.Interval;\n\tprivate pollInProgress = false;\n\tprivate refreshQueued = false;\n\tprivate stopping = false;\n\tprivate unloadCallbackCalled = false;\n\tprivate readonly abortController = new AbortController();\n\tprivate client?: SaicApiClient;\n\tprivate loginOptions?: {\n\t\tbaseUrl: string;\n\t\tregionCode: string;\n\t\ttenantId: string;\n\t\taccountType: 'email' | 'phone';\n\t\taccountIdentifier: string;\n\t\tphoneCountryCode?: string;\n\t\tpassword: string;\n\t};\n\tprivate accessToken?: string;\n\tprivate accessTokenExpiresAt = 0;\n\tprivate vehicles: SaicVehicle[] = [];\n\tprivate readonly lastStatusTimes = new Map<string, number>();\n\tprivate readonly lastCanonicalStatusTimes = new Map<string, number>();\n\tprivate readonly vehicleCommandsInProgress = new Set<string>();\n\n\tprivate async onReady(): Promise<void> {\n\t\tif (this.stopping) {\n\t\t\treturn;\n\t\t}\n\t\tconst config = this.config as unknown as MgSaicConfig;\n\t\tawait this.extendObjectAsync('info', { common: { name: getRuntimeName('info') } });\n\t\tawait this.extendObjectAsync('info.backend', { common: { name: getRuntimeName('backend') } });\n\t\tawait this.extendObjectAsync('info.connection', { common: { name: getRuntimeName('connection') } });\n\t\tawait this.extendObjectAsync('info.lastError', { common: { name: getRuntimeName('lastError') } });\n\t\tawait this.setObjectNotExistsAsync('commands', {\n\t\t\ttype: 'channel',\n\t\t\tcommon: { name: getRuntimeName('commands') },\n\t\t\tnative: {},\n\t\t});\n\t\tawait this.setObjectAsync('vehicles', {\n\t\t\ttype: 'folder',\n\t\t\tcommon: { name: 'Vehicles' },\n\t\t\tnative: {},\n\t\t});\n\t\tawait this.setObjectNotExistsAsync('commands.refresh', {\n\t\t\ttype: 'state',\n\t\t\tcommon: {\n\t\t\t\tname: getRuntimeName('refresh'),\n\t\t\t\ttype: 'boolean',\n\t\t\t\trole: 'button',\n\t\t\t\tread: false,\n\t\t\t\twrite: true,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\t\tawait this.extendObjectAsync('commands.refresh', { common: { name: getRuntimeName('refresh') } });\n\t\tif (this.stopping) {\n\t\t\treturn;\n\t\t}\n\t\tawait this.setStateAsync('commands.refresh', { val: false, ack: true });\n\t\tif (this.stopping) {\n\t\t\treturn;\n\t\t}\n\t\tthis.subscribeStates('commands.refresh');\n\t\tawait this.setState('info.connection', false, true);\n\t\tawait this.setState('info.backend', config.region?.trim() || 'not configured', true);\n\t\tconst errors = validateConfig(config);\n\t\tawait this.setState('info.lastError', errors.join('; '), true);\n\t\tif (errors.length) {\n\t\t\tthis.log.warn(`Configuration is incomplete: ${errors.join('; ')}`);\n\t\t\treturn;\n\t\t}\n\n\t\tconst region = resolveSaicRegion(config.region ?? '');\n\t\tif (!region) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tthis.client = new SaicApiClient(\n\t\t\t\tundefined,\n\t\t\t\tDate.now,\n\t\t\t\tundefined,\n\t\t\t\tmessage => this.log.debug(message),\n\t\t\t\tundefined,\n\t\t\t\t{\n\t\t\t\t\tsetTimeout: (callback, milliseconds) => {\n\t\t\t\t\t\tconst timer = this.setTimeout(callback, milliseconds);\n\t\t\t\t\t\treturn () => {\n\t\t\t\t\t\t\tif (timer !== undefined) {\n\t\t\t\t\t\t\t\tthis.clearTimeout(timer);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t\tthis.loginOptions = {\n\t\t\t\t...region,\n\t\t\t\taccountType: config.accountType as 'email' | 'phone',\n\t\t\t\taccountIdentifier: config.accountIdentifier ?? '',\n\t\t\t\tphoneCountryCode: config.phoneCountryCode,\n\t\t\t\tpassword: config.password ?? '',\n\t\t\t};\n\t\t\tawait this.authenticate();\n\t\t\tif (this.stopping) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.vehicles = await this.client.listVehicles(\n\t\t\t\tthis.loginOptions,\n\t\t\t\tthis.accessToken!,\n\t\t\t\tthis.abortController.signal,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tif (this.stopping) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst details = error instanceof Error ? error.message : 'Unknown initialization error';\n\t\t\tconst message = `SAIC initialization failed: ${details}`;\n\t\t\tawait this.setState('info.connection', false, true);\n\t\t\tawait this.setState('info.lastError', message, true);\n\t\t\tthis.log.warn(message);\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tfor (const vehicle of this.vehicles) {\n\t\t\t\tif (this.stopping) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tawait this.createVehicleObjects(vehicle);\n\t\t\t\tif (!EXPOSE_SOURCE_STATUS_DATAPOINTS) {\n\t\t\t\t\tawait this.delObjectAsync(`vehicles.${vehicle.vin}.cachedStatus`, { recursive: true });\n\t\t\t\t}\n\t\t\t\tawait this.delObjectAsync(`vehicles.${vehicle.vin}.canonicalStatus`, { recursive: true });\n\t\t\t}\n\t\t\tawait this.setState('info.connection', true, true);\n\t\t\tthis.log.info(`SAIC account authenticated; discovered ${this.vehicles.length} vehicle(s).`);\n\t\t\tif (this.vehicles.length === 0) {\n\t\t\t\tawait this.setState('info.lastError', 'No vehicles are linked to this SAIC account', true);\n\t\t\t\tthis.log.warn('No vehicles are linked to this SAIC account.');\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tawait this.refreshVehicleStatuses();\n\t\t\tconst intervalSeconds = config.pollIntervalSeconds ?? DEFAULT_POLL_INTERVAL_SECONDS;\n\t\t\tif (!this.stopping) {\n\t\t\t\tthis.pollTimer = this.setInterval(() => this.triggerRefresh(), intervalSeconds * 1000);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (this.stopping) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst details = error instanceof Error ? error.message : 'Unknown local adapter error';\n\t\t\tawait this.setState('info.lastError', `Could not initialize vehicle objects: ${details}`, true);\n\t\t\tthis.log.error(`Could not initialize vehicle objects: ${details}`);\n\t\t}\n\t}\n\n\tprivate async authenticate(): Promise<void> {\n\t\tif (!this.client || !this.loginOptions || this.stopping) {\n\t\t\tthrow new Error('Adapter is stopping or not initialized');\n\t\t}\n\t\tconst login = await this.client.login(this.loginOptions, this.abortController.signal);\n\t\tif (this.stopping) {\n\t\t\treturn;\n\t\t}\n\t\tthis.accessToken = login.accessToken;\n\t\tthis.accessTokenExpiresAt = Date.now() + login.expiresIn * 1000;\n\t\tawait this.setState('info.connection', true, true);\n\t}\n\n\tprivate triggerRefresh(): void {\n\t\tvoid this.refreshVehicleStatuses().catch(error => {\n\t\t\tconst details = error instanceof Error ? error.message : 'Unknown refresh error';\n\t\t\tthis.log.error(`Vehicle status refresh failed: ${details}`);\n\t\t});\n\t}\n\n\tprivate async refreshVehicleStatuses(): Promise<void> {\n\t\tif (this.stopping || !this.client || !this.loginOptions || !this.accessToken) {\n\t\t\treturn;\n\t\t}\n\t\tif (this.pollInProgress) {\n\t\t\tthis.refreshQueued = true;\n\t\t\treturn;\n\t\t}\n\t\tthis.pollInProgress = true;\n\t\tconst statusErrors: string[] = [];\n\t\tlet followUpUsed = false;\n\t\ttry {\n\t\t\tdo {\n\t\t\t\tthis.refreshQueued = false;\n\t\t\t\tfor (const vehicle of this.vehicles) {\n\t\t\t\t\tif (this.stopping) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tif (Date.now() >= this.accessTokenExpiresAt - 60_000) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tawait this.authenticate();\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tif (this.stopping) {\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst details = error instanceof Error ? error.message : 'Unknown authentication error';\n\t\t\t\t\t\t\tstatusErrors.push(`SAIC re-authentication failed: ${details}`);\n\t\t\t\t\t\t\tawait this.setState('info.connection', false, true);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst charging = await this.client.getVehicleChargingStatus(\n\t\t\t\t\t\t\tthis.loginOptions,\n\t\t\t\t\t\t\tthis.accessToken,\n\t\t\t\t\t\t\tvehicle.vin,\n\t\t\t\t\t\t\tthis.abortController.signal,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tawait this.createVehicleChargingObjects(vehicle.vin, charging);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tif (this.stopping) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst details = error instanceof Error ? error.message : 'Unknown charging data error';\n\t\t\t\t\t\tstatusErrors.push(`Charging data request failed for ${vehicle.vin}: ${details}`);\n\t\t\t\t\t\tthis.log.warn(`Could not retrieve charging data for vehicle ${vehicle.vin}: ${details}`);\n\t\t\t\t\t}\n\t\t\t\t\tlet status: SaicVehicleStatus;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.log.debug(`Refreshing live status for ${vehicle.vin}`);\n\t\t\t\t\t\tstatus = await this.client.getVehicleStatus(\n\t\t\t\t\t\t\tthis.loginOptions,\n\t\t\t\t\t\t\tthis.accessToken,\n\t\t\t\t\t\t\tvehicle.vin,\n\t\t\t\t\t\t\tthis.abortController.signal,\n\t\t\t\t\t\t);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tif (this.stopping) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (error instanceof SaicHttpError && (error.status === 401 || error.status === 403)) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tawait this.authenticate();\n\t\t\t\t\t\t\t\tstatus = await this.client.getVehicleStatus(\n\t\t\t\t\t\t\t\t\tthis.loginOptions,\n\t\t\t\t\t\t\t\t\tthis.accessToken,\n\t\t\t\t\t\t\t\t\tvehicle.vin,\n\t\t\t\t\t\t\t\t\tthis.abortController.signal,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} catch (reauthError) {\n\t\t\t\t\t\t\t\tif (this.stopping) {\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tconst details =\n\t\t\t\t\t\t\t\t\treauthError instanceof Error ? reauthError.message : 'Unknown authentication error';\n\t\t\t\t\t\t\t\tstatusErrors.push(`SAIC re-authentication failed for ${vehicle.vin}: ${details}`);\n\t\t\t\t\t\t\t\tawait this.setState('info.connection', false, true);\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconst details = error instanceof Error ? error.message : 'Unknown error';\n\t\t\t\t\t\t\tconst diagnostic =\n\t\t\t\t\t\t\t\terror instanceof SaicRemoteInstructionError\n\t\t\t\t\t\t\t\t\t? `SAIC/MG returned remote instruction code 4 for ${vehicle.vin}; this is a response from the MG/SAIC service or vehicle, not an adapter parsing/processing error. SAIC message: ${details}`\n\t\t\t\t\t\t\t\t\t: details;\n\t\t\t\t\t\t\tstatusErrors.push(`Vehicle status request failed for ${vehicle.vin}: ${diagnostic}`);\n\t\t\t\t\t\t\tthis.log.warn(\n\t\t\t\t\t\t\t\t`Could not retrieve current status for vehicle ${vehicle.vin}: ${diagnostic}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tlet cachedStatus: SaicVehicleStatus;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tthis.log.debug(`Refreshing cached status as fallback for ${vehicle.vin}`);\n\t\t\t\t\t\t\t\tcachedStatus = await this.client.getCachedVehicleStatus(\n\t\t\t\t\t\t\t\t\tthis.loginOptions,\n\t\t\t\t\t\t\t\t\tthis.accessToken,\n\t\t\t\t\t\t\t\t\tvehicle.vin,\n\t\t\t\t\t\t\t\t\tthis.abortController.signal,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} catch (cacheError) {\n\t\t\t\t\t\t\t\tif (this.stopping) {\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tconst cacheDetails = cacheError instanceof Error ? cacheError.message : 'Unknown error';\n\t\t\t\t\t\t\t\tstatusErrors.push(\n\t\t\t\t\t\t\t\t\t`Cached vehicle status request failed for ${vehicle.vin}: ${cacheDetails}`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tthis.log.warn(\n\t\t\t\t\t\t\t\t\t`Could not retrieve cached status for vehicle ${vehicle.vin}: ${cacheDetails}`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tif (EXPOSE_SOURCE_STATUS_DATAPOINTS) {\n\t\t\t\t\t\t\t\t\tawait this.createVehicleStatusObjects(\n\t\t\t\t\t\t\t\t\t\tvehicle.vin,\n\t\t\t\t\t\t\t\t\t\tcachedStatus,\n\t\t\t\t\t\t\t\t\t\t'cachedStatus',\n\t\t\t\t\t\t\t\t\t\t'cachedStatus',\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tawait this.createCanonicalVehicleStatusObjects(vehicle.vin, cachedStatus, 'cached');\n\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\tconst writeDetails =\n\t\t\t\t\t\t\t\t\terror instanceof Error ? error.message : 'Unknown state write error';\n\t\t\t\t\t\t\t\tstatusErrors.push(`Could not write cached status for ${vehicle.vin}: ${writeDetails}`);\n\t\t\t\t\t\t\t\tthis.log.error(`Could not write cached status for ${vehicle.vin}: ${writeDetails}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (this.stopping) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tif (!isVehicleStatusNotOlder(status.statusTime, this.lastStatusTimes.get(vehicle.vin))) {\n\t\t\t\t\t\tstatusErrors.push(`Ignored older live status for ${vehicle.vin}`);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (status.basicVehicleStatus.mileage === undefined) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst cachedStatus = await this.client.getCachedVehicleStatus(\n\t\t\t\t\t\t\t\tthis.loginOptions,\n\t\t\t\t\t\t\t\tthis.accessToken,\n\t\t\t\t\t\t\t\tvehicle.vin,\n\t\t\t\t\t\t\t\tthis.abortController.signal,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tconst cachedMileage = cachedStatus.basicVehicleStatus.mileage;\n\t\t\t\t\t\t\tconst mileage = resolveOdometerValue(undefined, cachedMileage);\n\t\t\t\t\t\t\tif (mileage !== undefined) {\n\t\t\t\t\t\t\t\tstatus = {\n\t\t\t\t\t\t\t\t\t...status,\n\t\t\t\t\t\t\t\t\tbasicVehicleStatus: { ...status.basicVehicleStatus, mileage },\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tthis.log.debug(\n\t\t\t\t\t\t\t\t\t`Used cached odometer for ${vehicle.vin} because live status omitted mileage`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch (cacheError) {\n\t\t\t\t\t\t\tif (this.stopping) {\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst details = cacheError instanceof Error ? cacheError.message : 'Unknown cache error';\n\t\t\t\t\t\t\tthis.log.debug(`Could not retrieve cached odometer for ${vehicle.vin}: ${details}`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.log.debug(\n\t\t\t\t\t\t\t`Received live status for ${vehicle.vin}: ${Object.keys(status.basicVehicleStatus).length} basic fields, statusTime ${status.statusTime ?? 'missing'}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (EXPOSE_SOURCE_STATUS_DATAPOINTS) {\n\t\t\t\t\t\t\tawait this.createVehicleStatusObjects(vehicle.vin, status, 'liveStatus', 'liveStatus');\n\t\t\t\t\t\t}\n\t\t\t\t\t\tawait this.createCanonicalVehicleStatusObjects(vehicle.vin, status, 'live');\n\t\t\t\t\t\tif (!this.stopping && status.statusTime !== undefined) {\n\t\t\t\t\t\t\tthis.lastStatusTimes.set(vehicle.vin, status.statusTime);\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tisVehicleStatusNotOlder(\n\t\t\t\t\t\t\t\t\tstatus.statusTime,\n\t\t\t\t\t\t\t\t\tthis.lastCanonicalStatusTimes.get(vehicle.vin),\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tthis.lastCanonicalStatusTimes.set(vehicle.vin, status.statusTime);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.log.debug(`Created/updated live status objects for ${vehicle.vin}`);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tconst details = error instanceof Error ? error.message : 'Unknown state write error';\n\t\t\t\t\t\tstatusErrors.push(`Could not write live status for ${vehicle.vin}: ${details}`);\n\t\t\t\t\t\tthis.log.error(`Could not write live status for ${vehicle.vin}: ${details}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (this.refreshQueued && followUpUsed) {\n\t\t\t\t\tthis.refreshQueued = false;\n\t\t\t\t} else if (this.refreshQueued) {\n\t\t\t\t\tfollowUpUsed = true;\n\t\t\t\t}\n\t\t\t} while (this.refreshQueued && !this.stopping);\n\t\t\tif (!this.stopping) {\n\t\t\t\tawait this.setState('info.lastError', statusErrors.join('; '), true);\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.pollInProgress = false;\n\t\t}\n\t}\n\n\tprivate onStateChange(id: string, state: ioBroker.State | null | undefined): void {\n\t\tif (this.stopping) {\n\t\t\treturn;\n\t\t}\n\t\tif (isRefreshCommand(id, this.namespace, state)) {\n\t\t\tvoid this.setStateAsync('commands.refresh', { val: false, ack: true }).catch(error => {\n\t\t\t\tconst details = error instanceof Error ? error.message : 'Unknown state error';\n\t\t\t\tthis.log.error(`Could not acknowledge refresh command: ${details}`);\n\t\t\t});\n\t\t\tthis.triggerRefresh();\n\t\t\treturn;\n\t\t}\n\t\tif (!state || state.ack) {\n\t\t\treturn;\n\t\t}\n\t\tconst settingAction = settingActions.find(({ id: actionId }) =>\n\t\t\tthis.vehicles.some(({ vin }) => id === `${this.namespace}.${vehicleCommandPath(vin, actionId)}`),\n\t\t);\n\t\tconst settingVehicle = this.vehicles.find(\n\t\t\t({ vin }) => settingAction && id === `${this.namespace}.${vehicleCommandPath(vin, settingAction.id)}`,\n\t\t);\n\t\tif (settingAction && settingVehicle) {\n\t\t\tvoid this.executeVehicleSetting(settingVehicle.vin, settingAction.id);\n\t\t\treturn;\n\t\t}\n\t\tconst settingInput = this.vehicles\n\t\t\t.flatMap(({ vin }) =>\n\t\t\t\tObject.keys(settingGroups)\n\t\t\t\t\t.filter(stateId => stateId !== 'driverSeatHeatLevel' && stateId !== 'passengerSeatHeatLevel')\n\t\t\t\t\t.map(stateId => ({ vin, stateId })),\n\t\t\t)\n\t\t\t.find(({ vin, stateId }) => id === `${this.namespace}.${vehicleCommandPath(vin, stateId)}`);\n\t\tif (settingInput) {\n\t\t\tvoid this.setStateAsync(vehicleCommandPath(settingInput.vin, settingInput.stateId), {\n\t\t\t\tval: state.val,\n\t\t\t\tack: true,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tconst seatHeating = this.vehicles\n\t\t\t.flatMap(({ vin }) =>\n\t\t\t\t(['driverSeatHeatLevel', 'passengerSeatHeatLevel'] as const).map(stateId => ({ vin, stateId })),\n\t\t\t)\n\t\t\t.find(({ vin, stateId }) => id === `${this.namespace}.${vehicleCommandPath(vin, stateId)}`);\n\t\tif (seatHeating) {\n\t\t\tconst seat = seatHeating.stateId === 'driverSeatHeatLevel' ? 'driver' : 'passenger';\n\t\t\tvoid this.executeSeatHeating(seatHeating.vin, seat, state.val);\n\t\t\treturn;\n\t\t}\n\t\tif (state.val !== true) {\n\t\t\treturn;\n\t\t}\n\t\tconst commandEntry = vehicleCommands.find(({ id: commandId }) =>\n\t\t\tthis.vehicles.some(({ vin }) => id === `${this.namespace}.${vehicleCommandPath(vin, commandId)}`),\n\t\t);\n\t\tconst vehicle = this.vehicles.find(\n\t\t\t({ vin }) => commandEntry && id === `${this.namespace}.${vehicleCommandPath(vin, commandEntry.id)}`,\n\t\t);\n\t\tif (!commandEntry || !vehicle) {\n\t\t\treturn;\n\t\t}\n\t\tvoid this.executeVehicleCommand(vehicle.vin, commandEntry.id);\n\t}\n\n\tprivate async executeSeatHeating(\n\t\tvin: string,\n\t\tseat: 'driver' | 'passenger',\n\t\tvalue: ioBroker.StateValue,\n\t): Promise<void> {\n\t\tconst stateId = vehicleCommandPath(vin, `${seat}SeatHeatLevel`);\n\t\tif (typeof value !== 'number' || !Number.isInteger(value) || value < 0 || value > 3) {\n\t\t\tawait this.setStateAsync(stateId, { ack: true });\n\t\t\tthis.log.warn(`Ignored ${seat} seat heating level for ${vin}: expected an integer from 0 to 3`);\n\t\t\treturn;\n\t\t}\n\t\tif (this.vehicleCommandsInProgress.has(vin)) {\n\t\t\tawait this.setStateAsync(stateId, { ack: true });\n\t\t\tthis.log.warn(`Ignored ${seat} seat heating for ${vin}: another vehicle command is still running`);\n\t\t\treturn;\n\t\t}\n\t\tthis.vehicleCommandsInProgress.add(vin);\n\t\ttry {\n\t\t\tif (!this.client || !this.loginOptions) {\n\t\t\t\tthrow new Error('SAIC client is not initialized');\n\t\t\t}\n\t\t\tif (!this.accessToken || this.accessTokenExpiresAt <= Date.now() + 30_000) {\n\t\t\t\tawait this.authenticate();\n\t\t\t}\n\t\t\tawait this.client.sendVehicleSeatHeating(\n\t\t\t\tthis.loginOptions,\n\t\t\t\tthis.accessToken!,\n\t\t\t\tvin,\n\t\t\t\tseat,\n\t\t\t\tvalue,\n\t\t\t\tthis.abortController.signal,\n\t\t\t);\n\t\t\tawait this.setStateAsync(stateId, { val: value, ack: true });\n\t\t\tthis.log.info(`SAIC ${seat} seat heating level ${value} completed for ${vin}`);\n\t\t} catch (error) {\n\t\t\tif (!this.stopping) {\n\t\t\t\tawait this.setStateAsync(stateId, { val: value, ack: true });\n\t\t\t\tconst details = error instanceof Error ? error.message : 'Unknown command error';\n\t\t\t\tthis.log.warn(`SAIC ${seat} seat heating failed for ${vin}: ${details}`);\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.vehicleCommandsInProgress.delete(vin);\n\t\t}\n\t}\n\n\tprivate async executeVehicleSetting(vin: string, action: SettingAction): Promise<void> {\n\t\tconst stateId = vehicleCommandPath(vin, action);\n\t\tif (this.vehicleCommandsInProgress.has(vin)) {\n\t\t\tawait this.setStateAsync(stateId, { val: false, ack: true });\n\t\t\tthis.log.warn(`Ignored ${action} for ${vin}: another vehicle command is still running`);\n\t\t\treturn;\n\t\t}\n\t\tthis.vehicleCommandsInProgress.add(vin);\n\t\ttry {\n\t\t\tawait this.setStateAsync(stateId, { val: false, ack: true });\n\t\t\tif (!this.client || !this.loginOptions) {\n\t\t\t\tthrow new Error('SAIC client is not initialized');\n\t\t\t}\n\t\t\tconst setting = await this.readVehicleSetting(vin, action);\n\t\t\tif (!this.accessToken || this.accessTokenExpiresAt <= Date.now() + 30_000) {\n\t\t\t\tawait this.authenticate();\n\t\t\t}\n\t\t\tawait this.client.sendVehicleSetting(\n\t\t\t\tthis.loginOptions,\n\t\t\t\tthis.accessToken!,\n\t\t\t\tvin,\n\t\t\t\tsetting,\n\t\t\t\tthis.abortController.signal,\n\t\t\t);\n\t\t\tthis.log.info(`SAIC ${action} completed for ${vin}`);\n\t\t} catch (error) {\n\t\t\tif (!this.stopping) {\n\t\t\t\tconst details = error instanceof Error ? error.message : 'Unknown settings error';\n\t\t\t\tthis.log.warn(`SAIC ${action} failed for ${vin}: ${details}`);\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.vehicleCommandsInProgress.delete(vin);\n\t\t}\n\t}\n\n\tprivate async readVehicleSetting(vin: string, action: SettingAction): Promise<SaicVehicleSetting> {\n\t\tconst readNumber = async (id: string): Promise<number> => {\n\t\t\tconst state = await this.getStateAsync(vehicleCommandPath(vin, id));\n\t\t\tif (!state || typeof state.val !== 'number' || !Number.isFinite(state.val)) {\n\t\t\t\tthrow new Error(`Setting ${id} must contain a finite number`);\n\t\t\t}\n\t\t\treturn state.val;\n\t\t};\n\t\tconst readString = async (id: string): Promise<string> => {\n\t\t\tconst state = await this.getStateAsync(vehicleCommandPath(vin, id));\n\t\t\tif (!state || typeof state.val !== 'string') {\n\t\t\t\tthrow new Error(`Setting ${id} must contain a time in HH:MM format`);\n\t\t\t}\n\t\t\treturn state.val;\n\t\t};\n\t\tif (action === 'climateTemperatureApply') {\n\t\t\tconst vehicle = this.vehicles.find(item => item.vin === vin);\n\t\t\treturn {\n\t\t\t\ttype: 'climateTemperature',\n\t\t\t\tvalue: climateTemperatureToIndex(await readNumber('climateTemperature'), vehicle?.series),\n\t\t\t};\n\t\t}\n\t\tif (action === 'chargingSettingsApply') {\n\t\t\treturn {\n\t\t\t\ttype: 'chargingSettings',\n\t\t\t\ttargetSoc: targetSocPercentToCode(await readNumber('chargeTargetSoc')),\n\t\t\t\tcurrentLimit: await readNumber('chargingCurrentLimit'),\n\t\t\t};\n\t\t}\n\t\tif (action === 'chargingScheduleApply') {\n\t\t\treturn {\n\t\t\t\ttype: 'chargingSchedule',\n\t\t\t\tstart: await readString('chargingScheduleStart'),\n\t\t\t\tend: await readString('chargingScheduleEnd'),\n\t\t\t\tmode: await readNumber('chargingScheduleMode'),\n\t\t\t};\n\t\t}\n\t\tconst enabled = await this.getStateAsync(vehicleCommandPath(vin, 'batteryHeatingScheduleEnabled'));\n\t\tif (!enabled || typeof enabled.val !== 'boolean') {\n\t\t\tthrow new Error('Battery heating schedule enabled must be boolean');\n\t\t}\n\t\treturn {\n\t\t\ttype: 'batteryHeatingSchedule',\n\t\t\tenabled: enabled.val,\n\t\t\tstart: await readString('batteryHeatingScheduleStart'),\n\t\t};\n\t}\n\n\tprivate async executeVehicleCommand(vin: string, command: SaicVehicleCommand): Promise<void> {\n\t\tconst stateId = vehicleCommandPath(vin, command);\n\t\tif (this.vehicleCommandsInProgress.has(vin)) {\n\t\t\tawait this.setStateAsync(stateId, { val: false, ack: true });\n\t\t\tthis.log.warn(`Ignored ${command} command for ${vin}: another vehicle command is still running`);\n\t\t\treturn;\n\t\t}\n\t\tthis.vehicleCommandsInProgress.add(vin);\n\t\ttry {\n\t\t\tawait this.setStateAsync(stateId, { val: false, ack: true });\n\t\t\tif (!this.client || !this.loginOptions) {\n\t\t\t\tthrow new Error('SAIC client is not initialized');\n\t\t\t}\n\t\t\tif (!this.accessToken || this.accessTokenExpiresAt <= Date.now() + 30_000) {\n\t\t\t\tawait this.authenticate();\n\t\t\t}\n\t\t\tawait this.client.sendVehicleCommand(\n\t\t\t\tthis.loginOptions,\n\t\t\t\tthis.accessToken!,\n\t\t\t\tvin,\n\t\t\t\tcommand,\n\t\t\t\tthis.abortController.signal,\n\t\t\t);\n\t\t\tthis.log.info(`SAIC ${command} command completed for ${vin}`);\n\t\t} catch (error) {\n\t\t\tif (!this.stopping) {\n\t\t\t\tconst details = error instanceof Error ? error.message : 'Unknown command error';\n\t\t\t\tthis.log.warn(`SAIC ${command} command failed for ${vin}: ${details}`);\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.vehicleCommandsInProgress.delete(vin);\n\t\t}\n\t}\n\n\tprivate async createVehicleStatusObjects(\n\t\tvin: string,\n\t\tstatus: SaicVehicleStatus,\n\t\tchannel = 'status',\n\t\tchannelName = 'currentStatus',\n\t): Promise<void> {\n\t\tif (this.stopping) {\n\t\t\treturn;\n\t\t}\n\t\tif (!EXPOSE_SOURCE_STATUS_DATAPOINTS && (channel === 'liveStatus' || channel === 'cachedStatus')) {\n\t\t\treturn;\n\t\t}\n\t\tconst statusId = `vehicles.${vin}.${channel}`;\n\t\tawait this.setObjectNotExistsAsync(statusId, {\n\t\t\ttype: 'channel',\n\t\t\tcommon: { name: getRuntimeName(channelName) },\n\t\t\tnative: {},\n\t\t});\n\t\tawait this.extendObjectAsync(statusId, { common: { name: getRuntimeName(channelName) } });\n\t\tif (this.stopping) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst values: Record<string, number | undefined> = { ...status.basicVehicleStatus };\n\t\tif (status.statusTime !== undefined) {\n\t\t\tvalues.statusTime = status.statusTime;\n\t\t}\n\t\tif (status.onlineStatus !== undefined) {\n\t\t\tvalues.onlineStatus = status.onlineStatus;\n\t\t}\n\t\tthis.log.debug(`Writing ${Object.keys(values).length} values under ${statusId}`);\n\t\tfor (const [key, value] of Object.entries(values)) {\n\t\t\tif (this.stopping) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst group = getVehicleStatusGroup(key);\n\t\t\tconst groupId = `${statusId}.${group}`;\n\t\t\tconst stateId = `${groupId}.${key}`;\n\t\t\tif (value === undefined) {\n\t\t\t\tif (shouldDeleteUnavailableStatusValue(key)) {\n\t\t\t\t\tawait this.delObjectAsync(stateId);\n\t\t\t\t} else {\n\t\t\t\t\tconst previousState = await this.getStateAsync(stateId);\n\t\t\t\t\tif (previousState?.val === null) {\n\t\t\t\t\t\tawait this.delObjectAsync(stateId);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tawait this.setObjectNotExistsAsync(groupId, {\n\t\t\t\ttype: 'channel',\n\t\t\t\tcommon: { name: getRuntimeName(group) },\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tawait this.extendObjectAsync(groupId, { common: { name: getRuntimeName(group) } });\n\t\t\tif (this.stopping) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst metadata = getVehicleStatusMetadata(key);\n\t\t\tconst common = {\n\t\t\t\tname: metadata.name,\n\t\t\t\ttype: metadata.type,\n\t\t\t\trole: metadata.role,\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t\t...(metadata.unit ? { unit: metadata.unit } : {}),\n\t\t\t};\n\t\t\tawait this.setObjectNotExistsAsync(stateId, {\n\t\t\t\ttype: 'state',\n\t\t\t\tcommon,\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tif (this.stopping) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait this.extendObjectAsync(stateId, {\n\t\t\t\ttype: 'state',\n\t\t\t\tcommon,\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tif (this.stopping) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait this.setStateAsync(stateId, { val: normalizeVehicleStatusValue(key, value), ack: true });\n\t\t\tif (this.stopping) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait this.delObjectAsync(`${statusId}.${key}`);\n\t\t}\n\t}\n\n\tprivate async createVehicleChargingObjects(vin: string, charging: SaicChargingStatus): Promise<void> {\n\t\tawait this.ensureVehicleChargingGroups(vin);\n\t\tconst rootId = `vehicles.${vin}.status.charging`;\n\t\tfor (const { source, id } of chargingGroups) {\n\t\t\tconst groupId = `${rootId}.${id}`;\n\t\t\tfor (const [field, value] of Object.entries(charging[source])) {\n\t\t\t\tif (this.stopping) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst stateId = `${groupId}.${field}`;\n\t\t\t\tif (value === undefined) {\n\t\t\t\t\tawait this.delObjectAsync(stateId);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst metadata = getChargingFieldMetadata(field);\n\t\t\t\tconst common: ioBroker.StateCommon = {\n\t\t\t\t\tname: getChargingFieldName(field),\n\t\t\t\t\ttype: metadata.type === 'boolean' ? 'boolean' : typeof value === 'string' ? 'string' : 'number',\n\t\t\t\t\trole: typeof value === 'string' ? 'text' : metadata.role,\n\t\t\t\t\tread: true,\n\t\t\t\t\twrite: false,\n\t\t\t\t};\n\t\t\t\tif (metadata.unit) {\n\t\t\t\t\tcommon.unit = metadata.unit;\n\t\t\t\t}\n\t\t\t\tawait this.setObjectNotExistsAsync(stateId, { type: 'state', common, native: {} });\n\t\t\t\tawait this.extendObjectAsync(stateId, { common });\n\t\t\t\tawait this.setStateAsync(stateId, {\n\t\t\t\t\tval: normalizeChargingValue(field, value),\n\t\t\t\t\tack: true,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tawait this.delObjectAsync(`vehicles.${vin}.charging`, { recursive: true });\n\t}\n\n\tprivate async ensureVehicleChargingGroups(vin: string): Promise<void> {\n\t\tconst statusId = `vehicles.${vin}.status`;\n\t\tconst rootId = `${statusId}.charging`;\n\t\tawait this.setObjectNotExistsAsync(statusId, {\n\t\t\ttype: 'channel',\n\t\t\tcommon: { name: getRuntimeName('currentStatus') },\n\t\t\tnative: {},\n\t\t});\n\t\tawait this.setObjectNotExistsAsync(rootId, {\n\t\t\ttype: 'channel',\n\t\t\tcommon: { name: getRuntimeName('commandGroup_charging') },\n\t\t\tnative: {},\n\t\t});\n\t\tawait this.extendObjectAsync(rootId, { common: { name: getRuntimeName('commandGroup_charging') } });\n\t\tfor (const { source, id, name } of chargingGroups) {\n\t\t\tconst groupId = `${rootId}.${id}`;\n\t\t\tconst groupName = getRuntimeName(name);\n\t\t\tawait this.setObjectNotExistsAsync(groupId, {\n\t\t\t\ttype: 'channel',\n\t\t\t\tcommon: { name: groupName },\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tawait this.extendObjectAsync(groupId, { common: { name: groupName } });\n\t\t\tawait this.delObjectAsync(`${rootId}.${source}`, { recursive: true });\n\t\t}\n\t}\n\n\tprivate async createCanonicalVehicleStatusObjects(\n\t\tvin: string,\n\t\tstatus: SaicVehicleStatus,\n\t\tsource: 'live' | 'cached',\n\t): Promise<void> {\n\t\tif (this.stopping || !isVehicleStatusNotOlder(status.statusTime, this.lastCanonicalStatusTimes.get(vin))) {\n\t\t\treturn;\n\t\t}\n\t\tawait this.createVehicleStatusObjects(vin, status);\n\t\tif (this.stopping) {\n\t\t\treturn;\n\t\t}\n\t\tconst sourceId = `vehicles.${vin}.status.source`;\n\t\tawait this.setObjectNotExistsAsync(sourceId, {\n\t\t\ttype: 'state',\n\t\t\tcommon: { name: getRuntimeName('statusSource'), type: 'string', role: 'text', read: true, write: false },\n\t\t\tnative: {},\n\t\t});\n\t\tawait this.extendObjectAsync(sourceId, { common: { name: getRuntimeName('statusSource') } });\n\t\tif (this.stopping) {\n\t\t\treturn;\n\t\t}\n\t\tawait this.setStateAsync(sourceId, { val: source, ack: true });\n\t\tif (status.statusTime !== undefined) {\n\t\t\tconst sourceTimestampId = `vehicles.${vin}.status.sourceTimestamp`;\n\t\t\tawait this.setObjectNotExistsAsync(sourceTimestampId, {\n\t\t\t\ttype: 'state',\n\t\t\t\tcommon: {\n\t\t\t\t\tname: getRuntimeName('statusSourceTimestamp'),\n\t\t\t\t\ttype: 'number',\n\t\t\t\t\trole: 'date',\n\t\t\t\t\tread: true,\n\t\t\t\t\twrite: false,\n\t\t\t\t},\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tawait this.extendObjectAsync(sourceTimestampId, {\n\t\t\t\tcommon: { name: getRuntimeName('statusSourceTimestamp') },\n\t\t\t});\n\t\t\tawait this.setStateAsync(sourceTimestampId, { val: status.statusTime * 1000, ack: true });\n\t\t\tthis.lastCanonicalStatusTimes.set(vin, status.statusTime);\n\t\t}\n\t}\n\n\tprivate async createVehicleObjects(vehicle: SaicVehicle): Promise<void> {\n\t\tif (this.stopping) {\n\t\t\treturn;\n\t\t}\n\t\tconst deviceId = `vehicles.${vehicle.vin}`;\n\t\tconst values: Record<string, string | boolean | undefined> = {\n\t\t\tvin: vehicle.vin,\n\t\t\tname: vehicle.name,\n\t\t\tbrandName: vehicle.brandName,\n\t\t\tmodelName: vehicle.modelName,\n\t\t\tseries: vehicle.series,\n\t\t\tmodelYear: vehicle.modelYear,\n\t\t\tcolorName: vehicle.colorName,\n\t\t\tisCurrentVehicle: vehicle.isCurrentVehicle,\n\t\t\tisSubaccount: vehicle.isSubaccount,\n\t\t};\n\n\t\tawait this.setObjectNotExistsAsync(deviceId, {\n\t\t\ttype: 'device',\n\t\t\tcommon: { name: vehicle.name || vehicle.modelName || vehicle.vin },\n\t\t\tnative: {},\n\t\t});\n\t\tif (this.stopping) {\n\t\t\treturn;\n\t\t}\n\t\tawait this.ensureVehicleChargingGroups(vehicle.vin);\n\t\tconst commandsId = `${deviceId}.commands`;\n\t\tawait this.setObjectNotExistsAsync(commandsId, {\n\t\t\ttype: 'channel',\n\t\t\tcommon: { name: getRuntimeName('commands') },\n\t\t\tnative: {},\n\t\t});\n\t\tawait this.extendObjectAsync(commandsId, { common: { name: getRuntimeName('commands') } });\n\t\tfor (const group of ['access', 'climate', 'heating', 'charging', 'schedules', 'vehicle']) {\n\t\t\tconst groupId = `${commandsId}.${group}`;\n\t\t\tconst groupName = getRuntimeName(`commandGroup_${group}`);\n\t\t\tawait this.setObjectNotExistsAsync(groupId, {\n\t\t\t\ttype: 'channel',\n\t\t\t\tcommon: { name: groupName },\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tawait this.extendObjectAsync(groupId, { common: { name: groupName } });\n\t\t}\n\t\tfor (const command of vehicleCommands) {\n\t\t\tconst commandId = vehicleCommandPath(vehicle.vin, command.id);\n\t\t\tawait this.setObjectNotExistsAsync(commandId, {\n\t\t\t\ttype: 'state',\n\t\t\t\tcommon: {\n\t\t\t\t\tname: getRuntimeName(command.id),\n\t\t\t\t\ttype: 'boolean',\n\t\t\t\t\trole: 'button',\n\t\t\t\t\tread: false,\n\t\t\t\t\twrite: true,\n\t\t\t\t},\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tawait this.extendObjectAsync(commandId, {\n\t\t\t\tcommon: { name: getRuntimeName(command.id) },\n\t\t\t});\n\t\t\tawait this.setStateAsync(commandId, { val: false, ack: true });\n\t\t}\n\t\tconst settingStates: Array<{\n\t\t\tid: string;\n\t\t\ttype: 'number' | 'string' | 'boolean';\n\t\t\trole: string;\n\t\t\tdef: number | string | boolean;\n\t\t\tmin?: number;\n\t\t\tmax?: number;\n\t\t\tstep?: number;\n\t\t\tunit?: string;\n\t\t\tstates?: Record<string, string>;\n\t\t}> = [\n\t\t\t{\n\t\t\t\tid: 'driverSeatHeatLevel',\n\t\t\t\ttype: 'number',\n\t\t\t\trole: 'level',\n\t\t\t\tdef: 0,\n\t\t\t\tmin: 0,\n\t\t\t\tmax: 3,\n\t\t\t\tstates: { 0: 'Off', 1: 'Low', 2: 'Medium', 3: 'High' },\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'passengerSeatHeatLevel',\n\t\t\t\ttype: 'number',\n\t\t\t\trole: 'level',\n\t\t\t\tdef: 0,\n\t\t\t\tmin: 0,\n\t\t\t\tmax: 3,\n\t\t\t\tstates: { 0: 'Off', 1: 'Low', 2: 'Medium', 3: 'High' },\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'climateTemperature',\n\t\t\t\ttype: 'number',\n\t\t\t\trole: 'level.temperature',\n\t\t\t\tdef: 22,\n\t\t\t\tmin: getClimateTemperatureRange(vehicle.series).min,\n\t\t\t\tmax: getClimateTemperatureRange(vehicle.series).max,\n\t\t\t\tunit: '\u00B0C',\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'chargeTargetSoc',\n\t\t\t\ttype: 'number',\n\t\t\t\trole: 'level',\n\t\t\t\tdef: 80,\n\t\t\t\tmin: 40,\n\t\t\t\tmax: 100,\n\t\t\t\tstep: 10,\n\t\t\t\tunit: '%',\n\t\t\t\tstates: { 40: '40%', 50: '50%', 60: '60%', 70: '70%', 80: '80%', 90: '90%', 100: '100%' },\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'chargingCurrentLimit',\n\t\t\t\ttype: 'number',\n\t\t\t\trole: 'level',\n\t\t\t\tdef: 4,\n\t\t\t\tmin: 1,\n\t\t\t\tmax: 4,\n\t\t\t\tstates: { 1: '6 A', 2: '8 A', 3: '16 A', 4: 'Maximum' },\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'chargingScheduleStart',\n\t\t\t\ttype: 'string',\n\t\t\t\trole: 'text',\n\t\t\t\tdef: '00:00',\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'chargingScheduleEnd',\n\t\t\t\ttype: 'string',\n\t\t\t\trole: 'text',\n\t\t\t\tdef: '06:00',\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'chargingScheduleMode',\n\t\t\t\ttype: 'number',\n\t\t\t\trole: 'level',\n\t\t\t\tdef: 2,\n\t\t\t\tmin: 1,\n\t\t\t\tmax: 3,\n\t\t\t\tstates: { 1: 'Until configured time', 2: 'Disabled', 3: 'Until configured SOC' },\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'batteryHeatingScheduleEnabled',\n\t\t\t\ttype: 'boolean',\n\t\t\t\trole: 'switch',\n\t\t\t\tdef: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'batteryHeatingScheduleStart',\n\t\t\t\ttype: 'string',\n\t\t\t\trole: 'text',\n\t\t\t\tdef: '00:00',\n\t\t\t},\n\t\t];\n\t\tfor (const setting of settingStates) {\n\t\t\tconst stateId = vehicleCommandPath(vehicle.vin, setting.id);\n\t\t\tconst legacyStateId = `${commandsId}.${setting.id}`;\n\t\t\tconst stateObject = await this.getObjectAsync(stateId);\n\t\t\tconst legacyState = await this.getStateAsync(legacyStateId);\n\t\t\tconst previousScheduleState = setting.id.startsWith('chargingSchedule')\n\t\t\t\t? await this.getStateAsync(`${commandsId}.schedules.${setting.id}`)\n\t\t\t\t: null;\n\t\t\tawait this.setObjectNotExistsAsync(stateId, {\n\t\t\t\ttype: 'state',\n\t\t\t\tcommon: {\n\t\t\t\t\tname: getRuntimeName(setting.id),\n\t\t\t\t\ttype: setting.type,\n\t\t\t\t\trole: setting.role,\n\t\t\t\t\tread: true,\n\t\t\t\t\twrite: true,\n\t\t\t\t\tdef: setting.def,\n\t\t\t\t\t...(setting.min === undefined ? {} : { min: setting.min }),\n\t\t\t\t\t...(setting.max === undefined ? {} : { max: setting.max }),\n\t\t\t\t\t...(setting.step === undefined ? {} : { step: setting.step }),\n\t\t\t\t\t...(setting.unit === undefined ? {} : { unit: setting.unit }),\n\t\t\t\t\t...(setting.states ? { states: setting.states } : {}),\n\t\t\t\t},\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tconst currentState = await this.getStateAsync(stateId);\n\t\t\tif (!currentState || currentState.val === null) {\n\t\t\t\tawait this.setStateAsync(stateId, {\n\t\t\t\t\tval: legacyState?.val ?? previousScheduleState?.val ?? setting.def,\n\t\t\t\t\tack: true,\n\t\t\t\t});\n\t\t\t} else if (typeof currentState.val === 'number' && stateObject?.common.unit !== setting.unit) {\n\t\t\t\tif (setting.id === 'chargeTargetSoc' && currentState.val >= 1 && currentState.val <= 7) {\n\t\t\t\t\tawait this.setStateAsync(stateId, { val: (currentState.val + 3) * 10, ack: true });\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait this.extendObjectAsync(stateId, {\n\t\t\t\tcommon: {\n\t\t\t\t\tname: getRuntimeName(setting.id),\n\t\t\t\t\ttype: setting.type,\n\t\t\t\t\trole: setting.role,\n\t\t\t\t\tread: true,\n\t\t\t\t\twrite: true,\n\t\t\t\t\tdef: setting.def,\n\t\t\t\t\t...(setting.min === undefined ? {} : { min: setting.min }),\n\t\t\t\t\t...(setting.max === undefined ? {} : { max: setting.max }),\n\t\t\t\t\t...(setting.step === undefined ? {} : { step: setting.step }),\n\t\t\t\t\t...(setting.unit === undefined ? {} : { unit: setting.unit }),\n\t\t\t\t\t...(setting.states ? { states: setting.states } : {}),\n\t\t\t\t},\n\t\t\t});\n\t\t\tawait this.delObjectAsync(legacyStateId);\n\t\t}\n\t\tfor (const action of settingActions) {\n\t\t\tconst actionId = vehicleCommandPath(vehicle.vin, action.id);\n\t\t\tawait this.setObjectNotExistsAsync(actionId, {\n\t\t\t\ttype: 'state',\n\t\t\t\tcommon: { name: getRuntimeName(action.id), type: 'boolean', role: 'button', read: false, write: true },\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tawait this.extendObjectAsync(actionId, {\n\t\t\t\tcommon: { name: getRuntimeName(action.id) },\n\t\t\t});\n\t\t\tawait this.setStateAsync(actionId, { val: false, ack: true });\n\t\t\tawait this.delObjectAsync(`${commandsId}.${action.id}`);\n\t\t}\n\t\tfor (const id of [\n\t\t\t'chargingScheduleStart',\n\t\t\t'chargingScheduleEnd',\n\t\t\t'chargingScheduleMode',\n\t\t\t'chargingScheduleApply',\n\t\t]) {\n\t\t\tawait this.delObjectAsync(`${commandsId}.schedules.${id}`);\n\t\t}\n\t\tfor (const command of vehicleCommands) {\n\t\t\tawait this.delObjectAsync(`${commandsId}.${command.id}`);\n\t\t}\n\t\tthis.subscribeStates(`${commandsId}.*`);\n\t\tif (this.stopping) {\n\t\t\treturn;\n\t\t}\n\t\tfor (const [key, value] of Object.entries(values)) {\n\t\t\tif (this.stopping) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (value === undefined) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst isBoolean = typeof value === 'boolean';\n\t\t\tconst name = getRuntimeName(key);\n\t\t\tawait this.setObjectNotExistsAsync(`${deviceId}.${key}`, {\n\t\t\t\ttype: 'state',\n\t\t\t\tcommon: {\n\t\t\t\t\tname,\n\t\t\t\t\ttype: isBoolean ? 'boolean' : 'string',\n\t\t\t\t\trole: isBoolean ? 'indicator' : key === 'vin' ? 'text' : 'info.name',\n\t\t\t\t\tread: true,\n\t\t\t\t\twrite: false,\n\t\t\t\t},\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tawait this.extendObjectAsync(`${deviceId}.${key}`, { common: { name } });\n\t\t\tif (this.stopping) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait this.setStateAsync(`${deviceId}.${key}`, { val: value, ack: true });\n\t\t}\n\t}\n\n\tprivate onUnload(callback: () => void): void {\n\t\tif (this.unloadCallbackCalled) {\n\t\t\treturn;\n\t\t}\n\t\tthis.unloadCallbackCalled = true;\n\t\tthis.stopping = true;\n\t\tthis.abortController.abort(new DOMException('Adapter is stopping', 'AbortError'));\n\t\tthis.refreshQueued = false;\n\t\tif (this.pollTimer) {\n\t\t\tthis.clearInterval(this.pollTimer);\n\t\t}\n\t\tcallback();\n\t}\n}\nif (require.main !== module) {\n\t// Export the constructor in compact mode\n\tmodule.exports = (options: Partial<utils.AdapterOptions> | undefined) => new MgSaic(options);\n} else {\n\t// otherwise start the instance directly\n\t(() => new MgSaic())();\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["error"]
|
|
7
7
|
}
|