From 5adce825013b49f0614db1746cffe43a7502de82 Mon Sep 17 00:00:00 2001
From: jiazx0107@163.com <jiazx0107@163.com>
Date: 星期二, 22 八月 2023 23:07:46 +0800
Subject: [PATCH] 更新MODBUS-TCP协议 1

---
 igds-protocol-modbus/src/main/java/com/ld/igds/protocol/modbus/command/AnalysisService.java          |   50 +++++
 igds-verb/src/main/java/com/ld/igds/verb/manager/VerbManager.java                                    |   32 +-
 igds-protocol-modbus/src/main/java/com/ld/igds/protocol/modbus/command/RemoteControlServiceImpl.java |  200 +++++++++++++++++----
 igds-core/src/main/java/com/ld/igds/view/Device.view.xml                                             |    7 
 igds-web/.rules                                                                                      |   30 +-
 igds-protocol-modbus/src/main/java/com/ld/igds/protocol/modbus/data/ModbusTcp.java                   |   57 +++++
 igds-core/src/main/java/com/ld/igds/models/Device.java                                               |    4 
 igds-protocol-modbus/src/main/java/com/ld/igds/protocol/modbus/ModbusConfig.java                     |    5 
 igds-protocol-modbus/src/main/java/com/ld/igds/protocol/modbus/ModbusUtil.java                       |   82 +++++---
 igds-verb/src/main/java/com/ld/igds/verb/controller/VerbController.java                              |    4 
 igds-core/src/main/java/models/igds.model.xml                                                        |    6 
 igds-protocol-modbus/src/main/java/com/ld/igds/protocol/modbus/ServerUtil.java                       |   41 ++++
 12 files changed, 401 insertions(+), 117 deletions(-)

diff --git a/igds-core/src/main/java/com/ld/igds/models/Device.java b/igds-core/src/main/java/com/ld/igds/models/Device.java
index f8ae9b6..eebb08e 100644
--- a/igds-core/src/main/java/com/ld/igds/models/Device.java
+++ b/igds-core/src/main/java/com/ld/igds/models/Device.java
@@ -78,6 +78,10 @@
     @PropertyDef(label = "鍏宠仈璁惧閫氶亾", description = "閽堝鍙岄�氶亾閰嶇疆璁惧锛屽娣锋祦椋庡彛鐨勯鏈恒�佽酱娴侀鍙g殑椋庢満")
     private String link;
 
+    @Column(name = "LINK_MODBUS_",length = 100)
+    @PropertyDef(label = "鍏宠仈璁惧Modbus")
+    private String linkModbus;
+
     @Column(name = "EXT1_", length = 20)
     @PropertyDef(label = "鎵╁睍瀛楁1", description = "鏍规嵁涓氬姟闇�瑕佽嚜瀹氫箟瀛樺偍鍊�")
     private String ext1;
diff --git a/igds-core/src/main/java/com/ld/igds/view/Device.view.xml b/igds-core/src/main/java/com/ld/igds/view/Device.view.xml
index 85ea20e..4e847df 100644
--- a/igds-core/src/main/java/com/ld/igds/view/Device.view.xml
+++ b/igds-core/src/main/java/com/ld/igds/view/Device.view.xml
@@ -153,7 +153,6 @@
       <ClientEvent name="onHide">view.id(&quot;dsDevice&quot;).getData().cancel();</ClientEvent>
       <Property name="caption">缂栬緫椤甸潰</Property>
       <Property name="width">800</Property>
-      <Property name="height">450</Property>
       <Buttons>
         <Button>
           <Property name="caption">纭畾</Property>
@@ -232,6 +231,12 @@
             <Property name="property">modbus</Property>
             <Editor/>
           </AutoFormElement>
+          <AutoFormElement layoutConstraint="colSpan:2">
+            <Property name="name">linkModbus</Property>
+            <Property name="property">linkModbus</Property>
+            <Property name="label">椋庢満Modbus</Property>
+            <Editor/>
+          </AutoFormElement>
           <Label layoutConstraint="colSpan:2">
             <Property name="text">modbus瑙勫垯锛氬紑鍦板潃-鍏冲湴鍧�-鍋滃湴鍧�-寮�鍒颁綅-鍏冲埌浣�-寮�鏁呴殰-鍏虫晠闅滐紝鏃犲湴鍧�鐢∟浠f浛</Property>
             <Property name="style">
diff --git a/igds-core/src/main/java/models/igds.model.xml b/igds-core/src/main/java/models/igds.model.xml
index cb59728..791ffe0 100644
--- a/igds-core/src/main/java/models/igds.model.xml
+++ b/igds-core/src/main/java/models/igds.model.xml
@@ -314,7 +314,7 @@
       <Property name="label">澶囨敞</Property>
     </PropertyDef>
     <PropertyDef name="ggm">
-      <Property/>
+      <Property></Property>
       <Property name="label">鍥借鐮�</Property>
     </PropertyDef>
   </DataType>
@@ -607,6 +607,10 @@
       <Property></Property>
       <Property name="label">Modbus閰嶇疆</Property>
     </PropertyDef>
+    <PropertyDef name="linkModbus">
+      <Property/>
+      <Property name="label">鍏宠仈璁惧Modbus</Property>
+    </PropertyDef>
     <PropertyDef name="ext1">
       <Property></Property>
       <Property name="label">鎵╁睍瀛楁1</Property>
diff --git a/igds-protocol-modbus/src/main/java/com/ld/igds/protocol/modbus/ModbusConfig.java b/igds-protocol-modbus/src/main/java/com/ld/igds/protocol/modbus/ModbusConfig.java
index 9d57d94..59d269d 100644
--- a/igds-protocol-modbus/src/main/java/com/ld/igds/protocol/modbus/ModbusConfig.java
+++ b/igds-protocol-modbus/src/main/java/com/ld/igds/protocol/modbus/ModbusConfig.java
@@ -40,7 +40,6 @@
         }
         return modbusMaster;
 
-
     }
 
     /**
@@ -53,10 +52,10 @@
         params.setPort(port);
         //璁剧疆涓簍rue锛屼細瀵艰嚧TimeoutException: request=com.serotonin.modbus4j.ip.encap.EncapMessageRequest@774dfba5",
         //params.setEncapsulated(true);
-        master = modbusFactory.createTcpMaster(params, true);// TCP 鍗忚
+        master = modbusFactory.createTcpMaster(params, false);// TCP 鍗忚
         try {
             //璁剧疆瓒呮椂鏃堕棿
-            master.setTimeout(3 * 1000);
+            master.setTimeout(2 * 1000);
             //璁剧疆閲嶈繛娆℃暟
             master.setRetries(3);
             //鍒濆鍖�
diff --git a/igds-protocol-modbus/src/main/java/com/ld/igds/protocol/modbus/ModbusUtil.java b/igds-protocol-modbus/src/main/java/com/ld/igds/protocol/modbus/ModbusUtil.java
index ae245da..416e7cb 100644
--- a/igds-protocol-modbus/src/main/java/com/ld/igds/protocol/modbus/ModbusUtil.java
+++ b/igds-protocol-modbus/src/main/java/com/ld/igds/protocol/modbus/ModbusUtil.java
@@ -1,8 +1,12 @@
 package com.ld.igds.protocol.modbus;
 
+import com.serotonin.modbus4j.BatchRead;
+import com.serotonin.modbus4j.BatchResults;
 import com.serotonin.modbus4j.ModbusMaster;
+import com.serotonin.modbus4j.code.DataType;
 import com.serotonin.modbus4j.exception.ModbusInitException;
 import com.serotonin.modbus4j.exception.ModbusTransportException;
+import com.serotonin.modbus4j.locator.BaseLocator;
 import com.serotonin.modbus4j.msg.ReadCoilsRequest;
 import com.serotonin.modbus4j.msg.ReadCoilsResponse;
 import com.serotonin.modbus4j.msg.ReadDiscreteInputsRequest;
@@ -19,6 +23,7 @@
 import com.serotonin.modbus4j.msg.WriteRegisterResponse;
 import com.serotonin.modbus4j.msg.WriteRegistersRequest;
 import com.serotonin.modbus4j.msg.WriteRegistersResponse;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
@@ -27,6 +32,7 @@
  * @author: Andy
  * @update-time: 2023/8/11
  */
