tescmd 0.1.2__py3-none-any.whl
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.
- tescmd/__init__.py +3 -0
- tescmd/__main__.py +5 -0
- tescmd/_internal/__init__.py +0 -0
- tescmd/_internal/async_utils.py +25 -0
- tescmd/_internal/permissions.py +43 -0
- tescmd/_internal/vin.py +44 -0
- tescmd/api/__init__.py +1 -0
- tescmd/api/charging.py +102 -0
- tescmd/api/client.py +189 -0
- tescmd/api/command.py +540 -0
- tescmd/api/energy.py +146 -0
- tescmd/api/errors.py +76 -0
- tescmd/api/partner.py +40 -0
- tescmd/api/sharing.py +65 -0
- tescmd/api/signed_command.py +277 -0
- tescmd/api/user.py +38 -0
- tescmd/api/vehicle.py +150 -0
- tescmd/auth/__init__.py +1 -0
- tescmd/auth/oauth.py +312 -0
- tescmd/auth/server.py +108 -0
- tescmd/auth/token_store.py +273 -0
- tescmd/ble/__init__.py +0 -0
- tescmd/cache/__init__.py +6 -0
- tescmd/cache/keys.py +51 -0
- tescmd/cache/response_cache.py +213 -0
- tescmd/cli/__init__.py +0 -0
- tescmd/cli/_client.py +603 -0
- tescmd/cli/_options.py +126 -0
- tescmd/cli/auth.py +682 -0
- tescmd/cli/billing.py +240 -0
- tescmd/cli/cache.py +85 -0
- tescmd/cli/charge.py +610 -0
- tescmd/cli/climate.py +501 -0
- tescmd/cli/energy.py +385 -0
- tescmd/cli/key.py +611 -0
- tescmd/cli/main.py +601 -0
- tescmd/cli/media.py +146 -0
- tescmd/cli/nav.py +242 -0
- tescmd/cli/partner.py +112 -0
- tescmd/cli/raw.py +75 -0
- tescmd/cli/security.py +495 -0
- tescmd/cli/setup.py +786 -0
- tescmd/cli/sharing.py +188 -0
- tescmd/cli/software.py +81 -0
- tescmd/cli/status.py +106 -0
- tescmd/cli/trunk.py +240 -0
- tescmd/cli/user.py +145 -0
- tescmd/cli/vehicle.py +837 -0
- tescmd/config/__init__.py +0 -0
- tescmd/crypto/__init__.py +19 -0
- tescmd/crypto/ecdh.py +46 -0
- tescmd/crypto/keys.py +122 -0
- tescmd/deploy/__init__.py +0 -0
- tescmd/deploy/github_pages.py +268 -0
- tescmd/models/__init__.py +85 -0
- tescmd/models/auth.py +108 -0
- tescmd/models/command.py +18 -0
- tescmd/models/config.py +63 -0
- tescmd/models/energy.py +56 -0
- tescmd/models/sharing.py +26 -0
- tescmd/models/user.py +37 -0
- tescmd/models/vehicle.py +185 -0
- tescmd/output/__init__.py +5 -0
- tescmd/output/formatter.py +132 -0
- tescmd/output/json_output.py +83 -0
- tescmd/output/rich_output.py +809 -0
- tescmd/protocol/__init__.py +23 -0
- tescmd/protocol/commands.py +175 -0
- tescmd/protocol/encoder.py +122 -0
- tescmd/protocol/metadata.py +116 -0
- tescmd/protocol/payloads.py +621 -0
- tescmd/protocol/protobuf/__init__.py +6 -0
- tescmd/protocol/protobuf/messages.py +564 -0
- tescmd/protocol/session.py +318 -0
- tescmd/protocol/signer.py +84 -0
- tescmd/py.typed +0 -0
- tescmd-0.1.2.dist-info/METADATA +458 -0
- tescmd-0.1.2.dist-info/RECORD +81 -0
- tescmd-0.1.2.dist-info/WHEEL +4 -0
- tescmd-0.1.2.dist-info/entry_points.txt +2 -0
- tescmd-0.1.2.dist-info/licenses/LICENSE +21 -0
tescmd/cli/_options.py
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"""Shared CLI decorator that propagates global options to leaf commands."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import functools
|
|
6
|
+
import logging
|
|
7
|
+
from typing import TYPE_CHECKING, Any
|
|
8
|
+
|
|
9
|
+
import click
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from tescmd.cli.main import AppContext
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def global_options(f: Any) -> Any:
|
|
16
|
+
"""Add global CLI options to a leaf command.
|
|
17
|
+
|
|
18
|
+
Allows ``--vin``, ``--profile``, ``--format``, ``--quiet``, ``--region``,
|
|
19
|
+
and ``--verbose`` to be specified **after** the subcommand name (e.g.
|
|
20
|
+
``tescmd vehicle info --vin X``). Command-level values override the
|
|
21
|
+
root-group values stored in :class:`AppContext`.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
@click.option(
|
|
25
|
+
"--units",
|
|
26
|
+
"local_units",
|
|
27
|
+
type=click.Choice(["us", "metric"]),
|
|
28
|
+
default=None,
|
|
29
|
+
help="Display units preset (us: °F/mi/psi, metric: °C/km/bar)",
|
|
30
|
+
)
|
|
31
|
+
@click.option(
|
|
32
|
+
"--wake",
|
|
33
|
+
"local_wake",
|
|
34
|
+
is_flag=True,
|
|
35
|
+
default=False,
|
|
36
|
+
help="Auto-wake vehicle without confirmation (billable)",
|
|
37
|
+
)
|
|
38
|
+
@click.option(
|
|
39
|
+
"--no-cache",
|
|
40
|
+
"--fresh",
|
|
41
|
+
"local_no_cache",
|
|
42
|
+
is_flag=True,
|
|
43
|
+
default=False,
|
|
44
|
+
help="Bypass response cache",
|
|
45
|
+
)
|
|
46
|
+
@click.option(
|
|
47
|
+
"--verbose",
|
|
48
|
+
"local_verbose",
|
|
49
|
+
is_flag=True,
|
|
50
|
+
default=False,
|
|
51
|
+
help="Enable verbose logging",
|
|
52
|
+
)
|
|
53
|
+
@click.option(
|
|
54
|
+
"--region",
|
|
55
|
+
"local_region",
|
|
56
|
+
type=click.Choice(["na", "eu", "cn"]),
|
|
57
|
+
default=None,
|
|
58
|
+
help="Tesla API region",
|
|
59
|
+
)
|
|
60
|
+
@click.option(
|
|
61
|
+
"--quiet",
|
|
62
|
+
"local_quiet",
|
|
63
|
+
is_flag=True,
|
|
64
|
+
default=False,
|
|
65
|
+
help="Suppress normal output",
|
|
66
|
+
)
|
|
67
|
+
@click.option(
|
|
68
|
+
"--format",
|
|
69
|
+
"local_output_format",
|
|
70
|
+
type=click.Choice(["rich", "json", "quiet"]),
|
|
71
|
+
default=None,
|
|
72
|
+
help="Output format (default: auto-detect)",
|
|
73
|
+
)
|
|
74
|
+
@click.option("--profile", "local_profile", default=None, help="Config profile name")
|
|
75
|
+
@click.option("--vin", "local_vin", default=None, help="Vehicle VIN")
|
|
76
|
+
@click.pass_obj
|
|
77
|
+
def wrapper(app_ctx: AppContext, /, **kwargs: Any) -> Any:
|
|
78
|
+
# Pop command-level global-option overrides
|
|
79
|
+
local_vin: str | None = kwargs.pop("local_vin", None)
|
|
80
|
+
local_profile: str | None = kwargs.pop("local_profile", None)
|
|
81
|
+
local_output_format: str | None = kwargs.pop("local_output_format", None)
|
|
82
|
+
local_quiet: bool = kwargs.pop("local_quiet", False)
|
|
83
|
+
local_region: str | None = kwargs.pop("local_region", None)
|
|
84
|
+
local_verbose: bool = kwargs.pop("local_verbose", False)
|
|
85
|
+
local_no_cache: bool = kwargs.pop("local_no_cache", False)
|
|
86
|
+
local_wake: bool = kwargs.pop("local_wake", False)
|
|
87
|
+
local_units: str | None = kwargs.pop("local_units", None)
|
|
88
|
+
|
|
89
|
+
# Merge overrides into AppContext (command-level wins)
|
|
90
|
+
if local_vin is not None:
|
|
91
|
+
app_ctx.vin = local_vin
|
|
92
|
+
if local_profile is not None:
|
|
93
|
+
app_ctx.profile = local_profile
|
|
94
|
+
if local_output_format is not None:
|
|
95
|
+
app_ctx.output_format = local_output_format
|
|
96
|
+
app_ctx._formatter = None # reset cached formatter
|
|
97
|
+
if local_quiet:
|
|
98
|
+
app_ctx.quiet = True
|
|
99
|
+
app_ctx._formatter = None
|
|
100
|
+
if local_region is not None:
|
|
101
|
+
app_ctx.region = local_region
|
|
102
|
+
if local_verbose:
|
|
103
|
+
app_ctx.verbose = True
|
|
104
|
+
logging.basicConfig(
|
|
105
|
+
level=logging.DEBUG,
|
|
106
|
+
format="%(name)s %(levelname)s: %(message)s",
|
|
107
|
+
)
|
|
108
|
+
if local_no_cache:
|
|
109
|
+
app_ctx.no_cache = True
|
|
110
|
+
if local_wake:
|
|
111
|
+
app_ctx.auto_wake = True
|
|
112
|
+
if local_units is not None:
|
|
113
|
+
if local_units == "metric":
|
|
114
|
+
app_ctx.temp_unit = "C"
|
|
115
|
+
app_ctx.distance_unit = "km"
|
|
116
|
+
app_ctx.pressure_unit = "bar"
|
|
117
|
+
else:
|
|
118
|
+
app_ctx.temp_unit = "F"
|
|
119
|
+
app_ctx.distance_unit = "mi"
|
|
120
|
+
app_ctx.pressure_unit = "psi"
|
|
121
|
+
app_ctx._formatter = None # reset cached formatter
|
|
122
|
+
|
|
123
|
+
return f(app_ctx, **kwargs)
|
|
124
|
+
|
|
125
|
+
functools.update_wrapper(wrapper, f)
|
|
126
|
+
return wrapper
|