#include "debugmaintain.h" #include "titlebar.h" #include "alarmbanner.h" #include "datacard.h" #include "ledindicator.h" #include "paramcontrol.h" #include "udpcommunication.h" #include #include #include #include #include "global.h" DebugMaintainPage::DebugMaintainPage(AppContext* ctx, QWidget* parent) : BasePage(ctx, parent) { QVBoxLayout* root = new QVBoxLayout(this); root->setContentsMargins(0, 0, 0, 0); root->setSpacing(0); m_titleBar = new TitleBar(ctx, this); m_titleBar->setTitle("洗消调试"); root->addWidget(m_titleBar); // 警告横幅(常显红闪) m_warn = new AlarmBanner(this); m_warn->showAlarm("警告:该模式下无保护功能,操作请谨慎!"); root->addWidget(m_warn); QHBoxLayout* main = new QHBoxLayout(); main->setContentsMargins(36, 16, 36, 16); main->setSpacing(28); // 左球阀控制区 QWidget* left = new QWidget(this); QVBoxLayout* leftLay = new QVBoxLayout(left); leftLay->setContentsMargins(0, 0, 0, 0); leftLay->setSpacing(16); leftLay->addWidget(makeValveGroup(1)); leftLay->addWidget(makeValveGroup(2)); leftLay->addStretch(1); left->setFixedWidth(300); main->addWidget(left); // 中央卡片区 QWidget* center = new QWidget(this); QVBoxLayout* centerLay = new QVBoxLayout(center); centerLay->setContentsMargins(0, 0, 0, 0); centerLay->setSpacing(10); QHBoxLayout* miniRow = new QHBoxLayout(); miniRow->setSpacing(10); m_chassisCard = new DataCard("底盘", center); m_chassisCard->addField("电量", "85%"); m_chassisCard->addField("电压", "360V"); m_armCard = new DataCard("机械臂", center); m_armCard->addField("末端位置", "XYZ"); m_armCard->addField("姿态", "RX/RY/RZ"); m_gasCard = new DataCard("气体检测仪", center); m_gasCard->addField("主机状态", "待机"); m_gasCard->addField("浓度", "0 ppb"); miniRow->addWidget(m_chassisCard, 1); miniRow->addWidget(m_armCard, 1); miniRow->addWidget(m_gasCard, 1); centerLay->addLayout(miniRow, 1); m_washCard = new DataCard("洗消参数", center); m_washCard->addField("洗消模式", "--"); m_washCard->addField("A组分液位", "100L"); m_washCard->addField("A药剂流量", "0 L/min"); m_washCard->addField("管路压力", "0 MPa"); m_washCard->addField("发泡倍数", "0"); m_washCard->addField("空压机故障代码", ""); m_washCard->addField("柱塞泵故障代码", ""); centerLay->addWidget(m_washCard, 1); main->addWidget(center, 1); // 右泵控制区 QWidget* right = new QWidget(this); QVBoxLayout* rightLay = new QVBoxLayout(right); rightLay->setContentsMargins(0, 0, 0, 0); rightLay->setSpacing(8); rightLay->addWidget(makePumpGroup("air", "空压机")); rightLay->addWidget(makePumpGroup("plunger", "柱塞泵")); rightLay->addWidget(makePumpGroup("leaf", "叶片泵")); rightLay->addStretch(1); right->setFixedWidth(420); main->addWidget(right); root->addLayout(main, 1); // 底部指示灯条 QWidget* bottom = new QWidget(this); bottom->setFixedHeight(94); bottom->setStyleSheet(QString("background-color:%1;border-top:1px solid %2;") .arg(C::PANEL, C::BORDER)); QHBoxLayout* bottomLay = new QHBoxLayout(bottom); bottomLay->setContentsMargins(36, 0, 24, 0); bottomLay->setSpacing(48); m_ledPlunger = new LedIndicator("柱塞泵", bottom); m_ledAir = new LedIndicator("空压机", bottom); m_ledLeaf = new LedIndicator("叶片泵", bottom); m_ledLevel = new LedIndicator("液位低", bottom); bottomLay->addWidget(m_ledPlunger); bottomLay->addWidget(m_ledAir); bottomLay->addWidget(m_ledLeaf); bottomLay->addWidget(m_ledLevel); bottomLay->addStretch(1); QPushButton* back = button("返回", "", bottom); back->setFixedSize(144, 76); connect(back, &QPushButton::clicked, this, [this]() { emit navigate(PageJob); }); bottomLay->addWidget(back); root->addWidget(bottom); connect(ctx->comm(), &UdpCommunication::telemetryUpdated, this, &DebugMaintainPage::refresh); refresh(); } QWidget* DebugMaintainPage::makeValveGroup(int valve) { QWidget* grp = new QWidget(this); grp->setProperty("card", true); grp->setStyleSheet(QString("QWidget[card=\"true\"]{background-color:%1;border:2px solid %2;border-radius:12px;}") .arg(C::PANEL, C::BORDER)); QVBoxLayout* lay = new QVBoxLayout(grp); lay->setContentsMargins(12, 12, 12, 12); lay->setSpacing(8); QLabel* title = label(QString("D%1 球阀").arg(valve), 20, C::TEXT, true, grp); lay->addWidget(title); // 控制开/关(toggle) QPushButton* ctrl = button(QString("D%1 控制:关闭").arg(valve), "", grp); ctrl->setCheckable(true); ctrl->setFixedHeight(64); connect(ctrl, &QPushButton::toggled, this, [this, valve, ctrl](bool on) { ctrl->setText(QString("D%1 控制:%2").arg(valve).arg(on ? "开启" : "关闭")); ctx()->comm()->sendBallValve(valve, on); }); lay->addWidget(ctrl); // 开启到位 / 关闭到位 LedIndicator* open = new LedIndicator("开启到位", grp); open->setState(LedIndicator::Off); LedIndicator* close = new LedIndicator("关闭到位", grp); close->setState(LedIndicator::Red); lay->addWidget(open); lay->addWidget(close); // 故障提示 QLabel* fault = label("", 16, C::DANGER, true, grp); fault->setAlignment(Qt::AlignCenter); fault->setProperty("alert", true); fault->hide(); lay->addWidget(fault); if (valve == 1) { m_valve1Btn = ctrl; m_v1Open = open; m_v1Close = close; m_valveFault1 = fault; } else { m_valve2Btn = ctrl; m_v2Open = open; m_v2Close = close; m_valveFault2 = fault; } return grp; } QWidget* DebugMaintainPage::makePumpGroup(const QString& pump, const QString& name) { QWidget* grp = new QWidget(this); grp->setProperty("card", true); grp->setStyleSheet(QString("QWidget[card=\"true\"]{background-color:%1;border:2px solid %2;border-radius:12px;}") .arg(C::PANEL, C::BORDER)); QVBoxLayout* lay = new QVBoxLayout(grp); lay->setContentsMargins(12, 8, 12, 8); lay->setSpacing(4); ParamControl* rpm = new ParamControl(name + "转速", "rpm", 10, 0, 2000, false, false, grp); rpm->setValue(200); connect(rpm, &ParamControl::valueChanged, this, [this, pump](double v) { ctx()->comm()->sendPumpRpm(pump, static_cast(v)); }); lay->addWidget(rpm); QPushButton* power = button("上电", "", grp); power->setCheckable(true); power->setFixedHeight(56); connect(power, &QPushButton::toggled, this, [this, pump, power](bool on) { power->setText(on ? "上电中" : "上电"); ctx()->comm()->sendPumpPower(pump, on); }); lay->addWidget(power); if (pump == "air") { m_airRpm = rpm; m_airPower = power; } else if (pump == "plunger") { m_plungerRpm = rpm; m_plungerPower = power; } else { m_leafRpm = rpm; m_leafPower = power; } return grp; } void DebugMaintainPage::refresh() { const Telemetry& t = ctx()->telemetry; m_chassisCard->setField(0, QString("%1%").arg(t.soc)); m_chassisCard->setField(1, QString("%1V").arg(t.volt, 0, 'f', 0)); m_armCard->setField(0, t.pos); m_armCard->setField(1, t.pose); m_gasCard->setField(0, t.gasHost == "detecting" ? "检测中" : (t.gasHost == "fault" ? "故障" : "待机")); m_gasCard->setField(1, QString("%1 ppb").arg(t.gasConc, 0, 'f', 0)); m_washCard->setField(0, t.washMode); m_washCard->setField(1, QString("%1L").arg(t.levelA, 0, 'f', 0)); m_washCard->setField(2, QString("%1 L/min").arg(t.flowA, 0, 'f', 1)); m_washCard->setField(3, QString("%1 MPa").arg(t.press, 0, 'f', 2)); m_washCard->setField(4, QString("%1").arg(t.foam, 0, 'f', 1)); m_washCard->setField(5, t.pumpFaults.value(0)); m_washCard->setField(6, t.pumpFaults.value(0)); // 球阀到位反馈 m_v1Open->setState(t.d1open ? LedIndicator::Green : LedIndicator::Off); m_v1Close->setState(t.d1close ? LedIndicator::Red : LedIndicator::Off); m_v2Open->setState(t.d2open ? LedIndicator::Green : LedIndicator::Off); m_v2Close->setState(t.d2close ? LedIndicator::Red : LedIndicator::Off); // 球阀故障提示 bool v1Fault = t.valveFault.contains("D1"); bool v2Fault = t.valveFault.contains("D2"); if (v1Fault) { m_valveFault1->setText(t.valveFault); m_valveFault1->show(); startBlink(m_valveFault1, "blink"); } else { stopBlink(m_valveFault1, "blink"); m_valveFault1->hide(); } if (v2Fault) { m_valveFault2->setText(t.valveFault); m_valveFault2->show(); startBlink(m_valveFault2, "blink"); } else { stopBlink(m_valveFault2, "blink"); m_valveFault2->hide(); } // 泵上电状态同步 if (m_airPower) m_airPower->setChecked(t.air); if (m_plungerPower) m_plungerPower->setChecked(t.plunger); if (m_leafPower) m_leafPower->setChecked(t.leaf); // 底部指示灯 m_ledPlunger->setState(t.plunger ? LedIndicator::Green : LedIndicator::Off); m_ledAir->setState(t.air ? LedIndicator::Green : LedIndicator::Off); m_ledLeaf->setState(t.leaf ? LedIndicator::Green : LedIndicator::Off); m_ledLevel->setState(t.levelA < 10 ? LedIndicator::RedBlink : LedIndicator::Off); }