Skip to content

Audit/wifi reliability#2610

Open
WinstonPoh wants to merge 34 commits into
Snapmaker:mainfrom
WinstonPoh:audit/wifi-reliability
Open

Audit/wifi reliability#2610
WinstonPoh wants to merge 34 commits into
Snapmaker:mainfrom
WinstonPoh:audit/wifi-reliability

Conversation

@WinstonPoh

@WinstonPoh WinstonPoh commented Jun 20, 2026

Copy link
Copy Markdown
  • make wifi connection more reliable
  • try to improve state sync between app and machine (for things like Laser on, enclosure LEDs on, etc)
  • make it home/go to work origin faster

WinstonPoh and others added 30 commits January 26, 2026 09:26
- ts problems
- nodemon/gulp issues
- tsconfig transpilation issues
- Move FullChannel type alias below import block (import/first)
- Merge duplicate app/constants import (import/no-duplicates)
- Suppress no-unused-vars on base-class no-op stopHeartbeat param

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
node_modules had stale webpack 4 despite package.json/lock already specifying
webpack 5.104.1; reinstalling synced node_modules and tidied the lockfile
(no version changes). Fixes the "Invalid configuration object" build failure
(webpack 4 running a webpack 5 config).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- 01 state synchronization (15 findings, 3 P0)
- 02 motion safety (14 findings, 3 P0)
- 03 connection lifecycle (12 findings, 1 P0)
- 04 command/ack robustness (17 findings, 3 P0)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
All 18 P0/P1 findings re-checked against code and Snapmaker2-Controller
firmware. None fully refuted; 4 materially corrected (noted in
Verification subsections).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…admap)

Synthesizes 58 findings into 5 root causes, maps each symptom to causes,
ranks 20 fixes (R1-R20) across 3 tiers, and lists live read-only checks
to resolve the pivotal transport-negotiation unknown.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Read-only probe confirms TCP 8888 refused, UDP 8889 SACP silent, HTTP 8080
open (AndServer). ProtocolDetector selects HTTP. Re-pivots Phase 2 to the
operative HTTP-path fixes; SACP fixes (R1/R2/R3) deprioritized (latent for
USB-serial only).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Captured /api/v1/status from A350: confirms no headStatus field
  (R9 operative), homed is a correct boolean (01-F10 HTTP not a bug),
  and exposes focal length / laser error state / camera / door state
  useful for feature specs.
- Add SACP-protocol-reference.md (wire format + full command-set map
  from the vendored SDK) as notes for the deferred SACP findings.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Operative HTTP-path fixes only, per live transport finding. TDD on
extracted pure helpers; manual live-validation scripts for motion fixes.
SACP fixes deferred to SACP-protocol-reference.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…F12)

onConnection fired per socket.io client connection and called stopHeartBeat(),
freezing the UI of an already-connected machine when a 2nd window opened or the
renderer reconnected. The poller is owned by startHeartbeat()/connectionClose();
startHeartbeat() already cycles the worker, so onConnection is now a no-op.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…9/01-F2)

HTTP /api/v1/status has no headStatus field; the renderer coerced !!headStatus
every poll, forcing the laser toggle off. Now: SstpHttpChannel derives headStatus
from numeric laserPower (deriveHeadStatus helper, unit-tested), and the renderer
only updates headStatus when present (!isNil), matching neighbouring fields.

Note: the tape suite cannot resolve .ts imports under @babel/register in this
branch (pre-existing), so the helper is plain .js and its test is run per-file.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…(R20/01-F7)

getEnclosureStatus cached undefined and emitted a Marlin:settings with all-
undefined fields on a failed/empty poll, blanking enclosure door/fan/light in
the UI. Now it returns early on error/empty data, preserving last known values.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…5+R7)

goHome (HTTP) emitted isHoming:true AFTER G28 and never isHoming:false, so the
homing modal stuck and homing looked slow (02-F5). Now emits true before G28,
false after. Also always restores G54 after homing (not just laser/CNC) so the
machine never lingers in modal G53 machine-space (02-F3). Drop now-unused
HEAD_CNC import.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
setWorkOrigin gated each axis with truthiness, silently dropping an axis set to
exactly 0 (common after homing or from AB-position/camera flows), leaving a stale
per-axis origin -> mixed origins, a bed-crash contributor. Extracted
buildSetWorkOriginGcode (Number.isFinite, unit-tested) and used it on the HTTP
branch; SACP branch flagged with a TODO for when that path is tackled.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ep (04-F9)

HTTP _executeGcode now returns an `ok` flag; consumeGCodeQueue stops at the first
failed line and reports result:-1 instead of always 0. startGcode inspects the
preparatory-move results and aborts the job (emitting StartGCode err) if any
failed, so a failed G53/G0 Z<focal+thickness>/G54 no longer silently starts the
job at the wrong Z. Added a .catch to the prep sequence.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…e (R7/02-F3)

startCameraAid emitted a bare G53 then restored G54 only on the success path. A
failed/throwing getCameraCalibration (early return) or a photo/stitch failure left
the machine in modal G53, so the next absolute move executed in machine space and
could plunge to machine Z0. Now G54 is restored on the calibration-failure return,
on a calibration throw, and via a .catch on the capture promise. (The goHome G53
leak was already fixed in the R5 commit by always restoring G54.)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…6/02-F2)

The button packed all axes into one G0 line, so the head moved diagonally toward
the origin with no Z clearance (the per-axis ordering in the UI was dead code).
Added sequenceGoToOrigin helper (unit-tested): when above the origin, move XY
first then lower Z; when at/below, raise Z first. New goToWorkOrigin action sends
the two lines as one atomic multi-line executeGcode so the HTTP channel runs them
strictly in order. Removed the dead per-axis branch and unused workPosition prop.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…2-F4)

