Compare commits

...

9 Commits

Author SHA1 Message Date
8af0f9e8a1 add support for M355 command to control chamber light, #67 2025-01-23 23:40:45 -05:00
ca30e0fe24 fix typo, #64 2024-12-29 12:58:04 -05:00
383f0c3cb3 fix new cloud verification process 2024-12-07 00:17:57 -05:00
8950778146 add missing constants from upstream pybambu module 2024-12-01 17:13:39 -05:00
52ba3ff214 0.1.8rc12
update pybambu module from upstream HA project
2024-12-01 16:30:12 -05:00
98ab94b371 0.1.8rc11
update pybambu/bambu_cloud.py from upstream HA project
2024-11-14 23:35:03 -05:00
b54e372342 0.1.8rc10
reduce settings save by refactoring ams data updates
2024-11-14 21:26:41 -05:00
76f706df19 0.1.8rc9
* check for filename in cache subfolder for files started through cloud connected printers
* send 0% progress when in prepare state and progress is 100
* minor UI tweaks
2024-11-09 21:57:17 -05:00
5c8a9787d4 0.1.8rc8
* updates to pybambu module
* update cloud login workflow, #59
2024-11-09 20:01:41 -05:00
17 changed files with 1761 additions and 1267 deletions

View File

@ -61,6 +61,7 @@ class BambuPrintPlugin(
_plugin_manager: octoprint.plugin.PluginManager _plugin_manager: octoprint.plugin.PluginManager
_bambu_file_system: RemoteSDCardFileList _bambu_file_system: RemoteSDCardFileList
_timelapse_files_view: CachedFileView _timelapse_files_view: CachedFileView
_bambu_cloud: None
def on_settings_initialized(self): def on_settings_initialized(self):
self._bambu_file_system = RemoteSDCardFileList(self._settings) self._bambu_file_system = RemoteSDCardFileList(self._settings)
@ -117,7 +118,8 @@ class BambuPrintPlugin(
return True return True
def get_api_commands(self): def get_api_commands(self):
return {"register": ["email", "password", "region", "auth_token"]} return {"register": ["email", "password", "region", "auth_token"],
"verify": ["auth_type", "password"]}
def on_api_command(self, command, data): def on_api_command(self, command, data):
if command == "register": if command == "register":
@ -128,16 +130,42 @@ class BambuPrintPlugin(
and "auth_token" in data and "auth_token" in data
): ):
self._logger.info(f"Registering user {data['email']}") self._logger.info(f"Registering user {data['email']}")
bambu_cloud = BambuCloud( self._bambu_cloud = BambuCloud(data["region"], data["email"], data["password"], data["auth_token"])
data["region"], data["email"], data["password"], data["auth_token"] auth_response = self._bambu_cloud.login(data["region"], data["email"], data["password"])
)
bambu_cloud.login(data["region"], data["email"], data["password"])
return flask.jsonify( return flask.jsonify(
{ {
"auth_token": bambu_cloud.auth_token, "auth_response": auth_response,
"username": bambu_cloud.username,
} }
) )
elif command == "verify":
auth_response = None
if (
"auth_type" in data
and "password" in data
and self._bambu_cloud is not None
):
self._logger.info(f"Verifying user {self._bambu_cloud._email}")
if data["auth_type"] == "verifyCode":
auth_response = self._bambu_cloud.login_with_verification_code(data["password"])
elif data["auth_type"] == "tfa":
auth_response = self._bambu_cloud.login_with_2fa_code(data["password"])
else:
self._logger.warning(f"Unknown verification type: {data['auth_type']}")
if auth_response == "success":
return flask.jsonify(
{
"auth_token": self._bambu_cloud.auth_token,
"username": self._bambu_cloud.username
}
)
else:
self._logger.info(f"Error verifying: {auth_response}")
return flask.jsonify(
{
"error": "Unable to verify"
}
)
def on_event(self, event, payload): def on_event(self, event, payload):
if event == Events.TRANSFER_DONE: if event == Events.TRANSFER_DONE:

View File

@ -170,22 +170,6 @@ class BambuVirtualPrinter:
def change_state(self, new_state: APrinterState): def change_state(self, new_state: APrinterState):
self._state_change_queue.put(new_state) self._state_change_queue.put(new_state)
def _convert2serialize(self, obj):
if isinstance(obj, dict):
return {k: self._convert2serialize(v) for k, v in obj.items()}
elif hasattr(obj, "_ast"):
return self._convert2serialize(obj._ast())
elif not isinstance(obj, str) and hasattr(obj, "__iter__"):
return [self._convert2serialize(v) for v in obj]
elif hasattr(obj, "__dict__"):
return {
k: self._convert2serialize(v)
for k, v in obj.__dict__.items()
if not callable(v) and not k.startswith('_')
}
else:
return obj
def new_update(self, event_type): def new_update(self, event_type):
if event_type == "event_hms_errors": if event_type == "event_hms_errors":
self._update_hms_errors() self._update_hms_errors()
@ -196,7 +180,8 @@ class BambuVirtualPrinter:
device_data = self.bambu_client.get_device() device_data = self.bambu_client.get_device()
print_job_state = device_data.print_job.gcode_state print_job_state = device_data.print_job.gcode_state
temperatures = device_data.temperature temperatures = device_data.temperature
ams_data = self._convert2serialize(device_data.ams.data) # strip out extra data to avoid unneeded settings updates
ams_data = [{"tray": asdict(x).pop("tray", None)} for x in device_data.ams.data if x is not None]
if self.ams_data != ams_data: if self.ams_data != ams_data:
self._log.debug(f"Recieveid AMS Update: {ams_data}") self._log.debug(f"Recieveid AMS Update: {ams_data}")
@ -274,19 +259,20 @@ class BambuVirtualPrinter:
f"connecting via local mqtt: {self._settings.get_boolean(['local_mqtt'])}" f"connecting via local mqtt: {self._settings.get_boolean(['local_mqtt'])}"
) )
bambu_client = BambuClient( bambu_client = BambuClient(
device_type=self._settings.get(["device_type"]), {"device_type": self._settings.get(["device_type"]),
serial=self._settings.get(["serial"]), "serial": self._settings.get(["serial"]),
host=self._settings.get(["host"]), "host": self._settings.get(["host"]),
username=( "username": (
"bblp" "bblp"
if self._settings.get_boolean(["local_mqtt"]) if self._settings.get_boolean(["local_mqtt"])
else self._settings.get(["username"]) else self._settings.get(["username"])
), ),
access_code=self._settings.get(["access_code"]), "access_code": self._settings.get(["access_code"]),
local_mqtt=self._settings.get_boolean(["local_mqtt"]), "local_mqtt": self._settings.get_boolean(["local_mqtt"]),
region=self._settings.get(["region"]), "region": self._settings.get(["region"]),
email=self._settings.get(["email"]), "email": self._settings.get(["email"]),
auth_token=self._settings.get(["auth_token"]), "auth_token": self._settings.get(["auth_token"]) if self._settings.get_boolean(["local_mqtt"]) is False else "",
}
) )
bambu_client.on_disconnect = self.on_disconnect(bambu_client.on_disconnect) bambu_client.on_disconnect = self.on_disconnect(bambu_client.on_disconnect)
bambu_client.on_connect = self.on_connect(bambu_client.on_connect) bambu_client.on_connect = self.on_connect(bambu_client.on_connect)
@ -610,6 +596,17 @@ class BambuVirtualPrinter:
self._current_state.pause_print() self._current_state.pause_print()
return True return True
@gcode_executor.register("M355")
def _case_lights(self, data: str) -> bool:
if data == "M355 S1":
light_command = commands.CHAMBER_LIGHT_ON
elif data == "M355 S0":
light_command = commands.CHAMBER_LIGHT_OFF
else:
return False
return self.bambu_client.publish(light_command)
@gcode_executor.register("M524") @gcode_executor.register("M524")
def _cancel_print(self): def _cancel_print(self):
self._current_state.cancel_print() self._current_state.cancel_print()

View File

@ -86,6 +86,10 @@ class CachedFileView:
file_name = f"{file_name}.3mf" file_name = f"{file_name}.3mf"
elif f"{file_name}.gcode.3mf" in file_list: elif f"{file_name}.gcode.3mf" in file_list:
file_name = f"{file_name}.gcode.3mf" file_name = f"{file_name}.gcode.3mf"
elif f"cache/{file_name}.3mf" in file_list:
file_name = f"cache/{file_name}.3mf"
elif f"cache/{file_name}.gcode.3mf" in file_list:
file_name = f"cache/{file_name}.gcode.3mf"
file_data = self.get_file_data_cached(file_name) file_data = self.get_file_data_cached(file_name)
if file_data is None: if file_data is None:

View File

