Example #1
0
    def offline_jianmo(self,
                       shujulujing,
                       moxinglujingqianzhui,
                       timestamp=0,
                       send=send):
        """Start building model for offline data

        Arguments:
            shujulujing {str} -- The offline data
            moxinglujingqianzhui {str} -- The prefix of model path, '.mat' will be added for real mpdel path

        Keyword Arguments:
            timestamp {int} -- [description] (default: {0})
            send {func} -- Sending method (default: {send})

        Returns:
            {int} -- 0 means success, 1 means fail
        """
        send(real_time_reply.OK())

        # The state should be 'Idle'
        if self.check_state('Idle', 'offline_jianmo', send=send) == 1:
            return 1

        # Check {shujulujing}
        if not os.path.exists(shujulujing):
            onerror(runtime_error.FileError, shujulujing, send=send)
            return 1

        # Try to mkdir and check of [moxinglujingqianzhui]
        try:
            mkdir(os.path.dirname(moxinglujingqianzhui))
        except:
            onerror(runtime_error.FileError, moxinglujingqianzhui, send=send)
            return 1

        # Workload
        moxinglujing = f'{moxinglujingqianzhui}.mat'

        # todo: Building a model
        self.latest_jianmo_send = send
        self.latest_shujulujing = shujulujing
        self.latest_moxinglujing = moxinglujing
        try:
            self.send_backend(
                dict(cmd='jianmo',
                     moxinglujing=moxinglujing,
                     shujulujing=shujulujing))
        except:
            logger.info('Fail on sending jianmo request to backend.')

        # If not USE_BACKEND,****************************************
        # use response_jianmo
        if not USE_BACKEND:
            self.response_jianmo(zhunquelv="1.0", timestamp=0, send=send)

        logger.debug('Building model.')
        logger.info('Building model.')

        return 0
Example #2
0
    def response_jianmo(self, zhunquelv, timestamp=0, send=send):
        moxinglujing = self.latest_moxinglujing
        shujulujing = self.latest_shujulujing

        self.latest_jianmo_send(
            dict(mode='Offline',
                 cmd='zhunquelv',
                 moxinglujing=moxinglujing,
                 zhunquelv=zhunquelv,
                 timestamp=time.time()))

        if not USE_BACKEND:
            print('-' * 80)
            print(moxinglujing)
            with open(moxinglujing, 'w') as f:
                f.writelines(['Fake model.'])

        logger.debug(
            f'Built model based on {shujulujing}, model has been saved in {moxinglujing}.'
        )
        logger.info(
            f'Built model based on {shujulujing}, model has been saved in {moxinglujing}.'
        )

        pass
Example #3
0
    def offline_jieshucaiji(self, timestamp=0, send=send):
        """Stop offline collection

        Keyword Arguments:
            timestamp {int} -- [description] (default: {0})
            send {func} -- Sending method (default: {send})

        Returns:
            {int} -- 0 means success, 1 means fail
        """
        send(real_time_reply.OK())

        # The state should be 'Offline'
        if self.check_state('Offline', 'offline_jieshucaiji', send=send) == 1:
            return 1

        # workload
        self.state = 'Idle'

        # Stop backend
        try:
            self.send_backend(dict(cmd='jieshucaiji'))
        except:
            logger.info('Fail to stop offline recording in backend.')
            traceback.print_exc()

        if not USE_BACKEND:
            with open(self._shujulujing, 'w') as f:
                f.writelines(['Fake data.'])

        logger.debug('Stopped offline collection.')
        return 0
Example #4
0
def send(msg):
    """ Virtual sending method,
    used when sending method is not provided.

    Arguments:
        msg {object} -- Message to be recorded.
    """
    logger.debug(f'Virtual send {msg}')
Example #5
0
    def state(self, s):
        """Safe switch STATE into [s]

        Arguments:
            s {str} -- The name of new state, one from ['Idle', 'Busy', 'Online', 'Offline']
        """
        assert (s in ['Idle', 'Busy', 'Online', 'Offline'])
        if not s == self._state:
            self._state = s
            logger.info(f'State switched to {s}.')
            logger.debug(f'State switched to {s}.')
