|
11 | 11 | from pylamarzocco.const import ( |
12 | 12 | BoilerStatus, |
13 | 13 | BoilerType, |
| 14 | + DoseMode, |
14 | 15 | MachineMode, |
15 | 16 | MachineState, |
16 | 17 | ModelCode, |
|
21 | 22 | ) |
22 | 23 | from pylamarzocco.exceptions import BluetoothConnectionFailed |
23 | 24 | from pylamarzocco.models import ( |
| 25 | + BrewByWeightDoses, |
24 | 26 | CoffeeAndFlushCounter, |
25 | 27 | CoffeeAndFlushTrend, |
26 | 28 | CoffeeBoiler, |
@@ -68,13 +70,13 @@ async def get_schedule(self) -> None: |
68 | 70 |
|
69 | 71 | async def get_model_info_from_bluetooth(self) -> None: |
70 | 72 | """Fetch and update model information from Bluetooth. |
71 | | - |
| 73 | +
|
72 | 74 | Retrieves machine capabilities via Bluetooth and updates the dashboard |
73 | 75 | with model_name and model_code information. |
74 | 76 | """ |
75 | 77 | if self._bluetooth_client is None: |
76 | 78 | raise BluetoothConnectionFailed("Bluetooth client not initialized") |
77 | | - |
| 79 | + |
78 | 80 | try: |
79 | 81 | capabilities = await self._bluetooth_client.get_machine_capabilities() |
80 | 82 | except (BleakError, BluetoothConnectionFailed) as exc: |
@@ -168,9 +170,13 @@ async def get_dashboard_from_bluetooth(self) -> None: |
168 | 170 | ), |
169 | 171 | ) |
170 | 172 | steam_level.enabled = boiler.is_enabled |
171 | | - self.dashboard.config[WidgetType.CM_STEAM_BOILER_LEVEL] = steam_level |
| 173 | + self.dashboard.config[WidgetType.CM_STEAM_BOILER_LEVEL] = ( |
| 174 | + steam_level |
| 175 | + ) |
172 | 176 | # Remove temperature widget if it exists (not applicable for this model) |
173 | | - self.dashboard.config.pop(WidgetType.CM_STEAM_BOILER_TEMPERATURE, None) |
| 177 | + self.dashboard.config.pop( |
| 178 | + WidgetType.CM_STEAM_BOILER_TEMPERATURE, None |
| 179 | + ) |
174 | 180 | else: |
175 | 181 | # Other models (GS3, original Mini) use steam temperature widget |
176 | 182 | steam_temp = cast( |
@@ -309,7 +315,7 @@ async def set_coffee_target_temperature(self, temperature: float) -> bool: |
309 | 315 | coffee_boiler.target_temperature = float(temperature) |
310 | 316 |
|
311 | 317 | return result |
312 | | - |
| 318 | + |
313 | 319 | @models_supported((ModelCode.GS3, ModelCode.GS3_AV, ModelCode.GS3_MP)) |
314 | 320 | async def set_steam_target_temperature(self, temperature: float) -> bool: |
315 | 321 | """Set the steam target temperature.""" |
@@ -401,6 +407,78 @@ async def set_wakeup_schedule( |
401 | 407 | self.serial_number, schedule |
402 | 408 | ) |
403 | 409 |
|
| 410 | + @cloud_only |
| 411 | + @models_supported((ModelCode.LINEA_MINI_R,)) |
| 412 | + async def set_brew_by_weight_dose_mode(self, mode: DoseMode) -> bool: |
| 413 | + """Set the brew by weight dose mode (Linea Mini R only). |
| 414 | +
|
| 415 | + Args: |
| 416 | + mode: The dose mode (DoseMode.DOSE_1, DoseMode.DOSE_2, or DoseMode.CONTINUOUS) |
| 417 | + """ |
| 418 | + assert self._cloud_client |
| 419 | + result = await self._cloud_client.change_brew_by_weight_dose_mode( |
| 420 | + self.serial_number, mode |
| 421 | + ) |
| 422 | + |
| 423 | + # Update dashboard if command succeeded |
| 424 | + if result and WidgetType.CM_BREW_BY_WEIGHT_DOSES in self.dashboard.config: |
| 425 | + brew_by_weight = cast( |
| 426 | + BrewByWeightDoses, |
| 427 | + self.dashboard.config[WidgetType.CM_BREW_BY_WEIGHT_DOSES], |
| 428 | + ) |
| 429 | + brew_by_weight.mode = mode |
| 430 | + |
| 431 | + return result |
| 432 | + |
| 433 | + @cloud_only |
| 434 | + @models_supported((ModelCode.LINEA_MINI_R,)) |
| 435 | + async def set_brew_by_weight_dose(self, dose: DoseMode, value: float) -> bool: |
| 436 | + """Set a brew by weight dose value (Linea Mini R only). |
| 437 | +
|
| 438 | + Args: |
| 439 | + dose: Which dose to set (must be DoseMode.DOSE_1 or DoseMode.DOSE_2, |
| 440 | + CONTINUOUS is not valid for setting dose values) |
| 441 | + value: The dose value in grams |
| 442 | +
|
| 443 | + Returns: |
| 444 | + True if the command was successful, False otherwise. |
| 445 | + Returns False if dose is not DOSE_1 or DOSE_2 or if the brew by |
| 446 | + weight widget is not available in the dashboard. |
| 447 | + """ |
| 448 | + assert self._cloud_client |
| 449 | + |
| 450 | + # Get current doses from dashboard |
| 451 | + if WidgetType.CM_BREW_BY_WEIGHT_DOSES not in self.dashboard.config: |
| 452 | + return False |
| 453 | + |
| 454 | + brew_by_weight = cast( |
| 455 | + BrewByWeightDoses, |
| 456 | + self.dashboard.config[WidgetType.CM_BREW_BY_WEIGHT_DOSES], |
| 457 | + ) |
| 458 | + |
| 459 | + # Set the dose values, keeping the other one unchanged |
| 460 | + if dose == DoseMode.DOSE_1: |
| 461 | + dose_1 = value |
| 462 | + dose_2 = brew_by_weight.doses.dose_2.dose |
| 463 | + elif dose == DoseMode.DOSE_2: |
| 464 | + dose_1 = brew_by_weight.doses.dose_1.dose |
| 465 | + dose_2 = value |
| 466 | + else: |
| 467 | + return False |
| 468 | + |
| 469 | + result = await self._cloud_client.set_brew_by_weight_dose( |
| 470 | + self.serial_number, dose_1, dose_2 |
| 471 | + ) |
| 472 | + |
| 473 | + # Update dashboard if command succeeded |
| 474 | + if result: |
| 475 | + if dose == DoseMode.DOSE_1: |
| 476 | + brew_by_weight.doses.dose_1.dose = value |
| 477 | + else: |
| 478 | + brew_by_weight.doses.dose_2.dose = value |
| 479 | + |
| 480 | + return result |
| 481 | + |
404 | 482 | def to_dict(self) -> dict[Any, Any]: |
405 | 483 | """Return self in dict represenation.""" |
406 | 484 | return { |
|
0 commit comments