@aigne/afs-tesla 1.11.0-beta.12

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.
@@ -0,0 +1,1720 @@
1
+ const require_auth = require('./auth.cjs');
2
+ const require_client = require('./client.cjs');
3
+ const require_decorate = require('./_virtual/_@oxc-project_runtime@0.108.0/helpers/decorate.cjs');
4
+ let _aigne_afs = require("@aigne/afs");
5
+ let _aigne_afs_provider = require("@aigne/afs/provider");
6
+ let ufo = require("ufo");
7
+ let zod = require("zod");
8
+
9
+ //#region src/tesla-provider.ts
10
+ const afsTeslaOptionsSchema = zod.z.object({
11
+ name: zod.z.string().default("tesla"),
12
+ description: zod.z.string().optional(),
13
+ clientId: zod.z.string(),
14
+ clientSecret: zod.z.string(),
15
+ redirectUri: zod.z.string().default("https://localhost:8443/callback"),
16
+ region: zod.z.enum([
17
+ "na",
18
+ "eu",
19
+ "cn"
20
+ ]).default("na"),
21
+ cacheTtl: zod.z.number().default(60),
22
+ cacheTtlStatic: zod.z.number().default(300),
23
+ autoWake: zod.z.boolean().default(false),
24
+ _testToken: zod.z.string().optional(),
25
+ _testBaseUrl: zod.z.string().optional()
26
+ });
27
+ const VEHICLE_ACTIONS = [
28
+ {
29
+ name: "wake",
30
+ severity: "boundary",
31
+ description: "Wake vehicle"
32
+ },
33
+ {
34
+ name: "lock",
35
+ severity: "boundary",
36
+ description: "Lock doors"
37
+ },
38
+ {
39
+ name: "unlock",
40
+ severity: "critical",
41
+ description: "Unlock doors"
42
+ },
43
+ {
44
+ name: "trunk",
45
+ severity: "boundary",
46
+ description: "Open/close trunk"
47
+ },
48
+ {
49
+ name: "frunk",
50
+ severity: "boundary",
51
+ description: "Open frunk"
52
+ },
53
+ {
54
+ name: "horn",
55
+ severity: "ambient",
56
+ description: "Honk horn"
57
+ },
58
+ {
59
+ name: "flash",
60
+ severity: "ambient",
61
+ description: "Flash lights"
62
+ },
63
+ {
64
+ name: "climate-on",
65
+ severity: "ambient",
66
+ description: "Start HVAC"
67
+ },
68
+ {
69
+ name: "climate-off",
70
+ severity: "ambient",
71
+ description: "Stop HVAC"
72
+ },
73
+ {
74
+ name: "set-temp",
75
+ severity: "ambient",
76
+ description: "Set temperature"
77
+ },
78
+ {
79
+ name: "charge-start",
80
+ severity: "boundary",
81
+ description: "Start charging"
82
+ },
83
+ {
84
+ name: "charge-stop",
85
+ severity: "boundary",
86
+ description: "Stop charging"
87
+ },
88
+ {
89
+ name: "set-charge-limit",
90
+ severity: "ambient",
91
+ description: "Set charge limit"
92
+ },
93
+ {
94
+ name: "sentry-on",
95
+ severity: "boundary",
96
+ description: "Enable sentry mode"
97
+ },
98
+ {
99
+ name: "sentry-off",
100
+ severity: "boundary",
101
+ description: "Disable sentry mode"
102
+ },
103
+ {
104
+ name: "set-charging-amps",
105
+ severity: "ambient",
106
+ description: "Set charging amperage"
107
+ },
108
+ {
109
+ name: "seat-heater",
110
+ severity: "ambient",
111
+ description: "Set seat heater level"
112
+ },
113
+ {
114
+ name: "charge-port-open",
115
+ severity: "boundary",
116
+ description: "Open charge port"
117
+ },
118
+ {
119
+ name: "charge-port-close",
120
+ severity: "boundary",
121
+ description: "Close charge port"
122
+ },
123
+ {
124
+ name: "navigate",
125
+ severity: "boundary",
126
+ description: "Navigate to address"
127
+ },
128
+ {
129
+ name: "share",
130
+ severity: "ambient",
131
+ description: "Share to vehicle"
132
+ },
133
+ {
134
+ name: "window-vent",
135
+ severity: "boundary",
136
+ description: "Vent windows"
137
+ },
138
+ {
139
+ name: "window-close",
140
+ severity: "boundary",
141
+ description: "Close windows"
142
+ },
143
+ {
144
+ name: "homelink",
145
+ severity: "boundary",
146
+ description: "Trigger HomeLink"
147
+ },
148
+ {
149
+ name: "remote-start",
150
+ severity: "critical",
151
+ description: "Remote start drive"
152
+ },
153
+ {
154
+ name: "schedule-update",
155
+ severity: "boundary",
156
+ description: "Schedule software update"
157
+ },
158
+ {
159
+ name: "cancel-update",
160
+ severity: "ambient",
161
+ description: "Cancel software update"
162
+ }
163
+ ];
164
+ const ENERGY_ACTIONS = [
165
+ {
166
+ name: "set-backup-reserve",
167
+ severity: "boundary",
168
+ description: "Set backup reserve percent"
169
+ },
170
+ {
171
+ name: "set-operation-mode",
172
+ severity: "boundary",
173
+ description: "Set operation mode"
174
+ },
175
+ {
176
+ name: "storm-mode-on",
177
+ severity: "boundary",
178
+ description: "Enable storm watch"
179
+ },
180
+ {
181
+ name: "storm-mode-off",
182
+ severity: "boundary",
183
+ description: "Disable storm watch"
184
+ }
185
+ ];
186
+ const VEHICLE_SUB_PATHS = [
187
+ "state",
188
+ "charge",
189
+ "climate",
190
+ "location",
191
+ "drive",
192
+ "vehicle",
193
+ "nearby-chargers",
194
+ "release-notes"
195
+ ];
196
+ const VEHICLE_COMMAND_MAP = {
197
+ lock: "door_lock",
198
+ unlock: "door_unlock",
199
+ trunk: "actuate_trunk",
200
+ frunk: "actuate_trunk",
201
+ horn: "honk_horn",
202
+ flash: "flash_lights",
203
+ "climate-on": "auto_conditioning_start",
204
+ "climate-off": "auto_conditioning_stop",
205
+ "set-temp": "set_temps",
206
+ "charge-start": "charge_start",
207
+ "charge-stop": "charge_stop",
208
+ "set-charge-limit": "set_charge_limit",
209
+ "sentry-on": "set_sentry_mode",
210
+ "sentry-off": "set_sentry_mode",
211
+ "set-charging-amps": "set_charging_amps",
212
+ "seat-heater": "remote_seat_heater_request",
213
+ "charge-port-open": "charge_port_door_open",
214
+ "charge-port-close": "charge_port_door_close",
215
+ navigate: "navigation_request",
216
+ share: "share",
217
+ "window-vent": "window_control",
218
+ "window-close": "window_control",
219
+ homelink: "trigger_homelink",
220
+ "remote-start": "remote_start_drive",
221
+ "schedule-update": "schedule_software_update",
222
+ "cancel-update": "cancel_software_update"
223
+ };
224
+ var AFSTesla = class AFSTesla extends _aigne_afs_provider.AFSBaseProvider {
225
+ static securityProfiles() {
226
+ return {
227
+ admin: {
228
+ actionPolicy: "full",
229
+ sensitivity: "full"
230
+ },
231
+ user: {
232
+ actionPolicy: "standard",
233
+ sensitiveFields: [
234
+ "latitude",
235
+ "longitude",
236
+ "native_latitude",
237
+ "native_longitude",
238
+ "vin",
239
+ "odometer"
240
+ ],
241
+ sensitivity: "redacted"
242
+ },
243
+ guest: {
244
+ actionPolicy: "safe",
245
+ accessMode: "readonly",
246
+ blockedActions: [
247
+ "unlock",
248
+ "remote-start",
249
+ "navigate"
250
+ ],
251
+ sensitiveFields: [
252
+ "latitude",
253
+ "longitude",
254
+ "native_latitude",
255
+ "native_longitude",
256
+ "vin",
257
+ "odometer"
258
+ ],
259
+ sensitivity: "redacted"
260
+ }
261
+ };
262
+ }
263
+ name;
264
+ description;
265
+ accessMode = "readwrite";
266
+ client;
267
+ options;
268
+ constructor(input) {
269
+ super();
270
+ const options = afsTeslaOptionsSchema.parse(input);
271
+ this.options = options;
272
+ this.name = options.name ?? "tesla";
273
+ this.description = options.description ?? "Tesla Fleet API";
274
+ const token = options._testToken || input.token || input.auth?.token || input._token || "";
275
+ if (!token) throw new _aigne_afs.AFSError("Tesla access token is required. Provide OAuth credentials output token or _testToken for tests.", "AFS_AUTH_ERROR");
276
+ this.client = new require_client.FleetClient({
277
+ token,
278
+ region: options.region,
279
+ baseUrl: options._testBaseUrl,
280
+ cacheTtl: options.cacheTtl,
281
+ cacheTtlStatic: options.cacheTtlStatic
282
+ });
283
+ }
284
+ static schema() {
285
+ return afsTeslaOptionsSchema;
286
+ }
287
+ static auth() {
288
+ return require_auth.TeslaAuth;
289
+ }
290
+ static manifest() {
291
+ return {
292
+ name: "tesla",
293
+ description: "Tesla Fleet API — vehicles and energy products as filesystem.\n- Browse vehicle state (charge, climate, location, drive)\n- Execute commands (lock, unlock, climate, charging)\n- Monitor energy sites (Powerwall, Solar)\n- Path structure: `/vehicles/{vin}/{state}` and `/energy/{siteId}/{data}`",
294
+ uriTemplate: "tesla://{region}",
295
+ category: "iot",
296
+ schema: afsTeslaOptionsSchema,
297
+ tags: [
298
+ "tesla",
299
+ "vehicle",
300
+ "ev",
301
+ "energy",
302
+ "powerwall",
303
+ "solar"
304
+ ],
305
+ capabilityTags: [
306
+ "read-write",
307
+ "crud",
308
+ "search",
309
+ "auth:oauth",
310
+ "remote",
311
+ "http",
312
+ "rate-limited"
313
+ ],
314
+ security: {
315
+ riskLevel: "external",
316
+ resourceAccess: ["internet"],
317
+ dataSensitivity: ["personal-data"],
318
+ notes: ["Controls physical vehicles — lock/unlock, climate, charging", "Exposes vehicle location and driving data"]
319
+ },
320
+ capabilities: {
321
+ network: {
322
+ egress: true,
323
+ allowedDomains: ["fleet-api.prd.*.vn.cloud.tesla.com", "fleet-auth.prd.vn.cloud.tesla.com"]
324
+ },
325
+ secrets: ["tesla/access-token"]
326
+ }
327
+ };
328
+ }
329
+ static treeSchema() {
330
+ return {
331
+ operations: [
332
+ "list",
333
+ "read",
334
+ "search",
335
+ "exec",
336
+ "stat",
337
+ "explain"
338
+ ],
339
+ tree: {
340
+ "/": { kind: "tesla:account" },
341
+ "/vehicles": {
342
+ kind: "tesla:vehicle-group",
343
+ operations: [
344
+ "list",
345
+ "read",
346
+ "search"
347
+ ]
348
+ },
349
+ "/vehicles/{vin}": {
350
+ kind: "tesla:vehicle",
351
+ operations: [
352
+ "list",
353
+ "read",
354
+ "exec"
355
+ ],
356
+ actions: [
357
+ "wake",
358
+ "lock",
359
+ "unlock",
360
+ "trunk",
361
+ "frunk",
362
+ "horn",
363
+ "flash",
364
+ "climate-on",
365
+ "climate-off",
366
+ "set-temp",
367
+ "charge-start",
368
+ "charge-stop",
369
+ "set-charge-limit",
370
+ "sentry-on",
371
+ "sentry-off",
372
+ "set-charging-amps",
373
+ "seat-heater",
374
+ "charge-port-open",
375
+ "charge-port-close",
376
+ "navigate",
377
+ "share",
378
+ "window-vent",
379
+ "window-close",
380
+ "homelink",
381
+ "remote-start",
382
+ "schedule-update",
383
+ "cancel-update"
384
+ ],
385
+ destructive: ["unlock", "remote-start"]
386
+ },
387
+ "/vehicles/{vin}/state": {
388
+ kind: "tesla:vehicle-state",
389
+ operations: ["read"]
390
+ },
391
+ "/vehicles/{vin}/charge": {
392
+ kind: "tesla:vehicle-state",
393
+ operations: ["read"]
394
+ },
395
+ "/vehicles/{vin}/climate": {
396
+ kind: "tesla:vehicle-state",
397
+ operations: ["read"]
398
+ },
399
+ "/vehicles/{vin}/location": {
400
+ kind: "tesla:vehicle-state",
401
+ operations: ["read"]
402
+ },
403
+ "/vehicles/{vin}/drive": {
404
+ kind: "tesla:vehicle-state",
405
+ operations: ["read"]
406
+ },
407
+ "/vehicles/{vin}/vehicle": {
408
+ kind: "tesla:vehicle-state",
409
+ operations: ["read"]
410
+ },
411
+ "/vehicles/{vin}/nearby-chargers": {
412
+ kind: "tesla:charger-list",
413
+ operations: ["read"]
414
+ },
415
+ "/vehicles/{vin}/release-notes": {
416
+ kind: "tesla:release-notes",
417
+ operations: ["read"]
418
+ },
419
+ "/energy": {
420
+ kind: "tesla:energy-group",
421
+ operations: [
422
+ "list",
423
+ "read",
424
+ "search"
425
+ ]
426
+ },
427
+ "/energy/{siteId}": {
428
+ kind: "tesla:energy-site",
429
+ operations: [
430
+ "list",
431
+ "read",
432
+ "exec"
433
+ ],
434
+ actions: [
435
+ "set-backup-reserve",
436
+ "set-operation-mode",
437
+ "storm-mode-on",
438
+ "storm-mode-off"
439
+ ]
440
+ },
441
+ "/energy/{siteId}/live": {
442
+ kind: "tesla:energy-state",
443
+ operations: ["read"]
444
+ },
445
+ "/energy/{siteId}/history": {
446
+ kind: "tesla:energy-state",
447
+ operations: ["read"]
448
+ }
449
+ },
450
+ auth: {
451
+ type: "oauth",
452
+ env: ["TESLA_CLIENT_ID", "TESLA_CLIENT_SECRET"]
453
+ },
454
+ bestFor: [
455
+ "vehicle monitoring",
456
+ "energy management",
457
+ "EV charging"
458
+ ],
459
+ notFor: ["file storage", "database queries"]
460
+ };
461
+ }
462
+ static async load({ config } = {}) {
463
+ return new AFSTesla(config ?? {});
464
+ }
465
+ async listRoot() {
466
+ return { data: [this.buildEntry("/vehicles", {
467
+ id: "vehicles",
468
+ meta: {
469
+ kind: "tesla:vehicle-group",
470
+ childrenCount: -1,
471
+ description: "Vehicles"
472
+ }
473
+ }), this.buildEntry("/energy", {
474
+ id: "energy",
475
+ meta: {
476
+ kind: "tesla:energy-group",
477
+ childrenCount: -1,
478
+ description: "Energy sites"
479
+ }
480
+ })] };
481
+ }
482
+ async readRoot() {
483
+ return this.buildEntry("/", {
484
+ id: "tesla",
485
+ content: {
486
+ type: "tesla:account",
487
+ region: this.options.region
488
+ },
489
+ meta: {
490
+ kind: "tesla:account",
491
+ childrenCount: 2,
492
+ description: "Tesla account"
493
+ }
494
+ });
495
+ }
496
+ async metaRoot() {
497
+ return this.buildEntry("/.meta", {
498
+ id: "meta",
499
+ content: {
500
+ kind: "tesla:account",
501
+ region: this.options.region,
502
+ provider: "tesla"
503
+ },
504
+ meta: {
505
+ kind: "tesla:account",
506
+ childrenCount: 2,
507
+ description: "Tesla account"
508
+ }
509
+ });
510
+ }
511
+ async readCapabilities() {
512
+ const manifest = {
513
+ schemaVersion: 1,
514
+ provider: "tesla",
515
+ description: "Tesla Fleet API provider",
516
+ tools: [],
517
+ actions: [{
518
+ kind: "tesla:vehicle",
519
+ description: "Vehicle commands",
520
+ catalog: VEHICLE_ACTIONS.map((a) => ({
521
+ name: a.name,
522
+ description: a.description
523
+ })),
524
+ discovery: { pathTemplate: "/vehicles/:vin/.actions" }
525
+ }, {
526
+ kind: "tesla:energy-site",
527
+ description: "Energy site commands",
528
+ catalog: ENERGY_ACTIONS.map((a) => ({
529
+ name: a.name,
530
+ description: a.description
531
+ })),
532
+ discovery: { pathTemplate: "/energy/:siteId/.actions" }
533
+ }],
534
+ operations: this.getOperationsDeclaration()
535
+ };
536
+ return this.buildEntry("/.meta/.capabilities", {
537
+ id: "capabilities",
538
+ content: manifest,
539
+ meta: { kind: "afs:capabilities" }
540
+ });
541
+ }
542
+ async statRoot() {
543
+ return { data: this.buildEntry("/", {
544
+ id: "tesla",
545
+ meta: {
546
+ kind: "tesla:account",
547
+ childrenCount: 2,
548
+ description: "Tesla account"
549
+ }
550
+ }) };
551
+ }
552
+ async explainRoot() {
553
+ const vehicles = await this.client.getVehicles();
554
+ const energySites = await this.client.getEnergySites();
555
+ return {
556
+ content: [
557
+ `# Tesla Account`,
558
+ ``,
559
+ `- **Region**: ${this.options.region}`,
560
+ `- **Vehicles**: ${vehicles.length}`,
561
+ `- **Energy sites**: ${energySites.length}`,
562
+ ``,
563
+ `## Vehicles`,
564
+ ...vehicles.map((v) => `- ${v.display_name} (${v.vin}) — ${v.state}`),
565
+ ``,
566
+ `## Energy Sites`,
567
+ ...energySites.map((s) => `- ${s.site_name} (${s.energy_site_id}) — ${s.resource_type}`)
568
+ ].join("\n"),
569
+ format: "markdown"
570
+ };
571
+ }
572
+ async searchRoot(_ctx, query, options) {
573
+ const results = [];
574
+ const lowerQuery = query.toLowerCase();
575
+ const limit = options?.limit ?? 1e3;
576
+ if (!query) return { data: [] };
577
+ const vehicles = await this.client.getVehicles();
578
+ for (const v of vehicles) {
579
+ if (results.length >= limit) break;
580
+ if (v.display_name.toLowerCase().includes(lowerQuery) || v.vin.toLowerCase().includes(lowerQuery)) results.push(this.buildEntry((0, ufo.joinURL)("/vehicles", v.vin), {
581
+ id: v.vin,
582
+ meta: {
583
+ kind: "tesla:vehicle",
584
+ childrenCount: 8,
585
+ description: v.display_name,
586
+ state: v.state
587
+ }
588
+ }));
589
+ }
590
+ if (results.length < limit) {
591
+ const sites = await this.client.getEnergySites();
592
+ for (const s of sites) {
593
+ if (results.length >= limit) break;
594
+ if (s.site_name.toLowerCase().includes(lowerQuery)) results.push(this.buildEntry((0, ufo.joinURL)("/energy", String(s.energy_site_id)), {
595
+ id: String(s.energy_site_id),
596
+ meta: {
597
+ kind: "tesla:energy-site",
598
+ childrenCount: 2,
599
+ description: s.site_name
600
+ }
601
+ }));
602
+ }
603
+ }
604
+ return { data: results };
605
+ }
606
+ async listRootActions() {
607
+ const entry = this.buildEntry("/.actions/refresh", {
608
+ id: "refresh",
609
+ meta: {
610
+ kind: "afs:executable",
611
+ childrenCount: 0,
612
+ description: "Force refresh all cached data",
613
+ name: "refresh"
614
+ }
615
+ });
616
+ entry.summary = "refresh";
617
+ return { data: [entry] };
618
+ }
619
+ async execRefresh() {
620
+ this.client.clearAllCaches();
621
+ return {
622
+ success: true,
623
+ data: { message: "All caches cleared" }
624
+ };
625
+ }
626
+ async listVehicles() {
627
+ return { data: (await this.client.getVehicles()).map((v) => this.buildEntry((0, ufo.joinURL)("/vehicles", v.vin), {
628
+ id: v.vin,
629
+ meta: {
630
+ kind: "tesla:vehicle",
631
+ childrenCount: 8,
632
+ description: v.display_name,
633
+ state: v.state
634
+ }
635
+ })) };
636
+ }
637
+ async readVehiclesGroup() {
638
+ const vehicles = await this.client.getVehicles();
639
+ return this.buildEntry("/vehicles", {
640
+ id: "vehicles",
641
+ content: { vehicles: vehicles.map((v) => ({
642
+ vin: v.vin,
643
+ name: v.display_name,
644
+ state: v.state
645
+ })) },
646
+ meta: {
647
+ kind: "tesla:vehicle-group",
648
+ childrenCount: vehicles.length,
649
+ description: "Vehicles"
650
+ }
651
+ });
652
+ }
653
+ async metaVehicles() {
654
+ const vehicles = await this.client.getVehicles();
655
+ return this.buildEntry("/vehicles/.meta", {
656
+ id: "meta",
657
+ content: {
658
+ kind: "tesla:vehicle-group",
659
+ vehicleCount: vehicles.length
660
+ },
661
+ meta: {
662
+ kind: "tesla:vehicle-group",
663
+ childrenCount: vehicles.length,
664
+ description: "Vehicles"
665
+ }
666
+ });
667
+ }
668
+ async statVehicles() {
669
+ const vehicles = await this.client.getVehicles();
670
+ return { data: this.buildEntry("/vehicles", {
671
+ id: "vehicles",
672
+ meta: {
673
+ kind: "tesla:vehicle-group",
674
+ childrenCount: vehicles.length,
675
+ description: "Vehicles"
676
+ }
677
+ }) };
678
+ }
679
+ async searchVehicles(_ctx, query, options) {
680
+ if (!query) return { data: [] };
681
+ const vehicles = await this.client.getVehicles();
682
+ const lowerQuery = query.toLowerCase();
683
+ const results = [];
684
+ const limit = options?.limit ?? 1e3;
685
+ for (const v of vehicles) {
686
+ if (results.length >= limit) break;
687
+ if (v.display_name.toLowerCase().includes(lowerQuery) || v.vin.toLowerCase().includes(lowerQuery)) results.push(this.buildEntry((0, ufo.joinURL)("/vehicles", v.vin), {
688
+ id: v.vin,
689
+ meta: {
690
+ kind: "tesla:vehicle",
691
+ childrenCount: 8,
692
+ description: v.display_name,
693
+ state: v.state
694
+ }
695
+ }));
696
+ }
697
+ return { data: results };
698
+ }
699
+ async explainVehicles() {
700
+ const vehicles = await this.client.getVehicles();
701
+ return {
702
+ content: [
703
+ `# Vehicles`,
704
+ ``,
705
+ `Total: ${vehicles.length}`,
706
+ ``,
707
+ ...vehicles.map((v) => `- **${v.display_name}** (${v.vin}) — ${v.state}`)
708
+ ].join("\n"),
709
+ format: "markdown"
710
+ };
711
+ }
712
+ async listVehicleSubPaths(ctx) {
713
+ const vin = ctx.params.vin;
714
+ await this.client.resolveVIN(vin);
715
+ return { data: VEHICLE_SUB_PATHS.map((name) => {
716
+ const kind = name === "nearby-chargers" ? "tesla:charger-list" : name === "release-notes" ? "tesla:release-notes" : "tesla:vehicle-state";
717
+ return this.buildEntry((0, ufo.joinURL)("/vehicles", vin, name), {
718
+ id: name,
719
+ meta: {
720
+ kind,
721
+ childrenCount: 0
722
+ }
723
+ });
724
+ }) };
725
+ }
726
+ async readVehicle(ctx) {
727
+ const vin = ctx.params.vin;
728
+ const vehicleData = await this.client.getVehicleData(vin);
729
+ return this.buildEntry((0, ufo.joinURL)("/vehicles", vin), {
730
+ id: vin,
731
+ content: {
732
+ name: vehicleData.display_name,
733
+ model: vehicleData.vehicle_config?.car_type,
734
+ color: vehicleData.vehicle_config?.exterior_color,
735
+ firmware: vehicleData.vehicle_state?.car_version,
736
+ state: vehicleData.state
737
+ },
738
+ meta: {
739
+ kind: "tesla:vehicle",
740
+ childrenCount: 8,
741
+ description: vehicleData.display_name,
742
+ state: vehicleData.state
743
+ }
744
+ });
745
+ }
746
+ async metaVehicle(ctx) {
747
+ const vin = ctx.params.vin;
748
+ const vehicle = (await this.client.getVehicles()).find((v) => v.vin === vin);
749
+ if (!vehicle) throw new _aigne_afs.AFSNotFoundError((0, ufo.joinURL)("/vehicles", vin));
750
+ let vehicleData;
751
+ try {
752
+ vehicleData = await this.client.getVehicleData(vin);
753
+ } catch {}
754
+ return this.buildEntry((0, ufo.joinURL)("/vehicles", vin, ".meta"), {
755
+ id: "meta",
756
+ content: {
757
+ vin: vehicle.vin,
758
+ name: vehicle.display_name,
759
+ model: vehicleData?.vehicle_config?.car_type ?? "unknown",
760
+ optionCodes: vehicle.option_codes,
761
+ state: vehicle.state
762
+ },
763
+ meta: {
764
+ kind: "tesla:vehicle",
765
+ childrenCount: 8,
766
+ description: vehicle.display_name,
767
+ state: vehicle.state
768
+ }
769
+ });
770
+ }
771
+ async statVehicle(ctx) {
772
+ const vin = ctx.params.vin;
773
+ const vehicle = (await this.client.getVehicles()).find((v) => v.vin === vin);
774
+ if (!vehicle) throw new _aigne_afs.AFSNotFoundError((0, ufo.joinURL)("/vehicles", vin));
775
+ const lastUpdated = this.client.getVehicleDataTimestamp(vin);
776
+ return { data: this.buildEntry((0, ufo.joinURL)("/vehicles", vin), {
777
+ id: vin,
778
+ meta: {
779
+ kind: "tesla:vehicle",
780
+ childrenCount: 8,
781
+ description: vehicle.display_name,
782
+ state: vehicle.state,
783
+ lastUpdated: lastUpdated ? new Date(lastUpdated).toISOString() : void 0
784
+ }
785
+ }) };
786
+ }
787
+ async explainVehicle(ctx) {
788
+ const vin = ctx.params.vin;
789
+ const vehicleData = await this.client.getVehicleData(vin);
790
+ const chargeState = vehicleData.charge_state;
791
+ const vehicleState = vehicleData.vehicle_state;
792
+ return {
793
+ content: [
794
+ `# ${vehicleData.display_name}`,
795
+ ``,
796
+ `- **VIN**: ${vin}`,
797
+ `- **Model**: ${vehicleData.vehicle_config?.car_type}`,
798
+ `- **State**: ${vehicleData.state}`,
799
+ `- **Firmware**: ${vehicleState?.car_version}`,
800
+ `- **Battery**: ${chargeState?.battery_level}%`,
801
+ `- **Range**: ${chargeState?.battery_range} mi`,
802
+ `- **Locked**: ${vehicleState?.locked}`,
803
+ `- **Sentry**: ${vehicleState?.sentry_mode}`,
804
+ `- **Odometer**: ${vehicleState?.odometer} mi`
805
+ ].join("\n"),
806
+ format: "markdown"
807
+ };
808
+ }
809
+ async readVehicleState(ctx) {
810
+ const vin = ctx.params.vin;
811
+ const data = await this.client.getVehicleData(vin);
812
+ return this.buildEntry((0, ufo.joinURL)("/vehicles", vin, "state"), {
813
+ id: "state",
814
+ content: data,
815
+ meta: {
816
+ kind: "tesla:vehicle-state",
817
+ childrenCount: 0
818
+ }
819
+ });
820
+ }
821
+ async readVehicleCharge(ctx) {
822
+ const vin = ctx.params.vin;
823
+ const data = await this.client.getVehicleData(vin);
824
+ return this.buildEntry((0, ufo.joinURL)("/vehicles", vin, "charge"), {
825
+ id: "charge",
826
+ content: data.charge_state,
827
+ meta: {
828
+ kind: "tesla:vehicle-state",
829
+ childrenCount: 0
830
+ }
831
+ });
832
+ }
833
+ async readVehicleClimate(ctx) {
834
+ const vin = ctx.params.vin;
835
+ const data = await this.client.getVehicleData(vin);
836
+ return this.buildEntry((0, ufo.joinURL)("/vehicles", vin, "climate"), {
837
+ id: "climate",
838
+ content: data.climate_state,
839
+ meta: {
840
+ kind: "tesla:vehicle-state",
841
+ childrenCount: 0
842
+ }
843
+ });
844
+ }
845
+ async readVehicleLocation(ctx) {
846
+ const vin = ctx.params.vin;
847
+ const data = await this.client.getVehicleData(vin);
848
+ return this.buildEntry((0, ufo.joinURL)("/vehicles", vin, "location"), {
849
+ id: "location",
850
+ content: data.drive_state,
851
+ meta: {
852
+ kind: "tesla:vehicle-state",
853
+ childrenCount: 0
854
+ }
855
+ });
856
+ }
857
+ async readVehicleDrive(ctx) {
858
+ const vin = ctx.params.vin;
859
+ const data = await this.client.getVehicleData(vin);
860
+ return this.buildEntry((0, ufo.joinURL)("/vehicles", vin, "drive"), {
861
+ id: "drive",
862
+ content: data.drive_state,
863
+ meta: {
864
+ kind: "tesla:vehicle-state",
865
+ childrenCount: 0
866
+ }
867
+ });
868
+ }
869
+ async readVehicleVehicle(ctx) {
870
+ const vin = ctx.params.vin;
871
+ const data = await this.client.getVehicleData(vin);
872
+ return this.buildEntry((0, ufo.joinURL)("/vehicles", vin, "vehicle"), {
873
+ id: "vehicle",
874
+ content: {
875
+ ...data.vehicle_state,
876
+ firmware: data.vehicle_state?.car_version
877
+ },
878
+ meta: {
879
+ kind: "tesla:vehicle-state",
880
+ childrenCount: 0
881
+ }
882
+ });
883
+ }
884
+ async readVehicleNearbyChargers(ctx) {
885
+ const vin = ctx.params.vin;
886
+ const data = await this.client.getNearbyChargers(vin);
887
+ return this.buildEntry((0, ufo.joinURL)("/vehicles", vin, "nearby-chargers"), {
888
+ id: "nearby-chargers",
889
+ content: data,
890
+ meta: {
891
+ kind: "tesla:charger-list",
892
+ childrenCount: 0
893
+ }
894
+ });
895
+ }
896
+ async readVehicleReleaseNotes(ctx) {
897
+ const vin = ctx.params.vin;
898
+ const data = await this.client.getReleaseNotes(vin);
899
+ return this.buildEntry((0, ufo.joinURL)("/vehicles", vin, "release-notes"), {
900
+ id: "release-notes",
901
+ content: data,
902
+ meta: {
903
+ kind: "tesla:release-notes",
904
+ childrenCount: 0
905
+ }
906
+ });
907
+ }
908
+ async statVehicleState(ctx) {
909
+ const vin = ctx.params.vin;
910
+ await this.client.resolveVIN(vin);
911
+ return { data: this.buildEntry((0, ufo.joinURL)("/vehicles", vin, "state"), {
912
+ id: "state",
913
+ meta: {
914
+ kind: "tesla:vehicle-state",
915
+ childrenCount: 0
916
+ }
917
+ }) };
918
+ }
919
+ async statVehicleCharge(ctx) {
920
+ const vin = ctx.params.vin;
921
+ await this.client.resolveVIN(vin);
922
+ return { data: this.buildEntry((0, ufo.joinURL)("/vehicles", vin, "charge"), {
923
+ id: "charge",
924
+ meta: {
925
+ kind: "tesla:vehicle-state",
926
+ childrenCount: 0
927
+ }
928
+ }) };
929
+ }
930
+ async statVehicleClimate(ctx) {
931
+ const vin = ctx.params.vin;
932
+ await this.client.resolveVIN(vin);
933
+ return { data: this.buildEntry((0, ufo.joinURL)("/vehicles", vin, "climate"), {
934
+ id: "climate",
935
+ meta: {
936
+ kind: "tesla:vehicle-state",
937
+ childrenCount: 0
938
+ }
939
+ }) };
940
+ }
941
+ async statVehicleLocation(ctx) {
942
+ const vin = ctx.params.vin;
943
+ await this.client.resolveVIN(vin);
944
+ return { data: this.buildEntry((0, ufo.joinURL)("/vehicles", vin, "location"), {
945
+ id: "location",
946
+ meta: {
947
+ kind: "tesla:vehicle-state",
948
+ childrenCount: 0
949
+ }
950
+ }) };
951
+ }
952
+ async statVehicleDrive(ctx) {
953
+ const vin = ctx.params.vin;
954
+ await this.client.resolveVIN(vin);
955
+ return { data: this.buildEntry((0, ufo.joinURL)("/vehicles", vin, "drive"), {
956
+ id: "drive",
957
+ meta: {
958
+ kind: "tesla:vehicle-state",
959
+ childrenCount: 0
960
+ }
961
+ }) };
962
+ }
963
+ async statVehicleVehicle(ctx) {
964
+ const vin = ctx.params.vin;
965
+ await this.client.resolveVIN(vin);
966
+ return { data: this.buildEntry((0, ufo.joinURL)("/vehicles", vin, "vehicle"), {
967
+ id: "vehicle",
968
+ meta: {
969
+ kind: "tesla:vehicle-state",
970
+ childrenCount: 0
971
+ }
972
+ }) };
973
+ }
974
+ async statVehicleNearbyChargers(ctx) {
975
+ const vin = ctx.params.vin;
976
+ await this.client.resolveVIN(vin);
977
+ return { data: this.buildEntry((0, ufo.joinURL)("/vehicles", vin, "nearby-chargers"), {
978
+ id: "nearby-chargers",
979
+ meta: {
980
+ kind: "tesla:charger-list",
981
+ childrenCount: 0
982
+ }
983
+ }) };
984
+ }
985
+ async statVehicleReleaseNotes(ctx) {
986
+ const vin = ctx.params.vin;
987
+ await this.client.resolveVIN(vin);
988
+ return { data: this.buildEntry((0, ufo.joinURL)("/vehicles", vin, "release-notes"), {
989
+ id: "release-notes",
990
+ meta: {
991
+ kind: "tesla:release-notes",
992
+ childrenCount: 0
993
+ }
994
+ }) };
995
+ }
996
+ async metaVehicleState(ctx) {
997
+ const vin = ctx.params.vin;
998
+ await this.client.resolveVIN(vin);
999
+ return this.buildEntry((0, ufo.joinURL)("/vehicles", vin, "state", ".meta"), {
1000
+ id: "meta",
1001
+ content: {
1002
+ kind: "tesla:vehicle-state",
1003
+ description: "Full vehicle data snapshot"
1004
+ },
1005
+ meta: {
1006
+ kind: "tesla:vehicle-state",
1007
+ childrenCount: 0
1008
+ }
1009
+ });
1010
+ }
1011
+ async metaVehicleCharge(ctx) {
1012
+ const vin = ctx.params.vin;
1013
+ await this.client.resolveVIN(vin);
1014
+ return this.buildEntry((0, ufo.joinURL)("/vehicles", vin, "charge", ".meta"), {
1015
+ id: "meta",
1016
+ content: {
1017
+ kind: "tesla:vehicle-state",
1018
+ description: "Charge state"
1019
+ },
1020
+ meta: {
1021
+ kind: "tesla:vehicle-state",
1022
+ childrenCount: 0
1023
+ }
1024
+ });
1025
+ }
1026
+ async metaVehicleClimate(ctx) {
1027
+ const vin = ctx.params.vin;
1028
+ await this.client.resolveVIN(vin);
1029
+ return this.buildEntry((0, ufo.joinURL)("/vehicles", vin, "climate", ".meta"), {
1030
+ id: "meta",
1031
+ content: {
1032
+ kind: "tesla:vehicle-state",
1033
+ description: "Climate state"
1034
+ },
1035
+ meta: {
1036
+ kind: "tesla:vehicle-state",
1037
+ childrenCount: 0
1038
+ }
1039
+ });
1040
+ }
1041
+ async metaVehicleLocation(ctx) {
1042
+ const vin = ctx.params.vin;
1043
+ await this.client.resolveVIN(vin);
1044
+ return this.buildEntry((0, ufo.joinURL)("/vehicles", vin, "location", ".meta"), {
1045
+ id: "meta",
1046
+ content: {
1047
+ kind: "tesla:vehicle-state",
1048
+ description: "Location data"
1049
+ },
1050
+ meta: {
1051
+ kind: "tesla:vehicle-state",
1052
+ childrenCount: 0
1053
+ }
1054
+ });
1055
+ }
1056
+ async metaVehicleDrive(ctx) {
1057
+ const vin = ctx.params.vin;
1058
+ await this.client.resolveVIN(vin);
1059
+ return this.buildEntry((0, ufo.joinURL)("/vehicles", vin, "drive", ".meta"), {
1060
+ id: "meta",
1061
+ content: {
1062
+ kind: "tesla:vehicle-state",
1063
+ description: "Drive state"
1064
+ },
1065
+ meta: {
1066
+ kind: "tesla:vehicle-state",
1067
+ childrenCount: 0
1068
+ }
1069
+ });
1070
+ }
1071
+ async metaVehicleVehicle(ctx) {
1072
+ const vin = ctx.params.vin;
1073
+ await this.client.resolveVIN(vin);
1074
+ return this.buildEntry((0, ufo.joinURL)("/vehicles", vin, "vehicle", ".meta"), {
1075
+ id: "meta",
1076
+ content: {
1077
+ kind: "tesla:vehicle-state",
1078
+ description: "Vehicle state"
1079
+ },
1080
+ meta: {
1081
+ kind: "tesla:vehicle-state",
1082
+ childrenCount: 0
1083
+ }
1084
+ });
1085
+ }
1086
+ async metaVehicleNearbyChargers(ctx) {
1087
+ const vin = ctx.params.vin;
1088
+ await this.client.resolveVIN(vin);
1089
+ return this.buildEntry((0, ufo.joinURL)("/vehicles", vin, "nearby-chargers", ".meta"), {
1090
+ id: "meta",
1091
+ content: {
1092
+ kind: "tesla:charger-list",
1093
+ description: "Nearby chargers"
1094
+ },
1095
+ meta: {
1096
+ kind: "tesla:charger-list",
1097
+ childrenCount: 0
1098
+ }
1099
+ });
1100
+ }
1101
+ async metaVehicleReleaseNotes(ctx) {
1102
+ const vin = ctx.params.vin;
1103
+ await this.client.resolveVIN(vin);
1104
+ return this.buildEntry((0, ufo.joinURL)("/vehicles", vin, "release-notes", ".meta"), {
1105
+ id: "meta",
1106
+ content: {
1107
+ kind: "tesla:release-notes",
1108
+ description: "Release notes"
1109
+ },
1110
+ meta: {
1111
+ kind: "tesla:release-notes",
1112
+ childrenCount: 0
1113
+ }
1114
+ });
1115
+ }
1116
+ async listVehicleState() {
1117
+ return { data: [] };
1118
+ }
1119
+ async listVehicleCharge() {
1120
+ return { data: [] };
1121
+ }
1122
+ async listVehicleClimate() {
1123
+ return { data: [] };
1124
+ }
1125
+ async listVehicleLocation() {
1126
+ return { data: [] };
1127
+ }
1128
+ async listVehicleDrive() {
1129
+ return { data: [] };
1130
+ }
1131
+ async listVehicleVehicle() {
1132
+ return { data: [] };
1133
+ }
1134
+ async listVehicleNearbyChargers() {
1135
+ return { data: [] };
1136
+ }
1137
+ async listVehicleReleaseNotes() {
1138
+ return { data: [] };
1139
+ }
1140
+ async listVehicleActions(ctx) {
1141
+ const vin = ctx.params.vin;
1142
+ await this.client.resolveVIN(vin);
1143
+ return { data: VEHICLE_ACTIONS.map((action) => {
1144
+ const entry = this.buildEntry((0, ufo.joinURL)("/vehicles", vin, ".actions", action.name), {
1145
+ id: action.name,
1146
+ meta: {
1147
+ kind: "afs:executable",
1148
+ childrenCount: 0,
1149
+ description: action.description,
1150
+ name: action.name,
1151
+ severity: action.severity
1152
+ }
1153
+ });
1154
+ entry.summary = action.name;
1155
+ return entry;
1156
+ }) };
1157
+ }
1158
+ async execVehicleAction(ctx, args) {
1159
+ const vin = ctx.params.vin;
1160
+ const action = ctx.params.action;
1161
+ if (!VEHICLE_ACTIONS.find((a) => a.name === action)) throw new _aigne_afs.AFSNotFoundError((0, ufo.joinURL)("/vehicles", vin, ".actions", action), `Unknown vehicle action: ${action}`);
1162
+ if (action === "wake") {
1163
+ this.assertNoArgs(action, args);
1164
+ await this.client.wakeVehicle(vin);
1165
+ return {
1166
+ success: true,
1167
+ data: { message: "Vehicle waking up" }
1168
+ };
1169
+ }
1170
+ const apiCommand = VEHICLE_COMMAND_MAP[action];
1171
+ if (!apiCommand) throw new _aigne_afs.AFSNotFoundError((0, ufo.joinURL)("/vehicles", vin, ".actions", action), `Unknown vehicle command: ${action}`);
1172
+ await this.buildAndSendVehicleCommand(vin, action, apiCommand, args);
1173
+ return {
1174
+ success: true,
1175
+ data: {
1176
+ command: action,
1177
+ vin
1178
+ }
1179
+ };
1180
+ }
1181
+ /**
1182
+ * Validate arguments and build the body for a vehicle command.
1183
+ * Throws AFSError for invalid arguments.
1184
+ */
1185
+ async buildVehicleCommandBody(vin, action, args) {
1186
+ switch (action) {
1187
+ case "frunk":
1188
+ this.assertNoArgs(action, args);
1189
+ return { which_trunk: "front" };
1190
+ case "trunk":
1191
+ this.assertNoArgs(action, args);
1192
+ return { which_trunk: "rear" };
1193
+ case "set-temp": {
1194
+ const driver = args.driver;
1195
+ const passenger = args.passenger;
1196
+ if (typeof driver !== "number") throw new _aigne_afs.AFSError("set-temp requires 'driver' as a number", "AFS_INVALID_ARGUMENT");
1197
+ return {
1198
+ driver_temp: driver,
1199
+ passenger_temp: typeof passenger === "number" ? passenger : driver
1200
+ };
1201
+ }
1202
+ case "set-charge-limit": {
1203
+ const percent = args.percent;
1204
+ if (typeof percent !== "number") throw new _aigne_afs.AFSError("set-charge-limit requires 'percent' as a number", "AFS_INVALID_ARGUMENT");
1205
+ if (percent < 0 || percent > 100) throw new _aigne_afs.AFSError("set-charge-limit 'percent' must be between 0 and 100", "AFS_INVALID_ARGUMENT");
1206
+ return { percent };
1207
+ }
1208
+ case "sentry-on":
1209
+ this.assertNoArgs(action, args);
1210
+ return { on: true };
1211
+ case "sentry-off":
1212
+ this.assertNoArgs(action, args);
1213
+ return { on: false };
1214
+ case "set-charging-amps": {
1215
+ const amps = args.amps;
1216
+ if (typeof amps !== "number") throw new _aigne_afs.AFSError("set-charging-amps requires 'amps' as a number", "AFS_INVALID_ARGUMENT");
1217
+ if (amps < 0 || amps > 48) throw new _aigne_afs.AFSError("set-charging-amps 'amps' must be between 0 and 48", "AFS_INVALID_ARGUMENT");
1218
+ return { charging_amps: amps };
1219
+ }
1220
+ case "seat-heater": {
1221
+ const seat = args.seat;
1222
+ const level = args.level;
1223
+ if (typeof seat !== "number" || typeof level !== "number") throw new _aigne_afs.AFSError("seat-heater requires 'seat' and 'level' as numbers", "AFS_INVALID_ARGUMENT");
1224
+ if (seat < 0 || seat > 5) throw new _aigne_afs.AFSError("seat-heater 'seat' must be between 0 and 5", "AFS_INVALID_ARGUMENT");
1225
+ if (level < 0 || level > 3) throw new _aigne_afs.AFSError("seat-heater 'level' must be between 0 and 3", "AFS_INVALID_ARGUMENT");
1226
+ return {
1227
+ heater: seat,
1228
+ level
1229
+ };
1230
+ }
1231
+ case "charge-port-open":
1232
+ case "charge-port-close":
1233
+ this.assertNoArgs(action, args);
1234
+ return;
1235
+ case "navigate": {
1236
+ const address = args.address;
1237
+ if (typeof address !== "string" || address.length === 0) throw new _aigne_afs.AFSError("navigate requires a non-empty 'address' string", "AFS_INVALID_ARGUMENT");
1238
+ return {
1239
+ type: "share_ext_content_raw",
1240
+ value: { "android.intent.extra.TEXT": address },
1241
+ locale: "en-US",
1242
+ timestamp_ms: String(Date.now())
1243
+ };
1244
+ }
1245
+ case "share": {
1246
+ const value = args.value;
1247
+ const type = args.type;
1248
+ if (typeof value !== "string") throw new _aigne_afs.AFSError("share requires 'value' as a string", "AFS_INVALID_ARGUMENT");
1249
+ if (typeof type !== "string" || !["url", "text"].includes(type)) throw new _aigne_afs.AFSError("share requires 'type' as 'url' or 'text'", "AFS_INVALID_ARGUMENT");
1250
+ return {
1251
+ type: "share_ext_content_raw",
1252
+ value: { "android.intent.extra.TEXT": value },
1253
+ locale: "en-US",
1254
+ timestamp_ms: String(Date.now())
1255
+ };
1256
+ }
1257
+ case "window-vent":
1258
+ case "window-close": {
1259
+ this.assertNoArgs(action, args);
1260
+ const { lat, lon } = await this.getVehicleCoordinates(vin);
1261
+ return {
1262
+ command: action === "window-vent" ? "vent" : "close",
1263
+ lat,
1264
+ lon
1265
+ };
1266
+ }
1267
+ case "homelink": {
1268
+ this.assertNoArgs(action, args);
1269
+ const { lat, lon } = await this.getVehicleCoordinates(vin);
1270
+ return {
1271
+ lat,
1272
+ lon
1273
+ };
1274
+ }
1275
+ case "remote-start":
1276
+ this.assertNoArgs(action, args);
1277
+ return;
1278
+ case "schedule-update": {
1279
+ const offsetSec = args.offset_sec;
1280
+ if (typeof offsetSec !== "number") throw new _aigne_afs.AFSError("schedule-update requires 'offset_sec' as a number", "AFS_INVALID_ARGUMENT");
1281
+ if (offsetSec < 0) throw new _aigne_afs.AFSError("schedule-update 'offset_sec' must be >= 0", "AFS_INVALID_ARGUMENT");
1282
+ return { offset_sec: offsetSec };
1283
+ }
1284
+ case "cancel-update":
1285
+ this.assertNoArgs(action, args);
1286
+ return;
1287
+ case "lock":
1288
+ case "unlock":
1289
+ case "horn":
1290
+ case "flash":
1291
+ case "climate-on":
1292
+ case "climate-off":
1293
+ case "charge-start":
1294
+ case "charge-stop":
1295
+ case "wake":
1296
+ this.assertNoArgs(action, args);
1297
+ return;
1298
+ default: throw new _aigne_afs.AFSError(`Unknown vehicle command: ${action}`, "AFS_INVALID_ARGUMENT");
1299
+ }
1300
+ }
1301
+ assertNoArgs(action, args) {
1302
+ if (Object.keys(args).length > 0) throw new _aigne_afs.AFSError(`${action} does not accept arguments`, "AFS_INVALID_ARGUMENT");
1303
+ }
1304
+ async getVehicleCoordinates(vin) {
1305
+ const driveState = (await this.client.getVehicleData(vin)).drive_state;
1306
+ const lat = driveState?.latitude;
1307
+ const lon = driveState?.longitude;
1308
+ if (typeof lat !== "number" || typeof lon !== "number") throw new _aigne_afs.AFSError("Vehicle location unavailable for this command", "AFS_INVALID_ARGUMENT");
1309
+ return {
1310
+ lat,
1311
+ lon
1312
+ };
1313
+ }
1314
+ isVehicleAsleepError(error) {
1315
+ if (!(error instanceof _aigne_afs.AFSError) || error.code !== "AFS_TIMEOUT") return false;
1316
+ const message = error.message.toLowerCase();
1317
+ return message.includes("asleep") || message.includes("vehicle unavailable") || message.includes("offline");
1318
+ }
1319
+ async buildAndSendVehicleCommand(vin, action, apiCommand, args) {
1320
+ try {
1321
+ const body$1 = await this.buildVehicleCommandBody(vin, action, args);
1322
+ await this.client.sendVehicleCommand(vin, apiCommand, body$1);
1323
+ return;
1324
+ } catch (error) {
1325
+ if (!this.options.autoWake || !this.isVehicleAsleepError(error)) throw error;
1326
+ }
1327
+ await this.client.wakeVehicle(vin);
1328
+ const body = await this.buildVehicleCommandBody(vin, action, args);
1329
+ await this.client.sendVehicleCommand(vin, apiCommand, body);
1330
+ }
1331
+ async listEnergySites() {
1332
+ return { data: (await this.client.getEnergySites()).map((s) => this.buildEntry((0, ufo.joinURL)("/energy", String(s.energy_site_id)), {
1333
+ id: String(s.energy_site_id),
1334
+ meta: {
1335
+ kind: "tesla:energy-site",
1336
+ childrenCount: 2,
1337
+ description: s.site_name
1338
+ }
1339
+ })) };
1340
+ }
1341
+ async readEnergyGroup() {
1342
+ const sites = await this.client.getEnergySites();
1343
+ return this.buildEntry("/energy", {
1344
+ id: "energy",
1345
+ content: { sites: sites.map((s) => ({
1346
+ id: s.energy_site_id,
1347
+ name: s.site_name,
1348
+ type: s.resource_type
1349
+ })) },
1350
+ meta: {
1351
+ kind: "tesla:energy-group",
1352
+ childrenCount: sites.length,
1353
+ description: "Energy sites"
1354
+ }
1355
+ });
1356
+ }
1357
+ async metaEnergy() {
1358
+ const sites = await this.client.getEnergySites();
1359
+ return this.buildEntry("/energy/.meta", {
1360
+ id: "meta",
1361
+ content: {
1362
+ kind: "tesla:energy-group",
1363
+ siteCount: sites.length
1364
+ },
1365
+ meta: {
1366
+ kind: "tesla:energy-group",
1367
+ childrenCount: sites.length,
1368
+ description: "Energy sites"
1369
+ }
1370
+ });
1371
+ }
1372
+ async statEnergy() {
1373
+ const sites = await this.client.getEnergySites();
1374
+ return { data: this.buildEntry("/energy", {
1375
+ id: "energy",
1376
+ meta: {
1377
+ kind: "tesla:energy-group",
1378
+ childrenCount: sites.length,
1379
+ description: "Energy sites"
1380
+ }
1381
+ }) };
1382
+ }
1383
+ async searchEnergy(_ctx, query, options) {
1384
+ if (!query) return { data: [] };
1385
+ const sites = await this.client.getEnergySites();
1386
+ const lowerQuery = query.toLowerCase();
1387
+ const results = [];
1388
+ const limit = options?.limit ?? 1e3;
1389
+ for (const s of sites) {
1390
+ if (results.length >= limit) break;
1391
+ if (s.site_name.toLowerCase().includes(lowerQuery)) results.push(this.buildEntry((0, ufo.joinURL)("/energy", String(s.energy_site_id)), {
1392
+ id: String(s.energy_site_id),
1393
+ meta: {
1394
+ kind: "tesla:energy-site",
1395
+ childrenCount: 2,
1396
+ description: s.site_name
1397
+ }
1398
+ }));
1399
+ }
1400
+ return { data: results };
1401
+ }
1402
+ async explainEnergy() {
1403
+ const sites = await this.client.getEnergySites();
1404
+ return {
1405
+ content: [
1406
+ `# Energy Sites`,
1407
+ ``,
1408
+ `Total: ${sites.length}`,
1409
+ ``,
1410
+ ...sites.map((s) => `- **${s.site_name}** (${s.energy_site_id}) — ${s.resource_type}`)
1411
+ ].join("\n"),
1412
+ format: "markdown"
1413
+ };
1414
+ }
1415
+ async listEnergySiteSubPaths(ctx) {
1416
+ const siteId = ctx.params.siteId;
1417
+ await this.client.resolveEnergySiteId(siteId);
1418
+ return { data: [this.buildEntry((0, ufo.joinURL)("/energy", siteId, "live"), {
1419
+ id: "live",
1420
+ meta: {
1421
+ kind: "tesla:energy-state",
1422
+ childrenCount: 0
1423
+ }
1424
+ }), this.buildEntry((0, ufo.joinURL)("/energy", siteId, "history"), {
1425
+ id: "history",
1426
+ meta: {
1427
+ kind: "tesla:energy-state",
1428
+ childrenCount: 0
1429
+ }
1430
+ })] };
1431
+ }
1432
+ async readEnergySite(ctx) {
1433
+ const siteId = ctx.params.siteId;
1434
+ const siteInfo = await this.client.getEnergySiteInfo(siteId);
1435
+ const site = (await this.client.getEnergySites()).find((s) => s.energy_site_id === Number.parseInt(siteId, 10));
1436
+ return this.buildEntry((0, ufo.joinURL)("/energy", siteId), {
1437
+ id: siteId,
1438
+ content: siteInfo,
1439
+ meta: {
1440
+ kind: "tesla:energy-site",
1441
+ childrenCount: 2,
1442
+ description: site?.site_name ?? `Energy site ${siteId}`
1443
+ }
1444
+ });
1445
+ }
1446
+ async metaEnergySite(ctx) {
1447
+ const siteId = ctx.params.siteId;
1448
+ const site = (await this.client.getEnergySites()).find((s) => s.energy_site_id === Number.parseInt(siteId, 10));
1449
+ if (!site) throw new _aigne_afs.AFSNotFoundError((0, ufo.joinURL)("/energy", siteId));
1450
+ return this.buildEntry((0, ufo.joinURL)("/energy", siteId, ".meta"), {
1451
+ id: "meta",
1452
+ content: {
1453
+ siteId: site.energy_site_id,
1454
+ name: site.site_name,
1455
+ resourceType: site.resource_type,
1456
+ backupCapable: site.backup_capable
1457
+ },
1458
+ meta: {
1459
+ kind: "tesla:energy-site",
1460
+ childrenCount: 2,
1461
+ description: site.site_name
1462
+ }
1463
+ });
1464
+ }
1465
+ async statEnergySite(ctx) {
1466
+ const siteId = ctx.params.siteId;
1467
+ const site = (await this.client.getEnergySites()).find((s) => s.energy_site_id === Number.parseInt(siteId, 10));
1468
+ if (!site) throw new _aigne_afs.AFSNotFoundError((0, ufo.joinURL)("/energy", siteId));
1469
+ return { data: this.buildEntry((0, ufo.joinURL)("/energy", siteId), {
1470
+ id: siteId,
1471
+ meta: {
1472
+ kind: "tesla:energy-site",
1473
+ childrenCount: 2,
1474
+ description: site.site_name,
1475
+ resourceType: site.resource_type
1476
+ }
1477
+ }) };
1478
+ }
1479
+ async explainEnergySite(ctx) {
1480
+ const siteId = ctx.params.siteId;
1481
+ const siteInfo = await this.client.getEnergySiteInfo(siteId);
1482
+ const site = (await this.client.getEnergySites()).find((s) => s.energy_site_id === Number.parseInt(siteId, 10));
1483
+ return {
1484
+ content: [
1485
+ `# ${site?.site_name ?? `Energy Site ${siteId}`}`,
1486
+ ``,
1487
+ `- **Site ID**: ${siteId}`,
1488
+ `- **Type**: ${site?.resource_type}`,
1489
+ `- **Backup capable**: ${siteInfo?.backup_capable}`,
1490
+ `- **Storm mode**: ${siteInfo?.storm_mode_enabled}`,
1491
+ `- **Battery**: ${siteInfo?.percentage_charged}%`
1492
+ ].join("\n"),
1493
+ format: "markdown"
1494
+ };
1495
+ }
1496
+ async readEnergySiteLive(ctx) {
1497
+ const siteId = ctx.params.siteId;
1498
+ const data = await this.client.getEnergySiteLiveStatus(siteId);
1499
+ return this.buildEntry((0, ufo.joinURL)("/energy", siteId, "live"), {
1500
+ id: "live",
1501
+ content: data,
1502
+ meta: {
1503
+ kind: "tesla:energy-state",
1504
+ childrenCount: 0
1505
+ }
1506
+ });
1507
+ }
1508
+ async readEnergySiteHistory(ctx) {
1509
+ const siteId = ctx.params.siteId;
1510
+ const data = await this.client.getEnergySiteHistory(siteId);
1511
+ return this.buildEntry((0, ufo.joinURL)("/energy", siteId, "history"), {
1512
+ id: "history",
1513
+ content: data,
1514
+ meta: {
1515
+ kind: "tesla:energy-state",
1516
+ childrenCount: 0
1517
+ }
1518
+ });
1519
+ }
1520
+ async listEnergySiteLive() {
1521
+ return { data: [] };
1522
+ }
1523
+ async listEnergySiteHistory() {
1524
+ return { data: [] };
1525
+ }
1526
+ async metaEnergySiteLive(ctx) {
1527
+ const siteId = ctx.params.siteId;
1528
+ await this.client.resolveEnergySiteId(siteId);
1529
+ return this.buildEntry((0, ufo.joinURL)("/energy", siteId, "live", ".meta"), {
1530
+ id: "meta",
1531
+ content: {
1532
+ kind: "tesla:energy-state",
1533
+ description: "Real-time power flow"
1534
+ },
1535
+ meta: {
1536
+ kind: "tesla:energy-state",
1537
+ childrenCount: 0
1538
+ }
1539
+ });
1540
+ }
1541
+ async metaEnergySiteHistory(ctx) {
1542
+ const siteId = ctx.params.siteId;
1543
+ await this.client.resolveEnergySiteId(siteId);
1544
+ return this.buildEntry((0, ufo.joinURL)("/energy", siteId, "history", ".meta"), {
1545
+ id: "meta",
1546
+ content: {
1547
+ kind: "tesla:energy-state",
1548
+ description: "Historical energy data"
1549
+ },
1550
+ meta: {
1551
+ kind: "tesla:energy-state",
1552
+ childrenCount: 0
1553
+ }
1554
+ });
1555
+ }
1556
+ async statEnergySiteLive(ctx) {
1557
+ const siteId = ctx.params.siteId;
1558
+ await this.client.resolveEnergySiteId(siteId);
1559
+ return { data: this.buildEntry((0, ufo.joinURL)("/energy", siteId, "live"), {
1560
+ id: "live",
1561
+ meta: {
1562
+ kind: "tesla:energy-state",
1563
+ childrenCount: 0
1564
+ }
1565
+ }) };
1566
+ }
1567
+ async statEnergySiteHistory(ctx) {
1568
+ const siteId = ctx.params.siteId;
1569
+ await this.client.resolveEnergySiteId(siteId);
1570
+ return { data: this.buildEntry((0, ufo.joinURL)("/energy", siteId, "history"), {
1571
+ id: "history",
1572
+ meta: {
1573
+ kind: "tesla:energy-state",
1574
+ childrenCount: 0
1575
+ }
1576
+ }) };
1577
+ }
1578
+ async listEnergySiteActions(ctx) {
1579
+ const siteId = ctx.params.siteId;
1580
+ await this.client.resolveEnergySiteId(siteId);
1581
+ return { data: ENERGY_ACTIONS.map((action) => {
1582
+ const entry = this.buildEntry((0, ufo.joinURL)("/energy", siteId, ".actions", action.name), {
1583
+ id: action.name,
1584
+ meta: {
1585
+ kind: "afs:executable",
1586
+ childrenCount: 0,
1587
+ description: action.description,
1588
+ name: action.name,
1589
+ severity: action.severity
1590
+ }
1591
+ });
1592
+ entry.summary = action.name;
1593
+ return entry;
1594
+ }) };
1595
+ }
1596
+ async execEnergySiteAction(ctx, args) {
1597
+ const siteId = ctx.params.siteId;
1598
+ const action = ctx.params.action;
1599
+ if (!ENERGY_ACTIONS.find((a) => a.name === action)) throw new _aigne_afs.AFSNotFoundError((0, ufo.joinURL)("/energy", siteId, ".actions", action), `Unknown energy site action: ${action}`);
1600
+ let apiCommand;
1601
+ let body;
1602
+ switch (action) {
1603
+ case "set-backup-reserve": {
1604
+ const percent = args.percent;
1605
+ if (typeof percent !== "number") throw new _aigne_afs.AFSError("set-backup-reserve requires 'percent' as a number", "AFS_INVALID_ARGUMENT");
1606
+ if (percent < 0 || percent > 100) throw new _aigne_afs.AFSError("set-backup-reserve 'percent' must be between 0 and 100", "AFS_INVALID_ARGUMENT");
1607
+ apiCommand = "backup";
1608
+ body = { backup_reserve_percent: percent };
1609
+ break;
1610
+ }
1611
+ case "set-operation-mode": {
1612
+ const mode = args.mode;
1613
+ if (typeof mode !== "string" || ![
1614
+ "autonomous",
1615
+ "self_consumption",
1616
+ "time_based"
1617
+ ].includes(mode)) throw new _aigne_afs.AFSError("set-operation-mode requires 'mode' as one of: autonomous, self_consumption, time_based", "AFS_INVALID_ARGUMENT");
1618
+ apiCommand = "operation";
1619
+ body = { default_real_mode: mode };
1620
+ break;
1621
+ }
1622
+ case "storm-mode-on":
1623
+ apiCommand = "storm_mode";
1624
+ body = { enabled: true };
1625
+ break;
1626
+ case "storm-mode-off":
1627
+ apiCommand = "storm_mode";
1628
+ body = { enabled: false };
1629
+ break;
1630
+ default: throw new _aigne_afs.AFSNotFoundError((0, ufo.joinURL)("/energy", siteId, ".actions", action), `Unknown energy site action: ${action}`);
1631
+ }
1632
+ await this.client.sendEnergySiteCommand(siteId, apiCommand, body);
1633
+ return {
1634
+ success: true,
1635
+ data: {
1636
+ command: action,
1637
+ siteId
1638
+ }
1639
+ };
1640
+ }
1641
+ };
1642
+ require_decorate.__decorate([(0, _aigne_afs_provider.List)("/")], AFSTesla.prototype, "listRoot", null);
1643
+ require_decorate.__decorate([(0, _aigne_afs_provider.Read)("/")], AFSTesla.prototype, "readRoot", null);
1644
+ require_decorate.__decorate([(0, _aigne_afs_provider.Meta)("/")], AFSTesla.prototype, "metaRoot", null);
1645
+ require_decorate.__decorate([(0, _aigne_afs_provider.Read)("/.meta/.capabilities")], AFSTesla.prototype, "readCapabilities", null);
1646
+ require_decorate.__decorate([(0, _aigne_afs_provider.Stat)("/")], AFSTesla.prototype, "statRoot", null);
1647
+ require_decorate.__decorate([(0, _aigne_afs_provider.Explain)("/")], AFSTesla.prototype, "explainRoot", null);
1648
+ require_decorate.__decorate([(0, _aigne_afs_provider.Search)("/")], AFSTesla.prototype, "searchRoot", null);
1649
+ require_decorate.__decorate([(0, _aigne_afs_provider.Actions)("/")], AFSTesla.prototype, "listRootActions", null);
1650
+ require_decorate.__decorate([_aigne_afs_provider.Actions.Exec("/", "refresh")], AFSTesla.prototype, "execRefresh", null);
1651
+ require_decorate.__decorate([(0, _aigne_afs_provider.List)("/vehicles")], AFSTesla.prototype, "listVehicles", null);
1652
+ require_decorate.__decorate([(0, _aigne_afs_provider.Read)("/vehicles")], AFSTesla.prototype, "readVehiclesGroup", null);
1653
+ require_decorate.__decorate([(0, _aigne_afs_provider.Meta)("/vehicles")], AFSTesla.prototype, "metaVehicles", null);
1654
+ require_decorate.__decorate([(0, _aigne_afs_provider.Stat)("/vehicles")], AFSTesla.prototype, "statVehicles", null);
1655
+ require_decorate.__decorate([(0, _aigne_afs_provider.Search)("/vehicles")], AFSTesla.prototype, "searchVehicles", null);
1656
+ require_decorate.__decorate([(0, _aigne_afs_provider.Explain)("/vehicles")], AFSTesla.prototype, "explainVehicles", null);
1657
+ require_decorate.__decorate([(0, _aigne_afs_provider.List)("/vehicles/:vin")], AFSTesla.prototype, "listVehicleSubPaths", null);
1658
+ require_decorate.__decorate([(0, _aigne_afs_provider.Read)("/vehicles/:vin")], AFSTesla.prototype, "readVehicle", null);
1659
+ require_decorate.__decorate([(0, _aigne_afs_provider.Meta)("/vehicles/:vin")], AFSTesla.prototype, "metaVehicle", null);
1660
+ require_decorate.__decorate([(0, _aigne_afs_provider.Stat)("/vehicles/:vin")], AFSTesla.prototype, "statVehicle", null);
1661
+ require_decorate.__decorate([(0, _aigne_afs_provider.Explain)("/vehicles/:vin")], AFSTesla.prototype, "explainVehicle", null);
1662
+ require_decorate.__decorate([(0, _aigne_afs_provider.Read)("/vehicles/:vin/state")], AFSTesla.prototype, "readVehicleState", null);
1663
+ require_decorate.__decorate([(0, _aigne_afs_provider.Read)("/vehicles/:vin/charge")], AFSTesla.prototype, "readVehicleCharge", null);
1664
+ require_decorate.__decorate([(0, _aigne_afs_provider.Read)("/vehicles/:vin/climate")], AFSTesla.prototype, "readVehicleClimate", null);
1665
+ require_decorate.__decorate([(0, _aigne_afs_provider.Read)("/vehicles/:vin/location")], AFSTesla.prototype, "readVehicleLocation", null);
1666
+ require_decorate.__decorate([(0, _aigne_afs_provider.Read)("/vehicles/:vin/drive")], AFSTesla.prototype, "readVehicleDrive", null);
1667
+ require_decorate.__decorate([(0, _aigne_afs_provider.Read)("/vehicles/:vin/vehicle")], AFSTesla.prototype, "readVehicleVehicle", null);
1668
+ require_decorate.__decorate([(0, _aigne_afs_provider.Read)("/vehicles/:vin/nearby-chargers")], AFSTesla.prototype, "readVehicleNearbyChargers", null);
1669
+ require_decorate.__decorate([(0, _aigne_afs_provider.Read)("/vehicles/:vin/release-notes")], AFSTesla.prototype, "readVehicleReleaseNotes", null);
1670
+ require_decorate.__decorate([(0, _aigne_afs_provider.Stat)("/vehicles/:vin/state")], AFSTesla.prototype, "statVehicleState", null);
1671
+ require_decorate.__decorate([(0, _aigne_afs_provider.Stat)("/vehicles/:vin/charge")], AFSTesla.prototype, "statVehicleCharge", null);
1672
+ require_decorate.__decorate([(0, _aigne_afs_provider.Stat)("/vehicles/:vin/climate")], AFSTesla.prototype, "statVehicleClimate", null);
1673
+ require_decorate.__decorate([(0, _aigne_afs_provider.Stat)("/vehicles/:vin/location")], AFSTesla.prototype, "statVehicleLocation", null);
1674
+ require_decorate.__decorate([(0, _aigne_afs_provider.Stat)("/vehicles/:vin/drive")], AFSTesla.prototype, "statVehicleDrive", null);
1675
+ require_decorate.__decorate([(0, _aigne_afs_provider.Stat)("/vehicles/:vin/vehicle")], AFSTesla.prototype, "statVehicleVehicle", null);
1676
+ require_decorate.__decorate([(0, _aigne_afs_provider.Stat)("/vehicles/:vin/nearby-chargers")], AFSTesla.prototype, "statVehicleNearbyChargers", null);
1677
+ require_decorate.__decorate([(0, _aigne_afs_provider.Stat)("/vehicles/:vin/release-notes")], AFSTesla.prototype, "statVehicleReleaseNotes", null);
1678
+ require_decorate.__decorate([(0, _aigne_afs_provider.Meta)("/vehicles/:vin/state")], AFSTesla.prototype, "metaVehicleState", null);
1679
+ require_decorate.__decorate([(0, _aigne_afs_provider.Meta)("/vehicles/:vin/charge")], AFSTesla.prototype, "metaVehicleCharge", null);
1680
+ require_decorate.__decorate([(0, _aigne_afs_provider.Meta)("/vehicles/:vin/climate")], AFSTesla.prototype, "metaVehicleClimate", null);
1681
+ require_decorate.__decorate([(0, _aigne_afs_provider.Meta)("/vehicles/:vin/location")], AFSTesla.prototype, "metaVehicleLocation", null);
1682
+ require_decorate.__decorate([(0, _aigne_afs_provider.Meta)("/vehicles/:vin/drive")], AFSTesla.prototype, "metaVehicleDrive", null);
1683
+ require_decorate.__decorate([(0, _aigne_afs_provider.Meta)("/vehicles/:vin/vehicle")], AFSTesla.prototype, "metaVehicleVehicle", null);
1684
+ require_decorate.__decorate([(0, _aigne_afs_provider.Meta)("/vehicles/:vin/nearby-chargers")], AFSTesla.prototype, "metaVehicleNearbyChargers", null);
1685
+ require_decorate.__decorate([(0, _aigne_afs_provider.Meta)("/vehicles/:vin/release-notes")], AFSTesla.prototype, "metaVehicleReleaseNotes", null);
1686
+ require_decorate.__decorate([(0, _aigne_afs_provider.List)("/vehicles/:vin/state")], AFSTesla.prototype, "listVehicleState", null);
1687
+ require_decorate.__decorate([(0, _aigne_afs_provider.List)("/vehicles/:vin/charge")], AFSTesla.prototype, "listVehicleCharge", null);
1688
+ require_decorate.__decorate([(0, _aigne_afs_provider.List)("/vehicles/:vin/climate")], AFSTesla.prototype, "listVehicleClimate", null);
1689
+ require_decorate.__decorate([(0, _aigne_afs_provider.List)("/vehicles/:vin/location")], AFSTesla.prototype, "listVehicleLocation", null);
1690
+ require_decorate.__decorate([(0, _aigne_afs_provider.List)("/vehicles/:vin/drive")], AFSTesla.prototype, "listVehicleDrive", null);
1691
+ require_decorate.__decorate([(0, _aigne_afs_provider.List)("/vehicles/:vin/vehicle")], AFSTesla.prototype, "listVehicleVehicle", null);
1692
+ require_decorate.__decorate([(0, _aigne_afs_provider.List)("/vehicles/:vin/nearby-chargers")], AFSTesla.prototype, "listVehicleNearbyChargers", null);
1693
+ require_decorate.__decorate([(0, _aigne_afs_provider.List)("/vehicles/:vin/release-notes")], AFSTesla.prototype, "listVehicleReleaseNotes", null);
1694
+ require_decorate.__decorate([(0, _aigne_afs_provider.Actions)("/vehicles/:vin")], AFSTesla.prototype, "listVehicleActions", null);
1695
+ require_decorate.__decorate([_aigne_afs_provider.Actions.Exec("/vehicles/:vin")], AFSTesla.prototype, "execVehicleAction", null);
1696
+ require_decorate.__decorate([(0, _aigne_afs_provider.List)("/energy")], AFSTesla.prototype, "listEnergySites", null);
1697
+ require_decorate.__decorate([(0, _aigne_afs_provider.Read)("/energy")], AFSTesla.prototype, "readEnergyGroup", null);
1698
+ require_decorate.__decorate([(0, _aigne_afs_provider.Meta)("/energy")], AFSTesla.prototype, "metaEnergy", null);
1699
+ require_decorate.__decorate([(0, _aigne_afs_provider.Stat)("/energy")], AFSTesla.prototype, "statEnergy", null);
1700
+ require_decorate.__decorate([(0, _aigne_afs_provider.Search)("/energy")], AFSTesla.prototype, "searchEnergy", null);
1701
+ require_decorate.__decorate([(0, _aigne_afs_provider.Explain)("/energy")], AFSTesla.prototype, "explainEnergy", null);
1702
+ require_decorate.__decorate([(0, _aigne_afs_provider.List)("/energy/:siteId")], AFSTesla.prototype, "listEnergySiteSubPaths", null);
1703
+ require_decorate.__decorate([(0, _aigne_afs_provider.Read)("/energy/:siteId")], AFSTesla.prototype, "readEnergySite", null);
1704
+ require_decorate.__decorate([(0, _aigne_afs_provider.Meta)("/energy/:siteId")], AFSTesla.prototype, "metaEnergySite", null);
1705
+ require_decorate.__decorate([(0, _aigne_afs_provider.Stat)("/energy/:siteId")], AFSTesla.prototype, "statEnergySite", null);
1706
+ require_decorate.__decorate([(0, _aigne_afs_provider.Explain)("/energy/:siteId")], AFSTesla.prototype, "explainEnergySite", null);
1707
+ require_decorate.__decorate([(0, _aigne_afs_provider.Read)("/energy/:siteId/live")], AFSTesla.prototype, "readEnergySiteLive", null);
1708
+ require_decorate.__decorate([(0, _aigne_afs_provider.Read)("/energy/:siteId/history")], AFSTesla.prototype, "readEnergySiteHistory", null);
1709
+ require_decorate.__decorate([(0, _aigne_afs_provider.List)("/energy/:siteId/live")], AFSTesla.prototype, "listEnergySiteLive", null);
1710
+ require_decorate.__decorate([(0, _aigne_afs_provider.List)("/energy/:siteId/history")], AFSTesla.prototype, "listEnergySiteHistory", null);
1711
+ require_decorate.__decorate([(0, _aigne_afs_provider.Meta)("/energy/:siteId/live")], AFSTesla.prototype, "metaEnergySiteLive", null);
1712
+ require_decorate.__decorate([(0, _aigne_afs_provider.Meta)("/energy/:siteId/history")], AFSTesla.prototype, "metaEnergySiteHistory", null);
1713
+ require_decorate.__decorate([(0, _aigne_afs_provider.Stat)("/energy/:siteId/live")], AFSTesla.prototype, "statEnergySiteLive", null);
1714
+ require_decorate.__decorate([(0, _aigne_afs_provider.Stat)("/energy/:siteId/history")], AFSTesla.prototype, "statEnergySiteHistory", null);
1715
+ require_decorate.__decorate([(0, _aigne_afs_provider.Actions)("/energy/:siteId")], AFSTesla.prototype, "listEnergySiteActions", null);
1716
+ require_decorate.__decorate([_aigne_afs_provider.Actions.Exec("/energy/:siteId")], AFSTesla.prototype, "execEnergySiteAction", null);
1717
+
1718
+ //#endregion
1719
+ exports.AFSTesla = AFSTesla;
1720
+ exports.afsTeslaOptionsSchema = afsTeslaOptionsSchema;