Example #1
0
    def Command(alert):
        if not isinstance(alert.trigger, alerttasks.VarChangeTrigger):
            logsupport.Logs.Log('Net Command not triggered by variable',
                                severity=ConsoleWarning)
        varval = valuestore.GetVal(alert.trigger.var)
        valuestore.SetVal(alert.trigger.var, 0)
        if varval == 1:
            logsupport.Logs.Log('Remote restart')
            exitutils.Exit_Screen_Message('Remote restart requested',
                                          'Remote Restart')
            config.terminationreason = 'remote restart'
            exitutils.Exit(exitutils.REMOTERESTART)
        elif varval == 2:
            logsupport.Logs.Log('Remote reboot')
            exitutils.Exit_Screen_Message('Remote reboot requested',
                                          'Remote Reboot')
            config.terminationreason = 'remote reboot'
            exitutils.Exit(exitutils.REMOTEREBOOT)
        elif varval == 3:
            logsupport.Logs.Log('Remote download stable')
            maintscreen.fetch_stable()
        elif varval == 4:
            logsupport.Logs.Log('Remote download beta')
            maintscreen.fetch_beta()
        elif varval == 5:
            logsupport.Logs.Log('Remote set stable')
            subprocess.Popen('sudo rm /home/pi/usebeta', shell=True)
        elif varval == 6:
            logsupport.Logs.Log('Remote set beta')
            subprocess.Popen('sudo touch /home/pi/usebeta', shell=True)
        elif varval == 7:
            logsupport.Logs.Log('Remote history buffer dump')
            entrytime = time.strftime('%m-%d-%y %H:%M:%S')
            historybuffer.DumpAll('Command Dump', entrytime)
        elif varval == 8:
            logsupport.Logs.Log('Remote error indicator cleared')
            config.sysStore.ErrorNotice = -1
        elif varval in range(100, 100 + len(debug.DbgFlags)):
            flg = debug.DbgFlags[varval - 100]
            valuestore.SetVal(('Debug', flg), True)
            logsupport.Logs.Log('Remote set debug ', flg)
        elif varval in range(200, 200 + len(debug.DbgFlags)):
            flg = debug.DbgFlags[varval - 200]
            valuestore.SetVal(('Debug', flg), False)
            logsupport.Logs.Log('Remote clear debug ', flg)
        elif varval in range(300, 310):
            valuestore.SetVal(('Debug', 'LogLevel'), varval - 300)
            logsupport.Logs.Log('Remote set LogLevel to ', varval - 300)

        else:
            logsupport.Logs.Log('Unknown remote command: ', varval)
Example #2
0
		def DoRestart():
			if self.fetcher is not None and self.fetcher.is_alive():
				logsupport.Logs.Log('Delaying restart until fetch completes')
				dly = timers.OnceTimer(10,start=True,name='RestartDelay',proc=DoDelayedRestart)
				ReportStatus('wait restart', hold=1)
				return
			ReportStatus('rmt restart', hold=1)
			exitutils.Exit_Screen_Message('Remote restart requested', 'Remote Restart')
			config.terminationreason = 'mqtt restart'
			exitutils.Exit(exitutils.REMOTERESTART)
