def test_bgsync(self): s = self.device["mystream"] # This time we test existing stream s.create({"type": "string"}) l = Logger("test.db") l.serverurl = TEST_URL l.apikey = self.apikey l.addStream("mystream") l.syncperiod = 1 self.assertEqual(0, len(s)) self.assertEqual(0, len(l)) l.start() l.insert("mystream", "hi") l.insert("mystream", "hello") self.assertEqual(0, len(s)) self.assertEqual(2, len(l)) time.sleep(1.1) self.assertEqual(2, len(s)) self.assertEqual(0, len(l)) l.insert("mystream", "har") self.assertEqual(2, len(s)) self.assertEqual(1, len(l)) time.sleep(1.1) self.assertEqual(3, len(s)) self.assertEqual(0, len(l)) l.stop() l.insert("mystream", "stopped") time.sleep(1.3) self.assertEqual(3, len(s)) self.assertEqual(1, len(l)) l.close()
class LaptopLogger(): def __init__(self,firstrun_callback=None): self.firstrun_callback = firstrun_callback self.syncer = None self.isrunning = False self.issyncing = False #Get the data gatherers. currentgatherers is the ones that are set to ON # gatherers is ALL of them self.currentgatherers = {} self.gatherers = {} for p in getplugins(): g = p() self.currentgatherers[g.streamname] = g self.gatherers[g.streamname] = g filedir = files.getFileFolder() cachefile = os.path.join(filedir,"cache.db") logging.info("Opening database " + cachefile) self.cache = Logger(cachefile,on_create=self.create_callback) # Disable the relevant gatherers for g in self.cache.data["disabled_gatherers"]: if g in self.currentgatherers: del self.currentgatherers[g] # If ConnectorDB is managed, start the executable self.localdir = os.path.join(filedir,"db") self.localrunning = False self.runLocal() #Start running the logger if it is supposed to be running if self.cache.data["isrunning"]: self.start() if self.cache.data["isbgsync"]: self.startsync() # This can be used to start a local version of ConnectorDB def runLocal(self): if self.cache.data["runlocal"] and not self.localrunning: logging.info("Starting ConnectorDB server") try: self.localrunning = True retcode = cdbmanager.Manager(self.localdir).start() # The method needed to start on windows doesn't return error codes. if (platform.system()=="Windows"): return True logging.debug("Start return code: " +str(retcode)) return retcode==0 except Exception as e: logging.error(str(e)) self.localrunning = False return False return False def create_callback(self,c): logging.info("Creating new cache file...") c.data = { "runlocal": False, # Whether or not to run a local ConnectorDB instance (the ConnectorDB server) "isrunning": False, # Whether or not the logger is currently gathering data. This NEEDS to be false - it is set to true later "isbgsync": False, # Whether or not the logger automatically syncs with ConnectorDB. Needs to be false - automatically set to True later "gathertime": 4.0, # The logger gathers datapoints every this number of seconds "disabled_gatherers": [], # The names of disabled gatherers } c.syncperiod = 60*60 # Sync once an hour #We now need to set the API key if self.firstrun_callback is not None: self.firstrun_callback(c) def removegatherer(self,g): logging.info("Removing gatherer " + g) if g in self.currentgatherers: del self.currentgatherers[g] if self.isrunning: self.gatherers[g].stop() # Save the setting d = self.cache.data if not g in d["disabled_gatherers"]: d["disabled_gatherers"].append(g) self.cache.data = d def addgatherer(self,g): logging.info("Adding gatherer " + g) if not g in self.currentgatherers: if self.isrunning: self.gatherers[g].start(self.cache) self.currentgatherers[g] = self.gatherers[g] # Save the setting d = self.cache.data if g in d["disabled_gatherers"]: d["disabled_gatherers"].remove(g) self.cache.data = d def gather(self): for g in self.currentgatherers: self.currentgatherers[g].run(self.cache) self.syncer = threading.Timer(self.cache.data["gathertime"],self.gather) self.syncer.daemon = True self.syncer.start() # Whether or not to run data gathering def start(self): if not self.isrunning: logging.info("Start acquisition") d = self.cache.data d["isrunning"] = True self.cache.data = d #First, make sure all streams are ready to go in the cache for g in self.gatherers: if not g in self.cache: gatherer = self.gatherers[g] logging.info("Adding {} stream ({})".format(g,self.gatherers[g].streamschema)) nickname = "" if hasattr(gatherer,"nickname"): nickname = gatherer.nickname datatype = "" if hasattr(gatherer,"datatype"): datatype = gatherer.datatype self.cache.addStream(g,gatherer.streamschema,description=gatherer.description,nickname=nickname,datatype=datatype) for g in self.currentgatherers: self.currentgatherers[g].start(self.cache) self.isrunning = True self.gather() # Whether or not to run background syncer def startsync(self): if not self.issyncing: logging.info("Start background sync") d = self.cache.data d["isbgsync"] = True self.cache.data = d self.cache.start() self.issyncing = True def stop(self,temporary=False): logging.info("Stop acquisition") if self.syncer is not None: self.syncer.cancel() self.syncer = None for g in self.currentgatherers: self.currentgatherers[g].stop() if not temporary: d = self.cache.data d["isrunning"] = False self.cache.data = d self.isrunning = False def stopsync(self): self.cache.stop() d = self.cache.data d["isbgsync"] = False self.cache.data = d self.issyncing= False def exit(self): # exit performs cleanup - in this case, shutting down the ConnectorDB database on exit if self.cache.data["runlocal"] and self.localrunning: logging.info("Shutting down ConnectorDB server") try: cdbmanager.Manager(self.localdir).stop() self.localrunning = False except: pass