# Raspberry Pi Disk Usage
#
# Description: Reports temperature and free disk space
#
# Author: elgringo
#
# History:
# 1.0.0   01-07-2017  Initial version
# 1.0.1   31-07-2017  Updated with new API

"""
<plugin key="RaspberryInfo" name="System Status" author="elgringo" version="1.0.1" externallink="https://github.com/ericstaal/domoticz/blob/master/">
  <params>
    <param field="Mode1" label="Size" width="50px" required="true">
      <options>
        <option label="Kb" value="Kb" />
        <option label="Mb" value="Mb" />
        <option label="Gb" value="Gb" default="true"/>
      </options>
    </param>
    <param field="Mode2" label="Heartbeat interval" width="50px" required="true">
      <options>
        <option label="20" value="10" />
        <option label="20" value="20" />
        <option label="30" value="30" />
        <option label="60" value="60" default="true"/>
      </options>
    </param>
    <param field="Mode6" label="Debug level" width="150px">
      <options>
        <option label="0 (No logging)" value="0" default="true"/>
        <option label="1" value="1"/> 
        <option label="2" value="2"/>
        <option label="3" value="3"/>
        <option label="4" value="4"/>
        <option label="5" value="5"/>
        <option label="6" value="6"/>
        <option label="7" value="7"/>
        <option label="8" value="8"/>
        <option label="9 (all)" value="9"/>
        <option label="10 (all with debug)" value="10"/>
      </options>
    </param>
  </params>
</plugin>
"""

import Domoticz
import collections 
import base64
import binascii
import html

# additional imports
import os

class BasePlugin:
  logLevel = 0                # logLevel
 
  def onStart(self):
    try:
      self.logLevel = int(Parameters["Mode6"])
    except:
      self.LogError("Debuglevel '"+Parameters["Mode6"]+"' is not an integer")
      
    if self.logLevel == 10:
      Domoticz.Debugging(1)
    self.LogMessage("onStart called", 9)
    
    Domoticz.Heartbeat(int(Parameters["Mode2"]))
      
    if (len(Devices) == 0):
      Domoticz.Device(Name="Free space", Unit=1, TypeName="Custom", Image=3, Options={"Custom": ("1;" + Parameters["Mode1"])}).Create()
      Domoticz.Device(Name="Temperature", Unit=2, Type=80, Subtype=5, Switchtype=0, Image=0).Create()
    elif 1 in Devices:
      Devices[1].Update(0, "0", Options={"Custom": ("1;" + Parameters["Mode1"])})
      
    self.DumpConfigToLog()
    
    return

  def onStop(self):
    self.LogMessage("onStop called", 9)
    
    return

  def onConnect(self, Connection, Status, Description):
    self.LogMessage("onConnect "+Connection.Address+":"+Connection.Port+" Status: "+ str(Status)+", Description:"+str(Description), 7)

    return

  def onMessage(self, Connection, Data):
    self.DumpVariable(Data, "OnMessage Data")

    return

  def onCommand(self, Unit, Command, Level, Hue):
    self.LogMessage("onCommand called for Unit " + str(Unit) + ": Parameter '" + str(Command) + "', Level: " + str(Level)+", Hue: " + str(Hue), 8)
    
    return

  def onNotification(self, Name, Subject, Text, Status, Priority, Sound, ImageFile):
    self.LogMessage("onNotification: " + Name + "," + Subject + "," + Text + "," + Status + "," + str(Priority) + "," + Sound + "," + ImageFile, 8)
    
    return

  def onDisconnect(self, Connection):
    self.LogMessage("onDisconnect "+Connection.Address+":"+Connection.Port, 7)

    return

  def onHeartbeat(self):
    self.LogMessage("onHeartbeat called", 9)
    try:
      # size
      data = os.popen("df -k | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{ print $6 \" \" $4 }'").read()
      # / 1.5g
      # /boot ...
      for line in data.split("\n"):
        koloms = line.split(' ')
        if koloms[0] == '/':
          size = float(koloms[1])
          
          if Parameters["Mode1"] == "Gb":
            size = size / 1048576
          elif Parameters["Mode1"] == "Mb":
            size = size / 1024
          
          self.UpdateDevice(1, 0, round(size,1))
          break 
      
      # temperature
      data = os.popen("cat /sys/class/thermal/thermal_zone0/temp").read()    
      temp = round(int(data) / 1000,1)
      self.UpdateDevice(2, 0, temp)
        
    except Exception as e:
      self.LogError("OnHeartbeat Error: "+ str(e))
      
    return

####################### Specific helper functions for plugin #######################  

