streamdeck 0.9.4__tar.gz → 0.9.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {streamdeck-0.9.4 → streamdeck-0.9.5}/CHANGELOG +3 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/PKG-INFO +8 -2
- {streamdeck-0.9.4 → streamdeck-0.9.5}/README.md +7 -1
- streamdeck-0.9.5/VERSION +1 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/StreamDeck/DeviceManager.py +3 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/StreamDeck/Devices/StreamDeck.py +228 -11
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/StreamDeck/Devices/StreamDeckMini.py +8 -3
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/StreamDeck/Devices/StreamDeckOriginal.py +8 -3
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/StreamDeck/Devices/StreamDeckOriginalV2.py +8 -3
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/StreamDeck/Devices/StreamDeckPedal.py +8 -3
- streamdeck-0.9.5/src/StreamDeck/Devices/StreamDeckPlus.py +479 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/StreamDeck/Devices/StreamDeckXL.py +8 -3
- streamdeck-0.9.5/src/StreamDeck/ImageHelpers/PILHelper.py +194 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/StreamDeck/ProductIDs.py +3 -2
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/StreamDeck/Transport/LibUSBHIDAPI.py +22 -135
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/StreamDeck/Transport/Transport.py +1 -1
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/example_animated.py +2 -2
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/example_basic.py +2 -2
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/example_deckinfo.py +15 -6
- streamdeck-0.9.5/src/example_plus.py +135 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/example_tileimage.py +2 -2
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/streamdeck.egg-info/PKG-INFO +8 -2
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/streamdeck.egg-info/SOURCES.txt +4 -1
- streamdeck-0.9.5/test/test.py +128 -0
- streamdeck-0.9.4/VERSION +0 -1
- streamdeck-0.9.4/src/StreamDeck/ImageHelpers/PILHelper.py +0 -108
- {streamdeck-0.9.4 → streamdeck-0.9.5}/ExampleDeck.jpg +0 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/LICENSE +0 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/MANIFEST.in +0 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/setup.cfg +0 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/setup.py +0 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/Assets/Apache License 2.0.txt +0 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/Assets/Attribution.txt +0 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/Assets/CC BY-SA 3.0 License.txt +0 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/Assets/CC0 License.txt +0 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/Assets/Elephant_Walking_animated.gif +0 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/Assets/Exit.png +0 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/Assets/Harold.jpg +0 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/Assets/Pressed.png +0 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/Assets/RGB_color_space_animated_view.gif +0 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/Assets/Released.png +0 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/Assets/Roboto-Regular.ttf +0 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/Assets/Simple_CV_Joint_animated.gif +0 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/StreamDeck/Devices/__init__.py +0 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/StreamDeck/ImageHelpers/__init__.py +0 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/StreamDeck/Transport/Dummy.py +0 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/StreamDeck/Transport/__init__.py +0 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/StreamDeck/__init__.py +0 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/example_pedal.py +0 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/streamdeck.egg-info/dependency_links.txt +0 -0
- {streamdeck-0.9.4 → streamdeck-0.9.5}/src/streamdeck.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: streamdeck
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.5
|
|
4
4
|
Summary: Library to control Elgato StreamDeck devices.
|
|
5
5
|
Home-page: https://github.com/abcminiuser/python-elgato-streamdeck
|
|
6
6
|
Author: Dean Camera
|
|
@@ -32,6 +32,7 @@ Description: # Python Elgato Stream Deck Library
|
|
|
32
32
|
* StreamDeck Mini
|
|
33
33
|
* StreamDeck XL
|
|
34
34
|
* StreamDeck Pedal
|
|
35
|
+
* StreamDeck Plus
|
|
35
36
|
|
|
36
37
|
|
|
37
38
|
## Package Installation:
|
|
@@ -57,14 +58,18 @@ Description: # Python Elgato Stream Deck Library
|
|
|
57
58
|
## Credits:
|
|
58
59
|
|
|
59
60
|
I've used the reverse engineering notes from
|
|
60
|
-
[this GitHub](https://github.com/
|
|
61
|
+
[this GitHub](https://github.com/alvancamp/node-elgato-stream-deck/blob/master/NOTES.md)
|
|
61
62
|
repository to implement this library. Thanks Alex Van Camp!
|
|
62
63
|
|
|
63
64
|
Thank you to the following contributors, large and small, for helping with the
|
|
64
65
|
development and maintenance of this library:
|
|
65
66
|
|
|
67
|
+
- [admiral0](https://github.com/admiral0)
|
|
66
68
|
- [Aetherdyne](https://github.com/Aetherdyne)
|
|
69
|
+
- [benedikt-bartscher](https://github.com/benedikt-bartscher)
|
|
70
|
+
- [brimston3](https://github.com/brimston3)
|
|
67
71
|
- [BS-Tek](https://github.com/BS-Tek)
|
|
72
|
+
- [Core447](https://github.com/Core447)
|
|
68
73
|
- [dirkk0](https://github.com/dirkk0)
|
|
69
74
|
- [dodgyrabbit](https://github.com/dodgyrabbit)
|
|
70
75
|
- [dubstech](https://github.com/dubstech)
|
|
@@ -72,6 +77,7 @@ Description: # Python Elgato Stream Deck Library
|
|
|
72
77
|
- [jakobbuis](https://github.com/jakobbuis)
|
|
73
78
|
- [jmudge14](https://github.com/jmudge14)
|
|
74
79
|
- [Kalle-Wirsch](https://github.com/Kalle-Wirsch)
|
|
80
|
+
- [karstlok](https://github.com/karstlok)
|
|
75
81
|
- [Lewiscowles1986](https://github.com/Lewiscowles1986)
|
|
76
82
|
- [m-weigand](https://github.com/m-weigand)
|
|
77
83
|
- [matrixinius](https://github.com/matrixinius)
|
|
@@ -24,6 +24,7 @@ variants:
|
|
|
24
24
|
* StreamDeck Mini
|
|
25
25
|
* StreamDeck XL
|
|
26
26
|
* StreamDeck Pedal
|
|
27
|
+
* StreamDeck Plus
|
|
27
28
|
|
|
28
29
|
|
|
29
30
|
## Package Installation:
|
|
@@ -49,14 +50,18 @@ directory.
|
|
|
49
50
|
## Credits:
|
|
50
51
|
|
|
51
52
|
I've used the reverse engineering notes from
|
|
52
|
-
[this GitHub](https://github.com/
|
|
53
|
+
[this GitHub](https://github.com/alvancamp/node-elgato-stream-deck/blob/master/NOTES.md)
|
|
53
54
|
repository to implement this library. Thanks Alex Van Camp!
|
|
54
55
|
|
|
55
56
|
Thank you to the following contributors, large and small, for helping with the
|
|
56
57
|
development and maintenance of this library:
|
|
57
58
|
|
|
59
|
+
- [admiral0](https://github.com/admiral0)
|
|
58
60
|
- [Aetherdyne](https://github.com/Aetherdyne)
|
|
61
|
+
- [benedikt-bartscher](https://github.com/benedikt-bartscher)
|
|
62
|
+
- [brimston3](https://github.com/brimston3)
|
|
59
63
|
- [BS-Tek](https://github.com/BS-Tek)
|
|
64
|
+
- [Core447](https://github.com/Core447)
|
|
60
65
|
- [dirkk0](https://github.com/dirkk0)
|
|
61
66
|
- [dodgyrabbit](https://github.com/dodgyrabbit)
|
|
62
67
|
- [dubstech](https://github.com/dubstech)
|
|
@@ -64,6 +69,7 @@ development and maintenance of this library:
|
|
|
64
69
|
- [jakobbuis](https://github.com/jakobbuis)
|
|
65
70
|
- [jmudge14](https://github.com/jmudge14)
|
|
66
71
|
- [Kalle-Wirsch](https://github.com/Kalle-Wirsch)
|
|
72
|
+
- [karstlok](https://github.com/karstlok)
|
|
67
73
|
- [Lewiscowles1986](https://github.com/Lewiscowles1986)
|
|
68
74
|
- [m-weigand](https://github.com/m-weigand)
|
|
69
75
|
- [matrixinius](https://github.com/matrixinius)
|
streamdeck-0.9.5/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.9.5
|
|
@@ -10,6 +10,7 @@ from .Devices.StreamDeckOriginal import StreamDeckOriginal
|
|
|
10
10
|
from .Devices.StreamDeckOriginalV2 import StreamDeckOriginalV2
|
|
11
11
|
from .Devices.StreamDeckXL import StreamDeckXL
|
|
12
12
|
from .Devices.StreamDeckPedal import StreamDeckPedal
|
|
13
|
+
from .Devices.StreamDeckPlus import StreamDeckPlus
|
|
13
14
|
from .Transport.Dummy import Dummy
|
|
14
15
|
from .Transport.LibUSBHIDAPI import LibUSBHIDAPI
|
|
15
16
|
from .ProductIDs import USBVendorIDs, USBProductIDs
|
|
@@ -38,6 +39,7 @@ class DeviceManager:
|
|
|
38
39
|
USB_PID_STREAMDECK_XL = 0x006c
|
|
39
40
|
USB_PID_STREAMDECK_MK2 = 0x0080
|
|
40
41
|
USB_PID_STREAMDECK_PEDAL = 0x0086
|
|
42
|
+
USB_PID_STREAMDECK_PLUS = 0x0084
|
|
41
43
|
|
|
42
44
|
@staticmethod
|
|
43
45
|
def _get_transport(transport):
|
|
@@ -108,6 +110,7 @@ class DeviceManager:
|
|
|
108
110
|
(USBVendorIDs.USB_VID_ELGATO, USBProductIDs.USB_PID_STREAMDECK_PEDAL, StreamDeckPedal),
|
|
109
111
|
(USBVendorIDs.USB_VID_ELGATO, USBProductIDs.USB_PID_STREAMDECK_MINI_MK2, StreamDeckMini),
|
|
110
112
|
(USBVendorIDs.USB_VID_ELGATO, USBProductIDs.USB_PID_STREAMDECK_XL_V2, StreamDeckXL),
|
|
113
|
+
(USBVendorIDs.USB_VID_ELGATO, USBProductIDs.USB_PID_STREAMDECK_PLUS, StreamDeckPlus),
|
|
111
114
|
]
|
|
112
115
|
|
|
113
116
|
streamdecks = list()
|
|
@@ -8,10 +8,41 @@
|
|
|
8
8
|
import threading
|
|
9
9
|
import time
|
|
10
10
|
from abc import ABC, abstractmethod
|
|
11
|
+
from enum import Enum
|
|
11
12
|
|
|
12
13
|
from ..Transport.Transport import TransportError
|
|
13
14
|
|
|
14
15
|
|
|
16
|
+
class TouchscreenEventType(Enum):
|
|
17
|
+
"""
|
|
18
|
+
Type of event that has occurred for a Touchscreen.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
SHORT = 1
|
|
22
|
+
LONG = 2
|
|
23
|
+
DRAG = 3
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class DialEventType(Enum):
|
|
27
|
+
"""
|
|
28
|
+
Type of event that has occurred for a Dial.
|
|
29
|
+
"""
|
|
30
|
+
TURN = 1
|
|
31
|
+
PUSH = 2
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class ControlType(Enum):
|
|
35
|
+
"""
|
|
36
|
+
Type of control. This is used when returning internal events from a
|
|
37
|
+
StreamDeck subclass.
|
|
38
|
+
|
|
39
|
+
:meta private:
|
|
40
|
+
"""
|
|
41
|
+
KEY = 1
|
|
42
|
+
DIAL = 2
|
|
43
|
+
TOUCHSCREEN = 3
|
|
44
|
+
|
|
45
|
+
|
|
15
46
|
class StreamDeck(ABC):
|
|
16
47
|
"""
|
|
17
48
|
Represents a physically attached StreamDeck device.
|
|
@@ -27,16 +58,29 @@ class StreamDeck(ABC):
|
|
|
27
58
|
KEY_FLIP = (False, False)
|
|
28
59
|
KEY_ROTATION = 0
|
|
29
60
|
|
|
61
|
+
TOUCHSCREEN_PIXEL_WIDTH = 0
|
|
62
|
+
TOUCHSCREEN_PIXEL_HEIGHT = 0
|
|
63
|
+
TOUCHSCREEN_IMAGE_FORMAT = ""
|
|
64
|
+
TOUCHSCREEN_FLIP = (False, False)
|
|
65
|
+
TOUCHSCREEN_ROTATION = 0
|
|
66
|
+
|
|
67
|
+
DIAL_COUNT = 0
|
|
68
|
+
|
|
30
69
|
DECK_TYPE = ""
|
|
31
70
|
DECK_VISUAL = False
|
|
71
|
+
DECK_TOUCH = False
|
|
32
72
|
|
|
33
73
|
def __init__(self, device):
|
|
34
74
|
self.device = device
|
|
35
75
|
self.last_key_states = [False] * self.KEY_COUNT
|
|
76
|
+
self.last_dial_states = [False] * self.DIAL_COUNT
|
|
36
77
|
self.read_thread = None
|
|
37
78
|
self.run_read_thread = False
|
|
38
79
|
self.read_poll_hz = 20
|
|
80
|
+
|
|
39
81
|
self.key_callback = None
|
|
82
|
+
self.dial_callback = None
|
|
83
|
+
self.touchscreen_callback = None
|
|
40
84
|
|
|
41
85
|
self.update_lock = threading.RLock()
|
|
42
86
|
|
|
@@ -72,12 +116,11 @@ class StreamDeck(ABC):
|
|
|
72
116
|
self.update_lock.release()
|
|
73
117
|
|
|
74
118
|
@abstractmethod
|
|
75
|
-
def
|
|
119
|
+
def _read_control_states(self):
|
|
76
120
|
"""
|
|
77
121
|
Reads the raw key states from an attached StreamDeck.
|
|
78
122
|
|
|
79
|
-
:
|
|
80
|
-
:return: List containing the raw key states.
|
|
123
|
+
:return: dictionary containing states for all controls
|
|
81
124
|
"""
|
|
82
125
|
pass
|
|
83
126
|
|
|
@@ -107,18 +150,34 @@ class StreamDeck(ABC):
|
|
|
107
150
|
"""
|
|
108
151
|
while self.run_read_thread:
|
|
109
152
|
try:
|
|
110
|
-
|
|
111
|
-
if
|
|
153
|
+
control_states = self._read_control_states()
|
|
154
|
+
if control_states is None:
|
|
112
155
|
time.sleep(1.0 / self.read_poll_hz)
|
|
113
156
|
continue
|
|
114
157
|
|
|
115
|
-
if self.key_callback is not None:
|
|
116
|
-
for k, (old, new) in enumerate(zip(self.last_key_states,
|
|
158
|
+
if ControlType.KEY in control_states and self.key_callback is not None:
|
|
159
|
+
for k, (old, new) in enumerate(zip(self.last_key_states, control_states[ControlType.KEY])):
|
|
117
160
|
if old != new:
|
|
118
161
|
self.key_callback(self, k, new)
|
|
162
|
+
self.last_key_states = control_states[ControlType.KEY]
|
|
163
|
+
|
|
164
|
+
elif ControlType.DIAL in control_states and self.dial_callback is not None:
|
|
165
|
+
if DialEventType.PUSH in control_states[ControlType.DIAL]:
|
|
166
|
+
for k, (old, new) in enumerate(zip(self.last_dial_states,
|
|
167
|
+
control_states[ControlType.DIAL][DialEventType.PUSH])):
|
|
168
|
+
if old != new:
|
|
169
|
+
self.dial_callback(self, k, DialEventType.PUSH, new)
|
|
170
|
+
self.last_dial_states = control_states[ControlType.DIAL][DialEventType.PUSH]
|
|
119
171
|
|
|
120
|
-
|
|
121
|
-
|
|
172
|
+
if DialEventType.TURN in control_states[ControlType.DIAL]:
|
|
173
|
+
for k, amount in enumerate(control_states[ControlType.DIAL][DialEventType.TURN]):
|
|
174
|
+
if amount != 0:
|
|
175
|
+
self.dial_callback(self, k, DialEventType.TURN, amount)
|
|
176
|
+
|
|
177
|
+
elif ControlType.TOUCHSCREEN in control_states and self.touchscreen_callback is not None:
|
|
178
|
+
self.touchscreen_callback(self, *control_states[ControlType.TOUCHSCREEN])
|
|
179
|
+
|
|
180
|
+
except TransportError:
|
|
122
181
|
self.run_read_thread = False
|
|
123
182
|
self.close()
|
|
124
183
|
|
|
@@ -223,12 +282,21 @@ class StreamDeck(ABC):
|
|
|
223
282
|
"""
|
|
224
283
|
return self.KEY_COUNT
|
|
225
284
|
|
|
285
|
+
def dial_count(self):
|
|
286
|
+
"""
|
|
287
|
+
Retrieves number of physical dials on the attached StreamDeck device.
|
|
288
|
+
|
|
289
|
+
:rtype: int
|
|
290
|
+
:return: Number of physical dials
|
|
291
|
+
"""
|
|
292
|
+
return self.DIAL_COUNT
|
|
293
|
+
|
|
226
294
|
def deck_type(self):
|
|
227
295
|
"""
|
|
228
296
|
Retrieves the model of Stream Deck.
|
|
229
297
|
|
|
230
298
|
:rtype: str
|
|
231
|
-
:return: String containing the model name of the StreamDeck device
|
|
299
|
+
:return: String containing the model name of the StreamDeck device.
|
|
232
300
|
"""
|
|
233
301
|
return self.DECK_TYPE
|
|
234
302
|
|
|
@@ -241,6 +309,15 @@ class StreamDeck(ABC):
|
|
|
241
309
|
"""
|
|
242
310
|
return self.DECK_VISUAL
|
|
243
311
|
|
|
312
|
+
def is_touch(self):
|
|
313
|
+
"""
|
|
314
|
+
Returns whether the Stream Deck can receive touch events
|
|
315
|
+
|
|
316
|
+
:rtype: bool
|
|
317
|
+
:return: `True` if the deck can receive touch events, `False` otherwise
|
|
318
|
+
"""
|
|
319
|
+
return self.DECK_TOUCH
|
|
320
|
+
|
|
244
321
|
def key_layout(self):
|
|
245
322
|
"""
|
|
246
323
|
Retrieves the physical button layout on the attached StreamDeck device.
|
|
@@ -269,6 +346,26 @@ class StreamDeck(ABC):
|
|
|
269
346
|
'rotation': self.KEY_ROTATION,
|
|
270
347
|
}
|
|
271
348
|
|
|
349
|
+
def touchscreen_image_format(self):
|
|
350
|
+
"""
|
|
351
|
+
Retrieves the image format accepted by the touchscreen of the Stream
|
|
352
|
+
Deck. Images should be given in this format when drawing on
|
|
353
|
+
touchscreen.
|
|
354
|
+
|
|
355
|
+
.. seealso:: See :func:`~StreamDeck.set_touchscreen_image` method to
|
|
356
|
+
draw an image on the StreamDeck touchscreen.
|
|
357
|
+
|
|
358
|
+
:rtype: dict()
|
|
359
|
+
:return: Dictionary describing the various image parameters
|
|
360
|
+
(size, image format).
|
|
361
|
+
"""
|
|
362
|
+
return {
|
|
363
|
+
'size': (self.TOUCHSCREEN_PIXEL_WIDTH, self.TOUCHSCREEN_PIXEL_HEIGHT),
|
|
364
|
+
'format': self.TOUCHSCREEN_IMAGE_FORMAT,
|
|
365
|
+
'flip': self.TOUCHSCREEN_FLIP,
|
|
366
|
+
'rotation': self.TOUCHSCREEN_ROTATION,
|
|
367
|
+
}
|
|
368
|
+
|
|
272
369
|
def set_poll_frequency(self, hz):
|
|
273
370
|
"""
|
|
274
371
|
Sets the frequency of the button polling reader thread, determining how
|
|
@@ -325,6 +422,94 @@ class StreamDeck(ABC):
|
|
|
325
422
|
|
|
326
423
|
self.set_key_callback(callback)
|
|
327
424
|
|
|
425
|
+
def set_dial_callback(self, callback):
|
|
426
|
+
"""
|
|
427
|
+
Sets the callback function called each time there is an interaction
|
|
428
|
+
with a dial on the StreamDeck.
|
|
429
|
+
|
|
430
|
+
.. note:: This callback will be fired from an internal reader thread.
|
|
431
|
+
Ensure that the given callback function is thread-safe.
|
|
432
|
+
|
|
433
|
+
.. note:: Only one callback can be registered at one time.
|
|
434
|
+
|
|
435
|
+
.. seealso:: See :func:`~StreamDeck.set_dial_callback_async` method
|
|
436
|
+
for a version compatible with Python 3 `asyncio`
|
|
437
|
+
asynchronous functions.
|
|
438
|
+
|
|
439
|
+
:param function callback: Callback function to fire each time a button
|
|
440
|
+
state changes.
|
|
441
|
+
"""
|
|
442
|
+
self.dial_callback = callback
|
|
443
|
+
|
|
444
|
+
def set_dial_callback_async(self, async_callback, loop=None):
|
|
445
|
+
"""
|
|
446
|
+
Sets the asynchronous callback function called each time there is an
|
|
447
|
+
interaction with a dial on the StreamDeck. The given callback should
|
|
448
|
+
be compatible with Python 3's `asyncio` routines.
|
|
449
|
+
|
|
450
|
+
.. note:: The asynchronous callback will be fired in a thread-safe
|
|
451
|
+
manner.
|
|
452
|
+
|
|
453
|
+
.. note:: This will override the callback (if any) set by
|
|
454
|
+
:func:`~StreamDeck.set_dial_callback`.
|
|
455
|
+
|
|
456
|
+
:param function async_callback: Asynchronous callback function to fire
|
|
457
|
+
each time a button state changes.
|
|
458
|
+
:param asyncio.loop loop: Asyncio loop to dispatch the callback into
|
|
459
|
+
"""
|
|
460
|
+
import asyncio
|
|
461
|
+
|
|
462
|
+
loop = loop or asyncio.get_event_loop()
|
|
463
|
+
|
|
464
|
+
def callback(*args):
|
|
465
|
+
asyncio.run_coroutine_threadsafe(async_callback(*args), loop)
|
|
466
|
+
|
|
467
|
+
self.set_dial_callback(callback)
|
|
468
|
+
|
|
469
|
+
def set_touchscreen_callback(self, callback):
|
|
470
|
+
"""
|
|
471
|
+
Sets the callback function called each time there is an interaction
|
|
472
|
+
with a touchscreen on the StreamDeck.
|
|
473
|
+
|
|
474
|
+
.. note:: This callback will be fired from an internal reader thread.
|
|
475
|
+
Ensure that the given callback function is thread-safe.
|
|
476
|
+
|
|
477
|
+
.. note:: Only one callback can be registered at one time.
|
|
478
|
+
|
|
479
|
+
.. seealso:: See :func:`~StreamDeck.set_touchscreen_callback_async`
|
|
480
|
+
method for a version compatible with Python 3 `asyncio`
|
|
481
|
+
asynchronous functions.
|
|
482
|
+
|
|
483
|
+
:param function callback: Callback function to fire each time a button
|
|
484
|
+
state changes.
|
|
485
|
+
"""
|
|
486
|
+
self.touchscreen_callback = callback
|
|
487
|
+
|
|
488
|
+
def set_touchscreen_callback_async(self, async_callback, loop=None):
|
|
489
|
+
"""
|
|
490
|
+
Sets the asynchronous callback function called each time there is an
|
|
491
|
+
interaction with the touchscreen on the StreamDeck. The given callback
|
|
492
|
+
should be compatible with Python 3's `asyncio` routines.
|
|
493
|
+
|
|
494
|
+
.. note:: The asynchronous callback will be fired in a thread-safe
|
|
495
|
+
manner.
|
|
496
|
+
|
|
497
|
+
.. note:: This will override the callback (if any) set by
|
|
498
|
+
:func:`~StreamDeck.set_touchscreen_callback`.
|
|
499
|
+
|
|
500
|
+
:param function async_callback: Asynchronous callback function to fire
|
|
501
|
+
each time a button state changes.
|
|
502
|
+
:param asyncio.loop loop: Asyncio loop to dispatch the callback into
|
|
503
|
+
"""
|
|
504
|
+
import asyncio
|
|
505
|
+
|
|
506
|
+
loop = loop or asyncio.get_event_loop()
|
|
507
|
+
|
|
508
|
+
def callback(*args):
|
|
509
|
+
asyncio.run_coroutine_threadsafe(async_callback(*args), loop)
|
|
510
|
+
|
|
511
|
+
self.set_touchscreen_callback(callback)
|
|
512
|
+
|
|
328
513
|
def key_states(self):
|
|
329
514
|
"""
|
|
330
515
|
Retrieves the current states of the buttons on the StreamDeck.
|
|
@@ -336,6 +521,18 @@ class StreamDeck(ABC):
|
|
|
336
521
|
"""
|
|
337
522
|
return self.last_key_states
|
|
338
523
|
|
|
524
|
+
def dial_states(self):
|
|
525
|
+
"""
|
|
526
|
+
Retrieves the current states of the dials (pressed or not) on the
|
|
527
|
+
Stream Deck
|
|
528
|
+
|
|
529
|
+
:rtype: list(bool)
|
|
530
|
+
:return: List describing the current states of each of the dials on
|
|
531
|
+
the device (`True` if the dial is being pressed, `False`
|
|
532
|
+
otherwise).
|
|
533
|
+
"""
|
|
534
|
+
return self.last_dial_states
|
|
535
|
+
|
|
339
536
|
@abstractmethod
|
|
340
537
|
def reset(self):
|
|
341
538
|
"""
|
|
@@ -382,7 +579,7 @@ class StreamDeck(ABC):
|
|
|
382
579
|
image being set should be in the correct format for the device, as an
|
|
383
580
|
enumerable collection of bytes.
|
|
384
581
|
|
|
385
|
-
.. seealso:: See :func:`~StreamDeck.
|
|
582
|
+
.. seealso:: See :func:`~StreamDeck.key_image_format` method for
|
|
386
583
|
information on the image format accepted by the device.
|
|
387
584
|
|
|
388
585
|
:param int key: Index of the button whose image is to be updated.
|
|
@@ -391,3 +588,23 @@ class StreamDeck(ABC):
|
|
|
391
588
|
color.
|
|
392
589
|
"""
|
|
393
590
|
pass
|
|
591
|
+
|
|
592
|
+
@abstractmethod
|
|
593
|
+
def set_touchscreen_image(self, image, x_pos=0, y_pos=0, width=0, height=0):
|
|
594
|
+
"""
|
|
595
|
+
Draws an image on the touchscreen in a certain position. The image
|
|
596
|
+
should be in the correct format for the devices, as an enumerable
|
|
597
|
+
collection of bytes.
|
|
598
|
+
|
|
599
|
+
.. seealso:: See :func:`~StreamDeck.touchscreen_image_format` method for
|
|
600
|
+
information on the image format accepted by the device.
|
|
601
|
+
|
|
602
|
+
:param enumerable image: Raw data of the image to set on the button.
|
|
603
|
+
If `None`, the touchscreen will be cleared.
|
|
604
|
+
:param int x_pos: Position on x axis of the image to draw
|
|
605
|
+
:param int y_pos: Position on y axis of the image to draw
|
|
606
|
+
:param int width: width of the image
|
|
607
|
+
:param int height: height of the image
|
|
608
|
+
|
|
609
|
+
"""
|
|
610
|
+
pass
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# www.fourwalledcubicle.com
|
|
6
6
|
#
|
|
7
7
|
|
|
8
|
-
from .StreamDeck import StreamDeck
|
|
8
|
+
from .StreamDeck import StreamDeck, ControlType
|
|
9
9
|
from ..ProductIDs import USBProductIDs
|
|
10
10
|
|
|
11
11
|
|
|
@@ -42,13 +42,15 @@ class StreamDeckMini(StreamDeck):
|
|
|
42
42
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
43
43
|
] + [0] * (KEY_PIXEL_WIDTH * KEY_PIXEL_HEIGHT * 3)
|
|
44
44
|
|
|
45
|
-
def
|
|
45
|
+
def _read_control_states(self):
|
|
46
46
|
states = self.device.read(1 + self.KEY_COUNT)
|
|
47
47
|
if states is None:
|
|
48
48
|
return None
|
|
49
49
|
|
|
50
50
|
states = states[1:]
|
|
51
|
-
return
|
|
51
|
+
return {
|
|
52
|
+
ControlType.KEY: [bool(s) for s in states],
|
|
53
|
+
}
|
|
52
54
|
|
|
53
55
|
def _reset_key_stream(self):
|
|
54
56
|
payload = bytearray(self.IMAGE_REPORT_LENGTH)
|
|
@@ -116,3 +118,6 @@ class StreamDeckMini(StreamDeck):
|
|
|
116
118
|
|
|
117
119
|
bytes_remaining = bytes_remaining - this_length
|
|
118
120
|
page_number = page_number + 1
|
|
121
|
+
|
|
122
|
+
def set_touchscreen_image(self, image, x_pos=0, y_pos=0, width=0, height=0):
|
|
123
|
+
pass
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# www.fourwalledcubicle.com
|
|
6
6
|
#
|
|
7
7
|
|
|
8
|
-
from .StreamDeck import StreamDeck
|
|
8
|
+
from .StreamDeck import StreamDeck, ControlType
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class StreamDeckOriginal(StreamDeck):
|
|
@@ -44,13 +44,15 @@ class StreamDeckOriginal(StreamDeck):
|
|
|
44
44
|
key_col = key % self.KEY_COLS
|
|
45
45
|
return (key - key_col) + ((self.KEY_COLS - 1) - key_col)
|
|
46
46
|
|
|
47
|
-
def
|
|
47
|
+
def _read_control_states(self):
|
|
48
48
|
states = self.device.read(1 + self.KEY_COUNT)
|
|
49
49
|
if states is None:
|
|
50
50
|
return None
|
|
51
51
|
|
|
52
52
|
states = states[1:]
|
|
53
|
-
return
|
|
53
|
+
return {
|
|
54
|
+
ControlType.KEY: [bool(states[s]) for s in map(self._convert_key_id_origin, range(self.KEY_COUNT))]
|
|
55
|
+
}
|
|
54
56
|
|
|
55
57
|
def _reset_key_stream(self):
|
|
56
58
|
payload = bytearray(self.IMAGE_REPORT_LENGTH)
|
|
@@ -120,3 +122,6 @@ class StreamDeckOriginal(StreamDeck):
|
|
|
120
122
|
|
|
121
123
|
bytes_remaining = bytes_remaining - this_length
|
|
122
124
|
page_number = page_number + 1
|
|
125
|
+
|
|
126
|
+
def set_touchscreen_image(self, image, x_pos=0, y_pos=0, width=0, height=0):
|
|
127
|
+
pass
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# www.fourwalledcubicle.com
|
|
6
6
|
#
|
|
7
7
|
|
|
8
|
-
from .StreamDeck import StreamDeck
|
|
8
|
+
from .StreamDeck import StreamDeck, ControlType
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class StreamDeckOriginalV2(StreamDeck):
|
|
@@ -73,13 +73,15 @@ class StreamDeckOriginalV2(StreamDeck):
|
|
|
73
73
|
0x28, 0xa0, 0x0f, 0xff, 0xd9
|
|
74
74
|
]
|
|
75
75
|
|
|
76
|
-
def
|
|
76
|
+
def _read_control_states(self):
|
|
77
77
|
states = self.device.read(4 + self.KEY_COUNT)
|
|
78
78
|
if states is None:
|
|
79
79
|
return None
|
|
80
80
|
|
|
81
81
|
states = states[4:]
|
|
82
|
-
return
|
|
82
|
+
return {
|
|
83
|
+
ControlType.KEY: [bool(s) for s in states]
|
|
84
|
+
}
|
|
83
85
|
|
|
84
86
|
def _reset_key_stream(self):
|
|
85
87
|
payload = bytearray(self.IMAGE_REPORT_LENGTH)
|
|
@@ -138,3 +140,6 @@ class StreamDeckOriginalV2(StreamDeck):
|
|
|
138
140
|
|
|
139
141
|
bytes_remaining = bytes_remaining - this_length
|
|
140
142
|
page_number = page_number + 1
|
|
143
|
+
|
|
144
|
+
def set_touchscreen_image(self, image, x_pos=0, y_pos=0, width=0, height=0):
|
|
145
|
+
pass
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# www.fourwalledcubicle.com
|
|
6
6
|
#
|
|
7
7
|
|
|
8
|
-
from .StreamDeck import StreamDeck
|
|
8
|
+
from .StreamDeck import StreamDeck, ControlType
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class StreamDeckPedal(StreamDeck):
|
|
@@ -20,13 +20,15 @@ class StreamDeckPedal(StreamDeck):
|
|
|
20
20
|
DECK_TYPE = "Stream Deck Pedal"
|
|
21
21
|
DECK_VISUAL = False
|
|
22
22
|
|
|
23
|
-
def
|
|
23
|
+
def _read_control_states(self):
|
|
24
24
|
states = self.device.read(4 + self.KEY_COUNT)
|
|
25
25
|
if states is None:
|
|
26
26
|
return None
|
|
27
27
|
|
|
28
28
|
states = states[4:]
|
|
29
|
-
return
|
|
29
|
+
return {
|
|
30
|
+
ControlType.KEY: [bool(s) for s in states]
|
|
31
|
+
}
|
|
30
32
|
|
|
31
33
|
def _reset_key_stream(self):
|
|
32
34
|
pass
|
|
@@ -47,3 +49,6 @@ class StreamDeckPedal(StreamDeck):
|
|
|
47
49
|
|
|
48
50
|
def set_key_image(self, key, image):
|
|
49
51
|
pass
|
|
52
|
+
|
|
53
|
+
def set_touchscreen_image(self, image, x_pos=0, y_pos=0, width=0, height=0):
|
|
54
|
+
pass
|