+@Slf4j
 @Component
 public class ModbusUtil {
 
@@ -37,7 +43,15 @@
     private ModbusConfig modbusConfig;
 
 
-    public boolean[] readCoilStatus(String ip, int port, int offset, int numberOfRegister) throws ModbusTransportException {
+    /**
+     * 璇荤嚎鍦�--01
+     *
+     * @param ip
+     * @param port
+     * @param offset
+     * @param numberOfRegister
+     */
+    public boolean[] readStatus01(String ip, int port, int offset, int numberOfRegister) throws ModbusTransportException {
 
         ModbusMaster master = modbusConfig.getMaster(ip, port);
         ReadCoilsRequest request = new ReadCoilsRequest(slaveId, offset, numberOfRegister);
@@ -48,32 +62,26 @@
     }
 
     /**
-     * @Description: 璇诲彇澶栧洿璁惧杈撳叆鐨勫紑鍏抽噺锛岀浉褰撲簬鍔熻兘鐮侊細02H-璇荤鏁h緭鍏ョ姸鎬�
+     * @Description: 02H-璇荤鏁h緭鍏ラ噺
      * @Param: [ip, offset, numberOfRegister]
      * @return: boolean[]
      * @throws:
-     * @Author: Ricardo.Liu
-     * @Date: 2020/5/8
      */
-    public boolean[] readInputStatus(String ip, int port, int offset, int numberOfRegister) throws ModbusTransportException {
-
+    public boolean[] readStatus02(String ip, int port, int offset, int numberOfRegister) throws ModbusTransportException {
         ModbusMaster master = modbusConfig.getMaster(ip, port);
         ReadDiscreteInputsRequest request = new ReadDiscreteInputsRequest(slaveId, offset, numberOfRegister);
         ReadDiscreteInputsResponse response = (ReadDiscreteInputsResponse) master.send(request);
         boolean[] booleans = response.getBooleanData();
-
         return valueRegroup(numberOfRegister, booleans);
     }
 
     /**
-     * @Description: 璇诲彇淇濇寔瀵勫瓨鍣ㄦ暟鎹紝鐩稿綋浜庡姛鑳界爜锛�03H-璇讳繚鎸佸瘎瀛樺櫒
+     * @Description: 03H-璇讳繚鎸佸瘎瀛樺櫒
      * @Param: [ip, offset, numberOfRegister]
      * @return: short[]
      * @throws:
-     * @Author: Ricardo.Liu
-     * @Date: 2020/5/8
      */
-    public short[] readHoldingRegister(String ip, int port, int offset, int numberOfRegister) throws ModbusTransportException {
+    public short[] readStatus03(String ip, int port, int offset, int numberOfRegister) throws ModbusTransportException {
 
         ModbusMaster master = modbusConfig.getMaster(ip, port);
         ReadHoldingRegistersRequest request = new ReadHoldingRegistersRequest(slaveId, offset, numberOfRegister);
@@ -82,19 +90,43 @@
     }
 
     /**
-     * @Description: 璇诲彇澶栧洿璁惧杈撳叆鐨勬暟鎹紝鐩稿綋浜庡姛鑳界爜锛�04H-璇昏緭鍏ュ瘎瀛樺櫒
+     * @Description: 04H-璇昏緭鍏ュ瘎瀛樺櫒
      * @Param: [ip, offset, numberOfRegister]
      * @return: short[]
      * @throws:
-     * @Author: Ricardo.Liu
-     * @Date: 2020/5/8
      */
-    public short[] readInputRegisters(String ip, int port, int offset, int numberOfRegister) throws ModbusTransportException {
-
+    public short[] readStatus04(String ip, int port, int offset, int numberOfRegister) throws ModbusTransportException {
         ModbusMaster master = modbusConfig.getMaster(ip, port);
         ReadInputRegistersRequest request = new ReadInputRegistersRequest(slaveId, offset, numberOfRegister);
         ReadInputRegistersResponse response = (ReadInputRegistersResponse) master.send(request);
         return response.getShortData();
+    }
+
+
+    public BatchResults<Integer> readBatch(String ip, int port) throws Exception {
+        ModbusMaster master = modbusConfig.getMaster(ip, port);
+
+        if (null == master) return null;
+
+        return readBatch(master);
+    }
+
+    /**
+     * 鎵归噺璇诲彇澶氫釜
+     *
+     * @param master
+     * @throws ModbusTransportException
+     */
+    public BatchResults<Integer> readBatch(ModbusMaster master) throws Exception {
+        BatchRead<Integer> batch = new BatchRead<>();
+        batch.addLocator(0, BaseLocator.holdingRegister(1, 1, DataType.TWO_BYTE_INT_SIGNED));
+        batch.addLocator(1, BaseLocator.inputStatus(1, 0));
+        batch.setContiguousRequests(true);
+        BatchResults<Integer> results = master.send(batch);
+        log.info("batchRead:" + results.getValue(0));
+        log.info("batchRead:" + results.getValue(1));
+
+        return results;
     }
 
     /**
@@ -102,10 +134,8 @@
      * @Param: [ip, writeOffset, writeValue]
      * @return: boolean
      * @throws:
-     * @Author: Ricardo.Liu
-     * @Date: 2020/5/8
      */
-    public boolean writeCoil(String ip, int port, int writeOffset, boolean writeValue) throws ModbusTransportException {
+    public boolean writeValue05(String ip, int port, int writeOffset, boolean writeValue) throws ModbusTransportException {
 
         ModbusMaster tcpMaster = modbusConfig.getMaster(ip, port);
         WriteCoilRequest request = new WriteCoilRequest(slaveId, writeOffset, writeValue);
@@ -118,10 +148,8 @@
      * @Param: [ip, startOffset, data]
      * @return: boolean
      * @throws:
-     * @Author: Ricardo.Liu
-     * @Date: 2020/5/8
      */
-    public boolean writeCoils(String ip, int port, int startOffset, boolean[] data) throws ModbusTransportException {
+    public boolean writeValues15(String ip, int port, int startOffset, boolean[] data) throws ModbusTransportException {
 
         ModbusMaster tcpMaster = modbusConfig.getMaster(ip, port);
         WriteCoilsRequest request = new WriteCoilsRequest(slaveId, startOffset, data);
@@ -135,10 +163,8 @@
      * @Param: [ip, writeOffset, writeValue]
      * @return: boolean
      * @throws:
-     * @Author: Ricardo.Liu
-     * @Date: 2020/5/8
      */
-    public boolean writeHoldingRegister(String ip, int port,int writeOffset, short writeValue) throws ModbusTransportException, ModbusInitException {
+    public boolean writeValue06(String ip, int port, int writeOffset, short writeValue) throws ModbusTransportException, ModbusInitException {
 
         ModbusMaster tcpMaster = modbusConfig.getMaster(ip, port);
         WriteRegisterRequest request = new WriteRegisterRequest(slaveId, writeOffset, writeValue);
@@ -152,10 +178,8 @@
      * @Param: [ip, startOffset, data]
      * @return: boolean
      * @throws:
-     * @Author: Ricardo.Liu
-     * @Date: 2020/5/8
      */
-    public boolean writeHoldingRegisters(String ip,int port, int startOffset, short[] data) throws ModbusTransportException, ModbusInitException {
+    public boolean writeValues16(String ip, int port, int startOffset, short[] data) throws ModbusTransportException, ModbusInitException {
 
         ModbusMaster tcpMaster = modbusConfig.getMaster(ip, port);
         WriteRegistersRequest request = new WriteRegistersRequest(slaveId, startOffset, data);
@@ -168,8 +192,6 @@
      * @Param: [numberOfBits, values]
      * @return: boolean[]
      * @throws:
-     * @Author: Ricardo.Liu
-     * @Date: 2020/5/8
      */
     private boolean[] valueRegroup(int numberOfBits, boolean[] values) {
         boolean[] bs = new boolean[numberOfBits];
diff --git a/igds-protocol-modbus/src/main/java/com/ld/igds/protocol/modbus/ServerUtil.java b/igds-protocol-modbus/src/main/java/com/ld/igds/protocol/modbus/ServerUtil.java
new file mode 100644
index 0000000..b31119c
--- /dev/null
+++ b/igds-protocol-modbus/src/main/java/com/ld/igds/protocol/modbus/ServerUtil.java
@@ -0,0 +1,41 @@
+package com.ld.igds.protocol.modbus;
+
+import com.ld.igds.util.ContextUtil;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *
+ */
+public class ServerUtil {
+
+
+    /**
+     * 鐢ㄦ潵缂撳瓨锛孴CP璁惧鎵ц鏃堕棿璁板綍key = TCP鍞竴鏍囧織锛寁alue = 褰撳墠鎵ц鏃堕棿
+     */
+    public static Map<String, Long> contextExeModbusTcp = new HashMap<>();
+
+
+    /**
+     * 璁惧鐘舵�佽繑鍥炵殑缁撴灉 KEY= companyId + serId + deviceCode value = 缁撴灉鐘舵��
+     */
+    private static Map<String, String> contextStatusMap = new HashMap<>();
+
+
+    /**
+     * 璁惧瑙f瀽鍚庣殑瑁呮硶瀛樻斁
+     *
+     * @param serId
+     * @param deviceCode 璁惧閫氶亾ID
+     * @param status     涓嶈�冭檻璁惧绫诲瀷锛屽彧鍦ㄩ�氶亾涓婃爣璁版槸OPEN鎴栬�匔LOSE鍗冲彲
+     */
+    public static void add2StatusMap(String companyId, String serId, String deviceCode, String status) {
+        contextStatusMap.put(ContextUtil.buildDeviceStatusKey(companyId, serId, deviceCode), status);
+    }
+
+    public static Map<String, String> getStatusMap() {
+        return contextStatusMap;
+    }
+
+}
diff --git a/igds-protocol-modbus/src/main/java/com/ld/igds/protocol/modbus/command/AnalysisService.java b/igds-protocol-modbus/src/main/java/com/ld/igds/protocol/modbus/command/AnalysisService.java
new file mode 100644
index 0000000..7e5dec7
--- /dev/null
+++ b/igds-protocol-modbus/src/main/java/com/ld/igds/protocol/modbus/command/AnalysisService.java
@@ -0,0 +1,50 @@
+package com.ld.igds.protocol.modbus.command;
+
+import com.ld.igds.common.CoreDeviceService;
+import com.ld.igds.io.constant.OrderRespEnum;
+import com.ld.igds.io.notify.NotifyWebInvoker;
+import com.ld.igds.io.request.DeviceControlRequest;
+import com.ld.igds.protocol.modbus.ServerUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+/**
+ * 瑙f瀽
+ */
+@Slf4j
+@Component
+public class AnalysisService {
+
+    @Resource
+    private CoreDeviceService deviceService;
+    @Resource
+    private NotifyWebInvoker notifyInvoker;
+
+
+    /**
+     * 寮傛鏇存柊璁惧鐘舵�侊紝
+     *
+     * @param request
+     * @param sleepTime 寤惰繜鎵ц鏃堕棿=姣鍊硷紝濡傛灉==0 锛岃〃绀轰笉寤惰繜
+     */
+    @Async
+    public void analysisDevice(DeviceControlRequest request, long sleepTime) {
+
+        try {
+            if (sleepTime > 0) {
+                Thread.sleep(sleepTime);
+            }
+
+            deviceService.updateStatus(request.getCompanyId(), request.getSerId(), ServerUtil.getStatusMap());
+
+            notifyInvoker.notifyAnalysisStatusSuccess(request.getCompanyId(), request.getSerId(), OrderRespEnum.MSG_SUCCESS, "璁惧鐘舵�佹煡璇㈡垚鍔熷苟瀹屾垚瑙f瀽锛�");
+
+        } catch (Exception e) {
+            log.error("---MODBUS-TCP-鐘舵�佽В鏋愬紓甯竰}", e);
+        }
+    }
+}
diff --git a/igds-protocol-modbus/src/main/java/com/ld/igds/protocol/modbus/command/RemoteControlServiceImpl.java b/igds-protocol-modbus/src/main/java/com/ld/igds/protocol/modbus/command/RemoteControlServiceImpl.java
index 0af4436..32d867b 100644
--- a/igds-protocol-modbus/src/main/java/com/ld/igds/protocol/modbus/command/RemoteControlServiceImpl.java
+++ b/igds-protocol-modbus/src/main/java/com/ld/igds/protocol/modbus/command/RemoteControlServiceImpl.java
@@ -13,6 +13,7 @@
 import com.ld.igds.io.response.DeviceControlResponse;
 import com.ld.igds.models.Device;
 import com.ld.igds.protocol.modbus.ModbusUtil;
+import com.ld.igds.protocol.modbus.ServerUtil;
 import com.ld.igds.protocol.modbus.data.ModbusTcp;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Component;
@@ -36,7 +37,10 @@
     @Resource
     private CoreDeviceService deviceService;
     @Resource
+    private AnalysisService analysisService;
+    @Resource
     private ModbusUtil modbusUtil;
+
 
     @Override
     public String getProtocol() {
@@ -51,14 +55,11 @@
             return new DeviceControlResponse(OrderRespEnum.ORDER_ERROR.getCode(), "娌℃湁闇�瑕佹墽琛岀殑璁惧");
         }
 
-
         try {
-
-
             Device device;
             ModbusTcp modbusTcp;
-            String[] addr;
-            String temp;
+            ModbusTcp modbusTcpLink = null;
+            String temp = Constant.YN_N;
             int addrExe = 65535;
             for (ExeDevice exeDevice : deviceList) {
                 device = deviceService.getCacheDeviceById(exeDevice.getCompanyId(), exeDevice.getId());
@@ -67,79 +68,200 @@
 
                 if (null == device.getModbus()) continue;
 
-                modbusTcp = new ModbusTcp();
+                modbusTcp = new ModbusTcp(device.getModbus());
                 modbusTcp.setIp(request.getIp());
                 modbusTcp.setPort(request.getPort());
-                modbusTcp.setDeviceId(device.getId());
+                modbusTcp.setDeviceCode(device.getPassCode() + "");
                 modbusTcp.setSerId(request.getSerId());
+                modbusTcp.setCompanyId(request.getCompanyId());
 
-                //modbus瑙勫垯锛氬紑鍦板潃-鍏冲湴鍧�-鍋滃湴鍧�-寮�鍒颁綅-鍏冲埌浣�-寮�鏁呴殰-鍏虫晠闅滐紝鏃犲湴鍧�鐢∟浠f浛
-                addr = device.getModbus().split("-");
-                temp = addr[0];
-                if (!Constant.YN_N.equals(temp)) modbusTcp.setAddrOpen(temp);
-                temp = addr[1];
-                if (!Constant.YN_N.equals(temp)) modbusTcp.setAddrClose(temp);
-                temp = addr[2];
-                if (!Constant.YN_N.equals(temp)) modbusTcp.setAddrStop(temp);
-                temp = addr[3];
-                if (!Constant.YN_N.equals(temp)) modbusTcp.setAddrOpenEnd(temp);
-                temp = addr[4];
-                if (!Constant.YN_N.equals(temp)) modbusTcp.setAddrCloseEnd(temp);
-                temp = addr[5];
-                if (!Constant.YN_N.equals(temp)) modbusTcp.setAddrOpenError(temp);
-                temp = addr[6];
-                if (!Constant.YN_N.equals(temp)) modbusTcp.setAddrCloseError(temp);
-
+                if (null != device.getLinkModbus()) {
+                    modbusTcpLink = new ModbusTcp(device.getLinkModbus());
+                    modbusTcpLink.setIp(request.getIp());
+                    modbusTcpLink.setPort(request.getPort());
+                    modbusTcpLink.setDeviceCode(device.getLink());
+                    modbusTcpLink.setSerId(request.getSerId());
+                    modbusTcpLink.setCompanyId(request.getCompanyId());
+                }
 
                 //鏍规嵁璁惧鐩爣鐩爣鐘舵�侊紝閫夋嫨闇�瑕佹墽琛岀殑閫氶亾
                 if (DeviceStatus.CLOSE.getCode().equals(device.getTargetStatus())) {
-                    addrExe = Integer.valueOf(modbusTcp.getAddrClose());
+                    temp = modbusTcp.getAddrClose();
                 }
 
-                if(DeviceStatus.OPEN.getCode().equals(device.getTargetStatus())){
-                    addrExe = Integer.valueOf(modbusTcp.getAddrOpen());
+                if (DeviceStatus.OPEN.getCode().equals(device.getTargetStatus())) {
+                    temp = modbusTcp.getAddrOpen();
+                }
+
+                if (null == modbusTcpLink) {
+                    //鏍规嵁璁惧鐩爣鐘舵�侊紝璋冪敤MODBUS鎵ц
+                    addrExe = Integer.valueOf(temp) - 1;
+                    modbusTcp.setAddrExe(addrExe);
+                    doExe(modbusTcp, device.getTargetStatus());
+                    continue;
                 }
 
 
-                //TODO 鍏朵粬鐘舵�佸緟瀹�
+                //濡傛灉鏄紑椋庢満
+                if (DeviceStatus.F_OPEN.getCode().equals(device.getTargetStatus())) {
 
-                //鏍规嵁璁惧鐩爣鐘舵�侊紝璋冪敤MODBUS鎵ц
-                modbusUtil.writeCoil(modbusTcp.getIp(), modbusTcp.getPort(),addrExe, true);
+                    //鍏堝紑绐楀彛
+                    temp = modbusTcp.getAddrOpen();
+                    addrExe = Integer.valueOf(temp) - 1;
+                    modbusTcp.setAddrExe(addrExe);
+
+                    doExe(modbusTcp, DeviceStatus.OPEN.getCode());
+
+
+                    Thread.sleep(300);
+
+                    //鍐嶅紑椋庢満
+                    temp = modbusTcpLink.getAddrOpen();
+                    addrExe = Integer.valueOf(temp) - 1;
+                    modbusTcpLink.setAddrExe(addrExe);
+
+                    doExe(modbusTcpLink, DeviceStatus.OPEN.getCode());
+                }
+
+                //濡傛灉鍏抽鏈�
+                if(DeviceStatus.F_CLOSE.equals(device.getTargetStatus())){
+                    temp = modbusTcpLink.getAddrClose();
+                    addrExe = Integer.valueOf(temp) - 1;
+                    modbusTcpLink.setAddrExe(addrExe);
+
+                    doExe(modbusTcpLink, DeviceStatus.CLOSE.getCode());
+                }
+
+
+                //濡傛灉寮�绐�
+                if(DeviceStatus.W_OPEN.equals(device.getTargetStatus())){
+                    temp = modbusTcp.getAddrOpen();
+                    addrExe = Integer.valueOf(temp) - 1;
+                    modbusTcp.setAddrExe(addrExe);
+
+                    doExe(modbusTcp, device.getTargetStatus());
+                }
+
+                //濡傛灉鏄叧绐楁埛
+                if(DeviceStatus.W_CLOSE.equals(device.getTargetStatus())){
+
+                    //鍏堝叧椋庢満
+                    temp = modbusTcpLink.getAddrClose();
+                    addrExe = Integer.valueOf(temp) - 1;
+                    modbusTcpLink.setAddrExe(addrExe);
+                    doExe(modbusTcpLink, DeviceStatus.CLOSE.getCode());
+
+                    Thread.sleep(300);
+
+                    //鍦ㄥ叧绐楁埛
+                    temp = modbusTcp.getAddrClose();
+                    addrExe = Integer.valueOf(temp) - 1;
+                    modbusTcp.setAddrExe(addrExe);
+
+                    doExe(modbusTcp, DeviceStatus.CLOSE.getCode());
+                }
 
             }
         } catch (Exception e) {
-
+            log.error("璋冪敤MODBUS-TCP鎵ц寮傚父锛歿}", e);
+            return new DeviceControlResponse(OrderRespEnum.ORDER_ERROR.getCode(), "鍚庡彴鎵ц寮傚父锛�" + e.getMessage());
         }
 
         return new DeviceControlResponse(OrderRespEnum.ORDER_SUCCESS);
     }
 
+    private void doExe(ModbusTcp modbusTcp, String targetStatus) throws Exception {
+        boolean exeResult = modbusUtil.writeValue05(modbusTcp.getIp(), modbusTcp.getPort(), modbusTcp.getAddrExe(), true);
+        if (exeResult) {
+            ServerUtil.add2StatusMap(modbusTcp.getCompanyId(), modbusTcp.getSerId(), modbusTcp.getDeviceCode(), targetStatus);
+        }
+    }
+
 
     @Override
     public DeviceControlResponse closeAll(DeviceControlRequest request) {
-        return null;
+        return new DeviceControlResponse(OrderRespEnum.ORDER_ERROR.getCode(), "缁堢鏌滀綋涓嶆敮鎸�");
     }
 
     @Override
     public DeviceControlResponse queryStatus(DeviceControlRequest request) {
-        return null;
+        try {
+            List<Device> list = deviceService.getCacheDeviceBySerId(request.getCompanyId(), request.getSerId());
+
+            if (null == list || list.isEmpty()) {
+                return new DeviceControlResponse(OrderRespEnum.ORDER_ERROR.getCode(), "鏈幏鍙栧埌璁惧鍒楄〃淇℃伅");
+            }
+
+            ModbusTcp modbusTcp;
+            ModbusTcp modbusTcpLink;
+            int addrStart;
+            boolean[] result;
+            for (Device device : list) {
+                if (null == device.getModbus()) continue;
+                modbusTcp = new ModbusTcp(device.getModbus());
+                modbusTcp.setIp(request.getIp());
+                modbusTcp.setPort(request.getPort());
+                modbusTcp.setDeviceCode(device.getPassCode() + "");
+                modbusTcp.setSerId(request.getSerId());
+
+                addrStart = Integer.valueOf(modbusTcp.getAddrOpenEnd()) - 1;
+
+                result = modbusUtil.readStatus02(modbusTcp.getIp(), modbusTcp.getPort(), addrStart, 2);
+                log.debug("---------璇诲彇鐘舵��------{}--{}", modbusTcp.getDeviceCode(), result.toString());
+                analysisResult(device.getCompanyId(), device.getSerId(), modbusTcp.getDeviceCode(), result);
+
+                if (null != device.getLinkModbus()) {
+                    Thread.sleep(300);
+                    modbusTcpLink = new ModbusTcp(device.getModbus());
+                    modbusTcpLink.setIp(request.getIp());
+                    modbusTcpLink.setPort(request.getPort());
+                    modbusTcpLink.setSerId(request.getSerId());
+                    modbusTcpLink.setDeviceCode(device.getLink());
+                    addrStart = Integer.valueOf(modbusTcpLink.getAddrOpenEnd()) - 1;
+                    result = modbusUtil.readStatus02(modbusTcpLink.getIp(), modbusTcpLink.getPort(), addrStart, 2);
+                    log.debug("---------璇诲彇鐘舵��-LINK------{}--{}", modbusTcpLink.getDeviceCode(), result.toString());
+
+                    analysisResult(device.getCompanyId(), device.getSerId(), modbusTcpLink.getDeviceCode(), result);
+                }
+            }
+
+        } catch (Exception e) {
+            log.error("璋冪敤MODBUS-TCP鎵ц寮傚父锛歿}", e);
+            return new DeviceControlResponse(OrderRespEnum.ORDER_ERROR.getCode(), "鍚庡彴鎵ц寮傚父锛�" + e.getMessage());
+        }
+
+        analysisService.analysisDevice(request, 3000);
+
+        return new DeviceControlResponse(OrderRespEnum.ORDER_SUCCESS);
+    }
+
+    /**
+     * 杩斿洖涓や綅锛岀涓�浣嶆槸寮�鍒颁綅锛岀浜屼綅鏄叧鍒颁綅锛屾牴鎹繖涓や釜鏍囪纭褰撳墠璁惧鐨勭姸鎬�
+     *
+     * @param deviceCode
+     * @param result
+     */
+    private void analysisResult(String companyId, String serId, String deviceCode, boolean[] result) {
+        if (result[0]) {
+            ServerUtil.add2StatusMap(companyId, serId, deviceCode, DeviceStatus.OPEN.getCode());
+        }
+        if (result[1]) {
+            ServerUtil.add2StatusMap(companyId, serId, deviceCode, DeviceStatus.CLOSE.getCode());
+        }
     }
 
     @Override
     public DeviceControlResponse tempControl(TempControlRequest request) {
-        return null;
+        return new DeviceControlResponse(OrderRespEnum.ORDER_ERROR.getCode(), "缁堢鏌滀綋鏈帴鍏ュ綋鍓嶆帶鍒�");
     }
 
     @Override
     public DeviceControlResponse airAutoControl(DeviceAutoControlRequest request) {
-
-
-        return null;
+        return new DeviceControlResponse(OrderRespEnum.ORDER_ERROR.getCode(), "缁堢鏌滀綋鏈帴鍏ュ綋鍓嶆帶鍒�");
     }
 
     @Override
     public DeviceControlResponse n2AutoControl(DeviceAutoControlRequest request) {
-
-        return null;
+        return new DeviceControlResponse(OrderRespEnum.ORDER_ERROR.getCode(), "缁堢鏌滀綋鏈帴鍏ュ綋鍓嶆帶鍒�");
     }
 }
diff --git a/igds-protocol-modbus/src/main/java/com/ld/igds/protocol/modbus/data/ModbusTcp.java b/igds-protocol-modbus/src/main/java/com/ld/igds/protocol/modbus/data/ModbusTcp.java
index 49d1ebc..88d5d63 100644
--- a/igds-protocol-modbus/src/main/java/com/ld/igds/protocol/modbus/data/ModbusTcp.java
+++ b/igds-protocol-modbus/src/main/java/com/ld/igds/protocol/modbus/data/ModbusTcp.java
@@ -1,5 +1,6 @@
 package com.ld.igds.protocol.modbus.data;
 
+import com.ld.igds.constant.Constant;
 import lombok.Data;
 
 /**
@@ -10,7 +11,10 @@
 @Data
 public class ModbusTcp {
 
-    private String deviceId;
+
+    private String companyId;
+    
+    private String deviceCode;
 
     private String serId;
 
@@ -21,36 +25,73 @@
     /**
      * 寮�鍦板潃
      **/
-    private String addrOpen = "65535";
+    private String addrOpen = Constant.YN_N;
 
     /**
      * 鍏冲湴鍧�
      **/
-    private String addrClose = "65535";
+    private String addrClose = Constant.YN_N;
 
     /**
      * 鍋滃湴鍧�
      **/
-    private String addrStop = "65535";
+    private String addrStop = Constant.YN_N;
 
     /**
      * 寮�鍒颁綅鍦板潃
      **/
-    private String addrOpenEnd = "65535";
+    private String addrOpenEnd = Constant.YN_N;
 
     /**
      * 鍏冲埌浣嶅湴鍧�
      **/
-    private String addrCloseEnd = "65535";
+    private String addrCloseEnd = Constant.YN_N;
 
     /**
      * 寮�鏁呴殰鍦板潃
      **/
-    private String addrOpenError = "65535";
+    private String addrOpenError = Constant.YN_N;
 
     /**
      * 鍏虫晠闅滃湴鍧�
      **/
-    private String addrCloseError = "65535";
+    private String addrCloseError = Constant.YN_N;
 
+    private int addrExe = 65535;
+
+
+    public ModbusTcp() {
+        super();
+    }
+
+    public ModbusTcp(String modbusStr) {
+        //modbus瑙勫垯锛氬紑鍦板潃-鍏冲湴鍧�-鍋滃湴鍧�-寮�鍒颁綅-鍏冲埌浣�-寮�鏁呴殰-鍏虫晠闅滐紝鏃犲湴鍧�鐢∟浠f浛
+        String[] addr = modbusStr.split("-");
+        this.addrOpen = addr[0];
+        this.addrClose = addr[1];
+        this.addrStop = addr[2];
+        this.addrOpenEnd = addr[3];
+        this.addrCloseEnd = addr[4];
+        this.addrOpenError = addr[5];
+        this.addrCloseError = addr[6];
+    }
+//
+//    public ModbusTcp(String modbusStr) {
+//        //modbus瑙勫垯锛氬紑鍦板潃-鍏冲湴鍧�-鍋滃湴鍧�-寮�鍒颁綅-鍏冲埌浣�-寮�鏁呴殰-鍏虫晠闅滐紝鏃犲湴鍧�鐢∟浠f浛
+//        String[] addr = modbusStr.split("-");
+//        String temp = addr[0];
+//        if (!Constant.YN_N.equals(temp)) this.addrOpen = temp;
+//        temp = addr[1];
+//        if (!Constant.YN_N.equals(temp)) this.addrClose = temp;
+//        temp = addr[2];
+//        if (!Constant.YN_N.equals(temp)) this.addrStop = temp;
+//        temp = addr[3];
+//        if (!Constant.YN_N.equals(temp)) this.addrOpenEnd = temp;
+//        temp = addr[4];
+//        if (!Constant.YN_N.equals(temp)) this.addrCloseEnd = temp;
+//        temp = addr[5];
+//        if (!Constant.YN_N.equals(temp)) this.addrOpenError = temp;
+//        temp = addr[6];
+//        if (!Constant.YN_N.equals(temp)) this.addrCloseError = temp;
+//    }
 }
diff --git a/igds-verb/src/main/java/com/ld/igds/verb/controller/VerbController.java b/igds-verb/src/main/java/com/ld/igds/verb/controller/VerbController.java
index 0733cdf..de89e50 100644
--- a/igds-verb/src/main/java/com/ld/igds/verb/controller/VerbController.java
+++ b/igds-verb/src/main/java/com/ld/igds/verb/controller/VerbController.java
@@ -64,10 +64,6 @@
             deptId = ContextUtil.subDeptId(user);
         }
 
-        // 鑾峰彇褰撳墠鐢ㄦ埛鎵�鍦ㄧ殑鍒嗗簱鍚嶇О
-//        DefaultDept dept = commonManager.getSubDept(user, deptId);
-//        view.addObject("dept", dept);
-
         view.addObject("deptId", deptId);
 
         // 鑾峰彇褰撳墠閮ㄩ棬锛屾墍鏈変粨搴撳垪琛�
diff --git a/igds-verb/src/main/java/com/ld/igds/verb/manager/VerbManager.java b/igds-verb/src/main/java/com/ld/igds/verb/manager/VerbManager.java
index 025a32a..38ea75f 100644
--- a/igds-verb/src/main/java/com/ld/igds/verb/manager/VerbManager.java
+++ b/igds-verb/src/main/java/com/ld/igds/verb/manager/VerbManager.java
@@ -5,7 +5,10 @@
 import com.ld.igds.common.CoreSerService;
 import com.ld.igds.common.DepotStatusService;
 import com.ld.igds.common.dto.DepotSerData;
-import com.ld.igds.constant.*;
+import com.ld.igds.constant.BizType;
+import com.ld.igds.constant.DepotType;
+import com.ld.igds.constant.DeviceType;
+import com.ld.igds.constant.RespCodeEnum;
 import com.ld.igds.data.PageResponse;
 import com.ld.igds.io.RemoteControlService;
 import com.ld.igds.io.RemoteManager;
@@ -22,11 +25,10 @@
 import com.ld.igds.util.ContextUtil;
 import com.ld.igds.verb.AreationModel;
 import com.ld.igds.verb.dto.VerbParam;
-import com.ld.igds.verb.service.CoreAreationService;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
+import javax.annotation.Resource;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -41,19 +43,17 @@
 @Component
 public class VerbManager {
 
-    @Autowired
+    @Resource
     private CoreCommonService coreCommonService;
-    @Autowired
+    @Resource
     private CoreDeviceService coreDeviceService;
-    @Autowired
+    @Resource
     private ExeOrderService exeOrderService;
-    @Autowired
+    @Resource
     private RemoteManager remoteManager;
-    @Autowired
+    @Resource
     private CoreSerService coreSerService;
-    @Autowired
-    private CoreAreationService areationService;
-    @Autowired
+    @Resource
     private DepotStatusService depotCheckService;
 
     private RemoteControlService remoteControlService;
@@ -243,11 +243,11 @@
         // 鑾峰彇鍒嗘満淇℃伅
         DeviceSer deviceSer = coreSerService.getCacheSer(param.getCompanyId(), serId);
 
-        if (Constant.YN_N.equals(deviceSer.getStatus())) {
-            return new DeviceControlResponse(
-                    OrderRespEnum.ORDER_ERROR.getCode(),
-                    "褰撳墠璁惧鎵�灞炴帶鍒舵煖[" + deviceSer.getName() + "]涓嶅湪绾匡紝鎵ц澶辫触銆�");
-        }
+//        if (Constant.YN_N.equals(deviceSer.getStatus())) {
+//            return new DeviceControlResponse(
+//                    OrderRespEnum.ORDER_ERROR.getCode(),
+//                    "褰撳墠璁惧鎵�灞炴帶鍒舵煖[" + deviceSer.getName() + "]涓嶅湪绾匡紝鎵ц澶辫触銆�");
+//        }
 
         DeviceControlRequest request = new DeviceControlRequest();
         request.setDepotId(param.getDepotId());
diff --git a/igds-web/.rules b/igds-web/.rules
index 1dc7dd5..e57472a 100644
--- a/igds-web/.rules
+++ b/igds-web/.rules
@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <RuleSet version="1.1"><PackageInfos>
 <PackageInfo name="dorado-core" version="7.6.0.2.190128.1750"/>
-<PackageInfo name="dorado-uploader" version="1.0.20-SNAPSHOT"/>
 <PackageInfo name="bdf2-orm" version="2.1.0"/>
 <PackageInfo name="bdf2-core" version="2.0.9"/>
-<PackageInfo name="bdf2-job" version="2.0.5-SNAPSHOT"/>
+<PackageInfo name="dorado-uploader" version="1.0.20-SNAPSHOT"/>
 <PackageInfo name="dorado-skin-sky" version="2.0.2"/>
+<PackageInfo name="bdf2-job" version="2.0.5-SNAPSHOT"/>
 <PackageInfo name="dorado-intro" version="0.2.1.140715.2255"/>
 <PackageInfo name="bdf2-swfviewer" version="2.0.6-SNAPSHOT"/>
 <PackageInfo name="bdf2-export" version="2.0.8"/>
@@ -283,7 +283,7 @@
 <Prop name="verticalText" type="boolean"/></Props><Children><Child rule="Tab" name="Tab" aggregated="true" public="false"></Child></Children></Rule><Rule name="ToolBar" parents="com.bstek.dorado.view.widget.Control" label="ToolBar" type="com.bstek.dorado.view.widget.base.toolbar.ToolBar" sortFactor="2023" category="General" icon="/com/bstek/dorado/view/widget/base/toolbar/ToolBar.png" clientTypes="desktop"><Props>
 <Prop name="fixRight" type="boolean"/>
 <Prop name="height" visible="false"/>
-<Prop name="showMenuOnHover" defaultValue="false" type="boolean"/></Props><Children><Child rule="Fill" name="Fill" aggregated="true"></Child><Child rule="MenuButton" name="MenuButton" aggregated="true"></Child><Child rule="com.bstek.dorado.view.widget.base.toolbar.Separator" name="Separator" aggregated="true"></Child><Child rule="com.bstek.dorado.view.widget.base.toolbar.Button" name="ToolBarButton" aggregated="true"></Child><Child rule="com.bstek.dorado.view.widget.base.toolbar.Label" name="ToolBarLabel" aggregated="true"></Child><Child rule="com.bstek.dorado.view.widget.Control" name="Items" aggregated="true"></Child></Children></Rule><Rule name="SplitPanel" parents="com.bstek.dorado.view.widget.Control" label="SplitPanel" type="com.bstek.dorado.view.widget.base.SplitPanel" sortFactor="2024" category="General" icon="/com/bstek/dorado/view/widget/base/SplitPanel.png" clientTypes="desktop"><Props>
+<Prop name="showMenuOnHover" defaultValue="false" type="boolean"/></Props><Children><Child rule="com.bstek.dorado.view.widget.base.toolbar.Button" name="ToolBarButton" aggregated="true"></Child><Child rule="Separator" name="Separator" aggregated="true"></Child><Child rule="com.bstek.dorado.view.widget.base.toolbar.Label" name="ToolBarLabel" aggregated="true"></Child><Child rule="MenuButton" name="MenuButton" aggregated="true"></Child><Child rule="Fill" name="Fill" aggregated="true"></Child><Child rule="com.bstek.dorado.view.widget.Control" name="Items" aggregated="true"></Child></Children></Rule><Rule name="SplitPanel" parents="com.bstek.dorado.view.widget.Control" label="SplitPanel" type="com.bstek.dorado.view.widget.base.SplitPanel" sortFactor="2024" category="General" icon="/com/bstek/dorado/view/widget/base/SplitPanel.png" clientTypes="desktop"><Props>
 <Prop name="animate" type="java.lang.Boolean"/>
 <Prop name="collapseBothSide" defaultValue="false" type="boolean"/>
 <Prop name="collapseable" defaultValue="true" type="boolean"/>
@@ -889,7 +889,11 @@
 <ClientEvent name="onTabContextMenu" parameters="self,arg"/>
 <ClientEvent name="onTabChange" parameters="self,arg"/>
 <ClientEvent name="onTabRemove" parameters="self,arg"/>
-<ClientEvent name="beforeTabChange" parameters="self,arg"/></ClientEvents></Rule><Rule name="Fill" parents="com.bstek.dorado.view.widget.Control" label="Fill" type="com.bstek.dorado.view.widget.base.toolbar.Fill" scope="protected" category="ToolBar" icon="/com/bstek/dorado/view/widget/base/toolbar/Fill.png" clientTypes="desktop"></Rule><Rule name="MenuButton" parents="Button" label="MenuButton" nodeName="MenuButton" type="com.bstek.dorado.view.widget.base.toolbar.MenuButton" scope="protected" category="ToolBar" icon="/com/bstek/dorado/view/widget/base/toolbar/MenuButton.png" clientTypes="desktop"><Props>
+<ClientEvent name="beforeTabChange" parameters="self,arg"/></ClientEvents></Rule><Rule name="com.bstek.dorado.view.widget.base.toolbar.Button" parents="Button" label="ToolBarButton" nodeName="ToolBarButton" type="com.bstek.dorado.view.widget.base.toolbar.Button" scope="protected" category="ToolBar" icon="/com/bstek/dorado/view/widget/base/toolbar/Button.png" clientTypes="desktop"><Props>
+<Prop name="hideMenuOnMouseLeave" type="boolean"/>
+<Prop name="hideMenuOnMouseLeaveDelay" defaultValue="300" type="int"/>
+<Prop name="showMenuOnHover" defaultValue="false" type="boolean"/></Props></Rule><Rule name="Separator" parents="com.bstek.dorado.view.widget.Control" label="Separator" type="com.bstek.dorado.view.widget.base.toolbar.Separator" scope="protected" category="ToolBar" icon="/com/bstek/dorado/view/widget/base/toolbar/Separator.png" clientTypes="desktop"></Rule><Rule name="com.bstek.dorado.view.widget.base.toolbar.Label" parents="com.bstek.dorado.view.widget.Control" label="Label" nodeName="ToolBarLabel" type="com.bstek.dorado.view.widget.base.toolbar.Label" scope="protected" category="ToolBar" icon="/com/bstek/dorado/view/widget/base/toolbar/Label.png" clientTypes="desktop"><Props>
+<Prop name="text"/></Props></Rule><Rule name="MenuButton" parents="Button" label="MenuButton" nodeName="MenuButton" type="com.bstek.dorado.view.widget.base.toolbar.MenuButton" scope="protected" category="ToolBar" icon="/com/bstek/dorado/view/widget/base/toolbar/MenuButton.png" clientTypes="desktop"><Props>
 <Prop name="hideMenuOnMouseLeave" type="boolean"/>
 <Prop name="hideMenuOnMouseLeaveDelay" defaultValue="300" type="int"/>
 <Prop name="menu" deprecated="true" visible="false"/>
@@ -907,7 +911,7 @@
 <Prop name="hideOnClick" defaultValue="true" type="boolean"/>
 <Prop name="icon"/>
 <Prop name="iconClass"/></Props><ClientEvents>
-<ClientEvent name="onClick" parameters="self,arg"/></ClientEvents></Rule><Rule name="Separator" parents="BaseMenuItem" label="Separator" type="com.bstek.dorado.view.widget.base.menu.Separator" icon="/com/bstek/dorado/view/widget/base/menu/Separator.png" clientTypes="desktop,touch"></Rule><Rule name="ControlMenuItem" parents="TextMenuItem" label="ControlMenuItem" type="com.bstek.dorado.view.widget.base.menu.ControlMenuItem" icon="/com/bstek/dorado/view/widget/base/menu/ControlMenuItem.png" clientTypes="desktop"><Children><Child rule="FloatControl" name="Control"></Child></Children></Rule><Rule name="FloatControl" abstract="true" type="com.bstek.dorado.view.widget.FloatControl"><Props>
+<ClientEvent name="onClick" parameters="self,arg"/></ClientEvents></Rule><Rule name="ControlMenuItem" parents="TextMenuItem" label="ControlMenuItem" type="com.bstek.dorado.view.widget.base.menu.ControlMenuItem" icon="/com/bstek/dorado/view/widget/base/menu/ControlMenuItem.png" clientTypes="desktop"><Children><Child rule="FloatControl" name="Control"></Child></Children></Rule><Rule name="FloatControl" abstract="true" type="com.bstek.dorado.view.widget.FloatControl"><Props>
 <Prop name="align" enumValues="left,innerleft,center,innerright,top" visible="false"/>
 <Prop name="anchorTarget" visible="false"/>
 <Prop name="animateTarget" visible="false"/>
@@ -928,14 +932,10 @@
 <Prop name="shadowMode" enumValues="drop,sides,frame,none"/>
 <Prop name="showAnimateType" enumValues="zoom,modernZoom,flip,slide,safeSlide,modernSlide,fade,none"/>
 <Prop name="top" type="int"/>
-<Prop name="vAlign" enumValues="top,innertop,center,innerbottom,bottom" visible="false"/></Props></Rule><Rule name="CheckableMenuItem" parents="MenuItem" label="CheckableMenuItem" type="com.bstek.dorado.view.widget.base.menu.CheckableMenuItem" icon="/com/bstek/dorado/view/widget/base/menu/CheckableMenuItem.png" clientTypes="desktop"><Props>
+<Prop name="vAlign" enumValues="top,innertop,center,innerbottom,bottom" visible="false"/></Props></Rule><Rule name="com.bstek.dorado.view.widget.base.menu.Separator" parents="BaseMenuItem" label="Separator" type="com.bstek.dorado.view.widget.base.menu.Separator" icon="/com/bstek/dorado/view/widget/base/menu/Separator.png" clientTypes="desktop,touch"></Rule><Rule name="CheckableMenuItem" parents="MenuItem" label="CheckableMenuItem" type="com.bstek.dorado.view.widget.base.menu.CheckableMenuItem" icon="/com/bstek/dorado/view/widget/base/menu/CheckableMenuItem.png" clientTypes="desktop"><Props>
 <Prop name="checked" type="boolean"/>
 <Prop name="group"/></Props><ClientEvents>
-<ClientEvent name="onCheckedChange" parameters="self,arg"/></ClientEvents></Rule><Rule name="com.bstek.dorado.view.widget.base.toolbar.Separator" parents="com.bstek.dorado.view.widget.Control" label="Separator" type="com.bstek.dorado.view.widget.base.toolbar.Separator" scope="protected" category="ToolBar" icon="/com/bstek/dorado/view/widget/base/toolbar/Separator.png" clientTypes="desktop"></Rule><Rule name="com.bstek.dorado.view.widget.base.toolbar.Button" parents="Button" label="ToolBarButton" nodeName="ToolBarButton" type="com.bstek.dorado.view.widget.base.toolbar.Button" scope="protected" category="ToolBar" icon="/com/bstek/dorado/view/widget/base/toolbar/Button.png" clientTypes="desktop"><Props>
-<Prop name="hideMenuOnMouseLeave" type="boolean"/>
-<Prop name="hideMenuOnMouseLeaveDelay" defaultValue="300" type="int"/>
-<Prop name="showMenuOnHover" defaultValue="false" type="boolean"/></Props></Rule><Rule name="com.bstek.dorado.view.widget.base.toolbar.Label" parents="com.bstek.dorado.view.widget.Control" label="Label" nodeName="ToolBarLabel" type="com.bstek.dorado.view.widget.base.toolbar.Label" scope="protected" category="ToolBar" icon="/com/bstek/dorado/view/widget/base/toolbar/Label.png" clientTypes="desktop"><Props>
-<Prop name="text"/></Props></Rule><Rule name="Section" parents="ClientEventSupportedElement" label="Section" type="com.bstek.dorado.view.widget.base.accordion.Section" icon="/com/bstek/dorado/view/widget/base/accordion/Section.png"><Props>
+<ClientEvent name="onCheckedChange" parameters="self,arg"/></ClientEvents></Rule><Rule name="Fill" parents="com.bstek.dorado.view.widget.Control" label="Fill" type="com.bstek.dorado.view.widget.base.toolbar.Fill" scope="protected" category="ToolBar" icon="/com/bstek/dorado/view/widget/base/toolbar/Fill.png" clientTypes="desktop"></Rule><Rule name="Section" parents="ClientEventSupportedElement" label="Section" type="com.bstek.dorado.view.widget.base.accordion.Section" icon="/com/bstek/dorado/view/widget/base/accordion/Section.png"><Props>
 <Prop name="caption"/>
 <Prop name="className"/>
 <Prop name="disabled" type="boolean"/>
@@ -1011,14 +1011,15 @@
 <Prop name="visible" defaultValue="true" type="boolean"/></Props><ClientEvents>
 <ClientEvent name="onGetCellEditor" parameters="self,arg"/>
 <ClientEvent name="onHeaderClick" parameters="self,arg"/>
-<ClientEvent name="onRenderHeaderCell" parameters="self,arg"/></ClientEvents></Rule><Rule name="AbstractDataColumn" parents="Column" abstract="true" type="com.bstek.dorado.view.widget.grid.AbstractDataColumn"><Props>
+<ClientEvent name="onRenderHeaderCell" parameters="self,arg"/></ClientEvents></Rule><Rule name="RowNumColumn" parents="AbstractDataColumn" label="RowNumColumn" type="com.bstek.dorado.view.widget.grid.RowNumColumn" icon="/com/bstek/dorado/view/widget/grid/RowNumColumn.png"></Rule><Rule name="AbstractDataColumn" parents="Column" abstract="true" type="com.bstek.dorado.view.widget.grid.AbstractDataColumn"><Props>
 <Prop name="filterBarRenderer"/>
 <Prop name="footerRenderer"/>
 <Prop name="renderer"/>
 <Prop name="resizeable" defaultValue="true" type="boolean"/>
 <Prop name="width"/></Props><ClientEvents>
 <ClientEvent name="onRenderFooterCell" parameters="self,arg"/>
-<ClientEvent name="onRenderCell" parameters="self,arg"/></ClientEvents></Rule><Rule name="DataColumn" parents="AbstractDataColumn" label="DataColumn" type="com.bstek.dorado.view.widget.grid.DataColumn" icon="/com/bstek/dorado/view/widget/grid/DataColumn.png" labelProperty="name,property"><Props>
+<ClientEvent name="onRenderCell" parameters="self,arg"/></ClientEvents></Rule><Rule name="IndicatorColumn" parents="AbstractDataColumn" label="IndicatorColumn" type="com.bstek.dorado.view.widget.grid.IndicatorColumn" icon="/com/bstek/dorado/view/widget/grid/IndicatorColumn.png"></Rule><Rule name="ColumnGroup" parents="Column" label="ColumnGroup" type="com.bstek.dorado.view.widget.grid.ColumnGroup" icon="/com/bstek/dorado/view/widget/grid/ColumnGroup.png"><Props>
+<Prop name="align" enumValues="left,center,right" visible="false"/></Props><Children><Child rule="Column" name="Columns" aggregated="true"></Child></Children></Rule><Rule name="DataColumn" parents="AbstractDataColumn" label="DataColumn" type="com.bstek.dorado.view.widget.grid.DataColumn" icon="/com/bstek/dorado/view/widget/grid/DataColumn.png" labelProperty="name,property"><Props>
 <Prop name="align" enumValues="left,center,right"/>
 <Prop name="dataType" type="com.bstek.dorado.data.type.DataType"/>
 <Prop name="defaultFilterOperator"/>
@@ -1033,8 +1034,7 @@
 <Prop name="summaryType" enumValues="sum,average,count,max,min"/>
 <Prop name="trigger" enumValues="triggerClear,autoMappingDropDown1,autoMappingDropDown2,autoOpenMappingDropDown1,autoOpenMappingDropDown2,defaultDateDropDown,defaultDateTimeDropDown,defaultYearMonthDropDown,defaultYearDropDown,defaultMonthDropDown" reference="Trigger:id"/>
 <Prop name="typeFormat"/>
-<Prop name="wrappable" type="boolean"/></Props><Children><Child name="Editor" fixed="true"><Rule name="Wrapper.Editor" label="Editor" nodeName="Editor" icon="/com/bstek/dorado/view/widget/grid/Editor.png"><Children><Child rule="com.bstek.dorado.view.widget.Control" name="Editor"></Child></Children></Rule></Child></Children></Rule><Rule name="ColumnGroup" parents="Column" label="ColumnGroup" type="com.bstek.dorado.view.widget.grid.ColumnGroup" icon="/com/bstek/dorado/view/widget/grid/ColumnGroup.png"><Props>
-<Prop name="align" enumValues="left,center,right" visible="false"/></Props><Children><Child rule="Column" name="Columns" aggregated="true"></Child></Children></Rule><Rule name="RowNumColumn" parents="AbstractDataColumn" label="RowNumColumn" type="com.bstek.dorado.view.widget.grid.RowNumColumn" icon="/com/bstek/dorado/view/widget/grid/RowNumColumn.png"></Rule><Rule name="RowSelectorColumn" parents="AbstractDataColumn" label="RowSelectorColumn" type="com.bstek.dorado.view.widget.grid.RowSelectorColumn" icon="/com/bstek/dorado/view/widget/grid/RowSelectorColumn.png"></Rule><Rule name="IndicatorColumn" parents="AbstractDataColumn" label="IndicatorColumn" type="com.bstek.dorado.view.widget.grid.IndicatorColumn" icon="/com/bstek/dorado/view/widget/grid/IndicatorColumn.png"></Rule><Rule name="AbstractList" parents="com.bstek.dorado.view.widget.Control" abstract="true" type="com.bstek.dorado.view.widget.list.AbstractList" scope="protected" clientTypes="desktop"><Props>
+<Prop name="wrappable" type="boolean"/></Props><Children><Child name="Editor" fixed="true"><Rule name="Wrapper.Editor" label="Editor" nodeName="Editor" icon="/com/bstek/dorado/view/widget/grid/Editor.png"><Children><Child rule="com.bstek.dorado.view.widget.Control" name="Editor"></Child></Children></Rule></Child></Children></Rule><Rule name="RowSelectorColumn" parents="AbstractDataColumn" label="RowSelectorColumn" type="com.bstek.dorado.view.widget.grid.RowSelectorColumn" icon="/com/bstek/dorado/view/widget/grid/RowSelectorColumn.png"></Rule><Rule name="AbstractList" parents="com.bstek.dorado.view.widget.Control" abstract="true" type="com.bstek.dorado.view.widget.list.AbstractList" scope="protected" clientTypes="desktop"><Props>
 <Prop name="allowNoCurrent" type="boolean"/>
 <Prop name="dragMode" defaultValue="item" enumValues="item,control,itemOrControl"/>
 <Prop name="dropMode" defaultValue="insertItems" enumValues="onControl,onItem,insertItems,onOrInsertItems,onAnyWhere"/>

--
Gitblit v1.9.3