Esempio n. 1
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': 'isomer.camera.manager' + str(cam_id),
                            'action': 'update'
                        }
                        # TODO: Kick out 2.x compat
                        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),
                               "isomer-web")
        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='isomer-web')
    def camera_list(self, event):
        try:
            client_uuid = event.client.uuid
            db_list = self._generate_camera_list()
            self.fireEvent(
                send(
                    client_uuid, {
                        'component': 'isomer.camera.manager',
                        'action': 'list',
                        'data': db_list
                    }), "isomer-web")
        except Exception as e:
            self.log("Listing error: ", e, type(e), lvl=error)

    @handler(camera_subscribe, channel='isomer-web')
    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='isomer-web')
    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)
Esempio n. 2
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)
Esempio n. 3
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)
Esempio n. 4
0
File: manager.py Progetto: ri0t/hfos
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)