lr-shuttle 0.2.8__py3-none-any.whl → 0.2.9__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.

Potentially problematic release.


This version of lr-shuttle might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lr-shuttle
3
- Version: 0.2.8
3
+ Version: 0.2.9
4
4
  Summary: CLI and Python client for host-side of json based serial communication with embedded device bridge.
5
5
  Author-email: Jonas Estberger <jonas.estberger@lumenradio.com>
6
6
  License: MIT
@@ -1,18 +1,18 @@
1
- shuttle/cli.py,sha256=fv5HfJxfg8hnyO4CCA2vwG-OfTDSygnV6MrsZwv1yD8,108548
1
+ shuttle/cli.py,sha256=3RkIJ4Z7RQiGObPTC_f4V2JqCTlwAaA_0PutqnYrwGU,109676
2
2
  shuttle/constants.py,sha256=GUlAg3iEuPxLQ2mDCvlv5gVXHnlawl_YeLtaUSqsnPM,757
3
3
  shuttle/flash.py,sha256=9ph23MHL40SjKZoL38Sbd3JbykGb-ECxvzBzCIjAues,4492
4
4
  shuttle/prodtest.py,sha256=nI8k2OndhqsOv8BMtXwfcpGEdmHU7ywbIgMuW49EULU,8006
5
- shuttle/serial_client.py,sha256=0srdCjKHW35LQFmZM_q-A9QEtSNadJp3WpqzIAHI1zo,19743
5
+ shuttle/serial_client.py,sha256=Wkkih00yt4M97S-P5kW06a2bY1fdTxafNGsf3G9Hx2Y,20408
6
6
  shuttle/timo.py,sha256=SfWgiYUtPjSsUln5hgDLiYMYOt8zg1DLL5t07sgu2wY,18336
7
7
  shuttle/firmware/__init__.py,sha256=KRXyz3xJ2GIB473tCHAky3DdPIQb78gX64Qn-uu55To,120
8
8
  shuttle/firmware/esp32c5/__init__.py,sha256=U2xXnb80Wv8EJaJ6Tv9iev1mVlpoaEeqsNmjmEtxdFQ,41
9
9
  shuttle/firmware/esp32c5/boot_app0.bin,sha256=-UxdeGp6j6sGrF0Q4zvzdxGmaXY23AN1WeoZzEEKF_A,8192
10
- shuttle/firmware/esp32c5/devboard.ino.bin,sha256=idrwg2JFHYjLK2KQVj4d_v31GHkqO8gEgr2TWkPHbbY,1101248
10
+ shuttle/firmware/esp32c5/devboard.ino.bin,sha256=HIS-3dQ_1BH0F-l0LJdkwVuFm8lG3IlYn2aHkEt0Y0g,1101248
11
11
  shuttle/firmware/esp32c5/devboard.ino.bootloader.bin,sha256=LPU51SdUwebYemCZb5Pya-wGe7RC4UXrkRmBnsHePp0,20784
12
12
  shuttle/firmware/esp32c5/devboard.ino.partitions.bin,sha256=FIuVnL_xw4qo4dXAup1hLFSZe5ReVqY_QSI-72UGU6E,3072
13
13
  shuttle/firmware/esp32c5/manifest.json,sha256=CPOegfEK4PTtI6UPeohuUKkJNeg0t8aWntEczpoxYt4,480
14
- lr_shuttle-0.2.8.dist-info/METADATA,sha256=6yYpMjMjWpAOEMIJntX3XDiX1MveRgqJ3TnjheFZ_Ks,15574
15
- lr_shuttle-0.2.8.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
16
- lr_shuttle-0.2.8.dist-info/entry_points.txt,sha256=obqdFPgvQLB1_EWcnD9ch8HjQRlNVT_pdB_EidDRDco,44
17
- lr_shuttle-0.2.8.dist-info/top_level.txt,sha256=PtNxNQQdya-Xs8DYublNTBTa8c1TrtfEpQ0lUd_OeZY,8
18
- lr_shuttle-0.2.8.dist-info/RECORD,,
14
+ lr_shuttle-0.2.9.dist-info/METADATA,sha256=vYewsrk-Da5kQrd8M5NRHe_vwbpdhThZ0V1E7fbLL90,15574
15
+ lr_shuttle-0.2.9.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
16
+ lr_shuttle-0.2.9.dist-info/entry_points.txt,sha256=obqdFPgvQLB1_EWcnD9ch8HjQRlNVT_pdB_EidDRDco,44
17
+ lr_shuttle-0.2.9.dist-info/top_level.txt,sha256=PtNxNQQdya-Xs8DYublNTBTa8c1TrtfEpQ0lUd_OeZY,8
18
+ lr_shuttle-0.2.9.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.10.1)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
shuttle/cli.py CHANGED
@@ -767,6 +767,9 @@ def _execute_timo_sequence(
767
767
  logger=logger,
768
768
  seq_tracker=seq_tracker,
769
769
  ) as client:
