Bambu Lab X1 X1C MQTT

Has anybody created a downloadable flow for this?

This is all great! Iā€™ll definitely be integrating some of these into my flow, good way to force myself to learn node-red more!

Now Iā€™m curious, if there are ways to publish 3mf files and such to start a print, I wonder if there is anyway to fetch the 3mf print preview image from the printer. Would be neat to do a % colouring of that based on print progress.

Iā€™ll definitely have to look into the liveview, with that added then I think weā€™re able to get pretty much every status worth monitoring except XYZ position. And for controlling, thereā€™s quite a bit there it seems! Good work.

The 3MFā€™s contain a the thumbnail that is used by the printer. Flow could be;

  • Get file name from the MQTT notification of print started
  • FTP to the printer, GET the related 3MF
  • Extract the 3MF (itā€™s ZIP format)
  • Fetch the Thumbnail image.

This may not be the best way, just what I could think of right now.

The thumbnail will be Metadata/plate_1.png which is what is referenced in the ā€œStart a Printā€ MQTT in my Github. The printer itself loads this same file to display it on the screen. I guess also that % print may not line up with % way through an object?

The printer itself doesnā€™t appear to send that information (the image) around in MQTT that Iā€™ve been able to find.

Iā€™m still learning how to get things done in Node Red - how, for example, can I correct the humidity output from the AMS? The value from MQTT is ā€œ3ā€ and ā€œ2ā€ from my AMS units, which just gets passed along as 3% and 2% respectively, which is not remotely correct.

@WolfwithSword I see from your flow screenshot that you have a more reasonable %, how did you get that to work? Hereā€™s my flow for reference:

Some additional commands for you;

Set Print Speed (e.g. Silent etc.)

{"print":{"sequence_id":"2004","command":"print_speed","param":"1"},"user_id":"1234567890"}

Param matches the data you already use for mapping Number ā†’ Name

:warning: :fire: Set Bed Temp (e.g. to pre-heat Chamber for ASA/ABS).

{"print":{"sequence_id":"2006","command":"gcode_line","param":"M140 S90 \n"},"user_id":"1234567890"}

Thatā€™s standard GCode, so easy. 90C in that case. Requires the trailing \n it appears.

Other things you can put in the GCode command which is how the apps do it;

M106 P1 S255 \n - Set Part Cooling to 100%
M106 P2 S255 \n - Set Aux Cooling to 100%

It appears this gcode_line is used a lot, so appears you can throw pretty much anything over MQTT commands :sweat_smile: Be careful with that.

Just swap these into the gcode_line message above and as before these all go to the /device/DEVICEID/request topic.

Thatā€™s strange, Iā€™m able to get the humidity values properly without any modification, currently sitting at 42%. If youā€™re using the .humidity value then maybe your AMS is soaking up the humidity really well :slight_smile:

Iā€™m surprised how low mine, since my area is usually quite humid outside of winter, and once winter hits we run humidifiers like no tomorrow.

Yeah, Iā€™m pretty sure the fact that gcode commands can be arbitrarily sent like that is one of the recent concerns that was brought up for their security. Iā€™d be surprised if the MQTT broker stays like it is, at the very least I hope if it gets auth, we have some way to still access it.

For my personal needs I wouldnā€™t want to do that anyway. My use case is mainly for monitoring and then a few bonuses like toggling the light, set speed, maybe an emergency pause/stop/resume.

I think I will integrate that set print speed command you got into my flow and see how to share it. Probably make a sanitized version in github maybe? Not sure how best to share NodeRed flows.

I will try tackling getting that thumbnail flow though :wink: Then I can try to figure out that liveview you had going.

I am in the beta program running the new firmware so maybe it is a bug - Iā€™m not supposed to discuss possible new features in the beta but letā€™s just say you shouldnā€™t be surprised if AMS humidity is exposed in the front end one day :slight_smile:

Iā€™ll report it up. BTW I have also requested, and will continue to request, some form of local user auth when they do implement the MQTT & related security changes. Allowing users to generate an application key that 3rd party software can use to read data isnā€™t difficult, itā€™s just a matter of whether they want to officially sanction it or not.

I am making the case they should - Bambu already gets a lot of flack for not being as ā€œopenā€ as say, Prusa, and something like this would help.

My conversation with them indicates they donā€™t mind us using MQTT, however they also wonā€™t guarantee that it stays as is. I would expect some changes to it - Iā€™d expect it only being there in LAN Only Mode and potentially using the same method that FTP uses for login (username, password from on device).

