Browse Source

STAR-322: Adding documentation and fixing model types

Daniel Schiavini 6 years ago
parent
commit
7668801564

+ 13 - 12
plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py

@@ -10,12 +10,12 @@ from UM.Logger import Logger
 from cura.API import Account
 from cura.NetworkClient import NetworkClient
 from ..Models import BaseModel
-from .Models.CloudCluster import CloudCluster
+from .Models.CloudClusterResponse import CloudClusterResponse
 from .Models.CloudErrorObject import CloudErrorObject
 from .Models.CloudClusterStatus import CloudClusterStatus
-from .Models.CloudJobUploadRequest import CloudJobUploadRequest
+from .Models.CloudPrintJobUploadRequest import CloudPrintJobUploadRequest
 from .Models.CloudPrintResponse import CloudPrintResponse
-from .Models.CloudJobResponse import CloudJobResponse
+from .Models.CloudPrintJobResponse import CloudPrintJobResponse
 
 
 ## The cloud API client is responsible for handling the requests and responses from the cloud.
@@ -43,9 +43,9 @@ class CloudApiClient(NetworkClient):
 
     ## Retrieves all the clusters for the user that is currently logged in.
     #  \param on_finished: The function to be called after the result is parsed.
-    def getClusters(self, on_finished: Callable[[List[CloudCluster]], any]) -> None:
+    def getClusters(self, on_finished: Callable[[List[CloudClusterResponse]], any]) -> None:
         url = "{}/clusters".format(self.CLUSTER_API_ROOT)
-        self.get(url, on_finished=self._wrapCallback(on_finished, CloudCluster))
+        self.get(url, on_finished=self._wrapCallback(on_finished, CloudClusterResponse))
 
     ## Retrieves the status of the given cluster.
     #  \param cluster_id: The ID of the cluster.
@@ -57,10 +57,11 @@ class CloudApiClient(NetworkClient):
     ## Requests the cloud to register the upload of a print job mesh.
     #  \param request: The request object.
     #  \param on_finished: The function to be called after the result is parsed.
-    def requestUpload(self, request: CloudJobUploadRequest, on_finished: Callable[[CloudJobResponse], any]) -> None:
+    def requestUpload(self, request: CloudPrintJobUploadRequest, on_finished: Callable[[CloudPrintJobResponse], any]
+                      ) -> None:
         url = "{}/jobs/upload".format(self.CURA_API_ROOT)
-        body = json.dumps({"data": request.__dict__})
-        self.put(url, body, on_finished=self._wrapCallback(on_finished, CloudJobResponse))
+        body = json.dumps({"data": request.toDict()})
+        self.put(url, body, on_finished=self._wrapCallback(on_finished, CloudPrintJobResponse))
 
     ## Requests the cloud to register the upload of a print job mesh.
     #  \param upload_response: The object received after requesting an upload with `self.requestUpload`.
@@ -68,7 +69,7 @@ class CloudApiClient(NetworkClient):
     #  \param on_finished: The function to be called after the result is parsed. It receives the print job ID.
     #  \param on_progress: A function to be called during upload progress. It receives a percentage (0-100).
     #  \param on_error: A function to be called if the upload fails. It receives a dict with the error.
-    def uploadMesh(self, upload_response: CloudJobResponse, mesh: bytes, on_finished: Callable[[str], any],
+    def uploadMesh(self, upload_response: CloudPrintJobResponse, mesh: bytes, on_finished: Callable[[str], any],
                    on_progress: Callable[[int], any], on_error: Callable[[dict], any]):
         
         def progressCallback(bytes_sent: int, bytes_total: int) -> None:
@@ -126,13 +127,13 @@ class CloudApiClient(NetworkClient):
     ## Parses the given models and calls the correct callback depending on the result.
     #  \param response: The response from the server, after being converted to a dict.
     #  \param on_finished: The callback in case the response is successful.
-    #  \param model: The type of the model to convert the response to. It may either be a single record or a list.
+    #  \param model_class: The type of the model to convert the response to. It may either be a single record or a list.
     def _parseModels(self, response: Dict[str, any],
                      on_finished: Callable[[Union[Model, List[Model]]], any],
-                     model: Type[Model]) -> None:
+                     model_class: Type[Model]) -> None:
         if "data" in response:
             data = response["data"]
