aboutsummaryrefslogtreecommitdiffstats
path: root/examples/serialbus/can/sendframebox.py
diff options
context:
space:
mode:
Diffstat (limited to 'examples/serialbus/can/sendframebox.py')
-rw-r--r--examples/serialbus/can/sendframebox.py195
1 files changed, 195 insertions, 0 deletions
diff --git a/examples/serialbus/can/sendframebox.py b/examples/serialbus/can/sendframebox.py
new file mode 100644
index 000000000..6472fc473
--- /dev/null
+++ b/examples/serialbus/can/sendframebox.py
@@ -0,0 +1,195 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import re
+
+from PySide6.QtGui import QValidator
+from PySide6.QtCore import QByteArray, Signal, Slot
+from PySide6.QtWidgets import QGroupBox
+from PySide6.QtSerialBus import QCanBusFrame
+
+from ui_sendframebox import Ui_SendFrameBox
+
+
+THREE_HEX_DIGITS_PATTERN = re.compile("[0-9a-fA-F]{3}")
+HEX_NUMBER_PATTERN = re.compile("^[0-9a-fA-F]+$")
+
+
+MAX_STANDARD_ID = 0x7FF
+MAX_EXTENDED_ID = 0x10000000
+MAX_PAYLOAD = 8
+MAX_PAYLOAD_FD = 64
+
+
+def is_even_hex(input):
+ return len(input.replace(" ", "")) % 2 == 0
+
+
+def insert_space(string, pos):
+ return string[0:pos] + " " + string[pos:]
+
+
+# Formats a string of hex characters with a space between every byte
+# Example: "012345" -> "01 23 45"
+def format_hex_data(input):
+ out = input.strip()
+ while True:
+ match = THREE_HEX_DIGITS_PATTERN.search(out)
+ if match:
+ out = insert_space(out, match.end(0) - 1)
+ else:
+ break
+ return out.strip().upper()
+
+
+class HexIntegerValidator(QValidator):
+
+ def __init__(self, parent):
+ super().__init__(parent)
+ self.m_maximum = MAX_STANDARD_ID
+
+ def validate(self, input, pos):
+ result = QValidator.Intermediate
+ if input:
+ result = QValidator.Invalid
+ try:
+ value = int(input, base=16)
+ if value < self.m_maximum:
+ result = QValidator.Acceptable
+ except ValueError:
+ pass
+ return result
+
+ def set_maximum(self, maximum):
+ self.m_maximum = maximum
+
+
+class HexStringValidator(QValidator):
+
+ def __init__(self, parent):
+ super().__init__(parent)
+ self.m_maxLength = MAX_PAYLOAD
+
+ def validate(self, input, pos):
+ max_size = 2 * self.m_maxLength
+ data = input.replace(" ", "")
+ if not data:
+ return QValidator.Intermediate
+
+ # limit maximum size
+ if len(data) > max_size:
+ return QValidator.Invalid
+
+ # check if all input is valid
+ if not HEX_NUMBER_PATTERN.match(data):
+ return QValidator.Invalid
+
+ # insert a space after every two hex nibbles
+ while True:
+ match = THREE_HEX_DIGITS_PATTERN.search(input)
+ if not match:
+ break
+ start = match.start(0)
+ end = match.end()
+ if pos == start + 1:
+ # add one hex nibble before two - Abc
+ input = insert_space(input, pos)
+ elif pos == start + 2:
+ # add hex nibble in the middle - aBc
+ input = insert_space(input, end - 1)
+ pos = end
+ else:
+ # add one hex nibble after two - abC
+ input = insert_space(input, end - 1)
+ pos = end + 1
+
+ return (QValidator.Acceptable, input, pos)
+
+ def set_max_length(self, maxLength):
+ self.m_maxLength = maxLength
+
+
+class SendFrameBox(QGroupBox):
+
+ send_frame = Signal(QCanBusFrame)
+
+ def __init__(self, parent):
+ super().__init__(parent)
+ self.m_ui = Ui_SendFrameBox()
+ self.m_ui.setupUi(self)
+
+ self.m_hexIntegerValidator = HexIntegerValidator(self)
+ self.m_ui.frameIdEdit.setValidator(self.m_hexIntegerValidator)
+ self.m_hexStringValidator = HexStringValidator(self)
+ self.m_ui.payloadEdit.setValidator(self.m_hexStringValidator)
+
+ self.m_ui.dataFrame.toggled.connect(self._data_frame)
+ self.m_ui.remoteFrame.toggled.connect(self._remote_frame)
+ self.m_ui.errorFrame.toggled.connect(self._error_frame)
+ self.m_ui.extendedFormatBox.toggled.connect(self._extended_format)
+ self.m_ui.flexibleDataRateBox.toggled.connect(self._flexible_datarate)
+ self.m_ui.frameIdEdit.textChanged.connect(self._frameid_or_payload_changed)
+ self.m_ui.payloadEdit.textChanged.connect(self._frameid_or_payload_changed)
+ self._frameid_or_payload_changed()
+ self.m_ui.sendButton.clicked.connect(self._send)
+
+ @Slot(bool)
+ def _data_frame(self, value):
+ if value:
+ self.m_ui.flexibleDataRateBox.setEnabled(True)
+
+ @Slot(bool)
+ def _remote_frame(self, value):
+ if value:
+ self.m_ui.flexibleDataRateBox.setEnabled(False)
+ self.m_ui.flexibleDataRateBox.setChecked(False)
+
+ @Slot(bool)
+ def _error_frame(self, value):
+ if value:
+ self.m_ui.flexibleDataRateBox.setEnabled(False)
+ self.m_ui.flexibleDataRateBox.setChecked(False)
+
+ @Slot(bool)
+ def _extended_format(self, value):
+ m = MAX_EXTENDED_ID if value else MAX_STANDARD_ID
+ self.m_hexIntegerValidator.set_maximum(m)
+
+ @Slot(bool)
+ def _flexible_datarate(self, value):
+ len = MAX_PAYLOAD_FD if value else MAX_PAYLOAD
+ self.m_hexStringValidator.set_max_length(len)
+ self.m_ui.bitrateSwitchBox.setEnabled(value)
+ if not value:
+ self.m_ui.bitrateSwitchBox.setChecked(False)
+
+ @Slot()
+ def _frameid_or_payload_changed(self):
+ has_frame_id = bool(self.m_ui.frameIdEdit.text())
+ self.m_ui.sendButton.setEnabled(has_frame_id)
+ tt = "" if has_frame_id else "Cannot send because no Frame ID was given."
+ self.m_ui.sendButton.setToolTip(tt)
+ if has_frame_id:
+ is_even = is_even_hex(self.m_ui.payloadEdit.text())
+ self.m_ui.sendButton.setEnabled(is_even)
+ tt = "" if is_even else "Cannot send because Payload hex string is invalid."
+ self.m_ui.sendButton.setToolTip(tt)
+
+ @Slot()
+ def _send(self):
+ frame_id = int(self.m_ui.frameIdEdit.text(), base=16)
+ data = self.m_ui.payloadEdit.text().replace(" ", "")
+ self.m_ui.payloadEdit.setText(format_hex_data(data))
+ payload = QByteArray.fromHex(bytes(data, encoding='utf8'))
+
+ frame = QCanBusFrame(frame_id, payload)
+ frame.setExtendedFrameFormat(self.m_ui.extendedFormatBox.isChecked())
+ frame.setFlexibleDataRateFormat(self.m_ui.flexibleDataRateBox.isChecked())
+ frame.setBitrateSwitch(self.m_ui.bitrateSwitchBox.isChecked())
+
+ if self.m_ui.errorFrame.isChecked():
+ frame.setFrameType(QCanBusFrame.ErrorFrame)
+ elif self.m_ui.remoteFrame.isChecked():
+ frame.setFrameType(QCanBusFrame.RemoteRequestFrame)
+
+ self.send_frame.emit(frame)