|
|
@@ -1,16 +1,22 @@
|
|
|
package com.its.vms.dto;
|
|
|
|
|
|
+import com.its.app.AppUtils;
|
|
|
import com.its.app.utils.SysUtils;
|
|
|
import com.its.vms.domain.*;
|
|
|
+import com.its.vms.domain.enums.eVmsFormType;
|
|
|
import com.its.vms.entity.TbVmsCtlr;
|
|
|
import com.its.vms.entity.TbVmsCtlrStts;
|
|
|
import com.its.vms.entity.TbVmsCtrlHs;
|
|
|
+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.domain.VmsFrameSequence;
|
|
|
+import com.its.vms.xnettcp.vms.protocol.dto.*;
|
|
|
import com.its.vms.xnettcp.vms.protocol.enums.eControlCommand;
|
|
|
import com.its.vms.xnettcp.vms.protocol.enums.eControlDeviceId;
|
|
|
+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.impl.VmsReqDownloadForm;
|
|
|
import com.its.vms.xnettcp.vms.task.VmsTimeoutTask;
|
|
|
import io.netty.channel.Channel;
|
|
|
import io.netty.channel.ChannelFuture;
|
|
|
@@ -22,7 +28,10 @@ import java.io.Serializable;
|
|
|
import java.net.InetSocketAddress;
|
|
|
import java.nio.ByteBuffer;
|
|
|
import java.text.SimpleDateFormat;
|
|
|
-import java.util.*;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Timer;
|
|
|
+import java.util.TimerTask;
|
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
|
|
@Slf4j
|
|
|
@@ -107,22 +116,25 @@ public class TbVmsCtlrDto implements Serializable {
|
|
|
private VmsModule module;
|
|
|
private VmsLuminance luminance;
|
|
|
private VmsControlMode controlMode;
|
|
|
- private VmsDownload download;
|
|
|
+ private byte txtOpCode;
|
|
|
|
|
|
private TbVmsCtlrStts stts;
|
|
|
private int netState;
|
|
|
private boolean isDupCon;
|
|
|
private boolean isDupLogin;
|
|
|
private String dstIpAddr;
|
|
|
- private Channel channel;
|
|
|
- private Channel dupChannel;
|
|
|
+ private Channel channel = null;
|
|
|
+ private Channel dupChannel = null;
|
|
|
private InetSocketAddress cliReq;
|
|
|
private long syncTime;
|
|
|
private VmsFrameSequence seq;
|
|
|
|
|
|
+ private VmsDownloadFile downloadFile; // 제어기로 다운로드할 파일정보(TB_VMS_DOWNLOAD)
|
|
|
+ private VmsDownloadData downloadData;
|
|
|
+ private ConcurrentHashMap<Integer, VmsDownloadForm> downloadFormMap = null;
|
|
|
+
|
|
|
private ConcurrentHashMap<Long, TbVmsRltnIfscDto> rltnIfscMap = null;
|
|
|
|
|
|
- //private ConcurrentHashMap<Long, C2CAuthenticatedMessage> registeredCommands = null;
|
|
|
private ConcurrentHashMap<Long, Timer> registeredCommandsTimer = null;
|
|
|
private ConcurrentHashMap<Long, TbVmsCtrlHs> userCommands = null;
|
|
|
|
|
|
@@ -136,6 +148,10 @@ public class TbVmsCtlrDto implements Serializable {
|
|
|
public void init() {
|
|
|
this.stts = new TbVmsCtlrStts(this.vmsCtlrNmbr);
|
|
|
this.seq = new VmsFrameSequence();
|
|
|
+
|
|
|
+ this.downloadData = new VmsDownloadData();
|
|
|
+ this.downloadFormMap = new ConcurrentHashMap<>();
|
|
|
+
|
|
|
this.registeredCommandsTimer = new ConcurrentHashMap<>();
|
|
|
this.userCommands = new ConcurrentHashMap<>();
|
|
|
this.rltnIfscMap = new ConcurrentHashMap<>();
|
|
|
@@ -149,7 +165,7 @@ public class TbVmsCtlrDto implements Serializable {
|
|
|
this.module = new VmsModule();
|
|
|
this.luminance = new VmsLuminance();
|
|
|
this.controlMode = new VmsControlMode();
|
|
|
- this.download = new VmsDownload();
|
|
|
+ this.downloadFile = new VmsDownloadFile();
|
|
|
|
|
|
this.connectCount = 0;
|
|
|
this.connectTm = "-";
|
|
|
@@ -163,17 +179,40 @@ public class TbVmsCtlrDto implements Serializable {
|
|
|
this.evehIngForm = false;
|
|
|
this.evehEndForm = false;
|
|
|
|
|
|
+ initDownloadFileInfo();
|
|
|
+ initDownloadFormDataInfo();
|
|
|
initNet();
|
|
|
|
|
|
this.dataProcess = new TcpServerSendDataProcess(this);
|
|
|
this.dataProcess.run();
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 파일 다운로드 정보 초기화
|
|
|
+ */
|
|
|
+ public void initDownloadFileInfo() {
|
|
|
+ this.downloadFile.setEnable(false);
|
|
|
+ this.downloadFile.setSaveFlag(true);
|
|
|
+ this.downloadFile.setDTimer(System.currentTimeMillis());
|
|
|
+ this.downloadFile.setCount(0);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 폼 파일 다운로드 정보를 초기화
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public void initDownloadFormDataInfo() {
|
|
|
+ this.downloadData.init();
|
|
|
+ this.downloadFormMap.forEach((formId, obj) -> {
|
|
|
+ obj.setAlreadyDownload(false);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
public short getSeqNext() {
|
|
|
return this.seq.nextValue();
|
|
|
}
|
|
|
- public void addRequestData(TcpServerSendData data) {
|
|
|
- this.dataProcess.add(data);
|
|
|
+ public boolean addRequestData(TcpServerSendData data) {
|
|
|
+ return this.dataProcess.add(data);
|
|
|
}
|
|
|
|
|
|
public synchronized void connected(ChannelHandlerContext ctx) {
|
|
|
@@ -187,10 +226,8 @@ public class TbVmsCtlrDto implements Serializable {
|
|
|
|
|
|
public synchronized void disconnected() {
|
|
|
this.netState = NET.CLOSED;
|
|
|
- //this.registeredCommands.clear();
|
|
|
this.registeredCommandsTimer.clear();
|
|
|
this.channel = null;
|
|
|
- this.stts.initError();
|
|
|
this.disConnectTm = SysUtils.getSysTimeStr();
|
|
|
this.stts.initError();
|
|
|
}
|
|
|
@@ -262,7 +299,7 @@ public class TbVmsCtlrDto implements Serializable {
|
|
|
*/
|
|
|
public boolean sendData(ByteBuffer sendBuffer, int delayMilliSeconds, String packetDesc) {
|
|
|
boolean result = false;
|
|
|
- log.info("~REQUEST-{}. VMS {}", packetDesc, this.vmsCtlrNmbr);
|
|
|
+ log.info("~REQUEST-{}. VMS {}, {} Bytes.", packetDesc, this.vmsCtlrNmbr, sendBuffer.capacity());
|
|
|
if (this.channel != null) {
|
|
|
ChannelFuture f = this.channel.writeAndFlush(sendBuffer);
|
|
|
f.awaitUninterruptibly();
|
|
|
@@ -447,4 +484,162 @@ public class TbVmsCtlrDto implements Serializable {
|
|
|
.protocolVer(this.protocolVer)
|
|
|
.build();
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 스케쥴 다운로드 초기화 작업을 수행한다.
|
|
|
+ * @param isSchedule
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public boolean downloadScheduleForm(boolean isSchedule) {
|
|
|
+ VmsFormService formService = (VmsFormService) AppUtils.getBean(VmsFormService.class);
|
|
|
+ this.controlMode.setSchedule(isSchedule);
|
|
|
+ this.txtOpCode = (byte)0x00;
|
|
|
+ this.downloadData.init();
|
|
|
+
|
|
|
+ int forms = 0;
|
|
|
+ int formCnt = this.formManager.count();
|
|
|
+ if (formCnt == 0) {
|
|
|
+ log.info("downloadScheduleForm: VMS {}, Form Data Not Found.", this.vmsCtlrNmbr);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ if (formCnt > this.maxPhaseNum) {
|
|
|
+ log.error("downloadScheduleForm: VMS {}, Form Count Over: {}/{} EA.", this.vmsCtlrNmbr, formCnt, this.maxPhaseNum);
|
|
|
+ formCnt = this.maxPhaseNum;
|
|
|
+ }
|
|
|
+
|
|
|
+ VmsDownloadData.VmsDownloadDataInfo[] units = this.downloadData.getUnits();
|
|
|
+ for (int ii = 0; ii < formCnt; ii++) {
|
|
|
+ VmsForm pForm = this.formManager.getItem(ii);
|
|
|
+ if (!pForm.isSuccess()) {
|
|
|
+ log.error("VMS {}, SEQ {}, SUCCESS {}", this.vmsCtlrNmbr, ii, pForm.isSuccess());
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ Integer vmsFormId = pForm.getVmsFormId();
|
|
|
+ TbVmsFormDto vmsForm = formService.find(vmsFormId);
|
|
|
+ if (vmsForm == null) {
|
|
|
+ log.error("VMS {}, SEQ {}, FORM ID {} Not Found.", this.vmsCtlrNmbr, ii, vmsFormId);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ units[forms].setVmsFormId(vmsFormId);
|
|
|
+ units[forms].setDownload(true);
|
|
|
+ units[forms].setFormIdx(ii);
|
|
|
+ units[forms].setBitmapId(forms + 1000);
|
|
|
+ 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);
|
|
|
+ units[forms].setBitmapId((vmsFormId % 1000) + 1000);
|
|
|
+ // 홍보폼이면서 신규폼이 아니면서 이전 다운로드 목록이 존재하는 경우에 다운로드 여부를 체크한다.
|
|
|
+ if (vmsForm.getVmsFormTypeCd() == eVmsFormType.eFormTp_hongbo.getValue() && !vmsForm.isNewForm() && downloadForm != null) {
|
|
|
+ if (downloadForm.isAlreadyDownload()) {
|
|
|
+ // 이미 이전에 다운로드를 했기때문에 이번에는 제어기로 다운로드를 하지 않는다.
|
|
|
+ units[forms].setDownload(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 이전에 다운로드한 정보가 존재하면
|
|
|
+ if (downloadForm != null) {
|
|
|
+ if (!vmsForm.getUpdtDt().equals(downloadForm.getUpdtDt())) {
|
|
|
+ // 업데이트시각이 다르기때문에 신규폼으로 판단한다.
|
|
|
+ downloadForm.setAlreadyDownload(false);
|
|
|
+ downloadForm.setUpdtDt(vmsForm.getUpdtDt());
|
|
|
+ units[forms].setDownload(true);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ downloadForm = new VmsDownloadForm();
|
|
|
+ downloadForm.setVmsFormId(vmsFormId);
|
|
|
+ downloadForm.setAlreadyDownload(false);
|
|
|
+ downloadForm.setUpdtDt(vmsForm.getUpdtDt());
|
|
|
+ this.downloadFormMap.put(vmsFormId, downloadForm);
|
|
|
+ }
|
|
|
+ forms++;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int ii = 0; ii < forms; ii++) {
|
|
|
+ log.info("VMS {}, Form schedule({}), VMS_FORM_ID: {}, FormIdx: {}, FormId: {}, BitmapId: {}, IsDownload: {}",
|
|
|
+ this.vmsCtlrNmbr, ii, units[ii].getVmsFormId(), units[ii].getFormIdx(), units[ii].getFormNo(), units[ii].getBitmapId(), units[ii].isDownload());
|
|
|
+ }
|
|
|
+
|
|
|
+ this.downloadData.setMaxSchedule(forms);
|
|
|
+ this.downloadData.setDownloadCnt(0);
|
|
|
+ this.downloadData.setDefault("B".equals(this.operMode));
|
|
|
+ if (this.downloadData.isDefault()) {
|
|
|
+ // 기본모드인 경우
|
|
|
+ // 폼 ID "FID0000" 에 여러개의 폼을 다운로드 해야함.
|
|
|
+ //e_vms_download_form = 0x9A,// Download Form 송신 Form download 센터 → VMS
|
|
|
+ //e_vms_file_download = 0x82,// 데이터 다운로드 송신 INI, CFG , Bitmap , Data파일송신 센터 → VMS
|
|
|
+ //e_vms_download_schedule_form = 0x96,// Display Schedule Form 송신 계획된 Form 표출 요구 센터 → VMS
|
|
|
+ //e_vms_blank = 0x9E,// Blank 송신 schedule 표출 센터 → VMS
|
|
|
+ downloadDefaultSchedule();
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ // 스케쥴 모드인 경우(A:자동, F:고정)
|
|
|
+ //e_vms_download_form = 0x9A,// Download Form 송신 Form download 센터 → VMS
|
|
|
+ //e_vms_file_download = 0x82,// 데이터 다운로드 송신 INI, CFG , Bitmap , Data파일송신 센터 → VMS
|
|
|
+ //e_vms_download_schedule_form = 0x96,// Display Schedule Form 송신 계획된 Form 표출 요구 센터 → VMS
|
|
|
+ //e_vms_blank = 0x9E,// Blank 송신 schedule 표출 센터 → VMS
|
|
|
+ downloadDefaultSchedule();
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean downloadDefaultSchedule() {
|
|
|
+ // Download Form (기본폼은 하나의 폼에 여러폼을 다운로드한다.)
|
|
|
+ int formCnt = this.downloadData.getMaxSchedule();
|
|
|
+ if (formCnt <= 0) {
|
|
|
+ log.info("VMS {}, Download Schedule Form Count Zero. {} EA.", this.vmsCtlrNmbr, formCnt);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ formCnt = 1;
|
|
|
+ VmsFormDataDto formData = new VmsFormDataDto(0, formCnt);
|
|
|
+ VmsDownloadData.VmsDownloadDataInfo[] units = this.downloadData.getUnits();
|
|
|
+ for (int ii = 0; ii < formCnt; ii++) {
|
|
|
+ VmsForm pForm = this.formManager.getItem(units[ii].getFormIdx());
|
|
|
+ List<VmsFormObject> objects = pForm.getObjects();
|
|
|
+ VmsFormDto formDto = formData.addForm(units[ii].getVmsFormId(), units[ii].getDisplaySec(), units[ii].getDisplayType(), units[ii].getBkClr(), objects.size());
|
|
|
+ for (int jj = 0; jj < objects.size(); jj++) {
|
|
|
+ VmsFormObject object = objects.get(jj);
|
|
|
+
|
|
|
+ int objSize = object.getObjectSize();
|
|
|
+ int blinking = object.getBlinking();
|
|
|
+ int posX = object.getPosX();
|
|
|
+ int posY = object.getPosY();
|
|
|
+ int bkClr = object.getBkColor();
|
|
|
+
|
|
|
+ VmsFormObj formObjDto;
|
|
|
+ if (objects.get(jj).getObjectKind() == eVmsFormObjectKind.OBJECT_TEXT) {
|
|
|
+ int clrR = object.getFontClr().getRed();
|
|
|
+ int clrG = object.getFontClr().getGreen();
|
|
|
+ int clrB = object.getFontClr().getBlue();
|
|
|
+ formObjDto = new VmsFormObjText(objSize, blinking, posX, posY, bkClr, clrR, clrG, clrB, object.getFontSize(), object.getFontNameCd(), object.getFontBold(), object.getTextData());
|
|
|
+ }
|
|
|
+ else if (objects.get(jj).getObjectKind() == eVmsFormObjectKind.OBJECT_BITMAP_ID) {
|
|
|
+ formObjDto = new VmsFormObjBitmapId(objSize, blinking, posX, posY, bkClr, object.getDsplWidth(), object.getDsplHeight(), eVmsImageType.VMS_IMAGE_TYPE_BMP.getValue(), units[ii].getBitmapId());
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ formObjDto = new VmsFormObjBitmapId(objSize, blinking, posX, posY, bkClr, object.getDsplWidth(), object.getDsplHeight(), eVmsImageType.VMS_IMAGE_TYPE_BMP.getValue(), units[ii].getBitmapId());
|
|
|
+ //formObjDto = new VmsFormObjBitmap(objSize, blinking, posX, posY, bkClr, object.getDsplWidth(), object.getDsplHeight(), eVmsImageType.VMS_IMAGE_TYPE_BMP.getValue(), object.getImageData());
|
|
|
+ }
|
|
|
+ formObjDto.calSize();
|
|
|
+ formDto.addObject(formObjDto);
|
|
|
+ }
|
|
|
+ formDto.calObjCount();
|
|
|
+ }
|
|
|
+ formData.calFormCount();
|
|
|
+
|
|
|
+ VmsReqDownloadForm downloadForm = new VmsReqDownloadForm(this, formData);
|
|
|
+ return sendData(downloadForm.getByteBuffer(), 10, downloadForm.getOpCodeDesc());
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean downloadAutoFixSchedule() {
|
|
|
+ // Download Form (기본폼은 하나의 폼에 하나의 폼만 다운로드한다.)
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
}
|