diff --git a/README.md b/README.md index 3e7ba35..6b35641 100644 --- a/README.md +++ b/README.md @@ -5,13 +5,9 @@ Stream Deck API Library for Home Assistant Stream Deck Integration Only compatible with separate [Stream Deck Plugin](https://github.com/Patrick762/streamdeckapi-plugin) or the bundled server. -## Requirements -- Python 3.10 or higher - ## Dependencies - [websockets](https://pypi.org/project/websockets/) 11.0.2 - ## Server This library also contains a server to use the streamdeck with Linux or without the official Stream Deck Software. @@ -21,3 +17,24 @@ For this to work, the following software is required: - cairo [Installation instructions for Windows](https://stackoverflow.com/a/73913080) The event `doubleTap` is not working with this server software. + +### Installation on Linux / Raspberry Pi + +Install requirements: +`sudo apt install -y libudev-dev libusb-1.0-0-dev libhidapi-libusb0 libjpeg-dev zlib1g-dev libopenjp2-7 libtiff5` + +Allow all users non-root access to Stream Deck Devices: +```bash +sudo tee /etc/udev/rules.d/10-streamdeck.rules << EOF +SUBSYSTEMS=="usb", ATTRS{idVendor}=="0fd9", GROUP="users", TAG+="uaccess" +EOF +``` + +Reload access rules: +`sudo udevadm control --reload-rules` + +Install the package: +`pip install streamdeckapi` + +Start the server: +`streamdeckapi-server` diff --git a/streamdeckapi/__init__.py b/streamdeckapi/__init__.py index 9bb9f9a..f412138 100644 --- a/streamdeckapi/__init__.py +++ b/streamdeckapi/__init__.py @@ -1,5 +1 @@ """Stream Deck API.""" - -from streamdeckapi.api import StreamDeckApi -from streamdeckapi.types import SDInfo, SDWebsocketMessage, SDSize, SDApplication, SDButton, SDButtonPosition, SDDevice -from streamdeckapi.tools import get_model diff --git a/streamdeckapi/server.py b/streamdeckapi/server.py index 2f4e992..1f2c140 100644 --- a/streamdeckapi/server.py +++ b/streamdeckapi/server.py @@ -110,7 +110,7 @@ def save_button(key: int, button: SDButton): database.close() -def get_button(key: int) -> SDButton | None: +def get_button(key: int) -> any: """Get a button from the database.""" database = sqlite3.connect(DB_FILE) cursor = database.cursor() @@ -134,7 +134,7 @@ def get_button(key: int) -> SDButton | None: return button -def get_button_by_uuid(uuid: str) -> SDButton | None: +def get_button_by_uuid(uuid: str) -> any: """Get a button from the database.""" database = sqlite3.connect(DB_FILE) cursor = database.cursor() @@ -220,7 +220,7 @@ def write_button_state(key: int, state: bool, update: str): database.close() -def get_button_state(key: int) -> tuple | None: +def get_button_state(key: int) -> any: """Load button_state from database.""" result = () database = sqlite3.connect(DB_FILE) @@ -265,7 +265,7 @@ async def api_icon_get_handler(request: web.Request): """Handle icon get requests.""" uuid = request.match_info["uuid"] button = get_button_by_uuid(uuid) - if button is None: + if not isinstance(button, SDButton): return web.Response(status=404, text="Button not found") return web.Response(text=button.svg, content_type="image/svg+xml") @@ -279,7 +279,7 @@ async def api_icon_set_handler(request: web.Request): if not body.startswith(" SDButtonPosition: async def on_key_change(_: StreamDeck, key: int, state: bool): """Handle key change callbacks.""" button = get_button(key) - if button is None: + if not isinstance(button, SDButton): return if state is True: @@ -395,7 +395,7 @@ async def on_key_change(_: StreamDeck, key: int, state: bool): db_button_state = get_button_state(key) - if db_button_state is None: + if not isinstance(db_button_state, tuple): write_button_state(key, state, now.strftime(DATETIME_FORMAT)) return @@ -431,7 +431,7 @@ def update_button_icon(uuid: str, svg: str): button = get_button_by_uuid(uuid) button_key = get_button_key(uuid) - if button is not None and button_key >= 0: + if isinstance(button, SDButton) and button_key >= 0: set_icon(deck, button_key, svg) button.svg = svg save_button(button_key, button) @@ -478,7 +478,7 @@ def init_all(): for key in range(deck.key_count()): # Only add if not already in dict button = get_button(key) - if button is None: + if not isinstance(button, SDButton): position = get_position(deck, key) new_button = SDButton( { diff --git a/streamdeckapi/types.py b/streamdeckapi/types.py index 34d103b..284564f 100644 --- a/streamdeckapi/types.py +++ b/streamdeckapi/types.py @@ -96,7 +96,7 @@ class SDWebsocketMessage: """Stream Deck Websocket Message Type.""" event: str - args: SDInfo | str | dict + args: any def __init__(self, obj: dict) -> None: """Init Stream Deck Websocket Message object."""