diff --git a/octoprint_SpoolManager/DatabaseManager.py b/octoprint_SpoolManager/DatabaseManager.py index 86162c2a..ea6fd265 100644 --- a/octoprint_SpoolManager/DatabaseManager.py +++ b/octoprint_SpoolManager/DatabaseManager.py @@ -19,7 +19,7 @@ FORCE_CREATE_TABLES = False -CURRENT_DATABASE_SCHEME_VERSION = 2 +CURRENT_DATABASE_SCHEME_VERSION = 3 # List all Models MODELS = [PluginMetaDataModel, SpoolModel] @@ -118,6 +118,38 @@ def _upgradeFrom3To4(self): def _upgradeFrom2To3(self): self._logger.info(" Starting 2 -> 3") + # What is changed: + # - version = IntegerField(null=True) # since V3 + # - diameterTolerance = FloatField(null=True) # since V3 + # - flowRateCompensation = IntegerField(null=True) # since V3 + # - bedTemperature = IntegerField(null=True) # since V3 + # - encloserTemperature = IntegerField(null=True) # since V3 + + connection = sqlite3.connect(self._databaseFileLocation) + cursor = connection.cursor() + + sql = """ + PRAGMA foreign_keys=off; + BEGIN TRANSACTION; + + ALTER TABLE 'spo_spoolmodel' ADD 'version' INTEGER; + ALTER TABLE 'spo_spoolmodel' ADD 'diameterTolerance' REAL; + ALTER TABLE 'spo_spoolmodel' ADD 'spoolWeight' REAL; + ALTER TABLE 'spo_spoolmodel' ADD 'flowRateCompensation' INTEGER; + ALTER TABLE 'spo_spoolmodel' ADD 'bedTemperature' INTEGER; + ALTER TABLE 'spo_spoolmodel' ADD 'encloserTemperature' INTEGER; + ALTER TABLE 'spo_spoolmodel' ADD 'totalLength' INTEGER; + + UPDATE 'spo_spoolmodel' SET version=1; + + UPDATE 'spo_pluginmetadatamodel' SET value=3 WHERE key='databaseSchemeVersion'; + COMMIT; + PRAGMA foreign_keys=on; + """ + cursor.executescript(sql) + + connection.close() + self._logger.info(" Successfully 2 -> 3") pass diff --git a/octoprint_SpoolManager/api/SpoolManagerAPI.py b/octoprint_SpoolManager/api/SpoolManagerAPI.py index 67dd4365..e74e7d0a 100644 --- a/octoprint_SpoolManager/api/SpoolManagerAPI.py +++ b/octoprint_SpoolManager/api/SpoolManagerAPI.py @@ -31,6 +31,7 @@ def _sendCSVUploadStatusToClient(self, importStatus, currenLineNumber, backupFil def _updateSpoolModelFromJSONData(self, spoolModel, jsonData): + spoolModel.version = self._getValueFromJSONOrNone("version", jsonData) spoolModel.databaseId = self._getValueFromJSONOrNone("databaseId", jsonData) spoolModel.isTemplate = self._getValueFromJSONOrNone("isTemplate", jsonData) spoolModel.displayName = self._getValueFromJSONOrNone("displayName", jsonData) @@ -38,11 +39,17 @@ def _updateSpoolModelFromJSONData(self, spoolModel, jsonData): spoolModel.material = self._getValueFromJSONOrNone("material", jsonData) spoolModel.density = self._getValueFromJSONOrNone("density", jsonData) spoolModel.diameter = self._getValueFromJSONOrNone("diameter", jsonData) + spoolModel.diameterTolerance = self._getValueFromJSONOrNone("diameterTolerance", jsonData) spoolModel.colorName = self._getValueFromJSONOrNone("colorName", jsonData) spoolModel.color = self._getValueFromJSONOrNone("color", jsonData) + spoolModel.flowRateCompensation = self._getValueFromJSONOrNone("flowRateCompensation", jsonData) spoolModel.temperature = self._getValueFromJSONOrNone("temperature", jsonData) + spoolModel.bedTemperature = self._getValueFromJSONOrNone("bedTemperature", jsonData) + spoolModel.encloserTemperature = self._getValueFromJSONOrNone("encloserTemperature", jsonData) spoolModel.totalWeight = self._getValueFromJSONOrNone("totalWeight", jsonData) + spoolModel.spoolWeight = self._getValueFromJSONOrNone("spoolWeight", jsonData) spoolModel.remainingWeight = self._getValueFromJSONOrNone("remainingWeight", jsonData) + spoolModel.totalLength = self._getValueFromJSONOrNone("totalLength", jsonData) spoolModel.usedLength = self._getValueFromJSONOrNone("usedLength", jsonData) spoolModel.usedWeight = self._getValueFromJSONOrNone("usedWeight", jsonData) spoolModel.code = self._getValueFromJSONOrNone("code", jsonData) @@ -100,11 +107,17 @@ def _createSampleSpoolModel(self): s1.vendor = "The Spool Company" s1.material = "PETG" s1.diameter = 1.75 + s1.diameterTolerance = 0.2 s1.density = 1.27 + s1.flowRateCompensation = 110 s1.temperature = 182 + s1.bedtemperature = 52 + s1.encloserTemperature = 23 s1.totalWeight = 1000.0 + s1.spoolWeight = 12.3 s1.usedWeight = 123.4 - s1.usedLength = 234.5 + s1.totalLength = 1321 + s1.usedLength = 234 s1.lastUse = datetime.datetime.now() s1.firstUse = datetime.datetime.strptime("2020-03-02 10:33", '%Y-%m-%d %H:%M') diff --git a/octoprint_SpoolManager/api/Transformer.py b/octoprint_SpoolManager/api/Transformer.py index a250a2a9..515d4e8a 100644 --- a/octoprint_SpoolManager/api/Transformer.py +++ b/octoprint_SpoolManager/api/Transformer.py @@ -20,7 +20,8 @@ def _calculateRemainingPercentage(remainingWeight, totalWeight): return None if ( (type(remainingWeight) == int or type(remainingWeight) == float) and - (type(totalWeight) == int or type(totalWeight) == float) ): + (type(totalWeight) == int or type(totalWeight) == float) and + (totalWeight > 0) ): result = remainingWeight / (totalWeight / 100.0) return result @@ -31,7 +32,8 @@ def _calculateUsedPercentage(usedWeight, totalWeight): return None if ( (type(usedWeight) == int or type(usedWeight) == float) and - (type(totalWeight) == int or type(totalWeight) == float) ): + (type(totalWeight) == int or type(totalWeight) == float) and + (totalWeight > 0) ): result = usedWeight / (totalWeight / 100.0) return result @@ -62,8 +64,21 @@ def transformSpoolModelToDict(spoolModel): # Decimal and date time needs to be converted. ATTENTION orgiginal fields will be modified spoolAsDict["totalWeight"] = StringUtils.formatFloat(spoolModel.totalWeight) + spoolAsDict["spoolWeight"] = StringUtils.formatFloat(spoolModel.spoolWeight) spoolAsDict["usedWeight"] = StringUtils.formatFloat(spoolModel.usedWeight) + usedLength = spoolModel.usedLength + totalLength = spoolModel.totalLength + remainingLength = calculateRemainingWeight(usedLength, totalLength) + remainingLengthPercentage = _calculateUsedPercentage(remainingLength, totalLength) + usedLengthPercentage = _calculateUsedPercentage(usedLength, totalLength) + + spoolAsDict["remainingLength"] = StringUtils.formatInt(remainingLength) + spoolAsDict["remainingLengthPercentage"] = StringUtils.formatInt(remainingLengthPercentage) + spoolAsDict["usedLengthPercentage"] = StringUtils.formatInt(usedLengthPercentage) + + + # spoolAsDict["temperature"] = StringUtils.formatSave("{:.02f}", spoolAsDict["temperature"], "") # spoolAsDict["weight"] = StringUtils.formatSave("{:.02f}", spoolAsDict["weight"], "") diff --git a/octoprint_SpoolManager/common/CSVExportImporter.py b/octoprint_SpoolManager/common/CSVExportImporter.py index 4bf6387f..319f8e46 100644 --- a/octoprint_SpoolManager/common/CSVExportImporter.py +++ b/octoprint_SpoolManager/common/CSVExportImporter.py @@ -17,9 +17,15 @@ COLUMN_MATERIAL = "Material" COLUMN_DENSITY = "Density [g/cm3]" COLUMN_DIAMETER = "Diameter [mm]" -COLUMN_TEMPERTURE = "Temperature [C]" +COLUMN_DIAMETER_TOLERANCE = "Diameter Tolerance[mm]" +COLUMN_FLOWRATECOMPENSATION = "Flow rate compensation [%]" +COLUMN_TEMPERATURE = "Temperature [C]" +COLUMN_TEMPERATURE_BED = "Bed Temperature [C]" +COLUMN_TEMPERATURE_ENCLOSER = "Encloser Temperature [C]" COLUMN_TOTAL_WEIGHT = "Total weight [g]" +COLUMN_SPOOL_WEIGHT = "Spool weight [g]" COLUMN_USED_WEIGHT = "Used weight [g]" +COLUMN_TOTAL_LENGTH = "Total length [mm]" COLUMN_USED_LENGTH = "Used length [mm]" COLUMN_FIST_USE_DATETIME = "First use [dd.mm.yyyy hh:mm]" COLUMN_LAST_USE_DATETIME = "Last use [dd.mm.yyyy hh:mm]" @@ -135,12 +141,24 @@ def parseAndAssignFieldValue(self, fieldLabel, fieldName, fieldValue, spoolModel fieldValue = float(fieldValue) if ("diameter" == fieldName): fieldValue = float(fieldValue) + if ("diameterTolerance" == fieldName): + fieldValue = float(fieldValue) + if ("flowRateCompensation" == fieldName): + fieldValue = int(fieldValue) if ("temperature" == fieldName): fieldValue = int(fieldValue) + if ("bedTemperature" == fieldName): + fieldValue = int(fieldValue) + if ("encloserTemperature" == fieldName): + fieldValue = int(fieldValue) if ("totalWeight" == fieldName): fieldValue = float(fieldValue) + if ("spoolWeight" == fieldName): + fieldValue = float(fieldValue) if ("usedWeight" == fieldName): fieldValue = float(fieldValue) + if ("totalLength" == fieldName): + fieldValue = int(fieldValue) if ("usedLength" == fieldName): fieldValue = int(fieldValue) if ("cost" == fieldName): @@ -158,9 +176,15 @@ def parseAndAssignFieldValue(self, fieldLabel, fieldName, fieldValue, spoolModel COLUMN_MATERIAL, COLUMN_DENSITY, COLUMN_DIAMETER, - COLUMN_TEMPERTURE, + COLUMN_DIAMETER_TOLERANCE, + COLUMN_FLOWRATECOMPENSATION, + COLUMN_TEMPERATURE, + COLUMN_TEMPERATURE_BED, + COLUMN_TEMPERATURE_ENCLOSER, COLUMN_TOTAL_WEIGHT, + COLUMN_SPOOL_WEIGHT, COLUMN_USED_WEIGHT, + COLUMN_TOTAL_LENGTH, COLUMN_USED_LENGTH, COLUMN_FIST_USE_DATETIME, COLUMN_LAST_USE_DATETIME, @@ -180,9 +204,15 @@ def parseAndAssignFieldValue(self, fieldLabel, fieldName, fieldValue, spoolModel COLUMN_MATERIAL: CSVColumn("material", COLUMN_MATERIAL, "", DefaultCSVFormattorParser()), COLUMN_DENSITY: CSVColumn("density", COLUMN_DENSITY, "", NumberCSVFormattorParser()), COLUMN_DIAMETER: CSVColumn("diameter", COLUMN_DIAMETER, "", NumberCSVFormattorParser()), - COLUMN_TEMPERTURE: CSVColumn("temperature", COLUMN_TEMPERTURE, "", NumberCSVFormattorParser()), + COLUMN_DIAMETER_TOLERANCE: CSVColumn("diameterTolerance", COLUMN_DIAMETER_TOLERANCE, "", NumberCSVFormattorParser()), + COLUMN_FLOWRATECOMPENSATION: CSVColumn("flowRateCompensation", COLUMN_FLOWRATECOMPENSATION, "", NumberCSVFormattorParser()), + COLUMN_TEMPERATURE: CSVColumn("temperature", COLUMN_TEMPERATURE, "", NumberCSVFormattorParser()), + COLUMN_TEMPERATURE_BED: CSVColumn("bedTemperature", COLUMN_TEMPERATURE_BED, "", NumberCSVFormattorParser()), + COLUMN_TEMPERATURE_ENCLOSER: CSVColumn("encloserTemperature", COLUMN_TEMPERATURE_ENCLOSER, "", NumberCSVFormattorParser()), COLUMN_TOTAL_WEIGHT: CSVColumn("totalWeight", COLUMN_TOTAL_WEIGHT, "", NumberCSVFormattorParser()), + COLUMN_SPOOL_WEIGHT: CSVColumn("spoolWeight", COLUMN_SPOOL_WEIGHT, "", NumberCSVFormattorParser()), COLUMN_USED_WEIGHT: CSVColumn("usedWeight", COLUMN_USED_WEIGHT, "", NumberCSVFormattorParser()), + COLUMN_TOTAL_LENGTH: CSVColumn("totalLength", COLUMN_TOTAL_LENGTH, "", NumberCSVFormattorParser()), COLUMN_USED_LENGTH: CSVColumn("usedLength", COLUMN_USED_LENGTH, "", NumberCSVFormattorParser()), COLUMN_FIST_USE_DATETIME: CSVColumn("firstUse", COLUMN_FIST_USE_DATETIME, "", DateTimeCSVFormattorParser()), COLUMN_LAST_USE_DATETIME: CSVColumn("lastUse", COLUMN_LAST_USE_DATETIME, "", DateTimeCSVFormattorParser()), diff --git a/octoprint_SpoolManager/common/StringUtils.py b/octoprint_SpoolManager/common/StringUtils.py index 80052729..ddb6a2b6 100644 --- a/octoprint_SpoolManager/common/StringUtils.py +++ b/octoprint_SpoolManager/common/StringUtils.py @@ -148,6 +148,15 @@ def formatFloat(floatValue): pass # do nothing return result +def formatInt(intValue): + result = "" + if (intValue != None ): + try: + result = "{:.0f}".format(float(intValue)) + except ValueError: + pass # do nothing + return result + def transformToDateTimeOrNone(dateTimeString): if dateTimeString != None and len(dateTimeString) != 0: index = dateTimeString.find(" ") diff --git a/octoprint_SpoolManager/models/SpoolModel.py b/octoprint_SpoolManager/models/SpoolModel.py index e0cc347d..4ed863a6 100644 --- a/octoprint_SpoolManager/models/SpoolModel.py +++ b/octoprint_SpoolManager/models/SpoolModel.py @@ -9,24 +9,31 @@ class SpoolModel(BaseModel): + version = IntegerField(null=True) # since V3 isTemplate = BooleanField(null=True) displayName = CharField(null=True) vendor = CharField(null=True) material = CharField(null=True) density = FloatField(null=True) diameter = FloatField(null=True) + diameterTolerance = FloatField(null=True) # since V3 colorName = CharField(null=True) color = CharField(null=True) - # Grad + flowRateCompensation = IntegerField(null=True) #since V3 + # Temperature temperature = IntegerField(null=True) + bedTemperature = IntegerField(null=True) # since V3 + encloserTemperature = IntegerField(null=True) # since V3 # in g totalWeight = FloatField(null=True) + spoolWeight = FloatField(null=True) # since V3 # in g usedWeight = FloatField(null=True) # in g remainingWeight = FloatField(null=True) # in mm + totalLength = IntegerField(null=True) # since V3 usedLength = IntegerField(null=True) # Bar or QR Code code = CharField(null=True) diff --git a/octoprint_SpoolManager/static/js/SpoolManager-EditSpoolDialog.js b/octoprint_SpoolManager/static/js/SpoolManager-EditSpoolDialog.js index 5a9a1302..d52f0835 100644 --- a/octoprint_SpoolManager/static/js/SpoolManager-EditSpoolDialog.js +++ b/octoprint_SpoolManager/static/js/SpoolManager-EditSpoolDialog.js @@ -97,6 +97,7 @@ function SpoolManagerEditSpoolDialog(){ }; // - list all attributes + this.version = ko.observable(); this.isSpoolVisible = ko.observable(false); this.isEmpty = ko.observable(); this.databaseId = ko.observable(); @@ -106,13 +107,22 @@ function SpoolManagerEditSpoolDialog(){ // this.material = ko.observable(); this.density = ko.observable(); this.diameter = ko.observable(); + this.diameterTolerance = ko.observable(); + this.flowRateCompensation = ko.observable(); this.temperature = ko.observable(); + this.bedTemperature = ko.observable(); + this.encloserTemperature = ko.observable(); this.colorName = ko.observable(); this.color = ko.observable(); this.totalWeight = ko.observable(); + this.spoolWeight = ko.observable(); this.remainingWeight = ko.observable(); this.remainingPercentage = ko.observable(); + this.totalLength = ko.observable(); this.usedLength = ko.observable(); + this.usedLengthPercentage = ko.observable(); + this.remainingLength = ko.observable(); + this.remainingLengthPercentage = ko.observable(); this.usedWeight = ko.observable(); this.usedPercentage = ko.observable(); this.code = ko.observable(); @@ -192,6 +202,7 @@ function SpoolManagerEditSpoolDialog(){ } this.isEmpty(data == null); + this.version(updateData.version); this.databaseId(updateData.databaseId); this.isTemplate(updateData.isTemplate); this.displayName(updateData.displayName); @@ -200,6 +211,7 @@ function SpoolManagerEditSpoolDialog(){ this.material(updateData.material); this.density(updateData.density); this.diameter(updateData.diameter); + this.diameterTolerance(updateData.diameterTolerance); this.colorName(updateData.colorName); this.color(updateData.color == null ? DEFAULT_COLOR : updateData.color); @@ -210,14 +222,22 @@ function SpoolManagerEditSpoolDialog(){ } } + this.flowRateCompensation(updateData.flowRateCompensation); this.temperature(updateData.temperature); + this.bedTemperature(updateData.bedTemperature); + this.encloserTemperature(updateData.encloserTemperature); this.totalWeight(updateData.totalWeight); + this.spoolWeight(updateData.spoolWeight); this.remainingWeight(updateData.remainingWeight); this.remainingPercentage(updateData.remainingPercentage); this.code(updateData.code); this.usedPercentage(updateData.usedPercentage); + this.totalLength(updateData.totalLength); this.usedLength(updateData.usedLength); + this.usedLengthPercentage(updateData.usedLengthPercentage); + this.remainingLength(updateData.remainingLength); + this.remainingLengthPercentage(updateData.remainingLengthPercentage); this.usedWeight(updateData.usedWeight); this.firstUse(updateData.firstUse); @@ -385,7 +405,7 @@ function SpoolManagerEditSpoolDialog(){ self.spoolItemForEditing.colorName(colorName); } }); - +// ----------------- start: weight stuff // update used percentage self.updateRemainingValues = function(){ var total = self.spoolItemForEditing.totalWeight(); @@ -436,6 +456,59 @@ function SpoolManagerEditSpoolDialog(){ self.updateUsedPercentage(); self.updateRemainingValues(); }); +// ----------------- end: weight stuff +// ----------------- start: length stuff + // update used percentage + self.updateRemainingLengthValues = function(){ + var total = self.spoolItemForEditing.totalLength(); + var used = self.spoolItemForEditing.usedLength(); + // - remaining weight + if (total != null && used != null){ + if (isNaN(total)==false && isNaN(used)==false && 0 != total.length && 0 != used.length){ + var remainingLength = (total - used).toFixed(0); + console.info("calculated remainLength:" + remainingLength ); + self.spoolItemForEditing.remainingLength(remainingLength); + } else { + self.spoolItemForEditing.remainingLength(""); + } + } else { + self.spoolItemForEditing.remainingLength(""); + } + // - remaininig percentage + var remainingLength = self.spoolItemForEditing.remainingLength(); + if (total != null && remainingLength != null){ + if (isNaN(total)==false && isNaN(remainingLength)==false){ + result = Number(remainingLength/(total/100)).toFixed(0); + self.spoolItemForEditing.remainingLengthPercentage(result); + } else { + self.spoolItemForEditing.remainingLengthPercentage(""); + } + } + } + + // update updateUsedLengthPercentage + self.updateUsedLengthPercentage = function(){ + var total = self.spoolItemForEditing.totalLength(); + var used = self.spoolItemForEditing.usedLength(); + if (total != null && used != null){ + if (isNaN(total)==false && isNaN(used)==false){ + result = Number(used/(total/100)).toFixed(1); + self.spoolItemForEditing.usedLengthPercentage(result); + } else { + self.spoolItemForEditing.usedLengthPercentage(""); + } + } + } + + self.spoolItemForEditing.totalLength.subscribe(function(newValue){ + self.updateUsedLengthPercentage(); + self.updateRemainingLengthValues(); + }); + self.spoolItemForEditing.usedLength.subscribe(function(newValue){ + self.updateUsedLengthPercentage(); + self.updateRemainingLengthValues(); + }); +// ----------------- end: length stuff } this.afterBinding = function(){ @@ -485,8 +558,10 @@ function SpoolManagerEditSpoolDialog(){ self.spoolItemForEditing.databaseId(null); self.spoolItemForEditing.costUnit(self.pluginSettings.currencySymbol()); self.spoolItemForEditing.displayName(null); + self.spoolItemForEditing.totalWeight(0.0); self.spoolItemForEditing.usedWeight(0.0); - self.spoolItemForEditing.usedLength(0.0); + self.spoolItemForEditing.totalLength(0); + self.spoolItemForEditing.usedLength(0); self.spoolItemForEditing.lastUse(null); self.spoolItemForEditing.firstUse(null); // self.spoolItemForEditing.displayName(null); diff --git a/octoprint_SpoolManager/templates/SpoolManager_tab_dialogs.jinja2 b/octoprint_SpoolManager/templates/SpoolManager_tab_dialogs.jinja2 index e0d20a45..243ef437 100644 --- a/octoprint_SpoolManager/templates/SpoolManager_tab_dialogs.jinja2 +++ b/octoprint_SpoolManager/templates/SpoolManager_tab_dialogs.jinja2 @@ -153,6 +153,7 @@