feat(focas): add cnc_getfigure wire command + focas-mock handler

This commit is contained in:
Joseph Doherty
2026-06-18 12:23:14 -04:00
parent e5b1a5574a
commit f320f323ae
4 changed files with 68 additions and 7 deletions
@@ -78,6 +78,10 @@ def make_default_state(profile: Mapping[str, Any]) -> dict[str, Any]:
"acts": 3200,
"acts2": [3200] + [0] * (max_spindles - 1),
"axis_names": axis_names[:max_axis],
# Per-axis position decimal places served by cnc_getfigure (command 0x00d3).
# Default every configured axis to 0 ⇒ 10^0 = 1.0 scale, leaving existing
# position reads unchanged. mock_patch can override individual axes.
"position_figures": {name: 0 for name in axis_names[:max_axis]},
"spindle_names": spindle_names,
"parameters": {
"6711": {"type": "long", "value": 1, "decimal": 0, "description": "example parameter"},
@@ -256,6 +256,8 @@ class FocasMockServer:
return self._wire_spindle_metric(request_block)
if command == 0x56:
return self._wire_servo_meter()
if command == 0xD3:
return self._wire_position_figures()
if command == 0x57:
mode = self.store.snapshot()["operation_mode"]
return self._u16(int(mode.get("mode", 0) if isinstance(mode, dict) else mode))
@@ -381,6 +383,14 @@ class FocasMockServer:
payload += self._name_record(name, 4)
return bytes(payload)
def _wire_position_figures(self) -> bytes:
state = self.store.snapshot()
figures = state.get("position_figures", {})
payload = bytearray()
for name in state["axis_names"]:
payload += self._u16(int(figures.get(name, 0)))
return bytes(payload)
def _wire_spindle_metric(self, request_block: bytes) -> bytes:
metric = self._block_u32(request_block, 8)
spindle = self.store.snapshot()["spindle"]