9b51dbca60
The mock had served the shapes the driver once agreed with it on, so it validated the very defects just fixed: it ANSWERED the non-existent 0x00D3 cnc_getfigure, wrote base/exponent 0/0 into position blocks, put the macro decimal at offset 4, and served spindle 'max rpm' as a raw constant. Ported from the sister ignitionoee mock (local divergence recorded in VENDORED.md; the LE timer and alarm cap are kept): - 0x00D3 refused with EW_FUNC, as the real control does. - 0x0026 blocks carry base 10 / position_figures exponent; signed arg2, arg2 = 0 or past the axis count refused EW_ATTRIB. - cnc_rdmacro is the 8-byte ODBM shape, 9-digit mantissa, unset = vacant. - servo/spindle meter records carry the envelope; spindle meters are 1/16384-of-full-scale counts (motor speed = speed / max_rpm). Integration tests: spindle test reads Load/MotorSpeedPct percentages; the position-scale test now proves the block's own scale wins; new Vacant_positions_and_macros_read_bad_over_the_wire. 12/12 pass against the mock run locally (python -m focas_mock.cli serve, OTOPCUA_FOCAS_SIM_ENDPOINT).
61 lines
2.5 KiB
Markdown
61 lines
2.5 KiB
Markdown
# focas-mock — vendored snapshot
|
|
|
|
Source: `C:\Users\dohertj2\Desktop\focas` (sibling project in this dev environment).
|
|
|
|
**Snapshot date:** 2026-04-24 (second refresh — pulled the native FOCAS2 Ethernet responder work in).
|
|
|
|
## Why vendored
|
|
|
|
OtOpcUa's FOCAS integration fixture runs against the Python mock server.
|
|
The upstream lives in its own repo; this directory is a verbatim
|
|
snapshot so CI can build the Docker image without network access to the
|
|
source repo and so OtOpcUa's test matrix pins a known-good revision.
|
|
|
|
The managed `WireFocasClient` speaks the mock's native FOCAS2 Ethernet
|
|
binary protocol directly — there's no longer a companion shim DLL.
|
|
|
|
## What's here
|
|
|
|
| Path | Purpose |
|
|
|------|---------|
|
|
| `src/focas_mock/` | Python package — TCP JSON/line-delimited mock server with 6 Fanuc CNC profiles |
|
|
| `pyproject.toml` | Package metadata; installs `focas-mock` CLI |
|
|
| `Dockerfile` | `python:3.11-slim` image built by the parent `docker-compose.yml` |
|
|
| `README.md` | Upstream README |
|
|
| `LICENSE` | MIT — permissive, vendoring allowed |
|
|
|
|
|
|
## Refreshing the snapshot
|
|
|
|
When upstream ships changes worth pulling:
|
|
|
|
```powershell
|
|
$src = "C:\Users\dohertj2\Desktop\focas"
|
|
$dest = "$PWD"
|
|
Remove-Item -Recurse -Force "$dest\src" 2>$null
|
|
Copy-Item -Recurse "$src\src" "$dest\src"
|
|
Copy-Item "$src\pyproject.toml" "$dest\"
|
|
Copy-Item "$src\README.md" "$dest\"
|
|
Copy-Item "$src\LICENSE" "$dest\"
|
|
Copy-Item "$src\Dockerfile" "$dest\"
|
|
```
|
|
|
|
Update the snapshot date at the top of this file afterward. No other
|
|
files belong here — the Docker build context is just the Python package
|
|
and its metadata.
|
|
|
|
## Local divergence (do not lose on refresh)
|
|
|
|
`src/focas_mock/server.py` and `defaults.py` carry OtOpcUa-local edits that make the wire
|
|
shapes match a real FANUC 31i-B (Makino Z-34184) instead of shapes the driver and the mock had
|
|
agreed on between themselves. A refresh that overwrites `src/` must re-apply them:
|
|
|
|
- the little-endian `cnc_rdtimer` minute/msec encoding (2026-06-25, live-validated);
|
|
- the alarm count cap on `cnc_rdalmmsg2`;
|
|
- (2026-10-07, ported from the sister ignitionoee FOCAS mock) `0x00D3` ("cnc_getfigure", not a
|
|
real FOCAS wire command) refused with `EW_FUNC`; `0x0026` position blocks carrying their own
|
|
`base/exponent` (`position_figures` is now that exponent) and a signed `arg2`;
|
|
`cnc_rdmacro` as the 8-byte ODBM shape (`dec_val` at `[6..7]`, 9-digit mantissa, unset
|
|
macro = vacant); servo/spindle meter records with the `base/exponent` envelope, spindle
|
|
meters in 1/16384-of-full-scale counts.
|