Example #1
0
def handler(signum, frame):
    HBMain.Entry('Signal: {}'.format(signum))
    if signum in (signal.SIGTERM, signal.SIGINT, signal.SIGUSR1):
        config.Running = False
        if signum == signal.SIGUSR1:
            logsupport.DevPrint('Watchdog termination')
            logsupport.Logs.Log(
                "Console received a watchdog termination signal: {} - Exiting".
                format(signum),
                tb=True)
            config.terminationreason = 'watchdog termination'
            config.ecode = exitutils.WATCHDOGTERM
        else:
            logsupport.DevPrint('Signal termination {}'.format(signum))
            logsupport.Logs.Log(
                "Console received termination signal: {} - Exiting".format(
                    signum),
                tb=True)
            if signum == signal.SIGINT:
                config.terminationreason = 'interrupt signal'
                config.ecode = exitutils.EXTERNALSIGINT
            else:
                config.terminationreason = 'termination signal'
                config.ecode = exitutils.EXTERNALSIGTERM
            if config.sysStore.Watchdog_pid != 0:
                os.kill(config.sysStore.Watchdog_pid, signal.SIGUSR1)
            if config.sysStore.Topper_pid != 0:
                os.kill(config.sysStore.Topper_pid, signal.SIGKILL)
    else:
        logsupport.Logs.Log(
            "Console received signal {} - Ignoring".format(signum))
Example #2
0
def MasterWatchDog():
    signal.signal(
        signal.SIGTERM,
        WatchdogDying)  # don't want the sig handlers from the main console
    signal.signal(signal.SIGINT, EndWatchDog)
    signal.signal(signal.SIGUSR1, EndWatchDog)
    signal.signal(signal.SIGHUP, IgnoreHUP)

    #failsafehooks.hook()
    atexit.register(failsafedeath)

    logsupport.DevPrint(
        'Master Watchdog Started {} for console pid: {}'.format(
            os.getpid(), config.sysStore.Console_pid))
    runningok = True
    while runningok:
        while timers.LongOpStart['maintenance'] != 0:
            logsupport.DevPrint('Failsafe suspended while in maintenance mode')
            time.sleep(120)
        while KeepAlive.wait(FailsafeInterval):
            # logsupport.DevPrint('Watchdog ok: {}'.format(time.time()))
            KeepAlive.clear()
            time.sleep(FailsafeInterval)

        if timers.LongOpStart['maintenance'] == 0:
            runningok = False  # not in maintenance mode and not acting alive
    logsupport.DevPrint('Watchdog loop exit: {}'.format(time.time()))
    # noinspection PyBroadException
    try:
        os.kill(config.sysStore.Console_pid, 0)
    except:
        logsupport.DevPrint('Normal watchdog exit')
        # logsupport.Logs.Log("Failsafe watchdog exiting normally")
        return
    logsupport.DevPrint('Failsafe interrupt {}'.format(
        config.sysStore.Console_pid))
    # logsupport.Logs.Log("Failsafe watchdog saw console go autistic - interrupting {}".format(config.sysStore.Console_pid))
    os.kill(config.sysStore.Console_pid, signal.SIGUSR1)
    time.sleep(3)  # wait for exit to complete
    try:
        os.kill(config.sysStore.Console_pid,
                0)  # check if console exited - raises exception if it is gone
        logsupport.DevPrint(
            "Failsafe watchdog interrupt didn't reset - killing {}".format(
                config.sysStore.Console_pid))
        # logsupport.Logs.Log("Failsafe watchdog interrupt didn't reset - killing {}".format(config.sysStore.Console_pid))
        os.kill(config.sysStore.Console_pid, signal.SIGKILL)
        logsupport.DevPrint("Failsafe exiting after kill attempt")
    # logsupport.Logs.Log("Failsafe exiting after kill attempt")
    except Exception as E:
        print('Failsafe exiting')
        logsupport.DevPrint(
            "Failsafe successfully ended console (pid: {}), failsafe (pid: {}) exiting (Exc: {})"
            .format(config.sysStore.Console_pid, os.getpid(), repr(E)))
    # logsupport.Logs.Log("Failsafe successfully ended console (pid: {}), failsafe (pid: {}) exiting".format(config.sysStore.Console_pid, os.getpid()))
    logsupport.DevPrint('Watchdog exiting')
