Example #1
0
def test():
    from src import messagebus
    succeed = [0]

    def f(m, v):
        succeed[0] = 1

    messagebus.subscribe("/system/selftest", f)
    messagebus.postMessage("/system/selftest", "Test")

    time.sleep(0.2)
    if not succeed[0]:
        time.sleep(2)
        if succeed[0]:
            raise RuntimeError(
                "Message not delivered within 0.2 second. This may happen occasionally if CPU load is high but otherwise should not occur."
            )
        else:
            raise RuntimeError("Message not delivered within 2 seconds")
    f2 = weakref.ref(f)

    del f
    succeed[0] = 0
    time.sleep(1)

    messagebus.postMessage("/system/selftest", "Test")
    time.sleep(3)
    if succeed[0]:
        if f2():
            logging.error("selftest: f still exists " + str(f2()))
        raise RuntimeError("Garbage collection fails to unsubscribe")
    def _onClear(self):
        if self.priority in ("error", "critical", "warning"):
            messagebus.postMessage(
                "/system/notifications",
                "Alarm " + self.name + " condition cleared, waiting for ACK")

        logger.info("Alarm " + self.name + " cleared")
        api.send(['shouldRefresh'])
    def _onKeyPress(self, key, fromUI=None):
        if fromUI or not self.testMode:
            #Synchronous must be true, no out of order messages allowed
            messagebus.postMessage("/devices/" + self.name + "/keypress",
                                   key,
                                   synchronous=True)
            self.onKeyPress(key)

        else:
            self.print(key, "keypress[IGNORED]")
 def runtest():
     try:
         theTest()
     except:
         messagebus.postMessage("/system/notifications/errors",
                                traceback.format_exc(6))
     finally:
         newevt.removeOneEvent('testevt', 'testevt')
         newevt.removeOneEvent('TEST1', 'TEST1')
         newevt.removeOneEvent('TEST2', 'TEST2')
    def acknowledge(self, by="unknown", notes=""):
        notes = notes[:64]
        if notes.strip():
            notes = ':\n' + notes
        else:
            notes = ''

        self.sm.event("acknowledge")
        if not by == "<DELETED>":
            logger.info("Alarm " + self.name + " acknowledged by" + by + notes)

            if self.priority in ("error", "critical", "warning"):
                messagebus.postMessage(
                    "/system/notifications",
                    "Alarm " + self.name + " acknowledged by " + by + notes)
Example #6
0
 def run_with_except_hook(*args, **kw):
     try:
         messagebus.postMessage("/system/threads/start",self.name)
         run_old(*args, **kw)
         messagebus.postMessage("/system/threads/stop",self.name)
     except Exception as e:
         messagebus.postMessage("/system/notifications/errors","Exception in thread %s, thread stopped. More details in logs."%self.name)
         messagebus.postMessage("/system/threads/errors","Exception in thread %s:\n%s"%(self.name, traceback.format_exc(6)))
         raise e
    def _onNormal(self):
        "Mostly defensivem but also cleans up if the autoclear occurs and we skio the acknowledged state"
        global unacknowledged, active
        if self.priority in ("info", "warning", "error", "critical"):
            messagebus.postMessage(
                "/system/notifications",
                "Alarm " + self.name + " returned to normal")

        with lock:
            cleanup()
            if self.id in _unacknowledged:
                del _unacknowledged[self.id]
            unacknowledged = _unacknowledged.copy()

            if self.id in _active:
                del _active[self.id]
            active = _active.copy()
        calcNextBeep()
        api.send(['shouldRefresh'])
    def _onActive(self):
        global unacknowledged
        global active
        with lock:
            cleanup()
            _unacknowledged[self.id] = weakref.ref(self)
            unacknowledged = _unacknowledged.copy()

            _active[self.id] = weakref.ref(self)
            active = _active.copy()
            s = calcNextBeep()
        if s:
            sound.playSound(s,handle="kaithem_sys_main_alarm")
        if self.priority in ("error, critical"):
            logger.error("Alarm "+self.name +" ACTIVE")
            messagebus.postMessage("/system/notifications/errors", "Alarm "+self.name+" is active")
        if self.priority in ("warning"):
            logger.warning("Alarm "+self.name +" ACTIVE")
        else:
            logger.info("Alarm "+self.name +" active")
