Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
AdrianGarside authored Jan 20, 2025
2 parents fc5616f + 89e88b9 commit f436e3f
Show file tree
Hide file tree
Showing 25 changed files with 827 additions and 217 deletions.
10 changes: 5 additions & 5 deletions custom_components/bambu_lab/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ async def async_step_user(

if self.email != '':
modes = [
SelectOptionDict(value=self.email, label=self.email),
SelectOptionDict(value="bambu", label=""),
SelectOptionDict(value=self.email, label=self.email),
SelectOptionDict(value="lan", label="")
]
else:
Expand Down Expand Up @@ -474,8 +474,8 @@ async def async_step_init(self, user_input: None = None) -> FlowResult:
if self.email != '':
default_option = self.email
modes = [
SelectOptionDict(value=self.email, label=self.email),
SelectOptionDict(value="bambu", label=""),
SelectOptionDict(value=self.email, label=self.email),
SelectOptionDict(value="lan", label="")
]
else:
Expand Down Expand Up @@ -691,12 +691,12 @@ async def async_step_Lan(
data = dict(self.config_entry.data)
options = {
"region": self.config_entry.options.get('region', ''),
"email": self.config_entry.options.get('email', ''),
"username": self.config_entry.options.get('username', ''),
"email": '',
"username": '',
"name": self.config_entry.options.get('name', ''),
"host": user_input['host'],
"local_mqtt": True,
"auth_token": self.config_entry.options.get('auth_token', ''),
"auth_token": '',
"access_code": user_input['access_code'],
"usage_hours": float(user_input['usage_hours'])
}
Expand Down
2 changes: 1 addition & 1 deletion custom_components/bambu_lab/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@
"st": "urn:bambulab-com:device:3dprinter:1"
}
],
"version": "2.0.40"
"version": "2.0.41"
}
2 changes: 1 addition & 1 deletion custom_components/bambu_lab/pybambu/bambu_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ def __init__(self, config):