@ -181,7 +181,7 @@ class ChamberImageThread(threading.Thread):
# Reset buffer # Reset buffer
img = None img = None
# else: # else:
# Otherwise we need to continue looping without reseting the buffer to receive the remaining data # Otherwise we need to continue looping without reseting the buffer to receive the remaining data
# and without delaying. # and without delaying.
@ -285,25 +285,32 @@ class BambuClient:
_camera = None _camera = None
_usage_hours: float _usage_hours: float
def __init__(self, device_type: str, serial: str, host: str, local_mqtt: bool, region: str, email: str, def __init__(self, config):
username: str, auth_token: str, access_code: str, usage_hours: float = 0, manual_refresh_mode: bool = False, chamber_image: bool = True): self.host = config['host']
self.callback = None self._callback = None
self.host = host
self._local_mqtt = local_mqtt self._access_code = config.get('access_code', '')
self._serial = serial self._auth_token = config.get('auth_token', '')
self._auth_token = auth_token self._device_type = config.get('device_type', 'unknown')
self._access_code = access_code self._local_mqtt = config.get('local_mqtt', False)
self._username = username self._manual_refresh_mode = config.get('manual_refresh_mode', False)
self._serial = config.get('serial', '')
self._usage_hours = config.get('usage_hours', 0)
self._username = config.get('username', '')
self._enable_camera = config.get('enable_camera', True)
self._connected = False self._connected = False
self._device_type = device_type
self._usage_hours = usage_hours
self._port = 1883 self._port = 1883
self._refreshed = False self._refreshed = False
self._manual_refresh_mode = manual_refresh_mode
self._device = Device(self) self._device = Device(self)
self.bambu_cloud = BambuCloud(region, email, username, auth_token) self.bambu_cloud = BambuCloud(
config.get('region', ''),
config.get('email', ''),
config.get('username', ''),
config.get('auth_token', '')
)
self.slicer_settings = SlicerSettings(self) self.slicer_settings = SlicerSettings(self)
self.use_chamber_image = chamber_image
@property @property
def connected(self): def connected(self):
@ -322,7 +329,22 @@ class BambuClient:
self.disconnect() self.disconnect()
else: else:
# Reconnect normally # Reconnect normally
self.connect(self.callback) self.connect(self._callback)
@property
def camera_enabled(self):
return self._enable_camera
def callback(self, event: str):
if self._callback is not None:
self._callback(event)
def set_camera_enabled(self, enable):
self._enable_camera = enable
if self._enable_camera:
self._start_camera()
else:
self._stop_camera()
def setup_tls(self): def setup_tls(self):
self.client.tls_set(tls_version=ssl.PROTOCOL_TLS, cert_reqs=ssl.CERT_NONE) self.client.tls_set(tls_version=ssl.PROTOCOL_TLS, cert_reqs=ssl.CERT_NONE)
@ -331,7 +353,7 @@ class BambuClient:
def connect(self, callback): def connect(self, callback):
"""Connect to the MQTT Broker""" """Connect to the MQTT Broker"""
self.client = mqtt.Client() self.client = mqtt.Client()
self.callback = callback self._callback = callback
self.client.on_connect = self.on_connect self.client.on_connect = self.on_connect
self.client.on_disconnect = self.on_disconnect self.client.on_disconnect = self.on_disconnect
self.client.on_message = self.on_message self.client.on_message = self.on_message
@ -371,6 +393,22 @@ class BambuClient:
LOGGER.info("On Connect: Connected to printer") LOGGER.info("On Connect: Connected to printer")
self._on_connect() self._on_connect()
def _start_camera(self):
if not self._device.supports_feature(Features.CAMERA_RTSP):
if self._device.supports_feature(Features.CAMERA_IMAGE):
if self._enable_camera:
LOGGER.debug("Starting Chamber Image thread")
self._camera = ChamberImageThread(self)
self._camera.start()
elif (self.host == "") or (self._access_code == ""):
LOGGER.debug("Skipping camera setup as local access details not provided.")
def _stop_camera(self):
if self._camera is not None:
LOGGER.debug("Stopping camera thread")
self._camera.stop()
self._camera.join()
def _on_connect(self): def _on_connect(self):
self._connected = True self._connected = True
self.subscribe_and_request_info() self.subscribe_and_request_info()
@ -379,14 +417,7 @@ class BambuClient:
self._watchdog = WatchdogThread(self) self._watchdog = WatchdogThread(self)
self._watchdog.start() self._watchdog.start()
if not self._device.supports_feature(Features.CAMERA_RTSP): self._start_camera()
if self._device.supports_feature(Features.CAMERA_IMAGE):
if self.use_chamber_image:
LOGGER.debug("Starting Chamber Image thread")
self._camera = ChamberImageThread(self)
self._camera.start()
elif (self.host == "") or (self._access_code == ""):
LOGGER.debug("Skipping camera setup as local access details not provided.")
def try_on_connect(self, def try_on_connect(self,
client_: mqtt.Client, client_: mqtt.Client,
@ -410,7 +441,7 @@ class BambuClient:
"""Called when MQTT Disconnects""" """Called when MQTT Disconnects"""
LOGGER.warn(f"On Disconnect: Printer disconnected with error code: {result_code}") LOGGER.warn(f"On Disconnect: Printer disconnected with error code: {result_code}")
self._on_disconnect() self._on_disconnect()
def _on_disconnect(self): def _on_disconnect(self):
LOGGER.debug("_on_disconnect: Lost connection to the printer") LOGGER.debug("_on_disconnect: Lost connection to the printer")
self._connected = False self._connected = False
@ -419,10 +450,7 @@ class BambuClient:
LOGGER.debug("Stopping watchdog thread") LOGGER.debug("Stopping watchdog thread")
self._watchdog.stop() self._watchdog.stop()
self._watchdog.join() self._watchdog.join()
if self._camera is not None: self._stop_camera()
LOGGER.debug("Stopping camera thread")
self._camera.stop()
self._camera.join()
def _on_watchdog_fired(self): def _on_watchdog_fired(self):
LOGGER.info("Watch dog fired") LOGGER.info("Watch dog fired")
@ -487,7 +515,7 @@ class BambuClient:
"""Force refresh data""" """Force refresh data"""
if self._manual_refresh_mode: if self._manual_refresh_mode:
self.connect(self.callback) self.connect(self._callback)
else: else:
LOGGER.debug("Force Refresh: Getting Version Info") LOGGER.debug("Force Refresh: Getting Version Info")
self._refreshed = True self._refreshed = True
@ -531,7 +559,7 @@ class BambuClient:
# Run the blocking tls_set method in a separate thread # Run the blocking tls_set method in a separate thread
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
await loop.run_in_executor(None, self.setup_tls) await loop.run_in_executor(None, self.setup_tls)
if self._local_mqtt: if self._local_mqtt:
self.client.username_pw_set("bblp", password=self._access_code) self.client.username_pw_set("bblp", password=self._access_code)
else: else:

View File

@ -1,9 +1,27 @@
from __future__ import annotations from __future__ import annotations
from enum import (
Enum,
)
import base64 import base64
import cloudscraper
import json import json
import requests
from curl_cffi import requests class ConnectionMechanismEnum(Enum):
CLOUDSCRAPER = 1,
CURL_CFFI = 2,
REQUESTS = 3
CONNECTION_MECHANISM = ConnectionMechanismEnum.CLOUDSCRAPER
curl_available = False
if CONNECTION_MECHANISM == ConnectionMechanismEnum.CURL_CFFI:
try:
from curl_cffi import requests as curl_requests
curl_available = True
except ImportError:
curl_available = False
from dataclasses import dataclass from dataclasses import dataclass
@ -16,9 +34,39 @@ from .utils import get_Url
IMPERSONATE_BROWSER='chrome' IMPERSONATE_BROWSER='chrome'
class CloudflareError(Exception):
def __init__(self):
super().__init__("Blocked by Cloudflare")
self.error_code = 403
class EmailCodeRequiredError(Exception):
def __init__(self):
super().__init__("Email code required")
self.error_code = 400
class EmailCodeExpiredError(Exception):
def __init__(self):
super().__init__("Email code expired")
self.error_code = 400
class EmailCodeIncorrectError(Exception):
def __init__(self):
super().__init__("Email code incorrect")
self.error_code = 400
class TfaCodeRequiredError(Exception):
def __init__(self):
super().__init__("Two factor authentication code required")
self.error_code = 400
class CurlUnavailableError(Exception):
def __init__(self):
super().__init__("curl library unavailable")
self.error_code = 400
@dataclass @dataclass
class BambuCloud: class BambuCloud:
def __init__(self, region: str, email: str, username: str, auth_token: str): def __init__(self, region: str, email: str, username: str, auth_token: str):
self._region = region self._region = region
self._email = email self._email = email
@ -26,12 +74,100 @@ class BambuCloud:
self._auth_token = auth_token self._auth_token = auth_token
self._tfaKey = None self._tfaKey = None
def _get_headers(self):
return {
'User-Agent': 'bambu_network_agent/01.09.05.01',
'X-BBL-Client-Name': 'OrcaSlicer',
'X-BBL-Client-Type': 'slicer',
'X-BBL-Client-Version': '01.09.05.51',
'X-BBL-Language': 'en-US',
'X-BBL-OS-Type': 'linux',
'X-BBL-OS-Version': '6.2.0',
'X-BBL-Agent-Version': '01.09.05.01',
'X-BBL-Executable-info': '{}',
'X-BBL-Agent-OS-Type': 'linux',
'accept': 'application/json',
'Content-Type': 'application/json'
}
# Orca/Bambu Studio also add this - need to work out what an appropriate ID is to put here:
# 'X-BBL-Device-ID': BBL_AUTH_UUID,
# Example: X-BBL-Device-ID: 370f9f43-c6fe-47d7-aec9-5fe5ef7e7673
def _get_headers_with_auth_token(self) -> dict: def _get_headers_with_auth_token(self) -> dict:
headers = {} if CONNECTION_MECHANISM == ConnectionMechanismEnum.CURL_CFFI:
headers = {}
else:
headers = self._get_headers()
headers['Authorization'] = f"Bearer {self._auth_token}" headers['Authorization'] = f"Bearer {self._auth_token}"
return headers return headers
def _get_authentication_token(self) -> dict: def _test_response(self, response, return400=False):
# Check specifically for cloudflare block
if response.status_code == 403 and 'cloudflare' in response.text:
LOGGER.debug("BLOCKED BY CLOUDFLARE")
raise CloudflareError()
if response.status_code == 400 and not return400:
LOGGER.error(f"Connection failed with error code: {response.status_code}")
LOGGER.debug(f"Response: '{response.text}'")
raise PermissionError(response.status_code, response.text)
if response.status_code > 400:
LOGGER.error(f"Connection failed with error code: {response.status_code}")
LOGGER.debug(f"Response: '{response.text}'")
raise PermissionError(response.status_code, response.text)
LOGGER.debug(f"Response: {response.status_code}")
def _get(self, urlenum: BambuUrl):
url = get_Url(urlenum, self._region)
headers=self._get_headers_with_auth_token()
if CONNECTION_MECHANISM == ConnectionMechanismEnum.CURL_CFFI:
if not curl_available:
LOGGER.debug(f"Curl library is unavailable.")
raise CurlUnavailableError()
response = curl_requests.get(url, headers=headers, timeout=10, impersonate=IMPERSONATE_BROWSER)
elif CONNECTION_MECHANISM == ConnectionMechanismEnum.CLOUDSCRAPER:
if len(headers) == 0:
headers = self._get_headers()
scraper = cloudscraper.create_scraper()
response = scraper.get(url, headers=headers, timeout=10)
elif CONNECTION_MECHANISM == ConnectionMechanismEnum.REQUESTS:
if len(headers) == 0:
headers = self._get_headers()
response = requests.get(url, headers=headers, timeout=10)
else:
raise NotImplementedError()
self._test_response(response)
return response
def _post(self, urlenum: BambuUrl, json: str, headers={}, return400=False):
url = get_Url(urlenum, self._region)
if CONNECTION_MECHANISM == ConnectionMechanismEnum.CURL_CFFI:
if not curl_available:
LOGGER.debug(f"Curl library is unavailable.")
raise CurlUnavailableError()
response = curl_requests.post(url, headers=headers, json=json, impersonate=IMPERSONATE_BROWSER)
elif CONNECTION_MECHANISM == ConnectionMechanismEnum.CLOUDSCRAPER:
if len(headers) == 0:
headers = self._get_headers()
scraper = cloudscraper.create_scraper()
response = scraper.post(url, headers=headers, json=json)
elif CONNECTION_MECHANISM == ConnectionMechanismEnum.REQUESTS:
if len(headers) == 0:
headers = self._get_headers()
response = requests.post(url, headers=headers, json=json)
else:
raise NotImplementedError()
self._test_response(response, return400)
return response
def _get_authentication_token(self) -> str:
LOGGER.debug("Getting accessToken from Bambu Cloud") LOGGER.debug("Getting accessToken from Bambu Cloud")
# First we need to find out how Bambu wants us to login. # First we need to find out how Bambu wants us to login.
@ -41,37 +177,34 @@ class BambuCloud:
"apiError": "" "apiError": ""
} }
response = requests.post(get_Url(BambuUrl.LOGIN, self._region), json=data, impersonate=IMPERSONATE_BROWSER) response = self._post(BambuUrl.LOGIN, json=data)
if response.status_code >= 400:
LOGGER.error(f"Login attempt failed with error code: {response.status_code}")
LOGGER.debug(f"Response: '{response.text}'")
raise ValueError(response.status_code)
LOGGER.debug(f"Response: {response.status_code}")
auth_json = response.json() auth_json = response.json()
accessToken = auth_json.get('accessToken', '') accessToken = auth_json.get('accessToken', '')
if accessToken != '': if accessToken != '':
# We were provided the accessToken directly. # We were provided the accessToken directly.
return accessToken return accessToken
loginType = auth_json.get("loginType", None) loginType = auth_json.get("loginType", None)
if loginType is None: if loginType is None:
LOGGER.error(f"loginType not present") LOGGER.error(f"loginType not present")
LOGGER.error(f"Response not understood: '{response.text}'") LOGGER.error(f"Response not understood: '{response.text}'")
return None return ValueError(0) # FIXME
elif loginType == 'verifyCode': elif loginType == 'verifyCode':
LOGGER.debug(f"Received verifyCode response") LOGGER.debug(f"Received verifyCode response")
# raise EmailCodeRequiredError()
return loginType
elif loginType == 'tfa': elif loginType == 'tfa':
# Store the tfaKey for later use # Store the tfaKey for later use
LOGGER.debug(f"Received tfa response") LOGGER.debug(f"Received tfa response")
self._tfaKey = auth_json.get("tfaKey") self._tfaKey = auth_json.get("tfaKey")
# raise TfaCodeRequiredError()
return loginType
else: else:
LOGGER.debug(f"Did not understand json. loginType = '{loginType}'") LOGGER.debug(f"Did not understand json. loginType = '{loginType}'")
LOGGER.error(f"Response not understood: '{response.text}'") LOGGER.error(f"Response not understood: '{response.text}'")
return ValueError(1) # FIXME
return loginType
def _get_email_verification_code(self): def _get_email_verification_code(self):
# Send the verification code request # Send the verification code request
data = { data = {
@ -80,14 +213,8 @@ class BambuCloud:
} }
LOGGER.debug("Requesting verification code") LOGGER.debug("Requesting verification code")
response = requests.post(get_Url(BambuUrl.EMAIL_CODE, self._region), json=data, impersonate=IMPERSONATE_BROWSER) self._post(BambuUrl.EMAIL_CODE, json=data)
LOGGER.debug("Verification code requested successfully.")
if response.status_code == 200:
LOGGER.debug("Verification code requested successfully.")
else:
LOGGER.error(f"Received error trying to send verification code: {response.status_code}")
LOGGER.debug(f"Response: '{response.text}'")
raise ValueError(response.status_code)
def _get_authentication_token_with_verification_code(self, code) -> dict: def _get_authentication_token_with_verification_code(self, code) -> dict:
LOGGER.debug("Attempting to connect with provided verification code.") LOGGER.debug("Attempting to connect with provided verification code.")
@ -96,30 +223,27 @@ class BambuCloud:
"code": code "code": code
} }
response = requests.post(get_Url(BambuUrl.LOGIN, self._region), json=data, impersonate=IMPERSONATE_BROWSER) response = self._post(BambuUrl.LOGIN, json=data, return400=True)
status_code = response.status_code
LOGGER.debug(f"Response: {response.status_code}") if status_code == 200:
if response.status_code == 200:
LOGGER.debug("Authentication successful.") LOGGER.debug("Authentication successful.")
elif response.status_code == 400: LOGGER.debug(f"Response = '{response.json()}'")
LOGGER.debug(f"Response: '{response.json()}'") elif status_code == 400:
LOGGER.debug(f"Received response: {response.json()}")
if response.json()['code'] == 1: if response.json()['code'] == 1:
# Code has expired. Request a new one. # Code has expired. Request a new one.
self._get_email_verification_code() self._get_email_verification_code()
return 'codeExpired' raise EmailCodeExpiredError()
elif response.json()['code'] == 2: elif response.json()['code'] == 2:
# Code was incorrect. Let the user try again. # Code was incorrect. Let the user try again.
return 'codeIncorrect' raise EmailCodeIncorrectError()
else: else:
LOGGER.error(f"Response not understood: '{response.json()}'") LOGGER.error(f"Response not understood: '{response.json()}'")
raise ValueError(response.json()['code']) raise ValueError(response.json()['code'])
else:
LOGGER.error(f"Received error trying to authenticate with verification code: {response.status_code}")
LOGGER.debug(f"Response: '{response.text}'")
raise ValueError(response.status_code)
return response.json()['accessToken'] return response.json()['accessToken']
def _get_authentication_token_with_2fa_code(self, code: str) -> dict: def _get_authentication_token_with_2fa_code(self, code: str) -> dict:
LOGGER.debug("Attempting to connect with provided 2FA code.") LOGGER.debug("Attempting to connect with provided 2FA code.")
@ -128,31 +252,58 @@ class BambuCloud:
"tfaCode": code "tfaCode": code
} }
response = requests.post(get_Url(BambuUrl.TFA_LOGIN, self._region), json=data, impersonate=IMPERSONATE_BROWSER) response = self._post(BambuUrl.TFA_LOGIN, json=data)
LOGGER.debug(f"Response: {response.status_code}") LOGGER.debug(f"Response: {response.status_code}")
if response.status_code == 200: if response.status_code == 200:
LOGGER.debug("Authentication successful.") LOGGER.debug("Authentication successful.")
else:
LOGGER.error(f"Received error trying to authenticate with verification code: {response.status_code}")
LOGGER.debug(f"Response: '{response.text}'")
raise ValueError(response.status_code)
cookies = response.cookies.get_dict() cookies = response.cookies.get_dict()
token_from_tfa = cookies.get("token") token_from_tfa = cookies.get("token")
LOGGER.debug(f"token_from_tfa: {token_from_tfa}") #LOGGER.debug(f"token_from_tfa: {token_from_tfa}")
return token_from_tfa return token_from_tfa
def _get_username_from_authentication_token(self) -> str: def _get_username_from_authentication_token(self) -> str:
LOGGER.debug("Trying to get username from authentication token.")
# User name is in 2nd portion of the auth token (delimited with periods) # User name is in 2nd portion of the auth token (delimited with periods)
b64_string = self._auth_token.split(".")[1] username = None
# String must be multiples of 4 chars in length. For decode pad with = character tokens = self._auth_token.split(".")
b64_string += "=" * ((4 - len(b64_string) % 4) % 4) if len(tokens) != 3:
jsonAuthToken = json.loads(base64.b64decode(b64_string)) LOGGER.debug("Received authToken is not a JWT.")
# Gives json payload with "username":"u_<digits>" within it LOGGER.debug("Trying to use project API to retrieve username instead")
return jsonAuthToken['username'] response = self.get_projects();
if response is not None:
projectsnode = response.get('projects', None)
if projectsnode is None:
LOGGER.debug("Failed to find projects node")
else:
if len(projectsnode) == 0:
LOGGER.debug("No projects node in response")
else:
project=projectsnode[0]
if project.get('user_id', None) is None:
LOGGER.debug("No user_id entry")
else:
username = f"u_{project['user_id']}"
LOGGER.debug(f"Found user_id of {username}")
else:
LOGGER.debug("Authentication token looks to be a JWT")
try:
b64_string = self._auth_token.split(".")[1]
# String must be multiples of 4 chars in length. For decode pad with = character
b64_string += "=" * ((4 - len(b64_string) % 4) % 4)
jsonAuthToken = json.loads(base64.b64decode(b64_string))
# Gives json payload with "username":"u_<digits>" within it
username = jsonAuthToken.get('username', None)
except:
LOGGER.debug("Unable to decode authToken to json to retrieve username.")
if username is None:
LOGGER.debug(f"Unable to decode authToken to retrieve username. AuthToken = {self._auth_token}")
return username
# Retrieves json description of devices in the form: # Retrieves json description of devices in the form:
# { # {
# 'message': 'success', # 'message': 'success',
@ -168,7 +319,7 @@ class BambuCloud:
# 'dev_product_name': 'P1S', # 'dev_product_name': 'P1S',
# 'dev_access_code': 'REDACTED', # 'dev_access_code': 'REDACTED',
# 'nozzle_diameter': 0.4 # 'nozzle_diameter': 0.4
# }, # },
# { # {
# 'dev_id': 'REDACTED', # 'dev_id': 'REDACTED',
# 'name': 'Bambu P1P', # 'name': 'Bambu P1P',
@ -178,7 +329,7 @@ class BambuCloud:
# 'dev_product_name': 'P1P', # 'dev_product_name': 'P1P',
# 'dev_access_code': 'REDACTED', # 'dev_access_code': 'REDACTED',
# 'nozzle_diameter': 0.4 # 'nozzle_diameter': 0.4
# }, # },
# { # {
# 'dev_id': 'REDACTED', # 'dev_id': 'REDACTED',
# 'name': 'Bambu X1C', # 'name': 'Bambu X1C',
@ -188,10 +339,10 @@ class BambuCloud:
# 'dev_product_name': 'X1 Carbon', # 'dev_product_name': 'X1 Carbon',
# 'dev_access_code': 'REDACTED', # 'dev_access_code': 'REDACTED',
# 'nozzle_diameter': 0.4 # 'nozzle_diameter': 0.4
# } # }
# ] # ]
# } # }
def test_authentication(self, region: str, email: str, username: str, auth_token: str) -> bool: def test_authentication(self, region: str, email: str, username: str, auth_token: str) -> bool:
self._region = region self._region = region
self._email = email self._email = email
@ -209,38 +360,38 @@ class BambuCloud:
self._password = password self._password = password
result = self._get_authentication_token() result = self._get_authentication_token()
if result == 'verifyCode': if result is None:
return result
elif result == 'tfa':
return result
elif result is None:
LOGGER.error("Unable to authenticate.") LOGGER.error("Unable to authenticate.")
return None return None
elif len(result) < 20:
return result
else: else:
self._auth_token = result self._auth_token = result
self._username = self._get_username_from_authentication_token() self._username = self._get_username_from_authentication_token()
return 'success' return 'success'
# self._auth_token = result
# self._username = self._get_username_from_authentication_token()
def login_with_verification_code(self, code: str): def login_with_verification_code(self, code: str):
result = self._get_authentication_token_with_verification_code(code) result = self._get_authentication_token_with_verification_code(code)
if result == 'codeExpired' or result == 'codeIncorrect':
return result
self._auth_token = result self._auth_token = result
self._username = self._get_username_from_authentication_token() self._username = self._get_username_from_authentication_token()
return 'success' if self._auth_token != "" and self._username != "" and self._auth_token != None and self._username != None:
return "success"
def login_with_2fa_code(self, code: str): def login_with_2fa_code(self, code: str):
result = self._get_authentication_token_with_2fa_code(code) result = self._get_authentication_token_with_2fa_code(code)
self._auth_token = result self._auth_token = result
self._username = self._get_username_from_authentication_token() self._username = self._get_username_from_authentication_token()
return 'success' if self._auth_token != "" and self._username != "" and self._auth_token != None and self._username != None:
return "success"
def get_device_list(self) -> dict: def get_device_list(self) -> dict:
LOGGER.debug("Getting device list from Bambu Cloud") LOGGER.debug("Getting device list from Bambu Cloud")
response = requests.get(get_Url(BambuUrl.BIND, self._region), headers=self._get_headers_with_auth_token(), timeout=10, impersonate=IMPERSONATE_BROWSER) try:
if response.status_code >= 400: response = self._get(BambuUrl.BIND)
LOGGER.debug(f"Received error: {response.status_code}") except:
raise ValueError(response.status_code) return None
return response.json()['devices'] return response.json()['devices']
# The slicer settings are of the following form: # The slicer settings are of the following form:
@ -312,13 +463,13 @@ class BambuCloud:
def get_slicer_settings(self) -> dict: def get_slicer_settings(self) -> dict:
LOGGER.debug("Getting slicer settings from Bambu Cloud") LOGGER.debug("Getting slicer settings from Bambu Cloud")
response = requests.get(get_Url(BambuUrl.SLICER_SETTINGS, self._region), headers=self._get_headers_with_auth_token(), timeout=10, impersonate=IMPERSONATE_BROWSER) try:
if response.status_code >= 400: response = self._get(BambuUrl.SLICER_SETTINGS)
LOGGER.error(f"Slicer settings load failed: {response.status_code}") except:
LOGGER.error(f"Slicer settings load failed: '{response.text}'")
return None return None
LOGGER.debug("Succeeded")
return response.json() return response.json()
# The task list is of the following form with a 'hits' array with typical 20 entries. # The task list is of the following form with a 'hits' array with typical 20 entries.
# #
# "total": 531, # "total": 531,
@ -362,24 +513,53 @@ class BambuCloud:
# }, # },
def get_tasklist(self) -> dict: def get_tasklist(self) -> dict:
url = get_Url(BambuUrl.TASKS, self._region) LOGGER.debug("Getting full task list from Bambu Cloud")
response = requests.get(url, headers=self._get_headers_with_auth_token(), timeout=10, impersonate=IMPERSONATE_BROWSER) try:
if response.status_code >= 400: response = self._get(BambuUrl.TASKS)
LOGGER.debug(f"Received error: {response.status_code}") except:
LOGGER.debug(f"Received error: '{response.text}'") return None
raise ValueError(response.status_code)
return response.json() return response.json()
# Returns a list of projects for the account.
#
# {
# "message": "success",
# "code": null,
# "error": null,
# "projects": [
# {
# "project_id": "164995388",
# "user_id": "1688388450",
# "model_id": "US48e2103d939bf8",
# "status": "ACTIVE",
# "name": "Alcohol_Marker_Storage_for_Copic,_Ohuhu_and_the_like",
# "content": "{'printed_plates': [{'plate': 1}]}",
# "create_time": "2024-11-17 06:12:33",
# "update_time": "2024-11-17 06:12:40"
# },
# ...
#
def get_projects(self) -> dict:
LOGGER.debug("Getting projects list from Bambu Cloud")
try:
response = self._get(BambuUrl.PROJECTS)
except:
return None
return response.json()
def get_latest_task_for_printer(self, deviceId: str) -> dict: def get_latest_task_for_printer(self, deviceId: str) -> dict:
LOGGER.debug(f"Getting latest task from Bambu Cloud") LOGGER.debug(f"Getting latest task for printer from Bambu Cloud")
data = self.get_tasklist_for_printer(deviceId) try:
if len(data) != 0: data = self.get_tasklist_for_printer(deviceId)
return data[0] if len(data) != 0:
LOGGER.debug("No tasks found for printer") return data[0]
return None LOGGER.debug("No tasks found for printer")
return None
except:
return None
def get_tasklist_for_printer(self, deviceId: str) -> dict: def get_tasklist_for_printer(self, deviceId: str) -> dict:
LOGGER.debug(f"Getting task list from Bambu Cloud") LOGGER.debug(f"Getting full task list for printer from Bambu Cloud")
tasks = [] tasks = []
data = self.get_tasklist() data = self.get_tasklist()
for task in data['hits']: for task in data['hits']:
@ -394,20 +574,25 @@ class BambuCloud:
def download(self, url: str) -> bytearray: def download(self, url: str) -> bytearray:
LOGGER.debug(f"Downloading cover image: {url}") LOGGER.debug(f"Downloading cover image: {url}")
response = requests.get(url, timeout=10, impersonate=IMPERSONATE_BROWSER) try:
if response.status_code >= 400: # This is just a standard download from an unauthenticated end point.
LOGGER.debug(f"Received error: {response.status_code}") response = requests.get(url)
raise ValueError(response.status_code) except:
return None
return response.content return response.content
@property @property
def username(self): def username(self):
return self._username return self._username
@property @property
def auth_token(self): def auth_token(self):
return self._auth_token return self._auth_token
@property
def bambu_connected(self) -> bool:
return self._auth_token != "" and self._auth_token != None
@property @property
def cloud_mqtt_host(self): def cloud_mqtt_host(self):
return "cn.mqtt.bambulab.com" if self._region == "China" else "us.mqtt.bambulab.com" return "cn.mqtt.bambulab.com" if self._region == "China" else "us.mqtt.bambulab.com"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,386 @@
HMS_AMS_ERRORS = {
"0700_0100_0001_0001": "The AMS A assist motor has slipped. The extrusion wheel may be worn down, or the filament may be too thin.",
"0700_0100_0001_0003": "The AMS A assist motor torque control is malfunctioning. The current sensor may be faulty.",
"0700_0100_0001_0004": "The AMS A assist motor speed control is malfunctioning. The speed sensor may be faulty.",
"0700_0100_0001_0011": "AMS A The assist motor calibration parameter error. Please pull out the filament from the filament hub and then restart the AMS.",
"0700_0100_0002_0002": "The AMS A assist motor is overloaded. The filament may be tangled or stuck.",
"0700_0200_0001_0001": "AMS A Filament speed and length error: The filament odometry may be faulty.",
"0700_1000_0001_0001": "The AMS A slot1 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"0700_1000_0001_0003": "The AMS A slot1 motor torque control is malfunctioning. The current sensor may be faulty.",
"0700_1000_0002_0002": "The AMS A slot1 motor is overloaded. The filament may be tangled or stuck.",
"0700_1100_0001_0001": "The AMS A slot2 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"0700_1100_0001_0003": "The AMS A slot2 motor torque control is malfunctioning. The current sensor may be faulty.",
"0700_1100_0002_0002": "The AMS A slot2 motor is overloaded. The filament may be tangled or stuck.",
"0700_1200_0001_0001": "The AMS A slot3 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"0700_1200_0001_0003": "The AMS A slot3 motor torque control is malfunctioning. The current sensor may be faulty.",
"0700_1200_0002_0002": "The AMS A slot3 motor is overloaded. The filament may be tangled or stuck.",
"0700_1300_0001_0001": "The AMS A slot4 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"0700_1300_0001_0003": "The AMS A slot4 motor torque control is malfunctioning. The current sensor may be faulty.",
"0700_1300_0002_0002": "The AMS A slot4 motor is overloaded. The filament may be tangled or stuck.",
"0700_2000_0002_0001": "AMS A Slot1 filament has run out. Please insert a new filament.",
"0700_2000_0002_0002": "AMS A Slot1 is empty; please insert a new filament.",
"0700_2000_0002_0003": "AMS A Slot1's filament may be broken in AMS.",
"0700_2000_0002_0004": "AMS A Slot1 filament may be broken in the tool head.",
"0700_2000_0002_0005": "AMS A Slot1 filament has run out, and purging the old filament went abnormally; please check whether the filament is stuck in the tool head.",
"0700_2000_0002_0006": "PTFE tube detached during the feeding process. Please check if the PTFE tube is connected to the AMS and extruder.",
"0700_2000_0003_0001": "AMS A Slot1 filament has run out. Please wait while old filament is purged.",
"0700_2000_0003_0002": "AMS A Slot1 filament has run out and automatically switched to the slot with the same filament.",
"0700_2100_0002_0001": "AMS A Slot2 filament has run out. Please insert a new filament.",
"0700_2100_0002_0002": "AMS A Slot2 is empty; please insert a new filament.",
"0700_2100_0002_0003": "AMS A Slot2's filament may be broken in AMS.",
"0700_2100_0002_0004": "AMS A Slot2 filament may be broken in the tool head.",
"0700_2100_0002_0005": "AMS A Slot2 filament has run out, and purging the old filament went abnormally; please check whether the filament is stuck in the tool head.",
"0700_2100_0003_0001": "AMS A Slot2 filament has run out. Please wait while old filament is purged.",
"0700_2100_0003_0002": "AMS A Slot2 filament has run out and automatically switched to the slot with the same filament.",
"0700_2200_0002_0001": "AMS A Slot3 filament has run out. Please insert a new filament.",
"0700_2200_0002_0002": "AMS A Slot3 is empty; please insert a new filament.",
"0700_2200_0002_0003": "AMS A Slot3's filament may be broken in AMS.",
"0700_2200_0002_0004": "AMS A Slot3 filament may be broken in the tool head.",
"0700_2200_0002_0005": "AMS A Slot3 filament has run out, and purging the old filament went abnormally; please check whether the filament is stuck in the tool head.",
"0700_2200_0003_0001": "AMS A Slot3 filament has run out. Please wait while old filament is purged.",
"0700_2200_0003_0002": "AMS A Slot3 filament has run out and automatically switched to the slot with the same filament.",
"0700_2300_0002_0001": "AMS A Slot4 filament has run out. Please insert a new filament.",
"0700_2300_0002_0002": "AMS A Slot4 is empty; please insert a new filament.",
"0700_2300_0002_0003": "AMS A Slot4's filament may be broken in AMS.",
"0700_2300_0002_0004": "AMS A Slot4 filament may be broken in the tool head.",
"0700_2300_0002_0005": "AMS A Slot4 filament has run out, and purging the old filament went abnormally; please check whether the filament is stuck in the tool head.",
"0700_2300_0003_0001": "AMS A Slot4 filament has run out. Please wait while old filament is purged.",
"0700_2300_0003_0002": "AMS A Slot4 filament has run out and automatically switched to the slot with the same filament.",
"0700_3000_0001_0001": "The AMS A RFID 0 board has an error.",
"0700_3000_0001_0004": "Encryption chip failure.",
"0700_3000_0002_0002": "The RFID-tag on AMS A Slot1 is damaged or the it's content cannot be identified.",
"0700_3000_0003_0003": "RFID cannot be read because of a hardware or structural error.",
"0700_3100_0001_0001": "The AMS A RFID 1 board has an error.",
"0700_3100_0001_0004": "Encryption chip failure.",
"0700_3100_0002_0002": "The RFID-tag on AMS A Slot2 is damaged or the it's content cannot be identified.",
"0700_3100_0003_0003": "RFID cannot be read because of a hardware or structural error.",
"0700_3200_0002_0002": "The RFID-tag on AMS A Slot3 is damaged or the it's content cannot be identified.",
"0700_3300_0002_0002": "The RFID-tag on AMS A Slot4 is damaged or the it's content cannot be identified.",
"0700_3500_0001_0001": "The temperature and humidity sensor has an error. The chip may be faulty.",
"0700_3500_0001_0002": "AMS A The humidity sensor is disconnected, which may due to poor connector contact.",
"0700_4000_0002_0001": "The filament buffer position signal lost: the cable or position sensor may be malfunctioning.",
"0700_4000_0002_0002": "The filament buffer position signal error: the position sensor may be malfunctioning.",
"0700_4000_0002_0003": "The AMS Hub communication is abnormal, the cable may be not well connected.",
"0700_4000_0002_0004": "The filament buffer signal is abnormal; the spring may be stuck or the filament may be tangle.",
"0700_4500_0002_0001": "The filament cutter sensor is malfunctioning; please check whether the connector is properly plugged in.",
"0700_4500_0002_0002": "The filament cutter's cutting distance is too large. The XY motor may lose steps.",
"0700_4500_0002_0003": "The filament cutter handle has not been released. The handle or blade may be jammed, or there could be an issue with the filament sensor connection.",
"0700_5000_0002_0001": "AMS A communication is abnormal; please check the connection cable.",
"0700_5100_0003_0001": "The AMS is disabled; please load filament from spool holder.",
"0700_6000_0002_0001": "The AMS A slot1 is overloaded. The filament may be tangled or the spool may be stuck.",
"0700_6100_0002_0001": "The AMS A slot2 is overloaded. The filament may be tangled or the spool may be stuck.",
"0700_6200_0002_0001": "The AMS A slot3 is overloaded. The filament may be tangled or the spool may be stuck.",
"0700_6300_0002_0001": "The AMS A slot4 is overloaded. The filament may be tangled or the spool may be stuck.",
"0700_7000_0002_0001": "Failed to pull out the filament from the extruder. Possible causes: clogged extruder or broken filament. Refer to the Assistant for details.",
"0700_7000_0002_0002": "Failed to feed filament into the toolhead. Possible cause: filament or spool stuck. Please refer to the Assistant for details.",
"0700_7000_0002_0003": "Failed to extrude the filament. Possible cause: extruder or nozzle clogged. Please refer to the Assistant for details.",
"0700_7000_0002_0004": "Failed to pull back the filament from the toolhead to AMS. Possible cause: filament or spool stuck. Please refer to the Assistant for details.",
"0700_7000_0002_0005": "Failed to feed the filament outside the AMS. Please clip the end of the filament flat and check to see if the spool is stuck. Please refer to the Assistant for details.",
"0700_7000_0002_0006": "Timeout purging old filament. Possible cause: filament stuck or extruder/nozzle clogged. Please refer to the Assistant for details.",
"0700_7000_0002_0007": "AMS filament ran out. Please put a new filament into AMS and click the 'Retry' button.",
"0700_7000_0002_0008": "Failed to get AMS mapping table; please click 'Resume' to retry",
"0700_7000_0002_0030": "",
"0700_7000_0002_0031": "",
"0700_7000_0002_0032": "",
"0700_7000_0002_0033": "",
"0700_7000_0002_0040": "",
"0700_7000_0002_0041": "",
"0700_7000_0002_0042": "",
"0700_7000_0002_0043": "",
"0700_7000_0002_0044": "",
"0700_7000_0002_0045": "",
"0700_7000_0002_0046": "",
"0700_7000_0002_0050": "",
"0700_7000_0002_0060": "",
"0700_7000_0002_0061": "",
"0700_8000_0001_0002": "AMS A The heater 1 is disconnected, which may due to poor connector contact.",
"0700_8100_0001_0002": "AMS A The heater 2 is disconnected, which may due to poor connector contact.",
"0700_9200_0001_0001": "AMS A The cooling fan of heater 1 is blocked, which may be due to the fan being stuck.",
"0700_9200_0002_0002": "AMS A The cooling fan speed of heater 1 is too low, which could be due to excessive fan resistance.",
"0700_9300_0001_0001": "AMS A The cooling fan of heater 2 is blocked, which may be due to the fan being stuck.",
"0700_9300_0002_0002": "AMS A The cooling fan speed of heater 2 is too low, which could be due to excessive fan resistance.",
"0700_9400_0001_0001": "AMS A The temperature sensor of heater 1 is malfunctioning, , which may due to poor connector contact.",
"0700_9500_0001_0001": "AMS A The temperature sensor of heater 2 is malfunctioning, , which may due to poor connector contact.",
"0701_0100_0001_0001": "The AMS B assist motor has slipped. The extrusion wheel may be worn down, or the filament may be too thin.",
"0701_0100_0001_0003": "The AMS B assist motor torque control is malfunctioning. The current sensor may be faulty.",
"0701_0100_0001_0004": "The AMS B assist motor speed control is malfunctioning. The speed sensor may be faulty.",
"0701_0100_0001_0011": "AMS B The assist motor calibration parameter error. Please pull out the filament from the filament hub and then restart the AMS.",
"0701_0100_0002_0002": "The AMS B assist motor is overloaded. The filament may be tangled or stuck.",
"0701_0200_0001_0001": "AMS B Filament speed and length error: The filament odometry may be faulty.",
"0701_1000_0001_0001": "The AMS B slot1 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"0701_1000_0001_0003": "The AMS B slot1 motor torque control is malfunctioning. The current sensor may be faulty.",
"0701_1000_0002_0002": "The AMS B slot1 motor is overloaded. The filament may be tangled or stuck.",
"0701_1100_0001_0001": "The AMS B slot2 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"0701_1100_0001_0003": "The AMS B slot2 motor torque control is malfunctioning. The current sensor may be faulty.",
"0701_1100_0002_0002": "The AMS B slot2 motor is overloaded. The filament may be tangled or stuck.",
"0701_1200_0001_0001": "The AMS B slot3 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"0701_1200_0001_0003": "The AMS B slot3 motor torque control is malfunctioning. The current sensor may be faulty.",
"0701_1200_0002_0002": "The AMS B slot3 motor is overloaded. The filament may be tangled or stuck.",
"0701_1300_0001_0001": "The AMS B slot4 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"0701_1300_0001_0003": "The AMS B slot4 motor torque control is malfunctioning. The current sensor may be faulty.",
"0701_1300_0002_0002": "The AMS B slot4 motor is overloaded. The filament may be tangled or stuck.",
"0701_2000_0002_0001": "AMS B Slot1 filament has run out. Please insert a new filament.",
"0701_2000_0002_0002": "AMS B Slot1 is empty; please insert a new filament.",
"0701_2000_0002_0003": "AMS B Slot1's filament may be broken in AMS.",
"0701_2000_0002_0004": "AMS B Slot1 filament may be broken in the tool head.",
"0701_2000_0002_0005": "AMS B Slot1 filament has run out, and purging the old filament went abnormally; please check whether the filament is stuck in the tool head.",
"0701_2000_0002_0006": "PTFE tube detached during the feeding process. Please check if the PTFE tube is connected to the AMS and extruder.",
"0701_2000_0003_0001": "AMS B Slot1 filament has run out. Please wait while old filament is purged.",
"0701_2000_0003_0002": "AMS B Slot1 filament has run out and automatically switched to the slot with the same filament.",
"0701_2100_0002_0001": "AMS B Slot2 filament has run out. Please insert a new filament.",
"0701_2100_0002_0002": "AMS B Slot2 is empty; please insert a new filament.",
"0701_2100_0002_0003": "AMS B Slot2's filament may be broken in AMS.",
"0701_2100_0002_0004": "AMS B Slot2 filament may be broken in the tool head.",
"0701_2100_0002_0005": "AMS B Slot2 filament has run out, and purging the old filament went abnormally; please check whether the filament is stuck in the tool head.",
"0701_2100_0003_0001": "AMS B Slot2 filament has run out. Please wait while old filament is purged.",
"0701_2100_0003_0002": "AMS B Slot2 filament has run out and automatically switched to the slot with the same filament.",
"0701_2200_0002_0001": "AMS B Slot3 filament has run out. Please insert a new filament.",
"0701_2200_0002_0002": "AMS B Slot3 is empty; please insert a new filament.",
"0701_2200_0002_0003": "AMS B Slot3's filament may be broken in AMS.",
"0701_2200_0002_0004": "AMS B Slot3 filament may be broken in the tool head.",
"0701_2200_0002_0005": "AMS B Slot3 filament has run out, and purging the old filament went abnormally; please check whether the filament is stuck in the tool head.",
"0701_2200_0003_0001": "AMS B Slot3 filament has run out. Please wait while old filament is purged.",
"0701_2200_0003_0002": "AMS B Slot3 filament has run out and automatically switched to the slot with the same filament.",
"0701_2300_0002_0001": "AMS B Slot4 filament has run out. Please insert a new filament.",
"0701_2300_0002_0002": "AMS B Slot4 is empty; please insert a new filament.",
"0701_2300_0002_0003": "AMS B Slot4's filament may be broken in AMS.",
"0701_2300_0002_0004": "AMS B Slot4 filament may be broken in the tool head.",
"0701_2300_0002_0005": "AMS B Slot4 filament has run out, and purging the old filament went abnormally; please check whether the filament is stuck in the tool head.",
"0701_2300_0003_0001": "AMS B Slot4 filament has run out. Please wait while old filament is purged.",
"0701_2300_0003_0002": "AMS B Slot4 filament has run out and automatically switched to the slot with the same filament.",
"0701_3000_0001_0001": "The AMS B RFID 0 board has an error.",
"0701_3000_0001_0004": "Encryption chip failure.",
"0701_3000_0002_0002": "The RFID-tag on AMS B Slot1 is damaged or the it's content cannot be identified.",
"0701_3000_0003_0003": "RFID cannot be read because of a hardware or structural error.",
"0701_3100_0001_0001": "The AMS B RFID 1 board has an error.",
"0701_3100_0001_0004": "Encryption chip failure.",
"0701_3100_0002_0002": "The RFID-tag on AMS B Slot2 is damaged or the it's content cannot be identified.",
"0701_3100_0003_0003": "RFID cannot be read because of a hardware or structural error.",
"0701_3200_0002_0002": "The RFID-tag on AMS B Slot3 is damaged or the it's content cannot be identified.",
"0701_3300_0002_0002": "The RFID-tag on AMS B Slot4 is damaged or the it's content cannot be identified.",
"0701_3500_0001_0001": "The temperature and humidity sensor has an error. The chip may be faulty.",
"0701_3500_0001_0002": "AMS B The humidity sensor is disconnected, which may due to poor connector contact.",
"0701_5000_0002_0001": "AMS B communication is abnormal; please check the connection cable.",
"0701_6000_0002_0001": "The AMS B slot1 is overloaded. The filament may be tangled or the spool may be stuck.",
"0701_6100_0002_0001": "The AMS B slot2 is overloaded. The filament may be tangled or the spool may be stuck.",
"0701_6200_0002_0001": "The AMS B slot3 is overloaded. The filament may be tangled or the spool may be stuck.",
"0701_6300_0002_0001": "The AMS B slot4 is overloaded. The filament may be tangled or the spool may be stuck.",
"0701_7000_0002_0001": "Failed to pull out the filament from the extruder. Possible causes: clogged extruder or broken filament. Refer to the Assistant for details.",
"0701_7000_0002_0002": "Failed to feed the filament into the toolhead. Possible cause: filament or spool stuck. Please refer to the Assistant for details.",
"0701_7000_0002_0003": "Failed to extrude the filament. Possible cause: extruder or nozzle clogged. Please refer to the Assistant for details.",
"0701_7000_0002_0004": "Failed to pull back the filament from the toolhead to AMS. Possible cause: filament or spool stuck. Please refer to the Assistant for details.",
"0701_7000_0002_0005": "Failed to feed the filament outside the AMS. Please clip the end of the filament flat and check to see if the spool is stuck. Please refer to the Assistant for details.",
"0701_7000_0002_0006": "Timeout purging old filament. Possible cause: filament stuck or extruder/nozzle clogged. Please refer to the Assistant for details.",
"0701_7000_0002_0007": "AMS filament ran out. Please put a new filament into AMS and click the 'Retry' button.",
"0701_7000_0002_0008": "Failed to get AMS mapping table; please click 'Resume' to retry",
"0701_7000_0002_0030": "",
"0701_7000_0002_0031": "",
"0701_7000_0002_0032": "",
"0701_7000_0002_0033": "",
"0701_7000_0002_0040": "",
"0701_7000_0002_0041": "",
"0701_7000_0002_0042": "",
"0701_7000_0002_0043": "",
"0701_7000_0002_0044": "",
"0701_7000_0002_0045": "",
"0701_7000_0002_0046": "",
"0701_7000_0002_0050": "",
"0701_7000_0002_0060": "",
"0701_7000_0002_0061": "",
"0701_8000_0001_0002": "AMS B The heater 1 is disconnected, which may due to poor connector contact.",
"0701_8100_0001_0002": "AMS B The heater 2 is disconnected, which may due to poor connector contact.",
"0701_9200_0001_0001": "AMS B The cooling fan of heater 1 is blocked, which may be due to the fan being stuck.",
"0701_9200_0002_0002": "AMS B The cooling fan speed of heater 1 is too low, which could be due to excessive fan resistance.",
"0701_9300_0001_0001": "AMS B The cooling fan of heater 2 is blocked, which may be due to the fan being stuck.",
"0701_9300_0002_0002": "AMS B The cooling fan speed of heater 2 is too low, which could be due to excessive fan resistance.",
"0701_9400_0001_0001": "AMS B The temperature sensor of heater 1 is malfunctioning, , which may due to poor connector contact.",
"0701_9500_0001_0001": "AMS B The temperature sensor of heater 2 is malfunctioning, , which may due to poor connector contact.",
"0702_0100_0001_0001": "The AMS C assist motor has slipped. The extrusion wheel may be worn down, or the filament may be too thin.",
"0702_0100_0001_0003": "The AMS C assist motor torque control is malfunctioning. The current sensor may be faulty.",
"0702_0100_0001_0004": "The AMS C assist motor speed control is malfunctioning. The speed sensor may be faulty.",
"0702_0100_0001_0011": "AMS C The assist motor calibration parameter error. Please pull out the filament from the filament hub and then restart the AMS.",
"0702_0100_0002_0002": "The AMS C assist motor is overloaded. The filament may be tangled or stuck.",
"0702_0200_0001_0001": "AMS C Filament speed and length error: The filament odometry may be faulty.",
"0702_1000_0001_0001": "The AMS C slot1 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"0702_1000_0001_0003": "The AMS C slot1 motor torque control is malfunctioning. The current sensor may be faulty.",
"0702_1000_0002_0002": "The AMS C slot1 motor is overloaded. The filament may be tangled or stuck.",
"0702_1100_0001_0001": "The AMS C slot2 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"0702_1100_0001_0003": "The AMS C slot2 motor torque control is malfunctioning. The current sensor may be faulty.",
"0702_1100_0002_0002": "The AMS C slot2 motor is overloaded. The filament may be tangled or stuck.",
"0702_1200_0001_0001": "The AMS C slot3 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"0702_1200_0001_0003": "The AMS C slot3 motor torque control is malfunctioning. The current sensor may be faulty.",
"0702_1200_0002_0002": "The AMS C slot3 motor is overloaded. The filament may be tangled or stuck.",
"0702_1300_0001_0001": "The AMS C slot4 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"0702_1300_0001_0003": "The AMS C slot4 motor torque control is malfunctioning. The current sensor may be faulty.",
"0702_1300_0002_0002": "The AMS C slot4 motor is overloaded. The filament may be tangled or stuck.",
"0702_2000_0002_0001": "AMS C Slot1 filament has run out. Please insert a new filament.",
"0702_2000_0002_0002": "AMS C Slot1 is empty; please insert a new filament.",
"0702_2000_0002_0003": "AMS C Slot1's filament may be broken in AMS.",
"0702_2000_0002_0004": "AMS C Slot1 filament may be broken in the tool head.",
"0702_2000_0002_0005": "AMS C Slot1 filament has run out, and purging the old filament went abnormally; please check whether the filament is stuck in the tool head.",
"0702_2000_0002_0006": "PTFE tube detached during the feeding process. Please check if the PTFE tube is connected to the AMS and extruder.",
"0702_2000_0003_0001": "AMS C Slot1 filament has run out. Please wait while old filament is purged.",
"0702_2000_0003_0002": "AMS C Slot1 filament has run out and automatically switched to the slot with the same filament.",
"0702_2100_0002_0001": "AMS C Slot2 filament has run out. Please insert a new filament.",
"0702_2100_0002_0002": "AMS C Slot2 is empty; please insert a new filament.",
"0702_2100_0002_0003": "AMS C Slot2's filament may be broken in AMS.",
"0702_2100_0002_0004": "AMS C Slot2 filament may be broken in the tool head.",
"0702_2100_0002_0005": "AMS C Slot2 filament has run out, and purging the old filament went abnormally; please check whether the filament is stuck in the tool head.",
"0702_2100_0003_0001": "AMS C Slot2 filament has run out. Please wait while old filament is purged.",
"0702_2100_0003_0002": "AMS C Slot2 filament has run out and automatically switched to the slot with the same filament.",
"0702_2200_0002_0001": "AMS C Slot3 filament has run out. Please insert a new filament.",
"0702_2200_0002_0002": "AMS C Slot3 is empty; please insert a new filament.",
"0702_2200_0002_0003": "AMS C Slot3's filament may be broken in AMS.",
"0702_2200_0002_0004": "AMS C Slot3 filament may be broken in the tool head.",
"0702_2200_0002_0005": "AMS C Slot3 filament has run out, and purging the old filament went abnormally; please check whether the filament is stuck in the tool head.",
"0702_2200_0003_0001": "AMS C Slot3 filament has run out. Please wait while old filament is purged.",
"0702_2200_0003_0002": "AMS C Slot3 filament has run out and automatically switched to the slot with the same filament.",
"0702_2300_0002_0001": "AMS C Slot4 filament has run out. Please insert a new filament.",
"0702_2300_0002_0002": "AMS C Slot4 is empty; please insert a new filament.",
"0702_2300_0002_0003": "AMS C Slot4's filament may be broken in AMS.",
"0702_2300_0002_0004": "AMS C Slot4 filament may be broken in the tool head.",
"0702_2300_0002_0005": "AMS C Slot4 filament has run out, and purging the old filament went abnormally; please check whether the filament is stuck in the tool head.",
"0702_2300_0003_0001": "AMS C Slot4 filament has run out. Please wait while old filament is purged.",
"0702_2300_0003_0002": "AMS C Slot4 filament has run out and automatically switched to the slot with the same filament.",
"0702_3000_0001_0001": "The AMS C RFID 0 board has an error.",
"0702_3000_0001_0004": "Encryption chip failure.",
"0702_3000_0002_0002": "The RFID-tag on AMS C Slot1 is damaged or the it's content cannot be identified.",
"0702_3000_0003_0003": "RFID cannot be read because of a hardware or structural error.",
"0702_3100_0001_0001": "The AMS C RFID 1 board has an error.",
"0702_3100_0001_0004": "Encryption chip failure.",
"0702_3100_0002_0002": "The RFID-tag on AMS C Slot2 is damaged or the it's content cannot be identified.",
"0702_3100_0003_0003": "RFID cannot be read because of a hardware or structural error.",
"0702_3200_0002_0002": "The RFID-tag on AMS C Slot3 is damaged or the it's content cannot be identified.",
"0702_3300_0002_0002": "The RFID-tag on AMS C Slot4 is damaged or the it's content cannot be identified.",
"0702_3500_0001_0001": "The temperature and humidity sensor has an error. The chip may be faulty.",
"0702_3500_0001_0002": "AMS C The humidity sensor is disconnected, which may due to poor connector contact.",
"0702_5000_0002_0001": "AMS C communication is abnormal; please check the connection cable.",
"0702_6000_0002_0001": "The AMS C slot1 is overloaded. The filament may be tangled or the spool may be stuck.",
"0702_6100_0002_0001": "The AMS C slot2 is overloaded. The filament may be tangled or the spool may be stuck.",
"0702_6200_0002_0001": "The AMS C slot3 is overloaded. The filament may be tangled or the spool may be stuck.",
"0702_6300_0002_0001": "The AMS C slot4 is overloaded. The filament may be tangled or the spool may be stuck.",
"0702_7000_0002_0001": "Failed to pull out the filament from the extruder. Possible causes: clogged extruder or broken filament. Refer to the Assistant for details.",
"0702_7000_0002_0002": "Failed to feed the filament into the toolhead. Possible cause: filament or spool stuck. Please refer to the Assistant for details.",
"0702_7000_0002_0003": "Failed to extrude the filament. Possible cause: extruder or nozzle clogged. Please refer to the Assistant for details.",
"0702_7000_0002_0004": "Failed to pull back the filament from the toolhead to AMS. Possible cause: filament or spool stuck. Please refer to the Assistant for details.",
"0702_7000_0002_0005": "Failed to feed the filament outside the AMS. Please clip the end of the filament flat and check to see if the spool is stuck. Please refer to the Assistant for details.",
"0702_7000_0002_0006": "Timeout purging old filament. Possible cause: filament stuck or extruder/nozzle clogged. Please refer to the Assistant for details.",
"0702_7000_0002_0007": "AMS filament ran out. Please put a new filament into AMS and click the 'Retry' button.",
"0702_7000_0002_0008": "Failed to get AMS mapping table; please click 'Resume' to retry",
"0702_7000_0002_0030": "",
"0702_7000_0002_0031": "",
"0702_7000_0002_0032": "",
"0702_7000_0002_0033": "",
"0702_7000_0002_0040": "",
"0702_7000_0002_0041": "",
"0702_7000_0002_0042": "",
"0702_7000_0002_0043": "",
"0702_7000_0002_0044": "",
"0702_7000_0002_0045": "",
"0702_7000_0002_0046": "",
"0702_7000_0002_0050": "",
"0702_7000_0002_0060": "",
"0702_7000_0002_0061": "",
"0702_8000_0001_0002": "AMS C The heater 1 is disconnected, which may due to poor connector contact.",
"0702_8100_0001_0002": "AMS C The heater 2 is disconnected, which may due to poor connector contact.",
"0702_9200_0001_0001": "AMS C The cooling fan of heater 1 is blocked, which may be due to the fan being stuck.",
"0702_9200_0002_0002": "AMS C The cooling fan speed of heater 1 is too low, which could be due to excessive fan resistance.",
"0702_9300_0001_0001": "AMS C The cooling fan of heater 2 is blocked, which may be due to the fan being stuck.",
"0702_9300_0002_0002": "AMS C The cooling fan speed of heater 2 is too low, which could be due to excessive fan resistance.",
"0702_9400_0001_0001": "AMS C The temperature sensor of heater 1 is malfunctioning, , which may due to poor connector contact.",
"0702_9500_0001_0001": "AMS C The temperature sensor of heater 2 is malfunctioning, , which may due to poor connector contact.",
"0703_0100_0001_0001": "The AMS D assist motor has slipped. The extrusion wheel may be worn down, or the filament may be too thin.",
"0703_0100_0001_0003": "The AMS D assist motor torque control is malfunctioning. The current sensor may be faulty.",
"0703_0100_0001_0004": "The AMS D assist motor speed control is malfunctioning. The speed sensor may be faulty.",
"0703_0100_0001_0011": "AMS D The assist motor calibration parameter error. Please pull out the filament from the filament hub and then restart the AMS.",
"0703_0100_0002_0002": "The AMS D assist motor is overloaded. The filament may be tangled or stuck.",
"0703_0200_0001_0001": "AMS D Filament speed and length error: The filament odometry may be faulty.",
"0703_1000_0001_0001": "The AMS D slot1 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"0703_1000_0001_0003": "The AMS D slot1 motor torque control is malfunctioning. The current sensor may be faulty.",
"0703_1000_0002_0002": "The AMS D slot1 motor is overloaded. The filament may be tangled or stuck.",
"0703_1100_0001_0001": "The AMS D slot2 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"0703_1100_0001_0003": "The AMS D slot2 motor torque control is malfunctioning. The current sensor may be faulty.",
"0703_1100_0002_0002": "The AMS D slot2 motor is overloaded. The filament may be tangled or stuck.",
"0703_1200_0001_0001": "The AMS D slot3 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"0703_1200_0001_0003": "The AMS D slot3 motor torque control is malfunctioning. The current sensor may be faulty.",
"0703_1200_0002_0002": "The AMS D slot3 motor is overloaded. The filament may be tangled or stuck.",
"0703_1300_0001_0001": "The AMS D slot4 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"0703_1300_0001_0003": "The AMS D slot4 motor torque control is malfunctioning. The current sensor may be faulty.",
"0703_1300_0002_0002": "The AMS D slot4 motor is overloaded. The filament may be tangled or stuck.",
"0703_2000_0002_0001": "AMS D Slot1 filament has run out. Please insert a new filament.",
"0703_2000_0002_0002": "AMS D Slot1 is empty; please insert a new filament.",
"0703_2000_0002_0003": "AMS D Slot1's filament may be broken in AMS.",
"0703_2000_0002_0004": "AMS D Slot1 filament may be broken in the tool head.",
"0703_2000_0002_0005": "AMS D Slot1 filament has run out, and purging the old filament went abnormally; please check whether the filament is stuck in the tool head.",
"0703_2000_0002_0006": "PTFE tube detached during the feeding process. Please check if the PTFE tube is connected to the AMS and extruder.",
"0703_2000_0003_0001": "AMS D Slot1 filament has run out. Please wait while old filament is purged.",
"0703_2000_0003_0002": "AMS D Slot1 filament has run out and automatically switched to the slot with the same filament.",
"0703_2100_0002_0001": "AMS D Slot2 filament has run out. Please insert a new filament.",
"0703_2100_0002_0002": "AMS D Slot2 is empty; please insert a new filament.",
"0703_2100_0002_0003": "AMS D Slot2's filament may be broken in AMS.",
"0703_2100_0002_0004": "AMS D Slot2 filament may be broken in the tool head.",
"0703_2100_0002_0005": "AMS D Slot2 filament has run out, and purging the old filament went abnormally; please check whether the filament is stuck in the tool head.",
"0703_2100_0003_0001": "AMS D Slot2 filament has run out. Please wait while old filament is purged.",
"0703_2100_0003_0002": "AMS D Slot2 filament has run out and automatically switched to the slot with the same filament.",
"0703_2200_0002_0001": "AMS D Slot3 filament has run out. Please insert a new filament.",
"0703_2200_0002_0002": "AMS D Slot3 is empty; please insert a new filament.",
"0703_2200_0002_0003": "AMS D Slot3's filament may be broken in AMS.",
"0703_2200_0002_0004": "AMS D Slot3 filament may be broken in the tool head.",
"0703_2200_0002_0005": "AMS D Slot3 filament has run out, and purging the old filament went abnormally; please check whether the filament is stuck in the tool head.",
"0703_2200_0003_0001": "AMS D Slot3 filament has run out. Please wait while old filament is purged.",
"0703_2200_0003_0002": "AMS D Slot3 filament has run out and automatically switched to the slot with the same filament.",
"0703_2300_0002_0001": "AMS D Slot4 filament has run out. Please insert a new filament.",
"0703_2300_0002_0002": "AMS D Slot4 is empty; please insert a new filament.",
"0703_2300_0002_0003": "AMS D Slot4's filament may be broken in AMS.",
"0703_2300_0002_0004": "AMS D Slot4 filament may be broken in the tool head.",
"0703_2300_0002_0005": "AMS D Slot4 filament has run out, and purging the old filament went abnormally; please check whether the filament is stuck in the tool head.",
"0703_2300_0003_0001": "AMS D Slot4 filament has run out. Please wait while old filament is purged.",
"0703_2300_0003_0002": "AMS D Slot4 filament has run out and automatically switched to the slot with the same filament.",
"0703_3000_0001_0001": "The AMS D RFID 0 board has an error.",
"0703_3000_0001_0004": "Encryption chip failure.",
"0703_3000_0002_0002": "The RFID-tag on AMS D Slot1 is damaged or the it's content cannot be identified.",
"0703_3000_0003_0003": "RFID cannot be read because of a hardware or structural error.",
"0703_3100_0001_0001": "The AMS D RFID 1 board has an error.",
"0703_3100_0001_0004": "Encryption chip failure.",
"0703_3100_0002_0002": "The RFID-tag on AMS D Slot2 is damaged or the it's content cannot be identified.",
"0703_3100_0003_0003": "RFID cannot be read because of a hardware or structural error.",
"0703_3200_0002_0002": "The RFID-tag on AMS D Slot3 is damaged or the it's content cannot be identified.",
"0703_3300_0002_0002": "The RFID-tag on AMS D Slot4 is damaged or the it's content cannot be identified.",
"0703_3500_0001_0001": "The temperature and humidity sensor has an error. The chip may be faulty.",
"0703_3500_0001_0002": "AMS D The humidity sensor is disconnected, which may due to poor connector contact.",
"0703_5000_0002_0001": "AMS D communication is abnormal; please check the connection cable.",
"0703_6000_0002_0001": "The AMS D slot1 is overloaded. The filament may be tangled or the spool may be stuck.",
"0703_6100_0002_0001": "The AMS D slot2 is overloaded. The filament may be tangled or the spool may be stuck.",
"0703_6200_0002_0001": "The AMS D slot3 is overloaded. The filament may be tangled or the spool may be stuck.",
"0703_6300_0002_0001": "The AMS D slot4 is overloaded. The filament may be tangled or the spool may be stuck.",
"0703_7000_0002_0001": "Failed to pull out the filament from the extruder. Possible causes: clogged extruder or broken filament. Refer to the Assistant for details.",
"0703_7000_0002_0002": "Failed to feed the filament into the toolhead. Possible cause: filament or spool stuck. Please refer to the Assistant for details.",
"0703_7000_0002_0003": "Failed to extrude the filament. Possible cause: extruder or nozzle clogged. Please refer to the Assistant for details.",
"0703_7000_0002_0004": "Failed to pull back the filament from the toolhead to AMS. Possible cause: filament or spool stuck. Please refer to the Assistant for details.",
"0703_7000_0002_0005": "Failed to feed the filament outside the AMS. Please clip the end of the filament flat and check to see if the spool is stuck. Please refer to the Assistant for details.",
"0703_7000_0002_0006": "Timeout purging old filament. Possible cause: filament stuck or extruder/nozzle clogged. Please refer to the Assistant for details.",
"0703_7000_0002_0007": "AMS filament ran out. Please put a new filament into AMS and click the 'Retry' button.",
"0703_7000_0002_0008": "Failed to get AMS mapping table; please click 'Resume' to retry",
"0703_7000_0002_0030": "",
"0703_7000_0002_0031": "",
"0703_7000_0002_0032": "",
"0703_7000_0002_0033": "",
"0703_7000_0002_0040": "",
"0703_7000_0002_0041": "",
"0703_7000_0002_0042": "",
"0703_7000_0002_0043": "",
"0703_7000_0002_0044": "",
"0703_7000_0002_0045": "",
"0703_7000_0002_0046": "",
"0703_7000_0002_0050": "",
"0703_7000_0002_0060": "",
"0703_7000_0002_0061": "",
"0703_8000_0001_0002": "AMS D The heater 1 is disconnected, which may due to poor connector contact.",
"0703_8100_0001_0002": "AMS D The heater 2 is disconnected, which may due to poor connector contact.",
"0703_9200_0001_0001": "AMS D The cooling fan of heater 1 is blocked, which may be due to the fan being stuck.",
"0703_9200_0002_0002": "AMS D The cooling fan speed of heater 1 is too low, which could be due to excessive fan resistance.",
"0703_9300_0001_0001": "AMS D The cooling fan of heater 2 is blocked, which may be due to the fan being stuck.",
"0703_9300_0002_0002": "AMS D The cooling fan speed of heater 2 is too low, which could be due to excessive fan resistance.",
"0703_9400_0001_0001": "AMS D The temperature sensor of heater 1 is malfunctioning, , which may due to poor connector contact.",
"0703_9500_0001_0001": "AMS D The temperature sensor of heater 2 is malfunctioning, , which may due to poor connector contact.",
}

