#include "grifoxlrumainwindow.h"
#include "ui_grifoxlrumainwindow.h"

#include "portbridge.h"

#include "connectioninfo.h"

#include <QTimer>

#include "lruserialport.h"
#include "unitsimulator.h"
#include "unitmonitor.h"

#include "xlru/xlru_lcu.h"
#include "xlru/xlru_pps.h"
#include "xlru/xlru_psm.h"

#include <QMap>

#include <QUdpSocket>
#include <QHostAddress>
#include <QTreeWidgetItem>
#include <QPlainTextEdit>
#include <QDockWidget>
#include <QSettings>

#include <QDebug>

//#include "xlruchartsform.h"
#include "xlrumultigfxform.h"
#include "xlrutftp.h"
#include "xlru_fpga.h"

//#define FPGA_DBG
#ifdef FPGA_DBG
#define FPGA_DEFAULT_ADDRESS    0xb0000000
#define FPGA_DEFAULT_IP 101
#else
#define FPGA_DEFAULT_ADDRESS    fpga_info_t::fpga_info_address
#define FPGA_DEFAULT_IP 111
#endif

class GrifoXLruMainWindow::Implementation: public LruSerialFilter
{
public:
    GrifoXLruMainWindow* mw;

    PortBridge* bridge;

    QTimer* updateTimer;

    QUdpSocket* s;

    XLruConnectionInfo info;

    QMap<QString, LruSerialPort*> smap;

    QVector<LruSerialPort*> portVector;
    QVector<QTreeWidgetItem*> portStatus;
    QVector<QTreeWidgetItem*> fpgaStatus;
    QVector<bool> fpgaInit;

    QTreeWidget* portListWidget;
    QTreeWidgetItem* udpTi;
    QTreeWidgetItem* udpFpga;

    QTreeWidgetItem* unitStat[4];

    UnitSimulator simulator;

    UnitMonitor udpMonitor;

    QDockWidget* logDock;

    //XlruChartsForm* chartform;
    XlruMultiGfxForm* chartform;

    XlruTftp* xlruTftp;
    int fpgaPending;
    QString fpga_address;
    QStringList fpga_set;

    Implementation(GrifoXLruMainWindow* w):
        mw(w),
        bridge(0),
        updateTimer(0),
        s(0)
    {
        fpgaPending=-1;

        fpga_address=QString("0x%1").arg(FPGA_DEFAULT_ADDRESS, 0, 16);
        //fpga_set.append("0x13");
    }

    bool serialFilterIn(LruSerialPort& port, QByteArray& data) override
    {
        int u=simulator.checkMessage(data);
        int type_mess = simulator.get_type_mess(data);

        if (u!=0)
        {
            //si tratta di comando inviato da master
            switch(u)
            {
            case UnitSimulator::u_psm:
                if (mw->ui->psm->isChecked())
                {
                    //SIMULATOR
                    chartform->addSampleAllGraph("psm_temp",    (float)mw->ui->sbPSMTemp->value());
                    chartform->addSampleAllGraph("psm_current", (float)mw->ui->sbPSMInAmp->value());
                    chartform->addSampleAllGraph("psm_15v",     (float)mw->ui->sbPSMOutVolt15v->value());
                    chartform->addSampleAllGraph("psm_m15v",    (float)mw->ui->sbPSMOutVoltm15v->value());
                    chartform->addSampleAllGraph("psm_3v3",     (float)mw->ui->sbPSMOutVolt3v3->value());
                    chartform->addSampleAllGraph("psm_5v",      (float)mw->ui->sbPSMOutVolt5v->value());

                    QByteArray simRes=simulator.psmStatus();


                      //simRes = "!1n+SGNcwANNNNNNN0E002100330096FF6C300002038901000008000140__47";
                    port.write(simRes);
                    mw->ui->psmTx->setText(simRes);

                    //mw->fromMessPSM(clearArray(simRes));
                    //return false;
                }
                break;
            case UnitSimulator::u_pps:
                if (mw->ui->pps->isChecked())
                {

                    chartform->addSampleAllGraph("pps_rx_board_temp",       (float)mw->ui->sbPPSRXtemp->value());

                    chartform->addSampleAllGraph("pps_tx1_board_temp",      (float)mw->ui->sbPPSTX1temp->value());
                    chartform->addSampleAllGraph("pps_tx2_board_temp",      (float)mw->ui->sbPPSTX2temp->value());
                    chartform->addSampleAllGraph("pps_tx3_board_temp",      (float)mw->ui->sbPPSTX3temp->value());
                    chartform->addSampleAllGraph("pps_liquid_inlet_temp",   (float)mw->ui->sbPPSInletTemp->value());
                    chartform->addSampleAllGraph("pps_liquid_outlet_temp",  (float)mw->ui->sbPPSOutletTemp->value());

                    chartform->addSampleAllGraph("pps_curr_42v",            (float)mw->ui->sbPPSRXcurrent->value());
                    chartform->addSampleAllGraph("pps_tx1_curr",            (float)mw->ui->sbPPSTX1current->value());
                    chartform->addSampleAllGraph("pps_tx2_curr",            (float)mw->ui->sbPPSTX2current->value());
                    chartform->addSampleAllGraph("pps_tx3_curr",            (float)mw->ui->sbPPSTX3current->value());

                    chartform->addSampleAllGraph("pps_tx1_curr_max",        (float)mw->ui->sbPPSTX1currentMAX_2->value());
                    chartform->addSampleAllGraph("pps_tx2_curr_max",        (float)mw->ui->sbPPSTX2currentMAX_2->value());
                    chartform->addSampleAllGraph("pps_tx3_curr_max",        (float)mw->ui->sbPPSTX3currentMAX_2->value());

                    chartform->addSampleAllGraph("pps_tx1_curr_avg",        (float)mw->ui->sbPPSTX1currentAVG_2->value());
                    chartform->addSampleAllGraph("pps_tx2_curr_avg",        (float)mw->ui->sbPPSTX2currentAVG_2->value());
                    chartform->addSampleAllGraph("pps_tx3_curr_avg",        (float)mw->ui->sbPPSTX3currentAVG_2->value());

                    chartform->addSampleAllGraph("pps_rx_phaser_min",       (float)mw->ui->sbPPSRXPhaseRmin_2->value());
                    chartform->addSampleAllGraph("pps_rx_phases_min",       (float)mw->ui->sbPPSRXPhaseSmin_2->value());
                    chartform->addSampleAllGraph("pps_rx_phaset_min",       (float)mw->ui->sbPPSRXPhaseTmin_2->value());

                    chartform->addSampleAllGraph("pps_rx_phaser_max",       (float)mw->ui->sbPPSRXPhaseRmax_2->value());
                    chartform->addSampleAllGraph("pps_rx_phases_max",       (float)mw->ui->sbPPSRXPhaseSmax_2->value());
                    chartform->addSampleAllGraph("pps_rx_phaset_max",       (float)mw->ui->sbPPSRXPhaseTmax_2->value());

                    QByteArray simRes=simulator.ppsStatus();
                    port.write(simRes);
                    mw->ui->ppsTx->setText(simRes);
                    //return false;
                }
                break;
            case UnitSimulator::u_lcu:
                if (mw->ui->lcu->isChecked())
                {
                    chartform->addSampleAllGraph("lcu_ctrl_board_temp",             (float)mw->ui->sbBoardTemp->value());
                    chartform->addSampleAllGraph("lcu_motor_speed_mfs",             (float)mw->ui->sbMFS->value());
                    chartform->addSampleAllGraph("lcu_motor_temp_mtsp",             (float)mw->ui->sbMTS->value());
                    chartform->addSampleAllGraph("lcu_liquid_inlet_temp_aesa_ts1",  (float)mw->ui->sbTS1->value());
                    chartform->addSampleAllGraph("lcu_liquid_inlet_temp_pps_ts2",   (float)mw->ui->sbTS2->value());
                    chartform->addSampleAllGraph("lcu_liquid_pump_inlet_temp_ts3",  (float)mw->ui->sbTS3->value());
                    chartform->addSampleAllGraph("lcu_liquid_outlet_temp_ts4",      (float)mw->ui->sbTS4->value());
                    chartform->addSampleAllGraph("lcu_air_inlet_temp_ts5",          (float)mw->ui->sbTS5->value());
                    chartform->addSampleAllGraph("lcu_air_outlet_temp_ts6",         (float)mw->ui->sbTS6->value());
                    chartform->addSampleAllGraph("lcu_liquid_outlet_pressure_ps",   (float)mw->ui->sbPS->value());
                    chartform->addSampleAllGraph("lcu_liquid_inlet_flow_aesa_fs1",  (float)mw->ui->sbFS1->value());
                    chartform->addSampleAllGraph("lcu_liquid_inlet_flow_pps_fs2",   (float)mw->ui->sbFS2->value());

                    QByteArray simRes;

                    simRes=simulator.lcuStatus();

                    if (type_mess==1)
                        simRes=simulator.lcuEti();
                    else
                        simRes=simulator.lcuStatus();

                    //simRes = "!3m+sGI_G_____00000000001F3A201A1A1A1A1B1B__3C0D0D__0223w___80\r";
                    port.write(simRes);
                    mw->ui->lcuTx->setText(simRes);
                    //return false;
                }
                break;

            default:
                break;
            }
        }
        return true;
    }