My chats are outside of the beta program, via support.

Iā€™m not going to comment on the security things, I have my own views on that and the way it was approached by the person and they arenā€™t for here :upside_down_face:

Oh, one set of things I forgot to include in the other postā€¦

Note: These are very lightly tested, they seem to work for me but YMMV etc.

Unload a filament thatā€™s been loaded (e.g. is all the way down to the extruder).

{"print":{"sequence_id":"2027","command":"gcode_line","param":"M620 S255\nM104 S250\nG28 X\nG91\nG1 Z3.0 F1200\nG90\n\nG1 X70 F12000\nG1 Y245\nG1 Y265 F3000\nM109 S250\nG1 X120 F12000\n\nG1 X20 Y50 F12000\nG1 Y-3\n\nT255\nM104 S25\nG1 X165 F5000\nG1 Y245\n\nG91\nG1 Z-3.0 F1200\nG90\nM621 S255\n"},"user_id":"1234567890"}

Load a filament and do the load purge.

{"print":{"sequence_id":"2024","command":"gcode_line","param":"M620 S2\nM104 S250\nG28 X\nG91\nG1 Z3.0 F1200\nG90\n\nG1 X70 F12000\nG1 Y245\nG1 Y265 F3000\nM109 S250\nG1 X120 F12000\n\nG1 X20 Y50 F12000\nG1 Y-3\n\nT2\n\nG1 X54  F12000\nG1 Y265\nM400\nM106 P1 S0\nG92 E0\nG1 E40 F200\nM400\nM109 S210\nM400\nM106 P1 S255\nG92 E0\nG1 E5 F300\nM400\nM106 P1 S0\nG1 X70  F9000\nG1 X76 F15000\nG1 X65 F15000\nG1 X76 F15000\nG1 X65 F15000\n\nG1 X70 F6000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X165 F5000\nG1 Y245\n\nG91\nG1 Z-3.0 F1200\nG90\nM621 S2"},"user_id":"1234567890"}

M620 S2 and M621 S2 relates to Slot 3 on the AMS. I canā€™t see more than 0-3 as I only have one AMS. Again these are captured from Bambu Handy so what Bambu is doing themselves.

My reason for snagging these is then I can set the filament type, colour, slot, and trigger a load all at the same time. As the colours are RGBA that are sent to the printer you can easy set this from a colour wheel or the like. Is that overkill? Absolutely :rofl:

1 Like

At least we can tinker around and have fun for the moment :smiley:

I havenā€™t tested yet but, for setting the filament type can it accept any string or a list of pre-defined ones? Because if we can set the tray_type to anything, then I can finally not be bothered by the fact my PLA+ is labelled as PLA. If only we could spoof the RFID tags for other filament rolls, but this would be a good compromise if it worked!

If it doesnā€™t match what it expectā€™s it ignores it. No PLA+ setting for the UI etc. so stuck with it saying PLA for now unless they add a mapping in.

Iā€™ve only grabbed the Generic ones so far, happy to get for the Bambu ones if needed.

Ah, shame. I assume that applies for all the other filament properties like subbrand type from RFID tags. I was surprised when Polymakerā€™s presets were in there since thatā€™s what I print with 80% of the time.

Think Iā€™ll personally keep updating those manually, since I have to be there manually anyways to put in filamentā€¦ Nevermind, I just convinced myself to make a filament_tray editor sort of functionality. If I canā€™t spoof bambuā€™s RFID tags, then Iā€™ll just hack up some NFC readers/tags into my AMS for my own spools to trigger auto-tray configuration. Alright, I know my xmas project now.

Though before I start putting an ESP module in my AMS with 4 NFC readers, I wonder if even failed RFID read events are sent via MQTT, and if so, I wonder if it can still read enough data that maybe I could fetch a single unique value from an unrecognized tag and identify settings from a dictionary/libraryā€¦

1 Like

Iā€™ve only got the one spool with RFID - eSun is pretty much the only stuff local here.

Having waved other RFID tags of the correct format/type at it while itā€™s loading spools, it seems to ignore them. The MQTT notification around the thing in the tray slot only appears to have information once itā€™s been detected without issue (or itā€™s given up). Admittedly, Iā€™ve not done a huge amount of testing on that one as it was on my todo list to actually work out the tag format over the summer break.

Hereā€™s the other Filaments from MQTT Requests:

