Пример #1
0
        def __init__(self, framer, *args, **kwargs):
            ''' Setup the client and start listening on the serial port

            :param factory: The factory to build clients with
            '''
            self.decoder = ClientDecoder()
            proto_cls = kwargs.pop("proto_cls", None)
            proto = SerialClientFactory(framer, proto_cls).buildProtocol()
            SerialPort.__init__(self, proto, *args, **kwargs)
Пример #2
0
        def __init__(self, framer, *args, **kwargs):
            ''' Setup the client and start listening on the serial port

            :param factory: The factory to build clients with
            '''
            self.decoder = ClientDecoder()
            proto_cls = kwargs.pop("proto_cls", None)
            proto = SerialClientFactory(framer, proto_cls).buildProtocol()
            SerialPort.__init__(self, proto, *args, **kwargs)
class BioharnessProtocol(LineReceiver):
    message_ids = {
        "ecg": 0x16,
        "breathing": 0x15,
        "acceleration": 0x1E,
        "rr": 0x19,
        "summary": 0xBD,
        "life_sign": 0xA4,
    }

    stream_states = {"ON": 1, "OFF": 0}

    columns_of_streams = {
        "summary": SummaryMessage._fields,
        "breathing": SignalSample._fields,
        "ecg": SignalSample._fields,
        "rr": SignalSample._fields,
        "acceleration": AccelerationSignalSample._fields,
    }

    def __init__(self, processing_proxy, port, reactor):
        self.rr_buffer = deque(maxlen=180)
        self.processing_proxy = processing_proxy
        self.port = port
        self.reactor = reactor
        self.serial = None
        self.realtimeVisWave = RealtimeVis()
        # very slow, discarded
        # self.realtimeVisRate = RealtimeVis()
        self.count = 0

    def send_device_command(self, message_id, payload):
        message_frame = create_message_frame(message_id, payload)
        logging.info(
            "Bioharness - sending a command to the device: msg_id : %s, Payload : %s"
            % (message_id, payload))
        self.transport.write(message_frame)

    def set_stream_state(self, stream_id, state):
        self.send_device_command(self.message_ids[stream_id],
                                 [self.stream_states[state]])

    def disable_lifesign_timeout(self):
        self.send_device_command(self.message_ids["life_sign"], [0, 0, 0, 0])

    def set_summary_packet_transmit_interval_to_one_second(self):
        self.send_device_command(self.message_ids["summary"], [1, 0])

    def send_initialization_commands(self):
        self.set_stream_state("ecg", "ON")
        self.set_stream_state("breathing", "ON")
        self.set_stream_state("acceleration", "OFF")
        self.set_stream_state("rr", "ON")
        self.disable_lifesign_timeout()
        self.set_summary_packet_transmit_interval_to_one_second()

    def default_signal_waveform_handler(self, signal_packet, start_new_stream):
        samples_iterator = SignalPacketIterator(
            signal_packet).iterate_timed_samples()
        bb_buffer = []
        for signal_sample in samples_iterator:
            print signal_sample.type
            self.logger_of_stream[signal_sample.type].write_tuple_to_log_file(
                signal_sample)
            # send data for processing
            if signal_sample.type == "breathing":
                # pass
                # self.count += 1
                bb_buffer.append(float(signal_sample.sample))
            if signal_sample.type == 'rr':
                self.rr_buffer.append(signal_sample.sample)
                if len(self.rr_buffer) == self.rr_buffer.maxlen:
                    self.send_data_for_processing("rr_buffer",
                                                  list(self.rr_buffer),
                                                  signal_sample.timestamp)
                    for _i in range(0, 18):
                        self.rr_buffer.popleft()
        self.realtimeVisWave.animate(bb_buffer)

    def signal_waveform_handler(self, signal_packet, start_new_stream):
        samples_iterator = SignalPacketIterator(
            signal_packet).iterate_timed_samples()
        bb_buffer = []
        ecg_buffer = []
        this_SDNN = 0
        for signal_sample in samples_iterator:
            self.logger_of_stream[signal_sample.type].write_tuple_to_log_file(
                signal_sample)
            # send data for processing
            if signal_sample.type == "breathing":
                # pass
                # self.count += 1
                bb_buffer.append(float(signal_sample.sample))
            # elif signal_sample.type == 'rr':
            #     self.rr_buffer.append(signal_sample.sample)
            #     if len(self.rr_buffer) == self.rr_buffer.maxlen:
            #         self.send_data_for_processing("rr_buffer", list(self.rr_buffer), signal_sample.timestamp)
            #         rr_df = pd.Series(np.array(self.rr_buffer))
            #         rr_df[rr_df.diff().abs() == 0] = np.nan
            #         std = rr_df.dropna().std()  # drop outliers
            #         rr_df[rr_df > 5 * std] = np.nan
            #         rr_df = rr_df.dropna()
            #         try:
            #             rr_df = rr_df.abs().interpolate(method='cubic')
            #         except ValueError:
            #             logging.warn("Processing - Could not interpolate rr data.")
            #             return None
            #         this_SDNN = rr_df.std()
            #         for _i in range(0,18):
            #             self.rr_buffer.popleft()
            # elif signal_sample.type == "ecg":
            #     ecg_buffer.append(signal_sample.sample)
        self.realtimeVisWave.animate(bb_buffer, True)

    def display_status_flags(self, summary_packet):
        if (summary_packet.heart_rate_unreliable
                or summary_packet.respiration_rate_unreliable) or (
                    summary_packet.hrv_unreliable
                    or summary_packet.button_pressed):
            logging.warn(
                "Bioharness - Heart Rate:%s ; Breathing Rate:%s ; HRV:%s" %
                ((not summary_packet.heart_rate_unreliable),
                 (not summary_packet.respiration_rate_unreliable),
                 (not summary_packet.hrv_unreliable)))

    def default_event_callback(self, summary_packet):
        self.display_status_flags(summary_packet)
        self.logger_of_stream["summary"].write_tuple_to_log_file(
            summary_packet)

        # send data for processing
        self.send_data_for_processing("respiration_rate",
                                      [summary_packet.respiration_rate],
                                      summary_packet.timestamp)

    def event_callback(self, summary_packet):
        self.default_event_callback(summary_packet)
        summary_str = ",".join([str(value) for value in summary_packet])
        # Visualize the respiration rate
        # print float(str(summary_packet[3]))
        # self.realtimeVisRate.animate(float(str(summary_packet[3])))

    def send_data_for_processing(self, type, value, timestamp):
        data = {"type": type}
        data["timestamp"] = timestamp
        data["value"] = value
        self.processing_proxy.notifyAll(data)

    def set_event_callbacks(self, callbacks=None):
        if callbacks is None: callbacks = [self.event_callback]
        self.event_callbacks = callbacks

    def set_waveform_callbacks(self, callbacks=None):
        if callbacks is None: callbacks = [self.signal_waveform_handler]
        self.waveform_callbacks = callbacks

    def set_data_loggers(self, logger_of_stream):
        self.logger_of_stream = logger_of_stream

    def connectionMade(self):
        # Setting the protocol to handle raw data rather than just lines
        self.setRawMode()

        # Sending commands to enable relevant streams and summary messages
        self.send_initialization_commands()

        self.signal_packet_handler_bh = BioHarnessPacketHandler(
            self.waveform_callbacks, self.event_callbacks)
        self.payload_parser = MessagePayloadParser(
            [self.signal_packet_handler_bh.handle_packet])
        self.message_parser = MessageFrameParser(
            self.payload_parser.handle_message)

    def rawDataReceived(self, data):
        if not data: return

        for byte in data:
            self.message_parser.parse_data(byte)

    def set_serial(self, serial):
        self.serial = serial

    def connectionLost(self, reason):
        logging.error("Bioharness - Lost connection (%s)" % reason)
        logging.info("Bioharness - Reconnecting in 5 seconds...")
        self.serial._serial.close()
        self.retry = self.reactor.callLater(5, self.reconnect)

    def reconnect(self):
        try:
            if self.serial is None:
                self.serial = SerialPort(self,
                                         self.port,
                                         self.reactor,
                                         baudrate=115200)
            else:
                self.serial.__init__(self,
                                     self.port,
                                     self.reactor,
                                     baudrate=115200)
            logging.info("Bioharness - Reconnected")

        except:
            logging.error("Bioharness - Error opening serial port %s (%s)" %
                          (self.port, sys.exc_info()[1]))
            logging.info("Bioharness - Reconnecting in 5 seconds...")
            self.retry = self.reactor.callLater(5, self.reconnect)