View File

@ -0,0 +1,528 @@
HMS_ERRORS = {
"0300_0100_0001_0001": "The heatbed temperature is abnormal; the heater may have a short circuit.",
"0300_0100_0001_0002": "The heatbed temperature is abnormal; the heater may have an open circuit, or the thermal switch may be open.",
"0300_0100_0001_0003": "The heatbed temperature is abnormal; the heater is over temperature.",
"0300_0100_0001_0006": "The heatbed temperature is abnormal; the sensor may have a short circuit.",
"0300_0100_0001_0007": "The heatbed temperature is abnormal; the sensor may have an open circuit.",
"0300_0100_0001_0008": "An abnormality occurs during the heating process of the heatbed, the heating modules may be broken.",
"0300_0100_0001_000A": "The heatbed temperature control is abnormal, the AC board may be broken.",
"0300_0100_0001_000C": "The heatbed has worked at full load for a long time. The temperature control system may be abnormal.",
"0300_0100_0001_000D": "An issue occurred when heating the heatbed previously. To continue using your printer, please refer to the wiki to troubleshoot.",
"0300_0100_0003_0008": "The temperature of the heated bed exceeds the limit and automatically adjusts to the limit temperature.",
"0300_0200_0001_0001": "The nozzle temperature is abnormal; the heater may have a short circuit.",
"0300_0200_0001_0002": "The nozzle temperature is abnormal; the heater may have an open circuit.",
"0300_0200_0001_0003": "The nozzle temperature is abnormal; the heater is over temperature.",
"0300_0200_0001_0006": "The nozzle temperature is abnormal; the sensor may have a short circuit. Please check whether the connector is properly plugged in.",
"0300_0200_0001_0007": "The nozzle temperature is abnormal; the sensor may have an open circuit.",
"0300_0200_0001_0009": "The nozzle temperature control is abnormal; the hot end may not be installed. If you want to heat the hot end without it being installed, please turn on maintenance mode on the settings page.",
"0300_0200_0001_000B": "The nozzle temperature is abnormal. Temperature control system may have an issue.",
"0300_0300_0001_0001": "The hotend cooling fan speed is too slow or stopped. It may be stuck or the connector is not plugged in properly.",
"0300_0300_0002_0002": "",
"0300_0400_0002_0001": "The speed of the part cooling fan is too slow or stopped. It may be stuck or the connector is not plugged in properly.",
"0300_0500_0001_0001": "The motor driver is overheating. Its radiator may be loose, or its cooling fan may be damaged.",
"0300_0600_0001_0001": "Motor-A has an open-circuit. There may be a loose connection, or the motor may have failed.",
"0300_0600_0001_0002": "Motor-A has a short-circuit. It may have failed.",
"0300_0600_0001_0003": "The resistance of Motor-A is abnormal, the motor may have failed.",
"0300_0700_0001_0001": "Motor-B has an open-circuit. The connection may be loose, or the motor may have failed.",
"0300_0700_0001_0002": "Motor-B has a short-circuit. It may have failed.",
"0300_0700_0001_0003": "The resistance of Motor-B is abnormal, the motor may have failed.",
"0300_0800_0001_0001": "Motor-Z has an open-circuit. The connection may be loose, or the motor may have failed.",
"0300_0800_0001_0002": "Motor-Z has a short-circuit. It may have failed.",
"0300_0800_0001_0003": "The resistance of Motor-Z is abnormal, the motor may have failed.",
"0300_0900_0001_0001": "Motor-E has an open-circuit. The connection may be loose, or the motor may have failed.",
"0300_0900_0001_0002": "Motor-E has a short-circuit. It may have failed.",
"0300_0900_0001_0003": "The resistance of Motor-E is abnormal, the motor may have failed.",
"0300_0A00_0001_0001": "Heatbed force sensor 1 is too sensitive. It may be stuck between the strain arm and heatbed support, or the adjusting screw may be too tight.",
"0300_0A00_0001_0002": "The signal of heatbed force sensor 1 is weak. The force sensor may be broken or have poor electric connection.",
"0300_0A00_0001_0003": "The signal of heatbed force sensor 1 is too weak. The electronic connection to the sensor may be broken.",
"0300_0A00_0001_0004": "An external disturbance was detected on force sensor 1. The heatbed plate may have touched something outside the heatbed.",
"0300_0A00_0001_0005": "Force sensor 1 detected unexpected continuous force. The heatbed may be stuck, or the analog front end may be broken.",
"0300_0B00_0001_0001": "Heatbed force sensor 2 is too sensitive. It may be stuck between the strain arm and heatbed support, or the adjusting screw may be too tight.",
"0300_0B00_0001_0002": "The signal of heatbed force sensor 2 is weak. The force sensor may be broken or have poor electric connection.",
"0300_0B00_0001_0003": "The signal of heatbed force sensor 2 is too weak. The electronic connection to the sensor may be broken.",
"0300_0B00_0001_0004": "An external disturbance was detected on force sensor 2. The heatbed plate may have touched something outside the heatbed.",
"0300_0B00_0001_0005": "Force sensor 2 detected unexpected continuous force. The heatbed may be stuck, or the analog front end may be broken.",
"0300_0C00_0001_0001": "Heatbed force sensor 3 is too sensitive. It may be stuck between the strain arm and heatbed support, or the adjusting screw may be too tight.",
"0300_0C00_0001_0002": "The signal of heatbed force sensor 3 is weak. The force sensor may be broken or have poor electric connection.",
"0300_0C00_0001_0003": "The signal of heatbed force sensor 3 is too weak. The electronic connection to the sensor may be broken.",
"0300_0C00_0001_0004": "An external disturbance was detected on force sensor 3. The heatbed plate may have touched something outside the heatbed.",
"0300_0C00_0001_0005": "Force sensor 3 detected unexpected continuous force. The heatbed may be stuck, or the analog front end may be broken.",
"0300_0D00_0001_0002": "Heatbed homing failed. The environmental vibration is too great.",
"0300_0D00_0001_0003": "The build plate is not placed properly. Please adjust it.",
"0300_0D00_0001_0004": "The build plate is not placed properly. Please adjust it.",
"0300_0D00_0001_0005": "The build plate is not placed properly. Please adjust it.",
"0300_0D00_0001_0006": "The build plate is not placed properly. Please adjust it.",
"0300_0D00_0001_0007": "The build plate is not placed properly. Please adjust it.",
"0300_0D00_0001_0008": "The build plate is not placed properly. Please adjust it.",
"0300_0D00_0001_0009": "The build plate is not placed properly. Please adjust it.",
"0300_0D00_0001_000A": "The build plate is not placed properly. Please adjust it.",
"0300_0D00_0001_000B": "The Z axis motor seems to be stuck when moving. Please check if there is any foreign matter on the Z sliders or Z timing belt wheels .",
"0300_0D00_0002_0001": "Heatbed homing abnormal: there may be a bulge on the heatbed or the nozzle tip may not be clean.",
"0300_0D00_0002_0003": "The build plate may not be properly placed. If this message appears repeatedly, please check the Wiki for more reasons.",
"0300_0D00_0002_0004": "The build plate may not be properly placed. If this message appears repeatedly, please check the Wiki for more reasons.",
"0300_0D00_0002_0005": "The build plate may not be properly placed. If this message appears repeatedly, please check the Wiki for more reasons.",
"0300_0D00_0002_0006": "The build plate may not be properly placed. If this message appears repeatedly, please check the Wiki for more reasons.",
"0300_0D00_0002_0007": "The build plate may not be properly placed. If this message appears repeatedly, please check the Wiki for more reasons.",
"0300_0D00_0002_0008": "The build plate may not be properly placed. If this message appears repeatedly, please check the Wiki for more reasons.",
"0300_0D00_0002_0009": "The build plate may not be properly placed. If this message appears repeatedly, please check the Wiki for more reasons.",
"0300_0D00_0002_000A": "The build plate may not be properly placed. If this message appears repeatedly, please check the Wiki for more reasons.",
"0300_0F00_0001_0001": "Abnormal accelerometer data detected. Please try to restart the printer.",
"0300_1000_0002_0001": "The resonance frequency of the X axis is low. The timing belt may be loose.",
"0300_1000_0002_0002": "The resonance frequency of the X axis differs greatly from last calibration. Please clean the carbon rod and rerun the machine calibration afterward.",
"0300_1100_0002_0001": "The resonance frequency of the Y axis is low. The timing belt may be loose.",
"0300_1100_0002_0002": "The resonance frequency of the Y axis differs greatly from the last calibration. Please clean the carbon rod and rerun the machine calibration afterward.",
"0300_1200_0002_0001": "The front cover of the toolhead fell off.",
"0300_1300_0001_0001": "The current sensor of Motor-A is abnormal. This may be caused by a failure of the hardware sampling circuit.",
"0300_1400_0001_0001": "The current sensor of Motor-B is abnormal. This may be caused by a failure of the hardware sampling circuit.",
"0300_1500_0001_0001": "The current sensor of Motor-Z is abnormal. This may be caused by a failure of the hardware sampling circuit.",
"0300_1600_0001_0001": "The current sensor of Motor-E is abnormal. This may be caused by a failure of the hardware sampling circuit.",
"0300_1700_0001_0001": "The hotend cooling fan speed is too slow or stopped. It may be stuck or the connector may not be plugged in properly.",
"0300_1700_0002_0002": "The hotend cooling fan speed is slow. It may be stuck and need cleaning.",
"0300_1800_0001_0001": "The value of extrusion force sensor is low, the nozzle seems to not be installed.",
"0300_1800_0001_0002": "The sensitivity of the extrusion force sensor is low, the nozzle may not installed correctly.",
"0300_1800_0001_0003": "The extrusion force sensor is not available, the link between the MC and TH may be broken or the sensor is broken.",
"0300_1800_0001_0004": "The data from extrusion force sensor is abnormal, the sensor should be broken.",
"0300_1800_0001_0005": "The Z axis motor got stuck while moving, or the extrusion force sensor may have an issue; please check if there is any foreign matter on the Z sliders or Z timing belt wheels.",
"0300_1900_0001_0001": "The eddy current sensor on Y-axis is not available, the wire should be broken.",
"0300_1900_0002_0002": "The sensitivity of Y-axis eddy current sensor is too low.",
"0300_1A00_0002_0001": "The nozzle is covered with filaments, or the build plate is put in crooked.",
"0300_1A00_0002_0002": "The nozzle is clogged with filament.",
"0300_1B00_0001_0001": "The signal of the heatbed acceleration sensor is weak. The sensor may have fallen off or been damaged.",
"0300_1B00_0001_0002": "External disturbance was detected on the heatbed acceleeration sensor. The sensor signal wire may not be fixed.",
"0300_1B00_0001_0003": "The heatbed acceleration sensor detected unexpected continuous force. The sensor may be stuck, or the analog front end may be broken.",
"0300_1C00_0001_0001": "The extrusion motor driver is abnormal. The MOSFET may have a short circuit.",
"0300_1D00_0001_0001": "The position sensor of extrusion motor is abnormal. The connection to sensor may be loose.",
"0300_2000_0001_0001": "X axis homing abnormal: please check if the tool head is stuck or the carbon rod has too much resistance.",
"0300_2000_0001_0002": "Y axis homing abnormal: please check if the tool head is stuck or the Y carriage has too much resistance.",
"0300_2000_0001_0003": "X axis homing abnormal: the timing belt may be loose.",
"0300_2000_0001_0004": "Y axis homing abnormal: the timing belt may be loose.",
"0300_4000_0002_0001": "Data transmission over the serial port is abnormal; the software system may be faulty.",
"0300_4100_0001_0001": "The system voltage is unstable; triggering the power failure protection function.",
"0300_9000_0001_0001": "Chamber heating failed. The chamber heater may be failing to blow hot air.",
"0300_9000_0001_0002": "Chamber heating failed. The chamber may not be enclosed, or the ambient temperature may be too low, or the heat dissipation vent of the power supply may be blocked.",
"0300_9000_0001_0003": "Chamber heating failed. The temperature of power supply may be too high.",
"0300_9000_0001_0004": "Chamber heating failed. The speed of the heating fan is too low.",
"0300_9000_0001_0005": "Chamber heating failed. The thermal resistance is too high.",
"0300_9000_0001_0010": "The communication of chamber temperature controller is abnormal.",
"0300_9100_0001_0001": "The temperature of chamber heater 1 is abnormal. The heater may have a short circuit.",
"0300_9100_0001_0002": "The temperature of chamber heater 1 is abnormal. The heater may have an open circuit or the thermal fuse may have taken effect.",
"0300_9100_0001_0003": "The temperature of chamber heater 1 is abnormal. The heater is over temperature.",
"0300_9100_0001_0006": "The temperature of chamber heater 1 is abnormal. The sensor may have a short circuit.",
"0300_9100_0001_0007": "The temperature of chamber heater 1 is abnormal. The sensor may have an open circuit.",
"0300_9100_0001_0008": "Chamber heater 1 failed to rise to target temperature.",
"0300_9100_0001_000A": "The temperature of chamber heater 1 is abnormal. The AC board may be broken.",
"0300_9100_0001_000C": "The chamber heater 1 has been working at full load for a long time. The temperature control system may have an issue.",
"0300_9200_0001_0001": "The temperature of chamber heater 2 is abnormal. The heater may have a short circuit.",
"0300_9200_0001_0002": "The temperature of chamber heater 2 is abnormal. The heater may have an open circuit or the thermal fuse may be in effect.",
"0300_9200_0001_0003": "The temperature of chamber heater 2 is abnormal. The heater is over temperature.",
"0300_9200_0001_0006": "The temperature of chamber heater 2 is abnormal. The sensor may have a short circuit.",
"0300_9200_0001_0007": "The temperature of chamber heater 2 is abnormal. The sensor may have an open circuit.",
"0300_9200_0001_0008": "Chamber heater 2 failed to rise to target temperature.",
"0300_9200_0001_000A": "The temperature of chamber heater 2 is abnormal. The AC board may be broken.",
"0300_9300_0001_0001": "Chamber temperature is abnormal. The chamber heater's temperature sensor may have a short circuit.",
"0300_9300_0001_0002": "Chamber temperature is abnormal. The chamber heater's temperature sensor may have an open circuit.",
"0300_9300_0001_0003": "Chamber temperature is abnormal. The chamber heater's temperature sensor at the air outlet may have a short circuit.",
"0300_9300_0001_0004": "Chamber temperature is abnormal. The chamber heater's temperature sensor at the air outlet may have an open circuit.",
"0300_9300_0001_0005": "Chamber temperature is abnormal. The chamber heater's temperature sensor at the air inlet may have a short circuit.",
"0300_9300_0001_0006": "Chamber temperature is abnormal. The chamber heater's temperature sensor at the air inlet may have an open circuit.",
"0300_9300_0001_0007": "Chamber temperature is abnormal. The temperature sensor at the power supply may have a short circuit.",
"0300_9300_0001_0008": "Chamber temperature is abnormal. The temperature sensor at power supply may have an open circuit.",
"0300_9400_0002_0003": "Chamber failed to reach the desired temperature. The machine will stop waiting for the chamber temperature.",
"0300_9400_0003_0001": "Chamber cooling may be too slow. You can open the front door or top cover to help cooling if the air in chamber is non-toxic.",
"0300_9400_0003_0002": "Chamber temperature setting value exceed the limit, the boundary value will be set.",
"0300_9500_0001_0007": "",
"0300_9900_0001_0001": "",
"0300_9900_0001_0002": "",
"0300_9900_0001_0003": "",
"0300_9900_0003_0001": "",
"0500_0100_0002_0001": "The media pipeline is malfunctioning.",
"0500_0100_0002_0002": "USB camera is not connected. Please check video camera cable connection.",
"0500_0100_0002_0003": "USB camera is malfunctioning.",
"0500_0100_0003_0004": "Not enough space in MicroSD Card; please clear some space.",
"0500_0100_0003_0005": "MicroSD Card error: please reinsert, format or replace it.",
"0500_0100_0003_0006": "Unformatted MicroSD Card: please format it.",
"0500_0100_0003_0007": "Unable to record time-lapse photography without MicroSD card inserted.",
"0500_0200_0002_0001": "Failed to connect internet. Please check the network connection.",
"0500_0200_0002_0002": "Device login failed; please check your account information.",
"0500_0200_0002_0003": "Failed to connect internet; please check the network connection.",
"0500_0200_0002_0004": "Unauthorized user: please check your account information.",
"0500_0200_0002_0005": "Failed to connect internet; please check the network connection.",
"0500_0200_0002_0006": "Streaming function error. Please check the network and try again. You can restart or update the printer if the issue persists.",
"0500_0200_0002_0007": "Liveview service login failed; please check your network connection.",
"0500_0200_0002_0008": "Time synchronization failed.",
"0500_0300_0001_0001": "The MC module is malfunctioning; please restart the device or check device cable connection.",
"0500_0300_0001_0002": "The toolhead is malfunctioning. Please restart the device.",
"0500_0300_0001_0003": "The AMS module is malfunctioning. Please restart the device.",
"0500_0300_0001_0004": "The AHB module is malfunctioning. Please restart the device.",
"0500_0300_0001_0005": "Internal service is malfunctioning. Please restart the device.",
"0500_0300_0001_0006": "A system panic occurred. Please restart the device.",
"0500_0300_0001_0008": "A system hang occurred. Please restart the device.",
"0500_0300_0001_0009": "A system hang occurred. It has been recovered by automatic restart.",
"0500_0300_0001_000A": "System state is abnormal; please restore factory settings.",
"0500_0300_0001_000B": "The screen is malfunctioning; please restart the device.",
"0500_0300_0001_0021": "Hardware incompatible: please check the laser.",
"0500_0300_0001_0023": "The Chamber Temperature Control module is malfunctioning. Please restart the device.",
"0500_0300_0001_0024": "The current temperature is too low. In order to protect you and your printer. Printing task, moving axis and other operations is disabled. Please move the printer to an environment above 10°C.",
"0500_0300_0001_0025": "The current firmware is abnormal. Please update again.",
"0500_0300_0002_000C": "Wireless hardware error: please turn off/on WiFi or restart the device.",
"0500_0300_0002_000D": "The SD Card controller is malfunctioning.",
"0500_0300_0002_0010": "forward coredump, it is recovering.",
"0500_0300_0002_0011": "upgrade coredump, it is recovering.",
"0500_0300_0002_0012": "ipcam coredump, it is recovering.",
"0500_0300_0002_0013": "xcam coredump, it is recovering.",
"0500_0300_0002_0014": "bbl_screen coredump, it is recovering.",
"0500_0300_0002_0015": "device_gate coredump, it is recovering.",
"0500_0300_0002_0016": "device_manager coredump, it is recovering.",
"0500_0300_0002_0017": "recorder coredump, it is recovering.",
"0500_0300_0002_0018": "security coredump, it is recovering.",
"0500_0300_0002_0020": "Micro SD Card capacity is insufficient to cache print files.",
"0500_0300_0003_0007": "A system panic occurred. It has been recovered by automatic restart.",
"0500_0300_0003_0022": "MicroSD Card performance degradation has been detected. It may affect print jobs, logs, and video records. Please try to format or change the MicroSD card.",
"0500_0400_0001_0001": "Failed to download print job. Please check your network connection.",
"0500_0400_0001_0002": "Failed to report print state. Please check your network connection.",
"0500_0400_0001_0003": "The content of print file is unreadable. Please resend the print job.",
"0500_0400_0001_0004": "The print file is unauthorized.",
"0500_0400_0001_0006": "Failed to resume previous print.",
"0500_0400_0002_0007": "The bed temperature exceeds the filament's vitrification temperature, which may cause a nozzle clog. Please keep the front door of the printer open or lower the bed temperature.",
"0500_0400_0002_0010": "The RFID-tag on AMS A Slot1 cannot be identified.",
"0500_0400_0002_0011": "The RFID-tag on AMS A Slot2 cannot be identified.",
"0500_0400_0002_0012": "The RFID-tag on AMS A Slot3 cannot be identified.",
"0500_0400_0002_0013": "The RFID-tag on AMS A Slot4 cannot be identified.",
"0500_0400_0002_0014": "The RFID-tag on AMS B Slot1 cannot be identified.",
"0500_0400_0002_0015": "The RFID-tag on AMS B Slot2 cannot be identified.",
"0500_0400_0002_0016": "The RFID-tag on AMS B Slot3 cannot be identified.",
"0500_0400_0002_0017": "The RFID-tag on AMS B Slot4 cannot be identified.",
"0500_0400_0002_0018": "The RFID-tag on AMS C Slot1 cannot be identified.",
"0500_0400_0002_0019": "The RFID-tag on AMS C Slot2 cannot be identified.",
"0500_0400_0002_001A": "The RFID-tag on AMS C Slot3 cannot be identified.",
"0500_0400_0002_001B": "The RFID-tag on AMS C Slot4 cannot be identified.",
"0500_0400_0002_001C": "The RFID-tag on AMS D Slot1 cannot be identified.",
"0500_0400_0002_001D": "The RFID-tag on AMS D Slot2 cannot be identified.",
"0500_0400_0002_001E": "The RFID-tag on AMS D Slot3 cannot be identified.",
"0500_0400_0002_001F": "The RFID-tag on AMS D Slot4 cannot be identified.",
"0500_0400_0002_0020": "",
"0500_0400_0003_0008": "The door is detected to be open.",
"0500_0400_0003_0009": "The bed temperature exceeds filament's vitrification temperature, which may cause nozzle clog. Please keep the front door of printer open. Already turning off the door opening detection temporarily.",
"0500_0500_0001_0001": "The factory data of AP board is abnormal; please replace the AP board with a new one.",
"0500_0500_0001_0006": "The factory data of AP board is abnormal, please replace the AP board with a new one.",
"0500_0500_0003_0002": "The device is in the engineering state; please pay attention to the information security related matters.",
"07FF_2000_0002_0001": "External filament has run out; please load a new filament.",
"07FF_2000_0002_0002": "External filament is missing; please load a new filament.",
"07FF_2000_0002_0004": "Please pull the external filament from the extruder.",
"0C00_0100_0001_0001": "The Micro Lidar camera is offline. Please check the hardware connection.",
"0C00_0100_0001_0003": "Synchronization between the Micro Lidar camera and MCU is abnormal. Please restart your printer.",
"0C00_0100_0001_0004": "The Micro Lidar camera lens seems to be dirty. Please clean the lens.",
"0C00_0100_0001_0005": "Micro Lidar camera OTP parameter is abnormal. Please contact after-sales.",
"0C00_0100_0001_0009": "The chamber camera lens seems to be dirty. Please clean the lens.",
"0C00_0100_0001_000A": "The Micro Lidar LED may be broken.",
"0C00_0100_0001_000B": "Failed to calibrate Micro Lidar. Please make sure the calibration chart is clean and not occluded, and run machine calibration again.",
"0C00_0100_0002_0002": "The Micro Lidar camera is malfunctioning and related functions may fail. Please contact after-sales if this message keeps appearing in multiple prints.",
"0C00_0100_0002_0006": "Micro Lidar camera extrinsic parameters are abnormal. Please enable flowrate calibration in your next print.",
"0C00_0100_0002_0007": "Micro Lidar laser parameters are drifted. Please re-calibrate your printer.",
"0C00_0100_0002_0008": "Failed to get image from chamber camera. Spaghetti and waste chute pileup detection is not available for now.",
"0C00_0200_0001_0001": "The horizontal laser is not lit. Please check if it's covered or hardware connection is normal.",
"0C00_0200_0001_0005": "A new Micro Lidar was detected. Please calibrate it on Calibration page before use.",
"0C00_0200_0002_0002": "The horizontal laser line is too wide. Please check if the heatbed is dirty.",
"0C00_0200_0002_0003": "The horizontal laser is not bright enough at homing position. Please clean or replace heatbed if this message appears repeatedly.",
"0C00_0200_0002_0004": "Nozzle height seems too low. Please check if the nozzle is worn or tilted. Re-calibrate Lidar if the nozzle has been replaced.",
"0C00_0200_0002_0006": "Nozzle height seems too high. Please check if there is filament residual attached to the nozzle.",
"0C00_0200_0002_0007": "The vertical laser is not lit. Please check if it's covered or hardware connection is normal.",
"0C00_0200_0002_0008": "The vertical laser line is too wide. Please check if the heatbed is dirty.",
"0C00_0200_0002_0009": "The vertical laser is not bright enough at homing position. Please clean or replace heatbed if this message appears repeatedly.",
"0C00_0300_0001_0009": "The first layer inspection module rebooted abnormally. The inspection result may be inaccurate.",
"0C00_0300_0001_000A": "Your printer is in factory mode. Please contact Technical Support.",
"0C00_0300_0002_0001": "Filament exposure metering failed because laser reflection is too weak on this material. First layer inspection may be inaccurate.",
"0C00_0300_0002_0002": "First layer inspection terminated due to abnormal Lidar data.",
"0C00_0300_0002_0004": "First layer inspection is not supported for the current print job.",
"0C00_0300_0002_0005": "First layer inspection timed out abnormally, and the current results may be inaccurate.",
"0C00_0300_0002_000C": "The build plate localization marker is not detected. Please check if the build plate is aligned correctly.",
"0C00_0300_0002_000F": "Parts skipped before first layer inspection; the inspection will not be supported for the current print.",
"0C00_0300_0002_0010": "Foreign objects detected on heatbed, Please check and clean the heatbed.",
"0C00_0300_0003_0006": "Purged filament may have piled up in the waste chute. Please check and clean the chute.",
"0C00_0300_0003_0007": "Possible first layer defects have been detected. Please check the first layer quality and decide if the job should be stopped.",
"0C00_0300_0003_0008": "Possible spaghetti defects were detected. Please check the print quality and decide if the job should be stopped.",
"0C00_0300_0003_000B": "Inspecting the first layer: please wait a moment.",
"0C00_0300_0003_000D": "Some objects may have fallen down, or the extruder is not extruding normally. Please check and decide if the printing should be stopped.",
"0C00_0300_0003_000E": "Your nozzle seems to be covered with jammed or clogged material.",
"0C00_0300_0003_000F": "Your nozzle seems to be covered with jammed or clogged material.",
"0C00_0300_0003_0010": "Your printer seems to be printing without extruding.",
"0C00_0400_0001_0017": "",
"1200_1000_0001_0001": "The AMS A Slot1 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"1200_1000_0001_0003": "The AMS A Slot1 motor torque control is malfunctioning. The current sensor may be faulty.",
"1200_1000_0002_0002": "The AMS A Slot1 motor is overloaded. The filament may be tangled or stuck.",
"1200_1100_0001_0001": "The AMS A Slot2 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"1200_1100_0001_0003": "The AMS A Slot2 motor torque control is malfunctioning. The current sensor may be faulty.",
"1200_1100_0002_0002": "The AMS A Slot2 motor is overloaded. The filament may be tangled or stuck.",
"1200_1200_0001_0001": "The AMS A Slot3 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"1200_1200_0001_0003": "The AMS A Slot3 motor torque control is malfunctioning. The current sensor may be faulty.",
"1200_1200_0002_0002": "The AMS A Slot3 motor is overloaded. The filament may be tangled or stuck.",
"1200_1300_0001_0001": "The AMS A Slot4 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"1200_1300_0001_0003": "The AMS A Slot4 motor torque control is malfunctioning. The current sensor may be faulty.",
"1200_1300_0002_0002": "The AMS A Slot4 motor is overloaded. The filament may be tangled or stuck.",
"1200_2000_0002_0001": "AMS A Slot1 filament has run out; please insert a new filament.",
"1200_2000_0002_0002": "AMS A Slot 1 is empty; please insert a new filament.",
"1200_2000_0002_0003": "AMS A Slot1 filament may be broken in the PTFE tube.",
"1200_2000_0002_0004": "AMS A Slot1 filament may be broken in the tool head.",
"1200_2000_0002_0005": "AMS A Slot1 filament has run out, and purging the old filament went abnormally; please check to see if filament is stuck in the toolhead.",
"1200_2000_0002_0006": "Failed to extrude AMS A Slot1 filament; the extruder may be clogged or the filament may be too thin, causing the extruder to slip.",
"1200_2000_0003_0001": "AMS A Slot1 filament has run out. Purging the old filament; please wait.",
"1200_2000_0003_0002": "AMS A Slot1 filament has run out and automatically switched to the slot with the same filament.",
"1200_2100_0002_0001": "AMS A Slot2 filament has run out; please insert a new filament.",
"1200_2100_0002_0002": "AMS A Slot 2 is empty; please insert a new filament.",
"1200_2100_0002_0003": "AMS A Slot2 filament may be broken in the PTFE tube.",
"1200_2100_0002_0004": "AMS A Slot2 filament may be broken in the tool head.",
"1200_2100_0002_0005": "AMS A Slot2 filament has run out, and purging the old filament went abnormally; please check to see if filament is stuck in the toolhead.",
"1200_2100_0002_0006": "Failed to extrude AMS A Slot2 filament; the extruder may be clogged or the filament may be too thin, causing the extruder to slip.",
"1200_2100_0003_0001": "AMS A Slot2 filament has run out. Purging the old filament; please wait.",
"1200_2100_0003_0002": "AMS A Slot2 filament has run out and automatically switched to the slot with the same filament.",
"1200_2200_0002_0001": "AMS A Slot3 filament has run out; please insert a new filament.",
"1200_2200_0002_0002": "AMS A Slot 3 is empty; please insert a new filament.",
"1200_2200_0002_0003": "AMS A Slot3 filament may be broken in the PTFE tube.",
"1200_2200_0002_0004": "AMS A Slot3 filament may be broken in the tool head.",
"1200_2200_0002_0005": "AMS A Slot3 filament has run out, and purging the old filament went abnormally; please check to see if filament is stuck in the toolhead.",
"1200_2200_0002_0006": "Failed to extrude AMS A Slot3 filament; the extruder may be clogged or the filament may be too thin, causing the extruder to slip.",
"1200_2200_0003_0001": "AMS A Slot3 filament has run out. Purging the old filament; please wait.",
"1200_2200_0003_0002": "AMS A Slot3 filament has run out and automatically switched to the slot with the same filament.",
"1200_2300_0002_0001": "AMS A Slot4 filament has run out; please insert a new filament.",
"1200_2300_0002_0002": "AMS A Slot 4 is empty; please insert a new filament.",
"1200_2300_0002_0003": "AMS A Slot4 filament may be broken in the PTFE tube.",
"1200_2300_0002_0004": "AMS A Slot4 filament may be broken in the tool head.",
"1200_2300_0002_0005": "AMS A Slot4 filament has run out, and purging the old filament went abnormally; please check to see if filament is stuck in the toolhead.",
"1200_2300_0002_0006": "Failed to extrude AMS A Slot4 filament; the extruder may be clogged or the filament may be too thin, causing the extruder to slip.",
"1200_2300_0003_0001": "AMS A Slot4 filament has run out. Purging the old filament; please wait.",
"1200_2300_0003_0002": "AMS A Slot4 filament has run out and automatically switched to the slot with the same filament.",
"1200_2400_0002_0001": "Filament may be broken in the tool head.",
"1200_2500_0002_0001": "Failed to extrude the filament and the extruder may be clogged.",
"1200_3000_0001_0001": "AMS A Slot 1 RFID coil is broken or the RF hardware circuit has an error.",
"1200_3000_0001_0004": "RFID cannot be read because of an encryption chip failure in AMSA.",
"1200_3000_0002_0002": "The RFID-tag on AMS A Slot 1 is damaged.",
"1200_3000_0003_0003": "AMS A Slot1 RFID cannot be read because of a structural error.",
"1200_3100_0001_0001": "AMS A Slot 2 RFID coil is broken or the RF hardware circuit has an error.",
"1200_3100_0002_0002": "The RFID-tag on AMS A Slot 2 is damaged.",
"1200_3100_0003_0003": "AMS A Slot2 RFID cannot be read because of a structural error.",
"1200_3200_0001_0001": "AMS A Slot 3 RFID coil is broken or the RF hardware circuit has an error.",
"1200_3200_0002_0002": "The RFID-tag on AMS A Slot 3 is damaged.",
"1200_3200_0003_0003": "AMS A Slot3 RFID cannot be read because of a structural error.",
"1200_3300_0001_0001": "AMS A Slot 4 RFID coil is broken or the RF hardware circuit has an error.",
"1200_3300_0002_0002": "The RFID-tag on AMS A Slot 4 is damaged.",
"1200_3300_0003_0003": "AMS A Slot4 RFID cannot be read because of a structural error.",
"1200_4500_0002_0001": "The filament cutter sensor is malfunctioning. Please check whether the connector is properly plugged in.",
"1200_4500_0002_0002": "The filament cutter's cutting distance is too large. The X motor may lose steps.",
"1200_4500_0002_0003": "The filament cutter handle has not been released. The handle or blade may be jammed, or there could be an issue with the filament sensor connection.",
"1200_5000_0002_0001": "AMS A communication is abnormal; please check the connection cable.",
"1200_5100_0003_0001": "AMS is disabled; please load filament from spool holder.",
"1200_7000_0001_0001": "AMS A Filament speed and length error: The slot 1 filament odometry may be faulty.",
"1200_7100_0001_0001": "AMS A Filament speed and length error: The slot 2 filament odometry may be faulty.",
"1200_7200_0001_0001": "AMS A Filament speed and length error: The slot 3 filament odometry may be faulty.",
"1200_7300_0001_0001": "AMS A Filament speed and length error: The slot 4 filament odometry may be faulty.",
"1200_8000_0002_0001": "AMS A Slot1 filament may be tangled or stuck.",
"1200_8100_0002_0001": "AMS A Slot2 filament may be tangled or stuck.",
"1200_8200_0002_0001": "AMS A Slot3 filament may be tangled or stuck.",
"1200_8300_0002_0001": "AMS A Slot4 filament may be tangled or stuck.",
"1201_1000_0001_0001": "The AMS B Slot1 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"1201_1000_0001_0003": "The AMS B Slot1 motor torque control is malfunctioning. The current sensor may be faulty.",
"1201_1000_0002_0002": "The AMS B Slot1 motor is overloaded. The filament may be tangled or stuck.",
"1201_1100_0001_0001": "The AMS B Slot2 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"1201_1100_0001_0003": "The AMS B Slot2 motor torque control is malfunctioning. The current sensor may be faulty.",
"1201_1100_0002_0002": "The AMS B Slot2 motor is overloaded. The filament may be tangled or stuck.",
"1201_1200_0001_0001": "The AMS B Slot3 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"1201_1200_0001_0003": "The AMS B Slot3 motor torque control is malfunctioning. The current sensor may be faulty.",
"1201_1200_0002_0002": "The AMS B Slot3 motor is overloaded. The filament may be tangled or stuck.",
"1201_1300_0001_0001": "The AMS B Slot4 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"1201_1300_0001_0003": "The AMS B Slot4 motor torque control is malfunctioning. The current sensor may be faulty.",
"1201_1300_0002_0002": "The AMS B Slot4 motor is overloaded. The filament may be tangled or stuck.",
"1201_2000_0002_0001": "AMS B Slot1 filament has run out; please insert a new filament.",
"1201_2000_0002_0002": "AMS B Slot 1 is empty; please insert a new filament.",
"1201_2000_0002_0003": "AMS B Slot1 filament may be broken in the PTFE tube.",
"1201_2000_0002_0004": "AMS B Slot1 filament may be broken in the tool head.",
"1201_2000_0002_0005": "AMS B Slot1 filament has run out, and purging the old filament went abnormally; please check to see if filament is stuck in the toolhead.",
"1201_2000_0002_0006": "Failed to extrude AMS B Slot1 filament; the extruder may be clogged or the filament may be too thin, causing the extruder to slip.",
"1201_2000_0003_0001": "AMS B Slot1 filament has run out. Purging the old filament; please wait.",
"1201_2000_0003_0002": "AMS B Slot1 filament has run out and automatically switched to the slot with the same filament.",
"1201_2100_0002_0001": "AMS B Slot2 filament has run out; please insert a new filament.",
"1201_2100_0002_0002": "AMS B Slot 2 is empty; please insert a new filament.",
"1201_2100_0002_0003": "AMS B Slot2 filament may be broken in the PTFE tube.",
"1201_2100_0002_0004": "AMS B Slot2 filament may be broken in the tool head.",
"1201_2100_0002_0005": "AMS B Slot2 filament has run out, and purging the old filament went abnormally; please check to see if filament is stuck in the toolhead.",
"1201_2100_0002_0006": "Failed to extrude AMS B Slot2 filament; the extruder may be clogged or the filament may be too thin, causing the extruder to slip.",
"1201_2100_0003_0001": "AMS B Slot2 filament has run out. Purging the old filament; please wait.",
"1201_2100_0003_0002": "AMS B Slot2 filament has run out and automatically switched to the slot with the same filament.",
"1201_2200_0002_0001": "AMS B Slot3 filament has run out; please insert a new filament.",
"1201_2200_0002_0002": "AMS B Slot 3 is empty; please insert a new filament.",
"1201_2200_0002_0003": "AMS B Slot3 filament may be broken in the PTFE tube.",
"1201_2200_0002_0004": "AMS B Slot3 filament may be broken in the tool head.",
"1201_2200_0002_0005": "AMS B Slot3 filament has run out, and purging the old filament went abnormally; please check to see if filament is stuck in the toolhead.",
"1201_2200_0002_0006": "Failed to extrude AMS B Slot3 filament; the extruder may be clogged or the filament may be too thin, causing the extruder to slip.",
"1201_2200_0003_0001": "AMS B Slot3 filament has run out. Purging the old filament; please wait.",
"1201_2200_0003_0002": "AMS B Slot3 filament has run out and automatically switched to the slot with the same filament.",
"1201_2300_0002_0001": "AMS B Slot4 filament has run out; please insert a new filament.",
"1201_2300_0002_0002": "AMS B Slot 4 is empty; please insert a new filament.",
"1201_2300_0002_0003": "AMS B Slot4 filament may be broken in the PTFE tube.",
"1201_2300_0002_0004": "AMS B Slot4 filament may be broken in the tool head.",
"1201_2300_0002_0005": "AMS B Slot4 filament has run out, and purging the old filament went abnormally; please check to see if filament is stuck in the toolhead.",
"1201_2300_0002_0006": "Failed to extrude AMS B Slot4 filament; the extruder may be clogged or the filament may be too thin, causing the extruder to slip.",
"1201_2300_0003_0001": "AMS B Slot4 filament has run out. Purging the old filament; please wait.",
"1201_2300_0003_0002": "AMS B Slot4 filament has run out and automatically switched to the slot with the same filament.",
"1201_3000_0001_0001": "AMS B Slot 1 RFID coil is broken or the RF hardware circuit has an error.",
"1201_3000_0001_0004": "RFID cannot be read because of an encryption chip failure in AMSB.",
"1201_3000_0002_0002": "The RFID-tag on AMS B Slot 1 is damaged.",
"1201_3000_0003_0003": "AMS B Slot1 RFID cannot be read because of a structural error.",
"1201_3100_0001_0001": "AMS B Slot 2 RFID coil is broken or the RF hardware circuit has an error.",
"1201_3100_0002_0002": "The RFID-tag on AMS B Slot 2 is damaged.",
"1201_3100_0003_0003": "AMS B Slot2 RFID cannot be read because of a structural error.",
"1201_3200_0001_0001": "AMS B Slot 3 RFID coil is broken or the RF hardware circuit has an error.",
"1201_3200_0002_0002": "The RFID-tag on AMS B Slot 3 is damaged.",
"1201_3200_0003_0003": "AMS B Slot3 RFID cannot be read because of a structural error.",
"1201_3300_0001_0001": "AMS B Slot 4 RFID coil is broken or the RF hardware circuit has an error.",
"1201_3300_0002_0002": "The RFID-tag on AMS B Slot 4 is damaged.",
"1201_3300_0003_0003": "AMS B Slot4 RFID cannot be read because of a structural error.",
"1201_5000_0002_0001": "AMS B communication is abnormal; please check the connection cable.",
"1201_7000_0001_0001": "AMS B Filament speed and length error: The slot 1 filament odometry may be faulty.",
"1201_7100_0001_0001": "AMS B Filament speed and length error: The slot 2 filament odometry may be faulty.",
"1201_7200_0001_0001": "AMS B Filament speed and length error: The slot 3 filament odometry may be faulty.",
"1201_7300_0001_0001": "AMS B Filament speed and length error: The slot 4 filament odometry may be faulty.",
"1201_8000_0002_0001": "AMS B Slot1 filament may be tangled or stuck.",
"1201_8100_0002_0001": "AMS B Slot2 filament may be tangled or stuck.",
"1201_8200_0002_0001": "AMS B Slot3 filament may be tangled or stuck.",
"1201_8300_0002_0001": "AMS B Slot4 filament may be tangled or stuck.",
"1202_1000_0001_0001": "The AMS C Slot1 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"1202_1000_0001_0003": "The AMS C Slot1 motor torque control is malfunctioning. The current sensor may be faulty.",
"1202_1000_0002_0002": "The AMS C Slot1 motor is overloaded. The filament may be tangled or stuck.",
"1202_1100_0001_0001": "The AMS C Slot2 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"1202_1100_0001_0003": "The AMS C Slot2 motor torque control is malfunctioning. The current sensor may be faulty.",
"1202_1100_0002_0002": "The AMS C Slot2 motor is overloaded. The filament may be tangled or stuck.",
"1202_1200_0001_0001": "The AMS C Slot3 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"1202_1200_0001_0003": "The AMS C Slot3 motor torque control is malfunctioning. The current sensor may be faulty.",
"1202_1200_0002_0002": "The AMS C Slot3 motor is overloaded. The filament may be tangled or stuck.",
"1202_1300_0001_0001": "The AMS C Slot4 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"1202_1300_0001_0003": "The AMS C Slot4 motor torque control is malfunctioning. The current sensor may be faulty.",
"1202_1300_0002_0002": "The AMS C Slot4 motor is overloaded. The filament may be tangled or stuck.",
"1202_2000_0002_0001": "AMS C Slot1 filament has run out; please insert a new filament.",
"1202_2000_0002_0002": "AMS C Slot 1 is empty; please insert a new filament.",
"1202_2000_0002_0003": "AMS C Slot1 filament may be broken in the PTFE tube.",
"1202_2000_0002_0004": "AMS C Slot1 filament may be broken in the tool head.",
"1202_2000_0002_0005": "AMS C Slot1 filament has run out, and purging the old filament went abnormally; please check to see if filament is stuck in the toolhead.",
"1202_2000_0002_0006": "Failed to extrude AMS C Slot1 filament; the extruder may be clogged or the filament may be too thin, causing the extruder to slip.",
"1202_2000_0003_0001": "AMS C Slot1 filament has run out. Purging the old filament; please wait.",
"1202_2000_0003_0002": "AMS C Slot1 filament has run out and automatically switched to the slot with the same filament.",
"1202_2100_0002_0001": "AMS C Slot2 filament has run out; please insert a new filament.",
"1202_2100_0002_0002": "AMS C Slot 2 is empty; please insert a new filament.",
"1202_2100_0002_0003": "AMS C Slot2 filament may be broken in the PTFE tube.",
"1202_2100_0002_0004": "AMS C Slot2 filament may be broken in the tool head.",
"1202_2100_0002_0005": "AMS C Slot2 filament has run out, and purging the old filament went abnormally; please check to see if filament is stuck in the toolhead.",
"1202_2100_0002_0006": "Failed to extrude AMS C Slot2 filament; the extruder may be clogged or the filament may be too thin, causing the extruder to slip.",
"1202_2100_0003_0001": "AMS C Slot2 filament has run out. Purging the old filament; please wait.",
"1202_2100_0003_0002": "AMS C Slot2 filament has run out and automatically switched to the slot with the same filament.",
"1202_2200_0002_0001": "AMS C Slot3 filament has run out; please insert a new filament.",
"1202_2200_0002_0002": "AMS C Slot 3 is empty; please insert a new filament.",
"1202_2200_0002_0003": "AMS C Slot3 filament may be broken in the PTFE tube.",
"1202_2200_0002_0004": "AMS C Slot3 filament may be broken in the tool head.",
"1202_2200_0002_0005": "AMS C Slot3 filament has run out, and purging the old filament went abnormally; please check to see if filament is stuck in the toolhead.",
"1202_2200_0002_0006": "Failed to extrude AMS C Slot3 filament; the extruder may be clogged or the filament may be too thin, causing the extruder to slip.",
"1202_2200_0003_0001": "AMS C Slot3 filament has run out. Purging the old filament; please wait.",
"1202_2200_0003_0002": "AMS C Slot3 filament has run out and automatically switched to the slot with the same filament.",
"1202_2300_0002_0001": "AMS C Slot4 filament has run out; please insert a new filament.",
"1202_2300_0002_0002": "AMS C Slot 4 is empty; please insert a new filament.",
"1202_2300_0002_0003": "AMS C Slot4 filament may be broken in the PTFE tube.",
"1202_2300_0002_0004": "AMS C Slot4 filament may be broken in the tool head.",
"1202_2300_0002_0005": "AMS C Slot4 filament has run out, and purging the old filament went abnormally; please check to see if filament is stuck in the toolhead.",
"1202_2300_0002_0006": "Failed to extrude AMS C Slot4 filament; the extruder may be clogged or the filament may be too thin, causing the extruder to slip.",
"1202_2300_0003_0001": "AMS C Slot4 filament has run out. Purging the old filament; please wait.",
"1202_2300_0003_0002": "AMS C Slot4 filament has run out and automatically switched to the slot with the same filament.",
"1202_3000_0001_0001": "AMS C Slot 1 RFID coil is broken or the RF hardware circuit has an error.",
"1202_3000_0001_0004": "RFID cannot be read because of an encryption chip failure in AMSC.",
"1202_3000_0002_0002": "The RFID-tag on AMS C Slot 1 is damaged.",
"1202_3000_0003_0003": "AMS C Slot1 RFID cannot be read because of a structural error.",
"1202_3100_0001_0001": "AMS C Slot 2 RFID coil is broken or the RF hardware circuit has an error.",
"1202_3100_0002_0002": "The RFID-tag on AMS C Slot 2 is damaged.",
"1202_3100_0003_0003": "AMS C Slot2 RFID cannot be read because of a structural error.",
"1202_3200_0001_0001": "AMS C Slot 3 RFID coil is broken or the RF hardware circuit has an error.",
"1202_3200_0002_0002": "The RFID-tag on AMS C Slot 3 is damaged.",
"1202_3200_0003_0003": "AMS C Slot3 RFID cannot be read because of a structural error.",
"1202_3300_0001_0001": "AMS C Slot 4 RFID coil is broken or the RF hardware circuit has an error.",
"1202_3300_0002_0002": "The RFID-tag on AMS C Slot 4 is damaged.",
"1202_3300_0003_0003": "AMS C Slot4 RFID cannot be read because of a structural error.",
"1202_5000_0002_0001": "AMS C communication is abnormal; please check the connection cable.",
"1202_7000_0001_0001": "AMS C Filament speed and length error: The slot 1 filament odometry may be faulty.",
"1202_7100_0001_0001": "AMS C Filament speed and length error: The slot 2 filament odometry may be faulty.",
"1202_7200_0001_0001": "AMS C Filament speed and length error: The slot 3 filament odometry may be faulty.",
"1202_7300_0001_0001": "AMS C Filament speed and length error: The slot 4 filament odometry may be faulty.",
"1202_8000_0002_0001": "AMS C Slot1 filament may be tangled or stuck.",
"1202_8100_0002_0001": "AMS C Slot2 filament may be tangled or stuck.",
"1202_8200_0002_0001": "AMS C Slot3 filament may be tangled or stuck.",
"1202_8300_0002_0001": "AMS C Slot4 filament may be tangled or stuck.",
"1203_1000_0001_0001": "The AMS D Slot1 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"1203_1000_0001_0003": "The AMS D Slot1 motor torque control is malfunctioning. The current sensor may be faulty.",
"1203_1000_0002_0002": "The AMS D Slot1 motor is overloaded. The filament may be tangled or stuck.",
"1203_1100_0001_0001": "The AMS D Slot2 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"1203_1100_0001_0003": "The AMS D Slot2 motor torque control is malfunctioning. The current sensor may be faulty.",
"1203_1100_0002_0002": "The AMS D Slot2 motor is overloaded. The filament may be tangled or stuck.",
"1203_1200_0001_0001": "The AMS D Slot3 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"1203_1200_0001_0003": "The AMS D Slot3 motor torque control is malfunctioning. The current sensor may be faulty.",
"1203_1200_0002_0002": "The AMS D Slot3 motor is overloaded. The filament may be tangled or stuck.",
"1203_1300_0001_0001": "The AMS D Slot4 motor has slipped. The extrusion wheel may be malfunctioning, or the filament may be too thin.",
"1203_1300_0001_0003": "The AMS D Slot4 motor torque control is malfunctioning. The current sensor may be faulty.",
"1203_1300_0002_0002": "The AMS D Slot4 motor is overloaded. The filament may be tangled or stuck.",
"1203_2000_0002_0001": "AMS D Slot1 filament has run out; please insert a new filament.",
"1203_2000_0002_0002": "AMS D Slot 1 is empty; please insert a new filament.",
"1203_2000_0002_0003": "AMS D Slot1 filament may be broken in the PTFE tube.",
"1203_2000_0002_0004": "AMS D Slot1 filament may be broken in the tool head.",
"1203_2000_0002_0005": "AMS D Slot1 filament has run out, and purging the old filament went abnormally; please check to see if filament is stuck in the toolhead.",
"1203_2000_0002_0006": "Failed to extrude AMS D Slot1 filament; the extruder may be clogged or the filament may be too thin, causing the extruder to slip.",
"1203_2000_0003_0001": "AMS D Slot1 filament has run out. Purging the old filament; please wait.",
"1203_2000_0003_0002": "AMS D Slot1 filament has run out and automatically switched to the slot with the same filament.",
"1203_2100_0002_0001": "AMS D Slot2 filament has run out; please insert a new filament.",
"1203_2100_0002_0002": "AMS D Slot 2 is empty; please insert a new filament.",
"1203_2100_0002_0003": "AMS D Slot2 filament may be broken in the PTFE tube.",
"1203_2100_0002_0004": "AMS D Slot2 filament may be broken in the tool head.",
"1203_2100_0002_0005": "AMS D Slot2 filament has run out, and purging the old filament went abnormally; please check to see if filament is stuck in the toolhead.",
"1203_2100_0002_0006": "Failed to extrude AMS D Slot2 filament; the extruder may be clogged or the filament may be too thin, causing the extruder to slip.",
"1203_2100_0003_0001": "AMS D Slot2 filament has run out. Purging the old filament; please wait.",
"1203_2100_0003_0002": "AMS D Slot2 filament has run out and automatically switched to the slot with the same filament.",
"1203_2200_0002_0001": "AMS D Slot3 filament has run out; please insert a new filament.",
"1203_2200_0002_0002": "AMS D Slot 3 is empty; please insert a new filament.",
"1203_2200_0002_0003": "AMS D Slot3 filament may be broken in the PTFE tube.",
"1203_2200_0002_0004": "AMS D Slot3 filament may be broken in the tool head.",
"1203_2200_0002_0005": "AMS D Slot3 filament has run out, and purging the old filament went abnormally; please check to see if filament is stuck in the toolhead.",
"1203_2200_0002_0006": "Failed to extrude AMS D Slot3 filament; the extruder may be clogged or the filament may be too thin, causing the extruder to slip.",
"1203_2200_0003_0001": "AMS D Slot3 filament has run out. Purging the old filament; please wait.",
"1203_2200_0003_0002": "AMS D Slot3 filament has run out and automatically switched to the slot with the same filament.",
"1203_2300_0002_0001": "AMS D Slot4 filament has run out; please insert a new filament.",
"1203_2300_0002_0002": "AMS D Slot 4 is empty; please insert a new filament.",
"1203_2300_0002_0003": "AMS D Slot4 filament may be broken in the PTFE tube.",
"1203_2300_0002_0004": "AMS D Slot4 filament may be broken in the tool head.",
"1203_2300_0002_0005": "AMS D Slot4 filament has run out, and purging the old filament went abnormally; please check to see if filament is stuck in the toolhead.",
"1203_2300_0002_0006": "Failed to extrude AMS D Slot4 filament; the extruder may be clogged or the filament may be too thin, causing the extruder to slip.",
"1203_2300_0003_0001": "AMS D Slot4 filament has run out. Purging the old filament; please wait.",
"1203_2300_0003_0002": "AMS D Slot4 filament has run out and automatically switched to the slot with the same filament.",
"1203_3000_0001_0001": "AMS D Slot 1 RFID coil is broken or the RF hardware circuit has an error.",
"1203_3000_0001_0004": "RFID cannot be read because of an encryption chip failure in AMSD.",
"1203_3000_0002_0002": "The RFID-tag on AMS D Slot 1 is damaged.",
"1203_3000_0003_0003": "AMS D Slot1 RFID cannot be read because of a structural error.",
"1203_3100_0001_0001": "AMS D Slot 2 RFID coil is broken or the RF hardware circuit has an error.",
"1203_3100_0002_0002": "The RFID-tag on AMS D Slot 2 is damaged.",
"1203_3100_0003_0003": "AMS D Slot2 RFID cannot be read because of a structural error.",
"1203_3200_0001_0001": "AMS D Slot 3 RFID coil is broken or the RF hardware circuit has an error.",
"1203_3200_0002_0002": "The RFID-tag on AMS D Slot 3 is damaged.",
"1203_3200_0003_0003": "AMS D Slot3 RFID cannot be read because of a structural error.",
"1203_3300_0001_0001": "AMS D Slot 4 RFID coil is broken or the RF hardware circuit has an error.",
"1203_3300_0002_0002": "The RFID-tag on AMS D Slot 4 is damaged.",
"1203_3300_0003_0003": "AMS D Slot4 RFID cannot be read because of a structural error.",
"1203_5000_0002_0001": "AMS D communication is abnormal; please check the connection cable.",
"1203_7000_0001_0001": "AMS D Filament speed and length error: The slot 1 filament odometry may be faulty.",
"1203_7100_0001_0001": "AMS D Filament speed and length error: The slot 2 filament odometry may be faulty.",
"1203_7200_0001_0001": "AMS D Filament speed and length error: The slot 3 filament odometry may be faulty.",
"1203_7300_0001_0001": "AMS D Filament speed and length error: The slot 4 filament odometry may be faulty.",
"1203_8000_0002_0001": "AMS D Slot1 filament may be tangled or stuck.",
"1203_8100_0002_0001": "AMS D Slot2 filament may be tangled or stuck.",
"1203_8200_0002_0001": "AMS D Slot3 filament may be tangled or stuck.",
"1203_8300_0002_0001": "AMS D Slot4 filament may be tangled or stuck.",
"12FF_2000_0002_0001": "Filament at the spool holder has run out; please insert a new filament.",
"12FF_2000_0002_0002": "Filament on the spool holder is empty; please insert a new filament.",
"12FF_2000_0002_0004": "Please pull out the filament on the spool holder from the extruder.",
"12FF_2000_0002_0005": "Filament may be broken in the tool head.",
"12FF_2000_0002_0006": "Failed to extrude the filament and the extruder may be clogged.",
"12FF_2000_0002_0007": "Failed to check the filament location in the tool head; please click for more help.",
"12FF_2000_0003_0007": "Checking the filament location of all AMS slots, please wait.",
"12FF_8000_0002_0001": "The filament on the spool holder may be tangled or stuck.",
}

