Metadata-Version: 2.4
Name: frame-msg
Version: 5.0.0
Summary: Handles various message types for the Brilliant Labs Frame
Project-URL: Homepage, https://github.com/CitizenOneX/frame_msg_python
Project-URL: Bug Tracker, https://github.com/CitizenOneX/frame_msg_python/issues
Project-URL: Changelog, https://github.com/CitizenOneX/frame_msg_python/blob/main/CHANGELOG.md
Author: CitizenOne
License-File: LICENSE
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.7
Requires-Dist: frame-ble>=1.0.5
Requires-Dist: lz4<5.0.0,>=4.4.3
Requires-Dist: numpy<3.0.0,>=2.2.3
Requires-Dist: pillow<12.0.0,>=11.1.0
Description-Content-Type: text/markdown

# Frame Message Package

A Python package for handling various types of messages for the Brilliant Labs Frame, including sprites, text, audio, IMU data, and photos.

## Installation

```bash
pip install frame-msg
```

## Usage

```python
import asyncio
from pathlib import Path

from frame_msg import FrameMsg, TxSprite

async def main():
    """
    Displays sample images on the Frame display.

    The images are indexed (palette) PNG images, in 2, 4, and 16 colors (that is, 1-, 2- and 4-bits-per-pixel).
    """
    frame = FrameMsg()
    try:
        await frame.connect()

        # Let the user know we're starting
        await frame.print_short_text('Loading...')

        # send the std lua files to Frame that handle data accumulation and sprite parsing
        await frame.upload_stdlua_libs(lib_names=['data', 'sprite'])

        # Send the main lua application from this project to Frame that will run the app
        await frame.upload_frame_app(local_filename="lua/sprite_frame_app.lua")

        # attach the print response handler so we can see stdout from Frame Lua print() statements
        frame.attach_print_response_handler()

        # "require" the main frame_app lua file to run it, and block until it has started.
        await frame.start_frame_app()

        # send the 1-bit image to Frame in chunks
        sprite = TxSprite.from_indexed_png_bytes(Path("images/logo_1bit.png").read_bytes())
        await frame.send_message(0x20, sprite.pack())

        # send a 2-bit image
        sprite = TxSprite.from_indexed_png_bytes(Path("images/street_2bit.png").read_bytes())
        await frame.send_message(0x20, sprite.pack())

        # send a 4-bit image
        sprite = TxSprite.from_indexed_png_bytes(Path("images/hotdog_4bit.png").read_bytes())
        await frame.send_message(0x20, sprite.pack())

        await asyncio.sleep(5.0)

        # unhook the print handler
        frame.detach_print_response_handler()

        # break out of the frame app loop and reboot Frame
        await frame.stop_frame_app()

    except Exception as e:
        print(f"An error occurred: {e}")
    finally:
        # clean disconnection
        await frame.disconnect()

if __name__ == "__main__":
    asyncio.run(main())
```

## Acknowledgements

* An early port of [TxSprite](https://github.com/CitizenOneX/frame_msg/blob/main/lib/tx/sprite.dart) from Flutter to Python was contributed by [David Khachatryan](https://github.com/KhachDavid) - _thanks!_