#####################################################
# SmartHome Monitor Plugin for Enigma2 Dreamboxes
# Coded by Homey (c) 2014
#
# Version: 0.3
# Support: www.dreambox-plugins.de
#####################################################
from Components.ActionMap import ActionMap
from Components.AVSwitch import AVSwitch
from Components.Button import Button
from Components.config import config, configfile, ConfigSelection, ConfigPassword, ConfigSubsection, ConfigText, getConfigListEntry
from Components.ConfigList import ConfigList, ConfigListScreen
from Components.Label import Label
from Components.MenuList import MenuList
from Components.MultiContent import MultiContentEntryText, MultiContentEntryPixmapAlphaTest
from Components.Pixmap import Pixmap
from Components.Sources.List import List
from Components.Sources.StaticText import StaticText
from enigma import eTimer, ePicLoad, eRect, loadPNG, eListboxPythonMultiContent, gFont #@UnresolvedImport # pylint: disable=E0611
from Plugins.Plugin import PluginDescriptor
from Screens.MessageBox import MessageBox
from Screens.Screen import Screen

from twisted.web.client import getPage
from xml.dom.minidom import parse, parseString
from urllib import quote, quote_plus, unquote, unquote_plus, urlencode

from . import _, __ #@UnresolvedImport # pylint: disable=W0611,F0401

from pygooglechart import Chart
from pygooglechart import SimpleLineChart
from pygooglechart import Axis

import re, time, hashlib
import xml.etree.ElementTree as ET
import json
import math

config.plugins.fritzsmarthome = ConfigSubsection()
config.plugins.fritzsmarthome.hostname = ConfigText(default="fritz.box", fixed_size=False)
config.plugins.fritzsmarthome.username = ConfigText(default="BoxAdmin", fixed_size=False)
config.plugins.fritzsmarthome.password = ConfigPassword(default="", fixed_size=False)
config.plugins.fritzsmarthome.statsType = ConfigSelection([("EnergyStats_10", _("Last 10 min")),("EnergyStats_hour", _("Last 60 min")),("EnergyStats_24h", _("Last 24 hrs")),("EnergyStats_month", _("Last 31 days")),("EnergyStats_year", _("Last 365 days"))], "EnergyStats_hour")

import logging
logger = logging.getLogger("SmartHomeMonitor")
logger.setLevel(int(config.plugins.FritzCall.debug.value))
fileHandler = logging.FileHandler('/tmp/SmartHomeMonitor.log', mode='w')
fileHandler.setFormatter(logging.Formatter('%(asctime)s %(levelname)-8s %(name)-26s %(funcName)s %(message)-15s', '%Y-%m-%d %H:%M:%S'))
logger.addHandler(fileHandler)

debug = logger.debug
info = logger.info
warn = logger.warn
error = logger.error
exception = logger.exception

USERAGENT="Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36"

#################################
###     SetPixMap Function    ###
#################################

def setPixmap(dest, ptr):
	pic_scale_size = ptr.scaleSize()

	if pic_scale_size.isValid():
		pic_size = ptr.size()
		pic_width = pic_size.width()
		pic_height = pic_size.height()

		dest_size = dest.getSize()
		dest_width = dest_size.width()
		dest_height = dest_size.height()

		pic_scale_width = pic_scale_size.width()
		pic_scale_height = pic_scale_size.height()

		if pic_scale_width == dest_width:
			dest_rect = eRect(0, (dest_height - pic_scale_height) / 2, pic_scale_width, pic_scale_height)
		else:
			dest_rect = eRect((dest_width - pic_scale_width) / 2, 0, pic_scale_width, pic_scale_height)

		dest.instance.setScale(1)
		dest.instance.setScaleDest(dest_rect)
	else:
		dest.instance.setScale(0)
	dest.instance.setPixmap(ptr.__deref__())
	
#AdapaterList
class AdapaterList(MenuList):
	def __init__(self, list, enableWrapAround=False):
		MenuList.__init__(self, list, enableWrapAround, eListboxPythonMultiContent)
		self.l.setFont(0, gFont("Regular", 22))
		self.l.setFont(1, gFont("Regular", 18))
		self.l.setItemHeight(55)

