arcsecond 3.20.0__tar.gz → 3.20.2__tar.gz
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.
- {arcsecond-3.20.0 → arcsecond-3.20.2}/PKG-INFO +1 -1
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/alpaca/commands.py +74 -31
- arcsecond-3.20.2/arcsecond/alpaca/dome_probe.py +89 -0
- arcsecond-3.20.0/arcsecond/alpaca/dome_probe.py → arcsecond-3.20.2/arcsecond/alpaca/probe.py +194 -106
- arcsecond-3.20.2/arcsecond/alpaca/telescope_probe.py +180 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/api/endpoint.py +30 -1
- {arcsecond-3.20.0 → arcsecond-3.20.2}/pyproject.toml +1 -1
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/api/test_api_endpoint.py +64 -6
- arcsecond-3.20.2/tests/test_alpaca_probe.py +883 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/uv.lock +1 -1
- arcsecond-3.20.0/tests/test_alpaca_probe.py +0 -406
- {arcsecond-3.20.0 → arcsecond-3.20.2}/.docker/Dockerfile_postgres +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/.docker/Dockerfile_redis +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/.flake8 +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/.github/dependabot.yml +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/.github/workflows/pythonpublish.yml +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/.github/workflows/tests.yml +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/.gitignore +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/LICENSE +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/Makefile +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/README.md +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/__init__.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/__version__.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/alpaca/__init__.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/api/__init__.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/api/config.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/api/constants.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/api/main.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/api/resources.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/cli.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/cloud/__init__.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/cloud/auth.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/cloud/resources.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/cloud/uploader/__init__.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/cloud/uploader/constants.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/cloud/uploader/context.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/cloud/uploader/datafiles/__init__.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/cloud/uploader/datafiles/context.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/cloud/uploader/datafiles/errors.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/cloud/uploader/datafiles/uploader.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/cloud/uploader/datafiles/utils.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/cloud/uploader/errors.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/cloud/uploader/logger.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/cloud/uploader/uploader.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/cloud/uploader/utils.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/cloud/uploader/walker.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/cloud/uploads.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/errors.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/hosting/__init__.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/hosting/backups.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/hosting/checks.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/hosting/constants.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/hosting/database.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/hosting/docker/__init__.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/hosting/docker/constants.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/hosting/docker/containers.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/hosting/docker/docker-compose.yml +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/hosting/docker/images.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/hosting/docker/utils.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/hosting/keygen/__init__.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/hosting/keygen/client.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/hosting/keygen/utils.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/hosting/local.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/hosting/main.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/hosting/postgres/init-db.sh +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/hosting/setup.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/hosting/utils.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/hosting/validation.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/imagesources/__init__.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/imagesources/commands.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/imagesources/detection.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/imagesources/proxy.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/imagesources/registry.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/imagesources/runtime.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/imagesources/sources/__init__.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/imagesources/sources/base.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/imagesources/sources/filewatch.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/imagesources/sources/mdns.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/imagesources/sources/network.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/imagesources/sources/opencv.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/imagesources/store.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/options.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/arcsecond/targets.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/examples/example_upload_files.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/requirements.txt +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/setup.cfg +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/setup.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/sonar-project.properties +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/__init__.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/api/__init__.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/api/test_api.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/api/test_config.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/api/test_targets.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/cloud/__init__.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/cloud/uploader/__init__.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/cloud/uploader/datafiles/__init__.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/cloud/uploader/datafiles/test_uploader_errors.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/cloud/uploader/datafiles/test_uploader_full_process.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/cloud/uploader/datafiles/test_uploader_init.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/cloud/uploader/datafiles/test_uploader_prepare.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/cloud/uploader/datafiles/test_uploader_upload.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/conftest.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/fixtures/file1.fits +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/test_cli.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/test_hosting_backups_restore.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/test_hosting_database.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/test_hosting_local.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/test_hosting_utils_secret_key.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/test_imagesources_commands.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/test_imagesources_detection.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/test_imagesources_mdns.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/test_imagesources_network.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/test_imagesources_proxy.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/test_imagesources_store.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/test_imagesources_webcam.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/test_targets_planning.py +0 -0
- {arcsecond-3.20.0 → arcsecond-3.20.2}/tests/utils.py +0 -0
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Click command group: ``arcsecond alpaca``.
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
``SupportedActions``, ``CommandString`` /
|
|
7
|
-
passthrough behaviour, and
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
``probe camera`` / ``probe focuser`` and
|
|
11
|
-
under the same group.
|
|
4
|
+
``arcsecond alpaca probe dome`` and ``arcsecond alpaca probe telescope`` are
|
|
5
|
+
read-only diagnostics that capture what surface a given Alpaca device server
|
|
6
|
+
exposes (device metadata, ``SupportedActions``, ``CommandString`` /
|
|
7
|
+
``CommandBool`` / ``CommandBlind`` passthrough behaviour, and local host hints
|
|
8
|
+
when the target is this machine), one JSON report per run.
|
|
9
|
+
|
|
10
|
+
Structure leaves room for ``probe camera`` / ``probe focuser`` and
|
|
11
|
+
``arcsecond alpaca discover`` later under the same group.
|
|
12
12
|
"""
|
|
13
13
|
|
|
14
14
|
from __future__ import annotations
|
|
@@ -17,11 +17,14 @@ import json
|
|
|
17
17
|
import os
|
|
18
18
|
from datetime import datetime, timezone
|
|
19
19
|
from pathlib import Path
|
|
20
|
+
from typing import Callable
|
|
20
21
|
|
|
21
22
|
import click
|
|
22
23
|
|
|
23
24
|
from ..errors import ArcsecondError
|
|
24
|
-
from .dome_probe import
|
|
25
|
+
from .dome_probe import probe_dome
|
|
26
|
+
from .probe import HOST_HINTS_REASON_LOCAL, ProbeProgress, ProbeResult
|
|
27
|
+
from .telescope_probe import probe_telescope
|
|
25
28
|
|
|
26
29
|
|
|
27
30
|
@click.group(name="alpaca", help="Diagnostics for local ASCOM Alpaca devices.")
|
|
@@ -72,12 +75,15 @@ _COMMON_OPTIONS = [
|
|
|
72
75
|
),
|
|
73
76
|
),
|
|
74
77
|
click.option(
|
|
75
|
-
"--collect-host-info",
|
|
76
|
-
|
|
77
|
-
default=
|
|
78
|
+
"--collect-host-info/--no-host-info",
|
|
79
|
+
"collect_host_info",
|
|
80
|
+
default=None,
|
|
78
81
|
help=(
|
|
79
|
-
"
|
|
80
|
-
"
|
|
82
|
+
"Best-effort local OS hints (open ports, COM ProgIDs matching "
|
|
83
|
+
"TCS/Galil), read-only. Collected automatically when HOST is this "
|
|
84
|
+
"machine, the only case in which they describe the Alpaca server's "
|
|
85
|
+
"host. --collect-host-info forces them for a remote HOST; "
|
|
86
|
+
"--no-host-info skips them."
|
|
81
87
|
),
|
|
82
88
|
),
|
|
83
89
|
click.option(
|
|
@@ -104,37 +110,38 @@ def _default_output_path(kind: str) -> str:
|
|
|
104
110
|
return str(Path.cwd() / f"alpaca_{kind}_probe_{stamp}.json")
|
|
105
111
|
|
|
106
112
|
|
|
113
|
+
def _describe_host_hints(report: dict) -> str:
|
|
114
|
+
hints = report.get("host_hints")
|
|
115
|
+
if hints is None:
|
|
116
|
+
return f"skipped ({report.get('host_hints_skipped_reason', 'not collected')})"
|
|
117
|
+
if hints.get("collected_because") == HOST_HINTS_REASON_LOCAL:
|
|
118
|
+
return "collected (HOST is this machine)"
|
|
119
|
+
return "collected (--collect-host-info)"
|
|
120
|
+
|
|
121
|
+
|
|
107
122
|
def _format_progress(label: str, ok: bool, detail: str | None) -> str:
|
|
108
123
|
tag = click.style("[OK ]", fg="green") if ok else click.style("[ERR]", fg="red")
|
|
109
124
|
suffix = f" — {detail}" if detail else ""
|
|
110
125
|
return f" {tag} {label}{suffix}"
|
|
111
126
|
|
|
112
127
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
"Captures device metadata, SupportedActions, and the behaviour of the "
|
|
118
|
-
"legacy CommandString / CommandBool / CommandBlind passthroughs. "
|
|
119
|
-
"Useful for figuring out whether a proprietary driver (e.g. TCSGalil) "
|
|
120
|
-
"exposes any vendor-specific extension surface beyond the standard "
|
|
121
|
-
"ASCOM IDome interface."
|
|
122
|
-
),
|
|
123
|
-
)
|
|
124
|
-
@_add_options(_COMMON_OPTIONS)
|
|
125
|
-
def probe_dome_cmd(
|
|
128
|
+
def _run_probe(
|
|
129
|
+
kind: str,
|
|
130
|
+
runner: Callable[..., ProbeResult],
|
|
131
|
+
*,
|
|
126
132
|
host: str,
|
|
127
133
|
port: int,
|
|
128
134
|
device_number: int,
|
|
129
135
|
protocol: str,
|
|
130
136
|
allow_active: bool,
|
|
131
|
-
collect_host_info: bool,
|
|
137
|
+
collect_host_info: bool | None,
|
|
132
138
|
output_path: str | None,
|
|
133
139
|
) -> None:
|
|
134
|
-
|
|
140
|
+
"""Drive one probe from the terminal: banner, progress lines, report, summary."""
|
|
141
|
+
output_path = output_path or _default_output_path(kind)
|
|
135
142
|
|
|
136
143
|
click.echo(
|
|
137
|
-
click.style("Alpaca
|
|
144
|
+
click.style(f"Alpaca {kind} probe", bold=True)
|
|
138
145
|
+ f" → {protocol}://{host}:{port} (device {device_number})"
|
|
139
146
|
)
|
|
140
147
|
if allow_active:
|
|
@@ -150,7 +157,7 @@ def probe_dome_cmd(
|
|
|
150
157
|
)
|
|
151
158
|
|
|
152
159
|
try:
|
|
153
|
-
result =
|
|
160
|
+
result = runner(
|
|
154
161
|
host=host,
|
|
155
162
|
port=port,
|
|
156
163
|
device_number=device_number,
|
|
@@ -177,4 +184,40 @@ def probe_dome_cmd(
|
|
|
177
184
|
click.echo(click.style("Summary", bold=True))
|
|
178
185
|
click.echo(f" Probes: {counts.ok}/{counts.total} OK")
|
|
179
186
|
click.echo(f" SupportedActions: {supported_n} entries")
|
|
187
|
+
click.echo(f" Host hints: {_describe_host_hints(result.report)}")
|
|
180
188
|
click.echo(f" Report written to {click.style(os.fspath(output_path), fg='cyan')}")
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
@probe_group.command(
|
|
192
|
+
name="dome",
|
|
193
|
+
help=(
|
|
194
|
+
"Probe a local Alpaca dome device read-only and write a JSON report.\n\n"
|
|
195
|
+
"Captures device metadata, SupportedActions, and the behaviour of the "
|
|
196
|
+
"legacy CommandString / CommandBool / CommandBlind passthroughs. "
|
|
197
|
+
"Useful for figuring out whether a proprietary driver (e.g. TCSGalil) "
|
|
198
|
+
"exposes any vendor-specific extension surface beyond the standard "
|
|
199
|
+
"ASCOM IDome interface. Local host hints (open ports, COM ProgIDs) "
|
|
200
|
+
"are added when HOST is this machine."
|
|
201
|
+
),
|
|
202
|
+
)
|
|
203
|
+
@_add_options(_COMMON_OPTIONS)
|
|
204
|
+
def probe_dome_cmd(**options) -> None:
|
|
205
|
+
_run_probe("dome", probe_dome, **options)
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
@probe_group.command(
|
|
209
|
+
name="telescope",
|
|
210
|
+
help=(
|
|
211
|
+
"Probe a local Alpaca telescope (mount) device read-only and write a "
|
|
212
|
+
"JSON report.\n\n"
|
|
213
|
+
"Captures device metadata, optics, site, pointing and tracking state, "
|
|
214
|
+
"capabilities, CanMoveAxis and AxisRates per movable axis, "
|
|
215
|
+
"SupportedActions, and the behaviour of the legacy CommandString / "
|
|
216
|
+
"CommandBool / CommandBlind passthroughs. Never moves the mount. "
|
|
217
|
+
"Local host hints (open ports, COM ProgIDs) are added when HOST is "
|
|
218
|
+
"this machine."
|
|
219
|
+
),
|
|
220
|
+
)
|
|
221
|
+
@_add_options(_COMMON_OPTIONS)
|
|
222
|
+
def probe_telescope_cmd(**options) -> None:
|
|
223
|
+
_run_probe("telescope", probe_telescope, **options)
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Read-only diagnostic for an ASCOM Alpaca *dome* device.
|
|
3
|
+
|
|
4
|
+
The standard ASCOM Alpaca ``IDome`` interface only exposes a single
|
|
5
|
+
``OpenShutter`` / ``CloseShutter`` pair. Multi-shutter domes (e.g. DFM domes
|
|
6
|
+
driven by TCSGalil) coordinate their shutters internally; if the driver does
|
|
7
|
+
not advertise per-shutter custom actions via ``SupportedActions``, there is
|
|
8
|
+
no canonical client-side way to drive the upper and lower shutters
|
|
9
|
+
independently. This probe writes down exactly what surface a dome server
|
|
10
|
+
exposes, so that decision can be made on evidence.
|
|
11
|
+
|
|
12
|
+
The engine, the report layout and the safety rules live in :mod:`.probe`;
|
|
13
|
+
this module only says which dome properties to read.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
from typing import Any, Callable, Iterable
|
|
19
|
+
|
|
20
|
+
from .probe import ProbeProgress, ProbeResult, probe_device
|
|
21
|
+
from .probe import iter_probe_labels as _iter_probe_labels
|
|
22
|
+
|
|
23
|
+
# Read-only device descriptors and dome state, in the order we want them
|
|
24
|
+
# presented in the report. Names are PascalCase to match the alpyca surface.
|
|
25
|
+
_READ_ONLY_PROPERTIES: tuple[str, ...] = (
|
|
26
|
+
"Name",
|
|
27
|
+
"Description",
|
|
28
|
+
"DriverInfo",
|
|
29
|
+
"DriverVersion",
|
|
30
|
+
"InterfaceVersion",
|
|
31
|
+
"ShutterStatus",
|
|
32
|
+
"Altitude",
|
|
33
|
+
"Azimuth",
|
|
34
|
+
"AtHome",
|
|
35
|
+
"AtPark",
|
|
36
|
+
"Slewing",
|
|
37
|
+
"Slaved",
|
|
38
|
+
"CanFindHome",
|
|
39
|
+
"CanPark",
|
|
40
|
+
"CanSetAltitude",
|
|
41
|
+
"CanSetPark",
|
|
42
|
+
"CanSetShutter",
|
|
43
|
+
"CanSlave",
|
|
44
|
+
"CanSyncAzimuth",
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def probe_dome(
|
|
49
|
+
host: str,
|
|
50
|
+
port: int,
|
|
51
|
+
device_number: int = 0,
|
|
52
|
+
*,
|
|
53
|
+
protocol: str = "http",
|
|
54
|
+
allow_active: bool = False,
|
|
55
|
+
collect_host_info: bool | None = None,
|
|
56
|
+
dome_factory: Callable[[str, int, str], Any] | None = None,
|
|
57
|
+
progress: ProbeProgress | None = None,
|
|
58
|
+
) -> ProbeResult:
|
|
59
|
+
"""
|
|
60
|
+
Build a JSON-serialisable diagnostic report for an Alpaca dome at
|
|
61
|
+
``protocol://host:port`` (device_number). See :func:`.probe.probe_device`
|
|
62
|
+
for the ``collect_host_info`` semantics.
|
|
63
|
+
|
|
64
|
+
``dome_factory(address, device_number, protocol)`` is only there for
|
|
65
|
+
tests — production callers leave it ``None`` and the real
|
|
66
|
+
``alpaca.dome.Dome`` is used.
|
|
67
|
+
"""
|
|
68
|
+
if dome_factory is None:
|
|
69
|
+
from alpaca.dome import Dome # local import: keep cost off cold paths
|
|
70
|
+
|
|
71
|
+
dome_factory = Dome
|
|
72
|
+
|
|
73
|
+
return probe_device(
|
|
74
|
+
"dome",
|
|
75
|
+
host,
|
|
76
|
+
port,
|
|
77
|
+
device_number,
|
|
78
|
+
properties=_READ_ONLY_PROPERTIES,
|
|
79
|
+
device_factory=dome_factory,
|
|
80
|
+
protocol=protocol,
|
|
81
|
+
allow_active=allow_active,
|
|
82
|
+
collect_host_info=collect_host_info,
|
|
83
|
+
progress=progress,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def iter_probe_labels() -> Iterable[str]:
|
|
88
|
+
"""Convenience for tests / docs: enumerate the labels emitted by a run."""
|
|
89
|
+
return _iter_probe_labels(_READ_ONLY_PROPERTIES)
|