####################### Generic helper member functions for plugin ####################### 
  def StringToMinutes(self, value):
    # hh:mm
    splitted = value.split(":")
    if len(splitted) >= 2:
      minutes = int(splitted[len(splitted)-1]) + int(splitted[len(splitted)-2])*60
    else:
      minutes = int(splitted[0])
    return minutes  
   
  def UpdateDevice(self, Unit, nValue, sValue1, sValue2 = None):
    # Make sure that the Domoticz device still exists (they can be deleted) before updating it 
    if (Unit in Devices):
      if sValue2 is None:
        sValue = str(sValue1)
      else:
        sValue = str(sValue1)+";"+str(sValue2)
        
      if (Devices[Unit].nValue != nValue) or (Devices[Unit].sValue != sValue):
        self.LogMessage("Update ["+Devices[Unit].Name+"] from: ('"+str(Devices[Unit].nValue)+":'"+str(Devices[Unit].sValue )+"') to: ("+str(nValue)+":'"+str(sValue)+"')", 5)
        Devices[Unit].Update(nValue, sValue)
    return
   
  def DumpDeviceToLog(self,Unit):
    self.LogMessage(str(Devices[Unit].ID)+":"+Devices[Unit].Name+", (n:"+str(Devices[Unit].nValue)+", s:"+Devices[Unit].sValue+", Sgl:"+str(Devices[Unit].SignalLevel)+", bl:"+str(Devices[Unit].BatteryLevel)+", img:"+ str(Devices[Unit].Image)+", typ:"+ str(Devices[Unit].Type)+", styp:"+ str(Devices[Unit].SubType)+")", 6)
    return   
    
  def DumpConfigToLog(self):
    for x in Parameters:
      if Parameters[x] != "":
        self.LogMessage( "'" + x + "':'" + str(Parameters[x]) + "'", 7)
    self.LogMessage("Device count: " + str(len(Devices)), 6)
    for x in Devices:
      self.DumpDeviceToLog(x)
    return
    
  def DumpVariable(self, Item, Varname, Level = 5, BytesAsStr = False, Prefix=""):
    if self.logLevel >= Level:
      Prefix = str(Prefix)
      if isinstance(Item, dict):
        self.LogMessage(Prefix + str(Varname) + " ("+type(Item).__name__+"["+str(len(Item))+"]): ", Level)
        
        if len(Prefix) < 3:
          Prefix = "--> "
        else:
          Prefix = "--" + Prefix
          
        for b in Item:
          if isinstance(b, str):
            self.DumpVariable( Item[b], "'"+str(b) + "'", Level, BytesAsStr, Prefix)
          else:
            self.DumpVariable( Item[b], str(b), Level, BytesAsStr, Prefix)
         
      elif isinstance(Item, (bytes, bytearray)):
        if BytesAsStr:
          txt = html.escape(Item.decode("utf-8", "ignore"))
        else:
          txt = "[ " 
          for b in Item:
            txt += str(hex(b))+" "
          txt +=  "]"
        
        self.LogMessage(Prefix + str(Varname) + " ("+type(Item).__name__+"["+str(len(Item))+"]): " + txt, Level)
      elif isinstance(Item, (tuple, list)):
        self.LogMessage(Prefix + str(Varname) + " ("+type(Item).__name__+"["+str(len(Item))+"]): ", Level)
        
        if len(Prefix) < 3:
          Prefix = "--> "
        else:
          Prefix = "--" + Prefix
          
        idx = 0
        for b in Item:
          self.DumpVariable( b, "["+str(idx) + "]", Level, BytesAsStr, Prefix)
          idx=idx+1

      elif isinstance(Item, str):
        self.LogMessage(Prefix + str(Varname) + " ("+type(Item).__name__+"["+str(len(Item))+"]): '"+Item+"'", Level)
      else:
        self.LogMessage(Prefix + str(Varname) + " ("+type(Item).__name__+"): "+str(Item), Level)
           
    return

  def LogMessage(self, Message, Level):
    if Level > 0:
      if self.logLevel >= Level:
        if self.logLevel >= 10:
          Domoticz.Debug(Message)
        else:
          Domoticz.Log(Message)
    elif (Level < 0) or (Level > 10):
      Domoticz.Error(Message)
      
    return
    
  def LogError(self, Message):
    self.LogMessage(Message, -1)
    return  
    
  def stringToBase64(self, s):
    return base64.b64encode(s.encode('utf-8')).decode("utf-8")

  def base64ToString(self, b):
    return base64.b64decode(b).decode('utf-8')    
    
####################### Global functions for plugin #######################
global _plugin
_plugin = BasePlugin()

def onStart():
  global _plugin
  _plugin.onStart()

def onStop():
  global _plugin
  _plugin.onStop()

def onConnect(Connection, Status, Description):
  global _plugin
  _plugin.onConnect(Connection, Status, Description)

def onMessage(Connection, Data):
  global _plugin
  _plugin.onMessage(Connection, Data)

def onCommand(Unit, Command, Level, Hue):
  global _plugin
  _plugin.onCommand(Unit, Command, Level, Hue)

def onNotification(Name, Subject, Text, Status, Priority, Sound, ImageFile):
  global _plugin
  _plugin.onNotification(Name, Subject, Text, Status, Priority, Sound, ImageFile)

def onDisconnect(Connection):
  global _plugin
  _plugin.onDisconnect(Connection)

def onHeartbeat():
  global _plugin
  _plugin.onHeartbeat()


cdc85b3a7d73a5666d86597ed6f29392cff191fd
<mask token>


