|
@@ -791,10 +791,251 @@ void DataqSdkDeviceConfWidget::addChannel()
|
791
|
791
|
insertChildNode(tr("Channel"), "dataqsdkchannel");
|
792
|
792
|
}
|
793
|
793
|
|
|
794
|
+@ Channel configuration requires a slightly more complex configuration than
|
|
795
|
+it does on other devices. As these devices can be used for both temperature and
|
|
796
|
+non-temperature measurements the channel requires both the column name for the
|
|
797
|
+measurement series and the unit that the measurements will eventually be
|
|
798
|
+transformed into. The output of each channel will likely need to be run through
|
|
799
|
+a |LinearCalibrator| so the lower and upper values for both the measured and
|
|
800
|
+the mapped ranges are set here. It is also necessary to know if that interval
|
|
801
|
+is open or closed, if adaptive smoothing should be enabled on that channel, and
|
|
802
|
+how much precision the measurements should be presented with. In addition to
|
|
803
|
+the controls for setting these values, there should be a panel that assists in
|
|
804
|
+determining appropriate values by connecting to the device, collecting
|
|
805
|
+measurements on the channel, and showing how those measurements are presented
|
|
806
|
+with the current settings.
|
|
807
|
+
|
|
808
|
+@<Class declarations@>=
|
|
809
|
+class DataqSdkChannelConfWidget : public BasicDeviceConfigurationWidget
|
|
810
|
+{
|
|
811
|
+ Q_OBJECT
|
|
812
|
+ public:
|
|
813
|
+ Q_INVOKABLE DataqSdkChannelConfWidget(DeviceTreeModel *model,
|
|
814
|
+ const QModelIndex &index);
|
|
815
|
+ private slots:
|
|
816
|
+ void updateUnits(const QString &unit);
|
|
817
|
+ void updateColumnName(const QString &value);
|
|
818
|
+ void updateMeasuredLower(const QString &value);
|
|
819
|
+ void updateMeasuredUpper(const QString &value);
|
|
820
|
+ void updateMappedLower(const QString &value);
|
|
821
|
+ void updateMappedUpper(const QString &value);
|
|
822
|
+ void updateClosedInterval(bool closed);
|
|
823
|
+ void updateSmoothingEnabled(bool enabled);
|
|
824
|
+ void updateSensitivity(const QString &value);
|
|
825
|
+ void startCalibration();
|
|
826
|
+ void stopCalibration();
|
|
827
|
+ void resetCalibration();
|
|
828
|
+};
|
|
829
|
+
|
|
830
|
+@ The constructor sets up the interface. Calibration settings line edits need
|
|
831
|
+to have numeric validators added.
|
|
832
|
+
|
|
833
|
+@<DataqSdkDeviceConfWidget implementation@>=
|
|
834
|
+DataqSdkChannelConfWidget::DataqSdkChannelConfWidget(DeviceTreeModel *model,
|
|
835
|
+ const QModelIndex &index)
|
|
836
|
+ : BasicDeviceConfigurationWidget(model, index)
|
|
837
|
+{
|
|
838
|
+ QVBoxLayout *layout = new QVBoxLayout;
|
|
839
|
+ QFormLayout *topLayout = new QFormLayout;
|
|
840
|
+ QLineEdit *columnEdit = new QLineEdit;
|
|
841
|
+ topLayout->addRow(tr("Column name"), columnEdit);
|
|
842
|
+ QComboBox *unitSelector = new QComboBox;
|
|
843
|
+ unitSelector->addItem(tr("Temperature"));
|
|
844
|
+ unitSelector->addItem(tr("Control"));
|
|
845
|
+ topLayout->addRow(tr("Measurement type"), unitSelector);
|
|
846
|
+ QCheckBox *smoothingBox = new QCheckBox(tr("Enable smoothing"));
|
|
847
|
+ topLayout->addRow(smoothingBox);
|
|
848
|
+ layout->addLayout(topLayout);
|
|
849
|
+ QLabel *calibrationLabel = new QLabel(tr("Calibration settings"));
|
|
850
|
+ layout->addWidget(calibrationLabel);
|
|
851
|
+ QFormLayout *calibrationControlsLayout = new QFormLayout;
|
|
852
|
+ QLineEdit *measuredLowerEdit = new QLineEdit;
|
|
853
|
+ measuredLowerEdit->setText("0");
|
|
854
|
+ QLineEdit *measuredUpperEdit = new QLineEdit;
|
|
855
|
+ measuredUpperEdit->setText("10");
|
|
856
|
+ QLineEdit *mappedLowerEdit = new QLineEdit;
|
|
857
|
+ mappedLowerEdit->setText("0");
|
|
858
|
+ QLineEdit *mappedUpperEdit = new QLineEdit;
|
|
859
|
+ mappedUpperEdit->setText("10");
|
|
860
|
+ calibrationControlsLayout->addRow(tr("Measured lower value"), measuredLowerEdit);
|
|
861
|
+ calibrationControlsLayout->addRow(tr("Mapped lower value"), mappedLowerEdit);
|
|
862
|
+ calibrationControlsLayout->addRow(tr("Measured upper value"), measuredUpperEdit);
|
|
863
|
+ calibrationControlsLayout->addRow(tr("Mapped upper value"), mappedUpperEdit);
|
|
864
|
+ QCheckBox *closedBox = new QCheckBox(tr("Closed range"));
|
|
865
|
+ calibrationControlsLayout->addRow(closedBox);
|
|
866
|
+ QLineEdit *sensitivityEdit = new QLineEdit;
|
|
867
|
+ sensitivityEdit->setText("0");
|
|
868
|
+ calibrationControlsLayout->addRow(tr("Discrete interval skip"), sensitivityEdit);
|
|
869
|
+ layout->addLayout(calibrationControlsLayout);
|
|
870
|
+
|
|
871
|
+ // Insert another panel to assist in determining proper calibration values.
|
|
872
|
+
|
|
873
|
+ @<Get device configuration data for current node@>@;
|
|
874
|
+ for(int i = 0; i < configData.size(); i++)
|
|
875
|
+ {
|
|
876
|
+ node = configData.at(i).toElement();
|
|
877
|
+ if(node.attribute("name") == "column")
|
|
878
|
+ {
|
|
879
|
+ columnEdit->setText(node.attribute("value"));
|
|
880
|
+ }
|
|
881
|
+ else if(node.attribute("name") == "type")
|
|
882
|
+ {
|
|
883
|
+ unitSelector->setCurrentIndex(unitSelector->findText(node.attribute("value")));
|
|
884
|
+ }
|
|
885
|
+ else if(node.attribute("name") == "smoothing")
|
|
886
|
+ {
|
|
887
|
+ smoothingBox->setChecked(node.attribute("value") == "true");
|
|
888
|
+ }
|
|
889
|
+ else if(node.attribute("name") == "calibrationMeasuredLower")
|
|
890
|
+ {
|
|
891
|
+ measuredLowerEdit->setText(node.attribute("value"));
|
|
892
|
+ }
|
|
893
|
+ else if(node.attribute("name") == "calibrationMeasuredUpper")
|
|
894
|
+ {
|
|
895
|
+ measuredUpperEdit->setText(node.attribute("value"));
|
|
896
|
+ }
|
|
897
|
+ else if(node.attribute("name") == "calibrationMappedLower")
|
|
898
|
+ {
|
|
899
|
+ mappedLowerEdit->setText(node.attribute("value"));
|
|
900
|
+ }
|
|
901
|
+ else if(node.attribute("name") == "calibrationMappedUpper")
|
|
902
|
+ {
|
|
903
|
+ mappedUpperEdit->setText(node.attribute("value"));
|
|
904
|
+ }
|
|
905
|
+ else if(node.attribute("name") == "calibrationClosedInterval")
|
|
906
|
+ {
|
|
907
|
+ closedBox->setChecked(node.attribute("value") == "true");
|
|
908
|
+ }
|
|
909
|
+ else if(node.attribute("name") == "calibrationSensitivity")
|
|
910
|
+ {
|
|
911
|
+ sensitivityEdit->setText(node.attribute("value"));
|
|
912
|
+ }
|
|
913
|
+ }
|
|
914
|
+ updateColumnName(columnEdit->text());
|
|
915
|
+ updateUnits(unitSelector->currentText());
|
|
916
|
+ updateSmoothingEnabled(smoothingBox->isChecked());
|
|
917
|
+ updateMeasuredLower(measuredLowerEdit->text());
|
|
918
|
+ updateMeasuredUpper(measuredUpperEdit->text());
|
|
919
|
+ updateMappedLower(mappedLowerEdit->text());
|
|
920
|
+ updateMappedUpper(mappedUpperEdit->text());
|
|
921
|
+ updateClosedInterval(closedBox->isChecked());
|
|
922
|
+ updateSensitivity(sensitivityEdit->text());
|
|
923
|
+ connect(columnEdit, SIGNAL(textChanged(QString)),
|
|
924
|
+ this, SLOT(updateColumnName(QString)));
|
|
925
|
+ connect(unitSelector, SIGNAL(currentIndexChanged(QString)),
|
|
926
|
+ this, SLOT(updateUnits(QString)));
|
|
927
|
+ connect(smoothingBox, SIGNAL(toggled(bool)),
|
|
928
|
+ this, SLOT(updateSmoothingEnabled(bool)));
|
|
929
|
+ connect(measuredLowerEdit, SIGNAL(textChanged(QString)),
|
|
930
|
+ this, SLOT(updateMeasuredLower(QString)));
|
|
931
|
+ connect(mappedLowerEdit, SIGNAL(tectChanged(QString)),
|
|
932
|
+ this, SLOT(updateMappedLower(QString)));
|
|
933
|
+ connect(measuredUpperEdit, SIGNAL(textChanged(QString)),
|
|
934
|
+ this, SLOT(updateMeasuredUpper(QString)));
|
|
935
|
+ connect(mappedUpperEdit, SIGNAL(textChanged(QString)),
|
|
936
|
+ this, SLOT(updateMappedUpper(QString)));
|
|
937
|
+ connect(closedBox, SIGNAL(toggled(bool)),
|
|
938
|
+ this, SLOT(updateClosedInterval(bool)));
|
|
939
|
+ connect(sensitivityEdit, SIGNAL(textChanged(QString)),
|
|
940
|
+ this, SLOT(updateSensitivity(QString)));
|
|
941
|
+ setLayout(layout);
|
|
942
|
+}
|
|
943
|
+
|
|
944
|
+@ We generate measurements with whatever unit will eventually be required to
|
|
945
|
+avoid the need for something that only exists to change one value of every
|
|
946
|
+measurement. At present we generate measurements either in Fahrenheit or as
|
|
947
|
+Unitless. It might not be a bad idea to have the calibration adjustment allow
|
|
948
|
+display of temperature measurements in Celsius.
|
|
949
|
+
|
|
950
|
+@<DataqSdkDeviceConfWidget implementation@>=
|
|
951
|
+void DataqSdkChannelConfWidget::updateUnits(const QString &unit)
|
|
952
|
+{
|
|
953
|
+ updateAttribute("type", unit);
|
|
954
|
+}
|
|
955
|
+
|
|
956
|
+@ Changing calibration settings requires both saving the settings and updating
|
|
957
|
+the |LinearCalibrator| used for calibration assistance.
|
|
958
|
+
|
|
959
|
+@<DataqSdkDeviceConfWidget implementation@>=
|
|
960
|
+void DataqSdkChannelConfWidget::updateMeasuredLower(const QString &value)
|
|
961
|
+{
|
|
962
|
+ updateAttribute("calibrationMeasuredLower", value);
|
|
963
|
+}
|
|
964
|
+
|
|
965
|
+void DataqSdkChannelConfWidget::updateMeasuredUpper(const QString &value)
|
|
966
|
+{
|
|
967
|
+ updateAttribute("calibrationMeasuredUpper", value);
|
|
968
|
+}
|
|
969
|
+
|
|
970
|
+void DataqSdkChannelConfWidget::updateMappedLower(const QString &value)
|
|
971
|
+{
|
|
972
|
+ updateAttribute("calibrationMappedLower", value);
|
|
973
|
+}
|
|
974
|
+
|
|
975
|
+void DataqSdkChannelConfWidget::updateMappedUpper(const QString &value)
|
|
976
|
+{
|
|
977
|
+ updateAttribute("calibrationMappedUpper", value);
|
|
978
|
+}
|
|
979
|
+
|
|
980
|
+void DataqSdkChannelConfWidget::updateClosedInterval(bool closed)
|
|
981
|
+{
|
|
982
|
+ updateAttribute("calibrationClosedInterval", closed ? "true" : "false");
|
|
983
|
+}
|
|
984
|
+
|
|
985
|
+void DataqSdkChannelConfWidget::updateSmoothingEnabled(bool enabled)
|
|
986
|
+{
|
|
987
|
+ updateAttribute("smoothing", enabled ? "true" : "false");
|
|
988
|
+}
|
|
989
|
+
|
|
990
|
+void DataqSdkChannelConfWidget::updateSensitivity(const QString &value)
|
|
991
|
+{
|
|
992
|
+ updateAttribute("calibrationSensitivity", value);
|
|
993
|
+}
|
|
994
|
+
|
|
995
|
+@ It must be possible to perform calibration operations with the hardware not
|
|
996
|
+connected. As such, the device should only be opened on request. Methods for
|
|
997
|
+opening and closing these connections to the hardware are provided.
|
|
998
|
+
|
|
999
|
+@<DataqSdkDeviceConfWidget implementation@>=
|
|
1000
|
+void DataqSdkChannelConfWidget::startCalibration()
|
|
1001
|
+{
|
|
1002
|
+
|
|
1003
|
+}
|
|
1004
|
+
|
|
1005
|
+void DataqSdkChannelConfWidget::stopCalibration()
|
|
1006
|
+{
|
|
1007
|
+
|
|
1008
|
+}
|
|
1009
|
+
|
|
1010
|
+@ When collecting calibration data it is useful to have a few types of
|
|
1011
|
+information. The most recent reported measurement is fine, but the hardware
|
|
1012
|
+supported here does not produce a constant value in response to a stable input,
|
|
1013
|
+making this less useful than it would be if that were not the case. Aggregate
|
|
1014
|
+data such as the minimum, maximum, and mean of measured values for a stable
|
|
1015
|
+input are useful to have, but it must be possible to reset these statistics for
|
|
1016
|
+convenient testing in multiple parts of the range.
|
|
1017
|
+
|
|
1018
|
+@<DataqSdkDeviceConfWidget implementation@>=
|
|
1019
|
+void DataqSdkChannelConfWidget::resetCalibration()
|
|
1020
|
+{
|
|
1021
|
+
|
|
1022
|
+}
|
|
1023
|
+
|
|
1024
|
+@ Column name is handled as usual.
|
|
1025
|
+
|
|
1026
|
+@<DataqSdkDeviceConfWidget implementation@>=
|
|
1027
|
+void DataqSdkChannelConfWidget::updateColumnName(const QString &value)
|
|
1028
|
+{
|
|
1029
|
+ updateAttribute("column", value);
|
|
1030
|
+}
|
|
1031
|
+
|
|
1032
|
+
|
794
|
1033
|
@ These configuration widgets are registered with the configuration system.
|
795
|
1034
|
|
796
|
1035
|
@<Register device configuration widgets@>=
|
797
|
1036
|
app.registerDeviceConfigurationWidget("dataqsdk", DataqSdkDeviceConfWidget::staticMetaObject);
|
|
1037
|
+app.registerDeviceConfigurationWidget("dataqsdkchannel",
|
|
1038
|
+ DataqSdkChannelConfWidget::staticMetaObject);
|
798
|
1039
|
|
799
|
1040
|
@ A |NodeInserter| is also added to provide access to
|
800
|
1041
|
|DataqSdkDeviceConfWidget|, but only on Windows.
|