28 @brief MQTT event type.
30 | Symbol | Value | Description |
31 | :------------------ | :---- | :---------------------- |
32 | `NyxMQTTEvent.OPEN` | 1100 | A connection is opened. |
33 | `NyxMQTTEvent.MSG` | 1101 | A message is received. |
44 @brief Nyx node exposing INDI, MQTT and Nyx Stream endpoints.
56 mqtt_username: str |
None,
57 mqtt_password: str |
None,
60 args: argparse.Namespace |
None =
None
63 @brief Allocates and initializes a Nyx node.
65 @param node_id Unique node identifier.
66 @param vectors Array of vectors.
67 @param indi_url Optional INDI URL.
68 @param mqtt_url Optional MQTT URL.
69 @param nss_url Optional Nyx Stream URL.
70 @param mqtt_username Optional MQTT username.
71 @param mqtt_password Optional MQTT password.
72 @param retry_ms Connect retry time [milliseconds].
73 @param enable_xml Enables the XML messages for INDI compatibility.
74 @param args Optional command-line arguments.
98 for i, vector
in enumerate(self.
_vectors):
102 raise TypeError(
'Expected Nyx Dict object')
104 self.
_vectors_ptr[i] = ctypes.cast(vector.ptr, bind.nyx_dict_p)
110 self.
_ptr = bind.lib.nyx_node_initialize(
111 bind.as_bytes(node_id, allow_none =
False),
113 bind.as_bytes(indi_url, allow_none =
True),
114 bind.as_bytes(mqtt_url, allow_none =
True),
115 bind.as_bytes(nss_url, allow_none =
True),
116 bind.as_bytes(mqtt_username, allow_none =
True),
117 bind.as_bytes(mqtt_password, allow_none =
True),
133 @brief C pointer to the Nyx Node object.
141 def args(self) -> argparse.Namespace | None:
143 @brief Optional command-line arguments provided in the constructor.
155 topic_buff: bind.c_void_p,
157 message_buff: bind.c_void_p,
168 if event_type == NyxMQTTEvent.OPEN:
172 for callback
in callbacks:
180 elif event_type == NyxMQTTEvent.MSG:
186 topic = ctypes.string_at(topic_buff, topic_size)
if topic_size
else b
''
187 message = ctypes.string_at(message_buff, message_size)
if message_size
else b
''
189 topic = topic.decode(
'utf-8')
191 for callback
in callbacks:
193 callback(topic, message)
198 @bind.nyx_timer_callback_t
199 def _on_timer(arg: bind.c_void_p) ->
None:
201 ctypes.cast(arg, ctypes.POINTER(ctypes.py_object)).contents.value()
205 def on_mqtt(self, event_type: NyxMQTTEvent) -> typing.Callable:
207 @brief Registers an MQTT event handler.
209 @param event_type MQTT event type.
210 @return A decorator registering the MQTT event handler.
213 with nyx.NyxNode(...) as node:
215 @node.on_mqtt(nyx.NyxMQTTEvent.OPEN)
219 @node.on_mqtt(nyx.NyxMQTTEvent.MSG)
220 def on_mqtt_msg(topic, message):
227 if not isinstance(event_type, NyxMQTTEvent):
229 raise TypeError(
'Expected NyxMQTTEvent enum')
233 def decorate(callback: typing.Callable) -> typing.Callable:
235 if not callable(callback):
237 raise TypeError(
'Expected a callable MQTT handler')
241 if event_type == NyxMQTTEvent.OPEN:
245 elif event_type == NyxMQTTEvent.MSG:
251 raise ValueError(f
'Unsupported MQTT event: {event_type!r}')
265 @brief Registers a timer handler.
267 @param interval_ms Interval [milliseconds].
268 @return A decorator registering the timer handler.
270 @note Timers are triggered by the @ref nyx.node.NyxNode.poll method.
273 with nyx.NyxNode(...) as node:
283 if not isinstance(interval_ms, int):
285 raise TypeError(
'Expected timer interval in milliseconds')
289 raise ValueError(
'Timer interval must be positive')
293 def decorate(callback: typing.Callable) -> typing.Callable:
295 if not callable(callback):
297 raise TypeError(
'Expected a callable timer handler')
301 timer_context = ctypes.py_object(callback)
307 bind.lib.nyx_node_add_timer(
310 type(self)._on_timer,
311 bind.c_void_p(ctypes.addressof(timer_context)),
326 @brief Finalizes the Nyx node.
331 bind.lib.nyx_node_finalize(self.
ptr,
False)
335 def poll(self, timeout_ms: int) ->
None:
336 """! @brief Performs a single poll iteration.
338 @param timeout_ms Timeout [milliseconds].
341 @note @c timeout_ms determines the minimum timer resolution.
344 bind.lib.nyx_node_poll(self.
ptr, timeout_ms)
348 def enable(self, device: str, name: str |
None =
None, message: str |
None =
None) ->
None:
350 @brief Enables a device or a vector and notifies clients.
352 @param device Device name.
353 @param name Optional vector name (`None` means the whole device).
354 @param message Optional human-oriented message.
358 bind.lib.nyx_node_enable(
360 bind.as_bytes(device, allow_none =
False),
361 bind.as_bytes(name, allow_none =
True),
362 bind.as_bytes(message, allow_none =
True)
367 def disable(self, device: str, name: str |
None =
None, message: str |
None =
None) ->
None:
369 @brief Disables a device or a vector and notifies clients.
371 @param device Device name.
372 @param name Optional vector name (`None` means the whole device).
373 @param message Optional human-oriented message.
377 bind.lib.nyx_node_disable(
379 bind.as_bytes(device, allow_none =
False),
380 bind.as_bytes(name, allow_none =
True),
381 bind.as_bytes(message, allow_none =
True)
386 def send_message(self, device: str, message: str |
None =
None) ->
None:
388 @brief Sends a human-oriented message to the clients.
390 @param device Device name.
391 @param message Human-oriented message.
395 bind.lib.nyx_node_send_message(
397 bind.as_bytes(device, allow_none =
False),
398 bind.as_bytes(message, allow_none =
True)
403 def send_del_property(self, device: str, name: str |
None =
None, message: str |
None =
None) ->
None:
405 @brief Sends a `del-property` message to the clients.
407 @param device Device name.
408 @param name Optional vector name (`None` means the whole device).
409 @param message Optional human-oriented message.
413 bind.lib.nyx_node_send_del_property(
415 bind.as_bytes(device, allow_none =
False),
416 bind.as_bytes(name, allow_none =
True),
417 bind.as_bytes(message, allow_none =
True)
422 def mqtt_sub(self, topic: str, qos: int = 0) ->
None:
424 @brief If MQTT is enabled, subscribes to an MQTT topic.
426 @param topic MQTT topic.
427 @param qos MQTT Quality Of Service.
430 @note MQTT handlers have to be added with the @ref nyx.node.NyxNode.on_mqtt decorator.
433 bind.lib.nyx_mqtt_sub(
435 bind.as_bytes(topic, allow_none =
False),
441 def mqtt_pub(self, topic: str, message: bytes, qos: int = 0) ->
None:
443 @brief If MQTT is enabled, publishes an MQTT message.
445 @param topic MQTT topic.
446 @param message Message payload.
447 @param qos MQTT Quality Of Service.
450 @note The message payload may contain arbitrary binary data.
453 message = bind.as_bytes(message, allow_none =
False)
455 bind.lib.nyx_mqtt_pub(
457 bind.as_bytes(topic, allow_none =
False),
471 def __exit__(self, exc_type, exc_value, traceback):
477__all__ = [
'NyxMQTTEvent',
'NyxNode']
None send_message(self, str device, str|None message=None)
Sends a human-oriented message to the clients.
__init__(self, str node_id, typing.List[json.NyxDict] vectors, str|None indi_url, str|None mqtt_url, str|None nss_url, str|None mqtt_username, str|None mqtt_password, int retry_ms, bool enable_xml, argparse.Namespace|None args=None)
Allocates and initializes a Nyx node.
None send_del_property(self, str device, str|None name=None, str|None message=None)
Sends a del-property message to the clients.
None close(self)
Finalizes the Nyx node.
None poll(self, int timeout_ms)
Performs a single poll iteration.
None enable(self, str device, str|None name=None, str|None message=None)
Enables a device or a vector and notifies clients.
typing.Callable on_mqtt(self, NyxMQTTEvent event_type)
Registers an MQTT event handler.
argparse.Namespace|None _args
None _on_mqtt(self, _, int event_type, int topic_size, bind.c_void_p topic_buff, int message_size, bind.c_void_p message_buff)
None mqtt_sub(self, str topic, int qos=0)
If MQTT is enabled, subscribes to an MQTT topic.
argparse.Namespace|None args(self)
Optional command-line arguments provided in the constructor.
None mqtt_pub(self, str topic, bytes message, int qos=0)
If MQTT is enabled, publishes an MQTT message.
on_timer(self, int interval_ms)
Registers a timer handler.
None disable(self, str device, str|None name=None, str|None message=None)
Disables a device or a vector and notifies clients.
Nyx node exposing INDI, MQTT and Nyx Stream endpoints.