low level com stuff
This commit is contained in:
parent
4368db004d
commit
a2ffeff2da
7 changed files with 134 additions and 43 deletions
|
|
@ -16,6 +16,9 @@ MainWindow::MainWindow(QWidget *parent)
|
|||
connect(&ctrl, &ShimLCController::newConfigAv, this, &MainWindow::updateAvDevices);
|
||||
connect(&ctrl, &ShimLCController::newStatusAv, this, &MainWindow::updateStatus);
|
||||
|
||||
// Status Timer
|
||||
connect(&statusTimer, &QTimer::timeout, &ctrl, &ShimLCController::updateStatus);
|
||||
|
||||
spinner->setRoundness(70.0);
|
||||
spinner->setMinimumTrailOpacity(15.0);
|
||||
spinner->setTrailFadePercentage(70.0);
|
||||
|
|
@ -87,22 +90,26 @@ void MainWindow::updateAvDevices()
|
|||
ui->detectorSelectorBox->clear();
|
||||
foreach(LCPort item, ctrl.configuration.detectors)
|
||||
ui->detectorSelectorBox->addItem(QString("Port %1: %2").arg(item.port).arg(item.name));
|
||||
ctrl.updateStatus();
|
||||
statusTimer.start(2000);
|
||||
}
|
||||
|
||||
void MainWindow::updateStatus()
|
||||
{
|
||||
// Stats
|
||||
vdebug.updateStatus(ctrl.lastStatus);
|
||||
ui->stateLabel->setText(vdebug.cur_stats.join(","));
|
||||
|
||||
|
||||
// Autospampler
|
||||
ui->autoSamplerStatus->setText(QString("Rack: %1").arg(ctrl.lastStatus.autosampler.rack));
|
||||
|
||||
// Pumps
|
||||
ui->pumpPress->display(ctrl.lastStatus.pump[ui->pumpsSelectorBox->currentIndex()].actPressure);
|
||||
ui->pumpFlow->setValue(ctrl.lastStatus.pump[ui->pumpsSelectorBox->currentIndex()].setFlow); // TODO: Not update if currently highlighted
|
||||
if(not ui->pumpFlow->hasFocus())
|
||||
ui->pumpFlow->setValue(ctrl.lastStatus.pump[ui->pumpsSelectorBox->currentIndex()].setFlow);
|
||||
|
||||
// Detectors
|
||||
ui->detectorNmSpinBox->setValue(ctrl.lastStatus.detector[ui->detectorSelectorBox->currentIndex()].waveLen1);
|
||||
if(not ui->detectorNmSpinBox->hasFocus())
|
||||
ui->detectorNmSpinBox->setValue(ctrl.lastStatus.detector[ui->detectorSelectorBox->currentIndex()].waveLen1);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ private:
|
|||
ZoomableChart* mainChart = nullptr;
|
||||
WaitingSpinnerWidget* spinner = nullptr;
|
||||
|
||||
QTimer statusTimer = QTimer(this);
|
||||
|
||||
private slots:
|
||||
void updateConnectionState(QAbstractSocket::SocketState state);
|
||||
void reconnect();
|
||||
|
|
|
|||
|
|
@ -420,6 +420,19 @@
|
|||
<item>
|
||||
<widget class="ZoomableChartWidget" name="chartWidget" native="true"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="stateLabel">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>12</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Loading...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
|
|
|
|||
|
|
@ -1,19 +1,31 @@
|
|||
#include "shimlccontroller.h"
|
||||
|
||||
/* Encode Message and store to data
|
||||
* 01 00 01 00 -> Generic Header
|
||||
* ll 00 00 00 -> ll => Msg len+1 (becuase of 0d at the end) (maybe more than one byte?
|
||||
* 01 00 01 00 -> Header: First 2 Bytes are type uint16 LE 1 called "info", second 2 bytes are uint8 LE 1 called "code"
|
||||
* (other info, code numbers unknown, always 1?)
|
||||
* xx xx xx xx => Msg len+1 (becuase of 0d at the end) uint32 LE
|
||||
* ... msg in ASCII ...
|
||||
* 0d -> End */
|
||||
void cbmenc(QString message, QByteArray *data)
|
||||
{
|
||||
data->append("\x01\x00\x01\x00", 4);
|
||||
data->append(message.length()+1);
|
||||
data->append("\x00\x00\x00", 3);
|
||||
data->append("\x01\x00\x01\x00", 4); // Fixed header
|
||||
char buf[4];
|
||||
qToLittleEndian((quint32)message.length()+1, buf);
|
||||
data->append(buf, 4);
|
||||
data->append(message.toLatin1());
|
||||
data->append("\x0d");
|
||||
}
|
||||
|
||||
void cbmenc(QByteArray *data)
|
||||
{
|
||||
quint32 len = data->length()+1;
|
||||
char buf[4];
|
||||
qToLittleEndian(len, buf);
|
||||
data->prepend(buf, 4);
|
||||
data->prepend("\x01\x00\x01\x00", 4);
|
||||
data->append("\x0d");
|
||||
}
|
||||
|
||||
// Encode Data with cbmenc and send to peer
|
||||
void ShimTCPController::cbmquery(QString message)
|
||||
{
|
||||
|
|
@ -23,20 +35,36 @@ void ShimTCPController::cbmquery(QString message)
|
|||
this->writeData(&data);
|
||||
}
|
||||
|
||||
void ShimTCPController::cbmir(QByteArray *irDataRet)
|
||||
/* Actual Read command
|
||||
* 49 52 -> IR (Interface Read?)
|
||||
* xx -> fileHandle
|
||||
* xx xx -> size (max 1020!)
|
||||
* Repeat until data complete, then exit */
|
||||
void ShimTCPController::cbmir(quint8 filehandle, QByteArray *irDataRet)
|
||||
{
|
||||
QByteArray data{"\x01\x00\x01\x00\x05\x00\x00\x00IR\x00", 11};
|
||||
QByteArray data{"IR"};
|
||||
irFileHandle = filehandle;
|
||||
char fh[1];
|
||||
qToLittleEndian(filehandle, fh);
|
||||
data.append(fh, 1);
|
||||
char buf[2];
|
||||
|
||||
if(irMode == 0)
|
||||
// Max Size 1020!
|
||||
if(irPendingSize > 1020)
|
||||
{
|
||||
data.append("\xfc\x03", 2);
|
||||
irData = irDataRet;
|
||||
irData->clear(); // Clear current Data in Array
|
||||
qToLittleEndian((quint16)1020, buf);
|
||||
irPendingSize -= 1020;
|
||||
}
|
||||
else
|
||||
data.append("\x72\x01", 2);
|
||||
irMode+=1;
|
||||
{
|
||||
qToLittleEndian((quint16)irPendingSize, buf);
|
||||
irPendingSize = 0;
|
||||
}
|
||||
data.append(buf, 2);
|
||||
cbmenc(&data);
|
||||
|
||||
if(irDataRet != nullptr)
|
||||
irData = irDataRet;
|
||||
writeData(&data);
|
||||
}
|
||||
|
||||
|
|
@ -113,7 +141,7 @@ void ShimTCPController::displayError(QAbstractSocket::SocketError socketError)
|
|||
// Parse Data and reset parserFunction signal
|
||||
void ShimTCPController::readData()
|
||||
{
|
||||
if(irMode == 0)
|
||||
if(irPendingSize == -1)
|
||||
parseCbmquery(socket->readAll());
|
||||
else
|
||||
parseCbmIr();
|
||||
|
|
@ -135,7 +163,7 @@ void ShimTCPController::parseCbmquery(QByteArray data)
|
|||
emit dataAvailable("-");
|
||||
return;
|
||||
}
|
||||
data.removeLast();
|
||||
//data.removeLast();
|
||||
QTextCodec::ConverterState state;
|
||||
QTextCodec *codec = QTextCodec::codecForName("ASCII");
|
||||
const QString validText = codec->toUnicode(data.constData(), data.size(), &state);
|
||||
|
|
@ -151,7 +179,7 @@ void ShimTCPController::parseCbmquery(QByteArray data)
|
|||
|
||||
void ShimTCPController::parseCbmIr()
|
||||
{
|
||||
if (irMode == -1)
|
||||
if (irPendingSize == -2)
|
||||
{
|
||||
QByteArray resp = socket->readAll();
|
||||
if(resp.at(10) != '0')
|
||||
|
|
@ -159,7 +187,7 @@ void ShimTCPController::parseCbmIr()
|
|||
qWarning("Did not exit IR mode!");
|
||||
qDebug() << "Response:" << resp;
|
||||
}
|
||||
irMode = 0;
|
||||
irPendingSize = -1;
|
||||
emit irDone();
|
||||
}
|
||||
else
|
||||
|
|
@ -173,17 +201,28 @@ void ShimTCPController::parseCbmIr()
|
|||
{
|
||||
qWarning("irData->length() != msgLen | Expected on 2nd request - FIXME");
|
||||
qDebug() << "msgLen:" << msgLen;
|
||||
qDebug() << "actual:" << irData->length() - len_before;
|
||||
qDebug() << "actual:" << irData->length() - len_before << " | TOTAL: " << irData->length();
|
||||
}
|
||||
if(check != 0x0)
|
||||
// More Data if last request was maxed out
|
||||
if(irData->length() - len_before == 1024)
|
||||
{
|
||||
cbmir(nullptr);
|
||||
cbmir((quint8)irFileHandle);
|
||||
return;
|
||||
}
|
||||
// Close File
|
||||
else
|
||||
{
|
||||
irMode = -1;
|
||||
socket->write("\x01\x00\x01\x00\x03\x00\x00\x00\x49\x43\x00", 11);
|
||||
if (irPendingSize != 0)
|
||||
{
|
||||
qDebug() << "File Size Configured wrong! Still pending " << irPendingSize << " but got STOP!";
|
||||
}
|
||||
QByteArray data{"IC"};
|
||||
char fh[1];
|
||||
qToLittleEndian((quint8)irFileHandle, fh);
|
||||
data.append(fh, 1);
|
||||
cbmenc(&data);
|
||||
writeData(&data);
|
||||
irPendingSize = -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -243,11 +282,11 @@ ShimLCCommandStack::~ShimLCCommandStack()
|
|||
|
||||
}
|
||||
|
||||
uint32_t ShimLCCommandStack::addCmd(char opcode, QString cmd, QByteArray* dest)
|
||||
uint32_t ShimLCCommandStack::addCmd(char opcode, QString cmd, QByteArray* dest, uint iSize)
|
||||
{
|
||||
qDebug() << TAG << "added cmd: Opcode:" << opcode << "Cmd:" << cmd;
|
||||
id ++;
|
||||
stackIn.push_back(ShimLCCmd{id, opcode, cmd, dest});
|
||||
stackIn.push_back(ShimLCCmd{id, opcode, cmd, dest, iSize});
|
||||
qDebug() << TAG << "Current size of cmd stack:" << stackIn.size();
|
||||
if(busy_id == 0)
|
||||
this->next();
|
||||
|
|
@ -280,6 +319,7 @@ void ShimLCCommandStack::next()
|
|||
void ShimLCCommandStack::newResult(QByteArray data)
|
||||
{
|
||||
bool ok = 0;
|
||||
if(stackIn.first().dest != nullptr)
|
||||
switch(stackIn.first().opcode)
|
||||
{
|
||||
case 'K':
|
||||
|
|
@ -292,11 +332,15 @@ void ShimLCCommandStack::newResult(QByteArray data)
|
|||
break;
|
||||
case 'I':
|
||||
if(data.mid(2,1).toInt(&ok) == 0 && ok)
|
||||
connection.cbmir(stackIn.first().dest);
|
||||
{
|
||||
quint8 fileHandle = data.mid(4,1).toHex().toUInt(nullptr, 16);
|
||||
connection.irPendingSize = stackIn.first().iSize;
|
||||
connection.cbmir(fileHandle, stackIn.first().dest);
|
||||
}
|
||||
else
|
||||
qWarning() << TAG << "Got invalid I command! Cmd, resp:" << stackIn.first().cmd << data;
|
||||
stackIn.pop_front();
|
||||
return;
|
||||
return; // Return without dataAV!
|
||||
}
|
||||
|
||||
stackIn.pop_front();
|
||||
|
|
@ -319,11 +363,6 @@ uint32_t ShimLCCommandStack::getActVal(QString cmd, QByteArray* dest)
|
|||
char opcode = 'M';
|
||||
return addCmd(opcode, cmd, dest);
|
||||
}
|
||||
uint32_t ShimLCCommandStack::iCmd(QString cmd, QByteArray* dest)
|
||||
{
|
||||
char opcode = 'I';
|
||||
return addCmd(opcode, cmd, dest);
|
||||
}
|
||||
|
||||
void ShimLCCommandStack::reconnect(QSettings *settings)
|
||||
{
|
||||
|
|
@ -342,20 +381,28 @@ void ShimLCCommandStack::exitedIr()
|
|||
next();
|
||||
}
|
||||
|
||||
uint32_t ShimLCCommandStack::readFile(QString filename, QByteArray* dest, uint size)
|
||||
{
|
||||
dest->clear();
|
||||
return addCmd('I', "OR "+filename, dest, size);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
void ShimLCController::updateConfig()
|
||||
{
|
||||
connect(&cmd, &ShimLCCommandStack::dataAvailable, this, &ShimLCController::parseLcnf);
|
||||
ids[ID_CONF] = cmd.iCmd("OR lcnf.", &data);
|
||||
ids[ID_CONF] = cmd.readFile("lcnf.", &data, 4236);
|
||||
//ids[ID_CONF] = cmd.iCmd("OR lcnf.", &data);
|
||||
}
|
||||
|
||||
void ShimLCController::updateStatus()
|
||||
{
|
||||
|
||||
connect(&cmd, &ShimLCCommandStack::dataAvailable, this, &ShimLCController::parseStatus);
|
||||
ids[ID_STATUS] = cmd.iCmd("OR lmon.", &data);
|
||||
ids[ID_STATUS] = cmd.readFile("lmon.", &data, 1575);
|
||||
//ids[ID_STATUS] = cmd.iCmd("OR lmon.", &data);
|
||||
}
|
||||
|
||||
void ShimLCController::reconnect(QSettings *settings)
|
||||
|
|
@ -366,6 +413,10 @@ void ShimLCController::reconnect(QSettings *settings)
|
|||
disconnect(&cmd, &ShimLCCommandStack::dataAvailable, this, &ShimLCController::parseLcnf);
|
||||
disconnect(&cmd, &ShimLCCommandStack::dataAvailable, this, &ShimLCController::parseStatus);
|
||||
// Reconnect done, clear to send new commands
|
||||
cmd.setVal("AUXOPE 64", nullptr);
|
||||
cmd.setVal("FIX.CH -1", nullptr);
|
||||
cmd.setVal("SETCBM", nullptr);
|
||||
cmd.setVal("LMONLVL=000000000L", nullptr);
|
||||
}
|
||||
|
||||
ShimLCController::ShimLCController(QObject *parent)
|
||||
|
|
@ -432,6 +483,10 @@ void ShimLCController::parseStatus(uint32_t idVal)
|
|||
lastStatus.stats.status2 += data.mid(4+591+i,1).toHex().toUInt(nullptr, 16) << 8*i;
|
||||
}
|
||||
|
||||
lastStatus.autosampler.rack = 0;
|
||||
for(int i = 0; i<4; i++)
|
||||
lastStatus.autosampler.rack += data.mid(49+i,1).toHex().toInt(nullptr, 16) << 8*i;
|
||||
|
||||
// --- PUMPS ---
|
||||
|
||||
// Pressure is at A: data[4:8], B: data[8:12], C:[12:16] encoded in int LE! Unit: wtf... Conversion was done via curve fitting!
|
||||
|
|
@ -461,7 +516,7 @@ void ShimLCController::parseStatus(uint32_t idVal)
|
|||
}
|
||||
|
||||
// --- AUTOSAMPLER ---
|
||||
lastStatus.autosampler.rack = data.mid(382,1).toHex().toInt();
|
||||
//lastStatus.autosampler.rack = data.mid(382,1).toHex().toUInt();
|
||||
|
||||
qDebug() << lastStatus.autosampler.rack;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include <cmath>
|
||||
#include <QAbstractSocket>
|
||||
#include <QMessageBox>
|
||||
#include <QtEndian>
|
||||
|
||||
struct ShimLCCmdStackResult
|
||||
{
|
||||
|
|
@ -27,8 +28,9 @@ class ShimTCPController : public QObject
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
int irPendingSize = -1;
|
||||
void cbmquery(QString message);
|
||||
void cbmir(QByteArray* irDataRet);
|
||||
void cbmir(quint8 filehandle, QByteArray* irDataRet = nullptr);
|
||||
explicit ShimTCPController(QObject *parent = 0);
|
||||
~ShimTCPController();
|
||||
|
||||
|
|
@ -55,7 +57,7 @@ private:
|
|||
QString TAG = "ShimTCPController";
|
||||
QTcpSocket *socket;
|
||||
QByteArray next_pkg{};
|
||||
int irMode = 0;
|
||||
int irFileHandle = -1;
|
||||
QByteArray* irData = nullptr;
|
||||
QByteArray* pendingData = nullptr;
|
||||
};
|
||||
|
|
@ -80,7 +82,7 @@ public:
|
|||
uint32_t setVal(QString cmd, QByteArray *dest);
|
||||
uint32_t getSetVal(QString cmd, QByteArray *dest);
|
||||
uint32_t getActVal(QString cmd, QByteArray *dest);
|
||||
uint32_t iCmd(QString cmd, QByteArray *dest);
|
||||
uint32_t readFile(QString filename, QByteArray *dest, uint size);
|
||||
void reconnect(QSettings *settings);
|
||||
|
||||
private:
|
||||
|
|
@ -89,12 +91,13 @@ private:
|
|||
using Connection = std::tuple<QObject*, const char*>;
|
||||
struct ShimLCCmd
|
||||
{
|
||||
ShimLCCmd(uint32_t id, char opcode, QString cmd, QByteArray* dest)
|
||||
: id(id), opcode(opcode), cmd(cmd), dest(dest) {}
|
||||
ShimLCCmd(uint32_t id, char opcode, QString cmd, QByteArray* dest, uint32_t iSize)
|
||||
: id(id), opcode(opcode), cmd(cmd), dest(dest), iSize(iSize) {}
|
||||
uint32_t id;
|
||||
char opcode;
|
||||
QString cmd;
|
||||
QByteArray* dest;
|
||||
uint32_t iSize; // Only needed for I commands
|
||||
};
|
||||
ShimTCPController connection{};
|
||||
QVector<ShimLCCmd> stackIn{};
|
||||
|
|
@ -102,7 +105,7 @@ private:
|
|||
uint32_t busy_id = 0;
|
||||
|
||||
void next();
|
||||
uint32_t addCmd(char opcode, QString cmd, QByteArray* dest);
|
||||
uint32_t addCmd(char opcode, QString cmd, QByteArray* dest, uint iSize = 0);
|
||||
|
||||
QObject* parent;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -17,12 +17,16 @@ ViewDebugStatus::~ViewDebugStatus()
|
|||
void ViewDebugStatus::updateStatus(LCStatus &status)
|
||||
{
|
||||
ui->listWidget->clear();
|
||||
cur_stats.clear();
|
||||
uint32_t i = 0;
|
||||
ui->listWidget->addItem(QString(">> SILST = %1").arg(status.stats.silst));
|
||||
foreach(QString itm, status.stats.silst_labels)
|
||||
{
|
||||
if(status.stats.silst & (0b1 << i))
|
||||
{
|
||||
ui->listWidget->addItem(QString("\t%1").arg(itm));
|
||||
cur_stats.push_back(itm);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
|
|
@ -31,7 +35,10 @@ void ViewDebugStatus::updateStatus(LCStatus &status)
|
|||
foreach(QString itm, status.stats.status1_labels)
|
||||
{
|
||||
if(status.stats.status1 & (0b1 << i))
|
||||
{
|
||||
ui->listWidget->addItem(QString("\t%1").arg(itm));
|
||||
cur_stats.push_back(itm);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
|
|
@ -40,7 +47,10 @@ void ViewDebugStatus::updateStatus(LCStatus &status)
|
|||
foreach(QString itm, status.stats.status2_labels)
|
||||
{
|
||||
if(status.stats.status2 & (0b1 << i))
|
||||
{
|
||||
ui->listWidget->addItem(QString("\t%1").arg(itm));
|
||||
cur_stats.push_back(itm);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ public:
|
|||
explicit ViewDebugStatus(QWidget *parent = nullptr);
|
||||
~ViewDebugStatus();
|
||||
void updateStatus(LCStatus &status);
|
||||
QStringList cur_stats{};
|
||||
|
||||
private:
|
||||
Ui::ViewDebugStatus *ui;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue