def TryCommand(self, state, fast): selcmd = (('DOF', 'DFOF'), ('DON', 'DFON')) config.debugPrint('ISY', "OnOff sent: ", selcmd[state][fast], ' to ', self.name) url = 'http://' + config.ISYaddr + '/rest/nodes/' + self.address + '/cmd/' + selcmd[state][fast] try: r = config.ISYrequestsession.get(url, verify=False) except requests.exceptions.ConnectTimeout: config.Logs.Log("ISY Comm Timeout (Send Cmd): " + self.address + 'Cmd: ' + selcmd[state][fast], severity=ConsoleError) config.Logs.Log(sys.exc_info()[1], severity=ConsoleError) return (1, 0) except requests.exceptions.ConnectionError: config.Logs.Log("ISY Comm ConnErr (Send Cmd): " + self.address + 'Cmd: ' + selcmd[state][fast], severity=ConsoleError) config.Logs.Log(sys.exc_info()[1], severity=ConsoleError) return (2, 0) except: config.Logs.Log("ISY Comm UnknownErr (Send Cmd): " + self.address + 'Cmd: ' + selcmd[state][fast], severity=ConsoleError) config.Logs.Log(sys.exc_info()[1], severity=ConsoleError) return (3, 0) if r.status_code <> 200: config.Logs.Log( 'ISY Bad status (Send Cmd)' + str(r.status_code) + ' on ' + self.address + 'Cmd: ' + selcmd[state][ fast], severity=ConsoleError) config.Logs.Log(r.text) return (4, r.status_code) else: return (0, 200)
def try_status(addr): # returns (code, respstatus, devicestatus) try: t = 'http://' + config.ISYaddr + '/rest/status/' + addr config.debugPrint('ISY', t) r = config.ISYrequestsession.get(t, verify=False) except requests.exceptions.ConnectTimeout: config.Logs.Log("ISY Comm Timeout (RT status): " + addr, severity=ConsoleError) config.Logs.Log(sys.exc_info()[1], severity=ConsoleError) return (1, 0, False) except requests.exceptions.ConnectionError: config.Logs.Log("ISY Comm ConnErr (RT status): " + addr, severity=ConsoleError) config.Logs.Log(sys.exc_info()[1], severity=ConsoleError) return (2, 0, False) except: config.Logs.Log("ISY Comm UnknownErr (RT status): " + addr, severity=ConsoleError) config.Logs.Log(sys.exc_info()[1], severity=ConsoleError) return (3, 0, False) if r.status_code <> 200: config.Logs.Log('ISY Bad status (RT status)' + str(r.status_code) + ' on ' + addr, severity=ConsoleError) config.Logs.Log(r.text) return (4, r.status_code, False) else: props = xmltodict.parse(r.text)['properties']['property'] if isinstance(props, dict): props = [props] devstate = 0 for item in props: if item['@id'] == "ST": devstate = item['@value'] break return (0, 200, devstate)
def BumpTemp(self, setpoint, degrees): debugPrint('Main', "Bump temp: ", setpoint, degrees) debugPrint('Main', "New: ", self.info[setpoint][0] + degrees) r = config.ISYrequestsession.get( config.ISYprefix + 'nodes/' + self.RealObj.address + '/set/' + setpoint + '/' + str( self.info[setpoint][0] + degrees))
def __init__(self, screensection, screenname): debugPrint('BuildScreen', "Build Clock Screen") screen.ScreenDesc.__init__(self, screensection, screenname) utilities.LocalizeParams(self, screensection, CharSize=[20], Font='droidsansmono', OutFormat=[]) for i in range(len(self.CharSize), len(self.OutFormat)): self.CharSize.append(self.CharSize[-1]) utilities.register_example("ClockScreen", self)
def __init__(self, screensection, screenname): debugPrint('BuildScreen', "Build House Status Screen") screen.ScreenDesc.__init__(self, screensection, screenname, ()) # no extra cmd keys utilities.LocalizeParams(self, screensection, NormalOn=[], NormalOff=[]) checklist = [nm for nm in config.ISY.NodesByName if ((nm in self.NormalOn) or (nm in self.NormalOff))] # addr -> name utilities.register_example("HouseStatusScreenDesc", self)
def Watcher(): config.watchstarttime = time.time() config.watchlist = ['init'] debugPrint('Daemon', "Watcher: ", config.watchstarttime, os.getpid()) config.Daemon_pid = os.getpid() server = ISYEvent() # can add parameter debug = 3 to have library dump some info out output server.subscribe(addr=config.ISYaddr, userl=config.ISYuser, userp=config.ISYpassword) server.set_process_func(event_feed, "") server.events_loop()
def __init__(self, screensection, screenname): debugPrint('BuildScreen', "New TimeTempDesc ", screenname) screen.ScreenDesc.__init__(self, screensection, screenname) utilities.LocalizeParams(self, screensection, WunderKey='', location='', CharSize=[20], Font='droidsansmono', TimeFormat=[], ConditionFields=[], ConditionFormat=[], ForecastFields=[], ForecastFormat=[], ForecastDays=1, SkipDays=0) self.scrlabel = screen.FlatenScreenLabel(self.label) self.WInfo = weatherinfo.WeatherInfo(self.WunderKey, self.location) for i in range(len(self.CharSize), len(self.TimeFormat) + len(self.ConditionFormat) + len(self.ForecastFormat)): self.CharSize.append(self.CharSize[-1])
def __init__(self, keys): debugPrint("BuildScreen", "Build Maintenance Screen") screen.BaseKeyScreenDesc.__init__(self, fixedoverrides, "Maint", withnav=False) utilities.LocalizeParams(self, None, TitleFontSize=40, SubFontSize=25) self.keysbyord = [] for k, kt in keys.iteritems(): self.keysbyord.append( toucharea.ManualKeyDesc(k, [kt[0]], "gold", "black", "white", KOn="black", KOff="white", proc=kt[1]) ) topoff = self.TitleFontSize + self.SubFontSize self.LayoutKeys(topoff, config.screenheight - 2 * config.topborder - topoff) utilities.register_example("MaintScreenDesc", self)
def __init__(self, screensection, screenname): debugPrint('BuildScreen', "New KeyScreenDesc ", screenname) screen.BaseKeyScreenDesc.__init__(self, screensection, screenname) self.subscriptionlist = {} # Build the Key objects for keyname in screensection: if isinstance(screensection[keyname], Section): NewKey = keydesc.KeyDesc(screensection[keyname], keyname) self.keysbyord.append(NewKey) self.LayoutKeys() utilities.register_example("KeyScreenDesc", self)
def SendCommand(self, state, fast): try: for i in range(3): error, status_code = self.TryCommand(state, fast) if error == 0: # good result raise GotIt() else: config.debugPrint('ISY', 'Send command failed', str(error), str(status_code)) time.sleep(.5) config.Logs.Log("Attempting ISY retry (Send Cmd) " + str(i + 1), severity=ConsoleError) config.Logs.Log("ISY Communications Failure (Send Cmd)", severity=ConsoleError) maintscreen.errorexit('reboot') except GotIt: pass
def __init__(self): config.debugPrint("Main", "Screensize: ", config.screenwidth, config.screenheight) config.Logs.Log("Screensize: " + str(config.screenwidth) + " x " + str(config.screenheight)) config.Logs.Log( "Scaling ratio: " + "{0:.2f}".format(config.dispratioW) + ':' + "{0:.2f}".format(config.dispratioH)) # define user events self.MAXTIMEHIT = pygame.event.Event(pygame.USEREVENT) self.INTERVALHIT = pygame.event.Event(pygame.USEREVENT + 1) self.GOHOMEHIT = pygame.event.Event(pygame.USEREVENT + 2) self.DIMCYCLE = pygame.event.Event(pygame.USEREVENT + 3) self.dimscreenindex = 0 self.isDim = False self.presscount = 0 self.AS = None self.BrightenToHome = False
def __init__(self, screensection, screenname): debugPrint('BuildScreen', "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)
def HandleScreen(self, newscr=True): # stop any watching for device stream config.toDaemon.put(["", self.RealObj.address]) self.ShowScreen() while 1: choice = config.DS.NewWaitPress(self) if choice[0] == WAITEXIT: return choice[1] elif (choice[0] == WAITNORMALBUTTON) or (choice[0] == WAITNORMALBUTTONFAST): if choice[1] < 4: self.BumpTemp(('CLISPH', 'CLISPH', 'CLISPC', 'CLISPC')[choice[1]], (2, -2, 2, -2)[choice[1]]) else: self.BumpMode(('CLIMD', 'CLIFS')[choice[1] - 4], (range(8), (7, 8))[choice[1] - 4]) elif choice[0] == WAITISYCHANGE: debugPrint('Main', "Thermo change", choice) self.ShowScreen()
def get_real_time_status(addrlist): # multiple calls here is substantially faster than one call for all status then selecting devices # this proc assumes a device that returns a simple ST value for status statusdict = {} for addr in addrlist: try: for i in range(3): error, status_code, devstate = try_status(addr) if error == 0: # good result statusdict[addr] = int(devstate if devstate.isdigit() else 0) raise GotIt() else: config.debugPrint('ISY', 'Get status failed: ', str(error), str(status_code), str(devstate)) time.sleep(.5) config.Logs.Log("Attempting ISY retry " + str(i + 1), severity=ConsoleError) config.Logs.Log("ISY Communications Failure", severity=ConsoleError) maintscreen.errorexit('reboot') except GotIt: pass config.debugPrint('ISY', statusdict) return statusdict
def __init__(self, screensection, screenname): debugPrint('BuildScreen', "New WeatherScreenDesc ", screenname) screen.ScreenDesc.__init__(self, screensection, screenname, (('which',('',)),)) utilities.LocalizeParams(self, screensection, WunderKey='', location='') self.scrlabel = screen.FlatenScreenLabel(self.label) # entries are (fontsize, centered, formatstring, values) self.conditions = [(2, True, "{d}", self.scrlabel), (1, True, "{d[0]}", ('Location',)), (1, False, u"Now: {d[0]} {d[1]}\u00B0F", ('Sky', 'Temp')), (0, False, u" Feels like: {d[0]}\u00B0", ('Feels',)), (1, False, "Wind {d[0]}", ('WindStr',)), (1, False, "Sunrise: {d[0]:02d}:{d[1]:02d}", ('SunriseH', 'SunriseM')), (1, False, "Sunset: {d[0]:02d}:{d[1]:02d}", ('SunsetH', 'SunsetM')), (0, False, "Moon rise: {d[0]} set: {d[1]}", ('Moonrise', 'Moonset')), (0, False, " {d[0]}% illuminated", ('MoonPct',)), (0, False, "will be replaced", "")] self.forecast = [(1, False, u"{d[0]} {d[1]}\u00B0/{d[2]}\u00B0 {d[3]}", ('Day', 'High', 'Low', 'Sky')), (1, False, "Wind: {d[0]} at {d[1]}", ('WindDir', 'WindSpd'))] self.Info = weatherinfo.WeatherInfo(self.WunderKey, self.location) utilities.register_example("WeatherScreenDesc", self)
def BumpMode(self, mode, vals): debugPrint('Main', "Bump mode: ", mode, vals) cv = vals.index(self.info[mode][0]) debugPrint('Main', cv, vals[cv]) cv = (cv + 1)%len(vals) debugPrint('Main', "new cv: ", cv) r = config.ISYrequestsession.get( config.ISYprefix + 'nodes/' + self.RealObj.address + '/set/' + mode + '/' + str(vals[cv]))
def ShowScreen(self): self.PaintBase() r = config.ISYrequestsession.get('http://' + config.ISYaddr + '/rest/nodes/' + self.RealObj.address, verify=False) tstatdict = xmltodict.parse(r.text) props = tstatdict["nodeInfo"]["properties"]["property"] self.info = {} for item in props: debugPrint('Main', item["@id"], ":", item["@value"], ":", item["@formatted"]) self.info[item["@id"]] = (int(item['@value']), item['@formatted']) config.screen.blit(self.TitleRen, self.TitlePos) r = config.fonts.Font(self.fsize[3], bold=True).render(u"{:4.1f}".format(self.info["ST"][0]/2), 0, wc(self.CharColor)) config.screen.blit(r, ((config.screenwidth - r.get_width())/2, self.TempPos)) if isinstance(self.info["CLIHCS"][0], int): r = config.fonts.Font(self.fsize[0]).render(("Idle", "Heating", "Cooling")[self.info["CLIHCS"][0]], 0, wc(self.CharColor)) else: r = config.fonts.Font(self.fsize[0]).render("n/a", 0, wc(self.CharColor)) config.screen.blit(r, ((config.screenwidth - r.get_width())/2, self.StatePos)) r = config.fonts.Font(self.fsize[2]).render( "{:2d} {:2d}".format(self.info["CLISPH"][0]/2, self.info["CLISPC"][0]/2), 0, wc(self.CharColor)) config.screen.blit(r, ((config.screenwidth - r.get_width())/2, self.SPPos)) config.screen.blit(self.AdjButSurf, (0, self.AdjButTops)) self.keysbyord[4].PaintKey() self.keysbyord[5].PaintKey() r1 = config.fonts.Font(self.fsize[1]).render( ('Off', 'Heat', 'Cool', 'Auto', 'Fan', 'Prog Auto', 'Prog Heat', 'Prog Cool')[self.info["CLIMD"][0]], 0, wc(self.CharColor)) r2 = config.fonts.Font(self.fsize[1]).render(('On', 'Auto')[self.info["CLIFS"][0] - 7], 0, wc(self.CharColor)) config.screen.blit(r1, (self.keysbyord[4].Center[0] - r1.get_width()/2, self.ModesPos)) config.screen.blit(r2, (self.keysbyord[5].Center[0] - r2.get_width()/2, self.ModesPos)) pygame.display.update()
def event_feed(*arg): data = arg[0] if config.seq <> int(data["Event-seqnum"]): config.fromDaemon.put( ("Log", "Event mismatch - Expected: " + str(config.seq) + " Got: " + str(data["Event-seqnum"]), ConsoleWarning)) config.seq = int(data["Event-seqnum"]) + 1 else: config.seq += 1 if config.streamid <> data["Event-sid"]: config.fromDaemon.put(("Log", "Now using event stream: " + str(data["Event-sid"]), ConsoleWarning)) config.streamid = data["Event-sid"] if time.time() < config.watchstarttime + 10: debugPrint('Daemon', time.time(), "Skipping item in stream: ", data["Event-seqnum"], ":", data["control"], " : ", data["node"], " : ", data["eventInfo"], " : ", data["action"]) return None while not config.toDaemon.empty(): msg = config.toDaemon.get() if len(msg) == 0: config.watchlist = ["empty"] elif msg[0] == 'flagchange': config.Flags[msg[1]] = msg[2] else: config.watchlist = msg debugPrint('Daemon', time.time(), "New watchlist: ", config.watchlist) data = arg[0] # data["Event-seqnum"],":",prcode," : ",data["node"]," : ",data["eventInfo"]," : ",data["action"]," : ",data["Event-sid"]) eventcode = data["control"] if eventcode in EVENT_CTRL: prcode = EVENT_CTRL[eventcode] # print "Orig EC", eventcode, prcode else: prcode = "**" + eventcode + "**" # print "Ugly EC", eventcode, prcode if (prcode == "Status" or config.watchlist[0] == "") and data["node"] in config.watchlist: debugPrint('Daemon', time.time(), "Status update in stream: ", data["Event-seqnum"], ":", prcode, " : ", data["node"], " : ", data["eventInfo"], " : ", data["action"]) debugPrint('Daemon', time.time(), "Raw stream item: ", data) if data["action"] is dict: data["action"] = data["action"]["action"] debugPrint('Daemon', "V5 stream - pull up action value: ", data["action"]) config.fromDaemon.put(("Node", data["node"], data["action"])) debugPrint('Daemon', "Qsize at daemon ", config.fromDaemon.qsize()) else: config.debugPrint('Daemon', time.time(), "Other update in stream: ", data["Event-seqnum"], ":", prcode, " : ", data["node"], " : ", data["eventInfo"], " : ", data["action"]) debugPrint('Daemon', time.time(), "Raw stream item: ", data)
def runThen(self): config.debugPrint('ISY', "runThen sent to ", self.name) url = config.ISYprefix + 'programs/' + self.address + '/runThen' r = config.ISYrequestsession.get(url) return r
def NewWaitPress(self, ActiveScreen, callbackint=0, callbackproc=None, callbackcount=0): self.AS = ActiveScreen cycle = 0 if callbackint <> 0: # todo needs a better structural fix for posted actions that persist across Waitpress calls pygame.time.set_timer(self.INTERVALHIT.type, int(callbackint*1000)) cycle = callbackcount if callbackcount <> 0 else 100000000 # essentially infinite if self.isDim and self.BrightenToHome: pygame.time.set_timer(self.GOHOMEHIT.type, 0) # in final quiet state so cancel gohome until a touch else: pygame.time.set_timer(self.MAXTIMEHIT.type, self.AS.DimTO*1000) # if not in final quiet state set dim timer while True: rtn = (0, 0) event = pygame.fastevent.poll() if event.type == pygame.NOEVENT: time.sleep(.01) pass elif event.type == pygame.MOUSEBUTTONDOWN: pos = (pygame.mouse.get_pos()[0], pygame.mouse.get_pos()[1]) # if self.presscount < 10: # this is debug code for a weird/unreproducible RPi behavior where touch is off # print pos # self.presscount += 1 tapcount = 1 pygame.time.delay(config.MultiTapTime) while True: eventx = pygame.fastevent.poll() if eventx.type == pygame.NOEVENT: break elif eventx.type == pygame.MOUSEBUTTONDOWN: tapcount += 1 pygame.time.delay(config.MultiTapTime) else: continue if tapcount > 2: self.GoDim(False) rtn = (WAITEXIT, tapcount) break # on any touch reset return to home screen pygame.time.set_timer(self.GOHOMEHIT.type, int(config.HomeScreenTO)*1000) # on any touch restart dim timer and reset to bright if dim pygame.time.set_timer(self.MAXTIMEHIT.type, self.AS.DimTO*1000) dimscr = self.GoDim(False) if dimscr is not None: rtn = (WAITEXIT, config.HomeScreen) break for i in range(len(self.AS.keysbyord)): K = self.AS.keysbyord[i] if K.touched(pos): if tapcount == 1: rtn = (WAITNORMALBUTTON, i) else: rtn = (WAITNORMALBUTTONFAST, i) if self.AS.PrevScreen is not None: if self.AS.PrevScreenKey.touched(pos): rtn = (WAITEXIT, self.AS.PrevScreen) elif self.AS.NextScreenKey.touched(pos): rtn = (WAITEXIT, self.AS.NextScreen) for K in self.AS.ExtraCmdKeys: if K.touched(pos): rtn = (WAITEXTRACONTROLBUTTON, K.name) if rtn[0] <> 0: break continue elif event.type == self.MAXTIMEHIT.type: dimscr = self.GoDim(True) if dimscr is not None: rtn = (WAITEXIT, dimscr) break continue elif event.type == self.DIMCYCLE.type: self.dimscreenindex = (self.dimscreenindex + 1)%len(config.DimIdleList) pygame.time.set_timer(self.DIMCYCLE.type, config.DimIdleTimes[self.dimscreenindex]) rtn = (WAITEXIT, config.DimIdleList[self.dimscreenindex]) break elif event.type == self.INTERVALHIT.type: if (callbackproc is not None) and (cycle > 0): callbackproc(cycle) cycle -= 1 continue elif event.type == self.GOHOMEHIT.type: rtn = (WAITEXIT, config.HomeScreen) break else: pass # ignore and flush other events if (not config.fromDaemon.empty()) and (cycle == 0): # todo don't process daemon reports while cycling debugPrint('Main', "Q size at main loop ", config.fromDaemon.qsize()) item = config.fromDaemon.get() debugPrint('Main', time.time(), "ISY reports change: ", "Key: ", str(item)) if item[0] == "Log": config.Logs.Log(item[1], severity=item[2]) continue elif item[0] == "Node": rtn = (WAITISYCHANGE, (item[1], item[2])) break else: config.Logs.Log("Bad msg from watcher: " + str(item), Severity=ConsoleWarning) # check for periodic alert items todo pygame.time.set_timer(self.INTERVALHIT.type, 0) pygame.time.set_timer(self.MAXTIMEHIT.type, 0) return rtn
def __init__(self, keysection, keyname): debugPrint('BuildScreen', " New Key Desc ", keyname) toucharea.ManualKeyDesc.__init__(self, keysection, keyname) utilities.LocalizeParams(self, keysection, SceneProxy='', KeyRunThenName='', type='ONOFF') self.MonitorObj = None # ISY Object monitored to reflect state in the key (generally a device within a Scene) # for ONOFF keys (and others later) map the real and monitored nodes in the ISY # map the key to a scene or device - prefer to map to a scene so check that first # Obj is the representation of the ISY Object itself, addr is the address of the ISY device/scene if self.type in ('ONOFF'): if keyname in config.ISY.ScenesByName: self.RealObj = config.ISY.ScenesByName[keyname] if self.SceneProxy <> '': # explicit proxy assigned if self.SceneProxy in config.ISY.NodesByAddr: # address given self.MonitorObj = config.ISY.NodesByAddr[self.SceneProxy] debugPrint('BuildScreen', "Scene ", keyname, " explicit address proxying with ", self.MonitorObj.name, '(', self.SceneProxy, ')') elif self.SceneProxy in config.ISY.NodesByName: self.MonitorObj = config.ISY.NodesByName[self.SceneProxy] debugPrint('BuildScreen', "Scene ", keyname, " explicit name proxying with ", self.MonitorObj.name, '(', self.MonitorObj.address, ')') else: config.Logs.Log('Bad explicit scene proxy:' + self.name, severity=ConsoleWarning) else: for i in self.RealObj.members: device = i[1] if device.enabled and device.hasstatus: self.MonitorObj = device # todo try to status the device here to see if it will respond break else: config.Logs.Log('Skipping disabled/nonstatus device: ' + device.name, severity=ConsoleWarning) if self.MonitorObj is None: config.Logs.Log("No proxy for scene: " + keyname, severity=ConsoleError) debugPrint('BuildScreen', "Scene ", keyname, " default proxying with ", self.MonitorObj.name) elif keyname in config.ISY.NodesByName: self.RealObj = config.ISY.NodesByName[keyname] self.MonitorObj = self.RealObj else: debugPrint('BuildScreen', "Screen", keyname, "unbound") config.Logs.Log('Key Binding missing: ' + self.name, severity=ConsoleWarning) elif self.type in ("ONBLINKRUNTHEN"): self.State = False try: self.RealObj = config.ISY.ProgramsByName[self.KeyRunThenName] except: self.RealObj = None debugPrint('BuildScreen', "Unbound program key: ", self.name) config.Logs.Log("Missing Prog binding: " + self.name, severity=ConsoleWarning) else: debugPrint('BuildScreen', "Unknown key type: ", self.name) config.Logs.Log("Bad keytype: " + self.name, severity=ConsoleWarning) utilities.register_example("KeyDesc", self) debugPrint('BuildScreen', repr(self))
def HandleScreen(self, newscr=True): def BlinkKey(scr, key, cycle): # thistime = finalstate if cycle % 2 <> 0 else not finalstate key.State = not key.State key.PaintKey() if newscr: # key screen change actually occurred self.PaintBase() self.subscriptionlist = {} debugPrint('Main', "Switching to screen: ", self.name) for K in self.keysbyord: if K.MonitorObj is not None: # skip program buttons self.subscriptionlist[K.MonitorObj.address] = K states = isy.get_real_time_status(self.subscriptionlist.keys()) for K in self.keysbyord: if K.MonitorObj is not None: K.State = not (states[K.MonitorObj.address] == 0) # K is off (false) only if state is 0 debugPrint('Main', "Active Subscription List will be:") addressestoscanfor = ["Status"] for i in self.subscriptionlist: debugPrint('Main', " Subscribe: ", i, self.subscriptionlist[i].name, " : ", self.subscriptionlist[i].RealObj.name, ' via ', self.subscriptionlist[i].MonitorObj.name) addressestoscanfor.append(i) config.toDaemon.put(addressestoscanfor) self.PaintKeys() else: debugPrint('Main', "Skipping screen recreation: ", self.name) blinkproc = None blinktime = 0 blinks = 0 while 1: choice = config.DS.NewWaitPress(self, callbackint=blinktime, callbackproc=blinkproc, callbackcount=blinks) blinkproc = None blinktime = 0 blinks = 0 if (choice[0] == WAITNORMALBUTTON) or (choice[0] == WAITNORMALBUTTONFAST): # handle various keytype cases K = self.keysbyord[choice[1]] if K.type == "ONOFF": K.State = not K.State if K.RealObj is not None: K.RealObj.SendCommand(K.State, choice[0] <> WAITNORMALBUTTON) # config.Logs.Log("Sent command to " + K.RealObj.name) else: config.Logs.Log("Screen: " + self.name + " press unbound key: " + K.name, severity=logsupport.ConsoleWarning) K.PaintKey() elif K.type == "ONBLINKRUNTHEN": # force double tap for programs for safety - too easy to accidentally single tap with touchscreen if choice[0] == WAITNORMALBUTTONFAST: K.RealObj.runThen() blinkproc = functools.partial(BlinkKey, config.screen, K) blinktime = .5 blinks = 8 # even number leaves final state of key same as initial state K.PaintKey() # leave K.State as is - key will return to off at end elif K.type == "ONOFFRUN": pass elif choice[0] == WAITEXIT: return choice[1] elif choice[0] == WAITISYCHANGE: K = self.subscriptionlist[choice[1][0]] ActState = int(choice[1][1]) <> 0 if ActState <> K.State: K.State = ActState K.PaintKey()
Build the ISY object structure and connect the configured screens to it """ configobjects.MyScreens() config.Logs.Log("Linked config to ISY") """ Set up the watcher daemon and its communications """ config.toDaemon = Queue(300) config.fromDaemon = Queue(300) p = Process(target=watchdaemon.Watcher, name="Watcher") p.daemon = True p.start() config.DaemonProcess = p config.Daemon_pid = p.pid debugPrint('Main', "Spawned watcher as: ", config.Daemon_pid) config.Logs.Log("Watcher pid: " + str(config.Daemon_pid)) config.Logs.livelog = False # turn off logging to the screen and give user a moment to scan time.sleep(2) # config.backlight.ChangeDutyCycle(config.BrightLevel) """ Set up the Maintenance Screen """ config.Logs.Log("Built Maintenance Screen") maintscreen.SetUpMaintScreens() """ Dump documentation """
def __init__(self): thisconfig = config.ParsedConfigFile debugPrint('BuildScreen', "Process Configuration File") mainlist = {} secondlist = {} extralist = {} for screenitem in thisconfig: NewScreen = None if isinstance(thisconfig[screenitem], Section): thisScreen = thisconfig[screenitem] # its a screen tempscreentype = thisScreen.get("type", "unspec") debugPrint('BuildScreen', "Screen of type ", tempscreentype) if tempscreentype in config.screentypes: NewScreen = config.screentypes[tempscreentype](thisScreen, screenitem) config.Logs.Log(tempscreentype + " screen " + screenitem) else: config.Logs.Log("Screentype error" + screenitem + " type " + tempscreentype, severity=ConsoleWarning) pass if NewScreen is not None: # set the standard navigation keys and navigation linkages if NewScreen.name in config.MainChain: mainlist[NewScreen.name] = NewScreen elif NewScreen.name in config.SecondaryChain: secondlist[NewScreen.name] = NewScreen else: extralist[NewScreen.name] = NewScreen config.ExtraChain.append(NewScreen.name) if len(secondlist) == 0: secondlist = extralist config.SecondaryChain = config.ExtraChain config.ExtraChain = [] config.Logs.Log("Main Screen List:") for scr in config.MainChain: if not scr in mainlist: config.Logs.Log("-- Undefined Screen:", scr, severity=ConsoleWarning) config.MainChain.remove(scr) for scr in config.MainChain: if scr in mainlist: S = mainlist[scr] S.PrevScreen = mainlist[config.MainChain[config.MainChain.index(scr) - 1]] S.NextScreen = mainlist[config.MainChain[(config.MainChain.index(scr) + 1)%len(config.MainChain)]] config.Logs.Log("---" + scr) config.Logs.Log("Secondary Screen List:") for scr in config.SecondaryChain: if not scr in secondlist: config.Logs.Log("-- Undefined Screen:", scr, severity=ConsoleWarning) config.SecondaryChain.remove(scr) for scr in config.SecondaryChain: if scr in secondlist: S = secondlist[scr] S.PrevScreen = secondlist[config.SecondaryChain[config.SecondaryChain.index(scr) - 1]] S.NextScreen = secondlist[ config.SecondaryChain[(config.SecondaryChain.index(scr) + 1)%len(config.SecondaryChain)]] config.Logs.Log("---" + scr) config.Logs.Log("Not on a screen list (unavailable)", severity=ConsoleWarning) for scr in config.ExtraChain: config.Logs.Log("---" + scr, severity=ConsoleWarning) for S in mainlist.itervalues(): S.FinishScreen() for S in secondlist.itervalues(): S.FinishScreen() if config.HomeScreenName in config.MainChain: config.HomeScreen = mainlist[config.HomeScreenName] else: config.Logs.Log("Error in Home Screen Name", severity=ConsoleWarning) config.HomeScreen = mainlist[config.MainChain[0]] config.HomeScreen2 = secondlist[config.SecondaryChain[0]] config.Logs.Log("Home Screen: " + config.HomeScreen.name) for sn, st in zip(config.DimIdleListNames, config.DimIdleListTimes): for l, d in zip((config.MainChain, config.SecondaryChain, config.ExtraChain), (mainlist, secondlist, extralist)): if sn in l: config.Logs.Log('Dim Screen: ' + sn + '/' + st) config.DimIdleList.append(d[sn]) config.DimIdleTimes.append(int(st)*1000) # handle deprecated DimHomeScreenCoverName if config.DimHomeScreenCoverName <> "" and len(config.DimIdleList) == 0: if config.DimHomeScreenCoverName in config.MainChain: config.DimIdleList.append(mainlist[config.DimHomeScreenCoverName]) config.DimIdleTimes.append(1000) config.Logs.Log("DimHS(deprecated): " + config.DimHomeScreenCoverName) if len(config.DimIdleList) == 0: config.DimIdleList[0] = config.HomeScreen config.DimIdleTimes[0] = 1000 config.Logs.Log("No Dim Home Screen Cover Set") config.Logs.Log("First Secondary Screen: " + config.HomeScreen2.name)