Example #3
0
    def MainControlLoop(self, InitScreen):

        TimerName = 0

        config.sysStore.ErrorNotice = -1  # don't pester for errors during startup

        threadmanager.StartThreads()
        config.sysStore.LogStartTime = time.time(
        )  # MQTT will start tracking other console errors now
        # so we can start broadcasting our errors
        logsupport.LocalOnly = False

        self.ScreensDict = screens.SecondaryDict.copy()
        self.ScreensDict.update(screens.MainDict)

        for a in alerttasks.AlertItems.AlertsList.values():
            a.state = 'Armed'
            logsupport.Logs.Log("Arming " + a.type + " alert " + a.name)
            logsupport.Logs.Log("->" + str(a), severity=ConsoleDetail)

            if a.type == 'Periodic':
                alerttasks.SchedulePeriodicEvent(a)
            elif a.type == 'NodeChange':
                a.trigger.node.Hub.SetAlertWatch(a.trigger.node, a)
                if a.trigger.IsTrue():
                    # noinspection PyArgumentList
                    PostEvent(
                        ConsoleEvent(CEvent.ISYAlert,
                                     hub='DS-NodeChange',
                                     alert=a))
            elif a.type == 'VarChange':
                a.state = 'Init'
                # Note: VarChange alerts don't need setup because the store has an alert proc
                pass
            elif a.type == 'Init':
                a.Invoke()
            else:
                logsupport.Logs.Log("Internal error - unknown alert type: ",
                                    a.type,
                                    ' for ',
                                    a.name,
                                    severity=ConsoleError,
                                    tb=False)

        logsupport.Logs.livelog = False  # turn off logging to the screen

        with open("{}/.ConsoleStart".format(config.sysStore.HomeDir),
                  "a") as f:
            f.write(str(time.time()) + '\n')
        if config.Running:  # allow for a very early restart request from things like autoversion
            self.SwitchScreen(InitScreen, 'Bright', 'Startup', newstate='Home')

        statusperiod = time.time()
        prevstatus = ''

        if config.sysStore.versionname in ('development'):
            TempThdList = threading.Thread(target=failsafe.TempThreadList,
                                           name='ThreadLister')
            TempThdList.daemon = True
            TempThdList.start()

        Injector = threading.Thread(target=failsafe.NoEventInjector,
                                    name='Injector')
        Injector.daemon = True
        Injector.start()
        Failsafe = multiprocessing.Process(target=failsafe.MasterWatchDog,
                                           name='Failsafe')
        Failsafe.daemon = True
        Failsafe.start()
        config.sysStore.SetVal('Watchdog_pid', Failsafe.pid)
        #if config.sysStore.versionname in ('development', 'homerelease'): topper.inittop()

        logsupport.Logs.Log('Starting master watchdog {} for {}'.format(
            config.sysStore.Watchdog_pid, config.sysStore.Console_pid))

        event = None

        pcslist = ''
        for pcs in ('Console', 'Watchdog', 'AsyncLogger', 'Topper'):
            try:
                if config.sysStore.GetVal(pcs + '_pid') != 0:
                    pcslist = pcslist + '{}: {} '.format(
                        pcs, config.sysStore.GetVal(pcs + '_pid'))
            except:
                pass
        logsupport.Logs.Log('Console Up: {}'.format(pcslist))

        perfdump = time.time()
        ckperf = time.time()
        dayord = time.localtime().tm_yday

        try:
            while config.Running:  # Operational Control Loop
                logsupport.maincyclecnt += 1
                if logsupport.maincyclecnt == 4:
                    logsupport.NewDay(Report=False)  # ignore startup delays
                if dayord != time.localtime().tm_yday:
                    dayord = time.localtime().tm_yday
                    logsupport.NewDay(Report=True)
                self.HBEvents.Entry('Start event loop iteration')

                StackCheck = traceback.format_stack()
                if len(StackCheck) != 4 and config.sysStore.versionname in (
                        'development', 'homerelease'):
                    logsupport.Logs.Log('Stack growth error',
                                        severity=ConsoleWarning,
                                        hb=True)
                    for L in StackCheck:
                        logsupport.Logs.Log(L.strip())

                if time.time() - ckperf > 900:  # todo 900:
                    ckperf = time.time()
                    if config.sysStore.versionname in (
                            'development',
                            'homerelease') and (logsupport.queuedepthmax > 4 or
                                                logsupport.queuetimemax > 1):
                        logsupport.Logs.Log(
                            'Console performance({}): maxq: {} maxwait: {}'.
                            format(time.time() - perfdump,
                                   logsupport.queuedepthmax,
                                   logsupport.queuetimemax),
                            severity=ConsoleWarning,
                            hb=True,
                            localonly=True)
                        logsupport.queuetimemax = 0
                        logsupport.queuedepthmax = 0
                        perfdump = time.time()

                if not Failsafe.is_alive():
                    logsupport.DevPrint('Watchdog died')
                    logsupport.Logs.Log('Watchdog died - restarting console',
                                        severity=ConsoleError,
                                        hb=True)
                    config.terminationreason = 'watchdog died'
                    exitutils.Exit(exitutils.ERRORRESTART)
                failsafe.KeepAlive.set()

                nowtime = time.time()
                if statusperiod <= nowtime or prevstatus != config.sysStore.consolestatus:
                    ReportStatus(config.sysStore.consolestatus)
                    prevstatus = config.sysStore.consolestatus
                    statusperiod = nowtime + 60

                if not threadmanager.Watcher.is_alive():
                    logsupport.Logs.Log("Threadmanager Failure",
                                        severity=ConsoleError,
                                        tb=False)
                    config.terminationreason = 'watcher died'
                    exitutils.Exit(exitutils.ERRORRESTART)

                logsupport.LoggerQueue.put(
                    (logsupport.Command.Touch,
                     "{}/.ConsoleStart".format(config.sysStore.HomeDir)))

                if debug.dbgStore.GetVal('StatesDump'):
                    debug.dbgStore.SetVal('StatesDump', False)
                    for h, hub in hubs.hubs.Hubs.items():
                        print('States dump for hub: ', h)
                        hub.StatesDump()
                    debug.dbgStore.SetVal('StatesDump', False)

                if self.Deferrals:  # an event was deferred mid screen touches - handle now
                    event = self.Deferrals.pop(0)
                    self.HBEvents.Entry('Got deferred event: {}   {}'.format(
                        time.time(), repr(event)))
                    debug.debugPrint('EventList', 'Deferred Event Pop', event)
                elif debug.dbgStore.GetVal('QDump'):
                    # todo QDump with new event mechanism
                    '''if events:
						debug.debugPrint('QDump', 'Time: ', time.time())
						for e in events:
							self.Deferrals.append(e)
							debug.debugPrint('QDump', e, e.type)
						else:
							debug.debugPrint('QDump', "Empty queue")
							time.sleep(0.01)
					event = pygame.event.Event(NOEVENT, dict={'inject':time.time(),'defer':True}) #eventfix
					'''
                    pass
                else:
                    needvalidevent = True
                    while needvalidevent:
                        event = GetEvent()
                        self.HBEvents.Entry('Got event: {}  {}'.format(
                            time.time(), repr(event)))
                        if event.type == CEvent.ACTIVITYTIMER:
                            if event.seq == self.activityseq:
                                needvalidevent = False
                            else:
                                if config.sysStore.versionname == 'development':
                                    logsupport.Logs.Log(
                                        'Outdated activity {} {}'.format(
                                            event.seq, self.activityseq))
                                    self.HBEvents.Entry(
                                        'outdated activity {} {}'.format(
                                            event.seq, self.activityseq))
                                    logsupport.DevPrint(
                                        'outdated activity {} {}'.format(
                                            event.seq, self.activityseq))
                        else:
                            needvalidevent = False
                self.HBEvents.Entry('Process at {}  {}'.format(
                    time.time(), repr(event)))

                postwaittime = time.time()

                if event.type == CEvent.FailSafePing:
                    self.HBEvents.Entry(
                        'Saw NOEVENT {} after injection at {}'.format(
                            time.time() - event.inject, event.inject))
                    pass  # these appear to make sure loop is running
                elif event.type == CEvent.MouseDown:  # pygame.MOUSEBUTTONDOWN:
                    self.HBEvents.Entry('MouseDown' + str(event.pos))
                    debug.debugPrint(
                        'Touch', 'MouseDown' + str(event.pos) + repr(event))
                    # screen touch events; this includes touches to non-sensitive area of screen
                    self.SetActivityTimer(self.AS.DimTO, 'Screen touch')
                    # refresh non-dimming in all cases including non=sensitive areas
                    # this refresh is redundant in some cases where the touch causes other activities

                    if self.dim == 'Dim':
                        # wake up the screen and if in a cover state go home
                        config.sysStore.consolestatus = 'active'
                        if self.state == 'Cover':
                            self.SwitchScreen(screens.HomeScreen,
                                              'Bright',
                                              'Wake up from cover',
                                              newstate='Home')
                        else:
                            self.Brighten(
                            )  # if any other screen just brighten
                        continue  # wakeup touches are otherwise ignored

                    # Screen was not Dim so the touch was meaningful
                    pos = event.pos
                    tapcount = 1
                    pygame.time.delay(config.sysStore.MultiTapTime)
                    while True:
                        eventx = GetEventNoWait()
                        if eventx is None:
                            break
                        elif eventx.type == CEvent.MouseDown:
                            self.HBEvents.Entry('Follow MouseDown: {}'.format(
                                repr(eventx)))
                            debug.debugPrint(
                                'Touch', 'Follow MouseDown' + str(event.pos) +
                                repr(event))
                            tapcount += 1
                            pygame.time.delay(config.sysStore.MultiTapTime
                                              )  # todo make general time call?
                        else:
                            if eventx.type in (CEvent.MouseUp,
                                               CEvent.MouseMotion):
                                debug.debugPrint(
                                    'Touch',
                                    'Other event: {}'.format(repr(eventx)))
                                self.HBEvents.Entry('Mouse Other: {}'.format(
                                    repr(eventx)))
                            else:
                                self.HBEvents.Entry('Defer' + repr(eventx))
                                self.Deferrals.append(
                                    eventx
                                )  # defer the event until after the clicks are sorted out
                        # Future add handling for hold here with checking for MOUSE UP etc.
                    if tapcount == 3:
                        # Switch screen chains
                        if screens.HomeScreen != screens.HomeScreen2:  # only do if there is a real secondary chain
                            if self.Chain == 0:
                                self.Chain = 1
                                self.SwitchScreen(screens.HomeScreen2,
                                                  'Bright',
                                                  'Chain switch to secondary',
                                                  newstate='NonHome')
                            else:
                                self.Chain = 0
                                self.SwitchScreen(screens.HomeScreen,
                                                  'Bright',
                                                  'Chain switch to main',
                                                  newstate='Home')
                        continue

                    elif tapcount > 3:
                        # Go to maintenance
                        # timers.StartLongOp(
                        #	'maintenance')  # todo a bit ugly - start long op here but end in gohome in maint screen
                        self.SwitchScreen(maintscreen.MaintScreen,
                                          'Bright',
                                          'Tap to maintenance',
                                          newstate='Maint')
                        continue

                    if self.AS.Keys is not None:
                        for K in self.AS.Keys.values():
                            if K.touched(pos):
                                K.Pressed(tapcount)

                    for K in self.AS.NavKeys.values():
                        if K.touched(pos):
                            K.Proc()  # todo make a goto key

                elif event.type in (CEvent.MouseUp, CEvent.MouseMotion):
                    debug.debugPrint('Touch',
                                     'Other mouse event {}'.format(event))

                # ignore for now - handle more complex gestures here if ever needed

                elif event.type == CEvent.ACTIVITYTIMER:  # ACTIVITYTIMER:
                    debug.debugPrint('Dispatch', 'Activity timer fired State=',
                                     self.state, '/', self.dim)

                    if self.dim == 'Bright':
                        self.HBEvents.Entry(
                            'ActivityTimer(Bright) state: {}'.format(
                                self.state))
                        config.sysStore.consolestatus = 'idle'
                        self.Dim()
                        self.SetActivityTimer(self.AS.PersistTO,
                                              'Go dim and wait persist')
                    else:
                        self.HBEvents.Entry(
                            'ActivityTimer(non-Bright) state: {}'.format(
                                self.state))
                        if self.state == 'NonHome':
                            self.SwitchScreen(screens.HomeScreen,
                                              'Dim',
                                              'Dim nonhome to dim home',
                                              newstate='Home',
                                              clear=True)
                        elif self.state == 'Home':
                            self.SwitchScreen(screens.DimIdleList[0],
                                              'Dim',
                                              'Go to cover',
                                              newstate='Cover',
                                              AsCover=True,
                                              clear=True)
                            # rotate covers - save even if only 1 cover
                            screens.DimIdleList = screens.DimIdleList[1:] + [
                                screens.DimIdleList[0]
                            ]
                            screens.DimIdleTimes = screens.DimIdleTimes[1:] + [
                                screens.DimIdleTimes[0]
                            ]
                        elif self.state == 'Cover':
                            if len(screens.DimIdleList) > 1:
                                self.SwitchScreen(screens.DimIdleList[0],
                                                  'Dim',
                                                  'Go to next cover',
                                                  newstate='Cover',
                                                  AsCover=True,
                                                  clear=True)
                                screens.DimIdleList = screens.DimIdleList[
                                    1:] + [screens.DimIdleList[0]]
                                screens.DimIdleTimes = screens.DimIdleTimes[
                                    1:] + [screens.DimIdleTimes[0]]
                        else:  # Maint or Alert - just ignore the activity action
                            # logsupport.Logs.Log('Activity timer fired while in state: {}'.format(self.state),severity=ConsoleWarning)
                            debug.debugPrint('Dispatch', 'TO while in: ',
                                             self.state)

                elif event.type == CEvent.GeneralRepaint:
                    self.HBEvents.Entry('General Repaint: {}'.format(
                        repr(event)))
                    debug.debugPrint('Dispatch', 'General Repaint Event',
                                     event)
                    self.AS.ReInitDisplay()

                elif event.type == CEvent.HubNodeChange:
                    self.HBEvents.Entry('Hub Change: {}'.format(repr(event)))
                    debug.debugPrint('Dispatch', 'Hub Change Event', event)
                    if hasattr(event, 'node'):
                        self.AS.NodeEvent(hub=event.hub,
                                          node=event.node,
                                          value=event.value)
                    elif hasattr(event, 'varinfo'):
                        self.AS.NodeEvent(hub=event.hub, varinfo=event.varinfo)
                    else:
                        debug.debugPrint('Dispatch', 'Bad Node Change Event: ',
                                         event)
                        logsupport.Logs.Log('Bad Node Change Event ',
                                            event,
                                            severity=ConsoleWarning)

                elif event.type in (CEvent.ISYVar, CEvent.ISYAlert):
                    self.HBEvents.Entry('Var or Alert' + repr(event))
                    evtype = 'variable' if event.type == CEvent.ISYVar else 'node'
                    debug.debugPrint('Dispatch', 'ISY ', evtype, ' change',
                                     event)
                    alert = event.alert
                    if alert.state in ('Armed', 'Init'):
                        if alert.trigger.IsTrue():  # alert condition holds
                            if alert.trigger.delay != 0:  # delay invocation
                                alert.state = 'Delayed'
                                debug.debugPrint('Dispatch',
                                                 "Post with delay:",
                                                 alert.name,
                                                 alert.trigger.delay)
                                TimerName += 1
                                alert.timer = timers.OnceTimer(
                                    alert.trigger.delay,
                                    start=True,
                                    name='MainLoop' + str(TimerName),
                                    proc=alerttasks.HandleDeferredAlert,
                                    param=alert)
                            else:  # invoke now
                                alert.state = 'FiredNoDelay'
                                debug.debugPrint('Dispatch', "Invoke: ",
                                                 alert.name)
                                alert.Invoke(
                                )  # either calls a proc or enters a screen and adjusts alert state appropriately
                        else:
                            if alert.state == 'Armed':
                                # condition cleared after alert rearmed  - timing in the queue?
                                logsupport.Logs.Log(
                                    'Anomolous Trigger clearing while armed: ',
                                    repr(alert),
                                    severity=ConsoleDetail,
                                    hb=True)
                            else:
                                alert.state = 'Armed'
                                logsupport.Logs.Log(
                                    'Initial var value for trigger is benign: ',
                                    repr(alert),
                                    severity=ConsoleDetail)
                    elif alert.state == 'Active' and not alert.trigger.IsTrue(
                    ):  # alert condition has cleared and screen is up
                        debug.debugPrint('Dispatch', 'Active alert cleared',
                                         alert.name)
                        alert.state = 'Armed'  # just rearm the alert
                        self.SwitchScreen(screens.HomeScreen,
                                          'Dim',
                                          'Cleared alert',
                                          newstate='Home')
                    elif ((alert.state == 'Delayed') or
                          (alert.state
                           == 'Deferred')) and not alert.trigger.IsTrue():
                        # condition changed under a pending action (screen or proc) so just cancel and rearm
                        if alert.timer is not None:
                            alert.timer.cancel()
                            alert.timer = None
                        else:
                            logsupport.DevPrint(
                                'Clear with no timer?? {}'.format(repr(alert)))
                        debug.debugPrint(
                            'Dispatch', 'Delayed event cleared before invoke',
                            alert.name)
                        alert.state = 'Armed'
                    # todo - verify this is correct.  Issue is that the alert might have gotten here from a delay or from the
                    # alert screen deferring.  The screen uses it's own id for this alert to might be either.  Probably should
                    # distinguish based on if delay or defer but doing both should be same id(alert.actiontarget))  originally this was id-alert for some
                    # reason I changed it to id-actiontarget don't know why but it was done while adding HASS this screwed up clearing deferred alerts
                    # so switched it back in hopes to remember why the change todo
                    else:
                        logsupport.Logs.Log(
                            "Anomolous change situation  State: ",
                            alert.state,
                            " Alert: ",
                            repr(alert),
                            " Trigger IsTue: ",
                            alert.trigger.IsTrue(),
                            severity=ConsoleWarning,
                            hb=True)
                        debug.debugPrint('Dispatch',
                                         'ISYVar/ISYAlert passing: ',
                                         alert.state, alert.trigger.IsTrue(),
                                         event, alert)
                # Armed and false: irrelevant report
                # Active and true: extaneous report
                # Delayed or deferred and true: redundant report

                elif event.type == CEvent.SchedEvent:
                    self.HBEvents.Entry('Sched event {}'.format(repr(event)))
                    eventnow = time.time()
                    diff = eventnow - event.TargetTime
                    if abs(diff) > controlevents.latencynotification:
                        logsupport.Logs.Log(
                            'Timer late by {} seconds. Event: {}'.format(
                                diff, repr(event)),
                            severity=ConsoleWarning,
                            hb=True,
                            localonly=True,
                            homeonly=True)
                        self.HBEvents.Entry(
                            'Event late by {} target: {} now: {}'.format(
                                diff, event.TargetTime, eventnow))
                    event.proc(event)

                elif event.type == CEvent.RunProc:
                    self.HBEvents.Entry('Run procedure {}'.format(event.name))
                    event.proc()

                else:
                    logsupport.Logs.Log("Unknown main event {}".format(
                        repr(event)),
                                        severity=ConsoleError,
                                        hb=True,
                                        tb=False)
                if time.time(
                ) - postwaittime > controlevents.latencynotification and not timers.LongOpInProgress:  # this loop took a long time
                    logsupport.Logs.Log(
                        "Slow loop at {} took {} for {}".format(
                            time.time(),
                            time.time() - postwaittime, event),
                        severity=ConsoleWarning,
                        hb=True,
                        localonly=True,
                        homeonly=True)
                self.HBEvents.Entry(
                    'End Event Loop took: {}'.format(time.time() -
                                                     postwaittime))
        except Exception as E:
            logsupport.Logs.Log('Main display loop had exception: {}'.format(
                repr(E)))
            traceback.print_exc()
            config.ecode = exitutils.ERRORRESTART
            print('Display Screen Exception: {}'.format(repr(E)))

        logsupport.Logs.Log('Main GUI loop exiting')
