예제 #1
0
    def _update(self):
        logger.debug("Update...")

        # noinspection PyBroadException
        try:
            entry = self._node_monitor.get(self._target_node_id)
        except Exception:
            self.setEnabled(False)
            return

        self.setEnabled(True)

        if entry.status:  # Status should be always available...
            self._mode_health_uptime[0].set(uavcan.value_to_constant_name(entry.status, "mode", keep_literal=True))
            self._mode_health_uptime[1].set(uavcan.value_to_constant_name(entry.status, "health", keep_literal=True))
            self._mode_health_uptime[2].set(datetime.timedelta(days=0, seconds=entry.status.uptime_sec))

            self._mode_health_uptime[0].set_background_color(node_mode_to_color(entry.status.mode))
            self._mode_health_uptime[1].set_background_color(node_health_to_color(entry.status.health))

            vssc = entry.status.vendor_specific_status_code
            self._vendor_status[0].set(vssc)
            self._vendor_status[1].set("0x%04x" % vssc)
            self._vendor_status[2].set(
                "0b" + bin((vssc >> 8) & 0xFF)[2:].zfill(8) + "_" + bin(vssc & 0xFF)[2:].zfill(8)
            )

        if entry.info:
            inf = entry.info
            self._node_id_name[1].set(inf.name.decode())

            swver = "%d.%d" % (inf.software_version.major, inf.software_version.minor)
            if inf.software_version.optional_field_flags & inf.software_version.OPTIONAL_FIELD_FLAG_VCS_COMMIT:
                swver += ".%08x" % inf.software_version.vcs_commit
            self._sw_version_crc[0].set(swver)

            if inf.software_version.optional_field_flags & inf.software_version.OPTIONAL_FIELD_FLAG_IMAGE_CRC:
                self._sw_version_crc[1].set("0x%016x" % inf.software_version.image_crc)
            else:
                self._sw_version_crc[1].clear()

            self._hw_version_uid[0].set("%d.%d" % (inf.hardware_version.major, inf.hardware_version.minor))

            if not all([x == 0 for x in inf.hardware_version.unique_id]):
                self._hw_version_uid[1].set(" ".join(["%02x" % x for x in inf.hardware_version.unique_id]))
            else:
                self._hw_version_uid[1].clear()

            if len(inf.hardware_version.certificate_of_authenticity):
                self._cert_of_auth.set(" ".join(["%02x" % x for x in inf.hardware_version.certificate_of_authenticity]))
            else:
                self._cert_of_auth.clear()
        else:
            self._node_id_name[1].disable()
            self._sw_version_crc[0].disable()
            self._sw_version_crc[1].disable()
            self._hw_version_uid[0].disable()
            self._hw_version_uid[1].disable()
            self._cert_of_auth.disable()
예제 #2
0
    def _update(self):
        logger.debug('Update...')

        # noinspection PyBroadException
        try:
            entry = self._node_monitor.get(self._target_node_id)
        except Exception:
            self.setEnabled(False)
            return

        self.setEnabled(True)

        if entry.status:        # Status should be always available...
            self._mode_health_uptime[0].set(uavcan.value_to_constant_name(entry.status, 'mode', keep_literal=True))
            self._mode_health_uptime[1].set(uavcan.value_to_constant_name(entry.status, 'health', keep_literal=True))
            self._mode_health_uptime[2].set(datetime.timedelta(days=0, seconds=entry.status.uptime_sec))

            self._mode_health_uptime[0].set_background_color(node_mode_to_color(entry.status.mode))
            self._mode_health_uptime[1].set_background_color(node_health_to_color(entry.status.health))

            vssc = entry.status.vendor_specific_status_code
            self._vendor_status[0].set(vssc)
            self._vendor_status[1].set('0x%04x' % vssc)
            self._vendor_status[2].set('0b' + bin((vssc >> 8) & 0xFF)[2:].zfill(8) +
                                       '_' + bin(vssc & 0xFF)[2:].zfill(8))

        if entry.info:
            inf = entry.info
            self._node_id_name[1].set(inf.name.decode())

            swver = '%d.%d' % (inf.software_version.major, inf.software_version.minor)
            if inf.software_version.optional_field_flags & inf.software_version.OPTIONAL_FIELD_FLAG_VCS_COMMIT:
                swver += '.%08x' % inf.software_version.vcs_commit
            self._sw_version_crc[0].set(swver)

            if inf.software_version.optional_field_flags & inf.software_version.OPTIONAL_FIELD_FLAG_IMAGE_CRC:
                self._sw_version_crc[1].set('0x%016x' % inf.software_version.image_crc)
            else:
                self._sw_version_crc[1].clear()

            self._hw_version_uid[0].set('%d.%d' % (inf.hardware_version.major, inf.hardware_version.minor))

            if not all([x == 0 for x in inf.hardware_version.unique_id]):
                self._hw_version_uid[1].set(' '.join(['%02x' % x for x in inf.hardware_version.unique_id]))
            else:
                self._hw_version_uid[1].clear()

            if len(inf.hardware_version.certificate_of_authenticity):
                self._cert_of_auth.set(' '.join(['%02x' % x for x in inf.hardware_version.certificate_of_authenticity]))
            else:
                self._cert_of_auth.clear()
        else:
            self._node_id_name[1].disable()
            self._sw_version_crc[0].disable()
            self._sw_version_crc[1].disable()
            self._hw_version_uid[0].disable()
            self._hw_version_uid[1].disable()
            self._cert_of_auth.disable()
    def _do_execute_opcode(self, opcode):
        request = uavcan.protocol.param.ExecuteOpcode.Request(opcode=opcode)
        opcode_str = uavcan.value_to_constant_name(request,
                                                   'opcode',
                                                   keep_literal=True)

        if not request_confirmation(
                'Confirm opcode execution',
                'Do you really want to execute param opcode %s?' % opcode_str,
                self):
            return

        def callback(e):
            if e is None:
                self.window().show_message(
                    'Opcode execution response for %s has timed out',
                    opcode_str)
            else:
                self.window().show_message(
                    'Opcode execution response for %s: %s', opcode_str,
                    e.response)

        try:
            self._node.request(request,
                               self._target_node_id,
                               callback,
                               priority=REQUEST_PRIORITY)
            self.window().show_message('Param opcode %s requested', opcode_str)
        except Exception as ex:
            show_error('Node error',
                       'Could not send param opcode execution request', ex,
                       self)