-            result = [model(**c) for c in data] if isinstance(data, list) else model(**data)
+            result = [model_class(**c) for c in data] if isinstance(data, list) else model_class(**data)
             on_finished(result)
         elif "errors" in response:
             self._on_error([CloudErrorObject(**error) for error in response["errors"]])

+ 13 - 13
plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py

@@ -20,11 +20,11 @@ from ..MeshFormatHandler import MeshFormatHandler
 from ..UM3PrintJobOutputModel import UM3PrintJobOutputModel
 from .CloudApiClient import CloudApiClient
 from .Models.CloudClusterStatus import CloudClusterStatus
-from .Models.CloudJobUploadRequest import CloudJobUploadRequest
+from .Models.CloudPrintJobUploadRequest import CloudPrintJobUploadRequest
 from .Models.CloudPrintResponse import CloudPrintResponse
-from .Models.CloudJobResponse import CloudJobResponse
-from .Models.CloudClusterPrinter import CloudClusterPrinter
-from .Models.CloudClusterPrintJob import CloudClusterPrintJob
+from .Models.CloudPrintJobResponse import CloudPrintJobResponse
+from .Models.CloudClusterPrinterStatus import CloudClusterPrinterStatus
+from .Models.CloudClusterPrintJobStatus import CloudClusterPrintJobStatus
 from .Utils import findChanges, formatDateCompleted, formatTimeCompleted
 
 
@@ -116,8 +116,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice):
         self._progress_message = None  # type: Optional[Message]
 
         # Keep server string of the last generated time to avoid updating models more than once for the same response
-        self._received_printers = None  # type: Optional[List[CloudClusterPrinter]]
-        self._received_print_jobs = None  # type: Optional[List[CloudClusterPrintJob]]
+        self._received_printers = None  # type: Optional[List[CloudClusterPrinterStatus]]
+        self._received_print_jobs = None  # type: Optional[List[CloudClusterPrintJobStatus]]
 
         # A set of the user's job IDs that have finished
         self._finished_jobs = set()  # type: Set[str]
@@ -166,7 +166,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice):
 
         mesh_bytes = mesh_format.getBytes(nodes)
 
-        request = CloudJobUploadRequest(
+        request = CloudPrintJobUploadRequest(
             job_name = file_name,
             file_size = len(mesh_bytes),
             content_type = mesh_format.mime_type,
@@ -199,9 +199,9 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice):
 
     ## Updates the local list of printers with the list received from the cloud.
     #  \param jobs: The printers received from the cloud.
-    def _updatePrinters(self, printers: List[CloudClusterPrinter]) -> None:
+    def _updatePrinters(self, printers: List[CloudClusterPrinterStatus]) -> None:
         previous = {p.key: p for p in self._printers}  # type: Dict[str, PrinterOutputModel]
-        received = {p.uuid: p for p in printers}  # type: Dict[str, CloudClusterPrinter]
+        received = {p.uuid: p for p in printers}  # type: Dict[str, CloudClusterPrinterStatus]
 
         removed_printers, added_printers, updated_printers = findChanges(previous, received)
 
@@ -224,8 +224,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice):
 
     ## Updates the local list of print jobs with the list received from the cloud.
     #  \param jobs: The print jobs received from the cloud.