Example #9
0
        def run_with_except_hook(*args, **kw):
            if self.name.startswith("nostartstoplog."):
                try:
                    run_old(*args, **kw)
                except Exception as e:
                    threadlogger.exception(
                        "Thread stopping due to exception: "+self.name)
                    raise e
            else:
                try:
                    threadlogger.info("Thread starting: "+self.name)
                    run_old(*args, **kw)
                    threadlogger.info("Thread stopping: "+self.name)

                except Exception as e:
                    threadlogger.exception(
                        "Thread stopping due to exception: "+self.name)
                    from src import messagebus
                    messagebus.postMessage("/system/notifications/errors","Thread: "+self.name +" stopped due to exception ")
                    raise e
    def checkPiFlags():
        global undervoltageDuringBootPosted
        global overTempDuringBootPosted
        try:
            # This is a trusted system util! Eval is fine here!
            x = subprocess.check_output(["vcgencmd", "get_throttled"])
            x = eval(x.decode('utf8').split("=")[1])

            # https://github.com/raspberrypi/documentation/blob/JamesH65-patch-vcgencmd-vcdbg-docs/raspbian/applications/vcgencmd.md
            if x & (2**0):
                undervoltageTagClaim.set(1)
            else:
                undervoltageTagClaim.set(0)

            if x & (2**3):
                overtemperatureTagClaim.set(1)
            else:
                overtemperatureTagClaim.set(0)

            # These are persistent flags. We check to see if something happened before Kaithem started,
            # But we don't actually need to do repeatedly spam the message

            if x & (2**16):
                if not undervoltageDuringBootPosted:
                    messagebus.postMessage(
                        "/system/notifications/errors",
                        "A low input voltage condition has occurred at some point on this system"
                    )
                    undervoltageDuringBootPosted = True

            if x & (2**19):
                if not overTempDuringBootPosted:
                    messagebus.postMessage(
                        "/system/notifications/errors",
                        "An overtemperature condition has occurred at some point on this system"
                    )
                    overTempDuringBootPosted = True

        except Exception:
            logging.exception("err")
    def f():
        try:
            import hardline

            from . import config
            hardline.setP2PPort(config.config['drayer-p2p-port'])
            # Ensure stopped
            hardline.stop()

            #Start at the standard port on localhost.  This doesn't need to be configured,
            #If there is a system instance running we just won't start the local port part and use theirs.
            hardline.start(7009)
            # Unload them at exit
            for i in hardline.loadedServices:
                hardline.loadedServices[i].close()
        except:
            logging.exception("Fail to lauuch Hardline/Drayer")
            from src import messagebus
            messagebus.postMessage(
                "/system/notifications/errors/",
                "Error loading DrayerDB/HardlineP2P, these features are disabled."
            )
    def on_message(self, bus, message, userdata):
        s = message.get_structure()
        if not s:
            return True
        msgtype = s.get_name()

        # Speech recognition, forward it on to the message bus.
        if msgtype == 'pocketsphinx':
            if message.get_structure().get_value('hypothesis'):
                messagebus.postMessage(
                    "/devices/" + self.name + "/hypothesis",
                    (message.get_structure().get_value('hypothesis'), ))

            if message.get_structure().get_value('final'):
                self.controller().print(
                    str((message.get_structure().get_value('hypothesis'),
                         message.get_structure().get_value('confidence'))))
                messagebus.postMessage(
                    "/devices/" + self.name + "/final",
                    (message.get_structure().get_value('hypothesis'),
                     message.get_structure().get_value('confidence')))
        return True
    def _onActive(self):
        global unacknowledged
        global active
        with lock:
            cleanup()
            _unacknowledged[self.id] = weakref.ref(self)
            unacknowledged = _unacknowledged.copy()

            _active[self.id] = weakref.ref(self)
            active = _active.copy()
            s = calcNextBeep()
        if s:
            # Sound drivers can actually use tagpoints, this was causing a
            # deadlock with the tag's lock in the __del__ function GCing some
            # other tag. I don't quite understand it but this should break the loop
            def f():
                # Ondemand to avoid circular import
                from . import sound
                beepDevice = file['all']['soundcard']
                sound.playSound(s,
                                handle="kaithem_sys_main_alarm",
                                output=beepDevice)
                api.send(['shouldRefresh'])

            workers.do(f)

        if self.priority in ("error", "critical"):
            logger.error("Alarm " + self.name + " ACTIVE")
            messagebus.postMessage("/system/notifications/errors",
                                   "Alarm " + self.name + " is active")
        if self.priority in ("warning"):
            messagebus.postMessage("/system/notifications/warnings",
                                   "Alarm " + self.name + " is active")
            logger.warning("Alarm " + self.name + " ACTIVE")
        else:
            logger.info("Alarm " + self.name + " active")

        if self.priority in ("info"):
            messagebus.postMessage("/system/notifications",
                                   "Alarm " + self.name + " is active")
