GHIElectronics.Endpoint.Devices.UsbHost 0.5.3__py3-none-any.whl

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.
@@ -0,0 +1,143 @@
1
+ """USB devices of Endpoint, with the same API as .NET's
2
+ GHIElectronics.Endpoint.Devices.UsbHost:
3
+
4
+ import serial
5
+ from GHIElectronics.Endpoint.Core import DeviceConnectionStatus
6
+ from GHIElectronics.Endpoint.Devices.UsbHost import DeviceType, UsbHostController
7
+
8
+ usb = UsbHostController.GetDefault()
9
+
10
+ def changed(sender, e):
11
+ if e.DeviceStatus == DeviceConnectionStatus.Connected and e.Type == DeviceType.Serial:
12
+ port = serial.Serial(e.DeviceName, 115200) # "/dev/ttyUSB0"
13
+
14
+ usb.ConnectionChanged += changed
15
+ usb.Enable() # the devices already plugged in are reported too
16
+
17
+ One event for each thing a device gives: a keyboard with a touchpad gives
18
+ Keyboard and Mouse, a webcam gives Webcam and Audio (its microphone).
19
+ DeviceName is what to open it with (see DeviceType). The events come on the
20
+ library's USB thread. USB drives come as MassStorage: use StorageController
21
+ (GHIElectronics.Endpoint.Devices.Storage) for them.
22
+
23
+ Keyboards, mice and joysticks have TinyCLR's classes:
24
+
25
+ if e.DeviceStatus == DeviceConnectionStatus.Connected and e.Type == DeviceType.Mouse:
26
+ mouse = Mouse(e.DeviceName)
27
+ mouse.SetCursorBounds(Position(0, 0), Position(799, 479))
28
+ mouse.CursorMoved += lambda sender, a: print("Cursor at", a.NewPosition.X, a.NewPosition.Y)
29
+ mouse.ButtonChanged += lambda sender, a: print(a.Which.name, a.State.name)
30
+
31
+ A program's own devices: pyusb for one with no driver (DeviceType.Unknown),
32
+ the hid package (hidapi) for HID devices; the board has their libraries:
33
+
34
+ pip install pyusb hid
35
+ device = usb.core.find(idVendor=e.VendorId, idProduct=e.ProductId)
36
+ device = hid.Device(vid=e.VendorId, pid=e.ProductId)
37
+
38
+ A controller or device stays alive until it is disposed, also when the
39
+ program keeps no variable for it.
40
+ """
41
+
42
+ from GHIElectronics.Endpoint.Core import DeviceConnectionStatus
43
+ from GHIElectronics.Endpoint.Core._event import Event
44
+ from GHIElectronics.Endpoint.Core._native import UsbHostCallback, native
45
+
46
+ from ._input import BaseDevice, Joystick, Keyboard, Mouse, Printer, PrinterStatus
47
+ from ._types import ButtonState, Buttons, Cursor, DeviceType, HatSwitchDirection, Key, KeyState, Position
48
+
49
+ __all__ = ["BaseDevice", "ButtonState", "Buttons", "Cursor", "DeviceConnectionStatus", "DeviceType",
50
+ "HatSwitchDirection", "Joystick", "Key", "KeyState", "Keyboard", "Mouse", "Position", "Printer",
51
+ "PrinterStatus",
52
+ "UsbDeviceConnectionEventArgs", "UsbHostController"]
53
+
54
+
55
+ class UsbDeviceConnectionEventArgs:
56
+ def __init__(self, deviceStatus, id, type, vendorId, productId, deviceName, manufacturer, product, serialNumber):
57
+ self.DeviceStatus = deviceStatus
58
+ self.Id = id
59
+ """The device's number: the same for all its events, a new one when it is plugged in again"""
60
+ self.Type = type
61
+ self.VendorId = vendorId
62
+ self.ProductId = productId
63
+ self.DeviceName = deviceName
64
+ """What to open: "/dev/ttyUSB0", "eth1"... (see DeviceType)"""
65
+ self.Manufacturer = manufacturer
66
+ """The device's own names ("Logitech", "USB Receiver"), empty if it has none"""
67
+ self.Product = product
68
+ self.SerialNumber = serialNumber
69
+
70
+ def __repr__(self):
71
+ return (f"UsbDeviceConnectionEventArgs({self.DeviceStatus.name}, Id={self.Id}, Type={self.Type.name}, "
72
+ f"DeviceName={self.DeviceName!r}, VendorId=0x{self.VendorId:04X}, ProductId=0x{self.ProductId:04X}, "
73
+ f"Manufacturer={self.Manufacturer!r}, Product={self.Product!r})")
74
+
75
+
76
+ def _text(value):
77
+ return value.decode(errors="replace") if value else ""
78
+
79
+
80
+ def _type(value):
81
+ try:
82
+ return DeviceType(value)
83
+ except ValueError:
84
+ return value # a type a newer libendpoint knows
85
+
86
+
87
+ class UsbHostController:
88
+ @staticmethod
89
+ def GetDefault():
90
+ return UsbHostController()
91
+
92
+ def __init__(self):
93
+ self._event = Event()
94
+ self._handle = None
95
+ self._callback = UsbHostCallback(self._changed) # kept: the library calls it
96
+ handle = native.out_handle()
97
+ native.usbhost_create(self._callback, None, native.ref(handle))
98
+ self._handle = handle
99
+ native.keep_alive(self)
100
+
101
+ @property
102
+ def ConnectionChanged(self):
103
+ """A device connected or disconnected: handler(sender, e). Add with +=, remove with -="""
104
+ return self._event
105
+
106
+ @ConnectionChanged.setter
107
+ def ConnectionChanged(self, value):
108
+ if value is not self._event:
109
+ raise TypeError("Use += and -= to add and remove an event handler")
110
+
111
+ def _h(self):
112
+ if self._handle is None:
113
+ raise native.disposed("UsbHostController")
114
+ return self._handle
115
+
116
+ def Enable(self):
117
+ """Starts reporting devices: first the ones already plugged in"""
118
+ native.usbhost_enable(self._h())
119
+
120
+ def Disable(self):
121
+ native.usbhost_disable(self._h())
122
+
123
+ def Dispose(self):
124
+ """Stops the events (one being delivered finishes first)"""
125
+ if self._handle is not None:
126
+ native.usbhost_dispose(self._handle)
127
+ self._handle = None
128
+ native.let_go(self)
129
+
130
+ def _changed(self, context, status, id, type, vendorId, productId, deviceName, manufacturer, product,
131
+ serialNumber):
132
+ self._event(self, UsbDeviceConnectionEventArgs(DeviceConnectionStatus(status), id, _type(type), vendorId,
133
+ productId, _text(deviceName), _text(manufacturer),
134
+ _text(product), _text(serialNumber)))
135
+
136
+ def __enter__(self):
137
+ return self
138
+
139
+ def __exit__(self, *exception):
140
+ self.Dispose()
141
+
142
+ def __del__(self):
143
+ self.Dispose()
@@ -0,0 +1,410 @@
1
+ """USB keyboards, mice and joysticks with TinyCLR's API, and printers. Each is
2
+ opened with the DeviceName its UsbHostController event gives
3
+ ("/dev/input/event2", "/dev/usb/lp0"); its events come on the device's own
4
+ thread; it stays alive until it is disposed."""
5
+
6
+ from enum import IntFlag
7
+ import ctypes
8
+
9
+ from GHIElectronics.Endpoint.Core._event import Event
10
+ from GHIElectronics.Endpoint.Core._native import InputCallback, UnpluggedCallback, native
11
+
12
+ from ._types import ButtonState, Buttons, Cursor, DeviceType, HatSwitchDirection, Key, KeyState, Position
13
+
14
+ # The libendpoint events (see Input::Event in libendpoint)
15
+ _KEY, _MOUSE_BUTTON, _MOUSE_MOVE, _WHEEL, _JOY_BUTTON, _JOY_MOVE, _HAT, _DISCONNECTED = range(1, 9)
16
+
17
+
18
+ class _EventProperty:
19
+ """An event: handlers are added with += and removed with -= (handler(sender, e))"""
20
+
21
+ def __set_name__(self, owner, name):
22
+ self.attribute = "_event_" + name
23
+
24
+ def __get__(self, target, owner=None):
25
+ return self if target is None else target.__dict__[self.attribute]
26
+
27
+ def __set__(self, target, value):
28
+ if value is not target.__dict__.get(self.attribute):
29
+ raise TypeError("Use += and -= to add and remove an event handler")
30
+
31
+
32
+ class _EventArgs:
33
+ def __init__(self, **values):
34
+ self.__dict__.update(values)
35
+
36
+ def __repr__(self):
37
+ values = ", ".join(f"{name}={value!r}" for name, value in self.__dict__.items())
38
+ return f"{type(self).__name__}({values})"
39
+
40
+
41
+ def _key(value):
42
+ try:
43
+ return Key(value)
44
+ except ValueError:
45
+ return value # a key TinyCLR has no name for: its USB key code
46
+
47
+
48
+ class BaseDevice:
49
+ """A USB device the program uses: Keyboard, Mouse, Joystick or Printer"""
50
+
51
+ Disconnected = _EventProperty()
52
+ """The device was unplugged: handler(sender, e)"""
53
+
54
+ def __init__(self, deviceName, deviceType):
55
+ # The events exist before the device can raise them
56
+ for klass in type(self).__mro__:
57
+ for value in vars(klass).values():
58
+ if isinstance(value, _EventProperty):
59
+ self.__dict__[value.attribute] = Event()
60
+ self._handle = None
61
+ self._printer = deviceType == DeviceType.Printer
62
+ handle = native.out_handle()
63
+ vendor, product, connected, capabilities = (native.out_int() for _ in range(4))
64
+ # The callbacks are kept: the library calls them
65
+ if self._printer:
66
+ self._callback = UnpluggedCallback(lambda context: self.Disconnected(self, None))
67
+ native.printer_open(str(deviceName).encode(), self._callback, None, native.ref(handle))
68
+ native.printer_info(handle, native.ref(vendor), native.ref(product), native.ref(connected))
69
+ else:
70
+ self._callback = InputCallback(self._changed)
71
+ native.input_open(str(deviceName).encode(), int(deviceType), self._callback, None, native.ref(handle))
72
+ native.input_info(handle, native.ref(vendor), native.ref(product), native.ref(connected),
73
+ native.ref(capabilities))
74
+ self._handle = handle
75
+ native.keep_alive(self)
76
+ self._deviceName = str(deviceName)
77
+ self._type = deviceType
78
+ self._vendorId = vendor.value
79
+ self._productId = product.value
80
+ self._capabilities = capabilities.value
81
+
82
+ @property
83
+ def DeviceName(self):
84
+ """What the device was opened with: "/dev/input/event2", "/dev/usb/lp0" """
85
+ return self._deviceName
86
+
87
+ @property
88
+ def Type(self):
89
+ return self._type
90
+
91
+ @property
92
+ def VendorId(self):
93
+ return self._vendorId
94
+
95
+ @property
96
+ def ProductId(self):
97
+ return self._productId
98
+
99
+ @property
100
+ def Connected(self):
101
+ if self._handle is None:
102
+ return False
103
+ values = [native.out_int() for _ in range(4)]
104
+ if self._printer:
105
+ native.printer_info(self._handle, *[native.ref(v) for v in values[:3]])
106
+ else:
107
+ native.input_info(self._handle, *[native.ref(v) for v in values])
108
+ return values[2].value != 0
109
+
110
+ def Dispose(self):
111
+ """Stops the device's events (one being delivered finishes first)"""
112
+ if self._handle is not None:
113
+ (native.printer_close if self._printer else native.input_close)(self._handle)
114
+ self._handle = None
115
+ native.let_go(self)
116
+
117
+ def _h(self):
118
+ if self._handle is None:
119
+ raise native.disposed(type(self).__name__)
120
+ return self._handle
121
+
122
+ def _changed(self, context, event, a, b, c, d, e):
123
+ if event == _DISCONNECTED:
124
+ self.Disconnected(self, None)
125
+ else:
126
+ self._on_event(event, a, b, c, d, e)
127
+
128
+ def _on_event(self, event, a, b, c, d, e):
129
+ pass
130
+
131
+ def __enter__(self):
132
+ return self
133
+
134
+ def __exit__(self, *exception):
135
+ self.Dispose()
136
+
137
+ def __repr__(self):
138
+ return f"{type(self).__name__}({self._deviceName!r})"
139
+
140
+
141
+ class Mouse(BaseDevice):
142
+ """A USB mouse. The cursor stays between 0 and 512 at first, as on TinyCLR:
143
+ set it to the screen with SetCursorBounds.
144
+
145
+ mouse = Mouse(e.DeviceName) # from UsbHostController, DeviceType.Mouse
146
+ mouse.SetCursorBounds(Position(0, 0), Position(799, 479))
147
+ mouse.CursorMoved += lambda sender, a: print("Cursor at", a.NewPosition.X, a.NewPosition.Y)
148
+ mouse.ButtonChanged += lambda sender, a: print(a.Which.name, a.State.name)
149
+ """
150
+
151
+ ButtonChanged = _EventProperty()
152
+ """A button was pressed or released: handler(sender, e) with e.Which (Buttons), e.State (ButtonState)"""
153
+ WheelMoved = _EventProperty()
154
+ """The wheel moved: e.NewPosition, e.Delta"""
155
+ CursorMoved = _EventProperty()
156
+ """The cursor moved: e.NewPosition, e.Delta (Position)"""
157
+
158
+ class ButtonChangedEventArgs(_EventArgs):
159
+ pass
160
+
161
+ class WheelMovedEventArgs(_EventArgs):
162
+ pass
163
+
164
+ class CursorMovedEventArgs(_EventArgs):
165
+ pass
166
+
167
+ def __init__(self, deviceName):
168
+ super().__init__(deviceName, DeviceType.Mouse)
169
+
170
+ def _state(self):
171
+ values = [native.out_int() for _ in range(4)]
172
+ native.input_mouse_state(self._h(), *[native.ref(v) for v in values])
173
+ return [v.value for v in values]
174
+
175
+ def _button(self, button):
176
+ return ButtonState.Pressed if self._state()[3] & button else ButtonState.Released
177
+
178
+ @property
179
+ def LeftButtonState(self):
180
+ return self._button(Buttons.Left)
181
+
182
+ @property
183
+ def RightButtonState(self):
184
+ return self._button(Buttons.Right)
185
+
186
+ @property
187
+ def MiddleButtonState(self):
188
+ return self._button(Buttons.Middle)
189
+
190
+ @property
191
+ def Extended1ButtonState(self):
192
+ return self._button(Buttons.Extended1)
193
+
194
+ @property
195
+ def Extended2ButtonState(self):
196
+ return self._button(Buttons.Extended2)
197
+
198
+ @property
199
+ def CursorPosition(self):
200
+ x, y, _, _ = self._state()
201
+ return Position(x, y)
202
+
203
+ @property
204
+ def WheelPosition(self):
205
+ return self._state()[2]
206
+
207
+ @property
208
+ def AbsolutePosition(self):
209
+ """False: a USB mouse moves relative"""
210
+ return False
211
+
212
+ def SetScale(self, scale):
213
+ """Scales the x, y, and wheel delta values"""
214
+ native.input_set_scale(self._h(), float(scale))
215
+
216
+ def SetCursorBounds(self, minimum, maximum):
217
+ """The cursor's smallest and largest Position"""
218
+ native.input_set_cursor_bounds(self._h(), 0, minimum.X, maximum.X, minimum.Y, maximum.Y)
219
+
220
+ def SetCursorPosition(self, newPosition):
221
+ native.input_set_cursor_position(self._h(), newPosition.X, newPosition.Y)
222
+
223
+ def _on_event(self, event, a, b, c, d, e):
224
+ if event == _MOUSE_BUTTON:
225
+ self.ButtonChanged(self, Mouse.ButtonChangedEventArgs(Which=Buttons(a), State=ButtonState(b)))
226
+ elif event == _MOUSE_MOVE:
227
+ self.CursorMoved(self, Mouse.CursorMovedEventArgs(NewPosition=Position(a, b), Delta=Position(c, d)))
228
+ elif event == _WHEEL:
229
+ self.WheelMoved(self, Mouse.WheelMovedEventArgs(NewPosition=a, Delta=b))
230
+
231
+
232
+ class Keyboard(BaseDevice):
233
+ """A USB keyboard. CharDown and CharUp come only for keys with an ASCII
234
+ character (a US keyboard; Ctrl+A to Ctrl+Z give 1 to 26). A key held down
235
+ gives one KeyDown.
236
+
237
+ keyboard = Keyboard(e.DeviceName) # from UsbHostController, DeviceType.Keyboard
238
+ keyboard.CharDown += lambda sender, a: print(a.Ascii, end="", flush=True)
239
+ """
240
+
241
+ KeyUp = _EventProperty()
242
+ """A key was released: handler(sender, e) with e.Which (Key) and e.Ascii (a str, "\\0" if none)"""
243
+ KeyDown = _EventProperty()
244
+ """A key was pressed"""
245
+ CharUp = _EventProperty()
246
+ """A key with an ASCII character was released"""
247
+ CharDown = _EventProperty()
248
+ """A key with an ASCII character was pressed"""
249
+
250
+ class KeyboardEventArgs(_EventArgs):
251
+ pass
252
+
253
+ def __init__(self, deviceName):
254
+ super().__init__(deviceName, DeviceType.Keyboard)
255
+
256
+ def IsKeyPressed(self, key):
257
+ """The KeyState of a key"""
258
+ state = native.out_int()
259
+ native.input_key_state(self._h(), int(key), native.ref(state))
260
+ return KeyState(state.value)
261
+
262
+ def _on_event(self, event, a, b, c, d, e):
263
+ if event != _KEY:
264
+ return
265
+ args = Keyboard.KeyboardEventArgs(Which=_key(a), Ascii=chr(c))
266
+ if b == KeyState.Pressed:
267
+ self.KeyDown(self, args)
268
+ if c:
269
+ self.CharDown(self, args)
270
+ else:
271
+ self.KeyUp(self, args)
272
+ if c:
273
+ self.CharUp(self, args)
274
+
275
+
276
+ class Joystick(BaseDevice):
277
+ """A USB joystick or game pad. The sticks go from -512 to 512 at first, as on
278
+ TinyCLR: Cursor1 is the left stick, Cursor2 the right one. Buttons are
279
+ numbered from 0.
280
+
281
+ joystick = Joystick(e.DeviceName) # from UsbHostController, DeviceType.Joystick
282
+ joystick.CursorMoved += lambda sender, a: print(a.Which.name, a.NewPosition)
283
+ joystick.ButtonChanged += lambda sender, a: print("Button", a.Which, a.State.name)
284
+ """
285
+
286
+ ButtonChanged = _EventProperty()
287
+ """A button was pressed or released: handler(sender, e) with e.Which (its number), e.State"""
288
+ CursorMoved = _EventProperty()
289
+ """A stick moved: e.Which (Cursor), e.NewPosition, e.Delta"""
290
+ HatSwitchPressed = _EventProperty()
291
+ """The hat switch moved: e.Direction (HatSwitchDirection)"""
292
+
293
+ class DeviceCapabilities(IntFlag):
294
+ CursorX = 0x01
295
+ CursorY = 0x02
296
+ Cursor2X = 0x04
297
+ Cursor2Y = 0x08
298
+ HatSwitch = 0x10
299
+ Buttons = 0x20
300
+
301
+ class ButtonChangedEventArgs(_EventArgs):
302
+ pass
303
+
304
+ class CursorMovedEventArgs(_EventArgs):
305
+ pass
306
+
307
+ class HatSwitchPressedEventArgs(_EventArgs):
308
+ pass
309
+
310
+ def __init__(self, deviceName):
311
+ super().__init__(deviceName, DeviceType.Joystick)
312
+
313
+ @property
314
+ def Capabilities(self):
315
+ return Joystick.DeviceCapabilities(self._capabilities)
316
+
317
+ def _state(self, cursor):
318
+ x, y, hat = native.out_int(), native.out_int(), native.out_int()
319
+ buttons = native.out_uint32()
320
+ native.input_joystick_state(self._h(), int(cursor), native.ref(x), native.ref(y), native.ref(hat),
321
+ native.ref(buttons))
322
+ return Position(x.value, y.value), HatSwitchDirection(hat.value), buttons.value
323
+
324
+ @property
325
+ def CursorPosition(self):
326
+ return self._state(Cursor.Cursor1)[0]
327
+
328
+ @property
329
+ def Cursor2Position(self):
330
+ return self._state(Cursor.Cursor2)[0]
331
+
332
+ @property
333
+ def CurrentHatSwitchDirection(self):
334
+ return self._state(Cursor.Cursor1)[1]
335
+
336
+ def SetCursorBounds(self, cursor, minX, maxX, minY, maxY):
337
+ native.input_set_cursor_bounds(self._h(), int(cursor), minX, maxX, minY, maxY)
338
+
339
+ def GetButtonState(self, buttonNumber):
340
+ """The ButtonState of a button (0 to 31)"""
341
+ if not 0 <= buttonNumber <= 31:
342
+ from GHIElectronics.Endpoint.Core import ArgumentOutOfRangeException
343
+ raise ArgumentOutOfRangeException("The button number must be 0 to 31")
344
+ return ButtonState.Pressed if self._state(Cursor.Cursor1)[2] & (1 << buttonNumber) else ButtonState.Released
345
+
346
+ def _on_event(self, event, a, b, c, d, e):
347
+ if event == _JOY_BUTTON:
348
+ self.ButtonChanged(self, Joystick.ButtonChangedEventArgs(Which=a, State=ButtonState(b)))
349
+ elif event == _JOY_MOVE:
350
+ self.CursorMoved(self, Joystick.CursorMovedEventArgs(Which=Cursor(a), NewPosition=Position(b, c),
351
+ Delta=Position(d, e)))
352
+ elif event == _HAT:
353
+ self.HatSwitchPressed(self, Joystick.HatSwitchPressedEventArgs(Direction=HatSwitchDirection(a)))
354
+
355
+
356
+ class PrinterStatus(IntFlag):
357
+ """What a printer reports about itself (Ready: nothing)"""
358
+
359
+ Ready = 0
360
+ PaperOut = 0x01
361
+ Offline = 0x02
362
+ Error = 0x04
363
+
364
+
365
+ class Printer(BaseDevice):
366
+ """A USB printer: the bytes it understands (ESC/POS for receipt printers, ZPL or
367
+ EPL for label printers, PCL or PostScript for office printers) go to it as
368
+ they are.
369
+
370
+ printer = Printer(e.DeviceName) # from UsbHostController, DeviceType.Printer
371
+ printer.Write("Hello\n\n\n")
372
+ printer.Write(bytes([0x1D, 0x56, 0x00])) # ESC/POS: cut the paper
373
+ """
374
+
375
+ def __init__(self, deviceName):
376
+ super().__init__(deviceName, DeviceType.Printer)
377
+ self.WriteTimeout = -1
378
+ """How long Write waits for the printer to take the data, in milliseconds (-1: as long as it takes)"""
379
+
380
+ @property
381
+ def DeviceId(self):
382
+ """The printer's IEEE 1284 Device ID: "MFG:EPSON;CMD:ESC/POS;MDL:TM-T20II;CLS:PRINTER;" """
383
+ text = ctypes.create_string_buffer(1024)
384
+ native.printer_device_id(self._h(), text, len(text))
385
+ return text.value.decode(errors="replace")
386
+
387
+ @property
388
+ def Status(self):
389
+ """PaperOut, Offline and Error, as the printer reports them (Ready: none)"""
390
+ status = native.out_int()
391
+ native.printer_status(self._h(), native.ref(status))
392
+ return PrinterStatus(status.value)
393
+
394
+ def Write(self, data):
395
+ """Sends bytes (or text, as UTF-8) to the printer; all of them, or a TimeoutException
396
+ after WriteTimeout"""
397
+ if isinstance(data, str):
398
+ data = data.encode()
399
+ pointer, length, keep = native.readable(data)
400
+ written = native.out_int()
401
+ native.printer_write(self._h(), pointer, length, int(self.WriteTimeout), native.ref(written))
402
+ return written.value
403
+
404
+ def Read(self, buffer, timeout=-1):
405
+ """Reads what the printer answers (to a status request) into a bytearray: its length,
406
+ 0 if nothing came in timeout milliseconds (-1: as long as it takes)"""
407
+ pointer, size = native.writable(buffer)
408
+ length = native.out_int()
409
+ native.printer_read(self._h(), pointer, size, int(timeout), native.ref(length))
410
+ return length.value
@@ -0,0 +1,217 @@
1
+ """The types of TinyCLR's USB host (GHIElectronics.TinyCLR.Devices.Usb): the
2
+ same names and values (Key is the USB key code). Python's None is a keyword:
3
+ Buttons.None_, Key.None_, HatSwitchDirection.None_."""
4
+
5
+ from enum import IntEnum, IntFlag
6
+
7
+
8
+ class DeviceType(IntEnum):
9
+ """What a device gives, and its DeviceName"""
10
+
11
+ Unknown = 0
12
+ """No driver on the board: the program talks to it with pyusb ("/dev/bus/usb/001/005"):
13
+ usb.core.find(idVendor=e.VendorId, idProduct=e.ProductId)"""
14
+ Hub = 1
15
+ """"/dev/bus/usb/001/002" """
16
+ HID = 2
17
+ """A HID device that is no keyboard, mouse or joystick ("/dev/hidraw0"): use the hid
18
+ package (hidapi), hid.Device(vid=e.VendorId, pid=e.ProductId)"""
19
+ Mouse = 3
20
+ """"/dev/input/event2": open it with Mouse(e.DeviceName)"""
21
+ Keyboard = 4
22
+ """"/dev/input/event1": open it with Keyboard(e.DeviceName)"""
23
+ Joystick = 5
24
+ """Joysticks and gamepads ("/dev/input/event3"): open it with Joystick(e.DeviceName)"""
25
+ MassStorage = 6
26
+ """A drive: use StorageController (no name)"""
27
+ Printer = 7
28
+ """"/dev/usb/lp0": open it with Printer(e.DeviceName)"""
29
+ Serial = 8
30
+ """A serial port, for pyserial ("/dev/ttyUSB0", "/dev/ttyACM0")"""
31
+ Webcam = 9
32
+ """"/dev/video0": open it with UsbCamera (GHIElectronics.Endpoint.Devices.Camera)"""
33
+ Audio = 10
34
+ """A sound card: speaker, microphone ("hw:1")"""
35
+ Network = 11
36
+ """An Ethernet, WiFi or cellular adapter: the network interface ("eth1", "wlan1")"""
37
+ Bluetooth = 12
38
+ """"hci0" """
39
+ Touch = 13
40
+ """"/dev/input/eventN": open it with Touch (built-in or USB touchscreen)"""
41
+
42
+
43
+ class Buttons(IntFlag):
44
+ """The mouse buttons"""
45
+
46
+ None_ = 0x00
47
+ Left = 0x01
48
+ Right = 0x02
49
+ Middle = 0x04
50
+ Extended1 = 0x08
51
+ Extended2 = 0x10
52
+
53
+
54
+ class ButtonState(IntEnum):
55
+ Released = 0
56
+ Pressed = 1
57
+
58
+
59
+ class Cursor(IntEnum):
60
+ """A joystick's sticks: Cursor1 (left), Cursor2 (right)"""
61
+
62
+ Cursor1 = 0
63
+ Cursor2 = 1
64
+
65
+
66
+ class KeyState(IntEnum):
67
+ Released = 2
68
+ Pressed = 1
69
+
70
+
71
+ class HatSwitchDirection(IntEnum):
72
+ Up = 0
73
+ UpRight = 1
74
+ Right = 2
75
+ DownRight = 3
76
+ Down = 4
77
+ DownLeft = 5
78
+ Left = 6
79
+ UpLeft = 7
80
+ None_ = 8
81
+
82
+
83
+ class Key(IntEnum):
84
+ """The keys on the keyboard: USB key codes. D0 to D9 are the number keys. A key
85
+ TinyCLR has no name for (F13, media keys) comes as its USB key code (an int)."""
86
+
87
+ None_ = 0
88
+ A = 4
89
+ B = 5
90
+ C = 6
91
+ D = 7
92
+ E = 8
93
+ F = 9
94
+ G = 10
95
+ H = 11
96
+ I = 12
97
+ J = 13
98
+ K = 14
99
+ L = 15
100
+ M = 16
101
+ N = 17
102
+ O = 18
103
+ P = 19
104
+ Q = 20
105
+ R = 21
106
+ S = 22
107
+ T = 23
108
+ U = 24
109
+ V = 25
110
+ W = 26
111
+ X = 27
112
+ Y = 28
113
+ Z = 29
114
+ D1 = 30
115
+ D2 = 31
116
+ D3 = 32
117
+ D4 = 33
118
+ D5 = 34
119
+ D6 = 35
120
+ D7 = 36
121
+ D8 = 37
122
+ D9 = 38
123
+ D0 = 39
124
+ Enter = 40
125
+ Escape = 41
126
+ BackSpace = 42
127
+ Tab = 43
128
+ Space = 44
129
+ Substract = 45
130
+ Equal = 46
131
+ OpenBrackets = 47
132
+ CloseBrackets = 48
133
+ Backslash = 49
134
+ NonUS = 50
135
+ Semicolon = 51
136
+ Quotes = 52
137
+ GraveAccent = 53
138
+ Comma = 54
139
+ Period = 55
140
+ Divide = 56
141
+ CapsLock = 57
142
+ F1 = 58
143
+ F2 = 59
144
+ F3 = 60
145
+ F4 = 61
146
+ F5 = 62
147
+ F6 = 63
148
+ F7 = 64
149
+ F8 = 65
150
+ F9 = 66
151
+ F10 = 67
152
+ F11 = 68
153
+ F12 = 69
154
+ PrintScreen = 70
155
+ ScrollLock = 71
156
+ Pause = 72
157
+ Insert = 73
158
+ Home = 74
159
+ PageUp = 75
160
+ Delete = 76
161
+ End = 77
162
+ PageDown = 78
163
+ RightArrow = 79
164
+ LeftArrow = 80
165
+ DownArrow = 81
166
+ UpArrow = 82
167
+ NumLock = 83
168
+ KeypadDivide = 84
169
+ KeypadMultiply = 85
170
+ KeypadSubstract = 86
171
+ KeypadAdd = 87
172
+ KeypadEnter = 88
173
+ Keypad1 = 89
174
+ Keypad2 = 90
175
+ Keypad3 = 91
176
+ Keypad4 = 92
177
+ Keypad5 = 93
178
+ Keypad6 = 94
179
+ Keypad7 = 95
180
+ Keypad8 = 96
181
+ Keypad9 = 97
182
+ Keypad0 = 98
183
+ KeypadDelete = 99
184
+ NonUS2 = 100
185
+ Application = 101
186
+ LeftCtrl = 0xE0
187
+ LeftShift = 0xE1
188
+ LeftAlt = 0xE2
189
+ LeftGUI = 0xE3
190
+ RightCtrl = 0xE4
191
+ RightShift = 0xE5
192
+ RightAlt = 0xE6
193
+ RightGUI = 0xE7
194
+
195
+
196
+ class Position:
197
+ """A position: X, Y (and Z)"""
198
+
199
+ def __init__(self, X=0, Y=0, Z=0):
200
+ self.X = X
201
+ self.Y = Y
202
+ self.Z = Z
203
+
204
+ def __sub__(self, other):
205
+ return Position(self.X - other.X, self.Y - other.Y, self.Z - other.Z)
206
+
207
+ def __eq__(self, other):
208
+ return isinstance(other, Position) and (self.X, self.Y, self.Z) == (other.X, other.Y, other.Z)
209
+
210
+ def __hash__(self):
211
+ return hash((self.X, self.Y, self.Z))
212
+
213
+ def __str__(self):
214
+ return f"({self.X}, {self.Y}, {self.Z})"
215
+
216
+ def __repr__(self):
217
+ return f"Position({self.X}, {self.Y}, {self.Z})"
@@ -0,0 +1,20 @@
1
+ Metadata-Version: 2.4
2
+ Name: GHIElectronics.Endpoint.Devices.UsbHost
3
+ Version: 0.5.3
4
+ Summary: USB devices of GHI Electronics Endpoint: connected and disconnected events, what each device is and its port or network interface.
5
+ Author-email: "GHI Electronics, LLC" <support@ghielectronics.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://www.ghielectronics.com/
8
+ Project-URL: Repository, https://github.com/ghi-electronics/Endpoint-Libraries
9
+ Project-URL: Issues, https://github.com/ghi-electronics/Endpoint-Libraries/issues
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Operating System :: POSIX :: Linux
12
+ Requires-Python: >=3.9
13
+ Description-Content-Type: text/markdown
14
+ Requires-Dist: GHIElectronics.Endpoint.Core<0.6,>=0.5.3
15
+
16
+ # GHIElectronics.Endpoint.Devices.UsbHost
17
+
18
+ USB devices of GHI Electronics Endpoint: connected and disconnected events, what each device is and its port or network interface.
19
+
20
+ Part of the [GHI Electronics Endpoint](https://github.com/ghi-electronics/Endpoint-Libraries) libraries. See the repository README for the full package list and getting-started guide.
@@ -0,0 +1,7 @@
1
+ GHIElectronics/Endpoint/Devices/UsbHost/__init__.py,sha256=gzNOm5rEgbFOVaEOA_6g9Mefp7feWWkRcM75X7mLXho,5764
2
+ GHIElectronics/Endpoint/Devices/UsbHost/_input.py,sha256=nPfnZp1lenmXX_sUVq1XEVV0qdi6UVRA5HHXO9eNup4,14972
3
+ GHIElectronics/Endpoint/Devices/UsbHost/_types.py,sha256=MVbgBPxptDKc6msY9Z5DWCtnA3BFzFwHWZ5GyL3aDm0,4633
4
+ ghielectronics_endpoint_devices_usbhost-0.5.3.dist-info/METADATA,sha256=dxi9liDMyT5LjzZvG3czKtGmq3DwfXu9xJm_VNjEcwA,1123
5
+ ghielectronics_endpoint_devices_usbhost-0.5.3.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
6
+ ghielectronics_endpoint_devices_usbhost-0.5.3.dist-info/top_level.txt,sha256=NpOZNgd0iquwrRPrTOhUDxc2V9TtNFLv5Z_Dx3YZtIU,15
7
+ ghielectronics_endpoint_devices_usbhost-0.5.3.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.2.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+