fixed python 3.9 compatibility
This commit is contained in:
25
README.md
25
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.
|
Only compatible with separate [Stream Deck Plugin](https://github.com/Patrick762/streamdeckapi-plugin) or the bundled server.
|
||||||
|
|
||||||
## Requirements
|
|
||||||
- Python 3.10 or higher
|
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
- [websockets](https://pypi.org/project/websockets/) 11.0.2
|
- [websockets](https://pypi.org/project/websockets/) 11.0.2
|
||||||
|
|
||||||
|
|
||||||
## Server
|
## Server
|
||||||
This library also contains a server to use the streamdeck with Linux or without the official Stream Deck Software.
|
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)
|
- cairo [Installation instructions for Windows](https://stackoverflow.com/a/73913080)
|
||||||
|
|
||||||
The event `doubleTap` is not working with this server software.
|
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`
|
||||||
|
|||||||
@@ -1,5 +1 @@
|
|||||||
"""Stream Deck API."""
|
"""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
|
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ def save_button(key: int, button: SDButton):
|
|||||||
database.close()
|
database.close()
|
||||||
|
|
||||||
|
|
||||||
def get_button(key: int) -> SDButton | None:
|
def get_button(key: int) -> any:
|
||||||
"""Get a button from the database."""
|
"""Get a button from the database."""
|
||||||
database = sqlite3.connect(DB_FILE)
|
database = sqlite3.connect(DB_FILE)
|
||||||
cursor = database.cursor()
|
cursor = database.cursor()
|
||||||
@@ -134,7 +134,7 @@ def get_button(key: int) -> SDButton | None:
|
|||||||
return button
|
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."""
|
"""Get a button from the database."""
|
||||||
database = sqlite3.connect(DB_FILE)
|
database = sqlite3.connect(DB_FILE)
|
||||||
cursor = database.cursor()
|
cursor = database.cursor()
|
||||||
@@ -220,7 +220,7 @@ def write_button_state(key: int, state: bool, update: str):
|
|||||||
database.close()
|
database.close()
|
||||||
|
|
||||||
|
|
||||||
def get_button_state(key: int) -> tuple | None:
|
def get_button_state(key: int) -> any:
|
||||||
"""Load button_state from database."""
|
"""Load button_state from database."""
|
||||||
result = ()
|
result = ()
|
||||||
database = sqlite3.connect(DB_FILE)
|
database = sqlite3.connect(DB_FILE)
|
||||||
@@ -265,7 +265,7 @@ async def api_icon_get_handler(request: web.Request):
|
|||||||
"""Handle icon get requests."""
|
"""Handle icon get requests."""
|
||||||
uuid = request.match_info["uuid"]
|
uuid = request.match_info["uuid"]
|
||||||
button = get_button_by_uuid(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(status=404, text="Button not found")
|
||||||
return web.Response(text=button.svg, content_type="image/svg+xml")
|
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("<svg"):
|
if not body.startswith("<svg"):
|
||||||
return web.Response(status=422, text="Only svgs are supported")
|
return web.Response(status=422, text="Only svgs are supported")
|
||||||
button = get_button_by_uuid(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(status=404, text="Button not found")
|
||||||
|
|
||||||
# Update icon
|
# Update icon
|
||||||
@@ -381,7 +381,7 @@ def get_position(deck: StreamDeck, key: int) -> SDButtonPosition:
|
|||||||
async def on_key_change(_: StreamDeck, key: int, state: bool):
|
async def on_key_change(_: StreamDeck, key: int, state: bool):
|
||||||
"""Handle key change callbacks."""
|
"""Handle key change callbacks."""
|
||||||
button = get_button(key)
|
button = get_button(key)
|
||||||
if button is None:
|
if not isinstance(button, SDButton):
|
||||||
return
|
return
|
||||||
|
|
||||||
if state is True:
|
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)
|
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))
|
write_button_state(key, state, now.strftime(DATETIME_FORMAT))
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -431,7 +431,7 @@ def update_button_icon(uuid: str, svg: str):
|
|||||||
|
|
||||||
button = get_button_by_uuid(uuid)
|
button = get_button_by_uuid(uuid)
|
||||||
button_key = get_button_key(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)
|
set_icon(deck, button_key, svg)
|
||||||
button.svg = svg
|
button.svg = svg
|
||||||
save_button(button_key, button)
|
save_button(button_key, button)
|
||||||
@@ -478,7 +478,7 @@ def init_all():
|
|||||||
for key in range(deck.key_count()):
|
for key in range(deck.key_count()):
|
||||||
# Only add if not already in dict
|
# Only add if not already in dict
|
||||||
button = get_button(key)
|
button = get_button(key)
|
||||||
if button is None:
|
if not isinstance(button, SDButton):
|
||||||
position = get_position(deck, key)
|
position = get_position(deck, key)
|
||||||
new_button = SDButton(
|
new_button = SDButton(
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ class SDWebsocketMessage:
|
|||||||
"""Stream Deck Websocket Message Type."""
|
"""Stream Deck Websocket Message Type."""
|
||||||
|
|
||||||
event: str
|
event: str
|
||||||
args: SDInfo | str | dict
|
args: any
|
||||||
|
|
||||||
def __init__(self, obj: dict) -> None:
|
def __init__(self, obj: dict) -> None:
|
||||||
"""Init Stream Deck Websocket Message object."""
|
"""Init Stream Deck Websocket Message object."""
|
||||||
|
|||||||
Reference in New Issue
Block a user