diff -r c82943fb205f -r cce0af6351f0 printrun-src/printrun/spoolmanager/spoolmanager.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/printrun-src/printrun/spoolmanager/spoolmanager.py Wed Jan 20 10:15:13 2021 +0100
@@ -0,0 +1,262 @@
+# This file is part of the Printrun suite.
+#
+# Printrun is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Printrun is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Printrun. If not, see .
+#
+# Copyright 2017 Rock Storm
+
+# This module indirectly depends of pronsole and settings but it does not
+# import them
+
+class SpoolManager():
+ """
+ Back-end for the Spool Manager.
+
+ It is expected to be called from an object which has the contents of
+ settings.py and pronsole.py. This way the class is able to '_add' and
+ 'set' settings.
+
+ This class basically handles a single variable called '_spool_list'. It is
+ a list of spool_items. A spool_item is in turn a list three elements: a
+ string, a float and an integer. Namely: the name of the spool, the
+ remaining length of filament and the extruder it is loaded to. E.g.:
+
+ spool_item = [string name, float length, int extruder]
+
+ _spool_list = [spool_item spool_1, ... , spool_item spool_n ]
+
+ '_spool_list' is somehow a Nx3 matrix where N is the number of recorded
+ spools. The first column contains the names of the spools, the second the
+ lengths of remaining filament and the third column contains which extruder
+ is the spool loaded for.
+
+ The variable '_spool_list' is saved in the configuration file using a
+ setting with the same name: 'spool_list'. It is saved as a single string.
+ It concatenates every item from the list and separates them by a comma and
+ a space. For instance, if the variable '_spool_list' was:
+
+ _spool_list = [["spool_1", 100.0, 0], ["spool_2", 200.0, -1]]
+
+ The 'spool_list' setting will look like:
+
+ "spool_1, 100.0, 0, spool_2, 200.0, -1"
+ """
+
+ def __init__(self, parent):
+ self.parent = parent
+ self.refresh()
+
+ def refresh(self):
+ """
+ Read the configuration file and populate the list of recorded spools.
+ """
+ self._spool_list = self._readSetting(self.parent.settings.spool_list)
+
+ def add(self, spool_name, spool_length):
+ """Add the given spool to the list of recorded spools."""
+ self._spool_list.append([spool_name, spool_length, -1])
+ self._save()
+
+ def load(self, spool_name, extruder):
+ """Set the extruder field of the given spool item."""
+
+ # If there was a spool already loaded for this extruder unload it
+ previous_spool = self._findByColumn(extruder, 2)
+ if previous_spool != -1:
+ self.unload(extruder)
+
+ # Load the given spool
+ new_spool = self._findByColumn(spool_name, 0)
+ self.remove(spool_name)
+ self._spool_list.append([new_spool[0], new_spool[1], extruder])
+ self._save()
+
+ def remove(self, spool_name):
+ """Remove the given spool item from the list of recorded spools."""
+ spool_item = self._findByColumn(spool_name, 0)
+ self._spool_list.remove(spool_item)
+ self._save()
+
+ def unload(self, extruder):
+ """Set to -1 the extruder field of the spool item currently on."""
+
+ spool_item = self._findByColumn(extruder, 2)
+ if spool_item != -1:
+ self.remove(spool_item[0])
+ self._spool_list.append([spool_item[0], spool_item[1], -1])
+ self._save()
+
+ def isLoaded(self, spool_name):
+ """
+ int isLoaded( string name )
+
+ Return the extruder that the given spool is loaded to. -1 if it is
+ not loaded for any extruder or None if the given name does not match
+ any known spool.
+ """
+
+ spool_item = self._findByColumn(spool_name, 0)
+ if spool_item != -1:
+ return spool_item[2]
+ else:
+ return None
+
+ def isListed(self, spool_name):
+ """Return 'True' if the given spool is on the list."""
+
+ spool_item = self._findByColumn(spool_name, 0)
+ if not spool_item == -1:
+ return True
+ else:
+ return False
+
+ def getSpoolName(self, extruder):
+ """
+ string getSpoolName( int extruder )
+
+ Return the name of the spool loaded for the given extruder.
+ """
+
+ spool_item = self._findByColumn(extruder, 2)
+ if spool_item != -1:
+ return spool_item[0]
+ else:
+ return None
+
+ def getRemainingFilament(self, extruder):
+ """
+ float getRemainingFilament( int extruder )
+
+ Return the name of the spool loaded for the given extruder.
+ """
+
+ spool_item = self._findByColumn(extruder, 2)
+ if spool_item != -1:
+ return spool_item[1]
+ else:
+ return float("NaN")
+
+ def editLength(self, increment, spool_name = None, extruder = -1):
+ """
+ int editLength ( float increment, string spool_name, int extruder )
+
+ Add the given 'increment' amount to the length of filament of the
+ given spool. Spool can be specified either by name or by the extruder
+ it is loaded to.
+ """
+
+ if spool_name != None:
+ spool_item = self._findByColumn(spool_name, 0)
+ elif extruder != -1:
+ spool_item = self._findByColumn(extruder, 2)
+ else:
+ return -1 # Not enough arguments
+
+ if spool_item == -1:
+ return -2 # No spool found for the given name or extruder
+
+ length = spool_item[1] + increment
+ self.remove(spool_item[0])
+ self.add(spool_item[0], length)
+ if spool_item[2] > -1:
+ self.load(spool_item[0], spool_item[2])
+ self._save()
+
+ return 0
+
+ def getExtruderCount(self):
+ """int getExtruderCount()"""
+ return self.parent.settings.extruders
+
+ def getSpoolCount(self):
+ """
+ int getSpoolCount()
+
+ Return the number of currently recorded spools.
+ """
+ return len(self._spool_list)
+
+ def getSpoolList(self):
+ """
+ [N][2] getSpoolList ()
+
+ Returns a list of the recorded spools. Returns a Nx2 matrix where N is
+ the number of recorded spools. The first column contains the names of
+ the spools and the second the lengths of remaining filament.
+ """
+
+ slist = []
+ for i in range(self.getSpoolCount()):
+ item = [self._spool_list[i][0], self._spool_list[i][1]]
+ slist.append(item)
+ return slist
+
+ def _findByColumn(self, data, col = 0):
+ """
+ Find which spool_item from the list contains certain data.
+
+ The 'col' argument specifies in which field from the spool_item to
+ look for. For instance, with the following list:
+
+ _spool_list = [["spool_1", 100.0, 1],
+ ["spool_2", 200.0, 0],
+ .
+ .
+ .
+ ["spool_10", 1000.0, 0]]
+
+ A call like: _findByColumn("spool_2", 0)
+
+ Will produce: ["spool_2", 200.0, 0]
+
+ col = 0, would look into the "name's column"
+ col = 1, would look into the "length's column"
+ col = 2, would look into the "extruder's column"
+ """
+
+ for spool_item in self._spool_list:
+ if data == spool_item[col]:
+ return spool_item
+
+ return -1
+
+ def _save(self):
+ """Update the list of recorded spools in the configuration file."""
+ self._setSetting(self._spool_list, "spool_list")
+
+ def _setSetting(self, variable, setting):
+ """
+ Write the given variable to the given setting of the configuration
+ file.
+ """
+ n = 3 # number of fields in spool_item
+ string_list = []
+ for i in range(len(variable)):
+ for j in range(n):
+ string_list.append(str(variable[i][j]))
+ separator = ", "
+ self.parent.set(setting, separator.join(string_list))
+
+ def _readSetting(self, setting):
+ """
+ Return the variable read.
+ """
+ n = 3 # number of fields in spool_item
+ string_list = setting.split(", ")
+ variable = []
+ for i in range(len(string_list)//n):
+ variable.append(
+ [string_list[n*i],
+ float(string_list[n*i+1]),
+ int(string_list[n*i+2])])
+ return variable