UNPKG

@hiv3d/bambu-node

Version:

A node.js library for connecting to and receiving data from Bambu Lab printers through their MQTT servers.

1,586 lines (1,555 loc) 63.5 kB
import * as mqtt from 'mqtt'; import { MqttClient } from 'mqtt'; import * as events from 'eventemitter3'; type State = "pause" | "resume" | "stop"; declare class UpdateStateCommand extends AbstractCommand { category: CommandInterface["category"]; command: CommandInterface["command"]; /** * Constructs a `print.print_speed` command, which is able to change the state of the printer, aka stop, resume or pause it. * @param state {State} The new state of the printer. */ constructor({ state }: { state: State; }); ownsResponse: typeof isUpdateStateCommand; } type PrintMessageCommands = "push_status" | "ams_control" | State | "gcode_line" | "gcode_file" | "project_file"; type PrintMessageCommand = { command: PrintMessageCommands; param?: string; sequence_id: string; }; interface PrintMessage { print: PrintMessageCommand; } declare function isPrintMessage(data: any): data is PrintMessage; interface GCodeFileResponse extends PrintMessageCommand { command: "gcode_file"; param: `${string}.code`; reason: "SUCCESS" | "FAILURE" | string; result: "SUCCESS" | "FAILURE" | string; sequence_id: StringNumber; } declare function isGcodeFileCommand(data: PrintMessageCommand): data is GCodeFileResponse; interface GCodeLineResponse extends PrintMessageCommand { command: "gcode_line"; reason: "SUCCESS" | "FAILURE" | string; result: "SUCCESS" | "FAILURE" | string; return_code: StringNumber; sequence_id: StringNumber; } declare function isGCodeLineCommand(data: PrintMessageCommand): data is GCodeLineResponse; interface ProjectFileResponse extends PrintMessageCommand { command: "project_file"; /** * The location of the project file. */ param: `Metadata/${string}.gcode`; reason: "SUCCESS" | "FAILURE" | string; result: "SUCCESS" | "FAILURE" | string; sequence_id: StringNumber; subtask_name: `${number}.3mf`; } declare function isProjectFileCommand(data: PrintMessageCommand): data is ProjectFileResponse; interface PushStatusResponse extends Partial<PushAllResponse> { command: "push_status"; sequence_id: StringNumber; } declare function isPushStatusCommand(data: PrintMessageCommand): data is PushStatusResponse; /** * Reports all sensors and statuses of the printer. */ interface PushAllResponse extends PrintMessageCommand { /** * Status of all connected AMSes. */ ams: { ams: [] | [AMS] | [AMS, AMS] | [AMS, AMS, AMS] | [AMS, AMS, AMS, AMS]; /** * Unknown. * * Probably used for checking for new AMSes. */ ams_exist_bits: StringNumber; /** * Unknown. * * Could possibly be related to storing whether the filament's data has been read from the AMSes. */ insert_flag: boolean; /** * Exact definition is unknown, but it appears to be used for checking if all filaments have been read since startup or not. */ power_on_flag: boolean; /** * Unknown. * * Probably used for checking for new AMSes. */ tray_exist_bits: StringNumber; /** * Unknown. * * Probably used for checking for new AMSes. */ tray_is_bbl_bits: StringNumber; /** * Current tray selected by all AMSes. * - 254: external spool (vt_tray) * - otherwise: ((ams_id * 4) + tray_id) for current tray * * @example Ams 2 tray 2 would be: (1*4)+1 = 5. */ tray_now: StringNumber; /** * Unknown. * * Probably used for checking which filament slots (trays) have already been read. */ tray_read_done_bits: StringNumber; /** * Unknown. * * Probably used for signalling which filament slots (trays) are currently being read. */ tray_reading_bits: StringNumber; /** * Unknown. Bambu Studio appears to do nothing with it. */ tray_tar: StringNumber; /** * Unknown. * * Could possibly be related to the AMS UI on the X1 series and in Bambu Studio. */ version: number; }; /** * The RFID reader status of the connected AMSes. */ ams_rfid_status: AmsRFIDStatus; /** * The AMS status. * * How to extract it: https://github.com/bambulab/BambuStudio/blob/f96b6cd433cf925e9759260925cd2142abf298ef/src/slic3r/GUI/DeviceManager.cpp#L736-L759 * * TODO: Extract when received from printer / provide helper function to do so. */ ams_status: number; /** * The target temperature of the printing bed in Celsius. */ bed_target_temper: number; /** * The temperature of the printing bed in Celsius. */ bed_temper: number; /** * Speed of the auxiliary fan in %. */ big_fan1_speed: StringNumberRange<0, 100>; /** * Speed of the chamber fan in %. */ big_fan2_speed: StringNumberRange<0, 100>; /** * Interior chamber temperature. */ chamber_temper: number; /** * The interior chamber's target temperature. * * Exists on the X1 series but only used on the X1E. */ ctt: number; /** * `chamber_temper` doesn't make sense on P1 series (due to it not being enclosed * by default) hence the `frame_temper` property. * * Even though `chamber_temper` exists, there is no physical sensor for it, but it is still included for some reason. * * The value of `chamber_temper` on the P1 series is a placeholder. */ frame_temper: number; /** * The command the response corresponds to. */ command: "push_status"; /** * Speed of the part cooling fan in %. */ cooling_fan_speed: StringNumberRange<0, 100>; /** * Unknown. Bambu Studio doesn't even check for it. */ fail_reason: StringNumber; /** * Array of filament backup groups. Each number is a bitmap where each bit represents * an AMS slot that can be used as backup for that filament group. Compatible slots * (same filament type and color) are grouped together. * * For example, if slots 0 and 4 contain the same filament type and color, * they would be in the same group with bitmap value 17 (binary: 0001 0001). */ filam_bak: number[]; /** * Contains the current speed of all the fans * * How to extract it: https://github.com/bambulab/BambuStudio/blob/master/src/slic3r/GUI/DeviceManager.cpp#L3273-L3279 * * TODO: Extract when received from printer / provide helper function to do so. */ fan_gear: number; /** * Something related to the firmware upgrades. */ force_upgrade: boolean; /** * Name of the GCode file that is currently printing. * * In most cases it's in the format "/plate_#.gcode", unless printing a * gcode file directly (bbl.gcode, or calibration gcodes) instead of a 3mf. */ gcode_file: string; /** * % of GCode prepared (sliced?) */ gcode_file_prepare_percent: StringNumberRange<0, 100>; /** * Epoch time when the print started. */ gcode_start_time: StringNumber; /** * The current status of the printer. */ gcode_state: PrinterStatus; /** * Fan speed in % * * Heat break fan: The smaller fan on the hotend itself */ heatbreak_fan_speed: StringNumberRange<0, 100>; /** * Bambu Lab's proprietary Health Management System (HMS) * * More info: https://wiki.bambulab.com/en/x1/troubleshooting/intro-hms * * All error codes: https://wiki.bambulab.com/en/hms/home */ hms: HMS[]; /** * This single property houses a lot of data regarding the printer. * There's currently no documentation for it except Bambu Studio's source code: * * - Check if axes are homed: https://github.com/bambulab/BambuStudio/blob/master/src/slic3r/GUI/DeviceManager.cpp#L1255-L1269 * - Check if printer is using 220V: https://github.com/bambulab/BambuStudio/blob/master/src/slic3r/GUI/DeviceManager.cpp#L1346-L1351 * - Check if camera is currently recording: https://github.com/bambulab/BambuStudio/blob/master/src/slic3r/GUI/DeviceManager.cpp#L1353 * - Check if AI camera detected filament entanglement: https://github.com/bambulab/BambuStudio/blob/master/src/slic3r/GUI/DeviceManager.cpp#L1368 * - Check if motor noise cancellation has been calibrated: https://github.com/bambulab/BambuStudio/blob/master/src/slic3r/GUI/DeviceManager.cpp#L1376-L1378 * - Check if the current machine is a P1P and has the enclosure enabled: https://github.com/bambulab/BambuStudio/blob/master/src/slic3r/GUI/DeviceManager.cpp#L1380-L1387 * - Check current SD card state (has a lot more info than the sdcard property): https://github.com/bambulab/BambuStudio/blob/master/src/slic3r/GUI/DeviceManager.cpp#L1389 * - Check if printer is using wired network (ethernet; X1E exclusive): https://github.com/bambulab/BambuStudio/blob/master/src/slic3r/GUI/DeviceManager.cpp#L1391 */ home_flag: number; hw_switch_state: number; /** * The printer's onboard camera. */ ipcam: { /** * The IP and path to the LAN liveview, otherwise disabled. * @version X1 series exclusive */ liveview: string | "disable"; /** * Unknown. Bambu Studio doesn't even check for it. */ tukt_server: string; /** * 0: Doesn't have camera * 1: Has camera */ ipcam_dev: StringNumberRange<0, 1>; /** * Whether recording while printing is enabled. */ ipcam_record: "enable" | "disable"; /** * Unknown. Bambu Studio doesn't even check for it. */ mode_bits: 3; /** * The camera's resolution * * The value is known to be very weird on the A1 series. */ resolution: "720p" | "1080p" | string; /** * Whether creating a timelapse while printing is enabled. */ timelapse: "enable" | "disable"; }; /** * Current layer number while printing. */ layer_num: number; /** * Probably to differentiate between in-house prototypes and production machines. */ lifecycle: "product" | "engineer"; /** * Internal light states */ lights_report: LightReport[]; /** * Unknown. Bambu Studio doesn't even check for it. */ maintain: number; /** * % of print done */ mc_percent: NumberRange<0, 100>; /** * Unknown. Bambu Studio appears to do nothing with it. * * Perhaps the current GCode line while printing? */ mc_print_line_number: StringNumber; /** * Unknown. Bambu Studio appears to do nothing with it. */ mc_print_error_code: "0" | StringNumber; /** * Something to do with signalling if calibration is done according to source code * * https://github.com/bambulab/BambuStudio/blob/master/src/slic3r/GUI/DeviceManager.cpp#L1331-L1342 */ mc_print_stage: StringNumberRange<1, 3>; /** * Unknown. Bambu Studio appears to do nothing with it. */ mc_print_sub_stage: number; /** * Remaining time from print. */ mc_remaining_time: number; /** * Probably to differentiate between in-house prototypes and production machines */ mess_production_state: "active" | "inactive"; /** * - 0: Full (pushAll) message * - 1: Partial (pushStatus) "difference" message (only changed properties are sent) * * @deprecated Unavailable on the X1 series in LAN mode. * * You can instead use isPushAllCommand or isPushStatusCommand from /responses or create a new PushAllCommand and PushStatus command from /commands and use their ownsResponse method for consistency. */ msg: NumberRange<0, 1>; /** * The target temperature of the nozzle in Celsius. */ nozzle_target_temper: number; /** * The temperature of the nozzle in Celsius. */ nozzle_temper: number; /** * Signals the status of some components of the printer and/or accessories. */ online: { /** * Unknown. */ ahb: boolean; /** * The RFID reader. */ rfid: boolean; /** * Unknown. */ version: number; }; /** * Unknown. Some error code standard which isn't defined in Bambu Studio. * * These codes can be cleared using `system.clean_print_error` command. */ print_error: number; /** * Unknown. Bambu Studio doesn't even check for it. */ print_gcode_action: number; /** * Unknown. Bambu Studio doesn't even check for it. */ print_real_action: number; /** * Where the print originates from. */ print_type: "cloud" | "system" | "local" | "idle"; /** * Unknown. Something related to what's being printed. */ profile_id: StringNumber; /** * Unknown. Something related to what's being printed. */ project_id: StringNumber; /** * Unknown. Something related to a print queue. (?) */ queue_est: number; /** * Unknown. Something related to a print queue. (?) */ queue_number: number; /** * Unknown. Something related to a print queue. (?) */ queue_sts: number; /** * Unknown. Something related to a print queue. (?) */ queue_total: number; /** * Objects that have been skipped by the printer while printing, */ s_obj: unknown[]; /** * Whether the SD card is inserted. */ sdcard: boolean; /** * Related to general MQTT commands on all Bambu Lab printers. Incremented by one each response/request. */ sequence_id: StringNumber; /** * The current speed level. */ spd_lvl: SpeedLevel; /** * The current speed level in %. */ spd_mag: NumberRange<50, 166>; /** * An x (unknown) amount of previous stages. */ stg: PrintStage[]; /** * The current print stage. */ stg_cur: PrintStage; /** * Main purpose is unknown. * - 0: printing from SD card */ subtask_id: StringNumber; /** * The name of the calibration gcode (without file extension), or the project file name (.3mf - with file extension) */ subtask_name: string; /** * Unknown. Bambu Studio appears to do nothing with it. */ task_id: StringNumber; /** * Total layer number of the current job. */ total_layer_num: number; /** * Firmware upgrade status data of the printer. */ upgrade_state: { /** * Unknown. * * Some component's new version number. */ ahb_new_version_number: string; /** * The new version number of the AMS(es). */ ams_new_version_number: string; /** * Unknown. Bambu Studio appears to do nothing with it. */ consistency_request: boolean; /** * What the display should say in the process. */ dis_state: UpgradeDisplayState; /** * Error codes thrown by the upgrade. */ err_code: UpgradeErrorCode; /** * Unknown. Bambu Studio appears to do nothing with it. * * Probably has something to do with an update the user can't deny. (for ex.: security vulnerabilities) */ force_upgrade: boolean; /** * Unknown. Bambu Studio appears to do nothing with it. */ message: string; /** * Unknown. Bambu Studio appears to do nothing with it. */ module: string; /** * Unknown. Bambu Studio appears to do nothing with it. */ new_ver_list: string; /** * Unknown. Bambu Studio appears to do nothing with it. */ new_version_state: number; /** * Unknown. Bambu Studio appears to do nothing with it. */ ota_new_version_number: string; /** * The progress of the update in %. */ progress: StringNumberRange<0, 100>; /** * Incremented by one every time a new status is returned. */ sequence_id: number; /** * The progress / finish states of the upgrade. */ status: UpgradeStatusProgressState & UpgradeStatusFinishState; }; /** * Print file download status data. */ upload: { /** * Downloaded file size (?) */ file_size: number; /** * Total file size (?) */ finish_size: number; /** * Unknown. Bambu Studio doesn't even check for it. */ message: string; /** * Unknown. Bambu Studio doesn't even check for it. */ oss_url: string; /** * The progress of the file download in %. */ progress: StringNumberRange<0, 100>; /** * Incremented by one every time a new status is returned. */ sequence_id: StringNumber; /** * Download speed in unknown units. */ speed: number; /** * Unknown. Bambu Studio doesn't even check for it. */ status: "idle" | string; /** * Unknown. Bambu Studio doesn't even check for it. */ task_id: string; /** * Time remaining until download completes in unknown units. */ time_remaining: number; /** * Unknown. Bambu Studio doesn't even check for it. * * Probably some kind of error code. */ trouble_id: string; }; /** * External spool (tray). This has unused values due to being a copy of the AMS trays. */ vt_tray: ExternalTray; /** * The signal strength of the Wi-Fi signal which the printer is connected to in dBm. */ wifi_signal: `-${number}dBm`; /** * AI-related features of the printer's camera. */ xcam: { /** * Whether skipping parts setting is enabled. */ allow_skip_parts: boolean; /** * Whether the printer should detect the correct orientation and type of the buildplate. */ buildplate_marker_detector: boolean; /** * Whether the first layer inspection is enabled for the printer. */ first_layer_inspector: boolean; /** * Whether the printer is allowed to stop the print in the event it detects an abnormality. */ print_halt: boolean; /** * The sensitivity for the spaghetti detector, first layer inspection, etc. */ halt_print_sensitivity: "low" | "medium" | "high"; /** * Whether print monitoring is enabled. */ printing_monitor: boolean; /** * Whether the spaghetti detector is enabled. */ spaghetti_detector: boolean; }; /** * AI-related features' status. */ xcam_status: StringNumber; } type PrinterStatus = "FINISH" | "FAILED" | "RUNNING" | "IDLE" | "PAUSE" | "PREPARE" | "SLICING"; /** * Detailed information about a print stage */ interface PrintStageInfo { /** The current stage of printing */ stage: PrintStage; /** Progress percentage within the current stage (0-100) */ progress: number; /** Human-readable name of the stage */ name: string; /** Detailed description of what's happening in this stage */ description: string; /** Whether this stage can be controlled (paused/resumed/skipped) */ controllable: boolean; /** Whether this stage is critical for print success */ critical: boolean; /** Estimated time remaining in this stage (seconds) */ timeRemaining?: number; } /** * Every stage of a print. * Extracted from https://github.com/bambulab/BambuStudio/blob/master/src/slic3r/GUI/DeviceManager.cpp */ declare enum PrintStage { "PRINTING" = "Printing", "BED_LEVELING" = "Auto bed leveling", "HEATBED_PREHEATING" = "Heatbed preheating", "XY_MECH_MODE_SWEEP" = "Sweeping XY mech mode", "CHANGE_MATERIAL" = "Changing filament", "M400_PAUSE" = "M400 pause", "FILAMENT_RUNOUT_PAUSE" = "Paused due to filament runout", "HOTEND_HEATING" = "Heating hotend", "EXTRUDE_COMPENSATION_SCAN" = "Calibrating extrusion", "BED_SCAN" = "Scanning bed surface", "FIRST_LAYER_SCAN" = "Inspecting first layer", "BE_SURFACE_TYPT_IDENTIFICATION" = "Identifying build plate type", "SCANNER_EXTRINSIC_PARA_CALI" = "Calibrating Micro Lidar", "TOOLHEAD_HOMING" = "Homing toolhead", "NOZZLE_TIP_CLEANING" = "Cleaning nozzle tip", "EXTRUDER_TEMP_PROTECT_CALI" = "Checking extruder temperature", "USER_PAUSE" = "Printing was paused by the user", "TOOLHEAD_SHELL_OFF_PAUSE" = "Pause of front cover falling", "SCANNER_LASER_PARA_CALI" = "Calibrating the micro lida", "EXTRUDER_ABSOLUTE_FLOW_CALI" = "Calibrating extrusion flow", "HOTEND_TEMPERATURE_ERROR_PAUSE" = "Paused due to nozzle temperature malfunction", "HEATED_BED_TEMPERATURE_ERROR_PAUSE" = "Paused due to heat bed temperature malfunction", "FILAMENT_UNLOADING" = "Filament unloading", "SKIP_STEP_PAUSE" = "Skip step pause", "FILAMENT_LOADING" = "Filament loading", "MOTOR_NOISE_CALIBRATION" = "Motor noise calibration", "AMS_LOST_PAUSE" = "Paused due to AMS lost", "HEAT_BREAK_FAN_PAUSE" = "Paused due to low speed of the heat break fan", "CHAMBER_TEMPERATURE_CONTROL_ERROR_PAUSE" = "Paused due to chamber temperature control error", "CHAMBER_COOLING" = "Cooling chamber", "USER_INSERT_GCODE_PAUSE" = "Paused by the Gcode inserted by user", "MOTOR_NOISE_SHOWOFF" = "Motor noise showoff", "NOZZLE_FILAMENT_COVERED_DETECTED_PAUSE" = "Nozzle filament covered detected pause", "CUTTER_ERROR_PAUSE" = "Cutter error pause", "FIRST_LAYER_ERROR_PAUSE" = "First layer error pause", "NOZZLE_CLOG_PAUSE" = "Nozzle clog pause" } /** * Maps print stages to their detailed information */ /** * Maps numeric stage_curr values to PrintStage enum values */ declare const stageCurrToStage: Record<number, PrintStage>; declare const PrintStageDetails: Record<PrintStage, Partial<PrintStageInfo>>; /** * Speed levels of the printer. * * Extracted from https://github.com/bambulab/BambuStudio/blob/master/src/slic3r/GUI/DeviceManager.hpp#L73-L80 */ declare enum SpeedLevel { SILENT = "1", NORMAL = "2", SPORT = "3", LUDICROUS = "4" } /** * An AMS instance. */ interface AMS { humidity: string; id: string; temp: string; tray: [ AMSTray | undefined, AMSTray | undefined, AMSTray | undefined, AMSTray | undefined ]; } /** * An AMS tray (filament slot) instance. */ interface AMSTray { /** * Unknown. Bambu Studio appears to do nothing with it. */ bed_temp: string; /** * Unknown. Bambu Studio appears to do nothing with it. */ bed_temp_type: string; /** * Unknown. Bambu Studio doesn't even check for it. * * Probably the temperature required for filament drying. */ drying_temp: string; /** * Probably the time required for filament drying. */ drying_time: string; /** * The ID of the tray. */ id: string; /** * The loaded filament's maximum nozzle temperature. */ nozzle_temp_max: StringNumber; /** * The loaded filament's minimum nozzle temperature. */ nozzle_temp_min: StringNumber; /** * The amount filament remaining in %, if enabled and an official Bambu filament is loaded. * * With non-official Bambu filament: * - 0: Tracking is disabled. * - -1: Tracking is enabled. */ remain: number; /** * The UID of the filament's NFC that was scanned. * * Uses: * - Check if filament's manufacturer is Bambu Lab: https://github.com/bambulab/BambuStudio/blob/master/src/slic3r/GUI/DeviceManager.cpp#L1090-L1101 * * TODO: Extract when received from printer / provide helper function to do so. */ tag_uid: string; /** * The color of the filament loaded in HEX color code. */ tray_color: string; /** * The diameter of the spool loaded. */ tray_diameter: 1.75; /** * Unknown. Bambu Studio appears to do nothing with it. */ tray_id_name: string; /** * The ID of the base config file for the filament. * * Uses: * - Associate the filament loaded with it's complete brand name. Use the `getFilamentConfig` function for getting the config. * * Config files can be found here: https://github.com/bambulab/BambuStudio/tree/master/resources/profiles/BBL/filament */ tray_info_idx: string; /** * No use cases are known. */ tray_sub_brands: ""; /** * The type of filament loaded into the tray (filament slot). */ tray_type: FilamentType; /** * Unknown. Bambu Studio appears to do nothing with it. */ tray_uuid: string; /** * Unknown. Bambu Studio appears to do nothing with it. */ tray_weight: string; /** * Information about the AI camera features (?) */ xcam_info: string; } /** * External spool (tray). This has unused values due to being a copy of the AMS trays. */ interface ExternalTray extends AMSTray { /** * Unknown. Bambu Studio appears to do nothing with it. */ cols: StringNumber[]; /** * The ID of the tray. */ id: "254"; /** * The loaded filament's "k" value (manually set in Bambu Studio). */ k: number; /** * The loaded filament's "n" value (manually set in Bambu Studio). */ n: number; } /** * Status of the AMS' RFID reader. */ declare enum AmsRFIDStatus { IDLE = 0, READING = 1, GCODE_TRANS = 2, GCODE_RUNNING = 3, ASSISTANT = 4, SWITCH_FILAMENT = 5, HAS_FILAMENT = 6 } /** * Bambu Lab's proprietary Health Management System (HMS). * * More info: https://wiki.bambulab.com/en/x1/troubleshooting/intro-hms * * All error codes: https://wiki.bambulab.com/en/hms/home */ interface HMS { attr: number; code: number; } /** * Interior lighting related status instance. */ interface LightReport { node: "chamber_light" | "work_light"; mode: "on" | "off" | "flashing"; } /** * The possible progress states of a firmware upgrade. * * Extracted from https://github.com/bambulab/BambuStudio/blob/master/src/slic3r/GUI/DeviceManager.cpp#L3481-L3494 */ declare enum UpgradeStatusProgressState { DOWNLOADING = "DOWNLOADING", UPGRADE_REQUEST = "UPGRADE_REQUEST", PRE_FLASH_START = "PRE_FLASH_START", PRE_FLASH_SUCCESS = "PRE_FLASH_SUCCESS" } /** * The possible finish states of a firmware upgrade. * * Extracted from https://github.com/bambulab/BambuStudio/blob/master/src/slic3r/GUI/DeviceManager.cpp#L3481-L3494 */ declare enum UpgradeStatusFinishState { UPGRADE_SUCCESS = "UPGRADE_SUCCESS", DOWNLOAD_FAIL = "DOWNLOAD_FAIL", FLASH_FAIL = "FLASH_FAIL", PRE_FLASH_FAIL = "PRE_FLASH_FAIL", UPGRADE_FAIL = "UPGRADE_FAIL" } /** * Error codes thrown by the upgrade. */ declare enum UpgradeErrorCode { UpgradeNoError = 0, UpgradeDownloadFailed = 1, UpgradeVerifyFailed = 2, UpgradeFlashFailed = 3, UpgradePrinting = 4 } /** * The possible states the printer's screen will display. */ declare enum UpgradeDisplayState { UNAVAILABLE = 0, IDLE = 1, UPGRADING = 2, UPGRADE_FINISHED = 3 } declare enum FilamentType { PLA = "PLA", ABS = "ABS", TPU = "TPU", PC = "PC", ASA = "ASA", PA_CF = "PA-CF", PA6_CF = "PA6-CF", PET_CF = "PET-CF", PETG = "PETG", PETG_CF = "PETG-CF", PLA_AERO = "PLA-AERO", PLA_CF = "PLA-CF", PPA_CF = "PPA-CF", PPA_GF = "PPA-GF", PA = "PA", HIPS = "HIPS", PPS = "PPS", PPS_CF = "PPS-CF", PVA = "PVA", PLA_S = "PLA-S", PA_S = "PLA-S" } /** * Contains basic data about a filament, which is then extended by the final product. */ interface BaseFilamentConfig { type: "filament"; name: string; inherits: string; from: string; instantiation: StringBoolean; fan_cooling_layer_time: [StringNumber]; filament_max_volumetric_speed: [StringNumber]; filament_density: [StringNumber]; filament_cost: [StringNumber]; cool_plate_temp: [StringNumber]; eng_plate_temp: [StringNumber]; hot_plate_temp: [StringNumber]; textured_plate_temp: [StringNumber]; cool_plate_temp_initial_layer: [StringNumber]; eng_plate_temp_initial_layer: [StringNumber]; hot_plate_temp_initial_layer: [StringNumber]; textured_plate_temp_initial_layer: [StringNumber]; nozzle_temperature_initial_layer: [StringNumber]; reduce_fan_stop_start_freq: [StringNumber]; fan_min_speed: [StringNumber]; overhang_fan_threshold: [StringNumber]; close_fan_the_first_x_layers: [StringNumber]; nozzle_temperature: [StringNumber]; temperature_vitrification: [StringNumber]; nozzle_temperature_range_low: [StringNumber]; nozzle_temperature_range_high: [StringNumber]; slow_down_min_speed: [StringNumber]; slow_down_layer_time: [StringNumber]; additional_cooling_fan_speed: [StringNumber]; filament_start_gcode: [string]; } /** * The config files ending with @base */ interface ExtendedFilamentConfig extends Partial<BaseFilamentConfig> { type: "filament"; name: string; inherits: string; from: string; filament_id: string; setting_id: string; } /** * The final filament config data. Contains the inherited and @base file data. */ interface FilamentConfig extends BaseFilamentConfig { type: "filament"; name: string; inherits: string; from: string; filament_id: string; instantiation: StringBoolean; filament_cost: [StringNumber]; filament_vendor: [string]; } /** * Retrieves the FilamentConfig object associated with the specified ID. * @param id - The ID of the FilamentConfig to retrieve. * @returns The FilamentConfig object if found, otherwise undefined. */ declare function getFilamentConfig(id: string): FilamentConfig | null; /** * Converts a numeric stage_curr value to its corresponding PrintStage enum value * @param stageCurr - The numeric stage value (0-35) * @returns The corresponding PrintStage enum value, or undefined if not found */ declare function getStageFromCurr(stageCurr: number): PrintStage | undefined; /** * Converts an array of numeric stage values to an array of PrintStage enum values * @param stages - Array of numeric stage values (0-35) * @returns Array of corresponding PrintStage enum values, filtering out any undefined stages */ declare function getStagesFromArray(stages: number[]): PrintStage[]; /** * Represents a stage with its details and completion status */ interface EnrichedStageInfo extends Partial<PrintStageInfo> { stage: PrintStage; description: string; completed: boolean; current: boolean; } /** * Creates an enriched array of stage information with completion status * @param currentStage - The current stage number (stage_curr) * @param stageHistory - Array of previous stage numbers (stg) * @returns Array of stages with their details and completion status * * @example * const stages = getEnrichedStages(4, [2, 13, 24, 4]); * // Returns array of EnrichedStageInfo with: * // - HEATBED_PREHEATING (completed) * // - TOOLHEAD_HOMING (completed) * // - FILAMENT_LOADING (completed) * // - CHANGE_MATERIAL (current, not completed) */ declare function getEnrichedStages(currentStage: number, stageHistory: number[]): EnrichedStageInfo[]; declare function isPushAllCommand(data: PrintMessageCommand): data is PushAllResponse; interface UpdateFanResponse extends PrintMessageCommand { command: "gcode_line"; param: string; reason: "SUCCESS" | "FAILURE" | string; result: "SUCCESS" | "FAILURE" | string; sequence_id: StringNumber; } declare function isUpdateFanCommand(data: PrintMessageCommand): data is UpdateFanResponse; interface UpdateLightResponse extends PushStatusResponse { param: string; lights_report: LightReport[]; reason: "SUCCESS" | "FAILURE" | string; result: "SUCCESS" | "FAILURE" | string; sequence_id: StringNumber; } declare function isUpdateLightCommand(data: PrintMessageCommand): data is UpdateLightResponse; interface UpdateSpeedResponse extends PushStatusResponse { param: string; spd_lvl: SpeedLevel; spd_mag: NumberRange<50, 166>; reason: "SUCCESS" | "FAILURE" | string; result: "SUCCESS" | "FAILURE" | string; sequence_id: StringNumber; } declare function isUpdateSpeedCommand(data: PrintMessageCommand): data is UpdateSpeedResponse; interface UpdateStateResponse extends PrintMessageCommand { command: State; param: string; reason: "SUCCESS" | "FAILURE" | string; result: "SUCCESS" | "FAILURE" | string; sequence_id: StringNumber; } declare function isUpdateStateCommand(data: PrintMessageCommand): data is UpdateStateResponse; interface UpdateTempResponse extends PrintMessageCommand { command: "gcode_line"; param: string; reason: "SUCCESS" | "FAILURE" | string; result: "SUCCESS" | "FAILURE" | string; sequence_id: StringNumber; } declare function isUpdateTempCommand(data: PrintMessageCommand): data is UpdateTempResponse; type MCPrintMessageCommands = "push_info"; type MCPrintMessageCommand = { command: MCPrintMessageCommands; sequence_id: string; }; interface MCPrintMessage { print: MCPrintMessageCommand; } declare function isMCPrintMessage(data: any): data is MCPrintMessage; interface PushInfoResponse extends MCPrintMessageCommand { command: "push_info"; param: string; sequence_id: StringNumber; } declare function isPushInfoCommand(data: MCPrintMessageCommand): data is PushInfoResponse; interface CleanPushInfoCommand { category: string; content: string; rawParam: string; sequenceId: number; subcategory?: string; } declare function getCleanPushInfoCommand(command: PushInfoResponse): CleanPushInfoCommand; type InfoMessageCommands = "get_version"; type InfoMessageCommand = { command: InfoMessageCommands; sequence_id: string; }; interface InfoMessage { info: InfoMessageCommand; } declare function isInfoMessage(data: any): data is InfoMessage; interface VersionModule { /** * The module's name. */ name: string; /** * The module's hardware version. */ hw_ver: string; /** * The module's serial number. */ sn: string; /** * The module's software version. */ sw_ver: string; } interface GetVersionResponse extends InfoMessageCommand { command: "get_version"; module: VersionModule[]; sequence_id: StringNumber; } declare function isGetVersionCommand(data: InfoMessageCommand): data is GetVersionResponse; interface AMSFilamentSettingResponse { command: "ams_filament_setting"; result: "success" | "failed"; info?: string; sequence_id: string; } declare function isAMSFilamentSettingResponse(response: { command: string; sequence_id: string; }, commandSeqId: string): response is AMSFilamentSettingResponse; type StringNumber = `${number}`; type StringBoolean = `${boolean}`; type NumberRange<start extends number, end extends number, arr extends unknown[] = [], acc extends number = never> = arr["length"] extends end ? acc | start | end : NumberRange<start, end, [ ...arr, 1 ], arr[start] extends undefined ? acc : acc | arr["length"]>; type StringNumberRange<F extends number, T extends number> = `${NumberRange<F, T>}`; interface IncomingMessageData { [key: string]: unknown; } type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>; interface PrinterData extends Optional<PushStatusResponse, "command" | "sequence_id"> { modules: VersionModule[]; model: PrinterModelNamesShort | undefined; } type ValueOf<T> = T[keyof T]; type CommandResponse = InfoMessageCommand | MCPrintMessageCommand | PrintMessageCommand | AMSFilamentSettingResponse; type BambuClientPrinterStatus = PrinterStatus | "OFFLINE"; type IConnackPacket = mqtt.IConnackPacket; declare enum PrinterModelNamesShort { X1C = "X1C", X1 = "X1", X1E = "X1E", P1P = "P1P", P1S = "P1S", A1 = "A1", A1M = "A1M" } /** * Represents a single print job. */ declare class Job { private _jobData; constructor(data: PushAllResponse, printerId: string, printerModel: PrinterModelNamesShort, createdAt?: Date); /** * Updates the job with new (up-to-date) data. */ update(data: Partial<PushAllResponse>): void; get data(): JobData; } /** * Represents the properties of a job. * * WARNING: Only values which are key information when the job finishes should be added here. */ interface JobData { /** * The unique CUID of the job. */ id: string; /** * The ID of the printer who created this job. */ printerId: string; /** * The model of the printer who created this job. */ printerModel: PrinterModelNamesShort; /** * The name of the job. * * Uses the `subtask_name` property and strips any file extensions. * @see PushAllCommand["subtask_name"] */ name: string; /** * The file name of the job. * * The `subtask_name` property. * @see PushAllCommand["subtask_name"] */ fileName: PushAllResponse["subtask_name"]; /** * The name of the GCode which gets executed. * @see PushAllCommand["gcode_file"] */ gcodeName: PushAllResponse["gcode_file"]; /** * The origin of the job. * @see PushAllCommand["print_type"] */ jobOrigin: PushAllResponse["print_type"]; /** * The total layer number of the job. */ totalLayerNumber: PushAllResponse["total_layer_num"]; /** * The total print time the Job takes to print in minutes. */ totalPrintTime: PushAllResponse["mc_remaining_time"]; /** * The status of the job (printer). */ status: PushAllResponse["gcode_state"]; /** * The current stage of the print job. */ stage: PrintStage; /** * The % of the print done from the job. */ percentDone: PushAllResponse["mc_percent"]; /** * The current layer number. */ layerNumber: PushAllResponse["layer_num"]; /** * The remaining time until the job finishes in minutes. */ remainingTime: PushAllResponse["mc_remaining_time"]; /** * Objects that have been skipped by the printer while printing. * @see PushStatusCommand["s_obj"] */ skippedObjects: PushAllResponse["s_obj"]; /** * Stores the status changes throughout the job. */ statusHistory: StatusChangeItem[]; /** * Stores the manual speed level changes throughout the job. */ speedLevelHistory: SpeedLevelHistoryItem[]; /** * Stores the printing stage changes throughout the job. */ printingStageHistory: PrintingStageHistoryItem[]; /** * Stores the temperature changes throughout the job. Updated every 5 seconds while printing. */ temperatureHistory: TemperatureHistoryItem[]; /** * The last time the temperature was updated. Used internally to ensure that we only update every 5 seconds. */ tempLastUpdatedAt: Date; /** * The HMS error codes the printer encountered while printing the Job. */ errorCodes: HMSCodeHistory[]; /** * The date time the job (print) started. */ createdAt: Date; } /** * A status change instance. */ interface StatusChangeItem { status: PrinterStatus; changedAt: Date; } /** * A manual speed level change instance. */ interface SpeedLevelHistoryItem { speedLevel: PushAllResponse["spd_lvl"]; speedMagnitude: PushAllResponse["spd_mag"]; changedAt: Date; } /** * A printing stage change instance with detailed information. */ interface PrintingStageHistoryItem { stage: PrintStage; progress: number; name: string; description: string; controllable: boolean; critical: boolean; timeRemaining?: number; changedAt: Date; } interface TemperatureHistoryItem { bedTemp: number; bedTargetTemp: number; /** * `frame_temper` or `chamber_temper` depending on the printer model. */ interiorTemp: number; nozzleTemp: number; nozzleTargetTemp: number; changedAt: Date; } interface HMSCodeHistory extends HMS { /** * The time the error code was thrown. */ thrownAt: Date; /** * The layer number the error code was thrown at. */ layerNumber: number; } type FinishOutcome = "SUCCESS" | "FAILED" | "UNEXPECTED"; interface BambuClientEvents { message: [topic: string, key: string, data: IncomingMessageData]; rawMessage: [topic: string, payload: Buffer]; "client:connect": []; "client:disconnect": [isDisconnectOffline: boolean]; "client:error": [error: Error]; "printer:dataUpdate": [data: PrinterData, updatePackage: Partial<PrinterData>]; "printer:statusUpdate": [ oldStatus: BambuClientPrinterStatus, newStatus: BambuClientPrinterStatus ]; "printer:amsUpdate": [ams: PushAllResponse["ams"]]; "job:update": [job: Job, updatePackage: Partial<JobData>]; "job:start": [job: Job]; "job:pause": [job: Job, isClientOffline: boolean]; "job:offlineRecovery": [job: Job]; "job:unpause": [job: Job]; "job:finish": [job: Job, outcome: FinishOutcome]; } interface BambuClientOptions { /** * The IP address / URL of the printer. */ host: string; /** * The port of the printer. * @default 8883 */ port?: number; /** * The access token of the printer. * It can be found in the settings. */ accessToken: string; /** * The serial number of the printer. * It can be found in the settings or the back sticker. */ serialNumber: string; /** * Whether to throw errors while running `publish` and `executeCommand` methods when offline. * @default false */ throwOnOfflineCommands?: boolean; /** * The time between 2 reconnection attempts in ms. * @default 1000 */ reconnectInterval?: number; /** * The time to wait before a `CONNACK` is received in ms. * @default 2000 */ connectTimeout?: number; /** * The amount of time that keep alive will consider the server inactive in seconds. * * Please note: numbers lower than 20 usually make the client go into a reconnect loop. If you have an idea on how to fix this then feel free to open a PR / issue. * @default 20 */ keepAlive?: number; /** * An array of jobs to load into the `jobHistory` array. * * You can use any kind of persistent storage to persist jobs and them load them back in to query them if need be. */ jobHistory?: Job[]; /** * The job to load into the `currentJob` array. * * You can use any kind of persistent storage to persist jobs and them load them back in to query them if need be. */ currentJob?: Job; } /** * Manages connectivity and messages from/to the printer. */ declare class BambuClient extends events.EventEmitter<keyof BambuClientEvents> { readonly clientOptions: BambuClientOptions; emit<K extends keyof BambuClientEvents>(event: K, ...arguments_: BambuClientEvents[K]): boolean; off<K extends keyof BambuClientEvents>(event: K, listener?: (...arguments_: BambuClientEvents[K]) => void): this; once<K extends keyof BambuClientEvents>(event: K, listener: (...arguments_: BambuClientEvents[K]) => void): this; on<K extends keyof BambuClientEvents>(event: K, listener: (...arguments_: BambuClientEvents[K]) => void): this; id: string; private mqttClient; config: { host: string; port: number; accessToken: string; serialNumber: string; throwOnOfflineCommands: boolean; reconnectInterval: number; connectTimeout: number; keepAlive: number; }; private _printerData; private _printerStatus; jobHistory: Job[]; currentJob: Job | null; private isJobInHistory; private addJobToHistory; constructor(clientOptions: BambuClientOptions); private connectMQTT; /** * Connect to the printer. */ connect(): Promise<[mqtt.IConnackPacket]>; /** * Disconnect from the printer. * @param force Forcefully disconnect. * @param options {Parameters<MqttClient["end"]>[1]} MQTT client options */ disconnect(force?: boolean, options?: Parameters<MqttClient["end"]>[1]): Promise<unknown>; private subscribe; /** * Execute a command. * @param command {AbstractCommand} Command to execute. * @returns {Promise<CommandResponse>} A promise which resolves to the CommandResponse once the command has been acknowledged by the printer, times out after 5 seconds. */ executeCommand(command: AbstractCommand, timeoutMs?: number): Promise<CommandResponse>; protected onConnect(packet: mqtt.IConnackPacket): Promise<mqtt.IConnackPacket>; private onMessage; /** * Used by the individual command types to publish messages to the printer. * @param message */ publish(message: string | object): Promise<void>; get data(): PrinterData; get connectionStatus(): boolean | undefined; get status(): BambuClientPrinterStatus; } interface CommandInterface { category: "info" | "pushing" | "system" | "print"; command: string; extra?: Record<string, unknown> & { sequence_id?: string; }; invoke(client: BambuClient): void; } declare abstract class AbstractCommand implements CommandInterface { extra: CommandInterface["extra"]; abstract category: CommandInterface["category"]; abstract command: CommandInterface["command"]; /** * Constructs a basic command class with the properties required for basic compatibility with @hiv3d/bambu-node. * @param extra Extra properties to add to the request object. */ protected constructor(extra?: CommandInterface["extra"]); invoke(client: BambuClient): Promise<string>; abstract ownsResponse(command: CommandResponse, squence_id?: string): boolean; } type GCodeCommandParam = "gcode_file" | "gcode_line"; declare abstract class GCodeCommand extends AbstractCommand { category: CommandInterface["category"]; abstract command: GCodeCommandParam; /** * Constructs a basic `print.gcode_file` or `print.gcode_line` command, which must be extended first to use. * @param gcode The array of Gcode instructions to execute. Implementation can be overridden if using with `gcode_file`. * @protected */ protected constructor(gcode: string[]); } declare class GCodeFileCommand extends AbstractCommand { category: CommandInterface["category"]; command: CommandInterface["command"]; /** * Constructs a new GCode file command, which executes a GCode file on the printer's filesystem. * @param fileName The file name of the GCode to execute on the printer. (on the printer's filesystem) */ constructor({ fileName }: { fileName: string; }); ownsResponse: typeof isGcodeFileCommand; } declare class GCodeLineCommand extends GCodeCommand { command: GCodeCommandParam; /** * Creates a raw GCode line command, which executes an array of GCode instructions on the printer. * @param gcodes The array of GCode instructions to execute. */ constructor({ gcodes }: { gcodes: string[]; }); ownsResponse: typeof isGCodeLineCommand; } declare class GetVersionCommand extends AbstractCommand { category: CommandInterface["category"]; command: CommandInterface["command"]; /** * Constructs a new get version command. */ constructor(); ownsResponse: typeof isGetVersionCommand; } declare class PushAllCommand extends AbstractCommand { category: CommandInterface["category"]; command: CommandInterface["command"]; /** * Constructs a new `pushing.pushall` command, which gets all properties from the printer. * @version * - X1 series: Already sends `pushing.pushall` responses automatically every ~2 secs. * - Other series: Only sends partial responses of `pushing.pushall` with only the values that have changed since the last response. */ constructor(); ownsResponse: typeof isPushAllCommand; } declare enum Fan { PART_COOLING_FAN = 1, AUXILIARY_FAN = 2, CHAMBER_FAN = 3 } declare class UpdateFanCommand extends GCodeCommand { command: GCodeCommandParam; /** * Constructs a `print.gcode_line` command, which is able to update the current speeds of every fan on the printer. * @param fan {Fan} The fan's speed to update. * @param speed {NumberRange<0, 100>} The fan's new speed in % (0-100). */ constructor({ fan, speed }: { fan: Fan; speed: NumberRange<0, 100>; }); ownsResponse: typeof isUpdateFanCommand; } interface UpdateLightLoopOpt