mirror of
https://github.com/mavlink/mavlink-devguide.git
synced 2026-06-19 07:36:26 +00:00
Skydio add illuminator protocol (#535)
* add test suite and microservice document * updated per comments from first commit * addressed PR comments
This commit is contained in:
committed by
GitHub
parent
b359926196
commit
b536684f27
@@ -0,0 +1,202 @@
|
||||
import os
|
||||
import threading
|
||||
import time
|
||||
from enum import Enum
|
||||
|
||||
from pymavlink import mavutil
|
||||
|
||||
|
||||
class IlluminatorStatusFields(Enum):
|
||||
UPTIME_MS = 0
|
||||
ENABLE = 1
|
||||
MODE_BITMASK = 2
|
||||
ERROR_STATUS = 3
|
||||
MODE = 4
|
||||
BRIGHTNESS = 5
|
||||
STROBE_PERIOD = 6
|
||||
STROBE_DUTY_CYCLE = 7
|
||||
TEMP_C = 8
|
||||
MIN_STROBE_PERIOD = 9
|
||||
MAX_STROBE_PERIOD = 10
|
||||
|
||||
|
||||
def stream_heartbeat(event, mavlink_connection_out):
|
||||
while True:
|
||||
event.wait()
|
||||
mavlink_connection_out.mav.heartbeat_send(
|
||||
mavutil.mavlink.MAV_TYPE_ILLUMINATOR, mavutil.mavlink.MAV_AUTOPILOT_INVALID, 0, 0, 0
|
||||
)
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
def stream_illuminator_status(event, mavlink_connection_out):
|
||||
while True:
|
||||
event.wait()
|
||||
mavlink_connection_out.mav.illuminator_status_send(*illuminator_status)
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
def publish_iluminator_status(mavlink_connection_out):
|
||||
mavlink_connection_out.mav.illuminator_status_send(*illuminator_status)
|
||||
|
||||
|
||||
def publish_component_information_basic(mavlink_connection_out):
|
||||
mavlink_connection_out.mav.component_information_basic_send(
|
||||
0, # time_boot_ms
|
||||
0, # capabilities
|
||||
0, # time_manufacture_s
|
||||
"Illuminator Vendor".encode(), # vendor_name
|
||||
"Illuminator Model".encode(), # model_name
|
||||
"Illuminator Software Version".encode(), # software_version
|
||||
"Illuminator Hardware Version".encode(), # hardware_version
|
||||
"Illuminator Serial Number".encode(), # serial_number
|
||||
)
|
||||
|
||||
|
||||
def update_illuminator_status(field, value):
|
||||
global illuminator_status
|
||||
tmp = list(illuminator_status)
|
||||
tmp[field.value] = value
|
||||
illuminator_status = tuple(tmp)
|
||||
|
||||
|
||||
def handle_command_long(msg, mavlink_connection_out):
|
||||
# MAV_CMD_REQUEST_MESSAGE
|
||||
if msg.command == mavutil.mavlink.MAV_CMD_REQUEST_MESSAGE:
|
||||
if msg.param1 == mavutil.mavlink.MAVLINK_MSG_ID_ILLUMINATOR_STATUS:
|
||||
mavlink_connection_out.mav.command_ack_send(
|
||||
msg.command, result=mavutil.mavlink.MAV_RESULT_ACCEPTED
|
||||
)
|
||||
publish_iluminator_status(mavlink_connection_out)
|
||||
elif msg.param1 == mavutil.mavlink.MAVLINK_MSG_ID_COMPONENT_INFORMATION_BASIC:
|
||||
mavlink_connection_out.mav.command_ack_send(
|
||||
msg.command, result=mavutil.mavlink.MAV_RESULT_ACCEPTED
|
||||
)
|
||||
publish_component_information_basic(mavlink_connection_out)
|
||||
else:
|
||||
mavlink_connection_out.mav.command_ack_send(
|
||||
msg.command, result=mavutil.mavlink.MAV_RESULT_DENIED
|
||||
)
|
||||
|
||||
# MAV_CMD_SET_MESSAGE_INTERVAL
|
||||
elif msg.command == mavutil.mavlink.MAV_CMD_SET_MESSAGE_INTERVAL:
|
||||
if msg.param1 == mavutil.mavlink.MAVLINK_MSG_ID_ILLUMINATOR_STATUS:
|
||||
if msg.param2 == -1:
|
||||
illuminator_status_thread_event.clear()
|
||||
else:
|
||||
illuminator_status_thread_event.set()
|
||||
mavlink_connection_out.mav.command_ack_send(
|
||||
msg.command, result=mavutil.mavlink.MAV_RESULT_ACCEPTED
|
||||
)
|
||||
else:
|
||||
mavlink_connection_out.mav.command_ack_send(
|
||||
msg.command, result=mavutil.mavlink.MAV_RESULT_DENIED
|
||||
)
|
||||
|
||||
# MAV_CMD_ILLUMINATOR_ON_OFF
|
||||
elif msg.command == mavutil.mavlink.MAV_CMD_ILLUMINATOR_ON_OFF:
|
||||
if msg.param1 == 0 or msg.param1 == 1:
|
||||
mavlink_connection_out.mav.command_ack_send(
|
||||
msg.command, result=mavutil.mavlink.MAV_RESULT_ACCEPTED
|
||||
)
|
||||
update_illuminator_status(IlluminatorStatusFields.ENABLE, int(msg.param1))
|
||||
else:
|
||||
mavlink_connection_out.mav.command_ack_send(
|
||||
msg.command, result=mavutil.mavlink.MAV_RESULT_DENIED
|
||||
)
|
||||
|
||||
# MAV_CMD_DO_ILLUMINATOR_CONFIGURE
|
||||
elif msg.command == mavutil.mavlink.MAV_CMD_DO_ILLUMINATOR_CONFIGURE:
|
||||
if (
|
||||
msg.param1 != mavutil.mavlink.ILLUMINATOR_MODE_INTERNAL_CONTROL
|
||||
and msg.param1 != mavutil.mavlink.ILLUMINATOR_MODE_EXTERNAL_SYNC
|
||||
):
|
||||
mavlink_connection_out.mav.command_ack_send(
|
||||
msg.command, result=mavutil.mavlink.MAV_RESULT_DENIED
|
||||
)
|
||||
elif msg.param2 < 0 or msg.param2 > 100:
|
||||
mavlink_connection_out.mav.command_ack_send(
|
||||
msg.command, result=mavutil.mavlink.MAV_RESULT_DENIED
|
||||
)
|
||||
elif (
|
||||
msg.param3 < illuminator_status[IlluminatorStatusFields.MIN_STROBE_PERIOD.value]
|
||||
or msg.param3 > illuminator_status[IlluminatorStatusFields.MAX_STROBE_PERIOD.value]
|
||||
):
|
||||
mavlink_connection_out.mav.command_ack_send(
|
||||
msg.command, result=mavutil.mavlink.MAV_RESULT_DENIED
|
||||
)
|
||||
elif msg.param4 < 0 or msg.param4 > 100:
|
||||
mavlink_connection_out.mav.command_ack_send(
|
||||
msg.command, result=mavutil.mavlink.MAV_RESULT_DENIED
|
||||
)
|
||||
else:
|
||||
mavlink_connection_out.mav.command_ack_send(
|
||||
msg.command, result=mavutil.mavlink.MAV_RESULT_ACCEPTED
|
||||
)
|
||||
update_illuminator_status(IlluminatorStatusFields.MODE, int(msg.param1))
|
||||
update_illuminator_status(IlluminatorStatusFields.BRIGHTNESS, msg.param2)
|
||||
update_illuminator_status(IlluminatorStatusFields.STROBE_PERIOD, msg.param3)
|
||||
update_illuminator_status(IlluminatorStatusFields.STROBE_DUTY_CYCLE, msg.param4)
|
||||
|
||||
else:
|
||||
mavlink_connection_out.mav.command_ack_send(
|
||||
msg.command, result=mavutil.mavlink.MAV_RESULT_UNSUPPORTED
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
os.environ["MAVLINK20"] = "1"
|
||||
os.environ["MAVLINK_DIALECT"] = "common"
|
||||
global illuminator_status_thread_event
|
||||
global illuminator_status
|
||||
|
||||
# Start UDP connections
|
||||
mavlink_connection_udpin = mavutil.mavlink_connection("udpin:localhost:14540", dialect="common")
|
||||
mavlink_connection_udpout = mavutil.mavlink_connection(
|
||||
"udpout:localhost:14541", dialect="common"
|
||||
)
|
||||
|
||||
# Heartbeat
|
||||
heartbeat_thread_event = threading.Event()
|
||||
heartbeat_thread = threading.Thread(
|
||||
target=stream_heartbeat,
|
||||
daemon=True,
|
||||
args=(heartbeat_thread_event, mavlink_connection_udpout),
|
||||
)
|
||||
heartbeat_thread.start()
|
||||
|
||||
# Illuminator status
|
||||
illuminator_status = (
|
||||
0, # uptime_ms
|
||||
0, # enable
|
||||
mavutil.mavlink.ILLUMINATOR_MODE_INTERNAL_CONTROL
|
||||
+ mavutil.mavlink.ILLUMINATOR_MODE_EXTERNAL_SYNC, # mode_bitmask
|
||||
0, # error_status
|
||||
mavutil.mavlink.ILLUMINATOR_MODE_INTERNAL_CONTROL, # mode
|
||||
100.0, # brightness
|
||||
0.0, # strobe_period
|
||||
0.0, # strobe_duty_cycle
|
||||
25.0, # temp_c
|
||||
0.0, # min_strobe_period
|
||||
10.0, # max_strobe_period
|
||||
)
|
||||
illuminator_status_thread_event = threading.Event()
|
||||
illuminator_status_thread = threading.Thread(
|
||||
target=stream_illuminator_status,
|
||||
daemon=True,
|
||||
args=(illuminator_status_thread_event, mavlink_connection_udpout),
|
||||
)
|
||||
illuminator_status_thread.start()
|
||||
|
||||
heartbeat_thread_event.set()
|
||||
illuminator_status_thread_event.set()
|
||||
|
||||
while True:
|
||||
msg = mavlink_connection_udpin.recv_match(type="COMMAND_LONG", blocking=True)
|
||||
if msg:
|
||||
# print(msg)
|
||||
handle_command_long(msg, mavlink_connection_udpout)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
File diff suppressed because it is too large
Load Diff
@@ -39,3 +39,4 @@ The main microservices are shown in the sidebar (most are listed below):
|
||||
- [Traffic Managment (UTM/ADS-B)](../services/traffic_management.md)
|
||||
- [Events Interface (WIP)](../services/events.md)
|
||||
- [Time Synchronization](../services/timesync.md)
|
||||
- [Illuminator Protocol](../services/illuminator.md)
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
# Illuminator Protocol
|
||||
|
||||
## Introduction
|
||||
|
||||
The illuminator protocol allows MAVLink control over the behavior of lights, LEDs, and/or emitters mounted or integrated on the drone.
|
||||
The protocol currently allows for the following control: brightness, on/off, and a strobe feature.
|
||||
|
||||
Along with this, the illuminator protocol also publishes status information for developers or users. The status messaging encompasses the current configuration of the illuminator and the health of the illuminator device.
|
||||
|
||||
|
||||
## MAVLink Illuminator Implementations
|
||||
|
||||
These illuminators have built-in MAVLink support:
|
||||
|
||||
- Skydio Spotlight for X10
|
||||
|
||||
## Message/Enum Summary
|
||||
|
||||
| Message | Description |
|
||||
| --------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| <span id="COMPONENT_INFORMATION_BASIC"></span>[COMPONENT_INFORMATION_BASIC](../messages/common.md#COMPONENT_INFORMATION_BASIC) | Basic illuminator information data. Should be requested using [MAV_CMD_REQUEST_MESSAGE ](https://mavlink.io/en/messages/common.html#MAV_CMD_REQUEST_MESSAGE) on startup, or when required. |
|
||||
| <span id="MAV_CMD_ILLUMINATOR_ON_OFF"></span>[MAV_CMD_ILLUMINATOR_ON_OFF](../messages/common.md#MAV_CMD_ILLUMINATOR_ON_OFF) | Turns illuminators ON/OFF. |
|
||||
| <span id="MAV_CMD_DO_ILLUMINATOR_CONFIGURE"></span>[MAV_CMD_DO_ILLUMINATOR_CONFIGURE](../messages/common.md#MAV_CMD_DO_ILLUMINATOR_CONFIGURE) | Configures illuminator settings. |
|
||||
| <span id="ILLUMINATOR_STATUS"></span>[ILLUMINATOR_STATUS](../messages/common.md#ILLUMINATOR_STATUS) | Current status of the illuminator. Recommended to publish this at a regular rate. |
|
||||
|
||||
|
||||
| Enum Values | Description |
|
||||
| ------------------------------------------------------------------------------------------------------------------ | ------------------------- |
|
||||
| <span id="MAV_TYPE_ILLUMINATOR"></span>[MAV_TYPE_ILLUMINATOR](../messages/minimal.md#MAV_TYPE_ILLUMINATOR) | Type of the component (illuminator). |
|
||||
| <span id="MAV_COMP_ID_ILLUMINATOR"></span>[MAV_COMP_ID_ILLUMINATOR](../messages/minimal.md#MAV_COMP_ID_ILLUMINATOR) | ID of the component (illuminator). |
|
||||
|
||||
| Enum | Description |
|
||||
| ------------------------------------------------------------------------------------------------------------------ | ------------------------- |
|
||||
| <span id="ILLUMINATOR_MODE"></span>[ILLUMINATOR_MODE](../messages/common.md#ILLUMINATOR_MODE) | Illuminator modes. |
|
||||
| <span id="ILLUMINATOR_ERROR_FLAGS"></span>[ILLUMINATOR_ERROR_FLAGS](../messages/common.md#ILLUMINATOR_ERROR_FLAGS) | Fault/health indications. |
|
||||
|
||||
|
||||
|
||||
## Implementation and Messages
|
||||
|
||||
### Illuminator Connection
|
||||
|
||||
Illuminators are expected to follow the [Heartbeat/Connection Protocol](https://github.com/mavlink/mavlink-devguide/blob/master/en/services/heartbeat.md) and send a constant flow of heartbeats (nominally at 1Hz). Illuminators are identified via their type [MAV_TYPE_ILLUMINATOR](#MAV_TYPE_ILLUMINATOR).
|
||||
Individual illuminators are distinguished via their unique component ID, which by default should be [MAV_COMP_ID_ILLUMINATOR](#MAV_COMP_ID_ILLUMINATOR) (though this is not mandated and any ID may be used).
|
||||
Once a heartbeat is received, the drone can then send a [MAV_CMD_REQUEST_MESSAGE ](https://mavlink.io/en/messages/common.html#MAV_CMD_REQUEST_MESSAGE) command to the illuminator to receive information, set settings, or control the illuminator. An example below illustrates how a drone can request the status of the illuminator.
|
||||
<!-- Mermaid graph:
|
||||
sequenceDiagram;
|
||||
participant Drone
|
||||
participant Illuminator
|
||||
Illuminator->>Drone: HEARTBEAT [cmp id: MAV_TYPE_ILLUMINATOR] (first)
|
||||
Drone->>Illuminator: MAV_CMD_REQUEST_MESSAGE(param1=ILLUMINATOR_STATUS)
|
||||
Drone->>Drone: Start timeout
|
||||
Illuminator->>Drone: COMMAND_ACK
|
||||
Note over Illuminator,Drone: If MAV_RESULT_ACCEPTED send info.
|
||||
Illuminator->>Drone: ILLUMINATOR_STATUS [cmp id: MAV_COMP_ID_ILLUMINATOR]
|
||||
-->
|
||||
|
||||
[](https://mermaid.live/edit#pako:eNp9UWFLwzAQ_SshnxxMwa8VB7ENWly32aSCrBJCe9XgktQ0FcbYfzeuEzoGu0_Hy3sv7-52uLI14Ah38N2DqSBR8sNJfVcaFKqVzqtKtdJ4lDhr4BxON5teKyO9dcPjCLiezQ6qCD1RkvMHSjhaZ-QV-W0bwNAJ_raiIp3PiyxdEL7M39FVo1znJ2hwO-iDz8h1EMZZInL6UlDGRUYZI4_0KuSS-vZ-ZCcYJ7xgk1OzYyjmwxzIKw229xfCx8ssI4tEkPh5YC2sB2R_wI350yM7bQ75csqKOQ-amK44TVAHpkbKNPbmwk_nydG60i1S9XHoZbYSaXKysMEOT7EGp6WqwzF3f1iJ_SdoKHEU2lq6rxKXZh94sveWbU2FI-96mOK-raX_PzyOGrnpYP8LFgqu1A)
|
||||
|
||||
### COMPONENT_INFORMATION_BASIC
|
||||
|
||||
While the `MAV_TYPE` and Component ID help identify the system and component, the [COMPONENT_INFORMATION_BASIC](#COMPONENT_INFORMATION_BASIC) command can be requested to retrieve component information data, which can help further identify the component being communicated with. This data includes `time_boot_ms`, `MAV_PROTOCOL_CAPABILITY`, `vendor_name`, `model_name`, `software_version`, `hardware_version`, and `serial_number`.
|
||||
|
||||
| Parameter | Description |
|
||||
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `time_boot_ms` | Time since system boot up in milliseconds. |
|
||||
| `MAV_PROTOCOL_CAPABILITY` | Bitmask detailing the component capability flags. |
|
||||
| `vendor_name` | Name of the component vendor (optional). |
|
||||
| `model_name` | Name of the component's model (optional). |
|
||||
| `software_version` | Software version on the module, recommended format is SEMVER: 'major.minor.patch' but any format can be used (24-character string) (optional). |
|
||||
| `hardware_version` | Hardware version on the module, recommended format is SEMVER: 'major.minor.patch' but any format can be used (24-character string) (optional). |
|
||||
| `serial_number` | Hardware's serial number (optional). |
|
||||
|
||||
Optional parameters can be left empty or set to zero.
|
||||
|
||||
### ON/OFF
|
||||
|
||||
The [MAV_CMD_ILLUMINATOR_ON_OFF](#MAV_CMD_ILLUMINATOR_ON_OFF) command is used to enable/disable the illuminator.
|
||||
It's usage can be seen below:
|
||||
|
||||
<!-- Mermaid graph:
|
||||
sequenceDiagram;
|
||||
participant Drone
|
||||
participant Illuminator
|
||||
Drone->>Illuminator: MAV_CMD_ILLUMINATOR_ON_OFF (param1 = 1)
|
||||
Drone->>Drone: Start timeout
|
||||
Illuminator->>Drone: MAV_RESULT_ACCEPTED
|
||||
-->
|
||||
|
||||
[](https://mermaid.live/edit#pako:eNplkMFqwzAMhl_F6LRCd-jVZYWQpBBImtGkOxmMSLTNLLYzVz6M0nef2zLWMV0kpE__j3SCwY8EEo70GckNVBh8C2jXyokUMwY2g5nRsSiCd_S_XU1TtMYh-3AbXrnHzeZuIEWTvei8KXRV14em2mV9u9ftTrfbrXhIamhX4kmsFn8VrlmKjpOdYGPJR74Rd9q_3MVjX3aHutdZnpfPfVnAEiwFi2ZMJ54uuwr4nSwpkKkcMXwoUO6cOIzsuy83gOQQaQlxHpF_3gHyFacjnb8BIBNkuQ)
|
||||
|
||||
|
||||
### CONFIGURE
|
||||
|
||||
The [MAV_CMD_DO_ILLUMINATOR_CONFIGURE](#MAV_CMD_DO_ILLUMINATOR_CONFIGURE) command controls the illuminator's settings. This will adjust how the illuminator behaves when enabled. The operation follows the normal [Command Protocol](https://github.com/mavlink/mavlink-devguide/blob/master/en/services/command.md) rules for command/acknowledgment. The four parameters for this command are: Mode, Brightness, Strobe Period, Strobe Duty.
|
||||
|
||||
Illuminators can be set in different modes which can change the behavior of the illuminator (described in a separate section, [Modes](#MODES)). The brightness can be set via "Brightness" as a percentage value (0-100%). Illuminators may also have the functionality to strobe the light source. This behavior is configured via "Strobe Period" and "Strobe Duty". These parameters can be set to 0 when not used. "Strobe Period" is in seconds and "Strobe Duty" is a percentage value (indicating the % of time in the "Strobe Period" the illuminator is enabled).
|
||||
|
||||
|
||||
#### MODES
|
||||
|
||||
If the mode is unknown, the mode parameter value will be set to 0.
|
||||
|
||||
A mode value of 1 is `ILLUMINATOR_MODE_INTERNAL_CONTROL`, where the illuminator behavior is controlled by [MAV_CMD_DO_ILLUMINATOR_CONFIGURE](#MAV_CMD_DO_ILLUMINATOR_CONFIGURE) settings.
|
||||
|
||||
When the value is set to 2, it indicates that the illuminator mode is `ILLUMINATOR_MODE_EXTERNAL_SYNC`. This mode is for instances where the illuminator behavior is controlled by external factors: e.g. an external hardware signal.
|
||||
|
||||
### STATUS
|
||||
|
||||
The [ILLUMINATOR_STATUS](#ILLUMINATOR_STATUS) message can be requested to receive information about the status of the illuminator. This includes information such as uptime, errors, whether the illuminator is enabled via [MAV_CMD_ILLUMINATOR_ON_OFF](#MAV_CMD_ILLUMINATOR_ON_OFF), current settings from the [MAV_CMD_DO_ILLUMINATOR_CONFIGURE](#MAV_CMD_DO_ILLUMINATOR_CONFIGURE) command, and the temperature of the illuminator.
|
||||
|
||||
#### ILLUMINATOR_ERROR_FLAGS
|
||||
|
||||
The [ILLUMINATOR_ERROR_FLAGS](#ILLUMINATOR_ERROR_FLAGS) can be used to indicate if there is any issue with the illuminator. At this time, there are three flags. If there is no error and the illuminator is behaving as normal, the [ILLUMINATOR_ERROR_FLAGS](#ILLUMINATOR_ERROR_FLAGS) bitmap will be 0. If [ILLUMINATOR_ERROR_FLAGS](#ILLUMINATOR_ERROR_FLAGS) is set to 1 or 2, this indicates an error related to the temperature of the illuminator.
|
||||
|
||||
"1" indicates `ILLUMINATOR_ERROR_FLAGS_THERMAL_THROTTLING` as in the illuminator is throttling its output due to a thermal issue. "2" indicates `ILLUMINATOR_ERROR_FLAGS_OVER_TEMPERATURE_SHUTDOWN` which means that the illuminator is shutting off due to passing some temperature threshold.
|
||||
|
||||
The status message utilization can be seen below:
|
||||
|
||||
<!-- Mermaid graph:
|
||||
sequenceDiagram;
|
||||
participant Drone
|
||||
participant Illuminator
|
||||
Drone->>Illuminator: MAV_CMD_REQUEST_MESSAGE(param1=ILLUMINATOR_STATUS)
|
||||
Drone->>Drone: Start timeout
|
||||
Illuminator->>Drone: MAV_RESULT_ACCEPTED
|
||||
Illuminator->>Drone: ILLUMINATOR_STATUS [(50000.0, 1, 1, 1, 1, 80.0, 0.0, 0.0, 95.0, 0.0, 10.0)]
|
||||
Note over Illuminator, Drone: Illuminator Status published as: <br> uptime_ms = 50000.0, enable = 1, mode_bitmask = 1 <br> error_status = 1, mode = 1, brightness = 80% <br> strobe_period = 0.0, strobe_duty_cycle = 0.0, temp_c = 95.0 <br>min_strobe_period = 0.0, max_strobe_period = 10.0
|
||||
|
||||
-->
|
||||
|
||||
[](https://mermaid.live/edit#pako:eNqFUm1rwjAQ_ishMHDghn4Qtm4KRcsQdC-27ss6QtreZrBJuuQyJmP_fWmdVlDYEdLLPc_dc5fmm-a6ABpQ4s3ChwOVw0Twd8PlTarIn1XcoMhFxRWSidEKTkPTsnRSKI7atISGfzEaHYABmYfPbDyfsEX0tIzihM2jOA7voo6vxmV_OJ3NlvPpfZg8LFichMkyPj8u2HwDEqPvgKCQoB22rAO5llvLLqJ4OUtYOB5Hj0k0-SfjuBPy0hn0vF32uqR_sK6aSLtdD_Zu3-_nr63SvUYg-hPMoWaX7CTbWD0cOksql5XCrqAg3AbkNjMj4qp6ZCYtGZJ9P6B4VoKP-H6k_7EsEyi5XdeRbRoYow2z27J73tbLjHhfoQJbI1e9s22GRaMzYBUYoQsPNEJ_wcLhhuWbvNFsAARZsdyf6vGbAn4UdrKG5F9HQH1TtEslGMlF4d_ld31rKcUVSEhp4N2Cm3VKU_XjedyhjjcqpwEaB13qqoLj7v3S4I2XFn5-AbUw5Hc)
|
||||
|
||||
## Test Script
|
||||
|
||||
#### Description
|
||||
|
||||
The test suite included in `illuminator.py` allows for testing both sides of the illuminator interaction. The first script `illuminator.py` will emulate a standard illuminator module. The second script will run a standard test suite against the emulator, testing all commands listed in this document.
|
||||
|
||||
##### Instructions
|
||||
|
||||
1. Run simple illuminator emulator `python3 illuminator.py`
|
||||
2. Run test `python3 -m unittest -v test_illuminator.py`
|
||||
Reference in New Issue
Block a user