diff --git a/.README.md.swp b/.README.md.swp new file mode 100644 index 0000000000000000000000000000000000000000..2b4e88a1f6b0cd589ec4a1f98fed36e44a984bc6 Binary files /dev/null and b/.README.md.swp differ diff --git a/InstrumentCluster/InstrumentCluster.pro b/InstrumentCluster/InstrumentCluster.pro new file mode 100644 index 0000000000000000000000000000000000000000..ccd93faa2fb995d6070ffa385e8f9e0c3c057c49 --- /dev/null +++ b/InstrumentCluster/InstrumentCluster.pro @@ -0,0 +1,34 @@ +QT += quick +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which as been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += main.cpp \ + contentsupplier.cpp + +RESOURCES += qml.qrc + +# Additional import path used to resolve QML modules in Qt Creator's code model +QML_IMPORT_PATH = + +# Additional import path used to resolve QML modules just for Qt Quick Designer +QML_DESIGNER_IMPORT_PATH = + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +HEADERS += \ + contentsupplier.h + +include(../Interface/Interface.pri) diff --git a/InstrumentCluster/contentsupplier.cpp b/InstrumentCluster/contentsupplier.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e794bcbdd46d02a4b8eaa02d2255388255a7d217 --- /dev/null +++ b/InstrumentCluster/contentsupplier.cpp @@ -0,0 +1,6 @@ +#include "contentsupplier.h" + +ContentSupplier::ContentSupplier(QObject *parent) : QObject(parent) +{ + +} diff --git a/InstrumentCluster/contentsupplier.h b/InstrumentCluster/contentsupplier.h new file mode 100644 index 0000000000000000000000000000000000000000..57669baba1781dc3b83fe6bab6778d9136b1641b --- /dev/null +++ b/InstrumentCluster/contentsupplier.h @@ -0,0 +1,29 @@ +#ifndef CONTENTSUPPLIER_H +#define CONTENTSUPPLIER_H + +#include <QObject> + +class ContentSupplier : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QPixmap bg READ bg NOTIFY bgChanged) + +public: + explicit ContentSupplier(QObject *parent = nullptr); + +signals: + +public slots: + + +private: + QMap<QString, iDriver*> _drivers; + QList<QThread*> _threads; + + QList<DriverInfo> _supportedDriversInfo; + QList<QPluginLoader*> _supportedDriversLoader; + +}; + +#endif // CONTENTSUPPLIER_H diff --git a/InstrumentCluster/main.cpp b/InstrumentCluster/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9e3ee52da6573c126cc1bf3fdd265f592be6c751 --- /dev/null +++ b/InstrumentCluster/main.cpp @@ -0,0 +1,22 @@ +#include <QGuiApplication> +#include <QQmlContext> +#include <QQmlApplicationEngine> +#include "contentsupplier.h" + +int main(int argc, char *argv[]) +{ + qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard")); + + QGuiApplication app(argc, argv); + + ContentSupplier* cs = new ContentSupplier(); + + QQmlApplicationEngine engine; + engine.rootContext()->setContextProperty("contentSupplier", QVariant::fromValue(cs)); + + engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} diff --git a/InstrumentCluster/main.qml b/InstrumentCluster/main.qml new file mode 100644 index 0000000000000000000000000000000000000000..5d9ec4d8cf14fa5392f68156cce5461d20d78e16 --- /dev/null +++ b/InstrumentCluster/main.qml @@ -0,0 +1,62 @@ +import QtQuick 2.8 +import QtQuick.Window 2.2 +import QtQuick.VirtualKeyboard 2.1 + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Hello World") + id: root + + MouseArea { + anchors.fill: parent + onClicked: { + console.log(qsTr('Clicked on background. Text: "' + textEdit.text + '"')) + } + } + + TextEdit { + id: textEdit + text: qsTr("Enter some text...") + verticalAlignment: Text.AlignVCenter + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + anchors.topMargin: 20 + Rectangle { + anchors.fill: parent + anchors.margins: -10 + color: "transparent" + border.width: 1 + } + } + + InputPanel { + id: inputPanel + z: 99 + x: 0 + y: root.height + width: root.width + + states: State { + name: "visible" + when: inputPanel.active + PropertyChanges { + target: inputPanel + y: root.height - inputPanel.height + } + } + transitions: Transition { + from: "" + to: "visible" + reversible: true + ParallelAnimation { + NumberAnimation { + properties: "y" + duration: 250 + easing.type: Easing.InOutQuad + } + } + } + } +} diff --git a/InstrumentCluster/qml.qrc b/InstrumentCluster/qml.qrc new file mode 100644 index 0000000000000000000000000000000000000000..e6ff3ecdac0c4b195f8485bbc184e73bca53b7ba --- /dev/null +++ b/InstrumentCluster/qml.qrc @@ -0,0 +1,6 @@ +<!DOCTYPE RCC> +<RCC version="1.0"> + <qresource prefix="/"> + <file>main.qml</file> + </qresource> +</RCC> diff --git a/Interface/Interface.pri b/Interface/Interface.pri new file mode 100644 index 0000000000000000000000000000000000000000..8daa5d285afcb22a4cee58e92189ce0a44acb53b --- /dev/null +++ b/Interface/Interface.pri @@ -0,0 +1,6 @@ +HEADERS += \ + $$PWD/iplugin.h \ + +INCLUDEPATH += $$PWD + +SOURCES += diff --git a/Interface/iplugin.h b/Interface/iplugin.h new file mode 100644 index 0000000000000000000000000000000000000000..8a0dd798a58be125dc6a6dce9193c684349d6f4c --- /dev/null +++ b/Interface/iplugin.h @@ -0,0 +1,23 @@ +#ifndef IDRIVER_H +#define IDRIVER_H +#include <QObject> + +class iPlugin : public QObject +{ + Q_OBJECT + +public: + explicit iPlugin(QObject *parent = 0):QObject(parent){} + virtual ~iPlugin(){} + +public slots: + QString property(const QString& name) const=0; + + QImage snapShot(void) const=0; + + +}; + +Q_DECLARE_INTERFACE(iPlugin, "iPlugin_iid") + +#endif // IDRIVER_H diff --git a/README.md b/README.md index c11adb1a3ef7e5520576d87cc9a921f04ab90df4..8e62d08269772486aa6344db9f9ffd894a91a1a9 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Experimental scene changing framework for cluster, with Qt5.10. # Detail 1. Scan dynamic scene plugins when start up. -2. Scene selector with brief previews. +2. Scene selector, with brief previews. 3. Dynamic add/remove qt resource collection files. 4. It will apply to every visual related components, including start-up transitions. 5. Cluster will store selected scene, and will load it after power on. diff --git a/SceneChangingFramwork.pro b/SceneChangingFramwork.pro new file mode 100644 index 0000000000000000000000000000000000000000..07cb701512c7ce50941a0d144da2c86324843004 --- /dev/null +++ b/SceneChangingFramwork.pro @@ -0,0 +1,4 @@ +TEMPLATE = subdirs + +SUBDIRS += InstrumentCluster +SUBDIRS += ScenePlugin diff --git a/ScenePlugin/Archermind/Archermind.pro b/ScenePlugin/Archermind/Archermind.pro new file mode 100644 index 0000000000000000000000000000000000000000..0f5d8284a762d78f714971229d73b49f58be8ad2 --- /dev/null +++ b/ScenePlugin/Archermind/Archermind.pro @@ -0,0 +1,19 @@ +QT+= network widgets + +TEMPLATE = lib +CONFIG += plugin +TARGET = $$qtLibraryTarget(ArchermindScene) +DESTDIR = ../../scenePlugin + +CONFIG += c++11 + +INCLUDEPATH += $$PWD\ + +HEADERS += \ + $$PWD/udpdatabaseprotocoldriver.h + +SOURCES += \ + $$PWD/udpdatabaseprotocoldriver.cpp + +#interface: +include(../../Interface/Interface.pri) diff --git a/ScenePlugin/Archermind/udpdatabaseProtocol.json b/ScenePlugin/Archermind/udpdatabaseProtocol.json new file mode 100644 index 0000000000000000000000000000000000000000..0967ef424bce6791893e9a57bb952f80fd536e93 --- /dev/null +++ b/ScenePlugin/Archermind/udpdatabaseProtocol.json @@ -0,0 +1 @@ +{} diff --git a/ScenePlugin/Archermind/udpdatabaseprotocoldriver.cpp b/ScenePlugin/Archermind/udpdatabaseprotocoldriver.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7a998608f28c54429674f336d6771758a341f1c6 --- /dev/null +++ b/ScenePlugin/Archermind/udpdatabaseprotocoldriver.cpp @@ -0,0 +1,388 @@ +#if _MSC_VER >= 1600 +#pragma execution_character_set("utf-8") +#endif +#include <QDateTime> +#include <QHostAddress> +#include "udpdatabaseprotocoldriverui.h" +#include "udpdatabaseprotocoldriver.h" +#include "loadsaveprocessorxml.h" + +UdpDatabaseProtocolDriver::UdpDatabaseProtocolDriver(QObject *parent) : iDriver(parent), + _udpdatabaseAddress( QHostAddress("127.0.0.1")), + _stationID(0xFA), + _port(5656), + _pUdpSocket(nullptr), + _pUI(nullptr), + _pWatchDogTimer(nullptr), + _scheduleTimer(nullptr) +{ + //default + if(QNetworkInterface::allInterfaces().size() == 0){ + emit msgEventString(tr("电脑上找ä¸åˆ°ç½‘å¡") ); + } + else{ + _networkInterface = QNetworkInterface::allInterfaces().at(0); + } + + + _setState(STAT_STOP); +} +UdpDatabaseProtocolDriver::~UdpDatabaseProtocolDriver(){ + stop(); + if(_pUdpSocket!=nullptr){ + _pUdpSocket->deleteLater(); + } + if(_pUI != nullptr){ + _pUI->deleteLater(); + } +} + +DriverInfo UdpDatabaseProtocolDriver::driverInfo()const{ + DriverInfo info; + info.driverType = "UdpDatabase Protocol"; + info.driverManufacturer = "CSIC711"; + info.description = "UdpDatabase Protocol for data acquisition\nDate:2017.9"; + info.majorVersion = QString::number(0); + info.minorVersion = QString::number(0); + info.microVersion = QString::number(1); + return info; +} + +void UdpDatabaseProtocolDriver::save(iLoadSaveProcessor* processor){ + processor->writeValue("udpdatabaseAddress",_udpdatabaseAddress); + processor->writeValue("port",_port); + QString networkInterfaceName = _networkInterface.name(); + processor->writeValue("networkInterface", networkInterfaceName ); +} + +void UdpDatabaseProtocolDriver::load(iLoadSaveProcessor* processor){ + processor->readValue("udpdatabaseAddress",_udpdatabaseAddress); + processor->readValue("port",_port); + QList<QNetworkInterface> allInterfaces = QNetworkInterface::allInterfaces(); + if(allInterfaces.size() == 0){ + emit msgEventString(tr("电脑上找ä¸åˆ°ç½‘å¡") ); + return; + } + QString networkInterfaceName; + processor->readValue("networkInterface", networkInterfaceName ); + bool foundInterface = false; + foreach (QNetworkInterface iface, allInterfaces) { + if(iface.name() == networkInterfaceName){ + foundInterface = true; + _networkInterface = iface; + break; + } + } + if(!foundInterface){ + emit msgEventString(tr("电脑上找ä¸åˆ°å为“%1â€çš„网å¡").arg(networkInterfaceName) ); + _networkInterface = allInterfaces.at(0); + } + if(state() == STAT_RUN){ + restart(); + } +} + +void UdpDatabaseProtocolDriver::_watchDogTimeOver(){ + emit msgEventString(tr("超时错误,长时间未收到数æ®") ); + _setState(STAT_ERR); +} + +int UdpDatabaseProtocolDriver::start(){ + if(_state!=iDriver::STAT_STOP) return-1; + if(_pUdpSocket != nullptr){ + _pUdpSocket->close(); + _pUdpSocket->deleteLater(); + } + else{ + _pUdpSocket = new QUdpSocket(this); + bool ret = _pUdpSocket->bind(_port, QUdpSocket::ShareAddress); + if(!ret){ + _setState( STAT_STOP ); + emit msgEventString(tr("å¯åŠ¨å¤±è´¥ï¼ç½‘络监å¬å¤±è´¥ï¼Œæ£€æŸ¥ç½‘络状æ€ï¼é”™è¯¯æè¿°ï¼š%1").arg(_pUdpSocket->errorString() ) ); + return -1; + } + else{ + connect(_pUdpSocket, SIGNAL(readyRead()), this, SLOT(_processPendingDatagrams())); + } + } + if(_pWatchDogTimer!=nullptr){ + _pWatchDogTimer->stop(); + _pWatchDogTimer->deleteLater(); + }else{ + _pWatchDogTimer = new QTimer(this); + _pWatchDogTimer->setSingleShot(true); + _pWatchDogTimer->setInterval(100 * 1000); + connect(_pWatchDogTimer,SIGNAL(timeout()),this,SLOT(_watchDogTimeOver())); + _pWatchDogTimer->start(); + } + if(_scheduleTimer!=nullptr){ + _scheduleTimer->stop(); + _scheduleTimer->deleteLater(); + }else{ + _scheduleTimer = new QTimer(this); + _scheduleTimer->setSingleShot(false); + _scheduleTimer->setInterval(500); + connect(_scheduleTimer,&QTimer::timeout,this,&UdpDatabaseProtocolDriver::_scheduleProcess); + _scheduleTimer->start(); + } + + _setState(STAT_RUN); + emit msgEventString(tr("å¯åЍæˆåŠŸï¼") ); + return 0; + +// if(_pUdpSocket != nullptr){ +// _pUdpSocket->close(); +// _pUdpSocket->deleteLater(); +// } +// else{ + +// _pUdpSocket = new QUdpSocket(this); +// ret = _pUdpSocket->bind(_port, QUdpSocket::ShareAddress); +// if(!ret){ +// _setState( STAT_STOP ); +// emit msgEventString(tr("å¯åŠ¨å¤±è´¥ï¼ç½‘络监å¬å¤±è´¥ï¼Œæ£€æŸ¥ç½‘络状æ€ï¼é”™è¯¯æè¿°ï¼š%1").arg(_pUdpSocket->errorString() ) ); +// return -1; +// } +// else{ +// connect(_pUdpSocket, SIGNAL(readyRead()), this, SLOT(_processPendingDatagrams())); +// _setState(STAT_RUN); +// emit msgEventString(tr("å¯åЍæˆåŠŸï¼") ); +// return 0; +// } +// } +} + +int UdpDatabaseProtocolDriver::stop(){ + if(_scheduleTimer!=nullptr){ + _scheduleTimer->stop(); + _scheduleTimer->deleteLater(); + _scheduleTimer=nullptr; + } + if(_pWatchDogTimer!=nullptr){ + _pWatchDogTimer->stop(); + _pWatchDogTimer->deleteLater(); + _pWatchDogTimer=nullptr; + } + if(_pUdpSocket != nullptr){ + _pUdpSocket->close(); + _pUdpSocket->deleteLater(); + _pUdpSocket=nullptr; + _setState(STAT_STOP); + emit msgEventString(tr("åœæ¢æˆåŠŸï¼") ); + } + return 0; +} + +int UdpDatabaseProtocolDriver::restart(){ + stop(); + return start(); +} + +QList<int> UdpDatabaseProtocolDriver::availableRWStrategy(void)const{ + QList<int> ret; + ret<<iTagInfo::RWS_DISABLE<<iTagInfo::RWS_WRITE_ONLY; + return ret; +} + +QList<int> UdpDatabaseProtocolDriver::availableRWStrategy(const QString& addr)const{ + QList<int> ret; + ret<<iTagInfo::RWS_DISABLE; + if(isAddressCorrect(addr)) + ret<<iTagInfo::RWS_WRITE_ONLY; + return ret; +} + +bool UdpDatabaseProtocolDriver::isAddressCorrect(const QString& addr)const{ + bool ret; + addr.toUInt(&ret,16); + return ret; +} + +QString UdpDatabaseProtocolDriver::addressErrorString(const QString& addr) const{ + if(isAddressCorrect(addr)){ + return QString(); + } + return tr("地å€å¿…须是å进制数å—ï¼"); +} + +int UdpDatabaseProtocolDriver::setUdpDatabaseAddress(const QHostAddress& hostaddr, qint16 hostport,qint16 localport){ + //if( addr.isUdpDatabase() ){ + // if(addr != _udpdatabaseAddress ){ + //_udpdatabaseAddress = addr; + _hostAddress = hostaddr; + _hostPort = hostport; + _port = localport; + // } + return 0; + //} +} +int UdpDatabaseProtocolDriver::setSMDERIMStation(qint16 station){ + if(station < 0 || station >255){ + emit msgEventString(tr("输入错误:StationID超出范围ï¼") ); + return -1; + } + else{ + _stationID = station; + return 0; + } +} + +int UdpDatabaseProtocolDriver::setNetworkInterface(const QNetworkInterface& networkInterface){ + if(networkInterface.isValid()){ + //if(networkInterface.flags().testFlag(QNetworkInterface::CanUdpDatabase) ){ + _networkInterface = networkInterface; + return 0; + //} + } + emit msgEventString(tr("设置失败。没有组æ’åŠŸèƒ½æˆ–æ— æ•ˆåœ°å€ï¼") ); + return -1; +} + +QString UdpDatabaseProtocolDriver::udpdatabaseAddress(void)const{ + return _udpdatabaseAddress.toString(); +} + +int UdpDatabaseProtocolDriver::udpdatabasePort(void)const{ + return _port; +} + +QNetworkInterface& UdpDatabaseProtocolDriver::networkInterface(void){ + return _networkInterface; +} + +int UdpDatabaseProtocolDriver::setRelatedTagAddresses(const QList<TagAddress *>& relatedTagAddresses){ + int count =0; + _relatedTags.clear(); + foreach (TagAddress* it, relatedTagAddresses) { + if(it->RWStrategy == iTagInfo::RWS_WRITE_ONLY){ + _relatedTags<<it; + count++; + } + } + qSort(_relatedTags.begin(), _relatedTags.end(), compareTagAddress); + return count; +} + +void UdpDatabaseProtocolDriver::showUI(bool show, QWidget *parent){ + if(_pUI == nullptr){ + _pUI = new UdpDatabaseProtocolDriverUI(this, parent); + } + if(show){ + _pUI->show(); + }else{ + _pUI->hide(); + } +} +void UdpDatabaseProtocolDriver::_scheduleProcess() +{ + QByteArray datagram; + int i = 0; + qint16 dmh = 0; + qint32 temp; + char*temp1; + if(_state != STAT_RUN) return; + datagram.clear(); + + datagram[0] = 0x53; + datagram[1] = 0x03; + datagram[2] = _stationID; + datagram[3] = 0x00; + datagram[4] = 0x00; + i = 5; + if(_relatedTags.size()!=0 && _hostAddress != nullptr){ + //prepare data + foreach(TagAddress* t, _relatedTags){ + if(t->RWStrategy == iTagInfo::RWS_DISABLE) continue; + if(t->RWStrategy == iTagInfo::RWS_READ_ONLY) continue; + if(t->RWStrategy == iTagInfo::RWS_READ_WRITE) continue; + + temp = t->address.toUInt(nullptr,16); + temp1 = (char*)&temp; + datagram.append(*(temp1+3)); + datagram.append(*(temp1+2)); + datagram.append(*(temp1+1)); + datagram.append(*(temp1+0)); + switch (t->tagInfo->type()) { + case iTagInfo::TYPE_INT32: + datagram.append(char(0x04)); + datagram.append(char(0x00)); + //datagram.append(0x00);//quality byte:0-ok,1-error; + temp =t->tagInfo->value().toUInt(); + temp1 =(char*)&temp; + datagram.append(*(temp1+3)); + datagram.append(*(temp1+2)); + datagram.append(*(temp1+1)); + datagram.append(*(temp1+0)); + break; + case iTagInfo::TYPE_INT16: + datagram.append(char(0x02)); + datagram.append(char(0x00)); + //datagram.append(0x00);//quality byte:0-ok,1-error; + temp =t->tagInfo->value().toUInt(); + temp1 =(char*)&temp; + datagram.append(*(temp1+1)); + datagram.append(*(temp1+0)); + break; + default: + break; + } + } + qint16 len = datagram.size() - 3; + datagram[3] = (len & 0xff00)>>8; + datagram[4] = len & 0xff; + for(int i=1;i<len;i++) { + dmh += datagram[i]; + } + + datagram.append(dmh & 0xff).append((dmh & 0xff00)>>8); + datagram.append(char(0x0D)); + //write data + _pUdpSocket->writeDatagram(datagram.data(),datagram.size(),_hostAddress,_hostPort); + } +} + +void UdpDatabaseProtocolDriver::_processPendingDatagrams() +{ + while (_pUdpSocket->hasPendingDatagrams()) { + emit dataReceived();//accept per UDP package + QByteArray datagram; + datagram.resize(_pUdpSocket->pendingDatagramSize()); + int count = _pUdpSocket->readDatagram(datagram.data(),datagram.size(),&_hostAddress,&_hostPort);//,&_hostAddress,&_hostPort + + if ((datagram[0] == 0x53) + && (count >= 7) + && (datagram[count - 1] == 0x0D)){ + switch (datagram[1]) { + case 1: + _pUdpSocket->writeDatagram(datagram.data(),datagram.size(),_hostAddress,_hostPort); + _pWatchDogTimer->start(); + + break; + default: + break; + } + } + + } +} + +void UdpDatabaseProtocolDriver::_setState(enum_states state){ + if(state != _state){ + _state = state; + emit stateChanged(state); + } +} + +bool UdpDatabaseProtocolDriver::_getTime(QDateTime& t, int year, int month, int day, int hour, int minute, int second, int millisecond){ + if(!QDate::isValid(year,month,day)) + return false; + if(!QTime::isValid(hour,minute,second,millisecond)) + return false; + t.setDate( QDate(year,month,day) ); + t.setTime( QTime(hour,minute,second,millisecond) ); + return true; +} + +bool UdpDatabaseProtocolDriver::compareTagAddress(const TagAddress *t1, const TagAddress *t2){ + return t1->address < t2->address; +} diff --git a/ScenePlugin/Archermind/udpdatabaseprotocoldriver.h b/ScenePlugin/Archermind/udpdatabaseprotocoldriver.h new file mode 100644 index 0000000000000000000000000000000000000000..76145cfc67d7161df746d43e4aa6e46f6d6b6f95 --- /dev/null +++ b/ScenePlugin/Archermind/udpdatabaseprotocoldriver.h @@ -0,0 +1,110 @@ +#ifndef UDPDATABASEPROTOCOLDRIVER_H +#define UDPDATABASEPROTOCOLDRIVER_H + +#include <QObject> +#include <QTimer> +#include <QtNetwork> +#include <QtNetwork/QUdpSocket> +#include "iplugin.h" + +class QUdpSocket; +class QHostAddress; +class UdpDatabaseProtocolDriverUI; + +class UdpDatabaseProtocolDriver : public iDriver +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "com.csic711.appServer.drivers.udpdatabaseProtocol" FILE "udpdatabaseProtocol.json") + Q_INTERFACES(iDriver) +public: + /*! + * æž„é€ å‡½æ•° + * 功能æè¿°ï¼š + * 1ã€åˆå§‹åŒ–傿•° + * 2ã€è¿›å…¥åœæ¢çŠ¶æ€ + */ + explicit UdpDatabaseProtocolDriver(QObject *parent = 0); + ~UdpDatabaseProtocolDriver(); + +public slots: + DriverInfo driverInfo()const override; + void save(iLoadSaveProcessor* processor) override; + void load(iLoadSaveProcessor* processor) override; + int start() override; + int stop() override; + int restart() override; + int state() override{ return _state; } + QList<int> availableRWStrategy(void)const override; + QList<int> availableRWStrategy(const QString& addr)const override; + bool isAddressCorrect(const QString& addr)const override; + QString addressErrorString(const QString& addr)const override; + int setRelatedTagAddresses(const QList<TagAddress *>& relatedTagAddresses) override; + void showUI(bool show=true, QWidget* parent=0) override; + + +public slots: + /*! + * 设置组æ’çš„Addresså’ŒPort + * 返回数值:0:æˆåŠŸ -1:失败 + * 功能æè¿°ï¼š + * 1ã€å¦‚果是组æ’的地å€åˆ™æˆåŠŸï¼Œå¦åˆ™å¤±è´¥ + */ + int setUdpDatabaseAddress(const QHostAddress& hostaddr, qint16 hostport,qint16 localport); + + /*! + * 设置组æ’çš„ç½‘å¡æŽ¥å£ + * 返回数值:0:æˆåŠŸ -1:失败 + * 功能æè¿°ï¼š + * 1ã€å¦‚果是组æ’çš„ç½‘å¡æŽ¥å£åˆ™æˆåŠŸï¼Œå¦åˆ™å¤±è´¥ + */ + int setNetworkInterface(const QNetworkInterface& networkInterface); + /*! + * 设置站å·-csic711定制 + * 返回数值:0:æˆåŠŸ -1:失败 + * 功能æè¿°ï¼š + * ç«™å·èŒƒå›´ï¼š1-255 + */ + int setSMDERIMStation(qint16 station); + + QString udpdatabaseAddress(void)const; + int udpdatabasePort(void)const; + QNetworkInterface& networkInterface(void); + +signals: + void msgEventString(const QString& msg); + //accept per udp package + void dataReceived(); + //emit per accepted tag + void dataAccepted(); + +private slots: + void _processPendingDatagrams(); + void _setState(enum_states state); + void _watchDogTimeOver(); + bool _getTime(QDateTime& t, int year, int month, int day, int hour, int minute, int second, int millisecond = 0); + void _scheduleProcess(); + +private: + + /*! + * For sorting + * instead of operator<() to compare the TagInfo* + */ + static bool compareTagAddress(const TagAddress* t1, const TagAddress* t2); + QUdpSocket * _pUdpSocket; + QHostAddress _udpdatabaseAddress; + QHostAddress _hostAddress; + QNetworkInterface _networkInterface; + UdpDatabaseProtocolDriverUI * _pUI; + int _port; + quint16 _hostPort; + char _stationID; + enum_states _state; + + QTimer *_pWatchDogTimer; + QList<TagAddress*> _relatedTags; + + QTimer* _scheduleTimer;//UDPå‘é€å®šæ—¶å™¨ +}; + +#endif // UDPDATABASEPROTOCOLDRIVER_H diff --git a/ScenePlugin/ScenePlugin.pro b/ScenePlugin/ScenePlugin.pro new file mode 100644 index 0000000000000000000000000000000000000000..95b727cf17c45f7061f339cef22cc819c27642ad --- /dev/null +++ b/ScenePlugin/ScenePlugin.pro @@ -0,0 +1,4 @@ +TEMPLATE = subdirs + +SUBDIRS += Archermind +SUBDIRS += Triton diff --git a/ScenePlugin/Triton/Triton.pro b/ScenePlugin/Triton/Triton.pro new file mode 100644 index 0000000000000000000000000000000000000000..c1faba9dbef372740aae890d2bc6a28c458ec320 --- /dev/null +++ b/ScenePlugin/Triton/Triton.pro @@ -0,0 +1,19 @@ +QT+= network widgets + +TEMPLATE = lib +CONFIG += plugin +TARGET = $$qtLibraryTarget(TritonScene) +DESTDIR = ../../ScenePlugin + +CONFIG += c++11 + +INCLUDEPATH += $$PWD\ + +HEADERS += \ + $$PWD/udpdatabaseprotocoldriver.h + +SOURCES += \ + $$PWD/udpdatabaseprotocoldriver.cpp + +#interface: +include(../../Interface/Interface.pri) diff --git a/ScenePlugin/Triton/udpdatabaseProtocol.json b/ScenePlugin/Triton/udpdatabaseProtocol.json new file mode 100644 index 0000000000000000000000000000000000000000..0967ef424bce6791893e9a57bb952f80fd536e93 --- /dev/null +++ b/ScenePlugin/Triton/udpdatabaseProtocol.json @@ -0,0 +1 @@ +{} diff --git a/ScenePlugin/Triton/udpdatabaseprotocoldriver.cpp b/ScenePlugin/Triton/udpdatabaseprotocoldriver.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7a998608f28c54429674f336d6771758a341f1c6 --- /dev/null +++ b/ScenePlugin/Triton/udpdatabaseprotocoldriver.cpp @@ -0,0 +1,388 @@ +#if _MSC_VER >= 1600 +#pragma execution_character_set("utf-8") +#endif +#include <QDateTime> +#include <QHostAddress> +#include "udpdatabaseprotocoldriverui.h" +#include "udpdatabaseprotocoldriver.h" +#include "loadsaveprocessorxml.h" + +UdpDatabaseProtocolDriver::UdpDatabaseProtocolDriver(QObject *parent) : iDriver(parent), + _udpdatabaseAddress( QHostAddress("127.0.0.1")), + _stationID(0xFA), + _port(5656), + _pUdpSocket(nullptr), + _pUI(nullptr), + _pWatchDogTimer(nullptr), + _scheduleTimer(nullptr) +{ + //default + if(QNetworkInterface::allInterfaces().size() == 0){ + emit msgEventString(tr("电脑上找ä¸åˆ°ç½‘å¡") ); + } + else{ + _networkInterface = QNetworkInterface::allInterfaces().at(0); + } + + + _setState(STAT_STOP); +} +UdpDatabaseProtocolDriver::~UdpDatabaseProtocolDriver(){ + stop(); + if(_pUdpSocket!=nullptr){ + _pUdpSocket->deleteLater(); + } + if(_pUI != nullptr){ + _pUI->deleteLater(); + } +} + +DriverInfo UdpDatabaseProtocolDriver::driverInfo()const{ + DriverInfo info; + info.driverType = "UdpDatabase Protocol"; + info.driverManufacturer = "CSIC711"; + info.description = "UdpDatabase Protocol for data acquisition\nDate:2017.9"; + info.majorVersion = QString::number(0); + info.minorVersion = QString::number(0); + info.microVersion = QString::number(1); + return info; +} + +void UdpDatabaseProtocolDriver::save(iLoadSaveProcessor* processor){ + processor->writeValue("udpdatabaseAddress",_udpdatabaseAddress); + processor->writeValue("port",_port); + QString networkInterfaceName = _networkInterface.name(); + processor->writeValue("networkInterface", networkInterfaceName ); +} + +void UdpDatabaseProtocolDriver::load(iLoadSaveProcessor* processor){ + processor->readValue("udpdatabaseAddress",_udpdatabaseAddress); + processor->readValue("port",_port); + QList<QNetworkInterface> allInterfaces = QNetworkInterface::allInterfaces(); + if(allInterfaces.size() == 0){ + emit msgEventString(tr("电脑上找ä¸åˆ°ç½‘å¡") ); + return; + } + QString networkInterfaceName; + processor->readValue("networkInterface", networkInterfaceName ); + bool foundInterface = false; + foreach (QNetworkInterface iface, allInterfaces) { + if(iface.name() == networkInterfaceName){ + foundInterface = true; + _networkInterface = iface; + break; + } + } + if(!foundInterface){ + emit msgEventString(tr("电脑上找ä¸åˆ°å为“%1â€çš„网å¡").arg(networkInterfaceName) ); + _networkInterface = allInterfaces.at(0); + } + if(state() == STAT_RUN){ + restart(); + } +} + +void UdpDatabaseProtocolDriver::_watchDogTimeOver(){ + emit msgEventString(tr("超时错误,长时间未收到数æ®") ); + _setState(STAT_ERR); +} + +int UdpDatabaseProtocolDriver::start(){ + if(_state!=iDriver::STAT_STOP) return-1; + if(_pUdpSocket != nullptr){ + _pUdpSocket->close(); + _pUdpSocket->deleteLater(); + } + else{ + _pUdpSocket = new QUdpSocket(this); + bool ret = _pUdpSocket->bind(_port, QUdpSocket::ShareAddress); + if(!ret){ + _setState( STAT_STOP ); + emit msgEventString(tr("å¯åŠ¨å¤±è´¥ï¼ç½‘络监å¬å¤±è´¥ï¼Œæ£€æŸ¥ç½‘络状æ€ï¼é”™è¯¯æè¿°ï¼š%1").arg(_pUdpSocket->errorString() ) ); + return -1; + } + else{ + connect(_pUdpSocket, SIGNAL(readyRead()), this, SLOT(_processPendingDatagrams())); + } + } + if(_pWatchDogTimer!=nullptr){ + _pWatchDogTimer->stop(); + _pWatchDogTimer->deleteLater(); + }else{ + _pWatchDogTimer = new QTimer(this); + _pWatchDogTimer->setSingleShot(true); + _pWatchDogTimer->setInterval(100 * 1000); + connect(_pWatchDogTimer,SIGNAL(timeout()),this,SLOT(_watchDogTimeOver())); + _pWatchDogTimer->start(); + } + if(_scheduleTimer!=nullptr){ + _scheduleTimer->stop(); + _scheduleTimer->deleteLater(); + }else{ + _scheduleTimer = new QTimer(this); + _scheduleTimer->setSingleShot(false); + _scheduleTimer->setInterval(500); + connect(_scheduleTimer,&QTimer::timeout,this,&UdpDatabaseProtocolDriver::_scheduleProcess); + _scheduleTimer->start(); + } + + _setState(STAT_RUN); + emit msgEventString(tr("å¯åЍæˆåŠŸï¼") ); + return 0; + +// if(_pUdpSocket != nullptr){ +// _pUdpSocket->close(); +// _pUdpSocket->deleteLater(); +// } +// else{ + +// _pUdpSocket = new QUdpSocket(this); +// ret = _pUdpSocket->bind(_port, QUdpSocket::ShareAddress); +// if(!ret){ +// _setState( STAT_STOP ); +// emit msgEventString(tr("å¯åŠ¨å¤±è´¥ï¼ç½‘络监å¬å¤±è´¥ï¼Œæ£€æŸ¥ç½‘络状æ€ï¼é”™è¯¯æè¿°ï¼š%1").arg(_pUdpSocket->errorString() ) ); +// return -1; +// } +// else{ +// connect(_pUdpSocket, SIGNAL(readyRead()), this, SLOT(_processPendingDatagrams())); +// _setState(STAT_RUN); +// emit msgEventString(tr("å¯åЍæˆåŠŸï¼") ); +// return 0; +// } +// } +} + +int UdpDatabaseProtocolDriver::stop(){ + if(_scheduleTimer!=nullptr){ + _scheduleTimer->stop(); + _scheduleTimer->deleteLater(); + _scheduleTimer=nullptr; + } + if(_pWatchDogTimer!=nullptr){ + _pWatchDogTimer->stop(); + _pWatchDogTimer->deleteLater(); + _pWatchDogTimer=nullptr; + } + if(_pUdpSocket != nullptr){ + _pUdpSocket->close(); + _pUdpSocket->deleteLater(); + _pUdpSocket=nullptr; + _setState(STAT_STOP); + emit msgEventString(tr("åœæ¢æˆåŠŸï¼") ); + } + return 0; +} + +int UdpDatabaseProtocolDriver::restart(){ + stop(); + return start(); +} + +QList<int> UdpDatabaseProtocolDriver::availableRWStrategy(void)const{ + QList<int> ret; + ret<<iTagInfo::RWS_DISABLE<<iTagInfo::RWS_WRITE_ONLY; + return ret; +} + +QList<int> UdpDatabaseProtocolDriver::availableRWStrategy(const QString& addr)const{ + QList<int> ret; + ret<<iTagInfo::RWS_DISABLE; + if(isAddressCorrect(addr)) + ret<<iTagInfo::RWS_WRITE_ONLY; + return ret; +} + +bool UdpDatabaseProtocolDriver::isAddressCorrect(const QString& addr)const{ + bool ret; + addr.toUInt(&ret,16); + return ret; +} + +QString UdpDatabaseProtocolDriver::addressErrorString(const QString& addr) const{ + if(isAddressCorrect(addr)){ + return QString(); + } + return tr("地å€å¿…须是å进制数å—ï¼"); +} + +int UdpDatabaseProtocolDriver::setUdpDatabaseAddress(const QHostAddress& hostaddr, qint16 hostport,qint16 localport){ + //if( addr.isUdpDatabase() ){ + // if(addr != _udpdatabaseAddress ){ + //_udpdatabaseAddress = addr; + _hostAddress = hostaddr; + _hostPort = hostport; + _port = localport; + // } + return 0; + //} +} +int UdpDatabaseProtocolDriver::setSMDERIMStation(qint16 station){ + if(station < 0 || station >255){ + emit msgEventString(tr("输入错误:StationID超出范围ï¼") ); + return -1; + } + else{ + _stationID = station; + return 0; + } +} + +int UdpDatabaseProtocolDriver::setNetworkInterface(const QNetworkInterface& networkInterface){ + if(networkInterface.isValid()){ + //if(networkInterface.flags().testFlag(QNetworkInterface::CanUdpDatabase) ){ + _networkInterface = networkInterface; + return 0; + //} + } + emit msgEventString(tr("设置失败。没有组æ’åŠŸèƒ½æˆ–æ— æ•ˆåœ°å€ï¼") ); + return -1; +} + +QString UdpDatabaseProtocolDriver::udpdatabaseAddress(void)const{ + return _udpdatabaseAddress.toString(); +} + +int UdpDatabaseProtocolDriver::udpdatabasePort(void)const{ + return _port; +} + +QNetworkInterface& UdpDatabaseProtocolDriver::networkInterface(void){ + return _networkInterface; +} + +int UdpDatabaseProtocolDriver::setRelatedTagAddresses(const QList<TagAddress *>& relatedTagAddresses){ + int count =0; + _relatedTags.clear(); + foreach (TagAddress* it, relatedTagAddresses) { + if(it->RWStrategy == iTagInfo::RWS_WRITE_ONLY){ + _relatedTags<<it; + count++; + } + } + qSort(_relatedTags.begin(), _relatedTags.end(), compareTagAddress); + return count; +} + +void UdpDatabaseProtocolDriver::showUI(bool show, QWidget *parent){ + if(_pUI == nullptr){ + _pUI = new UdpDatabaseProtocolDriverUI(this, parent); + } + if(show){ + _pUI->show(); + }else{ + _pUI->hide(); + } +} +void UdpDatabaseProtocolDriver::_scheduleProcess() +{ + QByteArray datagram; + int i = 0; + qint16 dmh = 0; + qint32 temp; + char*temp1; + if(_state != STAT_RUN) return; + datagram.clear(); + + datagram[0] = 0x53; + datagram[1] = 0x03; + datagram[2] = _stationID; + datagram[3] = 0x00; + datagram[4] = 0x00; + i = 5; + if(_relatedTags.size()!=0 && _hostAddress != nullptr){ + //prepare data + foreach(TagAddress* t, _relatedTags){ + if(t->RWStrategy == iTagInfo::RWS_DISABLE) continue; + if(t->RWStrategy == iTagInfo::RWS_READ_ONLY) continue; + if(t->RWStrategy == iTagInfo::RWS_READ_WRITE) continue; + + temp = t->address.toUInt(nullptr,16); + temp1 = (char*)&temp; + datagram.append(*(temp1+3)); + datagram.append(*(temp1+2)); + datagram.append(*(temp1+1)); + datagram.append(*(temp1+0)); + switch (t->tagInfo->type()) { + case iTagInfo::TYPE_INT32: + datagram.append(char(0x04)); + datagram.append(char(0x00)); + //datagram.append(0x00);//quality byte:0-ok,1-error; + temp =t->tagInfo->value().toUInt(); + temp1 =(char*)&temp; + datagram.append(*(temp1+3)); + datagram.append(*(temp1+2)); + datagram.append(*(temp1+1)); + datagram.append(*(temp1+0)); + break; + case iTagInfo::TYPE_INT16: + datagram.append(char(0x02)); + datagram.append(char(0x00)); + //datagram.append(0x00);//quality byte:0-ok,1-error; + temp =t->tagInfo->value().toUInt(); + temp1 =(char*)&temp; + datagram.append(*(temp1+1)); + datagram.append(*(temp1+0)); + break; + default: + break; + } + } + qint16 len = datagram.size() - 3; + datagram[3] = (len & 0xff00)>>8; + datagram[4] = len & 0xff; + for(int i=1;i<len;i++) { + dmh += datagram[i]; + } + + datagram.append(dmh & 0xff).append((dmh & 0xff00)>>8); + datagram.append(char(0x0D)); + //write data + _pUdpSocket->writeDatagram(datagram.data(),datagram.size(),_hostAddress,_hostPort); + } +} + +void UdpDatabaseProtocolDriver::_processPendingDatagrams() +{ + while (_pUdpSocket->hasPendingDatagrams()) { + emit dataReceived();//accept per UDP package + QByteArray datagram; + datagram.resize(_pUdpSocket->pendingDatagramSize()); + int count = _pUdpSocket->readDatagram(datagram.data(),datagram.size(),&_hostAddress,&_hostPort);//,&_hostAddress,&_hostPort + + if ((datagram[0] == 0x53) + && (count >= 7) + && (datagram[count - 1] == 0x0D)){ + switch (datagram[1]) { + case 1: + _pUdpSocket->writeDatagram(datagram.data(),datagram.size(),_hostAddress,_hostPort); + _pWatchDogTimer->start(); + + break; + default: + break; + } + } + + } +} + +void UdpDatabaseProtocolDriver::_setState(enum_states state){ + if(state != _state){ + _state = state; + emit stateChanged(state); + } +} + +bool UdpDatabaseProtocolDriver::_getTime(QDateTime& t, int year, int month, int day, int hour, int minute, int second, int millisecond){ + if(!QDate::isValid(year,month,day)) + return false; + if(!QTime::isValid(hour,minute,second,millisecond)) + return false; + t.setDate( QDate(year,month,day) ); + t.setTime( QTime(hour,minute,second,millisecond) ); + return true; +} + +bool UdpDatabaseProtocolDriver::compareTagAddress(const TagAddress *t1, const TagAddress *t2){ + return t1->address < t2->address; +} diff --git a/ScenePlugin/Triton/udpdatabaseprotocoldriver.h b/ScenePlugin/Triton/udpdatabaseprotocoldriver.h new file mode 100644 index 0000000000000000000000000000000000000000..76145cfc67d7161df746d43e4aa6e46f6d6b6f95 --- /dev/null +++ b/ScenePlugin/Triton/udpdatabaseprotocoldriver.h @@ -0,0 +1,110 @@ +#ifndef UDPDATABASEPROTOCOLDRIVER_H +#define UDPDATABASEPROTOCOLDRIVER_H + +#include <QObject> +#include <QTimer> +#include <QtNetwork> +#include <QtNetwork/QUdpSocket> +#include "iplugin.h" + +class QUdpSocket; +class QHostAddress; +class UdpDatabaseProtocolDriverUI; + +class UdpDatabaseProtocolDriver : public iDriver +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "com.csic711.appServer.drivers.udpdatabaseProtocol" FILE "udpdatabaseProtocol.json") + Q_INTERFACES(iDriver) +public: + /*! + * æž„é€ å‡½æ•° + * 功能æè¿°ï¼š + * 1ã€åˆå§‹åŒ–傿•° + * 2ã€è¿›å…¥åœæ¢çŠ¶æ€ + */ + explicit UdpDatabaseProtocolDriver(QObject *parent = 0); + ~UdpDatabaseProtocolDriver(); + +public slots: + DriverInfo driverInfo()const override; + void save(iLoadSaveProcessor* processor) override; + void load(iLoadSaveProcessor* processor) override; + int start() override; + int stop() override; + int restart() override; + int state() override{ return _state; } + QList<int> availableRWStrategy(void)const override; + QList<int> availableRWStrategy(const QString& addr)const override; + bool isAddressCorrect(const QString& addr)const override; + QString addressErrorString(const QString& addr)const override; + int setRelatedTagAddresses(const QList<TagAddress *>& relatedTagAddresses) override; + void showUI(bool show=true, QWidget* parent=0) override; + + +public slots: + /*! + * 设置组æ’çš„Addresså’ŒPort + * 返回数值:0:æˆåŠŸ -1:失败 + * 功能æè¿°ï¼š + * 1ã€å¦‚果是组æ’的地å€åˆ™æˆåŠŸï¼Œå¦åˆ™å¤±è´¥ + */ + int setUdpDatabaseAddress(const QHostAddress& hostaddr, qint16 hostport,qint16 localport); + + /*! + * 设置组æ’çš„ç½‘å¡æŽ¥å£ + * 返回数值:0:æˆåŠŸ -1:失败 + * 功能æè¿°ï¼š + * 1ã€å¦‚果是组æ’çš„ç½‘å¡æŽ¥å£åˆ™æˆåŠŸï¼Œå¦åˆ™å¤±è´¥ + */ + int setNetworkInterface(const QNetworkInterface& networkInterface); + /*! + * 设置站å·-csic711定制 + * 返回数值:0:æˆåŠŸ -1:失败 + * 功能æè¿°ï¼š + * ç«™å·èŒƒå›´ï¼š1-255 + */ + int setSMDERIMStation(qint16 station); + + QString udpdatabaseAddress(void)const; + int udpdatabasePort(void)const; + QNetworkInterface& networkInterface(void); + +signals: + void msgEventString(const QString& msg); + //accept per udp package + void dataReceived(); + //emit per accepted tag + void dataAccepted(); + +private slots: + void _processPendingDatagrams(); + void _setState(enum_states state); + void _watchDogTimeOver(); + bool _getTime(QDateTime& t, int year, int month, int day, int hour, int minute, int second, int millisecond = 0); + void _scheduleProcess(); + +private: + + /*! + * For sorting + * instead of operator<() to compare the TagInfo* + */ + static bool compareTagAddress(const TagAddress* t1, const TagAddress* t2); + QUdpSocket * _pUdpSocket; + QHostAddress _udpdatabaseAddress; + QHostAddress _hostAddress; + QNetworkInterface _networkInterface; + UdpDatabaseProtocolDriverUI * _pUI; + int _port; + quint16 _hostPort; + char _stationID; + enum_states _state; + + QTimer *_pWatchDogTimer; + QList<TagAddress*> _relatedTags; + + QTimer* _scheduleTimer;//UDPå‘é€å®šæ—¶å™¨ +}; + +#endif // UDPDATABASEPROTOCOLDRIVER_H