-    def _updatePrintJobs(self, jobs: List[CloudClusterPrintJob]) -> None:
-        received = {j.uuid: j for j in jobs}  # type: Dict[str, CloudClusterPrintJob]
+    def _updatePrintJobs(self, jobs: List[CloudClusterPrintJobStatus]) -> None:
+        received = {j.uuid: j for j in jobs}  # type: Dict[str, CloudClusterPrintJobStatus]
         previous = {j.key: j for j in self._print_jobs}  # type: Dict[str, UM3PrintJobOutputModel]
 
         removed_jobs, added_jobs, updated_jobs = findChanges(previous, received)
@@ -248,7 +248,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice):
 
     ## Registers a new print job received via the cloud API.
     #  \param job: The print job received.
-    def _addPrintJob(self, job: CloudClusterPrintJob) -> None:
+    def _addPrintJob(self, job: CloudClusterPrintJobStatus) -> None:
         model = job.createOutputModel(CloudOutputController(self))
         model.stateChanged.connect(self._onPrintJobStateChanged)
         if job.printer_uuid:
@@ -284,7 +284,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice):
     ## Uploads the mesh when the print job was registered with the cloud API.
     #  \param mesh: The bytes to upload.
     #  \param job_response: The response received from the cloud API.
-    def _onPrintJobCreated(self, mesh: bytes, job_response: CloudJobResponse) -> None:
+    def _onPrintJobCreated(self, mesh: bytes, job_response: CloudPrintJobResponse) -> None:
         self._api.uploadMesh(job_response, mesh, self._onPrintJobUploaded, self._updateUploadProgress,
                              lambda _: self._onUploadError(T.UPLOAD_ERROR))
 

+ 3 - 3
plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py

@@ -12,7 +12,7 @@ from cura.CuraApplication import CuraApplication
 from cura.Settings.GlobalStack import GlobalStack
 from .CloudApiClient import CloudApiClient
 from .CloudOutputDevice import CloudOutputDevice
-from .Models.CloudCluster import CloudCluster
+from .Models.CloudClusterResponse import CloudClusterResponse
 from .Models.CloudErrorObject import CloudErrorObject
 from .Utils import findChanges
 
@@ -72,8 +72,8 @@ class CloudOutputDeviceManager:
         self._api.getClusters(self._onGetRemoteClustersFinished)
 
     ##  Callback for when the request for getting the clusters. is finished.
-    def _onGetRemoteClustersFinished(self, clusters: List[CloudCluster]) -> None:
-        online_clusters = {c.cluster_id: c for c in clusters if c.is_online}  # type: Dict[str, CloudCluster]
+    def _onGetRemoteClustersFinished(self, clusters: List[CloudClusterResponse]) -> None:
+        online_clusters = {c.cluster_id: c for c in clusters if c.is_online}  # type: Dict[str, CloudClusterResponse]
 
         removed_devices, added_clusters, updates = findChanges(self._remote_clusters, online_clusters)
 

+ 43 - 5
plugins/UM3NetworkPrinting/src/Cloud/Models/BaseCloudModel.py

@@ -1,17 +1,55 @@
 # Copyright (c) 2018 Ultimaker B.V.
 # Cura is released under the terms of the LGPLv3 or higher.
 from datetime import datetime, timezone
+from typing import Dict, Union, TypeVar, Type, List
 
 from ...Models import BaseModel
 
 
+## Base class for the models used in the interface with the Ultimaker cloud APIs.
 class BaseCloudModel(BaseModel):
+    ## Checks whether the two models are equal.
+    #  \param other: The other model.
+    #  \return True if they are equal, False if they are different.
     def __eq__(self, other):
-        return type(self) == type(other) and self.__dict__ == other.__dict__
+        return type(self) == type(other) and self.toDict() == other.toDict()
 
-    def __ne__(self, other):
-        return type(self) != type(other) or self.__dict__ != other.__dict__
+    ## Checks whether the two models are different.
+    #  \param other: The other model.
+    #  \return True if they are different, False if they are the same.
+    def __ne__(self, other) -> bool:
+        return type(self) != type(other) or self.toDict() != other.toDict()
 
