def start(self): self.mainNotificationListenerThread = NotificationListener( self, self.PORT) self.mainNotificationListenerThread.daemon = True self.mainNotificationListenerThread.start() self.cacheListenerThread = CacheListener() self.cacheListenerThread.daemon = True self.cacheListenerThread.start()
def start (self): self.mainNotificationListenerThread = NotificationListener(self, self.PORT) self.mainNotificationListenerThread.daemon = True self.mainNotificationListenerThread.start() self.cacheListenerThread = CacheListener() self.cacheListenerThread.daemon = True self.cacheListenerThread.start()
class NotificationHandler: def __init__ (self): self.lock = threading.RLock() self.PORT = ListenerPort self.ignoreSeconds = 5 self.maxNotifcationsPerNode = 20 self.mainNotificationListenerThread = None self.cacheListenerThread = None self.robotLaunchers = [] self.client = MongoClient('mongodb://localhost:27017/') self.nodes = self.client.nodesdb.nodes self.notifications = self.client.notificationsdb.notifications def getNCB(self, nodeId): nodes = self.nodes.find({"nodeId": str(nodeId)}) if nodes.count() > 0: ncbdict = nodes[0] ncb = Node() ncb.__dict__.update(ncbdict) else: ncb = Node(str(nodeId)) self.nodes.insert_one(ncb.__dict__) return ncb def dump(self): report = "" report += "Notifications:\n" for notification in self.notifications.find(): report += str(notification) report += "\n" report += "Nodes:\n" for node in self.nodes.find(): report += str(node) report += "\n" return report def getNodeReport(self, nodeId): report = "EMPTY" return report def postBatteryValueNotification (self, nodeId, commandClass, fullHex, value): with self.lock: nodeIdStr = str(nodeId) notification = BatteryValueNotification(nodeId, commandClass, fullHex, value) logger.info("Created " + str(notification)) ncb = self.getNCB(nodeId) ncb.batteryValue = value self.nodes.replace_one({"_id": ncb._id}, ncb.__dict__) self.callRobots('battery', notification, None) def postWakeupNotification (self, nodeId, commandClass, fullHex, value): with self.lock: nodeIdStr = str(nodeId) notification = WakeupNotification(nodeId, commandClass, fullHex, value) logger.info("Created " + str(notification)) ncb = self.getNCB(nodeId) ncb.lastWakeupTime = notification.time ncb.wakeupInterval = value self.nodes.replace_one({"_id": ncb._id}, ncb.__dict__) self.callRobots('wakeup', notification, None) def postValueNotification (self, nodeId, commandClass, fullHex, value): notification = ValueNotification(nodeId, commandClass, fullHex, value) logger.info("Created " + str(notification)) self.postControlNotification(nodeId, notification) def postValueChangeNotification (self, nodeId, commandClass, fullHex, value, previousValue): notification = ValueChangeNotification(nodeId, commandClass, fullHex, value, previousValue) logger.info("Created " + str(notification)) self.postControlNotification(nodeId, notification) def postNodeEventNotification (self, nodeId, commandClass, fullHex, event): notification = NodeEventNotification(nodeId, commandClass, fullHex, event) logger.info("Created " + str(notification)) self.postControlNotification(nodeId, notification) def postControlNotification (self, nodeId, notification): with self.lock: nodeIdStr = str(nodeId) previous = self.getLatestNotificationFromNode (nodeIdStr) logger.info("Got latest notification to be: " + str(previous)) if previous is not None: diff = notification.time - previous.time diffSeconds = diff.total_seconds() logger.info("Last notification arrived " + str(diffSeconds) + " seconds ago") if (diffSeconds <= self.ignoreSeconds): if (notification.value == previous.value) : logger.info("Ignoring notification: " + str(notification.nid) + " since previous notification with same value came " + str(diffSeconds) + " seconds ago.") notification.ignore = True if notification.value == 'False': if previous.value == 'False': # If a sensor is closed, and it is still closed, we # do not really care about it. # However, if a sensor is open, we care about it no # matter what the previous state was. logger.info("Ignoring notification: " + str(notification.nid) + " since previous notification was false and current notification is false") notification.ignore = True else: logger.info("Making a dummy previous") previous = ValueNotification(notification.nodeId, notification.commandClass, notification.fullHex, "False") previous.time = datetime.datetime(1970, 1, 1) #Insert dummy notification self.notifications.insert_one(previous.__dict__) print "inserting one: " + str(notification.__dict__) self.notifications.insert_one(notification.__dict__) ncb = self.getNCB(nodeId) ncb.setValue(notification.value) self.nodes.replace_one({"_id": ncb._id}, ncb.__dict__) #self.callRobots('control', notification, previous) def callRobots(self, type, notification, previous): # The following code cannot be in the critical section, because it # dump and getNodeReport (or any robot apis) can lock. if notification.ignore is False: r = RobotLauncher(type, notification, previous) r.daemon = True r.start() self.robotLaunchers.append(r) def getNotificationFromNodeByIndex (self, nodeId, index, queue = "control"): indexInt = int(index) nodeIdStr = str(nodeId) logger.info("From node(" + nodeIdStr + ") getting notification at index[" + str(index) + "]") notifications = self.notifications.find({"nodeId": str(nodeId), "queue": queue}) notificationdict = notifications.get(indexInt) return fromDict(**notificationdict) def getNotificationFromNodeById (self, nodeId, notificationId, queue = "control"): nodeIdStr = str(nodeId) logger.info("From node(" + nodeIdStr + ") getting notification with nid[" + str(notificationId) + "]") notifications = self.notifications.find({"nodeId": str(nodeId), "queue": queue, "nid": notificationId}) notificationdict = notifications.get(0) #There should be exactly one return fromDict(**notificationdict) def getEarliestNotificationOfCurrentState (self, nodeId, queue = "control"): nodeIdStr = str(nodeId) logger.info("From node(" + nodeIdStr + ") getting earliest notification of current state") topnotification = self.notifications.findOne({"nodeId": str(nodeId), "queue": queue}) # make sure this gets the first one. notifications = self.notifications.find({"nodeId": str(nodeId), "queue": queue}) for n in notifications: if n.value == topnotification.value: topnotification = n return fromDict(**topnotification) def getLatestNotificationFromNode (self, nodeId, queue = "control"): # Need to reverse sort on time notifications = self.notifications.find({"nodeId": str(nodeId), "queue": queue}) for notification in notifications: if (notification["ignore"] == False): print str(notification) return fromDict(**notification) return None def getAllNotificationsFromNode(self, nodeId, queue = "control"): return list(self.notifications.find({"nodeId": str(nodeId), "queue": queue})) def waitForRobotLaunchers (self): logger.info("Waiting on any robot launchers") [robotLauncher.join() for robotLauncher in self.robotLaunchers] logger.info("All robotLaunchers dead!") def start (self): self.mainNotificationListenerThread = NotificationListener(self, self.PORT) self.mainNotificationListenerThread.daemon = True self.mainNotificationListenerThread.start() self.cacheListenerThread = CacheListener() self.cacheListenerThread.daemon = True self.cacheListenerThread.start() def stop(self): logger.info("Stopping NotificationHandler") self.waitForRobotLaunchers() if self.mainNotificationListenerThread is not None: self.mainNotificationListenerThread.stop() self.mainNotificationListenerThread.waitForChildren() self.mainNotificationListenerThread.join() if self.cacheListenerThread is not None: self.cacheListenerThread.stop() self.cacheListenerThread.join() logger.info("NotificationHandler dead.")
class NotificationHandler: def __init__ (self): self.lock = threading.RLock() self.PORT = ListenerPort self.ignoreSeconds = 5 self.maxNotifcationsPerNode = 20 self.shelf = shelve.open(nhShelfLocation) self.mainNotificationListenerThread = None self.cacheListenerThread = None self.robotLaunchers = [] def dump(self): report = "" with self.lock: for key in self.shelf.keys(): ncb = self.shelf.get(key, None) if ncb is not None: report += "Node ID: " + nodeId + ": " + getNodeName(nodeId) + "\n" report += " Control Value: " + str(ncb.value) + "\n" report += " State: " + str(ncb.state) + "\n" report += " Battery Level: " + str(ncb.batteryValue) + "\n" report += " Last Wakeup Time: " + str(ncb.lastWakeupTime) + "\n" report += " Wakeup Interval: " + str(ncb.wakeupInterval) + "\n" report += " Control Notifications:\n" for notification in ncb.notifications: report += " " + str(notification) + "\n" report += " Battery Notifications:\n" for notification in ncb.batteryNotifications: report += " " + str(notification) + "\n" report += " Wakeup Notifications:\n" for notification in ncb.wakeupNotifications: report += " " + str(notification) + "\n" return report def getNodeReport(self, nodeId): report = "" with self.lock: ncb = self.shelf.get(nodeId, None) if ncb is not None: report += "Node ID: " + nodeId + ": " + getNodeName(nodeId) + "\n" report += " Control Value: " + str(ncb.value) + "\n" report += " Battery Level: " + str(ncb.batteryValue) + "\n" report += " Last Wakeup Time: " + str(ncb.lastWakeupTime) + "\n" report += " Wakeup Interval: " + str(ncb.wakeupInterval) + "\n" report += " Control Notifications:\n" for notification in ncb.notifications: report += " " + str(notification) + "\n" report += " Battery Notifications:\n" for notification in ncb.batteryNotifications: report += " " + str(notification) + "\n" report += " Wakeup Notifications:\n" for notification in ncb.wakeupNotifications: report += " " + str(notification) + "\n" return report def postBatteryValueNotification (self, nodeId, commandClass, fullHex, value): with self.lock: nodeIdStr = str(nodeId) notification = BatteryValueNotification(nodeId, commandClass, fullHex, value) logger.info("Created " + str(notification)) ncb = self.shelf.get(nodeIdStr, NodeControlBlock(nodeIdStr)) l = ncb.batteryNotifications # Truncate list to maxNotifcationsPerNode size l.insert(0,notification) if len(l)>self.maxNotifcationsPerNode: ncb.batteryNotifications = l[:self.maxNotifcationsPerNode] # Set overall battery value for this node and put it on the shelf ncb.batteryValue = value self.shelf[nodeIdStr] = ncb self.shelf.sync() self.callRobots('battery', notification, None) def postWakeupNotification (self, nodeId, commandClass, fullHex, value): with self.lock: nodeIdStr = str(nodeId) notification = WakeupNotification(nodeId, commandClass, fullHex, value) logger.info("Created " + str(notification)) ncb = self.shelf.get(nodeIdStr, NodeControlBlock(nodeIdStr)) l = ncb.wakeupNotifications # Truncate list to maxNotifcationsPerNode size l.insert(0,notification) if len(l)>self.maxNotifcationsPerNode: ncb.wakeupNotifications = l[:self.maxNotifcationsPerNode] # Set overall wakeup value for this node and put it on the shelf ncb.lastWakeupTime = notification.time ncb.wakeupInterval = value self.shelf[nodeIdStr] = ncb self.shelf.sync() self.callRobots('wakeup', notification, None) def postValueNotification (self, nodeId, commandClass, fullHex, value): notification = ValueNotification(nodeId, commandClass, fullHex, value) logger.info("Created " + str(notification)) self.postControlNotification(nodeId, notification) def postValueChangeNotification (self, nodeId, commandClass, fullHex, value, previousValue): notification = ValueChangeNotification(nodeId, commandClass, fullHex, value, previousValue) logger.info("Created " + str(notification)) self.postControlNotification(nodeId, notification) def postNodeEventNotification (self, nodeId, commandClass, fullHex, event): notification = NodeEventNotification(nodeId, commandClass, fullHex, event) logger.info("Created " + str(notification)) self.postControlNotification(nodeId, notification) def postControlNotification (self, nodeId, notification): with self.lock: #Critical Section nodeIdStr = str(nodeId) previous = self.getLatestNotificationFromNode (nodeIdStr) logger.info("Got latest notification to be: " + str(previous)) if previous is not None: diff = notification.time - previous.time diffSeconds = diff.total_seconds() logger.info("Last notification arrived " + str(diffSeconds) + " seconds ago") if (diffSeconds <= self.ignoreSeconds): if (notification.value == previous.value) : logger.info("Ignoring notification: " + str(notification.nid) + " since previous notification with same value came " + str(diffSeconds) + " seconds ago.") notification.ignore = True if notification.value == 'False': if previous.value == 'False': # If a sensor is closed, and it is still closed, we # do not really care about it. # However, if a sensor is open, we care about it no # matter what the previous state was. logger.info("Ignoring notification: " + str(notification.nid) + " since previous notification was false and current notification is false") notification.ignore = True else: logger.info("Making a dummy previous") previous = ValueNotification(notification.nodeId, notification.commandClass, notification.fullHex, "False") previous.time = datetime.datetime(1970, 1, 1) ncb = self.shelf.get(nodeIdStr, NodeControlBlock(nodeIdStr)) l = ncb.notifications l.insert(0,previous) self.shelf[nodeIdStr] = ncb ncb = self.shelf.get(nodeIdStr, NodeControlBlock(nodeIdStr)) l = ncb.notifications # Truncate list to maxNotifcationsPerNode size l.insert(0,notification) if len(l)>self.maxNotifcationsPerNode: ncb.notifications = l[:self.maxNotifcationsPerNode] # Set overall control value for this node and put it on the shelf ncb.setValue(notification.value) self.shelf[nodeIdStr] = ncb self.shelf.sync() #End critical section self.callRobots('control', notification, previous) def callRobots(self, type, notification, previous): # The following code cannot be in the critical section, because it # dump and getNodeReport (or any robot apis) can lock. if notification.ignore is False: r = RobotLauncher(type, notification, previous) r.daemon = True r.start() self.robotLaunchers.append(r) def getNotificationFromNodeByIndex (self, nodeId, index, queue = "control"): indexInt = int(index) nodeIdStr = str(nodeId) logger.info("From node(" + nodeIdStr + ") getting notification at index[" + str(index) + "]") ncb = self.shelf.get(nodeIdStr, None) if not ncb: logger.info("no ncb") return None else: l = None if queue == 'battery': l = ncb.batteryNotifications elif queue == 'wakeup': l = ncb.wakeupNotifications else: l = ncb.notifications if indexInt >= len(l): logger.info( "length is short: " + str(len(l))) return None return l[indexInt] def getNotificationFromNodeById (self, nodeId, notificationId, queue = "control"): nodeIdStr = str(nodeId) logger.info("From node(" + nodeIdStr + ") getting notification with nid[" + str(notificationId) + "]") ncb = self.shelf.get(nodeIdStr, None) if not ncb: logger.info("no ncb") return None else: l = None if queue == 'battery': l = ncb.batteryNotifications elif queue == 'wakeup': l = ncb.wakeupNotifications else: l = ncb.notifications for notification in l: if notificationId == notification.nid: logger.info("Found notification: " + str(notification)) return notification return None def getEarliestNotificationOfCurrentState (self, nodeId, queue = "control"): notification = self.getNotificationFromNodeByIndex(nodeId, 0, queue) if notification is not None: for i in range(1, self.maxNotifcationsPerNode): n = self.getNotificationFromNodeByIndex(nodeId, i, queue) if n and n.value == notification.value: notification = n else: break return notification def getLatestNotificationFromNode (self, nodeId, queue = "control"): notification = self.getNotificationFromNodeByIndex(nodeId, 0, queue) i = 1 while (notification is not None) and (notification.ignore is True) and (i < self.maxNotifcationsPerNode): notification = self.getNotificationFromNodeByIndex(nodeId, i, queue) i += 1 return notification def getAllNotificationsFromNode(self, nodeId, queue = "control"): nodeIdStr = str(nodeId) ncb = self.shelf.get(nodeIdStr, None) if ncb is None: return [] else: if queue == 'battery': return ncb.batteryNotifications elif queue == 'wakeup': return ncb.wakeupNotifications else: return ncb.notifications def waitForRobotLaunchers (self): logger.info("Waiting on any robot launchers") [robotLauncher.join() for robotLauncher in self.robotLaunchers] logger.info("All robotLaunchers dead!") def start (self): self.mainNotificationListenerThread = NotificationListener(self, self.PORT) self.mainNotificationListenerThread.daemon = True self.mainNotificationListenerThread.start() self.cacheListenerThread = CacheListener() self.cacheListenerThread.daemon = True self.cacheListenerThread.start() def stop(self): logger.info("Stopping NotificationHandler") self.shelf.close() self.waitForRobotLaunchers() if self.mainNotificationListenerThread is not None: self.mainNotificationListenerThread.stop() self.mainNotificationListenerThread.waitForChildren() self.mainNotificationListenerThread.join() if self.cacheListenerThread is not None: self.cacheListenerThread.stop() self.cacheListenerThread.join() logger.info("NotificationHandler dead.")
class NotificationHandler: def __init__(self): self.lock = threading.RLock() self.PORT = ListenerPort self.ignoreSeconds = 5 self.maxNotifcationsPerNode = 20 self.shelf = shelve.open(nhShelfLocation) self.mainNotificationListenerThread = None self.cacheListenerThread = None self.robotLaunchers = [] def dump(self): report = "" with self.lock: for key in self.shelf.keys(): ncb = self.shelf.get(key, None) if ncb is not None: report += "Node ID: " + nodeId + ": " + getNodeName( nodeId) + "\n" report += " Control Value: " + str(ncb.value) + "\n" report += " State: " + str(ncb.state) + "\n" report += " Battery Level: " + str( ncb.batteryValue) + "\n" report += " Last Wakeup Time: " + str( ncb.lastWakeupTime) + "\n" report += " Wakeup Interval: " + str( ncb.wakeupInterval) + "\n" report += " Control Notifications:\n" for notification in ncb.notifications: report += " " + str(notification) + "\n" report += " Battery Notifications:\n" for notification in ncb.batteryNotifications: report += " " + str(notification) + "\n" report += " Wakeup Notifications:\n" for notification in ncb.wakeupNotifications: report += " " + str(notification) + "\n" return report def getNodeReport(self, nodeId): report = "" with self.lock: ncb = self.shelf.get(nodeId, None) if ncb is not None: report += "Node ID: " + nodeId + ": " + getNodeName( nodeId) + "\n" report += " Control Value: " + str(ncb.value) + "\n" report += " Battery Level: " + str(ncb.batteryValue) + "\n" report += " Last Wakeup Time: " + str( ncb.lastWakeupTime) + "\n" report += " Wakeup Interval: " + str( ncb.wakeupInterval) + "\n" report += " Control Notifications:\n" for notification in ncb.notifications: report += " " + str(notification) + "\n" report += " Battery Notifications:\n" for notification in ncb.batteryNotifications: report += " " + str(notification) + "\n" report += " Wakeup Notifications:\n" for notification in ncb.wakeupNotifications: report += " " + str(notification) + "\n" return report def postBatteryValueNotification(self, nodeId, commandClass, fullHex, value): with self.lock: nodeIdStr = str(nodeId) notification = BatteryValueNotification(nodeId, commandClass, fullHex, value) logger.info("Created " + str(notification)) ncb = self.shelf.get(nodeIdStr, NodeControlBlock(nodeIdStr)) l = ncb.batteryNotifications # Truncate list to maxNotifcationsPerNode size l.insert(0, notification) if len(l) > self.maxNotifcationsPerNode: ncb.batteryNotifications = l[:self.maxNotifcationsPerNode] # Set overall battery value for this node and put it on the shelf ncb.batteryValue = value self.shelf[nodeIdStr] = ncb self.shelf.sync() self.callRobots('battery', notification, None) def postWakeupNotification(self, nodeId, commandClass, fullHex, value): with self.lock: nodeIdStr = str(nodeId) notification = WakeupNotification(nodeId, commandClass, fullHex, value) logger.info("Created " + str(notification)) ncb = self.shelf.get(nodeIdStr, NodeControlBlock(nodeIdStr)) l = ncb.wakeupNotifications # Truncate list to maxNotifcationsPerNode size l.insert(0, notification) if len(l) > self.maxNotifcationsPerNode: ncb.wakeupNotifications = l[:self.maxNotifcationsPerNode] # Set overall wakeup value for this node and put it on the shelf ncb.lastWakeupTime = notification.time ncb.wakeupInterval = value self.shelf[nodeIdStr] = ncb self.shelf.sync() self.callRobots('wakeup', notification, None) def postValueNotification(self, nodeId, commandClass, fullHex, value): notification = ValueNotification(nodeId, commandClass, fullHex, value) logger.info("Created " + str(notification)) self.postControlNotification(nodeId, notification) def postValueChangeNotification(self, nodeId, commandClass, fullHex, value, previousValue): notification = ValueChangeNotification(nodeId, commandClass, fullHex, value, previousValue) logger.info("Created " + str(notification)) self.postControlNotification(nodeId, notification) def postNodeEventNotification(self, nodeId, commandClass, fullHex, event): notification = NodeEventNotification(nodeId, commandClass, fullHex, event) logger.info("Created " + str(notification)) self.postControlNotification(nodeId, notification) def postControlNotification(self, nodeId, notification): with self.lock: #Critical Section nodeIdStr = str(nodeId) previous = self.getLatestNotificationFromNode(nodeIdStr) logger.info("Got latest notification to be: " + str(previous)) if previous is not None: diff = notification.time - previous.time diffSeconds = diff.total_seconds() logger.info("Last notification arrived " + str(diffSeconds) + " seconds ago") if (diffSeconds <= self.ignoreSeconds): if (notification.value == previous.value): logger.info( "Ignoring notification: " + str(notification.nid) + " since previous notification with same value came " + str(diffSeconds) + " seconds ago.") notification.ignore = True if notification.value == 'False': if previous.value == 'False': # If a sensor is closed, and it is still closed, we # do not really care about it. # However, if a sensor is open, we care about it no # matter what the previous state was. logger.info( "Ignoring notification: " + str(notification.nid) + " since previous notification was false and current notification is false" ) notification.ignore = True else: logger.info("Making a dummy previous") previous = ValueNotification(notification.nodeId, notification.commandClass, notification.fullHex, "False") previous.time = datetime.datetime(1970, 1, 1) ncb = self.shelf.get(nodeIdStr, NodeControlBlock(nodeIdStr)) l = ncb.notifications l.insert(0, previous) self.shelf[nodeIdStr] = ncb ncb = self.shelf.get(nodeIdStr, NodeControlBlock(nodeIdStr)) l = ncb.notifications # Truncate list to maxNotifcationsPerNode size l.insert(0, notification) if len(l) > self.maxNotifcationsPerNode: ncb.notifications = l[:self.maxNotifcationsPerNode] # Set overall control value for this node and put it on the shelf ncb.setValue(notification.value) self.shelf[nodeIdStr] = ncb self.shelf.sync() #End critical section self.callRobots('control', notification, previous) def callRobots(self, type, notification, previous): # The following code cannot be in the critical section, because it # dump and getNodeReport (or any robot apis) can lock. if notification.ignore is False: r = RobotLauncher(type, notification, previous) r.daemon = True r.start() self.robotLaunchers.append(r) def getNotificationFromNodeByIndex(self, nodeId, index, queue="control"): indexInt = int(index) nodeIdStr = str(nodeId) logger.info("From node(" + nodeIdStr + ") getting notification at index[" + str(index) + "]") ncb = self.shelf.get(nodeIdStr, None) if not ncb: logger.info("no ncb") return None else: l = None if queue == 'battery': l = ncb.batteryNotifications elif queue == 'wakeup': l = ncb.wakeupNotifications else: l = ncb.notifications if indexInt >= len(l): logger.info("length is short: " + str(len(l))) return None return l[indexInt] def getNotificationFromNodeById(self, nodeId, notificationId, queue="control"): nodeIdStr = str(nodeId) logger.info("From node(" + nodeIdStr + ") getting notification with nid[" + str(notificationId) + "]") ncb = self.shelf.get(nodeIdStr, None) if not ncb: logger.info("no ncb") return None else: l = None if queue == 'battery': l = ncb.batteryNotifications elif queue == 'wakeup': l = ncb.wakeupNotifications else: l = ncb.notifications for notification in l: if notificationId == notification.nid: logger.info("Found notification: " + str(notification)) return notification return None def getEarliestNotificationOfCurrentState(self, nodeId, queue="control"): notification = self.getNotificationFromNodeByIndex(nodeId, 0, queue) if notification is not None: for i in range(1, self.maxNotifcationsPerNode): n = self.getNotificationFromNodeByIndex(nodeId, i, queue) if n and n.value == notification.value: notification = n else: break return notification def getLatestNotificationFromNode(self, nodeId, queue="control"): notification = self.getNotificationFromNodeByIndex(nodeId, 0, queue) i = 1 while (notification is not None) and (notification.ignore is True) and (i < self.maxNotifcationsPerNode): notification = self.getNotificationFromNodeByIndex( nodeId, i, queue) i += 1 return notification def getAllNotificationsFromNode(self, nodeId, queue="control"): nodeIdStr = str(nodeId) ncb = self.shelf.get(nodeIdStr, None) if ncb is None: return [] else: if queue == 'battery': return ncb.batteryNotifications elif queue == 'wakeup': return ncb.wakeupNotifications else: return ncb.notifications def waitForRobotLaunchers(self): logger.info("Waiting on any robot launchers") [robotLauncher.join() for robotLauncher in self.robotLaunchers] logger.info("All robotLaunchers dead!") def start(self): self.mainNotificationListenerThread = NotificationListener( self, self.PORT) self.mainNotificationListenerThread.daemon = True self.mainNotificationListenerThread.start() self.cacheListenerThread = CacheListener() self.cacheListenerThread.daemon = True self.cacheListenerThread.start() def stop(self): logger.info("Stopping NotificationHandler") self.shelf.close() self.waitForRobotLaunchers() if self.mainNotificationListenerThread is not None: self.mainNotificationListenerThread.stop() self.mainNotificationListenerThread.waitForChildren() self.mainNotificationListenerThread.join() if self.cacheListenerThread is not None: self.cacheListenerThread.stop() self.cacheListenerThread.join() logger.info("NotificationHandler dead.")