Example #4
0
            del ParsedConfigFile[i]
        for hubtyp, pkg in hubs.hubs.hubtypes.items():
            if stype == hubtyp:
                # noinspection PyBroadException
                try:
                    hubs.hubs.Hubs[i] = pkg(i, v.get('address', ''),
                                            v.get('user', ''),
                                            v.get('password', ''))
                except BaseException as e:
                    logsupport.Logs.Log(
                        "Fatal console error - fix config file: ",
                        e,
                        severity=ConsoleError,
                        tb=False)
                    exitutils.Exit(
                        exitutils.ERRORDIE,
                        immediate=True)  # shutdown and don't try restart
                del ParsedConfigFile[i]

from stores import genericweatherstore

for i, v in ParsedConfigFile.items():
    if isinstance(v, Section):
        # noinspection PyArgumentList
        stype = v.get('type', '', delkey=False)  #todo check no type param
        loccode = '*unset*'
        for wptyp, info in WeathProvs.items():
            if stype == wptyp:
                try:
                    desc = i
                    loccode = v.get('location', desc)
Example #5
0
def ForceRestart():
    logsupport.Logs.Log('Autoversion Restart Event')
    config.terminationreason = 'autoversion'
    exitutils.Exit(exitutils.AUTORESTART)
Example #6
0
	def AlertProc1(self, alert):
		logsupport.DevPrint("---------------------VC invocation" + str(self.ct1) + str(alert) + str(id(alert)))
		logsupport.Logs.Log('Alert proc test exiting')
		logsupport.Logs.Log('Restart for new version')
		exitutils.Exit(66)