예제 #4
0
class LogMessageDisplayWidget(QGroupBox):
    COLUMNS = [
        BasicTable.Column('NID', lambda e: e.transfer.source_node_id),
        BasicTable.Column('Local Time',
                          lambda e: datetime.datetime.fromtimestamp(
                              e.transfer.ts_real).strftime('%H:%M:%S.%f')[:-3],
                          searchable=False),
        BasicTable.Column(
            'Level', lambda e:
            (uavcan.value_to_constant_name(e.message.level, 'value'),
             log_level_to_color(e.message.level))),
        BasicTable.Column('Source', lambda e: e.message.source),
        BasicTable.Column('Text',
                          lambda e: e.message.text,
                          resize_mode=QHeaderView.Stretch),
    ]

    def __init__(self, parent, node):
        super(LogMessageDisplayWidget, self).__init__(parent)
        self.setTitle('Log messages (uavcan.protocol.debug.LogMessage)')

        self._log_widget = RealtimeLogWidget(self,
                                             columns=self.COLUMNS,
                                             multi_line_rows=True,
                                             started_by_default=True)

        self._subscriber = node.add_handler(uavcan.protocol.debug.LogMessage,
                                            self._log_widget.add_item_async)

        layout = QVBoxLayout(self)
        layout.addWidget(self._log_widget, 1)
        self.setLayout(layout)

    def close(self):
        self._subscriber.remove()
예제 #5
0
    def _do_execute_opcode(self, opcode):
        request = uavcan.protocol.param.ExecuteOpcode.Request(opcode=opcode)
        opcode_str = uavcan.value_to_constant_name(request, "opcode", keep_literal=True)

        if not request_confirmation(
            "Confirm opcode execution", "Do you really want to execute param opcode %s?" % opcode_str, self
        ):
            return

        def callback(e):
            if e is None:
                self.window().show_message("Opcode execution response for %s has timed out", opcode_str)
            else:
                self.window().show_message("Opcode execution response for %s: %s", opcode_str, e.response)

        try:
            self._node.request(request, self._target_node_id, callback, priority=REQUEST_PRIORITY)
            self.window().show_message("Param opcode %s requested", opcode_str)
        except Exception as ex:
            show_error("Node error", "Could not send param opcode execution request", ex, self)
