Machines.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. # Copyright (c) 2019 Ultimaker B.V.
  2. # Cura is released under the terms of the LGPLv3 or higher.
  3. from typing import Optional, Dict, List, TYPE_CHECKING, Any
  4. from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot, pyqtProperty
  5. from UM.i18n import i18nCatalog
  6. from UM.Logger import Logger
  7. if TYPE_CHECKING:
  8. from cura.CuraApplication import CuraApplication
  9. from cura.PrinterOutput.PrinterOutputDevice import PrinterOutputDevice
  10. i18n_catalog = i18nCatalog("cura")
  11. ## The account API provides a version-proof bridge to use Ultimaker Accounts
  12. #
  13. # Usage:
  14. # ```
  15. # from cura.API import CuraAPI
  16. # api = CuraAPI()
  17. # api.machines.addOutputDeviceToCurrentMachine()
  18. # ```
  19. ## Since Cura doesn't have a machine class, we're going to make a fake one to make our lives a
  20. # little bit easier.
  21. class Machine():
  22. def __init__(self) -> None:
  23. self.hostname = "" # type: str
  24. self.group_id = "" # type: str
  25. self.group_name = "" # type: str
  26. self.um_network_key = "" # type: str
  27. self.configuration = {} # type: Dict[str, Any]
  28. self.connection_types = [] # type: List[int]
  29. class Machines(QObject):
  30. def __init__(self, application: "CuraApplication", parent = None) -> None:
  31. super().__init__(parent)
  32. self._application = application
  33. @pyqtSlot(result="QVariantMap")
  34. def getCurrentMachine(self) -> Machine:
  35. fake_machine = Machine() # type: Machine
  36. global_stack = self._application.getGlobalContainerStack()
  37. if global_stack:
  38. metadata = global_stack.getMetaData()
  39. if "group_id" in metadata:
  40. fake_machine.group_id = global_stack.getMetaDataEntry("group_id")
  41. if "group_name" in metadata:
  42. fake_machine.group_name = global_stack.getMetaDataEntry("group_name")
  43. if "um_network_key" in metadata:
  44. fake_machine.um_network_key = global_stack.getMetaDataEntry("um_network_key")
  45. fake_machine.connection_types = global_stack.configuredConnectionTypes
  46. return fake_machine
  47. ## Set the current machine's friendy name.
  48. # This is the same as "group name" since we use "group" and "current machine" interchangeably.
  49. # TODO: Maybe make this "friendly name" to distinguish from "hostname"?
  50. @pyqtSlot(str)
  51. def setCurrentMachineGroupName(self, group_name: str) -> None:
  52. Logger.log("d", "Attempting to set the group name of the active machine to %s", group_name)
  53. global_stack = self._application.getGlobalContainerStack()
  54. if global_stack:
  55. # Update a GlobalStacks in the same group with the new group name.
  56. group_id = global_stack.getMetaDataEntry("group_id")
  57. machine_manager = self._application.getMachineManager()
  58. for machine in machine_manager.getMachinesInGroup(group_id):
  59. machine.setMetaDataEntry("group_name", group_name)
  60. # Set the default value for "hidden", which is used when you have a group with multiple types of printers
  61. global_stack.setMetaDataEntry("hidden", False)
  62. ## Set the current machine's configuration from an (optional) output device.
  63. # If no output device is given, the first one available on the machine will be used.
  64. # NOTE: Group and machine are used interchangeably.
  65. # NOTE: This doesn't seem to be used anywhere. Maybe delete?
  66. @pyqtSlot(QObject)
  67. def updateCurrentMachineConfiguration(self, output_device: Optional["PrinterOutputDevice"]) -> None:
  68. if output_device is None:
  69. machine_manager = self._application.getMachineManager()
  70. output_device = machine_manager.printerOutputDevices[0]
  71. hotend_ids = output_device.hotendIds
  72. for index in range(len(hotend_ids)):
  73. output_device.hotendIdChanged.emit(index, hotend_ids[index])
  74. material_ids = output_device.materialIds
  75. for index in range(len(material_ids)):
  76. output_device.materialIdChanged.emit(index, material_ids[index])
  77. ## Add an output device to the current machine.
  78. # In practice, this means:
  79. # - Setting the output device's network key in the current machine's metadata
  80. # - Adding the output device's connection type to the current machine's configured connection
  81. # types.
  82. # TODO: CHANGE TO HOSTNAME
  83. @pyqtSlot(QObject)
  84. def addOutputDeviceToCurrentMachine(self, output_device: "PrinterOutputDevice") -> None:
  85. if not output_device:
  86. return
  87. Logger.log("d",
  88. "Attempting to set the network key of the active machine to %s",
  89. output_device.key)
  90. global_stack = self._application.getGlobalContainerStack()
  91. if not global_stack:
  92. return
  93. metadata = global_stack.getMetaData()
  94. # Global stack already had a connection, but it's changed.
  95. if "um_network_key" in metadata:
  96. old_network_key = metadata["um_network_key"]
  97. # Since we might have a bunch of hidden stacks, we also need to change it there.
  98. metadata_filter = {"um_network_key": old_network_key}
  99. containers = self._application.getContainerRegistry().findContainerStacks(
  100. type = "machine", **metadata_filter)
  101. for container in containers:
  102. container.setMetaDataEntry("um_network_key", output_device.key)
  103. # Delete old authentication data.
  104. Logger.log("d", "Removing old authentication id %s for device %s",
  105. global_stack.getMetaDataEntry("network_authentication_id", None),
  106. output_device.key)
  107. container.removeMetaDataEntry("network_authentication_id")
  108. container.removeMetaDataEntry("network_authentication_key")
  109. # Ensure that these containers do know that they are configured for the given
  110. # connection type (can be more than one type; e.g. LAN & Cloud)
  111. container.addConfiguredConnectionType(output_device.connectionType.value)
  112. else: # Global stack didn't have a connection yet, configure it.
  113. global_stack.setMetaDataEntry("um_network_key", output_device.key)
  114. global_stack.addConfiguredConnectionType(output_device.connectionType.value)
  115. return None