Polylite PLA :{"print":{"sequence_id":"2045","command":"ams_filament_setting","ams_id":0,"tray_id":3,"tray_info_idx":"GFL00","tray_color":"161616FF","nozzle_temp_min":190,"nozzle_temp_max":250,"tray_type":"PLA"},"user_id":"1234567890"}
PolyTerra PLA: {"print":{"sequence_id":"2047","command":"ams_filament_setting","ams_id":0,"tray_id":3,"tray_info_idx":"GFL01","tray_color":"161616FF","nozzle_temp_min":190,"nozzle_temp_max":250,"tray_type":"PLA"},"user_id":"1234567890"}

Bambu ABS: {"print":{"sequence_id":"2051","command":"ams_filament_setting","ams_id":0,"tray_id":3,"tray_info_idx":"GFB00","tray_color":"161616FF","nozzle_temp_min":240,"nozzle_temp_max":270,"tray_type":"ABS"},"user_id":"1234567890"}
Bambu PA-CF: {"print":{"sequence_id":"2053","command":"ams_filament_setting","ams_id":0,"tray_id":3,"tray_info_idx":"GFN03","tray_color":"161616FF","nozzle_temp_min":270,"nozzle_temp_max":300,"tray_type":"PA-CF"},"user_id":"1234567890"}
Bambu PC: {"print":{"sequence_id":"2054","command":"ams_filament_setting","ams_id":0,"tray_id":3,"tray_info_idx":"GFC00","tray_color":"161616FF","nozzle_temp_min":260,"nozzle_temp_max":280,"tray_type":"PC"},"user_id":"1234567890"}
Bambu PLA Basic: {"print":{"sequence_id":"2056","command":"ams_filament_setting","ams_id":0,"tray_id":3,"tray_info_idx":"GFA00","tray_color":"161616FF","nozzle_temp_min":190,"nozzle_temp_max":250,"tray_type":"PLA"},"user_id":"1234567890"}
Bambu PLA Matte: {"print":{"sequence_id":"2059","command":"ams_filament_setting","ams_id":0,"tray_id":3,"tray_info_idx":"GFA01","tray_color":"161616FF","nozzle_temp_min":190,"nozzle_temp_max":250,"tray_type":"PLA"},"user_id":"1234567890"}
Support G: {"print":{"sequence_id":"2060","command":"ams_filament_setting","ams_id":0,"tray_id":3,"tray_info_idx":"GFS01","tray_color":"161616FF","nozzle_temp_min":190,"nozzle_temp_max":250,"tray_type":"PA-S"},"user_id":"1234567890"}
Support W: {"print":{"sequence_id":"2061","command":"ams_filament_setting","ams_id":0,"tray_id":3,"tray_info_idx":"GFS00","tray_color":"161616FF","nozzle_temp_min":190,"nozzle_temp_max":250,"tray_type":"PLA-S"},"user_id":"1234567890"}
Bambu TPU 95A: {"print":{"sequence_id":"2062","command":"ams_filament_setting","ams_id":0,"tray_id":3,"tray_info_idx":"GFU01","tray_color":"161616FF","nozzle_temp_min":200,"nozzle_temp_max":250,"tray_type":"TPU"},"user_id":"1234567890"}
1 Like

Got around to looking through its FTP server - I assume the gcode, 3mf, and other associated files are only there if you manually (or via your script @darkorb) upload the files to the sd card? For prints that I upload via the bambu slicer instead, it doesnā€™t seem to create anything unless Iā€™m looking in the wrong place.

Itā€™s interesting because it does say that the print is using /data/Metadata/plate_1.gcode, but when I look in the FTP directory I only see some misc files, and ipcam and timelapse folders. Iā€™ve actually yet to load any files onto the SD card and Iā€™ve had the printer since late Aug / early Sept. Octoprint on my old printerā€™s spoiled me with remote uploading/printing and I guess I got used to it.

Thatā€™s correct.

The /data/Metadata/plate_1.gcode Iā€™m guessing is from the point at which you load a print, itā€™ll extract the 3mf/zip file on some (local?) storage. This is the inside of an extracted one I use for testing as an example;

  inflating: [Content_Types].xml
  extracting: Metadata/plate_1.png
  extracting: Metadata/plate_1_pattern_layer_0.png
  inflating: Metadata/plate_1.json
  inflating: 3D/3dmodel.model
  inflating: 3D/_rels/3dmodel.model.rels
  inflating: 3D/Objects/CatGhost.stl_1.model
  inflating: Metadata/project_settings.config
  inflating: Metadata/model_settings.config
  inflating: Metadata/slice_info.config
  inflating: _rels/.rels

