shjung před 2 roky
rodič
revize
c7871e01f6
67 změnil soubory, kde provedl 1091 přidání a 530 odebrání
  1. 1 0
      conf/vms-comm-server.pid
  2. 1 1
      src/main/java/com/its/vms/VmsCommServerApplication.java
  3. 4 3
      src/main/java/com/its/vms/api/websocket/ItsWebSocketHandler.java
  4. 2 1
      src/main/java/com/its/vms/dao/mapper/VmsCtlrMapper.java
  5. 3 0
      src/main/java/com/its/vms/dao/mapper/VmsManageMapper.java
  6. 2 6
      src/main/java/com/its/vms/dao/mapper/batch/VmsCtlrDao.java
  7. 2 6
      src/main/java/com/its/vms/dao/mapper/batch/VmsManageDao.java
  8. 0 1
      src/main/java/com/its/vms/domain/VmsControlMode.java
  9. 32 0
      src/main/java/com/its/vms/domain/VmsCtlrStatus.java
  10. 61 0
      src/main/java/com/its/vms/domain/task/VmsCommandTimeoutTask.java
  11. 39 0
      src/main/java/com/its/vms/domain/task/VmsTimeoutTask.java
  12. 246 145
      src/main/java/com/its/vms/dto/TbVmsCtlrDto.java
  13. 6 6
      src/main/java/com/its/vms/entity/TbVmsCtlr.java
  14. 105 15
      src/main/java/com/its/vms/entity/TbVmsCtlrStts.java
  15. 34 0
      src/main/java/com/its/vms/entity/VmsCtlrParam.java
  16. 24 0
      src/main/java/com/its/vms/entity/VmsDsplDnldResult.java
  17. 30 5
      src/main/java/com/its/vms/process/DbmsDataProcess.java
  18. 3 0
      src/main/java/com/its/vms/process/DbmsDataType.java
  19. 1 1
      src/main/java/com/its/vms/scheduler/SchedulerTask.java
  20. 3 3
      src/main/java/com/its/vms/service/AppRepositoryService.java
  21. 12 12
      src/main/java/com/its/vms/service/VmsManageService.java
  22. 10 0
      src/main/java/com/its/vms/ui/CtlrSttsTableModel.java
  23. 9 1
      src/main/java/com/its/vms/ui/SubUI.java
  24. 1 1
      src/main/java/com/its/vms/xnettcp/vms/VmsTcpCommServerInitializer.java
  25. 4 1
      src/main/java/com/its/vms/xnettcp/vms/handler/VmsServerIdleStateHandler.java
  26. 5 0
      src/main/java/com/its/vms/xnettcp/vms/process/TcpServerRecvDataProcess.java
  27. 20 12
      src/main/java/com/its/vms/xnettcp/vms/process/TcpServerSendDataProcess.java
  28. 22 7
      src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResBlank.java
  29. 58 45
      src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResDataDownload.java
  30. 2 2
      src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResDataUpload.java
  31. 5 6
      src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResDisplayDefaultForm.java
  32. 5 6
      src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResDisplayFormId.java
  33. 7 7
      src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResDisplayModuleStatus.java
  34. 5 6
      src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResDownloadForm.java
  35. 5 6
      src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResDownloadFormSchedule.java
  36. 5 6
      src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResFormDataDisplay.java
  37. 17 10
      src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResParameter.java
  38. 8 9
      src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResPowerModuleStatus.java
  39. 11 3
      src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResStatus.java
  40. 5 6
      src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResStatusControl.java
  41. 2 2
      src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResStopImage.java
  42. 4 5
      src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResUploadCurrentDisplayForm.java
  43. 2 2
      src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResUploadFormSchedule.java
  44. 20 3
      src/main/java/com/its/vms/xnettcp/vms/protocol/VmsReqFramePacket.java
  45. 17 0
      src/main/java/com/its/vms/xnettcp/vms/protocol/VmsReqHead.java
  46. 2 1
      src/main/java/com/its/vms/xnettcp/vms/protocol/enums/eVmsOpCode.java
  47. 6 7
      src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqBlank.java
  48. 7 9
      src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqDataDownload.java
  49. 7 9
      src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqDataUpload.java
  50. 6 7
      src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqDisplayDefaultForm.java
  51. 6 8
      src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqDisplayFromId.java
  52. 6 7
      src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqDisplayModuleStatus.java
  53. 8 9
      src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqDownloadForm.java
  54. 7 9
      src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqDownloadFormSchedule.java
  55. 6 8
      src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqFormDataDisplay.java
  56. 68 0
      src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqLocalUserCommand.java
  57. 6 7
      src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqParameter.java
  58. 6 7
      src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqPowerModuleStatus.java
  59. 6 7
      src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqStatus.java
  60. 6 8
      src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqStatusControl.java
  61. 6 8
      src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqStopImage.java
  62. 6 7
      src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqUploadCurrentDisplayForm.java
  63. 6 7
      src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqUploadFormSchedule.java
  64. 0 1
      src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsResFramePacket.java
  65. 0 42
      src/main/java/com/its/vms/xnettcp/vms/task/VmsTimeoutTask.java
  66. 13 11
      src/main/resources/mybatis/mapper/VmsCtlrMapper.xml
  67. 47 0
      src/main/resources/mybatis/mapper/VmsManageMapper.xml

+ 1 - 0
conf/vms-comm-server.pid

@@ -0,0 +1 @@
+256076

+ 1 - 1
src/main/java/com/its/vms/VmsCommServerApplication.java

@@ -180,7 +180,7 @@ public class VmsCommServerApplication implements CommandLineRunner, ApplicationL
 
         VmsManageService vmsManageService = (VmsManageService)AppUtils.getBean(VmsManageService.class);
         vmsManageService.initVmsDsplPrst();
-        vmsManageService.jobMakeDownloadVmsForm();;
+        vmsManageService.jobMakeDownloadVmsForm();
 
         // VMS Communication Service Start.........
         VmsTcpCommServerService vmsTcpCommServerService = (VmsTcpCommServerService)AppUtils.getBean(VmsTcpCommServerService.class);

+ 4 - 3
src/main/java/com/its/vms/api/websocket/ItsWebSocketHandler.java