class BasePlugin:
    logLevel = 0

    def onStart(self):
        try:
            self.logLevel = int(Parameters['Mode6'])
        except:
            self.LogError("Debuglevel '" + Parameters['Mode6'] +
                "' is not an integer")
        if self.logLevel == 10:
            Domoticz.Debugging(1)
        self.LogMessage('onStart called', 9)
        Domoticz.Heartbeat(int(Parameters['Mode2']))
        if len(Devices) == 0:
            Domoticz.Device(Name='Free space', Unit=1, TypeName='Custom',
                Image=3, Options={'Custom': '1;' + Parameters['Mode1']}
                ).Create()
            Domoticz.Device(Name='Temperature', Unit=2, Type=80, Subtype=5,
                Switchtype=0, Image=0).Create()
        elif 1 in Devices:
            Devices[1].Update(0, '0', Options={'Custom': '1;' + Parameters[
                'Mode1']})
        self.DumpConfigToLog()
        return

    def onStop(self):
        self.LogMessage('onStop called', 9)
        return

    def onConnect(self, Connection, Status, Description):
        self.LogMessage('onConnect ' + Connection.Address + ':' +
            Connection.Port + ' Status: ' + str(Status) + ', Description:' +
            str(Description), 7)
        return

    def onMessage(self, Connection, Data):
        self.DumpVariable(Data, 'OnMessage Data')
        return

    def onCommand(self, Unit, Command, Level, Hue):
        self.LogMessage('onCommand called for Unit ' + str(Unit) +
            ": Parameter '" + str(Command) + "', Level: " + str(Level) +
            ', Hue: ' + str(Hue), 8)
        return

    def onNotification(self, Name, Subject, Text, Status, Priority, Sound,
        ImageFile):
        self.LogMessage('onNotification: ' + Name + ',' + Subject + ',' +
            Text + ',' + Status + ',' + str(Priority) + ',' + Sound + ',' +
            ImageFile, 8)
        return

    def onDisconnect(self, Connection):
        self.LogMessage('onDisconnect ' + Connection.Address + ':' +
            Connection.Port, 7)
        return

    def onHeartbeat(self):
        self.LogMessage('onHeartbeat called', 9)
        try:
            data = os.popen(
                'df -k | grep -vE \'^Filesystem|tmpfs|cdrom\' | awk \'{ print $6 " " $4 }\''
                ).read()
            for line in data.split('\n'):
                koloms = line.split(' ')
                if koloms[0] == '/':
                    size = float(koloms[1])
                    if Parameters['Mode1'] == 'Gb':
                        size = size / 1048576
                    elif Parameters['Mode1'] == 'Mb':
                        size = size / 1024
                    self.UpdateDevice(1, 0, round(size, 1))
                    break
            data = os.popen('cat /sys/class/thermal/thermal_zone0/temp').read()
            temp = round(int(data) / 1000, 1)
            self.UpdateDevice(2, 0, temp)
        except Exception as e:
            self.LogError('OnHeartbeat Error: ' + str(e))
        return

    def StringToMinutes(self, value):
        splitted = value.split(':')
        if len(splitted) >= 2:
            minutes = int(splitted[len(splitted) - 1]) + int(splitted[len(
                splitted) - 2]) * 60
        else:
            minutes = int(splitted[0])
        return minutes

    def UpdateDevice(self, Unit, nValue, sValue1, sValue2=None):
        if Unit in Devices:
            if sValue2 is None:
                sValue = str(sValue1)
            else:
                sValue = str(sValue1) + ';' + str(sValue2)
            if Devices[Unit].nValue != nValue or Devices[Unit
                ].sValue != sValue:
                self.LogMessage('Update [' + Devices[Unit].Name +
                    "] from: ('" + str(Devices[Unit].nValue) + ":'" + str(
                    Devices[Unit].sValue) + "') to: (" + str(nValue) + ":'" +
                    str(sValue) + "')", 5)
                Devices[Unit].Update(nValue, sValue)
        return

    def DumpDeviceToLog(self, Unit):
        self.LogMessage(str(Devices[Unit].ID) + ':' + Devices[Unit].Name +
            ', (n:' + str(Devices[Unit].nValue) + ', s:' + Devices[Unit].
            sValue + ', Sgl:' + str(Devices[Unit].SignalLevel) + ', bl:' +
            str(Devices[Unit].BatteryLevel) + ', img:' + str(Devices[Unit].
            Image) + ', typ:' + str(Devices[Unit].Type) + ', styp:' + str(
            Devices[Unit].SubType) + ')', 6)
        return

    def DumpConfigToLog(self):
        for x in Parameters:
            if Parameters[x] != '':
                self.LogMessage("'" + x + "':'" + str(Parameters[x]) + "'", 7)
        self.LogMessage('Device count: ' + str(len(Devices)), 6)
        for x in Devices:
            self.DumpDeviceToLog(x)
        return

    def DumpVariable(self, Item, Varname, Level=5, BytesAsStr=False, Prefix=''
        ):
        if self.logLevel >= Level:
            Prefix = str(Prefix)
            if isinstance(Item, dict):
                self.LogMessage(Prefix + str(Varname) + ' (' + type(Item).
                    __name__ + '[' + str(len(Item)) + ']): ', Level)
                if len(Prefix) < 3:
                    Prefix = '--> '
                else:
                    Prefix = '--' + Prefix
                for b in Item:
                    if isinstance(b, str):
                        self.DumpVariable(Item[b], "'" + str(b) + "'",
                            Level, BytesAsStr, Prefix)
                    else:
                        self.DumpVariable(Item[b], str(b), Level,
                            BytesAsStr, Prefix)
            elif isinstance(Item, (bytes, bytearray)):
                if BytesAsStr:
                    txt = html.escape(Item.decode('utf-8', 'ignore'))
                else:
                    txt = '[ '
                    for b in Item:
                        txt += str(hex(b)) + ' '
                    txt += ']'
                self.LogMessage(Prefix + str(Varname) + ' (' + type(Item).
                    __name__ + '[' + str(len(Item)) + ']): ' + txt, Level)
            elif isinstance(Item, (tuple, list)):
                self.LogMessage(Prefix + str(Varname) + ' (' + type(Item).
                    __name__ + '[' + str(len(Item)) + ']): ', Level)
                if len(Prefix) < 3:
                    Prefix = '--> '
                else:
                    Prefix = '--' + Prefix
                idx = 0
                for b in Item:
                    self.DumpVariable(b, '[' + str(idx) + ']', Level,
                        BytesAsStr, Prefix)
                    idx = idx + 1
            elif isinstance(Item, str):
                self.LogMessage(Prefix + str(Varname) + ' (' + type(Item).
                    __name__ + '[' + str(len(Item)) + "]): '" + Item + "'",
                    Level)
            else:
                self.LogMessage(Prefix + str(Varname) + ' (' + type(Item).
                    __name__ + '): ' + str(Item), Level)
        return

    def LogMessage(self, Message, Level):
        if Level > 0:
            if self.logLevel >= Level:
                if self.logLevel >= 10:
                    Domoticz.Debug(Message)
                else:
                    Domoticz.Log(Message)
        elif Level < 0 or Level > 10:
            Domoticz.Error(Message)
        return

    def LogError(self, Message):
        self.LogMessage(Message, -1)
        return

    def stringToBase64(self, s):
        return base64.b64encode(s.encode('utf-8')).decode('utf-8')

    def base64ToString(self, b):
        return base64.b64decode(b).decode('utf-8')


<mask token>


def onStart():
    global _plugin
    _plugin.onStart()


def onStop():
    global _plugin
    _plugin.onStop()


<mask token>

<mask token>