class BioharnessProtocol(LineReceiver):
    message_ids = {
        "ecg": 0x16,
        "breathing": 0x15,
        "acceleration": 0x1E,
        "rr": 0x19,
        "summary": 0xBD,
        "life_sign": 0xA4,
    }

    stream_states = {"ON": 1, "OFF": 0}

    columns_of_streams = {
        "summary": SummaryMessage._fields,
        "breathing": SignalSample._fields,
        "ecg": SignalSample._fields,
        "rr": SignalSample._fields,
        "acceleration": AccelerationSignalSample._fields,
    }

    def __init__(self, processing_proxy, port, reactor):
        self.rr_buffer = deque(maxlen=1024)
        self.processing_proxy = processing_proxy
        self.port = port
        self.reactor = reactor
        self.serial = None

    def send_device_command(self, message_id, payload):
        message_frame = create_message_frame(message_id, payload)
        logging.info(
            "Bioharness - sending a command to the device: msg_id : %s, Payload : %s"
            % (message_id, payload))
        self.transport.write(message_frame)

    def set_stream_state(self, stream_id, state):
        self.send_device_command(self.message_ids[stream_id],
                                 [self.stream_states[state]])

    def disable_lifesign_timeout(self):
        self.send_device_command(self.message_ids["life_sign"], [0, 0, 0, 0])

    def set_summary_packet_transmit_interval_to_one_second(self):
        self.send_device_command(self.message_ids["summary"], [1, 0])

    def send_initialization_commands(self):
        self.set_stream_state("ecg", "ON")
        self.set_stream_state("breathing", "ON")
        self.set_stream_state("acceleration", "OFF")
        self.set_stream_state("rr", "ON")
        self.disable_lifesign_timeout()
        self.set_summary_packet_transmit_interval_to_one_second()

    def default_signal_waveform_handler(self, signal_packet, start_new_stream):
        samples_iterator = SignalPacketIterator(
            signal_packet).iterate_timed_samples()
        for signal_sample in samples_iterator:
            self.logger_of_stream[signal_sample.type].write_tuple_to_log_file(
                signal_sample)

            # send data for processing
            if signal_sample.type == 'rr':
                self.rr_buffer.append(signal_sample.sample)
                if len(self.rr_buffer) == self.rr_buffer.maxlen:
                    self.send_data_for_processing("rr_buffer",
                                                  list(self.rr_buffer),
                                                  signal_sample.timestamp)

                    #empty buffer partially
                    for _i in range(0, 18):  #self.rr_buffer.maxlen/12):
                        self.rr_buffer.popleft()

    def display_status_flags(self, summary_packet):
        if (summary_packet.heart_rate_unreliable
                or summary_packet.respiration_rate_unreliable) or (
                    summary_packet.hrv_unreliable
                    or summary_packet.button_pressed):
            logging.warn(
                "Bioharness - Heart Rate:%s ; Breathing Rate:%s ; HRV:%s" %
                ((not summary_packet.heart_rate_unreliable),
                 (not summary_packet.respiration_rate_unreliable),
                 (not summary_packet.hrv_unreliable)))

    def default_event_callback(self, summary_packet):
        self.display_status_flags(summary_packet)
        self.logger_of_stream["summary"].write_tuple_to_log_file(
            summary_packet)

        # send data for processing
        self.send_data_for_processing("respiration_rate",
                                      [summary_packet.respiration_rate],
                                      summary_packet.timestamp)

    def send_data_for_processing(self, type, value, timestamp):
        data = {"type": type}
        data["timestamp"] = timestamp
        data["value"] = value
        self.processing_proxy.notifyAll(data)

    def set_event_callbacks(self, callbacks=None):
        if callbacks is None: callbacks = [self.default_event_callback]
        self.event_callbacks = callbacks

    def set_waveform_callbacks(self, callbacks=None):
        if callbacks is None:
            callbacks = [self.default_signal_waveform_handler]
        self.waveform_callbacks = callbacks

    def set_data_loggers(self, logger_of_stream):
        self.logger_of_stream = logger_of_stream

    def connectionMade(self):
        # Setting the protocol to handle raw data rather than just lines
        self.setRawMode()

        # Sending commands to enable relevant streams and summary messages
        self.send_initialization_commands()

        self.signal_packet_handler_bh = BioHarnessPacketHandler(
            self.waveform_callbacks, self.event_callbacks)
        self.payload_parser = MessagePayloadParser(
            [self.signal_packet_handler_bh.handle_packet])
        self.message_parser = MessageFrameParser(
            self.payload_parser.handle_message)

    def rawDataReceived(self, data):
        if not data: return

        for byte in data:
            self.message_parser.parse_data(byte)

    def set_serial(self, serial):
        self.serial = serial

    def connectionLost(self, reason):
        logging.error("Bioharness - Lost connection (%s)" % reason)
        logging.info("Bioharness - Reconnecting in 5 seconds...")
        self.serial._serial.close()
        self.retry = self.reactor.callLater(5, self.reconnect)

    def reconnect(self):
        try:
            if self.serial is None:
                self.serial = SerialPort(self,
                                         self.port,
                                         self.reactor,
                                         baudrate=115200)
            else:
                self.serial.__init__(self,
                                     self.port,
                                     self.reactor,
                                     baudrate=115200)
            logging.info("Bioharness - Reconnected")

        except:
            logging.error("Bioharness - Error opening serial port %s (%s)" %
                          (self.port, sys.exc_info()[1]))
            logging.info("Bioharness - Reconnecting in 5 seconds...")
            self.retry = self.reactor.callLater(5, self.reconnect)