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