argos.core.stellarium

Modules

Stellarium Telescope Protocol v1.0 — binary message codec.

Wire format (little-endian, all messages share a 4-byte header):

LENGTH (uint16) total message length including this header TYPE (uint16) message type

MessageType 0 in either direction carries a J2000 RA/Dec pointing:

Client -> Server (Stellarium asks the telescope to slew)

TIME (uint64) microseconds since Unix epoch (informational) RA (uint32) ra_rad * 0x80000000 / pi mod 2**32 DEC (int32) dec_rad * 0x80000000 / pi (signed) Total: 20 bytes

Server -> Client (telescope reports current pointing, ~1 Hz)

TIME (uint64) RA (uint32) DEC (int32) STATUS (uint32) 0 = OK, non-zero = error code (driver-specific) Total: 24 bytes

The RA encoding maps 0..2*pi radians (i.e. 0..24 hours) onto the full uint32 range, so wrap-around is implicit. Dec uses a signed int32 mapping -pi/2..+pi/2 onto -2**31..+2**31 (full Dec range fits in the lower half).

Reference: Stellarium docs/telescope_server.html and the libnova TelescopeServer implementation.

class argos.core.stellarium.protocol.GotoMessage(ra_hours: float, dec_degrees: float, sent_time_us: int)[source]

Bases: object

A Stellarium “go to this RA/Dec” command in J2000.

dec_degrees: float
ra_hours: float
sent_time_us: int
argos.core.stellarium.protocol.decode_goto(buf: bytes) → GotoMessage | None[source]

Decode a 20-byte client -> server slew request.

Returns None if the buffer is not a valid MessageType 0 frame.

argos.core.stellarium.protocol.encode_position(ra_hours: float, dec_degrees: float, status: int = 0, when_us: int | None = None) → bytes[source]

Encode a 24-byte server -> client current-position message.

Parameters:
  • ra_hours – Current RA in decimal hours (J2000).

  • dec_degrees – Current Dec in decimal degrees (J2000).

  • status – 0 for OK, non-zero to signal a driver error.

  • when_us – Microseconds since epoch; defaults to time.time().

argos.core.stellarium.protocol.find_next_message(buf: bytes) → int[source]

Return the byte length of the leading message in buf, or 0 if incomplete. Lets a buffered reader peel one frame at a time without knowing the message type in advance.

asyncio TCP server speaking the Stellarium Telescope Protocol v1.0.

Listens on a TCP port (10001 by default). Stellarium’s Telescope Control plugin connects, sends MessageType 0 to request a slew, and expects the telescope to keep streaming its current position so the on-screen reticle follows the mount in real time.

This module is pure asyncio — it has no Qt dependency. The QThread bridge in argos.workers.stellarium_worker wraps it so it can run inside the Argos event loop and exchange data with the UI via Qt signals.

class argos.core.stellarium.server.StellariumServer(host: str = '127.0.0.1', port: int = 10001, on_goto: Callable[[float, float], None] | None = None, push_interval_s: float = 1.0, on_client_count: Callable[[int], None] | None = None)[source]

Bases: object

Asynchronous Stellarium Telescope Protocol server.

Typical lifecycle:

srv = StellariumServer(port=10001, on_goto=lambda r, d: ...)
await srv.start()
srv.set_position(5.59, -5.39, slewing=False)   # push to clients
# ... later ...
await srv.stop()
Parameters:
  • host – Interface to bind. 127.0.0.1 for loopback only (default — safer), 0.0.0.0 to expose on LAN.

  • port – TCP port (10001 is Stellarium’s convention).

  • on_goto – Called from the event loop on every valid goto. Keep it cheap; offload long work to a queue.

  • push_interval_s – How often to broadcast current position to clients.

  • on_client_count – Optional callback that fires when a client connects or disconnects. Receives the new total count.

property client_count: int
set_position(ra_hours: float, dec_degrees: float, slewing: bool = False) → None[source]

Latest mount position; broadcast at the next push tick.

async start() → None[source]

Open the TCP socket and start the position-broadcast loop.

async stop() → None[source]

Close the listening socket and disconnect all clients.