Example #6
0
    def offline_kaishicaiji(self, shujulujingqianzhui, timestamp=0, send=send):
        """Start offline collection

        Arguments:
            shujulujingqianzhui {str} -- The prefix of data path, '.cnt' will be added for real data path

        Keyword Arguments:
            timestamp {int} -- [description] (default: {0})
            send {func} -- Sending method (default: {send})

        Returns:
            {int} -- 0 for success, 1 for fail
        """
        # Send OK means I has got everything in need,
        # but not guartee that all the things are correct,
        # if incorrect, I will reply Error in further
        send(real_time_reply.OK())

        # The state should be 'Idle'
        self.force_Idle()
        if self.check_state('Idle', 'offline_kaishicaiji', send=send) == 1:
            return 1

        # Try to mkdir and check of [shujulujingqianzhui] dir
        try:
            mkdir(os.path.dirname(shujulujingqianzhui))
        except:
            onerror(runtime_error.FileError, shujulujingqianzhui, send=send)
            return 1

        # Workload
        self.get_ready(state='Offline')
        path = f'{shujulujingqianzhui}.mat'

        if not USE_BACKEND:
            self._shujulujing = path

        try:
            self.send_backend(
                dict(cmd='kaishicaiji', mat_path=path, model_path='[empty]'))
        except:
            logger.info('Fail to start offline recording in backend.')
            traceback.print_exc()

        # Start self.record function as separate daemon threading
        # t = threading.Thread(target=self.record, args=(path,))
        # t.setDaemon(True)
        # t.start()

        logger.debug('Started offline collection.')
        return 0
Example #7
0
    def keepalive(self, timestamp=0, send=send):
        """Answer keep-alive package

        Keyword Arguments:
            timestamp {int} -- [description] (default: {0})
            send {func} -- Sending method (default: {send})

        Returns:
            {int} -- 0 means success, 1 means fail
        """
        # Reply keep alive package
        send(real_time_reply.KeepAlive())

        logger.debug(f'Responded to KeepAlive package.')
        return 0
Example #8
0
    def deal(self, D):
        """Deal with incoming message

        Arguments:
            D {dict} -- Parsed message dictionary
        """
        # Make sure D is legal,
        # send ParseError if illegal
        # D is dict
        if not isinstance(D, dict):
            self.send(real_time_reply.ParseError())
            logger.error(f'{D} is not dict')
            return 1

        logger.debug(f'Dealing with {D}')

        # D contains timestamp
        if 'timestamp' not in D:
            self.send(real_time_reply.ParseError())
            logger.error(f'{D} contains no timestamp')
            return 1

        # Record Delay
        logger.debug('Delay is {}'.format(delay(D['timestamp'])))

        # D contains 'mode', ['cmd'], and worker can deal with them
        # D contains 'mode'
        if 'mode' not in D:
            self.send(real_time_reply.ParseError())
            logger.error(f'{D} contains no mode')
            return 1

        # Deal with 'cmd' if it exists
        if 'cmd' in D:
            workload = '{mode}_{cmd}'.format(**D).lower()
        else:
            workload = '{mode}'.format(**D).lower()

        # Worker can deal with them
        if not hasattr(worker, workload):
            self.send(real_time_reply.ParseError())
            logger.error(f'{D} triggers no workload')
            return 1

        # Get ride of 'mode' and ['cmd']
        D.pop('mode')
        D.pop('cmd', None)

        # Operate
        logger.debug(f'Workload starts {workload}')
        try:
            eval(f'worker.{workload}(**D, send=self.send)')
            return 0
        except Exception as e:
            logger.error(f'Something went wrong in workload {workload}')
            logger.debug(traceback.format_exc())
            self.send(runtime_error.UnknownError(detail=e.__str__()))
            return 1
