Measured against a real machine (X2D / PF004-P, firmware as shipped, LAN Mode on) during Phase 0. This is the specification the Phase 3 driver is built from, and the reason it will not be guesswork.
Status: telemetry and control proven. File transfer proven at the transport level; the write itself is pending storage in the test machine.
Bambu printers broadcast on these ports. In our environment nothing was heard in 45 s (port 2021 could not even be bound — Windows reserves it), so discovery is optional and must never be a prerequisite. A printer is perfectly usable when its IP is known.
Phase 3: treat discovery as a convenience for adding printers, never as the source of truth for whether a printer exists.
- username
bblp, password is the LAN access code, self-signed certificate (CERT_NONE— the access code is the authentication factor) - subscribe
device/<serial>/report, publish todevice/<serial>/request {"pushing": {"sequence_id": "1", "command": "pushall"}}triggers a full state dump
Fields that map onto drivers.base.Telemetry:
| MQTT field | Meaning |
|---|---|
gcode_state |
FINISH, RUNNING, PAUSE, FAILED, IDLE |
mc_percent |
progress 0–100 |
layer_num / total_layer_num |
layer counters |
mc_remaining_time |
minutes remaining |
nozzle_temper / bed_temper |
temperatures |
ams.ams[].tray[] |
per-slot tray_type and tray_color |
FINISHis not "available". The machine reported 100%, 785/785 layers, nozzle cooled to 29 °C — numerically indistinguishable from idle, with the finished part still on the bed.PrinterState.accepts_jobis therefore true forIDLEonly.FINISHEDclears toIDLEwhen a human removes the part.tray_coloris 8-char RGBA (FFFFFFFF), not#RRGGBB. The driver must convert.subtask_nameis the print profile, not a filename — the observed value was"0.2mm layer, 2 walls, 15% infill". It cannot be used to correlate a running print back to a job; Phase 3 needs its own correlation key.
Transport proven: TLS handshake, bblp login, PROT P, and data channels all work.
The server is vsftpd 3.0.5, SYST = UNIX Type: L8, features include EPSV,
PASV, SIZE, MDTM, REST STREAM, TVFS, UTF8. Login lands at /.
vsftpd defaults to require_ssl_reuse=YES — the data connection must resume the
control connection's TLS session. Python's ftplib negotiates a fresh session, so
without a fix every LIST returns empty and every STOR fails with
553 Could not create file, a message that points at file permissions when the cause
is the TLS handshake.
The fix, in tools/bambu_ftps.py and required in the Phase 3 driver:
def ntransfercmd(self, cmd, rest=None):
conn, size = ftplib.FTP.ntransfercmd(self, cmd, rest)
if self._prot_p:
conn = self.context.wrap_socket(
conn, server_hostname=self.host, session=self.sock.session
)
return conn, sizePort 990 is implicit TLS — the socket is wrapped from the first byte, which stdlib
FTP_TLS does not do. Both overrides are needed.
With no card inserted, the filesystem is an empty read-only root:
LIST /→ 0 lines, no errorCWDinto/cache,/model,/data,/sdcard,/mnt,/usb, … → all550 Failed to change directorySTORanywhere →553 Could not create file
This is expected: on these machines FTP serves the removable storage. The remaining
verification is a single upload run with a card or USB drive inserted.
Product consequence, already encoded: a printer with no writable storage connects,
authenticates and reports telemetry perfectly, then fails only at dispatch. That is
DriverStorageError (error.driver.storage_unavailable) — distinct from "rejected"
and "unreachable", because the remedy is physical and an operator needs to be told
which machine to walk to. Such a printer must never be counted as available capacity.
A capture during a Bambu Studio session showed 322, 990 and 6000 open to the printer. 6000 is the chamber camera stream. 322 is a Bambu control channel we have not characterised — worth investigating in Phase 3 if 990 ever proves insufficient.
| Capability | Status |
|---|---|
| Connect + authenticate | proven |
| Live telemetry, progress, temperatures | proven |
| AMS slot → material mapping | proven |
| Normalized state machine | proven, and corrected by real data |
| FTPS transport incl. TLS session reuse | proven |
| Plate upload | pending storage in the test machine |
project_file dispatch command |
untested |
No evidence was found of firmware-level blocking of third-party LAN control. Every failure encountered was mundane and explained: a Windows port reservation, a vsftpd TLS requirement, and an absent storage device.