self._access_code = config.get('access_code', '')
self._auth_token = config.get('auth_token', '')
self._device_type = config.get('device_type', 'unknown')
self._device_type = config.get('device_type', 'unknown').upper()
self._local_mqtt = config.get('local_mqtt', False)
self._manual_refresh_mode = config.get('manual_refresh_mode', False)
self._serial = config.get('serial', '')
Expand Down
9 changes: 3 additions & 6 deletions custom_components/bambu_lab/pybambu/bambu_cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,11 +372,8 @@ def test_authentication(self, region: str, email: str, username: str, auth_token
self._email = email
self._username = username
self._auth_token = auth_token
try:
self.get_device_list()
except:
return False
return True
result = self.get_device_list()
return False if result is None else True

def login(self, region: str, email: str, password: str) -> str:
self._region = region
Expand Down Expand Up @@ -583,7 +580,7 @@ def get_tasklist_for_printer(self, deviceId: str) -> dict:
def get_device_type_from_device_product_name(self, device_product_name: str):
if device_product_name == "X1 Carbon":
return "X1C"
return device_product_name.replace(" ", "")
return device_product_name.replace(" ", "").upper()

def download(self, url: str) -> bytearray:
LOGGER.debug(f"Downloading cover image: {url}")
Expand Down
7 changes: 6 additions & 1 deletion custom_components/bambu_lab/pybambu/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,9 @@
SEND_GCODE_TEMPLATE = {"print": {"sequence_id": "0", "command": "gcode_line", "param": ""}} # param = GCODE_EACH_LINE_SEPARATED_BY_\n

# X1 only currently
GET_ACCESSORIES = {"system": {"sequence_id": "0", "command": "get_accessories", "accessory_type": "none"}}
GET_ACCESSORIES = {"system": {"sequence_id": "0", "command": "get_accessories", "accessory_type": "none"}}

# A1 only
PROMPT_SOUND_ENABLE = {"print" : {"sequence_id": "0", "command": "print_option", "sound_enable": True}}
PROMPT_SOUND_DISABLE = {"print" : {"sequence_id": "0", "command": "print_option", "sound_enable": False}}

1 change: 1 addition & 0 deletions custom_components/bambu_lab/pybambu/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class Features(Enum):
MANUAL_MODE = 17,
AMS_FILAMENT_REMAINING = 18,
SET_TEMPERATURE = 19,
PROMPT_SOUND = 20,


class FansEnum(Enum):
Expand Down
1 change: 1 addition & 0 deletions custom_components/bambu_lab/pybambu/const_print_errors.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
PRINT_ERROR_ERRORS = {
"012FF800": "Check nozzle. Click “Done” if filament was extruded.",
"03004000": "Printing stopped because homing Z axis failed.",
"03004001": "The printer timed out waiting for the nozzle to cool down before homing.",
"03004002": "Printing Stopped because Auto Bed Leveling failed.",
Expand Down
18 changes: 13 additions & 5 deletions custom_components/bambu_lab/pybambu/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
from .commands import (
CHAMBER_LIGHT_ON,
CHAMBER_LIGHT_OFF,
PROMPT_SOUND_ENABLE,
PROMPT_SOUND_DISABLE,
SPEED_PROFILE_TEMPLATE,
)

Expand Down Expand Up @@ -138,6 +140,8 @@ def supports_feature(self, feature):
return self.info.device_type != "A1" and self.info.device_type != "A1MINI"
elif feature == Features.SET_TEMPERATURE:
return self._supports_temperature_set()
elif feature == Features.PROMPT_SOUND:
return self.info.device_type == "A1" or self.info.device_type == "A1MINI"

return False

Expand Down Expand Up @@ -470,8 +474,6 @@ def print_update(self, data) -> bool:
self.print_percentage = data.get("mc_percent", self.print_percentage)
previous_gcode_state = self.gcode_state
self.gcode_state = data.get("gcode_state", self.gcode_state)
if previous_gcode_state != self.gcode_state:
LOGGER.debug(f"GCODE_STATE: {previous_gcode_state} -> {self.gcode_state}")
if self.gcode_state.lower() not in GCODE_STATE_OPTIONS:
LOGGER.error(f"Unknown gcode_state. Please log an issue : '{self.gcode_state}'")
self.gcode_state = "unknown"
Expand Down Expand Up @@ -642,8 +644,8 @@ def _update_task_data(self):
if self._client._device.supports_feature(Features.START_TIME_GENERATED) and (status == 4):
# If we generate the start time (not X1), then rely more heavily on the cloud task data and
# do so uniformly so we always have matched start/end times.

# "startTime": "2023-12-21T19:02:16Z"

cloud_time_str = self._task_data.get('startTime', "")
LOGGER.debug(f"CLOUD START TIME1: {self.start_time}")
if cloud_time_str != "":
Expand All @@ -663,7 +665,6 @@ def _update_task_data(self):
self.end_time = local_dt
LOGGER.debug(f"CLOUD END TIME2: {self.end_time}")


@dataclass
class Info:
"""Return all device related content"""
Expand All @@ -686,7 +687,7 @@ def __init__(self, client):
self._client = client

self.serial = self._client._serial
self.device_type = self._client._device_type.upper()
self.device_type = self._client._device_type
self.wifi_signal = 0
self.hw_ver = "unknown"
self.sw_ver = "unknown"
Expand Down Expand Up @@ -817,6 +818,13 @@ def print_update(self, data) -> bool:
@property
def has_bambu_cloud_connection(self) -> bool:
return self._client.bambu_cloud.auth_token != ""

def set_prompt_sound(self, enable: bool):
if enable:
self._client.publish(PROMPT_SOUND_ENABLE)
else:
self._client.publish(PROMPT_SOUND_DISABLE)


@dataclass
class AMSInstance:
Expand Down
34 changes: 34 additions & 0 deletions custom_components/bambu_lab/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@
entity_category=EntityCategory.CONFIG,
)

PROMPT_SOUND_SWITCH_DESCRIPTION = SwitchEntityDescription(
key="prompt_sound",
icon="mdi:audio",
translation_key="prompt_sound",
entity_category=EntityCategory.CONFIG,
)

CAMERA_SWITCH_DESCRIPION = SwitchEntityDescription(
key="camera",
icon="mdi:refresh-auto",
Expand Down Expand Up @@ -55,6 +62,9 @@ async def async_setup_entry(
if coordinator.get_model().supports_feature(Features.CAMERA_IMAGE):
async_add_entities([BambuLabCameraImageSwitch(coordinator, entry)])

if coordinator.get_model().supports_feature(Features.PROMPT_SOUND):
async_add_entities([BambuLabPromptSoundSwitch(coordinator, entry)])


class BambuLabSwitch(BambuLabEntity, SwitchEntity):
"""Base BambuLab Switch"""
Expand Down Expand Up @@ -168,3 +178,27 @@ async def async_turn_off(self, **kwargs: Any) -> None:
"""Disable the camera."""
self._attr_is_on = False
await self.coordinator.set_camera_as_image_sensor(self._attr_is_on)


class BambuLabPromptSoundSwitch(BambuLabSwitch):
"""BambuLab Refresh data Switch"""

entity_description = PROMPT_SOUND_SWITCH_DESCRIPTION

@property
def icon(self) -> str:
"""Return the icon for the switch."""
return "mdi:volume-on" if self.is_on else "mdi:volume-off"

@property
def is_on(self) -> bool:
"""Return True if entity is on."""
return self.coordinator.get_model().home_flag.xcam_prompt_sound

async def async_turn_on(self, **kwargs: Any) -> None:
"""Enable manual refresh mode."""
self.coordinator.get_model().info.set_prompt_sound(True)

async def async_turn_off(self, **kwargs: Any) -> None:
"""Disable manual refresh mode."""
self.coordinator.get_model().info.set_prompt_sound(False)
9 changes: 6 additions & 3 deletions custom_components/bambu_lab/translations/ca.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
},
"step": {
"user": {
"description": "La configuració mitjançant Bambu Cloud és més senzilla. Opcionalment, podeu configurar manualment l'accés només local, però perd algunes funcions; això és necessari per a les impressores configurades en mode Només LAN.\n\rSi existeixen i funcionen, també podeu reutilitzar les credencials d'autenticació existents d'altres impressores configurades.\n \rTingueu en compte que els comptes de xarxes socials sense contrasenya no són compatibles amb la configuració del núvol.",
"description": "La configuració mitjançant Bambu Cloud és la més senzilla i ràpida. Els comptes de xarxes socials sense contrasenya no són compatibles.\n\rTambé podeu reutilitzar les credencials d'autenticació que funcionen d'altres impressores. En cas de trobar-los, es mostraran a l'adreça de correu electrònic.\n\rO podeu connectar-vos proporcionant manualment els detalls de connexió local de la impressora. Això és necessari per a una impressora en mode Lan.",
"data": {
"printer_mode": "Mode de configuració de la impressora:"
}
Expand Down Expand Up @@ -585,15 +585,18 @@
},
"imagecamera": {
"name": "Usar càmera amb sensor d'imatge"
},
"prompt_sound": {
"name": "Permet el so ràpid"
}
}
},
"selector": {
"configuration_type": {
"options": {
"bambu": "Núvol Bambu",
"lan": "Connexió local"
"lan": "Mode Lan"
}
}
}
}
}
9 changes: 6 additions & 3 deletions custom_components/bambu_lab/translations/da.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
},
"step": {
"user": {
"description": "Konfiguration via Bambu Cloud er den enkleste metode. Du kan vælge at konfigurere manuelt til kun lokal adgang, men det medfører tab af visse funktioner - dette kræves for printere indstillet til Kun Lan Mode.\n\rHvis de allerede eksisterer og fungerer, kan du også genbruge eksisterende autentifikationsoplysninger fra andre konfigurerede printere.\n\rBemærk, at sociale mediekonti uden en adgangskode ikke understøttes til cloud-konfiguration.",
"description": "Konfiguration via Bambu Cloud er enklest og hurtigst. Konti på sociale medier uden adgangskode understøttes ikke.\n\rDu kan også genbruge fungerende godkendelsesoplysninger fra andre printere. Hvis de findes, vil disse blive angivet af e-mailadressen.\n\rEller du kan oprette forbindelse ved manuelt at angive printerens lokale forbindelsesoplysninger. Dette er påkrævet for en printer i Lan-tilstand.",
"data": {
"printer_mode": "Printerkonfigurationsmetode:"
}
Expand Down Expand Up @@ -585,15 +585,18 @@
},
"imagecamera": {
"name": "Brug billedsensor kamera"
},
"prompt_sound": {
"name": "Tillad promptlyd"
}
}
},
"selector": {
"configuration_type": {
"options": {
"bambu": "Bambu Cloud",
"lan": "Lokal forbindelse"
"lan": "Lan-tilstand"
}
}
}
}
}
9 changes: 6 additions & 3 deletions custom_components/bambu_lab/translations/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
},
"step": {
"user": {
"description": "Am einfachsten ist die Konfiguration über Bambu Cloud. Sie können den Zugriff optional manuell nur für den lokalen Zugriff konfigurieren, dabei gehen jedoch einige Funktionen verloren – dies ist für Drucker erforderlich, die auf den Nur-LAN-Modus eingestellt sind.\n\rWenn sie vorhanden sind und funktionieren, können Sie auch vorhandene Authentifizierungsdaten von anderen konfigurierten Druckern wiederverwenden.\n \rBeachten Sie, dass Social-Media-Konten ohne Passwort die Cloud-Konfiguration nicht unterstützen.",
"description": "Die Konfiguration über Bambu Cloud ist am einfachsten und schnellsten. Social-Media-Konten ohne Passwort werden nicht unterstützt.\n\rSie können auch funktionierende Authentifizierungsdaten von anderen Druckern wiederverwenden. Wenn diese gefunden werden, werden sie nach der E-Mail-Adresse aufgelistet.\n\rAlternativ können Sie eine Verbindung herstellen, indem Sie die lokalen Verbindungsdetails des Druckers manuell angeben. Dies ist für einen Drucker im Lan-Modus erforderlich.",
"data": {
"printer_mode": "Drucker-Konfigurationsmodus:"
}
Expand Down Expand Up @@ -585,15 +585,18 @@
},
"imagecamera": {
"name": "Verwenden Sie eine Bildsensorkamera"
},
"prompt_sound": {
"name": "Aufforderungston zulassen"
}
}
},
"selector": {
"configuration_type": {
"options": {
"bambu": "BambuLab-Cloud",
"lan": "LAN-Mode (lokal)"
"lan": "LAN-Mode"
}
}
}
}
}
9 changes: 6 additions & 3 deletions custom_components/bambu_lab/translations/el.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
},
"step": {
"user": {
"description": "Η διαμόρφωση μέσω του Bambu Cloud είναι απλούστερη. Μπορείτε προαιρετικά να διαμορφώσετε με μη αυτόματο τρόπο μόνο για τοπική πρόσβαση, αλλά χάνετε ορισμένες δυνατότητες - αυτό απαιτείται για εκτυπωτές που έχουν οριστεί σε Λειτουργία μόνο δικτύου.\n\rΕάν υπάρχουν και λειτουργούν, μπορείτε επίσης να χρησιμοποιήσετε ξανά υπάρχοντα διαπιστευτήρια ελέγχου ταυτότητας από άλλους διαμορφωμένους εκτυπωτές.\n \rΛάβετε υπόψη ότι οι λογαριασμοί μέσων κοινωνικής δικτύωσης χωρίς κωδικό πρόσβασης δεν υποστηρίζονται για διαμόρφωση cloud.",
"description": "Η διαμόρφωση μέσω του Bambu Cloud είναι απλούστερη και ταχύτερη. Οι λογαριασμοί μέσων κοινωνικής δικτύωσης χωρίς κωδικό πρόσβασης δεν υποστηρίζονται.\n\rΜπορείτε επίσης να χρησιμοποιήσετε ξανά διαπιστευτήρια ελέγχου ταυτότητας εργασίας από άλλους εκτυπωτές. Εάν βρεθούν, θα εμφανιστούν στη λίστα με τη διεύθυνση email.\n\rΉ μπορείτε να συνδεθείτε παρέχοντας με μη αυτόματο τρόπο τις λεπτομέρειες τοπικής σύνδεσης του εκτυπωτή. Αυτό απαιτείται για έναν εκτυπωτή σε Lan Mode.",
"data": {
"printer_mode": "Τρόπος ρύθμισης εκτυπωτή:"
}
Expand Down Expand Up @@ -585,15 +585,18 @@
},
"imagecamera": {
"name": "Χρησιμοποιήστε κάμερα αισθητήρα εικόνας"
},
"prompt_sound": {
"name": "Να επιτρέπεται ο ήχος προτροπής"
}
}
},
"selector": {
"configuration_type": {
"options": {
"bambu": "Σύννεφο Bambu",
"lan": "Τοπική Σύνδεση"
"lan": "Lan Mode"
}
}
}
}
}
7 changes: 5 additions & 2 deletions custom_components/bambu_lab/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
},
"step": {
"user": {
"description": "Configuration via Bambu Cloud is simplest. You can optionally manually configure for local only access but you lose some features - this is required for printers set to Lan Only Mode.\n\rIf they exist and are working, you may also reuse existing authentication credentials from other configured printers.\n\rNote that social media accounts without a password are not support for cloud configuration.",
"description": "Configuration via Bambu Cloud is simplest and fastest. Social media accounts without a password are not supported.\n\rYou can also reuse working authentication credentials from other printers. If found these will be listed by the email address.\n\rOr you can connect by manually providing the printer local connection details. This is required for a printer in Lan Mode.",
"data": {
"printer_mode": "Printer configuration mode:"
}
Expand Down Expand Up @@ -585,14 +585,17 @@
},
"imagecamera": {
"name": "Use image sensor camera"
},
"prompt_sound": {
"name": "Allow Prompt Sound"
}
}
},
"selector": {
"configuration_type": {
"options": {
"bambu": "Bambu Cloud",
"lan": "Local Connection"
"lan": "Lan Mode"
}
}
}
Expand Down
Loading

0 comments on commit f436e3f

Please sign in to comment.