770
+ # Drain any pending serial noise before issuing commands, to avoid
771
+ # mixing stale data into NDJSON responses.
772
+ client.flush_input_and_log()
770
773
  for transfer in sequence:
771
774
  response = client.spi_xfer(**transfer)
772
775
  responses.append(response)
@@ -2634,6 +2637,7 @@ def spi_enable_command(
2634
2637
  logger=resources.get("logger"),
2635
2638
  seq_tracker=resources.get("seq_tracker"),
2636
2639
  ) as client:
2640
+ client.flush_input_and_log()
2637
2641
  response = client.spi_enable()
2638
2642
  except ShuttleSerialError as exc:
2639
2643
  console.print(f"[red]{exc}[/]")
@@ -2668,6 +2672,7 @@ def spi_disable_command(
2668
2672
  logger=resources.get("logger"),
2669
2673
  seq_tracker=resources.get("seq_tracker"),
2670
2674
  ) as client:
2675
+ client.flush_input_and_log()
2671
2676
  response = client.spi_disable()
2672
2677
  except ShuttleSerialError as exc:
2673
2678
  console.print(f"[red]{exc}[/]")
@@ -3138,6 +3143,7 @@ def power_command(
3138
3143
  logger=resources.get("logger"),
3139
3144
  seq_tracker=resources.get("seq_tracker"),
3140
3145
  ) as client:
3146
+ client.flush_input_and_log()
3141
3147
  method = getattr(client, method_name)
3142
3148
  response = method()
3143
3149
  except ShuttleSerialError as exc:
@@ -3171,6 +3177,11 @@ def flash_command(
3171
3177
  "--erase-first/--no-erase-first",
3172
3178
  help="Erase the entire flash before writing",
3173
3179
  ),
3180
+ sleep_after_flash: float = typer.Option(
3181
+ 1.25,
3182
+ "--sleep-after-flash",
3183
+ help="Seconds to wait after flashing to allow device reboot",
3184
+ ),
3174
3185
  ):
3175
3186
  """Flash the bundled firmware image to the devboard."""
3176
3187
 
@@ -3194,6 +3205,24 @@ def flash_command(
3194
3205
  console.print(f"[red]{exc}[/]")
3195
3206
  raise typer.Exit(1) from exc
3196
3207
 
3208
+ if sleep_after_flash:
3209
+ time.sleep(
3210
+ sleep_after_flash
3211
+ ) # Give the device a moment to reboot. 0.75s is sometimes too short.
3212
+
3213
+ # After flashing, drain/log any startup output from the device before further commands
3214
+ logger = ctx.obj["logger"] if ctx.obj and "logger" in ctx.obj else None
3215
+ try:
3216
+ from .serial_client import NDJSONSerialClient
3217
+
3218
+ # Use a short timeout just for draining
3219
+ with NDJSONSerialClient(
3220
+ resolved_port, baudrate=baudrate, timeout=0.5, logger=logger
3221
+ ) as client:
3222
+ client.flush_input_and_log()
3223
+ except Exception:
3224
+ pass
3225
+
3197
3226
  label = str(manifest.get("label", board))
3198
3227
  console.print(
3199
3228
  f"[green]Successfully flashed {label} ({board}) over {resolved_port}[/]"
Binary file
shuttle/serial_client.py CHANGED
@@ -281,9 +281,27 @@ class NDJSONSerialClient:
281
281
  if getattr(self, "_serial", None) and self._serial.is_open:
282
282
  self._serial.close()
283
283
 
284
+ def flush_input_and_log(self):
285
+ """Read and log all available data from the serial buffer before sending a command."""
286
+ if not hasattr(self, "_serial") or not getattr(self._serial, "in_waiting", 0):
287
+ return
288
+ try:
289
+ while True:
290
+ waiting = getattr(self._serial, "in_waiting", 0)
291
+ if not waiting:
292
+ break
293
+ data = self._serial.read(waiting)
294
+ if data:
295
+ self._log_serial("RX", data)
296
+ except Exception:
297
+ pass
298
+
284
299
  def send_command(self, op: str, params: Dict[str, Any]) -> CommandFuture:
285
300
  """Send a command without blocking, returning a future for the response."""
286
301
 
302
+ # Flush and log any unread data before sending a command
303
+ self.flush_input_and_log()
304
+
287
305
  cmd_id = self._next_cmd_id()
288
306
  message: Dict[str, Any] = {"type": "cmd", "id": cmd_id, "op": op}
289
307
  message.update(params)