class BasePlugin:
    logLevel = 0

    def onStart(self):
        try:
            self.logLevel = int(Parameters['Mode6'])
        except:
            self.LogError("Debuglevel '" + Parameters['Mode6'] +
                "' is not an integer")
        if self.logLevel == 10:
            Domoticz.Debugging(1)
        self.LogMessage('onStart called', 9)
        Domoticz.Heartbeat(int(Parameters['Mode2']))
        if len(Devices) == 0:
            Domoticz.Device(Name='Free space', Unit=1, TypeName='Custom',
                Image=3, Options={'Custom': '1;' + Parameters['Mode1']}
                ).Create()
            Domoticz.Device(Name='Temperature', Unit=2, Type=80, Subtype=5,
                Switchtype=0, Image=0).Create()
        elif 1 in Devices:
            Devices[1].Update(0, '0', Options={'Custom': '1;' + Parameters[
                'Mode1']})
        self.DumpConfigToLog()
        return

    def onStop(self):
        self.LogMessage('onStop called', 9)
        return

    def onConnect(self, Connection, Status, Description):
        self.LogMessage('onConnect ' + Connection.Address + ':' +
            Connection.Port + ' Status: ' + str(Status) + ', Description:' +
            str(Description), 7)
        return

    def onMessage(self, Connection, Data):
        self.DumpVariable(Data, 'OnMessage Data')
        return

    def onCommand(self, Unit, Command, Level, Hue):
        self.LogMessage('onCommand called for Unit ' + str(Unit) +
            ": Parameter '" + str(Command) + "', Level: " + str(Level) +
            ', Hue: ' + str(Hue), 8)
        return

    def onNotification(self, Name, Subject, Text, Status, Priority, Sound,
        ImageFile):
        self.LogMessage('onNotification: ' + Name + ',' + Subject + ',' +
            Text + ',' + Status + ',' + str(Priority) + ',' + Sound + ',' +
            ImageFile, 8)
        return

    def onDisconnect(self, Connection):
        self.LogMessage('onDisconnect ' + Connection.Address + ':' +
            Connection.Port, 7)
        return

    def onHeartbeat(self):
        self.LogMessage('onHeartbeat called', 9)
        try:
            data = os.popen(
                'df -k | grep -vE \'^Filesystem|tmpfs|cdrom\' | awk \'{ print $6 " " $4 }\''
                ).read()
            for line in data.split('\n'):
                koloms = line.split(' ')
                if koloms[0] == '/':
                    size = float(koloms[1])
                    if Parameters['Mode1'] == 'Gb':
                        size = size / 1048576
                    elif Parameters['Mode1'] == 'Mb':
                        size = size / 1024
                    self.UpdateDevice(1, 0, round(size, 1))
                    break
            data = os.popen('cat /sys/class/thermal/thermal_zone0/temp').read()
            temp = round(int(data) / 1000, 1)
            self.UpdateDevice(2, 0, temp)
        except Exception as e:
            self.LogError('OnHeartbeat Error: ' + str(e))
        return

    def StringToMinutes(self, value):
        splitted = value.split(':')
        if len(splitted) >= 2:
            minutes = int(splitted[len(splitted) - 1]) + int(splitted[len(
                splitted) - 2]) * 60
        else:
            minutes = int(splitted[0])
        return minutes

    def UpdateDevice(self, Unit, nValue, sValue1, sValue2=None):
        if Unit in Devices:
            if sValue2 is None:
                sValue = str(sValue1)
            else:
                sValue = str(sValue1) + ';' + str(sValue2)
            if Devices[Unit].nValue != nValue or Devices[Unit
                ].sValue != sValue:
                self.LogMessage('Update [' + Devices[Unit].Name +
                    "] from: ('" + str(Devices[Unit].nValue) + ":'" + str(
                    Devices[Unit].sValue) + "') to: (" + str(nValue) + ":'" +
                    str(sValue) + "')", 5)
                Devices[Unit].Update(nValue, sValue)
        return

    def DumpDeviceToLog(self, Unit):
        self.LogMessage(str(Devices[Unit].ID) + ':' + Devices[Unit].Name +
            ', (n:' + str(Devices[Unit].nValue) + ', s:' + Devices[Unit].
            sValue + ', Sgl:' + str(Devices[Unit].SignalLevel) + ', bl:' +
            str(Devices[Unit].BatteryLevel) + ', img:' + str(Devices[Unit].
            Image) + ', typ:' + str(Devices[Unit].Type) + ', styp:' + str(
            Devices[Unit].SubType) + ')', 6)
        return

    def DumpConfigToLog(self):
        for x in Parameters:
            if Parameters[x] != '':
                self.LogMessage("'" + x + "':'" + str(Parameters[x]) + "'", 7)
        self.LogMessage('Device count: ' + str(len(Devices)), 6)
        for x in Devices:
            self.DumpDeviceToLog(x)
        return

    def DumpVariable(self, Item, Varname, Level=5, BytesAsStr=False, Prefix=''
        ):
        if self.logLevel >= Level:
            Prefix = str(Prefix)
            if isinstance(Item, dict):
                self.LogMessage(Prefix + str(Varname) + ' (' + type(Item).
                    __name__ + '[' + str(len(Item)) + ']): ', Level)
                if len(Prefix) < 3:
                    Prefix = '--> '
                else:
                    Prefix = '--' + Prefix
                for b in Item:
                    if isinstance(b, str):
                        self.DumpVariable(Item[b], "'" + str(b) + "'",
                            Level, BytesAsStr, Prefix)
                    else:
                        self.DumpVariable(Item[b], str(b), Level,
                            BytesAsStr, Prefix)
            elif isinstance(Item, (bytes, bytearray)):
                if BytesAsStr:
                    txt = html.escape(Item.decode('utf-8', 'ignore'))
                else:
                    txt = '[ '
                    for b in Item:
                        txt += str(hex(b)) + ' '
                    txt += ']'
                self.LogMessage(Prefix + str(Varname) + ' (' + type(Item).
                    __name__ + '[' + str(len(Item)) + ']): ' + txt, Level)
            elif isinstance(Item, (tuple, list)):
                self.LogMessage(Prefix + str(Varname) + ' (' + type(Item).
                    __name__ + '[' + str(len(Item)) + ']): ', Level)
                if len(Prefix) < 3:
                    Prefix = '--> '
                else:
                    Prefix = '--' + Prefix
                idx = 0
                for b in Item:
                    self.DumpVariable(b, '[' + str(idx) + ']', Level,
                        BytesAsStr, Prefix)
                    idx = idx + 1
            elif isinstance(Item, str):
                self.LogMessage(Prefix + str(Varname) + ' (' + type(Item).
                    __name__ + '[' + str(len(Item)) + "]): '" + Item + "'",
                    Level)
            else:
                self.LogMessage(Prefix + str(Varname) + ' (' + type(Item).
                    __name__ + '): ' + str(Item), Level)
        return

    def LogMessage(self, Message, Level):
        if Level > 0:
            if self.logLevel >= Level:
                if self.logLevel >= 10:
                    Domoticz.Debug(Message)
                else:
                    Domoticz.Log(Message)
        elif Level < 0 or Level > 10:
            Domoticz.Error(Message)
        return

    def LogError(self, Message):
        self.LogMessage(Message, -1)
        return

    def stringToBase64(self, s):
        return base64.b64encode(s.encode('utf-8')).decode('utf-8')

    def base64ToString(self, b):
        return base64.b64decode(b).decode('utf-8')


<mask token>


def onStart():
    global _plugin
    _plugin.onStart()


def onStop():
    global _plugin
    _plugin.onStop()


<mask token>


def onDisconnect(Connection):
    global _plugin
    _plugin.onDisconnect(Connection)


def onHeartbeat():
    global _plugin
    _plugin.onHeartbeat()

<mask token>


