Add the DomeWindScreen interface - #267
Conversation
Declares the wind-screen dome role (move_screen/get_screen + windscreen_begin/complete events) alongside DomeSlit/DomeFlap, and fixes the DomeFlap docstring (was 'Dome with Slit'). Interface only - no driver implements it yet; drafted so the in-progress work is not lost. Not deployed on opd-40 (the LNA dome has no wind screen).
…stroufsc#253 over master Audit follow-up. Reset every file that was diverging from upstream/master without an open PR back to master, per review decisions: - imagerequest.py: revert the dome-sync blast-radius containment (astroufsc#261 closed unmerged - a dome that cannot sync SHOULD fail the program); - DomeWindScreen + sextractor source-extractor fix: moved to their own draft PRs (astroufsc#267, astroufsc#268), dropped here (not needed on opd-40); - bus.py _outbound_dead vestige: dead after the merged bus refactor; - cli/guide.py: superseded by cli/guider.py (merged astroufsc#246); - misc core (constants, manager, proxy, fakes, old tests, AGENTS): master. Deploy branch now = upstream/master + astroufsc#255 + astroufsc#259 + astroufsc#253 content only.
The event was published as 'windscren_begin': EventWrapperDispatcher publishes under func.__name__, so the typo was the wire name and every subscriber would have to misspell it too. The default on windscreen_complete's status was inert and misleading: the event body never runs, the dispatcher forwards the call args verbatim, so firing it without arguments publishes an empty payload and breaks subscribers that declare the parameter. Status is now required and the events carry the altitude, like slew_begin/slew_complete carry the position. Also: name the screen consistently (screen_*), document units and datum (decimal degrees, horizon = 0, zenith = 90 -- ASCOM's Dome.Altitude convention), document the out-of-range exception, give get_screen the '...' body the other value-returning declarations in this module have, and export the dome sub-interfaces from __all__.
A screen move takes tens of seconds, so callers need is_screen_moving() to wait on it and abort_screen() to stop it -- without an abort there was also no way to ever reach screen_complete(ABORTED). ASCOM covers the same ground with Slewing/AbortSlew, which apply to dome altitude too. The config is what makes the screen usable without driver-private settings: travel limits for the range check, a resolution deadband and an offset for tracking, a park position for shutdown and a timeout for drivers, matching the slit's open/close_timeout. Both DomeConfig and __config__ carry it, they are duplicated in this module.
DomeBase gains the tracking half of the contract: while in Track mode the
control loop keeps the screen at telescope alt + screen_offset, clamped to
the travel limits and deadbanded by screen_alt_resolution, and
park_on_shutdown now stows the screen too. Both are guarded by
features("DomeWindScreen") -- DomeBase does not claim the interface, so
only drivers that mix it in pay for it.
FakeDome is the reference implementation, with a timed move that honours
abort_screen and reports ABORTED, so the interface has something to test
against. chimera-dome grows --move-screen, prints the screen altitude in
--info and aborts the screen on ^C; get_metadata writes DOME_WSC.
|
|
||
| if self.features("DomeWindScreen"): | ||
| metadata.append( | ||
| ("DOME_WSC", f"{self.get_screen():.2f}", "Dome wind screen altitude") |
There was a problem hiding this comment.
Done in e4c63f2: get_metadata writes DOME_FLP next to DOME_SLT. Since every dome inherits DomeFlap, features() cannot tell us whether the driver really has one, so the key is emitted only when is_flap_open() does not raise NotImplementedError.
There was a problem hiding this comment.
make the flap resolution mechanism same as windscreen
There was a problem hiding this comment.
Done in 176d360. DomeBase no longer inherits DomeFlap, so features("DomeFlap") now answers whether the driver actually has one — the same opt-in mixin the wind screen uses. get_metadata drops the NotImplementedError probe, FakeDome mixes DomeFlap in explicitly, and chimera-dome refuses --open-flap/--close-flap on flapless domes and prints the flap state in --info.
Heads-up on the fallout: out-of-tree drivers that implement the flap methods on DomeBase without declaring the interface — chimera-astelco (AstelcoDome) and chimera-domesync (DomeSync) — need DomeFlap added to their bases to keep advertising it. One-line change in each.
Also merged current master into the branch: the only conflict was in chimera-dome's __abort__, where #266 dropped the copy.copy(self.dome) workaround; kept the upstream form and added the screen abort on top. PR is mergeable again.
| is positioned in altitude. | ||
|
|
||
| Altitudes are in decimal degrees, horizon = 0 and zenith = 90, the same | ||
| convention used by ASCOM's Dome.Altitude. |
There was a problem hiding this comment.
remove ascom reference
There was a problem hiding this comment.
Removed in e4c63f2 — the docstring now just states the convention (decimal degrees, horizon = 0, zenith = 90).
get_metadata now writes DOME_FLP next to DOME_SLT. Every dome inherits DomeFlap, so features() says nothing about whether the driver implements it: the NotImplementedError from DomeBase is what tells us the dome has no flap, and the key is skipped for those.
…screen # Conflicts: # src/chimera/cli/dome.py
DomeBase no longer inherits DomeFlap, so features("DomeFlap") answers
whether the driver really has one instead of always saying yes -- the
same opt-in mixin the wind screen uses. get_metadata drops the
NotImplementedError probe, and chimera-dome refuses --open-flap /
--close-flap on flapless domes and prints the flap state in --info.
Out-of-tree drivers with a flap (chimera-astelco, chimera-domesync) need
DomeFlap added to their bases to keep advertising it.
phsilva
left a comment
There was a problem hiding this comment.
some renaming ideas... domes could have flat screens too, so maybe always add wind prefix in commands here to make sure about what which screen we are referring to.
| clamped to ['screen_min_alt', 'screen_max_alt']. | ||
| """ | ||
|
|
||
| def move_screen(self, alt: float) -> None: |
There was a problem hiding this comment.
| def move_screen(self, alt: float) -> None: | |
| def move_wind_screen(self, alt: float) -> None: |
| @rtype: None | ||
| """ | ||
|
|
||
| def get_screen(self) -> float: |
There was a problem hiding this comment.
| def get_screen(self) -> float: | |
| def get_wind_screen_alt(self) -> float: |
| """ | ||
| ... | ||
|
|
||
| def is_screen_moving(self) -> bool: |
There was a problem hiding this comment.
| def is_screen_moving(self) -> bool: | |
| def is_wind_screen_moving(self) -> bool: |
| """ | ||
| ... | ||
|
|
||
| def abort_screen(self) -> None: |
There was a problem hiding this comment.
| def abort_screen(self) -> None: | |
| def abort_wind_screen_move(self) -> None: |
| """ | ||
|
|
||
| @event | ||
| def screen_begin(self, alt: float) -> None: |
There was a problem hiding this comment.
| def screen_begin(self, alt: float) -> None: | |
| def wind_screen_move_begin(self, alt: float) -> None: |
| """ | ||
|
|
||
| @event | ||
| def screen_complete(self, alt: float, status: DomeStatus) -> None: |
There was a problem hiding this comment.
| def screen_complete(self, alt: float, status: DomeStatus) -> None: | |
| def wind_screen_move_complete(self, alt: float, status: DomeStatus) -> None: |
| self.out("OK") | ||
|
|
||
| @action( | ||
| long="move-screen", |
There was a problem hiding this comment.
| long="move-screen", | |
| long="move-wind-screen", |
Renames from phsilva's review -- a dome can carry a flat screen too, so 'screen' alone does not say which one: move_screen -> move_wind_screen get_screen -> get_wind_screen_alt is_screen_moving -> is_wind_screen_moving abort_screen -> abort_wind_screen_move screen_begin -> wind_screen_move_begin screen_complete -> wind_screen_move_complete --move-screen -> --move-wind-screen The config keys, the DomeBase helpers and the FakeDome internals follow the same prefix (screen_track -> wind_screen_track and so on), since the ambiguity is the same there.
|
All seven renames applied in 06e1715:
Carried the same prefix into the parts you did not annotate, since the flat-screen ambiguity is identical there: the config keys ( |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #267 +/- ##
==========================================
+ Coverage 51.57% 52.01% +0.44%
==========================================
Files 102 102
Lines 8521 8614 +93
Branches 978 997 +19
==========================================
+ Hits 4395 4481 +86
+ Misses 3928 3924 -4
- Partials 198 209 +11 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Declares the wind-screen dome role next to DomeSlit/DomeFlap: a screen positioned in altitude, in decimal degrees with horizon = 0 and zenith = 90. Also corrects the DomeFlap docstring ('Dome with Slit' -> 'Dome with Flap').
Interface —
move_screen(alt),get_screen(),is_screen_moving(),abort_screen(), plus thescreen_begin(alt)/screen_complete(alt, status)events. A move takes tens of seconds, so callers need the motion state to wait on it and the abort to stop it — without an abort,screen_complete(ABORTED)was unreachable. A position request is accepted with the slit closed and applied by the time it opens.Config (in both
DomeConfigand__config__):screen_track,screen_offset,screen_min_alt/screen_max_alt,screen_alt_resolution,screen_park_position,screen_timeout.Base implementation — while the dome is in Track mode, the control loop keeps the screen at telescope altitude +
screen_offset, clamped to the travel limits and deadbanded byscreen_alt_resolution;park_on_shutdownstows the screen;get_metadatawritesDOME_WSC, alongside a newDOME_FLPflap key. All of it is guarded byfeatures("DomeWindScreen")—DomeBasedoes not inherit the interface, drivers opt in by mixing it in.Driver and CLI —
FakeDomeis the reference implementation (timed move, honours abort, reportsABORTED).chimera-domegains--move-screen ALT, prints the screen altitude in--infoand aborts the screen on ^C. 21 tests cover signature conformance against the interface, the move/limits/abort lifecycle, event payloads, tracking (target, deadband, opt-out) and the control-loop integration.No hardware driver implements it yet: the LNA 40 cm dome has no wind screen. The closest real target is the LCO Swope TCS, whose screen is jog-based (
SCREENPOS GO UP|DOWN|STOPplus a position readout and a fully-open limit switch) — it would needstop_screen()and anis_screen_open(), left out of this PR.