py-uds-demo 26.0.1__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,422 @@
1
+ from nicegui import ui
2
+
3
+ from py_uds_demo.core.client import UdsClient
4
+
5
+
6
+ class Web:
7
+ """
8
+ WebUi provides a NiceGUI-based web interface for interacting with the UDS (Unified Diagnostic Services) simulator.
9
+
10
+ This class manages the UI components, handles user input, processes diagnostic requests, and logs interactions.
11
+ """
12
+
13
+ # UI Constants
14
+ HEADER_HEIGHT = '60px'
15
+ SIDEBAR_WIDTH = '400px'
16
+ HEADER_PADDING = '0 20px'
17
+ CARD_PADDING = '16px'
18
+ CARD_HEADER_MARGIN = '12px'
19
+ INNER_PADDING = '12px'
20
+ SMALL_PADDING = '8px'
21
+ HELP_INPUT_WIDTH = '180px'
22
+ CHAT_MAX_WIDTH = '80%'
23
+ SPACING_SM = '8px'
24
+ SPACING_MD = '12px'
25
+ SPACING_LG = '16px'
26
+
27
+ # Color Scheme
28
+ COLORS = {
29
+ 'header_gradient': 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
30
+ 'primary': '#667eea',
31
+ 'primary_light': '#8b9efc',
32
+ 'secondary': '#f093fb',
33
+ 'success': '#4ade80',
34
+ 'success_light': '#86efac',
35
+ 'warning': '#fbbf24',
36
+ 'error': '#f87171',
37
+ 'info': '#60a5fa',
38
+ 'purple': '#a855f7',
39
+ 'pink': '#ec4899',
40
+ 'indigo': '#6366f1',
41
+ 'teal': '#14b8a6',
42
+ 'orange': '#f97316',
43
+ 'user_message': 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
44
+ 'assistant_message': 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',
45
+ 'card_bg': '#ffffff',
46
+ 'card_shadow': '0 10px 40px rgba(0,0,0,0.1)',
47
+ 'card_shadow_hover': '0 20px 60px rgba(0,0,0,0.15)',
48
+ 'sidebar_bg': 'linear-gradient(180deg, #f8f9fa 0%, #e9ecef 100%)',
49
+ 'main_bg': 'linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%)',
50
+ }
51
+
52
+ # Animations
53
+ TRANSITIONS = {
54
+ 'smooth': 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',
55
+ 'bounce': 'all 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55)',
56
+ }
57
+
58
+ # Style Templates
59
+ GLASS_CONTAINER = 'background: rgba(255,255,255,0.12); backdrop-filter: blur(12px); border-radius: 24px; border: 1px solid rgba(255,255,255,0.2); transition: all 0.3s ease;'
60
+ CARD_BORDER_RADIUS = '16px'
61
+ CARD_ICON_RADIUS = '10px'
62
+ SID_ITEM_RADIUS = '10px'
63
+
64
+ # Quick Reference SIDs with icons and colors
65
+ SID_REFERENCE = [
66
+ ('settings', '0x10 - Diagnostic Session Control', '#667eea'),
67
+ ('refresh', '0x11 - ECU Reset', '#14b8a6'),
68
+ ('search', '0x22 - Read Data By Identifier', '#f97316'),
69
+ ('lock', '0x27 - Security Access', '#f87171'),
70
+ ('edit', '0x2E - Write Data By Identifier', '#a855f7'),
71
+ ('build', '0x31 - Routine Control', '#6366f1'),
72
+ ('favorite', '0x3E - Tester Present', '#ec4899'),
73
+ ]
74
+
75
+ def __init__(self):
76
+ """
77
+ Initialize the WebUi instance.
78
+
79
+ Sets up the UdsClient and builds the UI components.
80
+ """
81
+ self.uds_client = UdsClient()
82
+ self.logger = self.uds_client.server.logger
83
+ self._build_ui()
84
+
85
+ def _build_ui(self):
86
+ """Build the complete UI interface."""
87
+ self._build_header()
88
+ self._build_main_content()
89
+
90
+ # UI Helper Methods
91
+
92
+ def _create_card_header(self, icon: str, title: str, color1: str, color2: str):
93
+ """Create a card header with icon badge and gradient text.
94
+
95
+ Args:
96
+ icon: Material icon name
97
+ title: Header title text
98
+ color1: First gradient color
99
+ color2: Second gradient color
100
+ """
101
+ with ui.row().classes('items-center gap-3').style(f'margin-bottom: {self.CARD_HEADER_MARGIN};'):
102
+ with ui.card().classes('').style(f'padding: 8px; background: linear-gradient(135deg, {color1} 0%, {color2} 100%); border-radius: {self.CARD_ICON_RADIUS};'):
103
+ ui.icon(icon, size='sm').classes('text-white')
104
+ ui.label(title).classes('text-base font-bold').style(f'background: linear-gradient(135deg, {color1} 0%, {color2} 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent;')
105
+
106
+ def _create_glass_container(self, content_builder, hover_class: str = 'hover:bg-white/20'):
107
+ """Create a glass morphism container.
108
+
109
+ Args:
110
+ content_builder: Function to build content inside the container
111
+ hover_class: CSS class for hover effect
112
+ """
113
+ with ui.row().classes(f'items-center gap-2 px-3 py-2 {hover_class}').style(self.GLASS_CONTAINER):
114
+ content_builder()
115
+
116
+ def _create_sid_item(self, icon: str, sid_info: str, color: str, click_handler):
117
+ """Create a clickable SID reference item.
118
+
119
+ Args:
120
+ icon: Material icon name
121
+ sid_info: SID information text
122
+ color: Theme color for the item
123
+ click_handler: Click event handler
124
+ """
125
+ with ui.card().classes('w-full').style(
126
+ f'padding: {self.SPACING_SM} {self.SPACING_MD}; '
127
+ f'background: linear-gradient(135deg, {color}15 0%, {color}05 100%); '
128
+ f'border-radius: {self.SID_ITEM_RADIUS}; cursor: pointer; '
129
+ f'transition: {self.TRANSITIONS["smooth"]}; border-left: 3px solid {color};'
130
+ ).classes('hover:scale-105 hover:shadow-lg').on('click', click_handler):
131
+ with ui.row().classes('items-center gap-3'):
132
+ with ui.card().classes('').style(f'padding: 6px; background: {color}; border-radius: 8px;'):
133
+ ui.icon(icon, size='xs').classes('text-white')
134
+ ui.label(sid_info).classes('text-xs font-medium').style(f'color: {color};')
135
+
136
+ def run(self):
137
+ """
138
+ Launch the NiceGUI app for the UDS simulator UI.
139
+
140
+ Starts the NiceGUI server.
141
+ """
142
+ ui.run(title="PY-UDS-DEMO SIM", favicon="🚗")
143
+
144
+ def _build_header(self):
145
+ """Build the application header with controls."""
146
+ with ui.header().classes('text-white shadow-xl').style(
147
+ f'height: {self.HEADER_HEIGHT}; padding: {self.HEADER_PADDING}; '
148
+ f'background: {self.COLORS["header_gradient"]}; '
149
+ f'box-shadow: 0 8px 32px rgba(102, 126, 234, 0.3); '
150
+ f'border-bottom: 1px solid rgba(255,255,255,0.1);'
151
+ ):
152
+ with ui.row().classes('w-full items-center justify-between'):
153
+ self._build_header_branding()
154
+ self._build_header_controls()
155
+ self._build_header_help()
156
+
157
+ def _build_header_branding(self):
158
+ """Build the header branding section."""
159
+ with ui.row().classes('items-center gap-4'):
160
+ ui.icon('directions_car', size='lg').classes('text-white').style(
161
+ 'filter: drop-shadow(0 2px 8px rgba(255,255,255,0.3));'
162
+ )
163
+ ui.label('UDS Diagnostic Simulator').classes('text-lg font-bold text-white').style(
164
+ 'letter-spacing: 0.5px; text-shadow: 0 2px 4px rgba(0,0,0,0.3);'
165
+ )
166
+
167
+ def _build_header_controls(self):
168
+ """Build the header controls section."""
169
+ with ui.row().classes('items-center gap-6 flex-grow justify-end'):
170
+ with ui.row().classes('items-center gap-3 px-4 py-2 hover:bg-white/20').style(self.GLASS_CONTAINER):
171
+ self.tester_present_checkbox = ui.checkbox(
172
+ 'Tester Present',
173
+ value=False,
174
+ on_change=self._update_tester_present
175
+ ).classes('text-white font-medium').props('dark').style('margin: 0; font-size: 13px;')
176
+
177
+ def _build_header_help(self):
178
+ """Build the header help section."""
179
+ with ui.row().classes('items-center gap-2'):
180
+ def build_help_content():
181
+ ui.icon('help_outline', size='sm').classes('text-white').style('opacity: 0.9;')
182
+ self.help_sid_input = ui.input(
183
+ placeholder='Search SID...',
184
+ ).classes('text-sm').props('dark dense borderless').style(
185
+ f'width: {self.HELP_INPUT_WIDTH}; background: transparent; color: white;'
186
+ ).on('keydown.enter', self._show_help)
187
+ ui.button(icon='search', on_click=self._show_help).props('flat dense round').classes(
188
+ 'text-white'
189
+ ).tooltip('Search SID Help').style('transition: all 0.2s ease;').classes('hover:bg-white/20')
190
+
191
+ self._create_glass_container(build_help_content)
192
+
193
+ def _build_main_content(self):
194
+ """Build the main content area with sidebar and chat."""
195
+ with ui.row().classes('w-full gap-4 p-4').style(f'height: calc(100vh - {self.HEADER_HEIGHT}); background: {self.COLORS["main_bg"]}; overflow: hidden;'):
196
+ self._build_sidebar()
197
+ self._build_chat_area()
198
+
199
+ def _build_sidebar(self):
200
+ """Build the left sidebar with controls and reference."""
201
+ with ui.column().classes('gap-4').style(f'width: {self.SIDEBAR_WIDTH}; height: 100%; overflow-y: auto; background: {self.COLORS["sidebar_bg"]}; padding: {self.SPACING_MD}; border-radius: 20px; box-shadow: 0 8px 32px rgba(0,0,0,0.1);'):
202
+ self._build_diagnostic_request_card()
203
+ self._build_quick_reference_card()
204
+
205
+ def _build_diagnostic_request_card(self):
206
+ """Build the diagnostic request input card."""
207
+ with ui.card().classes('w-full shadow-lg').style(
208
+ f'padding: {self.CARD_PADDING}; background: {self.COLORS["card_bg"]}; '
209
+ f'border-radius: {self.CARD_BORDER_RADIUS}; border: 2px solid {self.COLORS["primary_light"]}; '
210
+ f'box-shadow: {self.COLORS["card_shadow"]};'
211
+ ):
212
+ self._create_card_header('send', 'Diagnostic Request', self.COLORS['primary'], self.COLORS['purple'])
213
+
214
+ self.diag_req_input = ui.input(
215
+ placeholder='e.g., 22 F1 87',
216
+ ).classes('w-full').props('outlined rounded dense').style(
217
+ 'font-size: 14px;'
218
+ ).on('keydown.enter', self._handle_diagnostic_request)
219
+
220
+ ui.button('Send Request', on_click=self._handle_diagnostic_request, icon='send').props(
221
+ 'rounded'
222
+ ).classes('w-full hover:scale-105').style(
223
+ f'background: linear-gradient(135deg, {self.COLORS["primary"]} 0%, {self.COLORS["purple"]} 100%); '
224
+ f'color: white; font-weight: 600; padding: {self.INNER_PADDING}; '
225
+ f'margin-top: {self.CARD_HEADER_MARGIN}; transition: {self.TRANSITIONS["smooth"]}; '
226
+ f'box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);'
227
+ )
228
+
229
+ def _build_quick_reference_card(self):
230
+ """Build the quick reference card with SID information."""
231
+ with ui.card().classes('w-full flex-grow shadow-lg').style(
232
+ f'padding: {self.CARD_PADDING}; background: {self.COLORS["card_bg"]}; '
233
+ f'border-radius: {self.CARD_BORDER_RADIUS}; border: 2px solid {self.COLORS["indigo"]}; '
234
+ f'box-shadow: {self.COLORS["card_shadow"]};'
235
+ ):
236
+ self._create_card_header('bookmarks', 'Quick Reference', self.COLORS['indigo'], self.COLORS['purple'])
237
+
238
+ with ui.column().classes('gap-2'):
239
+ for icon, sid_info, color in self.SID_REFERENCE:
240
+ sid_hex = sid_info.split(' ')[0]
241
+ self._create_sid_item(icon, sid_info, color, lambda sid=sid_hex: self._show_help_for_sid(sid))
242
+
243
+ def _build_chat_area(self):
244
+ """Build the chat display area."""
245
+ with ui.column().classes('flex-1').style(
246
+ f'height: 100%; overflow: hidden; '
247
+ f'background: linear-gradient(135deg, rgba(236, 72, 153, 0.05) 0%, rgba(249, 168, 212, 0.05) 100%); '
248
+ f'padding: {self.SPACING_MD}; border-radius: 20px; box-shadow: 0 8px 32px rgba(0,0,0,0.1);'
249
+ ):
250
+ with ui.card().classes('w-full shadow-lg').style(
251
+ f'padding: {self.CARD_PADDING}; background: {self.COLORS["card_bg"]}; '
252
+ f'border-radius: {self.CARD_BORDER_RADIUS}; border: 2px solid {self.COLORS["pink"]}; '
253
+ f'height: 100%; display: flex; flex-direction: column; box-shadow: {self.COLORS["card_shadow"]};'
254
+ ):
255
+ with ui.row().classes('items-center gap-3').style(f'flex-shrink: 0; margin-bottom: {self.CARD_HEADER_MARGIN};'):
256
+ self._create_card_header('chat', 'Diagnostic Communication', self.COLORS['pink'], self.COLORS['secondary'])
257
+
258
+ self.chat_container = ui.column().classes('w-full gap-2 rounded-lg').style(
259
+ f'flex: 1; overflow-y: auto; padding: {self.INNER_PADDING}; '
260
+ f'background: linear-gradient(135deg, #fdfbfb 0%, #ebedee 100%);'
261
+ )
262
+
263
+ def _add_message(self, role: str, content: str):
264
+ """
265
+ Add a message to the chat display.
266
+
267
+ Args:
268
+ role (str): Either 'user' or 'assistant'
269
+ content (str): The message content
270
+ """
271
+ is_user = role == 'user'
272
+ alignment = 'justify-end' if is_user else 'justify-start'
273
+ sender_name = 'You' if is_user else '🤖 UDS Simulator'
274
+ gradient = self.COLORS['user_message'] if is_user else self.COLORS['assistant_message']
275
+
276
+ with self.chat_container:
277
+ with ui.row().classes(f'w-full {alignment}').style(f'margin-bottom: {self.SPACING_SM}; animation: slideIn 0.3s ease-out;'):
278
+ with ui.card().classes('shadow-md').style(f'max-width: {self.CHAT_MAX_WIDTH}; background: {gradient}; border-radius: 16px; padding: {self.INNER_PADDING}; box-shadow: 0 4px 20px rgba(0,0,0,0.15);'):
279
+ ui.label(sender_name).classes('text-xs font-bold text-white').style(f'margin-bottom: {self.SPACING_SM};')
280
+ ui.label(content).classes('text-sm text-white').style('word-break: break-word; white-space: pre-wrap;')
281
+
282
+ # Add animation keyframes
283
+ ui.add_head_html('''
284
+ <style>
285
+ @keyframes slideIn {
286
+ from {
287
+ opacity: 0;
288
+ transform: translateY(10px);
289
+ }
290
+ to {
291
+ opacity: 1;
292
+ transform: translateY(0);
293
+ }
294
+ }
295
+ </style>
296
+ ''')
297
+
298
+ self._scroll_chat_to_bottom()
299
+
300
+ def _scroll_chat_to_bottom(self):
301
+ """Scroll chat container to the bottom."""
302
+ ui.run_javascript(f'getElement({self.chat_container.id}).scrollTop = getElement({self.chat_container.id}).scrollHeight')
303
+
304
+ def _handle_diagnostic_request(self):
305
+ """
306
+ Handle diagnostic request submission and display response.
307
+ """
308
+ diagnostic_request = self.diag_req_input.value
309
+ if not self._validate_input(diagnostic_request):
310
+ return
311
+
312
+ diagnostic_request_clean = diagnostic_request.replace(" ", "")
313
+
314
+ try:
315
+ diagnostic_request_stream = self._parse_hex_string(diagnostic_request_clean)
316
+ user_sent_request = self.uds_client.format_request(diagnostic_request_stream)
317
+ self._add_message('user', user_sent_request)
318
+
319
+ diagnostic_response = self.uds_client.send_request(diagnostic_request_stream, True)
320
+ self._add_message('assistant', diagnostic_response)
321
+ except ValueError:
322
+ self._handle_invalid_hex(diagnostic_request)
323
+ except Exception as e:
324
+ self._handle_request_error(diagnostic_request, e)
325
+ finally:
326
+ self.diag_req_input.value = ''
327
+
328
+ def _show_help(self):
329
+ """
330
+ Display help information for a specific SID.
331
+ """
332
+ sid_str = self.help_sid_input.value
333
+ if not self._validate_input(sid_str):
334
+ return
335
+
336
+ try:
337
+ sid = int(sid_str, 16)
338
+ service = self.uds_client.server.service_map.get(sid)
339
+
340
+ self._add_message('user', f'Help for SID 0x{sid:02X}')
341
+
342
+ help_text = service.__doc__ if service else f'No help found for SID 0x{sid:02X}.'
343
+ if service and not service.__doc__:
344
+ help_text = f'No documentation available for SID 0x{sid:02X}.'
345
+
346
+ self._add_message('assistant', help_text)
347
+ except (ValueError, IndexError):
348
+ self._add_message('user', f'Help for SID {sid_str}')
349
+ self._add_message('assistant', 'Invalid SID. Please enter a valid hex value.')
350
+ finally:
351
+ self.help_sid_input.value = ''
352
+
353
+ def _show_help_for_sid(self, sid_hex: str):
354
+ """Display help information for a clicked SID from Quick Reference.
355
+
356
+ Args:
357
+ sid_hex (str): The SID in hex format (e.g., '0x10')
358
+ """
359
+ try:
360
+ sid = int(sid_hex, 16)
361
+ service = self.uds_client.server.service_map.get(sid)
362
+
363
+ self._add_message('user', f'Help for SID {sid_hex}')
364
+
365
+ help_text = service.__doc__ if service else f'No help found for SID {sid_hex}.'
366
+ if service and not service.__doc__:
367
+ help_text = f'No documentation available for SID {sid_hex}.'
368
+
369
+ self._add_message('assistant', help_text)
370
+ except (ValueError, IndexError):
371
+ self._add_message('user', f'Help for SID {sid_hex}')
372
+ self._add_message('assistant', 'Invalid SID. Please enter a valid hex value.')
373
+
374
+ def _update_tester_present(self, event):
375
+ """
376
+ Update the tester present flag in the UDS server and log the action.
377
+
378
+ Args:
379
+ event: NiceGUI event object containing the checkbox value
380
+ """
381
+ value = event.value
382
+ self.uds_client.server.diagnostic_session_control.tester_present_active = value
383
+
384
+ status = 'activated' if value else 'deactivated'
385
+ icon = '✔️' if value else '✖️'
386
+ self.logger.info(f'tester present [{icon}] {status}')
387
+
388
+ ui.notify(
389
+ f'Tester Present {status} {icon}',
390
+ type='positive' if value else 'info'
391
+ )
392
+
393
+ # Validation & Parsing Helpers
394
+
395
+ @staticmethod
396
+ def _validate_input(value: str) -> bool:
397
+ """Validate that input is not empty."""
398
+ return bool(value and value.strip())
399
+
400
+ @staticmethod
401
+ def _parse_hex_string(hex_string: str) -> list[int]:
402
+ """Parse hex string into list of integers."""
403
+ return [int(hex_string[i:i+2], 16) for i in range(0, len(hex_string), 2)]
404
+
405
+ # Error Handling Helpers
406
+
407
+ def _handle_invalid_hex(self, diagnostic_request: str):
408
+ """Handle invalid hex input."""
409
+ self._add_message('user', diagnostic_request)
410
+ self._add_message('assistant', 'Invalid hex input. Please enter a valid hex string.')
411
+ self.logger.warning(f"Invalid Diagnostic Request 💉 {diagnostic_request}")
412
+
413
+ def _handle_request_error(self, diagnostic_request: str, error: Exception):
414
+ """Handle request processing error."""
415
+ self._add_message('user', diagnostic_request)
416
+ self._add_message('assistant', f'An error occurred while processing the request. {error}')
417
+ self.logger.error(f"Error occurred while processing request 💉 {diagnostic_request}: {error}")
418
+
419
+
420
+ if __name__ in {"__main__", "__mp_main__"}:
421
+ web_ui = Web()
422
+ web_ui.run()
@@ -0,0 +1,53 @@
1
+ Metadata-Version: 2.3
2
+ Name: py-uds-demo
3
+ Version: 26.0.1
4
+ Summary: Learn and Practice UDS Protocol
5
+ Keywords: python,template
6
+ Author: chaitu-ycr
7
+ Author-email: chaitu-ycr <chaitu.ycr@gmail.com>
8
+ License: MIT License
9
+
10
+ Copyright (c) 2026 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
30
+ Classifier: License :: OSI Approved :: MIT License
31
+ Classifier: Operating System :: Microsoft :: Windows
32
+ Requires-Dist: dearpygui
33
+ Requires-Dist: nicegui[native]
34
+ Requires-Python: >=3.10, <=3.14
35
+ Project-URL: homepage, https://github.com/chaitu-ycr/py-uds-demo
36
+ Project-URL: repository, https://github.com/chaitu-ycr/py-uds-demo
37
+ Project-URL: documentation, https://chaitu-ycr.github.io/py-uds-demo/
38
+ Description-Content-Type: text/markdown
39
+
40
+ # py_uds_demo
41
+
42
+ ## Overview
43
+
44
+ `py_uds_demo` is a Python package for learning and practicing the Unified Diagnostic Services (UDS) protocol. It provides a simulator with CLI, GUI, and Web interfaces, allowing users to send diagnostic requests and view responses as per ISO 14229.
45
+
46
+ ### Features
47
+
48
+ - UDS protocol simulation (ISO 14229)
49
+ - CLI, GUI (CustomTkinter), and Web (Gradio) interfaces
50
+ - Diagnostic session management, data transmission, input/output control, and more
51
+ - Extensible and modular codebase
52
+
53
+ ## [source manual](https://chaitu-ycr.github.io/py-uds-demo/source-manual)
@@ -0,0 +1,24 @@
1
+ py_uds_demo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ py_uds_demo/__main__.py,sha256=fA9chl-2dvQnEwASlZ61Bsh7zJvstHRokOYk0raYarA,2148
3
+ py_uds_demo/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ py_uds_demo/core/client.py,sha256=r9p-m68qsgyNLAji0znute0nAY_8VPvavvtbWCYTri4,3104
5
+ py_uds_demo/core/server.py,sha256=6DYcHajC7p4sEp-LP2UHYBEoCK2gZxNBauuQP_IUChM,12812
6
+ py_uds_demo/core/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ py_uds_demo/core/utils/helpers.py,sha256=mhrvOs1PCcgTNZFJPiVocp_3jOjgKC1sPnfCaUVwgmE,14162
8
+ py_uds_demo/core/utils/responses.py,sha256=Oqz36f79dF0pdawA04eXxfvjuvvgqdmxue45A0hk738,1749
9
+ py_uds_demo/core/utils/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ py_uds_demo/core/utils/services/data_transmission.py,sha256=JeTtcNKi3keLfDgdHh_4RdNm9ieCGl4twDvqa0oTyFA,16895
11
+ py_uds_demo/core/utils/services/diagnostic_and_commmunication_management.py,sha256=wX2qVEW29LGT4_XCM-iVhFXuGJukFVaY6lYcQQnids8,31161
12
+ py_uds_demo/core/utils/services/input_output_contol.py,sha256=DJ5z_JAYjphF7JSiSAkx1_Tj5511g4005duoLiFdDiQ,2495
13
+ py_uds_demo/core/utils/services/negative_response.py,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
14
+ py_uds_demo/core/utils/services/remote_activation_of_routine.py,sha256=id_vFBmANOTul5E-PU7ltRuMSE9poF4bTotbEKSkHFo,3311
15
+ py_uds_demo/core/utils/services/stored_data_transmission.py,sha256=IFeiFqZZtRvTm7MgZII1haU1FlATfjKsevC5kxG6D_4,5490
16
+ py_uds_demo/core/utils/services/upload_download.py,sha256=nLhGBANAYCuCTxv9D78FuEE2YR5FEsjCznK_aEkep40,6055
17
+ py_uds_demo/interface/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
+ py_uds_demo/interface/api.py,sha256=CIqQJx_WsTc5rb4D9gFXnScVjtlBV5WJnA0_xfNfVeY,813
19
+ py_uds_demo/interface/cli.py,sha256=aDkAGkJlTnSd45NzpObpf6rY8Jndty1vMWqaQ85LPEk,2138
20
+ py_uds_demo/interface/gui.py,sha256=IpRa--_UKhx2xF-hlWrdFOsQsTxlmnOnMNMwkSoPyTw,4259
21
+ py_uds_demo/interface/web.py,sha256=YwUyS-8Q3T4XiOC0qVfFkUAg2_1E8LZTUoaM_9iu5UY,19724
22
+ py_uds_demo-26.0.1.dist-info/WHEEL,sha256=fAguSjoiATBe7TNBkJwOjyL1Tt4wwiaQGtNtjRPNMQA,80
23
+ py_uds_demo-26.0.1.dist-info/METADATA,sha256=WVIgGapVoMVu__wNBrIHGmD8qujWWUtFfuCK2xxpi5U,2522
24
+ py_uds_demo-26.0.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: uv 0.9.28
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any