Compare commits
2 Commits
cc08435a3a
...
d8b17bdf51
Author | SHA1 | Date |
---|---|---|
|
d8b17bdf51 | |
|
93c11e7ecf |
|
@ -1 +1 @@
|
|||
Subproject commit 43240eab1f351a90afdc843119743b0aca4d311c
|
||||
Subproject commit 18edf9f0fdf0f11663d328a8166486226246e656
|
|
@ -2,13 +2,23 @@ cmake_minimum_required(VERSION 3.21)
|
|||
|
||||
project(ProtocolParser VERSION ${CMAKE_PROJECT_VERSION} LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
if(QT_VERSION VERSION_GREATER_EQUAL "6.3")
|
||||
qt_standard_project_setup()
|
||||
qt_policy(SET QTP0001 NEW)
|
||||
else()
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE)
|
||||
endif()
|
||||
|
||||
set(QML_IMPORT_PATH ${CMAKE_BINARY_DIR}/app_source CACHE STRING "Qt Creator extra QML import paths" FORCE)
|
||||
|
||||
set(PROJECT_COMPANY "Mentalflow's Lab")
|
||||
set(PROJECT_COPYRIGHT "Copyright (c) 2023 Mentalflow's Lab. All rights reserved.")
|
||||
set(PROJECT_DOMAIN "dev.ourdocs.cn.protocolparser")
|
||||
|
@ -36,7 +46,7 @@ set(
|
|||
qml/components/ZigBeeMessage.qml qml/components/SerialPortAssistant.qml
|
||||
qml/components/ZigBeeDataView.qml qml/components/TabBar.qml qml/components/CenterView.qml
|
||||
qml/components/ListTable.qml qml/components/DeviceList.qml qml/components/KeysList.qml
|
||||
qml/components/EventsHistoryList.qml
|
||||
qml/components/EventsHistoryList.qml qml/components/FrameChooser.qml
|
||||
)
|
||||
|
||||
INCLUDE_DIRECTORIES(dlln3x include)
|
||||
|
|
|
@ -9,17 +9,18 @@ class Config : public QObject
|
|||
{
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_SINGLETON
|
||||
QML_NAMED_ELEMENT(Config)
|
||||
public:
|
||||
static Config* instance();
|
||||
static Config* create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return instance();}
|
||||
Q_INVOKABLE void Set(QString qstrnodename,QString qstrkeyname,QVariant qvarvalue);
|
||||
Q_INVOKABLE void SetArray(QString qstrnodename,QString qstrkeyname,QVariant qvarvalue);
|
||||
Q_INVOKABLE QVariant Get(QString qstrnodename,QString qstrkeyname);
|
||||
Q_INVOKABLE QVariant GetArray(QString qstrnodename,QString qstrkeyname);
|
||||
Q_INVOKABLE void set(QString qstrnodename,QString qstrkeyname,QVariant qvarvalue);
|
||||
Q_INVOKABLE void setArray(QString qstrnodename,QString qstrkeyname,QVariant qvarvalue);
|
||||
Q_INVOKABLE QVariant get(QString qstrnodename,QString qstrkeyname);
|
||||
Q_INVOKABLE QVariant getArray(QString qstrnodename,QString qstrkeyname);
|
||||
void Clear();
|
||||
private:
|
||||
Config(QString qstrfilename = "");
|
||||
explicit Config(QString qstrfilename = "");
|
||||
~Config(void);
|
||||
Q_DISABLE_COPY_MOVE(Config)
|
||||
QString m_qstrFileName;
|
||||
|
|
|
@ -24,6 +24,7 @@ private:
|
|||
void src_port_parser(zigbee_protocol::ZigbeeFrame &zframe, bool is_demo = false);
|
||||
void des_port_parser(zigbee_protocol::ZigbeeFrame &zframe, bool is_demo = false);
|
||||
void remote_addr_parser(zigbee_protocol::ZigbeeFrame &zframe, bool is_demo = false);
|
||||
QString sensor_data_reader(void **data,QString type);
|
||||
zigbee_protocol::Protocol* _protocol = nullptr;
|
||||
QString _self_addr;
|
||||
QMap<uint16_t, QPair<device,device>> nodes;
|
||||
|
|
|
@ -33,9 +33,9 @@ public:
|
|||
QList<uint16_t> wait_queue(){if(!_resolver)_resolver=ZigBeeDataResolver::instance();return _resolver->get_wait_queue();};
|
||||
void setWait_queue(QList<uint16_t> wait_queue){if(!_resolver)_resolver=ZigBeeDataResolver::instance();QList<uint16_t> &a=_resolver->get_wait_queue();a=wait_queue;emit wait_queueChanged();};
|
||||
QString hmac_verify_key(){ return _protocol->hmac_verify_key;};
|
||||
void setHmac_verify_key(QString key){ _config->Set("Protocol","hmac_verify_key",key); _protocol->hmac_verify_key = key;emit hmac_verify_keyChanged();};
|
||||
void setHmac_verify_key(QString key){ _config->set("Protocol","hmac_verify_key",key); _protocol->hmac_verify_key = key;emit hmac_verify_keyChanged();};
|
||||
QStringList pre_hmac_verify_key(){ return _protocol->pre_hmac_verify_key;};
|
||||
void setPre_hmac_verify_key(QStringList keys){ _config->SetArray("Protocol","pre_hmac_verify_key",keys); _protocol->pre_hmac_verify_key = keys;emit pre_hmac_verify_keyChanged();};
|
||||
void setPre_hmac_verify_key(QStringList keys){ _config->setArray("Protocol","pre_hmac_verify_key",keys); _protocol->pre_hmac_verify_key = keys;emit pre_hmac_verify_keyChanged();};
|
||||
static ZigBeeParser* instance();
|
||||
static ZigBeeParser* create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return instance();}
|
||||
void message_parser(QJsonObject message);
|
||||
|
|
|
@ -10,7 +10,9 @@ import "components"
|
|||
RibbonWindow {
|
||||
id:root
|
||||
width: 1200
|
||||
minimumWidth: 1200
|
||||
height: 800
|
||||
minimumHeight: 800
|
||||
title: qsTr("Protocol Parser") + ` V${PPAPP_Version}`
|
||||
|
||||
TabBar{
|
||||
|
|
|
@ -7,7 +7,7 @@ import ProtocolParser
|
|||
Item {
|
||||
id:obj
|
||||
property var header_items: ["序号","事件"]
|
||||
property var header_items_width: [100,400]
|
||||
property var header_items_width: [100,700]
|
||||
property var data_source: []
|
||||
implicitHeight: list_layout.height
|
||||
implicitWidth: list_layout.width
|
||||
|
@ -21,7 +21,7 @@ Item {
|
|||
var data = []
|
||||
for (var i = 0; i < EventsBus.event_history.length; i++)
|
||||
{
|
||||
data.push({"序号":i+1,"事件":JSON.stringify(EventsBus.event_history)})
|
||||
data.push({"序号":i+1,"事件":JSON.stringify(EventsBus.event_history[i])})
|
||||
}
|
||||
data_source = data
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ Item {
|
|||
var data = []
|
||||
for (var i = 0; i < EventsBus.event_history.length; i++)
|
||||
{
|
||||
data.push({"序号":i+1,"事件":JSON.stringify(EventsBus.event_history)})
|
||||
data.push({"序号":i+1,"事件":JSON.stringify(EventsBus.event_history[i])})
|
||||
}
|
||||
data_source = data
|
||||
}
|
||||
|
|
|
@ -0,0 +1,373 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import RibbonUI
|
||||
import ProtocolParser
|
||||
|
||||
Item {
|
||||
clip: true
|
||||
id: root
|
||||
implicitWidth: layout.width + margins*2
|
||||
implicitHeight: layout.height + margins*2
|
||||
property double margins: 30
|
||||
property int object_width: 30
|
||||
|
||||
ListModel{
|
||||
id: frame_model
|
||||
ListElement{
|
||||
name:"温度"
|
||||
type:"float"
|
||||
}
|
||||
ListElement{
|
||||
name:"湿度"
|
||||
type:"float"
|
||||
}
|
||||
ListElement{
|
||||
name:"气体浓度"
|
||||
type:"float"
|
||||
}
|
||||
ListElement{
|
||||
name:"火焰指数"
|
||||
type:"float"
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
let result = Config.getArray('Protocol', 'data_frame_name')
|
||||
if (result.length)
|
||||
{
|
||||
frame_model.clear()
|
||||
var name_array=[],type_array=[]
|
||||
name_array = Config.getArray('Protocol', 'data_frame_name')
|
||||
type_array = Config.getArray('Protocol', 'data_frame_type')
|
||||
for (var i=0;i<name_array.length;i++)
|
||||
{
|
||||
frame_model.append({
|
||||
name:name_array[i],
|
||||
type:type_array[i]
|
||||
})
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
let name_array=[],type_array=[]
|
||||
for (let i=0;i<frame_model.count;i++)
|
||||
{
|
||||
name_array[i] = frame_model.get(i).name
|
||||
type_array[i] = frame_model.get(i).type
|
||||
}
|
||||
Config.setArray('Protocol', 'data_frame_name', name_array)
|
||||
Config.setArray('Protocol', 'data_frame_type', type_array)
|
||||
}
|
||||
}
|
||||
|
||||
RibbonButton{
|
||||
anchors{
|
||||
top:parent.top
|
||||
margins: 4
|
||||
right:parent.right
|
||||
}
|
||||
show_bg: false
|
||||
show_hovered_bg: false
|
||||
icon_source: RibbonIcons.Dismiss
|
||||
onClicked: window_popup.close()
|
||||
}
|
||||
|
||||
ColumnLayout{
|
||||
id:layout
|
||||
anchors{
|
||||
top:parent.top
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
margins: margins
|
||||
}
|
||||
RibbonText{
|
||||
Layout.alignment: Qt.AlignTop | Qt.AlignHCenter
|
||||
width: implicitWidth > parent.width ? parent.width : implicitWidth
|
||||
text: qsTr("自定义传感器数据结构")
|
||||
font.pixelSize: 20
|
||||
wrapMode: RibbonText.WordWrap
|
||||
view_only: true
|
||||
}
|
||||
RibbonText{
|
||||
Layout.topMargin: margins/2
|
||||
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
|
||||
width: implicitWidth > parent.width ? parent.width : implicitWidth
|
||||
text: qsTr("传感器数据帧结构组成:")
|
||||
wrapMode: RibbonText.WordWrap
|
||||
view_only: true
|
||||
}
|
||||
Rectangle{
|
||||
id: frame_bg
|
||||
radius: 5
|
||||
Layout.preferredHeight: object_width + frame.anchors.leftMargin*2
|
||||
Layout.preferredWidth: object_width * 16 + frame.anchors.leftMargin*2
|
||||
color: RibbonTheme.dark_mode ? '#2A2C31' : '#F2F4F7'
|
||||
ListView{
|
||||
id: frame
|
||||
property int current_size: 0
|
||||
property bool is_full: current_size === 16
|
||||
property int has_selected: 0
|
||||
clip: true
|
||||
model: frame_model
|
||||
orientation: ListView.Horizontal
|
||||
implicitHeight: object_width
|
||||
implicitWidth: contentWidth
|
||||
anchors{
|
||||
leftMargin: 2
|
||||
left: parent.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
delegate:RibbonRectangle{
|
||||
id: bg
|
||||
topLeftRadius: index === 0 ? 5 : 0
|
||||
bottomLeftRadius: topLeftRadius
|
||||
topRightRadius: frame.current_size === 16 && (index + 1) === frame.count ? 5 : 0
|
||||
bottomRightRadius: topRightRadius
|
||||
implicitHeight: object_width
|
||||
implicitWidth: object_width
|
||||
color: bg.selected || mouse.containsMouse ? "#506BBD" : RibbonTheme.dark_mode ? '#3A4045' : "white"
|
||||
property bool selected: false
|
||||
property bool is_focused: frame.currentIndex === index
|
||||
onIs_focusedChanged: {
|
||||
if (!is_focused && selected)
|
||||
bg.selected = !bg.selected
|
||||
}
|
||||
onSelectedChanged: frame.has_selected += bg.selected ? 1 : -1
|
||||
property string type: model.type
|
||||
property int data_size
|
||||
onTypeChanged: {
|
||||
data_size = cal_size(model.type)
|
||||
implicitWidth = object_width * data_size
|
||||
}
|
||||
RibbonText{
|
||||
anchors.centerIn: parent
|
||||
width: implicitWidth > parent.width ? parent.width : implicitWidth
|
||||
text: model.name
|
||||
wrapMode: RibbonText.WordWrap
|
||||
view_only: true
|
||||
color:{
|
||||
if(!RibbonTheme.dark_mode)
|
||||
{
|
||||
if(mouse.containsMouse&&!bg.selected)
|
||||
return 'black'
|
||||
else if(mouse.containsMouse&&bg.selected)
|
||||
return 'white'
|
||||
else if(!mouse.containsMouse&&bg.selected)
|
||||
return 'black'
|
||||
else
|
||||
return 'black'
|
||||
}
|
||||
else
|
||||
{
|
||||
if(mouse.containsMouse&&!bg.selected)
|
||||
return 'white'
|
||||
else if(mouse.containsMouse&&bg.selected)
|
||||
return 'black'
|
||||
else if(!mouse.containsMouse&&bg.selected)
|
||||
return 'white'
|
||||
else
|
||||
return 'white'
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
width: 1
|
||||
height: parent.height - frame.anchors.leftMargin * 2
|
||||
visible: index + 1 !== frame.count
|
||||
color: RibbonTheme.dark_mode ? "#525252" : "#D4D4D4"
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: 60
|
||||
easing.type: Easing.OutSine
|
||||
}
|
||||
}
|
||||
}
|
||||
RibbonToolTip{
|
||||
text: qsTr(`类型:${bg.type}, 长度:${bg.data_size}B`)
|
||||
visible: text && mouse.containsMouse
|
||||
}
|
||||
|
||||
MouseArea{
|
||||
id: mouse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked:
|
||||
{
|
||||
frame.currentIndex = index
|
||||
bg.selected = !bg.selected
|
||||
}
|
||||
}
|
||||
ListView.onRemove: cal_size(type,true)
|
||||
function cal_size(type,is_remove)
|
||||
{
|
||||
let size = frame.judge_size(type);
|
||||
if(!is_remove)
|
||||
frame.current_size += size
|
||||
else
|
||||
frame.current_size -= size
|
||||
return size
|
||||
}
|
||||
}
|
||||
function judge_size(type)
|
||||
{
|
||||
let size = 0
|
||||
switch(type)
|
||||
{
|
||||
case "float":
|
||||
size = 4
|
||||
break
|
||||
case "double":
|
||||
size = 8
|
||||
break
|
||||
case "int64_t":
|
||||
size = 8
|
||||
break
|
||||
case "int32_t":
|
||||
size = 4
|
||||
break
|
||||
case "int16_t":
|
||||
size = 2
|
||||
break
|
||||
case "int8_t":
|
||||
size = 1
|
||||
break
|
||||
case "uint64_t":
|
||||
size = 8
|
||||
break
|
||||
case "uint32_t":
|
||||
size = 4
|
||||
break
|
||||
case "uint16_t":
|
||||
size = 2
|
||||
break
|
||||
case "uint8_t":
|
||||
size = 1
|
||||
break
|
||||
}
|
||||
return size
|
||||
}
|
||||
}
|
||||
}
|
||||
RowLayout{
|
||||
Layout.preferredWidth: parent.width
|
||||
Layout.topMargin: margins/2
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: margins/3
|
||||
RibbonText{
|
||||
text: qsTr("类型:")
|
||||
view_only: true
|
||||
}
|
||||
RibbonComboBox{
|
||||
id: type_combo
|
||||
Layout.preferredWidth: 100
|
||||
model: ListModel {
|
||||
ListElement { text: "float" }
|
||||
ListElement { text: "double" }
|
||||
ListElement { text: "int64_t" }
|
||||
ListElement { text: "int32_t" }
|
||||
ListElement { text: "int16_t" }
|
||||
ListElement { text: "int8_t" }
|
||||
ListElement { text: "uint64_t" }
|
||||
ListElement { text: "uint32_t" }
|
||||
ListElement { text: "uint16_t" }
|
||||
ListElement { text: "uint8_t" }
|
||||
}
|
||||
enabled: frame.current_size !==16
|
||||
}
|
||||
RibbonText{
|
||||
text: qsTr("名称:")
|
||||
view_only: true
|
||||
}
|
||||
RibbonLineEdit{
|
||||
id: name_edit
|
||||
Layout.preferredWidth: 120
|
||||
placeholderText: qsTr("请输入数据名称")
|
||||
onCommit: save_btn.clicked()
|
||||
enabled: frame.current_size !==16
|
||||
}
|
||||
RibbonButton{
|
||||
id: add_btn
|
||||
icon_source: RibbonIcons.Add
|
||||
text: qsTr("添加")
|
||||
show_tooltip: false
|
||||
enabled: {
|
||||
if (frame.judge_size(type_combo.currentText)+frame.current_size>16)
|
||||
return false
|
||||
else
|
||||
return true
|
||||
}
|
||||
onClicked: {
|
||||
frame_model.append({
|
||||
type:type_combo.currentText,
|
||||
name:name_edit.text
|
||||
})
|
||||
}
|
||||
}
|
||||
RibbonButton{
|
||||
id: delete_btn
|
||||
icon_source: RibbonIcons.Delete
|
||||
text: qsTr("删除")
|
||||
show_tooltip: false
|
||||
enabled: frame.has_selected !== 0
|
||||
onClicked: {
|
||||
frame_model.remove(frame.currentIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
RowLayout{
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.topMargin: margins/2
|
||||
spacing: margins
|
||||
RibbonButton{
|
||||
id: save_btn
|
||||
Layout.preferredWidth: 150
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
icon_source: RibbonIcons.Save
|
||||
text: qsTr("保存")
|
||||
show_tooltip: false
|
||||
onClicked: {
|
||||
if (!type_combo.enabled && !name_edit.enabled && frame.current_size > 0)
|
||||
{
|
||||
let name_array=[],type_array=[]
|
||||
for (let i=0;i<frame_model.count;i++)
|
||||
{
|
||||
name_array[i] = frame_model.get(i).name
|
||||
type_array[i] = frame_model.get(i).type
|
||||
}
|
||||
Config.setArray('Protocol', 'data_frame_name', name_array)
|
||||
Config.setArray('Protocol', 'data_frame_type', type_array)
|
||||
}
|
||||
else
|
||||
{
|
||||
name_edit.text = qsTr("请检查数据长度")
|
||||
}
|
||||
}
|
||||
}
|
||||
RibbonButton{
|
||||
id: reset_btn
|
||||
Layout.preferredWidth: 150
|
||||
icon_source: RibbonIcons.ArrowReset
|
||||
text: qsTr("还原默认值")
|
||||
show_tooltip: false
|
||||
onClicked: {
|
||||
frame_model.clear()
|
||||
frame_model.append([{
|
||||
name:"温度",
|
||||
type:"float"
|
||||
},{
|
||||
name:"湿度",
|
||||
type:"float"
|
||||
},{
|
||||
name:"气体浓度",
|
||||
type:"float"
|
||||
},{
|
||||
name:"火焰指数",
|
||||
type:"float"
|
||||
}])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -93,7 +93,30 @@ Item {
|
|||
view_only: true
|
||||
text: modelData.data
|
||||
wrapMode: RibbonText.WordWrap
|
||||
color: RibbonTheme.dark_mode ? mouse.containsMouse ? 'black' : 'white' : mouse.containsMouse ? 'white':'black'
|
||||
color: {
|
||||
if(RibbonTheme.dark_mode)
|
||||
{
|
||||
if(mouse.containsMouse&&!row_bg.selected)
|
||||
return 'black'
|
||||
else if(mouse.containsMouse&&row_bg.selected)
|
||||
return 'white'
|
||||
else if(!mouse.containsMouse&&row_bg.selected)
|
||||
return 'black'
|
||||
else
|
||||
return 'white'
|
||||
}
|
||||
else
|
||||
{
|
||||
if(mouse.containsMouse&&!row_bg.selected)
|
||||
return 'white'
|
||||
else if(mouse.containsMouse&&row_bg.selected)
|
||||
return 'black'
|
||||
else if(!mouse.containsMouse&&row_bg.selected)
|
||||
return 'white'
|
||||
else
|
||||
return 'black'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -114,6 +137,11 @@ Item {
|
|||
add: Transition {
|
||||
NumberAnimation { properties: "y"; from: list_table.height; duration: 200 }
|
||||
}
|
||||
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
anchors.right: list_table.right
|
||||
anchors.rightMargin: 2
|
||||
}
|
||||
}
|
||||
|
||||
function getRowValues(index) {
|
||||
|
|
|
@ -8,11 +8,12 @@ Rectangle{
|
|||
color: "transparent"
|
||||
property double padding: 10
|
||||
default property alias content: message_layout.data
|
||||
property var data_model:model
|
||||
property var data_model: model
|
||||
property int font_size: 13
|
||||
property string sender_text: "sender"
|
||||
width: ListView.view.width
|
||||
height: bubble_layout.height + padding*2
|
||||
|
||||
ColumnLayout{
|
||||
id: bubble_layout
|
||||
anchors{
|
||||
|
|
|
@ -12,80 +12,53 @@ RibbonView{
|
|||
spacing: 0
|
||||
|
||||
property int max_msg_num: 10
|
||||
property bool auto_scroll_to_bottom: false
|
||||
property int animation_time: 200
|
||||
property alias delegate: message_list.delegate
|
||||
property alias message_model: message_model
|
||||
property alias view: message_list
|
||||
|
||||
ListModel{
|
||||
id: message_model
|
||||
property int begin_index: 0
|
||||
property int end_index: 0
|
||||
onCountChanged: {
|
||||
if (end_index == count - 2 || begin_index == end_index)
|
||||
{
|
||||
while(show_model.count > max_msg_num)
|
||||
{
|
||||
show_model.remove(0)
|
||||
begin_index++
|
||||
}
|
||||
show_model.append(message_model.get(count - 1))
|
||||
end_index = count-1
|
||||
//console.log('append:',begin_index,end_index)
|
||||
}
|
||||
if(count===0)
|
||||
show_model.clear()
|
||||
}
|
||||
onCountChanged: auto_scroll_btn_timer.restart()
|
||||
}
|
||||
ListModel{
|
||||
id: show_model
|
||||
|
||||
Timer{
|
||||
id: auto_scroll_btn_timer
|
||||
interval: animation_time
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
if(view.auto_scroll_to_bottom)
|
||||
view.scroll_to_bottom()
|
||||
}
|
||||
}
|
||||
|
||||
ListView{
|
||||
id: message_list
|
||||
cacheBuffer: message_list.height * 2
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.preferredHeight: contentHeight
|
||||
Layout.preferredHeight: parent.height
|
||||
Layout.preferredWidth: parent.width
|
||||
interactive: false
|
||||
model: show_model
|
||||
model: message_model
|
||||
add: Transition {
|
||||
NumberAnimation { properties: "y"; from: message_list.height; duration: 100 }
|
||||
NumberAnimation {
|
||||
properties: "y"
|
||||
from: message_list.height
|
||||
duration: animation_time
|
||||
}
|
||||
}
|
||||
displaced: Transition {
|
||||
NumberAnimation { properties: "y"; duration: 100 }
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
anchors.right: message_list.right
|
||||
anchors.rightMargin: 2
|
||||
}
|
||||
}
|
||||
Connections{
|
||||
target: view
|
||||
function onPull_up_triggered()
|
||||
{
|
||||
for(let i = message_model.begin_index - 1, count = 0;
|
||||
i >= 0 && count < max_msg_num; i--,count++ )
|
||||
{
|
||||
show_model.insert(0,message_model.get(i))
|
||||
message_model.begin_index = i
|
||||
if (show_model.count > max_msg_num + 2)
|
||||
{
|
||||
show_model.remove(show_model.count - 1)
|
||||
message_model.end_index--
|
||||
}
|
||||
}
|
||||
//console.log('up:',message_model.begin_index,message_model.end_index)
|
||||
}
|
||||
function onPull_down_triggered()
|
||||
{
|
||||
for(let i = message_model.end_index + 1, count = 0;
|
||||
i < message_model.count && count < max_msg_num; i++,count++ )
|
||||
{
|
||||
show_model.append(message_model.get(i))
|
||||
message_model.end_index = i
|
||||
if (show_model.count > max_msg_num)
|
||||
{
|
||||
show_model.remove(0)
|
||||
message_model.begin_index++
|
||||
}
|
||||
}
|
||||
//console.log('down:',message_model.begin_index,message_model.end_index)
|
||||
}
|
||||
|
||||
function scroll_to_up(){
|
||||
message_list.positionViewAtBeginning()
|
||||
}
|
||||
|
||||
function scroll_to_bottom(){
|
||||
message_list.positionViewAtEnd()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,22 +14,23 @@ Item{
|
|||
property double bottom_padding: 0
|
||||
property bool handle_serial: true
|
||||
|
||||
onAuto_scroll_to_bottomChanged: if(auto_scroll_to_bottom) serial_view.scroll_to_bottom()
|
||||
onAuto_scroll_to_bottomChanged: {
|
||||
serial_view.auto_scroll_to_bottom = auto_scroll_to_bottom
|
||||
if(auto_scroll_to_bottom)
|
||||
serial_view.scroll_to_bottom()
|
||||
}
|
||||
|
||||
RibbonMessageListView{
|
||||
id: serial_view
|
||||
anchors.fill: parent
|
||||
top_padding: serial_title_bar.height + control.top_padding + (!RibbonTheme.modern_style ? 10 : 0)
|
||||
bottom_padding: message_sender.height + control.bottom_padding
|
||||
auto_scroll_to_bottom: control.auto_scroll_to_bottom
|
||||
delegate: ZigBeeMessage{
|
||||
sender_text: `${model.time} ${model.recieved ? '收' : '发'}`
|
||||
show_tooltip: control.show_tooltip
|
||||
component_width: serial_view.width / 2
|
||||
}
|
||||
view.onHeightChanged: {
|
||||
if (control.auto_scroll_to_bottom)
|
||||
scroll_to_bottom()
|
||||
}
|
||||
Connections{
|
||||
target: SerialPortManager
|
||||
function onRecved(data)
|
||||
|
|
|
@ -404,8 +404,8 @@ RibbonTabBar {
|
|||
}
|
||||
|
||||
let repeat_count = 16
|
||||
let t = `FF 29 ${get_rand_byte()}${get_rand_byte()} 83 56 56 `+
|
||||
`AA AD 56 56 52 48 23 32 01 00 17 00 00 00 AA AA 01 10 00 FF FF `
|
||||
let t = `FF 2B ${get_rand_byte()}${get_rand_byte()} 83 56 56 `+
|
||||
`AA AD 56 56 EE EE 56 56 01 00 26 00 00 00 AA AA 01 FF 10 00 FF FF `
|
||||
for (let j=0;j<repeat_count;j++){
|
||||
t+=` ${get_rand_byte()}${get_rand_byte()}`
|
||||
}
|
||||
|
@ -458,5 +458,27 @@ RibbonTabBar {
|
|||
}
|
||||
}
|
||||
}
|
||||
RibbonTabGroup{
|
||||
text: qsTr("数据结构自定义")
|
||||
width: frame_custom_layout.width + 30
|
||||
RowLayout{
|
||||
id: frame_custom_layout
|
||||
anchors.centerIn: parent
|
||||
height: parent.height
|
||||
spacing: 10
|
||||
ColumnLayout{
|
||||
spacing: 10
|
||||
RibbonButton{
|
||||
Layout.fillWidth: true
|
||||
icon_source: RibbonIcons.CodeTextEdit
|
||||
text: qsTr("自定义数据帧")
|
||||
tip_text: qsTr("自定义传感器数据帧结构")
|
||||
onClicked: {
|
||||
show_popup("components/FrameChooser.qml")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,10 @@ Item{
|
|||
identify_view.scroll_to_bottom()
|
||||
data_view.scroll_to_bottom()
|
||||
}
|
||||
identify_view.auto_scroll_to_bottom = auto_scroll_to_bottom
|
||||
data_view.auto_scroll_to_bottom = auto_scroll_to_bottom
|
||||
}
|
||||
|
||||
Item{
|
||||
anchors{
|
||||
top:parent.top
|
||||
|
@ -56,14 +59,11 @@ Item{
|
|||
anchors.fill: parent
|
||||
top_padding: control.top_padding + identify_title_bar.height + (!RibbonTheme.modern_style ? 10 : 0)
|
||||
bottom_padding: control.bottom_padding
|
||||
auto_scroll_to_bottom: control.auto_scroll_to_bottom
|
||||
delegate: ZigBeeMessage{
|
||||
show_tooltip: control.show_tooltip
|
||||
component_width: identify_view.width / 2
|
||||
}
|
||||
view.onHeightChanged: {
|
||||
if (control.auto_scroll_to_bottom)
|
||||
scroll_to_bottom()
|
||||
}
|
||||
Event{
|
||||
id:identify_view_event
|
||||
type: "zigbee_identify_data_view"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
cmake_minimum_required(VERSION 3.21)
|
||||
|
||||
project(sm_crypto VERSION 1.0.0.0)
|
||||
project(sm_crypto VERSION 1.0.0)
|
||||
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
|
|
|
@ -35,12 +35,12 @@ Config* Config::instance()
|
|||
return singleton;
|
||||
}
|
||||
|
||||
void Config::Set(QString qstrnodename,QString qstrkeyname,QVariant qvarvalue)
|
||||
void Config::set(QString qstrnodename,QString qstrkeyname,QVariant qvarvalue)
|
||||
{
|
||||
m_psetting->setValue(QString("/%1/%2").arg(qstrnodename).arg(qstrkeyname), qvarvalue);
|
||||
}
|
||||
|
||||
void Config::SetArray(QString qstrnodename,QString qstrkeyname,QVariant qvarvalue)
|
||||
void Config::setArray(QString qstrnodename,QString qstrkeyname,QVariant qvarvalue)
|
||||
{
|
||||
m_psetting->beginWriteArray(QString("/%1/%2").arg(qstrnodename).arg(qstrkeyname));
|
||||
QList<QVariant> list = qvarvalue.toList();
|
||||
|
@ -52,13 +52,13 @@ void Config::SetArray(QString qstrnodename,QString qstrkeyname,QVariant qvarvalu
|
|||
m_psetting->endArray();
|
||||
}
|
||||
|
||||
QVariant Config::Get(QString qstrnodename,QString qstrkeyname)
|
||||
QVariant Config::get(QString qstrnodename,QString qstrkeyname)
|
||||
{
|
||||
QVariant qvar = m_psetting->value(QString("/%1/%2").arg(qstrnodename).arg(qstrkeyname));
|
||||
return qvar;
|
||||
}
|
||||
|
||||
QVariant Config::GetArray(QString qstrnodename,QString qstrkeyname)
|
||||
QVariant Config::getArray(QString qstrnodename,QString qstrkeyname)
|
||||
{
|
||||
QList<QVariant> list;
|
||||
int size = m_psetting->beginReadArray(QString("/%1/%2").arg(qstrnodename).arg(qstrkeyname));
|
||||
|
|
|
@ -31,9 +31,6 @@ int main(int argc, char *argv[])
|
|||
QList<int> verl = {PROTOCOLPARSER_VERSION};
|
||||
QString version = QString::number(verl[0])+'.'+QString::number(verl[1])+'.'+QString::number(verl[2]);
|
||||
engine.rootContext()->setContextProperty("PPAPP_Version",version);
|
||||
#ifdef RIBBONUI_BUILD_STATIC_LIB
|
||||
engine.addImportPath("qrc:/");
|
||||
#endif
|
||||
const QUrl url(u"qrc:/qt/qml/ProtocolParser/Main.qml"_qs);
|
||||
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
|
||||
&app, [url](QObject *obj, const QUrl &objUrl) {
|
||||
|
|
|
@ -5,20 +5,18 @@ using namespace zigbee_protocol;
|
|||
|
||||
Protocol::Protocol(){
|
||||
_config = Config::instance();
|
||||
if (_config->Get("Protocol","hmac_verify_key").toString().isEmpty())
|
||||
_config->Set("Protocol","hmac_verify_key",hmac_verify_key);
|
||||
if (_config->get("Protocol","hmac_verify_key").toString().isEmpty())
|
||||
_config->set("Protocol","hmac_verify_key",hmac_verify_key);
|
||||
else
|
||||
hmac_verify_key = _config->Get("Protocol","hmac_verify_key").toString();
|
||||
if (_config->GetArray("Protocol","pre_hmac_verify_key").toStringList().isEmpty())
|
||||
_config->SetArray("Protocol","pre_hmac_verify_key",pre_hmac_verify_key);
|
||||
hmac_verify_key = _config->get("Protocol","hmac_verify_key").toString();
|
||||
if (_config->getArray("Protocol","pre_hmac_verify_key").toStringList().isEmpty())
|
||||
_config->setArray("Protocol","pre_hmac_verify_key",pre_hmac_verify_key);
|
||||
else
|
||||
pre_hmac_verify_key = _config->GetArray("Protocol","pre_hmac_verify_key").toStringList();
|
||||
pre_hmac_verify_key = _config->getArray("Protocol","pre_hmac_verify_key").toStringList();
|
||||
}
|
||||
|
||||
Protocol::~Protocol()
|
||||
{
|
||||
_config->Set("Protocol","hmac_verify_key",hmac_verify_key);
|
||||
_config->SetArray("Protocol","pre_hmac_verify_key",pre_hmac_verify_key);
|
||||
}
|
||||
|
||||
Protocol* Protocol::getInstance()
|
||||
|
|
|
@ -221,6 +221,7 @@ void ZigBeeDataResolver::des_port_parser(zigbee_protocol::ZigbeeFrame &zframe, b
|
|||
QJsonObject object;
|
||||
if (node->first.verified)
|
||||
{
|
||||
QString note_text;
|
||||
new_data_frame(72) ndata;
|
||||
uint8_t data_len = 0;
|
||||
memset(&ndata,0,sizeof(ndata));
|
||||
|
@ -231,7 +232,7 @@ void ZigBeeDataResolver::des_port_parser(zigbee_protocol::ZigbeeFrame &zframe, b
|
|||
object.insert("type","zigbee_recv_data");
|
||||
if (*(u16 *)frame == CRYPTO_ZDATA_FRAME_HEAD)
|
||||
{
|
||||
QString note_text = "解密数据为按照未加密传输重新打包的原始数据,因此数据长度会有差异\n";
|
||||
note_text = "解密数据为按照未加密传输重新打包的原始数据,因此数据长度会有差异\n";
|
||||
new_base_frame(sizeof(ndata)) nbframe;
|
||||
memcpy(&nbframe, bframe, BASE_FRAME_PREFIX_LEN);
|
||||
zigbee_protocol::ZigbeeFrame nzframe = zframe;
|
||||
|
@ -242,21 +243,30 @@ void ZigBeeDataResolver::des_port_parser(zigbee_protocol::ZigbeeFrame &zframe, b
|
|||
nzframe.setData((char*)&nbframe,nbframe.length);
|
||||
zdata = QByteArray((char *)nzframe.data(), nzframe.size());
|
||||
object.insert("decrypted_text", QJsonValue(QString(zdata.toHex(' ').toUpper())));
|
||||
switch (ndata.type) {
|
||||
case SENSOR_DATA_TYPE:
|
||||
ddata = (data_frame*)&ndata;
|
||||
}
|
||||
else{
|
||||
ddata = (data_frame*)frame;
|
||||
}
|
||||
switch (ddata->type) {
|
||||
case SENSOR_DATA_TYPE:
|
||||
{
|
||||
QStringList name_list, type_list;
|
||||
name_list = Config::instance()->getArray("Protocol", "data_frame_name").toStringList();
|
||||
type_list = Config::instance()->getArray("Protocol", "data_frame_type").toStringList();
|
||||
if (!name_list.length())
|
||||
break;
|
||||
note_text += "传感器数据:";
|
||||
void* pdata = (void *)ddata->data;
|
||||
for (uint8_t i = 0; i < name_list.length(); i++)
|
||||
{
|
||||
note_text += "传感器数据:";
|
||||
sensor_data* sdata = (sensor_data*)ndata.data;
|
||||
note_text += "PPM:" + QString::number(sdata->ppm) + ' ';
|
||||
note_text += "Temperature:" + QString::number(sdata->temp) + ' ';
|
||||
note_text += "Humidity:" + QString::number(sdata->humi) + ' ';
|
||||
note_text += "Flare:" + QString::number(sdata->flare) + ' ';
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
note_text += name_list[i]+ ":" + sensor_data_reader(&pdata,type_list[i]) + ' ';
|
||||
}
|
||||
object.insert("note_text",QJsonValue(note_text));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (QRandomGenerator::global()->bounded(2)!=0 && is_demo)
|
||||
object.insert("decrypted_text", QJsonValue(QString(zdata.toHex(' ').toUpper())));
|
||||
|
@ -353,3 +363,59 @@ void ZigBeeDataResolver::message_parser(QJsonObject message, QString self_addr)
|
|||
data_parser(zf, message["type"] == "demo_recv_data");
|
||||
}
|
||||
}
|
||||
|
||||
QString ZigBeeDataResolver::sensor_data_reader(void **data,QString type)
|
||||
{
|
||||
QString d;
|
||||
uint8_t** pdata = (uint8_t**)(data);
|
||||
if (type.contains("64"))
|
||||
{
|
||||
if(type.contains("u"))
|
||||
d = QString::number(*(uint64_t*)(*data));
|
||||
else
|
||||
d = QString::number(*(int64_t*)(*data));
|
||||
*pdata += sizeof(uint64_t);
|
||||
return d;
|
||||
}
|
||||
else if (type.contains("32"))
|
||||
{
|
||||
if(type.contains("u"))
|
||||
d = QString::number(*(uint32_t*)(*data));
|
||||
else
|
||||
d = QString::number(*(int32_t*)(*data));
|
||||
*pdata += sizeof(uint32_t);
|
||||
return d;
|
||||
}
|
||||
else if (type.contains("16"))
|
||||
{
|
||||
if(type.contains("u"))
|
||||
d = QString::number(*(uint16_t*)(*data));
|
||||
else
|
||||
d = QString::number(*(int16_t*)(*data));
|
||||
*pdata += sizeof(uint16_t);
|
||||
return d;
|
||||
}
|
||||
else if (type.contains("8"))
|
||||
{
|
||||
if(type.contains("u"))
|
||||
d = QString::number(*(uint8_t*)(*data));
|
||||
else
|
||||
d = QString::number(*(int8_t*)(*data));
|
||||
*pdata += sizeof(uint8_t);
|
||||
return d;
|
||||
}
|
||||
else if (type=="float")
|
||||
{
|
||||
d = QString::number(*(float*)(*data), 'g', 1);
|
||||
*pdata += sizeof(float);
|
||||
return d;
|
||||
}
|
||||
else if (type=="double")
|
||||
{
|
||||
d = QString::number(*(double*)(*data), 'g', 1);
|
||||
*pdata += sizeof(double);
|
||||
return d;
|
||||
}
|
||||
else
|
||||
return d;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue