Device services¶
Device services are the bridge between SensorKit and your hardware. Each service connects to a hardware driver (an Alpaca server, a PWI4 instance, TheSky, …) and exposes its devices on the message bus, where the sensor controller and CLI address them by name.
Each driver module contributes its own section to the unified config file. Declaring a section both configures the devices and registers the service — sensorkit go will launch it automatically, or you can run it individually:
Don't forget the import
A module's config section is only recognized if the module appears in sensorkit.imports — otherwise config load rejects the section as unknown:
Device names (the keys under devices:) are the entity names you'll use everywhere else — in the sensor's devices: mapping, in constraints (provider:), and on the CLI (-e MyMount).
ASCOM Alpaca¶
Module: sensorkit.alpaca.service · Extra: pip install "sensorkit[alpaca]"
Connects to any ASCOM Alpaca server — including the ASCOM Remote adapter, so classic ASCOM drivers work too.
alpaca:
- id: Alpaca
endpoints:
- host: 192.168.1.10
port: 11111 # default: 11111 (the Alpaca standard port)
protocol: http # http or https
devices:
MyCamera:
device_type: camera
device_number: 0 # ASCOM device index; default 0
status_frequency: 1.0 # telemetry poll interval, seconds
MyMount:
device_type: telescope
MyDome:
device_type: dome
MyWheel:
device_type: filter_wheel
MyFocuser:
device_type: focuser
MyRotator:
device_type: rotator
MyWeather:
device_type: observing_conditions
MySafety:
device_type: safety_monitor
Supported device_type values: camera, telescope, dome, filter_wheel, focuser, rotator, observing_conditions, safety_monitor, cover_calibrator, switch
Camera options:
| Field | Default | Description |
|---|---|---|
cooler_on |
true |
Turn the cooler on at connect |
ccd_temperature_setpoint |
— | Target CCD temperature (°C) |
readout_mode |
— | Readout mode index or name |
PlaneWave PWI4¶
Module: sensorkit.pwi4.service · Extra: pip install "sensorkit[pwi4]"
Connects to PlaneWave's PWI4 software over its HTTP API: mount, focuser, rotator, and mirror cover.
pwi4:
- id: PlaneWave
endpoints:
- host: localhost
port: 8220 # default: 8220
devices:
MyMount:
device_type: mount
status_frequency: 1.0
park_absolute: true # park to explicit axis positions
park_axis0_degrees: 30.0
park_axis1_degrees: 0.0
disable_axis_on_deinit: false
MyFocuser:
device_type: focuser
MyRotator:
device_type: rotator
MyCover:
device_type: cover
Supported device_type values: mount, focuser, rotator, cover
Software Bisque TheSky¶
Module: sensorkit.thesky.service · Extra: pip install "sensorkit[thesky]"
Connects to TheSky/SkyX via its TCP scripting interface.
thesky:
- id: TheSky
endpoints:
- host: 192.168.1.20
port: 3040
devices:
MyMount:
device_type: telescope
MyCamera:
device_type: camera
MyDome:
device_type: dome
Supported device_type values: telescope, camera, dome, filter_wheel, focuser, rotator, weather, ota
Observable Space Node Platform¶
Module: sensorkit.node_platform.service · Extra: pip install "sensorkit[node-platform]"
Connects to a Node Platform observatory controller.
node_platform:
- id: NodePlatform
endpoints:
- host: 192.168.1.30
port: 9080 # default: 9080
env_file: .env # NODE_PLATFORM_API_KEY (and optional NODE_PLATFORM_LINEAGE_ID)
request_timeout: 30.0
operation_mode: assisted # or: manual
devices:
MyMount:
device_type: mount
MyCamera:
device_type: camera
MyWeather:
device_type: weather
Other modules (INDIGO, NINA) follow the same pattern; their sections are named after the module. Module maturity varies — Alpaca and PWI4 are the most heavily exercised.
Multiple endpoints and hosts¶
A single service can talk to several driver endpoints, and you can declare several services against different hosts. Connection settings on the endpoint propagate down to its devices:
alpaca:
- id: Alpaca
endpoints:
- host: camera-pc
devices:
MyCamera:
device_type: camera
- host: dome-pc
devices:
MyDome:
device_type: dome
How devices appear on the bus¶
Once connected, each device publishes:
- Details — the commands it supports, from which SensorKit derives its traits (structural capabilities like "can slew", "can capture") and archetype (mount, camera, …). Controllers match devices by capability, not by driver.
- Keywords — a stream of typed telemetry (pointing, temperatures, weather readings) polled at
status_frequency. - State — connection and enablement, persisted so it survives restarts.
You can poke any device directly from the CLI, bypassing the controller:
sensorkit device connect -e MyMount
sensorkit device disconnect -e MyMount
sensorkit device abort -e MyMount # stop motion immediately
Writing your own device¶
If your hardware speaks something SensorKit doesn't yet, a device is just a Python class with command handlers — see the API reference:
import sensorkit.api as sk
from sensorkit.std import Connect, Stop
@sk.declare_device
class MyMount:
@sk.command_handler
async def connect(self, cmd: Connect):
...
@sk.command_handler
async def stop(self, cmd: Stop):
...
@sk.service_entrypoint(version="1.0")
async def main(service: sk.Service):
service.include(MyMount, name="my-mount")
await service.run()