Created
January 24, 2025 08:48
-
-
Save Benny-Git/9d51f470650f1fd7bb98e57a2b98f223 to your computer and use it in GitHub Desktop.
Advertise a Bambu printer to Orca Slicer / Bambu Studio
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Derived from this: https://gist.github.com/Alex-Schaefer/72a9e2491a42da2ef99fb87601955cc3 | |
# This script mimics my Bambu printer's behavior and keeps advertising itself via SSDP every 5s. | |
# You could keep this running in the background, so you don't have to remember starting it whenever you start Orca Slicer or Bambu Studio. | |
import sys | |
import socket | |
import time | |
from datetime import datetime | |
TARGET_IP = "127.0.0.1" # Change this to the IP of the computer with the printer software. If you're running this on the same computer, leave it as is. | |
PRINTER_USN = "yourserial" # This is the serial number of the printer. https://wiki.bambulab.com/en/general/find-sn | |
PRINTER_DEV_MODEL = "C12" # "3DPrinter-X1-Carbon", "3DPrinter-X1", "C11" (for P1P), "C12" (for P1S), "C13" (for X1E), "N1" (A1 mini), "N2S" (A1) | |
PRINTER_DEV_NAME = "Drucker 001" # The friendly name displayed in Bambu Studio / Orca Slicer. Set this to whatever you want. | |
PRINTER_DEV_SIGNAL = "-44" # Fake wifi signal strength | |
PRINTER_DEV_CONNECT = "lan" # printer is in lan only mode | |
PRINTER_DEV_BIND = "free" # and is not bound to any cloud account | |
PRINTER_IP = None # If you want to hardcode the printer IP, set it here. Otherwise, pass it as the first argument to the script. | |
TARGET_PORT = 2021 # The port used for SSDP discovery | |
def send_udp_response(response): | |
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock: | |
try: | |
sock.sendto(response.encode(), (TARGET_IP, TARGET_PORT)) | |
print("UDP packet sent successfully.") | |
except socket.error as e: | |
print("Error sending UDP packet:", e) | |
def resolve_and_validate(input_str): | |
"""Resolve a hostname or FQDN to an IP address, or just return the IP address after validating it.""" | |
try: | |
# This will work for both FQDN and hostname | |
return socket.gethostbyname(input_str) | |
except socket.gaierror: | |
# If resolution fails, check if it's a valid IP | |
try: | |
socket.inet_aton(input_str) | |
return input_str # It's a valid IP, so return it as-is | |
except socket.error: | |
print(f"Unable to resolve {input_str} to an IP address.") | |
sys.exit(2) | |
def main(): | |
if PRINTER_IP is None: | |
# If PRINTER_IP is not set, check if it was passed as an argument | |
if len(sys.argv) == 2: | |
provided_ip = sys.argv[1] | |
else: | |
print("Please specify your printer's IP, FQDN or hostname.\nusage:", sys.argv[0], "<PRINTER_IP>\nAlternatively, set PRINTER_IP in the script.") | |
sys.exit(2) | |
else: | |
# If PRINTER_IP is set, use that | |
provided_ip = PRINTER_IP | |
# Now that we have a printer IP, FQDN or hostname, resolve and validate it | |
printer_ip = resolve_and_validate(provided_ip) | |
response = ( | |
f"NOTIFY * HTTP/1.1\r\n" | |
f"HOST: 239.255.255.250:1900\r\n" | |
f"Server: UPnP/1.0\r\n" | |
f"Location: {printer_ip}\r\n" | |
f"NT: urn:bambulab-com:device:3dprinter:1\r\n" | |
f"USN: {PRINTER_USN}\r\n" | |
f"Cache-Control: max-age=1800\r\n" | |
f"DevModel.bambu.com: {PRINTER_DEV_MODEL}\r\n" | |
f"DevName.bambu.com: {PRINTER_DEV_NAME}\r\n" | |
f"DevSignal.bambu.com: {PRINTER_DEV_SIGNAL}\r\n" | |
f"DevConnect.bambu.com: {PRINTER_DEV_CONNECT}\r\n" | |
f"DevBind.bambu.com: {PRINTER_DEV_BIND}\r\n" | |
f"Devseclink.bambu.com: secure\r\n" | |
f"DevVersion.bambu.com: 01.07.00.00\r\n" | |
f"DevCap.bambu.com: 1\r\n\r\n" | |
) | |
while True: | |
print(f"{datetime.now()} Sending response with PRINTER_IP={printer_ip} to {TARGET_IP}:{TARGET_PORT}") | |
send_udp_response(response) | |
time.sleep(5) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Derived from https://gist.github.com/Alex-Schaefer/72a9e2491a42da2ef99fb87601955cc3