def _ensure_valid_profile(self, profile): # ensure all keys are present if not dict_contains_keys(self.default, profile): return False # conversion helper def convert_value(profile, path, converter): value = profile for part in path[:-1]: if not isinstance(value, dict) or not part in value: raise RuntimeError("%s is not contained in profile" % ".".join(path)) value = value[part] if not isinstance(value, dict) or not path[-1] in value: raise RuntimeError("%s is not contained in profile" % ".".join(path)) value[path[-1]] = converter(value[path[-1]]) # convert ints for path in (("extruder", "count"), ("axes", "x", "speed"), ("axes", "y", "speed"), ("axes", "z", "speed")): try: convert_value(profile, path, int) except: return False # convert floats for path in (("volume", "width"), ("volume", "depth"), ("volume", "height"), ("extruder", "nozzleDiameter")): try: convert_value(profile, path, float) except: return False # convert booleans for path in (("axes", "x", "inverted"), ("axes", "y", "inverted"), ("axes", "z", "inverted")): try: convert_value(profile, path, bool) except: return False # validate form factor if not profile["volume"]["formFactor"] in BedTypes.values(): return False # validate offsets offsets = [] for offset in profile["extruder"]["offsets"]: if not len(offset) == 2: return False x_offset, y_offset = offset try: offsets.append((float(x_offset), float(y_offset))) except: return False profile["extruder"]["offsets"] = offsets return profile
def _ensure_valid_profile(self, profile): # ensure all keys are present if not dict_contains_keys(self.default, profile): return False # conversion helper def convert_value(profile, path, converter): value = profile for part in path[:-1]: if not isinstance(value, dict) or not part in value: raise RuntimeError("%s is not contained in profile" % ".".join(path)) value = value[part] if not isinstance(value, dict) or not path[-1] in value: raise RuntimeError("%s is not contained in profile" % ".".join(path)) value[path[-1]] = converter(value[path[-1]]) # convert ints for path in (("axes", "x", "speed"), ("axes", "y", "speed"), ("axes", "z", "speed")): try: convert_value(profile, path, int) except: return False # convert floats for path in (("volume", "width"), ("volume", "depth"), ("volume", "height")): try: convert_value(profile, path, float) except: return False # convert booleans for path in (("axes", "x", "inverted"), ("axes", "y", "inverted"), ("axes", "z", "inverted")): try: convert_value(profile, path, bool) except: return False return profile
def _ensure_valid_profile(self, profile): # ensure all keys are present if not dict_contains_keys(self.default, profile): self._logger.warn( "Profile invalid, missing keys. Expected: {expected!r}. Actual: {actual!r}" .format(expected=self.default.keys(), actual=profile.keys())) return False # conversion helper def convert_value(profile, path, converter): value = profile for part in path[:-1]: if not isinstance(value, dict) or not part in value: raise RuntimeError("%s is not contained in profile" % ".".join(path)) value = value[part] if not isinstance(value, dict) or not path[-1] in value: raise RuntimeError("%s is not contained in profile" % ".".join(path)) value[path[-1]] = converter(value[path[-1]]) # convert ints for path in (("extruder", "count"), ("axes", "x", "speed"), ("axes", "y", "speed"), ("axes", "z", "speed")): try: convert_value(profile, path, int) except Exception as e: self._logger.warn( "Profile has invalid value for path {path!r}: {msg}". format(path=".".join(path), msg=str(e))) return False # convert floats for path in (("volume", "width"), ("volume", "depth"), ("volume", "height"), ("extruder", "nozzleDiameter")): try: convert_value(profile, path, float) except Exception as e: self._logger.warn( "Profile has invalid value for path {path!r}: {msg}". format(path=".".join(path), msg=str(e))) return False # convert booleans for path in (("axes", "x", "inverted"), ("axes", "y", "inverted"), ("axes", "z", "inverted"), ("extruder", "sharedNozzle")): try: convert_value(profile, path, bool) except Exception as e: self._logger.warn( "Profile has invalid value for path {path!r}: {msg}". format(path=".".join(path), msg=str(e))) return False # validate form factor if not profile["volume"]["formFactor"] in BedFormFactor.values(): self._logger.warn( "Profile has invalid value volume.formFactor: {formFactor}". format(formFactor=profile["volume"]["formFactor"])) return False # validate origin type if not profile["volume"]["origin"] in BedOrigin.values(): self._logger.warn( "Profile has invalid value in volume.origin: {origin}".format( origin=profile["volume"]["origin"])) return False # ensure origin and form factor combination is legal if profile["volume"][ "formFactor"] == BedFormFactor.CIRCULAR and not profile[ "volume"]["origin"] == BedOrigin.CENTER: profile["volume"]["origin"] = BedOrigin.CENTER # force width and depth of volume to be identical for circular beds, with width being the reference if profile["volume"]["formFactor"] == BedFormFactor.CIRCULAR: profile["volume"]["depth"] = profile["volume"]["width"] # if we have a custom bounding box, validate it if profile["volume"]["custom_box"] and isinstance( profile["volume"]["custom_box"], dict): if not len(profile["volume"]["custom_box"]): profile["volume"]["custom_box"] = False else: default_box = self._default_box_for_volume(profile["volume"]) for prop, limiter in (("x_min", min), ("y_min", min), ("z_min", min), ("x_max", max), ("y_max", max), ("z_max", max)): if prop not in profile["volume"]["custom_box"] or profile[ "volume"]["custom_box"][prop] is None: profile["volume"]["custom_box"][prop] = default_box[ prop] else: value = profile["volume"]["custom_box"][prop] try: value = limiter(float(value), default_box[prop]) profile["volume"]["custom_box"][prop] = value except: self._logger.warn( "Profile has invalid value in volume.custom_box.{}: {!r}" .format(prop, value)) return False # make sure we actually do have a custom box and not just the same values as the # default box for prop in profile["volume"]["custom_box"]: if profile["volume"]["custom_box"][prop] != default_box[ prop]: break else: # exactly the same as the default box, remove custom box profile["volume"]["custom_box"] = False # validate offsets offsets = [] for offset in profile["extruder"]["offsets"]: if not len(offset) == 2: self._logger.warn( "Profile has an invalid extruder.offsets entry: {entry!r}". format(entry=offset)) return False x_offset, y_offset = offset try: offsets.append((float(x_offset), float(y_offset))) except: self._logger.warn( "Profile has an extruder.offsets entry with non-float values: {entry!r}" .format(entry=offset)) return False profile["extruder"]["offsets"] = offsets return profile
def _ensure_valid_profile(self, profile): # ensure all keys are present if not dict_contains_keys(self.default, profile): self._logger.warn("Profile invalid, missing keys. Expected: {expected!r}. Actual: {actual!r}".format(expected=self.default.keys(), actual=profile.keys())) return False # conversion helper def convert_value(profile, path, converter): value = profile for part in path[:-1]: if not isinstance(value, dict) or not part in value: raise RuntimeError("%s is not contained in profile" % ".".join(path)) value = value[part] if not isinstance(value, dict) or not path[-1] in value: raise RuntimeError("%s is not contained in profile" % ".".join(path)) value[path[-1]] = converter(value[path[-1]]) # convert ints for path in (("extruder", "count"), ("axes", "x", "speed"), ("axes", "y", "speed"), ("axes", "z", "speed")): try: convert_value(profile, path, int) except Exception as e: self._logger.warn("Profile has invalid value for path {path!r}: {msg}".format(path=".".join(path), msg=str(e))) return False # convert floats for path in (("volume", "width"), ("volume", "depth"), ("volume", "height"), ("extruder", "nozzleDiameter")): try: convert_value(profile, path, float) except Exception as e: self._logger.warn("Profile has invalid value for path {path!r}: {msg}".format(path=".".join(path), msg=str(e))) return False # convert booleans for path in (("axes", "x", "inverted"), ("axes", "y", "inverted"), ("axes", "z", "inverted")): try: convert_value(profile, path, bool) except Exception as e: self._logger.warn("Profile has invalid value for path {path!r}: {msg}".format(path=".".join(path), msg=str(e))) return False # validate form factor if not profile["volume"]["formFactor"] in BedTypes.values(): self._logger.warn("Profile has invalid value volume.formFactor: {formFactor}".format(formFactor=profile["volume"]["formFactor"])) return False # validate origin type if not profile["volume"]["origin"] in BedOrigin.values(): self._logger.warn("Profile has invalid value in volume.origin: {origin}".format(origin=profile["volume"]["origin"])) return False # ensure origin and form factor combination is legal if profile["volume"]["formFactor"] == BedTypes.CIRCULAR and not profile["volume"]["origin"] == BedOrigin.CENTER: profile["volume"]["origin"] = BedOrigin.CENTER # validate offsets offsets = [] for offset in profile["extruder"]["offsets"]: if not len(offset) == 2: self._logger.warn("Profile has an invalid extruder.offsets entry: {entry!r}".format(entry=offset)) return False x_offset, y_offset = offset try: offsets.append((float(x_offset), float(y_offset))) except: self._logger.warn("Profile has an extruder.offsets entry with non-float values: {entry!r}".format(entry=offset)) return False profile["extruder"]["offsets"] = offsets return profile
def _ensure_valid_profile(self, profile): # ensure all keys are present if not dict_contains_keys(self.default, profile): self._logger.warn("Profile invalid, missing keys. Expected: {expected!r}. Actual: {actual!r}".format(expected=self.default.keys(), actual=profile.keys())) return False # conversion helper def convert_value(profile, path, converter): value = profile for part in path[:-1]: if not isinstance(value, dict) or not part in value: raise RuntimeError("%s is not contained in profile" % ".".join(path)) value = value[part] if not isinstance(value, dict) or not path[-1] in value: raise RuntimeError("%s is not contained in profile" % ".".join(path)) value[path[-1]] = converter(value[path[-1]]) # convert ints for path in (("extruder", "count"), ("axes", "x", "speed"), ("axes", "y", "speed"), ("axes", "z", "speed")): try: convert_value(profile, path, int) except Exception as e: self._logger.warn("Profile has invalid value for path {path!r}: {msg}".format(path=".".join(path), msg=str(e))) return False # convert floats for path in (("volume", "width"), ("volume", "depth"), ("volume", "height"), ("extruder", "nozzleDiameter")): try: convert_value(profile, path, float) except Exception as e: self._logger.warn("Profile has invalid value for path {path!r}: {msg}".format(path=".".join(path), msg=str(e))) return False # convert booleans for path in (("axes", "x", "inverted"), ("axes", "y", "inverted"), ("axes", "z", "inverted"), ("extruder", "sharedNozzle")): try: convert_value(profile, path, bool) except Exception as e: self._logger.warn("Profile has invalid value for path {path!r}: {msg}".format(path=".".join(path), msg=str(e))) return False # validate form factor if not profile["volume"]["formFactor"] in BedTypes.values(): self._logger.warn("Profile has invalid value volume.formFactor: {formFactor}".format(formFactor=profile["volume"]["formFactor"])) return False # validate origin type if not profile["volume"]["origin"] in BedOrigin.values(): self._logger.warn("Profile has invalid value in volume.origin: {origin}".format(origin=profile["volume"]["origin"])) return False # ensure origin and form factor combination is legal if profile["volume"]["formFactor"] == BedTypes.CIRCULAR and not profile["volume"]["origin"] == BedOrigin.CENTER: profile["volume"]["origin"] = BedOrigin.CENTER # force width and depth of volume to be identical for circular beds, with width being the reference if profile["volume"]["formFactor"] == BedTypes.CIRCULAR: profile["volume"]["depth"] = profile["volume"]["width"] # if we have a custom bounding box, validate it if profile["volume"]["custom_box"] and isinstance(profile["volume"]["custom_box"], dict): if not len(profile["volume"]["custom_box"]): profile["volume"]["custom_box"] = False else: default_box = self._default_box_for_volume(profile["volume"]) for prop, limiter in (("x_min", min), ("y_min", min), ("z_min", min), ("x_max", max), ("y_max", max), ("z_max", max)): if prop not in profile["volume"]["custom_box"] or profile["volume"]["custom_box"][prop] is None: profile["volume"]["custom_box"][prop] = default_box[prop] else: value = profile["volume"]["custom_box"][prop] try: value = limiter(float(value), default_box[prop]) profile["volume"]["custom_box"][prop] = value except: self._logger.warn("Profile has invalid value in volume.custom_box.{}: {!r}".format(prop, value)) return False # make sure we actually do have a custom box and not just the same values as the # default box for prop in profile["volume"]["custom_box"]: if profile["volume"]["custom_box"][prop] != default_box[prop]: break else: # exactly the same as the default box, remove custom box profile["volume"]["custom_box"] = False # validate offsets offsets = [] for offset in profile["extruder"]["offsets"]: if not len(offset) == 2: self._logger.warn("Profile has an invalid extruder.offsets entry: {entry!r}".format(entry=offset)) return False x_offset, y_offset = offset try: offsets.append((float(x_offset), float(y_offset))) except: self._logger.warn("Profile has an extruder.offsets entry with non-float values: {entry!r}".format(entry=offset)) return False profile["extruder"]["offsets"] = offsets return profile