View File

@ -0,0 +1,276 @@
PRINT_ERROR_ERRORS = {
"0300_4000": "Printing stopped because homing Z axis failed.",
"0300_4001": "The printer timed out waiting for the nozzle to cool down before homing.",
"0300_4002": "Printing Stopped because Auto Bed Leveling failed.",
"0300_4003": "Nozzle temperature malfunction.",
"0300_4004": "Heatbed temperature malfunction.",
"0300_4005": "The hotend cooling fan speed is abnormal.",
"0300_4006": "The nozzle is clogged.",
"0300_4008": "The AMS failed to change filament.",
"0300_4009": "Homing XY axis failed.",
"0300_400A": "Mechanical resonance frequency identification failed.",
"0300_400B": "Internal communication exception.",
"0300_400C": "Printing was cancelled.",
"0300_400D": "Resume failed after power loss.",
"0300_400E": "The motor self-check failed.",
"0300_400F": "No build plate is placed.",
"0300_8000": "Printing was paused for unknown reason. You can tap 'Resume' to resume the print job.",
"0300_8001": "Printing paused. It was due to the pause command added in the printing file.",
"0300_8002": "First layer defects were detected by the Micro Lidar. Please check the quality of the printed model before continuing your print.",
"0300_8003": "Spaghetti defects were detected by the AI Print Monitoring. Please check the quality of the printed model before continuing your print.",
"0300_8004": "Filament ran out. Please load new filament.",
"0300_8005": "Toolhead front cover fell off. Please remount the front cover and check to make sure your print is going okay.",
"0300_8006": "The build plate marker was not detected. Please confirm the build plate is correctly positioned on the heatbed with all four corners aligned, and the maker is clear.",
"0300_8007": "There was an unfinished print job when the printer lost power. If the model is still adhered to the build plate, you can try resuming the print job.",
"0300_8008": "Printing Stopped because nozzle temperature problem.",
"0300_8009": "Heatbed temperature malfunction.",
"0300_800A": "A Filament pile-up was detected by the AI Print Monitoring. Please clean the filament from the waste chute.",
"0300_800B": "The cutter is stuck. Please make sure the cutter handle is out, and check the filament sensor cable connection.",
"0300_800C": "Skipping step detected, auto-recover complete; please resume print and check if there are any layer shift problems.",
"0300_800D": "Some objects have fallen down, or the extruder is not extruding normally. If the defects are acceptable, click 'Resume' button to resume the print job.",
"0300_800E": "The print file is not available. Please check to see if the storage media has been removed.",
"0300_800F": "The door seems to be open, so printing was paused.",
"0300_8010": "The hotend cooling fan speed is abnormal.",
"0300_8011": "Detected build plate is not the same as the Gcode file. Please adjust slicer settings or use the correct plate.",
"0300_8012": "",
"0300_8013": "Printing was paused by the user. You can select 'Resume' to continue printing.",
"0300_8014": "The nozzle is covered with filaments, or the build plate is installed incorrectly. Please cancel this printing and clean the nozzle or adjust the build plate according to the actual status, or tap 'Resume' button to resume the print job.",
"0300_8015": "The filament on external spool has run out, please load new filament. If the filament is loaded, please select 'Resume'.",
"0300_8016": "The nozzle is clogged up with filaments. Please cancel this printing and clean the nozzle according to the actual status, or tap 'Resume' button to resume the print job.",
"0300_8017": "Foreign objects detected on heatbed, Please check and clean the heatbed, Then tap 'Resume' button to resume the print job.",
"0300_8018": "Chamber temperature malfunction.",
"0300_8019": "No build plate is placed.",
"0300_801B": "Nozzle temperature problem detected. Refer to the Assistant to re-connect the hotend connector. POWER OFF the printer before this operation to avoid a short circuit.",
"0500_4001": "Failed to connect to Bambu Cloud. Please check your network connection.",
"0500_4002": "Unsupported print file path or name. Please resend the printing job.",
"0500_4003": "Printing stopped because the printer was unable to parse the file. Please resend your print job.",
"0500_4004": "The printer can't receive new print jobs while printing. Resend after the current print finishes.",
"0500_4005": "Print jobs are not allowed to be sent while updating firmware.",
"0500_4006": "There is not enough free storage space for the print job. Restoring to factory settings can release available space.",
"0500_4007": "Print jobs are not allowed to be sent while force updating or when repair updating is required.",
"0500_4008": "Starting printing failed. please power cycle the printer and resend the print job.",
"0500_4009": "Print jobs are not allowed to be sent while updating logs.",
"0500_400A": "The file name is not supported. Please rename and restart the printing job.",
"0500_400B": "There was a problem downloading a file. Please check you network connection and resend the printing job.",
"0500_400C": "Please insert a MicroSD card and restart the printing job.",
"0500_400D": "Please run a self-test and restart the printing job.",
"0500_400E": "Printing was cancelled.",
"0500_4012": "The door seems to be open, so printing was paused.",
"0500_4014": "Slicing for the print job failed. Please check your settings and restart the print job.",
"0500_4015": "There is not enough free storage space for the print job. Please format or clean MicroSD card to release available space.",
"0500_4016": "The MicroSD Card is write-protected. Please replace the MicroSD Card.",
"0500_4017": "Binding failed. Please retry or restart the printer and retry.",
"0500_4018": "Binding configuration information parsing failed, please try again.",
"0500_4019": "The printer has already been bound. Please unbind it and try again.",
"0500_401A": "Cloud access failed. Possible reasons include network instability caused by interference, inability to access the internet, or router firewall configuration restrictions. You can try moving the printer closer to the router or checking the router configuration and then try again.",
"0500_401B": "Cloud response is invalid. If you have tried multiple times and are still failing, please contact customer service.",
"0500_401C": "Cloud access is rejected. If you have tried multiple times and are still failing, please contact customer service.",
"0500_401D": "Cloud access failed, which may be caused by network instability due to interference. You can try moving the printer closer to the router before you try again.",
"0500_401E": "Cloud response is invalid. If you have tried multiple times and are still failing, please contact customer service.",
"0500_401F": "Authorization timed out. Please make sure that your phone or PC has access to the internet, and ensure that the Bambu Studio/Bambu Handy APP is running in the foreground during the binding operation.",
"0500_4020": "Cloud access rejected. If you have tried multiple times and are still failing, please contact customer service.",
"0500_4021": "Cloud access failed, which may be caused by network instability due to interference. You can try moving the printer closer to the router before you try again.",
"0500_4022": "Cloud response is invalid. If you have tried multiple times and are still failing, please contact customer service.",
"0500_4023": "Cloud access rejected. If you have tried multiple times and are still failing, please contact customer service.",
"0500_4024": "Cloud access failed. Possible reasons include network instability caused by interference, inability to access the internet, or router firewall configuration restrictions. You can try moving the printer closer to the router or checking the router configuration before you try again.",
"0500_4025": "Cloud response is invalid. If you have tried multiple times and are still failing, please contact customer service.",
"0500_4026": "Cloud access rejected. If you have tried multiple times and are still failing, please contact customer service.",
"0500_4027": "Cloud access failed; this may be caused by network instability due to interference. You can try moving the printer closer to the router before you try again.",
"0500_4028": "Cloud response is invalid. If you have tried multiple times and are still failing, please contact customer service.",
"0500_4029": "Cloud access is rejected. If you have tried multiple times and are still failing, please contact customer service.",
"0500_402A": "Failed to connect to the router, which may be caused by wireless interference or being too far away from the router. Please try again or move the printer closer to the router and try again.",
"0500_402B": "Router connection failed due to incorrect password. Please check the password and try again.",
"0500_402C": "Failed to obtain IP address, which may be caused by wireless interference resulting in data transmission failure or DHCP address pool of the router being full. Please move the printer closer to the router and try again. If the issue persists, please check router settings to see whether the IP addresses have been exhausted.",
"0500_402D": "System exception.",
"0500_402E": "The system does not support the file system currently used by the Micro SD card. Please replace the Micro SD card or format the current Micro SD card to FAT32.",
"0500_402F": "The Micro SD card sector data is damaged. Please use the SD card repair tool to repair or format it. If it still cannot be identified, please replace the Micro SD card.",
"0500_4037": "Your sliced file is not compatible with current printer model. This file can't be printed on this printer.",
"0500_4038": "The nozzle diameter in sliced file is not consistent with the current nozzle setting. This file can't be printed.",
"0500_403A": "The current temperature is too low. In order to protect you and your printer. Printing task, moving axis and other operations are disabled. Please move the printer to an environment above 10 celsius degree.",
"0500_8013": "The print file is not available. Please check to see if the storage media has been removed.",
"0500_8030": "",
"0500_8036": "Your sliced file is not consistent with the current printer model. Continue?",
"0500_C010": "MicroSD Card read/write exception. please reinsert or replace MicroSD Card .",
"0500_C011": "",
"0501_4017": "Binding failed. Please retry or restart the printer and retry.",
"0501_4018": "Binding configuration information parsing failed, please try again.",
"0501_4019": "The printer has already been bound. Please unbind it and try again.",
"0501_401A": "Cloud access failed. Possible reasons include network instability caused by interference, inability to access the internet, or router firewall configuration restrictions. You can try moving the printer closer to the router or checking the router configuration and then try again.",
"0501_401B": "Cloud response is invalid. If you have tried multiple times and are still failing, please contact customer service.",
"0501_401C": "Cloud access is rejected. If you have tried multiple times and are still failing, please contact customer service.",
"0501_401D": "Cloud access failed, which may be caused by network instability due to interference. You can try moving the printer closer to the router before you try again.",
"0501_401E": "Cloud response is invalid. If you have tried multiple times and are still failing, please contact customer service.",
"0501_401F": "Authorization timed out. Please make sure that your phone or PC has access to the internet, and ensure that the Bambu Studio/Bambu Handy APP is running in the foreground during the binding operation.",
"0501_4020": "Cloud access rejected. If you have tried multiple times and are still failing, please contact customer service.",
"0501_4021": "Cloud access failed, which may be caused by network instability due to interference. You can try moving the printer closer to the router before you try again.",
"0501_4022": "Cloud response is invalid. If you have tried multiple times and are still failing, please contact customer service.",
"0501_4023": "Cloud access rejected. If you have tried multiple times and are still failing, please contact customer service.",
"0501_4024": "Cloud access failed. Possible reasons include network instability caused by interference, inability to access the internet, or router firewall configuration restrictions. You can try moving the printer closer to the router or checking the router configuration before you try again.",
"0501_4025": "Cloud response is invalid. If you have tried multiple times and are still failing, please contact customer service.",
"0501_4026": "Cloud access rejected. If you have tried multiple times and are still failing, please contact customer service.",
"0501_4027": "Cloud access failed; this may be caused by network instability due to interference. You can try moving the printer closer to the router before you try again.",
"0501_4028": "Cloud response is invalid. If you have tried multiple times and are still failing, please contact customer service.",
"0501_4029": "Cloud access is rejected. If you have tried multiple times and are still failing, please contact customer service.",
"0501_4031": "Device discovery binding is in progress, and the QR code cannot be displayed on the screen. You can wait for the binding to finish or abort the device discovery binding process in the APP/Studio and retry scanning the QR code on the screen for binding.",
"0501_4032": "QR code binding is in progress, so device discovery binding cannot be performed. You can scan the QR code on the screen for binding or exit the QR code display page on screen and try device discovery binding.",
"0501_4033": "Your APP region is not matched with your printer; please download the APP in the corresponding region and register your account again.",
"0501_4034": "The slicing progress has not been updated for a long time, and the printing task has exited. Please confirm the parameters and reinitiate printing.",
"0501_4035": "The device is in the process of binding and cannot respond to new binding requests.",
"0501_4038": "The region settings do not match the printer; please check the printer's region settings.",
"0501_4039": "Device login has expired, please try to bind again.",
"0502_4001": "Current filament will be used in this print job. Settings cannot be changed.",
"0514_039": "Device login has expired; please try to bind again.",
"0700_4001": "The AMS has been disabled for a print, but it still has filament loaded. Please unload the AMS filament , and switch to the spool holder filament for printing.",
"0700_8001": "Failed to cut the filament. Please check the cutter. After troubleshooting, click the 'Retry' button.",
"0700_8002": "The cutter is stuck. Please make sure the cutter handle is out.",
"0700_8003": "Failed to pull out the filament from the extruder. This might be caused by clogged extruder or filament broken inside the extruder.",
"0700_8004": "AMS failed to pull back filament. This could be due to a stuck spool or the end of the filament being stuck in the path.",
"0700_8005": "The AMS failed to send out filament. You can clip the end of your filament flat, and reinsert. If this message persists, please check the PTFE tubes in AMS for any signs of wear and tear.",
"0700_8006": "Unable to feed filament into the extruder. This could be due to entangled filament or a stuck spool. If not, please check if the AMS PTFE tube is connected.",
"0700_8007": "Extruding filament failed. The extruder might be clogged.",
"0700_8010": "The AMS assist motor is overloaded. This could be due to entangled filament or a stuck spool.",
"0700_8011": "AMS filament ran out. Please insert a new filament into the same AMS slot.",
"0700_8012": "Failed to get AMS mapping table; please click 'Retry' to continue.",
"0700_8013": "Timeout purging old filament: Please check if the filament is stuck or the extruder is clogged. After troubleshooting, click the 'Retry' button.",
"0701_4001": "Filament is still loaded from the AMS after it has been disabled. Please unload the filament, load from the spool holder, and restart printing.",
"0701_8001": "Failed to cut the filament. Please check the cutter. After troubleshooting, click the 'Retry' button.",
"0701_8002": "The cutter is stuck. Please pull out the cutter handle and click the 'Retry' button.",
"0701_8003": "Failed to pull out the filament from the extruder. There may be an extruder clog or broken filament inside the extruder.",
"0701_8004": "AMS failed to pull back filament. This could be due to a stuck spool or the end of the filament being stuck in the path.",
"0701_8005": "The AMS failed to send out filament. You can clip the end of your filament flat, and reinsert. If this message persists, please check the PTFE tubes in AMS for any signs of wear and tear.",
"0701_8006": "Unable to feed filament into the extruder. This could be due to entangled filament or a stuck spool.",
"0701_8007": "Failed to extrude the filament. Please check if the extruder clogged. After troubleshooting, click the 'Retry' button.",
"0701_8010": "The AMS assist motor is overloaded. This could be due to entangled filament or a stuck spool.",
"0701_8011": "AMS filament ran out. Please insert a new filament into the same AMS slot.",
"0701_8012": "Failed to get AMS mapping table; please click 'Retry' to continue.",
"0701_8013": "Timeout purging old filament: Please check if the filament is stuck or the extruder is clogged. After troubleshooting, click the 'Retry' button.",
"0702_4001": "Filament is still loaded from the AMS after it has been disabled. Please unload the filament, load from the spool holder, and restart printing.",
"0702_8001": "Failed to cut the filament. Please check the cutter. After troubleshooting, click the 'Retry' button.",
"0702_8002": "The cutter is stuck. Please pull out the cutter handle and click the 'Retry' button.",
"0702_8003": "Failed to pull out the filament from the extruder. Please check whether the extruder is clogged or whether the filament is broken inside the extruder. After troubleshooting, click the 'Retry' button.",
"0702_8004": "Failed to pull back the filament from the toolhead to AMS. Please check whether the filament or the spool is stuck. After troubleshooting, click the 'Retry' button.",
"0702_8005": "The AMS failed to send out filament. You can clip the end of your filament flat, and reinsert. If this message persists, please check the PTFE tubes in AMS for any signs of wear and tear.",
"0702_8006": "Failed to feed the filament into the toolhead. Please check whether the filament or the spool is stuck. After troubleshooting, click the 'Retry' button.",
"0702_8007": "Failed to extrude the filament. Please check if the extruder clogged. After troubleshooting, click the 'Retry' button.",
"0702_8010": "The AMS assist motor is overloaded. This could be due to entangled filament or a stuck spool.",
"0702_8011": "AMS filament ran out. Please insert a new filament into the same AMS slot.",
"0702_8012": "Failed to get AMS mapping table; please click 'Retry' to continue.",
"0702_8013": "Timeout purging old filament: Please check if the filament is stuck or the extruder is clogged. After troubleshooting, click the 'Retry' button.",
"0703_4001": "Filament is still loaded from the AMS after it has been disabled. Please unload the filament, load from the spool holder, and restart printing.",
"0703_8001": "Failed to cut the filament. Please check the cutter. After troubleshooting, click the 'Retry' button.",
"0703_8002": "The cutter is stuck. Please pull out the cutter handle and click the 'Retry' button.",
"0703_8003": "Failed to pull out the filament from the extruder. Please check whether the extruder is clogged or whether the filament is broken inside the extruder. After troubleshooting, click the 'Retry' button.",
"0703_8004": "Failed to pull back the filament from the toolhead to AMS. Please check whether the filament or the spool is stuck. After troubleshooting, click the 'Retry' button.",
"0703_8005": "The AMS failed to send out filament. You can clip the end of your filament flat, and reinsert. If this message persists, please check the PTFE tubes in AMS for any signs of wear and tear.",
"0703_8006": "Failed to feed the filament into the toolhead. Please check whether the filament or the spool is stuck. After troubleshooting, click the 'Retry' button.",
"0703_8007": "Failed to extrude the filament. Please check if the extruder clogged. After troubleshooting, click the 'Retry' button.",
"0703_8010": "The AMS assist motor is overloaded. This could be due to entangled filament or a stuck spool.",
"0703_8011": "AMS filament ran out. Please insert a new filament into the same AMS slot.",
"0703_8012": "Failed to get AMS mapping table; please click 'Retry' to continue.",
"0703_8013": "Timeout purging old filament: Please check if the filament is stuck or the extruder is clogged. After troubleshooting, click the 'Retry' button.",
"07FF_4001": "Filament is still loaded from the AMS after it has been disabled. Please unload the filament, load from the spool holder, and restart printing.",
"07FF_8001": "Failed to cut the filament. Please check the cutter. After troubleshooting, click the 'Retry' button.",
"07FF_8002": "The cutter is stuck. Please pull out the cutter handle and click the 'Retry' button.",
"07FF_8003": "Please pull out the filament on the spool holder. If this message persists, please check to see if there is filament broken in the extruder. (Connect PTFE tube if you are about to use AMS)",
"07FF_8004": "Failed to pull back the filament from the toolhead to AMS. Please check whether the filament or the spool is stuck. After troubleshooting, click the 'retry' button.",
"07FF_8005": "Failed to feed the filament outside the AMS. Please clip the end of the filament flat and check to see if the spool is stuck. After troubleshooting, click the 'Retry' button.",
"07FF_8006": "Please feed filament into the PTFE tube until it can not be pushed any farther.",
"07FF_8007": "Please observe the nozzle. If the filament has been extruded, click 'Done'; if it is not, please push the filament forward slightly and then click 'Retry'.",
"07FF_8010": "The AMS assist motor is overloaded. This could be due to entangled filament or a stuck spool.",
"07FF_8011": "External filament has run out, please load a new filament.",
"07FF_8012": "Failed to get AMS mapping table; please click 'Retry' to continue.",
"07FF_8013": "Timeout purging old filament: Please check if the filament is stuck or the extruder is clogged. After troubleshooting, click the 'Retry' button.",
"07FF_C003": "Please pull out the filament on the spool holder. If this message persists, please check to see if there is filament broken in the extruder or PTFE Tube. (Connect PTFE tube if you are about to use AMS)",
"07FF_C006": "Please feed filament into the PTFE tube until it can not be pushed any farther.",
"07FF_C008": "Please pull out the filament on the spool holder. If this message persists, please check to see if there is filament broken in the extruder. (Connect PTFE tube if you are about to use AMS)",
"07FF_C009": "Please feed filament into the PTFE tube until it can not be pushed any farther.",
"07FF_C00A": "Please observe the nozzle. If the filament has been extruded, click 'Done'; if it is not, please push the filament forward slightly and then click 'Retry'.",
"0C00_402A": "",
"0C00_8001": "First layer defects were detected. If the defects are acceptable, click 'Resume' button to resume the print job.",
"0C00_8002": "Spaghetti failure was detected.",
"0C00_8005": "Purged filament has piled up in the waste chute, which may cause a tool head collision.",
"0C00_8009": "Build plate localization marker was not found.",
"0C00_800A": "The detected build plate is not the same as in G-code.",
"0C00_C003": "Possible defects were detected in the first layer.",
"0C00_C004": "Possible spaghetti failure was detected.",
"0C00_C006": "Purged filament may have piled up in the waste chute.",
"1000_C001": "High bed temperature may lead to filament clogging in the nozzle. You may open the chamber door.",
"1000_C002": "Printing CF material with stainless steel may cause nozzle damage.",
"1000_C003": "Enabling traditional timelapse might lead to defects. Please enable it as needed?",
"1001_C001": "Timelapse is not supported because Spiral vase is enabled in slicing presets.",
"1001_C002": "Timelapse is not supported because Print sequence is set to 'By object'.",
"1200_4001": "Filament is still loaded from the AMS when it has been disabled. Please unload AMS filament, load from spool holder, and restart print job.",
"1200_8001": "Cutting the filament failed. Please check to see if the cutter is stuck. Refer to the Assistant for solutions.",
"1200_8002": "The cutter is stuck. Please pull out the cutter handle and click the 'Retry' button.",
"1200_8003": "Failed to pull out the filament from the extruder. Please check whether the extruder is clogged or whether the filament is broken inside the extruder. After troubleshooting, click the 'Retry' button.",
"1200_8004": "Failed to pull back the filament from the toolhead. Please check whether the filament is stuck. After troubleshooting, click the 'Retry' button.",
"1200_8005": "Failed to feed the filament. Please load the filament, then click the 'Retry' button.",
"1200_8006": "Unable to feed filament into the extruder. This could be due to entangled filament or a stuck spool. If not, please check if the AMS PTFE tube is connected.",
"1200_8007": "Failed to extrude the filament. This might be caused by clogged extruder or stuck filament. Refer to the Assistant for solutions.",
"1200_8010": "Filament or spool may be stuck.",
"1200_8011": "AMS filament ran out. Please insert a new filament into the same AMS slot.",
"1200_8012": "Failed to get AMS mapping table. Please click the 'Retry' button to continue.",
"1200_8013": "Timeout while purging old filament. Please check if the filament is stuck or the extruder clogged. After troubleshooting, click the 'Retry' button.",
"1200_8014": "The filament location in the toolhead was not found. Refer to the Assistant for solutions.",
"1200_8015": "Failed to pull out the filament from the toolhead. Please check if the filament is stuck, or the filament is broken inside the extruder or PTFE tube.",
"1200_8016": "The extruder is not extruding normally. Refer to the Assistant for troubleshooting. There may be defects in this layer, you may resume if the defects are acceptable.",
"1201_4001": "Filament is still loaded from the AMS when it has been disabled. Please unload AMS filament, load from spool holder, and restart print job.",
"1201_8001": "Failed to cut the filament. Please check the cutter. After troubleshooting, click the 'Retry' button.",
"1201_8002": "The cutter is stuck. Please pull out the cutter handle and click the 'Retry' button.",
"1201_8003": "Failed to pull out the filament from the extruder. Please check whether the extruder is clogged or whether the filament is broken inside the extruder. After troubleshooting, click the 'Retry' button.",
"1201_8004": "Failed to pull back the filament from the toolhead. Please check whether the filament is stuck. After troubleshooting, click the 'Retry' button.",
"1201_8005": "Failed to feed the filament. Please load the filament and then click the 'Retry' button.",
"1201_8006": "Failed to feed the filament into the toolhead. Please check whether the filament is stuck. After troubleshooting, click the 'Retry' button.",
"1201_8007": "Failed to extrude the filament. The extruder may be clogged or the filament may be stuck; please refer to HMS. After troubleshooting, click 'Retry' button.",
"1201_8010": "Please check if the spool or filament is stuck. After troubleshooting, click the 'Retry' button.",
"1201_8011": "AMS filament has run out. Please insert a new filament into the same AMS slot.",
"1201_8012": "Failed to get AMS mapping table; please click the 'Retry' button to continue.",
"1201_8013": "Timeout while purging old filament. Please check if the filament is stuck or the extruder clogged. After troubleshooting, click the 'Retry' button.",
"1201_8014": "Failed to check the filament location in the tool head; please refer to the HMS. After troubleshooting, click the 'Retry' button.",
"1201_8015": "Failed to pull back the filament from the toolhead. Please check if the filament is stuck or the filament is broken inside the extruder. After troubleshooting, click the 'Retry' button.",
"1201_8016": "The extruder is not extruding normally; please refer to the HMS. After trouble shooting. If the defects are acceptable, please click 'Retry' button.",
"1202_4001": "Filament is still loaded from the AMS when it has been disabled. Please unload AMS filament, load from spool holder, and restart print job.",
"1202_8001": "Failed to cut the filament. Please check the cutter. After troubleshooting, click the 'Retry' button.",
"1202_8002": "The cutter is stuck. Please pull out the cutter handle and click the 'Retry' button.",
"1202_8003": "Failed to pull out the filament from the extruder. Please check whether the extruder is clogged or whether the filament is broken inside the extruder. After troubleshooting, click the 'Retry' button.",
"1202_8004": "Failed to pull back the filament from the toolhead. Please check whether the filament is stuck. After troubleshooting, click the 'Retry' button.",
"1202_8005": "Failed to feed the filament. Please load the filament, then click the 'Retry' button.",
"1202_8006": "Failed to feed the filament into the toolhead. Please check whether the filament is stuck. After troubleshooting, click the 'Retry' button.",
"1202_8007": "Failed to extrude the filament. The extruder may be clogged or the filament may be stuck; please refer to HMS. After troubleshooting, click 'Retry' button.",
"1202_8010": "Please check if the spool or filament is stuck. After troubleshooting, click the 'Retry' button.",
"1202_8011": "AMS filament has run out. Please insert a new filament into the same AMS slot.",
"1202_8012": "Failed to get AMS mapping table; please click the 'Retry' button to continue.",
"1202_8013": "Timeout while purging old filament. Please check if the filament is stuck or the extruder clogged. After troubleshooting, click the 'Retry' button.",
"1202_8014": "Failed to check the filament location in the tool head; please refer to the HMS. After troubleshooting, click the 'Retry' button.",
"1202_8015": "Failed to pull back the filament from the toolhead. Please check if the filament is stuck or is broken inside the extruder. After troubleshooting, click the 'Retry' button.",
"1202_8016": "The extruder is not extruding normally; please refer to the HMS. After trouble shooting. If the defects are acceptable, please click 'Retry' button.",
"1203_4001": "Filament is still loaded from the AMS when it has been disabled. Please unload AMS filament, load from spool holder, and restart print job.",
"1203_8001": "Failed to cut the filament. Please check the cutter. After troubleshooting, click the 'Retry' button.",
"1203_8002": "The cutter is stuck. Please pull out the cutter handle and click the 'Retry' button.",
"1203_8003": "Failed to pull out the filament from the extruder. Please check whether the extruder is clogged or whether the filament is broken inside the extruder. After troubleshooting, click the 'Retry' button.",
"1203_8004": "Failed to pull back the filament from the toolhead. Please check whether the filament is stuck. After troubleshooting, click the 'Retry' button.",
"1203_8005": "Failed to feed the filament. Please load the filament, then click the 'Retry' button.",
"1203_8006": "Failed to feed the filament into the toolhead. Please check whether the filament is stuck. After troubleshooting, click the 'Retry' button.",
"1203_8007": "Failed to extrude the filament. The extruder may be clogged or the filament may be stuck; please refer to HMS. After troubleshooting, click 'Retry' button.",
"1203_8010": "Please check if the spool or filament is stuck. After troubleshooting, click the 'Retry' button.",
"1203_8011": "AMS filament has run out. Please insert a new filament into the same AMS slot.",
"1203_8012": "Failed to get AMS mapping table; please click the 'Retry' button to continue.",
"1203_8013": "Timeout while purging old filament. Please check if the filament is stuck or the extruder clogged. After troubleshooting, click the 'Retry' button.",
"1203_8014": "Failed to check the filament location in the tool head; please refer to the HMS. After troubleshooting, click the 'Retry' button.",
"1203_8015": "Failed to pull back the filament from the toolhead. Please check if the filament is stuck or is broken inside the extruder. After troubleshooting, click the 'Retry' button.",
"1203_8016": "The extruder is not extruding normally; please refer to the HMS. After trouble shooting. If the defects are acceptable, please click 'Retry' button.",
"12FF_4001": "Filament is still loaded from the AMS when it has been disabled. Please unload AMS filament, load from spool holder, and restart print job.",
"12FF_8001": "Failed to cut the filament. Please check the cutter. After troubleshooting, click the 'Retry' button.",
"12FF_8002": "The cutter is stuck. Please pull out the cutter handle and click the 'Retry' button.",
"12FF_8003": "Please pull out the filament on the spool holder. If this message persists, please check to see if there is filament broken in the extruder or PTFE Tube. (Connect PTFE tube if you are about to use AMS)",
"12FF_8004": "Failed to pull back the filament from the toolhead. Please check whether the filament is stuck. After troubleshooting, click the 'Retry' button.",
"12FF_8005": "Failed to feed the filament. Please load the filament, then click the 'Retry' button.",
"12FF_8006": "Please feed filament into the PTFE tube until it can not be pushed any farther.",
"12FF_8007": "Check nozzle. Click 'Done' if filament was extruded, otherwise push filament forward slightly and click 'Retry.'",
"12FF_8010": "Please check if the filament or the spool is stuck.",
"12FF_8011": "AMS filament has run out. Please insert a new filament into the same AMS slot.",
"12FF_8012": "Failed to get AMS mapping table; please click the 'Retry' button to continue.",
"12FF_8013": "Timeout while purging old filament. Please check if the filament is stuck or the extruder clogged. After troubleshooting, click the 'Retry' button.",
"12FF_C003": "Please pull out the filament on the spool holder. If this message persists, please check to see if there is filament broken in the extruder or PTFE Tube. (Connect PTFE tube if you are about to use AMS)",
"12FF_C006": "Please feed filament into the PTFE tube until it can not be pushed any farther.",
}