+    ## Converts the model into a serializable dictionary
+    def toDict(self) -> Dict[str, any]:
+        return self.__dict__
+
+    # Type variable used in the parse methods below, which should be a subclass of BaseModel.
+    T = TypeVar("T", bound=BaseModel)
+
+    ## Parses a single model.
+    #  \param model_class: The model class.
+    #  \param values: The value of the model, which is usually a dictionary, but may also be already parsed.
+    #  \return An instance of the model_class given.
+    @staticmethod
+    def parseModel(model_class: Type[T], values: Union[T, Dict[str, any]]) -> T:
+        if isinstance(values, dict):
+            return model_class(**values)
+        return values
+
+    ## Parses a list of models.
+    #  \param model_class: The model class.
+    #  \param values: The value of the list. Each value is usually a dictionary, but may also be already parsed.
+    #  \return A list of instances of the model_class given.
+    @classmethod
+    def parseModels(cls, model_class: Type[T], values: List[Union[T, Dict[str, any]]]) -> List[T]:
+        return [cls.parseModel(model_class, value) for value in values]
+
+    ## Parses the given date string.
+    #  \param date: The date to parse.
+    #  \return The parsed date.
     @staticmethod
-    def parseDate(date_str: str) -> datetime:
-        return datetime.strptime(date_str, "%Y-%m-%dT%H:%M:%S.%fZ").replace(tzinfo=timezone.utc)
+    def parseDate(date: Union[str, datetime]) -> datetime:
+        if isinstance(date, datetime):
+            return date
+        return datetime.strptime(date, "%Y-%m-%dT%H:%M:%S.%fZ").replace(tzinfo=timezone.utc)

+ 0 - 21
plugins/UM3NetworkPrinting/src/Cloud/Models/CloudCluster.py

@@ -1,21 +0,0 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-from .BaseCloudModel import BaseCloudModel
-
-
-##  Class representing a cloud connected cluster.
-class CloudCluster(BaseCloudModel):
-    def __init__(self, **kwargs):
-        self.cluster_id = None  # type: str
-        self.host_guid = None  # type: str
-        self.host_name = None  # type: str
-        self.host_version = None  # type: str
-        self.status = None  # type: str
-        self.is_online = False  # type: bool
-        super().__init__(**kwargs)
-
-    # Validates the model, raising an exception if the model is invalid.
-    def validate(self) -> None:
-        super().validate()
-        if not self.cluster_id:
-            raise ValueError("cluster_id is required on CloudCluster")

+ 0 - 65
plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJob.py