The 3D/Objects/CatGhost.stl_1.model in this case is the XML file that contains the actual item to print. You can see how thatā€™d line up with the file name it references, Iā€™m guessing /data/ being a mount point of some internal storage somewhere. Iā€™m unaware of a way to get ā€œoutsideā€ the environment presented by the FTP server at the moment (Iā€™m trying though :sweat_smile:).

If you reprint from cloud (e.g. from Handy) it fetches the file from Bambuā€™s servers and printed from there. Iā€™ve not dug into that too much yet, maybe one for the weekend.

I also have a local_print.gcode.3mf which seems to be updated with the most recent object I printed when done through the Slicerā€™s Print button.

The Octoprint thing/Klipper is why I did the script in the end. Being able to save a file to a location and have it automatically upload is a thing I missed.

Yeah, thatā€™s part of the reason I want to attempt to dockerize the whole bambuslicer and essentially make my ā€œownā€ bambu cloud via my unraid server. Would let me keep all the files in one place easier and access it from anywhere. Though in that case I could probably get around trying to fetch thumbnails or anything by instead just polling the dockerā€™s mounted directory for matching name and stuff.

Okay as I was typing this I loaded up a second print and now I am all sorts of confused. I also now have the local_print_gcode.3mf, but I didnā€™t have it for the print I just finishedā€¦

Iā€™ve only ever started/uploaded a print via the slicerā€™s print button, and have never been in LAN only mode (except to get the access code for the ftp password).

It was (almost) this easy :slight_smile:

Iā€™ve managed to extract the image from the zip file now, assuming there is a 3mf file present. My current flow for this has 0 error handling if it doesnā€™t exist yet, or if the server is down etc. But it works! Currently I have a test button hooked up to force it to run, as well as an http service for testing.

image

Needed a few extra palettes installed.

  • node-red-contrib-zip
  • node-red-contrib-ftp
  • node-red-node-base64

Get Print File FTP in node:

Summary

image

FTP Server is the IP of the printer.

Filename is the 3mf file that should be in the ftp server. It may not always be there*

Local filename is the output file it downloads to. Make sure the directory exists first.

The delay is necessary before reading the file otherwise it reads 0 bytes. It could probably work with 1-2 seconds but to be safe I just have 5s, since it fetches the whole 3mf file.

Read 3mf & Decompress:

Summary

image

image

Extract Preview Image Buffer

Summary

You can ignore the stuff regarding msg.req and the status code unless you implement the http server.

var image = null;

if (msg.payload !== undefined && msg.payload.length > 0) {

    for (var file of msg.payload) {

        if (file.filename == "Metadata/plate_1.png") {

            image = file.payload;

            break;

        }

    }

}

if (image !== null) {

    msg.payload = image;

    if(msg.req !== undefined) {

        msg.statusCode = 200;

    }

    node.send(msg);

}

If you want an HTTP server to respond with the image file as a download, put the output of this function to the http response node.

base64 & Write Image

Summary

To write the image, you need to do the following

image
image

Make sure the directory exists first, the ā€œcreate if it doesnā€™t existā€ may not always work.


Now I just need to figure out the best way to use this image in HA. I could write the image to HAā€™s www directory, but Iā€™d rather not because thatā€™s asking for caching issues down the line.

Thought Iā€™d try using HTTP response and return the image, but the frontend in HA uses the browserā€™s network for http requests, so I canā€™t rely on my docker networkā€™s resolving there. I suppose I could ā€œfakeā€ it in my reverse proxy by redirecting a very specific /local/media path to somewhere else, but this isnā€™t suitable for most other peopleā€™s setups.

For now I may rely on writing it to HAā€™s www directory, which means NodeRed needs that mounted. Over the weekend I may try to find a better way to send the image upon request maybe? I know caching issues will come and bite me as always :stuck_out_tongue:

I may also try seeing if I could remove the white background via NR, but that may be overboard for now.

1 Like

The images should have a transparent layer to them, so shouldnā€™t need anything weird with the image processing?

The image for the first layer preview has transparency, but the other image (which also displays on the x1c lcd screen) is a more 3D view and has a white background. Iā€™m trying to use the other one as the first layer generated image may not look useful for all prints.

At least this was the case with my most recent print & 3mf file. And I recall most of the time seeing this white background before on the LCD screenā€™s preview too.