def updateOutputModel(self, model: PrinterOutputModel) -> None: model.updateKey(self.uuid) model.updateName(self.friendly_name) model.updateType(self.machine_variant) model.updateState(self.status if self.enabled else "disabled") model.updateBuildplate(self.build_plate.type if self.build_plate else "glass") for configuration, extruder_output, extruder_config in \ zip(self.configuration, model.extruders, model.printerConfiguration.extruderConfigurations): configuration.updateOutputModel(extruder_output) configuration.updateConfigurationModel(extruder_config)
def _onGlobalContainerStackChanged(self): container_stack = CuraApplication.getInstance( ).getGlobalContainerStack() num_extruders = container_stack.getProperty("machine_extruder_count", "value") # Ensure that a printer is created. controller = GenericOutputController(self) controller.setCanUpdateFirmware(True) self._printers = [ PrinterOutputModel(output_controller=controller, number_of_extruders=num_extruders) ] self._printers[0].updateName(container_stack.getName())
def test_availableConfigurations_removeConfig(): model = PrinterOutputModel(MagicMock()) configuration = MagicMock(spec=PrinterConfigurationModel) model.addAvailableConfiguration(configuration) model.removeAvailableConfiguration(configuration) assert model.availableConfigurations == []
def test_peripherals(): model = PrinterOutputModel(MagicMock()) model.peripheralsChanged = MagicMock() peripheral = MagicMock(spec=Peripheral) peripheral.name = "test" peripheral2 = MagicMock(spec=Peripheral) peripheral2.name = "test2" model.addPeripheral(peripheral) assert model.peripheralsChanged.emit.call_count == 1 model.addPeripheral(peripheral2) assert model.peripheralsChanged.emit.call_count == 2 assert model.peripherals == "test, test2" model.removePeripheral(peripheral) assert model.peripheralsChanged.emit.call_count == 3 assert model.peripherals == "test2"
def _updateAvailableConfigurations(self, model: PrinterOutputModel) -> None: # Generate a list of configurations for the left extruder. left_configurations = [ slot for slot in self.material_station.material_slots if self._isSupportedConfiguration(slot=slot, extruder_index=0) ] # Generate a list of configurations for the right extruder. right_configurations = [ slot for slot in self.material_station.material_slots if self._isSupportedConfiguration(slot=slot, extruder_index=1) ] # Create a list of all available combinations between both print cores. available_configurations = [ self._createAvailableConfigurationFromPrinterConfiguration( left_slot=left_slot, right_slot=right_slot, printer_configuration=model.printerConfiguration) for left_slot, right_slot in product(left_configurations, right_configurations) ] # Let Cura know which available configurations there are. model.setAvailableConfigurations(available_configurations)
def createOutputModel( self, controller: PrinterOutputController) -> PrinterOutputModel: """Creates a new output model. :param controller: - The controller of the model. """ # FIXME # Note that we're using '2' here as extruder count. We have hardcoded this for now to prevent issues where the # amount of extruders coming back from the API is actually lower (which it can be if a printer was just added # to a cluster). This should be fixed in the future, probably also on the cluster API side. model = PrinterOutputModel(controller, 2, firmware_version=self.firmware_version) self.updateOutputModel(model) return model
def test_availableConfigurations_addConfigTwice(): model = PrinterOutputModel(MagicMock()) configuration = MagicMock(spec=PrinterConfigurationModel) model.setAvailableConfigurations([configuration]) assert model.availableConfigurations == [configuration] # Adding it again should not have any effect model.addAvailableConfiguration(configuration) assert model.availableConfigurations == [configuration]
def test_uniqueConfigurations(printer_output_device): printer = PrinterOutputModel(MagicMock()) # Add a printer and fire the signal that ensures they get hooked up correctly. printer_output_device._printers = [printer] printer_output_device._onPrintersChanged() assert printer_output_device.uniqueConfigurations == [] configuration = PrinterConfigurationModel() printer.addAvailableConfiguration(configuration) assert printer_output_device.uniqueConfigurations == [configuration] # Once the type of printer is set, it's active configuration counts as being set. # In that case, that should also be added to the list of available configurations printer.updateType("blarg!") loaded_material = MaterialOutputModel(guid = "", type = "PLA", color = "Blue", brand = "Generic", name = "Blue PLA") loaded_left_extruder = ExtruderConfigurationModel(0) loaded_left_extruder.setMaterial(loaded_material) loaded_right_extruder = ExtruderConfigurationModel(1) loaded_right_extruder.setMaterial(loaded_material) printer.printerConfiguration.setExtruderConfigurations([loaded_left_extruder, loaded_right_extruder]) assert printer_output_device.uniqueConfigurations == [configuration, printer.printerConfiguration]
def _createPrinterList(self) -> None: printer = PrinterOutputModel(output_controller=self._output_controller, number_of_extruders=self._number_of_extruders) printer.updateName(self.name) self._printers = [printer] self.printersChanged.emit()
def updateOutputModel(self, model: PrinterOutputModel) -> None: model.updateKey(self.uuid) model.updateName(self.friendly_name) model.updateType(self.machine_variant) model.updateState(self.status if self.enabled else "disabled") model.updateBuildplate( self.build_plate.type if self.build_plate else "glass") model.setCameraUrl( QUrl("http://{}:8080/?action=stream".format(self.ip_address))) # Set the possible configurations based on whether a Material Station is present or not. if self.material_station and self.material_station.material_slots: self._updateAvailableConfigurations(model) if self.configuration: self._updateActiveConfiguration(model)
def updateOutputModel(self, model: PrinterOutputModel) -> None: model.updateKey(self.uuid) model.updateName(self.friendly_name) model.updateType(self.machine_variant) model.updateState(self.status if self.enabled else "disabled") model.updateBuildplate( self.build_plate.type if self.build_plate else "glass") model.setCameraUrl( QUrl("http://{}:8080/?action=stream".format(self.ip_address))) if model.printerConfiguration is not None: for configuration, extruder_output, extruder_config in \ zip(self.configuration, model.extruders, model.printerConfiguration.extruderConfigurations): configuration.updateOutputModel(extruder_output) configuration.updateConfigurationModel(extruder_config)
def _updatePrinter(self, printer: PrinterOutputModel, data: Dict[str, Any]) -> None: # For some unknown reason the cluster wants UUID for everything, except for sending a job directly to a printer. # Then we suddenly need the unique name. So in order to not have to mess up all the other code, we save a mapping. self._printer_uuid_to_unique_name_mapping[ data["uuid"]] = data["unique_name"] definitions = ContainerRegistry.getInstance().findDefinitionContainers( name=data["machine_variant"]) if not definitions: Logger.log("w", "Unable to find definition for machine variant %s", data["machine_variant"]) return machine_definition = definitions[0] printer.updateName(data["friendly_name"]) printer.updateKey(data["uuid"]) printer.updateType(data["machine_variant"]) if data["status"] != "unreachable": self._application.getDiscoveredPrintersModel( ).updateDiscoveredPrinter(data["ip_address"], name=data["friendly_name"], machine_type=data["machine_variant"]) # Do not store the build plate information that comes from connect if the current printer has not build plate information if "build_plate" in data and machine_definition.getMetaDataEntry( "has_variant_buildplates", False): printer.updateBuildplate(data["build_plate"]["type"]) if not data["enabled"]: printer.updateState("disabled") else: printer.updateState(data["status"]) for index in range(0, self._number_of_extruders): extruder = printer.extruders[index] try: extruder_data = data["configuration"][index] except IndexError: break extruder.updateHotendID(extruder_data.get("print_core_id", "")) material_data = extruder_data["material"] if extruder.activeMaterial is None or extruder.activeMaterial.guid != material_data[ "guid"]: material = self._createMaterialOutputModel(material_data) extruder.updateActiveMaterial(material)
def _onGetPrinterDataFinished(self, reply): status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) if status_code == 200: try: result = json.loads(bytes(reply.readAll()).decode("utf-8")) except json.decoder.JSONDecodeError: Logger.log("w", "Received an invalid printer state message: Not valid JSON.") return if not self._printers: # Quickest way to get the firmware version is to grab it from the zeroconf. firmware_version = self._properties.get(b"firmware_version", b"").decode("utf-8") self._printers = [PrinterOutputModel(output_controller=self._output_controller, number_of_extruders=self._number_of_extruders, firmware_version=firmware_version)] self._printers[0].setCameraUrl(QUrl("http://" + self._address + ":8080/?action=stream")) for extruder in self._printers[0].extruders: extruder.activeMaterialChanged.connect(self.materialIdChanged) extruder.hotendIDChanged.connect(self.hotendIdChanged) self.printersChanged.emit() # LegacyUM3 always has a single printer. printer = self._printers[0] printer.updateBedTemperature(result["bed"]["temperature"]["current"]) printer.updateTargetBedTemperature(result["bed"]["temperature"]["target"]) printer.updateState(result["status"]) try: # If we're still handling the request, we should ignore remote for a bit. if not printer.getController().isPreheatRequestInProgress(): printer.updateIsPreheating(result["bed"]["pre_heat"]["active"]) except KeyError: # Older firmwares don't support preheating, so we need to fake it. pass head_position = result["heads"][0]["position"] printer.updateHeadPosition(head_position["x"], head_position["y"], head_position["z"]) for index in range(0, self._number_of_extruders): temperatures = result["heads"][0]["extruders"][index]["hotend"]["temperature"] extruder = printer.extruders[index] extruder.updateTargetHotendTemperature(temperatures["target"]) extruder.updateHotendTemperature(temperatures["current"]) material_guid = result["heads"][0]["extruders"][index]["active_material"]["guid"] if extruder.activeMaterial is None or extruder.activeMaterial.guid != material_guid: # Find matching material (as we need to set brand, type & color) containers = ContainerRegistry.getInstance().findInstanceContainers(type="material", GUID=material_guid) if containers: color = containers[0].getMetaDataEntry("color_code") brand = containers[0].getMetaDataEntry("brand") material_type = containers[0].getMetaDataEntry("material") name = containers[0].getName() else: # Unknown material. color = "#00000000" brand = "Unknown" material_type = "Unknown" name = "Unknown" material = MaterialOutputModel(guid=material_guid, type=material_type, brand=brand, color=color, name = name) extruder.updateActiveMaterial(material) try: hotend_id = result["heads"][0]["extruders"][index]["hotend"]["id"] except KeyError: hotend_id = "" printer.extruders[index].updateHotendID(hotend_id) else: Logger.log("w", "Got status code {status_code} while trying to get printer data".format(status_code = status_code))
def _createPrinterModel(self, data: Dict[str, Any]) -> PrinterOutputModel: printer = PrinterOutputModel(output_controller = ClusterUM3PrinterOutputController(self), number_of_extruders = self._number_of_extruders) printer.setCameraUrl(QUrl("http://" + data["ip_address"] + ":8080/?action=stream")) self._printers.append(printer) return printer
def updateOutputModel(self, model: PrinterOutputModel) -> None: model.updateKey(self.uuid) model.updateName(self.friendly_name) model.updateType(self.machine_variant) model.updateState(self.status if self.enabled else "disabled") model.updateBuildplate( self.build_plate.type if self.build_plate else "glass") model.setCameraUrl( QUrl("http://{}:8080/?action=stream".format(self.ip_address))) if not model.printerConfiguration: # Prevent accessing printer configuration when not available. # This sometimes happens when a printer was just added to a group and Cura is connected to that group. return # Set the possible configurations based on whether a Material Station is present or not. if self.material_station and self.material_station.material_slots: self._updateAvailableConfigurations(model) if self.configuration: self._updateActiveConfiguration(model)
def _updatePrinter(self, printer: PrinterOutputModel, data: Dict[str, Any]) -> None: # For some unknown reason the cluster wants UUID for everything, except for sending a job directly to a printer. # Then we suddenly need the unique name. So in order to not have to mess up all the other code, we save a mapping. self._printer_uuid_to_unique_name_mapping[data["uuid"]] = data["unique_name"] definitions = ContainerRegistry.getInstance().findDefinitionContainers(name = data["machine_variant"]) if not definitions: Logger.log("w", "Unable to find definition for machine variant %s", data["machine_variant"]) return machine_definition = definitions[0] printer.updateName(data["friendly_name"]) printer.updateKey(data["uuid"]) printer.updateType(data["machine_variant"]) if data["status"] != "unreachable": self._application.getDiscoveredPrintersModel().updateDiscoveredPrinter(data["ip_address"], name = data["friendly_name"], machine_type = data["machine_variant"]) # Do not store the build plate information that comes from connect if the current printer has not build plate information if "build_plate" in data and machine_definition.getMetaDataEntry("has_variant_buildplates", False): printer.updateBuildplate(data["build_plate"]["type"]) if not data["enabled"]: printer.updateState("disabled") else: printer.updateState(data["status"]) for index in range(0, self._number_of_extruders): extruder = printer.extruders[index] try: extruder_data = data["configuration"][index] except IndexError: break extruder.updateHotendID(extruder_data.get("print_core_id", "")) material_data = extruder_data["material"] if extruder.activeMaterial is None or extruder.activeMaterial.guid != material_data["guid"]: material = self._createMaterialOutputModel(material_data) extruder.updateActiveMaterial(material)
def _build_printer_output_model(self) -> PrinterOutputModel: """Returns printer Output Model for this device.""" printer_output_model = PrinterOutputModel( output_controller=self._printer_output_controller, number_of_extruders=_NUM_EXTRUDERS) printer_output_model.updateKey(self._address) printer_output_model.updateName(self.address) printer_output_model.updateState('idle') printer_output_model.setAvailableConfigurations( [_build_printer_conf_model()]) printer_output_model.updateType('Monoprice Select Mini') printer_output_model.updateActivePrintJob(self._print_job_model) return printer_output_model
def createOutputModel(self, controller: PrinterOutputController) -> PrinterOutputModel: model = PrinterOutputModel(controller, len(self.configuration), firmware_version = self.firmware_version) self.updateOutputModel(model) return model
"value": ["yay"] }, ] test_validate_data_get_update = [ { "attribute": "configuration", "value": PrinterConfigurationModel() }, { "attribute": "owner", "value": "WHOO" }, { "attribute": "assignedPrinter", "value": PrinterOutputModel(MagicMock()) }, { "attribute": "key", "value": "YAY" }, { "attribute": "name", "value": "Turtles" }, { "attribute": "timeTotal", "value": 10 }, { "attribute": "timeElapsed",