Example #9
0
def onerror(error, detail, send=send):
    """ Handle runtime errors,
    logging and send RuntimeError,
    normally THIS should be followed by return 1.

    Arguments:
        error {RuntimeError func} -- Method for RuntimeError instance
        detail {object} -- Detail of the error.
        send {func} -- Send function to be used for Error report. (default: {send})
    """
    logger.error(detail)
    # Load [detail] into [error]
    errormsg = error(detail)
    # Send [errormsg]
    send(errormsg)
    logger.debug(f'Sent RuntimeError: {errormsg}')
Example #10
0
    def send(self, msg, encoding='utf-8'):
        """Send [msg] to connected TCP Client

        Arguments:
            msg {str} -- [description]
        """
        # Dumps dict
        if isinstance(msg, dict):
            msg = json.dumps(msg, ensure_ascii=False).encode(encoding)

        # Encode str
        if isinstance(msg, str):
            msg = msg.encode(encoding)

        # Send
        self.client.sendall(msg)
        logger.info(f'Sent {msg} to {self.address}')
        logger.debug(f'Sent {msg} to {self.address}')
Example #11
0
def mkdir(path):
    """Recursive (safe) mkdir function,
    use 1: Create [path],
    use 2: Check [path] is an already existing dir

    Arguments:
        path {str} -- Path to be created, it should be a legal dir path.
    """
    # Mkdir if not exists
    if not os.path.exists(path):
        s = os.path.split(path)
        # Recursive create parent
        if s[0]:
            mkdir(s[0])
        # Mkdir child
        os.mkdir(path)
        logger.debug(f'Created {path}')
    # Make sure path is a folder
    assert (os.path.isdir(path))
Example #12
0
    def force_Idle(self):
        """Force State to Idle, used for kaishicaiji by-force.
        """
        if self.state == 'Idle':
            return 0

        msg = f'Current state is {self.state}, setting it to Idle by-force.'
        logger.info(msg)
        logger.debug(msg)

        # Stop backend
        logger.debug('Send jieshucaiji to backend.')
        try:
            self.send_backend(dict(cmd='jieshucaiji'))
        except:
            logger.info('Fail to stop offline recording in backend.')
            traceback.print_exc()

        # workload
        self.state = 'Idle'
Example #13
0
    def response_query(self, gujibiaoqian, timestamp=0, send=send):
        self.latest_query_send(
            dict(mode='QueryReply',
                 gujibiaoqian=gujibiaoqian,
                 timestamp=time.time()))

        zhenshibiaoqian = self.latest_zhenshibiaoqian
        if all([gujibiaoqian == '1', zhenshibiaoqian == '1']):
            self.send_UI(
                dict(mode='Online', cmd='kaishiyundong',
                     timestamp=time.time()))

        self.labels.append((gujibiaoqian, zhenshibiaoqian))
        logger.info(
            f'Estimated label: {gujibiaoqian}, True label: {zhenshibiaoqian}')
        logger.debug(
            f'Estimated label: {gujibiaoqian}, True label: {zhenshibiaoqian}')
        logger.debug(f'Labels is {self.labels}')

        pass
Example #14
0
    def online_jieshucaiji(self, timestamp=0, send=send):
        """Stop online collection

        Keyword Arguments:
            timestamp {int} -- [description] (default: {0})
            send {func} -- Sending method. (default: {send})

        Returns:
            {int} -- 0 for success, 1 for fail
        """
        send(real_time_reply.OK())

        # The state should be 'Online'
        if self.check_state('Online', 'online_jieshucaiji', send=send) == 1:
            return 1

        # Workload

        # Stop backend
        try:
            self.send_backend(dict(cmd='jieshucaiji'))
        except:
            logger.info('Fail to stop offline recording in backend.')
            traceback.print_exc()

        if not USE_BACKEND:
            with open(self._shujulujing, 'w') as f:
                f.writelines(['Fake online data.'])

        # Calculate accuracy
        try:
            zhunquelv = self.accuracy()
            logger.debug(f'Accuracy is {zhunquelv}, labels are {self.labels}.')
        except:
            logger.debug(
                f'Accuracy can not be calculated, labels are {self.labels}')
            raise ValueError(
                f'Accuracy can not be calculated, labels are {self.labels}')

        # Send accuracy back to UI as remembered
        send(
            dict(
                mode='Online',
                cmd='zhunquelv',
                zhunquelv=str(zhunquelv),  # Covert accuracy into {str}
                moxinglujing=self.moxinglujing,
                shujulujing=self.shujulujing,
                timestamp=time.time()))
        self.state = 'Idle'

        logger.debug('Stopped online collection.')
        return 0
