mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-08-05 09:07:39 +00:00
139 lines
5.9 KiB
Markdown
139 lines
5.9 KiB
Markdown
# Printing through printer agents
|
|
|
|
*Owns the send path: connection choices, preflight, upload, start, and the
|
|
two recovery flows. Defers filament mapping delivery to
|
|
[Filament synchronization](filament.md), which is a separate contract even
|
|
though it is applied at print time.*
|
|
|
|
This chapter describes the printer-agent send path. It is separate from
|
|
the older print-host implementation, even when both target Moonraker.
|
|
Keep the paths separate unless their contracts and failure handling can
|
|
be deliberately reconciled.
|
|
|
|
## Connection choices
|
|
|
|
Three connection paths are in use:
|
|
|
|
| Target | Connection path | Use |
|
|
| --- | --- | --- |
|
|
| Native Bambu | Custom TLS tunnel on port 6000 | Send and optional eMMC preflight |
|
|
| Bambu Python agent | Implicit FTPS on port 990 | Upload and Bambu preflight fallback |
|
|
| Moonraker family | HTTP | Upload and start print |
|
|
|
|
The Bambu connection paths are independent. Selecting one does not prove that
|
|
the other is available. The Moonraker agent uploads with a multipart
|
|
request to its `gcodes` storage and then starts the uploaded filename;
|
|
it does not reuse the legacy `Moonraker` print-host class.
|
|
|
|
## Bambu native tunnel
|
|
|
|
The native tunnel depends on the versioned networking DLL and its
|
|
file-transfer module. `InitFTModule()` is a single-owner initialization:
|
|
it rejects a second call. Any future shared initialization must therefore
|
|
be idempotent, while `BBLNetworkPlugin` remains the single teardown owner.
|
|
It must call `UnloadFTModule()` before freeing the DLL, otherwise the
|
|
module's function pointers can point into unloaded code.
|
|
|
|
There is currently an initialization gap: selecting a printer agent does
|
|
not initialize this module. It is initialized only when the
|
|
`installed_networking` option causes the native BBL network plugin to
|
|
initialize. Calls to the tunnel must continue to fail safely until that
|
|
path has initialized the module. The Send UI catches this failure and
|
|
reports an initialization error instead of letting an exception leave a
|
|
wx event handler.
|
|
|
|
## Bambu FTPS upload
|
|
|
|
The Python Bambu agent uses implicit FTPS on port 990. Its live upload
|
|
path closes the data connection, then waits at most two seconds for the
|
|
control response with `voidresp()`. A `TimeoutError` is accepted as a
|
|
completed transfer. An `error_reply` is also accepted when its reply
|
|
begins with `200`. This is the behavior to preserve.
|
|
|
|
Do not describe the path as using TLS `unwrap()`: the live construction
|
|
does not enable it. Enabling it without a bounded wait could hang while
|
|
waiting for the peer's TLS close notification. The current timeout-based
|
|
handling has not been verified on hardware against every printer and FTP
|
|
server combination.
|
|
|
|
## Print preflight and recovery
|
|
|
|
For normal LAN prints, `PrintJob` performs a preflight before the real
|
|
send. When eMMC is eligible it tries the native tunnel, then it sends a
|
|
small `verify_job` upload through the selected agent. The latter is a real
|
|
upload, not a special protocol command. Non-Bambu agents therefore upload
|
|
the probe too.
|
|
|
|
> **Do not re-enable eMMC by default** without hardware coverage for the
|
|
> affected devices. It is opt-in because the tunnel can hang during upload
|
|
> on some printers.
|
|
|
|
The whole send, including the thread hop and the recovery fork:
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant UI as Send UI (UI thread)
|
|
participant J as PrintJob (worker)
|
|
participant A as Selected IPrinterAgent
|
|
participant P as Printer
|
|
|
|
UI->>J: Start send
|
|
opt eMMC eligible - off by default
|
|
J->>P: Native Bambu tunnel attempt
|
|
Note over J,P: Can hang on some printers
|
|
end
|
|
J->>A: verify_job preflight
|
|
Note over J,A: A real upload, not a protocol probe -<br/>non-Bambu agents upload it too
|
|
A->>P: Upload probe
|
|
|
|
alt Preflight and upload succeed
|
|
J->>A: Upload the real job
|
|
A->>P: Upload, then request print start
|
|
Note over A,P: The start response may stay open while<br/>the printer prepares - a timeout is not<br/>proof of failure, so check reported print state
|
|
A-->>UI: Result from the reported print state
|
|
else Upload fails
|
|
J-->>UI: Failure callback, marshalled to the UI thread
|
|
Note over UI: Re-resolve the machine here.<br/>Never reuse a machine pointer captured<br/>on the worker - agent or machine may have changed
|
|
alt Printer still connected
|
|
UI->>UI: Explain that storage upload failed
|
|
else Printer disconnected
|
|
UI->>UI: Open the IP or access-code flow
|
|
end
|
|
end
|
|
```
|
|
|
|
An upload failure and a disconnected printer need different recovery:
|
|
|
|
| Condition | UI response |
|
|
| --- | --- |
|
|
| Printer is still connected | Explain that storage upload failed. |
|
|
| Printer is disconnected | Open the IP or access-code flow. |
|
|
|
|
> **Do not retain a machine pointer from a worker callback.** The callback
|
|
> that chooses between these two outcomes runs on the UI thread and
|
|
> re-resolves the machine there, because the selected agent or machine can
|
|
> change first. The connection check is adequate for choosing the message,
|
|
> but is not a strong enough signal to authorize a reconnect.
|
|
|
|
## Moonraker upload and start
|
|
|
|
`MoonrakerPrinterAgent` uploads through Moonraker HTTP, then requests the
|
|
print start separately. The start endpoint may keep its response open
|
|
while the printer prepares the job. A timeout after that request is not
|
|
automatically proof that the start failed: the agent checks the reported
|
|
print state before deciding the result.
|
|
|
|
The legacy print-host Moonraker path implements its own upload and start
|
|
logic. It is not the agent path and should not be changed as an implicit
|
|
side effect of agent work.
|
|
|
|
## Maintenance checklist
|
|
|
|
- Test the selected connection path, not just another path on the same
|
|
printer.
|
|
- Preserve cancellation and progress callbacks across upload and start.
|
|
- Treat `verify_job` as an actual upload when estimating storage effects.
|
|
- Keep eMMC opt-in until its hanging behavior is resolved and verified.
|
|
- Keep the connected-upload-failure dialog distinct from the disconnected
|
|
recovery flow.
|