@@ -29,7 +29,7 @@ public class ItsWebSocketHandler extends TextWebSocketHandler {
     @Override
     public void afterConnectionEstablished(WebSocketSession session) throws Exception {
         // 클라이언트가 연결되었을때 실행
-        log.info("afterConnectionEstablished: " + session.getRemoteAddress() + ",  URI: " + session.getUri() + ", UUID: " + session.getId());
+        log.info("afterConnectionEstablished: {},  URI: {}, UUID: {}, message[{}].", session.getRemoteAddress(), session.getUri(), session.getId());
         super.afterConnectionEstablished(session);
 
         ItsWebSocketSession vo = new ItsWebSocketSession(this, session);
@@ -39,7 +39,8 @@ public class ItsWebSocketHandler extends TextWebSocketHandler {
     //클라이언트가 웹소켓 서버로 메시지를 전송했을 때 실행
     @Override
     protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
-        log.info("handleTextMessage: " + session.getRemoteAddress() + ",  Uri[" + session.getUri() + "], UUID[" + session.getId() + "], message[" + message.getPayload() + "]");
+        log.info("handleTextMessage: {},  URI: {}, UUID: {}, message[{}].", session.getRemoteAddress(), session.getUri(), session.getId(), message.getPayload());
+
         /*List<String> requests = ItsUtils.split(message.getPayload(), ":");
         if (requests.size() != 2) {
             log.error("Request data parsing error: {}", requests);
@@ -59,7 +60,7 @@ public class ItsWebSocketHandler extends TextWebSocketHandler {
     //클라이언트 연결을 끊었을 때 실행
     @Override
     public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
-        log.info("afterConnectionClosed: " + session.getRemoteAddress() + ",  URI: " + session.getUri() + ", UUID: " + session.getId());
+        log.info("afterConnectionClosed: {},  URI: {}, UUID: {}.", session.getRemoteAddress(), session.getUri(), session.getId());
         ItsWebSocketSessionManager.getInstance().removeSession(session);
         super.afterConnectionClosed(session, status);
     }

+ 2 - 1
src/main/java/com/its/vms/dao/mapper/VmsCtlrMapper.java

@@ -3,6 +3,7 @@ package com.its.vms.dao.mapper;
 import com.its.vms.entity.TbVmsCtlr;
 import com.its.vms.entity.TbVmsCtlrStts;
 import com.its.vms.entity.TbVmsCtrlHs;
+import com.its.vms.entity.VmsCtlrParam;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
@@ -20,5 +21,5 @@ public interface VmsCtlrMapper {
     int insertVmsCtrlHs(@Param("obj") TbVmsCtrlHs obj);
     int updateVmsCtrlHs(@Param("obj") TbVmsCtrlHs obj);
 
-    int updateVmsCtlrParam(@Param("obj") TbVmsCtlr obj);
+    int updateVmsCtlrParam(@Param("obj") VmsCtlrParam obj);
 }

+ 3 - 0
src/main/java/com/its/vms/dao/mapper/VmsManageMapper.java

@@ -22,4 +22,7 @@ public interface VmsManageMapper {
     int insertVmsDsplPrstHs(@Param("obj") TbVmsDsplPrst obj);
     int createVmsDsplPrstHs(@Param("obj") TbVmsDsplPrstResult obj);
 
+    int updateVmsDsplPrstResult(@Param("obj") VmsDsplDnldResult obj);
+    int insertVmsDsplPrstHsResult(@Param("obj") VmsDsplDnldResult obj);
+
 }

+ 2 - 6
src/main/java/com/its/vms/dao/mapper/batch/VmsCtlrDao.java

@@ -2,7 +2,6 @@ package com.its.vms.dao.mapper.batch;
 
 import com.its.app.utils.Elapsed;
 import com.its.vms.dao.mapper.BatchDaoService;
-import com.its.vms.dao.mapper.VmsCtlrMapper;
 import com.its.vms.entity.TbVmsCtlrStts;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.ibatis.session.SqlSessionFactory;
@@ -16,12 +15,9 @@ import java.util.List;
 @Repository
 public class VmsCtlrDao extends BatchDaoService {
 
-    private final VmsCtlrMapper mapper;
-
-    public VmsCtlrDao(VmsCtlrMapper mapper, SqlSessionFactory sqlSessionFactory) {
+    public VmsCtlrDao(SqlSessionFactory sqlSessionFactory) {
         super(sqlSessionFactory);
-        this.mapper = mapper;
-        this.serviceName = this.getClass().getName();
+        this.serviceName = "VmsCtlrDao";//this.getClass().getName();
     }
 
     public List<HashMap<String, Object>> getSttsList(List<TbVmsCtlrStts> req) {

+ 2 - 6
src/main/java/com/its/vms/dao/mapper/batch/VmsManageDao.java

@@ -2,7 +2,6 @@ package com.its.vms.dao.mapper.batch;
 
 import com.its.app.utils.Elapsed;
 import com.its.vms.dao.mapper.BatchDaoService;
-import com.its.vms.dao.mapper.VmsManageMapper;
 import com.its.vms.entity.TbVmsDsplPrst;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.ibatis.session.SqlSessionFactory;
@@ -16,12 +15,9 @@ import java.util.List;
 @Repository
 public class VmsManageDao extends BatchDaoService {
 
-    private final VmsManageMapper mapper;
-
-    public VmsManageDao(VmsManageMapper mapper, SqlSessionFactory sqlSessionFactory) {
+    public VmsManageDao(SqlSessionFactory sqlSessionFactory) {
         super(sqlSessionFactory);
-        this.mapper = mapper;
-        this.serviceName = this.getClass().getName();
+        this.serviceName = "VmsManageDao";//this.getClass().getName();
     }
 
     public List<HashMap<String, Object>> getVmsDsplList(List<TbVmsDsplPrst> req) {

+ 0 - 1
src/main/java/com/its/vms/domain/VmsControlMode.java

@@ -22,6 +22,5 @@ public class VmsControlMode implements Serializable {
     private boolean saveFlag;           // 제공정보 저장 여부
     private Long    timer;              // timer for provide
     private boolean isResult;
-    private boolean isSchedule;         // 스케줄에 의한 다운로드 인 경우
 
 }

+ 32 - 0
src/main/java/com/its/vms/domain/VmsCtlrStatus.java

@@ -0,0 +1,32 @@
+package com.its.vms.domain;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ *  DTO Class
+ */
+@Data
+public class VmsCtlrStatus implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private int door;       // Door Open/Close 상태, 0x00: Open, 0x01: Close, 0x09: Unknown
+    private int power;      // 전원의 ON/OFF 상태, 0x00: On, 0x01: Off, 0x09: Unknown (Sign Board)
+    private int fan;        // VMS Fan 동작 상태, 0x00: On, 0x01: Off, 0x09: Unknown
+    private int heater;     // VMS Heater 동작 상태, 0x00: On, 0x01: Off, 0x09: Unknown
+    private int formNo;     // 표출 폼 번호, 현재 표출중인 폼 번호 : 0~9999
+    private int reboot;     // 표출 폼 번호, 0x00: 정상, 0x01: 재실행
+    private int cboxTemp;   // 함체온도, 127 ~ -127, -128 : Unknown
+    private int brightMode; // 화면의 밝기 - 휘도 모드, 0x00:주간, 0x01:야간, 0x02:Auto, 0x03:수동
+    private int brightCurr; // 화면의 밝기 - 현재 휘도값, 0~100
+    private int brightWeek; // 화면의 밝기 - 주간 휘도값, 0~100
+    private int brightNght; // 화면의 밝기 - 야간 휘도값, 0~100
+    private int dpTemp;     // 외부온도, -127 ~ 127, -128: Unknown
+    private int dpHum;      // 외부습도,    0 ~ 100,  101: Unknown
+    private int powerModuleStts = 0x02; // 0x00: 정상, 0x01: 에러, 0x02: Unknown
+    private int moduleStts = 0x02;      // 0x00: 정상, 0x01: 불량, 0x02: Unknown
+    private int cboxFan = 0x09;         // 0x00: On, 0x01: Off, 0x09: Unknown
+    private int cboxHeather = 0x09;     // 0x00: On, 0x01: Off, 0x09: Unknown
+
+}

+ 61 - 0
src/main/java/com/its/vms/domain/task/VmsCommandTimeoutTask.java

@@ -0,0 +1,61 @@
+package com.its.vms.domain.task;
+
+import com.its.vms.domain.NET;
+import com.its.vms.dto.TbVmsCtlrDto;
+import com.its.vms.xnettcp.vms.handler.VmsServerIdleStateHandler;
+import com.its.vms.xnettcp.vms.protocol.VmsReqFramePacket;
+import lombok.extern.slf4j.Slf4j;
+import org.slf4j.MDC;
+
+import java.util.TimerTask;
+
+@Slf4j
+public class VmsCommandTimeoutTask extends TimerTask {
+
+    private final TbVmsCtlrDto vmsObj;
+    private final VmsReqFramePacket packet;
+    private final int          retryCnt;
+
+    public VmsCommandTimeoutTask(TbVmsCtlrDto vmsObj, VmsReqFramePacket packet, int retryCnt) {
+        this.vmsObj = vmsObj;
+        this.packet = packet;
+        this.retryCnt = retryCnt;
+    }
+
+    public TbVmsCtlrDto getCtlr() {
+        return this.vmsObj;
+    }
+
+    public VmsReqFramePacket getPacket() {
+        return this.packet;
+    }
+
+    public short getPacketNmbr() {
+        return this.packet.getPacketNmbr();
+    }
+
+    @Override
+    public void run() {
+
+        MDC.put("id", this.vmsObj.getLogKey());
+
+        log.info("VmsConnectTimeoutTask-run: VSM {}, opCode {}, retryCnt {}.", this.vmsObj.getVmsCtlrNmbr(), this.packet.getOpCode(), this.retryCnt);
+
+        if (this.vmsObj.getNetState() > NET.CLOSED) {
+            if (this.retryCnt >= 3) {
+                log.error("VmsConnectTimeoutTask-run: VSM {}, opCode {}, retryCnt {}, Command Retry Time out, will be closed.", this.vmsObj.getVmsCtlrNmbr(), this.packet.getOpCode(), this.retryCnt);
+                VmsServerIdleStateHandler.disconnectChannel(this.vmsObj, this.vmsObj.getChannel());
+            }
+            else {
+                this.vmsObj.sendData(this.packet, this.retryCnt+1);
+            }
+        }
+        else {
+            log.info("VmsConnectTimeoutTask-run: VSM {}, opCode {}, Network Already Closed.", this.vmsObj.getVmsCtlrNmbr(), this.packet.getOpCode());
+        }
+
+        MDC.remove(this.vmsObj.getLogKey());
+        MDC.clear();
+    }
+
+}

+ 39 - 0
src/main/java/com/its/vms/domain/task/VmsTimeoutTask.java

@@ -0,0 +1,39 @@
+package com.its.vms.domain.task;
+
+import com.its.vms.dto.TbVmsCtlrDto;
+import lombok.extern.slf4j.Slf4j;
+import org.slf4j.MDC;
+
+import java.util.TimerTask;
+
+@Slf4j
+public class VmsTimeoutTask extends TimerTask {
+
+    private final TbVmsCtlrDto obj;
+    private final Long      packetNmbr;
+
+    public VmsTimeoutTask(TbVmsCtlrDto obj, Long packetNmbr) {
+        this.obj = obj;
+        this.packetNmbr = packetNmbr;
+    }
+
+    @Override
+    public void run() {
+
+        MDC.put("id", this.obj.getLogKey());
+
+        log.info("VmsTimeoutTask-run: packetNmbr: {}, obj: {}", this.packetNmbr, this.obj.getVmsCtlrNmbr());
+//        this.obj.removeRegisteredCommands(this.packetNmbr, false);
+//        TbVmsCtrlHs command = this.obj.getUserCommands(this.packetNmbr);
+//        if (command != null) {
+//            this.obj.removeUserCommands(this.packetNmbr);
+//            // TODO: 제어명령 성공 전송(실패)
+//            //command.setRspsType("5");  // 명령 실패(타임아웃)로 설정
+//            VmsCtlrMapper mapper = (VmsCtlrMapper) AppUtils.getBean(VmsCtlrMapper.class);
+//            mapper.updateVmsCtrlHs(command);
+//        }
+
+        MDC.remove(this.obj.getLogKey());
+        MDC.clear();
+    }
+}

+ 246 - 145
src/main/java/com/its/vms/dto/TbVmsCtlrDto.java

@@ -5,20 +5,25 @@ import com.its.app.utils.SysUtils;
 import com.its.vms.config.ApplicationConfig;
 import com.its.vms.domain.*;
 import com.its.vms.domain.enums.eVmsFormType;
+import com.its.vms.domain.task.VmsCommandTimeoutTask;
 import com.its.vms.entity.TbVmsCtlr;
 import com.its.vms.entity.TbVmsCtlrStts;
 import com.its.vms.entity.TbVmsCtrlHs;
+import com.its.vms.entity.VmsCtlrParam;
+import com.its.vms.process.DbmsData;
+import com.its.vms.process.DbmsDataProcess;
+import com.its.vms.process.DbmsDataType;
 import com.its.vms.service.VmsFormService;
 import com.its.vms.xnettcp.vms.handler.VmsServerIdleStateHandler;
 import com.its.vms.xnettcp.vms.process.TcpServerSendData;
 import com.its.vms.xnettcp.vms.process.TcpServerSendDataProcess;
+import com.its.vms.xnettcp.vms.protocol.VmsReqFramePacket;
 import com.its.vms.xnettcp.vms.protocol.dto.*;
 import com.its.vms.xnettcp.vms.protocol.enums.eVmsFileSaveLocation;
 import com.its.vms.xnettcp.vms.protocol.enums.eVmsFormObjectKind;
 import com.its.vms.xnettcp.vms.protocol.enums.eVmsImageType;
 import com.its.vms.xnettcp.vms.protocol.enums.eVmsOpCode;
 import com.its.vms.xnettcp.vms.protocol.impl.*;
-import com.its.vms.xnettcp.vms.task.VmsTimeoutTask;
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelFuture;
 import io.netty.channel.ChannelHandlerContext;
@@ -32,7 +37,6 @@ import java.text.SimpleDateFormat;
 import java.util.List;
 import java.util.Map;
 import java.util.Timer;
-import java.util.TimerTask;
 import java.util.concurrent.ConcurrentHashMap;
 
 @Slf4j
@@ -58,30 +62,32 @@ public class TbVmsCtlrDto implements Serializable {
     private String typeCd;
     private String modlTypeCd;
     private String operMode;
-    private Integer cmncFailRate;
-    private Integer brghNghtStep;
-    private Integer brghWeekStep;
-    private Integer defPhseChngCycl;
-    private Integer modlErrRate;
     private Integer cmncfailSlotNmbr;
     private Integer pwerFailSlotNmbr;
     private String cmtrinfrCnctYn;
     private String wthrinfrCnctYn;
     private String envrinfrCnctYn;
     private Integer maxPhaseNum;
-    private String panlOnTime;
-    private String panlOffTime;
-    private String panlPwerMode;
-    private String brghMode;
     private String istlLctnNm;
+    private String istlLctnAddr;
     private String trfcStrgUseYn;
     private Long locIfscId;
-    private Double fanRunTmpr;
-    private Double hetrRunTmpr;
-    private Integer fanMode;
-    private Integer hetrMode;
-    private Integer brghCurrStep;
-    private String istlLctnAddr;
+
+    private Integer defPhseChngCycl;    // 기본메시지주기
+    private String panlOnTime;          // 전광판 ON TIME
+    private String panlOffTime;         // 전광판 OFF TIME
+    private Integer panlPwerMode;        // 전광판 전원 모드(0x00:꺼짐,0x01:켜짐,0x02:자동,0x09:알수없음)
+    private Integer fanMode;            // FAN 동작모드(0x00:꺼짐,0x01:켜짐,0x02:자동,0x09:알수없음)
+    private Integer fanRunTmpr;          // 팬 동작 온도
+    private Integer hetrMode;           // 히터 동작모드(0x00:꺼짐,0x01:켜짐,0x02:자동,0x09:알수없음)
+    private Integer hetrRunTmpr;         // 히터 동작 온도
+    private Integer brghMode;           // 휘도 모드(0x00:주간,0x01:야간,0x02:자동,0x09:수동)
+    private Integer brghCurrStep;       // 휘도 현재 단계(0~100)
+    private Integer brghWeekStep;       // 휘도 주간 단계(0~100)
+    private Integer brghNghtStep;       // 휘도 야간 단계(0~100)
+    private Integer modlErrRate;        // VMS 모듈 오류 율
+    private Integer cmncFailRate;       // VMS 통신 오류 기본 값
+
     private Integer protocolVer;
     private String delYn;
 
@@ -132,15 +138,17 @@ public class TbVmsCtlrDto implements Serializable {
 
     private Integer downloadFormId;
     private VmsDownloadFile downloadFile;           // 제어기로 다운로드할 파일정보(TB_VMS_DOWNLOAD)
-    private VmsDownloadData downloadData;
+    private VmsDownloadData downloadData;           // 제어기로 다운로드할 파일 데이터
     private ConcurrentHashMap<Integer, VmsDownloadForm> downloadFormMap = null;
     private ConcurrentHashMap<Integer, TbVmsSymbLibDnldDto> dnldSymbMap = null;
     private ConcurrentHashMap<Integer, VmsScheduleSymbDto> reqDnldSymbMap;
     Integer dnldSymbLibNmbr;
 
-    private ConcurrentHashMap<Long, TbVmsRltnIfscDto> rltnIfscMap = null;
+    private ConcurrentHashMap<Long, TbVmsRltnIfscDto> rltnIfscMap = null;   // VMS 에 설정된 VMS 정보제공구간 목록
+
+    private ConcurrentHashMap<Short, Timer> registeredCommandTimer = null;
+    private ConcurrentHashMap<Short, VmsCommandTimeoutTask> registeredCommand = null;
 
-    private ConcurrentHashMap<Long, Timer> registeredCommandsTimer = null;
     private ConcurrentHashMap<Long, TbVmsCtrlHs> userCommands = null;
 
     private int connectCount;
@@ -148,20 +156,22 @@ public class TbVmsCtlrDto implements Serializable {
     private String disConnectTm;
     private long lastRecvTime;
 
-    private TcpServerSendDataProcess dataProcess;
+    private TcpServerSendDataProcess dataProcess;   // 제어기로 데이터를 전송할 전송 전송 큐를 처리할 스레드
 
     public void init() {
         this.stts = new TbVmsCtlrStts(this.vmsCtlrNmbr);
         this.seq  = new VmsFrameSequence();
 
-        this.downloadData = new VmsDownloadData();
         this.downloadFormMap = new ConcurrentHashMap<>();
         this.dnldSymbMap = new ConcurrentHashMap<>();
         this.reqDnldSymbMap = new ConcurrentHashMap<>();
         this.dnldSymbLibNmbr = 0;
 
-        this.registeredCommandsTimer = new ConcurrentHashMap<>();
+        this.registeredCommandTimer = new ConcurrentHashMap<>();
+        this.registeredCommand = new ConcurrentHashMap<>();
+
         this.userCommands = new ConcurrentHashMap<>();
+
         this.rltnIfscMap = new ConcurrentHashMap<>();
 
         this.formManager = new VmsFormManager(this.vmsWidth, this.vmsHeight);
@@ -173,7 +183,9 @@ public class TbVmsCtlrDto implements Serializable {
         this.module = new VmsModule();
         this.luminance = new VmsLuminance();
         this.controlMode = new VmsControlMode();
+        this.downloadFormId = 0;
         this.downloadFile = new VmsDownloadFile();
+        this.downloadData = new VmsDownloadData();
 
         this.connectCount = 0;
         this.connectTm = "-";
@@ -220,14 +232,27 @@ public class TbVmsCtlrDto implements Serializable {
         });
     }
 
+    /**
+     * 제어기 전송 패킷의 패킷 번호를 구한다.
+     * @return
+     */
     public short getSeqNext() {
         return this.seq.nextValue();
     }
 
+    /**
+     * 제어기 전송 스레드 타스크 큐에 명령을 전송
+     * @param data
+     * @return
+     */
     public synchronized boolean addRequestData(TcpServerSendData data) {
         return this.dataProcess.add(data);
     }
 
+    /**
+     * 제어기 네트워크 최초 접속시 발생 이벤트
+     * @param ctx
+     */
     public synchronized void connected(ChannelHandlerContext ctx) {
         this.netState = NET.LOGIN_REQ;
         this.connectTm = SysUtils.getSysTimeStr();
@@ -235,11 +260,15 @@ public class TbVmsCtlrDto implements Serializable {
         this.lastRecvTime = System.currentTimeMillis();
         this.connectCount++;
         this.stts.initNormal();
+        clearRegisteredCommandTimer();
     }
 
+    /**
+     * 제어기 네트워크 연결 종료 이벤트
+     */
     public synchronized void disconnected() {
+        clearRegisteredCommandTimer();
         this.netState = NET.CLOSED;
-        this.registeredCommandsTimer.clear();
         this.channel = null;
         this.disConnectTm = SysUtils.getSysTimeStr();
         this.stts.initError();
@@ -268,61 +297,80 @@ public class TbVmsCtlrDto implements Serializable {
         this.syncTime   = 0;
     }
 
-    public synchronized void channelLogin(Channel channel) {
-        this.channel = channel;
-
-        //this.registeredCommands.clear();
-        for (Map.Entry<Long, Timer> e : this.registeredCommandsTimer.entrySet()) {
+    /**
+     * 제어기 명령 타임아웃 타스크 클리어
+     */
+    public synchronized void clearRegisteredCommandTimer() {
+        this.registeredCommand.clear();
+        for (Map.Entry<Short, Timer> e : this.registeredCommandTimer.entrySet()) {
             Timer task = e.getValue();
             task.cancel();
         }
-        this.registeredCommandsTimer.clear();
-
-        this.netState = NET.LOGINED;
+        this.registeredCommandTimer.clear();
     }
-    public synchronized void channelLoginInit() {
-        //this.registeredCommands.clear();
-        for (Map.Entry<Long, Timer> e : this.registeredCommandsTimer.entrySet()) {
-            Timer task = e.getValue();
-            task.cancel();
-        }
-        this.registeredCommandsTimer.clear();
 
-        this.netState = NET.LOGINED;
+    /**
+     * 제어기 명령 타임아웃 타스크 추가
+     * @param cmdTimeoutTask
+     * @return
+     */
+    public synchronized void addRegisteredCommandsTimer(VmsCommandTimeoutTask cmdTimeoutTask) {
+        long timeoutSec = 1000L * 5;
+        Timer timer = new Timer();
+        timer.schedule(cmdTimeoutTask, timeoutSec);
+        this.registeredCommandTimer.put(cmdTimeoutTask.getPacketNmbr(), timer);
+        this.registeredCommand.put(cmdTimeoutTask.getPacketNmbr(), cmdTimeoutTask);
+//        log.info("addRegisteredCommandsTimer: VMS {}, Task {} EA, OpCode {}.",
+//                cmdTimeoutTask.getCtlr().getVmsCtlrNmbr(), this.registeredCommandTimer.size(), cmdTimeoutTask.getPacket().getOpCode());
     }
 
-    public void sleep(long milliSeconds) {
-        try {
-            Thread.sleep(milliSeconds);
-        } catch (InterruptedException e) {
-            log.error("sleep: InterruptedException");
+    /**
+     * 제어기 명령 타임아웃 타스크 제거
+     * @param opCode
+     */
+    public synchronized void removeRegisteredCommandsTimer(eVmsOpCode opCode) {
+        short packetNmbr = (short)opCode.getValue();
+        Timer timer = this.registeredCommandTimer.get(packetNmbr);
+        if (timer != null) {
+            timer.cancel();
+            this.registeredCommandTimer.remove(packetNmbr);
+        }
+        VmsCommandTimeoutTask cmdTimeoutTask = this.registeredCommand.get(packetNmbr);
+        if (cmdTimeoutTask != null) {
+            this.registeredCommand.remove(packetNmbr);
+//            log.info("removeRegisteredCommandsTimer: VMS {}, Task {} EA, OpCode {}.",
+//                    cmdTimeoutTask.getCtlr().getVmsCtlrNmbr(), this.registeredCommandTimer.size(), cmdTimeoutTask.getPacket().getOpCode());
         }
     }
 
     /**
      * Channel Send Data
-     * @param sendBuffer
-     * @param delayMilliSeconds
-     * @param packetDesc
+     * @param packet
+     * @param retryCnt
      * @return
      */
-    public synchronized boolean sendData(ByteBuffer sendBuffer, int delayMilliSeconds, String packetDesc) {
+    public synchronized boolean sendData(VmsReqFramePacket packet, int retryCnt) {
         boolean result = false;
+
+        ByteBuffer sendBuffer = packet.getByteBuffer();
+        String packetDesc = packet.getOpCodeDesc();
+
         log.info("~REQUEST-{}. VMS {}, {} Bytes.", packetDesc, this.vmsCtlrNmbr, sendBuffer.capacity());
         if (this.channel != null) {
             ChannelFuture f = this.channel.writeAndFlush(sendBuffer);
             f.awaitUninterruptibly();
             if (f.isDone() || f.isSuccess()) {
                 result = true;
-                if (delayMilliSeconds > 0) {
-                    sleep(delayMilliSeconds);
-                }
             } else {
                 log.error("~REQUEST-{}. VMS {}, sendData Failed. {} Bytes.", packetDesc, this.vmsCtlrNmbr, sendBuffer.array().length);
             }
         } else {
             log.error("~REQUEST-{}. VMS {}, sendData Failed. Not Connected. {} Bytes.", packetDesc, this.vmsCtlrNmbr, sendBuffer.array().length);
         }
+        if (result) {
+            VmsCommandTimeoutTask cmdTimeoutTask = new VmsCommandTimeoutTask(this, packet, retryCnt);
+            addRegisteredCommandsTimer(cmdTimeoutTask);
+        }
         return result;
     }
 
@@ -345,12 +393,6 @@ public class TbVmsCtlrDto implements Serializable {
         return addRequestData(new TcpServerSendData(eVmsOpCode.OP_VMS_STATUS_CONTROL, resetControl));
     }
 
-    public synchronized boolean addUserCommands(Long packetNmbr, TbVmsCtrlHs command) {
-
-        this.userCommands.put(packetNmbr, command);
-        return addCommandTimer(packetNmbr);
-    }
-
     public synchronized boolean removeUserCommands(Long packetNmbr) {
 
         TbVmsCtrlHs command = this.userCommands.get(packetNmbr);
@@ -367,49 +409,6 @@ public class TbVmsCtlrDto implements Serializable {
         return command;
     }
 
-    private boolean addCommandTimer(Long packetNmbr) {
-
-        long timeoutSec = 10;//this.login.getDatexLoginResponseTimeOutQty().value.longValue();
-        if (timeoutSec == 0L || timeoutSec > 30L) {
-            timeoutSec = 30L;
-        }
-        if (timeoutSec < 5L)
-            timeoutSec = 5L;
-
-        timeoutSec = 1000L * timeoutSec;
-        Timer timer = new Timer();
-        timer.schedule((TimerTask)new VmsTimeoutTask(this, packetNmbr), timeoutSec);
-        this.registeredCommandsTimer.put(packetNmbr, timer);
-
-        log.info("addCommandTimer: [{}], packetNmbr: {}, timeoutSec: {} ms, {}", this.vmsCtlrNmbr, packetNmbr, timeoutSec, timer);
-        return true;
-    }
-
-    public synchronized boolean removeRegisteredCommandsTimer(int packetNmbr) {
-
-        Timer timer = this.registeredCommandsTimer.get(Integer.valueOf(packetNmbr));
-        if (timer != null) {
-            this.registeredCommandsTimer.remove(Integer.valueOf(packetNmbr));
-        }
-        return true;
-    }
-
-    public synchronized boolean removeRegisteredCommands(Long packetNmbr, boolean cancelTimer) {
-
-        Timer timer = this.registeredCommandsTimer.get(packetNmbr);
-        if (timer != null) {
-            if (cancelTimer)
-                timer.cancel();
-            this.registeredCommandsTimer.remove(packetNmbr);
-        }
-
-//		C2CAuthenticatedMessage c2c = this.registeredCommands.get(packetNmbr);
-//		if (c2c != null) {
-//			this.registeredCommands.remove(packetNmbr);
-//		}
-        return false;
-    }
-
     public TbVmsCtlr toDto() {
         return TbVmsCtlr.builder()
                 .vmsCtlrNmbr(this.vmsCtlrNmbr)
@@ -458,12 +457,10 @@ public class TbVmsCtlrDto implements Serializable {
      * 2. 파일 다운로드(이미지, 심볼) - downloadFile
      * 3. 폼 스케쥴 다운로드 - downloadFormSchedule
      * 4. Blank - downloadBlank
-     * @param isSchedule
      * @return
      */
-    public boolean downloadForm(boolean isSchedule) {
+    public boolean downloadForm() {
         VmsFormService formService = (VmsFormService) AppUtils.getBean(VmsFormService.class);
-        this.controlMode.setSchedule(isSchedule);
         this.txtOpCode = (byte)0x00;
         this.downloadData.init();
 
@@ -495,37 +492,39 @@ public class TbVmsCtlrDto implements Serializable {
             units[forms].setVmsFormId(vmsFormId);
             units[forms].setDownload(true);
             units[forms].setFormIdx(ii);
-            units[forms].setBitmapId(forms + 1000);
+            //units[forms].setBitmapId(forms + 1000);
+            units[forms].setBitmapId(pForm.getDnldFormNo());
             units[forms].setFormNo(9000 + forms);
             units[forms].setDisplaySec(pForm.getDsplHh());
             units[forms].setDisplayType(pForm.getVmsFormDsplMthdCd());
             units[forms].setBkClr(pForm.getVmsFormColrCd());
 
-            VmsDownloadForm downloadForm = this.downloadFormMap.get(vmsFormId);
-            // 홍보폼이면서 신규폼이 아니면서 이전 다운로드 목록이 존재하는 경우에 다운로드 여부를 체크한다.
-            if (vmsForm.getVmsFormTypeCd() == eVmsFormType.eFormTp_hongbo.getValue() && !vmsForm.isNewForm() && downloadForm != null) {
-                if (downloadForm.isAlreadyDownload()) {
-                    // 이미 이전에 다운로드를 했기때문에 이번에는 제어기로 다운로드를 하지 않는다.
-                    units[forms].setDownload(false);
+            if (vmsForm.getVmsFormTypeCd() == eVmsFormType.eFormTp_hongbo.getValue()) {
+                // 다운로드 할 폼이 홍보폼이면 여러번 다운로드 하지 않도록 메모리에서 관리하자.
+                VmsDownloadForm downloadForm = this.downloadFormMap.get(vmsFormId);
+                if (downloadForm != null) {
+                    // 이전에 다운로드한 폼 정보가 존재하면
+                    if (!vmsForm.getUpdtDt().equals(downloadForm.getUpdtDt())) {
+                        // 업데이트시각이 다르기때문에 신규폼으로 판단한다.
+                        downloadForm.setAlreadyDownload(false);
+                        downloadForm.setUpdtDt(vmsForm.getUpdtDt());
+                        units[forms].setDownload(true); // 현재 스케쥴폼으로 다운로드 플래그 설정
+                    }
+                    if (downloadForm.isAlreadyDownload()) {
+                        // 이미 이전에 다운로드를 했기때문에 이번에는 제어기로 다운로드를 하지 않는다.
+                        units[forms].setDownload(false);
+                    }
                 }
-            }
-
-            // 이전에 다운로드한 정보가 존재하면
-            if (downloadForm != null) {
-                if (!vmsForm.getUpdtDt().equals(downloadForm.getUpdtDt())) {
-                    // 업데이트시각이 다르기때문에 신규폼으로 판단한다.
+                else {
+                    // 이전에 다운로드 한 정보가 없기때문에 메모리에 저장해 놓는다.
+                    downloadForm = new VmsDownloadForm();
+                    downloadForm.setVmsFormId(vmsFormId);
                     downloadForm.setAlreadyDownload(false);
                     downloadForm.setUpdtDt(vmsForm.getUpdtDt());
-                    units[forms].setDownload(true);
+                    this.downloadFormMap.put(vmsFormId, downloadForm);
                 }
             }
-            else {
-                downloadForm = new VmsDownloadForm();
-                downloadForm.setVmsFormId(vmsFormId);
-                downloadForm.setAlreadyDownload(false);
-                downloadForm.setUpdtDt(vmsForm.getUpdtDt());
-                this.downloadFormMap.put(vmsFormId, downloadForm);
-            }
+
             forms++;
         }
 
@@ -608,7 +607,7 @@ public class TbVmsCtlrDto implements Serializable {
         formData.calFormCount();
 
         VmsReqDownloadForm downloadForm = new VmsReqDownloadForm(this, formData);
-        return sendData(downloadForm.getByteBuffer(), 10, downloadForm.getOpCodeDesc());
+        return sendData(downloadForm, 1);
     }
 
     /**
@@ -624,7 +623,7 @@ public class TbVmsCtlrDto implements Serializable {
             return true;
         }
         int downloadCnt = this.downloadData.getDownloadCnt();
-        log.info("downloadAutoFixForm: VMS {}, Form {} EA, Download Count {} EA.", this.vmsCtlrNmbr, formCnt, downloadCnt);
+        log.info("downloadAutoFixForm: VMS {}, Schedule Form {} EA, Download Count {} EA.", this.vmsCtlrNmbr, formCnt, downloadCnt);
         if (downloadCnt >= formCnt) {
             // 폼정보를 모두 다운로드 했기때문에 폼파일을 다운로드 해야 한다.
             this.downloadData.setDownloadCnt(0); // 폼이미지파일을 다운로드해야 하기때문에 다운로드 인덱스를 다시 0으로 리셋
@@ -654,7 +653,10 @@ public class TbVmsCtlrDto implements Serializable {
         formDto.addObject(formObjDto);
         formData.calFormCount();
 
-        log.info("downloadAutoFixForm: DownloadCnt: VMS {}, IDX {}, FormId {}, BitmapId {}, VMS_FORM_ID: {}", this.vmsCtlrNmbr, formCnt, formId, bitmapId, this.downloadFormId);
+        this.downloadData.setDownloadCnt(downloadCnt+1);
+
+        log.info("downloadAutoFixForm: VMS {}, Schedule Form {} EA, Download Count {} EA, VmsFormId {}, FormId {}, BitmapId {}.",
+                this.vmsCtlrNmbr, formCnt, downloadCnt+1, pForm.getVmsFormId(), formId, bitmapId);
 
 //        VmsFormDataDto formData = new VmsFormDataDto(formId, downloadFormCnt);
 //        int ii = downloadCnt;
@@ -696,10 +698,8 @@ public class TbVmsCtlrDto implements Serializable {
 //        formDto.calObjCount();
 //        formData.calFormCount();
 
-        this.downloadData.setDownloadCnt(downloadCnt+1);
-
         VmsReqDownloadForm downloadForm = new VmsReqDownloadForm(this, formData);
-        return sendData(downloadForm.getByteBuffer(), 10, downloadForm.getOpCodeDesc());
+        return sendData(downloadForm, 1);
     }
 
     /**
@@ -714,35 +714,43 @@ public class TbVmsCtlrDto implements Serializable {
         }
 
         int downloadCnt = this.downloadData.getDownloadCnt();
-        log.info("downloadFile: VMS {}, Form {} EA, Download Count {} EA.", this.vmsCtlrNmbr, formCnt, downloadCnt);
+        log.info("downloadFile: VMS {}, Schedule Form {} EA, Download Count {} EA.", this.vmsCtlrNmbr, formCnt, downloadCnt);
         if (downloadCnt >= formCnt) {
             // 폼파일이(폼이미지파일) 모두 다운로드 되었으므로 스케쥴 정보를 다운로드 한다.
             return downloadFormSchedule();  // Display Schedule Form
         }
 
+        this.downloadFormId = 0;
         ApplicationConfig config = (ApplicationConfig)AppUtils.getBean(ApplicationConfig.class);
         VmsDownloadData.VmsDownloadDataInfo[] units = this.downloadData.getUnits();
         for (int ii = downloadCnt; ii < formCnt; ii++) {
             this.downloadData.setDownloadCnt(downloadCnt+1);
 
-            int formId   = units[ii].getFormNo();
-            int bitmapId = units[ii].getBitmapId();
-            int formIdx  = units[ii].getFormIdx();
+            int vmsFormId = units[ii].getVmsFormId();
+            int formId    = units[ii].getFormNo();
+            int bitmapId  = units[ii].getBitmapId();
+            int formIdx   = units[ii].getFormIdx();
             VmsForm pForm = this.formManager.getItem(formIdx);
             if (config.isCheckNewForm() && !units[ii].isDownload()) {
                 // 이미 다운로드 했기 때문에 다시 다운로드 하지 않는다.
-                log.info("downloadFile: VMS {}, IDX {}, FormId {}, BitmapId {}, already download...", this.vmsCtlrNmbr, ii, formId, bitmapId);
+                log.info("downloadFile: VMS {}, IDX {}, VmsFormId {}, FormId {}, BitmapId {}, formIdx {}, DownloadFormID: {}, already download...",
+                        this.vmsCtlrNmbr, ii, vmsFormId, formId, bitmapId, formIdx, this.downloadFormId));
                 continue;
             }
 
-            this.downloadFormId = units[ii].getVmsFormId();
+            if (pForm.getVmsFormTypeCd() == eVmsFormType.eFormTp_hongbo.getValue()) {
+                // 홈보폼인 경우 다운로드 폼 ID를 저장해 놓는다.
+                this.downloadFormId = vmsFormId;
+            }
+
+            log.info("downloadFile: VMS {}, Idx {}, VmsFormId {}, FormId {}, BitmapId {}, formIdx {}, DownloadFormID: {}",
+                    this.vmsCtlrNmbr, ii, pForm.getVmsFormId(), formId, bitmapId, formIdx, this.downloadFormId);
 
-            log.info("downloadFile: DownloadCnt: VMS {}, IDX {}, FormId {}, BitmapId {}, VMS_FORM_ID: {}", this.vmsCtlrNmbr, ii, formId, bitmapId, this.downloadFormId);
             String fileName = String.format("BID%04d.BMP", bitmapId);
             eVmsFileSaveLocation saveLoc = eVmsFileSaveLocation.LOC_DOWNLOAD_PROG_IMAGE;
 
             VmsReqDataDownload dataDownload = new VmsReqDataDownload(this, saveLoc, fileName, pForm.getImageData());
-            return sendData(dataDownload.getByteBuffer(), 10, dataDownload.getOpCodeDesc());
+            return sendData(dataDownload, 1);
         }
 
         // 폼이미지 정보가 모두 다운로드 되었으므로 스케쥴 정보를 다운로드 한다.
@@ -769,22 +777,22 @@ public class TbVmsCtlrDto implements Serializable {
             dispSec[ii] = 0;
         }
 
-        log.info("downloadFormSchedule: VMS {}, Schedule {} EA, Default Schedule {}.", this.vmsCtlrNmbr, maxSchedule, this.downloadData.isDefault());
+        log.info("downloadFormSchedule: VMS {}, Schedule {} EA, Default Schedule {}.", this.vmsCtlrNmbr, formCnt, this.downloadData.isDefault());
         if (this.downloadData.isDefault()) {
             formId[0] = (short)VmsConstants.DEFAULT_FORM_ID;
             dispSec[0] = 4;
-            log.info("downloadFormSchedule: VMS {}, Schedule {} EA, Default Schedule {}.", this.vmsCtlrNmbr, maxSchedule, this.downloadData.isDefault());
+            log.info("downloadFormSchedule: VMS {}, Schedule {} EA, Default Schedule {}.", this.vmsCtlrNmbr, formCnt, this.downloadData.isDefault());
         }
         else {
             for (int ii = 0; ii < formCnt && ii < maxSchedule; ii++) {
                 formId[ii] = (short) this.downloadData.getUnits()[ii].getFormNo();
                 dispSec[ii] = (byte)(this.downloadData.getUnits()[ii].getDisplaySec() & 0xFF);
-                log.info("downloadFormSchedule: VMS {}, Schedule {} EA, FormId {}, DisplayTm {} .", this.vmsCtlrNmbr, maxSchedule, formId[ii], dispSec[ii]);
+                log.info("downloadFormSchedule: VMS {}, Schedule {} EA, Idx {}, FormId {}, DisplayTm {}.", this.vmsCtlrNmbr, formCnt, ii+1, formId[ii], dispSec[ii]);
             }
         }
 
         VmsReqDownloadFormSchedule downloadFormSchedule = new VmsReqDownloadFormSchedule(this, formId, dispSec);
-        return sendData(downloadFormSchedule.getByteBuffer(), 10, downloadFormSchedule.getOpCodeDesc());
+        return sendData(downloadFormSchedule, 1);
     }
 
     /**
@@ -794,9 +802,13 @@ public class TbVmsCtlrDto implements Serializable {
     public boolean downloadBlank() {
         log.info("downloadBlank: VMS {}.", this.vmsCtlrNmbr);
         VmsReqBlank reqBlank = new VmsReqBlank(this);
-        return sendData(reqBlank.getByteBuffer(), 10, reqBlank.getOpCodeDesc());
+        return sendData(reqBlank, 1);
     }
 
+    /**
+     * 제어기로 심벌라이브러리를 다운로드한다.
+     * @return
+     */
     public boolean downloadSymbLib() {
         this.dnldSymbLibNmbr = 0;
         if (this.reqDnldSymbMap.size() == 0) {
@@ -815,9 +827,98 @@ public class TbVmsCtlrDto implements Serializable {
             eVmsFileSaveLocation saveLoc = eVmsFileSaveLocation.LOC_DOWNLOAD_PROG_IMAGE;
 
             VmsReqDataDownload dataDownload = new VmsReqDataDownload(this, saveLoc, fileName, dnldSymb.getImageData());
-            sendData(dataDownload.getByteBuffer(), 10, dataDownload.getOpCodeDesc());
+            sendData(dataDownload, 1);
             return true;
         }
         return false;
     }
+/*
+    private int   powerCtrlMode;  // 전원제어 모드                1 Byte  0x00 : 꺼짐, 0x01 : 켜짐,
+    private int   fanRunMode;     // Fan 동작모드                 1 Byte  0x00 : 꺼짐, 0x01 : 켜짐, 0x02 : 자동, 0x09: Unknown
+    private int   fanRunTemp;     // Fan 의 동작개시온도          1 Byte  온도( 0x00 ~0x03f )
+    private int   heaterRunMode;  // Heater 의 동작모드           1 Byte  0x00 : 꺼짐, 0x01 : 켜짐, 0x02 : 자동, 0x09: Unknown
+    private int   heaterRunTemp;  // Heater 의 동작개시온도       1 Byte  온도(0x00 ~ 0x3f )
+    private int   brightMode; // 화면의 밝기 - 휘도 모드, 0x00:주간, 0x01:야간, 0x02:Auto, 0x03:수동
+    private int   brightCurr; // 화면의 밝기 - 현재 휘도값, 0~100
+    private int   brightWeek; // 화면의 밝기 - 주간 휘도값, 0~100
+    private int   brightNght; // 화면의 밝기 - 야간 휘도값, 0~100
+    private int   blinkTime;      // 깜빡이는 시간주기            1 Byte  문자 비트맵의 깜빡이는 시간주기 0x00 ~ 0x1e( 0.1 ~3.0 )
+    private short scnTurnTime;    // 디폴트 시나리오로 전환시간   2 Byte  디폴트 시나리오로 전환될 때까지 기다리는 시간, 단위 : 초
+    private int   modlErrRate;    // 장애 모듈비율(%)             1 Byte  에러난 픽셀의 백분율 (0~100: 초기값:10%)
+*/
+    public void updateParameter(int powerCtrlMode, int fanRunMode, int fanRunTemp, int heaterRunMode, int heaterRunTemp,
+                                int brightMode, int brightCurr, int brightWeek, int brightNght, int blinkTime, short scnTurnTime, int modlErrRate) {
+        boolean isDifferent = false;
+
+        if (powerCtrlMode != this.panlPwerMode) {
+            isDifferent = true;
+            this.panlPwerMode = powerCtrlMode;
+        }
+        if (fanRunMode != this.fanMode) {
+            isDifferent = true;
+            this.fanMode = fanRunMode;
+        }
+        if (fanRunTemp != this.fanRunTmpr) {
+            isDifferent = true;
+            this.fanRunTmpr = fanRunTemp;
+        }
+        if (heaterRunMode != this.hetrMode) {
+            isDifferent = true;
+            this.hetrMode = heaterRunMode;
+        }
+        if (heaterRunTemp != this.hetrRunTmpr) {
+            isDifferent = true;
+            this.hetrRunTmpr = heaterRunTemp;
+        }
+
+        if (brightMode != this.brghMode) {
+            isDifferent = true;
+            this.brghMode = brightMode;
+        }
+        if (brightCurr != this.brghCurrStep) {
+            isDifferent = true;
+            this.brghCurrStep = brightCurr;
+        }
+        if (brightWeek != this.brghWeekStep) {
+            isDifferent = true;
+            this.brghWeekStep = brightWeek;
+        }
+        if (brightNght != this.brghNghtStep) {
+            isDifferent = true;
+            this.brghNghtStep = brightNght;
+        }
+
+        if (scnTurnTime != this.defPhseChngCycl) {
+            isDifferent = true;
+            this.defPhseChngCycl = (int)scnTurnTime;
+        }
+        if (modlErrRate != this.modlErrRate) {
+            isDifferent = true;
+            this.modlErrRate = modlErrRate;
+        }
+
+        if (isDifferent) {
+            DbmsDataProcess dbmsDataProcess = (DbmsDataProcess) AppUtils.getBean(DbmsDataProcess.class);
+            dbmsDataProcess.add(new DbmsData(DbmsDataType.DBMS_DATA_CTLR_PARAMETER, false, toParamEntity()));
+        }
+    }
+
+    public VmsCtlrParam toParamEntity() {
+        return VmsCtlrParam.builder()
+                .vmsCtlrNmbr(this.vmsCtlrNmbr)
+                .panlPwerMode(this.panlPwerMode)
+                .fanMode(this.fanMode)
+                .fanRunTmpr(this.fanRunTmpr)
+                .hetrMode(this.hetrMode)
+                .hetrRunTmpr(this.hetrRunTmpr)
+                .brghMode(this.brghMode)
+                .brghCurrStep(this.brghCurrStep)
+                .brghWeekStep(this.brghWeekStep)
+                .brghNghtStep(this.brghNghtStep)
+                .modlErrRate(this.modlErrRate)
+                .cmncFailRate(this.cmncFailRate)
+                .build();
+    }
+
 }
+

+ 6 - 6
src/main/java/com/its/vms/entity/TbVmsCtlr.java

@@ -38,13 +38,13 @@ public class TbVmsCtlr implements Serializable {
     private Integer vmsMaxPhseNum;
     private String panlOnTime;
     private String panlOffTime;
-    private String panlPwerMode;
-    private String brghMode;
+    private Integer panlPwerMode;
+    private Integer brghMode;
     private String istlLctnNm;
     private String trfcStrgUseYn;
     private Long vmsLocIfscId;
-    private Double fanRunTmpr;
-    private Double hetrRunTmpr;
+    private Integer fanRunTmpr;
+    private Integer hetrRunTmpr;
     private Integer fanMode;
     private Integer hetrMode;
     private Integer brghCurrStep;
@@ -72,8 +72,8 @@ public class TbVmsCtlr implements Serializable {
         if (this.pwerFailSlotNmbr == null) this.pwerFailSlotNmbr = 0;
         if (this.vmsMaxPhseNum == null) this.vmsMaxPhseNum = 10;
         if (this.vmsLocIfscId == null) this.vmsLocIfscId = 0L;
-        if (this.fanRunTmpr == null) this.fanRunTmpr = 0.;
-        if (this.hetrRunTmpr == null) this.hetrRunTmpr = 0.;
+        if (this.fanRunTmpr == null) this.fanRunTmpr = 0;
+        if (this.hetrRunTmpr == null) this.hetrRunTmpr = 0;
         if (this.fanMode == null) this.fanMode = 10;
         if (this.hetrMode == null) this.hetrMode = 10;
         if (this.brghCurrStep == null) this.brghCurrStep = 10;

+ 105 - 15
src/main/java/com/its/vms/entity/TbVmsCtlrStts.java

@@ -14,17 +14,17 @@ public class TbVmsCtlrStts implements Serializable {
 
     private Long vmsCtlrNmbr;
     private String updtDt;
-    private String cmncSttsCd;
-    private String pwerSttsCd;
-    private String modlSttsCd;
-    private String cboxDoorSttsCd;
-    private String fanSttsCd;
-    private String hetrSttsCd;
-    private Integer cboxTmpr;
-    private Integer brghVal;
-    private String commSttsCd;
-    private String modlStts;
-    private String pwerStts;
+    private String cmncSttsCd;      // 통신 상태 코드('CMS')
+    private String pwerSttsCd;      // 전원 상태 코드('PWS')
+    private String modlSttsCd;      // 모듈(LED) 상태 코드
+    private String cboxDoorSttsCd;  // 함체 문 상태 코드('CDS')
+    private String fanSttsCd;       // 팬 상태 코드('PAS')
+    private String hetrSttsCd;      // 히터 상태 코드('HTS')
+    private Integer cboxTmpr;       // 함체 온도
+    private Integer brghVal;        // 휘도값
+    private String commSttsCd;      // 통신 상태 코드('CMS')
+    private String modlStts;        // 모듈상태(문자열, 0: 꺼짐, 1: 켜짐, 9: 알수없음)
+    private String pwerStts;        // 전원상태(문자열, 0: 꺼짐, 1: 켜짐, 9: 알수없음)
 
     public TbVmsCtlrStts(Long vmsCtlrNmbr) {
         this.vmsCtlrNmbr = vmsCtlrNmbr;
@@ -57,7 +57,7 @@ public class TbVmsCtlrStts implements Serializable {
     public void initUnknown() {
         this.updtDt = SysUtils.getSysTime();
         this.cmncSttsCd = "CMS2";
-        this.pwerSttsCd = "MOS2";
+        this.pwerSttsCd = "PWS2";
         this.modlSttsCd = "MOS2";
         this.cboxDoorSttsCd = "CDS2";
         this.fanSttsCd = "PAS2";
@@ -80,9 +80,6 @@ public class TbVmsCtlrStts implements Serializable {
         this.commSttsCd = "CMS0";
     }
 
-    public void setStts(int frontDoor, int backDoor, int fan, int hetr, int rtu, int tmpr, int hmdt) {
-    }
-
     public void updateStts(TbVmsCtlrStts dto) {
         this.updtDt = dto.getUpdtDt();
         this.cmncSttsCd = dto.getCmncSttsCd();
@@ -97,4 +94,97 @@ public class TbVmsCtlrStts implements Serializable {
         this.modlStts = dto.getModlStts();
         this.pwerStts = dto.getPwerStts();
     }
+/*
+    private int door;       // Door Open/Close 상태, 0x00: Open, 0x01: Close, 0x09: Unknown
+    private int power;      // 전원의 ON/OFF 상태, 0x00: On, 0x01: Off, 0x09: Unknown (Sign Board)
+    private int fan;        // VMS Fan 동작 상태, 0x00: On, 0x01: Off, 0x09: Unknown
+    private int heater;     // VMS Heater 동작 상태, 0x00: On, 0x01: Off, 0x09: Unknown
+    private int formNo;     // 표출 폼 번호, 현재 표출중인 폼 번호 : 0~9999
+    private int reboot;     // 표출 폼 번호, 0x00: 정상, 0x01: 재실행
+    private int cboxTemp;   // 함체온도, 127 ~ -127, -128 : Unknown
+    private int brightMode; // 화면의 밝기 - 휘도 모드, 0x00:주간, 0x01:야간, 0x02:Auto, 0x03:수동
+    private int brightCurr; // 화면의 밝기 - 현재 휘도값, 0~100
+    private int brightWeek; // 화면의 밝기 - 주간 휘도값, 0~100
+    private int brightNght; // 화면의 밝기 - 야간 휘도값, 0~100
+    private int dpTemp;     // 외부온도, -127 ~ 127, -128: Unknown
+    private int dpHum;      // 외부습도,    0 ~ 100,  101: Unknown
+    private int powerModuleStts = 0x02; // 0x00: 정상, 0x01: 에러, 0x02: Unknown
+    private int moduleStts = 0x02;      // 0x00: 정상, 0x01: 불량, 0x02: Unknown
+    private int cboxFan = 0x09;         // 0x00: On, 0x01: Off, 0x09: Unknown
+    private int cboxHeather = 0x09;     // 0x00: On, 0x01: Off, 0x09: Unknown
+
+ */
+    public boolean updateStatus(int door, int power, int fan, int heater, int formNo, int reboot, int cboxTemp,
+                                int brightMode, int brightCurr, int brightWeek, int brightNght, int dpTemp, int dpHum,
+                                int powerModuleStts, int moduleStts, int cboxFan, int cboxHeather) {
+        boolean isDifferent = false;
+        this.updtDt = SysUtils.getSysTime();
+
+        int doorSttsCd;
+        if (door == 0) doorSttsCd = 1;
+        else if (door == 1) doorSttsCd = 0;
+        else doorSttsCd = 2;
+
+        if (fan > 1) {
+            fan = 2;
+        }
+        if (heater > 1) {
+            heater = 2;
+        }
+
+        String pwerSttsCd = "PWS" + powerModuleStts;
+        String modlSttsCd = "MOS" + moduleStts;
+        String cboxDoorSttsCd = "CDS" + doorSttsCd;
+        String fanSttsCd = "PAS" + fan;
+        String hetrSttsCd = "HTS" + heater;
+
+        if (!pwerSttsCd.equals(this.pwerSttsCd)) {
+            isDifferent = true;
+            this.pwerSttsCd = pwerSttsCd;
+        }
+        if (!modlSttsCd.equals(this.modlSttsCd)) {
+            isDifferent = true;
+            this.modlSttsCd = modlSttsCd;
+        }
+        if (!cboxDoorSttsCd.equals(this.cboxDoorSttsCd)) {
+            isDifferent = true;
+            this.cboxDoorSttsCd = cboxDoorSttsCd;
+        }
+        if (!fanSttsCd.equals(this.fanSttsCd)) {
+            isDifferent = true;
+            this.fanSttsCd = fanSttsCd;
+        }
+        if (!hetrSttsCd.equals(this.hetrSttsCd)) {
+            isDifferent = true;
+            this.hetrSttsCd = hetrSttsCd;
+        }
+
+        if (cboxTemp != this.cboxTmpr) {
+            isDifferent = true;
+            this.cboxTmpr = cboxTemp;
+        }
+        if (brightCurr != this.brghVal) {
+            isDifferent = true;
+            this.brghVal = brightCurr;
+        }
+
+        return isDifferent;
+    }
+
+    public boolean updatePowerModuleStts(String stts) {
+        if (stts.equals(this.pwerStts)) {
+            return false;
+        }
+        this.pwerStts = stts;
+        return true;
+    }
+
+    public boolean updateModuleStts(String stts) {
+        if (stts.equals(this.modlStts)) {
+            return false;
+        }
+        this.modlStts = stts;
+        return true;
+    }
+
 }

+ 34 - 0
src/main/java/com/its/vms/entity/VmsCtlrParam.java

@@ -0,0 +1,34 @@
+package com.its.vms.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * VMS 파라미터 정보 Entity Class
+ */
+@Getter
+@Builder
+@NoArgsConstructor//(access = AccessLevel.PROTECTED)
+@AllArgsConstructor
+public class VmsCtlrParam implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private Long vmsCtlrNmbr;
+
+    private Integer panlPwerMode;        // 전광판 전원 모드(0x00:꺼짐,0x01:켜짐,0x02:자동,0x09:알수없음)
+    private Integer fanMode;            // FAN 동작모드(0x00:꺼짐,0x01:켜짐,0x02:자동,0x09:알수없음)
+    private Integer fanRunTmpr;          // 팬 동작 온도
+    private Integer hetrMode;           // 히터 동작모드(0x00:꺼짐,0x01:켜짐,0x02:자동,0x09:알수없음)
+    private Integer hetrRunTmpr;         // 히터 동작 온도
+    private Integer brghMode;           // 휘도 모드(0x00:주간,0x01:야간,0x02:자동,0x09:수동)
+    private Integer brghCurrStep;       // 휘도 현재 단계(0~100)
+    private Integer brghWeekStep;       // 휘도 주간 단계(0~100)
+    private Integer brghNghtStep;       // 휘도 야간 단계(0~100)
+    private Integer modlErrRate;        // VMS 모듈 오류 율
+    private Integer cmncFailRate;       // VMS 통신 오류 기본 값
+
+}

+ 24 - 0
src/main/java/com/its/vms/entity/VmsDsplDnldResult.java

@@ -0,0 +1,24 @@
+package com.its.vms.entity;
+
+import lombok.*;
+
+import java.io.Serializable;
+
+/**
+ * VMS 표출정보 제어기 다운로드 결과 정보 Entity Class
+ */
+@Getter
+@Setter
+@Builder
+@NoArgsConstructor//(access = AccessLevel.PROTECTED)
+@AllArgsConstructor
+public class VmsDsplDnldResult implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private Long vmsCtlrNmbr;
+
+    private String dsplDt;
+    private Integer formCnt;
+    private String dnldYn;
+
+}

+ 30 - 5
src/main/java/com/its/vms/process/DbmsDataProcess.java

@@ -4,6 +4,7 @@ import com.its.app.AppUtils;
 import com.its.vms.config.ThreadPoolInitializer;
 import com.its.vms.dao.mapper.UnitSystMapper;
 import com.its.vms.dao.mapper.VmsCtlrMapper;
+import com.its.vms.dao.mapper.VmsManageMapper;
 import com.its.vms.dao.mapper.VmsSymbMapper;
 import com.its.vms.dao.mapper.batch.VmsCtlrDao;
 import com.its.vms.dao.mapper.batch.VmsManageDao;
@@ -12,6 +13,9 @@ import com.its.vms.domain.VmsForm;
 import com.its.vms.dto.TbVmsCtlrDto;
 import com.its.vms.entity.*;
 import com.its.vms.service.AppRepositoryService;
+import com.its.vms.xnettcp.vms.process.TcpServerSendData;
+import com.its.vms.xnettcp.vms.protocol.enums.eVmsOpCode;
+import com.its.vms.xnettcp.vms.protocol.impl.VmsReqLocalUserCommand;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
@@ -38,6 +42,7 @@ public class DbmsDataProcess {
     private final UnitSystMapper unitSystMapper;
     private final VmsCtlrMapper vmsCtlrMapper;
     private final VmsSymbMapper symbMapper;
+    private final VmsManageMapper vmsManageMapper;
     private final AppRepositoryService repoService;
 
     private int maxCore = Runtime.getRuntime().availableProcessors();
@@ -89,6 +94,7 @@ public class DbmsDataProcess {
     }
 
     public void process(DbmsData data) {
+        int cnt = 0;
         try {
             DbmsDataType type = data.getType();
             switch(type) {
@@ -104,6 +110,11 @@ public class DbmsDataProcess {
                     }
                     ctlrSttsList.clear();
                     break;
+                case DBMS_DATA_CTLR_PARAMETER:
+                    VmsCtlrParam param = (VmsCtlrParam)data.getData();
+                    cnt = this.vmsCtlrMapper.updateVmsCtlrParam(param);
+                    log.info("DbmsJobProcess.process: DBMS_DATA_CTLR_PARAMETER, VMS {} Updated {}.", param.getVmsCtlrNmbr(), cnt);
+                    break;
                 case DBMS_DATA_CTRL_HS:
                     this.vmsCtlrMapper.insertVmsCtrlHs((TbVmsCtrlHs)data.getData());
                     break;
@@ -113,22 +124,30 @@ public class DbmsDataProcess {
                     List<TbVmsDsplPrst> dsplPrstList = new ArrayList<>();
                     List<TbVmsDsplPrst> dsplPrstHsList = new ArrayList<>();
 
+                    boolean isScheduled = data.isHistory();
                     for (Map.Entry<Long, TbVmsCtlrDto> e : this.repoService.getCtlrMap().entrySet()) {
                         TbVmsCtlrDto vmsObj = e.getValue();
                         int formCnt = vmsObj.getFormManager().count();
                         for (int ii = 0; ii < formCnt; ii++) {
                             VmsForm vmsForm = vmsObj.getFormManager().getItem(ii);
                             TbVmsDsplPrst dsplPrst = vmsForm.toDsplPrstEntity(vmsObj, ii+1, dsplDt, "N");
+                            // 모든 제어기의 현재 표출폼 정보를 업데이트 한다.
                             dsplPrstList.add(dsplPrst);
-                            if (vmsObj.getNetState() != NET.CLOSED) {
-                                //TcpServerSendData reqData = new TcpServerSendData(TcpServerSendData.DATA_REQ_FORM_DOWNLOAD, null);
-                                //vmsObj.addRequestData(reqData);
-                            }
-                            else {
+                            if (vmsObj.getNetState() == NET.CLOSED) {
+                                // 통신상태가 연결되지 않은 경우 표출폼 이력데이터를 함께 저장한다.
                                 dsplPrstHsList.add(dsplPrst);
                             }
                         }
                     }
+                    for (Map.Entry<Long, TbVmsCtlrDto> e : this.repoService.getCtlrMap().entrySet()) {
+                        TbVmsCtlrDto vmsObj = e.getValue();
+                        if (vmsObj.getNetState() != NET.CLOSED) {
+                            // 통신상태가 연결되어 있는 경우 표출폼을 제어기로 전송한 후 결과를 저장하도록 한다.
+                            VmsReqLocalUserCommand reqLocalUserCommand = new VmsReqLocalUserCommand(vmsObj, (short)0, isScheduled ? (short)1 : (short)0);
+                            vmsObj.addRequestData(new TcpServerSendData(eVmsOpCode.OP_VMS_LOCAL_USER_COMMAND, reqLocalUserCommand));
+                        }
+                    }
+
                     if (!dsplPrstList.isEmpty()) {
                         this.vmsManageDao.updateVmsDsplPrst(dsplPrstList);
                     }
@@ -136,6 +155,12 @@ public class DbmsDataProcess {
                         this.vmsManageDao.insertVmsDsplPrst(dsplPrstHsList);
                     }
                     break;
+                case DBMS_DATA_VMS_FORM_DOWNLOAD_RESULT:
+                    VmsDsplDnldResult dnldResult = (VmsDsplDnldResult)data.getData();
+                    this.vmsManageMapper.updateVmsDsplPrstResult(dnldResult);
+                    cnt = this.vmsManageMapper.insertVmsDsplPrstHsResult(dnldResult);
+                    log.info("DbmsJobProcess.process: DBMS_DATA_VMS_FORM_DOWNLOAD_RESULT, VMS {} Forms {}/{} EA.", dnldResult.getVmsCtlrNmbr(), dnldResult.getFormCnt(), cnt);
+                    break;
                 case DBMS_DATA_SYMB_DNLD:
                     TbVmsSymbLibDnld symbLibDnld = (TbVmsSymbLibDnld)data.getData();
                     if (symbLibDnld != null) {

+ 3 - 0
src/main/java/com/its/vms/process/DbmsDataType.java

@@ -5,7 +5,10 @@ public enum DbmsDataType {
     DBMS_DATA_UNIT_SYST_STTS,
     DBMS_DATA_CTLR_STTS,
     DBMS_DATA_CTLR_STTS_LIST,
+    DBMS_DATA_CTLR_PARAMETER,
+
     DBMS_DATA_VMS_FORM_DOWNLOAD,
+    DBMS_DATA_VMS_FORM_DOWNLOAD_RESULT,
     DBMS_DATA_SECT_TRAF_HS,
     DBMS_DATA_SECT_PASS_HS,
     DBMS_DATA_LOG_HS,

+ 1 - 1
src/main/java/com/its/vms/scheduler/SchedulerTask.java

@@ -62,7 +62,7 @@ public class SchedulerTask {
         Elapsed elapsed = new Elapsed();
         log.info("scheduleVmsFormDownload..: start. {}", Thread.currentThread().getName());
         this.repoService.setStaticCycle(true);
-        this.vmsManageService.jobMakeDownloadVmsForm();;
+        this.vmsManageService.jobMakeDownloadVmsForm();
         log.info("scheduleVmsFormDownload..: ..end. {} ms. {}", elapsed.milliSeconds(), Thread.currentThread().getName());
     }
 

+ 3 - 3
src/main/java/com/its/vms/service/AppRepositoryService.java

@@ -16,9 +16,9 @@ import java.util.concurrent.ConcurrentMap;
 @RequiredArgsConstructor
 public class AppRepositoryService {
 
-    private final ConcurrentHashMap<Long, TbVmsCtlrDto> ctlrMap = new ConcurrentHashMap<>();;
-    private final ConcurrentHashMap<String, TbVmsCtlrDto> ipAddrMap = new ConcurrentHashMap<>();;
-    private final ConcurrentHashMap<Channel, TbVmsCtlrDto> channelMap = new ConcurrentHashMap<>();;
+    private final ConcurrentHashMap<Long, TbVmsCtlrDto> ctlrMap = new ConcurrentHashMap<>();
+    private final ConcurrentHashMap<String, TbVmsCtlrDto> ipAddrMap = new ConcurrentHashMap<>();
+    private final ConcurrentHashMap<Channel, TbVmsCtlrDto> channelMap = new ConcurrentHashMap<>();
 
     private boolean isStaticCycle = false;
     private String dsplDt;  // 폼 정보 다운로드 시각

+ 12 - 12
src/main/java/com/its/vms/service/VmsManageService.java

@@ -96,13 +96,13 @@ public class VmsManageService {
                 if (nOnTime > nOffTime) {
                     // 0100(off), 0500(on)
                     if (nCurrTime >= nOffTime && nCurrTime < nOnTime) {
-                        controlOnOff = eVmsReqBoardPower.vms_req_board_power_off.getValue();;
+                        controlOnOff = eVmsReqBoardPower.vms_req_board_power_off.getValue();
                     }
                 }
                 else {
                     // 2300(off), 0500(on)
                     if (nCurrTime >= nOffTime || nCurrTime < nOnTime) {
-                        controlOnOff = eVmsReqBoardPower.vms_req_board_power_off.getValue();;
+                        controlOnOff = eVmsReqBoardPower.vms_req_board_power_off.getValue();
                     }
                 }
             }
@@ -409,7 +409,7 @@ public class VmsManageService {
         else {
             for (int ii = 0; ii < ifscIds.size() && ii < fromMaxCnt; ii++) {
                 TbVmsScheduleDto trafSchedule = schedule.clone();
-                trafSchedule.setVmsFormId(schedule.getDnldFormId()+ii);
+                trafSchedule.setDnldFormId(schedule.getDnldFormId()+ii);
                 trafSchedule.initTrafId();
                 trafSchedule.setVmsIfscId(ifscIds.get(ii));
                 trafSchedule.setFrstVmsIfscId(ifscIds.get(ii));
@@ -760,7 +760,7 @@ public class VmsManageService {
          * 데이터베이스 처리 프로레스에서 제어기의 네트워크 상태에 따라서 통신 정상인 제어기로 데이터를 전송한다.
          */
         this.repoService.setDsplDt(ItsUtils.getSysTime());
-        this.dbmsDataProcess.add(new DbmsData(DbmsDataType.DBMS_DATA_VMS_FORM_DOWNLOAD, false, this.repoService.getDsplDt()));
+        this.dbmsDataProcess.add(new DbmsData(DbmsDataType.DBMS_DATA_VMS_FORM_DOWNLOAD, this.repoService.isStaticCycle(), this.repoService.getDsplDt()));
         log.info("VmsManageService.jobMakeDownloadVmsForm: {} ms.", elapsed.milliSeconds());
     }
 
@@ -835,14 +835,14 @@ public class VmsManageService {
                     if (vmsSchFormType != eVmsScheduleType.eSchTp_evehicle || vmsForm.getVmsFormDsplDrctCd() != 0) {
                         // 긴급차량우선신호 진행중 일때 스케쥴 유형 및 폼유형이 맞지 않으면 리턴
                         // 단일 메시지로 표출하는 경우
-                        log.info("VmsManageService.makeVmsProvideForm: VMS {}, FORM {}, EVehicle Ing {}. {} DsplDrctCd {}.",
-                                ctlrNmbr, vmsForm.getVmsFormId(), isEVehIngForm, vmsSchFormType, vmsForm.getVmsFormDsplDrctCd());
+//                        log.info("VmsManageService.makeVmsProvideForm: VMS {}, FORM {}, EVehicle Ing {}. {} DsplDrctCd {}.",
+//                                ctlrNmbr, vmsForm.getVmsFormId(), isEVehIngForm, vmsSchFormType, vmsForm.getVmsFormDsplDrctCd());
                         continue;
                     }
                 } else {
                     if (vmsSchFormType == eVmsScheduleType.eSchTp_evehicle && vmsForm.getVmsFormDsplDrctCd() == 0) {
-                        log.info("VmsManageService.makeVmsProvideForm: VMS {}, FORM {}, EVehicle Ing {}. {} DsplDrctCd {}.",
-                                ctlrNmbr, vmsForm.getVmsFormId(), isEVehIngForm, vmsSchFormType, vmsForm.getVmsFormDsplDrctCd());
+//                        log.info("VmsManageService.makeVmsProvideForm: VMS {}, FORM {}, EVehicle Ing {}. {} DsplDrctCd {}.",
+//                                ctlrNmbr, vmsForm.getVmsFormId(), isEVehIngForm, vmsSchFormType, vmsForm.getVmsFormDsplDrctCd());
                         continue;
                     }
                 }
@@ -857,8 +857,8 @@ public class VmsManageService {
 //                    }
                 } else {
                     if (vmsSchFormType == eVmsScheduleType.eSchTp_evehicle && vmsForm.getVmsFormDsplDrctCd() == 1) {
-                        log.info("VmsManageService.makeVmsProvideForm: VMS {}, FORM {}, EVehicle End {}. {} DsplDrctCd {}.",
-                                ctlrNmbr, vmsForm.getVmsFormId(), isEVehEndForm, vmsSchFormType, vmsForm.getVmsFormDsplDrctCd());
+//                        log.info("VmsManageService.makeVmsProvideForm: VMS {}, FORM {}, EVehicle End {}. {} DsplDrctCd {}.",
+//                                ctlrNmbr, vmsForm.getVmsFormId(), isEVehEndForm, vmsSchFormType, vmsForm.getVmsFormDsplDrctCd());
                         continue;
                     }
                 }
@@ -1501,8 +1501,8 @@ public class VmsManageService {
             }
             pForm.setSuccess(true);
 
-            log.info("VmsManagerService.makeVmsDatabaseFormData: VMS {}, FORM {}, Objects {}. ScheduleType {}, FileType {}, File/FtpName {}/{}.",
-                    vmsObj.getVmsCtlrNmbr(), pForm.getVmsFormId(), pForm.count(), eVmsScheduleType.getValue(pForm.getVmsSchFormType()), pForm.getFileType(), pForm.getLocalFileName(), pForm.getFtpFileName());
+            log.info("VmsManagerService.makeVmsDatabaseFormData: VMS {}, FORM {}, DnldFormNo {}, Objects {}. ScheduleType {}, FileType {}, File/FtpName {}/{}.",
+                    vmsObj.getVmsCtlrNmbr(), pForm.getVmsFormId(), pForm.getDnldFormNo(), pForm.count(), eVmsScheduleType.getValue(pForm.getVmsSchFormType()), pForm.getFileType(), pForm.getLocalFileName(), pForm.getFtpFileName());
         }
     }
 

+ 10 - 0
src/main/java/com/its/vms/ui/CtlrSttsTableModel.java

@@ -97,21 +97,31 @@ public class CtlrSttsTableModel extends AbstractTableModel {
                     fDoor = "닫힘";
                 } else if ("CDS1".equals(stts.getCboxDoorSttsCd())) {
                     fDoor = "열림";
+                } else {
+                    fDoor = "-?-";
                 }
+
                 if ("CDS0".equals(stts.getCboxDoorSttsCd())) {
                     bDoor = "닫힘";
                 } else if ("CDS1".equals(stts.getCboxDoorSttsCd())) {
                     bDoor = "열림";
+                } else {
+                    bDoor = "-?-";
                 }
+
                 if ("PAS0".equals(stts.getFanSttsCd())) {
                     fan = "가동";
                 } else if ("PAS1".equals(stts.getFanSttsCd())) {
                     fan = "중지";
+                } else {
+                    fan = "-?-";
                 }
                 if ("HTS0".equals(stts.getHetrSttsCd())) {
                     hetr = "가동";
                 } else if ("HTS1".equals(stts.getHetrSttsCd())) {
                     hetr = "중지";
+                } else {
+                    hetr = "-?-";
                 }
             }
             switch (columnIndex) {

+ 9 - 1
src/main/java/com/its/vms/ui/SubUI.java

@@ -206,7 +206,7 @@ public abstract class SubUI {
                 this.selObj.addRequestData(new TcpServerSendData(eVmsOpCode.OP_VMS_PARAMETER_REQ, null));
                 return;
             case 3:
-                this.selObj.downloadForm(false);
+                this.selObj.downloadForm();
                 return;
             case 4:
                 statusControl.controlSystemTime();
@@ -266,17 +266,25 @@ public abstract class SubUI {
                     door = "닫힘";
                 } else if (stts.getCboxDoorSttsCd().equals("CDS1")) {
                     door = "열림";
+                } else {
+                    door = "-?-";
                 }
                 if (stts.getFanSttsCd().equals("PAS0")) {
                     fan = "중지";
                 } else if (stts.getFanSttsCd().equals("PAS1")) {
                     fan = "가동";
                 }
+                else {
+                    fan = "-?-";
+                }
                 if (stts.getHetrSttsCd().equals("HTS0")) {
                     heater = "중지";
                 } else if (stts.getHetrSttsCd().equals("HTS1")) {
                     heater = "가동";
                 }
+                else {
+                    heater = "-?-";
+                }
                 temper = String.valueOf(stts.getCboxTmpr());
             }
             txtDoor.setText(door);

+ 1 - 1
src/main/java/com/its/vms/xnettcp/vms/VmsTcpCommServerInitializer.java

@@ -47,7 +47,7 @@ public class VmsTcpCommServerInitializer extends ChannelInitializer<Channel> {
             ChannelPipeline pipeline = channel.pipeline();
             //pipeline.addLast(new LoggingHandler(LogLevel.INFO));
             pipeline.addLast("vmsTcpIdleStateHandler", tcpIdleStateHandler);
-            pipeline.addLast("vmsServerIdleStateHandler", new VmsServerIdleStateHandler(obj, this.dbmsDataProcess));   // packet idle state handler, event handler
+            pipeline.addLast("vmsServerIdleStateHandler", new VmsServerIdleStateHandler(obj, this.dbmsDataProcess, this.config));   // packet idle state handler, event handler
             if (obj.getProtocolVer() == 0) {
                 pipeline.addLast("vmsServerDecoder", new VmsTcpServerDleStuffingDecoder(this.config, this.repoService, obj));  // Decoding handler
             }

+ 4 - 1
src/main/java/com/its/vms/xnettcp/vms/handler/VmsServerIdleStateHandler.java

@@ -2,6 +2,7 @@ package com.its.vms.xnettcp.vms.handler;
 
 import com.its.app.AppUtils;
 import com.its.app.utils.NettyUtils;
+import com.its.vms.config.CommunicationConfig;
 import com.its.vms.dto.TbVmsCtlrDto;
 import com.its.vms.entity.TbVmsCtlrStts;
 import com.its.vms.process.DbmsData;
@@ -29,6 +30,7 @@ public class VmsServerIdleStateHandler extends ChannelDuplexHandler {
 
     private final TbVmsCtlrDto vmsObj;
     private final DbmsDataProcess dbmsDataProcess;
+    private final CommunicationConfig config;
 
     @Override
     public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
@@ -37,7 +39,8 @@ public class VmsServerIdleStateHandler extends ChannelDuplexHandler {
             if (e.state() == IdleState.READER_IDLE) {
                 MDC.put("id", this.vmsObj.getLogKey());
                 String ipAddress  = NettyUtils.getRemoteIpAddress(ctx.channel());
-                log.error("VmsServerIdleStateHandler.userEventTriggered, ----READER_IDLE: {},  will be closed.", ipAddress);
+                log.error("VmsServerIdleStateHandler.userEventTriggered, ----READER_IDLE: {}, R: {}, W: {}, A: {} will be closed.",
+                        ipAddress, this.config.getReaderIdleTimeSeconds(), this.config.getWriterIdleTimeSeconds(), this.config.getAllIdleTimeSeconds());
                 ctx.channel().disconnect();
                 ctx.channel().close();
                 MDC.remove(this.vmsObj.getLogKey());

+ 5 - 0
src/main/java/com/its/vms/xnettcp/vms/process/TcpServerRecvDataProcess.java

@@ -83,6 +83,11 @@ public class TcpServerRecvDataProcess {
 
             VmsResponse response = null;
             eVmsOpCode opCode = eVmsOpCode.getValue(packet.getOpCode());
+            /**
+             * 제어기 명령 타임아웃 타스크 제거
+             */
+            vmsObj.removeRegisteredCommandsTimer(opCode);
+
             switch(opCode) {
                 case OP_VMS_STATUS_REQ:
                     response = new VmsResStatus(vmsObj, packet);

+ 20 - 12
src/main/java/com/its/vms/xnettcp/vms/process/TcpServerSendDataProcess.java

@@ -44,27 +44,35 @@ public class TcpServerSendDataProcess {
 
         boolean isConnected = (this.vmsObj.getNetState() > NET.CLOSED && this.vmsObj.getChannel() != null);
         boolean isRequested = false;
-        log.info("TcpServerReqDataProcess.process: VMS {}, command({}), connected({}), Elapsed: {} ms.", this.vmsObj.getVmsCtlrNmbr(), data.getOpCode(), isConnected, data.elapsed());
+        if (data.elapsed() > 500) {
+            log.info("TcpServerReqDataProcess.process: VMS {}, command({}), connected({}), Elapsed: {} ms.", this.vmsObj.getVmsCtlrNmbr(), data.getOpCode(), isConnected, data.elapsed());
+        }
 
         boolean result = true;
         if (isConnected) {
             try {
                 switch (data.getOpCode()) {
+                    case OP_VMS_LOCAL_USER_COMMAND:
+                        VmsReqLocalUserCommand reqLocalUserCommand = (VmsReqLocalUserCommand)data.getData();
+                        if (reqLocalUserCommand.getCommand() == 0) {
+                            result = vmsObj.downloadForm();
+                        }
+                        break;
                     case OP_VMS_STATUS_REQ:
                         VmsReqStatus reqStatus = new VmsReqStatus(this.vmsObj);
-                        result = this.vmsObj.sendData(reqStatus.getByteBuffer(), 10, reqStatus.getOpCodeDesc());
+                        result = this.vmsObj.sendData(reqStatus, 1);
                         break;
                     case OP_VMS_POWER_MODULE_STATUS_REQ:
                         VmsReqPowerModuleStatus reqPowerModuleStatus = new VmsReqPowerModuleStatus(this.vmsObj);
-                        result = this.vmsObj.sendData(reqPowerModuleStatus.getByteBuffer(), 10, reqPowerModuleStatus.getOpCodeDesc());
+                        result = this.vmsObj.sendData(reqPowerModuleStatus, 1);
                         break;
                     case OP_VMS_DISPLAY_MODULE_STATUS_REQ:
                         VmsReqDisplayModuleStatus reqDisplayModuleStatus = new VmsReqDisplayModuleStatus(this.vmsObj);
-                        result = this.vmsObj.sendData(reqDisplayModuleStatus.getByteBuffer(), 10, reqDisplayModuleStatus.getOpCodeDesc());
+                        result = this.vmsObj.sendData(reqDisplayModuleStatus, 1);
                         break;
                     case OP_VMS_PARAMETER_REQ:
                         VmsReqParameter reqParameter = new VmsReqParameter(this.vmsObj);
-                        result = this.vmsObj.sendData(reqParameter.getByteBuffer(), 10, reqParameter.getOpCodeDesc());
+                        result = this.vmsObj.sendData(reqParameter, 1);
                         break;
 //                    case OP_VMS_DOWNLOAD_FORM_SCHEDULE:
 //                        VmsJobDownloadScheduleFrom downloadScheduleFrom = new VmsJobDownloadScheduleFrom(this.vmsObj, (boolean) data.getData());
@@ -72,27 +80,27 @@ public class TcpServerSendDataProcess {
 //                        break;
                     case OP_VMS_STOP_IMAGE_REQ:
                         VmsReqStopImage reqStopImage = new VmsReqStopImage(this.vmsObj, (Integer)data.getData());
-                        result = this.vmsObj.sendData(reqStopImage.getByteBuffer(), 10, reqStopImage.getOpCodeDesc());
+                        result = this.vmsObj.sendData(reqStopImage, 1);
                         break;
                     case OP_VMS_UPLOAD_CURRENT_DISPLAY_FORM:
                         VmsReqUploadCurrentDisplayForm reqUploadCurrentDisplayForm = new VmsReqUploadCurrentDisplayForm(this.vmsObj);
-                        result = this.vmsObj.sendData(reqUploadCurrentDisplayForm.getByteBuffer(), 10, reqUploadCurrentDisplayForm.getOpCodeDesc());
+                        result = this.vmsObj.sendData(reqUploadCurrentDisplayForm, 1);
                         break;
                     case OP_VMS_DISPLAY_DEFAULT_FORM:
                         VmsReqDisplayDefaultForm reqDisplayDefaultForm = new VmsReqDisplayDefaultForm(this.vmsObj);
-                        result = this.vmsObj.sendData(reqDisplayDefaultForm.getByteBuffer(), 10, reqDisplayDefaultForm.getOpCodeDesc());
+                        result = this.vmsObj.sendData(reqDisplayDefaultForm, 1);
                         break;
                     case OP_VMS_BLANK:
                         VmsReqBlank reqBlank = new VmsReqBlank(this.vmsObj);
-                        result = this.vmsObj.sendData(reqBlank.getByteBuffer(), 10, reqBlank.getOpCodeDesc());
+                        result = this.vmsObj.sendData(reqBlank, 1);
                         break;
                     case OP_VMS_DISPLAY_FORM_ID:
                         VmsReqDisplayFromId reqDisplayFormId = new VmsReqDisplayFromId(this.vmsObj, (Integer)data.getData());
-                        result = this.vmsObj.sendData(reqDisplayFormId.getByteBuffer(), 10, reqDisplayFormId.getOpCodeDesc());
+                        result = this.vmsObj.sendData(reqDisplayFormId, 1);
                         break;
                     case OP_VMS_UPLOAD_FORM_SCHEDULE:
                         VmsReqUploadFormSchedule reqUploadScheduleFrom = new VmsReqUploadFormSchedule(this.vmsObj);
-                        result = this.vmsObj.sendData(reqUploadScheduleFrom.getByteBuffer(), 10, reqUploadScheduleFrom.getOpCodeDesc());
+                        result = this.vmsObj.sendData(reqUploadScheduleFrom, 1);
                         break;
 
                     case OP_VMS_DATA_DOWNLOAD:
@@ -102,7 +110,7 @@ public class TcpServerSendDataProcess {
                         break;
                     case OP_VMS_STATUS_CONTROL:
                         VmsReqStatusControl statusControl = (VmsReqStatusControl) data.getData();
-                        result = this.vmsObj.sendData(statusControl.getByteBuffer(), 10, statusControl.getOpCodeDesc());
+                        result = this.vmsObj.sendData(statusControl, 1);
 //                        byte[] command = control.getCommand();
 //                        // TODO: 전송성공하면
 //                        if (isRequested) {

+ 22 - 7
src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResBlank.java

@@ -1,12 +1,18 @@
 package com.its.vms.xnettcp.vms.process.response.impl;
 
+import com.its.app.AppUtils;
+import com.its.app.utils.SysUtils;
 import com.its.vms.dto.TbVmsCtlrDto;
+import com.its.vms.entity.VmsDsplDnldResult;
+import com.its.vms.process.DbmsData;
+import com.its.vms.process.DbmsDataProcess;
+import com.its.vms.process.DbmsDataType;
 import com.its.vms.xnettcp.vms.process.response.VmsResponse;
-import com.its.vms.xnettcp.vms.protocol.impl.dle.VmsDleFramePacket;
 import com.its.vms.xnettcp.vms.protocol.VmsFramePacket;
 import com.its.vms.xnettcp.vms.protocol.VmsProtocolConst;
 import com.its.vms.xnettcp.vms.protocol.enums.eVmsErrorCode;
 import com.its.vms.xnettcp.vms.protocol.enums.eVmsOpCode;
+import com.its.vms.xnettcp.vms.protocol.impl.dle.VmsDleFramePacket;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 
@@ -27,9 +33,9 @@ public class VmsResBlank implements VmsResponse {
          * ACK/NAK 확인
          */
         byte[] body = this.resFramePacket.getBody();
-        log.info("VmsResBlank.process: VMS {}, body length: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+        log.info("VmsResBlank.process: VMS {}, body length: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
         if (body == null || body.length < 1) {
-            log.error("VmsResBlank.process: VMS {}, body length error: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+            log.error("VmsResBlank.process: VMS {}, body length error: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
             return false;
         }
 
@@ -42,14 +48,24 @@ public class VmsResBlank implements VmsResponse {
                 byte errorCode = byteBuffer.get();
                 this.error = eVmsErrorCode.getValue(errorCode & 0xFF);
                 if (this.error == null) {
-                    log.error("VmsResBlank.process: VMS {}, Unknown error code: {} ", this.vmsObj.getVmsCtlrNmbr(), String.format("%02X", errorCode & 0xFF));
+                    log.error("VmsResBlank.process: VMS {}, Unknown error code: {}.", this.vmsObj.getVmsCtlrNmbr(), String.format("%02X", errorCode & 0xFF));
                     this.error = eVmsErrorCode.ERROR_UNKNOWN;
                 }
             }
         }
         else {
-            this.error = eVmsErrorCode.ERROR_NONE;;
+            this.error = eVmsErrorCode.ERROR_NONE;
         }
+
+        /**
+         * 표출정보 제어기 다운로드 결과를 데이터베이스에 저장한다.
+         */
+        String dnldYn = (this.error == eVmsErrorCode.ERROR_NONE) ? "Y" : "N";
+        int formCnt = this.vmsObj.getFormManager().count();
+        VmsDsplDnldResult dnldResult = new VmsDsplDnldResult(this.vmsObj.getVmsCtlrNmbr(), SysUtils.getSysTime(), formCnt, dnldYn);
+        DbmsDataProcess dbmsDataProcess = (DbmsDataProcess) AppUtils.getBean(DbmsDataProcess.class);
+        dbmsDataProcess.add(new DbmsData(DbmsDataType.DBMS_DATA_VMS_FORM_DOWNLOAD_RESULT, false, dnldResult));
+
         log.info("{}", toString());
 
         return true;
@@ -59,8 +75,7 @@ public class VmsResBlank implements VmsResponse {
         StringBuilder data = new StringBuilder();
         data.append(String.format("RESPONSE-%s. VMS %d", eVmsOpCode.OP_VMS_BLANK, this.vmsObj.getVmsCtlrNmbr()));
         data.append(System.getProperty("line.separator"));
-        data.append(String.format("Blank: %s, ", this.success));
-        data.append(String.format("NAK: %s", this.error));
+        data.append(String.format("Blank: %s, NAK: %s", this.success, this.error));
         return data.toString();
     }
 

+ 58 - 45
src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResDataDownload.java

@@ -3,6 +3,7 @@ package com.its.vms.xnettcp.vms.process.response.impl;
 import com.its.app.AppUtils;
 import com.its.app.utils.SysUtils;
 import com.its.vms.domain.NET;
+import com.its.vms.domain.VmsDownloadForm;
 import com.its.vms.dto.TbVmsCtlrDto;
 import com.its.vms.dto.TbVmsSymbLibDnldDto;
 import com.its.vms.dto.VmsScheduleSymbDto;
@@ -35,9 +36,9 @@ public class VmsResDataDownload implements VmsResponse {
          * ACK/NAK 확인
          */
         byte[] body = this.resFramePacket.getBody();
-        log.info("VmsResDataDownload.process: VMS {}, body length: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+        log.info("VmsResDataDownload.process: VMS {}, body length: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
         if (body == null || body.length < 1) {
-            log.error("VmsResDataDownload.process: VMS {}, body length error: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+            log.error("VmsResDataDownload.process: VMS {}, body length error: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
             return false;
         }
 
@@ -50,58 +51,71 @@ public class VmsResDataDownload implements VmsResponse {
                 byte errorCode = byteBuffer.get();
                 this.error = eVmsErrorCode.getValue(errorCode & 0xFF);
                 if (this.error == null) {
-                    log.error("VmsResDataDownload.process: VMS {}, Unknown error code: {} ", this.vmsObj.getVmsCtlrNmbr(), String.format("%02X", errorCode & 0xFF));
+                    log.error("VmsResDataDownload.process: VMS {}, Unknown error code: {}", this.vmsObj.getVmsCtlrNmbr(), String.format("%02X", errorCode & 0xFF));
                     this.error = eVmsErrorCode.ERROR_UNKNOWN;
                 }
             }
         }
         else {
-            this.error = eVmsErrorCode.ERROR_NONE;;
+            this.error = eVmsErrorCode.ERROR_NONE;
         }
         log.info("{}", toString());
 
-        if (this.error == eVmsErrorCode.ERROR_NONE) {
-            if (this.vmsObj.getReqDnldSymbMap().size() == 0 || this.vmsObj.getDnldSymbLibNmbr() == 0) {
-                this.vmsObj.downloadFile();
-            }
-            else {
-                if (this.vmsObj.getDnldSymbLibNmbr() != 0) {
-                    VmsScheduleSymbDto dnldSymb = this.vmsObj.getReqDnldSymbMap().get(this.vmsObj.getDnldSymbLibNmbr());
-                    if (dnldSymb != null) {
-                        TbVmsSymbLibDnldDto dnldDto = this.vmsObj.getDnldSymbMap().get(this.vmsObj.getDnldSymbLibNmbr());
-                        if (dnldDto == null) {
-                            dnldDto = TbVmsSymbLibDnldDto.builder()
-                                    .vmsCtlrNmbr(this.vmsObj.getVmsCtlrNmbr())
-                                    .dnldSymbLibNmbr(this.vmsObj.getDnldSymbLibNmbr())
-                                    .dnldDt(SysUtils.getSysTime())
-                                    .dnldCnt(1)
-                                    .symbLibNmbr(dnldSymb.getSymbLibNmbr())
-                                    .updtDt(dnldSymb.getUpdtDt())
-                                    .build();
-                            this.vmsObj.getDnldSymbMap().put(dnldDto.getDnldSymbLibNmbr(), dnldDto);
-                        }
-                        else {
-                            dnldDto.setDnldDt(SysUtils.getSysTime());
-                            dnldDto.setDnldCnt(dnldDto.getDnldCnt() + 1);
-                            dnldDto.setUpdtDt(dnldSymb.getUpdtDt());
-                        }
-                        this.vmsObj.getReqDnldSymbMap().remove(this.vmsObj.getDnldSymbLibNmbr());
+//        if (this.error != eVmsErrorCode.ERROR_NONE) {
+//            return true;
+//        }
 
-                        DbmsDataProcess dbmsDataProcess = (DbmsDataProcess)AppUtils.getBean(DbmsDataProcess.class);
-                        dbmsDataProcess.add(new DbmsData(DbmsDataType.DBMS_DATA_SYMB_DNLD, false, dnldDto.toEntity()));
+        if (this.vmsObj.getDownloadFormId() != 0) {
+            // 홍보폼을 다운로드 한 경우
+            VmsDownloadForm downloadForm = this.vmsObj.getDownloadFormMap().get(this.vmsObj.getDownloadFormId());
+            if (downloadForm != null) {
+                // 이미 다운로드 되었음을 설정해 놓는다.
+                downloadForm.setAlreadyDownload(true);
+            }
+        }
+        if (this.vmsObj.getReqDnldSymbMap().size() == 0 || this.vmsObj.getDnldSymbLibNmbr() == 0) {
+            // 다운로드 할 심벌라이브러리가 없는 경우 스케쥴 폼을 다운로드 한다.
+            this.vmsObj.downloadFile();
+        }
+        else {
+            if (this.vmsObj.getDnldSymbLibNmbr() != 0) {
+                // 다운로드한 심벌라이브러리 번호가 존재하므로 심벌라리브러리 다운로드 정보를 업데이트 한다.
+                VmsScheduleSymbDto dnldSymb = this.vmsObj.getReqDnldSymbMap().get(this.vmsObj.getDnldSymbLibNmbr());
+                if (dnldSymb != null) {
+                    TbVmsSymbLibDnldDto dnldDto = this.vmsObj.getDnldSymbMap().get(this.vmsObj.getDnldSymbLibNmbr());
+                    if (dnldDto == null) {
+                        dnldDto = TbVmsSymbLibDnldDto.builder()
+                                .vmsCtlrNmbr(this.vmsObj.getVmsCtlrNmbr())
+                                .dnldSymbLibNmbr(this.vmsObj.getDnldSymbLibNmbr())
+                                .dnldDt(SysUtils.getSysTime())
+                                .dnldCnt(1)
+                                .symbLibNmbr(dnldSymb.getSymbLibNmbr())
+                                .updtDt(dnldSymb.getUpdtDt())
+                                .build();
+                        this.vmsObj.getDnldSymbMap().put(dnldDto.getDnldSymbLibNmbr(), dnldDto);
                     }
-                }
-                /**
-                 * 다운로드할 심벌 라이브러리가 존재하면 다운로드한다.
-                 */
-                if (this.vmsObj.downloadSymbLib()) {
-                    // 더이상 다운로드 할 심벌 라이브러리가 없는 경우....
-                    if (this.vmsObj.getNetState() == NET.LOGIN_REQ) {
-                        // 최초 접속후, 심벌 라이브러리를 다운로드 한 경우이기 때문에 네트워크 상태를 변경하고
-                        // 스케쥴을 다운로드 한다.
-                        this.vmsObj.setNetState(NET.LOGINED);
-                        this.vmsObj.downloadForm(false);
+                    else {
+                        dnldDto.setDnldDt(SysUtils.getSysTime());
+                        dnldDto.setDnldCnt(dnldDto.getDnldCnt() + 1);
+                        dnldDto.setUpdtDt(dnldSymb.getUpdtDt());
                     }
+                    this.vmsObj.getReqDnldSymbMap().remove(this.vmsObj.getDnldSymbLibNmbr());
+
+                    DbmsDataProcess dbmsDataProcess = (DbmsDataProcess)AppUtils.getBean(DbmsDataProcess.class);
+                    dbmsDataProcess.add(new DbmsData(DbmsDataType.DBMS_DATA_SYMB_DNLD, false, dnldDto.toEntity()));
+                }
+            }
+
+            /**
+             * 다운로드할 심벌 라이브러리가 존재하면 다운로드한다.
+             */
+            if (this.vmsObj.downloadSymbLib()) {
+                // 더이상 다운로드 할 심벌 라이브러리가 없는 경우....
+                if (this.vmsObj.getNetState() == NET.LOGIN_REQ) {
+                    // 최초 접속후, 심벌 라이브러리를 다운로드 한 경우이기 때문에 네트워크 상태를 변경하고
+                    // 스케쥴을 다운로드 한다.
+                    this.vmsObj.setNetState(NET.LOGINED);
+                    this.vmsObj.downloadForm();
                 }
             }
         }
@@ -112,8 +126,7 @@ public class VmsResDataDownload implements VmsResponse {
         StringBuilder data = new StringBuilder();
         data.append(String.format("RESPONSE-%s. VMS %d", eVmsOpCode.OP_VMS_DATA_DOWNLOAD, this.vmsObj.getVmsCtlrNmbr()));
         data.append(System.getProperty("line.separator"));
-        data.append(String.format("Data Download: %s, ", this.success));
-        data.append(String.format("NAK: %s", this.error));
+        data.append(String.format("Data Download: %s, NAK: %s", this.success, this.error));
         return data.toString();
     }
 

+ 2 - 2
src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResDataUpload.java

@@ -27,9 +27,9 @@ public class VmsResDataUpload implements VmsResponse {
          * ACK/NAK 확인
          */
         byte[] body = this.resFramePacket.getBody();
-        log.info("VmsResDataUpload.process: VMS {}, body length: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+        log.info("VmsResDataUpload.process: VMS {}, body length: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
         if (body == null || body.length < 6) {
-            log.error("VmsResDataUpload.process: VMS {}, body length error: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+            log.error("VmsResDataUpload.process: VMS {}, body length error: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
             return false;
         }
 

+ 5 - 6
src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResDisplayDefaultForm.java

@@ -27,9 +27,9 @@ public class VmsResDisplayDefaultForm implements VmsResponse {
          * ACK/NAK 확인
          */
         byte[] body = this.resFramePacket.getBody();
-        log.info("VmsResDisplayDefaultForm.process: VMS {}, body length: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+        log.info("VmsResDisplayDefaultForm.process: VMS {}, body length: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
         if (body == null || body.length < 1) {
-            log.error("VmsResDisplayDefaultForm.process: VMS {}, body length error: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+            log.error("VmsResDisplayDefaultForm.process: VMS {}, body length error: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
             return false;
         }
 
@@ -42,13 +42,13 @@ public class VmsResDisplayDefaultForm implements VmsResponse {
                 byte errorCode = byteBuffer.get();
                 this.error = eVmsErrorCode.getValue(errorCode & 0xFF);
                 if (this.error == null) {
-                    log.error("VmsResDisplayDefaultForm.process: VMS {}, Unknown error code: {} ", this.vmsObj.getVmsCtlrNmbr(), String.format("%02X", errorCode & 0xFF));
+                    log.error("VmsResDisplayDefaultForm.process: VMS {}, Unknown error code: {}.", this.vmsObj.getVmsCtlrNmbr(), String.format("%02X", errorCode & 0xFF));
                     this.error = eVmsErrorCode.ERROR_UNKNOWN;
                 }
             }
         }
         else {
-            this.error = eVmsErrorCode.ERROR_NONE;;
+            this.error = eVmsErrorCode.ERROR_NONE;
         }
         log.info("{}", toString());
 
@@ -59,8 +59,7 @@ public class VmsResDisplayDefaultForm implements VmsResponse {
         StringBuilder data = new StringBuilder();
         data.append(String.format("RESPONSE-%s. VMS %d", eVmsOpCode.OP_VMS_DISPLAY_DEFAULT_FORM, this.vmsObj.getVmsCtlrNmbr()));
         data.append(System.getProperty("line.separator"));
-        data.append(String.format("Display Default Form: %s, ", this.success));
-        data.append(String.format("NAK: %s", this.error));
+        data.append(String.format("Display Default Form: %s, NAK: %s", this.success, this.error));
         return data.toString();
     }
 

+ 5 - 6
src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResDisplayFormId.java

@@ -27,9 +27,9 @@ public class VmsResDisplayFormId implements VmsResponse {
          * ACK/NAK 확인
          */
         byte[] body = this.resFramePacket.getBody();
-        log.info("VmsResDisplayFormId.process: VMS {}, body length: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+        log.info("VmsResDisplayFormId.process: VMS {}, body length: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
         if (body == null || body.length < 1) {
-            log.error("VmsResDisplayFormId.process: VMS {}, body length error: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+            log.error("VmsResDisplayFormId.process: VMS {}, body length error: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
             return false;
         }
 
@@ -42,13 +42,13 @@ public class VmsResDisplayFormId implements VmsResponse {
                 byte errorCode = byteBuffer.get();
                 this.error = eVmsErrorCode.getValue(errorCode & 0xFF);
                 if (this.error == null) {
-                    log.error("VmsResDisplayFormId.process: VMS {}, Unknown error code: {} ", this.vmsObj.getVmsCtlrNmbr(), String.format("%02X", errorCode & 0xFF));
+                    log.error("VmsResDisplayFormId.process: VMS {}, Unknown error code: {}.", this.vmsObj.getVmsCtlrNmbr(), String.format("%02X", errorCode & 0xFF));
                     this.error = eVmsErrorCode.ERROR_UNKNOWN;
                 }
             }
         }
         else {
-            this.error = eVmsErrorCode.ERROR_NONE;;
+            this.error = eVmsErrorCode.ERROR_NONE;
         }
         log.info("{}", toString());
 
@@ -59,8 +59,7 @@ public class VmsResDisplayFormId implements VmsResponse {
         StringBuilder data = new StringBuilder();
         data.append(String.format("RESPONSE-%s. VMS %d", eVmsOpCode.OP_VMS_DISPLAY_FORM_ID, this.vmsObj.getVmsCtlrNmbr()));
         data.append(System.getProperty("line.separator"));
-        data.append(String.format("Display Form Id: %s, ", this.success));
-        data.append(String.format("NAK: %s", this.error));
+        data.append(String.format("Display Form Id: %s, NAK: %s", this.success, this.error));
         return data.toString();
     }
 

+ 7 - 7
src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResDisplayModuleStatus.java

@@ -3,9 +3,9 @@ package com.its.vms.xnettcp.vms.process.response.impl;
 import com.its.vms.dto.TbVmsCtlrDto;
 import com.its.vms.xnettcp.vms.process.TcpServerSendData;
 import com.its.vms.xnettcp.vms.process.response.VmsResponse;
-import com.its.vms.xnettcp.vms.protocol.impl.dle.VmsDleFramePacket;
 import com.its.vms.xnettcp.vms.protocol.VmsFramePacket;
 import com.its.vms.xnettcp.vms.protocol.enums.eVmsOpCode;
+import com.its.vms.xnettcp.vms.protocol.impl.dle.VmsDleFramePacket;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 
@@ -24,17 +24,14 @@ public class VmsResDisplayModuleStatus implements VmsResponse {
     @Override
     public boolean process() {
 
-        // 제어기 파라미터 정보 요청
-        this.vmsObj.addRequestData(new TcpServerSendData(eVmsOpCode.OP_VMS_PARAMETER_REQ, null));
-
         this.x = 0;
         this.y = 0;
         this.stts = "";
 
         byte[] body = this.resFramePacket.getBody();
-        log.info("VmsResDisplayModuleStatus.process: VMS {}, body length: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+        log.info("VmsResDisplayModuleStatus.process: VMS {}, body length: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
         if (body == null || body.length < 2) {
-            log.error("VmsResDisplayModuleStatus.process: VMS {}, body length error: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+            log.error("VmsResDisplayModuleStatus.process: VMS {}, body length error: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
             return false;
         }
 
@@ -72,7 +69,10 @@ public class VmsResDisplayModuleStatus implements VmsResponse {
 
         log.info("{}", toString());
 
-        return true;
+        this.vmsObj.getStts().updateModuleStts(this.stts);
+
+        // 제어기 파라미터 정보 요청
+        return this.vmsObj.addRequestData(new TcpServerSendData(eVmsOpCode.OP_VMS_PARAMETER_REQ, null));
     }
 
     public String toString() {

+ 5 - 6
src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResDownloadForm.java

@@ -27,9 +27,9 @@ public class VmsResDownloadForm implements VmsResponse {
          * ACK/NAK 확인
          */
         byte[] body = this.resFramePacket.getBody();
-        log.info("VmsResDownloadForm.process: VMS {}, body length: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+        log.info("VmsResDownloadForm.process: VMS {}, body length: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
         if (body == null || body.length < 1) {
-            log.error("VmsResDownloadForm.process: VMS {}, body length error: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+            log.error("VmsResDownloadForm.process: VMS {}, body length error: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
             return false;
         }
 
@@ -42,13 +42,13 @@ public class VmsResDownloadForm implements VmsResponse {
                 byte errorCode = byteBuffer.get();
                 this.error = eVmsErrorCode.getValue(errorCode & 0xFF);
                 if (this.error == null) {
-                    log.error("VmsResDownloadForm.process: VMS {}, Unknown error code: {} ", this.vmsObj.getVmsCtlrNmbr(), String.format("%02X", errorCode & 0xFF));
+                    log.error("VmsResDownloadForm.process: VMS {}, Unknown error code: {}.", this.vmsObj.getVmsCtlrNmbr(), String.format("%02X", errorCode & 0xFF));
                     this.error = eVmsErrorCode.ERROR_UNKNOWN;
                 }
             }
         }
         else {
-            this.error = eVmsErrorCode.ERROR_NONE;;
+            this.error = eVmsErrorCode.ERROR_NONE;
         }
         log.info("{}", toString());
 
@@ -67,8 +67,7 @@ public class VmsResDownloadForm implements VmsResponse {
         StringBuilder data = new StringBuilder();
         data.append(String.format("RESPONSE-%s. VMS %d", eVmsOpCode.OP_VMS_DOWNLOAD_FORM, this.vmsObj.getVmsCtlrNmbr()));
         data.append(System.getProperty("line.separator"));
-        data.append(String.format("Download Form: %s, ", this.success));
-        data.append(String.format("NAK: %s", this.error));
+        data.append(String.format("Download Form: %s, NAK: %s", this.success, this.error));
         return data.toString();
     }
 

+ 5 - 6
src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResDownloadFormSchedule.java

@@ -27,9 +27,9 @@ public class VmsResDownloadFormSchedule implements VmsResponse {
          * ACK/NAK 확인
          */
         byte[] body = this.resFramePacket.getBody();
-        log.info("VmsResDownloadFormSchedule.process: VMS {}, body length: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+        log.info("VmsResDownloadFormSchedule.process: VMS {}, body length: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
         if (body == null || body.length < 1) {
-            log.error("VmsResDownloadFormSchedule.process: VMS {}, body length error: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+            log.error("VmsResDownloadFormSchedule.process: VMS {}, body length error: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
             return false;
         }
 
@@ -42,13 +42,13 @@ public class VmsResDownloadFormSchedule implements VmsResponse {
                 byte errorCode = byteBuffer.get();
                 this.error = eVmsErrorCode.getValue(errorCode & 0xFF);
                 if (this.error == null) {
-                    log.error("VmsResDownloadFormSchedule.process: VMS {}, Unknown error code: {} ", this.vmsObj.getVmsCtlrNmbr(), String.format("%02X", errorCode & 0xFF));
+                    log.error("VmsResDownloadFormSchedule.process: VMS {}, Unknown error code: {}.", this.vmsObj.getVmsCtlrNmbr(), String.format("%02X", errorCode & 0xFF));
                     this.error = eVmsErrorCode.ERROR_UNKNOWN;
                 }
             }
         }
         else {
-            this.error = eVmsErrorCode.ERROR_NONE;;
+            this.error = eVmsErrorCode.ERROR_NONE;
         }
         log.info("{}", toString());
 
@@ -62,8 +62,7 @@ public class VmsResDownloadFormSchedule implements VmsResponse {
         StringBuilder data = new StringBuilder();
         data.append(String.format("RESPONSE-%s. VMS %d", eVmsOpCode.OP_VMS_DOWNLOAD_FORM_SCHEDULE, this.vmsObj.getVmsCtlrNmbr()));
         data.append(System.getProperty("line.separator"));
-        data.append(String.format("Download Schedule Form: %s, ", this.success));
-        data.append(String.format("NAK: %s", this.error));
+        data.append(String.format("Download Schedule Form: %s, NAK: %s", this.success, this.error));
         return data.toString();
     }
 

+ 5 - 6
src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResFormDataDisplay.java

@@ -27,9 +27,9 @@ public class VmsResFormDataDisplay implements VmsResponse {
          * ACK/NAK 확인
          */
         byte[] body = this.resFramePacket.getBody();
-        log.info("VmsResFormDataDisplay.process: VMS {}, body length: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+        log.info("VmsResFormDataDisplay.process: VMS {}, body length: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
         if (body == null || body.length < 1) {
-            log.error("VmsResFormDataDisplay.process: VMS {}, body length error: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+            log.error("VmsResFormDataDisplay.process: VMS {}, body length error: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
             return false;
         }
 
@@ -42,13 +42,13 @@ public class VmsResFormDataDisplay implements VmsResponse {
                 byte errorCode = byteBuffer.get();
                 this.error = eVmsErrorCode.getValue(errorCode & 0xFF);
                 if (this.error == null) {
-                    log.error("VmsResFormDataDisplay.process: VMS {}, Unknown error code: {} ", this.vmsObj.getVmsCtlrNmbr(), String.format("%02X", errorCode & 0xFF));
+                    log.error("VmsResFormDataDisplay.process: VMS {}, Unknown error code: {}.", this.vmsObj.getVmsCtlrNmbr(), String.format("%02X", errorCode & 0xFF));
                     this.error = eVmsErrorCode.ERROR_UNKNOWN;
                 }
             }
         }
         else {
-            this.error = eVmsErrorCode.ERROR_NONE;;
+            this.error = eVmsErrorCode.ERROR_NONE;
         }
         log.info("{}", toString());
 
@@ -59,8 +59,7 @@ public class VmsResFormDataDisplay implements VmsResponse {
         StringBuilder data = new StringBuilder();
         data.append(String.format("RESPONSE-%s. VMS %d", eVmsOpCode.OP_VMS_FORM_DATA_DISPLAY, this.vmsObj.getVmsCtlrNmbr()));
         data.append(System.getProperty("line.separator"));
-        data.append(String.format("Form Data Display: %s, ", this.success));
-        data.append(String.format("NAK: %s", this.error));
+        data.append(String.format("Form Data Display: %s, NAK: %s", this.success, this.error));
         return data.toString();
     }
 

+ 17 - 10
src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResParameter.java

@@ -23,13 +23,13 @@ public class VmsResParameter implements VmsResponse {
     private int   fanRunTemp;     // Fan 의 동작개시온도          1 Byte  온도( 0x00 ~0x03f )
     private int   heaterRunMode;  // Heater 의 동작모드           1 Byte  0x00 : 꺼짐, 0x01 : 켜짐, 0x02 : 자동, 0x09: Unknown
     private int   heaterRunTemp;  // Heater 의 동작개시온도       1 Byte  온도(0x00 ~ 0x3f )
-    private int   brightMode; // 화면의 밝기 - 휘도 모드, 0x00:주간, 0x01:야간, 0x02:Auto, 0x03:수동
-    private int   brightCurr; // 화면의 밝기 - 현재 휘도값, 0~100
-    private int   brightWeek; // 화면의 밝기 - 주간 휘도값, 0~100
-    private int   brightNght; // 화면의 밝기 - 야간 휘도값, 0~100
+    private int   brightMode;     // 화면의 밝기 - 휘도 모드, 0x00:주간, 0x01:야간, 0x02:Auto, 0x03:수동
+    private int   brightCurr;     // 화면의 밝기 - 현재 휘도값, 0~100
+    private int   brightWeek;     // 화면의 밝기 - 주간 휘도값, 0~100
+    private int   brightNght;     // 화면의 밝기 - 야간 휘도값, 0~100
     private int   blinkTime;      // 깜빡이는 시간주기            1 Byte  문자 비트맵의 깜빡이는 시간주기 0x00 ~ 0x1e( 0.1 ~3.0 )
     private short scnTurnTime;    // 디폴트 시나리오로 전환시간   2 Byte  디폴트 시나리오로 전환될 때까지 기다리는 시간, 단위 : 초
-    private int   reserved;       // 기타                         1 Byte
+    private int   modlErrRate;    // 장애 모듈비율(%)             1 Byte  에러난 픽셀의 백분율 (0~100: 초기값:10%)
 
     //현재 로컬 제어기의 시간
     private int   year;           // 년       1 Byte  0x00 ~ 0x32
@@ -43,9 +43,9 @@ public class VmsResParameter implements VmsResponse {
     public boolean process() {
 
         byte[] body = this.resFramePacket.getBody();
-        log.info("VmsResParameter.process: VMS {}, body length: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+        log.info("VmsResParameter.process: VMS {}, body length: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
         if (body == null || body.length < 17) {
-            log.error("VmsResParameter.process: VMS {}, body length error: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+            log.error("VmsResParameter.process: VMS {}, body length error: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
             return false;
         }
 
@@ -69,7 +69,7 @@ public class VmsResParameter implements VmsResponse {
         }
         this.blinkTime = byteBuffer.get() & 0xFF;
         this.scnTurnTime = (short) (byteBuffer.getShort() & 0xFFFF);
-        this.reserved = byteBuffer.get() & 0xFF;
+        this.modlErrRate = byteBuffer.get() & 0xFF;
         this.year = byteBuffer.get() & 0xFF;
         this.mon = byteBuffer.get() & 0xFF;
         this.day = byteBuffer.get() & 0xFF;
@@ -79,6 +79,14 @@ public class VmsResParameter implements VmsResponse {
 
         log.info("{}", toString());
 
+        this.vmsObj.updateParameter(powerCtrlMode, fanRunMode, fanRunTemp, heaterRunMode, heaterRunTemp,
+                                    brightMode, brightCurr, brightWeek, brightNght, blinkTime, scnTurnTime, modlErrRate);
+
+        nextCommand();
+        return true;
+    }
+
+    public void nextCommand() {
         if (this.vmsObj.getNetState() == NET.LOGIN_REQ) {
             // 최초 접속후, 상태정보->파워모듈상태->표출모듈상태->파라미터정보 조회 완료후
             // 네트워크 로그인 상태로 설정하고 스케쥴을 다운로드 하도록 한다.
@@ -87,10 +95,9 @@ public class VmsResParameter implements VmsResponse {
             }
             else {
                 this.vmsObj.setNetState(NET.LOGINED);
-                this.vmsObj.downloadForm(false);
+                this.vmsObj.downloadForm();
             }
         }
-        return true;
     }
 
     public String toString() {

+ 8 - 9
src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResPowerModuleStatus.java

@@ -3,9 +3,9 @@ package com.its.vms.xnettcp.vms.process.response.impl;
 import com.its.vms.dto.TbVmsCtlrDto;
 import com.its.vms.xnettcp.vms.process.TcpServerSendData;
 import com.its.vms.xnettcp.vms.process.response.VmsResponse;
-import com.its.vms.xnettcp.vms.protocol.impl.dle.VmsDleFramePacket;
 import com.its.vms.xnettcp.vms.protocol.VmsFramePacket;
 import com.its.vms.xnettcp.vms.protocol.enums.eVmsOpCode;
+import com.its.vms.xnettcp.vms.protocol.impl.dle.VmsDleFramePacket;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 
@@ -23,16 +23,13 @@ public class VmsResPowerModuleStatus implements VmsResponse {
     @Override
     public boolean process() {
 
-        // 제어기 표출모듈상태 요청
-        this.vmsObj.addRequestData(new TcpServerSendData(eVmsOpCode.OP_VMS_DISPLAY_MODULE_STATUS_REQ, null));
-
         this.moduleCnt = 0;
         this.stts = "";
 
         byte[] body = this.resFramePacket.getBody();
-        log.info("VmsResPowerModuleStatus.process: VMS {}, body length: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+        log.info("VmsResPowerModuleStatus.process: VMS {}, body length: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
         if (body == null || body.length < 2) {
-            log.error("VmsResPowerModuleStatus.process: VMS {}, body length error: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+            log.error("VmsResPowerModuleStatus.process: VMS {}, body length error: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
             return false;
         }
 
@@ -66,15 +63,17 @@ public class VmsResPowerModuleStatus implements VmsResponse {
 
         log.info("{}", toString());
 
-        return true;
+        this.vmsObj.getStts().updatePowerModuleStts(this.stts);
+
+        // 제어기 표출모듈상태 요청
+        return this.vmsObj.addRequestData(new TcpServerSendData(eVmsOpCode.OP_VMS_DISPLAY_MODULE_STATUS_REQ, null));
     }
 
     public String toString() {
         StringBuilder data = new StringBuilder();
         data.append(String.format("RESPONSE-%s. VMS %d", eVmsOpCode.OP_VMS_POWER_MODULE_STATUS_REQ, this.vmsObj.getVmsCtlrNmbr()));
         data.append(System.getProperty("line.separator"));
-        data.append(String.format("Power Modules (%d), ", this.moduleCnt));
-        data.append(this.stts);
+        data.append(String.format("Power Modules (%d), %s", this.moduleCnt, this.stts));
         return data.toString();
     }
 

+ 11 - 3
src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResStatus.java

@@ -43,7 +43,7 @@ public class VmsResStatus implements VmsResponse {
         if (this.vmsObj.getNetState() == NET.LOGIN_REQ) {
             if (this.vmsObj.getVmsCtlrNmbr() != this.resFramePacket.getHead().getControllerNo() &&
                 this.vmsObj.getCtlrLocalNo() != this.resFramePacket.getHead().getControllerNo()) {
-                log.error("VmsResStatus.process: Controller Number Error: VMS {}, NMBR {}, LOCAL {}, RECV {} ",
+                log.error("VmsResStatus.process: Controller Number Error: VMS {}, NMBR {}, LOCAL {}, RECV {}.",
                         this.vmsObj.getVmsCtlrNmbr(), this.vmsObj.getVmsCtlrNmbr(), this.vmsObj.getCtlrLocalNo(), this.resFramePacket.getHead().getControllerNo());
                 return false;
             }
@@ -51,9 +51,9 @@ public class VmsResStatus implements VmsResponse {
         }
 
         byte[] body = this.resFramePacket.getBody();
-        log.info("VmsResStatus.process: VMS {}, body length: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+        log.info("VmsResStatus.process: VMS {}, body length: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
         if (body == null || body.length < 14) {
-            log.error("VmsResStatus.process: VMS {}, body length error: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+            log.error("VmsResStatus.process: VMS {}, body length error: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
             return false;
         }
 
@@ -91,10 +91,18 @@ public class VmsResStatus implements VmsResponse {
             this.cboxFan = tmpFan2;
             this.heater = tmpHtr1;
             this.cboxHeather = tmpHtr2;
+            this.powerModuleStts = this.power;    // 전원 모듈 상태, 0x00: 정상, 0x01: 에러, 0x02: Unknown
+            this.moduleStts = this.power;         // 모듈 상태, 0x00: 정상, 0x01: 불량, 0x02: Unknown
         }
 
         log.info("{}", toString());
 
+        if (this.vmsObj.getStts().updateStatus(door, power, fan, heater, formNo, reboot, cboxTemp,
+                brightMode, brightCurr, brightWeek, brightNght, dpTemp, dpHum,
+                powerModuleStts, moduleStts, cboxFan, cboxHeather)) {
+            // 상태정보가 변경되었으므로 상태정보 업데이트 하도록 한다.
+        }
+
         // 제어기 전원모듈상태 요청
         return this.vmsObj.addRequestData(new TcpServerSendData(eVmsOpCode.OP_VMS_POWER_MODULE_STATUS_REQ, null));
     }

+ 5 - 6
src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResStatusControl.java

@@ -27,9 +27,9 @@ public class VmsResStatusControl implements VmsResponse {
          * ACK/NAK 확인
          */
         byte[] body = this.resFramePacket.getBody();
-        log.info("VmsResStatusControl.process: VMS {}, body length: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+        log.info("VmsResStatusControl.process: VMS {}, body length: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
         if (body == null || body.length < 1) {
-            log.error("VmsResStatusControl.process: VMS {}, body length error: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+            log.error("VmsResStatusControl.process: VMS {}, body length error: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
             return false;
         }
 
@@ -42,13 +42,13 @@ public class VmsResStatusControl implements VmsResponse {
                 byte errorCode = byteBuffer.get();
                 this.error = eVmsErrorCode.getValue(errorCode & 0xFF);
                 if (this.error == null) {
-                    log.error("VmsResStatusControl.process: VMS {}, Unknown error code: {} ", this.vmsObj.getVmsCtlrNmbr(), String.format("%02X", errorCode & 0xFF));
+                    log.error("VmsResStatusControl.process: VMS {}, Unknown error code: {}.", this.vmsObj.getVmsCtlrNmbr(), String.format("%02X", errorCode & 0xFF));
                     this.error = eVmsErrorCode.ERROR_UNKNOWN;
                 }
             }
         }
         else {
-            this.error = eVmsErrorCode.ERROR_NONE;;
+            this.error = eVmsErrorCode.ERROR_NONE;
         }
         log.info("{}", toString());
 
@@ -59,8 +59,7 @@ public class VmsResStatusControl implements VmsResponse {
         StringBuilder data = new StringBuilder();
         data.append(String.format("RESPONSE-%s. VMS %d", eVmsOpCode.OP_VMS_STATUS_CONTROL, this.vmsObj.getVmsCtlrNmbr()));
         data.append(System.getProperty("line.separator"));
-        data.append(String.format("Status Control: %s, ", this.success));
-        data.append(String.format("NAK: %s", this.error));
+        data.append(String.format("Status Control: %s, NAK: %s", this.success, this.error));
         return data.toString();
     }
 

+ 2 - 2
src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResStopImage.java

@@ -26,9 +26,9 @@ public class VmsResStopImage implements VmsResponse {
     @Override
     public boolean process() {
         byte[] body = this.resFramePacket.getBody();
-        log.info("VmsResStopImage.process: VMS {}, body length: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+        log.info("VmsResStopImage.process: VMS {}, body length: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
         if (body == null || body.length < 21) {
-            log.error("VmsResStopImage.process: VMS {}, body length error: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+            log.error("VmsResStopImage.process: VMS {}, body length error: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
             return false;
         }
         ByteBuffer byteBuffer = ByteBuffer.wrap(body);

+ 4 - 5
src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResUploadCurrentDisplayForm.java

@@ -30,9 +30,9 @@ public class VmsResUploadCurrentDisplayForm implements VmsResponse {
          * ACK/NAK 확인
          */
         byte[] body = this.resFramePacket.getBody();
-        log.info("VmsResUploadCurrentDisplayForm.process: VMS {}, body length: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+        log.info("VmsResUploadCurrentDisplayForm.process: VMS {}, body length: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
         if (body == null || body.length < 2) {
-            log.error("VmsResUploadCurrentDisplayForm.process: VMS {}, body length error: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+            log.error("VmsResUploadCurrentDisplayForm.process: VMS {}, body length error: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
             return false;
         }
 
@@ -44,7 +44,7 @@ public class VmsResUploadCurrentDisplayForm implements VmsResponse {
             this.success = false;
             this.error = eVmsErrorCode.getValue(result & 0xFF);
             if (this.error == null) {
-                log.error("VmsResUploadCurrentDisplayForm.process: VMS {}, Unknown error code: {} ", this.vmsObj.getVmsCtlrNmbr(), String.format("0x%02X", result & 0xFF));
+                log.error("VmsResUploadCurrentDisplayForm.process: VMS {}, Unknown error code: {}.", this.vmsObj.getVmsCtlrNmbr(), String.format("0x%02X", result & 0xFF));
                 this.error = eVmsErrorCode.ERROR_UNKNOWN;
             }
             this.content = "NONE";
@@ -162,8 +162,7 @@ public class VmsResUploadCurrentDisplayForm implements VmsResponse {
         StringBuilder data = new StringBuilder();
         data.append(String.format("RESPONSE-%s. VMS %d", eVmsOpCode.OP_VMS_UPLOAD_CURRENT_DISPLAY_FORM, this.vmsObj.getVmsCtlrNmbr()));
         data.append(System.getProperty("line.separator"));
-        data.append(String.format("Upload Current Display Form: %s, ", this.success));
-        data.append(String.format("NAK: %s", this.error));
+        data.append(String.format("Upload Current Display Form: %s, NAK: %s", this.success, this.error));
         data.append(System.getProperty("line.separator"));
         data.append("CONTENT:");
         data.append(System.getProperty("line.separator"));

+ 2 - 2
src/main/java/com/its/vms/xnettcp/vms/process/response/impl/VmsResUploadFormSchedule.java

@@ -23,9 +23,9 @@ public class VmsResUploadFormSchedule implements VmsResponse {
     public boolean process() {
 
         byte[] body = this.resFramePacket.getBody();
-        log.info("VmsResUploadFormSchedule.process: VMS {}, body length: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+        log.info("VmsResUploadFormSchedule.process: VMS {}, body length: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
         if (body == null || body.length < 30) {
-            log.error("VmsResUploadFormSchedule.process: VMS {}, body length error: {} ", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
+            log.error("VmsResUploadFormSchedule.process: VMS {}, body length error: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
             return false;
         }
 

+ 20 - 3
src/main/java/com/its/vms/xnettcp/vms/protocol/VmsReqFramePacket.java

@@ -1,10 +1,27 @@
 package com.its.vms.xnettcp.vms.protocol;
 
+import com.its.vms.xnettcp.vms.protocol.enums.eVmsOpCode;
+
 import java.nio.ByteBuffer;
 
-public interface VmsReqFramePacket {
+public abstract class VmsReqFramePacket {
+
+    protected eVmsOpCode opCode;
+    protected short packetNmbr;
+
+    public abstract ByteBuffer getByteBuffer();
 
-    ByteBuffer getByteBuffer();
-    String getOpCodeDesc();
+    public eVmsOpCode getOpCode() {
+        return this.opCode;
+    }
+    public String getOpCodeDesc() {
+        if (this.opCode != null) {
+            return opCode.toString();
+        }
+        return "ERROR: OpCode is Not Set.";
+    }
+    public short getPacketNmbr() {
+        return this.packetNmbr;
+    }
 
 }

+ 17 - 0
src/main/java/com/its/vms/xnettcp/vms/protocol/VmsReqHead.java

@@ -0,0 +1,17 @@
+package com.its.vms.xnettcp.vms.protocol;
+
+import com.its.vms.xnettcp.vms.protocol.enums.eVmsOpCode;
+
+public class VmsReqHead {
+
+    protected eVmsOpCode opCode;
+    protected short packetNmbr;
+
+    public eVmsOpCode getOpCode() {
+        return this.opCode;
+    }
+    public short getPacketNmbr() {
+        return this.packetNmbr;
+    }
+
+}

+ 2 - 1
src/main/java/com/its/vms/xnettcp/vms/protocol/enums/eVmsOpCode.java

@@ -20,7 +20,8 @@ public enum eVmsOpCode {
     OP_VMS_DOWNLOAD_FORM                (0x9A, "0x9A.Download Form"),           // Form download,                             SERVER→VMS
     OP_VMS_UPLOAD_FORM_SCHEDULE         (0x9C, "0x9C.Upload Schedule Form"),    // 스케줄 메시지 업로드 요구,                 SERVER→VMS
     OP_VMS_BLANK                        (0x9E, "0x9E.Blank"),                   // schedule 표출,                             SERVER→VMS
-    OP_VMS_DISPLAY_FORM_ID              (0xA0, "0xA0.Display Form ID");         // 수신, 통신 session 유효 확인 요청,         SERVER←VMS
+    OP_VMS_DISPLAY_FORM_ID              (0xA0, "0xA0.Display Form ID"),         // 수신, 통신 session 유효 확인 요청,         SERVER←VMS
+    OP_VMS_LOCAL_USER_COMMAND           (0xFE, "0xFE.Local User Command");      // 서버 프로그램 내에서 사용할 내부 명령      SERVER←SERVER
 
     private final int value;
     private final String string;

+ 6 - 7
src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqBlank.java

@@ -13,14 +13,17 @@ import java.nio.ByteBuffer;
 /**
  * BLANK 요청
  */
-public class VmsReqBlank implements VmsReqFramePacket {
+public class VmsReqBlank extends VmsReqFramePacket{
 
     private final VmsFramePacket framePacket;
 
     public VmsReqBlank(TbVmsCtlrDto vmsObj) {
-        byte opCode = (byte)eVmsOpCode.OP_VMS_BLANK.getValue();
+        this.opCode = eVmsOpCode.OP_VMS_BLANK;
+        this.packetNmbr = (short)this.opCode.getValue();
+        byte opCode = (byte)this.opCode.getValue();
         if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_ANDONG.getValue()) {
-            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), vmsObj.getSeqNext(), opCode);
+            this.packetNmbr = vmsObj.getSeqNext();
+            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), this.packetNmbr, opCode);
         }
         else if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_EX_FIGURE.getValue()) {
             this.framePacket = new VmsDleFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getCtlrLocalNo(), opCode);
@@ -35,8 +38,4 @@ public class VmsReqBlank implements VmsReqFramePacket {
         return this.framePacket.getByteBuffer();
     }
 
-    @Override
-    public String getOpCodeDesc() {
-        return this.framePacket.getOpCodeDesc();
-    }
 }

+ 7 - 9
src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqDataDownload.java

@@ -17,14 +17,17 @@ import java.nio.ByteOrder;
  * Data Download 요청
  */
 @Slf4j
-public class VmsReqDataDownload implements VmsReqFramePacket {
+public class VmsReqDataDownload extends VmsReqFramePacket {
 
     private final VmsFramePacket framePacket;
 
     public VmsReqDataDownload(TbVmsCtlrDto vmsObj, eVmsFileSaveLocation saveLoc, String fileName, byte[] data) {
-        byte opCode = (byte)eVmsOpCode.OP_VMS_DATA_DOWNLOAD.getValue();
+        this.opCode = eVmsOpCode.OP_VMS_DATA_DOWNLOAD;
+        this.packetNmbr = (short)this.opCode.getValue();
+        byte opCode = (byte)this.opCode.getValue();
         if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_ANDONG.getValue()) {
-            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), vmsObj.getSeqNext(), opCode);
+            this.packetNmbr = vmsObj.getSeqNext();
+            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), this.packetNmbr, opCode);
         }
         else if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_EX_FIGURE.getValue()) {
             this.framePacket = new VmsDleFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getCtlrLocalNo(), opCode);
@@ -45,7 +48,7 @@ public class VmsReqDataDownload implements VmsReqFramePacket {
         int fileNameSize = fileName.length();
         int dataSize = data.length;
         int bodySize = 6 + fileNameSize + dataSize;
-        log.info("VmsReqDataDownload.makeBody: bodySize {}", bodySize);
+        //log.info("VmsReqDataDownload.makeBody: bodySize {}", bodySize);
         ByteBuffer byteBuffer = ByteBuffer.allocate(bodySize);
         byteBuffer.order(ByteOrder.BIG_ENDIAN);
 
@@ -63,9 +66,4 @@ public class VmsReqDataDownload implements VmsReqFramePacket {
         return this.framePacket.getByteBuffer();
     }
 
-    @Override
-    public String getOpCodeDesc() {
-        return this.framePacket.getOpCodeDesc();
-    }
-
 }

+ 7 - 9
src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqDataUpload.java

@@ -17,14 +17,17 @@ import java.nio.ByteOrder;
  * Data Upload 요청
  */
 @Slf4j
-public class VmsReqDataUpload implements VmsReqFramePacket {
+public class VmsReqDataUpload extends VmsReqFramePacket {
 
     private final VmsFramePacket framePacket;
 
     public VmsReqDataUpload(TbVmsCtlrDto vmsObj, eVmsFileSaveLocation saveLoc, String fileName) {
-        byte opCode = (byte)eVmsOpCode.OP_VMS_DATA_UPLOAD.getValue();
+        this.opCode = eVmsOpCode.OP_VMS_DATA_UPLOAD;
+        this.packetNmbr = (short)this.opCode.getValue();
+        byte opCode = (byte)this.opCode.getValue();
         if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_ANDONG.getValue()) {
-            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), vmsObj.getSeqNext(), opCode);
+            this.packetNmbr = vmsObj.getSeqNext();
+            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), this.packetNmbr, opCode);
         }
         else if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_EX_FIGURE.getValue()) {
             this.framePacket = new VmsDleFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getCtlrLocalNo(), opCode);
@@ -43,7 +46,7 @@ public class VmsReqDataUpload implements VmsReqFramePacket {
 //        저장할 파일명                  n
         int fileNameSize = fileName.length();
         int bodySize = 3 + fileNameSize;
-        log.info("VmsReqDataUpload.makeBody: bodySize {}", bodySize);
+        //log.info("VmsReqDataUpload.makeBody: bodySize {}", bodySize);
         ByteBuffer byteBuffer = ByteBuffer.allocate(bodySize);
         byteBuffer.order(ByteOrder.BIG_ENDIAN);
 
@@ -60,9 +63,4 @@ public class VmsReqDataUpload implements VmsReqFramePacket {
         return this.framePacket.getByteBuffer();
     }
 
-    @Override
-    public String getOpCodeDesc() {
-        return this.framePacket.getOpCodeDesc();
-    }
-
 }

+ 6 - 7
src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqDisplayDefaultForm.java

@@ -13,14 +13,17 @@ import java.nio.ByteBuffer;
 /**
  * Display Default Form 요청
  */
-public class VmsReqDisplayDefaultForm implements VmsReqFramePacket {
+public class VmsReqDisplayDefaultForm extends VmsReqFramePacket {
 
     private final VmsFramePacket framePacket;
 
     public VmsReqDisplayDefaultForm(TbVmsCtlrDto vmsObj) {
-        byte opCode = (byte)eVmsOpCode.OP_VMS_DISPLAY_DEFAULT_FORM.getValue();
+        this.opCode = eVmsOpCode.OP_VMS_DISPLAY_DEFAULT_FORM;
+        this.packetNmbr = (short)this.opCode.getValue();
+        byte opCode = (byte)this.opCode.getValue();
         if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_ANDONG.getValue()) {
-            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), vmsObj.getSeqNext(), opCode);
+            this.packetNmbr = vmsObj.getSeqNext();
+            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), this.packetNmbr, opCode);
         }
         else if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_EX_FIGURE.getValue()) {
             this.framePacket = new VmsDleFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getCtlrLocalNo(), opCode);
@@ -35,8 +38,4 @@ public class VmsReqDisplayDefaultForm implements VmsReqFramePacket {
         return this.framePacket.getByteBuffer();
     }
 
-    @Override
-    public String getOpCodeDesc() {
-        return this.framePacket.getOpCodeDesc();
-    }
 }

+ 6 - 8
src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqDisplayFromId.java

@@ -15,14 +15,17 @@ import java.nio.ByteBuffer;
  * Display Form Id 요청
  */
 @Slf4j
-public class VmsReqDisplayFromId implements VmsReqFramePacket {
+public class VmsReqDisplayFromId extends VmsReqFramePacket {
 
     private final VmsFramePacket framePacket;
 
     public VmsReqDisplayFromId(TbVmsCtlrDto vmsObj, int formNo) {
-        byte opCode = (byte)eVmsOpCode.OP_VMS_DISPLAY_FORM_ID.getValue();
+        this.opCode = eVmsOpCode.OP_VMS_DISPLAY_FORM_ID;
+        this.packetNmbr = (short)this.opCode.getValue();
+        byte opCode = (byte)this.opCode.getValue();
         if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_ANDONG.getValue()) {
-            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), vmsObj.getSeqNext(), opCode);
+            this.packetNmbr = vmsObj.getSeqNext();
+            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), this.packetNmbr, opCode);
         }
         else if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_EX_FIGURE.getValue()) {
             this.framePacket = new VmsDleFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getCtlrLocalNo(), opCode);
@@ -46,9 +49,4 @@ public class VmsReqDisplayFromId implements VmsReqFramePacket {
         return this.framePacket.getByteBuffer();
     }
 
-    @Override
-    public String getOpCodeDesc() {
-        return this.framePacket.getOpCodeDesc();
-    }
-
 }

+ 6 - 7
src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqDisplayModuleStatus.java

@@ -13,14 +13,17 @@ import java.nio.ByteBuffer;
 /**
  * Display Module Status 요청
  */
-public class VmsReqDisplayModuleStatus implements VmsReqFramePacket {
+public class VmsReqDisplayModuleStatus extends VmsReqFramePacket {
 
     private final VmsFramePacket framePacket;
 
     public VmsReqDisplayModuleStatus(TbVmsCtlrDto vmsObj) {
-        byte opCode = (byte)eVmsOpCode.OP_VMS_DISPLAY_MODULE_STATUS_REQ.getValue();
+        this.opCode = eVmsOpCode.OP_VMS_DISPLAY_MODULE_STATUS_REQ;
+        this.packetNmbr = (short)this.opCode.getValue();
+        byte opCode = (byte)this.opCode.getValue();
         if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_ANDONG.getValue()) {
-            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), vmsObj.getSeqNext(), opCode);
+            this.packetNmbr = vmsObj.getSeqNext();
+            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), this.packetNmbr, opCode);
         }
         else if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_EX_FIGURE.getValue()) {
             this.framePacket = new VmsDleFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getCtlrLocalNo(), opCode);
@@ -35,8 +38,4 @@ public class VmsReqDisplayModuleStatus implements VmsReqFramePacket {
         return this.framePacket.getByteBuffer();
     }
 
-    @Override
-    public String getOpCodeDesc() {
-        return this.framePacket.getOpCodeDesc();
-    }
 }

+ 8 - 9
src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqDownloadForm.java

@@ -19,14 +19,17 @@ import java.nio.ByteOrder;
  * Download Schedule Form 요청
  */
 @Slf4j
-public class VmsReqDownloadForm implements VmsReqFramePacket {
+public class VmsReqDownloadForm extends VmsReqFramePacket {
 
     private final VmsFramePacket framePacket;
 
     public VmsReqDownloadForm(TbVmsCtlrDto vmsObj, VmsFormDataDto formData) {
-        byte opCode = (byte)eVmsOpCode.OP_VMS_DOWNLOAD_FORM.getValue();
+        this.opCode = eVmsOpCode.OP_VMS_DOWNLOAD_FORM;
+        this.packetNmbr = (short)this.opCode.getValue();
+        byte opCode = (byte)this.opCode.getValue();
         if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_ANDONG.getValue()) {
-            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), vmsObj.getSeqNext(), opCode);
+            this.packetNmbr = vmsObj.getSeqNext();
+            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), this.packetNmbr, opCode);
         }
         else if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_EX_FIGURE.getValue()) {
             this.framePacket = new VmsDleFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getCtlrLocalNo(), opCode);
@@ -48,7 +51,8 @@ public class VmsReqDownloadForm implements VmsReqFramePacket {
                 bodySize += formData.getFormList().get(ii).getObjList().get(jj).getObjSize(); // 오브젝트 데이터 크기
             }
         }
-        log.info("VmsReqDownloadForm.makeBody: bodySize {}", bodySize);
+
+        //log.info("VmsReqDownloadForm.makeBody: bodySize {}", bodySize);
         ByteBuffer byteBuffer = ByteBuffer.allocate(bodySize);
         byteBuffer.order(ByteOrder.BIG_ENDIAN);
 
@@ -109,9 +113,4 @@ public class VmsReqDownloadForm implements VmsReqFramePacket {
         return this.framePacket.getByteBuffer();
     }
 
-    @Override
-    public String getOpCodeDesc() {
-        return this.framePacket.getOpCodeDesc();
-    }
-
 }

+ 7 - 9
src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqDownloadFormSchedule.java

@@ -16,14 +16,17 @@ import java.nio.ByteOrder;
  * Download Form Schedule 요청
  */
 @Slf4j
-public class VmsReqDownloadFormSchedule implements VmsReqFramePacket {
+public class VmsReqDownloadFormSchedule extends VmsReqFramePacket {
 
     private final VmsFramePacket framePacket;
 
     public VmsReqDownloadFormSchedule(TbVmsCtlrDto vmsObj, short[] formId, byte[] dispSec) {
-        byte opCode = (byte)eVmsOpCode.OP_VMS_DOWNLOAD_FORM_SCHEDULE.getValue();
+        this.opCode = eVmsOpCode.OP_VMS_DOWNLOAD_FORM_SCHEDULE;
+        this.packetNmbr = (short)this.opCode.getValue();
+        byte opCode = (byte)this.opCode.getValue();
         if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_ANDONG.getValue()) {
-            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), vmsObj.getSeqNext(), opCode);
+            this.packetNmbr = vmsObj.getSeqNext();
+            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), this.packetNmbr, opCode);
         }
         else if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_EX_FIGURE.getValue()) {
             this.framePacket = new VmsDleFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getCtlrLocalNo(), opCode);
@@ -37,7 +40,7 @@ public class VmsReqDownloadFormSchedule implements VmsReqFramePacket {
 
     public void makeBody(short[] formId, byte[] dispSec) {
         int bodySize = (2 * formId.length) + (dispSec.length);
-        log.info("VmsReqDownloadFormSchedule.makeBody: bodySize {}", bodySize);
+        //log.info("VmsReqDownloadFormSchedule.makeBody: bodySize {}", bodySize);
         ByteBuffer byteBuffer = ByteBuffer.allocate(bodySize);
         byteBuffer.order(ByteOrder.BIG_ENDIAN);
 
@@ -54,9 +57,4 @@ public class VmsReqDownloadFormSchedule implements VmsReqFramePacket {
         return this.framePacket.getByteBuffer();
     }
 
-    @Override
-    public String getOpCodeDesc() {
-        return this.framePacket.getOpCodeDesc();
-    }
-
 }

+ 6 - 8
src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqFormDataDisplay.java

@@ -15,14 +15,17 @@ import java.nio.ByteBuffer;
  * 폼 데이터 표출 요청
  */
 @Slf4j
-public class VmsReqFormDataDisplay implements VmsReqFramePacket {
+public class VmsReqFormDataDisplay extends VmsReqFramePacket {
 
     private final VmsFramePacket framePacket;
 
     public VmsReqFormDataDisplay(TbVmsCtlrDto vmsObj, byte[] schedule) {
-        byte opCode = (byte)eVmsOpCode.OP_VMS_FORM_DATA_DISPLAY.getValue();
+        this.opCode = eVmsOpCode.OP_VMS_FORM_DATA_DISPLAY;
+        this.packetNmbr = (short)this.opCode.getValue();
+        byte opCode = (byte)this.opCode.getValue();
         if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_ANDONG.getValue()) {
-            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), vmsObj.getSeqNext(), opCode);
+            this.packetNmbr = vmsObj.getSeqNext();
+            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), this.packetNmbr, opCode);
         }
         else if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_EX_FIGURE.getValue()) {
             this.framePacket = new VmsDleFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getCtlrLocalNo(), opCode);
@@ -45,9 +48,4 @@ public class VmsReqFormDataDisplay implements VmsReqFramePacket {
         return this.framePacket.getByteBuffer();
     }
 
-    @Override
-    public String getOpCodeDesc() {
-        return this.framePacket.getOpCodeDesc();
-    }
-
 }

+ 68 - 0
src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqLocalUserCommand.java

@@ -0,0 +1,68 @@
+package com.its.vms.xnettcp.vms.protocol.impl;
+
+import com.its.vms.dto.TbVmsCtlrDto;
+import com.its.vms.xnettcp.vms.protocol.VmsFramePacket;
+import com.its.vms.xnettcp.vms.protocol.VmsReqFramePacket;
+import com.its.vms.xnettcp.vms.protocol.enums.eVmsOpCode;
+import com.its.vms.xnettcp.vms.protocol.enums.eVmsProtocolVersion;
+import com.its.vms.xnettcp.vms.protocol.impl.dle.VmsDleFramePacket;
+import com.its.vms.xnettcp.vms.protocol.impl.std.VmsStdFramePacket;
+import lombok.extern.slf4j.Slf4j;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Stop Image 요청
+ */
+@Slf4j
+public class VmsReqLocalUserCommand extends VmsReqFramePacket {
+
+    private final VmsFramePacket framePacket;
+    private final short command;
+    private final short value;
+
+    public VmsReqLocalUserCommand(TbVmsCtlrDto vmsObj, short command, short value) {
+        this.opCode = eVmsOpCode.OP_VMS_STOP_IMAGE_REQ;
+        this.packetNmbr = (short)this.opCode.getValue();
+        byte opCode = (byte)this.opCode.getValue();
+        if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_ANDONG.getValue()) {
+            this.packetNmbr = vmsObj.getSeqNext();
+            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), this.packetNmbr, opCode);
+        }
+        else if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_EX_FIGURE.getValue()) {
+            this.framePacket = new VmsDleFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getCtlrLocalNo(), opCode);
+        }
+        else {
+            this.framePacket = new VmsDleFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getCtlrLocalNo(), opCode);
+        }
+
+        this.command = command;
+        this.value = value;
+        makeBody(command, value);
+    }
+
+    public void makeBody(short command, short value) {
+        byte[] body = new byte[4];
+        body[0] = (byte)(((command & 0xFF00) >> 8) & 0xFF);
+        body[1] = (byte)(((command * 0x00FF)     ) * 0xFF);
+
+        body[2] = (byte)(((value & 0xFF00) >> 8) & 0xFF);
+        body[3] = (byte)(((value * 0x00FF)     ) * 0xFF);
+
+        this.framePacket.setBody(body);
+    }
+
+    public int getCommand() {
+        return this.command;
+    }
+
+    public int getValue() {
+        return this.value;
+    }
+
+    @Override
+    public ByteBuffer getByteBuffer() {
+        return this.framePacket.getByteBuffer();
+    }
+
+}

+ 6 - 7
src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqParameter.java

@@ -13,14 +13,17 @@ import java.nio.ByteBuffer;
 /**
  * Parameter 요청
  */
-public class VmsReqParameter implements VmsReqFramePacket {
+public class VmsReqParameter extends VmsReqFramePacket {
 
     private final VmsFramePacket framePacket;
 
     public VmsReqParameter(TbVmsCtlrDto vmsObj) {
-        byte opCode = (byte)eVmsOpCode.OP_VMS_PARAMETER_REQ.getValue();
+        this.opCode = eVmsOpCode.OP_VMS_PARAMETER_REQ;
+        this.packetNmbr = (short)this.opCode.getValue();
+        byte opCode = (byte)this.opCode.getValue();
         if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_ANDONG.getValue()) {
-            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), vmsObj.getSeqNext(), opCode);
+            this.packetNmbr = vmsObj.getSeqNext();
+            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), this.packetNmbr, opCode);
         }
         else if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_EX_FIGURE.getValue()) {
             this.framePacket = new VmsDleFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getCtlrLocalNo(), opCode);
@@ -35,8 +38,4 @@ public class VmsReqParameter implements VmsReqFramePacket {
         return this.framePacket.getByteBuffer();
     }
 
-    @Override
-    public String getOpCodeDesc() {
-        return this.framePacket.getOpCodeDesc();
-    }
 }

+ 6 - 7
src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqPowerModuleStatus.java

@@ -13,14 +13,17 @@ import java.nio.ByteBuffer;
 /**
  * Power Module Status 요청
  */
-public class VmsReqPowerModuleStatus implements VmsReqFramePacket {
+public class VmsReqPowerModuleStatus extends VmsReqFramePacket {
 
     private final VmsFramePacket framePacket;
 
     public VmsReqPowerModuleStatus(TbVmsCtlrDto vmsObj) {
-        byte opCode = (byte)eVmsOpCode.OP_VMS_POWER_MODULE_STATUS_REQ.getValue();
+        this.opCode = eVmsOpCode.OP_VMS_POWER_MODULE_STATUS_REQ;
+        this.packetNmbr = (short)this.opCode.getValue();
+        byte opCode = (byte)this.opCode.getValue();
         if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_ANDONG.getValue()) {
-            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), vmsObj.getSeqNext(), opCode);
+            this.packetNmbr = vmsObj.getSeqNext();
+            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), this.packetNmbr, opCode);
         }
         else if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_EX_FIGURE.getValue()) {
             this.framePacket = new VmsDleFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getCtlrLocalNo(), opCode);
@@ -35,8 +38,4 @@ public class VmsReqPowerModuleStatus implements VmsReqFramePacket {
         return this.framePacket.getByteBuffer();
     }
 
-    @Override
-    public String getOpCodeDesc() {
-        return this.framePacket.getOpCodeDesc();
-    }
 }

+ 6 - 7
src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqStatus.java

@@ -13,14 +13,17 @@ import java.nio.ByteBuffer;
 /**
  * Status 요청
  */
-public class VmsReqStatus implements VmsReqFramePacket {
+public class VmsReqStatus extends VmsReqFramePacket {
 
     private final VmsFramePacket framePacket;
 
     public VmsReqStatus(TbVmsCtlrDto vmsObj) {
-        byte opCode = (byte)eVmsOpCode.OP_VMS_STATUS_REQ.getValue();
+        this.opCode = eVmsOpCode.OP_VMS_STATUS_REQ;
+        this.packetNmbr = (short)this.opCode.getValue();
+        byte opCode = (byte)this.opCode.getValue();
         if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_ANDONG.getValue()) {
-            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), vmsObj.getSeqNext(), opCode);
+            this.packetNmbr = vmsObj.getSeqNext();
+            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), this.packetNmbr, opCode);
         }
         else if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_EX_FIGURE.getValue()) {
             this.framePacket = new VmsDleFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getCtlrLocalNo(), opCode);
@@ -35,8 +38,4 @@ public class VmsReqStatus implements VmsReqFramePacket {
         return this.framePacket.getByteBuffer();
     }
 
-    @Override
-    public String getOpCodeDesc() {
-        return this.framePacket.getOpCodeDesc();
-    }
 }

+ 6 - 8
src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqStatusControl.java

@@ -18,15 +18,18 @@ import java.nio.ByteOrder;
  * Status Control 요청
  */
 @Slf4j
-public class VmsReqStatusControl implements VmsReqFramePacket {
+public class VmsReqStatusControl extends VmsReqFramePacket {
 
     private final VmsFramePacket framePacket;
 
     private byte[] body;
     public VmsReqStatusControl(TbVmsCtlrDto vmsObj) {
-        byte opCode = (byte)eVmsOpCode.OP_VMS_STATUS_CONTROL.getValue();
+        this.opCode = eVmsOpCode.OP_VMS_STATUS_CONTROL;
+        this.packetNmbr = (short)this.opCode.getValue();
+        byte opCode = (byte)this.opCode.getValue();
         if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_ANDONG.getValue()) {
-            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), vmsObj.getSeqNext(), opCode);
+            this.packetNmbr = vmsObj.getSeqNext();
+            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), this.packetNmbr, opCode);
         }
         else if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_EX_FIGURE.getValue()) {
             this.framePacket = new VmsDleFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getCtlrLocalNo(), opCode);
@@ -122,9 +125,4 @@ public class VmsReqStatusControl implements VmsReqFramePacket {
         return this.framePacket.getByteBuffer();
     }
 
-    @Override
-    public String getOpCodeDesc() {
-        return this.framePacket.getOpCodeDesc();
-    }
-
 }

+ 6 - 8
src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqStopImage.java

@@ -15,14 +15,17 @@ import java.nio.ByteBuffer;
  * Stop Image 요청
  */
 @Slf4j
-public class VmsReqStopImage implements VmsReqFramePacket {
+public class VmsReqStopImage extends VmsReqFramePacket {
 
     private final VmsFramePacket framePacket;
 
     public VmsReqStopImage(TbVmsCtlrDto vmsObj, int deviceId) {
-        byte opCode = (byte)eVmsOpCode.OP_VMS_STOP_IMAGE_REQ.getValue();
+        this.opCode = eVmsOpCode.OP_VMS_STOP_IMAGE_REQ;
+        this.packetNmbr = (short)this.opCode.getValue();
+        byte opCode = (byte)this.opCode.getValue();
         if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_ANDONG.getValue()) {
-            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), vmsObj.getSeqNext(), opCode);
+            this.packetNmbr = vmsObj.getSeqNext();
+            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), this.packetNmbr, opCode);
         }
         else if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_EX_FIGURE.getValue()) {
             this.framePacket = new VmsDleFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getCtlrLocalNo(), opCode);
@@ -46,9 +49,4 @@ public class VmsReqStopImage implements VmsReqFramePacket {
         return this.framePacket.getByteBuffer();
     }
 
-    @Override
-    public String getOpCodeDesc() {
-        return this.framePacket.getOpCodeDesc();
-    }
-
 }

+ 6 - 7
src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqUploadCurrentDisplayForm.java

@@ -13,14 +13,17 @@ import java.nio.ByteBuffer;
 /**
  * Upload Current Display Form 요청
  */
-public class VmsReqUploadCurrentDisplayForm implements VmsReqFramePacket {
+public class VmsReqUploadCurrentDisplayForm extends VmsReqFramePacket {
 
     private final VmsFramePacket framePacket;
 
     public VmsReqUploadCurrentDisplayForm(TbVmsCtlrDto vmsObj) {
-        byte opCode = (byte)eVmsOpCode.OP_VMS_UPLOAD_CURRENT_DISPLAY_FORM.getValue();
+        this.opCode = eVmsOpCode.OP_VMS_UPLOAD_CURRENT_DISPLAY_FORM;
+        this.packetNmbr = (short)this.opCode.getValue();
+        byte opCode = (byte)this.opCode.getValue();
         if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_ANDONG.getValue()) {
-            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), vmsObj.getSeqNext(), opCode);
+            this.packetNmbr = vmsObj.getSeqNext();
+            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), this.packetNmbr, opCode);
         }
         else if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_EX_FIGURE.getValue()) {
             this.framePacket = new VmsDleFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getCtlrLocalNo(), opCode);
@@ -35,8 +38,4 @@ public class VmsReqUploadCurrentDisplayForm implements VmsReqFramePacket {
         return this.framePacket.getByteBuffer();
     }
 
-    @Override
-    public String getOpCodeDesc() {
-        return this.framePacket.getOpCodeDesc();
-    }
 }

+ 6 - 7
src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsReqUploadFormSchedule.java

@@ -13,14 +13,17 @@ import java.nio.ByteBuffer;
 /**
  * Upload Form Schedule 요청
  */
-public class VmsReqUploadFormSchedule implements VmsReqFramePacket {
+public class VmsReqUploadFormSchedule extends VmsReqFramePacket {
 
     private final VmsFramePacket framePacket;
 
     public VmsReqUploadFormSchedule(TbVmsCtlrDto vmsObj) {
-        byte opCode = (byte)eVmsOpCode.OP_VMS_UPLOAD_FORM_SCHEDULE.getValue();
+        this.opCode = eVmsOpCode.OP_VMS_UPLOAD_FORM_SCHEDULE;
+        this.packetNmbr = (short)this.opCode.getValue();
+        byte opCode = (byte)this.opCode.getValue();
         if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_ANDONG.getValue()) {
-            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), vmsObj.getSeqNext(), opCode);
+            this.packetNmbr = vmsObj.getSeqNext();
+            this.framePacket = new VmsStdFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getVmsCtlrNmbr().intValue(), this.packetNmbr, opCode);
         }
         else if (vmsObj.getProtocolVer() == eVmsProtocolVersion.PROTOCOL_EX_FIGURE.getValue()) {
             this.framePacket = new VmsDleFramePacket(vmsObj.getGroupNo().intValue(), vmsObj.getCtlrLocalNo(), opCode);
@@ -35,8 +38,4 @@ public class VmsReqUploadFormSchedule implements VmsReqFramePacket {
         return this.framePacket.getByteBuffer();
     }
 
-    @Override
-    public String getOpCodeDesc() {
-        return this.framePacket.getOpCodeDesc();
-    }
 }

+ 0 - 1
src/main/java/com/its/vms/xnettcp/vms/protocol/impl/VmsResFramePacket.java

@@ -18,4 +18,3 @@ public class VmsResFramePacket {
         System.arraycopy(packet, 0, this.packet, 0, msgLen);
     }
 }
-

+ 0 - 42
src/main/java/com/its/vms/xnettcp/vms/task/VmsTimeoutTask.java

@@ -1,42 +0,0 @@
-package com.its.vms.xnettcp.vms.task;
-
-import com.its.app.AppUtils;
-import com.its.vms.dao.mapper.VmsCtlrMapper;
-import com.its.vms.entity.TbVmsCtrlHs;
-import com.its.vms.dto.TbVmsCtlrDto;
-import lombok.extern.slf4j.Slf4j;
-import org.slf4j.MDC;
-
-import java.util.TimerTask;
-
-@Slf4j
-public class VmsTimeoutTask extends TimerTask {
-
-    private final TbVmsCtlrDto obj;
-    private final Long      packetNmbr;
-
-    public VmsTimeoutTask(TbVmsCtlrDto obj, Long packetNmbr) {
-        this.obj = obj;
-        this.packetNmbr = packetNmbr;
-    }
-
-    @Override
-    public void run() {
-
-        MDC.put("id", this.obj.getLogKey());
-
-        log.info("VmsTimeoutTask-run: packetNmbr: {}, obj: {}", this.packetNmbr, this.obj.getVmsCtlrNmbr());
-        this.obj.removeRegisteredCommands(this.packetNmbr, false);
-        TbVmsCtrlHs command = this.obj.getUserCommands(this.packetNmbr);
-        if (command != null) {
-            this.obj.removeUserCommands(this.packetNmbr);
-            // TODO: 제어명령 성공 전송(실패)
-            //command.setRspsType("5");  // 명령 실패(타임아웃)로 설정
-            VmsCtlrMapper mapper = (VmsCtlrMapper) AppUtils.getBean(VmsCtlrMapper.class);
-            mapper.updateVmsCtrlHs(command);
-        }
-
-        MDC.remove(this.obj.getLogKey());
-        MDC.clear();
-    }
-}

+ 13 - 11
src/main/resources/mybatis/mapper/VmsCtlrMapper.xml

@@ -305,20 +305,22 @@
         ]]>
     </insert>
 
-    <update id="updateVmsCtlrParam" parameterType="com.its.vms.entity.TbVmsCtlr">
+    <update id="updateVmsCtlrParam" parameterType="com.its.vms.entity.VmsCtlrParam">
     <![CDATA[
         update tb_vms_ctlr
         set
-            panl_pwer_mode      = #{panlPwerMode},
-            fan_mode            = #{fanMode},
-            fan_run_tmpr        = #{fanRunTmpr},
-            hetr_mode           = #{hetrMode},
-            hetr_run_tmpr       = #{hetrRunTmpr},
-            brgh_mode           = #{brghMode},
-            brgh_curr_step      = #{brghCurrStep},
-            brgh_week_step      = #{brghWeekStep},
-            brgh_nght_step      = #{brghNghtStep}
-        where vms_ctlr_nmbr = #{vmsCtlrNmbr}
+            panl_pwer_mode      = #{obj.panlPwerMode},
+            fan_mode            = #{obj.fanMode},
+            fan_run_tmpr        = #{obj.fanRunTmpr},
+            hetr_mode           = #{obj.hetrMode},
+            hetr_run_tmpr       = #{obj.hetrRunTmpr},
+            brgh_mode           = #{obj.brghMode},
+            brgh_curr_step      = #{obj.brghCurrStep},
+            brgh_week_step      = #{obj.brghWeekStep},
+            brgh_nght_step      = #{obj.brghNghtStep},
+            modl_err_rate       = #{obj.modlErrRate},
+            cmnc_fail_rate      = #{obj.cmncFailRate}
+        where vms_ctlr_nmbr = #{obj.vmsCtlrNmbr}
         ]]>
     </update>
 

+ 47 - 0
src/main/resources/mybatis/mapper/VmsManageMapper.xml

@@ -426,4 +426,51 @@
         ]]>
     </insert>
 
+
+    <update id="updateVmsDsplPrstResult" parameterType="com.its.vms.entity.VmsDsplDnldResult">
+    <![CDATA[
+        update tb_vms_dspl_prst
+        set
+            dspl_dt = #{obj.dsplDt},
+            dnld_yn = #{obj.dnldYn}
+        where vms_ctlr_nmbr  = #{obj.vmsCtlrNmbr}
+          and phase         <= #{obj.formCnt}
+        ]]>
+    </update>
+
+    <insert id="insertVmsDsplPrstHsResult" parameterType="com.its.vms.entity.VmsDsplDnldResult">
+    <![CDATA[
+        insert into tb_vms_dspl_hs (
+            dspl_dt,
+            vms_ctlr_nmbr,
+            phase,
+            vms_sch_type,
+            vms_sch_form_type,
+            vms_form_id,
+            dspl_hh,
+            vms_dspl_msg_data,
+            vms_dspl_msg_txt,
+            vms_form_dspl_drct_cd,
+            vms_form_dspl_mthd_cd,
+            dnld_yn )
+        select
+            dspl_dt,
+            vms_ctlr_nmbr,
+            phase,
+            vms_sch_type,
+            vms_sch_form_type,
+            vms_form_id,
+            dspl_hh,
+            vms_dspl_msg_data,
+            vms_dspl_msg_txt,
+            vms_form_dspl_drct_cd,
+            vms_form_dspl_mthd_cd,
+            dnld_yn
+        from tb_vms_dspl_prst
+        where vms_ctlr_nmbr = #{obj.vmsCtlrNmbr}
+          and dspl_dt       = #{obj.dsplDt}
+          and phase        <= #{obj.formCnt}
+        ]]>
+    </insert>
+
 </mapper>