Skip to content

Commit 5f3298d

Browse files
committed
Clarify what the -pluginUUID option passed in by StreamDeck is doing and how it is used
1 parent d28c233 commit 5f3298d

5 files changed

Lines changed: 36 additions & 18 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
[project]
99
name = "streamdeck-plugin-sdk"
10-
version = "0.2.1"
10+
version = "0.2.2"
1111
description = "Write Streamdeck plugins using Python"
1212
readme = "README.md"
1313
authors = [

streamdeck/__main__.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ def main():
203203
args = cast(CliArgsNamespace, parser.parse_args())
204204

205205
info = json.loads(args.info)
206-
plugin_name = info["plugin"]["uuid"]
206+
plugin_uuid = info["plugin"]["uuid"]
207207

208208
action_scripts = determine_action_scripts(
209209
plugin_dir=args.plugin_dir,
@@ -214,7 +214,10 @@ def main():
214214

215215
manager = PluginManager(
216216
port=args.port,
217-
plugin_uuid=args.pluginUUID,
217+
plugin_uuid=plugin_uuid,
218+
# NOT the configured plugin UUID in the manifest.json,
219+
# which can be pulled out of `info["plugin"]["uuid"]`
220+
plugin_registration_uuid=args.pluginUUID,
218221
register_event=args.registerEvent,
219222
info=info,
220223
)

streamdeck/command_sender.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -257,17 +257,23 @@ def send_to_plugin(
257257
def send_action_registration(
258258
self,
259259
register_event: str,
260-
plugin_uuid: str,
260+
plugin_registration_uuid: str,
261261
) -> None:
262-
"""Send a payload to another plugin.
262+
"""Registers a plugin with the Stream Deck software very shortly after the plugin is started.
263+
264+
Upon running a plugin's startup command, the Stream Deck software will pass in args that include a
265+
register event type string (almost definitely "registerPlugin") and a unique random ID, which the
266+
plugin needs to immediately send back as an event message in order to register itself.
267+
If the Stream Deck software doesn't receive this event after a very brief period, it will keep
268+
trying to re-run the plugin until getting the event.
263269
264270
Args:
265-
action: The unique identifier of the receiving plugin's action.
266-
If your plugin supports multiple actions, you should use this value to find out
267-
which action was triggered.
268-
payload: The data that will be received by the receiving plugin.
271+
register_event (str): The registration event type, passed in by the Stream Deck software as -registerEvent option.
272+
It's value will almost definitely will be "registerPlugin".
273+
plugin_registration_uuid (str): Randomly-generated unique ID passed in by StreamDeck as -pluginUUID option,
274+
used to send back in the registerPlugin event. Note that this is NOT the manifest.json -configured plugin UUID value.
269275
"""
270276
self._send_event(
271277
event=register_event,
272-
uuid=plugin_uuid,
273-
)
278+
uuid=plugin_registration_uuid,
279+
)

streamdeck/manager.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,20 +29,27 @@ class PluginManager:
2929
def __init__(
3030
self,
3131
port: int,
32-
plugin_uuid: str, # Passed in by Streamdeck to the entry-point script. should we compare what's in the manifest.json file?
32+
plugin_uuid: str,
33+
plugin_registration_uuid: str, # Passed in by Streamdeck to the entry-point script. should we compare what's in the manifest.json file?
3334
register_event: Literal["registerPlugin"], # Passed in by Streamdeck to the entry-point script. Will this always be "registerPlugin"?
3435
info: dict[str, Any]
3536
):
3637
"""Initialize a PluginManager instance.
3738
3839
Args:
3940
port (int): The port number for WebSocket connection.
40-
plugin_uuid (str): The unique identifier for the plugin.
41-
register_event (str): The registration event type.
41+
plugin_uuid (str): The unique identifier for the plugin, as configured in the manifest.json file.
42+
This can be retrieved either from the manifest.json, or from the -info json object string option passed in by
43+
the Stream Deck software under `{"plugin": {"uuid": "MY-PLUGIN-UUID"}}`
44+
plugin_registration_uuid (str): Randomly-generated unique ID passed in by Stream Deck as -pluginUUID option,
45+
used to send back in the registerPlugin event.
46+
register_event (str): The registration event type, passed in by the Stream Deck software as -registerEvent option.
47+
It's value will almost definitely will be "registerPlugin".
4248
info (dict[str, Any]): The information related to the plugin.
4349
"""
4450
self._port = port
4551
self.uuid = plugin_uuid
52+
self._registration_uuid = plugin_registration_uuid
4653
self._register_event = register_event
4754
self._info = info
4855

@@ -65,7 +72,7 @@ def run(self) -> None:
6572
with WebSocketClient(port=self._port) as client:
6673
command_sender = StreamDeckCommandSender(client)
6774

68-
command_sender.send_action_registration(register_event=self._register_event, plugin_uuid=self.uuid)
75+
command_sender.send_action_registration(register_event=self._register_event, plugin_registration_uuid=self._registration_uuid)
6976

7077
for message in client.listen_forever():
7178
data: EventBase = event_adapter.validate_json(message)

tests/test_plugin_manager.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import uuid
12
from typing import cast
23
from unittest.mock import MagicMock, Mock
34

@@ -22,12 +23,14 @@ def plugin_manager(port_number: int) -> PluginManager:
2223
PluginManager: An instance of PluginManager with test parameters.
2324
"""
2425
plugin_uuid = "test-plugin-uuid"
26+
plugin_registration_uuid = str(uuid.uuid1())
2527
register_event = "registerPlugin"
2628
info = {"some": "info"}
2729

2830
return PluginManager(
2931
port=port_number,
3032
plugin_uuid=plugin_uuid,
33+
plugin_registration_uuid=plugin_registration_uuid,
3134
register_event=register_event,
3235
info=info
3336
)
@@ -43,7 +46,6 @@ def patch_websocket_client(monkeypatch: pytest.MonkeyPatch) -> tuple[MagicMock,
4346
Returns:
4447
tuple: Mocked instance of WebSocketClient, and a fake DialRotateEvent.
4548
"""
46-
4749
mock_websocket_client = MagicMock(spec=WebSocketClient)
4850

4951
mock_websocket_client.__enter__.return_value = mock_websocket_client
@@ -117,7 +119,7 @@ def test_plugin_manager_sends_registration_event(mock_command_sender: Mock, plug
117119

118120
mock_command_sender.send_action_registration.assert_called_once_with(
119121
register_event=plugin_manager._register_event,
120-
plugin_uuid=plugin_manager.uuid,
122+
plugin_registration_uuid=plugin_manager._registration_uuid,
121123
)
122124

123125

@@ -135,4 +137,4 @@ def test_plugin_manager_process_event(patch_websocket_client: tuple[MagicMock, E
135137
spied_event_adapter_validate_json.assert_called_once_with(fake_event_message.model_dump_json())
136138
assert spied_event_adapter_validate_json.spy_return == fake_event_message
137139

138-
cast(Mock, plugin_manager._registry.get_action_handlers).assert_called_once_with(fake_event_message.event)
140+
cast(Mock, plugin_manager._registry.get_action_handlers).assert_called_once_with(fake_event_message.event)

0 commit comments

Comments
 (0)