@@ -1,65 +0,0 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-from typing import List
-
-from cura.PrinterOutput.ConfigurationModel import ConfigurationModel
-from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputController import CloudOutputController
-from .CloudClusterPrinterConfiguration import CloudClusterPrinterConfiguration
-from .CloudClusterPrintJobConstraint import CloudClusterPrintJobConstraint
-from .BaseCloudModel import BaseCloudModel
-
-
-##  Class representing a print job
-from plugins.UM3NetworkPrinting.src.UM3PrintJobOutputModel import UM3PrintJobOutputModel
-
-
-class CloudClusterPrintJob(BaseCloudModel):
-    def __init__(self, **kwargs) -> None:
-        self.assigned_to = None  # type: str
-        self.configuration = []  # type: List[CloudClusterPrinterConfiguration]
-        self.constraints = []  # type: List[CloudClusterPrintJobConstraint]
-        self.created_at = None  # type: str
-        self.force = None  # type: str
-        self.last_seen = None  # type: str
-        self.machine_variant = None  # type: str
-        self.name = None  # type: str
-        self.network_error_count = None  # type: int
-        self.owner = None  # type: str
-        self.printer_uuid = None  # type: str
-        self.started = None  # type: str
-        self.status = None  # type: str
-        self.time_elapsed = None  # type: str
-        self.time_total = None  # type: str
-        self.uuid = None  # type: str
-        super().__init__(**kwargs)
-        self.configuration = [CloudClusterPrinterConfiguration(**c) if isinstance(c, dict) else c
-                              for c in self.configuration]
-        self.constraints = [CloudClusterPrintJobConstraint(**p) if isinstance(p, dict) else p
-                            for p in self.constraints]
-
-    ## Creates an UM3 print job output model based on this cloud cluster print job.
-    #  \param printer: The output model of the printer
-    def createOutputModel(self, controller: CloudOutputController) -> UM3PrintJobOutputModel:
-        model = UM3PrintJobOutputModel(controller, self.uuid, self.name)
-        self.updateOutputModel(model)
-
-        return model
-
-    ## Creates a new configuration model
-    def _createConfigurationModel(self) -> ConfigurationModel:
-        extruders = [extruder.createConfigurationModel() for extruder in self.configuration or ()]
-        configuration = ConfigurationModel()
-        configuration.setExtruderConfigurations(extruders)
-        return configuration
-
-    ## Updates an UM3 print job output model based on this cloud cluster print job.
-    #  \param model: The model to update.
-    def updateOutputModel(self, model: UM3PrintJobOutputModel) -> None:
-        # TODO: Add `compatible_machine_families` to the cloud, than add model.setCompatibleMachineFamilies()
-        # TODO: Add `impediments_to_printing` to the cloud, see ClusterUM3OutputDevice._updatePrintJob
-        # TODO: Use model.updateConfigurationChanges, see ClusterUM3OutputDevice#_createConfigurationChanges
-        model.updateConfiguration(self._createConfigurationModel())
-        model.updateTimeTotal(self.time_total)
-        model.updateTimeElapsed(self.time_elapsed)
-        model.updateOwner(self.owner)
-        model.updateState(self.status)

+ 9 - 3
plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConstraint.py

@@ -1,10 +1,16 @@
 # Copyright (c) 2018 Ultimaker B.V.
 # Cura is released under the terms of the LGPLv3 or higher.
+from typing import Optional
+
 from .BaseCloudModel import BaseCloudModel
 
 
 ## Class representing a cloud cluster print job constraint
-class CloudClusterPrintJobConstraint(BaseCloudModel):
-    def __init__(self, **kwargs) -> None:
-        self.require_printer_name = None  # type: str
+#  Spec: https://api-staging.ultimaker.com/connect/v1/spec
+class CloudClusterPrintJobConstraints(BaseCloudModel):
+    ## Creates a new print job constraint.
+    #  \param require_printer_name: Unique name of the printer that this job should be printed on.
+    #       Should be one of the unique_name field values in the cluster, e.g. 'ultimakersystem-ccbdd30044ec'
+    def __init__(self, require_printer_name: Optional[str] = None, **kwargs) -> None:
+        self.require_printer_name = require_printer_name
         super().__init__(**kwargs)

+ 87 - 0
plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py