Example #15
0
    def listening(self):
        """ Listen and handling incoming message """
        while True:
            try:
                # Get data
                data = self.client.recv(BUF_SIZE)
                logger.info(f'Received {data}, from {self.address}')
                logger.debug(
                    '{dash} New data received {dash}'.format(dash='-' * 8))
                logger.debug(f'Received {data}, from {self.address}')

                # If empty package received, it means the client to be closed.
                assert (not data == b'')

                # Parse data using JSON format,
                # Decode data
                try:
                    decoded_data = data.decode('utf-8')
                except:
                    logger.info(f'{data} can not be decoded.')
                    logger.debug(f'{data} can not be decoded.')
                    continue

                # send ParseError if parsing is failed
                try:
                    D = json.loads(decoded_data)
                except:
                    logger.debug(
                        f'{decoded_data} can not be loaded by JSON, try linked expection.'
                    )
                    try:
                        split = decoded_data.split('}{')

                        D = list()
                        for s in split:
                            if not s.startswith('{'):
                                s = '{' + s
                            if not s.endswith('}'):
                                s = s + '}'
                            D.append(json.loads(s))
                        logger.debug(f'Link exception success: {D}.')
                    except:
                        logger.error(
                            f'{decoded_data} can not be loaded by JSON')
                        logger.error('{}'.format(traceback.format_exc()))
                        self.send(
                            real_time_reply.ParseError(detail=decoded_data))
                        continue
                # print(D)

                # Deal with D
                if isinstance(D, list):
                    for d in D:
                        self.deal(d)
                else:
                    self.deal(D)

            except Exception:
                traceback.print_exc()
                logger.debug(traceback.format_exc())
                # Close the client
                self.client.close()
                # Stop listening
                break

        # Run onclose function
        self.onclose()
        logger.info(f'Connection closed {self.client}.')
Example #16
0
    def online_kaishicaiji(self,
                           moxinglujing,
                           shujulujingqianzhui,
                           timestamp=0,
                           send=send):
        """Start Online collection

        Arguments:
            moxinglujing {str} -- The path of model, it should be an existing path
            shujulujingqianzhui {str} -- The prefix of data path, '.cnt' will be added in real data path

        Keyword Arguments:
            timestamp {int} -- [description] (default: {0})
            send {func} -- Sending method (default: {send})

        Returns:
            {int} -- 0 for success, 1 for fail
        """
        send(real_time_reply.OK())

        # Check moxinglujing
        if not os.path.exists(os.path.dirname(moxinglujing)):
            onerror(runtime_error.FileError, moxinglujing, send=send)
            return 1

        # Try to mkdir and check of {shujulujingqianzhui}
        try:
            mkdir(os.path.dirname(shujulujingqianzhui))
        except:
            onerror(runtime_error.FileError, shujulujingqianzhui, send=send)
            return 1

        # The state should be 'Idle'
        self.force_Idle()
        if self.check_state('Idle', 'online_kaishicaiji', send=send) == 1:
            return 1

        # Workload
        path = f'{shujulujingqianzhui}.mat'

        if not USE_BACKEND:
            self._shujulujing = path

        # Remember Send-to-UI method,
        # as Start online collection can only be triggered by UI.
        self.get_ready(state='Online',
                       moxinglujing=moxinglujing,
                       shujulujing=path,
                       send_UI=send)

        try:
            self.send_backend(
                dict(cmd='kaishicaiji', mat_path=path,
                     model_path=moxinglujing))
        except:
            logger.info('Fail to start online recording in backend.')
            traceback.print_exc()

        # Start daemon thread for data collection and start it
        # t = threading.Thread(target=self.record, args=(path, moxinglujing))
        # t.setDaemon(True)
        # t.start()

        logger.debug('Started online collection.')
        return 0