Fix wake beacon serial latency and pretty-print JSON

This commit is contained in:
Joey Yakimowich-Payne 2026-09-19 22:18:51 -06:00
commit b7b2041e3d
2 changed files with 34 additions and 5 deletions

View file

@ -224,13 +224,20 @@ class WakeBeaconClient:
def _exchange(self, command: bytes, deadline: float) -> WakeBeaconStatus:
try:
self.transport.write_timeout = min(0.25, self._remaining(deadline))
write_timeout = min(0.25, self._remaining(deadline))
if self.transport.write_timeout != write_timeout:
self.transport.write_timeout = write_timeout
# A partial write may already have reached the device. Never resend.
if self.transport.write(command) != len(command):
raise TransportError("Incomplete serial write; command was not retried")
response = bytearray()
while True:
self.transport.timeout = min(0.1, self._remaining(deadline))
read_timeout = min(0.1, self._remaining(deadline))
# pyserial reconfigures the Windows port on every assignment,
# even for an unchanged timeout. Avoid USB control transfers
# per response byte, while still shortening reads at deadline.
if self.transport.timeout != read_timeout:
self.transport.timeout = read_timeout
chunk = self.transport.read(1)
if not chunk:
continue
@ -398,7 +405,7 @@ def main(argv: Sequence[str] | None = None) -> int:
"status": exc.status.to_dict() if exc.status else None,
}
if args.json:
print(json.dumps(result, separators=(",", ":")))
print(json.dumps(result, indent=2))
else:
print(f"Wake beacon: {exc}", file=sys.stderr)
return 1
@ -406,11 +413,11 @@ def main(argv: Sequence[str] | None = None) -> int:
print(
json.dumps(
{"ok": True, "action": action, "status": status.to_dict()},
separators=(",", ":"),
indent=2,
)
)
elif args.status:
print(json.dumps(status.to_dict(), sort_keys=True))
print(json.dumps(status.to_dict(), indent=2, sort_keys=True))
else:
print(
f"Advertising burst complete (request {status.request_id}); console power state is not confirmed."

View file

@ -179,6 +179,28 @@ def test_fragmented_burst_completes_once_and_excludes_retained_id(beacon):
assert beacon.closed
def test_slow_serial_reconfiguration_does_not_delay_each_response_byte(
beacon, monkeypatch
):
# pyserial reconfigures an open Windows port even when assigned the same
# timeout. Model USB control-transfer latency on each such assignment.
def set_timeout(device, value):
device.__dict__["timeout"] = value
device.clock.sleep(0.02)
monkeypatch.setattr(
SimulatedBeacon,
"timeout",
property(lambda device: device.__dict__["timeout"], set_timeout),
raising=False,
)
result = wake.request_wake("COM13", timeout=1)
assert result.state == "complete"
assert beacon.bursts == 1
assert beacon.clock.now < 1
assert beacon.closed
@pytest.mark.parametrize(
"change",
[