printrun-src/printrun/spoolmanager/spoolmanager.py

changeset 46
cce0af6351f0
--- /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 <http://www.gnu.org/licenses/>.
+#
+# Copyright 2017 Rock Storm <rockstorm@gmx.com>
+
+# 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

mercurial