View File

@ -15,6 +15,7 @@
"GFB01": "Bambu ASA", "GFB01": "Bambu ASA",
"GFB02": "Bambu ASA-Aero", "GFB02": "Bambu ASA-Aero",
"GFB50": "Bambu ABS-GF", "GFB50": "Bambu ABS-GF",
"GFB51": "Bambu ASA-CF",
"GFB60": "PolyLite ABS", "GFB60": "PolyLite ABS",
"GFB61": "PolyLite ASA", "GFB61": "PolyLite ASA",
"GFB98": "Generic ASA", "GFB98": "Generic ASA",
@ -26,6 +27,7 @@
"GFG02": "Bambu PETG HF", "GFG02": "Bambu PETG HF",
"GFG50": "Bambu PETG-CF", "GFG50": "Bambu PETG-CF",
"GFG60": "PolyLite PETG", "GFG60": "PolyLite PETG",
"GFG96": "Generic PETG HF",
"GFG97": "Generic PCTG", "GFG97": "Generic PCTG",
"GFG98": "Generic PETG-CF", "GFG98": "Generic PETG-CF",
"GFG99": "Generic PETG", "GFG99": "Generic PETG",
@ -34,6 +36,13 @@
"GFL03": "eSUN PLA+", "GFL03": "eSUN PLA+",
"GFL04": "Overture PLA", "GFL04": "Overture PLA",
"GFL05": "Overture Matte PLA", "GFL05": "Overture Matte PLA",
"GFL06": "Fiberon PETG-ESD",
"GFL50": "Fiberon PA6-CF",
"GFL51": "Fiberon PA6-GF",
"GFL52": "Fiberon PA12-CF",
"GFL53": "Fiberon PA612-CF",
"GFL54": "Fiberon PET-CF",
"GFL55": "Fiberon PETG-rCF",
"GFL95": "Generic PLA High Speed", "GFL95": "Generic PLA High Speed",
"GFL96": "Generic PLA Silk", "GFL96": "Generic PLA Silk",
"GFL98": "Generic PLA-CF", "GFL98": "Generic PLA-CF",
@ -41,6 +50,7 @@
"GFN03": "Bambu PA-CF", "GFN03": "Bambu PA-CF",
"GFN04": "Bambu PAHT-CF", "GFN04": "Bambu PAHT-CF",
"GFN05": "Bambu PA6-CF", "GFN05": "Bambu PA6-CF",
"GFN06": "Bambu PPA-CF",
"GFN08": "Bambu PA6-GF", "GFN08": "Bambu PA6-GF",
"GFN96": "Generic PPA-GF", "GFN96": "Generic PPA-GF",
"GFN97": "Generic PPA-CF", "GFN97": "Generic PPA-CF",
@ -64,9 +74,12 @@
"GFS98": "Generic HIPS", "GFS98": "Generic HIPS",
"GFS99": "Generic PVA", "GFS99": "Generic PVA",
"GFT01": "Bambu PET-CF", "GFT01": "Bambu PET-CF",
"GFT02": "Bambu PPS-CF",
"GFT97": "Generic PPS", "GFT97": "Generic PPS",
"GFT98": "Generic PPS-CF", "GFT98": "Generic PPS-CF",
"GFU00": "Bambu TPU 95A HF", "GFU00": "Bambu TPU 95A HF",
"GFU01": "Bambu TPU 95A", "GFU01": "Bambu TPU 95A",
"GFU02": "Bambu TPU for AMS",
"GFU98": "Generic TPU for AMS",
"GFU99": "Generic TPU" "GFU99": "Generic TPU"
} }