def AdapaterEntryComponent(adapterInfo, description):
	adapterId = int(adapterInfo[0])
	adapterName = adapterInfo[1]
	adapterAIN = adapterInfo[2]
	adapterMode = adapterInfo[3]
	adapterSwitchState = int(adapterInfo[4])
	adapterTemperature = str(adapterInfo[5])
	
	res = [ (adapterId, adapterName, adapterAIN, adapterMode, adapterSwitchState, adapterTemperature) ]

	if adapterSwitchState == 1:
		status_img = "/usr/share/enigma2/skin_default/buttons/button_green.png"
	else:
		status_img = "/usr/share/enigma2/skin_default/buttons/button_green_off.png"
	
	res.append(MultiContentEntryPixmapAlphaTest(pos=(15, 15), size=(15, 16), png=loadPNG(status_img)))
	res.append(MultiContentEntryText(pos=(50, 5), size=(350, 30), font=0, text=adapterName))
	res.append(MultiContentEntryText(pos=(50, 30), size=(350, 25), font=1, text=description))
	
	return res
	
##########################################################

class SmartHomeMonitorMain(Screen):

	skin = """
	<screen position="center,center" size="700,440" title="Smart Home Monitor">
		<widget name="adapterlist" position="10,10" zPosition="1" size="400,390" scrollbarMode="showOnDemand" />
		<widget name="adapterinfo" position="430,10" size="250,250" zPosition="2" font="Regular;16" noWrap="1" foregroundColor="#ffffff" transparent="1" />
		<widget name="adapterchart" position="430,235" zPosition="2" size="250,150" alphatest="on" />
		<widget name="info" position="30,380" size="370,20" zPosition="2" font="Regular;18" noWrap="1" foregroundColor="#ffffff" transparent="1" valign="center" />
		<ePixmap name="red"    position="20,400"   zPosition="3" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
		<ePixmap name="green"  position="160,400" zPosition="3" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
		<ePixmap name="yellow" position="300,400" zPosition="3" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
		<ePixmap name="blue"   position="440,400" zPosition="3" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
		<widget name="key_red" position="20,400" zPosition="4" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
		<widget name="key_green" position="160,400" zPosition="4" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
		<widget name="key_yellow" position="300,400" zPosition="4" size="140,40" valign="center" halign="center"  font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
		<widget name="key_blue" position="440,400" zPosition="4" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
	</screen>"""
	
	def __init__(self, session):
		Screen.__init__(self, session)
		
		self.session = session

		self["key_red"] = Button("Turn Off")
		self["key_green"] = Button("Turn On")
		self["key_yellow"] = Button("Refresh")
		self["key_blue"] = Button("Settings")
		
		self["actions"] = ActionMap(["OkCancelActions" , "ColorActions"],
		{
			"ok": self.okClicked,
			"red": self.switchOff,
			"green": self.switchOn,
			"yellow": self.getAdapterList,
			"blue": self.settingsMenu,
			"cancel": self.close
		}, -1)
		
		self.md5Sid = None
		self.fbChallengeId = None
		self.fbTriedLogin = False
		self.adapterlist = []
		self.adapterCount = 0
		self.statsTotalPower = 0
		self.statsTotalAmp = 0
		self.requestCount = 0

		self["adapterlist"] = AdapaterList([])
		self["adapterlist"].onSelectionChanged.append(self.getAdapterStats)
		self["adapterinfo"] = Label()
		self["adapterchart"] = Pixmap()
		self["info"] = Label()
		
		self.RefreshTimer = eTimer()
		self.RefreshTimer.callback.append(self.getAdapterList)
		
		# Get FrameBuffer Scale for ePicLoad()
		sc = AVSwitch().getFramebufferScale()
		
		# Init ePicLoad
		self.picload = ePicLoad()
		self.picload.PictureData.get().append(self.showChartGraph)
		self.picload.setPara((250, 150, sc[0], sc[1], 0, 1, "#00000000"))

		self.onLayoutFinish.append(self._login)

	# TODO: does not work with newer FW
	def _login(self):
		# http://fritz.box/login_lua.xml
		url = "http://%s/login_sid.lua" % (config.plugins.fritzsmarthome.hostname.value)
		debug(time.ctime() + " :"+ url)
		getPage(url,
			method="GET",
			agent=USERAGENT,
			headers={'Content-Type': "application/x-www-form-urlencoded"}
			).addCallback(self._md5Login).addErrback(self._errorLogin)

	def _md5Login(self, sidXml):
		def buildResponse(challenge, text):
			debug("challenge: " + challenge + ' text: ' + __(text))
			text = (challenge + '-' + text).decode('utf-8','ignore').encode('utf-16-le')
			for i in range(len(text)):
				if ord(text[i]) > 255:
					text[i] = '.'
			md5 = hashlib.md5()
			md5.update(text) # pylint: disable=e1101
			debug(md5.hexdigest())
			return challenge + '-' + md5.hexdigest()

		#=======================================================================
		# linkP = open("/tmp/fritzsmarthome_sid.xml", "w")
		# linkP.write(sidXml)
		# linkP.close()
		#=======================================================================

		debug("")
		sidX = ET.fromstring(sidXml)

		challenge = sidX.find("Challenge").text
		if challenge:
			debug("challenge " + challenge)
		else:
			error("login necessary and no challenge! That is terribly wrong.")

		# TODO: check validity of username?
		parms = urlencode({
						'username': config.plugins.fritzsmarthome.username.value,
						'response': buildResponse(challenge, config.plugins.fritzsmarthome.password.value),
						})
		url = "http://%s/login_sid.lua" % (config.plugins.fritzsmarthome.hostname.value)
		debug(time.ctime() + " :"+ url + "?" + parms)
		getPage(url,
			method="POST",
			agent=USERAGENT,
			headers={'Content-Type': "application/x-www-form-urlencoded", 'Content-Length': str(len(parms))
					}, postdata=parms).addCallback(self._gotPageLogin).addErrback(self._errorLogin)

	def _gotPageLogin(self, sidXml):
		debug("")
		#=======================================================================
		# linkP = open("/tmp/sid.xml", "w")
		# linkP.write(sidXml)
		# linkP.close()
		#=======================================================================

		sidX = ET.fromstring(sidXml)
		md5Sid = sidX.find("SID").text
		if md5Sid and md5Sid != "0000000000000000":
			debug("found sid: " + md5Sid)
		else:
			error("found no sid")
			return

		self.md5Sid = md5Sid
		self.getAdapterList()

	def _errorLogin(self, errorM):
		if type(errorM).__name__ == "str":
			text = errorM
		else:
			text = errorM.getErrorMessage()
		self.exception(text)

	def createPyChart(self, data):
		# Get TimerType
		timerType = int(data["EnStats_timer_type"])
		if (timerType == 10):
			valueDivider = 100
		elif (timerType == 86400 or timerType == 2678400):
			valueDivider = 1000
		else:
			valueDivider = 1
			
		# Set the vertical range
		max_y = int(data["EnStats_max_value"])/valueDivider

		# Chart size and specifying the range for the Y axis
		chart = SimpleLineChart(250, 150, y_range=[0, max_y+(max_y/4)])
		
		# Add the chart data
		itemCount = int(data["EnStats_count"])

		chartdata = []
		valcount = itemCount
		for x in range(1, itemCount+1):
			wattvalue = int(data["EnStats_watt_value_" + str(valcount)])/valueDivider
			valcount -= 1
			chartdata.append(wattvalue)

		#print chartdata
		
		chart.add_data(chartdata)
		chart.add_data([0] * 2)
		
		# Set the line colour
		chart.set_colours(['000000'])

		# Filled colours
		chart.add_fill_range('6EC462', 0, 1)

		# The Y axis labels
		chart.set_axis_labels(Axis.LEFT, ['', max_y/4, max_y/2, int((max_y / 100.00) * 75), max_y, max_y+(max_y/4)])
		
		# X axis labels
		axisdata = []
		valcount = (itemCount/6)
		divider = valcount/10
		
		if divider == 0:
			divider = 1
		
		for x in range(0, valcount+1, divider):
			if valcount == 0:
				axisdata.append("0")
			else:
				axisdata.append("-" + str(valcount))
			valcount -= divider
			
		chart.set_axis_labels(Axis.BOTTOM, axisdata)
		
		chart.download('/tmp/smarthomechart.png')

		self.picload.startDecode('/tmp/smarthomechart.png')
		
	def showChartGraph(self, picInfo=None):
		ptr = self.picload.getData()
		if ptr != None:
			setPixmap(self["adapterchart"], ptr)
			self["adapterchart"].show()
		
	def switchOn(self):
		self.setDeviceSwitchStatus(1)
		
	def switchOff(self):
		self.setDeviceSwitchStatus(0)
		
	def setDeviceSwitchStatus(self, status):
		selectedAdapter = self["adapterlist"].getCurrent()
		if selectedAdapter is None:
			return
			
		selectedAdapterId = selectedAdapter[0][0]
		parms = urlencode({
						'command':'SwitchOnOff',
						'id': selectedAdapterId,
						'value_to_set': status,
						'sid': self.md5Sid,
						'xhr': '1'
						})
						
		url = "http://" + config.plugins.fritzsmarthome.hostname.value + "/net/home_auto_query.lua"
		debug(time.ctime() + " :"+ url + "?" + parms)
		getPage(url, method="POST",
			agent=USERAGENT,
			headers={'Content-Type': "application/x-www-form-urlencoded", 'Content-Length': str(len(parms))
					}, postdata=parms).addCallback(self.refreshAdapterList, 500).addErrback(self.showError)
		
	def resetAdapterList(self):
		debug("")
		self.adapterlist = []
		self.adapterCount = 0
		self.requestCount = 0
		self.statsTotalPower = 0
		self.statsTotalAmp = 0

	def refreshAdapterList(self, data="", timeout=15000):
		debug("")
		self.RefreshTimer.start(timeout, True)
		
	def getAdapterList(self):
		debug("")
		self.resetAdapterList()
		url = "http://" + config.plugins.fritzsmarthome.hostname.value + "/net/home_auto_overview.lua?sid=" + self.md5Sid
		debug(url)
		getPage(url, agent=USERAGENT, method="GET").addCallback(self.gotAdapterList).addErrback(self.showError)

	def gotAdapterList(self, html=""):
		debug("")
		linkP = open("/tmp/gotAdapterList.html", "w")
		linkP.write(html)
		linkP.close()
		devicemask = re.compile('uiDeviceConnectState_([^"]*)"', re.S)
		devices = devicemask.finditer(html)
		deviceIdList = []
		for value in devices:
			self.adapterCount += 1
			deviceIdList.append(value.group(1))

		deviceTemperatureList = []
		temperaturemask = re.compile('uiView_Temperature_([^"]*)" title="([^"]*)"', re.S)
		temperatures = temperaturemask.finditer(html)
		for value in temperatures:
			deviceTemperatureList.append(value.group(2))

		statusmask = re.compile('/css/default/images/icon_schalter_([^"]*).png', re.S)
		statuslist = statusmask.finditer(html)
		deviceStatusList = []
		for value in statuslist:
			if value.group(1) == "on":
				deviceStatusList.append(1)
			else:
				deviceStatusList.append(0)
				
		entrymask = re.compile('<td class="c([^"]*)"><nobr><span title="([^"]*)" >([^"]*)</span></nobr></td>', re.S)
		entries = entrymask.finditer(html)

		valCount = 0
		deviceCount = 0
		for value in entries:
			valCount += 1
			if valCount == 1:
				adapterId = deviceIdList[deviceCount]
				adapterName = value.group(2)
				adapterSwitchState = deviceStatusList[deviceCount]
				adapterTemperature = deviceTemperatureList[deviceCount]
				deviceCount += 1
			#elif valCount == 2:
			#	adapterAIN = value.group(2)
			elif valCount == 2:
				adapterMode = value.group(2)
				
				adapterAIN = "unknown"
				
				adapterInfo = [adapterId, adapterName, adapterAIN, adapterMode, adapterSwitchState, adapterTemperature]

				self.getAdapterMultiMeterState(adapterInfo, deviceCount)
				valCount = 0
		
		self.RefreshTimer.start(15000, True)
		
	def getAdapterStats(self):
		selectedAdapter = self["adapterlist"].getCurrent()
		if selectedAdapter is None:
			return
			
		adapterInfo = selectedAdapter[0]

		url = "http://" + config.plugins.fritzsmarthome.hostname.value + "/net/home_auto_query.lua?command=%s&id=%s&xhr=1&sid=%s" % (config.plugins.fritzsmarthome.statsType.value, adapterInfo[0], self.md5Sid)
		debug(time.ctime() + " :"+ url)
		getPage(url, agent=USERAGENT).addCallback(self.gotAdapterStats, adapterInfo).addErrback(self.showError)
		
	def gotAdapterStats(self, data="", adapterInfo=[]):
		data = json.loads(data)
		
		if (int(data["DeviceSwitchState"]) == 1):
			switchState = _("On")
		else:
			switchState = _("Off")
			
		if (int(data["DeviceConnectState"]) == 2):
			connectState = _("Yes")
		else:
			connectState = _("No")
		
		#config.plugins.fritzsmarthome.statsType = ConfigSelection([("EnergyStats_10", _("Last 10 min")),("EnergyStats_hour", _("Last 60 min")),("EnergyStats_24h", _("Last 24 hrs")),("EnergyStats_month", _("Last 31 days")),("EnergyStats_year", _("Last 365 days"))], "EnergyStats_hour")
		statsType = config.plugins.fritzsmarthome.statsType.value
		if statsType == "EnergyStats_10" or statsType == "EnergyStats_hour":
			powerLabel = " Watt"
			powerDivider = 100
		elif statsType == "EnergyStats_24h":
			powerLabel = " Wh"
			powerDivider = 1
		else:
			powerLabel = " kWh"
			powerDivider = 1000

		infoText = str(adapterInfo[1]) + "\n"
		#infoText += "AIN: " + str(adapterInfo[2]) + "\n"
		infoText += "\n"
		infoText += "Status: " + switchState + "\n"
		infoText += "Verbunden: " + connectState + "\n"
		infoText += "Modus: " + str(adapterInfo[3]) + "\n"
		infoText += "Temperatur: " + str(adapterInfo[5]) + "\n"
		infoText += "\n"
		infoText += "Verbrauch (" + statsType[12:] + "):\n"
		infoText += "Aktuell: " + str(int(data["EnStats_watt_value_1"])/powerDivider) + powerLabel + "\n"
		infoText += "Durchschnitt: " + str(int(data["EnStats_average_value"])/powerDivider) + powerLabel + "\n"
		infoText += "Minimum: " + str(int(data["EnStats_min_value"])/powerDivider) + powerLabel + "\n"
		infoText += "Maximum: " + str(int(data["EnStats_max_value"])/powerDivider) + powerLabel + "\n"
		
		self["adapterinfo"].setText(infoText)
		
		self.createPyChart(data)
		
	def getAdapterMultiMeterState(self, adapterInfo, adapterCount):
		url = "http://" + config.plugins.fritzsmarthome.hostname.value + "/net/home_auto_query.lua?command=MultiMeterState&id=%s&xhr=1&sid=%s" % (adapterInfo[0], self.md5Sid)
		debug(time.ctime() + " :"+ url)
		getPage(url, agent=USERAGENT).addCallback(self.gotAdapterMultiMeterState, adapterInfo, adapterCount).addErrback(self.showError)
		
	def gotAdapterMultiMeterState(self, data="", adapterInfo=[], adapterCount=0):
		# Get Adapter Info
		adapterId = int(adapterInfo[0])
		adapterName = adapterInfo[1]
		adapterAIN = adapterInfo[2]
		adapterMode = adapterInfo[3]
		adapterSwitchState = int(adapterInfo[4])
		adapterTemperature = adapterInfo[5]
		
		# Add Adapter to list
		data = json.loads(data)
		description = str(int(data["MM_Value_Power"])/100) + " Watt (" + str(int(data["MM_Value_Volt"])/1000) + "V)"
		self.adapterlist.append(AdapaterEntryComponent(adapterInfo, description))
		
		# Overall Stats
		self.statsTotalPower += int(data["MM_Value_Power"])/100
		self.statsTotalAmp += int(data["MM_Value_Amp"])/100
		
		# Update AdapterList
		if adapterCount == self.adapterCount:
			self["adapterlist"].setList(self.adapterlist)
			self["info"].setText("Aktueller Verbrauch: " + str(self.statsTotalPower) + " Watt")
		
		#self.getAdapterInfo(adapterId)
		
	def showError(self, error=""):
		print str(error)
		#self["info"].setText(error)

	def okClicked(self):
		selected = self["adapterlist"].getCurrent()
		if selected is not None:
			print "Show Adapter Info: " + str(selected[0])

	def settingsMenu(self):
		self.session.openWithCallback(self._login, SmartHomeMonitorSettings)
			