예제 #6
0
class UWBNodeTable(BasicTable):
    COLUMNS = [
        BasicTable.Column('NID', lambda e: e.node_id),
        BasicTable.Column('UWB_NID', lambda e: hex(e.status.node_id)),
        BasicTable.Column('UWB_BID', lambda e: e.status.body_id),
        BasicTable.Column(
            'UWB_SID', lambda e: "UNALLOCATED"
            if e.status.data_slot_id == 255 else e.status.data_slot_id),
        BasicTable.Column(
            'TX_Type',
            lambda e: uavcan.value_to_constant_name(e.status, 'type'),
            QHeaderView.Stretch),
        BasicTable.Column('Num_Pkt', lambda e: e.status.pkt_cnt),
        BasicTable.Column(
            'P_STATE',
            lambda e: uavcan.value_to_constant_name(e.status, 'pstate'),
            QHeaderView.Stretch),
        BasicTable.Column('Progress', lambda e: e.progress)
    ]

    class Row_value:
        """docstring for Row_value"""
        def __init__(self, status, progress):
            self.node_id = status.transfer.source_node_id
            self.status = status.message
            self.progress = progress

    def __init__(self, parent, node, monitor):
        super(UWBNodeTable, self).__init__(parent,
                                           self.COLUMNS,
                                           font=get_monospace_font())
        self._monitor = monitor
        self._timer = QTimer(self)
        self._timer.setSingleShot(False)
        self._timer.timeout.connect(self._update)
        self._timer.start(500)
        self.setMinimumWidth(700)
        self.progress = {}

    def selectedBodyID(self):
        if len(self.selectionModel().selectedRows()) == 0:
            return None
        x = self.selectionModel().selectedRows()[0]
        return int(self.item(x.row(), 2).text(), 0)

    def _update(self):
        known_nodes = {
            e.transfer.source_node_id: e
            for e in self._monitor.find_all(lambda _: True)
        }
        displayed_nodes = set()
        rows_to_remove = []

        # Updating existing entries
        for row in range(self.rowCount()):
            nid = int(self.item(row, 0).text(), 0)
            displayed_nodes.add(nid)
            if nid not in known_nodes:
                rows_to_remove.append(row)
                self.progress.pop(nid, None)
            else:
                row_val = UWBNodeTable.Row_value(known_nodes[nid],
                                                 self.progress[nid])
                self.set_row(row, row_val)

        # Removing nonexistent entries
        for row in rows_to_remove[::
                                  -1]:  # It is important to traverse from end
            logger.info('Removing row %d', row)
            self.removeRow(row)

        # Adding new entries
        def find_insertion_pos_for_node_id(target_slot_id):
            for row in range(self.rowCount()):
                slot_id = int(self.item(row, 1).text(), 0) + int(
                    self.item(row, 2).text(), 0)
                if slot_id > target_slot_id:
                    return row
            return self.rowCount()

        for nid in set(known_nodes.keys()) - displayed_nodes:
            row = find_insertion_pos_for_node_id(
                known_nodes[nid].message.data_slot_id +
                known_nodes[nid].message.body_id)
            self.insertRow(row)
            self.progress[nid] = 0
            row_val = UWBNodeTable.Row_value(known_nodes[nid],
                                             self.progress[nid])
            self.set_row(row, row_val)

    def set_progress(self, nid, progress):
        try:
            self.progress[nid] = progress
        except KeyError:
            pass
class NodeTable(BasicTable):
    COLUMNS = [
        BasicTable.Column('NID', lambda e: e.node_id),
        BasicTable.Column('Name', lambda e: e.info.name
                          if e.info else '?', QHeaderView.Stretch),
        BasicTable.Column(
            'Mode', lambda e: (uavcan.value_to_constant_name(e.status, 'mode'),
                               node_mode_to_color(e.status.mode))),
        BasicTable.Column(
            'Health', lambda e: (uavcan.value_to_constant_name(
                e.status, 'health'), node_health_to_color(e.status.health))),
        BasicTable.Column(
            'Uptime',
            lambda e: datetime.timedelta(days=0, seconds=e.status.uptime_sec)),
        BasicTable.Column(
            'VSSC', lambda e: '%d  0x%04x' %
            (e.status.vendor_specific_status_code, e.status.
             vendor_specific_status_code))
    ]

    info_requested = pyqtSignal([int])

    def __init__(self, parent, node):
        super(NodeTable, self).__init__(parent,
                                        self.COLUMNS,
                                        font=get_monospace_font())

        self.cellDoubleClicked.connect(
            lambda row, col: self._call_info_requested_callback_on_row(row))
        self.on_enter_pressed = self._on_enter

        self._monitor = uavcan.app.node_monitor.NodeMonitor(node)

        self._timer = QTimer(self)
        self._timer.setSingleShot(False)
        self._timer.timeout.connect(self._update)
        self._timer.start(500)

        self.setMinimumWidth(500)

    @property
    def monitor(self):
        return self._monitor

    def close(self):
        self._monitor.close()

    def _call_info_requested_callback_on_row(self, row):
        nid = int(self.item(row, 0).text())
        self.info_requested.emit(nid)

    def _on_enter(self, list_of_row_col_pairs):
        unique_rows = set([row for row, _col in list_of_row_col_pairs])
        if len(unique_rows) == 1:
            self._call_info_requested_callback_on_row(list(unique_rows)[0])

    def _update(self):
        known_nodes = {
            e.node_id: e
            for e in self._monitor.find_all(lambda _: True)
        }
        displayed_nodes = set()
        rows_to_remove = []

        # Updating existing entries
        for row in range(self.rowCount()):
            nid = int(self.item(row, 0).text())
            displayed_nodes.add(nid)
            if nid not in known_nodes:
                rows_to_remove.append(row)
            else:
                self.set_row(row, known_nodes[nid])

        # Removing nonexistent entries
        for row in rows_to_remove[::
                                  -1]:  # It is important to traverse from end
            logger.info('Removing row %d', row)
            self.removeRow(row)

        # Adding new entries
        def find_insertion_pos_for_node_id(target_nid):
            for row in range(self.rowCount()):
                nid = int(self.item(row, 0).text())
                if nid > target_nid:
                    return row
            return self.rowCount()

        for nid in set(known_nodes.keys()) - displayed_nodes:
            row = find_insertion_pos_for_node_id(nid)
            logger.info('Adding new row %d for node %d', row, nid)
            self.insertRow(row)
            self.set_row(row, known_nodes[nid])