Skip to content

Upgrade to MADSci 0.8 + split COM driver into 32-bit sidecar#3

Open
RyanTheRobothead wants to merge 1 commit into
mainfrom
update/madsci-v0.8
Open

Upgrade to MADSci 0.8 + split COM driver into 32-bit sidecar#3
RyanTheRobothead wants to merge 1 commit into
mainfrom
update/madsci-v0.8

Conversation

@RyanTheRobothead
Copy link
Copy Markdown
Member

Summary

  • Upgrade madsci.* pin from ~=0.6.0 to ~=0.8.0; bump Python floor to 3.10 (required by v0.8).
  • Split the COM-owning driver into a new 32-bit FastAPI sidecar under sidecar/, since madsci.common 0.8 pulls in psycopg2-binary which has no win32 wheel and breaks installs on the 32-bit Python the BMG ActiveX COM server requires.
  • Refactor src/bmg_rest_node.py to talk to the sidecar over loopback HTTP (mirrors the pattern already used by inheco_incubator_module), and delete the now-replaced src/bmg_interface.py + src/bmg_object_thread.py.

Architecture

workcell  --HTTP-->  bmg_rest_node (64-bit, madsci v0.8)  --HTTP-->  bmg_sidecar (32-bit, ActiveX)
                     port 3003 on suestorm                            port 7002 loopback

The split is the v0.8-specific workaround for upstream issue AD-SDL/MADSci#343 — the sidecar has no madsci dep at all, so the win32 wheel problem doesn't bite.

Notable details

  • New sidecar/ package has its own pyproject.toml, its own venv (32-bit Python 3.12), and minimal deps (fastapi, uvicorn, pydantic, comtypes, pywin32).
  • BMGNodeConfig gains sidecar_host / sidecar_port / sidecar_timeout fields.
  • self.node_definition.node_nameself.node_info.node_name (v0.8 removed node_definition).
  • BmgCom.read_temps() now returns None per-sensor instead of raising when GetInfo returns a non-numeric value (typical when the device hasn't been initialized in SMART Control yet) — pre-existing bug exposed by the new HTTP-mediated state polling.

Cross-references

Test plan

  • pdm install in bmg_module/ (64-bit venv) resolves cleanly with v0.8.
  • pdm install in bmg_module/sidecar/ (32-bit venv) resolves cleanly with no madsci deps.
  • Sidecar boots and opens the BMG ActiveX COM connection (Init and read_temps round-trip).
  • Node boots, probes the sidecar at startup, and serves /info, /state, /status.
  • state_handler polls the sidecar without 500s.
  • Actions: open, close, set_temp, run_assay round-trip through node → sidecar → COM.
  • Under process-compose orchestration: sidecar reaches Ready first, node depends on it via process_healthy.

🤖 Generated with Claude Code

MADSci 0.8 (via madsci-common 0.8.0) pulls in psycopg2-binary as a hard
runtime dep. psycopg2-binary has no win32 wheel and falls back to a source
build that needs pg_config — which means it can't be installed in 32-bit
Python. The BMG node needs 32-bit Python because BMG_ActiveX.BMGRemoteControl
is a 32-bit COM server.

This splits the module into two processes (mirroring the pattern already
used by inheco_incubator_module):

- A new 32-bit FastAPI sidecar under sidecar/ that owns the ActiveX COM
  connection. Has no madsci dependency; minimal deps (fastapi, uvicorn,
  comtypes, pywin32, pydantic).

- The existing src/bmg_rest_node.py now runs in 64-bit Python, drops the
  in-process BMGThread/BmgCom imports, and talks to the sidecar over
  loopback HTTP via the new sidecar_host / sidecar_port / sidecar_timeout
  config fields.

Old src/bmg_interface.py and src/bmg_object_thread.py are deleted — the
COM-owning code moved into sidecar/bmg_interface.py (with the EventClient
dep stripped in favor of stdlib logging), and the thread/queue dispatcher
is replaced by FastAPI request handling plus a single threading.Lock to
serialize COM access.

Also:
- BmgCom.read_temps() now returns None per-sensor instead of raising when
  GetInfo returns a non-numeric value (typical when the device hasn't been
  initialized in SMART Control yet).
- node uses self.node_info.node_name instead of the removed
  self.node_definition.node_name attribute (v0.8 breaking change).
- pyproject: madsci.*~=0.6.0 → ~=0.8.0; requires-python >=3.9.1 → >=3.10
  (v0.8 requires 3.10+); add requests; drop pywin32/comtypes (now sidecar-
  only).
- .gitignore: ignore .madsci/ (runtime state) and .python-version (local
  dev).

Cross-reference: blocks until upstream addresses
AD-SDL/MADSci#343 (psycopg2-binary should not be
a hard dep of madsci-common).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants