예제 #1
0
파일: system.py 프로젝트: pamxy/AstroBox
	def manufacturerPackage(self, data ,sendMessage):
		manPackage = manufacturerPkgManager()
		result = {}

		if data:
			if "parameter" in data:
				if data['parameter'] == "strings":
					lang = "en"
					if "language" in data:
						lang = data['language']
					# Get strings from passed keys
					if "keys" in data:
						keys = data["keys"]
						for k in keys:
							result[k]= manPackage.getString(k,lang)
					# Get all the strings if no keys passed
					else:
						strings = manPackage.data.get("strings")
						for s in strings:
							result[s]= manPackage.getString(s,lang)
				else:
					result = manPackage.data.get(data["parameter"])
		else:
			result = manPackage.data

		sendMessage(result)
예제 #2
0
	def _constructSrcChain(self):
		self.__videoSourceElement = Gst.ElementFactory.make('v4l2src', 'video_source')
		self.__videoSourceElement.set_property("device", self._device)

		self.__videoSourceCaps = Gst.ElementFactory.make("capsfilter", "caps_filter")
		self.__videoSourceCaps.set_property("caps", Gst.Caps.from_string(self._getVideoSourceCaps()))

		#Add Elements to the pipeline
		self._bin.add(self.__videoSourceElement)
		self._bin.add(self.__videoSourceCaps)

		self.__videoSourceElement.link(self.__videoSourceCaps)

		width, height = self._size

		#check if we need to rotate the video
		if self._rotation == 0:
			lastLink = self.__videoSourceCaps

		else:
			if self._rotation in [1,3]:
				#dimentions are flipped
				height, width = self._size

			self.__videoflipElement = Gst.ElementFactory.make('videoflip', 'videoflip')
			self.__videoflipElement.set_property("method", self._rotation)

			self._bin.add(self.__videoflipElement)
			self.__videoSourceCaps.link(self.__videoflipElement)

			lastLink = self.__videoflipElement

		mfWatermark = manufacturerPkgManager().video_watermark

		if mfWatermark is False: #There is no watermark
			return lastLink

		else: # We need to setup a watermark
			logoHeight = round(height * self.LOGO_HEIGHT_PERCENT)
			logoWidth = round(logoHeight / self.LOGO_ASPECT_RATIO)

			# ASTROPRINT'S LOGO FROM DOWN RIGHT CORNER
			self.__videoLogoElement = Gst.ElementFactory.make('gdkpixbufoverlay', 'logo_overlay')

			if mfWatermark is None: # Use AstroPrint's default
				self.__videoLogoElement.set_property('location', '/AstroBox/src/astroprint/static/img/astroprint_logo.png')
			else:
				self.__videoLogoElement.set_property('location', '/AstroBox/src/astroprint/static/img/variant/%s' % mfWatermark)

			self.__videoLogoElement.set_property('overlay-width', logoWidth)
			self.__videoLogoElement.set_property('overlay-height', logoHeight)
			self.__videoLogoElement.set_property('offset-x', width - ( logoWidth + 10 ) )
			self.__videoLogoElement.set_property('offset-y', height - ( logoHeight + 5 ) )

			self._bin.add(self.__videoLogoElement)

			lastLink.link(self.__videoLogoElement)

		return self.__videoLogoElement
예제 #3
0
파일: __init__.py 프로젝트: pamxy/AstroBox
	def savedBaudrate(self):
		mf = manufacturerPkgManager()
		baudrate = None

		if mf.variant['printer_profile_edit']:
			baudrate = settings().getInt(["serial", "baudrate"])

		if baudrate is None:
			baudrate = mf.printerConnection['baudrate']

		return baudrate
예제 #4
0
파일: __init__.py 프로젝트: pamxy/AstroBox
	def savedPort(self):
		mf = manufacturerPkgManager()
		port = None

		if mf.variant['printer_profile_edit']:
			port = settings().get(["serial", "port"])

		if port is None:
			port = mf.printerConnection['port']

		return port
예제 #5
0
	def savedBaudrate(self):
		mf = manufacturerPkgManager()
		baudrate = None

		if mf.variant['printer_profile_edit']:
			baudrate = settings().getInt(["serial", "baudrate"])

		if baudrate is None:
			baudrate = mf.printerConnection['baudrate']

		return baudrate
예제 #6
0
	def savedPort(self):
		mf = manufacturerPkgManager()
		port = None

		if mf.variant['printer_profile_edit']:
			port = settings().get(["serial", "port"])

		if port is None:
			port = mf.printerConnection['port']

		return port
예제 #7
0
	def __init__(self):
		self._eventManager = eventManager()

		self.logger = logging.getLogger(__name__)

		self.mfDefinition = manufacturerPkgManager()
		self.softwareMgr = softwareManager()

		# upnp/ssdp
		self._ssdp_monitor_active = False
		self._ssdp_monitor_thread = None
		self._ssdp_notify_timeout = 10
		self._ssdp_last_notify = 0
		self._ssdp_last_unregister = 0

		# SSDP
		if networkManager().isOnline():
			self._ssdp_register()

		self._eventManager.subscribe(Events.NETWORK_STATUS, self._onNetworkStateChanged)
예제 #8
0
    def __init__(self):
        self._eventManager = eventManager()

        self.logger = logging.getLogger(__name__)

        self.mfDefinition = manufacturerPkgManager()
        self.softwareMgr = softwareManager()

        # upnp/ssdp
        self._ssdp_monitor_active = False
        self._ssdp_monitor_thread = None
        self._ssdp_notify_timeout = 10
        self._ssdp_last_notify = 0
        self._ssdp_last_unregister = 0

        # SSDP
        if networkManager().isOnline():
            self._ssdp_register()

        self._eventManager.subscribe(Events.NETWORK_STATUS,
                                     self._onNetworkStateChanged)
예제 #9
0
	def __init__(self):
		self._settings = settings()

		configDir = self._settings.getConfigFolder()

		self._infoFile = "%s/printer-profile.yaml" % configDir
		self._logger = logging.getLogger(__name__)
		self.data = {
			'driver': "marlin",
			'plugin': None,
			'extruder_count': 1,
			'max_nozzle_temp': 280,
			'max_bed_temp': 140,
			'heated_bed': True,
			'cancel_gcode': ['G28 X0 Y0'],
			'invert_z': False,
			'invert_x': False,
			'invert_y': False,
			'printer_model': {
				'id': None,
				'name': None
			},
			'temp_presets' : [
					{ 'id' : "3e0fc9b398234f2f871310c1998aa000",
					'name' : "PLA",
					'nozzle_temp' : 220,
					'bed_temp' : 40},
				 	{'id' : "2cc9df599f3e4292b379913f4940c000s",
					'name': "ABS",
					'nozzle_temp': 230,
					'bed_temp' : 80}
			],
			'last_presets_used' : [
			]
		}

		config = None
		if not os.path.isfile(self._infoFile):
			factoryFile = "%s/printer-profile.factory" % configDir

			if os.path.isfile(factoryFile):
				with open(factoryFile, "r") as f:
					config = yaml.safe_load(f)

			#overlay manufactuer definition of printer profile
			if not config:
				config = {}

			mfDefinition = manufacturerPkgManager().printerProfile
			for k in mfDefinition.keys():
				v = mfDefinition[k]
				if v is not None:
					config[k] = v

			if config:
				merge_dict(self.data, config)

			self.save()

		else:
			with open(self._infoFile, "r") as f:
				config = yaml.safe_load(f)

			if config:
				merge_dict(self.data, config)
예제 #10
0
    def __init__(self):
        self._settings = settings()

        configDir = self._settings.getConfigFolder()

        self._infoFile = "%s/printer-profile.yaml" % configDir
        self._logger = logging.getLogger(__name__)
        self.data = {
            'last_definition_version': None,
            'driver': "marlin",
            'plugin': None,
            'extruder_count': 1,
            'check_clear_bed': True,
            'max_nozzle_temp': 280,
            'max_bed_temp': 140,
            'heated_bed': True,
            'cancel_gcode': ['G28 X0 Y0'],
            'invert_z': False,
            'invert_x': False,
            'invert_y': False,
            'manufacturer_id': None,
            'printer_model': {
                'id': None,
                'name': None
            },
            'filament': {
                'color': None,
                'name': None
            },
            'temp_presets': {
                '3e0fc9b398234f2f871310c1998aa000': {
                    'name': "PLA",
                    'nozzle_temp': 220,
                    'bed_temp': 40
                },
                '2cc9df599f3e4292b379913f4940c000': {
                    'name': "ABS",
                    'nozzle_temp': 230,
                    'bed_temp': 80
                },
            },
            'last_presets_used': {}
        }
        config = None

        if not os.path.isfile(self._infoFile):
            factoryFile = "%s/printer-profile.factory" % configDir

            if os.path.isfile(factoryFile):
                with open(factoryFile, "r") as f:
                    config = yaml.safe_load(f)

            if not config:
                config = {}

            if config:
                merge_dict(self.data, config)

            self.save()

        else:
            with open(self._infoFile, "r") as f:
                config = yaml.safe_load(f)

            if config:
                # remove old array formats
                if 'temp_presets' in config and isinstance(
                        config['temp_presets'], list) == True:
                    del config['temp_presets']
                if 'last_presets_used' in config and isinstance(
                        config['last_presets_used'], list) == True:
                    del config['last_presets_used']

                merge_dict(self.data, config)

        # check manufacturer definition update
        version = manufacturerPkgManager().version
        mfDefProfile = manufacturerPkgManager().printerProfile
        mfConfig = {}
        if version != self.data['last_definition_version']:
            self._logger.info(
                "A New update for manufacturer package has been found: %s" %
                (version))

            mfDefVariant = manufacturerPkgManager().variant
            for k in mfDefProfile.keys():
                v = mfDefProfile[k]
                if v is not None:
                    mfConfig[k] = v
                    if k == "temp_presets":
                        for mfPresetID in v.keys():
                            p = mfConfig[k][mfPresetID]

                            if self.data[k] is not None:
                                dKey = self._checkPresetExisted(k, mfPresetID)
                                if dKey:
                                    # if manufacturer updates its preset and user it's not allowed to edit => REPLACE
                                    if mfPresetID and mfDefVariant[
                                            'temperature_presets_edit'] is False:
                                        mfConfig[k][dKey] = {
                                            "manufacturer_id": mfPresetID,
                                            "name": p['name'],
                                            "bed_temp": p['bed_temp'],
                                            "nozzle_temp": p['nozzle_temp'],
                                        }
                                        del mfConfig[k][mfPresetID]

                                    # if manfufacturer updates its preset and user it's allowed to edit => check if different ID. This way is user has edited a preset, and manufacturer update it after using same ID, it wont be overwritten but ignored it.
                                    else:
                                        matchedId = ""
                                        for i in self.data['temp_presets']:
                                            if "manufacturer_id" in self.data[
                                                    'temp_presets'][i]:
                                                if self.data['temp_presets'][i][
                                                        'manufacturer_id'] == mfPresetID:
                                                    matchedId = mfPresetID

                                        if not matchedId:
                                            mfConfig[k][dKey] = {
                                                "manufacturer_id": mfPresetID,
                                                "name": p['name'],
                                                "bed_temp": p['bed_temp'],
                                                "nozzle_temp":
                                                p['nozzle_temp'],
                                            }
                                        else:
                                            del mfConfig[k][mfPresetID]

                                else:
                                    # Add new attribute object with correct format
                                    mfConfig[k][uuid.uuid4().hex] = {
                                        "manufacturer_id": mfPresetID,
                                        "name": p['name'],
                                        "bed_temp": p['bed_temp'],
                                        "nozzle_temp": p['nozzle_temp'],
                                    }
                                    del mfConfig[k][mfPresetID]
                            else:
                                mfConfig[k][uuid.uuid4().hex] = {
                                    "manufacturer_id": mfPresetID,
                                    "name": p['name'],
                                    "bed_temp": p['bed_temp'],
                                    "nozzle_temp": p['nozzle_temp'],
                                }
                                del mfConfig[k][mfPresetID]
            # update version number
            self.data['last_definition_version'] = version

        if version or mfConfig:
            if "temp_presets" in mfConfig.keys() or version:
                self._removeDefaultTempPresets()
            merge_dict(self.data, mfConfig)
        self.save()
예제 #11
0
class Server():
    def __init__(self,
                 configfile=None,
                 basedir=None,
                 host="0.0.0.0",
                 port=5000,
                 debug=False,
                 allowRoot=False,
                 logConf=None):
        self._configfile = configfile
        self._basedir = basedir
        self._host = host
        self._port = port
        self._debug = debug
        self._allowRoot = allowRoot
        self._logConf = logConf
        self._ioLoop = None

    def stop(self):
        if self._ioLoop:
            self._ioLoop.stop()
            self._ioLoop = None

    def run(self):
        if not self._allowRoot:
            self._checkForRoot()

        global userManager
        global eventManager
        global loginManager
        global debug
        global softwareManager
        global discoveryManager
        global VERSION
        global UI_API_KEY

        from tornado.wsgi import WSGIContainer
        from tornado.httpserver import HTTPServer
        from tornado.ioloop import IOLoop
        from tornado.web import Application, FallbackHandler

        from astroprint.printfiles.watchdogs import UploadCleanupWatchdogHandler

        debug = self._debug

        # first initialize the settings singleton and make sure it uses given configfile and basedir if available
        self._initSettings(self._configfile, self._basedir)
        s = settings()

        if not s.getBoolean(['api', 'regenerate']) and s.getString(
            ['api', 'key']):
            UI_API_KEY = s.getString(['api', 'key'])
        else:
            UI_API_KEY = ''.join('%02X' % ord(z) for z in uuid.uuid4().bytes)

        # then initialize logging
        self._initLogging(self._debug, self._logConf)
        logger = logging.getLogger(__name__)

        if s.getBoolean(["accessControl", "enabled"]):
            userManagerName = s.get(["accessControl", "userManager"])
            try:
                clazz = util.getClass(userManagerName)
                userManager = clazz()
            except AttributeError, e:
                logger.exception(
                    "Could not instantiate user manager %s, will run with accessControl disabled!"
                    % userManagerName)

        softwareManager = swManager()
        VERSION = softwareManager.versionString

        logger.info("Starting AstroBox (%s) - Commit (%s)" %
                    (VERSION, softwareManager.commit))

        from astroprint.migration import migrateSettings
        migrateSettings()

        manufacturerPkgManager()
        ppm = printerProfileManager()
        pluginManager().loadPlugins()

        eventManager = events.eventManager()
        printer = printerManager(ppm.data['driver'])

        #Start some of the managers here to make sure there are no thread collisions
        from astroprint.network.manager import networkManager
        from astroprint.boxrouter import boxrouterManager

        networkManager()
        boxrouterManager()

        # configure timelapse
        #octoprint.timelapse.configureTimelapse()

        app.wsgi_app = ReverseProxied(app.wsgi_app)

        app.secret_key = boxrouterManager().boxId
        loginManager = LoginManager()
        loginManager.session_protection = "strong"
        loginManager.user_callback = load_user
        if userManager is None:
            loginManager.anonymous_user = users.DummyUser
            principals.identity_loaders.appendleft(users.dummy_identity_loader)
        loginManager.init_app(app)

        # setup command triggers
        events.CommandTrigger(printer)
        if self._debug:
            events.DebugEventListener()

        if networkManager().isOnline():
            softwareManager.checkForcedUpdate()

        if self._host is None:
            self._host = s.get(["server", "host"])
        if self._port is None:
            self._port = s.getInt(["server", "port"])

        app.debug = self._debug

        from octoprint.server.api import api

        app.register_blueprint(api, url_prefix="/api")

        boxrouterManager(
        )  # Makes sure the singleton is created here. It doesn't need to be stored
        self._router = SockJSRouter(self._createSocketConnection, "/sockjs")

        discoveryManager = DiscoveryManager()

        externalDriveManager()

        def access_validation_factory(validator):
            """
			Creates an access validation wrapper using the supplied validator.

			:param validator: the access validator to use inside the validation wrapper
			:return: an access validation wrapper taking a request as parameter and performing the request validation
			"""
            def f(request):
                """
				Creates a custom wsgi and Flask request context in order to be able to process user information
				stored in the current session.

				:param request: The Tornado request for which to create the environment and context
				"""
                wsgi_environ = tornado.wsgi.WSGIContainer.environ(request)
                with app.request_context(wsgi_environ):
                    app.session_interface.open_session(app, request)
                    loginManager.reload_user()
                    validator(request)

            return f

        self._tornado_app = Application(self._router.urls + [
            #(r"/downloads/timelapse/([^/]*\.mpg)", LargeResponseHandler, {"path": s.getBaseFolder("timelapse"), "as_attachment": True}),
            (r"/downloads/files/local/([^/]*\.(gco|gcode))",
             LargeResponseHandler, {
                 "path": s.getBaseFolder("uploads"),
                 "as_attachment": True
             }),
            (r"/downloads/logs/([^/]*)", LargeResponseHandler, {
                "path": s.getBaseFolder("logs"),
                "as_attachment": True,
                "access_validation": access_validation_factory(admin_validator)
            }),
            #(r"/downloads/camera/current", UrlForwardHandler, {"url": s.get(["webcam", "snapshot"]), "as_attachment": True, "access_validation": access_validation_factory(user_validator)}),
            (r".*", FallbackHandler, {
                "fallback": WSGIContainer(app.wsgi_app)
            })
        ])
        self._server = HTTPServer(self._tornado_app,
                                  max_buffer_size=1048576 *
                                  s.getInt(['server', 'maxUploadSize']))
        self._server.listen(self._port, address=self._host)

        logger.info("Listening on http://%s:%d" % (self._host, self._port))

        eventManager.fire(events.Events.STARTUP)
        if s.getBoolean(["serial", "autoconnect"]):
            t = threading.Thread(target=printer.connect)
            t.daemon = True
            t.start()

        # start up watchdogs
        observer = Observer()
        observer.daemon = True
        observer.schedule(UploadCleanupWatchdogHandler(),
                          s.getBaseFolder("uploads"))
        observer.start()

        #Load additional Tasks
        additionalTasksManager()

        #Load maintenance menu
        maintenanceMenuManager()

        try:
            self._ioLoop = IOLoop.instance()
            self._ioLoop.start()

        except SystemExit:
            pass

        except:
            logger.fatal(
                "Please report this including the stacktrace below in AstroPrint's bugtracker. Thanks!"
            )
            logger.exception("Stacktrace follows:")

        finally:
            observer.stop()
            self.cleanup()
            logger.info('Cleanup complete')

        observer.join(1.0)
        logger.info('Good Bye!')
예제 #12
0
def index():
    s = settings()
    loggedUsername = s.get(["cloudSlicer", "loggedUser"])
    publicKey = None

    if loggedUsername:
        user = userManager.findUser(loggedUsername)
        if user:
            publicKey = user.publicKey

    if (s.getBoolean(["server", "firstRun"])):
        swm = swManager()

        # we need to get the user to sign into their AstroPrint account
        return render_template("setup.jinja2",
                               debug=debug,
                               uiApiKey=UI_API_KEY,
                               version=VERSION,
                               commit=swm.commit,
                               astroboxName=networkManager().getHostname(),
                               checkSoftware=swm.shouldCheckForNew,
                               settings=s,
                               wsToken=create_ws_token(publicKey),
                               mfDefinition=manufacturerPkgManager())

    elif softwareManager.status != 'idle' or softwareManager.forceUpdateInfo:
        return render_template(
            "updating.jinja2",
            uiApiKey=UI_API_KEY,
            forceUpdateInfo=softwareManager.forceUpdateInfo,
            releases=softwareManager.updatingReleases
            or [softwareManager.forceUpdateInfo['id']],
            lastCompletionPercent=softwareManager.lastCompletionPercent,
            lastMessage=softwareManager.lastMessage,
            astroboxName=networkManager().getHostname(),
            wsToken=create_ws_token(publicKey),
            status=softwareManager.status,
            mfDefinition=manufacturerPkgManager())

    elif loggedUsername and (current_user is None
                             or not current_user.is_authenticated
                             or current_user.get_id() != loggedUsername):
        if current_user.is_authenticated:
            logout_user()
        return render_template("locked.jinja2",
                               username=loggedUsername,
                               uiApiKey=UI_API_KEY,
                               astroboxName=networkManager().getHostname(),
                               mfDefinition=manufacturerPkgManager())

    else:
        pm = printerManager()
        nm = networkManager()
        swm = swManager()
        cm = cameraManager()
        mmm = maintenanceMenuManager()

        paused = pm.isPaused()
        printing = pm.isPrinting()
        online = nm.isOnline()

        return render_template(
            "app.jinja2",
            user_email=loggedUsername,
            show_bad_shutdown=swm.wasBadShutdown and not swm.badShutdownShown,
            version=VERSION,
            commit=swm.commit,
            printing=printing,
            paused=paused,
            online=online,
            print_capture=cm.timelapseInfo if printing or paused else None,
            printer_profile=printerProfileManager().data,
            uiApiKey=UI_API_KEY,
            astroboxName=nm.getHostname(),
            checkSoftware=swm.shouldCheckForNew,
            serialLogActive=s.getBoolean(['serial', 'log']),
            additionalTasks=True,
            maintenanceMenu=True,
            cameraManager=cm.name,
            wsToken=create_ws_token(publicKey),
            mfDefinition=manufacturerPkgManager())
예제 #13
0
	def __init__(self):
		self._settings = settings()

		configDir = self._settings.getConfigFolder()

		self._infoFile = "%s/printer-profile.yaml" % configDir
		self._logger = logging.getLogger(__name__)
		self.data = {
			'last_definition_version': None,
			'driver': "marlin",
			'plugin': None,
			'extruder_count': 1,
			'max_nozzle_temp': 280,
			'max_bed_temp': 140,
			'heated_bed': True,
			'cancel_gcode': ['G28 X0 Y0'],
			'invert_z': False,
			'invert_x': False,
			'invert_y': False,
			'printer_model': {
				'id': None,
				'name': None
			},
			'filament': {
				'color': None,
				'name': None
			},
			'temp_presets' : {
				'3e0fc9b398234f2f871310c1998aa000': {
					'name' : "PLA",
					'nozzle_temp' : 220,
					'bed_temp' : 40
				},
				'2cc9df599f3e4292b379913f4940c000': {
					'name' : "ABS",
					'nozzle_temp' : 230,
					'bed_temp' : 80
				},
			},
			'last_presets_used' : {}
		}
		config = None

		if not os.path.isfile(self._infoFile):
			factoryFile = "%s/printer-profile.factory" % configDir

			if os.path.isfile(factoryFile):
				with open(factoryFile, "r") as f:
					config = yaml.safe_load(f)

			if not config:
				config = {}

			if config:
				merge_dict(self.data, config)

			self.save()

		else:
			with open(self._infoFile, "r") as f:
				config = yaml.safe_load(f)

			if config:
				# remove old array formats
				if 'temp_presets' in config and isinstance(config['temp_presets'], list) == True:
					del config['temp_presets']
				if 'last_presets_used'in config and isinstance(config['last_presets_used'], list) == True:
					del config['last_presets_used']

				merge_dict(self.data, config)

		# check manufacturer definition update
		version = manufacturerPkgManager().version
		mfDefProfile = manufacturerPkgManager().printerProfile
		mfConfig = {}
		if version != self.data['last_definition_version']:
			self._logger.info("A New update for manufacturer package has been found: %s" % (version))

			mfDefVariant = manufacturerPkgManager().variant
			for k in mfDefProfile.keys():
				v = mfDefProfile[k]
				if v is not None:
					mfConfig[k] = v
					if k == "temp_presets":
						for mfPresetID in v.keys():
							p = mfConfig[k][mfPresetID]

							if self.data[k] is not None:
								dKey = self._checkPresetExisted(k, mfPresetID)
								if dKey:
									# if manufacturer updates its preset and user it's not allowed to edit => REPLACE
									if mfPresetID and mfDefVariant['temperature_presets_edit'] is False:
										mfConfig[k][dKey] = {
											"manufacturer_id": mfPresetID,
											"name": p['name'],
											"bed_temp": p['bed_temp'],
											"nozzle_temp": p['nozzle_temp'],
										}
										del mfConfig[k][mfPresetID]

									# if manfufacturer updates its preset and user it's allowed to edit => check if different ID. This way is user has edited a preset, and manufacturer update it after using same ID, it wont be overwritten but ignored it.
									else:
										matchedId = ""
										for i in self.data['temp_presets']:
											if "manufacturer_id" in self.data['temp_presets'][i]:
												if self.data['temp_presets'][i]['manufacturer_id'] == mfPresetID:
													matchedId = mfPresetID

										if not matchedId:
											mfConfig[k][dKey] = {
												"manufacturer_id": mfPresetID,
												"name": p['name'],
												"bed_temp": p['bed_temp'],
												"nozzle_temp": p['nozzle_temp'],
											}
										else:
											del mfConfig[k][mfPresetID]

								else:
									# Add new attribute object with correct format
									mfConfig[k][uuid.uuid4().hex] = {
										"manufacturer_id": mfPresetID,
										"name": p['name'],
										"bed_temp": p['bed_temp'],
										"nozzle_temp": p['nozzle_temp'],
									}
									del mfConfig[k][mfPresetID]
							else:
								mfConfig[k][uuid.uuid4().hex] = {
									"manufacturer_id": mfPresetID,
									"name": p['name'],
									"bed_temp": p['bed_temp'],
									"nozzle_temp": p['nozzle_temp'],
								}
								del mfConfig[k][mfPresetID]
			# update version number
			self.data['last_definition_version'] = version

		if version or mfConfig:
			if "temp_presets" in mfConfig.keys() or version:
				self._removeDefaultTempPresets()
			merge_dict(self.data, mfConfig)
		self.save()