else:
    file = {}

# Legacy registry stuff.
lat = registry.get("system/location/lat", None)
lon = registry.get("system/location/lon", None)

if 'default' in file:
    lat = file['default'].get('lat', None)
    lon = file['default'].get('lon', None)

if not lat or not lon:
    try:
        l = ip_geolocate()
        messagebus.postMessage(
            "/system/notifications/important",
            "Got server location by IP geolocation.  You can change this in settings."
        )
        file['default'] = l
    except:
        # The location called "default" is to be the main one.
        file['default'] = {'lat': lat, 'lon': lon, 'city': ''}
else:
    # The location called "default" is to be the main one.
    file['default'] = {'lat': lat, 'lon': lon, 'city': ''}

try:
    persist.save(file, fn, private=True)
except:
    logging.exception("Save fail")

    def theTest():
        running_tests.append(1)
        modules_state.scopes['x'] = {}
        #Create an event that sets y to 0 if it is 1
        with newevt._event_list_lock:
            x = newevt.Event("y==1", "global y\ny=0", locals(), setup="y=0")
            x.module = x.resource = "testevt"
            newevt.EventReferences[x.module, x.resource] = x

            #Register event with polling.
            x.register()
        #Set y to 1
        x.pymodule.y = 1

        time.sleep(2)

        try:
            #y should immediately be set back to 0 at the next polling cycle
            if x.pymodule.y == 1:
                raise RuntimeError("Edge-Triggered Event did nothing")
        except:
            print(x.pymodule.__dict__)
            raise
        finally:
            x.unregister()

        x.pymodule.y = 1
        if not x.pymodule.y == 1:
            raise RuntimeError(
                "Edge-Triggered Event did not go away when unregistered")

        blah = [False]

        def f():
            return blah[0]

        def g():
            blah[0] = False

        newevt.when(f, g)
        time.sleep(0.5)
        blah[0] = True

        time.sleep(0.5)
        if blah[0]:
            time.sleep(2)
            if blah[0]:
                raise RuntimeError("One time event did not trigger")

        blah[0] = True
        time.sleep(1)
        if not blah[0]:
            raise RuntimeError("One time event did not delete itself properly")

        newevt.after(1, g)
        blah[0] = True
        time.sleep(1.5)
        if blah[0]:
            raise RuntimeError("Time delay event did not trigger")

        blah[0] = True
        time.sleep(2)
        if not blah[0]:
            raise RuntimeError(
                "Time delay event did not delete itself properly")

        with newevt._event_list_lock:
            #Same exact thing exept we use the onchange
            x = newevt.Event("!onchange y", "global y\ny=5")
            #Give it a value to change from
            x.pymodule.y = 0

            x.module = x.resource = "TEST1"
            newevt.EventReferences[x.module, x.resource] = x

            #Register event with polling.
            x.register()

        #Let it notice the old value
        time.sleep(1)
        #Set y to 1
        x.pymodule.y = 1

        time.sleep(1)
        #y should immediately be set back to 0 at the next polling cycle
        x.unregister()

        if x.pymodule.y == 1:
            raise RuntimeError("Onchange Event did nothing")

        x.pymodule.y = 1
        if not x.pymodule.y == 1:
            raise RuntimeError(
                "Onchange Event did not go away when unregistered")

        #There is a weird old feature where message events don't work if not in EventReferences
        #It was an old thing to caths a circular reference bug.
        with newevt._event_list_lock:
            #Now we test the message bus event
            x = newevt.Event("!onmsg /test", "global y\ny='test'")
            x.module = x.resource = 'TEST2'
            #Make sure nobody is iterating the eventlist
            #Add new event
            x.register()
            #Update index
            newevt.EventReferences[x.module, x.resource] = x
        time.sleep(0.25)
        #Give it a value to change from
        messagebus.postMessage("/test", 'foo')
        #Let it notice the old value

        time.sleep(0.25)
        x.unregister()
        #y should immediately be set back to 0 at the next polling cycle
        if not hasattr(x.pymodule, 'y'):
            time.sleep(5)
            if not hasattr(x.pymodule, 'y'):
                raise RuntimeError(
                    "Message Event did nothing or took longer than 5s")
            else:
                raise RuntimeError(
                    "Message Event had slow performance, delivery took more than 0.25s"
                )

        try:
            x.pymodule.y = 1
        except:
            #This might fail if the implementatino makes pymodule not exist anymore
            pass

        messagebus.postMessage('foo', "/test")
        #If there is no y or pymodule, this test won't work but we can probably assume it unregistered correctly.
        #Maybe we should add a real test that works either way?
        if hasattr(x, 'pymodule') and hasattr(x.pymodule, 'y'):
            if x.pymodule.y == 'test':
                raise RuntimeError(
                    "Message Event did not go away when unregistered")

        print("Success in testing event system")
        running_tests.pop()
Example #16
0
cherrypy.tree.mount(root,config=cnf)


#As far as I can tell, this second server inherits everything from the "implicit" server
#except what we override.
server2 = cherrypy._cpserver.Server()
server2.socket_port= config['http-port']
server2._socket_host= bindto
server2.thread_pool=config['http-thread-pool']
server2.subscribe()




if time.time() < 1420070400:
    messagebus.postMessage('/system/notifications/errors',"System Clock is wrong, some features may not work properly.")

if time.time() < util.min_time:
        messagebus.postMessage('/system/notifications/errors',"System Clock may be wrong, or time has been set backwards at some point. If system clock is correct and this error does not go away, you can fix it manually be correcting folder name timestamps in the var dir.")

sys.modules['kaithem'] = sys.modules['__main__']
from src import kaithemobj
kaithemobj.kaithem.misc.version      = __version__
kaithemobj.kaithem.misc.version_info = __version_info__
cherrypy.engine.start()
#If configured that way on unix, check if we are root and drop root.
util.drop_perms(config['run-as-user'], config['run-as-group'])
messagebus.postMessage('/system/startup','System Initialized')
messagebus.postMessage('/system/notifications/important','System Initialized')
cherrypy.engine.block()
 def dataCallback(self, db, record, signature):
     messagebus.postMessage("/devices/" + self.name + "/record", record)
#Plugin that manages TP-Link Kasa devices.

from src import devices,alerts, scheduling,tagpoints,messagebus
import os,mako,time,threading,logging

try:
	from pyHS100 import SmartPlug, SmartBulb
except:
	logger.exception()
	messagebus.postMessage("/system/notifications/errors","Problem loading Kasa support")

from src import widgets

logger = logging.Logger("plugins.kasa")

from mako.lookup import TemplateLookup
templateGetter = TemplateLookup(os.path.dirname(__file__))


lookup={}

lastRefreshed = 0

lock = threading.Lock()

def maybeRefresh(t=30):
	global lastRefreshed
	if lastRefreshed<time.time()-t:
		refresh()
	elif lastRefreshed<time.time()-5:
		refresh(1)