Example #3
0
def KillMe():
    time.sleep(5)
    if not timersshut:
        TimerHB.Entry("Timer Shutdown Failsafe hit")
        logsupport.DevPrint("Timer Shutdown Failsafe hit")
        #time.sleep(30)
        logsupport.Logs.log("Timer Shutdown Failsafe hit")
        time.sleep(1)
        x = threading.enumerate()
        for t in x:
            logsupport.DevPrint(t.name)
        os.kill(config.sysStore.Console_pid, signal.SIGKILL)
    else:
        pass
Example #4
0
def NoEventInjector():
    logsupport.Logs.Log('Starting watchdog activity injector')
    while config.Running:
        # noinspection PyBroadException
        try:
            now = time.time()
            logsupport.Logs.Log('Inject: {}'.format(now),
                                severity=logsupport.ConsoleDetail)
            #logsupport.DevPrint('Inject: {}'.format(now))
            PostEvent(ConsoleEvent(CEvent.FailSafePing, inject=now))
            time.sleep(FailsafeInterval / 2)
        except Exception as E:
            time.sleep(FailsafeInterval / 2)
            logsupport.DevPrint('Inject Exception {}'.format(repr(E)))
            # spurious exceptions during shutdown
    logsupport.DevPrint('Injector exiting')
Example #5
0
 def DoCheck(hubnm, hub):
     logsupport.Logs.Log('Integrity check for hub: ', hubnm,
                         ' starting')
     logsupport.DevPrint('Integrity check for hub {}'.format(hubnm))
     valuestore.ValueStores[hubnm].CheckValsUpToDate()
     hub.CheckStates()
     logsupport.Logs.Log('Integrity check thread for hub: ', hubnm,
                         ' complete')
Example #6
0
def failsafedeath():
    logsupport.DevPrint('Failsafe exit hook')
    with open("/home/pi/Console/fsmsg.txt", "a") as f:
        f.writelines('failsafedeath {} watching {} at {}\n'.format(
            os.getpid(), config.sysStore.Console_pid, time.time()))
    os.kill(config.sysStore.Console_pid, signal.SIGUSR1)
    time.sleep(3)
    os.kill(config.sysStore.Console_pid, signal.SIGKILL)  # with predjudice
Example #7
0
def WatchdogDying(signum, frame):
    if signum == signal.SIGTERM:
        logsupport.DevPrint('Watchdog saw SIGTERM - must be from systemd')
        # console should have also seen this - give it time to shut down
        time.sleep(30)  # we should see a USR1 from console
        os._exit(0)
    else:
        logsupport.DevPrint('Watchdog dying signum: {} frame: {}'.format(
            signum, frame))
        try:
            os.kill(config.sysStore.Console_pid, signal.SIGUSR1)
        except:
            pass  # probably main console already gone
        time.sleep(3)
        try:
            os.kill(config.sysStore.Console_pid,
                    signal.SIGKILL)  # with predjudice
        except:
            pass  # probably already gone
        os._exit(0)
Example #8
0
def fetch_stable():
    basedir = os.path.dirname(config.sysStore.ExecDir)
    ReportStatus("updt stable", hold=1)
    # noinspection PyBroadException
    try:
        if os.path.exists(basedir + '/homesystem'):
            # personal system
            logsupport.Logs.Log("New version fetch(homerelease)")
            logsupport.DevPrint("New Version Fetch Requested (homesystem)")
            U.StageVersion(basedir + '/consolestable', 'homerelease',
                           'Maint Dnld')
        else:
            logsupport.Logs.Log("New version fetch(currentrelease)")
            logsupport.DevPrint("New Version Fetch Requested (currentrelease)")
            U.StageVersion(basedir + '/consolestable', 'currentrelease',
                           'Maint Dnld')
        U.InstallStagedVersion(basedir + '/consolestable')
        logsupport.Logs.Log("Staged version installed in consolestable")
    except:
        logsupport.Logs.Log('Failed release download', severity=ConsoleWarning)
    ReportStatus("done stable", hold=2)