View File

@ -22,6 +22,7 @@ from .utils import (
get_generic_AMS_HMS_error_code, get_generic_AMS_HMS_error_code,
get_HMS_severity, get_HMS_severity,
get_HMS_module, get_HMS_module,
set_temperature_to_gcode,
) )
from .const import ( from .const import (
LOGGER, LOGGER,
@ -32,6 +33,7 @@ from .const import (
SPEED_PROFILE, SPEED_PROFILE,
GCODE_STATE_OPTIONS, GCODE_STATE_OPTIONS,
PRINT_TYPE_OPTIONS, PRINT_TYPE_OPTIONS,
TempEnum,
) )
from .commands import ( from .commands import (
CHAMBER_LIGHT_ON, CHAMBER_LIGHT_ON,
@ -42,7 +44,7 @@ from .commands import (
class Device: class Device:
def __init__(self, client): def __init__(self, client):
self._client = client self._client = client
self.temperature = Temperature() self.temperature = Temperature(client = client)
self.lights = Lights(client = client) self.lights = Lights(client = client)
self.info = Info(client = client) self.info = Info(client = client)
self.print_job = PrintJob(client = client) self.print_job = PrintJob(client = client)
@ -53,7 +55,7 @@ class Device:
self.external_spool = ExternalSpool(client = client) self.external_spool = ExternalSpool(client = client)
self.hms = HMSList(client = client) self.hms = HMSList(client = client)
self.print_error = PrintErrorList(client = client) self.print_error = PrintErrorList(client = client)
self.camera = Camera() self.camera = Camera(client = client)
self.home_flag = HomeFlag(client=client) self.home_flag = HomeFlag(client=client)
self.push_all_data = None self.push_all_data = None
self.get_version_data = None self.get_version_data = None
@ -77,8 +79,7 @@ class Device:
send_event = send_event | self.camera.print_update(data = data) send_event = send_event | self.camera.print_update(data = data)
send_event = send_event | self.home_flag.print_update(data = data) send_event = send_event | self.home_flag.print_update(data = data)
if send_event and self._client.callback is not None: self._client.callback("event_printer_data_update")
self._client.callback("event_printer_data_update")
if data.get("msg", 0) == 0: if data.get("msg", 0) == 0:
self.push_all_data = data self.push_all_data = data
@ -90,6 +91,16 @@ class Device:
if data.get("command") == "get_version": if data.get("command") == "get_version":
self.get_version_data = data self.get_version_data = data
def _supports_temperature_set(self):
# When talking to the Bambu cloud mqtt, setting the temperatures is allowed.
if self.info.mqtt_mode == "bambu_cloud":
return True
# X1* have not yet blocked setting the temperatures when in nybrid connection mode.
if self.info.device_type == "X1" or self.info.device_type == "X1C" or self.info.device_type == "X1E":
return True
# What's left is P1 and A1 printers that we are connecting by local mqtt. These are supported only in pure Lan Mode.
return not self._client.bambu_cloud.bambu_connected
def supports_feature(self, feature): def supports_feature(self, feature):
if feature == Features.AUX_FAN: if feature == Features.AUX_FAN:
return self.info.device_type != "A1" and self.info.device_type != "A1MINI" return self.info.device_type != "A1" and self.info.device_type != "A1MINI"
@ -126,6 +137,8 @@ class Device:
elif feature == Features.AMS_FILAMENT_REMAINING: elif feature == Features.AMS_FILAMENT_REMAINING:
# Technically this is not the AMS Lite but that's currently tied to only these printer types. # Technically this is not the AMS Lite but that's currently tied to only these printer types.
return self.info.device_type != "A1" and self.info.device_type != "A1MINI" return self.info.device_type != "A1" and self.info.device_type != "A1MINI"
elif feature == Features.SET_TEMPERATURE:
return self._supports_temperature_set()
return False return False
@ -185,15 +198,13 @@ class Lights:
def TurnChamberLightOn(self): def TurnChamberLightOn(self):
self.chamber_light = "on" self.chamber_light = "on"
self.chamber_light_override = "on" self.chamber_light_override = "on"
if self._client.callback is not None: self._client.callback("event_light_update")
self._client.callback("event_light_update")
self._client.publish(CHAMBER_LIGHT_ON) self._client.publish(CHAMBER_LIGHT_ON)
def TurnChamberLightOff(self): def TurnChamberLightOff(self):
self.chamber_light = "off" self.chamber_light = "off"
self.chamber_light_override = "off" self.chamber_light_override = "off"
if self._client.callback is not None: self._client.callback("event_light_update")
self._client.callback("event_light_update")
self._client.publish(CHAMBER_LIGHT_OFF) self._client.publish(CHAMBER_LIGHT_OFF)
@ -205,7 +216,8 @@ class Camera:
rtsp_url: str rtsp_url: str
timelapse: str timelapse: str
def __init__(self): def __init__(self, client):
self._client = client
self.recording = '' self.recording = ''
self.resolution = '' self.resolution = ''
self.rtsp_url = None self.rtsp_url = None
@ -227,7 +239,10 @@ class Camera:
self.timelapse = data.get("ipcam", {}).get("timelapse", self.timelapse) self.timelapse = data.get("ipcam", {}).get("timelapse", self.timelapse)
self.recording = data.get("ipcam", {}).get("ipcam_record", self.recording) self.recording = data.get("ipcam", {}).get("ipcam_record", self.recording)
self.resolution = data.get("ipcam", {}).get("resolution", self.resolution) self.resolution = data.get("ipcam", {}).get("resolution", self.resolution)
self.rtsp_url = data.get("ipcam", {}).get("rtsp_url", self.rtsp_url) if self._client._enable_camera:
self.rtsp_url = data.get("ipcam", {}).get("rtsp_url", self.rtsp_url)
else:
self.rtsp_url = None
return (old_data != f"{self.__dict__}") return (old_data != f"{self.__dict__}")
@ -240,7 +255,8 @@ class Temperature:
nozzle_temp: int nozzle_temp: int
target_nozzle_temp: int target_nozzle_temp: int
def __init__(self): def __init__(self, client):
self._client = client
self.bed_temp = 0 self.bed_temp = 0
self.target_bed_temp = 0 self.target_bed_temp = 0
self.chamber_temp = 0 self.chamber_temp = 0
@ -258,6 +274,20 @@ class Temperature:
return (old_data != f"{self.__dict__}") return (old_data != f"{self.__dict__}")
def set_target_temp(self, temp: TempEnum, temperature: int):
command = set_temperature_to_gcode(temp, temperature)
# if type == TempEnum.HEATBED:
# self.bed_temp = temperature
# elif type == TempEnum.NOZZLE:
# self.nozzle_temp = temperature
LOGGER.debug(command)
self._client.publish(command)
self._client.callback("event_printer_data_update")
@dataclass @dataclass
class Fans: class Fans:
"""Return all fan related info""" """Return all fan related info"""
@ -337,8 +367,7 @@ class Fans:
LOGGER.debug(command) LOGGER.debug(command)
self._client.publish(command) self._client.publish(command)
if self._client.callback is not None: self._client.callback("event_printer_data_update")
self._client.callback("event_printer_data_update")
def get_fan_speed(self, fan: FansEnum) -> int: def get_fan_speed(self, fan: FansEnum) -> int:
if fan == FansEnum.PART_COOLING: if fan == FansEnum.PART_COOLING:
@ -483,8 +512,7 @@ class PrintJob:
currently_idle = self.gcode_state == "IDLE" or self.gcode_state == "FAILED" or self.gcode_state == "FINISH" currently_idle = self.gcode_state == "IDLE" or self.gcode_state == "FAILED" or self.gcode_state == "FINISH"
if previously_idle and not currently_idle: if previously_idle and not currently_idle:
if self._client.callback is not None: self._client.callback("event_print_started")
self._client.callback("event_print_started")
# Generate the start_time for P1P/S when printer moves from idle to another state. Original attempt with remaining time # Generate the start_time for P1P/S when printer moves from idle to another state. Original attempt with remaining time
# becoming non-zero didn't work as it never bounced to zero in at least the scenario where a print was canceled. # becoming non-zero didn't work as it never bounced to zero in at least the scenario where a print was canceled.
@ -508,20 +536,17 @@ class PrintJob:
isCanceledPrint = False isCanceledPrint = False
if data.get("print_error") == 50348044 and self.print_error == 0: if data.get("print_error") == 50348044 and self.print_error == 0:
isCanceledPrint = True isCanceledPrint = True
if self._client.callback is not None: self._client.callback("event_print_canceled")
self._client.callback("event_print_canceled")
self.print_error = data.get("print_error", self.print_error) self.print_error = data.get("print_error", self.print_error)
# Handle print failed # Handle print failed
if previous_gcode_state != "unknown" and previous_gcode_state != "FAILED" and self.gcode_state == "FAILED": if previous_gcode_state != "unknown" and previous_gcode_state != "FAILED" and self.gcode_state == "FAILED":
if not isCanceledPrint: if not isCanceledPrint:
if self._client.callback is not None: self._client.callback("event_print_failed")
self._client.callback("event_print_failed")
# Handle print finish # Handle print finish
if previous_gcode_state != "unknown" and previous_gcode_state != "FINISH" and self.gcode_state == "FINISH": if previous_gcode_state != "unknown" and previous_gcode_state != "FINISH" and self.gcode_state == "FINISH":
if self._client.callback is not None: self._client.callback("event_print_finished")
self._client.callback("event_print_finished")
if currently_idle and not previously_idle and previous_gcode_state != "unknown": if currently_idle and not previously_idle and previous_gcode_state != "unknown":
if self.start_time != None: if self.start_time != None:
@ -674,8 +699,7 @@ class Info:
def set_online(self, online): def set_online(self, online):
if self.online != online: if self.online != online:
self.online = online self.online = online
if self._client.callback is not None: self._client.callback("event_printer_data_update")
self._client.callback("event_printer_data_update")
def info_update(self, data): def info_update(self, data):
@ -704,8 +728,7 @@ class Info:
LOGGER.debug(f"Device is {self.device_type}") LOGGER.debug(f"Device is {self.device_type}")
self.hw_ver = get_hw_version(modules, self.hw_ver) self.hw_ver = get_hw_version(modules, self.hw_ver)
self.sw_ver = get_sw_version(modules, self.sw_ver) self.sw_ver = get_sw_version(modules, self.sw_ver)
if self._client.callback is not None: self._client.callback("event_printer_info_update")
self._client.callback("event_printer_info_update")
def print_update(self, data) -> bool: def print_update(self, data) -> bool:
old_data = f"{self.__dict__}" old_data = f"{self.__dict__}"
@ -891,8 +914,7 @@ class AMSList:
data_changed = data_changed or (old_data != f"{self.__dict__}") data_changed = data_changed or (old_data != f"{self.__dict__}")
if data_changed: if data_changed:
if self._client.callback is not None: self._client.callback("event_ams_info_update")
self._client.callback("event_ams_info_update")
def print_update(self, data) -> bool: def print_update(self, data) -> bool:
old_data = f"{self.__dict__}" old_data = f"{self.__dict__}"
@ -1121,8 +1143,7 @@ class Speed:
command = SPEED_PROFILE_TEMPLATE command = SPEED_PROFILE_TEMPLATE
command['print']['param'] = f"{id}" command['print']['param'] = f"{id}"
self._client.publish(command) self._client.publish(command)
if self._client.callback is not None: self._client.callback("event_speed_update")
self._client.callback("event_speed_update")
@dataclass @dataclass
@ -1187,7 +1208,8 @@ class HMSList:
attr = int(hms['attr']) attr = int(hms['attr'])
code = int(hms['code']) code = int(hms['code'])
hms_notif = HMSNotification(attr=attr, code=code) hms_notif = HMSNotification(attr=attr, code=code)
errors[f"{index}-Error"] = f"HMS_{hms_notif.hms_code}: {get_HMS_error_text(hms_notif.hms_code)}" errors[f"{index}-Code"] = f"HMS_{hms_notif.hms_code}"
errors[f"{index}-Error"] = get_HMS_error_text(hms_notif.hms_code)
errors[f"{index}-Wiki"] = hms_notif.wiki_url errors[f"{index}-Wiki"] = hms_notif.wiki_url
errors[f"{index}-Severity"] = hms_notif.severity errors[f"{index}-Severity"] = hms_notif.severity
#LOGGER.debug(f"HMS error for '{hms_notif.module}' and severity '{hms_notif.severity}': HMS_{hms_notif.hms_code}") #LOGGER.debug(f"HMS error for '{hms_notif.module}' and severity '{hms_notif.severity}': HMS_{hms_notif.hms_code}")
@ -1198,8 +1220,7 @@ class HMSList:
self._errors = errors self._errors = errors
if self._count != 0: if self._count != 0:
LOGGER.warning(f"HMS ERRORS: {errors}") LOGGER.warning(f"HMS ERRORS: {errors}")
if self._client.callback is not None: self._client.callback("event_printer_error")
self._client.callback("event_hms_errors")
return True return True
return False return False
@ -1217,11 +1238,9 @@ class HMSList:
class PrintErrorList: class PrintErrorList:
"""Return all print_error related info""" """Return all print_error related info"""
_error: dict _error: dict
_count: int
def __init__(self, client): def __init__(self, client):
self._error = None self._error = None
self._count = 0
self._client = client self._client = client
def print_update(self, data) -> bool: def print_update(self, data) -> bool:
@ -1238,14 +1257,13 @@ class PrintErrorList:
hex_conversion = f'0{int(print_error_code):x}' hex_conversion = f'0{int(print_error_code):x}'
print_error_code_hex = hex_conversion[slice(0,4,1)] + "_" + hex_conversion[slice(4,8,1)] print_error_code_hex = hex_conversion[slice(0,4,1)] + "_" + hex_conversion[slice(4,8,1)]
errors = {} errors = {}
errors[f"Code"] = f"{print_error_code_hex.upper()}" errors[f"code"] = print_error_code_hex.upper()
errors[f"Error"] = f"{print_error_code_hex.upper()}: {get_print_error_text(print_error_code)}" errors[f"error"] = get_print_error_text(print_error_code)
# LOGGER.warning(f"PRINT ERRORS: {errors}") # This will emit a message to home assistant log every 1 second if enabled # LOGGER.warning(f"PRINT ERRORS: {errors}") # This will emit a message to home assistant log every 1 second if enabled
if self._error != errors: if self._error != errors:
self._error = errors self._error = errors
if self._client.callback is not None: self._client.callback("event_print_error")
self._client.callback("event_print_error")
# We send the error event directly so always return False for the general data event. # We send the error event directly so always return False for the general data event.
return False return False
@ -1296,13 +1314,23 @@ class ChamberImage:
def __init__(self, client): def __init__(self, client):
self._client = client self._client = client
self._bytes = bytearray() self._bytes = bytearray()
self._image_last_updated = datetime.now()
def set_jpeg(self, bytes): def set_jpeg(self, bytes):
self._bytes = bytes self._bytes = bytes
self._image_last_updated = datetime.now()
self._client.callback("event_printer_chamber_image_update")
def get_jpeg(self) -> bytearray: def get_jpeg(self) -> bytearray:
return self._bytes.copy() return self._bytes.copy()
def get_last_update_time(self) -> datetime:
return self._image_last_updated
@property
def available(self):
return self._client._enable_camera
@dataclass @dataclass
class CoverImage: class CoverImage:
"""Returns the cover image from the Bambu API""" """Returns the cover image from the Bambu API"""
@ -1311,8 +1339,7 @@ class CoverImage:
self._client = client self._client = client
self._bytes = bytearray() self._bytes = bytearray()
self._image_last_updated = datetime.now() self._image_last_updated = datetime.now()
if self._client.callback is not None: self._client.callback("event_printer_cover_image_update")
self._client.callback("event_printer_cover_image_update")
def set_jpeg(self, bytes): def set_jpeg(self, bytes):
self._bytes = bytes self._bytes = bytes

View File

@ -11,8 +11,9 @@ from .const import (
HMS_SEVERITY_LEVELS, HMS_SEVERITY_LEVELS,
HMS_MODULES, HMS_MODULES,
LOGGER, LOGGER,
BAMBU_URL,
FansEnum, FansEnum,
BAMBU_URL TempEnum
) )
from .commands import SEND_GCODE_TEMPLATE from .commands import SEND_GCODE_TEMPLATE
@ -49,6 +50,18 @@ def fan_percentage_to_gcode(fan: FansEnum, percentage: int):
return command return command
def set_temperature_to_gcode(temp: TempEnum, temperature: int):
"""Converts a temperature to the gcode command to set that"""
if temp == TempEnum.NOZZLE:
tempCommand = "M104"
elif temp == TempEnum.HEATBED:
tempCommand = "M140"
command = SEND_GCODE_TEMPLATE
command['print']['param'] = f"{tempCommand} S{temperature}\n"
return command
def to_whole(number): def to_whole(number):
if not number: if not number:
return 0 return 0

View File

@ -71,7 +71,7 @@ class PrintingState(APrinterState):
subtask_name: str = print_job_info.subtask_name subtask_name: str = print_job_info.subtask_name
gcode_file: str = print_job_info.gcode_file gcode_file: str = print_job_info.gcode_file
self._log.info(f"update_print_job_info: {print_job_info}") self._log.debug(f"update_print_job_info: {print_job_info}")
project_file_info = self._printer.project_files.get_file_by_name(subtask_name) or self._printer.project_files.get_file_by_name(gcode_file) project_file_info = self._printer.project_files.get_file_by_name(subtask_name) or self._printer.project_files.get_file_by_name(gcode_file)
if project_file_info is None: if project_file_info is None:
@ -81,6 +81,8 @@ class PrintingState(APrinterState):
return return
progress = print_job_info.print_percentage progress = print_job_info.print_percentage
if print_job_info.gcode_state == "PREPARE" and progress == 100:
progress = 0
self._printer.current_print_job = PrintJob(project_file_info, progress, print_job_info.remaining_time, print_job_info.current_layer, print_job_info.total_layers) self._printer.current_print_job = PrintJob(project_file_info, progress, print_job_info.remaining_time, print_job_info.current_layer, print_job_info.total_layers)
self._printer.select_project_file(project_file_info.path.as_posix()) self._printer.select_project_file(project_file_info.path.as_posix())

View File

@ -20,6 +20,16 @@ $(function () {
self.job_info = ko.observable(); self.job_info = ko.observable();
self.auth_type = ko.observable("");
self.show_password = ko.pureComputed(function(){
return self.settingsViewModel.settings.plugins.bambu_printer.auth_token() === '';
});
self.show_verification = ko.pureComputed(function(){
return self.auth_type() !== '';
});
self.ams_mapping_computed = function(){ self.ams_mapping_computed = function(){
var output_list = []; var output_list = [];
var index = 0; var index = 0;
@ -38,18 +48,46 @@ $(function () {
return output_list; return output_list;
}; };
self.getAdditionalControls = function() {
var buttons = [
{ name: "Bambu", type: "section", layout: "horizontal", children: [
{type: "command", name: "Light On", enabled: "true", command: "M355 S1"},
{type: "command", name: "Light Off", enabled: "true", command: "M355 S0"}
]}
];
return buttons;
};
self.getAuthToken = function (data) { self.getAuthToken = function (data) {
self.settingsViewModel.settings.plugins.bambu_printer.auth_token(""); self.settingsViewModel.settings.plugins.bambu_printer.auth_token("");
self.auth_type("");
OctoPrint.simpleApiCommand("bambu_printer", "register", { OctoPrint.simpleApiCommand("bambu_printer", "register", {
"email": self.settingsViewModel.settings.plugins.bambu_printer.email(), "email": self.settingsViewModel.settings.plugins.bambu_printer.email(),
"password": $("#bambu_cloud_password").val(), "password": $("#bambu_cloud_password").val(),
"region": self.settingsViewModel.settings.plugins.bambu_printer.region(), "region": self.settingsViewModel.settings.plugins.bambu_printer.region(),
"auth_token": self.settingsViewModel.settings.plugins.bambu_printer.auth_token() "auth_token": self.settingsViewModel.settings.plugins.bambu_printer.auth_token()
})
.done(function (response) {
self.auth_type(response.auth_response);
});
};
self.verifyCode = function (data) {
self.settingsViewModel.settings.plugins.bambu_printer.auth_token("");
OctoPrint.simpleApiCommand("bambu_printer", "verify", {
"password": $("#bambu_cloud_verify_code").val(),
"auth_type": self.auth_type(),
}) })
.done(function (response) { .done(function (response) {
console.log(response); console.log(response);
self.settingsViewModel.settings.plugins.bambu_printer.auth_token(response.auth_token); if (response.auth_token) {
self.settingsViewModel.settings.plugins.bambu_printer.username(response.username); self.settingsViewModel.settings.plugins.bambu_printer.auth_token(response.auth_token);
self.settingsViewModel.settings.plugins.bambu_printer.username(response.username);
self.auth_type("");
} else if (response.error) {
self.settingsViewModel.settings.plugins.bambu_printer.auth_token("");
$("#bambu_cloud_verify_code").val("");
}
}); });
}; };
@ -105,7 +143,7 @@ $(function () {
}; };
self.onAfterBinding = function () { self.onAfterBinding = function () {
console.log(self.ams_mapping_computed()); // console.log(self.ams_mapping_computed());
}; };
self.showTimelapseThumbnail = function(data) { self.showTimelapseThumbnail = function(data) {

View File

@ -16,7 +16,7 @@
</div> </div>
</div> </div>
<div class="row-fluid" data-bind="visible: settingsViewModel.settings.plugins.bambu_printer.use_ams"> <div class="row-fluid" data-bind="visible: settingsViewModel.settings.plugins.bambu_printer.use_ams">
{{ _('Filament Assighnment') }}: {{ _('Click') }} <a href="#">{{ _('here') }}</a> {{ _('for usage details.') }} {{ _('Filament Assignment') }}: {{ _('Click') }} <a href="#">{{ _('here') }}</a> {{ _('for usage details.') }}
</div> </div>
<div class="row-fluid" data-bind="visible: settingsViewModel.settings.plugins.bambu_printer.use_ams, sortable: {data: ams_mapping, options: {cancel: '.unsortable'}}"> <div class="row-fluid" data-bind="visible: settingsViewModel.settings.plugins.bambu_printer.use_ams, sortable: {data: ams_mapping, options: {cancel: '.unsortable'}}">
<div class="btn" data-bind="attr: {title: name}, event: {dblclick: $root.toggle_spool_active}, css: {disabled: (index()<0)}"> <div class="btn" data-bind="attr: {title: name}, event: {dblclick: $root.toggle_spool_active}, css: {disabled: (index()<0)}">

View File

@ -40,15 +40,24 @@
<div class="control-group" data-bind="visible: !settingsViewModel.settings.plugins.bambu_printer.local_mqtt()"> <div class="control-group" data-bind="visible: !settingsViewModel.settings.plugins.bambu_printer.local_mqtt()">
<label class="control-label">{{ _('Email') }}</label> <label class="control-label">{{ _('Email') }}</label>
<div class="controls"> <div class="controls">
<input type="text" class="input-block-level" data-bind="value: settingsViewModel.settings.plugins.bambu_printer.email" title="{{ _('Registered email address') }}"></input> <input type="text" class="input-block-level" data-bind="value: settingsViewModel.settings.plugins.bambu_printer.email" title="{{ _('Registered email address') }}" autocomplete="off"></input>
</div> </div>
</div> </div>
<div class="control-group" data-bind="visible: !settingsViewModel.settings.plugins.bambu_printer.local_mqtt()"> <div class="control-group" data-bind="visible: !settingsViewModel.settings.plugins.bambu_printer.local_mqtt() && show_password()">
<label class="control-label">{{ _('Password') }}</label> <label class="control-label">{{ _('Password') }}</label>
<div class="controls"> <div class="controls">
<div class="input-block-level input-append" data-bind="css: {'input-append': !show_verification()}">
<input id="bambu_cloud_password" type="password" class="input-text input-block-level" title="{{ _('Password to generate verification code') }}" autocomplete="new-password"></input>
<span class="btn btn-primary add-on" data-bind="visible: !show_verification(), click: getAuthToken">{{ _('Login') }}</span>
</div>
</div>
</div>
<div class="control-group" data-bind="visible: show_verification()">
<label class="control-label">{{ _('Verify') }}</label>
<div class="controls">
<div class="input-block-level input-append"> <div class="input-block-level input-append">
<input id="bambu_cloud_password" type="password" class="input-text input-block-level" title="{{ _('Password to generate Auth Token') }}"></input> <input id="bambu_cloud_verify_code" type="password" class="input-text input-block-level" title="{{ _('Verification code to generate auth token') }}"></input>
<span class="btn btn-primary add-on" data-bind="click: getAuthToken">{{ _('Login') }}</span> <span class="btn btn-primary add-on" data-bind="click: verifyCode">{{ _('Verify') }}</span>
</div> </div>
</div> </div>
</div> </div>

View File

@ -14,7 +14,7 @@ plugin_package = "octoprint_bambu_printer"
plugin_name = "OctoPrint-BambuPrinter" plugin_name = "OctoPrint-BambuPrinter"
# The plugin's version. Can be overwritten within OctoPrint's internal data via __plugin_version__ in the plugin module # The plugin's version. Can be overwritten within OctoPrint's internal data via __plugin_version__ in the plugin module
plugin_version = "0.1.8rc7" plugin_version = "0.1.8rc15"
# The plugin's description. Can be overwritten within OctoPrint's internal data via __plugin_description__ in the plugin # The plugin's description. Can be overwritten within OctoPrint's internal data via __plugin_description__ in the plugin
# module # module
@ -33,7 +33,7 @@ plugin_url = "https://github.com/jneilliii/OctoPrint-BambuPrinter"
plugin_license = "AGPLv3" plugin_license = "AGPLv3"
# Any additional requirements besides OctoPrint should be listed here # Any additional requirements besides OctoPrint should be listed here
plugin_requires = ["paho-mqtt<2", "python-dateutil", "curl_cffi"] plugin_requires = ["paho-mqtt<2", "python-dateutil", "cloudscraper"]
### -------------------------------------------------------------------------------------------------------------------- ### --------------------------------------------------------------------------------------------------------------------
### More advanced options that you usually shouldn't have to touch follow after this point ### More advanced options that you usually shouldn't have to touch follow after this point