hid-usb-relay 25.0.0__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.
- hid_usb_relay/__init__.py +0 -0
- hid_usb_relay/hid_usb_relay_bin/__init__.py +0 -0
- hid_usb_relay/hid_usb_relay_bin/linux/32bit/hidusb-relay-cmd +0 -0
- hid_usb_relay/hid_usb_relay_bin/linux/64bit/hidusb-relay-cmd +0 -0
- hid_usb_relay/hid_usb_relay_bin/windows/32bit/GUIapp.exe +0 -0
- hid_usb_relay/hid_usb_relay_bin/windows/32bit/USB_RELAY_DEVICE.dll +0 -0
- hid_usb_relay/hid_usb_relay_bin/windows/32bit/hidusb-relay-cmd.exe +0 -0
- hid_usb_relay/hid_usb_relay_bin/windows/64bit/GUIapp.exe +0 -0
- hid_usb_relay/hid_usb_relay_bin/windows/64bit/USB_RELAY_DEVICE.dll +0 -0
- hid_usb_relay/hid_usb_relay_bin/windows/64bit/hidusb-relay-cmd.exe +0 -0
- hid_usb_relay/rest_api.py +116 -0
- hid_usb_relay/usb_relay.py +197 -0
- hid_usb_relay-25.0.0.dist-info/METADATA +48 -0
- hid_usb_relay-25.0.0.dist-info/RECORD +15 -0
- hid_usb_relay-25.0.0.dist-info/WHEEL +4 -0
|
File without changes
|
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import socket
|
|
2
|
+
import uvicorn
|
|
3
|
+
import logging
|
|
4
|
+
from fastapi import FastAPI, HTTPException
|
|
5
|
+
from fastapi.responses import HTMLResponse
|
|
6
|
+
|
|
7
|
+
from hid_usb_relay.usb_relay import (
|
|
8
|
+
set_relay_device_state,
|
|
9
|
+
set_relay_device_relay_state,
|
|
10
|
+
get_relay_device_state,
|
|
11
|
+
get_relay_device_relay_state,
|
|
12
|
+
set_default_relay_device_state,
|
|
13
|
+
set_default_relay_device_relay_state,
|
|
14
|
+
get_default_relay_device_state,
|
|
15
|
+
get_default_relay_device_relay_state,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
app = FastAPI()
|
|
19
|
+
|
|
20
|
+
logging.basicConfig(level=logging.INFO)
|
|
21
|
+
|
|
22
|
+
helper_text = """
|
|
23
|
+
<h1>YCR HID USB Relay Web API</h1>
|
|
24
|
+
<h2>Endpoints</h2>
|
|
25
|
+
<ul>
|
|
26
|
+
<li><b>/</b> ➖ This page</li>
|
|
27
|
+
<li><b>/relay/1/on</b> ➖ Turn ON Relay 1 of Default Relay Device</li>
|
|
28
|
+
<li><b>/relay/2/off</b> ➖ Turn OFF Relay 2 of Default Relay Device</li>
|
|
29
|
+
<li><b>/relay/all/on</b> ➖ Turn ON all Relays of Default Relay Device</li>
|
|
30
|
+
<li><b>/relay/all/off</b> ➖ Turn OFF all Relays of Default Relay Device</li>
|
|
31
|
+
<li><b>/relay/HURTM/1/on</b> ➖ Turn ON Relay 1 of Relay Id "HURTM"</li>
|
|
32
|
+
<li><b>/relay/HURTM/2/off</b> ➖ Turn OFF Relay 2 of Relay Id "HURTM"</li>
|
|
33
|
+
<li><b>/relay/HURTM/all/on</b> ➖ Turn ON all Relays of Relay Id "HURTM"</li>
|
|
34
|
+
<li><b>/relay/HURTM/all/off</b> ➖ Turn OFF all Relays of Relay Id "HURTM"</li>
|
|
35
|
+
</ul>
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
@app.get("/", response_class=HTMLResponse)
|
|
39
|
+
def root_page_help() -> str:
|
|
40
|
+
"""
|
|
41
|
+
Provides help text for the root page.
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
str: The help text for the root page.
|
|
45
|
+
"""
|
|
46
|
+
return helper_text
|
|
47
|
+
|
|
48
|
+
@app.get("/relay/{relay_id}/{relay_number}/{relay_state}")
|
|
49
|
+
def relay_control_by_id(relay_id: str, relay_number: str, relay_state: str) -> dict:
|
|
50
|
+
"""
|
|
51
|
+
Controls the state of a relay by its ID and relay number.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
relay_id (str): The ID of the relay device.
|
|
55
|
+
relay_number (str): The number of the relay to control. Use "all" to control all relays.
|
|
56
|
+
relay_state (str): The desired state of the relay (e.g., "on", "off").
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
dict: A dictionary containing the status of the operation and the current state of the relay.
|
|
60
|
+
|
|
61
|
+
Raises:
|
|
62
|
+
HTTPException: If the relay state could not be set or if an internal server error occurs.
|
|
63
|
+
"""
|
|
64
|
+
try:
|
|
65
|
+
if relay_number.lower() == "all":
|
|
66
|
+
ret_val = set_relay_device_state(relay_id, relay_state.upper())
|
|
67
|
+
else:
|
|
68
|
+
ret_val = set_relay_device_relay_state(relay_id, relay_number, relay_state.upper())
|
|
69
|
+
|
|
70
|
+
if ret_val:
|
|
71
|
+
if relay_number.lower() == "all":
|
|
72
|
+
response_text = get_relay_device_state(relay_id)
|
|
73
|
+
else:
|
|
74
|
+
response_text = get_relay_device_relay_state(relay_id, relay_number)
|
|
75
|
+
return {"status": "success", "relay_state": response_text}
|
|
76
|
+
else:
|
|
77
|
+
raise HTTPException(status_code=400, detail="Failed to set relay state. Check command.")
|
|
78
|
+
except Exception as e:
|
|
79
|
+
logging.error(f"Error in relay_control_by_id: {e}")
|
|
80
|
+
raise HTTPException(status_code=500, detail="Internal Server Error")
|
|
81
|
+
|
|
82
|
+
@app.get("/relay/{relay_number}/{relay_state}")
|
|
83
|
+
def default_relay_control(relay_number: str, relay_state: str) -> dict:
|
|
84
|
+
"""
|
|
85
|
+
Controls the state of a relay or all relays on the default relay device.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
relay_number (str): The relay number to control. Use "all" to control all relays.
|
|
89
|
+
relay_state (str): The desired state of the relay(s). Typically "on" or "off".
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
dict: A dictionary containing the status of the operation and the current state of the relay(s).
|
|
93
|
+
|
|
94
|
+
Raises:
|
|
95
|
+
HTTPException: If the relay state could not be set or if an internal error occurs.
|
|
96
|
+
"""
|
|
97
|
+
try:
|
|
98
|
+
if relay_number.lower() == "all":
|
|
99
|
+
ret_val = set_default_relay_device_state(relay_state.upper())
|
|
100
|
+
else:
|
|
101
|
+
ret_val = set_default_relay_device_relay_state(relay_number, relay_state.upper())
|
|
102
|
+
|
|
103
|
+
if ret_val:
|
|
104
|
+
if relay_number.lower() == "all":
|
|
105
|
+
response_text = get_default_relay_device_state()
|
|
106
|
+
else:
|
|
107
|
+
response_text = get_default_relay_device_relay_state(relay_number)
|
|
108
|
+
return {"status": "success", "relay_state": response_text}
|
|
109
|
+
else:
|
|
110
|
+
raise HTTPException(status_code=400, detail="Failed to set relay state. Check command.")
|
|
111
|
+
except Exception as e:
|
|
112
|
+
logging.error(f"Error in default_relay_control: {e}")
|
|
113
|
+
raise HTTPException(status_code=500, detail="Internal Server Error")
|
|
114
|
+
|
|
115
|
+
if __name__ == "__main__":
|
|
116
|
+
uvicorn.run(app, host=socket.getfqdn(), port=9400)
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module provides functions to interact with a USB relay device using command-line commands.
|
|
3
|
+
It allows users to get and set the state of the relay device, as well as retrieve information about the relay device's status.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
import platform
|
|
8
|
+
import subprocess
|
|
9
|
+
from typing import Optional, Tuple, List
|
|
10
|
+
|
|
11
|
+
def get_platform_and_architecture() -> Tuple[str, str]:
|
|
12
|
+
"""
|
|
13
|
+
Get the current system platform and architecture.
|
|
14
|
+
|
|
15
|
+
Returns:
|
|
16
|
+
tuple: (system, architecture), both lowercase strings.
|
|
17
|
+
"""
|
|
18
|
+
return platform.system().lower(), platform.architecture()[0].lower()
|
|
19
|
+
|
|
20
|
+
def get_bin_path() -> str:
|
|
21
|
+
"""
|
|
22
|
+
Get the absolute path to the package's binary folder.
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
str: Path to the binary folder.
|
|
26
|
+
"""
|
|
27
|
+
return os.path.join(os.path.dirname(os.path.abspath(__file__)), 'hid_usb_relay_bin')
|
|
28
|
+
|
|
29
|
+
def get_relay_path(file_name: str) -> str:
|
|
30
|
+
"""
|
|
31
|
+
Build the path to a relay binary/library for the current platform and architecture.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
file_name (str): Name of the binary/library file.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
str: Full path to the file.
|
|
38
|
+
|
|
39
|
+
Raises:
|
|
40
|
+
OSError: If the system platform is unsupported.
|
|
41
|
+
"""
|
|
42
|
+
bin_dir = get_bin_path()
|
|
43
|
+
system, arch = get_platform_and_architecture()
|
|
44
|
+
if system not in ['windows', 'linux']:
|
|
45
|
+
raise OSError(f'Unsupported system platform: {system}')
|
|
46
|
+
return os.path.join(bin_dir, system, arch, file_name)
|
|
47
|
+
|
|
48
|
+
def get_relay_executable() -> str:
|
|
49
|
+
"""
|
|
50
|
+
Get the path to the relay command-line executable for the current platform.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
str: Full path to the relay executable.
|
|
54
|
+
"""
|
|
55
|
+
exe_name = "hidusb-relay-cmd.exe" if platform.system().lower() == 'windows' else "hidusb-relay-cmd"
|
|
56
|
+
return get_relay_path(exe_name)
|
|
57
|
+
|
|
58
|
+
def get_relay_library() -> str:
|
|
59
|
+
"""
|
|
60
|
+
Get the path to the relay library for the current platform.
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
str: Full path to the relay library.
|
|
64
|
+
"""
|
|
65
|
+
lib_name = "USB_RELAY_DEVICE.dll" if platform.system().lower() == 'windows' else "usb_relay_device.so"
|
|
66
|
+
return get_relay_path(lib_name)
|
|
67
|
+
|
|
68
|
+
def run_command(command: List[str]) -> Optional[str]:
|
|
69
|
+
"""
|
|
70
|
+
Run a command using subprocess and return its output.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
command (List[str]): Command and arguments as a list.
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
Optional[str]: Output string if successful, None otherwise.
|
|
77
|
+
"""
|
|
78
|
+
process = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
|
|
79
|
+
if process.returncode == 0:
|
|
80
|
+
return process.stdout.strip()
|
|
81
|
+
print(f"Error executing command: {process.stderr}")
|
|
82
|
+
return None
|
|
83
|
+
|
|
84
|
+
def get_default_relay_device_state() -> Optional[List[str]]:
|
|
85
|
+
"""
|
|
86
|
+
Get the status of the default relay device.
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
Optional[List[str]]: List of relay states, or None on error.
|
|
90
|
+
"""
|
|
91
|
+
output = run_command([get_relay_executable(), "STATUS"])
|
|
92
|
+
return output.split(':')[-1].strip().split(' ') if output else None
|
|
93
|
+
|
|
94
|
+
def set_default_relay_device_state(relay_state: str) -> bool:
|
|
95
|
+
"""
|
|
96
|
+
Set all relays on the default device to a given state.
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
relay_state (str): "ON" or "OFF".
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
bool: True if successful, False otherwise.
|
|
103
|
+
"""
|
|
104
|
+
return run_command([get_relay_executable(), relay_state, "ALL"]) is not None
|
|
105
|
+
|
|
106
|
+
def get_relay_device_state(relay_id: str) -> Optional[List[str]]:
|
|
107
|
+
"""
|
|
108
|
+
Get the status of a specific relay device by ID.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
relay_id (str): Relay device ID.
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
Optional[List[str]]: List of relay states, or None on error.
|
|
115
|
+
"""
|
|
116
|
+
output = run_command([get_relay_executable(), f"id={relay_id}", "STATUS"])
|
|
117
|
+
return output.split(':')[-1].strip().split(' ') if output else None
|
|
118
|
+
|
|
119
|
+
def set_relay_device_state(relay_id: str, relay_state: str) -> bool:
|
|
120
|
+
"""
|
|
121
|
+
Set all relays on a specific device to a given state.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
relay_id (str): Relay device ID.
|
|
125
|
+
relay_state (str): "ON" or "OFF".
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
bool: True if successful, False otherwise.
|
|
129
|
+
"""
|
|
130
|
+
return run_command([get_relay_executable(), f"id={relay_id}", relay_state, "ALL"]) is not None
|
|
131
|
+
|
|
132
|
+
def get_all_relay_device_state() -> Optional[str]:
|
|
133
|
+
"""
|
|
134
|
+
Get the status of all connected relay devices.
|
|
135
|
+
|
|
136
|
+
Returns:
|
|
137
|
+
Optional[str]: Status string, or None on error.
|
|
138
|
+
"""
|
|
139
|
+
return run_command([get_relay_executable(), "ENUM"])
|
|
140
|
+
|
|
141
|
+
def get_relay_device_relay_state(relay_id: str, relay_number: str) -> Optional[str]:
|
|
142
|
+
"""
|
|
143
|
+
Get the state of a specific relay on a specific device.
|
|
144
|
+
|
|
145
|
+
Args:
|
|
146
|
+
relay_id (str): Relay device ID.
|
|
147
|
+
relay_number (str): Relay number as string (e.g., "1").
|
|
148
|
+
|
|
149
|
+
Returns:
|
|
150
|
+
Optional[str]: State ("ON"/"OFF") or None on error.
|
|
151
|
+
"""
|
|
152
|
+
states = get_relay_device_state(relay_id)
|
|
153
|
+
if states:
|
|
154
|
+
return states[int(relay_number) - 1].split('=')[-1]
|
|
155
|
+
return None
|
|
156
|
+
|
|
157
|
+
def set_relay_device_relay_state(relay_id: str, relay_number: str, relay_state: str) -> bool:
|
|
158
|
+
"""
|
|
159
|
+
Set the state of a specific relay on a specific device.
|
|
160
|
+
|
|
161
|
+
Args:
|
|
162
|
+
relay_id (str): Relay device ID.
|
|
163
|
+
relay_number (str): Relay number as string (e.g., "1").
|
|
164
|
+
relay_state (str): "ON" or "OFF".
|
|
165
|
+
|
|
166
|
+
Returns:
|
|
167
|
+
bool: True if successful, False otherwise.
|
|
168
|
+
"""
|
|
169
|
+
return run_command([get_relay_executable(), f"id={relay_id}", relay_state, relay_number]) is not None
|
|
170
|
+
|
|
171
|
+
def get_default_relay_device_relay_state(relay_number: str) -> Optional[str]:
|
|
172
|
+
"""
|
|
173
|
+
Get the state of a specific relay on the default device.
|
|
174
|
+
|
|
175
|
+
Args:
|
|
176
|
+
relay_number (str): Relay number as string (e.g., "1").
|
|
177
|
+
|
|
178
|
+
Returns:
|
|
179
|
+
Optional[str]: State ("ON"/"OFF") or None on error.
|
|
180
|
+
"""
|
|
181
|
+
states = get_default_relay_device_state()
|
|
182
|
+
if states:
|
|
183
|
+
return states[int(relay_number) - 1].split('=')[-1]
|
|
184
|
+
return None
|
|
185
|
+
|
|
186
|
+
def set_default_relay_device_relay_state(relay_number: str, relay_state: str) -> bool:
|
|
187
|
+
"""
|
|
188
|
+
Set the state of a specific relay on the default device.
|
|
189
|
+
|
|
190
|
+
Args:
|
|
191
|
+
relay_number (str): Relay number as string (e.g., "1").
|
|
192
|
+
relay_state (str): "ON" or "OFF".
|
|
193
|
+
|
|
194
|
+
Returns:
|
|
195
|
+
bool: True if successful, False otherwise.
|
|
196
|
+
"""
|
|
197
|
+
return run_command([get_relay_executable(), relay_state, relay_number]) is not None
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: hid-usb-relay
|
|
3
|
+
Version: 25.0.0
|
|
4
|
+
Summary: hid based usb relay package
|
|
5
|
+
Keywords: Python,HID,USB,RELAY
|
|
6
|
+
Author: chaitu-ycr
|
|
7
|
+
Author-email: chaitu-ycr <chaitu.ycr@gmail.com>
|
|
8
|
+
License: MIT License
|
|
9
|
+
|
|
10
|
+
Copyright (c) 2025 chaitu-ycr
|
|
11
|
+
|
|
12
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
13
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
14
|
+
in the Software without restriction, including without limitation the rights
|
|
15
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
16
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
17
|
+
furnished to do so, subject to the following conditions:
|
|
18
|
+
|
|
19
|
+
The above copyright notice and this permission notice shall be included in all
|
|
20
|
+
copies or substantial portions of the Software.
|
|
21
|
+
|
|
22
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
23
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
24
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
25
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
26
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
27
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
28
|
+
SOFTWARE.
|
|
29
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
30
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
31
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
32
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
33
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
34
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
35
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
36
|
+
Requires-Dist: gradio
|
|
37
|
+
Requires-Dist: fastapi[standard]
|
|
38
|
+
Requires-Python: >=3.10, <=3.14
|
|
39
|
+
Project-URL: documentation, https://chaitu-ycr.github.io/automotive-test-kit/packages/hid_usb_relay
|
|
40
|
+
Project-URL: homepage, https://github.com/chaitu-ycr/automotive-test-kit/tree/main/packages/hid_usb_relay
|
|
41
|
+
Project-URL: repository, https://github.com/chaitu-ycr/automotive-test-kit
|
|
42
|
+
Description-Content-Type: text/markdown
|
|
43
|
+
|
|
44
|
+
# hid_usb_relay
|
|
45
|
+
|
|
46
|
+
hid based usb relay package
|
|
47
|
+
|
|
48
|
+
## [source manual](https://chaitu-ycr.github.io/automotive-test-kit/packages/hid_usb_relay/#source-manual)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
hid_usb_relay/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
hid_usb_relay/hid_usb_relay_bin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
+
hid_usb_relay/hid_usb_relay_bin/linux/32bit/hidusb-relay-cmd,sha256=kZpUbPucCsGzHXizusMupgSMhfJhj9-As1E5gzLFtX4,17051
|
|
4
|
+
hid_usb_relay/hid_usb_relay_bin/linux/64bit/hidusb-relay-cmd,sha256=RvWPyw5o0TPBqLcjZfc3iCBHodM9k_l5NrstWDTnr90,18759
|
|
5
|
+
hid_usb_relay/hid_usb_relay_bin/windows/32bit/GUIapp.exe,sha256=KYPvhXRzh8XcG2_T01a9F1rDTNZ2lSvF6alzbVu_INY,61440
|
|
6
|
+
hid_usb_relay/hid_usb_relay_bin/windows/32bit/USB_RELAY_DEVICE.dll,sha256=O-WWBlxyNJzuvJswQ_rnFTkg6FeWR-LBqsLfPCBqNWU,52736
|
|
7
|
+
hid_usb_relay/hid_usb_relay_bin/windows/32bit/hidusb-relay-cmd.exe,sha256=uhuw_pnRRmQAcbZHC9fwwTbL8fwfyN6jMfXsNHB_GAk,66048
|
|
8
|
+
hid_usb_relay/hid_usb_relay_bin/windows/64bit/GUIapp.exe,sha256=HxUtZEguzAV41H3CQfAG6EbiOVChJxgjWj_0IHCaJvI,69632
|
|
9
|
+
hid_usb_relay/hid_usb_relay_bin/windows/64bit/USB_RELAY_DEVICE.dll,sha256=vcbH-kbY6QCWRYGQ-EiRCIoXgIgZlckc0pHXoU9eJIE,86528
|
|
10
|
+
hid_usb_relay/hid_usb_relay_bin/windows/64bit/hidusb-relay-cmd.exe,sha256=wknn0l05jSHsvmwKrFlit2p8gPMbQP3LkV_5gwjmWTs,92672
|
|
11
|
+
hid_usb_relay/rest_api.py,sha256=5HzVPE5WAkVg2M_w7-0YFUvCnsGMTp8pDO91Vg2iI1o,4644
|
|
12
|
+
hid_usb_relay/usb_relay.py,sha256=B5lnTDhMQjjhFzg9sIVeGC-08gy7CEUvm9tP5k4uFVg,6418
|
|
13
|
+
hid_usb_relay-25.0.0.dist-info/WHEEL,sha256=5h_Q-_6zWQhhADpsAD_Xpw7gFbCRK5WjOOEq0nB806Q,79
|
|
14
|
+
hid_usb_relay-25.0.0.dist-info/METADATA,sha256=fw-zZoVFpzMJELZcZsZqMe8W9mCb_Y9NymAgiwaYijE,2375
|
|
15
|
+
hid_usb_relay-25.0.0.dist-info/RECORD,,
|