class BasePlugin:
    logLevel = 0

    def onStart(self):
        try:
            self.logLevel = int(Parameters['Mode6'])
        except:
            self.LogError("Debuglevel '" + Parameters['Mode6'] +
                "' is not an integer")
        if self.logLevel == 10:
            Domoticz.Debugging(1)
        self.LogMessage('onStart called', 9)
        Domoticz.Heartbeat(int(Parameters['Mode2']))
        if len(Devices) == 0:
            Domoticz.Device(Name='Free space', Unit=1, TypeName='Custom',
                Image=3, Options={'Custom': '1;' + Parameters['Mode1']}
                ).Create()
            Domoticz.Device(Name='Temperature', Unit=2, Type=80, Subtype=5,
                Switchtype=0, Image=0).Create()
        elif 1 in Devices:
            Devices[1].Update(0, '0', Options={'Custom': '1;' + Parameters[
                'Mode1']})
        self.DumpConfigToLog()
        return

    def onStop(self):
        self.LogMessage('onStop called', 9)
        return

    def onConnect(self, Connection, Status, Description):
        self.LogMessage('onConnect ' + Connection.Address + ':' +
            Connection.Port + ' Status: ' + str(Status) + ', Description:' +
            str(Description), 7)
        return

    def onMessage(self, Connection, Data):
        self.DumpVariable(Data, 'OnMessage Data')
        return

    def onCommand(self, Unit, Command, Level, Hue):
        self.LogMessage('onCommand called for Unit ' + str(Unit) +
            ": Parameter '" + str(Command) + "', Level: " + str(Level) +
            ', Hue: ' + str(Hue), 8)
        return

    def onNotification(self, Name, Subject, Text, Status, Priority, Sound,
        ImageFile):
        self.LogMessage('onNotification: ' + Name + ',' + Subject + ',' +
            Text + ',' + Status + ',' + str(Priority) + ',' + Sound + ',' +
            ImageFile, 8)
        return

    def onDisconnect(self, Connection):
        self.LogMessage('onDisconnect ' + Connection.Address + ':' +
            Connection.Port, 7)
        return

    def onHeartbeat(self):
        self.LogMessage('onHeartbeat called', 9)
        try:
            data = os.popen(
                'df -k | grep -vE \'^Filesystem|tmpfs|cdrom\' | awk \'{ print $6 " " $4 }\''
                ).read()
            for line in data.split('\n'):
                koloms = line.split(' ')
                if koloms[0] == '/':
                    size = float(koloms[1])
                    if Parameters['Mode1'] == 'Gb':
                        size = size / 1048576
                    elif Parameters['Mode1'] == 'Mb':
                        size = size / 1024
                    self.UpdateDevice(1, 0, round(size, 1))
                    break
            data = os.popen('cat /sys/class/thermal/thermal_zone0/temp').read()
            temp = round(int(data) / 1000, 1)
            self.UpdateDevice(2, 0, temp)
        except Exception as e:
            self.LogError('OnHeartbeat Error: ' + str(e))
        return

    def StringToMinutes(self, value):
        splitted = value.split(':')
        if len(splitted) >= 2:
            minutes = int(splitted[len(splitted) - 1]) + int(splitted[len(
                splitted) - 2]) * 60
        else:
            minutes = int(splitted[0])
        return minutes

    def UpdateDevice(self, Unit, nValue, sValue1, sValue2=None):
        if Unit in Devices:
            if sValue2 is None:
                sValue = str(sValue1)
            else:
                sValue = str(sValue1) + ';' + str(sValue2)
            if Devices[Unit].nValue != nValue or Devices[Unit
                ].sValue != sValue:
                self.LogMessage('Update [' + Devices[Unit].Name +
                    "] from: ('" + str(Devices[Unit].nValue) + ":'" + str(
                    Devices[Unit].sValue) + "') to: (" + str(nValue) + ":'" +
                    str(sValue) + "')", 5)
                Devices[Unit].Update(nValue, sValue)
        return

    def DumpDeviceToLog(self, Unit):
        self.LogMessage(str(Devices[Unit].ID) + ':' + Devices[Unit].Name +
            ', (n:' + str(Devices[Unit].nValue) + ', s:' + Devices[Unit].
            sValue + ', Sgl:' + str(Devices[Unit].SignalLevel) + ', bl:' +
            str(Devices[Unit].BatteryLevel) + ', img:' + str(Devices[Unit].
            Image) + ', typ:' + str(Devices[Unit].Type) + ', styp:' + str(
            Devices[Unit].SubType) + ')', 6)
        return

    def DumpConfigToLog(self):
        for x in Parameters:
            if Parameters[x] != '':
                self.LogMessage("'" + x + "':'" + str(Parameters[x]) + "'", 7)
        self.LogMessage('Device count: ' + str(len(Devices)), 6)
        for x in Devices:
            self.DumpDeviceToLog(x)
        return

    def DumpVariable(self, Item, Varname, Level=5, BytesAsStr=False, Prefix=''
        ):
        if self.logLevel >= Level:
            Prefix = str(Prefix)
            if isinstance(Item, dict):
                self.LogMessage(Prefix + str(Varname) + ' (' + type(Item).
                    __name__ + '[' + str(len(Item)) + ']): ', Level)
                if len(Prefix) < 3:
                    Prefix = '--> '
                else:
                    Prefix = '--' + Prefix
                for b in Item:
                    if isinstance(b, str):
                        self.DumpVariable(Item[b], "'" + str(b) + "'",
                            Level, BytesAsStr, Prefix)
                    else:
                        self.DumpVariable(Item[b], str(b), Level,
                            BytesAsStr, Prefix)
            elif isinstance(Item, (bytes, bytearray)):
                if BytesAsStr:
                    txt = html.escape(Item.decode('utf-8', 'ignore'))
                else:
                    txt = '[ '
                    for b in Item:
                        txt += str(hex(b)) + ' '
                    txt += ']'
                self.LogMessage(Prefix + str(Varname) + ' (' + type(Item).
                    __name__ + '[' + str(len(Item)) + ']): ' + txt, Level)
            elif isinstance(Item, (tuple, list)):
                self.LogMessage(Prefix + str(Varname) + ' (' + type(Item).
                    __name__ + '[' + str(len(Item)) + ']): ', Level)
                if len(Prefix) < 3:
                    Prefix = '--> '
                else:
                    Prefix = '--' + Prefix
                idx = 0
                for b in Item:
                    self.DumpVariable(b, '[' + str(idx) + ']', Level,
                        BytesAsStr, Prefix)
                    idx = idx + 1
            elif isinstance(Item, str):
                self.LogMessage(Prefix + str(Varname) + ' (' + type(Item).
                    __name__ + '[' + str(len(Item)) + "]): '" + Item + "'",
                    Level)
            else:
                self.LogMessage(Prefix + str(Varname) + ' (' + type(Item).
                    __name__ + '): ' + str(Item), Level)
        return

    def LogMessage(self, Message, Level):
        if Level > 0:
            if self.logLevel >= Level:
                if self.logLevel >= 10:
                    Domoticz.Debug(Message)
                else:
                    Domoticz.Log(Message)
        elif Level < 0 or Level > 10:
            Domoticz.Error(Message)
        return

    def LogError(self, Message):
        self.LogMessage(Message, -1)
        return

    def stringToBase64(self, s):
        return base64.b64encode(s.encode('utf-8')).decode('utf-8')

    def base64ToString(self, b):
        return base64.b64decode(b).decode('utf-8')


global _plugin
<mask token>


def onStart():
    global _plugin
    _plugin.onStart()


def onStop():
    global _plugin
    _plugin.onStop()


def onConnect(Connection, Status, Description):
    global _plugin
    _plugin.onConnect(Connection, Status, Description)


def onMessage(Connection, Data):
    global _plugin
    _plugin.onMessage(Connection, Data)


def onCommand(Unit, Command, Level, Hue):
    global _plugin
    _plugin.onCommand(Unit, Command, Level, Hue)


def onNotification(Name, Subject, Text, Status, Priority, Sound, ImageFile):
    global _plugin
    _plugin.onNotification(Name, Subject, Text, Status, Priority, Sound,
        ImageFile)


def onDisconnect(Connection):
    global _plugin
    _plugin.onDisconnect(Connection)


def onHeartbeat():
    global _plugin
    _plugin.onHeartbeat()

<mask token>


class BasePlugin:
    logLevel = 0

    def onStart(self):
        try:
            self.logLevel = int(Parameters['Mode6'])
        except:
            self.LogError("Debuglevel '" + Parameters['Mode6'] +
                "' is not an integer")
        if self.logLevel == 10:
            Domoticz.Debugging(1)
        self.LogMessage('onStart called', 9)
        Domoticz.Heartbeat(int(Parameters['Mode2']))
        if len(Devices) == 0:
            Domoticz.Device(Name='Free space', Unit=1, TypeName='Custom',
                Image=3, Options={'Custom': '1;' + Parameters['Mode1']}
                ).Create()
            Domoticz.Device(Name='Temperature', Unit=2, Type=80, Subtype=5,
                Switchtype=0, Image=0).Create()
        elif 1 in Devices:
            Devices[1].Update(0, '0', Options={'Custom': '1;' + Parameters[
                'Mode1']})
        self.DumpConfigToLog()
        return

    def onStop(self):
        self.LogMessage('onStop called', 9)
        return

    def onConnect(self, Connection, Status, Description):
        self.LogMessage('onConnect ' + Connection.Address + ':' +
            Connection.Port + ' Status: ' + str(Status) + ', Description:' +
            str(Description), 7)
        return

    def onMessage(self, Connection, Data):
        self.DumpVariable(Data, 'OnMessage Data')
        return

    def onCommand(self, Unit, Command, Level, Hue):
        self.LogMessage('onCommand called for Unit ' + str(Unit) +
            ": Parameter '" + str(Command) + "', Level: " + str(Level) +
            ', Hue: ' + str(Hue), 8)
        return

    def onNotification(self, Name, Subject, Text, Status, Priority, Sound,
        ImageFile):
        self.LogMessage('onNotification: ' + Name + ',' + Subject + ',' +
            Text + ',' + Status + ',' + str(Priority) + ',' + Sound + ',' +
            ImageFile, 8)
        return

    def onDisconnect(self, Connection):
        self.LogMessage('onDisconnect ' + Connection.Address + ':' +
            Connection.Port, 7)
        return

    def onHeartbeat(self):
        self.LogMessage('onHeartbeat called', 9)
        try:
            data = os.popen(
                'df -k | grep -vE \'^Filesystem|tmpfs|cdrom\' | awk \'{ print $6 " " $4 }\''
                ).read()
            for line in data.split('\n'):
                koloms = line.split(' ')
                if koloms[0] == '/':
                    size = float(koloms[1])
                    if Parameters['Mode1'] == 'Gb':
                        size = size / 1048576
                    elif Parameters['Mode1'] == 'Mb':
                        size = size / 1024
                    self.UpdateDevice(1, 0, round(size, 1))
                    break
            data = os.popen('cat /sys/class/thermal/thermal_zone0/temp').read()
            temp = round(int(data) / 1000, 1)
            self.UpdateDevice(2, 0, temp)
        except Exception as e:
            self.LogError('OnHeartbeat Error: ' + str(e))
        return

    def StringToMinutes(self, value):
        splitted = value.split(':')
        if len(splitted) >= 2:
            minutes = int(splitted[len(splitted) - 1]) + int(splitted[len(
                splitted) - 2]) * 60
        else:
            minutes = int(splitted[0])
        return minutes

    def UpdateDevice(self, Unit, nValue, sValue1, sValue2=None):
        if Unit in Devices:
            if sValue2 is None:
                sValue = str(sValue1)
            else:
                sValue = str(sValue1) + ';' + str(sValue2)
            if Devices[Unit].nValue != nValue or Devices[Unit
                ].sValue != sValue:
                self.LogMessage('Update [' + Devices[Unit].Name +
                    "] from: ('" + str(Devices[Unit].nValue) + ":'" + str(
                    Devices[Unit].sValue) + "') to: (" + str(nValue) + ":'" +
                    str(sValue) + "')", 5)
                Devices[Unit].Update(nValue, sValue)
        return

    def DumpDeviceToLog(self, Unit):
        self.LogMessage(str(Devices[Unit].ID) + ':' + Devices[Unit].Name +
            ', (n:' + str(Devices[Unit].nValue) + ', s:' + Devices[Unit].
            sValue + ', Sgl:' + str(Devices[Unit].SignalLevel) + ', bl:' +
            str(Devices[Unit].BatteryLevel) + ', img:' + str(Devices[Unit].
            Image) + ', typ:' + str(Devices[Unit].Type) + ', styp:' + str(
            Devices[Unit].SubType) + ')', 6)
        return

    def DumpConfigToLog(self):
        for x in Parameters:
            if Parameters[x] != '':
                self.LogMessage("'" + x + "':'" + str(Parameters[x]) + "'", 7)
        self.LogMessage('Device count: ' + str(len(Devices)), 6)
        for x in Devices:
            self.DumpDeviceToLog(x)
        return

    def DumpVariable(self, Item, Varname, Level=5, BytesAsStr=False, Prefix=''
        ):
        if self.logLevel >= Level:
            Prefix = str(Prefix)
            if isinstance(Item, dict):
                self.LogMessage(Prefix + str(Varname) + ' (' + type(Item).
                    __name__ + '[' + str(len(Item)) + ']): ', Level)
                if len(Prefix) < 3:
                    Prefix = '--> '
                else:
                    Prefix = '--' + Prefix
                for b in Item:
                    if isinstance(b, str):
                        self.DumpVariable(Item[b], "'" + str(b) + "'",
                            Level, BytesAsStr, Prefix)
                    else:
                        self.DumpVariable(Item[b], str(b), Level,
                            BytesAsStr, Prefix)
            elif isinstance(Item, (bytes, bytearray)):
                if BytesAsStr:
                    txt = html.escape(Item.decode('utf-8', 'ignore'))
                else:
                    txt = '[ '
                    for b in Item:
                        txt += str(hex(b)) + ' '
                    txt += ']'
                self.LogMessage(Prefix + str(Varname) + ' (' + type(Item).
                    __name__ + '[' + str(len(Item)) + ']): ' + txt, Level)
            elif isinstance(Item, (tuple, list)):
                self.LogMessage(Prefix + str(Varname) + ' (' + type(Item).
                    __name__ + '[' + str(len(Item)) + ']): ', Level)
                if len(Prefix) < 3:
                    Prefix = '--> '
                else:
                    Prefix = '--' + Prefix
                idx = 0
                for b in Item:
                    self.DumpVariable(b, '[' + str(idx) + ']', Level,
                        BytesAsStr, Prefix)
                    idx = idx + 1
            elif isinstance(Item, str):
                self.LogMessage(Prefix + str(Varname) + ' (' + type(Item).
                    __name__ + '[' + str(len(Item)) + "]): '" + Item + "'",
                    Level)
            else:
                self.LogMessage(Prefix + str(Varname) + ' (' + type(Item).
                    __name__ + '): ' + str(Item), Level)
        return

    def LogMessage(self, Message, Level):
        if Level > 0:
            if self.logLevel >= Level:
                if self.logLevel >= 10:
                    Domoticz.Debug(Message)
                else:
                    Domoticz.Log(Message)
        elif Level < 0 or Level > 10:
            Domoticz.Error(Message)
        return

    def LogError(self, Message):
        self.LogMessage(Message, -1)
        return

    def stringToBase64(self, s):
        return base64.b64encode(s.encode('utf-8')).decode('utf-8')

    def base64ToString(self, b):
        return base64.b64decode(b).decode('utf-8')


