summaryrefslogtreecommitdiffstats
path: root/clients/tde/src/part
diff options
context:
space:
mode:
Diffstat (limited to 'clients/tde/src/part')
-rw-r--r--clients/tde/src/part/scope/part.cpp1
-rw-r--r--clients/tde/src/part/sensormonitor/part.cpp468
-rw-r--r--clients/tde/src/part/sensormonitor/part.h90
3 files changed, 535 insertions, 24 deletions
diff --git a/clients/tde/src/part/scope/part.cpp b/clients/tde/src/part/scope/part.cpp
index 03b6b25..7e64592 100644
--- a/clients/tde/src/part/scope/part.cpp
+++ b/clients/tde/src/part/scope/part.cpp
@@ -396,6 +396,7 @@ void ScopePart::setTickerMessage(TQString message) {
} \
else { \
m_commHandlerState = ScopeState_ExternalCommandRequest; \
+ EXEC_NEXT_STATE_IMMEDIATELY \
}
#define EXEC_NEXT_STATE_IMMEDIATELY m_forcedUpdateTimer->start(0, TRUE);
diff --git a/clients/tde/src/part/sensormonitor/part.cpp b/clients/tde/src/part/sensormonitor/part.cpp
index 469f24d..31f1213 100644
--- a/clients/tde/src/part/sensormonitor/part.cpp
+++ b/clients/tde/src/part/sensormonitor/part.cpp
@@ -40,6 +40,7 @@
#include <tqvbox.h>
#include <tqsocket.h>
#include <tqmutex.h>
+#include <tqlayout.h>
#include <tqeventloop.h>
#include <tqapplication.h>
#include <tqgroupbox.h>
@@ -58,13 +59,21 @@
#define NETWORK_COMM_TIMEOUT_MS 2500
enum connectionModes {
- ModeIdle = 0
+ ModeIdle = 0,
+ ModeInterruptRequested = 1,
+ ModeGetSample = 2
};
enum connectionStates {
- ModeIdle_StateStatusRequest = 0,
- ModeIdle_StateProcessStatus = 1,
- ModeIdle_StateDelay = 2
+ ModeIdle_StateSensorListRequest = 0,
+ ModeIdle_StateProcessSensorList = 1,
+ ModeIdle_StateStatusRequest = 2,
+ ModeIdle_StateProcessStatus = 3,
+ ModeIdle_StateDelay = 4,
+ ModeIdle_StatePaused = 5,
+ ModeIdle_StateExternalRequest = 6,
+ ModeGetSample_StateSampleRequest = 7,
+ ModeGetSample_StateProcessSample = 8
};
namespace RemoteLab {
@@ -73,8 +82,103 @@ typedef KParts::GenericFactory<RemoteLab::SensorMonitorPart> Factory;
#define CLIENT_LIBRARY "libremotelab_sensormonitor"
K_EXPORT_COMPONENT_FACTORY(libremotelab_sensormonitor, RemoteLab::Factory)
+TQValueTimer::TQValueTimer(TQObject *parent, const char *name)
+ : TQTimer(parent, name)
+{
+ connect(this, SIGNAL(timeout()), this, SLOT(timeoutHandler()));
+}
+
+TQValueTimer::~TQValueTimer() {
+ //
+}
+
+void TQValueTimer::timeoutHandler() {
+ emit(valueTimeout(m_value));
+}
+
+int TQValueTimer::value() {
+ return m_value;
+}
+
+void TQValueTimer::setValue(int value) {
+ m_value = value;
+}
+
+TraceControlWidget::TraceControlWidget(TQWidget *parent, const char *name)
+ : TQWidget(parent, name), m_minimumTimeStep(0.0), m_nominalTimeStep(1.0)
+{
+ TQGridLayout *topGrid = new TQGridLayout(this);
+ m_groupBox = new TQGroupBox(this);
+ m_groupBox->setColumnLayout(0, TQt::Vertical);
+ topGrid->addMultiCellWidget(m_groupBox, 0, 0, 0, 0);
+ m_groupBox->setTitle(i18n("Unknown Channel"));
+ m_primaryLayout = new TQGridLayout(m_groupBox->layout(), KDialog::marginHint(), KDialog::spacingHint());
+
+ m_channelEnabledCheckBox = new TQCheckBox(m_groupBox);
+ connect(m_channelEnabledCheckBox, SIGNAL(clicked()), this, SLOT(enableClicked()));
+ m_channelEnabledCheckBox->setText(i18n("Enable"));
+ m_primaryLayout->addMultiCellWidget(m_channelEnabledCheckBox, 0, 0, 0, 0);
+
+ m_timestepSpinBox = new FloatSpinBox(m_groupBox);
+ m_timestepSpinBox->setFloatMax(60*60*24); // 1 day
+ connect(m_timestepSpinBox, SIGNAL(floatValueChanged(double)), this, SLOT(timestepChanged(double)));
+ m_primaryLayout->addMultiCellWidget(m_timestepSpinBox, 0, 0, 1, 1);
+
+ m_sampleTimer = new TQTimer();
+ connect(m_sampleTimer, SIGNAL(timeout()), this, SIGNAL(newSampleDesired()));
+}
+
+TraceControlWidget::~TraceControlWidget() {
+ m_sampleTimer->stop();
+ delete m_sampleTimer;
+}
+
+void TraceControlWidget::startSampleTimer(int msecs) {
+ if (m_channelEnabledCheckBox->isOn()) {
+ m_nominalTimeStep = msecs/1.0e3;
+ m_sampleTimer->start(msecs, FALSE);
+ }
+ else {
+ m_sampleTimer->stop();
+ }
+}
+
+void TraceControlWidget::stopSampleTimer() {
+ m_sampleTimer->stop();
+}
+
+void TraceControlWidget::setTraceEnabled(bool enabled) {
+ m_channelEnabledCheckBox->setChecked(enabled);
+}
+
+void TraceControlWidget::setTraceName(TQString name) {
+ m_groupBox->setTitle(name);
+}
+
+void TraceControlWidget::setTimestep(double seconds) {
+ m_nominalTimeStep = seconds;
+ m_timestepSpinBox->setFloatValue(m_nominalTimeStep);
+ startSampleTimer(m_nominalTimeStep*1.0e3);
+}
+
+void TraceControlWidget::setMinTimestep(double seconds) {
+ m_minimumTimeStep = seconds;
+ m_timestepSpinBox->setFloatMin(seconds);
+}
+
+void TraceControlWidget::enableClicked() {
+ bool enabled = m_channelEnabledCheckBox->isOn();
+ emit(enableChanged(enabled));
+ startSampleTimer(m_nominalTimeStep*1.0e3);
+}
+
+void TraceControlWidget::timestepChanged(double value) {
+ m_sampleTimer->stop();
+ startSampleTimer(value*1.0e3);
+}
+
SensorMonitorPart::SensorMonitorPart(TQWidget *parentWidget, const char *widgetName, TQObject *parent, const char *name, const TQStringList&)
- : RemoteInstrumentPart( parent, name ), m_base(NULL), m_commHandlerState(0), m_connectionActiveAndValid(false), m_tickerState(0)
+ : RemoteInstrumentPart( parent, name ), m_base(NULL), m_commHandlerState(0), m_connectionActiveAndValid(false), m_tickerState(0), stopTraceUpdate(false)
{
// Initialize important base class variables
m_clientLibraryName = CLIENT_LIBRARY;
@@ -94,12 +198,57 @@ SensorMonitorPart::SensorMonitorPart(TQWidget *parentWidget, const char *widgetN
m_pingDelayTimer = new TQTimer(this);
connect(m_pingDelayTimer, SIGNAL(timeout()), this, SLOT(mainEventLoop()));
+ // Initialize data
+ m_hdivs = 10;
+ m_vdivs = 8;
+ m_maxNumberOfTraces = 0;
+ for (int traceno=0; traceno<=MAXTRACES; traceno++) {
+ m_samplesInTrace[traceno] = 0;
+ m_channelActive[traceno] = false;
+ m_traceUnits[traceno] = "";
+ m_traceControlWidgetList[traceno] = NULL;
+ m_sampleRequestInProgress[traceno] = false;
+ }
+
// Create widgets
m_base = new SensorMonitorBase(widget());
+ m_traceControlWidgetGrid = new TQGridLayout(m_base->traceControlLayoutWidget);
+ m_traceWidget = m_base->traceWidget;
+ m_traceWidget->setSizePolicy(TQSizePolicy(TQSizePolicy::MinimumExpanding, TQSizePolicy::MinimumExpanding));
+ m_traceWidget->setNumberOfCursors(4);
+ m_traceWidget->setZoomCursorStartIndex(0);
+ m_traceWidget->setCursorOrientation(0, TQt::Horizontal);
+ m_traceWidget->setCursorOrientation(1, TQt::Horizontal);
+ m_traceWidget->setCursorOrientation(2, TQt::Vertical);
+ m_traceWidget->setCursorOrientation(3, TQt::Vertical);
+ m_traceWidget->setCursorEnabled(0, true);
+ m_traceWidget->setCursorEnabled(1, true);
+ m_traceWidget->setCursorEnabled(2, true);
+ m_traceWidget->setCursorEnabled(3, true);
+ m_traceWidget->setCursorName(0, "Cursor H1");
+ m_traceWidget->setCursorName(1, "Cursor H2");
+ m_traceWidget->setCursorName(2, "Cursor V1");
+ m_traceWidget->setCursorName(3, "Cursor V2");
+ m_traceWidget->setCursorPosition(0, 25);
+ m_traceWidget->setCursorPosition(1, 75);
+ m_traceWidget->setCursorPosition(2, 25);
+ m_traceWidget->setCursorPosition(3, 75);
+ TraceNumberList activeTraces;
+ for (uint trace=0; trace<MAXTRACES; trace++) {
+ activeTraces.append(trace);
+ }
+ m_traceWidget->setCursorActiveTraceList(0, activeTraces);
+ m_traceWidget->setCursorActiveTraceList(1, activeTraces);
+ m_traceWidget->setCursorActiveTraceList(2, activeTraces);
+ m_traceWidget->setCursorActiveTraceList(3, activeTraces);
+ m_traceWidget->setZoomBoxEnabled(true);
+
+ m_base->traceZoomWidget->setSizePolicy(TQSizePolicy(TQSizePolicy::MinimumExpanding, TQSizePolicy::MinimumExpanding));
+ connect(m_traceWidget, SIGNAL(zoomBoxChanged(const TQRectF&)), this, SLOT(updateZoomWidgetLimits(const TQRectF&)));
// Initialize widgets
- connect(m_base->runControlStartButton, SIGNAL(clicked()), this, SLOT(programStartButtonClicked()));
- connect(m_base->runControlStopButton, SIGNAL(clicked()), this, SLOT(programStopButtonClicked()));
+ connect(m_base->runControlStartButton, SIGNAL(clicked()), this, SLOT(acquisitionStartButtonClicked()));
+ connect(m_base->runControlStopButton, SIGNAL(clicked()), this, SLOT(acquisitionStopButtonClicked()));
TQTimer::singleShot(0, this, TQT_SLOT(postInit()));
}
@@ -123,6 +272,14 @@ void SensorMonitorPart::processLockouts() {
mainWidget->setEnabled(false);
}
}
+ if (stopTraceUpdate) {
+ m_base->runControlStartButton->setEnabled(true);
+ m_base->runControlStopButton->setEnabled(false);
+ }
+ else {
+ m_base->runControlStartButton->setEnabled(false);
+ m_base->runControlStopButton->setEnabled(true);
+ }
}
void SensorMonitorPart::resizeToHint() {
@@ -160,7 +317,7 @@ void SensorMonitorPart::connectionFinishedCallback() {
m_socket->processPendingData();
connect(m_socket, SIGNAL(newDataReceived()), this, SLOT(mainEventLoop()));
m_tickerState = 0;
- m_commHandlerState = ModeIdle_StateStatusRequest;
+ m_commHandlerState = ModeIdle_StateSensorListRequest;
m_commHandlerMode = ModeIdle;
m_socket->setDataTimeout(NETWORK_COMM_TIMEOUT_MS);
m_updateTimeoutTimer->start(NETWORK_COMM_TIMEOUT_MS, TRUE);
@@ -177,6 +334,9 @@ void SensorMonitorPart::connectionStatusChangedCallback() {
m_tickerState = 0; \
m_commHandlerState = ModeIdle_StateStatusRequest; \
m_commHandlerMode = ModeIdle; \
+ for (int traceno=0; traceno<=MAXTRACES; traceno++) { \
+ m_sampleRequestInProgress[traceno] = false; \
+ } \
m_socket->clearIncomingData(); \
setStatusMessage(i18n("Server ping timeout. Please verify the status of your network connection.")); \
m_updateTimeoutTimer->start(NETWORK_COMM_TIMEOUT_MS, TRUE); \
@@ -186,7 +346,14 @@ void SensorMonitorPart::connectionStatusChangedCallback() {
#define SET_WATCHDOG_TIMER if (!m_updateTimeoutTimer->isActive()) m_updateTimeoutTimer->start(NETWORK_COMM_TIMEOUT_MS, TRUE);
#define PAT_WATCHDOG_TIMER m_updateTimeoutTimer->stop(); m_updateTimeoutTimer->start(NETWORK_COMM_TIMEOUT_MS, TRUE);
-#define SET_NEXT_STATE(x) m_commHandlerState = x;
+#define SET_NEXT_STATE(x) if ((m_commHandlerMode == ModeIdle) || (m_commHandlerMode == ModeGetSample)) { \
+ m_commHandlerState = x; \
+ } \
+ else { \
+ m_commHandlerState = ModeIdle_StateExternalRequest; \
+ EXEC_NEXT_STATE_IMMEDIATELY \
+ }
+#define SET_NEXT_STATE_DATA_WAITING(x) m_commHandlerState = x;
#define EXEC_NEXT_STATE_IMMEDIATELY m_forcedUpdateTimer->start(0, TRUE);
@@ -224,17 +391,42 @@ void SensorMonitorPart::mainEventLoop() {
}
if (m_socket) {
- if (m_commHandlerMode == ModeIdle) {
+ if ((m_commHandlerMode == ModeIdle) || (m_commHandlerMode == ModeInterruptRequested)) {
// Normal operation
switch (m_commHandlerState) {
+ case ModeIdle_StateSensorListRequest:
+ PAT_WATCHDOG_TIMER
+ ds << TQString("SENSORS");
+ m_socket->writeEndOfFrame();
+ SET_NEXT_STATE_DATA_WAITING(ModeIdle_StateProcessSensorList)
+ break;
+ case ModeIdle_StateProcessSensorList:
+ if (m_socket->canReadFrame()) {
+ PAT_WATCHDOG_TIMER
+
+ ds >> m_sensorList;
+ m_socket->clearFrameTail();
+
+ m_maxNumberOfTraces = m_sensorList.count();
+ updateTraceControlWidgets();
+
+ SET_NEXT_STATE(ModeIdle_StateStatusRequest)
+ EXEC_NEXT_STATE_IMMEDIATELY
+ }
+ else {
+ if (!m_updateTimeoutTimer->isActive()) {
+ UPDATEDISPLAY_TIMEOUT
+ }
+ }
+ break;
case ModeIdle_StateStatusRequest:
- // Get status of remote system
- // Clear buffers to synchronize frames in case of data corruption
- m_socket->clearIncomingData();
- ds << TQString("STATUS");
+ PAT_WATCHDOG_TIMER
+
+ // Ping remote system
+ ds << TQString("PING");
m_socket->writeEndOfFrame();
- SET_NEXT_STATE(ModeIdle_StateProcessStatus)
+ SET_NEXT_STATE_DATA_WAITING(ModeIdle_StateProcessStatus)
break;
case ModeIdle_StateProcessStatus:
// Get all data
@@ -249,16 +441,14 @@ void SensorMonitorPart::mainEventLoop() {
// Transfer probably failed
UPDATEDISPLAY_TIMEOUT
}
- else if (status == "IDLE") {
+ else if (status == "PONG") {
// Do nothing
}
setTickerMessage(i18n("Connected"));
- if (m_commHandlerState == ModeIdle_StateProcessStatus) {
- m_pingDelayTimer->start(250, TRUE);
- SET_NEXT_STATE(ModeIdle_StateDelay);
- }
+ m_pingDelayTimer->start(250, TRUE);
+ SET_NEXT_STATE(ModeIdle_StateDelay);
}
else {
if (!m_updateTimeoutTimer->isActive()) {
@@ -275,6 +465,67 @@ void SensorMonitorPart::mainEventLoop() {
}
PAT_WATCHDOG_TIMER
break;
+ case ModeIdle_StatePaused:
+ PAT_WATCHDOG_TIMER
+ break;
+ case ModeIdle_StateExternalRequest:
+ m_commHandlerMode = ModeGetSample;
+ m_commHandlerState = m_commHandlerNextState;
+ break;
+ }
+ }
+ else if (m_commHandlerMode == ModeGetSample) {
+ if (m_commHandlerState == ModeGetSample_StateSampleRequest) {
+ PAT_WATCHDOG_TIMER
+ ds << TQString("SAMPLE");
+ ds << m_sampleRequestIndex;
+ m_socket->writeEndOfFrame();
+ SET_NEXT_STATE_DATA_WAITING(ModeGetSample_StateProcessSample)
+ setTickerMessage(i18n("Obtaining new data point for sensor %1").arg(m_sensorList[m_sampleRequestIndex].name));
+ }
+ else if (m_commHandlerState == ModeGetSample_StateProcessSample) {
+ if (m_socket->canReadFrame()) {
+ PAT_WATCHDOG_TIMER
+
+ TQString result;
+ double newValue;
+ TQDateTime timestamp;
+
+ ds >> result;
+ if (result == "ACK") {
+ ds >> newValue;
+ ds >> timestamp;
+
+ TQDoubleArray sampleArray = m_traceWidget->samples(m_sampleRequestIndex);
+ TQDoubleArray positionArray = m_traceWidget->positions(m_sampleRequestIndex);
+ m_samplesInTrace[m_sampleRequestIndex]++;
+ sampleArray.resize(m_samplesInTrace[m_sampleRequestIndex]);
+ positionArray.resize(m_samplesInTrace[m_sampleRequestIndex]);
+ sampleArray[m_samplesInTrace[m_sampleRequestIndex]-1] = newValue;
+ positionArray[m_samplesInTrace[m_sampleRequestIndex]-1] = (timestamp.toTime_t()+(timestamp.time().msec()*1.0e-3));
+
+ m_traceWidget->setSamples(m_sampleRequestIndex, sampleArray);
+ m_traceWidget->setPositions(m_sampleRequestIndex, positionArray);
+ m_base->traceZoomWidget->setSamples(m_sampleRequestIndex, sampleArray);
+ m_base->traceZoomWidget->setPositions(m_sampleRequestIndex, positionArray);
+
+ updateGraticule();
+ m_traceWidget->repaint(false);
+ m_base->traceZoomWidget->repaint(false);
+ }
+
+ m_socket->clearFrameTail();
+ m_sampleRequestInProgress[m_sampleRequestIndex] = false;
+ m_commHandlerMode = ModeIdle;
+ m_pingDelayTimer->start(250, TRUE);
+ SET_NEXT_STATE(ModeIdle_StateDelay);
+ EXEC_NEXT_STATE_IMMEDIATELY
+ }
+ else {
+ if (!m_updateTimeoutTimer->isActive()) {
+ UPDATEDISPLAY_TIMEOUT
+ }
+ }
}
}
@@ -288,6 +539,183 @@ void SensorMonitorPart::mainEventLoop() {
m_connectionMutex->unlock();
}
+void SensorMonitorPart::updateZoomWidgetLimits(const TQRectF& zoomRect) {
+ for (int traceno=0; traceno<m_maxNumberOfTraces; traceno++) {
+ TQRectF fullZoomRect = m_traceWidget->displayLimits(traceno);
+ double widthSpan = fullZoomRect.width()-fullZoomRect.x();
+ double heightSpan = fullZoomRect.height()-fullZoomRect.y();
+
+ TQRectF zoomLimitsRect((fullZoomRect.x()+(widthSpan*(zoomRect.x()/100.0))), (fullZoomRect.y()+(heightSpan*(zoomRect.y()/100.0))), (fullZoomRect.x()+(widthSpan*((zoomRect.x()/100.0)+(zoomRect.width()/100.0)))), (fullZoomRect.y()+(heightSpan*((zoomRect.y()/100.0)+(zoomRect.height()/100.0)))));
+
+ m_base->traceZoomWidget->setDisplayLimits(traceno, zoomLimitsRect);
+ }
+}
+
+void SensorMonitorPart::updateGraticule() {
+ m_traceWidget->setNumberOfHorizontalDivisions(m_hdivs);
+ m_traceWidget->setNumberOfVerticalDivisions(m_vdivs);
+ m_base->traceZoomWidget->setNumberOfHorizontalDivisions(m_hdivs);
+ m_base->traceZoomWidget->setNumberOfVerticalDivisions(m_vdivs);
+
+ if (m_maxNumberOfTraces > 0) m_traceWidget->setTraceColor(0, TQColor(255, 255, 255));
+ if (m_maxNumberOfTraces > 1) m_traceWidget->setTraceColor(1, TQColor(128, 255, 128));
+ if (m_maxNumberOfTraces > 2) m_traceWidget->setTraceColor(2, TQColor(255, 255, 128));
+ if (m_maxNumberOfTraces > 3) m_traceWidget->setTraceColor(3, TQColor(128, 128, 255));
+
+ if (m_maxNumberOfTraces > 0) m_base->traceZoomWidget->setTraceColor(0, TQColor(255, 255, 255));
+ if (m_maxNumberOfTraces > 1) m_base->traceZoomWidget->setTraceColor(1, TQColor(128, 255, 128));
+ if (m_maxNumberOfTraces > 2) m_base->traceZoomWidget->setTraceColor(2, TQColor(255, 255, 128));
+ if (m_maxNumberOfTraces > 3) m_base->traceZoomWidget->setTraceColor(3, TQColor(128, 128, 255));
+
+ for (int traceno=0; traceno<m_maxNumberOfTraces; traceno++) {
+ m_traceWidget->setTraceEnabled(traceno, m_channelActive[traceno]);
+ m_traceWidget->setTraceName(traceno, m_sensorList[traceno].name);
+ m_traceWidget->setTraceHorizontalUnits(traceno, "s");
+ m_traceWidget->setTraceVerticalUnits(traceno, m_sensorList[traceno].units);
+
+ m_base->traceZoomWidget->setTraceEnabled(traceno, m_channelActive[traceno], false);
+ m_base->traceZoomWidget->setTraceName(traceno, m_sensorList[traceno].name);
+ m_base->traceZoomWidget->setTraceHorizontalUnits(traceno, "s");
+ m_base->traceZoomWidget->setTraceVerticalUnits(traceno, m_sensorList[traceno].units);
+
+ m_traceWidget->setNumberOfSamples(traceno, m_samplesInTrace[traceno]);
+ m_base->traceZoomWidget->setNumberOfSamples(traceno, m_samplesInTrace[traceno]);
+
+ double starttime = 0.0;
+ double endtime = 0.0;
+ if (m_samplesInTrace[traceno] > 0) {
+ starttime = m_traceWidget->positions(traceno)[0];
+ endtime = m_traceWidget->positions(traceno)[m_samplesInTrace[traceno]-1];
+ }
+ m_traceWidget->setDisplayLimits(traceno, TQRectF(starttime, m_sensorList[traceno].max, endtime, m_sensorList[traceno].min));
+ if (m_traceControlWidgetList[traceno]) {
+ m_traceControlWidgetList[traceno]->setTraceEnabled(m_channelActive[traceno]);
+ }
+ }
+ updateZoomWidgetLimits(m_traceWidget->zoomBox());
+}
+
+void SensorMonitorPart::updateTraceControlWidgets() {
+ // Add or remove trace control widgets as needed...
+ int i;
+ for (i=0; i<m_maxNumberOfTraces;i++) {
+ if (!m_traceControlWidgetList[i]) {
+ m_traceControlWidgetList[i] = new TraceControlWidget(m_base->traceControlLayoutWidget);
+ connect(m_traceControlWidgetList[i], SIGNAL(enableChanged(bool)), this, SLOT(traceControlEnableChanged(bool)));
+ connect(m_traceControlWidgetList[i], SIGNAL(newSampleDesired()), this, SLOT(processNewSampleRequest()));
+ m_traceControlWidgetGrid->addMultiCellWidget(m_traceControlWidgetList[i], i, i, 0, 0);
+ m_traceControlWidgetList[i]->setTraceName(m_sensorList[i].name);
+ m_traceControlWidgetList[i]->show();
+ // Set sample rate
+ m_traceControlWidgetList[i]->setMinTimestep(m_sensorList[i].mininterval);
+ m_traceControlWidgetList[i]->setTimestep(m_sensorList[i].nominalinterval);
+ }
+ }
+ for (i=m_maxNumberOfTraces; i<MAXTRACES;i++) {
+ if (m_traceControlWidgetList[i]) {
+ m_traceControlWidgetGrid->remove(m_traceControlWidgetList[i]);
+ delete m_traceControlWidgetList[i];
+ }
+ }
+}
+
+void SensorMonitorPart::traceControlEnableChanged(bool enabled) {
+ int i;
+ int channel = -1;
+ const TraceControlWidget* widget = dynamic_cast<const TraceControlWidget*>(sender());
+ if (widget) {
+ for (i=0; i<MAXTRACES;i++) {
+ if (m_traceControlWidgetList[i] == widget) {
+ channel = i;
+ break;
+ }
+ }
+ if ((channel >= 0) && (channel <=MAXTRACES)) {
+ m_channelActive[channel] = enabled;
+ }
+ }
+
+ updateGraticule();
+ m_traceWidget->repaint(false);
+ m_base->traceZoomWidget->repaint(false);
+ updateTraceControlWidgets();
+}
+
+void SensorMonitorPart::processNewSampleRequest() {
+ int i;
+ int channel = -1;
+ const TraceControlWidget* widget = dynamic_cast<const TraceControlWidget*>(sender());
+ if (widget) {
+ for (i=0; i<MAXTRACES;i++) {
+ if (m_traceControlWidgetList[i] == widget) {
+ channel = i;
+ break;
+ }
+ }
+ if ((channel >= 0) && (channel <=MAXTRACES)) {
+ if (!stopTraceUpdate) {
+ if (!m_sampleRequestInProgress[channel]) {
+ m_sampleRequestInProgress[channel] = true;
+ processNewSampleRequest(channel);
+ }
+ else {
+ printf("[WARNING] Sample request made while previous sample not collected. Some data was not captured (therefore lost)...\n\r");
+ }
+ }
+ }
+ }
+}
+
+void SensorMonitorPart::processNewSampleRequest(int channel) {
+ TQValueTimer* senderTimer = const_cast<TQValueTimer*>(dynamic_cast<const TQValueTimer*>(sender()));
+ if (senderTimer) {
+ senderTimer->stop();
+ delete senderTimer;
+ }
+ if (m_commHandlerMode == ModeIdle) {
+ // Request a sample
+ if (m_commHandlerState == ModeIdle_StateDelay) {
+ m_commHandlerMode = ModeGetSample;
+ m_commHandlerState = ModeGetSample_StateSampleRequest;
+ EXEC_NEXT_STATE_IMMEDIATELY
+ }
+ else {
+ m_commHandlerMode = ModeInterruptRequested;
+ m_commHandlerNextState = ModeGetSample_StateSampleRequest;
+ }
+ m_sampleRequestIndex = channel;
+ }
+ else {
+ // The main loop is already getting a sample
+ // Resubmit the request later on
+ TQValueTimer* timer = new TQValueTimer;
+ timer->setValue(channel);
+ connect(timer, SIGNAL(valueTimeout(int)), this, SLOT(processNewSampleRequest(int)));
+ timer->start(10, TRUE);
+ }
+}
+
+void SensorMonitorPart::acquisitionStartButtonClicked() {
+ stopTraceUpdate = false;
+ processLockouts();
+ if (m_socket) m_socket->clearIncomingData();
+ m_commHandlerMode = ModeIdle;
+ m_commHandlerState = ModeIdle_StateStatusRequest;
+ EXEC_NEXT_STATE_IMMEDIATELY
+}
+
+void SensorMonitorPart::acquisitionStopButtonClicked() {
+ stopTraceUpdate = true;
+ processLockouts();
+ for (int i=0; i<MAXTRACES;i++) {
+ m_sampleRequestInProgress[i] = false;
+ }
+ m_commHandlerMode = ModeIdle;
+ m_commHandlerState = ModeIdle_StatePaused;
+ setStatusMessage(i18n("Acquisition stopped"));
+ mainEventLoop();
+}
+
KAboutData* SensorMonitorPart::createAboutData() {
return new KAboutData( APP_NAME, I18N_NOOP( APP_PRETTYNAME ), APP_VERSION );
}
diff --git a/clients/tde/src/part/sensormonitor/part.h b/clients/tde/src/part/sensormonitor/part.h
index a6c176c..27b40a5 100644
--- a/clients/tde/src/part/sensormonitor/part.h
+++ b/clients/tde/src/part/sensormonitor/part.h
@@ -33,21 +33,83 @@
#include <kparts/statusbarextension.h>
#include <kparts/part.h>
#include <kurl.h>
-#include <kled.h>
#include <tqtrla.h>
+#include "floatspinbox.h"
+
+#define MAXTRACES 255
+
class KAboutData;
using KParts::StatusBarExtension;
class TraceWidget;
class TQSocket;
class TQTimer;
class TQMutex;
+class TQRectF;
+class TQGridLayout;
+class TQCheckBox;
+class TQGroupBox;
class TQFile;
class SensorMonitorBase;
namespace RemoteLab
{
+ class Q_EXPORT TQValueTimer : public TQTimer
+ {
+ Q_OBJECT
+
+ public:
+ TQValueTimer(TQObject *parent=0, const char *name=0);
+ ~TQValueTimer();
+ int value();
+ void setValue(int);
+
+ signals:
+ void valueTimeout(int);
+
+ private slots:
+ void timeoutHandler();
+
+ private:
+ int m_value;
+ };
+
+ class TraceControlWidget : public TQWidget
+ {
+ Q_OBJECT
+
+ public:
+ TraceControlWidget(TQWidget *parent=0, const char *name=0);
+ ~TraceControlWidget();
+
+ public:
+ void setTraceEnabled(bool enabled);
+ void setTraceName(TQString name);
+ void setTimestep(double seconds);
+ void setMinTimestep(double seconds);
+ void startSampleTimer(int msecs);
+ void stopSampleTimer();
+
+ signals:
+ void enableChanged(bool enabled);
+ void newSampleDesired();
+
+ private slots:
+ void enableClicked();
+ void timestepChanged(double);
+
+ private:
+ TQGroupBox* m_groupBox;
+ TQGridLayout* m_primaryLayout;
+ TQCheckBox* m_channelEnabledCheckBox;
+ FloatSpinBox* m_timestepSpinBox;
+ TQTimer* m_sampleTimer;
+
+ double m_minimumTimeStep;
+ double m_nominalTimeStep;
+ };
+
class SensorMonitorPart : public KParts::RemoteInstrumentPart
{
Q_OBJECT
@@ -62,6 +124,7 @@ namespace RemoteLab
public slots:
virtual bool openURL(const KURL &url);
+ void updateZoomWidgetLimits(const TQRectF& zoomRect);
private slots:
void postInit();
@@ -73,9 +136,19 @@ namespace RemoteLab
void disconnectFromServerCallback();
void connectionStatusChangedCallback();
void setTickerMessage(TQString message);
+
+ void updateGraticule();
+ void updateTraceControlWidgets();
+ void traceControlEnableChanged(bool enabled);
+ void processNewSampleRequest();
+ void processNewSampleRequest(int channel);
+ void acquisitionStartButtonClicked();
+ void acquisitionStopButtonClicked();
private:
SensorMonitorBase* m_base;
+ TraceWidget* m_traceWidget;
+ TQGridLayout* m_traceControlWidgetGrid;
TQMutex* m_connectionMutex;
TQTimer* m_pingDelayTimer;
TQTimer* m_forcedUpdateTimer;
@@ -87,9 +160,18 @@ namespace RemoteLab
int m_commHandlerNextMode;
bool m_connectionActiveAndValid;
unsigned char m_tickerState;
- TQByteArray m_programmingFileData;
- TQ_ULONG m_programmingFileTotalSize;
- TQ_ULONG m_programmingFileTransferredBytes;
+
+ bool stopTraceUpdate;
+ SensorList m_sensorList;
+ TQ_INT16 m_maxNumberOfTraces;
+ TQ_INT16 m_hdivs;
+ TQ_INT16 m_vdivs;
+ TQ_INT32 m_samplesInTrace[MAXTRACES+1];
+ bool m_channelActive[MAXTRACES+1];
+ TQString m_traceUnits[MAXTRACES+1];
+ TraceControlWidget* m_traceControlWidgetList[MAXTRACES];
+ TQ_UINT32 m_sampleRequestIndex;
+ bool m_sampleRequestInProgress[MAXTRACES+1];
};
}