    LruSerialPort* createPort(const QString& name, int speed, deviceID device, const QString deviceName)
    {
        if (name.isEmpty())
            return 0;
        LruSerialPort* s0=0;
        auto spi=smap.find(name);
        if (spi==smap.end())
        {
            QSerialPort::BaudRate baud=speed>0 ? QSerialPort::Baud115200 : QSerialPort::Baud9600;
            QSerialPort::Parity parity=speed>0 ? QSerialPort::NoParity : QSerialPort::EvenParity;
            s0=new LruSerialPort(name, device, baud, parity);

            s0->setUnitMonitor(new UnitMonitor);

            smap[name]=s0;
            bool ok=s0->realPortOk;
            QTreeWidgetItem* wi=new QTreeWidgetItem;
            wi->setFlags(wi->flags()|Qt::ItemIsUserCheckable);
            wi->setCheckState(0, Qt::Checked);

            wi->setText(0, (ok ? "+" : "-") + name + ":" + deviceName);
            s0->attachUserInfo(wi);
#if 0
            switch (device)
            {
            case 1:  //psm
                wi->setText(0, ok ? name+ "-PSM" : "!"+name + "-PSM");
                break;
            case 2:  //pps
                wi->setText(0, ok ? name+ "-PPS" : "!"+name + "-PPS");
                break;
            case 3: //lcu
                wi->setText(0, ok ? name+ "-LCU" : "!"+name + "-LCU");
                break;
            case 4: //master
                wi->setText(0, ok ? name+ "-EIF" : "!"+name + "-EIF");
            }
#endif
            wi->setData(0, Qt::UserRole, (unsigned long long)s0);
            portListWidget->insertTopLevelItem(0, wi);
            portVector.append(s0);
            portStatus.append(wi);
            //return s0;
        }
        else
        {
            s0=smap[name];
            if (!deviceName.isEmpty())
            {
                QTreeWidgetItem* wi=reinterpret_cast<QTreeWidgetItem*>(s0->userInfo());
                QString tmp=wi->text(0);
                tmp+="/"+deviceName;
                wi->setText(0, tmp);
            }
        }
        return s0;
        //return smap[name]; //spi.value();
    }

    void addConnection(const ConnectionInfo& i, bool masterFast)
    {
        //if (!i.serialPort.isEmpty())
        QString portName=!i.serialPort.isEmpty() ? i.serialPort : "<dummy>";
        {
            LruSerialPort* s0=createPort(portName, i.speed, i.device, i.unitName);

            if (i.bridgePort=="UDP")
            {
                if (s)
                {
                    bridge->addUdpBridge(s0, i.speed==Qt::PartiallyChecked);
                }
            }
            else
            {
                QString masterPortName=i.bridgePort.isEmpty() ? "<master>" : i.bridgePort;

                LruSerialPort* s1=createPort(masterPortName, masterFast, EIF_ID, QString());
                s1->setFilter(this);
                if (s0 && s1)
                    bridge->addBridge(s0, s1, i.speed==Qt::PartiallyChecked);
            }
        }
    }

    void addConnection(const XLruConnectionInfo& info)
    {
        if (info.psm.enabled)
            addConnection(info.psm, info.masterFast);
        if (info.pps.enabled)
            addConnection(info.pps, info.masterFast);
        if (info.lcu.enabled)
            addConnection(info.lcu, info.masterFast);
    }


    QByteArray clearArray(QByteArray& data)
    {
        QByteArray result;
        result.clear();
        for (int i = 0; i< data.size()-1; i++)
        {
            if (data[i] != '\0')
                result.append(data[i]);
            else
                result.append('0');
        }

        return result;
    }

    bool processMessages(QByteArray& data, UnitMonitor* monitor) override
    {
        int index=0;
        int round=0;
        if (!monitor)
            monitor=&udpMonitor;

        while(int u=monitor->checkMessage(data, &index))
        {
            //int u=monitor.checkMessage(data);

            if (u!=0)
            {
                //si tratta di comando ricevuto dallo slave
                QByteArray cleanData=clearArray(monitor->pendingMessage);

                qDebug()<<"Monitor"<<u<<cleanData;

                switch(u)
                {
                case UnitSimulator::u_psm:
                    if (!mw->ui->psm->isChecked())
                    {
                        //MONITOR PSM

                        mw->ui->psmTx->setText(cleanData);
                        mw->fromMessPSM(cleanData);

                    }
                    break;
                case UnitSimulator::u_pps:
                    if (!mw->ui->pps->isChecked())
                    {
                        //MONITOR PPS
                        mw->ui->ppsTx->setText(cleanData);
                        mw->fromMessPPS(cleanData);
                    }
                    break;
                case UnitSimulator::u_lcu:
                    if (!mw->ui->lcu->isChecked())
                    {
                        //MONITOR LCU
                        mw->ui->lcuTx->setText(cleanData);
                        mw->fromMessLCU(cleanData);

                    }
                    break;

                default:
                    break;
                }
            }
            ++round;
            //qDebug()<<"XXX"<<round<<index<<u;
            if (round>8)
            {
               qDebug()<<"UDP overload?"<<round<<index<<u;
               break;
            }
        }
        return true;
    }

    QTreeWidgetItem* createUnitStatTreeItem(unsigned int index, const QString& unitName, xlru_counter_t* counters)
    {
        QTreeWidgetItem* wi=new QTreeWidgetItem;
        wi->setText(0, unitName);
        wi->setData(0, Qt::UserRole, (unsigned long long)counters);
        unitStat[index]=wi;
        return wi;
    }

    /*template<int ID_, class T_> void sampleForwardToSim(int v, void (T_::*ptr)(int))
    {
        chartform->addSampleAllGraph(ID_, v);
        //chartform->addSample(ID_, v);
        (simulator.*ptr)(v);
    }*/

};

static QPlainTextEdit* txtLogger;
static QAction* actLogger;

static void myMessageOutput(QtMsgType type, const QMessageLogContext &/*context*/, const QString &msg)
  {
      //QByteArray localMsg = msg.toLocal8Bit();
      switch (type) {
      case QtDebugMsg:
      case QtInfoMsg:
          //fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
          if (actLogger->isChecked())
            txtLogger->appendPlainText(msg);
          //fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
          break;
      case QtWarningMsg:
          txtLogger->appendPlainText(msg);
          //fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
          break;
      case QtCriticalMsg:
          txtLogger->appendPlainText(msg);
          //fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
          break;
      case QtFatalMsg:
          //fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
          abort();
      }
  }

GrifoXLruMainWindow::GrifoXLruMainWindow(const XLruConnectionInfo &info, QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::GrifoXLruMainWindow),
    p_(*new GrifoXLruMainWindow::Implementation(this))
{
    ui->setupUi(this);

    ui->actionLog->setChecked(true);
    ui->actionDisable->setChecked(true);

    ui->traffic->setColumnCount(7);
    p_.portListWidget=ui->traffic;

    ui->traffic->setHeaderLabels(QStringList()<<"Port"<<"In"<<"Out"<<"ok"<<"errs"<<"cksum errs"<<"note");

    p_.info=info;

    p_.bridge=new PortBridge;

    p_.bridge->setMasterFilter(&p_);

    p_.bridge->forwardDisabled=true;

    {
        p_.s=new QUdpSocket(this);
        p_.s->bind(QHostAddress(info.network), 51011);

        p_.bridge->setSocket(p_.s);

        QTreeWidgetItem* wi=new QTreeWidgetItem;
        wi->setFlags(wi->flags()|Qt::ItemIsUserCheckable);
        wi->setCheckState(0, Qt::Checked);
        wi->setText(0, "UDP");
        wi->setData(0, Qt::UserRole, (unsigned long long)p_.s);
        ui->traffic->insertTopLevelItem(0, wi);
        p_.udpTi=wi;

    }

    {//FPGA temperature
        QSettings s("./xlru_mon.ini", QSettings::IniFormat);
        s.beginGroup("FPGA");
        QString tmp=s.value("fpga_address").toString();
        if (!tmp.isEmpty())
            p_.fpga_address=tmp;
#if 0
        int ip_last=s.value("server_ip3", FPGA_DEFAULT_IP).toInt();

        tmp=s.value("fpga_list").toString();
        if (!tmp.isEmpty())
        {
            p_.fpga_set=tmp.split(QChar(';'));
        }
        s.endGroup();
#endif
        p_.fpga_set=info.fpgaList;
        unsigned int ip_last=info.fpagServer;

        QTreeWidgetItem* wi=new QTreeWidgetItem;
        wi->setFlags(wi->flags()|Qt::ItemIsUserCheckable);
        wi->setCheckState(0, Qt::Unchecked); //Checked);
        wi->setText(0, "FPGA");
        wi->setData(0, Qt::UserRole, 0);//(unsigned long long)p_.s);
        ui->traffic->insertTopLevelItem(0, wi);
        p_.udpFpga=wi;

        p_.xlruTftp=new XlruTftp;

        QHostAddress a=QHostAddress(info.network);

        p_.xlruTftp->bind(a);
        quint32 ip=a.toIPv4Address();
        ip=ip & 0xFFFFFF00;
        ip|=ip_last;

        p_.xlruTftp->bindRemote(QHostAddress(ip), 50069);

        qDebug()<<"FPGA bind:"<<QHostAddress(ip)<<p_.fpga_address<<p_.fpga_set;

        connect(p_.xlruTftp, &XlruTftp::receiveTerminated, this, fpgaTftpReceived);
    }

    {
        ui->traffic->insertTopLevelItem(0, p_.createUnitStatTreeItem(0, "PSM", &xlru_psm::xlru_counter));
        ui->traffic->insertTopLevelItem(0, p_.createUnitStatTreeItem(1, "PPS", &xlru_pps::xlru_counter));
        ui->traffic->insertTopLevelItem(0, p_.createUnitStatTreeItem(2, "LCU", &xlru_lcu::xlru_counter));
    }

    connect(ui->traffic, &QTreeWidget::itemClicked, this, [this](QTreeWidgetItem* i, int /*column*/)
    {
        if (i==p_.udpTi)
            p_.bridge->udpEnable(i->checkState(0)!=Qt::Unchecked);
    });


    p_.updateTimer=new QTimer(this);
    p_.updateTimer->setSingleShot(false);

    connect(p_.updateTimer, &QTimer::timeout, this, [this]()
    {
        int n=p_.portVector.size();
        for(int i=0; i<n; ++i)
        {
            QTreeWidgetItem* ti=p_.portStatus[i];
            LruSerialPort* s=p_.portVector[i];
            ti->setText(1, QString("%1").arg(s->chars_in));
            ti->setText(2, QString("%1").arg(s->chars_out));
            s->setEnabled(ti->checkState(0)!=Qt::Unchecked);
        }
        p_.udpTi->setText(1, QString("%1").arg(p_.bridge->udpCharIn()));
        p_.udpTi->setText(2, QString("%1").arg(p_.bridge->udpCharOut()));

        for(int i=0; i<3; ++i)
        {
            QTreeWidgetItem* wi=p_.unitStat[i];
            xlru_counter_t* c=reinterpret_cast<xlru_counter_t*>(wi->data(0, Qt::UserRole).toULongLong());
            wi->setText(3, QString("%1").arg(c->rx_mess));
            wi->setText(4, QString("%1").arg(c->rx_mess_error));
            wi->setText(5, QString("%1").arg(c->checksum_error));
            wi->setText(6, c->last_error);
        }
        fpgaTftpPoll();
    });

    {
        txtLogger=new QPlainTextEdit("Logger");
        QDockWidget* dw=new QDockWidget("Log");
        dw->setWidget(txtLogger);
        this->addDockWidget(Qt::BottomDockWidgetArea, dw);

        txtLogger->setReadOnly(true);
        txtLogger->setMaximumBlockCount(3000);
        QFont font = QFont ("Courier New");
        font.setStyleHint (QFont::Monospace);
        font.setPointSize (8);
        font.setFixedPitch (true);
        txtLogger->setFont(font);

        p_.logDock=dw;

        dw->setVisible(false);
    }

    {
        p_.chartform=new XlruMultiGfxForm();

        p_.chartform->setListFpga(p_.fpga_set);
        p_.chartform->startAcquisition();


#if 0
        //Fast patch to make FPGA selectable run-time
        static const char* const fpga_names[]={"0x13","0x73","0x14","0x74","0x15","0x75","0x16","0x76"};

        for(unsigned int i=0; i<(sizeof(fpga_names)/sizeof(fpga_names[0])); ++i)
        {
            QString name=QString("F#%1").arg(fpga_names[i]);
            QTreeWidgetItem* wi=QTreeWidgetItem(p_.udpFpga);
            wi->setText(0, name);
            wi->setFlags(wi->flags()|Qt::ItemIsUserCheckable);
            bool active=p_.fpga_set.contains(fpga_names[i]);
            wi->setCheckState(0, active);
            wi->setData(0, Qt::UserRole, 0);
        }
#else
        for(int i=0; i<p_.fpga_set.size(); ++i)
        {
            const QString& f=p_.fpga_set[i];
            QString name=QString("F#%1").arg(f);
            //p_.chartform->addSensor(name, p_.chartform->temperatureAxis, s_fpga_1+i);
            QTreeWidgetItem* wi=new QTreeWidgetItem(p_.udpFpga);
            wi->setText(0, name);
            wi->setFlags(wi->flags()|Qt::ItemIsUserCheckable);
            wi->setCheckState(0, Qt::Checked);
            wi->setData(0, Qt::UserRole, 0);//(unsigned long long)p_.s);
            p_.fpgaStatus.append(wi);
            p_.fpgaInit.append(false);
        }
#endif
    }

    actLogger=ui->actionLog;

    p_.addConnection(info);

    foreach(LruSerialPort* sp, p_.portVector)
    {
        ui->portSel->addItem(sp->portName(), (unsigned long long)sp);
    }
    connect(ui->portCmd, &QLineEdit::returnPressed, this, [this]()
    {
        QString tmp=ui->portCmd->text();
        if (!tmp.isEmpty())
        {
            LruSerialPort* sp=reinterpret_cast<LruSerialPort*>(ui->portSel->currentData().toULongLong());
            sp->write(tmp.toLatin1());
        }
        ui->portCmd->clear();
    });

    p_.updateTimer->start(2000);

    qInstallMessageHandler(myMessageOutput);

    //connect(ui->psmGo, &QCheckBox::clicked, &p_.simulator, &UnitSimulator::pmsGo);

    //LCU
    connect(ui->cdLCUModeStatus, &QComboBox::currentTextChanged, &p_.simulator, &UnitSimulator::cdLCUModeStatus);
    connect(ui->cdLCUProgress, &QComboBox::currentTextChanged, &p_.simulator, &UnitSimulator::cdLCUProgress);
    connect(ui->cdLCUHealth, &QComboBox::currentTextChanged, &p_.simulator, &UnitSimulator::cdLCUHealth);
    connect(ui->cdLCUByPass, &QComboBox::currentTextChanged, &p_.simulator, &UnitSimulator::cdLCUByPass);
    connect(ui->cdLCUHazard, &QComboBox::currentTextChanged, &p_.simulator, &UnitSimulator::cdLCUHazard);
    connect(ui->cdLCUOverride, &QComboBox::currentTextChanged, &p_.simulator, &UnitSimulator::cdLCUOverride);
    connect(ui->sbTS1, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::dsbTS1);
    connect(ui->sbTS2, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::dsbTS2);
    connect(ui->sbTS3, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::dsbTS3);
    connect(ui->sbTS4, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::dsbTS4);
    connect(ui->sbTS5, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::dsbTS5);
    connect(ui->sbTS6, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::dsbTS6);
    connect(ui->sbBoardTemp, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::dsbBoardTemp);
    connect(ui->sbMTS, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::dsbMTS);
    connect(ui->sbMFS, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::dsbMFS);
    connect(ui->sbFS1, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::dsbFS1);
    connect(ui->sbFS2, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::dsbFS2);
    connect(ui->sbPS, static_cast<void (QDoubleSpinBox::*)(double t)>(&QDoubleSpinBox::valueChanged), &p_.simulator, &UnitSimulator::dsbPS);
    connect(ui->sbLCUVersion, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbLCUVersion);
    connect(ui->sbLCURelease, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbLCURelease);

    connect(ui->sbLCURelease, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbLCURelease);

    connect(ui->cbLCU11, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU11);
    connect(ui->cbLCU12, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU12);
    connect(ui->cbLCU13, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU13);
    connect(ui->cbLCU14, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU14);
    connect(ui->cbLCU17, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU17);

    connect(ui->cbLCU21, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU21);
    connect(ui->cbLCU22, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU22);
    connect(ui->cbLCU23, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU23);
    connect(ui->cbLCU24, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU24);
    connect(ui->cbLCU25, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU25);

    connect(ui->cbLCU31, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU31);
    connect(ui->cbLCU32, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU32);
    connect(ui->cbLCU33, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU33);
    connect(ui->cbLCU34, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU34);
    connect(ui->cbLCU38, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU38);

    connect(ui->cbLCU41, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU41);
    connect(ui->cbLCU42, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU42);
    connect(ui->cbLCU43, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU43);
    connect(ui->cbLCU44, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU44);
    connect(ui->cbLCU45, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU45);
    connect(ui->cbLCU46, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU46);
    connect(ui->cbLCU47, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU47);
    connect(ui->cbLCU48, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU48);

    connect(ui->cbLCU51, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU51);
    connect(ui->cbLCU52, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU52);
    connect(ui->cbLCU53, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU53);
    connect(ui->cbLCU55, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU55);
    connect(ui->cbLCU56, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU56);
    connect(ui->cbLCU57, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU57);
    connect(ui->cbLCU58, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbLCU58);

    connect(ui->sbLCUETI, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbLCUETI);


    //PSM
    connect(ui->cdPSMModeStatus, &QComboBox::currentTextChanged, &p_.simulator, &UnitSimulator::cdPSMModeStatus);
    connect(ui->cbPSMHazard, &QComboBox::currentTextChanged, &p_.simulator, &UnitSimulator::cbPSMHazard);
    connect(ui->cbPSM3Sec, &QComboBox::currentTextChanged, &p_.simulator, &UnitSimulator::cbPSM3Sec);
    connect(ui->cbPSMWow, &QComboBox::currentTextChanged, &p_.simulator, &UnitSimulator::cbPSMWow);
    connect(ui->cbPSMAc, &QComboBox::currentTextChanged, &p_.simulator, &UnitSimulator::cbPSMAc);
    connect(ui->cbPSMbs, &QComboBox::currentTextChanged, &p_.simulator, &UnitSimulator::cbPSMbs);
    connect(ui->cbPSMdc, &QComboBox::currentTextChanged, &p_.simulator, &UnitSimulator::cbPSMdc);
    connect(ui->cbPSMpfc, &QComboBox::currentTextChanged, &p_.simulator, &UnitSimulator::cbPSMpfc);
    connect(ui->cbPSMvolt3v3, &QComboBox::currentTextChanged, &p_.simulator, &UnitSimulator::cbPSMvolt3v3);
    connect(ui->cbPSMvolt5, &QComboBox::currentTextChanged, &p_.simulator, &UnitSimulator::cbPSMvolt5);
    connect(ui->cbPSMvolt15, &QComboBox::currentTextChanged, &p_.simulator, &UnitSimulator::cbPSMvolt12);
    connect(ui->cbPSMvoltneg15, &QComboBox::currentTextChanged, &p_.simulator, &UnitSimulator::cbPSMvoltneg12);
    connect(ui->cbPSMLastRecycle, &QComboBox::currentTextChanged, &p_.simulator, &UnitSimulator::cbPSMLastRecycle);
    connect(ui->editLastRecycleReasonFromEif, &QLineEdit::textChanged, &p_.simulator, &UnitSimulator::editLastRecycleReasonFromEif);

    connect(ui->sbPSMInAmp, static_cast<void (QDoubleSpinBox::*)(double t)>(&QDoubleSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPSMInAmp);
    connect(ui->sbPSMTemp, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPSMTemp);
#if 0
    connect(ui->sbPSMTemp, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), this, [this](int t)
    {
        p_.sampleForwardToSim<0, UnitSimulator>(t, &UnitSimulator::sbPSMTemp);
        //p_.simulator, &UnitSimulator::sbPSMTemp
    });
#endif

    connect(ui->sbPSMETI, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPSMETI);
    connect(ui->sbPSMOnCount, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPSMOnCount);
    connect(ui->sbPSMUncCount, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPSMUncCount);
    connect(ui->sbPSMVer, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPSMVer);
    connect(ui->sbPSMRel, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPSMRel);
    connect(ui->sbPSMOutVolt3v3, static_cast<void (QDoubleSpinBox::*)(double t)>(&QDoubleSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPSMOutVolt3v3);
    connect(ui->sbPSMOutVolt5v, static_cast<void (QDoubleSpinBox::*)(double t)>(&QDoubleSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPSMOutVolt5v);
    connect(ui->sbPSMOutVolt15v, static_cast<void (QDoubleSpinBox::*)(double t)>(&QDoubleSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPSMOutVolt15v);
    connect(ui->sbPSMOutVoltm15v, static_cast<void (QDoubleSpinBox::*)(double t)>(&QDoubleSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPSMOutVoltm15v);

    connect(ui->cbPSM11, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM11);
    connect(ui->cbPSM12, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM12);
    connect(ui->cbPSM13, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM13);
    connect(ui->cbPSM14, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM14);
    connect(ui->cbPSM15, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM15);
    connect(ui->cbPSM16, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM16);
    connect(ui->cbPSM17, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM17);
    connect(ui->cbPSM18, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM18);

    connect(ui->cbPSM21, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM21);
    connect(ui->cbPSM22, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM22);
    connect(ui->cbPSM23, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM23);
    connect(ui->cbPSM24, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM24);
    connect(ui->cbPSM25, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM25);
    connect(ui->cbPSM26, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM26);
    connect(ui->cbPSM27, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM27);
    connect(ui->cbPSM28, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM28);

    connect(ui->cbPSM31, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM31);
    connect(ui->cbPSM32, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM32);
    connect(ui->cbPSM33, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM33);
    connect(ui->cbPSM34, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM34);
    connect(ui->cbPSM35, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM35);
    connect(ui->cbPSM36, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM36);
    connect(ui->cbPSM37, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM37);
    connect(ui->cbPSM38, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM38);

    connect(ui->cbPSM41, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM41);
    connect(ui->cbPSM42, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM42);
    connect(ui->cbPSM43, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM43);
    connect(ui->cbPSM44, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM44);
    connect(ui->cbPSM45, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM45);
    connect(ui->cbPSM46, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM46);
    connect(ui->cbPSM47, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM47);
    connect(ui->cbPSM48, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPSM48);


    //PPS
    connect(ui->cbPPSModeStatus, &QComboBox::currentTextChanged, &p_.simulator, &UnitSimulator::cbPPSModeStatus);
    connect(ui->cbPPShealth, &QComboBox::currentTextChanged, &p_.simulator, &UnitSimulator::cbPPShealth);
    connect(ui->cbPPSwow, &QComboBox::currentTextChanged, &p_.simulator, &UnitSimulator::cbPPSwow);
    connect(ui->cbPPShazard, &QComboBox::currentTextChanged, &p_.simulator, &UnitSimulator::cbPPShazard);
    connect(ui->cbPPSlimit, &QComboBox::currentTextChanged, &p_.simulator, &UnitSimulator::cbPPSlimit);

    connect(ui->cbPPS11, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS11);
    connect(ui->cbPPS12, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS12);
    connect(ui->cbPPS13, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS13);
    connect(ui->cbPPS14, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS14);
    connect(ui->cbPPS16, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS16);
    connect(ui->cbPPS17, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS17);
    connect(ui->cbPPS18, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS18);

    connect(ui->cbPPS21, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS21);
    connect(ui->cbPPS22, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS22);
    connect(ui->cbPPS23, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS23);
    connect(ui->cbPPS25, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS25);
    connect(ui->cbPPS26, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS26);
    connect(ui->cbPPS27, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS27);
    connect(ui->cbPPS28, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS28);

    connect(ui->cbPPS31, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS31);
    connect(ui->cbPPS32, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS32);
    connect(ui->cbPPS33, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS33);
    connect(ui->cbPPS34, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS34);
    connect(ui->cbPPS35, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS35);
    connect(ui->cbPPS36, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS36);
    connect(ui->cbPPS37, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS37);
    connect(ui->cbPPS38, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS38);

    connect(ui->cbPPS41, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS41);
    connect(ui->cbPPS42, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS42);
    connect(ui->cbPPS43, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS43);
    connect(ui->cbPPS44, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS44);
    connect(ui->cbPPS45, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS45);
    connect(ui->cbPPS46, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS46);
    connect(ui->cbPPS47, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS47);
    connect(ui->cbPPS48, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS48);

    connect(ui->cbPPS51, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS51);
    connect(ui->cbPPS52, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS52);
    connect(ui->cbPPS53, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS53);
    connect(ui->cbPPS54, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS54);
    connect(ui->cbPPS55, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS55);
    connect(ui->cbPPS56, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS56);
    connect(ui->cbPPS57, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS57);
    connect(ui->cbPPS58, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS58);

    connect(ui->cbPPS61, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS61);
    connect(ui->cbPPS62, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS62);
    connect(ui->cbPPS63, &QCheckBox::stateChanged, &p_.simulator, &UnitSimulator::cbPPS63);

    connect(ui->sbPPSRXver, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSRXver);
    connect(ui->sbPPSRXrel, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSRXrel);
    connect(ui->sbPPSTX1ver, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSTX1ver);
    connect(ui->sbPPSTX1rel, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSTX1rel);
    connect(ui->sbPPSTX2ver, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSTX2ver);
    connect(ui->sbPPSTX2rel, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSTX2rel);
    connect(ui->sbPPSTX3ver, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSTX3ver);
    connect(ui->sbPPSTX3rel, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSTX3rel);
    connect(ui->sbPPSRXtemp, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSRXtemp);
    connect(ui->sbPPSTX1temp, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSTX1temp);
    connect(ui->sbPPSTX2temp, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSTX2temp);
    connect(ui->sbPPSTX3temp, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSTX3temp);
    connect(ui->sbPPSInletTemp, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSInletTemp);
    connect(ui->sbPPSOutletTemp, static_cast<void (QSpinBox::*)(int t)>(&QSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSOutletTemp);

    connect(ui->sbPPSRXcurrent, static_cast<void (QDoubleSpinBox::*)(double t)>(&QDoubleSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSCurr);
    connect(ui->sbPPSTX1current, static_cast<void (QDoubleSpinBox::*)(double t)>(&QDoubleSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSTX1current);
    connect(ui->sbPPSTX2current, static_cast<void (QDoubleSpinBox::*)(double t)>(&QDoubleSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSTX2current);
    connect(ui->sbPPSTX3current, static_cast<void (QDoubleSpinBox::*)(double t)>(&QDoubleSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSTX3current);

    connect(ui->sbPPSTX1currentMAX_2, static_cast<void (QDoubleSpinBox::*)(double t)>(&QDoubleSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSTX1currentMAX_2);
    connect(ui->sbPPSTX2currentMAX_2, static_cast<void (QDoubleSpinBox::*)(double t)>(&QDoubleSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSTX2currentMAX_2);
    connect(ui->sbPPSTX3currentMAX_2, static_cast<void (QDoubleSpinBox::*)(double t)>(&QDoubleSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSTX3currentMAX_2);

    connect(ui->sbPPSTX1currentAVG_2, static_cast<void (QDoubleSpinBox::*)(double t)>(&QDoubleSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSTX1currentAVG_2);
    connect(ui->sbPPSTX2currentAVG_2, static_cast<void (QDoubleSpinBox::*)(double t)>(&QDoubleSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSTX2currentAVG_2);
    connect(ui->sbPPSTX3currentAVG_2, static_cast<void (QDoubleSpinBox::*)(double t)>(&QDoubleSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSTX3currentAVG_2);

    connect(ui->sbPPSRXPhaseRmin_2, static_cast<void (QDoubleSpinBox::*)(double t)>(&QDoubleSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSRXPhaseRmin_2);
    connect(ui->sbPPSRXPhaseSmin_2, static_cast<void (QDoubleSpinBox::*)(double t)>(&QDoubleSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSRXPhaseSmin_2);
    connect(ui->sbPPSRXPhaseTmin_2, static_cast<void (QDoubleSpinBox::*)(double t)>(&QDoubleSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSRXPhaseTmin_2);

    connect(ui->sbPPSRXPhaseRmax_2, static_cast<void (QDoubleSpinBox::*)(double t)>(&QDoubleSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSRXPhaseRmax_2);
    connect(ui->sbPPSRXPhaseSmax_2, static_cast<void (QDoubleSpinBox::*)(double t)>(&QDoubleSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSRXPhaseSmax_2);
    connect(ui->sbPPSRXPhaseTmax_2, static_cast<void (QDoubleSpinBox::*)(double t)>(&QDoubleSpinBox::valueChanged), &p_.simulator, &UnitSimulator::sbPPSRXPhaseTmax_2);


    ui->actionLCU_Show->setChecked(true);
    ui->actionPPS_Show->setChecked(true);
    ui->actionPSM_Show->setChecked(true);

    /*connect(&p_.simulator, &UnitSimulator::psmCommand, this, [this](const QString& cmd)
    {
        int n=ui->psmCmd->findText(cmd);
        if (n<0)
            ui->psmCmd->addItem(cmd);
        else
            ui->psmCmd->setCurrentIndex(n);
    });*/
}

GrifoXLruMainWindow::~GrifoXLruMainWindow()
{
    delete ui;
}

void GrifoXLruMainWindow::on_tbDisable_clicked()
{
    //p_.bridge->forwardDisbaled=ui->tbDisable->isChecked();
}

void GrifoXLruMainWindow::on_actionDisable_triggered()
{
    p_.bridge->forwardDisabled=ui->actionDisable->isChecked();
}

void GrifoXLruMainWindow::on_actionLogClear_triggered()
{    
    //ui->log->clear();
    txtLogger->clear();

    p_.logDock->setVisible(true);
}

void GrifoXLruMainWindow::on_portCmd_returnPressed()
{

}

void GrifoXLruMainWindow::on_psm_toggled(bool arg1)
{
    if (arg1)
        ui->psm->setTitle("PSM (1) mon/sim: SIMULATOR");
    else
        ui->psm->setTitle("PSM (1) mon/sim: MONITOR");

}

void GrifoXLruMainWindow::on_pps_toggled(bool arg1)
{
    if (arg1)
        ui->pps->setTitle("PPS (2) mon/sim: SIMULATOR");
    else
        ui->pps->setTitle("PPS (2) mon/sim: MONITOR");
}

void GrifoXLruMainWindow::on_lcu_toggled(bool arg1)
{
    if (arg1)
        ui->lcu->setTitle("LCU (3) mon/sim: SIMULATOR");
    else
        ui->lcu->setTitle("LCU (3) mon/sim: MONITOR");
}

void GrifoXLruMainWindow::visualMess(QByteArray atext)
{
    ui->portCmd->insert(atext);
}

void set_last_error(char* msg, char device)
{
    switch (device)
    {
        case DSTID_LCU:
            xlru_lcu::xlru_set_last_error(msg);
            break;
        case DSTID_PPS:
            xlru_pps::xlru_set_last_error(msg);
            break;
        case DSTID_PSM:
            xlru_psm::xlru_set_last_error(msg);
            break;
        default:	//ALL
            xlru_psm::xlru_set_last_error(msg);
            xlru_pps::xlru_set_last_error(msg);
            xlru_lcu::xlru_set_last_error(msg);
            break;
        }
}

void GrifoXLruMainWindow::fromMessLCU(QByteArray data)
{
    int res = DECODE_NO_ERROR;

    res = xlru_lcu::xlru_lcu_command_message_decoder(data.data());

    if (res==DECODE_TOO_SHORT)
    {
        //message is too short
        xlru_lcu::xlru_add_rx_error(1);
        xlru_lcu::xlru_add_rx(1);
        set_last_error((char*)STR_TOO_SHOORT, DSTID_LCU);
    }
    else
    if (res!=0)
    {
        xlru_lcu::xlru_add_rx_error(1);
        xlru_lcu::xlru_add_rx(1);
        set_last_error((char*)STR_ERROR_DECODING,DSTID_LCU);
    }
    else
    {
        xlru_lcu::xlru_add_rx(1);
    }

    ui->sbLCUVersion->setValue(xlru_lcu::xlru_lcu_status.crtl_board_version);
    ui->sbLCURelease->setValue(xlru_lcu::xlru_lcu_status.crtl_board_release);
    ui->sbBoardTemp->setValue(xlru_lcu::xlru_lcu_status.ctrl_board_temp);
    ui->sbMFS->setValue(xlru_lcu::xlru_lcu_status.motor_speed_mfs);
    ui->sbMTS->setValue(xlru_lcu::xlru_lcu_status.motor_temp_mts);
    ui->sbTS1->setValue(xlru_lcu::xlru_lcu_status.liquid_inlet_temp_aesa_ts1);
    ui->sbTS2->setValue(xlru_lcu::xlru_lcu_status.liquid_inlet_temp_pps_ts2);
    ui->sbTS3->setValue(xlru_lcu::xlru_lcu_status.liquid_pump_inlet_temp_ts3);
    ui->sbTS4->setValue(xlru_lcu::xlru_lcu_status.liquid_outlet_temp_ts4);
    ui->sbTS5->setValue(xlru_lcu::xlru_lcu_status.air_inlet_temp_ts5);
    ui->sbTS6->setValue(xlru_lcu::xlru_lcu_status.air_outlet_temp_ts6);
    ui->sbPS->setValue(xlru_lcu::xlru_lcu_status.liquid_outlet_pressure_ps);
    ui->sbFS1->setValue(xlru_lcu::xlru_lcu_status.liquid_inlet_flow_aesa_fs1);
    ui->sbFS2->setValue(xlru_lcu::xlru_lcu_status.liquid_inlet_flow_pps_fs2);

    ui->cbLCU11->setChecked(xlru_lcu::xlru_lcu_status.byte1_general_pressure.b1_phase_A_fail);
    ui->cbLCU12->setChecked(xlru_lcu::xlru_lcu_status.byte1_general_pressure.b2_phase_B_fail);
    ui->cbLCU13->setChecked(xlru_lcu::xlru_lcu_status.byte1_general_pressure.b3_phase_C_fail);
    ui->cbLCU14->setChecked(xlru_lcu::xlru_lcu_status.byte1_general_pressure.b4_phase_sequence_fail);
    ui->cbLCU17->setChecked(xlru_lcu::xlru_lcu_status.byte1_general_pressure.b7_pressure_sensor_fail);

    ui->cbLCU21->setChecked(xlru_lcu::xlru_lcu_status.byte2_ctrl_board.b1_temperature_hazard);
    ui->cbLCU22->setChecked(xlru_lcu::xlru_lcu_status.byte2_ctrl_board.b2_temperature_warning);
    ui->cbLCU23->setChecked(xlru_lcu::xlru_lcu_status.byte2_ctrl_board.b3_nvm_access_warning);
    ui->cbLCU24->setChecked(xlru_lcu::xlru_lcu_status.byte2_ctrl_board.b4_board_error_fail);
    ui->cbLCU25->setChecked(xlru_lcu::xlru_lcu_status.byte2_ctrl_board.b5_link_fail);

    ui->cbLCU31->setChecked(xlru_lcu::xlru_lcu_status.byte3_motor_pump.b1_motor_speed_sensor_fail);
    ui->cbLCU32->setChecked(xlru_lcu::xlru_lcu_status.byte3_motor_pump.b2_temperature_hazard);
    ui->cbLCU33->setChecked(xlru_lcu::xlru_lcu_status.byte3_motor_pump.b3_temperature_warning);
    ui->cbLCU34->setChecked(xlru_lcu::xlru_lcu_status.byte3_motor_pump.b4_motor_fail);
    ui->cbLCU38->setChecked(xlru_lcu::xlru_lcu_status.byte3_motor_pump.b8_motor_temperature_sensor_fail);

    ui->cbLCU41->setChecked(xlru_lcu::xlru_lcu_status.byte4_sensor.b1_inlet_temp_sensor_fail_aesa_ts1);
    ui->cbLCU42->setChecked(xlru_lcu::xlru_lcu_status.byte4_sensor.b2_inlet_temp_sensor_fail_pps_ts2);
    ui->cbLCU43->setChecked(xlru_lcu::xlru_lcu_status.byte4_sensor.b3_inlet_temp_sensor_fail_combo_ts3);
    ui->cbLCU44->setChecked(xlru_lcu::xlru_lcu_status.byte4_sensor.b4_outlet_temp_sensor_fail_ts4);
    ui->cbLCU45->setChecked(xlru_lcu::xlru_lcu_status.byte4_sensor.b5_inlet_air_temp_sensor_fail_ts5);
    ui->cbLCU46->setChecked(xlru_lcu::xlru_lcu_status.byte4_sensor.b6_outlet_air_temp_sensor_fail_ts6);
    ui->cbLCU47->setChecked(xlru_lcu::xlru_lcu_status.byte4_sensor.b7_inlet_flow_sensor_aesa_branch_fs1);
    ui->cbLCU48->setChecked(xlru_lcu::xlru_lcu_status.byte4_sensor.b8_inlet_flow_sensor_pps_branch_fs2);

    ui->cbLCU51->setChecked(xlru_lcu::xlru_lcu_status.byte5_general_fails.b1_dirty_filter_he_warn);
    ui->cbLCU52->setChecked(xlru_lcu::xlru_lcu_status.byte5_general_fails.b2_dirty_aesa_stream_warn1);
    ui->cbLCU53->setChecked(xlru_lcu::xlru_lcu_status.byte5_general_fails.b3_dirty_aesa_stream_warn2);
    ui->cbLCU55->setChecked(xlru_lcu::xlru_lcu_status.byte5_general_fails.b5_dirty_filter_he_failure);
    ui->cbLCU56->setChecked(xlru_lcu::xlru_lcu_status.byte5_general_fails.b6_dirty_aesa_stream_fail1);
    ui->cbLCU57->setChecked(xlru_lcu::xlru_lcu_status.byte5_general_fails.b7_dirty_aesa_stream_fail2);
    ui->cbLCU58->setChecked(xlru_lcu::xlru_lcu_status.byte5_general_fails.b8_by_pass_fail);


    ui->cdLCUModeStatus->setCurrentText((QString)xlru_lcu::xlru_lcu_status.mode_status);
    ui->cdLCUProgress->setCurrentText((QString)xlru_lcu::xlru_lcu_status.bit_progress);
    ui->cdLCUHealth->setCurrentText((QString)xlru_lcu::xlru_lcu_status.health_status);
    ui->cdLCUByPass->setCurrentText((QString)xlru_lcu::xlru_lcu_status.byPass_status);
    ui->cdLCUHazard->setCurrentText((QString)xlru_lcu::xlru_lcu_status.hazard_status);
    ui->cdLCUOverride->setCurrentText((QString)xlru_lcu::xlru_lcu_status.override_status);

    p_.chartform->addSampleAllGraph("lcu_ctrl_board_temp", xlru_lcu::xlru_lcu_status.ctrl_board_temp);
    p_.chartform->addSampleAllGraph("lcu_motor_speed_mfs", xlru_lcu::xlru_lcu_status.motor_speed_mfs);
    p_.chartform->addSampleAllGraph("lcu_motor_temp_mtsp", xlru_lcu::xlru_lcu_status.motor_temp_mts);
    p_.chartform->addSampleAllGraph("lcu_liquid_inlet_temp_aesa_ts1", xlru_lcu::xlru_lcu_status.liquid_inlet_temp_aesa_ts1);
    p_.chartform->addSampleAllGraph("lcu_liquid_inlet_temp_pps_ts2", xlru_lcu::xlru_lcu_status.liquid_inlet_temp_pps_ts2);
    p_.chartform->addSampleAllGraph("lcu_liquid_pump_inlet_temp_ts3", xlru_lcu::xlru_lcu_status.liquid_pump_inlet_temp_ts3);
    p_.chartform->addSampleAllGraph("lcu_liquid_outlet_temp_ts4", xlru_lcu::xlru_lcu_status.liquid_outlet_temp_ts4);
    p_.chartform->addSampleAllGraph("lcu_air_inlet_temp_ts5", xlru_lcu::xlru_lcu_status.air_inlet_temp_ts5);
    p_.chartform->addSampleAllGraph("lcu_air_outlet_temp_ts6", xlru_lcu::xlru_lcu_status.air_outlet_temp_ts6);
    p_.chartform->addSampleAllGraph("lcu_liquid_outlet_pressure_ps", xlru_lcu::xlru_lcu_status.liquid_outlet_pressure_ps);
    p_.chartform->addSampleAllGraph("lcu_liquid_inlet_flow_aesa_fs1", xlru_lcu::xlru_lcu_status.liquid_inlet_flow_aesa_fs1);
    p_.chartform->addSampleAllGraph("lcu_liquid_inlet_flow_pps_fs2", xlru_lcu::xlru_lcu_status.liquid_inlet_flow_pps_fs2);

}

void GrifoXLruMainWindow::fromMessPPS(QByteArray data)
{
    int res = DECODE_NO_ERROR;

    res = xlru_pps::xlru_pps_command_message_decoder(data.data());

    if (res==DECODE_TOO_SHORT)
    {
        //message is too short
        xlru_pps::xlru_add_rx_error(1);
        xlru_pps::xlru_add_rx(1);
        set_last_error((char*)STR_TOO_SHOORT, DSTID_PPS);
    }
    else
    if (res!=0)
    {
        xlru_pps::xlru_add_rx_error(1);
        xlru_pps::xlru_add_rx(1);
        set_last_error((char*)STR_ERROR_DECODING,DSTID_PPS);
    }
    else
    {
        xlru_pps::xlru_add_rx(1);
    }

    ui->cbPPSModeStatus->setCurrentText((QString)xlru_pps::xlru_pps_status.mode_status);
    ui->cbPPShealth->setCurrentText((QString)xlru_pps::xlru_pps_status.health_status);
    ui->cbPPSwow->setCurrentText((QString)xlru_pps::xlru_pps_status.wow);
    ui->cbPPShazard->setCurrentText((QString)xlru_pps::xlru_pps_status.hazard_status);
    ui->cbPPSlimit->setCurrentText((QString)xlru_pps::xlru_pps_status.current_limitation_status);

    ui->sbPPSRXver->setValue(xlru_pps::xlru_pps_status.rx_board_version);
    ui->sbPPSRXrel->setValue(xlru_pps::xlru_pps_status.rx_board_release);
    ui->sbPPSTX1ver->setValue(xlru_pps::xlru_pps_status.tx1_board_version);
    ui->sbPPSTX1rel->setValue(xlru_pps::xlru_pps_status.tx1_board_release);
    ui->sbPPSTX2ver->setValue(xlru_pps::xlru_pps_status.tx2_board_version);
    ui->sbPPSTX2rel->setValue(xlru_pps::xlru_pps_status.tx2_board_release);
    ui->sbPPSTX3ver->setValue(xlru_pps::xlru_pps_status.tx3_board_version);
    ui->sbPPSTX3rel->setValue(xlru_pps::xlru_pps_status.tx3_board_release);
    ui->sbPPSRXtemp->setValue(xlru_pps::xlru_pps_status.rx_board_temp);
    ui->sbPPSTX1temp->setValue(xlru_pps::xlru_pps_status.tx1_board_temp);
    ui->sbPPSTX2temp->setValue(xlru_pps::xlru_pps_status.tx2_board_temp);
    ui->sbPPSTX3temp->setValue(xlru_pps::xlru_pps_status.tx3_board_temp);
    ui->sbPPSInletTemp->setValue(xlru_pps::xlru_pps_status.liquid_inlet_temp);
    ui->sbPPSOutletTemp->setValue(xlru_pps::xlru_pps_status.liquid_outlet_temp);

    ui->sbPPSRXcurrent->setValue(xlru_pps::xlru_pps_status.curr_42v);
    ui->sbPPSTX1current->setValue(xlru_pps::xlru_pps_status.tx_curr[0]);
    ui->sbPPSTX2current->setValue(xlru_pps::xlru_pps_status.tx_curr[1]);
    ui->sbPPSTX3current->setValue(xlru_pps::xlru_pps_status.tx_curr[2]);

    ui->sbPPSTX1currentMAX_2->setValue(xlru_pps::xlru_pps_status.tx_curr_max[0]);
    ui->sbPPSTX2currentMAX_2->setValue(xlru_pps::xlru_pps_status.tx_curr_max[1]);
    ui->sbPPSTX3currentMAX_2->setValue(xlru_pps::xlru_pps_status.tx_curr_max[2]);

    ui->sbPPSTX1currentAVG_2->setValue(xlru_pps::xlru_pps_status.tx_curr_avg[0]);
    ui->sbPPSTX2currentAVG_2->setValue(xlru_pps::xlru_pps_status.tx_curr_avg[1]);
    ui->sbPPSTX3currentAVG_2->setValue(xlru_pps::xlru_pps_status.tx_curr_avg[2]);

    ui->sbPPSRXPhaseRmin_2->setValue(xlru_pps::xlru_pps_status.rx_phase_min[0]);
    ui->sbPPSRXPhaseSmin_2->setValue(xlru_pps::xlru_pps_status.rx_phase_min[1]);
    ui->sbPPSRXPhaseTmin_2->setValue(xlru_pps::xlru_pps_status.rx_phase_min[2]);

    ui->sbPPSRXPhaseRmax_2->setValue(xlru_pps::xlru_pps_status.rx_phase_max[0]);
    ui->sbPPSRXPhaseSmax_2->setValue(xlru_pps::xlru_pps_status.rx_phase_max[1]);
    ui->sbPPSRXPhaseTmax_2->setValue(xlru_pps::xlru_pps_status.rx_phase_max[2]);


    ui->cbPPS11->setChecked(xlru_pps::xlru_pps_status.byte1_holdUp_boards.b1_LP_under_voltage_fail);
    ui->cbPPS12->setChecked(xlru_pps::xlru_pps_status.byte1_holdUp_boards.b2_HP_under_voltage_fail);
    //ui->cbPPS13->setChecked(xlru_pps::xlru_pps_status.byte1_holdUp_boards.b3_LP_under_voltage_fail);
    //ui->cbPPS14->setChecked(xlru_pps::xlru_pps_status.byte1_holdUp_boards.b4_LP_charging_time_fail);
    ui->cbPPS16->setChecked(xlru_pps::xlru_pps_status.byte1_holdUp_boards.b6_AC_power_umbalance_fail_ph1);
    ui->cbPPS17->setChecked(xlru_pps::xlru_pps_status.byte1_holdUp_boards.b7_AC_power_umbalance_fail_ph2);
    ui->cbPPS18->setChecked(xlru_pps::xlru_pps_status.byte1_holdUp_boards.b8_AC_power_umbalance_fail_ph3);

    ui->cbPPS21->setChecked(xlru_pps::xlru_pps_status.byte2_rx_board.b1_rx_link_fail);
    ui->cbPPS22->setChecked(xlru_pps::xlru_pps_status.byte2_rx_board.b2_rx_input_dc_overcurrent_fail);
    ui->cbPPS23->setChecked(xlru_pps::xlru_pps_status.byte2_rx_board.b3_rx_rectified_dc_under_voltage_fail_ac_power_loss);
    ui->cbPPS25->setChecked(xlru_pps::xlru_pps_status.byte2_rx_board.b5_output_rx_over_voltage_fail);
    ui->cbPPS26->setChecked(xlru_pps::xlru_pps_status.byte2_rx_board.b6_output_rx_under_voltage_fail);
    ui->cbPPS27->setChecked(xlru_pps::xlru_pps_status.byte2_rx_board.b7_rx_hazard);
    ui->cbPPS28->setChecked(xlru_pps::xlru_pps_status.byte2_rx_board.b8_rx_hazard);

    ui->cbPPS31->setChecked(xlru_pps::xlru_pps_status.byte3_tx1_board.b1_tx1_link_with_rx);
    ui->cbPPS32->setChecked(xlru_pps::xlru_pps_status.byte3_tx1_board.b2_tx1_input_dc_over_current_fail);
    ui->cbPPS33->setChecked(xlru_pps::xlru_pps_status.byte3_tx1_board.b3_tx1_rectified_dc_under_voltage_fail_270_uv);
    //ui->cbPPS34->setChecked(xlru_pps::xlru_pps_status.byte3_tx1_board.b4_tx1_rectified_dc_over_voltage_fail);
    ui->cbPPS35->setChecked(xlru_pps::xlru_pps_status.byte3_tx1_board.b5_output_tx1_over_voltage_fail);
    ui->cbPPS36->setChecked(xlru_pps::xlru_pps_status.byte3_tx1_board.b6_output_tx1_under_voltage_fail);
    ui->cbPPS37->setChecked(xlru_pps::xlru_pps_status.byte3_tx1_board.b7_tx1_hazard);
    ui->cbPPS38->setChecked(xlru_pps::xlru_pps_status.byte3_tx1_board.b8_tx1_hazard);

    ui->cbPPS41->setChecked(xlru_pps::xlru_pps_status.byte4_tx2_board.b1_tx2_link_with_rx);
    ui->cbPPS42->setChecked(xlru_pps::xlru_pps_status.byte4_tx2_board.b2_tx2_input_dc_over_current_fail);
    ui->cbPPS43->setChecked(xlru_pps::xlru_pps_status.byte4_tx2_board.b3_tx2_rectified_dc_under_voltage_fail_270_uv);
    //ui->cbPPS44->setChecked(xlru_pps::xlru_pps_status.byte4_tx2_board.b4_tx2_rectified_dc_over_voltage_fail);
    ui->cbPPS45->setChecked(xlru_pps::xlru_pps_status.byte4_tx2_board.b5_output_tx2_over_voltage_fail);
    ui->cbPPS46->setChecked(xlru_pps::xlru_pps_status.byte4_tx2_board.b6_output_tx2_under_voltage_fail);
    ui->cbPPS47->setChecked(xlru_pps::xlru_pps_status.byte4_tx2_board.b7_tx2_hazard);
    ui->cbPPS48->setChecked(xlru_pps::xlru_pps_status.byte4_tx2_board.b8_tx2_hazard);

    ui->cbPPS51->setChecked(xlru_pps::xlru_pps_status.byte5_tx3_board.b1_tx3_link_with_rx);
    ui->cbPPS52->setChecked(xlru_pps::xlru_pps_status.byte5_tx3_board.b2_tx3_input_dc_over_current_fail);
    ui->cbPPS53->setChecked(xlru_pps::xlru_pps_status.byte5_tx3_board.b3_tx3_rectified_dc_under_voltage_fail_270_uv);
    //ui->cbPPS54->setChecked(xlru_pps::xlru_pps_status.byte5_tx3_board.b4_tx3_rectified_dc_over_voltage_fail);
    ui->cbPPS55->setChecked(xlru_pps::xlru_pps_status.byte5_tx3_board.b5_output_tx3_over_voltage_fail);
    ui->cbPPS56->setChecked(xlru_pps::xlru_pps_status.byte5_tx3_board.b6_output_tx3_under_voltage_fail);
    ui->cbPPS57->setChecked(xlru_pps::xlru_pps_status.byte5_tx3_board.b7_tx3_hazard);
    ui->cbPPS58->setChecked(xlru_pps::xlru_pps_status.byte5_tx3_board.b8_tx3_hazard);

    ui->cbPPS61->setChecked(xlru_pps::xlru_pps_status.byte6_general.b1_wow_tellback_1);
    ui->cbPPS62->setChecked(xlru_pps::xlru_pps_status.byte6_general.b2_wow_tellback_2);
    ui->cbPPS63->setChecked(xlru_pps::xlru_pps_status.byte6_general.b3_wow_tellback_3);

    p_.chartform->addSampleAllGraph("pps_rx_board_temp", xlru_pps::xlru_pps_status.rx_board_temp);

    p_.chartform->addSampleAllGraph("pps_tx1_board_temp", xlru_pps::xlru_pps_status.tx1_board_temp);
    p_.chartform->addSampleAllGraph("pps_tx2_board_temp", xlru_pps::xlru_pps_status.tx2_board_temp);
    p_.chartform->addSampleAllGraph("pps_tx3_board_temp", xlru_pps::xlru_pps_status.tx3_board_temp);
    p_.chartform->addSampleAllGraph("pps_liquid_inlet_temp", xlru_pps::xlru_pps_status.liquid_inlet_temp);
    p_.chartform->addSampleAllGraph("pps_liquid_outlet_temp", xlru_pps::xlru_pps_status.liquid_outlet_temp);

    p_.chartform->addSampleAllGraph("pps_curr_42v", xlru_pps::xlru_pps_status.curr_42v);
    p_.chartform->addSampleAllGraph("pps_tx1_curr", xlru_pps::xlru_pps_status.tx_curr[0]);
    p_.chartform->addSampleAllGraph("pps_tx2_curr", xlru_pps::xlru_pps_status.tx_curr[1]);
    p_.chartform->addSampleAllGraph("pps_tx3_curr", xlru_pps::xlru_pps_status.tx_curr[2]);

    p_.chartform->addSampleAllGraph("pps_tx1_curr_max", xlru_pps::xlru_pps_status.tx_curr_max[0]);
    p_.chartform->addSampleAllGraph("pps_tx2_curr_max", xlru_pps::xlru_pps_status.tx_curr_max[1]);
    p_.chartform->addSampleAllGraph("pps_tx3_curr_max", xlru_pps::xlru_pps_status.tx_curr_max[2]);

    p_.chartform->addSampleAllGraph("pps_tx1_curr_avg", xlru_pps::xlru_pps_status.tx_curr_avg[0]);
    p_.chartform->addSampleAllGraph("pps_tx2_curr_avg", xlru_pps::xlru_pps_status.tx_curr_avg[1]);
    p_.chartform->addSampleAllGraph("pps_tx3_curr_avg", xlru_pps::xlru_pps_status.tx_curr_avg[2]);

    p_.chartform->addSampleAllGraph("pps_rx_phaser_min", xlru_pps::xlru_pps_status.rx_phase_min[0]);
    p_.chartform->addSampleAllGraph("pps_rx_phases_min", xlru_pps::xlru_pps_status.rx_phase_min[1]);
    p_.chartform->addSampleAllGraph("pps_rx_phaset_min", xlru_pps::xlru_pps_status.rx_phase_min[2]);

    p_.chartform->addSampleAllGraph("pps_rx_phaser_max", xlru_pps::xlru_pps_status.rx_phase_max[0]);
    p_.chartform->addSampleAllGraph("pps_rx_phases_max", xlru_pps::xlru_pps_status.rx_phase_max[1]);
    p_.chartform->addSampleAllGraph("pps_rx_phaset_max", xlru_pps::xlru_pps_status.rx_phase_max[2]);


}

void GrifoXLruMainWindow::fromMessPSM(QByteArray data)
{
    int res = DECODE_NO_ERROR;

    res = xlru_psm::xlru_psm_command_message_decoder(data.data());

    if (res==DECODE_TOO_SHORT)
    {
        //message is too short
        xlru_psm::xlru_add_rx_error(1);
        xlru_psm::xlru_add_rx(1);
        set_last_error((char*)STR_TOO_SHOORT, DSTID_PSM);
    }
    else
    if (res!=0)
    {
        xlru_psm::xlru_add_rx_error(1);
        xlru_psm::xlru_add_rx(1);
        set_last_error((char*)STR_ERROR_DECODING,DSTID_PSM);
    }
    else
    {
        xlru_psm::xlru_add_rx(1);
    }

    ui->cdPSMModeStatus->setCurrentText((QString)xlru_psm::xlru_psm_status.mode_status);
    ui->cbPSMHazard->setCurrentText((QString)xlru_psm::xlru_psm_status.hazard_status);
    ui->cbPSM3Sec->setCurrentText((QString)xlru_psm::xlru_psm_status._3sec_status);
    ui->cbPSMWow->setCurrentText((QString)xlru_psm::xlru_psm_status.wow_status);
    ui->cbPSMAc->setCurrentText((QString)xlru_psm::xlru_psm_status.ac_status);
    ui->cbPSMbs->setCurrentText((QString)xlru_psm::xlru_psm_status.bs_status);
    ui->cbPSMdc->setCurrentText((QString)xlru_psm::xlru_psm_status.dc_status);
    ui->cbPSMpfc->setCurrentText((QString)xlru_psm::xlru_psm_status.pfc_status);

    ui->sbPSMOutVolt3v3->setValue(xlru_psm::xlru_psm_status.out_volt_VOLT3V3);
    ui->sbPSMOutVolt15v->setValue(xlru_psm::xlru_psm_status.out_volt_VOLT15V);
    ui->sbPSMOutVolt5v->setValue(xlru_psm::xlru_psm_status.out_volt_VOLT5V);
    ui->sbPSMOutVoltm15v->setValue(xlru_psm::xlru_psm_status.out_volt_VOLTNEG15V);
    ui->cbPSMvolt3v3->setCurrentText((QString)xlru_psm::xlru_psm_status.out_rail_VOLT3V3_status);
    ui->cbPSMvolt15->setCurrentText((QString)xlru_psm::xlru_psm_status.out_rail_VOLT15V_status);
    ui->cbPSMvolt5->setCurrentText((QString)xlru_psm::xlru_psm_status.out_rail_VOLT5V_status);
    ui->cbPSMvoltneg15->setCurrentText((QString)xlru_psm::xlru_psm_status.out_rail_VOLTNEG15V_status);
    ui->cbPSMLastRecycle->setCurrentText((QString)xlru_psm::xlru_psm_status.last_recycle);
    ui->editLastRecycleReasonFromEif->setText((QString)xlru_psm::xlru_psm_status.last_recycle_reason);

    ui->sbPSMVer->setValue(xlru_psm::xlru_psm_status.sw_major);
    ui->sbPSMRel->setValue(xlru_psm::xlru_psm_status.sw_minor);
    ui->sbPSMInAmp->setValue(xlru_psm::xlru_psm_status.in_amp);
    ui->sbPSMTemp->setValue(xlru_psm::xlru_psm_status.temperature);
    ui->sbPSMETI->setValue(xlru_psm::xlru_psm_status.eti);
    ui->sbPSMOnCount->setValue(xlru_psm::xlru_psm_status.on_counter);
    ui->sbPSMUncCount->setValue(xlru_psm::xlru_psm_status.unc_counter);


    ui->cbPSM11->setChecked(xlru_psm::xlru_psm_status.byte1.b0_PSM_recycle_panic);//b0_spare);
    ui->cbPSM12->setChecked(xlru_psm::xlru_psm_status.byte1.b1_PSM_EIF_comm);
    ui->cbPSM13->setChecked(xlru_psm::xlru_psm_status.byte1.b2_rs422_comm);
    ui->cbPSM14->setChecked(xlru_psm::xlru_psm_status.byte1.b3_rs485_comm);
    ui->cbPSM15->setChecked(xlru_psm::xlru_psm_status.byte1.b4_rs232_comm);
    ui->cbPSM16->setChecked(xlru_psm::xlru_psm_status.byte1.b5_ov_temp_haz_2);
    ui->cbPSM17->setChecked(xlru_psm::xlru_psm_status.byte1.b6_ov_board_temp);
    ui->cbPSM18->setChecked(xlru_psm::xlru_psm_status.byte1.b7_ov_dc_bus_current);

    ui->cbPSM21->setChecked(xlru_psm::xlru_psm_status.byte2.b0_ov_m15v);
    ui->cbPSM22->setChecked(xlru_psm::xlru_psm_status.byte2.b1_uv_m15v);
    ui->cbPSM23->setChecked(xlru_psm::xlru_psm_status.byte2.b2_ov_15v);
    ui->cbPSM24->setChecked(xlru_psm::xlru_psm_status.byte2.b3_uv_15v);
    ui->cbPSM25->setChecked(xlru_psm::xlru_psm_status.byte2.b4_ov_5v);
    ui->cbPSM26->setChecked(xlru_psm::xlru_psm_status.byte2.b5_uv_5v);
    ui->cbPSM27->setChecked(xlru_psm::xlru_psm_status.byte2.b6_ov_3v3);
    ui->cbPSM28->setChecked(xlru_psm::xlru_psm_status.byte2.b7_uv_3v3);

    ui->cbPSM31->setChecked(xlru_psm::xlru_psm_status.byte3.b0_ov_13v_b);
    ui->cbPSM32->setChecked(xlru_psm::xlru_psm_status.byte3.b1_uv_13v_b);
    ui->cbPSM33->setChecked(xlru_psm::xlru_psm_status.byte3.b2_wow_out);
    ui->cbPSM34->setChecked(xlru_psm::xlru_psm_status.byte3.b3_3sec_in);
    ui->cbPSM35->setChecked(xlru_psm::xlru_psm_status.byte3.b4_uv_350v);
    ui->cbPSM36->setChecked(xlru_psm::xlru_psm_status.byte3.b5_ov_350v);
    ui->cbPSM37->setChecked(xlru_psm::xlru_psm_status.byte3.b6_blko_tst);
    ui->cbPSM38->setChecked(xlru_psm::xlru_psm_status.byte3.b7_pwr_err);

    ui->cbPSM41->setChecked(xlru_psm::xlru_psm_status.byte4.b0_rdr_on_sts);
    ui->cbPSM42->setChecked(xlru_psm::xlru_psm_status.byte4.b1_lcu_rdy_uc);
    ui->cbPSM43->setChecked(xlru_psm::xlru_psm_status.byte4.b2_uc_interlock_o);
    ui->cbPSM44->setChecked(xlru_psm::xlru_psm_status.byte4.b3_ac_loss);
    ui->cbPSM45->setChecked(xlru_psm::xlru_psm_status.byte4.b4_ps_interlock_n);
    ui->cbPSM46->setChecked(xlru_psm::xlru_psm_status.byte4.b5_ov_temp_haz);
    ui->cbPSM47->setChecked(xlru_psm::xlru_psm_status.byte4.b6_uv_270v);
    ui->cbPSM48->setChecked(xlru_psm::xlru_psm_status.byte4.b7_battle_short_cmd);

    p_.chartform->addSampleAllGraph("psm_temp", xlru_psm::xlru_psm_status.temperature);
    p_.chartform->addSampleAllGraph("psm_current", xlru_psm::xlru_psm_status.in_amp);
    p_.chartform->addSampleAllGraph("psm_15v", xlru_psm::xlru_psm_status.out_volt_VOLT15V);
    p_.chartform->addSampleAllGraph("psm_m15v", xlru_psm::xlru_psm_status.out_volt_VOLTNEG15V);
    p_.chartform->addSampleAllGraph("psm_3v3", xlru_psm::xlru_psm_status.out_volt_VOLT3V3);
    p_.chartform->addSampleAllGraph("psm_5v", xlru_psm::xlru_psm_status.out_volt_VOLT5V);

}



void GrifoXLruMainWindow::on_actionPSM_Show_triggered(bool checked)
{
    ui->psm->setVisible(checked);
}

void GrifoXLruMainWindow::on_actionPPS_Show_triggered(bool checked)
{
    ui->pps->setVisible(checked);
}

void GrifoXLruMainWindow::on_actionLCU_Show_triggered(bool checked)
{
    ui->lcu->setVisible(checked);
}


void GrifoXLruMainWindow::closeEvent(QCloseEvent */*event*/)
{
    foreach (LruSerialPort* p, p_.smap)
    {
        p->close();
    }
    p_.s->close();
    p_.chartform->close();
}

void GrifoXLruMainWindow::on_actionLog_triggered(bool checked)
{
    if (checked)
        p_.logDock->setVisible(true);
}

void GrifoXLruMainWindow::on_actionGFX_triggered(bool /*checked*/)
{
    p_.chartform->show();
    p_.chartform->raise();
}

static struct
{
    unsigned int guard_low[128];
    fpga_info_t fpga_info;
    unsigned int guard_high[128];
} fpga_buffer;

void GrifoXLruMainWindow::fpgaTftpPoll()
{
    static int fpga_selector;
    static unsigned int request;
    static unsigned int pending;

    if (p_.udpFpga->checkState(0)==Qt::Unchecked)
    {
        p_.fpgaPending=-1;
        return;
    }
    if (p_.fpgaPending<0)
    {
        ++pending;
        p_.udpFpga->setText(2, QString("%1").arg(pending));
        //return;
    }

    if (fpga_selector>=p_.fpga_set.size())
    {
        return;
    }

    if (p_.fpgaStatus[fpga_selector]->checkState(0)!=Qt::Unchecked)
    {
        //QString name("$SRIO:0x13/0x44000780+256");

        QString name;
        const QString dst=p_.fpga_set.at(fpga_selector);
        if (dst.startsWith("0x5"))
            name=QString("$SRIO:%1/%2+256").arg(dst).arg("0x500E0780");//0xb0000000+256");
        else
        if (dst.startsWith("0x3"))
            name=QString("$SRIO:%1/%2+256").arg(dst).arg("0x80FFF000");//0xb0000000+256");
        else
            name=QString("$SRIO:%1/%2+256").arg(dst).arg(p_.fpga_address);//0xb0000000+256");

        p_.fpgaPending=fpga_selector;
        p_.xlruTftp->receiveMemory(&fpga_buffer.fpga_info.uc_info, 256, name);
        ++request;
        p_.udpFpga->setText(1, QString("%1").arg(request));
    }
    else
        p_.fpgaInit[p_.fpgaPending]=false;


    ++fpga_selector;
    if (fpga_selector>=p_.fpga_set.size())
        fpga_selector=0;
}

void GrifoXLruMainWindow::fpgaTftpReceived(bool ok)
{
    /*if (ok && p_.fpgaPending>=0)
    {
        XlruChartClass::sensor_id_t index=static_cast<XlruChartClass::sensor_id_t>(static_cast<int>(XlruChartClass::s_fpga_1) + p_.fpgaPending);
        p_.chartform->addSampleAllGraph(index, fpga_buffer.fpga_info.uc_info.temperature_value[0]);
        //p_.chartform->addSample(index, fpga_buffer.fpga_info.uc_info.temperature_value[0]);
    }*/

	if (ok && p_.fpgaPending>=0)
    {

        //int index=XlruChartClass::s_fpga_1+p_.fpgaPending;
        //p_.chartform->addSample(index, fpga_buffer.fpga_info.uc_info.temperature_value[0]);
        //p_.chartform->addSample(s_fpga_2, fpga_buffer.fpga_info.uc_info.temperature_value[1]);

        QString Chanel1 = QString("%1_0").arg(p_.fpga_set[p_.fpgaPending]);
        QString Chanel2 = QString("%1_1").arg(p_.fpga_set[p_.fpgaPending]);
        QString Chanel3 = QString("%1_2").arg(p_.fpga_set[p_.fpgaPending]);
        QString Chanel4 = QString("%1_3").arg(p_.fpga_set[p_.fpgaPending]);
        QString Chanel5 = QString("%1_4").arg(p_.fpga_set[p_.fpgaPending]);
        QString Chanel6 = QString("%1_5").arg(p_.fpga_set[p_.fpgaPending]);
        QString Chanel7 = QString("%1_6").arg(p_.fpga_set[p_.fpgaPending]);
        QString Chanel8 = QString("%1_7").arg(p_.fpga_set[p_.fpgaPending]);
        p_.chartform->addSampleAllGraph(Chanel1, fpga_buffer.fpga_info.uc_info.temperature_value[0]);
        p_.chartform->addSampleAllGraph(Chanel2, fpga_buffer.fpga_info.uc_info.temperature_value[1]);
        p_.chartform->addSampleAllGraph(Chanel3, fpga_buffer.fpga_info.uc_info.temperature_value[2]);
        p_.chartform->addSampleAllGraph(Chanel4, fpga_buffer.fpga_info.uc_info.temperature_value[3]);
        p_.chartform->addSampleAllGraph(Chanel5, fpga_buffer.fpga_info.uc_info.temperature_value[4]);
        p_.chartform->addSampleAllGraph(Chanel6, fpga_buffer.fpga_info.uc_info.temperature_value[5]);
        p_.chartform->addSampleAllGraph(Chanel7, fpga_buffer.fpga_info.uc_info.temperature_value[6]);
        p_.chartform->addSampleAllGraph(Chanel8, fpga_buffer.fpga_info.uc_info.temperature_value[7]);
        if (!p_.fpgaInit[p_.fpgaPending])
        {
            p_.fpgaStatus[p_.fpgaPending]->setText(1, QString("0x%1").arg(fpga_buffer.fpga_info.uc_info.slot_address, 0, 16));
            QByteArray v0((const char*)fpga_buffer.fpga_info.uc_info.sw_id, sizeof fpga_buffer.fpga_info.uc_info.sw_id);
            QByteArray v1((const char*)&fpga_buffer.fpga_info.uc_info.sw_release[0], sizeof fpga_buffer.fpga_info.uc_info.sw_release[0]);
            QByteArray v2((const char*)&fpga_buffer.fpga_info.uc_info.sw_release[1], sizeof fpga_buffer.fpga_info.uc_info.sw_release[1]);
            QByteArray v3((const char*)&fpga_buffer.fpga_info.uc_info.sw_build, sizeof fpga_buffer.fpga_info.uc_info.sw_build);

            QString v=QString("%1 v%2.%3-%5").arg(v0.constData()).arg(v1.constData()).arg(v2.constData()).arg(v3.constData());
            p_.fpgaStatus[p_.fpgaPending]->setText(2, v);
            p_.fpgaInit[p_.fpgaPending]=true;
        }
    }
    p_.fpgaPending=0;
}

void GrifoXLruMainWindow::on_actionLog_triggered()
{

}
