更新为通过json文件定义解码,详细配置见json文件
parent
63b9f7d141
commit
33ab44bd08
|
@ -67,7 +67,7 @@ void CustomDisplayPanel::Build()
|
||||||
//" font-family: 'Alimama DongFangDaKai';" // 需确保字体已加载
|
//" font-family: 'Alimama DongFangDaKai';" // 需确保字体已加载
|
||||||
" font-family: 'Arial';"
|
" font-family: 'Arial';"
|
||||||
" font-size: 20px;"
|
" font-size: 20px;"
|
||||||
" color: #13396E;"
|
" color: #20549E;"
|
||||||
" font-weight: bold;"
|
" font-weight: bold;"
|
||||||
" font-style: black;"
|
" font-style: black;"
|
||||||
"}"
|
"}"
|
||||||
|
@ -139,6 +139,8 @@ void CustomDisplayPanel::Build()
|
||||||
tableWidget->setShowGrid(true); // 默认显示网格线[3](@ref)
|
tableWidget->setShowGrid(true); // 默认显示网格线[3](@ref)
|
||||||
tableWidget->setStyleSheet("QTableWidget { gridline-color: #e0e0e0; background-color: white; border-radius: 10px;}");
|
tableWidget->setStyleSheet("QTableWidget { gridline-color: #e0e0e0; background-color: white; border-radius: 10px;}");
|
||||||
|
|
||||||
|
tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||||
|
|
||||||
// **应用阴影效果**
|
// **应用阴影效果**
|
||||||
QGraphicsDropShadowEffect *shadowTable = new QGraphicsDropShadowEffect(this);
|
QGraphicsDropShadowEffect *shadowTable = new QGraphicsDropShadowEffect(this);
|
||||||
shadowTable->setBlurRadius(10);
|
shadowTable->setBlurRadius(10);
|
||||||
|
@ -169,7 +171,7 @@ void CustomDisplayPanel::UpdateData(OpenJson& json)
|
||||||
void CustomDisplayPanel::UpdateTemperature(OpenJson &json)
|
void CustomDisplayPanel::UpdateTemperature(OpenJson &json)
|
||||||
{
|
{
|
||||||
auto& nodeLabel = json["text_panel"];
|
auto& nodeLabel = json["text_panel"];
|
||||||
qDebug() << nodeLabel.size();
|
qDebug() << "text_panel: " << nodeLabel.size();
|
||||||
for(size_t i=0; i<nodeLabel.size(); i++)
|
for(size_t i=0; i<nodeLabel.size(); i++)
|
||||||
{
|
{
|
||||||
auto& node = nodeLabel[i];
|
auto& node = nodeLabel[i];
|
||||||
|
@ -180,10 +182,32 @@ void CustomDisplayPanel::UpdateTemperature(OpenJson &json)
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
{
|
{
|
||||||
if (value == "1")
|
if (value == "1")
|
||||||
|
{
|
||||||
disp = QString("Online");
|
disp = QString("Online");
|
||||||
|
m_txtLabels[i]->setStyleSheet(
|
||||||
|
"QLabel {"
|
||||||
|
//" font-family: 'Alimama DongFangDaKai';" // 需确保字体已加载
|
||||||
|
" font-family: 'Arial';"
|
||||||
|
" font-size: 20px;"
|
||||||
|
" color: #2E86C1;"
|
||||||
|
" font-weight: bold;"
|
||||||
|
"}"
|
||||||
|
);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
disp = QString("Offline");
|
disp = QString("Offline");
|
||||||
|
m_txtLabels[i]->setStyleSheet(
|
||||||
|
"QLabel {"
|
||||||
|
//" font-family: 'Alimama DongFangDaKai';" // 需确保字体已加载
|
||||||
|
" font-family: 'Arial';"
|
||||||
|
" font-size: 20px;"
|
||||||
|
" color: #FF0000;"
|
||||||
|
" font-weight: bold;"
|
||||||
|
" font-style: black"
|
||||||
|
"}"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -193,7 +217,7 @@ void CustomDisplayPanel::UpdateTemperature(OpenJson &json)
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& nodeTable = json["table"];
|
auto& nodeTable = json["table"];
|
||||||
qDebug() << nodeTable.size();
|
qDebug() << "table: "<< nodeTable.size();
|
||||||
|
|
||||||
m_pTableWidget->clear();
|
m_pTableWidget->clear();
|
||||||
m_pTableWidget->setRowCount(nodeTable.size());
|
m_pTableWidget->setRowCount(nodeTable.size());
|
||||||
|
@ -255,6 +279,8 @@ void CustomDisplayPanel::UpdateAlarm(OpenJson &json)
|
||||||
|
|
||||||
auto& nodeTable = json["alarm"];
|
auto& nodeTable = json["alarm"];
|
||||||
qDebug() << nodeTable.size();
|
qDebug() << nodeTable.size();
|
||||||
|
|
||||||
|
m_pTableWidget->setUpdatesEnabled(false);
|
||||||
for(size_t i=0; i<nodeTable.size(); i++)
|
for(size_t i=0; i<nodeTable.size(); i++)
|
||||||
{
|
{
|
||||||
m_pTableWidget->insertRow(0);
|
m_pTableWidget->insertRow(0);
|
||||||
|
@ -280,6 +306,22 @@ void CustomDisplayPanel::UpdateAlarm(OpenJson &json)
|
||||||
m_pTableWidget->setItem(0, 1, item1);
|
m_pTableWidget->setItem(0, 1, item1);
|
||||||
m_pTableWidget->setItem(0, 2, item2);
|
m_pTableWidget->setItem(0, 2, item2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_pTableWidget->setUpdatesEnabled(true);
|
||||||
|
|
||||||
|
// 自动定位到首行
|
||||||
|
if(m_pTableWidget->rowCount() > 0)
|
||||||
|
{
|
||||||
|
// 创建首行索引
|
||||||
|
QModelIndex firstIndex = m_pTableWidget->model()->index(0, 0);
|
||||||
|
|
||||||
|
// 滚动到首行并置顶
|
||||||
|
m_pTableWidget->scrollTo(firstIndex, QAbstractItemView::PositionAtTop);
|
||||||
|
|
||||||
|
// 选中整行(需提前设置选择模式)
|
||||||
|
m_pTableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||||
|
m_pTableWidget->setCurrentIndex(firstIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////
|
////////
|
||||||
|
|
|
@ -1,67 +1,36 @@
|
||||||
;通用设置
|
|
||||||
[version]
|
[version]
|
||||||
ver="1_0_0"
|
ver=1_0_0
|
||||||
|
|
||||||
[modbus]
|
[modbus]
|
||||||
;1=RTU 0=TCP
|
|
||||||
type=1
|
type=1
|
||||||
|
ip=127.0.0.1
|
||||||
;if type=1, ignore ip and port setting
|
|
||||||
ip="127.0.0.1"
|
|
||||||
port=502
|
port=502
|
||||||
|
com=COM20
|
||||||
com="COM20"
|
|
||||||
baund=9600
|
baund=9600
|
||||||
data=8
|
data=8
|
||||||
|
|
||||||
;0=None 1=Odd 2=Even
|
|
||||||
parity=0
|
parity=0
|
||||||
|
|
||||||
stop=1
|
stop=1
|
||||||
|
|
||||||
[slaves]
|
[slaves]
|
||||||
;如果从机数量多于1,则从机地址slave_id以:分隔(英文冒号)
|
slave_id=1
|
||||||
slave_id="1"
|
|
||||||
|
|
||||||
;每一个从机的配置
|
|
||||||
;由两个节组成:slave_%d 和 slave_%d_function_%d
|
|
||||||
|
|
||||||
[slave_1]
|
[slave_1]
|
||||||
;支持的功能码数量
|
|
||||||
function_code_counts=2
|
function_code_counts=2
|
||||||
|
|
||||||
[slave_1_function_0]
|
[slave_1_function_0]
|
||||||
;功能码
|
|
||||||
function_code=3
|
function_code=3
|
||||||
|
|
||||||
;起始地址,10进制
|
|
||||||
start_addr=40000
|
start_addr=40000
|
||||||
|
|
||||||
;读取数量
|
|
||||||
quantity=9
|
quantity=9
|
||||||
|
|
||||||
;扫描间隔,单位ms
|
|
||||||
interval=1000
|
interval=1000
|
||||||
|
|
||||||
;serial_number与read_quantity的元素数量要一样
|
|
||||||
equipment_code=81
|
equipment_code=81
|
||||||
serial_number="0:1:2:3:4:5:6:7:8:9:10:11:12:13:14"
|
serial_number=0:1:2:3:4:5:6:7:8:9:10:11:12:13:14
|
||||||
read_quantity="1:1:1:1:1:1:1:1:1:1:1:1:1:1:1"
|
read_quantity=1:1:1:1:1:1:1:1:1:1:1:1:1:1:1
|
||||||
|
|
||||||
[slave_1_function_1]
|
[slave_1_function_1]
|
||||||
;功能码
|
|
||||||
function_code=3
|
function_code=3
|
||||||
|
|
||||||
;起始地址,10进制
|
|
||||||
start_addr=40009
|
start_addr=40009
|
||||||
|
|
||||||
;读取数量
|
|
||||||
quantity=6
|
quantity=6
|
||||||
|
|
||||||
;扫描间隔,单位ms
|
|
||||||
interval=1000
|
interval=1000
|
||||||
|
|
||||||
;serial_number与read_quantity的元素数量要一样
|
|
||||||
equipment_code=81
|
equipment_code=81
|
||||||
serial_number="0:1:2:3:4:5:6:7:8:9:10:11:12:13:14"
|
serial_number=0:1:2:3:4:5:6:7:8:9:10:11:12:13:14
|
||||||
read_quantity="1:1:1:1:1:1:1:1:1:1:1:1:1:1:1"
|
read_quantity=1:1:1:1:1:1:1:1:1:1:1:1:1:1:1
|
||||||
|
|
|
@ -0,0 +1,191 @@
|
||||||
|
{
|
||||||
|
"modbus":
|
||||||
|
{
|
||||||
|
"type":"rs485",
|
||||||
|
"port":"COM1",
|
||||||
|
"baudrate":9600,
|
||||||
|
"parity":"N",
|
||||||
|
"stopbits":1,
|
||||||
|
"data":8,
|
||||||
|
"ip":"127.0.0.1",
|
||||||
|
"ip_port":502
|
||||||
|
},
|
||||||
|
"slaves":[
|
||||||
|
{
|
||||||
|
"id":1,
|
||||||
|
"function_code":3,
|
||||||
|
"address":[
|
||||||
|
{
|
||||||
|
"start_addr":40000,
|
||||||
|
"quantity":9,
|
||||||
|
"bytes_per_register":2,
|
||||||
|
"device_name_chn":"温湿度",
|
||||||
|
"device_name_eng":"Temperature",
|
||||||
|
"device_type":1,
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"comment":"在线状态",
|
||||||
|
"order":0,
|
||||||
|
"precision":1,
|
||||||
|
"unit":"",
|
||||||
|
"title_chn":"在线状态",
|
||||||
|
"title_eng":"Online",
|
||||||
|
"display":1,
|
||||||
|
"skip":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"comment":"温度",
|
||||||
|
"order":1,
|
||||||
|
"precision":10,
|
||||||
|
"unit":"℃",
|
||||||
|
"title_chn":"温度",
|
||||||
|
"title_eng":"T (℃) ",
|
||||||
|
"display":1,
|
||||||
|
"skip":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"comment":"湿度",
|
||||||
|
"order":2,
|
||||||
|
"precision":10,
|
||||||
|
"unit":"%",
|
||||||
|
"title_chn":"湿度",
|
||||||
|
"title_eng":"RH (%)",
|
||||||
|
"display":1 ,
|
||||||
|
"skip":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"comment":"露点",
|
||||||
|
"order":3,
|
||||||
|
"precision":1,
|
||||||
|
"unit":"",
|
||||||
|
"title_chn":"露点",
|
||||||
|
"title_eng":"DewPoint",
|
||||||
|
"display":2,
|
||||||
|
"skip":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"comment":"跳过",
|
||||||
|
"order":4,
|
||||||
|
"precision":1,
|
||||||
|
"unit":"",
|
||||||
|
"title_chn":"",
|
||||||
|
"title_eng":"",
|
||||||
|
"display":0,
|
||||||
|
"skip":1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"comment":"跳过",
|
||||||
|
"order":5,
|
||||||
|
"precision":1,
|
||||||
|
"unit":"",
|
||||||
|
"title_chn":"",
|
||||||
|
"title_eng":"",
|
||||||
|
"display":0,
|
||||||
|
"skip":1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"comment":"DO",
|
||||||
|
"order":6,
|
||||||
|
"precision":1,
|
||||||
|
"unit":"",
|
||||||
|
"title_chn":"DO",
|
||||||
|
"title_eng":"DO",
|
||||||
|
"display":2,
|
||||||
|
"skip":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"comment":"DI1",
|
||||||
|
"order":7,
|
||||||
|
"precision":1,
|
||||||
|
"unit":"",
|
||||||
|
"title_chn":"DI1",
|
||||||
|
"title_eng":"DI1",
|
||||||
|
"display":2,
|
||||||
|
"skip":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"comment":"DI2",
|
||||||
|
"order":8,
|
||||||
|
"precision":1,
|
||||||
|
"unit":"",
|
||||||
|
"title_chn":"DI2",
|
||||||
|
"title_eng":"DI2",
|
||||||
|
"display":2,
|
||||||
|
"skip":0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"start_addr":40009,
|
||||||
|
"quantity":6,
|
||||||
|
"bytes_per_register":2,
|
||||||
|
"device_name_chn":"温湿度告警",
|
||||||
|
"device_name_eng":"Alarm",
|
||||||
|
"device_type":6,
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"comment":"温度阈值",
|
||||||
|
"order":0,
|
||||||
|
"precision":10,
|
||||||
|
"unit":"",
|
||||||
|
"title_chn":"温度阈值",
|
||||||
|
"title_eng":"Temp_threshold",
|
||||||
|
"display":0,
|
||||||
|
"skip":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"comment":"温度偏移",
|
||||||
|
"order":1,
|
||||||
|
"precision":1,
|
||||||
|
"unit":"",
|
||||||
|
"title_chn":"温度偏移",
|
||||||
|
"title_eng":"Temp_offset",
|
||||||
|
"display":0,
|
||||||
|
"skip":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"comment":"跳过",
|
||||||
|
"order":2,
|
||||||
|
"precision":1,
|
||||||
|
"unit":"",
|
||||||
|
"title_chn":"",
|
||||||
|
"title_eng":"",
|
||||||
|
"display":0,
|
||||||
|
"skip":1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"comment":"高温告警",
|
||||||
|
"order":3,
|
||||||
|
"precision":1,
|
||||||
|
"unit":"",
|
||||||
|
"title_chn":"高温告警",
|
||||||
|
"title_eng":"High Temp.",
|
||||||
|
"display":1,
|
||||||
|
"skip":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"comment":"高湿告警",
|
||||||
|
"order":4,
|
||||||
|
"precision":1,
|
||||||
|
"unit":"",
|
||||||
|
"title_chn":"高湿告警",
|
||||||
|
"title_eng":"High Humidity",
|
||||||
|
"display":1,
|
||||||
|
"skip":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"comment":"低温告警",
|
||||||
|
"order":5,
|
||||||
|
"precision":1,
|
||||||
|
"unit":"",
|
||||||
|
"title_chn":"低温告警",
|
||||||
|
"title_eng":"Low Temp.",
|
||||||
|
"display":0,
|
||||||
|
"skip":0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -25,6 +25,10 @@
|
||||||
#define TH08D_TEMPERATURE_EQUIPMENT_81_00_09 40000
|
#define TH08D_TEMPERATURE_EQUIPMENT_81_00_09 40000
|
||||||
#define TH08D_TEMPERATURE_EQUIPMENT_81_09_06 40009
|
#define TH08D_TEMPERATURE_EQUIPMENT_81_09_06 40009
|
||||||
|
|
||||||
|
void DecodeWorker::setSlaveAddress(const slaveAddress& sa)
|
||||||
|
{
|
||||||
|
m_slaveAddress = sa;
|
||||||
|
}
|
||||||
// 处理数组的槽函数
|
// 处理数组的槽函数
|
||||||
void DecodeWorker::processArray(const QVector<uint16_t>& array,int slave_id,int start_addr,int quantity,DeviceData* pData)
|
void DecodeWorker::processArray(const QVector<uint16_t>& array,int slave_id,int start_addr,int quantity,DeviceData* pData)
|
||||||
{
|
{
|
||||||
|
@ -88,6 +92,31 @@ void DecodeWorker::processArray(const QVector<uint16_t>& array,int slave_id,int
|
||||||
emit finished();
|
emit finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DecodeWorker::processRegisterData(const QVector<uint16_t> &array, const slaveAddress& sa, DeviceData *pData)
|
||||||
|
{
|
||||||
|
GeneralDeviceData* pGeneralData = (GeneralDeviceData*)pData;
|
||||||
|
RegisterDataItems::const_iterator iter = sa.register_data_items.begin();
|
||||||
|
int idx = 0;
|
||||||
|
for(; iter!=sa.register_data_items.end(); iter++)
|
||||||
|
{
|
||||||
|
if (iter->second.skip ==0)
|
||||||
|
{
|
||||||
|
DisplayDataItem ddi;
|
||||||
|
ddi.device_type = sa.device_type;
|
||||||
|
ddi.display_location = iter->second.display;
|
||||||
|
ddi.order = iter->second.order;
|
||||||
|
ddi.precision = iter->second.precision;
|
||||||
|
ddi.title = iter->second.title_chn;
|
||||||
|
ddi.unit = iter->second.unit;
|
||||||
|
ddi.value = array[idx];
|
||||||
|
pGeneralData->m_PanelDisplayDataItems.emplace_back(ddi);
|
||||||
|
}
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget *parent)
|
MainWindow::MainWindow(QWidget *parent)
|
||||||
: QMainWindow(parent)
|
: QMainWindow(parent)
|
||||||
, ui(new Ui::MainWindow)
|
, ui(new Ui::MainWindow)
|
||||||
|
@ -153,6 +182,7 @@ void MainWindow::getConfiguration(QString iniFilePath)
|
||||||
m_modbus_parity = m_pSettings->value("modbus/parity").toInt();
|
m_modbus_parity = m_pSettings->value("modbus/parity").toInt();
|
||||||
m_modbus_stop = m_pSettings->value("modbus/stop").toInt();
|
m_modbus_stop = m_pSettings->value("modbus/stop").toInt();
|
||||||
|
|
||||||
|
#if 0
|
||||||
m_modbus_slave_id = m_pSettings->value("slaves/slave_id").toInt();
|
m_modbus_slave_id = m_pSettings->value("slaves/slave_id").toInt();
|
||||||
|
|
||||||
QString app = QString("slave_%1/function_code_counts").arg(m_modbus_slave_id);
|
QString app = QString("slave_%1/function_code_counts").arg(m_modbus_slave_id);
|
||||||
|
@ -202,6 +232,61 @@ void MainWindow::getConfiguration(QString iniFilePath)
|
||||||
m_SlaveData.push_back(pSlaveData);
|
m_SlaveData.push_back(pSlaveData);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::ReadConfiguration(QString jsonFilePath)
|
||||||
|
{
|
||||||
|
OpenJson json;
|
||||||
|
json.decodeFile(jsonFilePath.toStdString());
|
||||||
|
auto& nodeSlaves = json["slaves"];
|
||||||
|
qDebug() << nodeSlaves.size();
|
||||||
|
|
||||||
|
|
||||||
|
for (size_t i = 0; i < nodeSlaves.size(); i++)
|
||||||
|
{
|
||||||
|
auto& node = nodeSlaves[i];
|
||||||
|
|
||||||
|
slaveItem slave_item;
|
||||||
|
|
||||||
|
slave_item.slave_id = node["id"].i32();
|
||||||
|
slave_item.function_code = node["function_code"].i32();
|
||||||
|
|
||||||
|
auto& nodeAddress = node["address"];
|
||||||
|
for (size_t j = 0; j < nodeAddress.size(); j++)
|
||||||
|
{
|
||||||
|
auto& nodeAddrItem = nodeAddress[j];
|
||||||
|
|
||||||
|
slaveAddress address_item;
|
||||||
|
address_item.start_addr = nodeAddrItem["start_addr"].i32();
|
||||||
|
address_item.quantity = nodeAddrItem["quantity"].i32();
|
||||||
|
address_item.bytes_per_register = nodeAddrItem["bytes_per_register"].i32();
|
||||||
|
address_item.device_name_chn = nodeAddrItem["device_name_chn"].s();
|
||||||
|
address_item.device_name_eng = nodeAddrItem["device_name_eng"].s();
|
||||||
|
address_item.device_type = nodeAddrItem["device_type"].i32();
|
||||||
|
auto& nodeData = nodeAddrItem["data"];
|
||||||
|
for (size_t k = 0; k < nodeData.size(); k++)
|
||||||
|
{
|
||||||
|
auto& nodeRegister = nodeData[k];
|
||||||
|
|
||||||
|
registryData rdata;
|
||||||
|
rdata.comment = nodeRegister["comment"].s();
|
||||||
|
rdata.order = nodeRegister["order"].i32();
|
||||||
|
rdata.precision = (float)nodeRegister["precision"].d();
|
||||||
|
rdata.unit = nodeRegister["unit"].s();
|
||||||
|
rdata.title_chn = nodeRegister["title_chn"].s();
|
||||||
|
rdata.title_en = nodeRegister["title_eng"].s();
|
||||||
|
rdata.display = nodeRegister["display"].i32();
|
||||||
|
rdata.skip = nodeRegister["skip"].i32();
|
||||||
|
|
||||||
|
address_item.register_data_items.insert(std::make_pair(rdata.order,rdata));
|
||||||
|
}
|
||||||
|
|
||||||
|
slave_item.slave_address_items.emplace_back(address_item);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_total_slave_items.emplace_back(slave_item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MainWindow::InitializeUI()
|
bool MainWindow::InitializeUI()
|
||||||
|
@ -249,10 +334,12 @@ bool MainWindow::InitializeUI()
|
||||||
m_pTemperaturePanel->Build();
|
m_pTemperaturePanel->Build();
|
||||||
mainLayout->addWidget(m_pTemperaturePanel, 0, 0);
|
mainLayout->addWidget(m_pTemperaturePanel, 0, 0);
|
||||||
|
|
||||||
|
m_Panels.insert(std::make_pair(CustomDisplayPanel::PANEL_TEMPERATURE,m_pTemperaturePanel));
|
||||||
|
|
||||||
//电源
|
//电源
|
||||||
m_pPowerPanel = new CustomDisplayPanel(this);
|
m_pPowerPanel = new CustomDisplayPanel(this);
|
||||||
m_pPowerPanel->setImage(":/icons/main_power.png");
|
m_pPowerPanel->setImage(":/icons/main_power.png");
|
||||||
QStringList l2{QStringList{tr("Online"),tr("Input Voltage"),tr("Output Voltage"),tr("Output Current"),tr("Module Temp.")}};
|
QStringList l2{QStringList{tr("Online"),tr("Vin."),tr("Vout"),tr("Iout"),tr("T_mod")}};
|
||||||
m_pPowerPanel->setLableCount(l2.count());
|
m_pPowerPanel->setLableCount(l2.count());
|
||||||
m_pPowerPanel->setTableRowsCount(10);
|
m_pPowerPanel->setTableRowsCount(10);
|
||||||
m_pPowerPanel->setLables(l2);
|
m_pPowerPanel->setLables(l2);
|
||||||
|
@ -261,10 +348,12 @@ bool MainWindow::InitializeUI()
|
||||||
m_pPowerPanel->Build();
|
m_pPowerPanel->Build();
|
||||||
mainLayout->addWidget(m_pPowerPanel, 0, 1);
|
mainLayout->addWidget(m_pPowerPanel, 0, 1);
|
||||||
|
|
||||||
|
m_Panels.insert(std::make_pair(CustomDisplayPanel::PANEL_POWER,m_pPowerPanel));
|
||||||
|
|
||||||
//电池
|
//电池
|
||||||
m_pBatteryPanel = new CustomDisplayPanel(this);
|
m_pBatteryPanel = new CustomDisplayPanel(this);
|
||||||
m_pBatteryPanel->setImage(":/icons/main_battery.png");
|
m_pBatteryPanel->setImage(":/icons/main_battery.png");
|
||||||
QStringList l3{QStringList{tr("Online"),tr("SOC"),tr("SOH"),tr("Group Voltage"),tr("Cell V.Avg"),tr("Cell V.Max"),tr("Cell V.Min")}};
|
QStringList l3{QStringList{tr("Online"),tr("SOC"),tr("SOH"),tr("Vpack")}};
|
||||||
m_pBatteryPanel->setLableCount(l3.count());
|
m_pBatteryPanel->setLableCount(l3.count());
|
||||||
m_pBatteryPanel->setTableRowsCount(10);
|
m_pBatteryPanel->setTableRowsCount(10);
|
||||||
m_pBatteryPanel->setLables(l3);
|
m_pBatteryPanel->setLables(l3);
|
||||||
|
@ -273,6 +362,8 @@ bool MainWindow::InitializeUI()
|
||||||
m_pBatteryPanel->Build();
|
m_pBatteryPanel->Build();
|
||||||
mainLayout->addWidget(m_pBatteryPanel, 0, 2);
|
mainLayout->addWidget(m_pBatteryPanel, 0, 2);
|
||||||
|
|
||||||
|
m_Panels.insert(std::make_pair(CustomDisplayPanel::PANEL_BATTERY,m_pBatteryPanel));
|
||||||
|
|
||||||
//空调
|
//空调
|
||||||
m_pACPanel = new CustomDisplayPanel(this);
|
m_pACPanel = new CustomDisplayPanel(this);
|
||||||
m_pACPanel->setImage(":/icons/main_ac.png");
|
m_pACPanel->setImage(":/icons/main_ac.png");
|
||||||
|
@ -285,10 +376,12 @@ bool MainWindow::InitializeUI()
|
||||||
m_pACPanel->Build();
|
m_pACPanel->Build();
|
||||||
mainLayout->addWidget(m_pACPanel, 0, 3);
|
mainLayout->addWidget(m_pACPanel, 0, 3);
|
||||||
|
|
||||||
|
m_Panels.insert(std::make_pair(CustomDisplayPanel::PANEL_AC,m_pACPanel));
|
||||||
|
|
||||||
//交流配电
|
//交流配电
|
||||||
m_pInverterPanel = new CustomDisplayPanel(this);
|
m_pInverterPanel = new CustomDisplayPanel(this);
|
||||||
m_pInverterPanel->setImage(":/icons/main_invertor.png");
|
m_pInverterPanel->setImage(":/icons/main_invertor.png");
|
||||||
QStringList l5{QStringList{tr("Online"),tr("Input Voltage"),tr("Input Current"),tr("Module Temp.")}};
|
QStringList l5{QStringList{tr("Online"),tr("Vin"),tr("Iin"),tr("T_mod")}};
|
||||||
m_pInverterPanel->setLableCount(l5.count());
|
m_pInverterPanel->setLableCount(l5.count());
|
||||||
m_pInverterPanel->setTableRowsCount(10);
|
m_pInverterPanel->setTableRowsCount(10);
|
||||||
m_pInverterPanel->setLables(l5);
|
m_pInverterPanel->setLables(l5);
|
||||||
|
@ -297,10 +390,12 @@ bool MainWindow::InitializeUI()
|
||||||
m_pInverterPanel->Build();
|
m_pInverterPanel->Build();
|
||||||
mainLayout->addWidget(m_pInverterPanel, 1, 0);
|
mainLayout->addWidget(m_pInverterPanel, 1, 0);
|
||||||
|
|
||||||
|
m_Panels.insert(std::make_pair(CustomDisplayPanel::PANEL_INVERTER,m_pInverterPanel));
|
||||||
|
|
||||||
//PV太阳能
|
//PV太阳能
|
||||||
m_pPVPanel = new CustomDisplayPanel(this);
|
m_pPVPanel = new CustomDisplayPanel(this);
|
||||||
m_pPVPanel->setImage(":/icons/main_pv.png");
|
m_pPVPanel->setImage(":/icons/main_pv.png");
|
||||||
QStringList l6{QStringList{tr("Online"),tr("Output Voltage"),tr("Output Current"),tr("Module Temp.")}};
|
QStringList l6{QStringList{tr("Online"),tr("Vout"),tr("Iout"),tr("T_mod")}};
|
||||||
m_pPVPanel->setLableCount(l6.count());
|
m_pPVPanel->setLableCount(l6.count());
|
||||||
m_pPVPanel->setTableRowsCount(10);
|
m_pPVPanel->setTableRowsCount(10);
|
||||||
m_pPVPanel->setLables(l6);
|
m_pPVPanel->setLables(l6);
|
||||||
|
@ -309,10 +404,12 @@ bool MainWindow::InitializeUI()
|
||||||
m_pPVPanel->Build();
|
m_pPVPanel->Build();
|
||||||
mainLayout->addWidget(m_pPVPanel, 1, 1);
|
mainLayout->addWidget(m_pPVPanel, 1, 1);
|
||||||
|
|
||||||
|
m_Panels.insert(std::make_pair(CustomDisplayPanel::PANEL_PV,m_pPVPanel));
|
||||||
|
|
||||||
//门禁
|
//门禁
|
||||||
m_pHomePanel = new CustomDisplayPanel(this);
|
m_pHomePanel = new CustomDisplayPanel(this);
|
||||||
m_pHomePanel->setImage(":/icons/main_cab.png");
|
m_pHomePanel->setImage(":/icons/main_cab.png");
|
||||||
QStringList l7{QStringList{tr("Online"),tr("Output Voltage"),tr("Output Current"),tr("Module Temp.")}};
|
QStringList l7{QStringList{tr("Online"),tr("Vout"),tr("Iout"),tr("T_mod")}};
|
||||||
m_pHomePanel->setLableCount(l7.count());
|
m_pHomePanel->setLableCount(l7.count());
|
||||||
m_pHomePanel->setTableRowsCount(10);
|
m_pHomePanel->setTableRowsCount(10);
|
||||||
m_pHomePanel->setLables(l7);
|
m_pHomePanel->setLables(l7);
|
||||||
|
@ -321,6 +418,8 @@ bool MainWindow::InitializeUI()
|
||||||
m_pHomePanel->Build();
|
m_pHomePanel->Build();
|
||||||
mainLayout->addWidget(m_pHomePanel, 1, 2);
|
mainLayout->addWidget(m_pHomePanel, 1, 2);
|
||||||
|
|
||||||
|
m_Panels.insert(std::make_pair(CustomDisplayPanel::PANEL_HOME,m_pHomePanel));
|
||||||
|
|
||||||
//告警
|
//告警
|
||||||
m_pAlarmPanel = new CustomWarningPanel(this);
|
m_pAlarmPanel = new CustomWarningPanel(this);
|
||||||
m_pAlarmPanel->setImage(":/icons/main_alarm.png");
|
m_pAlarmPanel->setImage(":/icons/main_alarm.png");
|
||||||
|
@ -334,6 +433,8 @@ bool MainWindow::InitializeUI()
|
||||||
m_pAlarmPanel->Build();
|
m_pAlarmPanel->Build();
|
||||||
mainLayout->addWidget(m_pAlarmPanel, 1, 3);
|
mainLayout->addWidget(m_pAlarmPanel, 1, 3);
|
||||||
|
|
||||||
|
m_Panels.insert(std::make_pair(CustomDisplayPanel::PANEL_ALARM,m_pAlarmPanel));
|
||||||
|
|
||||||
// 设置布局的间距和边距
|
// 设置布局的间距和边距
|
||||||
mainLayout->setSpacing(5);
|
mainLayout->setSpacing(5);
|
||||||
//mainLayout->setContentsMargins(10, 40, 10, 10); // 顶部留出工具栏空间
|
//mainLayout->setContentsMargins(10, 40, 10, 10); // 顶部留出工具栏空间
|
||||||
|
@ -364,11 +465,7 @@ bool MainWindow::InitializeUI()
|
||||||
QPixmap pixmap(":/icons/logo-en.png"); // 替换为实际图片路径
|
QPixmap pixmap(":/icons/logo-en.png"); // 替换为实际图片路径
|
||||||
logoLabel->setPixmap(pixmap.scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
logoLabel->setPixmap(pixmap.scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||||||
toolBar->addWidget(logoLabel);
|
toolBar->addWidget(logoLabel);
|
||||||
toolBar->addSeparator();
|
//toolBar->addSeparator();
|
||||||
|
|
||||||
//添加按钮
|
|
||||||
toolBar->addAction(actionRead);
|
|
||||||
toolBar->addSeparator();
|
|
||||||
|
|
||||||
// 添加间隔控件
|
// 添加间隔控件
|
||||||
QWidget *spacer = new QWidget();
|
QWidget *spacer = new QWidget();
|
||||||
|
@ -388,6 +485,7 @@ bool MainWindow::InitializeUI()
|
||||||
//customFont.setBold(true);
|
//customFont.setBold(true);
|
||||||
//label->setFont(customFont);
|
//label->setFont(customFont);
|
||||||
//label->setStyleSheet("color: #2E86C1;");
|
//label->setStyleSheet("color: #2E86C1;");
|
||||||
|
|
||||||
label->setStyleSheet(
|
label->setStyleSheet(
|
||||||
"QLabel {"
|
"QLabel {"
|
||||||
//" font-family: 'Alimama DongFangDaKai';" // 需确保字体已加载
|
//" font-family: 'Alimama DongFangDaKai';" // 需确保字体已加载
|
||||||
|
@ -404,6 +502,10 @@ bool MainWindow::InitializeUI()
|
||||||
spacerWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
spacerWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||||
toolBar->addWidget(spacerWidget);
|
toolBar->addWidget(spacerWidget);
|
||||||
|
|
||||||
|
//添加按钮
|
||||||
|
toolBar->addAction(actionRead);
|
||||||
|
toolBar->addSeparator();
|
||||||
|
|
||||||
toolBar->addAction(actionSetting);
|
toolBar->addAction(actionSetting);
|
||||||
toolBar->addSeparator();
|
toolBar->addSeparator();
|
||||||
|
|
||||||
|
@ -429,6 +531,9 @@ bool MainWindow::InitializeModbus()
|
||||||
|
|
||||||
getConfiguration(iniFilePath);
|
getConfiguration(iniFilePath);
|
||||||
|
|
||||||
|
QString jsonFilePath = appDir + QString::fromStdString("/emsshower.json");
|
||||||
|
ReadConfiguration(jsonFilePath);
|
||||||
|
|
||||||
m_bInitializeModbus = true;
|
m_bInitializeModbus = true;
|
||||||
switch (m_modbus_type)
|
switch (m_modbus_type)
|
||||||
{
|
{
|
||||||
|
@ -454,7 +559,7 @@ bool MainWindow::InitializeRtu()
|
||||||
std::string com = std::string("\\\\.\\") + m_modbus_com.toStdString();
|
std::string com = std::string("\\\\.\\") + m_modbus_com.toStdString();
|
||||||
|
|
||||||
m_pModbus = modbus_new_rtu(com.c_str(), m_modbus_baund, 'N', m_modbus_data, m_modbus_stop);
|
m_pModbus = modbus_new_rtu(com.c_str(), m_modbus_baund, 'N', m_modbus_data, m_modbus_stop);
|
||||||
|
#if 1
|
||||||
int slave_id = m_modbus_slave_id;
|
int slave_id = m_modbus_slave_id;
|
||||||
//modbus_set_debug(m_pModbus, true);
|
//modbus_set_debug(m_pModbus, true);
|
||||||
modbus_set_slave(m_pModbus, slave_id); //设置modbus从机地址
|
modbus_set_slave(m_pModbus, slave_id); //设置modbus从机地址
|
||||||
|
@ -468,7 +573,7 @@ bool MainWindow::InitializeRtu()
|
||||||
t.tv_sec=0;
|
t.tv_sec=0;
|
||||||
t.tv_usec=1000000; //设置modbus超时时间为1000毫秒
|
t.tv_usec=1000000; //设置modbus超时时间为1000毫秒
|
||||||
modbus_set_response_timeout(m_pModbus, t.tv_usec,t.tv_usec);
|
modbus_set_response_timeout(m_pModbus, t.tv_usec,t.tv_usec);
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -559,6 +664,75 @@ bool MainWindow::readRegister(int addr,int nb,uint16_t* dest)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MainWindow::readRegister()
|
||||||
|
{
|
||||||
|
if(!InitializeModbus()) //这里有问题,如果是虚拟串口,连接的通常会返回成功
|
||||||
|
{
|
||||||
|
ui->statusbar->showMessage(tr("Failed to open Modbus device,Check modbus connection please!")); //打开MODBUS设备失败,请检查设备连接情况!"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//对每一个slave进行读取
|
||||||
|
//枚举每一个slave id;这里因为实际上只有一个slave,所以实际上只会执行一次循环
|
||||||
|
|
||||||
|
SlaveItems::iterator iter = m_total_slave_items.begin();
|
||||||
|
for(; iter!=m_total_slave_items.end(); iter++)
|
||||||
|
{
|
||||||
|
SlaveAddressItems::iterator iterAddress = iter->slave_address_items.begin();
|
||||||
|
for(; iterAddress!=iter->slave_address_items.end(); iterAddress++)
|
||||||
|
{
|
||||||
|
uint16_t* tab_reg = new uint16_t[iterAddress->quantity];
|
||||||
|
int regs = modbus_read_registers(m_pModbus, iterAddress->start_addr, iterAddress->quantity, tab_reg);
|
||||||
|
|
||||||
|
QVector<uint16_t> registers;
|
||||||
|
for (int i = 0; i < regs; ++i)
|
||||||
|
{
|
||||||
|
registers.push_back(tab_reg[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete []tab_reg;
|
||||||
|
|
||||||
|
DeviceData* pDevice = new GeneralDeviceData();
|
||||||
|
|
||||||
|
DecodeSync(registers, *iterAddress, pDevice);
|
||||||
|
|
||||||
|
OpenJson json;
|
||||||
|
CreateJson2(pDevice,json);
|
||||||
|
|
||||||
|
m_Panels[iterAddress->device_type]->UpdateData(json);
|
||||||
|
|
||||||
|
delete pDevice;
|
||||||
|
|
||||||
|
qDebug() << "decode an item";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::DecodeSync(const QVector<uint16_t>& array,const slaveAddress& sa,DeviceData* pData)
|
||||||
|
{
|
||||||
|
GeneralDeviceData* pGeneralData = (GeneralDeviceData*)pData;
|
||||||
|
RegisterDataItems::const_iterator iter = sa.register_data_items.begin();
|
||||||
|
int idx = 0;
|
||||||
|
for(; iter!=sa.register_data_items.end(); iter++)
|
||||||
|
{
|
||||||
|
if (iter->second.skip ==0)
|
||||||
|
{
|
||||||
|
DisplayDataItem ddi;
|
||||||
|
ddi.device_type = sa.device_type;
|
||||||
|
ddi.display_location = iter->second.display;
|
||||||
|
ddi.order = iter->second.order;
|
||||||
|
ddi.precision = iter->second.precision;
|
||||||
|
ddi.title = iter->second.title_en;
|
||||||
|
ddi.unit = iter->second.unit;
|
||||||
|
ddi.value = array[idx];
|
||||||
|
pGeneralData->m_PanelDisplayDataItems.emplace_back(ddi);
|
||||||
|
}
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::startAsyncProcess(const QVector<uint16_t>& array,int slave_id,int start_addr,int quantity, DeviceData* pDevice)
|
void MainWindow::startAsyncProcess(const QVector<uint16_t>& array,int slave_id,int start_addr,int quantity, DeviceData* pDevice)
|
||||||
{
|
{
|
||||||
QThread* thread = new QThread;
|
QThread* thread = new QThread;
|
||||||
|
@ -595,6 +769,42 @@ void MainWindow::startAsyncProcess(const QVector<uint16_t>& array,int slave_id,i
|
||||||
qDebug() << "同步读取完成";
|
qDebug() << "同步读取完成";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::startAsyncProcess2(const QVector<uint16_t> &array, const slaveAddress& sa,DeviceData *pData)
|
||||||
|
{
|
||||||
|
QThread* thread = new QThread;
|
||||||
|
DecodeWorker* worker = new DecodeWorker;
|
||||||
|
worker->moveToThread(thread);
|
||||||
|
|
||||||
|
worker->setSlaveAddress(sa);
|
||||||
|
|
||||||
|
// 连接线程启动信号和槽函数
|
||||||
|
connect(this, &MainWindow::startProcessing2, worker, &DecodeWorker::processRegisterData);
|
||||||
|
|
||||||
|
// 工作完成后退出线程
|
||||||
|
connect(worker, &DecodeWorker::finished, thread, &QThread::quit);
|
||||||
|
connect(worker, &DecodeWorker::finished, worker, &DecodeWorker::deleteLater);
|
||||||
|
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
|
||||||
|
|
||||||
|
//// 可选:连接进度信号更新UI
|
||||||
|
//connect(worker, &DecodeWorker::progress, this, [](int index)
|
||||||
|
//{
|
||||||
|
// qDebug() << "进度更新,当前处理到索引:" << index;
|
||||||
|
//});
|
||||||
|
|
||||||
|
thread->start();
|
||||||
|
|
||||||
|
QEventLoop loop;
|
||||||
|
QObject::connect(worker, &DecodeWorker::finished, &loop, &QEventLoop::quit);
|
||||||
|
|
||||||
|
// 发射信号传递参数
|
||||||
|
emit startProcessing2(array,sa, pData);
|
||||||
|
|
||||||
|
// 阻塞,等待线程结束
|
||||||
|
loop.exec();
|
||||||
|
|
||||||
|
qDebug() << "同步读取完成";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void MainWindow::ReadSerialPortData()
|
void MainWindow::ReadSerialPortData()
|
||||||
{
|
{
|
||||||
|
@ -608,9 +818,9 @@ void MainWindow::ReadSerialPortData()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_pTimer->setInterval(10000); // 10秒
|
m_pTimer->setInterval(10 * 1000); // 10秒
|
||||||
connect(m_pTimer, &QTimer::timeout, this, &MainWindow::onTimeout);
|
connect(m_pTimer, &QTimer::timeout, this, &MainWindow::onTimeout);
|
||||||
ui->statusbar->showMessage(tr("Begin Readding"));
|
ui->statusbar->showMessage(tr("Begin Reading"));
|
||||||
m_pTimer->start();
|
m_pTimer->start();
|
||||||
onTimeout();
|
onTimeout();
|
||||||
}
|
}
|
||||||
|
@ -618,7 +828,8 @@ void MainWindow::ReadSerialPortData()
|
||||||
|
|
||||||
void MainWindow::onTimeout()
|
void MainWindow::onTimeout()
|
||||||
{
|
{
|
||||||
readRegister(0,0,0);
|
//readRegister(0,0,0);
|
||||||
|
readRegister();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::SettingSerialPort()
|
void MainWindow::SettingSerialPort()
|
||||||
|
@ -633,6 +844,7 @@ void MainWindow::SettingSerialPort()
|
||||||
// QMessageBox::information(this, "Cancel Clicked", "Cancel was clicked!");
|
// QMessageBox::information(this, "Cancel Clicked", "Cancel was clicked!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool MainWindow::CreateJson(DeviceData* pData,OpenJson& json)
|
bool MainWindow::CreateJson(DeviceData* pData,OpenJson& json)
|
||||||
{
|
{
|
||||||
int data_type = pData->m_device_type;
|
int data_type = pData->m_device_type;
|
||||||
|
@ -648,10 +860,10 @@ bool MainWindow::CreateJson(DeviceData* pData,OpenJson& json)
|
||||||
nodeLabel[0]["title"] = "Online";
|
nodeLabel[0]["title"] = "Online";
|
||||||
|
|
||||||
nodeLabel[1]["value"] = pTempData->TempValue;
|
nodeLabel[1]["value"] = pTempData->TempValue;
|
||||||
nodeLabel[1]["title"] = "Temp(℃)";
|
nodeLabel[1]["title"] = "T (℃) ";
|
||||||
|
|
||||||
nodeLabel[2]["value"] = pTempData->HumidityValue;
|
nodeLabel[2]["value"] = pTempData->HumidityValue;
|
||||||
nodeLabel[2]["title"] = "RH (%) ";
|
nodeLabel[2]["title"] = "RH (%)";
|
||||||
|
|
||||||
auto& nodeTable = json["table"];
|
auto& nodeTable = json["table"];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -720,3 +932,64 @@ bool MainWindow::CreateJson(DeviceData* pData,OpenJson& json)
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MainWindow::CreateJson2(DeviceData* pData,OpenJson& json)
|
||||||
|
{
|
||||||
|
assert(pData);
|
||||||
|
GeneralDeviceData* pDevice = (GeneralDeviceData*)pData;
|
||||||
|
DisplayDataItems::const_iterator iter = pDevice->m_PanelDisplayDataItems.begin();
|
||||||
|
|
||||||
|
int idx0=0;
|
||||||
|
int idx1=0;
|
||||||
|
json["panel_type"] = iter->device_type;
|
||||||
|
|
||||||
|
if (iter->device_type == 6) //告警,需要特别处理
|
||||||
|
{
|
||||||
|
|
||||||
|
auto& nodeTable = json["alarm"];
|
||||||
|
for(; iter!=pDevice->m_PanelDisplayDataItems.end(); iter++)
|
||||||
|
{
|
||||||
|
if(iter->display_location == 0)
|
||||||
|
continue;
|
||||||
|
nodeTable[idx0]["time"] = QDateTime::currentDateTime().toString("MM-dd HH:mm:ss").toStdString();
|
||||||
|
nodeTable[idx0]["signal"] = iter->title;
|
||||||
|
nodeTable[idx0]["value"] = iter->value * 1.0f / iter->precision;
|
||||||
|
idx0++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto& nodeLabel = json["text_panel"];
|
||||||
|
auto& nodeTable = json["table"];
|
||||||
|
for(; iter!=pDevice->m_PanelDisplayDataItems.end(); iter++)
|
||||||
|
{
|
||||||
|
if(iter->display_location == 1) //显示在面板
|
||||||
|
{
|
||||||
|
nodeLabel[idx0]["value"] = iter->value * 1.0f / iter->precision;
|
||||||
|
nodeLabel[idx0]["title"] = iter->title;
|
||||||
|
idx0++;
|
||||||
|
}
|
||||||
|
if (iter->display_location == 2) // 显示在表格
|
||||||
|
{
|
||||||
|
if (idx1 == 0)
|
||||||
|
{
|
||||||
|
nodeTable[idx1]["value"] = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss").toStdString();
|
||||||
|
nodeTable[idx1]["signal"] = "Time";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nodeTable[idx1]["value"] = iter->value * 1.0f / iter->precision;
|
||||||
|
nodeTable[idx1]["signal"] = iter->title;
|
||||||
|
}
|
||||||
|
idx1++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string a = json.encode();
|
||||||
|
|
||||||
|
qDebug() << QString::fromStdString(a);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -42,12 +42,15 @@ public:
|
||||||
this->pDevice = pDevice;
|
this->pDevice = pDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setSlaveAddress(const slaveAddress& sa);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QVector<uint16_t> array;
|
QVector<uint16_t> array;
|
||||||
int slave_id;
|
int slave_id;
|
||||||
int start_addr;
|
int start_addr;
|
||||||
int quantity;
|
int quantity;
|
||||||
DeviceData* pDevice;
|
DeviceData* pDevice;
|
||||||
|
slaveAddress m_slaveAddress;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
// 处理进度信号
|
// 处理进度信号
|
||||||
|
@ -59,6 +62,8 @@ public slots:
|
||||||
// 处理数组的槽函数
|
// 处理数组的槽函数
|
||||||
// 根据从机id、开始地址、寄存器数量三个变量进行辨别和解码处理
|
// 根据从机id、开始地址、寄存器数量三个变量进行辨别和解码处理
|
||||||
void processArray(const QVector<uint16_t>& array,int slave_id,int start_addr,int quantity,DeviceData* pData);
|
void processArray(const QVector<uint16_t>& array,int slave_id,int start_addr,int quantity,DeviceData* pData);
|
||||||
|
|
||||||
|
void processRegisterData(const QVector<uint16_t>& array,const slaveAddress& sa,DeviceData* pData);
|
||||||
};
|
};
|
||||||
|
|
||||||
//处理主界面
|
//处理主界面
|
||||||
|
@ -72,12 +77,15 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void getConfiguration(QString iniFilePath);
|
void getConfiguration(QString iniFilePath);
|
||||||
|
void ReadConfiguration(QString jsonFilePath);
|
||||||
bool InitializeUI();
|
bool InitializeUI();
|
||||||
bool InitializeModbus();
|
bool InitializeModbus();
|
||||||
bool InitializeRtu();
|
bool InitializeRtu();
|
||||||
bool InitializeTcp();
|
bool InitializeTcp();
|
||||||
|
|
||||||
bool readRegister(int addr,int nb,uint16_t* dest);
|
bool readRegister(int addr,int nb,uint16_t* dest);
|
||||||
|
bool readRegister();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
|
|
||||||
|
@ -99,9 +107,12 @@ protected:
|
||||||
QSettings* m_pSettings;
|
QSettings* m_pSettings;
|
||||||
bool m_bInitializeModbus;
|
bool m_bInitializeModbus;
|
||||||
|
|
||||||
|
SlaveItems m_total_slave_items;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//异步处理数据
|
//异步处理数据
|
||||||
void startAsyncProcess(const QVector<uint16_t>& array,int slave_id,int start_addr,int quantity,DeviceData* pData);
|
void startAsyncProcess(const QVector<uint16_t>& array,int slave_id,int start_addr,int quantity,DeviceData* pData);
|
||||||
|
void startAsyncProcess2(const QVector<uint16_t>& array,const slaveAddress& sa,DeviceData* pData);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void ReadSerialPortData();
|
void ReadSerialPortData();
|
||||||
|
@ -117,9 +128,12 @@ private:
|
||||||
CustomDisplayPanel* m_pAlarmPanel; //告警
|
CustomDisplayPanel* m_pAlarmPanel; //告警
|
||||||
CustomDisplayPanel* m_pInverterPanel; //逆变器
|
CustomDisplayPanel* m_pInverterPanel; //逆变器
|
||||||
CustomDisplayPanel* m_pPVPanel; //太阳能
|
CustomDisplayPanel* m_pPVPanel; //太阳能
|
||||||
|
std::map<int,CustomDisplayPanel*> m_Panels;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool CreateJson(DeviceData* pData,OpenJson& json);
|
bool CreateJson(DeviceData* pData,OpenJson& json);
|
||||||
|
bool CreateJson2(DeviceData* pData,OpenJson& json);
|
||||||
|
void DecodeSync(const QVector<uint16_t>& array,const slaveAddress& sa,DeviceData* pData); //同步解码
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
// 处理进度信号
|
// 处理进度信号
|
||||||
|
@ -129,5 +143,6 @@ signals:
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void startProcessing(const QVector<uint16_t>& array, int slave_id, int start_addr, int quantity, DeviceData* pData);
|
void startProcessing(const QVector<uint16_t>& array, int slave_id, int start_addr, int quantity, DeviceData* pData);
|
||||||
|
void startProcessing2(const QVector<uint16_t>& array,const slaveAddress& sa,DeviceData* pData);
|
||||||
};
|
};
|
||||||
#endif // MAINWINDOW_H
|
#endif // MAINWINDOW_H
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#ifndef SLAVE_DEFINE_H
|
#ifndef SLAVE_DEFINE_H
|
||||||
#define SLAVE_DEFINE_H
|
#define SLAVE_DEFINE_H
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
typedef struct _tagSlave
|
typedef struct _tagSlave
|
||||||
{
|
{
|
||||||
|
@ -14,6 +16,20 @@ typedef struct _tagSlave
|
||||||
|
|
||||||
typedef std::vector<SlaveItem*> SlaveData;
|
typedef std::vector<SlaveItem*> SlaveData;
|
||||||
|
|
||||||
|
//存储解码后的数据
|
||||||
|
typedef struct __DisplayDataItem
|
||||||
|
{
|
||||||
|
int device_type;
|
||||||
|
int order;
|
||||||
|
std::string title;
|
||||||
|
int precision;
|
||||||
|
int value;
|
||||||
|
std::string unit;
|
||||||
|
int display_location; //1:board 2:table
|
||||||
|
} DisplayDataItem;
|
||||||
|
|
||||||
|
typedef std::vector<DisplayDataItem> DisplayDataItems;
|
||||||
|
|
||||||
class DeviceData
|
class DeviceData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -29,6 +45,19 @@ public:
|
||||||
int m_device_online_state;
|
int m_device_online_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class GeneralDeviceData: public DeviceData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GeneralDeviceData()
|
||||||
|
{
|
||||||
|
m_device_type = 8899;
|
||||||
|
m_device_online_state = 0;
|
||||||
|
}
|
||||||
|
virtual ~GeneralDeviceData() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
DisplayDataItems m_PanelDisplayDataItems;
|
||||||
|
};
|
||||||
|
|
||||||
class TemperatureData : public DeviceData
|
class TemperatureData : public DeviceData
|
||||||
{
|
{
|
||||||
|
@ -43,8 +72,8 @@ public:
|
||||||
virtual ~TemperatureData() {}
|
virtual ~TemperatureData() {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool bDecodeAlarm;
|
bool bDecodeAlarm;
|
||||||
bool bDecodeTemp;
|
bool bDecodeTemp;
|
||||||
float TempValue;
|
float TempValue;
|
||||||
float HumidityValue;
|
float HumidityValue;
|
||||||
float DewPointValue;
|
float DewPointValue;
|
||||||
|
@ -56,4 +85,79 @@ public:
|
||||||
int TempLowAlarm;
|
int TempLowAlarm;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// //
|
||||||
|
// 以下数据结构是为了存取json配置文件设置 //
|
||||||
|
// 保存串口的从机号、寄存器开始地址、数量、寄存器数据描述等等信息 //
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* 逻辑结构
|
||||||
|
*
|
||||||
|
SlaveItems 定义有多少个从机
|
||||||
|
slaveAddress 定义每一个从机有多少要读取的地址,每一个起始地址并不保证连续
|
||||||
|
registryData 定义每一个起始地址需要读取的数据
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*****************************************************************/
|
||||||
|
|
||||||
|
//寄存器的数据,以及控制策略描述
|
||||||
|
typedef struct __registryData
|
||||||
|
{
|
||||||
|
__registryData():
|
||||||
|
comment(""), precision(1.0f), unit(""), title_chn("中文"), title_en("eng"), display(1), skip(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::string comment; // ":"在线状态", 注释字段,为了方便读,无实际意义
|
||||||
|
int order; // 定义解码的顺序,从0开始,数量 =slaveAddress.quantity,
|
||||||
|
float precision; // " : 1, 精度,标注小数点用
|
||||||
|
std::string unit; // " : "", 单位
|
||||||
|
std::string title_chn; // " : 中文显示
|
||||||
|
std::string title_en; // " : 英文显示
|
||||||
|
int display; // " : 1, 是否显示,0不显示,1显示在board,2显示在表格
|
||||||
|
int skip; //" : 0 //1跳过 0不跳过
|
||||||
|
} registryData;
|
||||||
|
|
||||||
|
//寄存器的数据数组
|
||||||
|
typedef std::map<int,registryData> RegisterDataItems;
|
||||||
|
|
||||||
|
typedef struct __slaveAddress
|
||||||
|
{
|
||||||
|
int start_addr; // ":40000, 寄存器地址
|
||||||
|
unsigned short quantity; // " : 9, 连续读取多少个寄存器
|
||||||
|
unsigned short bytes_per_register; // " : 2, 每个寄存器的字节数,缺省是uint16,两个字节
|
||||||
|
std::string device_name_chn; // " : "温湿度", 该寄存器数组代表的设备名称
|
||||||
|
std::string device_name_eng; // " : "温湿度", 该寄存器数组代表的设备名称,英文
|
||||||
|
|
||||||
|
//标识本地址的数据是哪一个类型的设备
|
||||||
|
/*
|
||||||
|
PANEL_TEMPERATURE = 1,
|
||||||
|
PANEL_BATTERY = 2,
|
||||||
|
PANEL_POWER = 3,
|
||||||
|
PANEL_AC = 4,
|
||||||
|
PANEL_PV = 5,
|
||||||
|
PANEL_ALARM = 6,
|
||||||
|
PANEL_INVERTER = 7,
|
||||||
|
PANEL_OTHER = 88,
|
||||||
|
PANEL_HOME = 99,
|
||||||
|
* */
|
||||||
|
int device_type;
|
||||||
|
|
||||||
|
RegisterDataItems register_data_items; //寄存器数据,数组
|
||||||
|
} slaveAddress;
|
||||||
|
|
||||||
|
//需要读取的从机的地址信息
|
||||||
|
typedef std::vector<slaveAddress> SlaveAddressItems;
|
||||||
|
|
||||||
|
typedef struct __slaveItem
|
||||||
|
{
|
||||||
|
int slave_id; //从机ID
|
||||||
|
int function_code; //功能码,缺省是3
|
||||||
|
SlaveAddressItems slave_address_items; //该从机ID需要读取的地址信息描述
|
||||||
|
} slaveItem;
|
||||||
|
|
||||||
|
//需要处理的从机列表
|
||||||
|
typedef std::vector<slaveItem> SlaveItems;
|
||||||
|
|
||||||
|
|
||||||
#endif // SLAVE_DEFINE_H
|
#endif // SLAVE_DEFINE_H
|
||||||
|
|
Loading…
Reference in New Issue