def __init__(self, host="matelight", port=1337, *args): super(Matelight, self).__init__(*args) self.log("Initializing matelight output") self.host = host self.port = port self.size = (40, 16) self.gamma = 0.5 self.fading = None self.auto_restart = True self.output_broken = False self.last_frame = np.zeros(self.size, np.uint8) path = os.path.abspath("./images/startscreen_matelight.png") boot_image = cv.imread(path) self.boot_image = cv.cvtColor(boot_image, cv.COLOR_BGR2RGB) self._transmit(self.boot_image) self.fade_timer = None self.init_timer = Timer(5, fade_out_ml()).register(self) self.refresh_timer = Timer(1, refresh_ml(), persist=True).register(self)
def test_datetime(app): now = datetime.now() d = now + timedelta(seconds=0.1) timer = Timer(d, test(), "timer") timer.register(app) assert pytest.wait_for(app, "flag") app.reset()
def started(self, *args): self.conn = ModbusClient(host=self.ip[0], port=self.ip[1], auto_open=True) self.fire(sample(), self) self.sample_timer = Timer(self.DEFAULT_INTERVAL + random.uniform(0, 1), sample(), self, persist=True).register(self) return
def __init__(self, maxcams=16, *args): super(Manager, self).__init__("CAM", *args) self._cameras = {} self._subscribers = {} self._filming = True self._frame_count = 0 self._frames = {} if opencv is not None: self.log("Checking opencv for cameras.", lvl=debug) for cam in range(maxcams): video = opencv.VideoCapture(cam) if video.isOpened(): camera = { 'uuid': str(uuid4()), 'name': 'Camera' + str(cam), 'cam': video } self._cameras[cam] = camera self.log("Found camera [", cam, "]: ", camera) if len(self._cameras) > 0: self.log("Starting timer") self.timer = Timer(0.05, Event.create("rec"), persist=True).register(self) self.log("Found cameras: ", self._cameras, lvl=debug) else: self.log("No opencv, no cameras.") self.log("Started")
def start_heartbeats(self): LOG.info("Client HB: %s Server HB: %s", self._client.clientHeartBeat, self._client.serverHeartBeat) if self._client.clientHeartBeat: if self.client_heartbeat: # Timer already exists, just reset it self.client_heartbeat.reset() else: LOG.info("Client will send heartbeats to server") # Send heartbeats at 80% of agreed rate self.client_heartbeat = Timer( (self._client.clientHeartBeat / 1000.0) * 0.8, ClientHeartbeat(), persist=True) self.client_heartbeat.register(self) else: LOG.info("No Client heartbeats will be sent") if self._client.serverHeartBeat: if self.server_heartbeat: # Timer already exists, just reset it self.server_heartbeat.reset() else: LOG.info("Requested heartbeats from server.") # Allow a grace period on server heartbeats self.server_heartbeat = Timer( (self._client.serverHeartBeat / 1000.0) * self.ALLOWANCE, ServerHeartbeat(), persist=True) self.server_heartbeat.register(self) else: LOG.info("Expecting no heartbeats from Server")
def _start_auto_refresh(self, incident): # Get the interval from the avalon_auto_refresh_time field refresh_interval_minutes = self.actions.res.incident_get_avalon_auto_refresh_time( incident) # default to 60 minutes if not set in IBM Resilient if not refresh_interval_minutes: refresh_interval_minutes = 60 # create timer incident_id = incident["id"] auto_refresh_event = auto_refresh(incident_id) timer = Timer(60 * refresh_interval_minutes, auto_refresh_event, self.channel, persist=True) # keep timer in the incident map self.incident_timer[incident_id] = timer # start ticking timer.register(self) # fire event once to refresh nodes now self.fire(auto_refresh_event)
def init_scene(self): print(EventReport("Info", "Init Scene")) self.sensors = [] num_sensors = len(c["sensor"]) for i in range(0, num_sensors): s1 = Sensor(i, c["sensor"][i]["name"], c["sensor"][i]["readlatency"], c["sensor"][i]["period"], c["sensor"][i]["pin"]) self.sensors.append(s1) self.set_endtime(c["interval"]["M"]) self.bought_data = c["params"]["D"] print(self.sensors) for i in range(0, num_sensors): s1 = self.sensors[i] CircuitsApp.timers["sense"] = Timer(s1.period, SenseEvent( s1, self.readings_queue), persist=False).register(self) CircuitsApp.timers["upload"] = Timer(c["interval"]["upload"], UploadEvent(self.readings_queue), persist=False).register(self)
def start_heartbeats(self): LOG.info("Client HB: %s Server HB: %s", self._client.clientHeartBeat, self._client.serverHeartBeat) if self._client.clientHeartBeat: if self.client_heartbeat: # Timer already exists, just reset it self.client_heartbeat.reset() else: LOG.info("Client will send heartbeats to server") # Send heartbeats at 80% of agreed rate self.client_heartbeat = Timer((self._client.clientHeartBeat / 1000.0) * 0.8, client_heartbeat(), persist=True) self.client_heartbeat.register(self) else: LOG.info("No Client heartbeats will be sent") if self._client.serverHeartBeat: if self.server_heartbeat: # Timer already exists, just reset it self.server_heartbeat.reset() else: LOG.info("Requested heartbeats from server.") # Allow a grace period on server heartbeats self.server_heartbeat = Timer((self._client.serverHeartBeat / 1000.0) * self.ALLOWANCE, server_heartbeat(), persist=True) self.server_heartbeat.register(self) else: LOG.info("Expecting no heartbeats from Server")
def __init__(self, maxcams=16, *args): super(CameraManager, self).__init__(*args) self._cameras = {} self._subscribers = {} self._filming = True self._framecount = 0 self._frames = {} hfoslog("[CAM] Checking opencv for cameras.", lvl=debug) for cam in range(maxcams): video = opencv.VideoCapture(cam) if video.isOpened(): camera = { 'uuid': str(uuid4()), 'name': 'Camera' + str(cam), 'cam': video } self._cameras[cam] = camera hfoslog("[CAM] Found camera [", cam, "]: ", camera) hfoslog("[CAM] Starting timer") self.timer = Timer(0.05, Event.create("rec"), persist=True).register(self) hfoslog("[CAM] Found cameras: ", self._cameras, lvl=debug) hfoslog("[CAM] Started")
def persistent(self, interval): timer = Timer(interval, single(), persist=True) timer.register(self) yield sleep(interval * 10) timer.unregister()
def play(self): self.log('Play!', lvl=debug) self.playing = True if self.timer is None: self.ptime = time.time() self.timer = Timer(self.config['delay'] / 1000.0, render(), persist=True).register(self)
def started(self, component): print("started") Timer(20, Event.create("end")).register(self) # Fire some test events N = 3 for loop in range(1, N): self.fire(ActionMessage(source="test_thing", headers=None, message={"who": "you"})) Timer(1, ActionMessage(source="test_thing", headers=None, message={"who": "me"})).register(self) Timer(2, ActionMessage(source="test_thing", headers=None, message={"who": "us"})).register(self)
def __init__(self, *args, **kwargs): super(FloodProtectedManager, self).__init__(*args, **kwargs) self._flooding = {} self._flood_counter = {} self._flood_counters_resetter = Timer( 2, Event.create("reset_flood_counters"), persist=True ).register(self) self._flood_offender_resetter = Timer( 10, Event.create("reset_flood_offenders"), persist=True ).register(self)
def cli_test_gifplayer(self, *args): if 'stop' in args: self.log("Stopping test video") self.stop() else: self.log('Running test video') self.config['filename'] = os.path.abspath( os.path.join(__file__, "../../test.gif")) self.get_frames() self.timer = Timer(self.config['delay'] / 1000.0, render(), persist=True).register(self)
def started(self, component): """started Event handler Setup 3 timers at 5, 1 and 3 seconds. The 2nd two timers are persitent meaning that they are fired repeatedly every 1 and 3 seconds respectively. """ # Timer(seconds, event, persist=False) Timer(5, Event.create("hello")).register(self) Timer(1, Event.create("foo"), persist=True).register(self) Timer(3, Event.create("bar"), persist=True).register(self)
def fade_out_ml(self, event): if self.fading is None: self.fading = 20 self.fade_timer = Timer(1 / 60.0, fade_out_ml(), persist=True).register( self) elif self.fading > 0: new_frame = (self.last_frame * 0.9).astype(np.uint8) self._transmit(new_frame) self.fading -= 1 elif self.fading <= 0: self._clear() self.fade_timer.unregister() self.fading = None
def _process_download(self): if not self.downloading and self.queue: if not self.process: self.downloading = self.queue.popleft() flags = ' '.join(self.options) # Still not sure why I have to give a stock Manager() rather than self. self.process = Process( self.yt_dl + ' ' + flags + ' ' + self.downloading, cwd=self.save_dir).register(self.manager) self.process.start() self.start_time = time.clock() if not self.timer: self.timer = Timer(1, poll_process(), persist=True).register(self)
def __init__(self, maxcams=16, *args): super(Manager, self).__init__("CAM", *args) self._cameras = {} self._subscribers = {} self._filming = True self._frame_count = 0 self._frames = {} if opencv is not None: self.log("Checking opencv for cameras.", lvl=debug) for cam in range(maxcams): video = opencv.VideoCapture(cam) if video.isOpened(): camera = {'uuid': str(uuid4()), 'name': 'Camera' + str(cam), 'cam': video } self._cameras[cam] = camera self.log("Found camera [", cam, "]: ", camera) if len(self._cameras) > 0: self.log("Starting timer") self.timer = Timer(0.05, Event.create("rec"), persist=True).register(self) self.log("Found cameras: ", self._cameras, lvl=debug) else: self.log("No opencv, no cameras.") self.log("Started")
def test_persistentTimer(app): app.timestamps.append(time.time()) timer = Timer(0.2, test(), "timer", persist=True) timer.register(app) wait_res = pytest.wait_for(app, "count", 2) assert app.count >= 2 assert wait_res delta = app.timestamps[1] - app.timestamps[0] # Should be 0.1, but varies depending on timer precision and load assert delta >= 0.08 and delta < 0.5 delta = app.timestamps[2] - app.timestamps[1] assert delta >= 0.08 and delta < 0.5 app.reset() timer.unregister()
def upload_event(self, *args, **kwargs): ## args[0] is the reading queue queue = args[0] print(EventReport("UploadEvent", (str(args) + ", " + str(kwargs)))) #lprint(EventReport("UploadEvent", "started")) CircuitsApp.shareState = 0 yield self.call(task(upload_a_bundle(queue))) print("Upload successful.") CircuitsApp.shareState = 1 lprint(EventReport("UploadEvent", "ENDED")) CircuitsApp.last_uploaded = getSentByte() - CircuitsApp.startbyte lprint( EventReport("UploadedSoFar", str(convert_size(CircuitsApp.last_uploaded))), 45) M = c["interval"]["M"] t = time.time() - CircuitsApp.starttime if (M == t): return #~ if(M - t < c["interval"]["upload"]): #~ CircuitsApp.timers["upload"] = Timer((M - t), UploadEvent(args[0]), persist=False).register(self) #~ else: if not CircuitsApp.isEnd: CircuitsApp.timers["upload"] = Timer(c["interval"]["upload"], UploadEvent(args[0]), persist=False).register(self) rate = CircuitsApp.upload_rate u = CircuitsApp.last_uploaded CircuitsApp.upload_rate = min((c["params"]["D"] - u) * 1.0 / (M - t), c["upload"]["max_rate"])
def sense_event(self, *args, **kwargs): "hello, I got an event" print(EventReport("SenseEvent", (str(args) + ", " + str(kwargs)))) CircuitsApp.timers["sense"] = Timer(args[0].period, SenseEvent(args[0], args[1]), persist=False).register(self) self.fire(ReadEvent(args[0], args[1]))
def started(self, component): # x = yield self.call(task(factorial, 10)) Timer(1, Event.create("foo"), persist=True).register(self) self.fire(task(download_web_page, 'http://www.slickdeals.net')) # async self.fire(task(download_web_page, 'http://www.google.com')) # async self.fire(task(download_web_page, 'http://www.yahoo.com')) # async
def __init__(self, maxcams=16, *args): super(CameraManager, self).__init__("CAM", *args) self._cameras = {} self._subscribers = {} self._filming = True self._framecount = 0 self._frames = {} if opencv is not None: self.log("Checking opencv for cameras.", lvl=debug) for cam in range(maxcams): video = opencv.VideoCapture(cam) if video.isOpened(): camera = {"uuid": str(uuid4()), "name": "Camera" + str(cam), "cam": video} self._cameras[cam] = camera self.log("Found camera [", cam, "]: ", camera) self.log("Starting timer") self.timer = Timer(0.05, Event.create("rec"), persist=True).register(self) self.log("Found cameras: ", self._cameras, lvl=debug) else: self.log("No opencv, no cameras.") AuthorizedEvents["camera"] = camerarequest self.log("Started")
def __init__(self, *args): ConfigurableComponent.__init__(self, "IRCBOT", *args) if self.config.get('password', None) is None: self.config.password = std_uuid() self.config.save() self.channel = 'ircbot' self.fireEvent(cli_register_event('test_irc_send', cli_test_irc_send), "isomer-web") self.log("Started") self.host = self.config.host self.port = self.config.port self.hostname = gethostname() self.nick = self.config.nick self.irc_channels = self.config.channels # Mapping of IRC Channel -> Set of Nicks self.channel_map = defaultdict(set) # Mapping of Nick -> Set of IRC Channels self.nick_map = defaultdict(set) # Add TCPClient and IRC to the system. self.transport = TCPClient(channel=self.channel).register(self) self.protocol = IRC(channel=self.channel).register(self) # Keep-Alive Timer Timer(60, Event.create("keepalive"), persist=True).register(self)
def init(self, events, gui=None): self.timers = [] # Create and register all the events defined in PeriodicEvents events.register(self) # Construct the list of timer handlers for all events iff interval[e] is defined/registered self.timers = [ Timer(events.interval[e], Event.create(e), persist=True).register(self) for e in events.event_names if events.interval.get(e) ] # Set up GUI handler for updating if gui is not None: self.gui = gui Timer(0.01, Event.create('update_gui'), persist=True).register(self) self.queue = Queue.Queue()
def __init__(self, *args, **kwargs): super(BackupManager, self).__init__("BACKUP", *args, **kwargs) self.log("Backup manager started") self.timer = Timer(self.config.interval, Event.create("backup"), persist=True).register(self)
def joystickchange(self, event): if event.input.type != pygame.JOYBUTTONUP: return # self.log(event.input, pretty=True) button = event.input.button key = "" if button == 0: key = "X" elif button == 1: key = "O" elif button == 2: key = "A" elif button == 3: key = "S" self.input += key if self.timer is not None: self.timer.unregister() if self.input in self.combos: self.log("Firing combo event for combo", self.input, lvl=debug) self.fireEvent(Event.create(self.combos[self.input])) self.input = "" else: self.timer = Timer(self.config.timeout, reset_combo_trigger()).register(self)
def __init__(self, *args): """ Initialize the navigation sensor data component. :param args: """ super(Sensors, self).__init__('NAVDATA', *args) self.datatypes = {} # self._update_sensordata() self.sensed = {} self.referenceframe = {} # objectmodels['sensordata']() self.referenceages = {} self.changed = False self.interval = 1 self.passiveinterval = 10 self.intervalcount = 0 self.subscriptions = {} Timer(self.interval, Event.create('navdatapush'), self.channel, persist=True).register(self)
def __init__(self, opts): super(FunctionComponent, self).__init__(opts) self.options = opts.get("fn_symantec_dlp", {}) self.dlp_listener = DLPListener(opts) if "pytest" in sys.modules: # Reaching here indicates that the component is invoked from within a testing session. # In this case, don't start the Poller LOG.info("Running within a test environment. Not starting listener") else: # The dlp_listener_toggle will determine whether the Poller will run if str_to_bool(self.options.get("sdlp_should_poller_run", None)): if self.dlp_listener.soap_client.is_connected: self.setup_listener() # Use a circuits timer to fire off an event every N seconds. # When the event is fired, a function with the decorator @handler(name_of_event) # will be used to handle the event and perform some task polling_interval = int(self.options.get("sdlp_listener_timer", DEFAULT_POLLING_INTERVAL)) LOG.debug(u"DLP Polling interval will be %s seconds", polling_interval) Timer(interval=polling_interval, event=Event.create("DLPListenerPollingEvent"), persist=True).register(self)
def __init__(self, *args): super(ConnectivityMonitor, self).__init__("NETMON", *args) self.fireEvent( cli_register_event('test_connectivity', cli_test_connectivity)) self.old_status = True self.status = False self.nodestate = objectmodels['nodestate'].find_one( {'uuid': STATE_UUID_CONNECTIVITY}) status = self._can_connect() self.log('Initial connectivity state:', status) self.fireEvent( backend_nodestate_toggle(STATE_UUID_CONNECTIVITY, on=status, force=True)) self.old_status = self.status = status self.timer = Timer(self.config.interval, timed_connectivity_check(), persist=True).register(self) self.log("Started")
def __init__(self, maxcams=16, *args): super(CameraManager, self).__init__(*args) self._cameras = {} self._subscribers = {} self._filming = True self._framecount = 0 self._frames = {} hfoslog("[CAM] Checking opencv for cameras.", lvl=debug) for cam in range(maxcams): video = opencv.VideoCapture(cam) if video.isOpened(): camera = {'uuid': str(uuid4()), 'name': 'Camera' + str(cam), 'cam': video } self._cameras[cam] = camera hfoslog("[CAM] Found camera [", cam, "]: ", camera) hfoslog("[CAM] Starting timer") self.timer = Timer(0.05, Event.create("rec"), persist=True).register(self) hfoslog("[CAM] Found cameras: ", self._cameras, lvl=debug) hfoslog("[CAM] Started")
def call_loop(self, event): """Runs a given client loop for interactive processes""" self.log('Running external loop') try: self.loop_function() except Exception: self.loop_timer.unregister() Timer(2, Event.create("quit")).register(self)
def __init__(self, *args): super(NavdataSim, self).__init__("NAVSIM", *args) if self.config.active is True: self.log("Started, channel:", self.channel) Timer(3, generatenavdata(), persist=True).register(self) else: self.log("Disabled.")
class CVCamera(AVIOComponent): def __init__(self, device_id=0, targetresolution=(40, 16), *args, **kwargs): super(CVCamera, self).__init__(*args, **kwargs) self.targetresolution = targetresolution self.cam = cv2.VideoCapture(device_id) self.cam.set(3, 320) self.cam.set(4, 240) self.framerate = 20 / 1000.0 self.recording = True self.worker = Worker(process=False, workers=1, channel="camera").register(self) self.cam_timer = Timer(2, Event.create('takepicture')).register( self) self.surface = pygame.Surface(targetresolution) self.log('Camera started') def takepicture(self): if self.recording: self.log('Taking a pic') self.fireEvent(task(take_picture, self.cam), 'camera') @handler('task_success', channel='camera') def task_success(self, event, call, result): frame = result if frame is None: self.log("Oh, no camera attached! Change this and rerun!") self.cam_timer.unregister() return newframe = numpy.rot90(frame) #newframe = cv2.resize(frame, self.targetresolution) surfarr = pygame.surfarray.make_surface(newframe) srf = pygame.transform.scale(surfarr, self.targetresolution) self.fireEvent(cameraframe(srf)) self.fireEvent(Event.create('takepicture'))
def on_read(self, *args): print(args) parsed_data = json.loads(args[0].decode()) if parsed_data.get("ACK"): print("Write data!!!", file_data) self.write(file_data) if parsed_data.get("info"): print(parsed_data.get("info")) Timer(1, disconnect()).register(self)
def _execute_action_from_queue(self): discard = False action = None if len(self.actionqueue): logging.debug('dequeuing next API action') # pop from queue action = self.actionqueue.popleft() elif self.shm['state']['ICHCAPI']['room_joined']: # no actions; simply receive any new message from the API action = ['recv'] delay = self.config['polling_interval'] if action: requeue = True # process only join requests when not joined query_type = action[0] if query_type == 'join': # ensure rejoin gets sent requeue = False if not self.shm['state']['ICHCAPI']['join_lock']: self.shm['state']['ICHCAPI']['join_lock'] = True else: # suppress superfluous join requests discard = True elif self.shm['state']['ICHCAPI']['room_joined']: requeue = False if requeue: # put back actions we're not ready to execute self.actionqueue.appendleft(action) elif not discard: self.shm['state']['ICHCAPI']['last_action'] = action[0] self.shm['state']['ICHCAPI']['last_query'] = time() # send in line self._query_api_from_action(action) self.shm['stats']['ICHCAPI']['api_requests'] += 1 # throttle if we recv'd last time and got no new messages if (action[0] == 'recv' and self.shm['state']['ICHCAPI']['last_action'] == 'recv' and self.shm['state']['ICHCAPI']['empty_recvs'] > (int(self.config['api_throttle_idle_timeout'] // self.config['polling_interval']) - 1)): delay = self.shm['state']['ICHCAPI']['last_interval'] if (delay < self.config['max_polling_interval']): delay += self.config['api_throttle_step'] self.shm['state']['ICHCAPI']['last_interval'] = delay logging.debug( "throttling API polling to {}s".format(delay)) self.http_poll_timer = Timer(float(delay), events.do_process_next_action(), self.channel).register(self)
class PancakesBot(Component): channel = "pancakesbot" def init(self, **kwargs): # Default Settings prop_defaults = { "nick": "pancakesbot", "network": "irc.slashnet.org", "port": 6667, "channels": ["#bots"], "plugins": ["admin"], "plugins_path": "plugins", "command_prefix": "~", "storage_path": "storage", } self.__dict__.update(prop_defaults) # Overwrite defaults with kwargs if kwargs: self.__dict__.update(kwargs) self.terminate = False self.storage_path = os.path.abspath(self.storage_path) # Add a logger self.logger = logging.getLogger(__name__) # Message Queue used by plugins, as to avoid kicks for flooding. self.msg_queue = [] # Global mesasge queue timer, only activated when there are messages # to process. self.queue_timer = None # Add TCPClient and IRC to the system. TCPClient(channel=self.channel).register(self) IRC(channel=self.channel).register(self) # Creates an instance of UserManager self.logger.debug("Initializing user manager.") user_db_file = os.path.join(self.storage_path, "users-{}.db".format(self.network)) if not os.path.exists(self.storage_path): os.makedirs(self.storage_path) self.user_mngr = UserManager(self, user_db_file) self.user_mngr.register(self) # Add plugins directory to path self.logger.debug("Initializing plugin manager.") self.plugins_path = os.path.abspath(self.plugins_path) if not os.path.exists(self.plugins_path): os.makedirs(self.plugins_path) sys.path.append(self.plugins_path) # Keeps track of plugins and commands self.plugin_mngr = PluginManager(self, self.command_prefix, os.path.basename(self.plugins_path)).register(self) for plugin in self.plugins: self.plugin_mngr.load(plugin) # Send Keepalive PING every 5 minutes Timer(300.0, Event.create("keepalive"), persist=True).register(self) def enqueue_msg(self, target, message): if self.queue_timer: self.msg_queue.append((target, message)) else: self.fire(PRIVMSG(target, message)) self.queue_timer = Timer(1.0, Event.create("process_queue"), persist=True).register(self) def process_queue(self): if self.msg_queue: msg = self.msg_queue[0] self.fire(PRIVMSG(msg[0], msg[1])) self.msg_queue.pop(0) if not self.msg_queue: self.queue_timer.unregister() self.queue_timer = None def keepalive(self): timestamp = int(time() * 1000) self.logger.debug("PING: {}".format(timestamp)) self.fire(request(Message("PING", "LAG{0}".format(timestamp)))) @handler("signal", channels="*") def signal(self, signo, stack): if signo in (SIGINT, SIGTERM): self.fire(QUIT("Received SIGTERM, terminating...")) self.fire(events.terminate()) ####################################################### # Event Handlers # # These handle events and fire the pancakesbot events # ####################################################### @handler("privmsg") def _on_text(self, user, target, message): user += (self.user_mngr.get_user_id(user),) if (message.startswith("\x01ACTION ")) and (message[-1] == "\x01"): message = message[7:] self.logger.debug("ACTION: {}({})@{}: {}".format(user[0], user[3], target, message)) self.fire(events.on_action(user, target, message), "plugins") else: self.logger.debug("MSG: {}({})@{}: {}".format(user[0], user[3], target, message)) self.fire(events.on_text(user, target, message), "plugins") @handler("ready") def _on_ready(self, component): self.logger.info("Ready. " "Connecting to {0.network}:{0.port}".format(self)) self.fire(connect(self.network, self.port)) @handler("connected") def _on_connected(self, network, port): self.logger.info("Connected. Signing in as {0.nick}".format(self)) self.fire(NICK(self.nick)) self.fire(USER("pancakes", "pancakes", network, "robot")) self.fire(events.on_logon(network, port), "plugins") @handler("disconnected") def _on_disconnected(self): self.logger.info("Disconnected.") self.fire(events.on_disconnect(), "plugins") if self.terminate: raise SystemExit(0) else: self.logger.info("Reconnecting.") self.fire(events.on_reconnect(), "plugins") self.fire(connect(self.network, self.port)) @handler("terminate") def _on_terminate(self): self.terminate = True self.fire(events.on_exit(), "plugins") self.logger.info("Terminating.") raise SystemExit(0) @handler("join") def _on_join(self, user, channel): # Send a who for channel on join if user[0] == self.nick: self.fire(WHO(channel)) user += (self.user_mngr.get_user_id(user),) self.fire(events.on_join(user, channel), "plugins") self.logger.info("JOIN: {} ({}) to {}".format(user[0], user[3], channel)) @handler("part") def _on_part(self, user, channel, *args): if args: message = args[0] else: message = "" user += (self.user_mngr.get_user_id(user),) self.fire(events.on_part(user, channel, message), "plugins") self.logger.debug("PART: {} ({}) from {} ({})".format(user[0], user[3], channel, message)) @handler("quit") def _on_quit(self, user, *args): if args: message = args[0] else: message = "" user += (self.user_mngr.get_user_id(user),) self.fire(events.on_quit(user, message), "plugins") self.logger.debug("QUIT: {} ({})".format(user[0], user[3], message)) @handler("notice") def _on_notice(self, user, target, message): user += (self.user_mngr.get_user_id(user),) self.fire(events.on_notice(user, target, message), "plugins") self.logger.debug("NOTICE: {}@{}: {}".format(user[0], target, message)) @handler("invite") def _on_invite(self, nickname, channel): user = self.user_mngr.get_full_user(nick=nickname) self.fire(events.on_invite(user, channel), "plugins") self.logger.info("INVITE: {} ({}) invited us to {}.".format(user[0], user[3], channel)) @handler("kick") def _on_kick(self, user, channel, target, message): user += (self.user_mngr.get_user_id(user),) target = self.user_mngr.get_full_user(nick=target) self.fire(events.on_kick(user, target, channel, message), "plugins") self.logger.debug( "KICK: {} ({}) kicked {} ({}) from {} ({})".format(user[0], user[3], target[0], target[3], channel, message) ) @handler("mode") def _on_mode(self, user, target, mode, *args): if mode == "+b": user += (self.user_mngr.get_user_id(user),) self.fire(events.on_ban(user, args[0], target), "plugins") self.logger.debug("BAN: {} banned {} from {}".format(user[0], args[0], target)) elif mode == "-b": user += (self.user_mngr.get_user_id(user),) self.fire(events.on_unban(user, args[0], target), "plugins") self.logger.debug("UNBAN: {} unbanned {} from {}".format(user[0], args[0], target)) elif mode == "+v": user += (self.user_mngr.get_user_id(user),) t_user = self.user_mngr.get_full_user(nick=args[0]) self.fire(events.on_voice(user, t_user, target), "plugins") self.logger.debug("VOICE: {} gave voice " "to {} in {}".format(user[0], t_user[0], target)) elif mode == "-v": user += (self.user_mngr.get_user_id(user),) t_user = self.user_mngr.get_full_user(nick=args[0]) self.fire(events.on_devoice(user, t_user, target), "plugins") self.logger.debug("DEVOICE: {} removed voice " "from {} in {}".format(user[0], t_user[0], target)) elif mode == "+o": user += (self.user_mngr.get_user_id(user),) t_user = self.user_mngr.get_full_user(nick=args[0]) self.fire(events.on_op(user, t_user, target), "plugins") self.logger.debug("OP: {} gave operator " "to {} in {}".format(user[0], t_user[0], target)) elif mode == "-o": user += (self.user_mngr.get_user_id(user),) t_user = self.user_mngr.get_full_user(nick=args[0]) self.fire(events.on_deop(user, t_user, target), "plugins") self.logger.debug("DEOP: {} removed operator " "from {} in {}".format(user[0], t_user[0], target)) elif mode == "+q": user += (self.user_mngr.get_user_id(user),) t_user = self.user_mngr.get_full_user(nick=args[0]) self.fire(events.on_owner(user, t_user, target), "plugins") self.logger.debug("OWNER: {} gave owner " "to {} in {}".format(user[0], t_user[0], target)) elif mode == "-q": user += (self.user_mngr.get_user_id(user),) t_user = self.user_mngr.get_full_user(nick=args[0]) self.fire(events.on_deowner(user, t_user, target), "plugins") self.logger.debug("DEOWNER: {} removed owner " "from {} in {}".format(user[0], t_user[0], target)) elif target.startswith("#"): user += (self.user_mngr.get_user_id(user),) self.fire(events.on_mode(user, mode, target), "plugins") self.logger.debug("MODE: {} set {} in {} ({})".format(user[0], mode, target, args)) @handler("nick") def _on_nick(self, user, new_nick): self.user_mngr.changed_nick(user, new_nick) user += (self.user_mngr.get_user_id(user),) self.fire(events.on_nick(user, new_nick), "plugins") self.logger.debug("NICK: {} ({}) changed nick to {}".format(user[0], user[3], new_nick)) @handler("topic") def _on_topic(self, user, channel, topic): user += (self.user_mngr.get_user_id(user),) self.logger.debug('TOPIC: {} ({}) changed topic of {} to "{}"'.format(user[0], user[3], channel, topic)) @handler("numeric") def _on_numeric(self, source, numeric, *args): self.logger.debug("NUMERIC: {} - {}".format(numeric, ", ".join(args))) if numeric == ERR_NICKNAMEINUSE: # Change Nick if in use newnick = "{0:s}_".format(args[1]) self.nick = newnick self.fire(NICK(newnick)) if numeric == RPL_WHOREPLY: print(args) user = (args[5], args[2], args[3]) user += (self.user_mngr.get_user_id(user),) print(user) elif numeric in (RPL_ENDOFMOTD, ERR_NOMOTD): self.fire(events.on_connect(self.network, self.port), "plugins") for chan in self.channels: self.fire(JOIN(chan)) # Used to test handlers to determine arguments @handler("test") def _gen_handler(self, *args, **kwargs): if args: for arg in args: self.logger.info("from args: {}".format(arg)) if kwargs: for key, value in kwargs: self.logger.info("from kwargs: {} == {}".format(key, value))
def enqueue_msg(self, target, message): if self.queue_timer: self.msg_queue.append((target, message)) else: self.fire(PRIVMSG(target, message)) self.queue_timer = Timer(1.0, Event.create("process_queue"), persist=True).register(self)
class StompClient(BaseComponent): """ Send and Receive messages from a STOMP queue """ channel = "stomp" def init(self, host, port, username=None, password=None, connect_timeout=3, connected_timeout=3, version=StompSpec.VERSION_1_2, accept_versions=["1.0", "1.1", "1.2"], heartbeats=(0, 0), ssl_context=None, use_ssl=True, key_file=None, cert_file=None, ca_certs=None, ssl_version=ssl.PROTOCOL_SSLv23, key_file_password=None, proxy_host=None, proxy_port=None, proxy_user=None, proxy_password=None, channel=channel): """ Initialize StompClient. Called after __init__ """ self.channel = channel if proxy_host: LOG.info("Connect to %s:%s through proxy %s:%d", host, port, proxy_host, proxy_port) else: LOG.info("Connect to %s:%s", host, port) if use_ssl and not ssl_context: ssl_params = dict(key_file=key_file, cert_file=cert_file, ca_certs=ca_certs, ssl_version=ssl_version, password=key_file_password) LOG.info("Request to use old-style socket wrapper: %s", ssl_params) ssl_context = ssl_params if use_ssl: uri = "ssl://%s:%s" % (host, port) else: uri = "tcp://%s:%s" % (host, port) # Configure failover options so it only tries to connect once self._stomp_server = "failover:(%s)?maxReconnectAttempts=1,startupMaxReconnectAttempts=1" % uri self._stomp_config = StompConfig(uri=self._stomp_server, sslContext=ssl_context, version=version, login=username, passcode=password) self._heartbeats = heartbeats self._accept_versions = accept_versions self._connect_timeout = connect_timeout self._connected_timeout = connected_timeout Stomp._transportFactory = EnhancedStompFrameTransport Stomp._transportFactory.proxy_host = proxy_host Stomp._transportFactory.proxy_port = proxy_port Stomp._transportFactory.proxy_user = proxy_user Stomp._transportFactory.proxy_password = proxy_password self._client = Stomp(self._stomp_config) self._subscribed = {} self.server_heartbeat = None self.client_heartbeat = None self.ALLOWANCE = 2 # multiplier for heartbeat timeouts @property def connected(self): if self._client.session: return self._client.session.state == StompSession.CONNECTED else: return False @property def subscribed(self): return self._subscribed.keys() @property def stomp_logger(self): return LOG_CATEGORY @handler("disconnect") def _disconnect(self, receipt=None): if self.connected: self._client.disconnect(receipt=receipt) self._client.close(flush=True) self.fire(disconnected(reconnect=False)) self._subscribed = {} return "disconnected" def start_heartbeats(self): LOG.info("Client HB: %s Server HB: %s", self._client.clientHeartBeat, self._client.serverHeartBeat) if self._client.clientHeartBeat: if self.client_heartbeat: # Timer already exists, just reset it self.client_heartbeat.reset() else: LOG.info("Client will send heartbeats to server") # Send heartbeats at 80% of agreed rate self.client_heartbeat = Timer((self._client.clientHeartBeat / 1000.0) * 0.8, client_heartbeat(), persist=True) self.client_heartbeat.register(self) else: LOG.info("No Client heartbeats will be sent") if self._client.serverHeartBeat: if self.server_heartbeat: # Timer already exists, just reset it self.server_heartbeat.reset() else: LOG.info("Requested heartbeats from server.") # Allow a grace period on server heartbeats self.server_heartbeat = Timer((self._client.serverHeartBeat / 1000.0) * self.ALLOWANCE, server_heartbeat(), persist=True) self.server_heartbeat.register(self) else: LOG.info("Expecting no heartbeats from Server") @handler("connect") def connect(self, event, host=None, *args, **kwargs): """ connect to Stomp server """ LOG.info("Connect to Stomp...") try: self._client.connect(heartBeats=self._heartbeats, host=host, versions=self._accept_versions, connectTimeout=self._connect_timeout, connectedTimeout=self._connected_timeout) LOG.info("State after Connection Attempt: %s", self._client.session.state) if self.connected: LOG.info("Connected to %s", self._stomp_server) self.fire(connected()) self.start_heartbeats() return "success" except StompConnectionError: LOG.debug(traceback.format_exc()) self.fire(connection_failed(self._stomp_server)) event.success = False return "fail" @handler("server_heartbeat") def check_server_heartbeat(self, event): """ Confirm that heartbeat from server hasn't timed out """ now = time.time() last = self._client.lastReceived or 0 if last: elapsed = now - last else: elapsed = -1 LOG.debug("Last received data %d seconds ago", elapsed) if ((self._client.serverHeartBeat / 1000.0) * self.ALLOWANCE + last) < now: LOG.error("Server heartbeat timeout. %d seconds since last heartbeat. Disconnecting.", elapsed) event.success = False self.fire(heartbeat_timeout()) if self.connected: self._client.disconnect() # TODO: Try to auto-reconnect? @handler("client_heartbeat") def send_heartbeat(self, event): if self.connected: LOG.debug("Sending heartbeat") try: self._client.beat() except StompConnectionError: event.success = False self.fire(disconnected()) @handler("generate_events") def generate_events(self, event): if not self.connected: return try: if self._client.canRead(1): frame = self._client.receiveFrame() LOG.debug("Recieved frame %s", frame) self.fire(message(frame)) except StompConnectionError: self.fire(disconnected()) @handler("send") def send(self, event, destination, body, headers=None, receipt=None): LOG.debug("send()") if not self.connected: LOG.error("Can't send when Stomp is disconnected") self.fire(on_stomp_error(None, Exception("Message send attempted with stomp disconnected"))) event.success = False return try: self._client.send(destination, body=body.encode('utf-8'), headers=headers, receipt=receipt) LOG.debug("Message sent") except StompConnectionError as err: event.success = False self.fire(disconnected()) except StompError as err: LOG.error("Error sending ack") event.success = False self.fire(on_stomp_error(None, err)) @handler("subscribe") def _subscribe(self, event, destination, ack=ACK_CLIENT_INDIVIDUAL): if ack not in ACK_MODES: raise ValueError("Invalid client ack mode specified") LOG.info("Subscribe to message destination %s", destination) try: # Set ID to match destination name for easy reference later frame, token = self._client.subscribe(destination, headers={StompSpec.ACK_HEADER: ack, 'id': destination}) self._subscribed[destination] = token except StompConnectionError as err: event.success = False self.fire(disconnected()) except StompError as err: event.success = False LOG.debug(traceback.format_exc()) self.fire(on_stomp_error(None, err)) @handler("unsubscribe") def _unsubscribe(self, event, destination): if destination not in self._subscribed: LOG.error("Unsubscribe Request Ignored. Not subscribed to %s", destination) return try: token = self._subscribed.pop(destination) frame = self._client.unsubscribe(token) LOG.debug("Unsubscribed: %s", frame) except StompConnectionError as err: event.success = False self.fire(disconnected()) except StompError as err: LOG.error("Error sending ack") event.success = False self.fire(on_stomp_error(frame, err)) @handler("message") def on_message(self, event, headers, message): LOG.info("Stomp message received") @handler("ack") def ack_frame(self, event, frame): LOG.debug("ack_frame()") try: self._client.ack(frame) LOG.debug("Ack Sent") except StompConnectionError as err: LOG.error("Error sending ack") event.success = False self.fire(disconnected()) except StompError as err: LOG.error("Error sending ack") event.success = False self.fire(on_stomp_error(frame, err)) def get_subscription(self, frame): """ Get subscription from frame """ LOG.info(self._subscribed) _, token = self._client.message(frame) return self._subscribed[token]
class ModbusTCPDevice(Component): MODBUS_PORT = 502 DEFAULT_INTERVAL = 60 * 15 PREFIX = 'XXXX' def __init__(self, ip): super(ModbusTCPDevice, self).__init__() self.sample_timer = None self.ip = ip self.sn = ip self.registers = [] self.conn = None self._set_channel() self.queued_time = time.time() self.time_d = 0 self.sample_pending = False self.asap = False def set_asap_sampling(self, flag): if self.sample_timer is None: return False self.sample_timer.persist = not flag self.asap = flag if flag: self.fire(sample(), self) else: self.sample_timer.reset(self.sample_timer.interval) def _set_channel(self): self.channel = self.__class__.__name__ + str(id(self)) def started(self, *args): self.conn = ModbusClient(host=self.ip[0], port=self.ip[1], auto_open=True) self.fire(sample(), self) self.sample_timer = Timer(self.DEFAULT_INTERVAL + random.uniform(0, 1), sample(), self, persist=True).register(self) return def update_interval(self, interval, stray=1): if self.sample_timer is not None: self.sample_timer.reset(interval + random.uniform(0, stray)) return True return False def sample_success(self, addr, regs): tab = prettytable.PrettyTable() # tab.field_names = [str(x) for x in xrange(0xf)] num_rows = (len(regs) / 0x10) + 1 for x in xrange(0x10): column = [stringify_reg([_]) for _ in regs[x::0x10]] column += [''] * (num_rows - len(column)) tab.add_column(str(x), column) logging.debug("Sample from %s address %s:\n%s", addr, self.sn, tab.get_string()) def sample(self): if self.sample_pending: logging.warn("%s already has a sample pending.", self.get_dev_id()) else: logging.debug("%s Spawning sample task", self.sn) self.queued_time = time.time() self.sample_pending = True self.fire(task(self._sample), "sample_worker") def _sample(self): logging.debug("Sampling from %s", self.sn) for t in self.registers: try: regs = self.conn.read_holding_registers(t[0], t[1]) except Exception as e: logging.error(e) else: if regs is None: logging.warn("%s sent empty sample", self.get_dev_id()) else: self.fire(sample_success(t[0], regs), self) self.time_d = time.time() - self.queued_time logging.debug("Sampling %s took %s", self.get_dev_id(), self.time_d) self.sample_pending = False if self.asap: logging.debug("%s firing ASAP sample", self.get_dev_id()) self.fire(sample(), self) if self.time_d > self.sample_timer.interval: logging.warn("Sampling %s took %s! (> %s)", self.get_dev_id(), self.time_d, self.sample_timer.interval) return def get_dev_id(self): return "{}-{}".format(self.PREFIX, self.sn)
class CameraManager(Component): """ Handles camera updates, subscriptions and broadcasts """ channel = "cam" def __init__(self, maxcams=16, *args): super(CameraManager, self).__init__(*args) self._cameras = {} self._subscribers = {} self._filming = True self._framecount = 0 self._frames = {} hfoslog("[CAM] Checking opencv for cameras.", lvl=debug) for cam in range(maxcams): video = opencv.VideoCapture(cam) if video.isOpened(): camera = {'uuid': str(uuid4()), 'name': 'Camera' + str(cam), 'cam': video } self._cameras[cam] = camera hfoslog("[CAM] Found camera [", cam, "]: ", camera) hfoslog("[CAM] Starting timer") self.timer = Timer(0.05, Event.create("rec"), persist=True).register(self) hfoslog("[CAM] Found cameras: ", self._cameras, lvl=debug) hfoslog("[CAM] Started") def rec(self): """Records a single snapshot""" try: self._snapshot() except Exception as e: hfoslog("[CAM] Timer error: ", e, type(e), lvl=error) def _snapshot(self): self._framecount += 1 try: for camid, cam in self._cameras.items(): if cam['uuid'] in self._subscribers: # hfoslog("[CAM] Taking input of ", cam) success, cvresult = cam['cam'].read() # hfoslog("[CAM] Result: ", cvresult) if success: campacketheader = {'component': 'camera' + str(camid), 'action': 'update', } if six.PY3: # noinspection PyArgumentList campacket = bytes(str(campacketheader), encoding="UTF8") + cvresult.tostring() else: campacket = bytes(str(campacketheader)) + cvresult.tostring() self._broadcast(campacket, cam['uuid']) else: hfoslog("[CAM] Failed to get an image.", success, cvresult) except Exception as e: hfoslog("[CAM] Error: ", e, type(e), lvl=error) if self._framecount % 100 == 0: hfoslog("[CAM] ", self._framecount, " frames taken.", lvl=debug) def toggleFilming(self): """Toggles the camera system recording state""" if self._filming: hfoslog("[CAM] Stopping operation") self._filming = False self.timer.stop() else: hfoslog("[CAM] Starting operation") self._filming = True self.timer.start() def _broadcast(self, camerapacket, camerauuid): try: for recipient in self._subscribers[camerauuid]: self.fireEvent(send(recipient, camerapacket, raw=True), "hfosweb") except Exception as e: hfoslog("[CAM] Failed broadcast: ", e, type(e), lvl=error) def _generatecameralist(self): try: result = {} for item in self._cameras.values(): result[item['name']] = item['uuid'] return result except Exception as e: hfoslog("[CAM] Error during list retrieval:", e, type(e), lvl=error) def _unsubscribe(self, clientuuid, camerauuid=None): # TODO: Verify everything and send a response if not camerauuid: for subscribers in self._subscribers.values(): if clientuuid in subscribers: subscribers.remove(clientuuid) hfoslog("[CAM] Subscription removed: ", clientuuid, lvl=debug) else: self._subscribers[camerauuid].remove(clientuuid) if len(self._subscribers[camerauuid]) == 0: del (self._subscribers[camerauuid]) hfoslog("[CAM] Subscription deleted: ", camerauuid, clientuuid) def client_disconnect(self, event): """ A client has disconnected, update possible subscriptions accordingly. :param event: """ hfoslog("[CAM] Removing disconnected client from subscriptions", lvl=debug) clientuuid = event.clientuuid self._unsubscribe(clientuuid) @handler("camerarequest", channel="hfosweb") def camerarequest(self, event): """ Handles new camera category requests :param event: CameraRequest with actions * subscribe * unsubscribe * update """ hfoslog("[CAM] Event: '%s'" % event.__dict__) try: try: action = event.action data = event.data clientuuid = event.client.uuid except Exception as e: raise ValueError("[CAM] Problem during event unpacking:", e, type(e)) if action == 'list': try: dblist = self._generatecameralist() self.fireEvent(send(clientuuid, {'component': 'camera', 'action': 'list', 'data': dblist}), "hfosweb") except Exception as e: hfoslog("[CAM] Listing error: ", e, type(e), lvl=error) return elif action == 'get': return elif action == 'subscribe': # TODO: Verify everything and send a response if data in self._subscribers: if clientuuid not in self._subscribers[data]: self._subscribers[data].append(clientuuid) else: self._subscribers[data] = [clientuuid] hfoslog("[CAM] Subscription registered: ", data, clientuuid) return elif action == 'unsubscribe': self._unsubscribe(clientuuid, data) return except Exception as e: hfoslog("[CAM] Global Error: '%s' %s" % (e, type(e)), lvl=error)
class Manager(ConfigurableComponent): """ Handles camera updates, subscriptions and broadcasts """ channel = "cam" def __init__(self, maxcams=16, *args): super(Manager, self).__init__("CAM", *args) self._cameras = {} self._subscribers = {} self._filming = True self._frame_count = 0 self._frames = {} if opencv is not None: self.log("Checking opencv for cameras.", lvl=debug) for cam in range(maxcams): video = opencv.VideoCapture(cam) if video.isOpened(): camera = {'uuid': str(uuid4()), 'name': 'Camera' + str(cam), 'cam': video } self._cameras[cam] = camera self.log("Found camera [", cam, "]: ", camera) if len(self._cameras) > 0: self.log("Starting timer") self.timer = Timer(0.05, Event.create("rec"), persist=True).register(self) self.log("Found cameras: ", self._cameras, lvl=debug) else: self.log("No opencv, no cameras.") self.log("Started") def rec(self): """Records a single snapshot""" try: self._snapshot() except Exception as e: self.log("Timer error: ", e, type(e), lvl=error) def _snapshot(self): try: for cam_id, cam in self._cameras.items(): if cam['uuid'] in self._subscribers: # self.log("Taking input of ", cam) success, cvresult = cam['cam'].read() # self.log("Result: ", cvresult) if success: cam_packet_header = { 'component': 'hfos.camera.manager' + str( cam_id), 'action': 'update' } if six.PY3: # noinspection PyArgumentList cam_packet = bytes(str(cam_packet_header), encoding="UTF8") + \ cvresult.tostring() else: cam_packet = bytes( str(cam_packet_header)) + cvresult.tostring() self._broadcast(cam_packet, cam['uuid']) else: self.log("Failed to get an image.", success, cvresult) self._frame_count += 1 if self._frame_count > 0 and self._frame_count % 100 == 0: self.log("", self._frame_count, " frames taken.", lvl=debug) except Exception as e: self.log("Error: ", e, type(e), lvl=error) def _toggle_filming(self): """Toggles the camera system recording state""" if self._filming: self.log("Stopping operation") self._filming = False self.timer.stop() else: self.log("Starting operation") self._filming = True self.timer.start() def _broadcast(self, camera_packet, camera_uuid): try: for recipient in self._subscribers[camera_uuid]: self.fireEvent(send(recipient, camera_packet, raw=True), "hfosweb") except Exception as e: self.log("Failed broadcast: ", e, type(e), lvl=error) def _generate_camera_list(self): try: result = {} for item in self._cameras.values(): result[item['name']] = item['uuid'] return result except Exception as e: self.log("Error during list retrieval:", e, type(e), lvl=error) def _unsubscribe(self, client_uuid, camera_uuid=None): # TODO: Verify everything and send a response if not camera_uuid: for subscribers in self._subscribers.values(): if client_uuid in subscribers: subscribers.remove(client_uuid) self.log("Subscription removed: ", client_uuid, lvl=debug) else: self._subscribers[camera_uuid].remove(client_uuid) if len(self._subscribers[camera_uuid]) == 0: del (self._subscribers[camera_uuid]) self.log("Subscription deleted: ", camera_uuid, client_uuid) def client_disconnect(self, event): """ A client has disconnected, update possible subscriptions accordingly. :param event: """ self.log("Removing disconnected client from subscriptions", lvl=debug) client_uuid = event.clientuuid self._unsubscribe(client_uuid) @handler(camera_list, channel='hfosweb') def camera_list(self, event): try: client_uuid = event.client.uuid db_list = self._generate_camera_list() self.fireEvent(send(client_uuid, { 'component': 'hfos.camera.manager', 'action': 'list', 'data': db_list }), "hfosweb") except Exception as e: self.log("Listing error: ", e, type(e), lvl=error) @handler(camera_subscribe, channel='hfosweb') def camera_subscribe(self, event): # TODO: Verify everything and send response try: data = event.data client_uuid = event.client.uuid if data in self._subscribers: if client_uuid not in self._subscribers[data]: self._subscribers[data].append(client_uuid) else: self._subscribers[data] = [client_uuid] self.log("Subscription registered: ", data, client_uuid) return except Exception as e: self.log("Subscription Error:", e, type(e), lvl=error) @handler(camera_unsubscribe, channel='hfosweb') def camera_unsubscribe(self, event): try: client_uuid = event.client.uuid data = event.data self._unsubscribe(client_uuid, data) return except Exception as e: self.log("Global Error: '%s' %s" % (e, type(e)), lvl=error)
def test_timer(app): timer = Timer(0.1, test(), "timer") timer.register(app) assert pytest.wait_for(app, "flag") app.reset()