API Reference
brilliant_msg - Message Package defines Transmit- and Receive-related message classes and their associated Lua handlers for Brilliant Labs Frame and Halo devices (https://brilliant.xyz/)
BrilliantMsg
- class brilliant_msg.brilliant_msg.BrilliantMsg[source]
Bases:
objectA high-level library for interacting with Brilliant Labs Frame by passing structured messages between a Frameside app and a hostside app.
- async connect(initialize: bool = True, name=None)[source]
Connect to the Frame device and optionally run the initialization sequence.
- Parameters:
- Returns:
- The BLE local name of the connected device (e.g. “Halo 08”),
also available afterwards as self.name.
- Return type:
- Raises:
Any exceptions from the underlying BrilliantBle connection –
- async print_short_text(text: str = '')[source]
Convenience wrapper around frame.display.text() that can only be used prior to the main frame_app starting (e.g. immediately after connection).
- async upload_stdlua_libs(lib_names: List[str] = ['data'], minified: bool = True)[source]
Send the specified standard frame-msg Lua files to Frame that are used by the frame_app, e.g. [‘data’, ‘camera’]
- async upload_frame_app(local_filename: str, frame_filename: str = 'frame_app.lua')[source]
Send the main lua application from this project to Frame that will run the app (but doesn’t run the file)
- async start_frame_app(frame_app_name: str = 'frame_app', await_print: bool = True)[source]
‘require’ the main lua file to run it
Note: This require() doesn’t return - frame_app.lua has a main loop, so we can’t put a ‘print(0)’ after the require() statement and wait for it to print, however if our main loop prints something (even a byte) once it has started up, then the await_print can be used to determine that the frameside app is ready rather than waiting for an app-dependent amount of time, or sending messages to Frame too early. Set await_print to False if the Frame app should be asynchronously started and without waiting for any printed confirmation that the frameside app is ready.
- async stop_frame_app(reset=True)[source]
Sends a break signal to terminate the running main loop on Frame, if applicable. A custom app may prefer to send a specific TxCode to the Frameside app to instruct it to shut down cleanly, but a break signal will also be caught by the exception handler of the main loop and is enough to clean up the display, release memory etc.
If reset is True (default), then also send a reset signal that will reinitialize the Lua VM and boot into a saved main.lua, if present.
- attach_print_response_handler(handler=<built-in function print>)[source]
Attach the print response handler so we can see stdout from Frame Lua print() statements
- detach_print_response_handler()[source]
Detach the print response handler so we no longer see stdout from Frame Lua print() statements
- async send_message(msg_code: int, payload: bytes, show_me: bool = False) None[source]
Sends a structured message from hostside to the Frameside app, identified by the specified msg_code. For example, if the frame_app is expecting a TxCaptureSettings message on msg_code 0x0d to initiate a photo capture, you might send: frame.send_message(0x0d, TxCaptureSettings(resolution=720).pack()) Wraps the brilliant_ble function of the same name
- register_data_response_handler(subscriber, msg_codes: List[int], handler: Callable[[bytes], None])[source]
Register a handler for a subscriber that is interested in specific msg codes.
- Parameters:
subscriber – The subscriber object.
msg_codes (List[int]) – List of single byte msg codes the subscriber is interested in.
handler – The handler function to receive the data.
RxAudio
- class brilliant_msg.rx_audio.RxAudio(non_final_chunk_flag: int = 5, final_chunk_flag: int = 6, streaming: bool = False)[source]
Bases:
object- handle_data(data: bytes) None[source]
Process incoming audio data packets with either a non-final or a final msg code.
- Parameters:
data – Bytes containing audio data with flag byte prefix
- async attach(frame: BrilliantMsg) Queue[source]
Attach the audio handler to the Frame data response and return a queue that will receive audio data.
- Returns:
asyncio.Queue that will receive bytes containing audio data. In streaming mode, receives chunks as they arrive. In single-clip mode, receives complete audio clip at once. A None value indicates end of stream/clip.
- detach(frame: BrilliantMsg) None[source]
Detach the audio handler from the Frame data response and clean up resources
- static to_wav_bytes(pcm_data: bytes, sample_rate: int = 8000, bits_per_sample: int = 8, channels: int = 1) bytes[source]
Create a WAV file from PCM data.
- Parameters:
pcm_data – Raw PCM audio data - signed 8-bit or 16-bit samples straight from Frame (8-bit signed will be converted to unsigned 8-bit for WAV)
sample_rate – Audio sample rate in Hz
bits_per_sample – Number of bits per sample
channels – Number of audio channels
- Returns:
Bytes containing complete WAV file
RxAutoExpResult
- class brilliant_msg.rx_auto_exp_result.RxAutoExpResult(msg_code: int = 17)[source]
Bases:
object- handle_data(data: bytes) None[source]
Process incoming data packets.
- Parameters:
data – Bytes containing auto exposure result data with flag byte prefix and 16 floats
- async attach(frame: BrilliantMsg) Queue[source]
Attach the receive handler to the Frame data response and return a queue that will receive autoexposure result data.
- Returns:
asyncio.Queue that will receive autoexposure result objects
- detach(frame: BrilliantMsg) None[source]
Detach the receive handler from the Frame data response and clean up resources
RxIMU
- class brilliant_msg.rx_imu.SensorBuffer(max_size: int)[source]
Bases:
objectBuffer class to provide smoothed moving average of samples
- class brilliant_msg.rx_imu.IMURawData(compass: Tuple[float, float, float], accel: Tuple[float, float, float])[source]
Bases:
object
- class brilliant_msg.rx_imu.IMUData(compass: Tuple[float, float, float], accel: Tuple[float, float, float], raw: brilliant_msg.rx_imu.IMURawData | None = None)[source]
Bases:
object- raw: IMURawData | None = None
- class brilliant_msg.rx_imu.RxIMU(imu_flag: int = 10, smoothing_samples: int = 1)[source]
Bases:
object- handle_data(data: bytes) None[source]
Process incoming IMU data packets.
- Parameters:
data – Bytes containing IMU data with flag byte prefix
- async attach(frame: BrilliantMsg) Queue[source]
Attach the IMU handler to the Frame data response and return a queue that will receive IMU data.
- Returns:
asyncio.Queue that will receive IMUData objects
- detach(frame: BrilliantMsg) None[source]
Detach the IMU handler from the Frame data response and clean up resources
RxMeteringData
- class brilliant_msg.rx_metering_data.RxMeteringData(msg_code: int = 18)[source]
Bases:
object- handle_data(data: bytes) None[source]
Process incoming data packets.
- Parameters:
data – Bytes containing metering data with flag byte prefix and 6 unsigned bytes (spot r,g,b, matrix r,g,b)
- async attach(frame: BrilliantMsg) Queue[source]
Attach the receive handler to the Frame data response and return a queue that will receive metering data.
- Returns:
asyncio.Queue that will receive metering data objects
- detach(frame: BrilliantMsg) None[source]
Detach the receive handler from the Frame data response and clean up resources
RxPhoto
- class brilliant_msg.rx_photo.RxPhoto(non_final_chunk_flag: int = 7, final_chunk_flag: int = 8, upright: bool = True, is_raw: bool = False, quality: str | None = None, resolution: int | None = None)[source]
Bases:
object- classmethod has_jpeg_header(quality: str, resolution: int) bool[source]
Check if we have a stored JPEG header for the given quality and resolution
- handle_data(data: bytes) None[source]
Process incoming chunks of image data.
- Parameters:
data – Bytes containing image chunk with flag byte prefix
- async attach(frame: BrilliantMsg) Queue[source]
Attach the photo handler to the Frame data response and return a queue that will receive complete images.
- Returns:
asyncio.Queue that will receive bytes containing complete JPEG images
- detach(frame: BrilliantMsg) None[source]
Detach the photo handler from the Frame data response and clean up resources
RxTap
- class brilliant_msg.rx_tap.RxTap(tap_flag: int = 9, threshold: float = 0.3)[source]
Bases:
object- handle_data(data: bytes) None[source]
Process an incoming Tap message
- Parameters:
data – The tap_flag byte, optionally followed by a kind byte (1=single, 2=double, 3=triple) on Halo firmware 0.8.8+
- async attach(frame: BrilliantMsg) Queue[source]
Attach the tap handler to the Frame data response and return a queue that will receive tap counts.
- Returns:
asyncio.Queue that will receive integers representing tap counts
- detach(frame: BrilliantMsg) None[source]
Detach the tap handler from the Frame data response and clean up resources
TxAutoExpSettings
- class brilliant_msg.tx_auto_exp_settings.TxAutoExpSettings(metering_index: int = 1, exposure: float = 0.1, exposure_speed: float = 0.45, shutter_limit: int = 16383, analog_gain_limit: int = 16, white_balance_speed: float = 0.5, rgb_gain_limit: int = 287)[source]
Bases:
objectMessage for auto exposure and gain settings.
- metering_index
Zero-based index into [‘SPOT’, ‘CENTER_WEIGHTED’, ‘AVERAGE’] i.e. 0, 1 or 2.
- Type:
TxCaptureSettings
TxCode
TxImageSpriteBlock
- class brilliant_msg.tx_image_sprite_block.TxImageSpriteBlock(image: TxSprite, sprite_line_height: int = 16, progressive_render: bool = True, updatable: bool = True)[source]
Bases:
objectAn image split into horizontal sprite strips.
- image
Source sprite to split
- sprite_line_height
Height of each sprite strip. If the TxSprite is compressed, the strip has a packed size limit of 4kB and this value is ignored.
- Type:
TxManualExpSettings
TxPlainText
TxSprite
- class brilliant_msg.tx_sprite.TxSprite(width: int, height: int, num_colors: int, palette_data: bytes, pixel_data: bytes, compress: bool = False)[source]
Bases:
objectA sprite message containing image data with a custom palette.
- static from_indexed_png_bytes(image_bytes: bytes, compress=False) TxSprite[source]
Create a TxSprite from an indexed PNG with minimal processing.