Example #19
0
if x.pymodule.y == 1:
    common.fail("Onchange Event did nothing")

#Unregister event and make sure it really goes away
x.unregister()
x.pymodule.y = 1
if not x.pymodule.y == 1:
    common.fail("Onchange Event did not go away when unregistered")

#Now we test the message bus event
x = newevt.Event("!onmsg /test", "global y\ny='test'", locals())

#Register event with polling.
x.register()
#Give it a value to change from
messagebus.postMessage("/test", 'poo')
#Let it notice the old value

time.sleep(0.25)
#y should immediately be set back to 0 at the next polling cycle
if not x.pymodule.y == 'test':
    common.fail("Message Event did nothing")

#Unregister event and make sure it really goes away
x.unregister()
x.pymodule.y = 1

messagebus.postMessage('poo', "/test")
if x.pymodule.y == 'test':
    common.fail("Message Event did not go away when unregistered")
Example #20
0
x.unregister() 
x.pymodule.y =1
if not x.pymodule.y == 1:
        common.fail("Onchange Event did not go away when unregistered")
   
   
   
        
#Now we test the message bus event
x = newevt.Event("!onmsg /test","global y\ny='test'",locals())


#Register event with polling.
x.register()
#Give it a value to change from
messagebus.postMessage("/test",'poo')
#Let it notice the old value

time.sleep(0.25)
#y should immediately be set back to 0 at the next polling cycle 
if not  x.pymodule.y == 'test':
        common.fail("Message Event did nothing")
    
#Unregister event and make sure it really goes away
x.unregister() 
x.pymodule.y =1

messagebus.postMessage('poo',"/test")
if x.pymodule.y == 'test':
        common.fail("Message Event did not go away when unregistered")
        
 def acknowledge(self,by="unknown"):
     self.sm.event("acknowledge")
     logger.info("Alarm "+self.name +" acknowledged by" + by)
     if self.priority in ("error, critical","warnings"):
         messagebus.postMessage("/system/notifications", "Alarm "+self.name+" acknowledged by "+ by)
Example #22
0
            # inserting into the old list . Note that here we consider very rarely losing a record
            # to be better than bad performace

            for i in range(30):
                time.sleep(0.001)

            self.history = sqlite3.Connection(self.filename)
            with self.history:
                if needsGC:
                    for i in self.children:
                        x = self.children[i]()
                        if x:
                            with x.lock:
                                x.clearOldData(force)

                for i in pending:
                    self.history.execute('INSERT INTO record VALUES (?,?,?)',
                                         i)
            self.history.close()


try:
    historian = TagHistorian(newHistoryDBFile)
    ramHistorian = TagHistorian(ramdbfile)
    os.chmod(ramdbfile, 0o750)
except Exception:
    messagebus.postMessage(
        "/system/notifications/errors",
        "Failed to create tag historian, logging will not work." + "\n" +
        traceback.format_exc())
Example #23
0
cherrypy.config.update(site_config)
cherrypy.tools.pageloadnotify = cherrypy.Tool('on_start_resource',
                                              pageloadnotify)
cherrypy.config['tools.pageloadnotify.on'] = True

cherrypy.tools.addheader = cherrypy.Tool('before_finalize', addheader)

if hasattr(cherrypy.engine, 'signal_handler'):
    cherrypy.engine.signal_handler.subscribe()

cherrypy.tree.mount(root, config=cnf)

#As far as I can tell, this second server inherits everything from the "implicit" server
#except what we override.
server2 = cherrypy._cpserver.Server()
server2.socket_port = config['http-port']
server2._socket_host = bindto
server2.thread_pool = config['http-thread-pool']
server2.subscribe()

messagebus.postMessage('/system/startup', 'System Initialized')
messagebus.postMessage('/system/notifications', 'System Initialized')

if time.time() < 1420070400:
    messagebus.postMessage(
        '/system/notifications/errors',
        "System Clock probably wrong, some features may not work properly.")

cherrypy.engine.start()
cherrypy.engine.block()