1947 lines
95 KiB
C++
1947 lines
95 KiB
C++
#include "m3kte.h"
|
||
#include "ui_m3kte.h"
|
||
|
||
#include "settingsdialog.h"
|
||
#include "writeregistermodel.h"
|
||
|
||
#include <QModbusTcpClient>
|
||
#include <QModbusRtuSerialMaster>
|
||
#include <QStandardItemModel>
|
||
#include <QStatusBar>
|
||
#include <QUrl>
|
||
#include <QScrollBar>
|
||
|
||
#include <QTableWidget>
|
||
#include <QPointer>
|
||
#include <QDebug>
|
||
#include <QProcess>
|
||
#include <QCoreApplication>
|
||
|
||
QWidget* init(QWidget *parent)
|
||
{
|
||
return new M3KTE(parent);
|
||
}
|
||
|
||
//1024 768
|
||
//Ширина колбы - уже
|
||
M3KTE::M3KTE(QWidget *parent)
|
||
: QMainWindow(parent)
|
||
, ui(new Ui::M3KTE)
|
||
{
|
||
ui->setupUi(this);
|
||
//Массив указателей на индикаторы напряжения топливных элементов
|
||
{
|
||
int i = 0;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_1;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_2;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_3;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_4;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_5;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_6;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_7;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_8;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_9;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_10;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_11;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_12;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_13;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_14;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_15;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_16;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_17;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_18;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_19;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_20;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_21;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_22;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_23;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_24;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_25;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_26;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_27;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_28;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_29;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_30;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_31;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_32;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_33;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_34;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_35;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_36;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_37;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_38;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_39;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_40;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_41;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_42;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_43;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_44;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_45;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_46;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_47;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_48;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_49;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_50;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_51;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_52;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_53;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_54;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_55;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_56;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_57;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_58;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_59;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_60;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_61;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_62;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_63;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_64;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_65;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_66;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_67;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_68;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_69;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_70;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_71;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_72;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_73;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_74;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_75;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_76;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_77;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_78;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_79;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_80;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_81;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_82;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_83;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_84;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_85;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_86;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_87;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_88;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_89;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_90;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_91;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_92;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_93;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_94;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_95;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_96;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_97;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_98;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_99;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_100;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_101;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_102;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_103;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_104;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_105;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_106;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_107;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_108;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_109;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_110;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_111;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_112;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_113;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_114;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_115;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_116;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_117;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_118;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_119;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_120;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_121;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_122;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_123;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_124;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_125;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_126;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_127;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_128;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_129;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_130;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_131;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_132;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_133;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_134;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_135;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_136;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_137;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_138;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_139;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_140;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_141;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_142;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_143;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_144;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_145;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_146;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_147;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_148;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_149;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_150;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_151;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_152;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_153;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_154;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_155;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_156;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_157;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_158;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_159;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_160;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_161;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_162;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_163;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_164;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_165;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_166;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_167;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_168;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_169;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_170;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_171;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_172;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_173;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_174;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_175;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_176;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_177;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_178;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_179;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_180;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_181;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_182;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_183;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_184;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_185;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_186;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_187;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_188;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_189;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_190;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_191;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_192;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_193;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_194;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_195;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_196;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_197;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_198;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_199;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_200;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_201;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_202;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_203;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_204;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_205;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_206;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_207;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_208;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_209;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_210;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_211;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_212;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_213;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_214;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_215;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_216;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_217;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_218;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_219;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_220;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_221;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_222;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_223;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_224;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_225;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_226;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_227;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_228;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_229;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_230;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_231;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_232;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_233;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_234;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_235;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_236;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_237;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_238;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_239;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_240;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_241;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_242;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_243;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_244;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_245;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_246;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_247;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_248;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_249;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_250;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_251;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_252;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_253;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_254;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_255;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_256;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_257;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_258;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_259;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_260;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_261;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_262;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_263;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_264;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_265;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_266;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_267;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_268;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_269;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_270;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_271;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_272;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_273;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_274;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_275;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_276;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_277;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_278;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_279;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_280;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_281;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_282;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_283;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_284;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_285;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_286;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_287;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_288;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_289;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_290;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_291;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_292;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_293;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_294;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_295;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_296;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_297;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_298;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_299;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_300;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_301;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_302;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_303;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_304;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_305;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_306;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_307;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_308;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_309;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_310;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_311;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_312;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_313;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_314;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_315;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_316;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_317;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_318;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_319;
|
||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_320;
|
||
}
|
||
m_settingsDialog = new SettingsDialog(this);
|
||
ui->writeTable->addItem(tr("Exceptions"), QModbusDataUnit::Coils);
|
||
ui->writeTable->addItem(tr("Warnings"), QModbusDataUnit::HoldingRegisters);
|
||
ui->writeTable->addItem(tr("Accidents"), QModbusDataUnit::HoldingRegisters);
|
||
for(int i = 0; i < 4; i++) {
|
||
Boards[i].ModbusModelCoil = new WriteRegisterModel(this, 85 - (i/4*20), false);
|
||
Boards[i].ModbusModelCoil->setStartAddress(0);
|
||
Boards[i].ModbusModelCoil->setNumberOfValues(QString::number(85-(i/4*20)));
|
||
Boards[i].ModbusModelHoldingReg = new WriteRegisterModel(this, (85 - (i/4*20))*2, true);
|
||
Boards[i].ModbusModelHoldingReg->setStartAddress(0);
|
||
Boards[i].ModbusModelHoldingReg->setNumberOfValues(QString::number(85-(i/4*20)));
|
||
}
|
||
m_deviceSettingsDialog = new DeviceSettingsDialog(this);
|
||
m_regMultipleSettings = new MultipleSettings(this);
|
||
modbusDevice = new QModbusRtuSerialMaster(this);
|
||
m_lineRinger = new LineRinger();
|
||
Boards[0].boardScanners = new QTimer();
|
||
Boards[1].boardScanners = new QTimer();
|
||
Boards[2].boardScanners = new QTimer();
|
||
Boards[3].boardScanners = new QTimer();
|
||
Boards[0].boardScanners->setSingleShot(true);
|
||
Boards[1].boardScanners->setSingleShot(true);
|
||
Boards[2].boardScanners->setSingleShot(true);
|
||
Boards[3].boardScanners->setSingleShot(true);
|
||
connect(Boards[0].boardScanners, &QTimer::timeout, this, [this]() {
|
||
boardScan(0);
|
||
});
|
||
connect(Boards[1].boardScanners, &QTimer::timeout, this, [this]() {
|
||
boardScan(1);
|
||
});
|
||
connect(Boards[2].boardScanners, &QTimer::timeout, this, [this]() {
|
||
boardScan(2);
|
||
});
|
||
connect(Boards[3].boardScanners, &QTimer::timeout, this, [this]() {
|
||
boardScan(3);
|
||
});
|
||
{
|
||
Boards[0].adr = 1;
|
||
Boards[1].adr = 2;
|
||
Boards[2].adr = 3;
|
||
Boards[3].adr = 4;
|
||
}
|
||
ui->M3kteRegSettings->setEnabled(false);
|
||
ui->BSM_Warning->setEnabled(false);
|
||
ui->BSM_Accident->setEnabled(false);
|
||
ui->BSM_WorkInProgress->setEnabled(false);
|
||
initActions();
|
||
ui->BST_On->setCheckable(false);
|
||
ui->BST_Off->setChecked(true);
|
||
ui->boardSelectBox->setCurrentIndex(0);
|
||
ui->writeTable->setCurrentIndex(0);
|
||
changeTable(0, 0);
|
||
{
|
||
Boards_Fields[0] = ui->FCBoardBox;
|
||
Boards_Fields[1] = ui->FCBoardBox_2;
|
||
Boards_Fields[2] = ui->FCBoardBox_3;
|
||
Boards_Fields[3] = ui->FCBoardBox_4;
|
||
}
|
||
{
|
||
Boards[0].timerStatus = ui->timeStatus_1;
|
||
Boards[1].timerStatus = ui->timeStatus_2;
|
||
Boards[2].timerStatus = ui->timeStatus_3;
|
||
Boards[3].timerStatus = ui->timeStatus_4;
|
||
}
|
||
{
|
||
Boards[0].timerData = ui->timeData_1;
|
||
Boards[1].timerData = ui->timeData_2;
|
||
Boards[2].timerData = ui->timeData_3;
|
||
Boards[3].timerData = ui->timeData_4;
|
||
}
|
||
{
|
||
Boards[0].localError = ui->localErrorEdit_1;
|
||
Boards[1].localError = ui->localErrorEdit_2;
|
||
Boards[2].localError = ui->localErrorEdit_3;
|
||
Boards[3].localError = ui->localErrorEdit_4;
|
||
}
|
||
{
|
||
Boards[0].localState[LOCAL_STATE_POLL] = ui->localPollChkBox_1;
|
||
Boards[1].localState[LOCAL_STATE_POLL] = ui->localPollChkBox_2;
|
||
Boards[2].localState[LOCAL_STATE_POLL] = ui->localPollChkBox_3;
|
||
Boards[3].localState[LOCAL_STATE_POLL] = ui->localPollChkBox_4;
|
||
|
||
|
||
Boards[0].localState[LOCAL_STATE_WARN] = ui->localWarnChkBox_1;
|
||
Boards[1].localState[LOCAL_STATE_WARN] = ui->localWarnChkBox_2;
|
||
Boards[2].localState[LOCAL_STATE_WARN] = ui->localWarnChkBox_3;
|
||
Boards[3].localState[LOCAL_STATE_WARN] = ui->localWarnChkBox_4;
|
||
|
||
Boards[0].localState[LOCAL_STATE_ERR] = ui->localErrChkBox_1;
|
||
Boards[1].localState[LOCAL_STATE_ERR] = ui->localErrChkBox_2;
|
||
Boards[2].localState[LOCAL_STATE_ERR] = ui->localErrChkBox_3;
|
||
Boards[3].localState[LOCAL_STATE_ERR] = ui->localErrChkBox_4;
|
||
|
||
}
|
||
{ // не кликабельные чекбоксы и радиобоксы
|
||
for(int i = 0; i < 4; i++)
|
||
{
|
||
connect(Boards[i].localState[LOCAL_STATE_POLL], &QCheckBox::clicked,
|
||
this, [i, this](bool checked) {
|
||
m_deviceSettingsDialog->sendPollCommand(i, checked);
|
||
});
|
||
Boards[i].localState[LOCAL_STATE_WARN]->setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
||
Boards[i].localState[LOCAL_STATE_ERR]->setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
||
}
|
||
|
||
ui->BSM_Warning->setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
||
ui->BSM_Accident->setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
||
ui->BSM_WorkInProgress->setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
||
ui->BST_On->setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
||
ui->BST_Off->setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
||
}
|
||
for(int i = 0; i < 4; i++) {
|
||
statusM3KTE.Warnings[i] = false;
|
||
statusM3KTE.Accidents[i] = false;
|
||
Boards_Fields[i]->setEnabled(false);
|
||
Boards[i].timerData->setText(" ");
|
||
Boards[i].timerStatus->setText(" ");;
|
||
Boards[i].localError->setText(" ");;
|
||
}
|
||
for(int i = 0; i < 5; i++) {
|
||
ui->writeValueTable->resizeColumnToContents(i);
|
||
}
|
||
QBrush tb(Qt::transparent); // Transparent brush, solid pattern
|
||
for(int i = 0; i < 320; i++) {
|
||
m_ProgressBar[i]->setTextVisible(true);
|
||
m_ProgressBar[i]->setMinimumSize(25, 25);
|
||
m_ProgressBar[i]->setMaximumSize(25, 25);
|
||
m_ProgressBar[i]->resize(25, 25);
|
||
m_ProgressBar[i]->setAlignment(Qt::AlignCenter);
|
||
m_ProgressBar[i]->setFormat(QString("%1").arg((i%85+1)));
|
||
m_ProgressBar[i]->setValue(3);
|
||
QString style_fc_off = "QProgressBar {border: 2px solid black; font: bold 10px} QProgressBar::chunk {background: hsva(" + QString::number(30) + ", 30, 30, 30%);} ";
|
||
m_ProgressBar[i]->setStyleSheet(style_fc_off);
|
||
ThePhantomMenace[i] = new QPushButton(m_ProgressBar[i]);
|
||
ThePhantomMenace[i]->setFlat(true);
|
||
ThePhantomMenace[i]->setPalette(QPalette(tb, tb, tb, tb, tb, tb, tb, tb, tb));
|
||
connect(ThePhantomMenace[i], &QPushButton::clicked, this, [this, i]() {
|
||
selectPositionOnTree(i);
|
||
});
|
||
}
|
||
connect(m_deviceSettingsDialog, &DeviceSettingsDialog::parityChanged, this, &M3KTE::onParityUpdate);
|
||
connect(m_deviceSettingsDialog, &DeviceSettingsDialog::speedChanged, this, &M3KTE::onSpeedUpdate);
|
||
loggerTable = new QTableWidget(ui->loggerWidget);
|
||
ui->loggerWidget->layout()->addWidget(loggerTable);
|
||
loggerTable->setColumnCount(5);
|
||
QStringList headers;
|
||
headers << "Время" << "Плата" << "Тип ошибки" << "Счётчик" << "Примечание";
|
||
loggerTable->setHorizontalHeaderLabels(headers);
|
||
loggerTable->setSortingEnabled(true);
|
||
loggerTable->setAutoScroll(true);
|
||
}
|
||
|
||
M3KTE::~M3KTE()
|
||
{
|
||
if(modbusDevice->state() == QModbusDevice::ConnectedState) {
|
||
onConnectClicked();
|
||
}
|
||
delete ui;
|
||
}
|
||
|
||
void M3KTE::initActions()
|
||
{
|
||
ui->ConnectionMenuConnect->setEnabled(true);
|
||
ui->ConnectionMenuDisconnect->setEnabled(false);
|
||
ui->ConnectionMenuSettings->setEnabled(true);
|
||
connect(ui->ConnectionMenuConnect, &QAction::triggered,
|
||
this, &M3KTE::onConnectClicked);
|
||
connect(ui->ConnectionMenuDisconnect, &QAction::triggered,
|
||
this, &M3KTE::onConnectClicked);
|
||
connect(ui->readButton, &QPushButton::clicked,
|
||
this, &M3KTE::onReadButtonClicked);
|
||
connect(ui->writeButton, &QPushButton::clicked,
|
||
this, &M3KTE::onWriteButtonClicked);
|
||
connect(ui->clearLoggerBtn, &QPushButton::clicked,
|
||
this, &M3KTE::clearLogger);
|
||
connect(ui->boardSelectBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||
this, &M3KTE::onSelectedBoardChanged);
|
||
connect(ui->writeTable, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||
this, &M3KTE::onWriteTableChanged);
|
||
connect(ui->LineCall, &QAction::triggered, m_lineRinger, &QWidget::show);
|
||
connect(ui->M3kteRegSettings, &QAction::triggered, m_regMultipleSettings, &QDialog::show);
|
||
connect(m_regMultipleSettings, &MultipleSettings::write, this, &M3KTE::slotmultipleRegWrite);
|
||
connect(m_regMultipleSettings, &MultipleSettings::writeAndSend, this, &M3KTE::slotmultipleRegWriteAndSend);
|
||
connect(ui->ConnectionMenuSettings, &QAction::triggered, m_settingsDialog, &QDialog::show);
|
||
connect(ui->M3kteMenuSettings, &QAction::triggered, m_deviceSettingsDialog, &QDialog::show);
|
||
}
|
||
|
||
void M3KTE::logError(const QString &errorPlace, const QString &errorString, unsigned errorCount, const QString &description)
|
||
{
|
||
unsigned newRow = loggerTable->rowCount();
|
||
loggerTable->insertRow(newRow);
|
||
loggerTable->setItem(newRow, 0, new QTableWidgetItem(QTime::currentTime().toString("HH:mm:ss")));
|
||
loggerTable->setItem(newRow, 1, new QTableWidgetItem(errorPlace));
|
||
loggerTable->setItem(newRow, 2, new QTableWidgetItem(errorString));
|
||
loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(errorCount)));
|
||
loggerTable->setItem(newRow, 4, new QTableWidgetItem(description));
|
||
loggerTable->resizeColumnsToContents();
|
||
if(!loggerTable->verticalScrollBar()->isSliderDown())
|
||
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
|
||
}
|
||
void M3KTE::clearLogger()
|
||
{
|
||
// Проверяем, что таблица инициализирована
|
||
if (!loggerTable) {
|
||
return;
|
||
}
|
||
// Отключаем обновление UI для повышения производительности
|
||
loggerTable->setUpdatesEnabled(false);
|
||
// Очищаем все строки таблицы
|
||
loggerTable->setRowCount(0);
|
||
// Включаем обновление UI
|
||
loggerTable->setUpdatesEnabled(true);
|
||
}
|
||
|
||
void M3KTE::onConnectClicked()
|
||
{
|
||
if(!modbusDevice)
|
||
return;
|
||
statusBar()->clearMessage();
|
||
if(modbusDevice->state() != QModbusDevice::ConnectedState) {
|
||
modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter,
|
||
m_settingsDialog->settings().portName);
|
||
#if QT_CONFIG(modbus_serialport)
|
||
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter,
|
||
m_settingsDialog->settings().parity);
|
||
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,
|
||
m_settingsDialog->settings().baud);
|
||
modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter,
|
||
m_settingsDialog->settings().dataBits);
|
||
modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter,
|
||
m_settingsDialog->settings().stopBits);
|
||
#endif
|
||
modbusDevice->setTimeout(m_settingsDialog->settings().responseTime);
|
||
modbusDevice->setNumberOfRetries(m_settingsDialog->settings().numberOfRetries);
|
||
if(!modbusDevice->connectDevice()) {
|
||
statusBar()->showMessage(tr("Connect failed: ") + modbusDevice->errorString(), 5000);
|
||
} else {
|
||
ui->ConnectionMenuConnect->setEnabled(false);
|
||
ui->ConnectionMenuDisconnect->setEnabled(true);
|
||
if(pingNetworkDevices()) { //Опрос устройств
|
||
unsigned tmp_adr[4];
|
||
bool ActiveDevices[4];
|
||
for(int i = 0; i < 4; i++) {
|
||
tmp_adr[i] = Boards[i].adr;
|
||
ActiveDevices[i] = Boards[i].isActive;
|
||
}
|
||
ui->M3kteRegSettings->setEnabled(true);
|
||
m_deviceSettingsDialog->updateSettingsAfterConnection(m_settingsDialog->settings().baud, m_settingsDialog->settings().parity, tmp_adr, ActiveDevices);
|
||
ui->boardSelectBox->setCurrentIndex(0);
|
||
ui->writeTable->setCurrentIndex(0);
|
||
changeTable(0, 0);
|
||
ui->M3kteMenuSettings->setEnabled(true);
|
||
ui->M3kteRegSettings->setEnabled(true);
|
||
ui->BST_Off->setCheckable(false);
|
||
ui->BST_Off->setChecked(false);
|
||
ui->BST_On->setCheckable(true);
|
||
ui->BST_On->setChecked(true);
|
||
ui->BSM_Warning->setEnabled(true);
|
||
ui->BSM_Accident->setEnabled(true);
|
||
ui->BSM_WorkInProgress->setEnabled(true);
|
||
ui->BSM_WorkInProgress->setChecked(true);
|
||
}
|
||
}
|
||
} else {
|
||
QString style_fc_off = "QProgressBar {border: 2px solid black; font: bold 10px} QProgressBar::chunk {background: hsva(" + QString::number(30) + ", 30, 30, 30%);} ";
|
||
for(int i = 0; i < 4; i++) {
|
||
Boards[i].boardScanners->stop();
|
||
Boards_Fields[i]->setEnabled(false);
|
||
Boards[i].isActive=false;
|
||
for(int j = 0; j < (85 - (i/3*20)); j++) {
|
||
Boards[i].coil[j] = false;
|
||
Boards[i].ModbusModelCoil->m_coils[j]=0;
|
||
Boards[i].ModbusModelHoldingReg->m_currentU[j]=0;
|
||
Boards[i].ModbusModelHoldingReg->m_holdingRegisters[j] = 0;
|
||
Boards[i].ModbusModelHoldingReg->m_holdingRegisters[j + (85 - (i/3*20))] = 0;
|
||
}
|
||
Boards_Fields[i]->setTitle(QString("Плата №%1").arg(i+1));
|
||
Boards[i].timerData->setText(" ");;
|
||
Boards[i].timerStatus->setText(" ");;
|
||
Boards[i].localError->setText(" ");;
|
||
}
|
||
for(int i = 0; i < 320; i++) {
|
||
m_ProgressBar[i]->setStatusTip(QString("П%1 ТЭ%2: Топливный Элемент не учитывается.").arg(QString::number(i/85+1), QString::number(i%85)));
|
||
m_ProgressBar[i]->setWhatsThis(QString("П%1 ТЭ%2: Топливный Элемент не учитывается.").arg(QString::number(i/85+1), QString::number(i%85)));
|
||
m_ProgressBar[i]->setValue(3);
|
||
m_ProgressBar[i]->setStyleSheet(style_fc_off);
|
||
}
|
||
modbusDevice->disconnectDevice();
|
||
ui->M3kteMenuSettings->setEnabled(false);
|
||
ui->M3kteRegSettings->setEnabled(false);
|
||
ui->ConnectionMenuConnect->setEnabled(true);
|
||
ui->ConnectionMenuDisconnect->setEnabled(false);
|
||
ui->BST_Off->setCheckable(true);
|
||
ui->BST_Off->setChecked(true);
|
||
ui->BST_On->setCheckable(false);
|
||
ui->BST_On->setChecked(false);
|
||
ui->BSM_Warning->setChecked(false);
|
||
ui->BSM_Accident->setChecked(false);
|
||
ui->BSM_WorkInProgress->setChecked(false);
|
||
ui->BSM_Warning->setEnabled(false);
|
||
ui->BSM_Accident->setEnabled(false);
|
||
ui->BSM_WorkInProgress->setEnabled(false);
|
||
ui->M3kteRegSettings->setEnabled(false);
|
||
m_deviceSettingsDialog->onDisconnect();
|
||
}
|
||
}
|
||
|
||
void M3KTE::onReadButtonClicked()
|
||
{
|
||
if(!modbusDevice)
|
||
return;
|
||
statusBar()->clearMessage();
|
||
if(auto *reply = modbusDevice->sendReadRequest(readRequest(), Boards[ui->boardSelectBox->currentIndex()].adr)) {
|
||
if(!reply->isFinished())
|
||
connect(reply, &QModbusReply::finished, this, &M3KTE::onReadReady);
|
||
else
|
||
delete reply; // broadcast replies return immediately
|
||
} else {
|
||
statusBar()->showMessage(tr("Read error: ") + modbusDevice->errorString(), 5000);
|
||
}
|
||
}
|
||
|
||
void M3KTE::onReadReady()
|
||
{
|
||
auto reply = qobject_cast<QModbusReply *>(sender());
|
||
if(!reply)
|
||
return;
|
||
int Adr = 255;
|
||
for(int i = 0; i < 4; i++) {
|
||
if(Boards[i].isActive && Boards[i].adr==reply->serverAddress()) {
|
||
Adr = i;
|
||
break;
|
||
}
|
||
}
|
||
if(reply->error() == QModbusDevice::NoError) {
|
||
const QModbusDataUnit unit = reply->result();
|
||
for(int i = 0, total = int(unit.valueCount()); i < total; ++i) {
|
||
if(unit.registerType() == QModbusDataUnit::Coils) {
|
||
Boards[Adr].coil[i + unit.startAddress()] = unit.value(i);
|
||
if(unit.value(i)==1)
|
||
Boards[Adr].ModbusModelCoil->setData(ui->writeValueTable->model()->index(i + unit.startAddress(), 2), Qt::Checked, Qt::CheckStateRole);
|
||
else
|
||
Boards[Adr].ModbusModelCoil->setData(ui->writeValueTable->model()->index(i + unit.startAddress(), 2), Qt::Unchecked, Qt::CheckStateRole);
|
||
} else if(unit.registerType() == QModbusDataUnit::HoldingRegisters) {
|
||
Boards[Adr].HR[i + unit.startAddress()] = unit.value(i);
|
||
Boards[Adr].ModbusModelHoldingReg->setData(ui->writeValueTable->model()->index(i + unit.startAddress(), 3), QString::number(unit.value(i), 16), Qt::EditRole);
|
||
}
|
||
}
|
||
switch(unit.registerType()) {
|
||
case QModbusDataUnit::Coils:
|
||
Boards[Adr].ModbusModelCoil->dataChanged(ui->writeValueTable->model()->index(unit.startAddress(), 2),
|
||
ui->writeValueTable->model()->index(unit.startAddress() + unit.valueCount() -1, 2));
|
||
break;
|
||
case QModbusDataUnit::HoldingRegisters:
|
||
Boards[Adr].ModbusModelHoldingReg->dataChanged(ui->writeValueTable->model()->index(unit.startAddress(), 3),
|
||
ui->writeValueTable->model()->index(unit.startAddress() + unit.valueCount() -1, 3));
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
} else if(reply->error() == QModbusDevice::ProtocolError) {
|
||
statusBar()->showMessage(tr("Read response error: %1 (Mobus exception: 0x%2)").
|
||
arg(reply->errorString()).
|
||
arg(reply->rawResult().exceptionCode(), -1, 16), 5000);
|
||
logError(tr("Плата %1 (ID %2)").arg(Adr+1).arg(Boards[Adr].adr),
|
||
reply->errorString(), ++Boards[Adr].error_RX,
|
||
QString::number(reply->rawResult().exceptionCode()));
|
||
} else {
|
||
statusBar()->showMessage(tr("Read response error: %1 (code: 0x%2)").
|
||
arg(reply->errorString()).
|
||
arg(reply->error(), -1, 16), 5000);
|
||
logError(tr("Плата %1 (ID %2)").arg(Adr+1).arg(Boards[Adr].adr),
|
||
reply->errorString(), ++Boards[Adr].error_RX,
|
||
QString::number(reply->error(), 16));
|
||
}
|
||
reply->deleteLater();
|
||
}
|
||
|
||
void M3KTE::onWriteButtonClicked()
|
||
{
|
||
if(!modbusDevice)
|
||
return;
|
||
statusBar()->clearMessage();
|
||
QModbusDataUnit writeUnit = writeRequest();
|
||
QModbusDataUnit::RegisterType table = writeUnit.registerType();
|
||
for(int i = 0, total = int(writeUnit.valueCount()); i < total; ++i) {
|
||
if(table == QModbusDataUnit::Coils)
|
||
{
|
||
Boards[ui->boardSelectBox->currentIndex()].coil[i+writeUnit.startAddress()] =
|
||
Boards[ui->boardSelectBox->currentIndex()].ModbusModelCoil->m_coils[i + writeUnit.startAddress()];
|
||
writeUnit.setValue(i, Boards[ui->boardSelectBox->currentIndex()].ModbusModelCoil->m_coils[i + writeUnit.startAddress()]);
|
||
} else {
|
||
Boards[ui->boardSelectBox->currentIndex()].HR[i+writeUnit.startAddress()] =
|
||
Boards[ui->boardSelectBox->currentIndex()].ModbusModelHoldingReg->m_holdingRegisters[i+writeUnit.startAddress()];
|
||
writeUnit.setValue(i, Boards[ui->boardSelectBox->currentIndex()].ModbusModelHoldingReg->m_holdingRegisters[i + writeUnit.startAddress()]);
|
||
}
|
||
}
|
||
if(auto *reply = modbusDevice->sendWriteRequest(writeUnit, Boards[ui->boardSelectBox->currentIndex()].adr)) {
|
||
if(!reply->isFinished()) {
|
||
unsigned tmp_id = ui->boardSelectBox->currentIndex();
|
||
connect(reply, &QModbusReply::finished, this, [this, reply, tmp_id]() {
|
||
if(reply->error() == QModbusDevice::ProtocolError) {
|
||
statusBar()->showMessage(tr("Write response error: %1 (Mobus exception: 0x%2)")
|
||
.arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16),
|
||
5000);
|
||
logError(tr("Плата %1 (ID %2)").arg(tmp_id+1).arg(Boards[tmp_id].adr),
|
||
reply->errorString(), ++Boards[tmp_id].error_TX,
|
||
QString::number(reply->rawResult().exceptionCode(), 16));
|
||
} else if(reply->error() != QModbusDevice::NoError) {
|
||
statusBar()->showMessage(tr("Write response error: %1 (code: 0x%2)").
|
||
arg(reply->errorString()).arg(reply->error(), -1, 16), 5000);
|
||
logError(tr("Плата %1 (ID %2)").arg(tmp_id+1).arg(Boards[tmp_id].adr),
|
||
reply->errorString(), ++Boards[tmp_id].error_TX,
|
||
QString::number(reply->error()));
|
||
}
|
||
reply->deleteLater();
|
||
});
|
||
} else {
|
||
// broadcast replies return immediately
|
||
reply->deleteLater();
|
||
}
|
||
} else {
|
||
statusBar()->showMessage(tr("Write error: ") + modbusDevice->errorString(), 5000);
|
||
logError(tr("Терминал"), modbusDevice->errorString(), 0, "");
|
||
}
|
||
}
|
||
|
||
void M3KTE::onSelectedBoardChanged(int index)
|
||
{
|
||
changeTable(index, ui->writeTable->currentIndex());
|
||
}
|
||
|
||
void M3KTE::onWriteTableChanged(int index)
|
||
{
|
||
changeTable(ui->boardSelectBox->currentIndex(), index);
|
||
}
|
||
|
||
void M3KTE::changeTable(int board, int tabletype)
|
||
{
|
||
if(tabletype==0) {
|
||
ui->writeValueTable->setModel(Boards[board].ModbusModelCoil);
|
||
int i = 0;
|
||
for(;i<Boards[board].ModbusModelHoldingReg->rowCount();i++) {
|
||
ui->writeValueTable->setRowHidden(i, ui->writeValueTable->model()->index(i, 0).parent(), false);
|
||
}
|
||
ui->writeValueTable->hideColumn(3);
|
||
ui->writeValueTable->showColumn(2);
|
||
} else {
|
||
ui->writeValueTable->setModel(Boards[board].ModbusModelHoldingReg);
|
||
if(tabletype==1) {
|
||
Boards[board].ModbusModelHoldingReg->setStartAddress(0);
|
||
int i = 0;
|
||
for(;i<Boards[board].ModbusModelHoldingReg->rowCount()/2;i++) {
|
||
ui->writeValueTable->setRowHidden(i, ui->writeValueTable->model()->index(i, 0).parent(), false);
|
||
}
|
||
for(;i<Boards[board].ModbusModelHoldingReg->rowCount();i++) {
|
||
ui->writeValueTable->setRowHidden(i, ui->writeValueTable->model()->index(i, 0).parent(), true);
|
||
}
|
||
} else {
|
||
Boards[board].ModbusModelHoldingReg->setStartAddress(Boards[board].ModbusModelHoldingReg->rowCount()/2);
|
||
int i = 0;
|
||
for(;i<Boards[board].ModbusModelHoldingReg->rowCount()/2;i++) {
|
||
ui->writeValueTable->setRowHidden(i, ui->writeValueTable->model()->index(i, 0).parent(), true);
|
||
}
|
||
for(;i<Boards[board].ModbusModelHoldingReg->rowCount();i++) {
|
||
ui->writeValueTable->setRowHidden(i, ui->writeValueTable->model()->index(i, 0).parent(), false);
|
||
}
|
||
}
|
||
ui->writeValueTable->hideColumn(2);
|
||
ui->writeValueTable->showColumn(3);
|
||
}
|
||
for(int i = 0; i < 5; i++) {
|
||
ui->writeValueTable->resizeColumnToContents(i);
|
||
}
|
||
}
|
||
|
||
QModbusDataUnit M3KTE::readRequest() const
|
||
{
|
||
const auto table =
|
||
static_cast<QModbusDataUnit::RegisterType>(ui->writeTable->currentData().toInt());
|
||
int startAddress = 85 * (ui->writeTable->currentIndex()/2);
|
||
Q_ASSERT(startAddress >= 0 && startAddress < 340);
|
||
quint16 numberOfEntries = qMin((ushort)(85 - (ui->boardSelectBox->currentIndex()/3*20)), quint16(340 - startAddress));
|
||
return QModbusDataUnit(table, startAddress, numberOfEntries);
|
||
}
|
||
|
||
QModbusDataUnit M3KTE::writeRequest() const
|
||
{
|
||
const auto table =
|
||
static_cast<QModbusDataUnit::RegisterType>(ui->writeTable->currentData().toInt());
|
||
int startAddress = 85 * (ui->writeTable->currentIndex()/2);
|
||
Q_ASSERT(startAddress >= 0 && startAddress < 340);
|
||
quint16 numberOfEntries = qMin((ushort)(85 - (ui->boardSelectBox->currentIndex()/3*20)), quint16(340 - startAddress));
|
||
return QModbusDataUnit(table, startAddress, numberOfEntries);
|
||
}
|
||
|
||
bool M3KTE::event(QEvent *event)
|
||
{
|
||
if(event->type() == QEvent::User) {
|
||
BoardIdHasBeenChanged* _event = static_cast<BoardIdHasBeenChanged*>(event);
|
||
QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 172, 1);
|
||
_unit->setValue(0, _event->BoardNewID());
|
||
Boards[_event->BoardNum()]._tmp_adr = _event->BoardNewID();
|
||
if(auto *reply = modbusDevice->sendWriteRequest(*_unit, Boards[_event->BoardNum()].adr)) {
|
||
if(!reply->isFinished())
|
||
connect(reply, &QModbusReply::finished, this, [reply, this, _event, _unit]() {
|
||
if(reply->error()==QModbusDevice::TimeoutError) {
|
||
if(auto *subreply = modbusDevice->sendReadRequest(*_unit, Boards[_event->BoardNum()]._tmp_adr)) {
|
||
if(!subreply->isFinished()) {
|
||
connect(subreply, &QModbusReply::finished, this, [subreply, this, _event]() {
|
||
checkAdrChange(subreply, _event->BoardNum());
|
||
});
|
||
} else {
|
||
logError(tr("Плата %1 (ID %2)").arg(_event->BoardNum()+1).arg(Boards[_event->BoardNum()].adr),
|
||
subreply->errorString(), ++Boards[_event->BoardNum()].error_adr_change,
|
||
"Не удалось изменить адрес устройства. [1]");
|
||
reply->deleteLater();
|
||
delete subreply; // broadcast replies return immediately
|
||
}
|
||
} else {
|
||
logError(tr("Плата %1 (ID %2)").arg(_event->BoardNum()+1).arg(Boards[_event->BoardNum()].adr),
|
||
modbusDevice->errorString(), ++Boards[_event->BoardNum()].error_adr_change,
|
||
"Не удалось изменить адрес устройства. [2]");
|
||
reply->deleteLater();
|
||
}
|
||
} else {
|
||
logError(tr("Плата %1 (ID %2)").arg(_event->BoardNum()+1).arg(Boards[_event->BoardNum()].adr),
|
||
reply->errorString(), ++Boards[_event->BoardNum()].error_adr_change,
|
||
"Не удалось изменить адрес устройства. [3]");
|
||
reply->deleteLater();
|
||
}
|
||
});
|
||
else {
|
||
logError(tr("Плата %1 (ID %2)").arg(_event->BoardNum()+1).arg(Boards[_event->BoardNum()].adr),
|
||
reply->errorString(), ++Boards[_event->BoardNum()].error_adr_change,
|
||
"Не удалось изменить адрес устройства. [4]");
|
||
reply->deleteLater();
|
||
delete reply;
|
||
}
|
||
} else {
|
||
logError(tr("Плата %1 (ID %2)").arg(_event->BoardNum()+1).arg(Boards[_event->BoardNum()].adr),
|
||
modbusDevice->errorString(), ++Boards[_event->BoardNum()].error_adr_change,
|
||
"Не удалось изменить адрес устройства. [5]");
|
||
reply->deleteLater();
|
||
}
|
||
m_deviceSettingsDialog->show();
|
||
return true;
|
||
} else if(event->type() == (QEvent::Type)1001) {
|
||
pollStatusChange* _event = static_cast<pollStatusChange*>(event);
|
||
QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 170, 1);
|
||
_unit->setValue(0, _event->Status());
|
||
if(auto *reply = modbusDevice->sendWriteRequest(*_unit, Boards[_event->BoardID()].adr)) {
|
||
if(!reply->isFinished())
|
||
connect(reply, &QModbusReply::finished, this, [reply, this, _event]() {
|
||
if(reply->error()!=QModbusDevice::NoError) {
|
||
logError(tr("Плата %1 (ID %2)").arg(_event->BoardID()+1).arg(Boards[_event->BoardID()].adr),
|
||
reply->errorString(), ++Boards[_event->BoardID()].error_cmd_change, "");
|
||
reply->deleteLater();
|
||
}
|
||
});
|
||
} else {
|
||
logError(tr("Плата %1 (ID %2)").arg(_event->BoardID()+1).arg(Boards[_event->BoardID()].adr),
|
||
modbusDevice->errorString(), ++Boards[_event->BoardID()].error_cmd_change, "");
|
||
reply->deleteLater();
|
||
}
|
||
return true;
|
||
}
|
||
return QWidget::event(event);
|
||
}
|
||
|
||
void M3KTE::checkAdrChange(QModbusReply *reply, unsigned boardNum)
|
||
{
|
||
if(!reply) {
|
||
logError(tr("Плата %1 (ID %2)").arg(boardNum+1).arg(Boards[boardNum].adr),
|
||
modbusDevice->errorString(), ++Boards[boardNum].error_adr_change,
|
||
"Не удалось проверить изменение адреса устройства.");
|
||
reply->deleteLater();
|
||
return;
|
||
}
|
||
if(reply->error() == QModbusDevice::NoError) {
|
||
//OK
|
||
Boards[boardNum].adr = Boards[boardNum]._tmp_adr;
|
||
reply->deleteLater();
|
||
} else {
|
||
logError(tr("Плата %1 (ID %2)").arg(boardNum+1).arg(Boards[boardNum].adr),
|
||
reply->errorString(), ++Boards[boardNum].error_adr_change,
|
||
"Ошибка при подтверждении изменения адреса устройства.");
|
||
reply->deleteLater();
|
||
}
|
||
}
|
||
|
||
void M3KTE::checkBoards()
|
||
{
|
||
QModbusDataUnit unitCheck(QModbusDataUnit::InputRegisters, 85, 1);
|
||
|
||
// Используем shared pointers вместо ссылок на стековые переменные
|
||
auto totalActiveBoards = QSharedPointer<int>::create(0);
|
||
auto confirmedBoards = QSharedPointer<int>::create(0);
|
||
auto pendingBoards = QSharedPointer<QSet<int>>::create();
|
||
|
||
for(int i = 0; i < 4; ++i) {
|
||
if(!Boards[i].isActive)
|
||
continue;
|
||
(*totalActiveBoards)++;
|
||
int slaveAddress = Boards[i].adr;
|
||
QModbusReply *reply = modbusDevice->sendReadRequest(unitCheck, slaveAddress);
|
||
if(!reply) {
|
||
revertToOldSpeedAndRestart();
|
||
return;
|
||
}
|
||
pendingBoards->insert(slaveAddress);
|
||
|
||
connect(reply, &QModbusReply::finished, this,
|
||
[this, i, reply, slaveAddress, totalActiveBoards, confirmedBoards, pendingBoards]() {
|
||
if(reply->error() == QModbusDevice::NoError) {
|
||
(*confirmedBoards)++;
|
||
} else {
|
||
logError(tr("Плата %1 (ID %2)").arg(i+1).arg(slaveAddress),
|
||
reply->errorString(), ++Boards[i].error_baud_change,
|
||
"Ошибка при подтверждении изменения скорости обмена.");
|
||
}
|
||
pendingBoards->remove(slaveAddress);
|
||
reply->deleteLater();
|
||
|
||
if(pendingBoards->isEmpty()) {
|
||
if(*confirmedBoards != *totalActiveBoards) {
|
||
emit errorAtCheckBoards();
|
||
} else {
|
||
emit successAtCheckBoards();
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
// Если нет ни одной активной платы — сразу запускаем сканирование
|
||
if(*totalActiveBoards == 0) {
|
||
emit errorAtCheckBoards();
|
||
}
|
||
}
|
||
|
||
void M3KTE::onSpeedUpdate()
|
||
{
|
||
stopScanBoard();
|
||
modbusDevice->setTimeout(500);
|
||
unsigned tmp_speed = 0;
|
||
switch(m_deviceSettingsDialog->currentSpeed()) {
|
||
case 0: tmp_speed = 9600; break;
|
||
case 1: tmp_speed = 14400; break;
|
||
case 2: tmp_speed = 19200; break;
|
||
case 3: tmp_speed = 31250; break;
|
||
case 4: tmp_speed = 38400; break;
|
||
case 5: tmp_speed = 56000; break;
|
||
case 6: tmp_speed = 57600; break;
|
||
case 7: tmp_speed = 115200; break;
|
||
}
|
||
|
||
if(tmp_speed == 0) {
|
||
logError(tr("Программная ошибка"), "Неожиданное значение скорости", 0,
|
||
"Ошибка при изменении скорости обмена.");
|
||
beginScanBoards();
|
||
return;
|
||
}
|
||
|
||
// Используем shared pointers вместо ссылок на стековые переменные
|
||
auto totalActiveBoards = QSharedPointer<int>::create(0);
|
||
auto confirmedBoards = QSharedPointer<int>::create(0);
|
||
auto pendingBoards = QSharedPointer<QSet<int>>::create();
|
||
auto newSpeed = tmp_speed; // копируем для захвата
|
||
|
||
QModbusDataUnit unit(QModbusDataUnit::HoldingRegisters, 173, 1);
|
||
unit.setValue(0, m_deviceSettingsDialog->currentSpeed());
|
||
|
||
// Лямбда для обработки результата
|
||
auto processResult = [this, totalActiveBoards, confirmedBoards, newSpeed]() {
|
||
if(*confirmedBoards != *totalActiveBoards) {
|
||
modbusDevice->setTimeout(m_settingsDialog->settings().responseTime);
|
||
revertToOldSpeedAndRestart();
|
||
beginScanBoards();
|
||
} else {
|
||
modbusDevice->disconnectDevice();
|
||
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, newSpeed);
|
||
modbusDevice->connectDevice();
|
||
|
||
// Используем QPointer для безопасного доступа к this
|
||
QPointer<M3KTE> safeThis(this);
|
||
|
||
connect(this, &M3KTE::errorAtCheckBoards, this, [safeThis]() {
|
||
if (!safeThis) return;
|
||
safeThis->disconnect(safeThis, &M3KTE::errorAtCheckBoards, safeThis, nullptr);
|
||
safeThis->modbusDevice->setTimeout(safeThis->m_settingsDialog->settings().responseTime);
|
||
safeThis->revertToOldSpeedAndRestart();
|
||
safeThis->beginScanBoards();
|
||
});
|
||
|
||
connect(this, &M3KTE::successAtCheckBoards, this, [safeThis]() {
|
||
if (!safeThis) return;
|
||
safeThis->disconnect(safeThis, &M3KTE::successAtCheckBoards, safeThis, nullptr);
|
||
safeThis->m_settingsDialog->UpdateBaud(safeThis->m_deviceSettingsDialog->currentSpeed());
|
||
safeThis->modbusDevice->setTimeout(safeThis->m_settingsDialog->settings().responseTime);
|
||
safeThis->beginScanBoards();
|
||
});
|
||
|
||
checkBoards();
|
||
}
|
||
};
|
||
|
||
for(int i = 0; i < 4; i++) {
|
||
if(!Boards[i].isActive)
|
||
continue;
|
||
int slaveAdress = Boards[i].adr;
|
||
auto *reply = modbusDevice->sendWriteRequest(unit, slaveAdress);
|
||
if(reply) {
|
||
(*totalActiveBoards)++;
|
||
pendingBoards->insert(slaveAdress);
|
||
|
||
// Захватываем shared pointers по значению - это безопасно
|
||
connect(reply, &QModbusReply::finished, this,
|
||
[this, i, reply, slaveAdress, totalActiveBoards, confirmedBoards, pendingBoards, processResult]() {
|
||
if(reply->error() == QModbusDevice::TimeoutError) {
|
||
(*confirmedBoards)++;
|
||
} else if (reply->error() == QModbusDevice::NoError) {
|
||
logError(tr("Плата %1 (ID %2)").arg(i+1).arg(slaveAdress),
|
||
tr("Неожиданный ответ."), ++Boards[i].error_baud_change,
|
||
"Ошибка при изменении скорости обмена.");
|
||
} else {
|
||
logError(tr("Плата %1 (ID %2)").arg(i+1).arg(slaveAdress),
|
||
reply->errorString(), ++Boards[i].error_baud_change,
|
||
"Ошибка при изменении скорости обмена.");
|
||
}
|
||
pendingBoards->remove(slaveAdress);
|
||
reply->deleteLater();
|
||
|
||
if(pendingBoards->isEmpty()) {
|
||
processResult();
|
||
}
|
||
});
|
||
}
|
||
}
|
||
}
|
||
|
||
// Вспомогательная функция восстановления старой скорости
|
||
void M3KTE::revertToOldSpeedAndRestart()
|
||
{
|
||
modbusDevice->disconnectDevice();
|
||
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,
|
||
m_settingsDialog->curBaud());
|
||
modbusDevice->setTimeout(m_settingsDialog->settings().responseTime);
|
||
modbusDevice->connectDevice();
|
||
}
|
||
|
||
void M3KTE::onParityUpdate()
|
||
{
|
||
stopScanBoard();
|
||
modbusDevice->setTimeout(500);
|
||
QModbusDataUnit unit(QModbusDataUnit::HoldingRegisters, 174, 1);
|
||
switch(m_deviceSettingsDialog->currentParity()) {
|
||
case 0: //Нет контроля
|
||
unit.setValue(0, 0x000);
|
||
break;
|
||
case 1: //Четный
|
||
unit.setValue(0, 0x0400);
|
||
break;
|
||
case 2: //Нечетный
|
||
unit.setValue(0, 0x0600);
|
||
break;
|
||
}
|
||
|
||
// Используем shared pointers вместо ссылок на стековые переменные
|
||
auto totalActiveBoards = QSharedPointer<int>::create(0);
|
||
auto confirmedBoards = QSharedPointer<int>::create(0);
|
||
auto pendingBoards = QSharedPointer<QSet<int>>::create();
|
||
auto oldParity = m_settingsDialog->curParity(); // сохраняем старую четность для отката
|
||
auto newParity = m_deviceSettingsDialog->currentParity();
|
||
|
||
// Лямбда для обработки результата
|
||
auto processResult = [this, totalActiveBoards, confirmedBoards, oldParity, newParity]() {
|
||
if(*confirmedBoards != *totalActiveBoards) {
|
||
modbusDevice->setTimeout(m_settingsDialog->settings().responseTime);
|
||
beginScanBoards();
|
||
} else {
|
||
modbusDevice->disconnectDevice();
|
||
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, newParity);
|
||
modbusDevice->connectDevice();
|
||
|
||
auto errorHandler = [this, oldParity]() {
|
||
disconnect(this, &M3KTE::errorAtCheckBoards, this, nullptr);
|
||
modbusDevice->setTimeout(m_settingsDialog->settings().responseTime);
|
||
modbusDevice->disconnectDevice();
|
||
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, oldParity);
|
||
modbusDevice->connectDevice();
|
||
beginScanBoards();
|
||
};
|
||
|
||
auto successHandler = [this, newParity]() {
|
||
disconnect(this, &M3KTE::successAtCheckBoards, this, nullptr);
|
||
m_settingsDialog->UpdateParity(newParity);
|
||
modbusDevice->setTimeout(m_settingsDialog->settings().responseTime);
|
||
beginScanBoards();
|
||
};
|
||
|
||
connect(this, &M3KTE::errorAtCheckBoards, this, errorHandler);
|
||
connect(this, &M3KTE::successAtCheckBoards, this, successHandler);
|
||
|
||
checkBoards();
|
||
}
|
||
};
|
||
|
||
for(int i = 0; i < 4; i++) {
|
||
if(!Boards[i].isActive)
|
||
continue;
|
||
int slaveAdress = Boards[i].adr;
|
||
auto *reply = modbusDevice->sendWriteRequest(unit, slaveAdress);
|
||
if(reply) {
|
||
(*totalActiveBoards)++;
|
||
pendingBoards->insert(slaveAdress);
|
||
|
||
connect(reply, &QModbusReply::finished, this,
|
||
[this, i, reply, slaveAdress, totalActiveBoards, confirmedBoards, pendingBoards, processResult]() {
|
||
if(reply->error() == QModbusDevice::TimeoutError) {
|
||
(*confirmedBoards)++;
|
||
} else if (reply->error() == QModbusDevice::NoError) {
|
||
logError(tr("Плата %1 (ID %2)").arg(i+1).arg(slaveAdress),
|
||
tr("Неожиданный ответ."), ++Boards[i].error_baud_change,
|
||
"Ошибка при изменении чётности.");
|
||
} else {
|
||
logError(tr("Плата %1 (ID %2)").arg(i+1).arg(slaveAdress),
|
||
reply->errorString(), ++Boards[i].error_baud_change,
|
||
"Ошибка при изменении чётности.");
|
||
}
|
||
pendingBoards->remove(slaveAdress);
|
||
reply->deleteLater();
|
||
|
||
if(pendingBoards->isEmpty()) {
|
||
processResult();
|
||
}
|
||
});
|
||
}
|
||
}
|
||
}
|
||
|
||
bool M3KTE::pingNetworkDevices()
|
||
{
|
||
CurrentConnectedDevice = 0;
|
||
int tmp_adr = 1;
|
||
bool isRun = false;
|
||
bool *tmp_isRun = &isRun;
|
||
auto bar = new QProgressDialog(this);
|
||
connect(bar, &QProgressDialog::canceled, this, [tmp_isRun]() {
|
||
*tmp_isRun = true;
|
||
});
|
||
bar->setLabelText(tr("Поиск плат... Текущий адрес: %1").arg(tmp_adr));
|
||
bar->setCancelButton(nullptr);
|
||
bar->setRange(0, 4);
|
||
bar->setMinimumDuration(100);
|
||
bar->setValue(CurrentConnectedDevice);
|
||
modbusDevice->setNumberOfRetries(0);
|
||
QModbusRequest requestOfDeviceType(QModbusRequest::EncapsulatedInterfaceTransport, QByteArray::fromHex("0E0404"));
|
||
QModbusRequest requestOfBoardID(QModbusRequest::EncapsulatedInterfaceTransport, QByteArray::fromHex("0E0401"));
|
||
|
||
for(CurrentConnectedDevice=0; CurrentConnectedDevice<4;) {
|
||
modbusDevice->setTimeout(1000);
|
||
auto *reply = modbusDevice->sendRawRequest(requestOfDeviceType, tmp_adr);
|
||
//Запрос типа устройства.
|
||
if(reply == nullptr) {
|
||
onConnectClicked();
|
||
bar->close();
|
||
bar->deleteLater();
|
||
return false;
|
||
}
|
||
while(!reply->isFinished()) {
|
||
if(isRun && CurrentConnectedDevice < 1) {
|
||
onConnectClicked();
|
||
bar->close();
|
||
bar->deleteLater();
|
||
return false;
|
||
} else if(isRun) {
|
||
break;
|
||
}
|
||
QCoreApplication::processEvents();
|
||
}
|
||
if(isRun && CurrentConnectedDevice < 1) {
|
||
onConnectClicked();
|
||
bar->close();
|
||
bar->deleteLater();
|
||
return false;
|
||
} else if(isRun) {
|
||
break;
|
||
} else if(!isRun) {
|
||
//Нужна проверка типа устройства
|
||
if(reply->error()==QModbusDevice::NoError) {
|
||
QModbusResponse resp = reply->rawResult();
|
||
QString result = QString(resp.data().remove(0, MODBUS_REQUEST_PROTOCOL_INFO_LENGTH));
|
||
if(result == QString("KTE")) {
|
||
modbusDevice->setTimeout(1000);
|
||
auto *subreply = modbusDevice->sendRawRequest(requestOfBoardID, tmp_adr);
|
||
|
||
while(!subreply->isFinished()) {
|
||
if(isRun && CurrentConnectedDevice < 1) {
|
||
onConnectClicked();
|
||
bar->close();
|
||
bar->deleteLater();
|
||
return false;
|
||
} else if(isRun) {
|
||
break;
|
||
}
|
||
QCoreApplication::processEvents();
|
||
}
|
||
int plata_ind = 0;
|
||
if(subreply->rawResult().data().size() >= MODBUS_REQUEST_PROTOCOL_INFO_LENGTH) // ответ принят
|
||
plata_ind = subreply->rawResult().data().at(MODBUS_REQUEST_PROTOCOL_INFO_LENGTH); // парс ответа
|
||
if(plata_ind == 0) // если номер = 0 повторяем всё еще раз
|
||
{
|
||
qDebug() << "Reqest plata_ind again for address " << tmp_adr;
|
||
subreply = modbusDevice->sendRawRequest(requestOfBoardID, tmp_adr);
|
||
|
||
while(!subreply->isFinished()) {
|
||
if(isRun && CurrentConnectedDevice < 1) {
|
||
onConnectClicked();
|
||
bar->close();
|
||
bar->deleteLater();
|
||
return false;
|
||
} else if(isRun) {
|
||
break;
|
||
}
|
||
QCoreApplication::processEvents();
|
||
}
|
||
plata_ind = subreply->rawResult().data().at(MODBUS_REQUEST_PROTOCOL_INFO_LENGTH);
|
||
}
|
||
if(plata_ind == 0)
|
||
{
|
||
QMessageBox::warning(this, "Ошибка при сканировании сети.",
|
||
QString("Не удалось получить порядковый номер платы по адресу %1").arg(tmp_adr));
|
||
onConnectClicked();
|
||
bar->close();
|
||
bar->deleteLater();
|
||
return false;
|
||
}
|
||
|
||
int board_ind = plata_ind-1;
|
||
if(isRun && CurrentConnectedDevice < 1) {
|
||
onConnectClicked();
|
||
bar->close();
|
||
bar->deleteLater();
|
||
return false;
|
||
} else if(isRun) {
|
||
break;
|
||
} else {
|
||
statusBar()->showMessage(tr("Плата %1 найдена по адресу %2.").arg(board_ind).arg(tmp_adr),
|
||
m_settingsDialog->settings().responseTime);
|
||
if(Boards[board_ind].isActive) {
|
||
QMessageBox::warning(this, "Ошибка при сканировании сети.",
|
||
QString("Платы по адресам %1 и %2 имеют одинаковый порядковый номер %3").arg(Boards[board_ind].adr).arg(tmp_adr).arg(plata_ind));
|
||
onConnectClicked();
|
||
bar->close();
|
||
bar->deleteLater();
|
||
return false;
|
||
}
|
||
CurrentConnectedDevice++;
|
||
Boards[board_ind].adr = Boards[board_ind]._tmp_adr = tmp_adr;
|
||
|
||
|
||
Boards[board_ind].isActive = true;
|
||
bar->setValue(CurrentConnectedDevice);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
tmp_adr++;
|
||
bar->setLabelText(tr("Поиск плат... Текущий адрес: %1").arg(tmp_adr));
|
||
if(tmp_adr>=247 && (CurrentConnectedDevice<1)) {
|
||
//ERROR
|
||
//OUT OF RANGE
|
||
QMessageBox::warning(this, "Ошибка при сканировании сети.",
|
||
QString("Выход за пределы допустимых адресов. Найдено %1 плат.").arg(CurrentConnectedDevice));
|
||
bar->setValue(4);
|
||
bar->close();
|
||
bar->deleteLater();
|
||
onConnectClicked();
|
||
return false;
|
||
} else if(tmp_adr>=247) {
|
||
break;
|
||
}
|
||
}
|
||
isRun=false;
|
||
QMessageBox::warning(this, "Сканирование сети завершено.", tr("Найдено плат: %1 из 4.").arg(CurrentConnectedDevice));
|
||
if(isRun) {
|
||
QMessageBox::warning(this, "Ошибка при получении текущих настроек.", QString("Прерывание по запросу пользователя."));
|
||
onConnectClicked();
|
||
bar->close();
|
||
bar->deleteLater();
|
||
return false;
|
||
}
|
||
modbusDevice->setTimeout(m_settingsDialog->settings().responseTime);
|
||
bar->setLabelText(tr("Считывание текущих настроек..."));
|
||
bar->setRange(0, CurrentConnectedDevice*3);
|
||
QModbusDataUnit* _unit_settings[3];
|
||
_unit_settings[0] = new QModbusDataUnit(QModbusDataUnit::Coils, 0, 85);
|
||
_unit_settings[1] = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 0, 85);
|
||
_unit_settings[2] = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 85, 85);
|
||
for(int i = 0; i < 4; i++) {
|
||
if(Boards[i].isActive) {
|
||
Boards_Fields[i]->setEnabled(true);
|
||
for(int j = 0; j < 3; j++) {
|
||
bar->setValue(i*3+j);
|
||
if(isRun) {
|
||
onConnectClicked();
|
||
bar->close();
|
||
bar->deleteLater();
|
||
return false;
|
||
}
|
||
auto *reply = modbusDevice->sendReadRequest(*_unit_settings[j], Boards[i].adr);
|
||
if(!reply) {
|
||
onConnectClicked();
|
||
bar->close();
|
||
bar->deleteLater();
|
||
return false;
|
||
}
|
||
while(!reply->isFinished()) {
|
||
if(isRun) {
|
||
QMessageBox::warning(this, "Ошибка при получении текущих настроек.",
|
||
QString("Прерывание по запросу пользователя."));
|
||
onConnectClicked();
|
||
bar->close();
|
||
bar->deleteLater();
|
||
return false;
|
||
}
|
||
QCoreApplication::processEvents();
|
||
}
|
||
if(reply->error()==QModbusDevice::NoError) {
|
||
applySettingsFromScan(reply);
|
||
} else {
|
||
QMessageBox::warning(this, "Ошибка при получении текущих настроек.",
|
||
QString("Таймаут при опросе устройства %1 по адресу %2").arg(i+1).arg(Boards[i].adr));
|
||
bar->setValue(CurrentConnectedDevice*3);
|
||
bar->close();
|
||
bar->deleteLater();
|
||
onConnectClicked();
|
||
return false;
|
||
}
|
||
}
|
||
Boards_Fields[i]->setTitle(QString("Плата №%1 (ID %2)").arg(i+1).arg(Boards[i].adr));
|
||
}
|
||
}
|
||
modbusDevice->setNumberOfRetries(m_settingsDialog->settings().numberOfRetries);
|
||
beginScanBoards();
|
||
bar->deleteLater();
|
||
return true;
|
||
}
|
||
|
||
void M3KTE::beginScanBoards()
|
||
{
|
||
for(int i = 0; i < 4; i++) {
|
||
if(Boards[i].isActive) {
|
||
m_deviceSettingsDialog->initPollForBoard(i, Boards[i].adr);
|
||
boardScan(i);
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
void M3KTE::boardScan(unsigned boardID)
|
||
{
|
||
if (!modbusDevice) {
|
||
return;
|
||
}
|
||
|
||
statusBar()->clearMessage();
|
||
|
||
QModbusDataUnit statusUnit(QModbusDataUnit::InputRegisters, 85, 1);
|
||
|
||
if (auto *reply = modbusDevice->sendReadRequest(statusUnit, Boards[boardID].adr)) {
|
||
Boards[boardID].timerToStatusResponse.start();
|
||
|
||
if (!reply->isFinished()) {
|
||
connect(reply, &QModbusReply::finished, this, [this, boardID, reply]() {
|
||
if(!Boards[boardID].isActive)
|
||
return;
|
||
|
||
// Обработка ответа статуса
|
||
Boards[boardID].timerStatus->setText(QString("Status: %1 ms").arg(Boards[boardID].timerToStatusResponse.elapsed()));
|
||
|
||
if (reply->error() == QModbusDevice::NoError) {
|
||
statusreg StatusReg;
|
||
StatusReg.AllReg = reply->result().value(0);
|
||
|
||
// Запрос полных данных
|
||
QModbusDataUnit dataUnit(QModbusDataUnit::InputRegisters, 0, 85);
|
||
if (auto *dataReply = modbusDevice->sendReadRequest(dataUnit, Boards[boardID].adr)) {
|
||
Boards[boardID].timerToDataResponse.start();
|
||
|
||
if (!dataReply->isFinished()) {
|
||
connect(dataReply, &QModbusReply::finished, this, [this, boardID, dataReply, StatusReg]() {
|
||
if(!Boards[boardID].isActive)
|
||
return;
|
||
Boards[boardID].timerData->setText(QString("Data: %1 ms").arg(Boards[boardID].timerToDataResponse.elapsed()));
|
||
displayResultOfScan(dataReply, boardID, StatusReg.AllReg);
|
||
dataReply->deleteLater();
|
||
unsigned timerInterval = m_deviceSettingsDialog->currentBoardTimer(boardID);
|
||
Boards[boardID].boardScanners->start(timerInterval);
|
||
});
|
||
} else {
|
||
// Мгновенно завершенный запрос данных
|
||
Boards[boardID].timerToDataResponse.elapsed();
|
||
// shouldLog для dataReply должен определяться здесь, но используем тот же принцип
|
||
if (Boards[boardID].isActive && !(reply->error() == QModbusDevice::ReplyAbortedError)) {
|
||
logError(tr("Плата %1 (ID %2)").arg(boardID + 1).arg(Boards[boardID].adr),
|
||
modbusDevice->errorString(), ++Boards[boardID].error_TX, "");
|
||
}
|
||
dataReply->deleteLater();
|
||
unsigned timerInterval = m_deviceSettingsDialog->currentBoardTimer(boardID);
|
||
Boards[boardID].boardScanners->start(timerInterval);
|
||
}
|
||
} else {
|
||
// Ошибка отправки запроса данных
|
||
if (Boards[boardID].isActive && !(reply->error() == QModbusDevice::ReplyAbortedError)) {
|
||
logError(tr("Плата %1 (ID %2)").arg(boardID + 1).arg(Boards[boardID].adr),
|
||
modbusDevice->errorString(), ++Boards[boardID].error_TX, "");
|
||
}
|
||
unsigned timerInterval = m_deviceSettingsDialog->currentBoardTimer(boardID);
|
||
Boards[boardID].boardScanners->start(timerInterval);
|
||
}
|
||
|
||
} else {
|
||
// Ошибка в ответе статуса
|
||
if (Boards[boardID].isActive && !(reply->error() == QModbusDevice::ReplyAbortedError)) {
|
||
logError(tr("Плата %1 (ID %2)").arg(boardID + 1).arg(Boards[boardID].adr),
|
||
reply->errorString(), ++Boards[boardID].error_TX, "");
|
||
}
|
||
unsigned timerInterval = m_deviceSettingsDialog->currentBoardTimer(boardID);
|
||
Boards[boardID].boardScanners->start(timerInterval);
|
||
}
|
||
|
||
reply->deleteLater();
|
||
});
|
||
} else {
|
||
// Мгновенно завершенный запрос статуса
|
||
Boards[boardID].timerToStatusResponse.elapsed();
|
||
// Для мгновенно завершенных запросов определяем shouldLog здесь
|
||
if (Boards[boardID].isActive && !(reply->error() == QModbusDevice::ReplyAbortedError)) {
|
||
logError(tr("Плата %1 (ID %2)").arg(boardID + 1).arg(Boards[boardID].adr),
|
||
modbusDevice->errorString(), ++Boards[boardID].error_TX, "");
|
||
}
|
||
reply->deleteLater();
|
||
unsigned timerInterval = m_deviceSettingsDialog->currentBoardTimer(boardID);
|
||
Boards[boardID].boardScanners->start(timerInterval);
|
||
}
|
||
} else {
|
||
// Ошибка отправки запроса статуса
|
||
if (Boards[boardID].isActive) {
|
||
logError(tr("Плата %1 (ID %2)").arg(boardID + 1).arg(Boards[boardID].adr),
|
||
modbusDevice->errorString(), ++Boards[boardID].error_TX, "");
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
void M3KTE::displayResultOfScan(QModbusReply *reply, int boardID, int status)
|
||
{
|
||
if(!reply)
|
||
return;
|
||
if(reply->error() == QModbusDevice::NoError) {
|
||
const QModbusDataUnit unit = reply->result();
|
||
bool W_Flag = false;
|
||
bool A_Flag = false;
|
||
if(unit.startAddress() != 0 || unit.valueCount() != 85) {
|
||
logError(tr("Плата %1 (ID %2)").arg(boardID+1).arg(Boards[boardID].adr),
|
||
"Ошибка при приёме.", ++Boards[boardID].error_RX,
|
||
tr("Принятый ответ: Стартовый адрес %1, Количество элементов %2").arg(unit.startAddress()).arg(unit.valueCount()));
|
||
reply->deleteLater();
|
||
return;
|
||
}
|
||
|
||
statusreg StatusReg;
|
||
StatusReg.AllReg = status;
|
||
|
||
// Обрабатываем статус MZKT
|
||
QString statusText;
|
||
int state = StatusReg.ParsingReg.mzkte_status;
|
||
int numb_err = StatusReg.ParsingReg.mzkte_error;
|
||
if (state == 0) {
|
||
statusText = "Ok";
|
||
} else if (state == 1) {
|
||
statusText = "Non-Critical";
|
||
} else if (state == 2) {
|
||
statusText = "Critical";
|
||
}
|
||
if (state) {
|
||
switch (numb_err) {
|
||
case 1:
|
||
statusText += QString(" (Err 5 VD)");
|
||
break;
|
||
case 2:
|
||
statusText += QString(" (Err 5 VA)");
|
||
break;
|
||
case 3:
|
||
statusText += QString(" (Err 5 Vsci)");
|
||
break;
|
||
case 4:
|
||
statusText += QString(" (Err 24 V)");
|
||
break;
|
||
case 5:
|
||
statusText += QString(" (Hardfault)");
|
||
break;
|
||
case 6:
|
||
statusText += QString(" (ADC Error)");
|
||
break;
|
||
case 7:
|
||
statusText += QString(" (UART Error)");
|
||
break;
|
||
case 8:
|
||
statusText += QString(" (Measure Error)");
|
||
break;
|
||
default:
|
||
statusText += QString(" (Program Err %1)").arg(numb_err - 4);
|
||
break;
|
||
}
|
||
}
|
||
Boards[boardID].localError->setText(statusText);
|
||
|
||
|
||
Boards[boardID].localState[LOCAL_STATE_POLL]->setChecked(StatusReg.ParsingReg.poll_allowed);
|
||
Boards[boardID].localState[LOCAL_STATE_WARN]->setChecked(StatusReg.ParsingReg.warning);
|
||
Boards[boardID].localState[LOCAL_STATE_ERR]->setChecked(StatusReg.ParsingReg.accident);
|
||
|
||
|
||
QString W_Adr;
|
||
QString A_Adr;
|
||
for(int i = unit.startAddress(), total = int(unit.valueCount()); i < total; ++i) {
|
||
if(Boards[boardID].coil[i]==true) {
|
||
int j = 0;
|
||
if(Boards[boardID].HR[i+85] > unit.value(i)) {
|
||
j = 1;
|
||
if(j != m_ProgressBar[i+boardID*85]->value()) {
|
||
A_Adr += tr("ТЭ%1 ").arg(i);
|
||
Boards[boardID].error_A++;
|
||
}
|
||
m_ProgressBar[i+boardID*85]->setStatusTip(QString("П%1 ТЭ%2: Аварийный уровень напряжения.").arg(QString::number(boardID+1), QString::number(i%85)));
|
||
m_ProgressBar[i+boardID*85]->setWhatsThis(QString("П%1 ТЭ%2: Аварийный уровень напряжения.").arg(QString::number(boardID+1), QString::number(i%85)));
|
||
A_Flag = true;
|
||
} else if(Boards[boardID].HR[i] > unit.value(i)) {
|
||
j = 2;
|
||
if(j != m_ProgressBar[i+boardID*85]->value()) {
|
||
W_Adr += tr("ТЭ%1 ").arg(i);
|
||
Boards[boardID].error_W++;
|
||
}
|
||
m_ProgressBar[i+boardID*85]->setStatusTip(QString("П%1 ТЭ%2: Предупредительный уровень напряжения.").arg(QString::number(boardID+1), QString::number(i%85)));
|
||
m_ProgressBar[i+boardID*85]->setWhatsThis(QString("П%1 ТЭ%2: Предупредительный уровень напряжения.").arg(QString::number(boardID+1), QString::number(i%85)));
|
||
W_Flag = true;
|
||
} else {
|
||
j = 3;
|
||
m_ProgressBar[i+boardID*85]->setStatusTip(QString("П%1 ТЭ%2: Уровень напряжения в норме.").arg(QString::number(boardID+1), QString::number(i%85)));
|
||
m_ProgressBar[i+boardID*85]->setWhatsThis(QString("П%1 ТЭ%2: Уровень напряжения в норме.").arg(QString::number(boardID+1), QString::number(i%85)));
|
||
}
|
||
m_ProgressBar[i+boardID*85]->setValue(j);
|
||
QString style_fc = "QProgressBar {border: 2px solid black; font: bold 10px} QProgressBar::chunk {background: hsva(" + QString::number(j*50-50) + ", 255, 255, 100%);} ";
|
||
m_ProgressBar[i+boardID*85]->setStyleSheet(style_fc);
|
||
} else {
|
||
m_ProgressBar[i+boardID*85]->setValue(3);
|
||
m_ProgressBar[i+boardID*85]->setStatusTip(QString("П%1 ТЭ%2: Топливный Элемент не учитывается.").arg(QString::number(boardID+1), QString::number(i%85)));
|
||
m_ProgressBar[i+boardID*85]->setWhatsThis(QString("П%1 ТЭ%2: Топливный Элемент не учитывается.").arg(QString::number(boardID+1), QString::number(i%85)));
|
||
QString style_fc_off = "QProgressBar {border: 2px solid black; font: bold 10px} QProgressBar::chunk {background: hsva(" + QString::number(30) + ", 30, 30, 30%);} ";
|
||
m_ProgressBar[i+boardID*85]->setStyleSheet(style_fc_off);
|
||
}
|
||
Boards[boardID].ModbusModelCoil->set_currentU(unit.value(i), i);
|
||
Boards[boardID].ModbusModelHoldingReg->set_currentU(unit.value(i), i);
|
||
}
|
||
Boards[boardID].ModbusModelCoil->dataChanged(ui->writeValueTable->model()->index(unit.startAddress(), 2),
|
||
ui->writeValueTable->model()->index(unit.startAddress() + unit.valueCount() -1, 2));
|
||
Boards[boardID].ModbusModelHoldingReg->dataChanged(ui->writeValueTable->model()->index(unit.startAddress(), 3),
|
||
ui->writeValueTable->model()->index(unit.startAddress() + unit.valueCount() -1, 3));
|
||
if(A_Flag && !A_Adr.isEmpty()) {
|
||
statusM3KTE.Accidents[boardID] = true;
|
||
logError(tr("Плата %1 (ID %2)").arg(boardID+1).arg(Boards[boardID].adr),
|
||
"Авария", Boards[boardID].error_A, A_Adr);
|
||
} else
|
||
statusM3KTE.Accidents[boardID] = false;
|
||
if(W_Flag && !W_Adr.isEmpty()) {
|
||
statusM3KTE.Warnings[boardID] = true;
|
||
logError(tr("Плата %1 (ID %2)").arg(boardID+1).arg(Boards[boardID].adr),
|
||
"Предупреждение", Boards[boardID].error_W, W_Adr);
|
||
} else
|
||
statusM3KTE.Warnings[boardID] = false;
|
||
ui->BSM_Warning->setChecked(false);
|
||
ui->BSM_Accident->setChecked(false);
|
||
ui->BSM_WorkInProgress->setChecked(true);
|
||
for(int i = 0; i < 4; i++) {
|
||
if(statusM3KTE.Accidents[i]) {
|
||
ui->BSM_WorkInProgress->setChecked(false);
|
||
ui->BSM_Warning->setChecked(false);
|
||
ui->BSM_Accident->setChecked(true);
|
||
break;
|
||
}
|
||
if(statusM3KTE.Warnings[i]) {
|
||
ui->BSM_WorkInProgress->setChecked(false);
|
||
ui->BSM_Accident->setChecked(false);
|
||
ui->BSM_Warning->setChecked(true);
|
||
}
|
||
}
|
||
} else if(reply->error() == QModbusDevice::ProtocolError) {
|
||
statusBar()->showMessage(tr("Read response error: %1 (Mobus exception: 0x%2)").
|
||
arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16), 5000);
|
||
logError(tr("Плата %1 (ID %2)").arg(boardID+1).arg(Boards[boardID].adr),
|
||
reply->errorString(), ++Boards[boardID].error_RX,
|
||
QString("Mobus exception: 0x%1").arg(reply->rawResult().exceptionCode(), -1, 16));
|
||
} else {
|
||
statusBar()->showMessage(tr("Read response error: %1 (code: 0x%2)").
|
||
arg(reply->errorString()).arg(reply->error(), -1, 16), 5000);
|
||
logError(tr("Плата %1 (ID %2)").arg(boardID+1).arg(Boards[boardID].adr),
|
||
reply->errorString(), ++Boards[boardID].error_RX,
|
||
QString::number(reply->error(), 16));
|
||
}
|
||
reply->deleteLater();
|
||
}
|
||
|
||
void M3KTE::applySettingsFromScan(QModbusReply *reply)
|
||
{
|
||
int Adr = 255;
|
||
for(int i = 0; i < 4; i++) {
|
||
if(Boards[i].adr==reply->serverAddress() &&Boards[i].isActive) {
|
||
Adr = i;
|
||
break;
|
||
}
|
||
}
|
||
if(reply->error() == QModbusDevice::NoError) {
|
||
const QModbusDataUnit unit = reply->result();
|
||
for(int i = 0, total = int(unit.valueCount()); i < (total); ++i) {
|
||
if(unit.registerType() == QModbusDataUnit::Coils) {
|
||
Boards[Adr].coil[i + unit.startAddress()] = unit.value(i);
|
||
if(unit.value(i)==1) {
|
||
Boards[Adr].ModbusModelCoil->setData(ui->writeValueTable->model()->index(i + unit.startAddress(), 2), Qt::Checked, Qt::CheckStateRole);
|
||
} else {
|
||
Boards[Adr].ModbusModelCoil->setData(ui->writeValueTable->model()->index(i + unit.startAddress(), 2), Qt::Unchecked, Qt::CheckStateRole);
|
||
}
|
||
} else if(unit.registerType() == QModbusDataUnit::HoldingRegisters) {
|
||
Boards[Adr].HR[i + unit.startAddress()] = unit.value(i);
|
||
Boards[Adr].ModbusModelHoldingReg->setData(Boards[Adr].ModbusModelHoldingReg->index(i + unit.startAddress(), 3), QString::number(unit.value(i), 16), Qt::EditRole);
|
||
}
|
||
}
|
||
} else if(reply->error() == QModbusDevice::ProtocolError) {
|
||
statusBar()->showMessage(tr("Read response error: %1 (Mobus exception: 0x%2)").
|
||
arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16), 5000);
|
||
logError(tr("Плата %1 (ID %2)").arg(Adr+1).arg(Boards[Adr].adr),
|
||
reply->errorString(), ++Boards[Adr].error_RX,
|
||
QString("Mobus exception: 0x%1").arg(reply->rawResult().exceptionCode(), -1, 16));
|
||
} else {
|
||
statusBar()->showMessage(tr("Read response error: %1 (code: 0x%2)").
|
||
arg(reply->errorString()).arg(reply->error(), -1, 16), 5000);
|
||
logError(tr("Плата %1 (ID %2)").arg(Adr+1).arg(Boards[Adr].adr),
|
||
reply->errorString(), ++Boards[Adr].error_RX,
|
||
QString::number(reply->error(), 16));
|
||
}
|
||
reply->deleteLater();
|
||
}
|
||
|
||
void M3KTE::slotmultipleRegWrite()
|
||
{
|
||
if(!modbusDevice)
|
||
return;
|
||
multipleRegWrite();
|
||
}
|
||
|
||
void M3KTE::slotmultipleRegWriteAndSend()
|
||
{
|
||
if(!modbusDevice)
|
||
return;
|
||
multipleRegWrite();
|
||
multipleRegSend();
|
||
}
|
||
|
||
void M3KTE::multipleRegSend()
|
||
{
|
||
QModbusDataUnit *unit_tx = nullptr;
|
||
if(m_regMultipleSettings->getTypeReg()) {
|
||
unit_tx = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, m_regMultipleSettings->getStartAdr(), m_regMultipleSettings->getCountReg());
|
||
} else {
|
||
unit_tx = new QModbusDataUnit(QModbusDataUnit::Coils, m_regMultipleSettings->getStartAdr(), m_regMultipleSettings->getCountReg());
|
||
}
|
||
for(unsigned i = 0; i < m_regMultipleSettings->getCountReg(); i++) {
|
||
unit_tx->setValue(i, m_regMultipleSettings->getNewValue());
|
||
if(m_regMultipleSettings->getTypeReg()) {
|
||
Boards[m_regMultipleSettings->getBoardId()].HR[i+m_regMultipleSettings->getStartAdr()] = m_regMultipleSettings->getNewValue();
|
||
} else {
|
||
Boards[m_regMultipleSettings->getBoardId()].coil[i+m_regMultipleSettings->getStartAdr()] = m_regMultipleSettings->getNewValue();
|
||
}
|
||
}
|
||
if(auto *reply = modbusDevice->sendWriteRequest(*unit_tx, Boards[m_regMultipleSettings->getBoardId()].adr)) {
|
||
unsigned Adr = m_regMultipleSettings->getBoardId();
|
||
if(!reply->isFinished()) {
|
||
connect(reply, &QModbusReply::finished, this, [this, reply, Adr]() {
|
||
if(reply->error() == QModbusDevice::ProtocolError) {
|
||
statusBar()->showMessage(tr("Write response error: %1 (Mobus exception: 0x%2)")
|
||
.arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16), 5000);
|
||
logError(tr("Плата %1 (ID %2)").arg(Adr+1).arg(Boards[Adr].adr),
|
||
reply->errorString(), ++Boards[Adr].error_TX,
|
||
QString("Mobus exception: 0x%1").arg(reply->rawResult().exceptionCode(), -1, 16));
|
||
} else if(reply->error() != QModbusDevice::NoError) {
|
||
statusBar()->showMessage(tr("Write response error: %1 (code: 0x%2)").
|
||
arg(reply->errorString()).arg(reply->error(), -1, 16), 5000);
|
||
logError(tr("Плата %1 (ID %2)").arg(Adr+1).arg(Boards[Adr].adr),
|
||
reply->errorString(), ++Boards[Adr].error_TX,
|
||
QString::number(reply->error(), 16));
|
||
}
|
||
reply->deleteLater();
|
||
});
|
||
} else {
|
||
// broadcast replies return immediately
|
||
reply->deleteLater();
|
||
}
|
||
} else {
|
||
statusBar()->showMessage(tr("Write error: ") + modbusDevice->errorString(), 5000);
|
||
}
|
||
}
|
||
|
||
void M3KTE::multipleRegWrite()
|
||
{
|
||
for(unsigned i = 0; i < m_regMultipleSettings->getCountReg(); i++) {
|
||
if(m_regMultipleSettings->getTypeReg()) {
|
||
Boards[m_regMultipleSettings->getBoardId()].ModbusModelHoldingReg->m_holdingRegisters[i+m_regMultipleSettings->getStartAdr()] = m_regMultipleSettings->getNewValue();
|
||
} else {
|
||
Boards[m_regMultipleSettings->getBoardId()].ModbusModelCoil->m_coils[i+m_regMultipleSettings->getStartAdr()] = (bool)m_regMultipleSettings->getNewValue();
|
||
}
|
||
}
|
||
}
|
||
|
||
void M3KTE::selectPositionOnTree(unsigned int index)
|
||
{
|
||
ui->boardSelectBox->setCurrentIndex(index/85);
|
||
QModelIndex selected = ui->writeValueTable->model()->index(index%85, 0);
|
||
ui->writeValueTable->selectionModel()->select(selected, QItemSelectionModel::ClearAndSelect |QItemSelectionModel::Rows);
|
||
ui->writeValueTable->scrollTo(selected);
|
||
}
|
||
|
||
bool M3KTE::autoBaudRateScan()
|
||
{
|
||
unsigned countOfDeviceOnLine = 0;
|
||
QString resultOfScan;
|
||
QVector<unsigned> KTE[8];
|
||
modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter,
|
||
m_settingsDialog->settings().portName);
|
||
#if QT_CONFIG(modbus_serialport)
|
||
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter,
|
||
m_settingsDialog->settings().parity);
|
||
modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter,
|
||
m_settingsDialog->settings().dataBits);
|
||
modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter,
|
||
m_settingsDialog->settings().stopBits);
|
||
#endif
|
||
modbusDevice->setTimeout(50);
|
||
modbusDevice->setNumberOfRetries(0);
|
||
uint m_baud[] = {9600, 14400, 19200, 31250, 38400, 56000, 57600, 115200};
|
||
bool isRun = false;
|
||
bool *tmp_isRun = &isRun;
|
||
auto bar = new QProgressDialog(this);
|
||
connect(bar, &QProgressDialog::canceled, this, [tmp_isRun]() {
|
||
*tmp_isRun = true;
|
||
});
|
||
bar->setCancelButton(nullptr);
|
||
bar->setRange(0, 8);
|
||
bar->setMinimumDuration(100);
|
||
bar->setValue(0);
|
||
QModbusRequest requestOfDeviceType(QModbusRequest::EncapsulatedInterfaceTransport, QByteArray::fromHex("0E0404"));
|
||
for(int i = 0; i < 8; i++) {
|
||
bar->setValue(i);
|
||
bar->setLabelText(tr("Поиск плат... Текущая скорость: %1").arg(m_baud[i]));
|
||
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, m_baud[i]);
|
||
if(!modbusDevice->connectDevice()) {
|
||
statusBar()->showMessage(tr("Connect failed: ") + modbusDevice->errorString(), 5000);
|
||
}
|
||
for(int tmp_adr = 1; tmp_adr < 248; tmp_adr++) {
|
||
auto *reply = modbusDevice->sendRawRequest(requestOfDeviceType, tmp_adr);
|
||
//Запрос типа устройства.
|
||
if(reply == nullptr) {
|
||
onConnectClicked();
|
||
bar->close();
|
||
bar->deleteLater();
|
||
return false;
|
||
}
|
||
while(!reply->isFinished()) {
|
||
if(isRun) {
|
||
onConnectClicked();
|
||
bar->close();
|
||
bar->deleteLater();
|
||
return false;
|
||
}
|
||
QCoreApplication::processEvents();
|
||
}
|
||
if(isRun) {
|
||
onConnectClicked();
|
||
bar->close();
|
||
bar->deleteLater();
|
||
return false;
|
||
} else if(!isRun) {
|
||
//Нужна проверка типа устройства
|
||
if(reply->error()==QModbusDevice::NoError) {
|
||
QModbusResponse resp = reply->rawResult();
|
||
QString result = QString(resp.data().remove(0, MODBUS_REQUEST_PROTOCOL_INFO_LENGTH));
|
||
if(result == QString("KTE")) {
|
||
countOfDeviceOnLine++;
|
||
KTE[i].append(tmp_adr);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if(countOfDeviceOnLine>0)
|
||
resultOfScan += QString("%1 плат M3KTE работают на скорости %2.\n").arg(countOfDeviceOnLine).arg(m_baud[i]);
|
||
countOfDeviceOnLine = 0;
|
||
modbusDevice->disconnectDevice();
|
||
}
|
||
if(m_scanBoard->exec()==QDialog::Accepted) {
|
||
if(m_scanBoard->getCheckState()==Qt::Checked) {
|
||
for(int i = 0; i < 8; i++) {
|
||
for(int j = 0; j < KTE[i].size(); j++) {
|
||
for(int l = i; l < 8; l++) {
|
||
if(KTE[l].indexOf(KTE[i].at(j))==-1) {
|
||
QMessageBox::warning(this, "Error",
|
||
QString("Несколько устройств по адресу %1, работающих на скоростях %2 и %3.").arg(KTE[i].at(j)).arg(m_baud[i]).arg(m_baud[l]));
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 173, 1);
|
||
_unit->setValue(0, m_scanBoard->getBaud());
|
||
for(int i = 0; i < 8; i++) {
|
||
bar->setValue(i);
|
||
bar->setLabelText(tr("Синхронизация плат на скорости %1").arg(m_baud[i]));
|
||
for(int j = 0; j < KTE[i].size(); j++) {
|
||
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, m_baud[i]);
|
||
if(!modbusDevice->connectDevice()) {
|
||
statusBar()->showMessage(tr("Connect failed: ") + modbusDevice->errorString(), 5000);
|
||
}
|
||
auto *reply = modbusDevice->sendWriteRequest(*_unit, KTE[i].at(j));
|
||
if(!reply) {
|
||
onConnectClicked();
|
||
bar->close();
|
||
bar->deleteLater();
|
||
return false;
|
||
}
|
||
while(!reply->isFinished()) {
|
||
if(isRun) {
|
||
onConnectClicked();
|
||
bar->close();
|
||
bar->deleteLater();
|
||
return false;
|
||
}
|
||
QCoreApplication::processEvents();
|
||
}
|
||
if(reply->error()==QModbusDevice::TimeoutError) {
|
||
modbusDevice->disconnectDevice();
|
||
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,
|
||
m_settingsDialog->UpdateBaud(m_scanBoard->getBaud()));
|
||
modbusDevice->connectDevice();
|
||
QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::InputRegisters, 85, 1);
|
||
if(auto *subreply = modbusDevice->sendReadRequest(*_unit, Boards[i].adr)) {
|
||
while(!subreply->isFinished()) {
|
||
if(isRun) {
|
||
onConnectClicked();
|
||
bar->close();
|
||
bar->deleteLater();
|
||
return false;
|
||
}
|
||
QCoreApplication::processEvents();
|
||
}
|
||
if(subreply->error()!=QModbusDevice::NoError) {
|
||
onConnectClicked();
|
||
bar->close();
|
||
bar->deleteLater();
|
||
return false;
|
||
}
|
||
}
|
||
} else if(reply->error()!=QModbusDevice::NoError) {
|
||
return false;
|
||
}
|
||
modbusDevice->disconnectDevice();
|
||
}
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
else
|
||
return false;
|
||
}
|
||
|
||
void M3KTE::stopScanBoard()
|
||
{
|
||
for(int i = 0; i < 4; i++) {
|
||
Boards[i].boardScanners->stop();
|
||
}
|
||
return;
|
||
}
|