Example #9
0
def GetEvent():
    global latencynotification
    qs = ConsoleOpsQueue.qsize()
    try:
        evnt = ConsoleOpsQueue.get(
            block=True, timeout=120
        )  # timeout is set to twice the failsafe injection time so should never see it
    except queue.Empty:
        logsupport.DevPrint('Queue wait timeout')
        HBControl.Entry("Main loop timeout - inserting ping event")
        evnt = ConsoleEvent(CEvent.FailSafePing,
                            inject=time.time(),
                            QTime=time.time())
        logsupport.Logs.Log('Main queue timeout',
                            severity=logsupport.ConsoleWarning,
                            hb=True)
    if evnt is None:
        logsupport.Logs.Log('Got none from blocking get',
                            severity=logsupport.ConsoleError,
                            hb=True)
    cpu = psutil.Process(config.sysStore.Console_pid).cpu_times()
    HBControl.Entry("Get: {} queuesize: {}".format(evnt, qs))

    now = time.time()
    if qs >= logsupport.queuedepthmax:
        logsupport.queuedepthmax = qs
        logsupport.queuedepthmaxtime = now
    if qs >= logsupport.queuedepthmax24:
        logsupport.queuedepthmax24 = qs
        logsupport.queuedepthmax24time = now

    qt = time.time() - evnt.QTime
    if qt > logsupport.queuetimemax:
        logsupport.queuetimemax = qt
        logsupport.queuetimemaxtime = now
    if qt > logsupport.queuetimemax24:
        logsupport.queuetimemax24 = qt
        logsupport.queuetimemax24time = now

    if qt > latencynotification:
        HBControl.Entry(
            'Long on queue: {} user: {} system: {} event: {}'.format(
                time.time() - evnt.QTime, cpu.user - evnt.usercpu,
                cpu.system - evnt.syscpu, evnt))
        if not timers.LongOpInProgress:
            logsupport.Logs.Log(
                'Long on queue {} (user: {} sys: {}) event: {}'.format(
                    time.time() - evnt.QTime, cpu.user - evnt.usercpu,
                    cpu.system - evnt.syscpu, evnt),
                severity=logsupport.ConsoleWarning,
                hb=True,
                localonly=True,
                homeonly=True)
    if time.time(
    ) - evnt.QTime < 2:  # cleared any pending long waiting startup events
        if config.sysStore.versionname in ('development', 'homerelease') and (
                latencynotification != LateTolerance
        ):  # after some startup stabilisation sensitize latency watch if my system
            latencynotification = LateTolerance
            logsupport.queuedepthmax = 0
            logsupport.queuetimemax = 0
    # logsupport.DevPrint('Set latency tolerance: {}'.format(latencynotification))
    return evnt
Example #10
0
def IgnoreHUP(signum, frame):
    logsupport.DevPrint('Watchdog got HUP - ignoring')
Example #11
0
def EndWatchDog(signum, frame):
    logsupport.DevPrint('Watchdog ending on shutdown {}'.format(signum))
    os._exit(0)
Example #12
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 #13
0
maintscreen.SetUpMaintScreens()
logsupport.Logs.Log("Built Maintenance Screen")

LogBadParams(ParsedConfigFile, "Globals")
LogBadParams(alertspec, "Alerts")
"""
Dump documentation if development version
"""
# if config.sysStore.versionname == 'development':
#	utilities.DumpDocumentation()
"""
Run the main console loop
"""
for n in alerttasks.monitoredvars:  # make sure vars used in alerts are updated to starting values
    valuestore.GetVal(n)
config.sysStore.ErrorNotice = -1
gui = threading.Thread(name='GUI',
                       target=screens.DS.MainControlLoop,
                       args=(screens.HomeScreen, ))
config.ecode = 99
gui.start()

gui.join()
logsupport.Logs.Log("Main line exit: ", config.ecode)
timers.ShutTimers(config.terminationreason)
logsupport.Logs.Log('Console exiting')
hw.GoBright(100)
pygame.quit()
logsupport.DevPrint('Exit handling done')

sys.exit(config.ecode)
Example #14
0
def handler(signum, frame):
    logsupport.DevPrint('Systemd signal hack raised {} {}'.format(
        signum, repr(frame)))
    pass
Example #15
0
	def AlertProc2(self, alert):
		logsupport.DevPrint("=====================VC alt incovation" + str(self.ct2) + str(alert) + str(id(alert)))
		self.ct2 += 1
Example #16
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)