@@ -0,0 +1,87 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+from typing import List, Optional, Union, Dict
+
+from cura.PrinterOutput.ConfigurationModel import ConfigurationModel
+from plugins.UM3NetworkPrinting.src.Cloud.CloudOutputController import CloudOutputController
+from .CloudClusterPrinterConfiguration import CloudClusterPrinterConfiguration
+from .CloudClusterPrintJobConstraint import CloudClusterPrintJobConstraints
+from .BaseCloudModel import BaseCloudModel
+
+
+##  Class representing a print job
+from plugins.UM3NetworkPrinting.src.UM3PrintJobOutputModel import UM3PrintJobOutputModel
+
+
+## Model for the status of a single print job in a cluster.
+#  Spec: https://api-staging.ultimaker.com/connect/v1/spec
+class CloudClusterPrintJobStatus(BaseCloudModel):
+    ## Creates a new cloud print job status model.
+    #  \param assigned_to: The name of the printer this job is assigned to while being queued.
+    #  \param configuration: The required print core configurations of this print job.
+    #  \param constraints: Print job constraints object.
+    #  \param created_at: The timestamp when the job was created in Cura Connect.
+    #  \param force: Allow this job to be printed despite of mismatching configurations.
+    #  \param last_seen: The number of seconds since this job was checked.
+    #  \param machine_variant: The machine type that this job should be printed on.Coincides with the machine_type field
+    #       of the printer object.
+    #  \param name: The name of the print job. Usually the name of the .gcode file.
+    #  \param network_error_count: The number of errors encountered when requesting data for this print job.
+    #  \param owner: The name of the user who added the print job to Cura Connect.
+    #  \param printer_uuid: UUID of the printer that the job is currently printing on or assigned to.
+    #  \param started: Whether the job has started printing or not.
+    #  \param status: The status of the print job.
+    #  \param time_elapsed: The remaining printing time in seconds.
+    #  \param time_total: The total printing time in seconds.
+    #  \param uuid: UUID of this print job. Should be used for identification purposes.
+    def __init__(self, created_at: str, force: bool, machine_variant: str, name: str, started: bool, status: str,
+                 time_total: int, uuid: str,
+                 configuration: List[Union[Dict[str, any], CloudClusterPrinterConfiguration]],
+                 constraints: List[Union[Dict[str, any], CloudClusterPrintJobConstraints]],
+                 last_seen: Optional[float] = None, network_error_count: Optional[int] = None,
+                 owner: Optional[str] = None, printer_uuid: Optional[str] = None, time_elapsed: Optional[int] = None,
+                 assigned_to: Optional[str] = None, **kwargs) -> None:
+        self.assigned_to = assigned_to  # type: str
+        self.configuration = self.parseModels(CloudClusterPrinterConfiguration, configuration)
+        self.constraints = self.parseModels(CloudClusterPrintJobConstraints, constraints)
+        self.created_at = created_at
+        self.force = force
+        self.last_seen = last_seen
+        self.machine_variant = machine_variant
+        self.name = name
+        self.network_error_count = network_error_count
+        self.owner = owner
+        self.printer_uuid = printer_uuid
+        self.started = started
+        self.status = status
+        self.time_elapsed = time_elapsed
+        self.time_total = time_total
+        self.uuid = uuid
+        super().__init__(**kwargs)
+
+    ## Creates an UM3 print job output model based on this cloud cluster print job.
+    #  \param printer: The output model of the printer
+    def createOutputModel(self, controller: CloudOutputController) -> UM3PrintJobOutputModel:
+        model = UM3PrintJobOutputModel(controller, self.uuid, self.name)
+        self.updateOutputModel(model)
+
+        return model
+
+    ## Creates a new configuration model
+    def _createConfigurationModel(self) -> ConfigurationModel:
+        extruders = [extruder.createConfigurationModel() for extruder in self.configuration or ()]
+        configuration = ConfigurationModel()
+        configuration.setExtruderConfigurations(extruders)
+        return configuration
+
+    ## Updates an UM3 print job output model based on this cloud cluster print job.
+    #  \param model: The model to update.
+    def updateOutputModel(self, model: UM3PrintJobOutputModel) -> None:
+        # TODO: Add `compatible_machine_families` to the cloud, than add model.setCompatibleMachineFamilies()
+        # TODO: Add `impediments_to_printing` to the cloud, see ClusterUM3OutputDevice._updatePrintJob
+        # TODO: Use model.updateConfigurationChanges, see ClusterUM3OutputDevice#_createConfigurationChanges
+        model.updateConfiguration(self._createConfigurationModel())
+        model.updateTimeTotal(self.time_total)
+        model.updateTimeElapsed(self.time_elapsed)
+        model.updateOwner(self.owner)
+        model.updateState(self.status)

+ 0 - 49
plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinter.py