The saved G54 work origin survives homing and material/toolhead changes, so
descending to a stale origin can drive the head into the workpiece/bed. Added
originMoveNeedsConfirm helper (unit-tested, 1mm margin) and a confirm dialog in
the goToWorkOrigin action that warns before a meaningful descent; small descents
proceed without prompting.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ollow-up)

Code review caught that marking ok:false on any superagent err included the
special 202/203 machine statuses that _getResult and the rest of the channel
treat as non-fatal. That could truncate modal sequences (G53/G28/G54 -> re-leak
G53) or cancel valid jobs on a transient busy reply. Now 202/203 resolve ok:true.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…provements

Curved-surface: Marlin laser G-code already emits per-move Z and the toolpath
JSON schema has an optional Z field, so Z-modulation is feasible as a JS
post-processing pass over the engine's flat toolpath (no closed-engine change).
Hard blocker documented: 10W laser has no height-sensing hardware, so the height
map must be imported or manually probed (camera/SACP grid parked).

Camera: A350/HTTP uses the image-getPhoto.js REST endpoints (not SACP); ranks
robustness fixes + job-framing overlay as highest value/effort, with
camera-focus height as a research spike that could later feed the height map.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… (regression)

The 04-F9 change added a break-on-first-failed-line in consumeGCodeQueue. Jog
gcode arrives with a leading newline, so split('\n') yields an empty first
element; POSTing the empty code errors, and the break then skipped the actual
G0 move -> X/Y/Z jog stopped working. Now blank lines are skipped and a failed
line no longer aborts the rest of the group (failure is still recorded so
startGcode's job-prep abort from 04-F9 keeps working).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…sition

Patching the locally-bundled MainToolbarAbPosition onto the imported ES module
namespace (Icons.X = ...) triggered a webpack-5 "export not found" warning (the
namespace is read-only) and was a no-op there, surfacing as a build-overlay
warning on every hot reload. Merge package icons + the local icon into a plain
object instead. Webpack-5 migration follow-up.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a "Fast homing (workspace clear)" toggle next to Home. When on, goHome
raises the firmware homing feedrate (M1028 S1 X80 Y80 Z25, mm/s; defaults are
XY50/Z10/B30), runs G28, then restores defaults (M1028 S1 X50 Y50 Z10). The slow
endstop bump is unaffected so accuracy is preserved. Threaded fastHome through
executeGcodeAutoHome -> MachineAgent.goHome -> ConnectionManager.goHome (HTTP
path; SACP path has a TODO). Validated live on an A350: full-travel home ~15.6s
at Z25 vs ~35-40s at the stock Z10.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a "Diagonal move (workspace clear)" toggle by Go To Work Origin. When on,
the head moves all axes at once in a single G0 (hypotenuse) for speed; when off
(default), Z is sequenced separately to avoid a diagonal bed plunge (audit R6).
sequenceGoToOrigin gains a `diagonal` arg (unit-tested); the R10 descend-below-Z
confirm still applies in both modes. Validated live: diagonal emits a single
"G0 X0 Y0 B0 Z0".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The firmware clamps every move to DEFAULT_MAX_FEEDRATE (X120 Y120 Z40 mm/s), so
the M1028 homing-feedrate bump only helps up to those ceilings — higher values
(e.g. Z80/Z150) are clamped to Z40 with no extra speed. Use the axis maxes for
the fastest safe fast-home (Z is also limited by its low 100 mm/s^2 accel).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
WinstonPoh and others added 4 commits June 20, 2026 17:59
True hold-to-jog needs a firmware change: neither SACP nor the HTTP screen API
exposes continuous-jog/move-cancel for XYZ; all host moves are discrete fire-and-
wait. Firmware has the infinity-move+abort-resync primitive but only for the E
axis. M410 quickstop is position-safe here. Best non-firmware option is streamed
small-step emulation (bounded 1-step overrun), better over USB-serial. Anti-flood
safety fix needed regardless.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Scopes the controller-firmware change (XYZ infinity-move/stop mirroring the
E-axis precedent, deadman + soft-endstop clamp) and analyses transports: only
USB-serial SACP can carry new jog opcodes reliably; SACP-TCP/UDP are gated by
the closed touchscreen relay (and off on this A350); HTTP can't stream;
WebSockets never reach the controller; "raw TCP serial" = an external bridge.
Recommends Phase 0 anti-flood safety fix now, firmware jog as opt-in USB feature.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… screen)

Scopes an ESP32 wired to controller USART1 (host serial, G-code) as a low-latency
Wi-Fi(raw TCP/WebSocket)->UART bridge that bypasses the closed touchscreen.
Grounded in firmware research: CAN ruled out (modules are peripherals; no motion
command), USART1 is the clean tap (firmware already parses G-code; M410 = position-
safe out-of-band stop), and the 10W laser's onboard ESP32/USART3 is precedent.
Key safety: ESP32 runs the deadman locally. Level A (G-code streaming, no firmware
change) then Level B (XYZ infinity-move custom M-codes). Transport: raw TCP/WS.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…on modals

Replace the inline checkboxes next to Home and Go To Work Origin with a per-action
confirmation modal that contains the toggle. Clicking Home now confirms ("Fast
homing (workspace clear)" inside); Go To Work Origin now always confirms
("Diagonal move (workspace clear)" inside) and folds the R10 descend-below-Z
warning into that same modal. Adds a reusable showConfirmWithCheckbox helper;
removes the inline toggle state/UI and the separate R10-only modal.

Co-Authored-By: Claude Opus 4.7 (1M context) <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.

1 participant