예제 #1
0
 def __init__(self):
     screen.BaseKeyScreenDesc.__init__(self, None, 'LOG', withnav=False)
     self.keysbyord = [
         toucharea.TouchPoint(
             (config.screenwidth / 2, config.screenheight / 2),
             (config.screenwidth, config.screenheight))
     ]
     utilities.register_example("LogDisplayScreen", self)
예제 #2
0
    def __init__(self, screensection, screenname):
        debug.debugPrint('Screen', "New WeatherScreenDesc ", screenname)
        screen.ScreenDesc.__init__(self, screensection, screenname)

        self.fmt = WFormatter()

        butsize = self.ButSize(1, 1, 0)
        self.Keys = OrderedDict({
            'condorfcst':
            toucharea.TouchPoint('condorfcst',
                                 (self.HorizBorder + .5 * butsize[0],
                                  self.TopBorder + .5 * butsize[1]),
                                 butsize,
                                 proc=self.CondOrFcst)
        })
        self.currentconditions = True  # show conditions or forecast
        screen.AddUndefaultedParams(self,
                                    screensection,
                                    location='',
                                    LocationSize=40)

        self.SetScreenTitle(screen.FlatenScreenLabel(self.label), 50,
                            self.CharColor)

        self.condformat = u"{d[0]} {d[1]}\u00B0F", u"  Feels like: {d[2]}\u00B0", "Wind {d[3]}@{d[4]}"
        self.condfields = list(
            ((self.location, 'Cond', x)
             for x in ('Sky', 'Temp', 'Feels', 'WindDir', 'WindMPH')))

        # self.dayformat  = "Sunrise: {d[0]:02d}:{d[1]:02d}","Sunset:  {d[2]:02d}:{d[3]:02d}","Moon rise: {d[4]} set: {d[5]}","{d[6]}% illuminated"
        # self.dayfields  = list(((self.location, 'Cond', x) for x in ('SunriseH','SunriseM','SunsetH','SunsetM','Moonrise','Moonset','MoonPct')))
        self.dayformat = "Sunrise: {d[0]}", "Sunset:  {d[1]}", "Moon rise: {d[2]} set: {d[3]}"
        self.dayfields = list(
            ((self.location, 'Cond', x)
             for x in ('Sunrise', 'Sunset', 'Moonrise', 'Moonset')))

        self.footformat = "Readings as of {d[0]}",
        self.footfields = ((self.location, 'Cond', 'Age'), )

        self.fcstformat = u"{d[0]}   {d[1]}\u00B0/{d[2]}\u00B0 {d[3]}", "Wind: {d[4]}"
        self.fcstfields = list(
            ((self.location, 'Fcst', x)
             for x in ('Day', 'High', 'Low', 'Sky', 'WindSpd')))

        try:
            self.store = valuestore.ValueStores[self.location]
        except KeyError:
            logsupport.Logs.Log(
                "Weather screen {} using non-existent location {}".format(
                    screenname, self.location),
                severity=logsupport.ConsoleWarning)
            raise ValueError
        utilities.register_example("WeatherScreenDesc", self)
예제 #3
0
 def __init__(self):
     screen.BaseKeyScreenDesc.__init__(self, None, 'LOG')
     self.NavKeysShowing = False
     self.DefaultNavKeysShowing = False
     self.state = 'init'  # init: new entry to logs; scroll: doing error scroll manual: user control
     self.startat = 0  # where in log page starts
     self.startpage = 0
     self.item = 0
     self.pageno = -1
     self.PageStartItem = [0]
     self.Keys = {
         'nextpage':
         toucharea.TouchPoint('nextpage',
                              (hw.screenwidth / 2, 3 * hw.screenheight / 4),
                              (hw.screenwidth, hw.screenheight),
                              proc=self.NextPage),
         'prevpage':
         toucharea.TouchPoint('prevpage',
                              (hw.screenwidth / 2, hw.screenheight / 4),
                              (hw.screenwidth, hw.screenheight / 2),
                              proc=self.PrevPage)
     }
     self.name = 'Log'
     utilities.register_example("LogDisplayScreen", self)
