Skip to content

Commit eaf31a2

Browse files
committed
feat: wait_until_simulation_time() method for better simulation control
Added a new method in WokwiClient to pause the simulation and wait for a specified duration. Updated the hello_esp32 example to use this new method. This will make the simulation results predictable and repeatable.
1 parent a621204 commit eaf31a2

File tree

2 files changed

+18
-2
lines changed

2 files changed

+18
-2
lines changed

examples/hello_esp32/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ async def main() -> None:
5454
# Stream serial output for a few seconds
5555
serial_task = asyncio.create_task(client.serial_monitor_cat())
5656
print(f"Simulation started, waiting for {SLEEP_TIME} seconds…")
57-
await asyncio.sleep(SLEEP_TIME)
57+
await client.wait_until_simulation_time(SLEEP_TIME)
5858
serial_task.cancel()
5959

6060
# Disconnect from the simulator

src/wokwi_client/client.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,24 @@
77

88
from .__version__ import get_version
99
from .constants import DEFAULT_WS_URL
10+
from .event_queue import EventQueue
1011
from .file_ops import upload, upload_file
11-
from .protocol_types import ResponseMessage
12+
from .protocol_types import EventMessage, ResponseMessage
1213
from .serial import monitor_lines
1314
from .simulation import pause, restart, resume, start
1415
from .transport import Transport
1516

1617

1718
class WokwiClient:
1819
version: str
20+
last_pause_nanos: int
1921

2022
def __init__(self, token: str, server: Optional[str] = None):
2123
self.version = get_version()
2224
self._transport = Transport(token, server or DEFAULT_WS_URL)
25+
self.last_pause_nanos = 0
26+
self._transport.add_event_listener("sim:pause", self._on_pause)
27+
self._pause_queue = EventQueue(self._transport, "sim:pause")
2328

2429
async def connect(self) -> dict[str, Any]:
2530
return await self._transport.connect()
@@ -44,9 +49,20 @@ async def pause_simulation(self) -> ResponseMessage:
4449
async def resume_simulation(self, pause_after: Optional[int] = None) -> ResponseMessage:
4550
return await resume(self._transport, pause_after)
4651

52+
async def wait_until_simulation_time(self, seconds: float) -> None:
53+
await pause(self._transport)
54+
remaining_nanos = seconds * 1e9 - self.last_pause_nanos
55+
if remaining_nanos > 0:
56+
self._pause_queue.flush()
57+
await resume(self._transport, int(remaining_nanos))
58+
await self._pause_queue.get()
59+
4760
async def restart_simulation(self, pause: bool = False) -> ResponseMessage:
4861
return await restart(self._transport, pause)
4962

5063
async def serial_monitor_cat(self) -> None:
5164
async for line in monitor_lines(self._transport):
5265
print(line.decode("utf-8"), end="", flush=True)
66+
67+
def _on_pause(self, event: EventMessage) -> None:
68+
self.last_pause_nanos = int(event["nanos"])

0 commit comments

Comments
 (0)