global _plugin
_plugin = BasePlugin()


def onStart():
    global _plugin
    _plugin.onStart()


def onStop():
    global _plugin
    _plugin.onStop()


def onConnect(Connection, Status, Description):
    global _plugin
    _plugin.onConnect(Connection, Status, Description)


def onMessage(Connection, Data):
    global _plugin
    _plugin.onMessage(Connection, Data)


def onCommand(Unit, Command, Level, Hue):
    global _plugin
    _plugin.onCommand(Unit, Command, Level, Hue)


def onNotification(Name, Subject, Text, Status, Priority, Sound, ImageFile):
    global _plugin
    _plugin.onNotification(Name, Subject, Text, Status, Priority, Sound,
        ImageFile)


def onDisconnect(Connection):
    global _plugin
    _plugin.onDisconnect(Connection)


def onHeartbeat():
    global _plugin
    _plugin.onHeartbeat()

# Raspberry Pi Disk Usage
#
# Description: Reports temperature and free disk space
#
# Author: elgringo
#
# History:
# 1.0.0   01-07-2017  Initial version
# 1.0.1   31-07-2017  Updated with new API

"""
<plugin key="RaspberryInfo" name="System Status" author="elgringo" version="1.0.1" externallink="https://github.com/ericstaal/domoticz/blob/master/">
  <params>
    <param field="Mode1" label="Size" width="50px" required="true">
      <options>
        <option label="Kb" value="Kb" />
        <option label="Mb" value="Mb" />
        <option label="Gb" value="Gb" default="true"/>
      </options>
    </param>
    <param field="Mode2" label="Heartbeat interval" width="50px" required="true">
      <options>
        <option label="20" value="10" />
        <option label="20" value="20" />
        <option label="30" value="30" />
        <option label="60" value="60" default="true"/>
      </options>
    </param>
    <param field="Mode6" label="Debug level" width="150px">
      <options>
        <option label="0 (No logging)" value="0" default="true"/>
        <option label="1" value="1"/> 
        <option label="2" value="2"/>
        <option label="3" value="3"/>
        <option label="4" value="4"/>
        <option label="5" value="5"/>
        <option label="6" value="6"/>
        <option label="7" value="7"/>
        <option label="8" value="8"/>
        <option label="9 (all)" value="9"/>
        <option label="10 (all with debug)" value="10"/>
      </options>
    </param>
  </params>
</plugin>
"""

import Domoticz
import collections 
import base64
import binascii
import html

# additional imports
import os

class BasePlugin:
  logLevel = 0                # logLevel
 
  def onStart(self):
    try:
      self.logLevel = int(Parameters["Mode6"])
    except:
      self.LogError("Debuglevel '"+Parameters["Mode6"]+"' is not an integer")
      
    if self.logLevel == 10:
      Domoticz.Debugging(1)
    self.LogMessage("onStart called", 9)
    
    Domoticz.Heartbeat(int(Parameters["Mode2"]))
      
    if (len(Devices) == 0):
      Domoticz.Device(Name="Free space", Unit=1, TypeName="Custom", Image=3, Options={"Custom": ("1;" + Parameters["Mode1"])}).Create()
      Domoticz.Device(Name="Temperature", Unit=2, Type=80, Subtype=5, Switchtype=0, Image=0).Create()
    elif 1 in Devices:
      Devices[1].Update(0, "0", Options={"Custom": ("1;" + Parameters["Mode1"])})
      
    self.DumpConfigToLog()
    
    return

  def onStop(self):
    self.LogMessage("onStop called", 9)
    
    return

  def onConnect(self, Connection, Status, Description):
    self.LogMessage("onConnect "+Connection.Address+":"+Connection.Port+" Status: "+ str(Status)+", Description:"+str(Description), 7)

    return

  def onMessage(self, Connection, Data):
    self.DumpVariable(Data, "OnMessage Data")

    return

  def onCommand(self, Unit, Command, Level, Hue):
    self.LogMessage("onCommand called for Unit " + str(Unit) + ": Parameter '" + str(Command) + "', Level: " + str(Level)+", Hue: " + str(Hue), 8)
    
    return

  def onNotification(self, Name, Subject, Text, Status, Priority, Sound, ImageFile):
    self.LogMessage("onNotification: " + Name + "," + Subject + "," + Text + "," + Status + "," + str(Priority) + "," + Sound + "," + ImageFile, 8)
    
    return

  def onDisconnect(self, Connection):
    self.LogMessage("onDisconnect "+Connection.Address+":"+Connection.Port, 7)

    return

  def onHeartbeat(self):
    self.LogMessage("onHeartbeat called", 9)
    try:
      # size
      data = os.popen("df -k | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{ print $6 \" \" $4 }'").read()
      # / 1.5g
      # /boot ...
      for line in data.split("\n"):
        koloms = line.split(' ')
        if koloms[0] == '/':
          size = float(koloms[1])
          
          if Parameters["Mode1"] == "Gb":
            size = size / 1048576
          elif Parameters["Mode1"] == "Mb":
            size = size / 1024
          
          self.UpdateDevice(1, 0, round(size,1))
          break 
      
      # temperature
      data = os.popen("cat /sys/class/thermal/thermal_zone0/temp").read()    
      temp = round(int(data) / 1000,1)
      self.UpdateDevice(2, 0, temp)
        
    except Exception as e:
      self.LogError("OnHeartbeat Error: "+ str(e))
      
    return

