拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

OctoPrint 虚拟打印机(Virtual Printer)开发调试完全指南:config.yaml 配置详解与 `!!DEBUG:` 调试命令速查

OctoPrint 虚拟打印机(Virtual Printer)开发调试完全指南:config.yaml 配置详解与 `!!DEBUG:` 调试命令速查 物联网后端【免费下载链接】OctoPrintOctoPrint is the snappy web interface for your 3D printer!项目地址https://gitcode.com/gh_mirrors/oc/OctoPrint点击查看免费下载本文以 OctoPrint 内置的 Virtual Printer 插件为核心系统讲解如何在不连接真实硬件的前提下调试 OctoPrint 的串口通信从启用方式、config.yaml全套配置项含默认值与源码级行为解析到终端里可直接触发的调试命令再到插件源码内部的队列/线程模型与工厂钩子实现。读完本文你将掌握用虚拟打印机复现固件怪癖、通信错误、SD 打印等边界场景的完整套路可直接用于插件开发与通信层调试。为什么需要一台虚拟打印机OctoPrint 的通信层octoprint.comm负责与真实打印机进行 G 代码收发、校验和与行号管理、重发resend协商、温度轮询等一系列复杂交互。在开发插件或排查通信问题时反复开关真实打印机既不现实也很危险——尤其是测试 M112 急停、断连、固件无响应这类破坏性场景。OctoPrint 从 2013 年的早期版本起就一直内置虚拟打印机能力自 OctoPrint 1.4.1 起被完整抽取为独立的 bundled 插件。根据 docs/bundledplugins/virtual_printer.rst 的描述它能够模拟多种固件怪癖Repetier、Smoothie、Klipper 风格的温度/应答行为模拟通信问题校验和错误、行号错乱、超时无响应通过config.yaml高度定制行为用于测试固件识别、重发逻辑、SD 打印等路径。该插件的实际定位在其元数据中写得很清楚Provides a virtual printer via a virtual serial port for development and testing purposes见 src/octoprint/plugins/virtual_printer/init.py。注意虚拟打印机虽然能模拟温度变化、移动耗时等物理行为但它的目的是调试 OctoPrint 的串口通信逻辑而不是替代真实打印机的机械运动验证。启用虚拟打印机启用方式有两种任选其一方式一界面设置。在 OctoPrint 的 Settings设置→ 插件面板中打开 Virtual Printer 的配置页。该页面只有一个开关Enable the virtual printer对应settings.plugins.virtual_printer.enabled键其模板源码位于 src/octoprint/plugins/virtual_printer/templates/virtual_printer_settings.jinja2帮助文本明确说明启用后会出现一个额外的串口VIRTUAL由假打印机实现支撑适用于开发调试。方式二config.yaml 配置。在config.yaml中写入plugins.virtual_printer.enabled: true详见下文完整配置示例。注意历史版本中该配置位于devel.virtualPrinter插件提供了从旧位置到plugins.virtual_printer的自动迁移逻辑见 src/octoprint/plugins/virtual_printer/init.py。启用后在 Connection连接面板的串口下拉列表中会出现名为VIRTUAL的额外端口。这是通过插件钩子octoprint.comm.transport.serial.additional_port_names注入的见 src/octoprint/plugins/virtual_printer/init.py只有当enabled为 true 时该端口才会出现在列表中。在 tests/playwright/specs/connect.spec.js 中OctoPrint 的端到端测试正是通过selectOption(VIRTUAL)完成连接/断开虚拟打印机的用例。虚拟打印机的底层实现端口、队列与线程在深入配置项之前先理解虚拟打印机的实现模型这有助于理解每个配置项的作用。插件的串口工厂钩子octoprint.comm.transport.serial.factory在端口名为VIRTUAL且插件已启用时会构造一个VirtualPrinter实例并交给 OctoPrint 的通信层见 src/octoprint/plugins/virtual_printer/init.py。也就是说对 OctoPrint 而言它就是一个普通的串口对象只是背后是纯软件模拟。核心类VirtualPrinter定义在 src/octoprint/plugins/virtual_printer/virtual.py它对外暴露了与 pyserial 一致的最小接口write、readline、close、timeout属性等内部则是一个精巧的模拟器incomingRX 缓冲区一个容量为rxBuffer字节的有界队列对应固件的串口接收缓冲区。当它被写满时write()会抛出SerialTimeoutException模拟真实串口的阻塞见 virtual.pybuffered命令缓冲区容量为commandBuffer条的队列用于模拟 Marlin 式的运动命令缓冲SD 打印线程把 G0/G1/G2/G3 送入该队列由_processBuffer线程按耗时模拟执行见 virtual.py 与 virtual.pyoutgoing输出队列readline()从中取行返回给 OctoPrint模拟固件回复两条后台线程wait_thread_processIncoming解析收到的命令并生成回复与buffer_thread_processBuffer消费运动缓冲在构造函数中启动见 virtual.py温度模拟每个处理周期调用_simulateTemps()让实际温度按剩余温差比例向目标/环境温度收敛见 virtual.py。理解了这套模型下面配置项的作用就一目了然了。config.yaml 完整配置参考以下配置位于config.yaml的plugins.virtual_printer键下。所有默认值以插件get_settings_defaults()的返回为准见 src/octoprint/plugins/virtual_printer/init.py并与官方文档 docs/development/virtual_printer.rst 交叉核对plugins: # Settings for the virtual printer virtual_printer: # 是否启用虚拟打印机并将其加入可用串口列表。默认 false enabled: true # 是否在 resend 请求之后额外发送一个 ok模仿 Repetier。默认 false okAfterResend: false # 是否强制通信必须携带校验和与行号模仿 Repetier。 # 为 true 时没有行号/校验和的命令会被拒绝并报错。默认 false forceChecksum: false # 是否在 ok 响应中附带被确认的行号。默认 false okWithLinenumber: false # 模拟的挤出机数量。默认 1 numExtruders: 1 # 将指定热端钉死在固定温度形如 {0: 200.0, 1: 210.0}。默认 null pinnedExtruders: null # M105 输出中是否额外包含当前工具温度段 T独立于 T0/T1...。 # true: M105 # ok T:23.5/0.0 T0:34.3/0.0 T1:23.5/0.0 B:43.2/0.0 # false: M105 # ok T0:34.3/0.0 T1:23.5/0.0 B:43.2/0.0 includeCurrentToolInTemps: true # M23 打开文件响应中是否包含文件名。 # true: M23 filename.gcode # File opened: filename.gcode Size: 27 # false: M23 filename.gcode # File opened includeFilenameInOpened: true # 是否模拟热床。默认 true hasBed: true # 是否模拟加热舱室。默认 false hasChamber: false # 是否以独立消息上报目标温度Repetier 风格。 # true: M109 S220.0 # TargetExtr0:220.0 # ok # M105 # ok T0:34.3 T1:23.5 B:43.2 # false: M109 S220.0 # ok # M105 # ok T0:34.3/220.0 T1:23.5/0.0 B:43.2/0.0 repetierStyleTargetTemperature: false # 是否采用 Repetier 风格的重发对同一行多次发送 resend。默认 false repetierStyleResends: false # 是否在命令输出之前发送 ok。 # true: M20 # ok # Begin file list # End file list # false: M20 # Begin file list # End file list # ok okBeforeCommandOutput: false # M105 响应中第一个挤出机是否以 T 而非 T0 上报Smoothie 风格。默认 false smoothieTemperatureReporting: false # Klipper 风格温度上报单挤出机时以 T0 而非 T 上报。默认 false源码新增项 klipperTemperatureReporting: false # 是否启用 reprapfw 风格 M114 坐标响应。默认 false源码新增项 reprapfwM114: false # SD 文件列表M20输出相关 sdFiles: # M20 响应是否包含文件大小。默认 true size: true # M20 响应是否包含时间戳仅当 sizetrue 时生效。默认 false timestamp: false # M20 响应是否包含长文件名仅当 sizetrue 时生效。默认 false longname: false # 长文件名是否加引号输出。默认 true longname_quoted: true # 是否以大写 DOS 文件名输出。默认 false upper_case: false # 从输出缓冲区取回数据的强制暂停间隔秒。默认 0.01 throttle: 0.01 # 当串口 RX 缓冲区为空时是否每隔 waitInterval 秒发送 wait。默认 false # 注意源码默认值为 true见 __init__.py get_settings_defaults sendWait: false # 发送 wait 行的间隔秒。默认 1 waitInterval: 1 # 模拟 RX 缓冲区大小字节。写满后 OctoPrint 侧的发送将阻塞。默认 64 rxBuffer: 64 # 模拟命令缓冲区容量条数。满时缓冲的命令将阻塞直到有空闲槽位。默认 4 commandBuffer: 4 # 是否支持 M112模拟 kill。默认 true supportM112: true # 是否把通过 M117 收到的消息以 echo: 行回显。默认 true echoOnM117: true # 是否模拟 M29 的残缺行为响应后缺失 ok。默认 true brokenM29: true # 是否模拟残缺的 resend 行为源码新增项。默认 false brokenResend: false # F 是否作为独立命令被支持。默认 false supportF: false # 上报的固件名称用于测试固件识别。默认 Virtual Marlin 1.0 firmwareName: Virtual Marlin 1.0 # 是否模拟共享喷嘴多个挤出机共享同一温度传感器。默认 false sharedNozzle: false # 忙处理时是否发送 busy 消息。默认 false sendBusy: false # 发送 busy 消息的间隔秒。默认 2.0 busyInterval: 2.0 # 是否在连接时模拟一次复位。默认 true simulateReset: true # 模拟复位时发送的行 resetLines: - start - Marlin: Virtual Marlin! - SD card ok # 源码默认还包含一个二进制字符 \x80 # 可用于测试通信层对非常规字节的处理 # 预置的 ok 响应池用于模拟发错的 ok也可在运行时通过 !!DEBUG:prepare_ok 填充。默认 [] preparedOks: [] # ok 响应的格式串。占位符 # lastN : 最后确认的行号 # buffer: 内部命令缓冲区空余槽位数 # 示例扩展 ok 格式: ok N{lastN} P{buffer} okFormatString: ok # M115 输出格式串。占位符 # firmware_name: firmwareName 定义的固件名 m115FormatString: FIRMWARE_NAME: {firmware_name} PROTOCOL_VERSION:1.0 # M115 输出是否包含能力报告。默认 true m115ReportCapabilities: true # 能力报告内容enabled 时生效 capabilities: AUTOREPORT_TEMP: true AUTOREPORT_SD_STATUS: true AUTOREPORT_POS: false BUSY_PROTOCOL: false CHAMBER_TEMPERATURE: false EMERGENCY_PARSER: true EXTENDED_M20: false LFN_WRITE: false # M115 输出是否包含打印区域几何报告对应 Marlin 的 M115_GEOMETRY_REPORT。默认 false m115ReportArea: false # M114 坐标输出格式串源码新增项 m114FormatString: X:{x} Y:{y} Z:{z} E:{e[current]} Count: A:{a} B:{b} C:{c} # 模拟环境温度°C。默认 21.3 ambientTemperature: 21.3 # 存在目标温度时 M105 的响应格式。占位符 # heater: 加热器 id如 T0、T1、B # actual: 加热器实际温度 # target: 加热器目标温度 m105TargetFormatString: {heater}:{actual:.2f}/ {target:.2f} # 无目标温度时 M105 的响应格式。占位符同上无 target m105NoTargetFormatString: {heater}:{actual:.2f} # M123 风扇 RPM 响应格式。占位符 # fan: 风扇 id如 E0 # rpm: 风扇转速 m123RPMFormatString: {fan}:{rpm} RPM # M123 风扇功率响应格式。占位符 # fan: 风扇 id # power: 风扇功率等级 m123PowerFormatString: {fan}:{power} # 虚拟风扇的最高转速RPM。默认 4560 fanMaxSpeed: 4560 # 是否启用虚拟 EEPROM。启用后在插件数据目录生成 eeprom.json # 使设置跨连接持久化并支持 M500/M501/M502/M504 等设置命令 # 响应风格参照 Marlin 2.0。默认 true enable_eeprom: true # 是否支持 M503。默认 true support_m503: true # 模拟线路噪声的重发比例百分比。默认 0 resend_ratio: 0 # 在指定行号上模拟通信错误每项格式为 行号:错误类型 # 100:resend 在第 100 行请求一次简单重发 # 105:resend_with_timeout 在第 105 行请求重发并模拟超时无响应 # 110:missing_lineno 在第 110 行模拟缺失行号 # 115:checksum_mismatch 在第 115 行模拟校验和不匹配 simulated_errors: - 100:resend - 105:resend_with_timeout - 110:missing_lineno - 115:checksum_mismatch配置项的源码级行为解读以下几个配置项的行为值得结合源码细看因为它们直接影响通信层的判定路径forceChecksum/ 校验和与行号解析。在_processIncoming中收到含*的行会先剥离校验和并比对不匹配则直接触发 resend当行以N开头时按lastN 1校验行号而如果行既不带校验和、forceChecksum又为 true则发送Error: Missing checksum并丢弃该行见 virtual.py。这可以精确测试 OctoPrint 通信层在强制校验模式下的行为。simulated_errors的实现与上述解析深度耦合只有携带行号N开头且行号恰好命中配置值的命令才会触发对应错误动作且每个行号只触发一次_already_simulated_errors去重M110 重置行号时会清空已触发记录见 virtual.py。四种错误类型的含义与官方文档 docs/development/virtual_printer.rst 中给出的示例完全一致。resend_ratio内部换算为_resend_every_n 100 // resend_ratio即每收到n行触发一次带校验和错误的 resend用于模拟线路噪声导致的行丢失见 virtual.py 与 virtual.py。okFormatString与preparedOks_ok()每次回复时优先从preparedOks弹出预置的错误 ok否则用okFormatString格式化占位符lastN为最后确认行号、buffer为命令缓冲区空余槽位见 virtual.py。用ok N{lastN} P{buffer}即可模拟扩展 ok格式测试 OctoPrint 对这类固件的兼容性。pinnedExtruders与ambientTemperature_simulateTemps()在每轮模拟中若热端 id 命中pinnedExtruders则直接固定为该温度否则按与目标/环境温度的差值比例逼近见 virtual.py。注意目标为 0 时温度会回落向ambientTemperature因此该参数决定了加热关闭后冷却的基准值。enable_eeprom/ 虚拟 EEPROM启用后会在插件数据目录get_plugin_data_folder()创建eeprom.json首次启动写入默认设置后续启动读取从而跨连接持久化 M500 系列写入的值。EEPROM 默认设置模拟 Marlin 2.0 风格steps、feedrate、max_accel 等定义在VirtualEEPROM.get_default_settings()见 virtual.py 及后续行。两点官方文档与源码默认值的差异以源码为准文档示例中sendWait: false而源码默认值为true文档的capabilities示例重复列出了两次AUTOREPORT_TEMP实际源码能力集还包含BUSY_PROTOCOL、CHAMBER_TEMPERATURE文档中m123RPMFormatString出现两次第二个实际是m123PowerFormatString。配置时建议以本文表格源码核对版为准。日志文件启用后虚拟打印机会把所有串口通信写入plugin_virtual_printer_serial.log位于 OctoPrint 的日志文件夹logs 目录中。该日志由CleaningTimedRotatingFileHandler按天轮转、保留 3 份备份格式为时间戳 消息见 src/octoprint/plugins/virtual_printer/init.py。日志中每行通过标记 OctoPrint 发送给打印机的数据write()方向、通过标记打印机回复的数据readline()方向是排查OctoPrint 到底发了什么、固件回了什么的第一手证据。配合 OctoPrint 的日志下载功能可以把该文件一并打包用于问题复现。终端调试命令!!DEBUG:虚拟打印机最强的调试手段是通过 OctoPrint 的 Terminal终端标签页直接触发各种边界条件。所有命令以!!DEBUG:开头例如发送!!DEBUG:action_disconnect会立即触发// action:disconnect让打印机断开。只发送!!DEBUG不带命令会回显完整的帮助信息。以下是帮助文本中列出的全部命令与 src/octoprint/plugins/virtual_printer/virtual.py 中的_debugTrigger帮助文本一致并补充了帮助文本未完整列出但源码已实现的部分OctoPrint Virtual Printer debug commands help ? | This help. # Action Triggers动作触发 action_pause | 向主机发送 // action:pause 动作触发。 action_resume | 向主机发送 // action:resume 动作触发。 action_disconnect | 向主机发送 // action:disconnect 动作触发。 action_custom action[ parameters] | 向主机发送自定义 // action:action parameters 动作触发。 # Communication Errors通信错误模拟 dont_answer | 不确认下一条命令。 go_awol | 完全停止回复对应源码 _debug_awolwrite/readline 直接静默。 trigger_resend_lineno | 触发一次行号不匹配的 resend 错误。 trigger_resend_checksum | 触发一次校验和不匹配的 resend 错误。 trigger_missing_checksum | 触发一次缺失校验和的 resend 错误。 trigger_missing_lineno | 触发一次带校验和却无行号的错误不请求 resend。 trigger_fatal_error_marlin | 触发一次 Marlin 风格的致命错误/模拟加热失败。 trigger_fatal_error_repetier | 触发一次 Repetier 风格的致命错误/模拟加热失败。 drop_connection | 断开串口连接后续 write/readline 抛 SerialTimeoutException。 prepare_ok broken ok | 将 broken ok 入队后续用它替代真正的 ok。 rerequest_last | 对最后一行 1 无限请求重发。 resend_ratio int:percentage | 将重发比例设为给定百分比0-100模拟线路噪声设为 0 关闭。 toggle_klipper_connection | 切换 Klipper 连接状态关闭后对所有命令回复 !! Lost communication with MCU mcu。 # Reply Timing / Sleeping回复时机与睡眠 sleep int:seconds | 睡眠 seconds 秒。 sleep_after str:command int:seconds | 每次执行 command 后睡眠 seconds 秒。 sleep_after_next str:command int:seconds | 下一次执行 command 后睡眠 seconds 秒。 # SD printingSD 打印 start_sd str:file | 从 SD 中选择并开始打印文件 file。 select_sd str:file | 从 SD 中选择文件 file暂不开始打印用 start_sd 开始。 cancel_sd | 取消正在进行的 SD 打印。 # Misc其他 send str:message | 向主机回发 message。 reset | 模拟复位内部状态将丢失对应 _reset()会清空队列与调试标志。 unbusy | 退出 busy 循环。 set_ambient 温度 | 动态设置环境温度源码实现帮助文本未列出。 mintemp_error | 发送 MINTEMP 错误源码实现帮助文本未列出。 maxtemp_error | 发送 MAXTEMP 错误源码实现帮助文本未列出。调试命令的典型使用场景测试超时/无响应路径go_awol或dont_answer可用于验证 OctoPrint 的 read timeout 处理、连接监控和打印机无响应告警逻辑。源码中_debug_awol会让write()静默吞掉数据、readline()睡眠一个 read timeout 后返回空行见 virtual.py与真实固件挂死行为一致。测试重发协商trigger_resend_lineno、trigger_resend_checksum、rerequest_last、resend_ratio分别覆盖行号错乱、校验和错误、无限重发、随机噪声四种重发场景是验证 OctoPrint 通信层重发逻辑是否健壮的标准手段。测试动作钩子action_pause/action_resume/action_disconnect/action_custom触发// action:前缀的动作可验证 OctoPrint 的动作命令处理与依赖它的插件行为。测试 SD 打印链路start_sd/select_sd/cancel_sd配合虚拟 SD 卡文件夹virtualSd基础目录可以不走 OctoPrint 的上传/打印路径而直接从固件侧发起 SD 打印测试 SD 状态轮询M27、暂停/恢复M25/M24等交互。测试温度报告set_ambient、mintemp_error、maxtemp_error可用于验证温度告警与错误恢复逻辑。这些命令的解析入口在_processIncoming中凡是以!!DEBUG:开头或恰好为!!DEBUG的行都会被路由到_debugTrigger()不会进入正常的命令处理见 virtual.py。参数型命令如sleep、action_custom、prepare_ok、send、set_ambient、start_sd、select_sd、resend_ratio通过类级预编译正则匹配定义在 virtual.py。从源码看插件的可扩展性虚拟打印机插件本身还预留了扩展点它注册了钩子octoprint.plugin.virtual_printer.custom_action允许其他插件自定义!!DEBUG:action_custom的动作行为见 virtual.py。这意味着你可以在自己的插件中实现octoprint.plugin.virtual_printer.custom_action钩子为调试注入完全自定义的固件行为。小结与上手路线虚拟打印机是 OctoPrint 通信层开发调试的沙盒。推荐的上手路线在设置面板勾选启用或写入plugins.virtual_printer.enabled: true在连接面板选择VIRTUAL端口连接观察 Terminal 中的握手与温度轮询打开plugin_virtual_printer_serial.log建立/双向通信日志的阅读习惯按需在config.yaml中调整simulated_errors、resend_ratio、forceChecksum等参数复现目标 bug在 Terminal 中使用!!DEBUG:命令动态注入故障配合!!DEBUG查看完整命令帮助结合 tests/playwright/specs/connect.spec.js 的端到端用例思路把关键场景固化为自动化测试。进一步阅读插件的用户视角说明见 docs/bundledplugins/virtual_printer.rst完整源码位于 src/octoprint/plugins/virtual_printer/配置项默认值可直接查阅 src/octoprint/plugins/virtual_printer/init.py。赞分享物联网后端【免费下载链接】OctoPrintOctoPrint is the snappy web interface for your 3D printer!项目地址https://gitcode.com/gh_mirrors/oc/OctoPrint点击查看免费下载相关推荐OctoPrint虚拟打印机配置与调试指南OctoPrint虚拟打印机配置与调试指南 虚拟打印机简介 OctoPrint内置了一个强大的虚拟打印机插件这个工具对于开发者调试串口通信功能特别有用。它能够物联网后端Virtual ZPL Printer虚拟标签打印机完全使用指南Virtual ZPL Printer是一款基于以太网的虚拟斑马标签打印机专为测试条形码标签应用程序而设计。它利用Labelary服务让您无需物理打印机就能开发工具后端Fixed-Data-Table-2如何用React构建处理百万级数据的高性能表格组件Fixed Data Table 2如何用React构建处理百万级数据的高性能表格组件 在当今数据驱动的应用开发中处理大规模数据集是每个前端开发者面临的共同上一篇终极Reor本地AI笔记应用优化指南监控资源使用与提升性能的7个实用技巧下一篇如何快速掌握Leela Zero从零开始构建围棋AI的完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表