Exemple #1
0
    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()
Exemple #3
0
	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
Exemple #4
0
    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")
Exemple #5
0
    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)
Exemple #7
0
    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)
Exemple #8
0
    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 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()
Exemple #10
0
    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")
Exemple #11
0
    def persistent(self, interval):
        timer = Timer(interval, single(), persist=True)
        timer.register(self)

        yield sleep(interval * 10)

        timer.unregister()
Exemple #12
0
 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)
Exemple #14
0
    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)
Exemple #15
0
 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)
Exemple #16
0
    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)
Exemple #17
0
 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
Exemple #18
0
    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)
Exemple #19
0
    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()
Exemple #21
0
    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"])
Exemple #22
0
 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]))
Exemple #23
0
 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
Exemple #24
0
    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")
Exemple #25
0
    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)
Exemple #26
0
 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()
Exemple #27
0
    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)
Exemple #28
0
    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)
Exemple #29
0
    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)
Exemple #31
0
    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")
Exemple #32
0
    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")
Exemple #33
0
 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)
Exemple #34
0
    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.")
Exemple #35
0
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'))
Exemple #36
0
 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)
Exemple #37
0
    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)
Exemple #40
0
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)
Exemple #42
0
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)
Exemple #43
0
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()