sima-cli 0.0.28__py3-none-any.whl → 0.0.29__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.
- sima_cli/__version__.py +1 -1
- sima_cli/serial/serial.py +85 -10
- {sima_cli-0.0.28.dist-info → sima_cli-0.0.29.dist-info}/METADATA +1 -1
- {sima_cli-0.0.28.dist-info → sima_cli-0.0.29.dist-info}/RECORD +8 -8
- {sima_cli-0.0.28.dist-info → sima_cli-0.0.29.dist-info}/WHEEL +0 -0
- {sima_cli-0.0.28.dist-info → sima_cli-0.0.29.dist-info}/entry_points.txt +0 -0
- {sima_cli-0.0.28.dist-info → sima_cli-0.0.29.dist-info}/licenses/LICENSE +0 -0
- {sima_cli-0.0.28.dist-info → sima_cli-0.0.29.dist-info}/top_level.txt +0 -0
sima_cli/__version__.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
# sima_cli/__version__.py
|
2
|
-
__version__ = "0.0.
|
2
|
+
__version__ = "0.0.29"
|
sima_cli/serial/serial.py
CHANGED
@@ -3,6 +3,8 @@ import subprocess
|
|
3
3
|
import shutil
|
4
4
|
import click
|
5
5
|
import os
|
6
|
+
import errno
|
7
|
+
import glob
|
6
8
|
from sima_cli.utils.env import is_sima_board
|
7
9
|
|
8
10
|
def connect_serial(ctx, baud):
|
@@ -69,6 +71,37 @@ def _connect_mac(baud):
|
|
69
71
|
except KeyboardInterrupt:
|
70
72
|
click.echo("\n❎ Serial connection interrupted by user.")
|
71
73
|
|
74
|
+
def _is_busy(port: str) -> bool:
|
75
|
+
# Try fuser
|
76
|
+
try:
|
77
|
+
r = subprocess.run(["fuser", "-s", port], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
78
|
+
if r.returncode == 0:
|
79
|
+
return True
|
80
|
+
if r.returncode == 1:
|
81
|
+
return False
|
82
|
+
except FileNotFoundError:
|
83
|
+
pass
|
84
|
+
|
85
|
+
try:
|
86
|
+
r = subprocess.run(["lsof", "-Fn", port], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
87
|
+
return r.returncode == 0
|
88
|
+
except FileNotFoundError:
|
89
|
+
pass
|
90
|
+
return False
|
91
|
+
|
92
|
+
def _has_rw_permission(port: str) -> bool:
|
93
|
+
# Quick check
|
94
|
+
if not os.access(port, os.R_OK | os.W_OK):
|
95
|
+
# Double-check by attempting to open; some perms lie with access()
|
96
|
+
try:
|
97
|
+
fd = os.open(port, os.O_RDWR | os.O_NOCTTY | os.O_NONBLOCK)
|
98
|
+
os.close(fd)
|
99
|
+
return True
|
100
|
+
except OSError as e:
|
101
|
+
if e.errno in (errno.EACCES, errno.EPERM):
|
102
|
+
return False
|
103
|
+
# Other errors (e.g., EBUSY) are handled elsewhere
|
104
|
+
return True
|
72
105
|
|
73
106
|
def _connect_linux(baud):
|
74
107
|
terminal = "picocom"
|
@@ -118,20 +151,62 @@ def _connect_linux(baud):
|
|
118
151
|
click.echo("❌ No USB serial device found.")
|
119
152
|
raise SystemExit(1)
|
120
153
|
|
121
|
-
|
154
|
+
# Discover ports
|
155
|
+
ports = sorted(glob.glob("/dev/ttyUSB*"))
|
156
|
+
if not ports:
|
157
|
+
click.echo("❌ No USB serial device found.")
|
158
|
+
raise SystemExit(1)
|
159
|
+
|
160
|
+
# Classify ports
|
161
|
+
busy, no_perm, free_ok = [], [], []
|
162
|
+
for p in ports:
|
163
|
+
if _is_busy(p):
|
164
|
+
busy.append(p)
|
165
|
+
elif not _has_rw_permission(p):
|
166
|
+
no_perm.append(p)
|
167
|
+
else:
|
168
|
+
free_ok.append(p)
|
169
|
+
|
170
|
+
if busy:
|
171
|
+
click.echo("⚠ Busy (in use): " + ", ".join(busy))
|
172
|
+
if no_perm:
|
173
|
+
click.echo("⛔ No permission: " + ", ".join(no_perm))
|
174
|
+
click.echo(
|
175
|
+
"\nTo fix permissions on Ubuntu/Debian:\n"
|
176
|
+
" sudo usermod -aG dialout $USER\n"
|
177
|
+
" # then log out and log back in (or reboot)\n"
|
178
|
+
"Temporary (until reboot):\n"
|
179
|
+
" sudo chmod a+rw /dev/ttyUSBX # not recommended long-term\n"
|
180
|
+
)
|
181
|
+
|
182
|
+
if not free_ok:
|
183
|
+
click.echo("❌ No accessible, free USB serial ports available.")
|
184
|
+
raise SystemExit(1)
|
185
|
+
|
186
|
+
# Choose port
|
187
|
+
if len(free_ok) == 1:
|
188
|
+
port = free_ok[0]
|
189
|
+
click.echo(f"✅ Using the only free port: {port}")
|
190
|
+
else:
|
191
|
+
click.echo("🔍 Multiple free ports found:")
|
192
|
+
for i, p in enumerate(free_ok, 1):
|
193
|
+
click.echo(f" {i}. {p}")
|
194
|
+
idx = click.prompt(f"Select a port [1-{len(free_ok)}]", type=int, default=1)
|
195
|
+
if not (1 <= idx <= len(free_ok)):
|
196
|
+
click.echo("❌ Invalid selection.")
|
197
|
+
raise SystemExit(1)
|
198
|
+
port = free_ok[idx - 1]
|
199
|
+
|
200
|
+
# Connect
|
122
201
|
click.echo(f"🔌 Connecting to {port} with {terminal} ({baud} 8N1)...")
|
123
202
|
try:
|
124
203
|
if terminal == "picocom":
|
125
|
-
click.echo("🧷 To exit:
|
126
|
-
subprocess.run(
|
127
|
-
["sudo", terminal, "-b", f"{baud}", "--databits", "8", "--parity", "n", "--stopbits", "1", port]
|
128
|
-
)
|
204
|
+
click.echo("🧷 To exit: Ctrl+A, then Ctrl+X")
|
205
|
+
subprocess.run([terminal, "-b", f"{baud}", "--databits", "8", "--parity", "n", "--stopbits", "1", port])
|
129
206
|
else: # minicom
|
130
|
-
|
131
|
-
click.echo("🧷 To exit:
|
132
|
-
subprocess.run(
|
133
|
-
["sudo", terminal, "-C", config_file, "-D", port]
|
134
|
-
)
|
207
|
+
cfg = os.path.expanduser("~/.minirc.custom")
|
208
|
+
click.echo("🧷 To exit: Ctrl+A, then Q")
|
209
|
+
subprocess.run([terminal, "-C", cfg, "-D", port])
|
135
210
|
except KeyboardInterrupt:
|
136
211
|
click.echo("\n❎ Serial connection interrupted by user.")
|
137
212
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
sima_cli/__init__.py,sha256=Nb2jSg9-CX1XvSc1c21U9qQ3atINxphuNkNfmR-9P3o,332
|
2
2
|
sima_cli/__main__.py,sha256=ehzD6AZ7zGytC2gLSvaJatxeD0jJdaEvNJvwYeGsWOg,69
|
3
|
-
sima_cli/__version__.py,sha256=
|
3
|
+
sima_cli/__version__.py,sha256=2CZTSSWitwWN8SjkJ0aMqI9jsY-Mo2BPRi6u1w3Ympk,49
|
4
4
|
sima_cli/cli.py,sha256=GYmQ7_XObl9VgFwuWWkWDo-_Y_Vn6lM53F7mKiYGubI,17126
|
5
5
|
sima_cli/app_zoo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
6
6
|
sima_cli/app_zoo/app.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -25,7 +25,7 @@ sima_cli/network/network.py,sha256=ToDCQBfX0bUFEWWtfS8srImK5T11MX6R4MBQFM80faY,7
|
|
25
25
|
sima_cli/sdk/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
26
26
|
sima_cli/sdk/syscheck.py,sha256=h9zCULW67y4i2hqiGc-hc1ucBDShA5FAe9NxwBGq-fM,4575
|
27
27
|
sima_cli/serial/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
28
|
-
sima_cli/serial/serial.py,sha256=
|
28
|
+
sima_cli/serial/serial.py,sha256=c5k0H2BTJGGCfysmBX1Ijp2pUT9serwdmE6_WyLUiQs,8664
|
29
29
|
sima_cli/storage/nvme.py,sha256=cCzYWcyPwcFu5pSMBkovsS4EwovaIMGolhEFStogXMA,4739
|
30
30
|
sima_cli/storage/sdcard.py,sha256=-WULjdV31-n8v5OOqfxR77qBbIK4hJnrD3xWxUVMoGI,6324
|
31
31
|
sima_cli/update/__init__.py,sha256=0P-z-rSaev40IhfJXytK3AFWv2_sdQU4Ry6ei2sEus0,66
|
@@ -44,7 +44,7 @@ sima_cli/utils/disk.py,sha256=66Kr631yhc_ny19up2aijfycWfD35AeLQOJgUsuH2hY,446
|
|
44
44
|
sima_cli/utils/env.py,sha256=IP5HrH0lE7RMSiBeXcEt5GCLMT5p-QQroG-uGzl5XFU,8181
|
45
45
|
sima_cli/utils/net.py,sha256=WVntA4CqipkNrrkA4tBVRadJft_pMcGYh4Re5xk3rqo,971
|
46
46
|
sima_cli/utils/network.py,sha256=UvqxbqbWUczGFyO-t1SybG7Q-x9kjUVRNIn_D6APzy8,1252
|
47
|
-
sima_cli-0.0.
|
47
|
+
sima_cli-0.0.29.dist-info/licenses/LICENSE,sha256=a260OFuV4SsMZ6sQCkoYbtws_4o2deFtbnT9kg7Rfd4,1082
|
48
48
|
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
49
49
|
tests/test_app_zoo.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
50
50
|
tests/test_auth.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -53,8 +53,8 @@ tests/test_download.py,sha256=t87DwxlHs26_ws9rpcHGwr_OrcRPd3hz6Zmm0vRee2U,4465
|
|
53
53
|
tests/test_firmware.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
54
54
|
tests/test_model_zoo.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
55
55
|
tests/test_utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
56
|
-
sima_cli-0.0.
|
57
|
-
sima_cli-0.0.
|
58
|
-
sima_cli-0.0.
|
59
|
-
sima_cli-0.0.
|
60
|
-
sima_cli-0.0.
|
56
|
+
sima_cli-0.0.29.dist-info/METADATA,sha256=1MSfBv5taVOiFdadoLN9hElB33o0aKhHRgU-EgnH-e8,3705
|
57
|
+
sima_cli-0.0.29.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
58
|
+
sima_cli-0.0.29.dist-info/entry_points.txt,sha256=xRYrDq1nCs6R8wEdB3c1kKuimxEjWJkHuCzArQPT0Xk,47
|
59
|
+
sima_cli-0.0.29.dist-info/top_level.txt,sha256=FtrbAUdHNohtEPteOblArxQNwoX9_t8qJQd59fagDlc,15
|
60
|
+
sima_cli-0.0.29.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|