##########################################################

class SmartHomeMonitorSettings(Screen, ConfigListScreen):
	skin = """
		<screen name="SmartHomeMonitorSettings" position="center,center" size="560,330" title="Smart Home Monitor - Settings">
			<widget name="config" position="10,10" size="540,250" scrollbarMode="showOnDemand" />
			<ePixmap name="red"    position="0,280"   zPosition="4" size="140,40" pixmap="/usr/share/enigma2/skin_default/buttons/red.png" transparent="1" alphatest="on" />
			<ePixmap name="green"  position="140,280" zPosition="4" size="140,40" pixmap="/usr/share/enigma2/skin_default/buttons/green.png" transparent="1" alphatest="on" />
			<ePixmap name="yellow" position="280,280" zPosition="4" size="140,40" pixmap="/usr/share/enigma2/skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
			<ePixmap name="blue"   position="420,280" zPosition="4" size="140,40" pixmap="/usr/share/enigma2/skin_default/buttons/blue.png" transparent="1" alphatest="on" />
			<widget name="key_red" position="0,280" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
			<widget name="key_green" position="140,280" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
			<widget name="key_yellow" position="280,280" zPosition="5" size="140,40" valign="center" halign="center"  font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
			<widget name="key_blue" position="420,280" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
		</screen>"""

	def __init__(self, session):
		Screen.__init__(self, session)

		self["key_red"] = Button(_("Cancel"))
		self["key_green"] = Button(_("OK"))
		self["key_yellow"] = Button("")
		self["key_blue"] = Button("")

		self["actions"] = ActionMap(["SetupActions", "ColorActions"],
		{
			"ok": self.keySave,
			"green": self.keySave,
			"red": self.keyCancel,
			"cancel": self.keyCancel
		}, -2)

		self.cfglist = []
		self.cfglist.append(getConfigListEntry(_("FritzBox Hostname / Ip"), config.plugins.fritzsmarthome.hostname))
		self.cfglist.append(getConfigListEntry(_("FritzBox Username"), config.plugins.fritzsmarthome.username))
		self.cfglist.append(getConfigListEntry(_("FritzBox Password"), config.plugins.fritzsmarthome.password))
		self.cfglist.append(getConfigListEntry(_("History Graph Range"), config.plugins.fritzsmarthome.statsType))
		ConfigListScreen.__init__(self, self.cfglist, session)

	def keySave(self):
		config.plugins.fritzsmarthome.save()
		configfile.save()
		self.close()

	def keyCancel(self):
		for item in self.cfglist:
			item[1].cancel()
		self.close()


##########################################################

def main(session, **kwargs):
	session.open(SmartHomeMonitorMain)

def Plugins(path, **kwargs):
	return [
		PluginDescriptor(name="Smart Home Monitor", description="Smart Home Monitor", where=PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=main), 
		PluginDescriptor(name="Smart Home Monitor", description="Smart Home Monitor", where=PluginDescriptor.WHERE_PLUGINMENU, fnc=main) ]