@@ -1,49 +0,0 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-from typing import List
-
-from cura.PrinterOutput.ConfigurationModel import ConfigurationModel
-from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
-from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
-from .CloudClusterPrinterConfiguration import CloudClusterPrinterConfiguration
-from .BaseCloudModel import BaseCloudModel
-
-
-##  Class representing a cluster printer
-class CloudClusterPrinter(BaseCloudModel):
-    def __init__(self, **kwargs) -> None:
-        self.configuration = []  # type: List[CloudClusterPrinterConfiguration]
-        self.enabled = None  # type: str
-        self.firmware_version = None  # type: str
-        self.friendly_name = None  # type: str
-        self.ip_address = None  # type: str
-        self.machine_variant = None  # type: str
-        self.status = None  # type: str
-        self.unique_name = None  # type: str
-        self.uuid = None  # type: str
-        super().__init__(**kwargs)
-
-        self.configuration = [CloudClusterPrinterConfiguration(**c)
-                              if isinstance(c, dict) else c for c in self.configuration]
-
-    ## Creates a new output model.
-    #  \param controller - The controller of the model.
-    def createOutputModel(self, controller: PrinterOutputController) -> PrinterOutputModel:
-        model = PrinterOutputModel(controller, len(self.configuration), firmware_version = self.firmware_version)
-        self.updateOutputModel(model)
-        return model
-
-    ## Updates the given output model.
-    #  \param model - The output model to update.
-    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")
-
-        for configuration, extruder_output, extruder_config in \
-                zip(self.configuration, model.extruders, model.printerConfiguration.extruderConfigurations):
-            configuration.updateOutputModel(extruder_output)
-            configuration.updateConfigurationModel(extruder_config)
-
-        pass

+ 15 - 8
plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfiguration.py

@@ -1,5 +1,7 @@
 # Copyright (c) 2018 Ultimaker B.V.
 # Cura is released under the terms of the LGPLv3 or higher.
+from typing import Union, Dict, Optional
+
 from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel
 from cura.PrinterOutput.ExtruderOutputModel import ExtruderOutputModel
 from .CloudClusterPrinterConfigurationMaterial import CloudClusterPrinterConfigurationMaterial
@@ -7,17 +9,22 @@ from .BaseCloudModel import BaseCloudModel
 
 
 ##  Class representing a cloud cluster printer configuration
+#  Spec: https://api-staging.ultimaker.com/connect/v1/spec
 class CloudClusterPrinterConfiguration(BaseCloudModel):
-    def __init__(self, **kwargs) -> None:
-        self.extruder_index = None  # type: int
-        self.material = None  # type: CloudClusterPrinterConfigurationMaterial
-        self.nozzle_diameter = None  # type: str
-        self.print_core_id = None  # type: str
+    ## Creates a new cloud cluster printer configuration object
+    #  \param extruder_index: The position of the extruder on the machine as list index. Numbered from left to right.
+    #  \param material: The material of a configuration object in a cluster printer. May be in a dict or an object.
+    #  \param nozzle_diameter: The diameter of the print core at this position in millimeters, e.g. '0.4'.
+    #  \param print_core_id: The type of print core inserted at this position, e.g. 'AA 0.4'.
+    def __init__(self, extruder_index: int,
+                 material: Union[None, Dict[str, any], CloudClusterPrinterConfigurationMaterial],
+                 nozzle_diameter: Optional[str] = None, print_core_id: Optional[str] = None, **kwargs) -> None:
+        self.extruder_index = extruder_index
+        self.material = self.parseModel(CloudClusterPrinterConfigurationMaterial, material)
+        self.nozzle_diameter = nozzle_diameter
+        self.print_core_id = print_core_id
         super().__init__(**kwargs)
 
-        if isinstance(self.material, dict):
-            self.material = CloudClusterPrinterConfigurationMaterial(**self.material)
-
     ## Updates the given output model.
     #  \param model - The output model to update.
     def updateOutputModel(self, model: ExtruderOutputModel) -> None:

Some files were not shown because too many files changed in this diff