A way to document printed parts

We were wondering if anybody knows how to get a list of parts printed out for the printer or slicer for a given amount of time.

IE we bill parts based on time printed to our customer and it would be nice at the end of a week to be able to print out parts printed on a machine showing print time?

Currently looks like we could do a screen print from the slicer software

Thanks in advance!

1 Like

Do you need a “proof” to be shown to the client, or rather a way to just retrieve these informations ?
Are you “tech guys” ?

One idea (if you are a bit technical …) could be to write a small “something” (a python script, …) allowing to connect to the Bambu Lab MQTT server, and that would automatically extract the time spent for one build.

It’s rather easy to do, i would say.

Algorithm of the python script (or whatever) :

  1. Connect on the MQTT Broker (192.168.X.Y:1889) (no auth)
  2. Continuously read the messages pushed in the MQTT topic “device/<BAMBU_ID>/report” (= a “while loop”)
  3. Decode the message and extract the few needed fields like “mc_percent” (percentage of progress of build from 0 to 100%), “mc_print_stage” (just a guess), “mc_remaining_time” (number of minutes before end of build), “gcode_start_timestamp” (hours and minutes of the beginning of the gcode being processed), …
  4. When “mc_percent” reaches “100” (= 100% of print) (or maybe when “pc_print_stage” changes from 2 to 1 (just another guess), then : just calculate the difference between “current timestamp” at that time minus “gcode_start_timestamp” : that will give you the exact amount of seconds for the print done during that period
  5. You could have the script running for a long time and “capture” several successive prints and sum the hours taken, and so on

Of course up to you to see how to map “customer” and “results” : for example, launch the script with some parameters, keep it running for days with a few prints during the day, and stop it when you stop working for that customer and switch to another one (of course “idle time” during which the printer is not printing won’t be taken in account) - so you would launch the script with :
python3 bambu.py <BAMBU_ID> <CUSTOMER_ID>

and the script could display over time something like :

CUSTOMER_ID           Total prints done          Time taken by last print                 Cumulative time for all prints"
CUSTOMER_ID_0001      1 print done               2 h                                      2 h
CUSTOMER_ID_0001      2 prints done              1 h                                      3 h
CUSTOMER_ID_0001      3 prints done              30 m                                     3 h 30 min

Example of full JSON content sent by Bambu printers each seconds :

device/00M00A261900054/report {
    "print": {
        "ams": {
            "ams": [
                {
                    "humidity": "2",
                    "id": "0",
                    "temp": "22.5",
                    "tray": [
                        {
                            "bed_temp": "0",
                            "bed_temp_type": "0",
                            "drying_temp": "0",
                            "drying_time": "0",
                            "id": "0",
                            "nozzle_temp_max": "260",
                            "nozzle_temp_min": "220",
                            "remain": 0,
                            "tag_uid": "0000000000000000",
                            "tray_color": "161616FF",
                            "tray_diameter": "0.00",
                            "tray_id_name": "",
                            "tray_info_idx": "GFG99",
                            "tray_sub_brands": "",
                            "tray_type": "PETG",
                            "tray_uuid": "00000000000000000000000000000000",
                            "tray_weight": "0",
                            "xcam_info": "000000000000000000000000"
                        },
                        {
                            "bed_temp": "0",
                            "bed_temp_type": "0",
                            "drying_temp": "0",
                            "drying_time": "0",
                            "id": "1",
                            "nozzle_temp_max": "260",
                            "nozzle_temp_min": "220",
                            "remain": 0,
                            "tag_uid": "0000000000000000",
                            "tray_color": "F98C36FF",
                            "tray_diameter": "0.00",
                            "tray_id_name": "",
                            "tray_info_idx": "GFG99",
                            "tray_sub_brands": "",
                            "tray_type": "PETG",
                            "tray_uuid": "00000000000000000000000000000000",
                            "tray_weight": "0",
                            "xcam_info": "000000000000000000000000"
                        },
                        {
                            "bed_temp": "0",
                            "bed_temp_type": "0",
                            "drying_temp": "0",
                            "drying_time": "0",
                            "id": "2",
                            "nozzle_temp_max": "260",
                            "nozzle_temp_min": "220",
                            "remain": 0,
                            "tag_uid": "0000000000000000",
                            "tray_color": "FFFFFFFF",
                            "tray_diameter": "0.00",
                            "tray_id_name": "",
                            "tray_info_idx": "GFG99",
                            "tray_sub_brands": "",
                            "tray_type": "PETG",
                            "tray_uuid": "00000000000000000000000000000000",
                            "tray_weight": "0",
                            "xcam_info": "000000000000000000000000"
                        },
                        {
                            "bed_temp": "0",
                            "bed_temp_type": "0",
                            "drying_temp": "0",
                            "drying_time": "0",
                            "id": "3",
                            "nozzle_temp_max": "260",
                            "nozzle_temp_min": "220",
                            "remain": 0,
                            "tag_uid": "0000000000000000",
                            "tray_color": "0ACC38FF",
                            "tray_diameter": "0.00",
                            "tray_id_name": "",
                            "tray_info_idx": "GFG99",
                            "tray_sub_brands": "",
                            "tray_type": "PETG",
                            "tray_uuid": "00000000000000000000000000000000",
                            "tray_weight": "0",
                            "xcam_info": "000000000000000000000000"
                        }
                    ]
                },
                {
                    "humidity": "5",
                    "id": "1",
                    "temp": "20.6",
                    "tray": [
                        {
                            "bed_temp": "0",
                            "bed_temp_type": "0",
                            "drying_temp": "0",
                            "drying_time": "0",
                            "id": "0",
                            "nozzle_temp_max": "260",
                            "nozzle_temp_min": "220",
                            "remain": 0,
                            "tag_uid": "0000000000000000",
                            "tray_color": "F72323FF",
                            "tray_diameter": "0.00",
                            "tray_id_name": "",
                            "tray_info_idx": "GFG99",
                            "tray_sub_brands": "",
                            "tray_type": "PETG",
                            "tray_uuid": "00000000000000000000000000000000",
                            "tray_weight": "0",
                            "xcam_info": "000000000000000000000000"
                        },
                        {
                            "bed_temp": "0",
                            "bed_temp_type": "0",
                            "drying_temp": "0",
                            "drying_time": "0",
                            "id": "1",
                            "nozzle_temp_max": "260",
                            "nozzle_temp_min": "220",
                            "remain": 0,
                            "tag_uid": "0000000000000000",
                            "tray_color": "A03CF7FF",
                            "tray_diameter": "0.00",
                            "tray_id_name": "",
                            "tray_info_idx": "GFG99",
                            "tray_sub_brands": "",
                            "tray_type": "PETG",
                            "tray_uuid": "00000000000000000000000000000000",
                            "tray_weight": "0",
                            "xcam_info": "000000000000000000000000"
                        },
                        {
                            "bed_temp": "0",
                            "bed_temp_type": "0",
                            "drying_temp": "0",
                            "drying_time": "0",
                            "id": "2",
                            "nozzle_temp_max": "260",
                            "nozzle_temp_min": "220",
                            "remain": 0,
                            "tag_uid": "0000000000000000",
                            "tray_color": "898989FF",
                            "tray_diameter": "0.00",
                            "tray_id_name": "",
                            "tray_info_idx": "GFG99",
                            "tray_sub_brands": "",
                            "tray_type": "PETG",
                            "tray_uuid": "00000000000000000000000000000000",
                            "tray_weight": "0",
                            "xcam_info": "000000000000000000000000"
                        },
                        {
                            "bed_temp": "0",
                            "bed_temp_type": "0",
                            "drying_temp": "0",
                            "drying_time": "0",
                            "id": "3",
                            "nozzle_temp_max": "260",
                            "nozzle_temp_min": "220",
                            "remain": 0,
                            "tag_uid": "0000000000000000",
                            "tray_color": "AF7933FF",
                            "tray_diameter": "0.00",
                            "tray_id_name": "",
                            "tray_info_idx": "GFG99",
                            "tray_sub_brands": "",
                            "tray_type": "PETG",
                            "tray_uuid": "00000000000000000000000000000000",
                            "tray_weight": "0",
                            "xcam_info": "000000000000000000000000"
                        }
                    ]
                }
            ],
            "ams_exist_bits": "3",
            "insert_flag": true,
            "power_on_flag": false,
            "tray_exist_bits": "ff",
            "tray_is_bbl_bits": "ff",
            "tray_now": "6",
            "tray_read_done_bits": "ff",
            "tray_reading_bits": "0",
            "tray_tar": "6",
            "version": 13
        },
        "ams_rfid_status": 2,
        "ams_status": 768,
        "bed_target_temper": 70.0,
        "bed_temper": 70.0,
        "big_fan1_speed": "0",
        "big_fan2_speed": "15",
        "chamber_temper": 31.0,
        "command": "push_status",
        "cooling_fan_speed": "0",
        "fail_reason": "0",
        "fan_gear": 16711680,
        "force_upgrade": false,
        "gcode_file": "/data/Metadata/plate_1.gcode",
        "gcode_file_prepare_percent": "100",
        "gcode_start_time": "1673860282",
        "gcode_state": "RUNNING",
        "heatbreak_fan_speed": "15",
        "hms": [],
        "home_flag": 271,
        "hw_switch_state": 1,
        "ipcam": {
            "ipcam_dev": "1",
            "ipcam_record": "disable",
            "resolution": "1080p",
            "timelapse": "enable"
        },
        "lifecycle": "product",
        "lights_report": [
            {
                "mode": "on",
                "node": "chamber_light"
            },
            {
                "mode": "flashing",
                "node": "work_light"
            }
        ],
        "mc_percent": 6,
        "mc_print_error_code": "0",
        "mc_print_stage": "2",
        "mc_print_sub_stage": 0,
        "mc_remaining_time": 326,
        "mess_production_state": "active",
        "nozzle_target_temper": 255.0,
        "nozzle_temper": 255.0,
        "online": {
            "ahb": true,
            "rfid": false
        },
        "print_error": 0,
        "print_gcode_action": 0,
        "print_real_action": 0,
        "print_type": "cloud",
        "profile_id": "1264843",
        "project_id": "1264845",
        "sdcard": true,
        "sequence_id": "2021",
        "spd_lvl": 2,
        "spd_mag": 100,
        "stg": [
            2,
            14,
            1,
            8
        ],
        "stg_cur": 0,
        "subtask_id": "2435333",
        "subtask_name": "boardgame-the-king-is-dead_plate_1",
        "task_id": "2435332",
        "upgrade_state": {
            "ahb_new_version_number": "",
            "ams_new_version_number": "",
            "consistency_request": false,
            "dis_state": 0,
            "err_code": 0,
            "force_upgrade": false,
            "message": "",
            "module": "null",
            "new_version_state": 2,
            "ota_new_version_number": "",
            "progress": "0",
            "sequence_id": 0,
            "status": "IDLE"
        },
        "upload": {
            "file_size": 0,
            "finish_size": 0,
            "message": "Good",
            "oss_url": "",
            "progress": 0,
            "sequence_id": "0903",
            "speed": 0,
            "status": "idle",
            "task_id": "",
            "time_remaining": 0,
            "trouble_id": ""
        },
        "wifi_signal": "-60dBm",
        "xcam": {
            "allow_skip_parts": false,
            "buildplate_marker_detector": false,
            "first_layer_inspector": true,
            "halt_print_sensitivity": "medium",
            "print_halt": true,
            "printing_monitor": true,
            "spaghetti_detector": true
        },
        "xcam_status": "0"
    }
}
1 Like

We aren’t technical enough to pull this off - if you are and would be willing we would pay for this

2 Likes

Wow great to know there is a MQTT broker on Bambulab !

@SR-G : How do you find this ? (I scanned ports and sniff network without seeing anything else than the ftp server and the UDP packets of the video)

@user_3827062560 :
Easyway is to install mqtt client :

sudo apt-get install mosquitto-clients
mosquitto_sub -h 192.168.0.74  -t "#"

Note that mine is on the standard MQTT port 1883 not 1889

Obviously replace the IP (192.168.0.74) by your bambulab local IP, you can redirect the output of mosquitto_sub -h 192.168.0.74 -t "#" to a script you write using either Shell, PHP, Python, Javascript, C, etc… or a text file that you can open later… mosquitto_sub -h 192.168.0.74 -t "#" >> output.json

EDIT: there are some Json converter to CSV/column based software (eg: https://www.convertcsv.com/json-to-csv.htm)

1 Like

Here is something that should do the job you want :

First dont forget to install a mosquitto client :

sudo apt-get install mosquitto-clients

Second run :

mosquitto_sub -h 192.168.0.74 -t "#" | grep "gcode"

This will ouput something like :

        "print_gcode_action": 0,
        "gcode_file": "/data/Metadata/plate_1.gcode",
        "gcode_file_prepare_percent": "0",
        "gcode_start_time": "1674828723",
        "gcode_state": "RUNNING",
        "print_gcode_action": 0,
        "gcode_file": "/data/Metadata/plate_1.gcode",
        "gcode_file_prepare_percent": "0",
        "gcode_start_time": "1674828723",
        "gcode_state": "RUNNING",
        "print_gcode_action": 0,
        "gcode_file": "/data/Metadata/plate_1.gcode",
        "gcode_file_prepare_percent": "0",
        "gcode_start_time": "1674828723",
        "gcode_state": "RUNNING",
        "print_gcode_action": 0,
        "gcode_file": "/data/Metadata/plate_1.gcode",
        "gcode_file_prepare_percent": "0",
        "gcode_start_time": "1674828723",
        "gcode_state": "RUNNING",
        "print_gcode_action": 0,
        "gcode_file": "/data/Metadata/plate_1.gcode",
        "gcode_file_prepare_percent": "0",
        "gcode_start_time": "1674828723",
        "gcode_state": "RUNNING",
        "print_gcode_action": 0,

So you got :

  • filename
  • start time
  • state RUNNING/FINISH

EDIT:
A bit dirty but may do the job

mosquitto_sub -h 192.168.0.74 -t "#" | egrep '("gcode\_start\_time"|"gcode\_file"|"gcode\_state")' | xargs -n 6 echo `date`,

Output :

ven. 27 janv. 2023 15:48:23 CET, gcode_file: /data/Metadata/plate_1.gcode, gcode_start_time: 1674828723, gcode_state: FINISH,
ven. 27 janv. 2023 15:48:23 CET, gcode_file: /data/Metadata/plate_1.gcode, gcode_start_time: 1674828723, gcode_state: FINISH,
ven. 27 janv. 2023 15:48:23 CET, gcode_file: /data/Metadata/plate_1.gcode, gcode_start_time: 1674828723, gcode_state: FINISH,
ven. 27 janv. 2023 15:48:23 CET, gcode_file: /data/Metadata/plate_1.gcode, gcode_start_time: 1674828723, gcode_state: FINISH,
ven. 27 janv. 2023 15:48:23 CET, gcode_file: /data/Metadata/plate_1.gcode, gcode_start_time: 1674828723, gcode_state: FINISH,
ven. 27 janv. 2023 15:48:23 CET, gcode_file: /data/Metadata/plate_1.gcode, gcode_start_time: 1674828723, gcode_state: FINISH,
ven. 27 janv. 2023 15:48:23 CET, gcode_file: /data/Metadata/plate_1.gcode, gcode_start_time: 1674828723, gcode_state: FINISH,
ven. 27 janv. 2023 15:48:23 CET, gcode_file: /data/Metadata/plate_1.gcode, gcode_start_time: 1674828723, gcode_state: FINISH,
ven. 27 janv. 2023 15:48:23 CET, gcode_file: /data/Metadata/plate_1.gcode, gcode_start_time: 1674828723, gcode_state: FINISH,
ven. 27 janv. 2023 15:48:23 CET, gcode_file: /data/Metadata/plate_1.gcode, gcode_start_time: 1674828723, gcode_state: FINISH,
ven. 27 janv. 2023 15:48:23 CET, gcode_file: /data/Metadata/plate_1.gcode, gcode_start_time: 1674828723, gcode_state: FINISH,
ven. 27 janv. 2023 15:48:23 CET, gcode_file: /data/Metadata/plate_1.gcode, gcode_start_time: 1674828723, gcode_state: FINISH,
ven. 27 janv. 2023 15:48:23 CET, gcode_file: /data/Metadata/plate_1.gcode, gcode_start_time: 1674828723, gcode_state: FINISH,
ven. 27 janv. 2023 15:48:23 CET, gcode_file: /data/Metadata/plate_1.gcode, gcode_start_time: 1674828723, gcode_state: FINISH,
ven. 27 janv. 2023 15:48:23 CET, gcode_file: /data/Metadata/plate_1.gcode, gcode_start_time: 1674828723, gcode_state: FINISH,

Using excel or like you should be able to read this as a CSV, and should be able to group/count by column (start time)

1 Like

I typed the previous post very quickly and without checking the details : the port is obviously 1883, being the default one.

JQ (linux binary) is quite useful to extract with JSONPATH values, for debugging purposes.
But anyway - and this is what i was suggesting - it’s probably better to write a small python script (or a GOLANG binary, in order to have something even simpler to be executed without dependencies = just with GOLANG, it would be just a .exe to be launched on windows and nothing else to install / manage) in order to put in place the simple and small logic that i was describing.

Note : I put some time ago some notes (in french) in that forum => [WIP] Lire les données publiées par les imprimantes Bambu (usage domotique, etc.) - Bambu Lab - Forum pour les imprimantes 3D et l'impression 3D

For MQTT, for example, for first manual steps of discoveries :

# Launch a docker container in order to have a MQTT client
docker run --rm -it -v $(pwd):/data -w /data/ --name mqtt-client2 debian:bullseye-slim /bin/bash

# Once inside the container, install the MQTT client and JQ (for JSON formatting)
apt-get update && apt-get install -y mosquitto-clients jq

# Put your informations here regarding the Bambu (IP address + internal ID (visible in Bambu Studio))
export BAMBU_X1C_IP="192.168.8.130"
export BAMBU_X1C_ID="00M00A261900054"

# Display continuously all messages sent by the printer
mosquitto_sub -h ${BAMBU_X1C_IP} -v -t '#' 

# Send them to a file
mosquitto_sub -h ${BAMBU_X1C_IP} -v -t '#' > bambu-traces-$(date '+%Y-%m-%d_%H-%M').log

# Display all messages except the (continuously sent) reports : there should be nothing
mosquitto_sub -h ${BAMBU_X1C_IP} -v -t '#' -T "device/${BAMBU_X1C_ID}/report"

# Extract the %age of the current print in progress from the continuous reports (to monitor progress of current print)
mosquitto_sub -h ${BAMBU_X1C_IP} -t "device/${BAMBU_X1C_ID}/report" | jq '.print.mc_percent' 

(last command is an example with “jq” - extracting the %age of print - with “jq” being IMHO is the proper way to extract - through shell - the informations (with JSON path))
(and again, of course, with a proper PYTHON or GOLANG code, it would be done in a different and nicer / more robust way)

@SR-G this is a nice idea of a simple open source project :slight_smile:

Preferably it should embed a MQTT library to be standalone & executed without dependencies (and maybe as an executable, script require user to install interpreter, not the best for end user)

1 Like

This is a very preliminary draft.

You can try it if you want = this is a “single binary program”, monitoring what is printed and putting results in a .CSV file (then openable in EXCEL or anything else) - and that should then allow to easily group prints and make sum of times.

Results in XLS should be like this :

Executable file is working in LINUX, WINDOWS, … :

It’s just a .exe on windows + a JSON (text) configuration file :

JSON configuration file has to be edited in NOTEPAD.exe (or anything else) in order to change the Bambu Lab IP address (mine is 192.168.8.130) (this is visible inside the printer under “Network” settings, or inside your router) (= no auto-discovery of Bambu IP for now)
screenshot-configuration
(several printers can be monitored, just enter extra IP “BambuLabsIP” : [ “IP1”, “IP2” ])

For now when executed it’s a command line binary displaying some logs over time (START DETECTED, PRINT IN PROGRESS, END, …) (= no graphical or web UI at this time) :

It has to be launched before or after the start of a print (but of course BEFORE the end of any print) and can be kept running all the time on one NAS or one server (new lines will be added in the .CSV file at the end each time a print is finished).

I think i’ll use on my side just for that : build a continuous report of what i’m printing and time taken for each print.

Binaries are here :
https://anonymfile.com/JOOEJ/bambu-lab-observer-100-snapshot.zip

I tried to download the file but it was deleted any chance you could re-share it?

Thanks this looks like it would be exactly what we are looking for!

There is a dedicated thread here (with a more stable binary location) :

1 Like