예제 #4
0
	def __init__(self, screensection, screenname):
		debugprint(config.dbgscreenbuild, "New ThermostatScreenDesc ", screenname)
		screen.BaseKeyScreenDesc.__init__(self, screensection, screenname)
		utilities.LocalizeParams(self, screensection, 'KeyColor', 'KeyOffOutlineColor', 'KeyOnOutlineColor')
		self.info = {}
		self.fsize = (30, 50, 80, 160)

		if screenname in config.ISY.NodesByName:
			self.RealObj = config.ISY.NodesByName[screenname]
		else:
			self.RealObj = None
			config.Logs.Log("No Thermostat: " + screenname, severity=logsupport.ConsoleWarning)

		self.TitleRen = config.fonts.Font(self.fsize[1]).render(screen.FlatenScreenLabel(self.label), 0,
																wc(self.CharColor))
		self.TitlePos = ((config.screenwidth - self.TitleRen.get_width())/2, config.topborder)
		self.TempPos = config.topborder + self.TitleRen.get_height()
		self.StatePos = self.TempPos + config.fonts.Font(self.fsize[3]).get_linesize() - scaleH(20)
		self.SPPos = self.StatePos + scaleH(25)
		self.AdjButSurf = pygame.Surface((config.screenwidth, scaleH(40)))
		self.AdjButTops = self.SPPos + config.fonts.Font(self.fsize[2]).get_linesize() - scaleH(5)
		centerspacing = config.screenwidth/5
		self.AdjButSurf.fill(wc(self.BackgroundColor))
		arrowsize = scaleH(40)  # pixel

		for i in range(4):
			gfxdraw.filled_trigon(self.AdjButSurf, *trifromtop(centerspacing, arrowsize/2, i + 1, arrowsize,
															   wc(("red", "blue", "red", "blue")[i]), i%2 <> 0))
			self.keysbyord.append(toucharea.TouchPoint((centerspacing*(i + 1), self.AdjButTops + arrowsize/2),
													   (arrowsize*1.2, arrowsize*1.2)))
		self.ModeButPos = self.AdjButTops + scaleH(85)  # pixel

		bsize = (scaleW(100), scaleH(50))  # pixel
		self.keysbyord.append(toucharea.ManualKeyDesc("Mode", ["Mode"],
													  self.KeyColor, self.CharColor, self.CharColor,
													  center=(config.screenwidth/4, self.ModeButPos), size=bsize,
													  KOn=config.KeyOffOutlineColor))  # todo clean up
		self.keysbyord.append(toucharea.ManualKeyDesc("Fan", ["Fan"],
													  self.KeyColor, self.CharColor, self.CharColor,
													  center=(3*config.screenwidth/4, self.ModeButPos), size=bsize,
													  KOn=config.KeyOffOutlineColor))
		self.keysbyord[4].FinishKey((0,0),(0,0))
		self.keysbyord[5].FinishKey((0,0),(0,0))
		self.ModesPos = self.ModeButPos + bsize[1]/2 + scaleH(5)
		utilities.register_example("ThermostatScreenDesc", self)
예제 #5
0
    def SetScreenContents(self):
        self.numplayers = 0  # if 0 then Sonos didn't get set up correctly
        self.numgroups = 0
        self.nms = []
        self.gpingrms = []
        self.PlayerInputs = []
        self.SourceSet = None
        self.SonosNodes = {}
        self.NodeVPos = []
        self.KeysSum = {}
        self.GCVPos = []
        self.KeysGC = {}
        self.KeysGpCtl = {}
        self.GPCtlVPos = []
        self.SrcSlotsVPos = []
        self.KeysSrc = {}
        self.ButLocSize = []
        self.SonosGroups = {}
        self.RoomNames = {}
        self.SlotToGp = []
        self.Subscreen = -1
        self.SourceItem = 0
        self.SourceSelection = ''
        self.ExtraSource = {}
        self.HubInterestList[self.HA.name] = {}
        for n, p in self.HA.DomainEntityReg['media_player'].items(
        ):  # todo can simplify if sonos becomes a separate module from media player
            if p.Sonos:
                self.SonosNodes[p.entity_id] = p
                self.SlotToGp.append('')
                self.HubInterestList[self.HA.name][p.entity_id] = p.entity_id
        self.numplayers = len(self.SonosNodes)

        for i in range(self.numplayers + 1):
            self.GCVPos.append(self.startvertspace + i * 50)

        # set up the control screen for a group
        self.ctlhgt = self.useablevertspace // (2 * self.numplayers + 2)
        for i in range(self.numplayers + 1):
            self.GPCtlVPos.append(self.startvertspace + i * 2 * self.ctlhgt)

        # set up the main summary screen
        vpos = self.startvertspace
        if self.numplayers != 0:
            self.roomheight = self.useablevertspace // self.numplayers
        else:
            self.roomheight = self.useablevertspace  # dummy value to avoid div by 0 in error case
        self.roomdisplayinfo = (1.5, 1, 1, 1)
        for n, p in self.SonosNodes.items():
            self.NodeVPos.append(vpos)
            vpos += self.roomheight
            lineheight = self.roomheight / (sum(self.roomdisplayinfo) /
                                            self.roomdisplayinfo[0])
            self.RoomNames[p.entity_id] = screenutil.CreateTextBlock(
                p.FriendlyName, lineheight, self.CharColor, True, FitLine=True)
        self.NodeVPos.append(vpos)

        for i in range(self.numplayers):
            self.KeysSum['Slot' + str(i)] = toucharea.TouchPoint(
                'Slot' + str(i),
                (hw.screenwidth // 2,
                 (self.NodeVPos[i] + self.NodeVPos[i + 1]) // 2),
                (hw.screenwidth, self.roomheight),
                proc=functools.partial(self.RoomSelect, i),
                procdbl=functools.partial(self.RoomSelectDbl, i))
            self.KeysGC['SlotGC' + str(i)] = toucharea.TouchPoint(
                'SlotGC' + str(i),
                (hw.screenwidth // 2,
                 (self.GCVPos[i] + self.GCVPos[i + 1]) // 2),
                (hw.screenwidth, 50),
                proc=functools.partial(self.GroupMemberToggle, i))
            butvert = self.GPCtlVPos[i] + self.ctlhgt * 1.5
            butsz = (self.ctlhgt, self.ctlhgt)
            self.ButLocSize.append(
                {'Dn': ((hw.screenwidth // 4, butvert), butsz)})
            self.KeysGpCtl['Dn' + str(i)] = toucharea.TouchPoint(
                'Dn' + str(i), (hw.screenwidth // 4, butvert),
                butsz,
                proc=functools.partial(self.VolChange, i, -1))

            self.ButLocSize[i]['Up'] = ((hw.screenwidth // 2, butvert), butsz)
            self.KeysGpCtl['Up' + str(i)] = toucharea.TouchPoint(
                'Up' + str(i), (hw.screenwidth // 2, butvert),
                butsz,
                proc=functools.partial(self.VolChange, i, 1))

            self.ButLocSize[i]['Mute'] = ((3 * hw.screenwidth // 4, butvert),
                                          butsz)
            self.KeysGpCtl['Mute' + str(i)] = toucharea.TouchPoint(
                'Mute' + str(i), (3 * hw.screenwidth // 4, butvert),
                butsz,
                proc=functools.partial(self.VolChange, i, 0))

        self.KeysGpCtl['Source'] = toucharea.ManualKeyDesc(
            self,
            'Source', ['Source'],
            self.BackgroundColor,
            self.CharColor,
            self.CharColor,
            center=(3 * hw.screenwidth // 4, self.GPCtlVPos[-1] + self.ctlhgt),
            size=(hw.screenwidth // 3, self.ctlhgt),
            KOn='',
            KOff='',
            proc=self.SetSource)

        self.KeysGpCtl['OKCtl'] = toucharea.ManualKeyDesc(
            self,
            'OKCtl', ['OK'],
            self.BackgroundColor,
            self.CharColor,
            self.CharColor,
            center=(hw.screenwidth // 4, self.GPCtlVPos[-1] + self.ctlhgt),
            size=(hw.screenwidth // 3, self.ctlhgt),
            KOn='',
            KOff='',
            proc=self.GpCtlOK)

        self.KeysGC['OK'] = toucharea.ManualKeyDesc(
            self,
            'OK', ['OK'],
            self.BackgroundColor,
            self.CharColor,
            self.CharColor,
            center=(hw.screenwidth // 2, self.GCVPos[-1] + 30),
            size=(hw.screenwidth // 4, self.ctlhgt),
            KOn='',
            KOff='',
            proc=self.GroupMemberOK)

        self.Keys = self.KeysSum
예제 #6
0
    def __init__(self, screensection, screenname):
        config.SonosScreen = self  # todo hack to handle late appearing players
        debug.debugPrint('Screen', "New SonosScreenDesc ", screenname)
        screen.BaseKeyScreenDesc.__init__(self, screensection, screenname)
        screen.IncorporateParams(self, 'SonosScreen', {'KeyColor'},
                                 screensection)
        self.DullKeyColor = wc(self.KeyColor, .5, self.BackgroundColor)
        self.HA = self.DefaultHubObj
        self.Subscreen = -1

        self.SetScreenTitle(
            'Sonos', hw.screenheight / 12, self.CharColor
        )  # todo correct the fontsize and maybe the color choice and change to useable vert
        if not isinstance(self.DefaultHubObj, hasshub.HA):
            logsupport.Logs.Log("Sonos Default Hub is not HA hub",
                                severity=ConsoleError,
                                tb=False)
            return

        self.SetScreenContents()

        if self.numplayers == 0:
            logsupport.Logs.Log("No Sonos Players reported - check network",
                                severity=ConsoleWarning)
            return

        # set up source selection screen
        self.SourceSlot = []
        vpos = self.startvertspace  # todo add buffer?
        self.sourceslots = 8
        self.sourceheight = self.useablevertspace // (
            self.sourceslots + 1)  # allow space at bottom right for arrow

        for i in range(self.sourceslots):
            self.SrcSlotsVPos.append(vpos)
            self.KeysSrc['Src' + str(i)] = toucharea.TouchPoint(
                'Scr' + str(i),
                (hw.screenwidth // 2, vpos + self.sourceheight // 2),
                (hw.screenwidth, self.sourceheight),
                proc=functools.partial(self.PickSource, i))
            vpos += self.sourceheight
            self.SourceSlot.append('')
        self.SrcPrev = (
            hw.screenwidth - self.sourceheight - self.HorizBorder,
            self.startvertspace - self.sourceheight // 2
        )  # todo change to horizstart + useablehoriz - sourceheight
        self.SrcNext = (hw.screenwidth - self.sourceheight - self.HorizBorder,
                        vpos + self.sourceheight // 2 + 10)  # for appearance
        self.KeysSrc['Prev'] = toucharea.TouchPoint(
            'Prev',
            self.SrcPrev, (self.sourceheight, self.sourceheight),
            proc=functools.partial(self.PrevNext, False))
        self.KeysSrc['Next'] = toucharea.TouchPoint(
            'Next',
            self.SrcNext, (self.sourceheight, self.sourceheight),
            proc=functools.partial(self.PrevNext, True))
        self.KeysSrc['OKSrc'] = toucharea.ManualKeyDesc(
            self,
            'OKSrc', ['OK'],
            self.BackgroundColor,
            self.CharColor,
            self.CharColor,
            center=(self.SrcNext[0] - 2.5 * self.sourceheight,
                    self.SrcNext[1]),
            size=(2 * self.sourceheight, self.sourceheight),
            KOn='',
            KOff='',
            proc=functools.partial(self.PickSourceOK, True))
        self.KeysSrc['CnclSrc'] = toucharea.ManualKeyDesc(
            self,
            'CnclSrc', ['Back'],
            self.BackgroundColor,
            self.CharColor,
            self.CharColor,
            center=(self.SrcNext[0] - 5 * self.sourceheight, self.SrcNext[1]),
            size=(2 * self.sourceheight, self.sourceheight),
            KOn='',
            KOff='',
            proc=functools.partial(self.PickSourceOK, False))

        utilities.register_example("SonosScreenDesc", self)
예제 #7
0
    def __init__(self, masterscreen, choosername, slots, screenhgt, voffset,
                 proc):
        """
		Create subscreen(s) that allow choosing from a list
		:param masterscreen: the real screen for which this operates
		:param slots: number of slots to create per selection screen
		:param screenhgt: height of the area to be used for the list
		:param voffset: vertical offset for start of area to be used
		:param proc: function called with resultant selection index or -1 if cancelled
		"""
        screen.ScreenDesc.__init__(self, {},
                                   masterscreen.name + '-' + choosername +
                                   '-Chooser',
                                   parentscreen=masterscreen)
        self.Result = proc
        self.masterscreen = masterscreen
        self.selection = -1
        self.itemlist = []
        self.firstitem = 0
        self.NumSlots = slots
        self.ListKeySlots = {}
        self.SlotsVPos = []
        self.SlotItem = []
        vpos = voffset
        self.BackgroundColor = self.masterscreen.BackgroundColor
        self.DullKeyColor = wc(self.masterscreen.KeyColor, .5,
                               self.BackgroundColor)
        self.CharColor = self.masterscreen.CharColor
        self.sourceheight = screenhgt // (self.NumSlots + 1)

        for i in range(self.NumSlots):
            self.SlotsVPos.append(vpos)
            self.ListKeySlots['Src' + str(i)] = toucharea.TouchPoint(
                'Slot' + str(i),
                (hw.screenwidth // 2, vpos + self.sourceheight // 2),
                (hw.screenwidth, self.sourceheight),
                proc=functools.partial(self.PickItem, i))
            vpos += self.sourceheight
            self.SlotItem.append('')
        self.SrcPrev = (hw.screenwidth - self.sourceheight - self.HorizBorder,
                        voffset - self.sourceheight // 2)
        self.SrcNext = (hw.screenwidth - self.sourceheight - self.HorizBorder,
                        vpos + self.sourceheight // 2 + 10)  # for appearance
        self.ListKeySlots['Prev'] = toucharea.TouchPoint(
            'Prev',
            self.SrcPrev, (self.sourceheight, self.sourceheight),
            proc=functools.partial(self.PrevNext, False))
        self.ListKeySlots['Next'] = toucharea.TouchPoint(
            'Next',
            self.SrcNext, (self.sourceheight, self.sourceheight),
            proc=functools.partial(self.PrevNext, True))
        self.ListKeySlots['OKSrc'] = toucharea.ManualKeyDesc(
            self,
            'OKSrc', ['OK'],
            self.BackgroundColor,
            self.CharColor,
            self.CharColor,
            center=(self.SrcNext[0] - 2.5 * self.sourceheight,
                    self.SrcNext[1]),
            size=(2 * self.sourceheight, self.sourceheight),
            KOn='',
            KOff='',
            proc=functools.partial(self.PickItemOK, True))
        '''
예제 #8
0
    def __init__(self, screensection, screenname):
        debug.debugPrint('Screen', "New Nest ThermostatScreenDesc ",
                         screenname)
        screen.BaseKeyScreenDesc.__init__(self, screensection, screenname)
        screen.IncorporateParams(
            self, 'NestThermostatScreen',
            {'KeyColor', 'KeyOffOutlineColor', 'KeyOnOutlineColor'},
            screensection)
        nominalfontsz = (30, 50, 80, 160)
        nominalspacers = (5, 20, 25, 40, 50, 85)
        self.fsize = []
        self.spacer = []

        self.HA = self.DefaultHubObj
        self.ThermNode = self.HA.GetNode(screenname)[0]  # use ControlObj (0)
        if self.ThermNode is None:
            logsupport.Logs.Log("No Thermostat: " + screenname,
                                severity=ConsoleWarning)
            raise ValueError
        # if isinstance(self.DefaultHub,hasshub.HA):
        #	self.HA = self.DefaultHub
        #	self.ThermNode = self.HA.GetNode(screenname)[0]  # use ControlObj (0)
        #	if self.ThermNode is None:
        #		logsupport.Logs.Log("No Thermostat: " + screenname, severity=ConsoleWarning)
        #		raise ValueError
        # else:
        #	logsupport.Logs.Log("Nest Thermostat screen only works with HA hub", severity=ConsoleError)
        #	self.self.ThermNode = None
        #	raise ValueError

        self.SetScreenTitle(screen.FlatenScreenLabel(self.label),
                            nominalfontsz[1], self.CharColor)
        self.TempPos = self.startvertspace
        '''
		Size and positions based on nominal 480 vertical screen less top/bottom borders less default title size of 50
		Compute other fonts sizes based on what is left after that given user ability to set actual title size
		'''
        tempsurf = fonts.fonts.Font(50).render('Temp', 0, wc(self.CharColor))
        useable = self.useablevertspace / (self.useablevertspace -
                                           tempsurf.get_height())

        for fs in nominalfontsz:
            self.fsize.append(int(fs * useable))

        for fs in nominalspacers:
            self.spacer.append(int(fs * useable))

        self.StatePos = self.TempPos + fonts.fonts.Font(
            self.fsize[3]).get_linesize() - scaleH(self.spacer[1])
        self.SPVPos = self.StatePos + scaleH(self.spacer[2])
        sp = fonts.fonts.Font(self.fsize[2]).render("{:2d}".format(99), 0,
                                                    wc(self.CharColor))
        self.SPHgt = sp.get_height()
        self.SPWdt = sp.get_width()
        self.SetPointSurf = pygame.Surface((self.SPWdt, self.SPHgt))
        self.SetPointSurf.fill(wc(self.BackgroundColor))
        self.AdjButSurf = pygame.Surface(
            (hw.screenwidth, scaleH(self.spacer[3])))
        self.AdjButTops = self.SPVPos + fonts.fonts.Font(
            self.fsize[2]).get_linesize() - scaleH(self.spacer[0])
        centerspacing = hw.screenwidth // 5
        self.SPHPosL = int(1.5 * centerspacing)
        self.SPHPosR = int(3.5 * centerspacing)
        self.AdjButSurf.fill(wc(self.BackgroundColor))
        self.LocalOnly = [0.0, 0.0
                          ]  # Heat setpoint, Cool setpoint:  0 is normal color
        self.ModeLocal = 0.0
        self.FanLocal = 0.0
        arrowsize = scaleH(
            40)  # pixel todo should this be other than a constant?
        self.t_low = 0
        self.t_high = 99
        self.t_cur = 0
        self.t_state = "Unknown"
        self.mode = 'auto'
        self.fan = 'auto'
        self.modes, self.fanstates = self.ThermNode.GetModeInfo()
        self.TimeBumpSP = None
        self.TimeBumpModes = None
        self.TimeBumpFan = None
        self.TimerName = 0

        for i in range(4):
            gfxdraw.filled_trigon(
                self.AdjButSurf,
                *trifromtop(centerspacing, arrowsize // 2, i + 1, arrowsize,
                            wc(("red", "blue", "red", "blue")[i]), i % 2 != 0))
            self.Keys['temp' + str(i)] = toucharea.TouchPoint(
                'temp' + str(i),
                (centerspacing * (i + 1), self.AdjButTops + arrowsize // 2),
                (arrowsize * 1.2, arrowsize * 1.2),
                proc=functools.partial(self.BumpTemp,
                                       (True, True, False, False)[i],
                                       (1, -1, 1, -1)[i]))

        self.ModeButPos = self.AdjButTops + scaleH(self.spacer[5])  # pixel

        bsize = (scaleW(100), scaleH(self.spacer[4]))  # pixel

        self.Keys['Mode'] = toucharea.ManualKeyDesc(
            self,
            "Mode", ["Mode"],
            self.KeyColor,
            self.CharColor,
            self.CharColor,
            center=(self.SPHPosL, self.ModeButPos),
            size=bsize,
            KOn=self.KeyOffOutlineColor,
            proc=self.BumpMode)

        self.Keys['Fan'] = toucharea.ManualKeyDesc(self,
                                                   "Fan", ["Fan"],
                                                   self.KeyColor,
                                                   self.CharColor,
                                                   self.CharColor,
                                                   center=(self.SPHPosR,
                                                           self.ModeButPos),
                                                   size=bsize,
                                                   KOn=self.KeyOffOutlineColor,
                                                   proc=self.BumpFan)

        self.ModesPos = self.ModeButPos + bsize[1] // 2 + scaleH(
            self.spacer[0])
        if self.ThermNode is not None:
            self.HubInterestList[self.HA.name] = {
                self.ThermNode.address: self.Keys['Mode']
            }  # placeholder for thermostat node
        utilities.register_example("NestThermostatScreenDesc", self)
예제 #9
0
    def __init__(self, screensection, screenname):
        debug.debugPrint('Screen', "New ThermostatScreenDesc ", screenname)
        screen.BaseKeyScreenDesc.__init__(self, screensection, screenname)
        screen.IncorporateParams(
            self, 'ThermostatScreen',
            {'KeyColor', 'KeyOffOutlineColor', 'KeyOnOutlineColor'},
            screensection)
        self.info = {}
        self.oldinfo = {}
        nominalfontsz = (30, 50, 80, 160)
        nominalspacers = (5, 20, 25, 40, 50, 85)

        self.fsize = []
        self.spacer = []
        if isinstance(self.DefaultHubObj, isy.ISY):
            self.isy = self.DefaultHubObj
            self.ISYObj = self.isy.GetNode(screenname)[0]  # use ControlObj (0)
            if self.ISYObj is None:
                logsupport.Logs.Log("No Thermostat: " + screenname,
                                    severity=ConsoleWarning)
        else:
            logsupport.Logs.Log("Thermostat screen only works with ISY hub",
                                severity=ConsoleError)
            self.ISYObj = None

        self.SetScreenTitle(screen.FlatenScreenLabel(self.label),
                            nominalfontsz[1], self.CharColor)
        self.TempPos = self.startvertspace
        '''
		Size and positions based on vertical screen space less top/bottom borders less default title size of 50
		Compute other fonts sizes based on what is left after that given user ability to set actual title size
		'''
        tempsurf = fonts.fonts.Font(50).render('Temp', 0, wc(
            self.CharColor))  # todo should the 50 be scaled now?
        sizingratio = self.useablevertspace / (self.useablevertspace -
                                               tempsurf.get_height())

        for fs in nominalfontsz:
            self.fsize.append(int(fs * sizingratio))
        for fs in nominalspacers:
            self.spacer.append(int(fs * sizingratio))

        self.StatePos = self.TempPos + fonts.fonts.Font(
            self.fsize[3]).get_linesize() - scaleH(self.spacer[1])
        self.SPPos = self.StatePos + scaleH(self.spacer[2])
        self.AdjButSurf = pygame.Surface(
            (hw.screenwidth, scaleH(self.spacer[3])))
        self.AdjButTops = self.SPPos + fonts.fonts.Font(
            self.fsize[2]).get_linesize() - scaleH(self.spacer[0])
        centerspacing = hw.screenwidth // 5
        self.SPHPosL = int(1.5 * centerspacing)
        self.SPHPosR = int(3.5 * centerspacing)
        self.AdjButSurf.fill(wc(self.BackgroundColor))
        arrowsize = scaleH(self.spacer[3])  # pixel

        for i in range(4):
            gfxdraw.filled_trigon(
                self.AdjButSurf,
                *trifromtop(centerspacing, arrowsize // 2, i + 1, arrowsize,
                            wc(("red", "blue", "red", "blue")[i]), i % 2 != 0))
            self.Keys['temp' + str(i)] = toucharea.TouchPoint(
                'temp' + str(i),
                (centerspacing * (i + 1), self.AdjButTops + arrowsize // 2),
                (arrowsize * 1.2, arrowsize * 1.2),
                proc=functools.partial(self.BumpTemp, ('CLISPH', 'CLISPH',
                                                       'CLISPC', 'CLISPC')[i],
                                       (2, -2, 2, -2)[i]))

        self.ModeButPos = self.AdjButTops + scaleH(self.spacer[5])  # pixel

        bsize = (scaleW(100), scaleH(self.spacer[4]))  # pixel

        self.Keys['Mode'] = toucharea.ManualKeyDesc(
            self,
            "Mode", ["Mode"],
            self.KeyColor,
            self.CharColor,
            self.CharColor,
            center=(self.SPHPosL, self.ModeButPos),
            size=bsize,
            KOn=self.KeyOffOutlineColor,
            proc=functools.partial(self.BumpMode, 'CLIMD', range(8)))

        self.Keys['Fan'] = toucharea.ManualKeyDesc(
            self,
            "Fan", ["Fan"],
            self.KeyColor,
            self.CharColor,
            self.CharColor,
            center=(self.SPHPosR, self.ModeButPos),
            size=bsize,
            KOn=self.KeyOffOutlineColor,
            proc=functools.partial(self.BumpMode, 'CLIFS', (7, 8)))

        self.ModesPos = self.ModeButPos + bsize[1] // 2 + scaleH(
            self.spacer[0])
        if self.ISYObj is not None:
            self.HubInterestList[self.isy.name] = {
                self.ISYObj.address: self.Keys['Mode']
            }  # placeholder for thermostat node
        utilities.register_example("ThermostatScreenDesc", self)