UPDATE:
Im develop Branch (also für SmartHomeNG v1.6) ist eine allgemein gültige Lösung implementiert. (Danke an ohinckel für die Idee).
Ab der Version muss der Fehler nicht mehr im einzelnen Plugin abgefangen werden, es sei denn, man möchte nicht das Laden des Plugins unterbinden, sondern vielleicht nur einzelne Funktionen des Plugins deaktivieren.
Wenn ein Plugin ein spezielles Python Package benötigt (Requirement) und dieses auf dem System des Anwenders nicht installiert ist, wird im Log beim ersten Zugriff auf Funktionen dieses Packages eine Exception in das Logfile geschrieben.
Für viele Anwender ist es schwierig, aus der Fehlermeldung auf die eigentliche Ursache zu schließen.
Durch einen kleinen Kniff im Plugin, kann im Logfile eine klare Fehlermeldung geschrieben werden. Außerdem kann das Laden des Plugins unterbunden werden, um Folgefehler zu vermeiden.
Vorgehen
Die zwei notwendigen Änderungen sind hier Beispiel des homematic Plugins und des benötigten Packages pyhomematic beschrieben.
Normalerweise wird das Package folgendermaßen importiert:
from pyhomematic import HMConnection
Um den Fehler zu behandeln, werden folgende zwei Änderungen vorgenommen:
- Um den Fehler zu erkennen, wird die import Anweisung in ein try/except Konstrukt eingebettet und abhängig vom Ergebnis eine Variable gesetzt. (Zeilen 8 bis 12 im folgenden Beispiel)
- Um den erkannten Fehler auszuwerten, wird eine If-Anweisung zur__init__ Methode hinzugefügt (Zeilen 37 bis 41), die Im Fehlerfall einen sinnvollen Log-Eintrag schreibt und durch das setzen der Variable self._init_complete signaliseiert, dass das Plugin sich nicht fehlerfrei initialisieren konnte. Das anschließende return sorgt dann noch für den Abbruch der Initialisierung.
# You should have received a copy of the GNU General Public License
# along with SmartHomeNG. If not, see <http://www.gnu.org/licenses/>.
#
#########################################################################
import logging
try:
from pyhomematic import HMConnection
REQUIRED_PACKAGE_IMPORTED = True
except:
REQUIRED_PACKAGE_IMPORTED = False
from lib.module import Modules
from lib.model.smartplugin import *
from time import sleep
class Homematic(SmartPlugin):
"""
Main class of the Plugin. Does all plugin specific stuff and provides
the update functions for the items
"""
PLUGIN_VERSION = '1.5.0'
connected = False
def __init__(self, sh, *args, **kwargs):
"""
Initalizes the plugin. The parameters descriptions for this method are pulled from the entry in plugin.yaml.
"""
self.logger = logging.getLogger(__name__)
# Exit if the required package(s) could not be imported
if not REQUIRED_PACKAGE_IMPORTED:
self.logger.error("{}: Unable to import Python package 'pyhomematic'".format(self.get_fullname()))
self._init_complete = False
return
# get the parameters for the plugin (as defined in metadata plugin.yaml):
# self.param1 = self.get_parameter_value('param1')
Im Logfile wird der Fehler dann durch zwei Zeilen, wie im folgenden Beispiel angezeigt:
2018-08-12 09:59:03 ERROR plugins.homematic homematic_hm1: Unable to import Python package 'pyhomematic'
2018-08-12 09:59:03 ERROR lib.plugin Plugins: Plugin 'homematic' initialization failed, plugin not loaded
3 Kommentare
Martin Sinn · 13. August 2018 um 7:21
Ich wollte eine möglichst schlanke Lösung skizzieren. Die meisten Plugins importieren höchstens ein „exotische“ Package.
Ansonsten kann man im try Statement einfach mehrere Imports durchführen und im Log Eintrag schreiben, dass eines der aufgeführten Plugins nicht geladen werden konnte.
Marc René Frieß · 13. August 2018 um 5:59
By the way: better in my view would be to use an array of package names instead of a bool: so in case of more than 1 import. a more expressive error handling could be done
Marc René Frieß · 12. August 2018 um 10:07
Cool. Werde ich bei meinen Plugins sukzessive nachziehen!
Update: ist erledigt