####################### Specific helper functions for plugin #######################  

####################### Generic helper member functions for plugin ####################### 
  def StringToMinutes(self, value):
    # hh:mm
    splitted = value.split(":")
    if len(splitted) >= 2:
      minutes = int(splitted[len(splitted)-1]) + int(splitted[len(splitted)-2])*60
    else:
      minutes = int(splitted[0])
    return minutes  
   
  def UpdateDevice(self, Unit, nValue, sValue1, sValue2 = None):
    # Make sure that the Domoticz device still exists (they can be deleted) before updating it 
    if (Unit in Devices):
      if sValue2 is None:
        sValue = str(sValue1)
      else:
        sValue = str(sValue1)+";"+str(sValue2)
        
      if (Devices[Unit].nValue != nValue) or (Devices[Unit].sValue != sValue):
        self.LogMessage("Update ["+Devices[Unit].Name+"] from: ('"+str(Devices[Unit].nValue)+":'"+str(Devices[Unit].sValue )+"') to: ("+str(nValue)+":'"+str(sValue)+"')", 5)
        Devices[Unit].Update(nValue, sValue)
    return
   
  def DumpDeviceToLog(self,Unit):
    self.LogMessage(str(Devices[Unit].ID)+":"+Devices[Unit].Name+", (n:"+str(Devices[Unit].nValue)+", s:"+Devices[Unit].sValue+", Sgl:"+str(Devices[Unit].SignalLevel)+", bl:"+str(Devices[Unit].BatteryLevel)+", img:"+ str(Devices[Unit].Image)+", typ:"+ str(Devices[Unit].Type)+", styp:"+ str(Devices[Unit].SubType)+")", 6)
    return   
    
  def DumpConfigToLog(self):
    for x in Parameters:
      if Parameters[x] != "":
        self.LogMessage( "'" + x + "':'" + str(Parameters[x]) + "'", 7)
    self.LogMessage("Device count: " + str(len(Devices)), 6)
    for x in Devices:
      self.DumpDeviceToLog(x)
    return
    
  def DumpVariable(self, Item, Varname, Level = 5, BytesAsStr = False, Prefix=""):
    if self.logLevel >= Level:
      Prefix = str(Prefix)
      if isinstance(Item, dict):
        self.LogMessage(Prefix + str(Varname) + " ("+type(Item).__name__+"["+str(len(Item))+"]): ", Level)
        
        if len(Prefix) < 3:
          Prefix = "--> "
        else:
          Prefix = "--" + Prefix
          
        for b in Item:
          if isinstance(b, str):
            self.DumpVariable( Item[b], "'"+str(b) + "'", Level, BytesAsStr, Prefix)
          else:
            self.DumpVariable( Item[b], str(b), Level, BytesAsStr, Prefix)
         
      elif isinstance(Item, (bytes, bytearray)):
        if BytesAsStr:
          txt = html.escape(Item.decode("utf-8", "ignore"))
        else:
          txt = "[ " 
          for b in Item:
            txt += str(hex(b))+" "
          txt +=  "]"
        
        self.LogMessage(Prefix + str(Varname) + " ("+type(Item).__name__+"["+str(len(Item))+"]): " + txt, Level)
      elif isinstance(Item, (tuple, list)):
        self.LogMessage(Prefix + str(Varname) + " ("+type(Item).__name__+"["+str(len(Item))+"]): ", Level)
        
        if len(Prefix) < 3:
          Prefix = "--> "
        else:
          Prefix = "--" + Prefix
          
        idx = 0
        for b in Item:
          self.DumpVariable( b, "["+str(idx) + "]", Level, BytesAsStr, Prefix)
          idx=idx+1

      elif isinstance(Item, str):
        self.LogMessage(Prefix + str(Varname) + " ("+type(Item).__name__+"["+str(len(Item))+"]): '"+Item+"'", Level)
      else:
        self.LogMessage(Prefix + str(Varname) + " ("+type(Item).__name__+"): "+str(Item), Level)
           
    return

  def LogMessage(self, Message, Level):
    if Level > 0:
      if self.logLevel >= Level:
        if self.logLevel >= 10:
          Domoticz.Debug(Message)
        else:
          Domoticz.Log(Message)
    elif (Level < 0) or (Level > 10):
      Domoticz.Error(Message)
      
    return
    
  def LogError(self, Message):
    self.LogMessage(Message, -1)
    return  
    
  def stringToBase64(self, s):
    return base64.b64encode(s.encode('utf-8')).decode("utf-8")

  def base64ToString(self, b):
    return base64.b64decode(b).decode('utf-8')    
    
####################### Global functions for plugin #######################
global _plugin
_plugin = BasePlugin()

def onStart():
  global _plugin
  _plugin.onStart()

def onStop():
  global _plugin
  _plugin.onStop()

def onConnect(Connection, Status, Description):
  global _plugin
  _plugin.onConnect(Connection, Status, Description)

def onMessage(Connection, Data):
  global _plugin
  _plugin.onMessage(Connection, Data)

def onCommand(Unit, Command, Level, Hue):
  global _plugin
  _plugin.onCommand(Unit, Command, Level, Hue)

def onNotification(Name, Subject, Text, Status, Priority, Sound, ImageFile):
  global _plugin
  _plugin.onNotification(Name, Subject, Text, Status, Priority, Sound, ImageFile)

def onDisconnect(Connection):
  global _plugin
  _plugin.onDisconnect(Connection)

def onHeartbeat():
  global _plugin
  _plugin.onHeartbeat()

