TsiCpuPacket.java 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. package com.tsi.comm.server.protocol;
  2. import com.tsi.comm.server.dto.TsiCvimAbnormal;
  3. import com.tsi.comm.server.dto.TsiCvimControl;
  4. import com.tsi.comm.server.dto.TsiCvimStatus;
  5. import com.tsi.comm.server.protocol.enums.eLightsStatus;
  6. import com.tsi.comm.server.protocol.enums.eLightsType;
  7. import com.tsi.comm.server.protocol.enums.eOpCode;
  8. import com.tsi.comm.server.protocol.enums.eTimeReliability;
  9. import com.tsi.comm.server.xnet.NettyUtils;
  10. import com.tsi.comm.server.dto.mongodb.TcsNodeStatus;
  11. import com.tsi.comm.server.repository.TsiNodeAddManager;
  12. import com.tsi.comm.server.vo.TsiNodeAddDetailVo;
  13. import com.tsi.comm.server.vo.TsiNodeAddVo;
  14. import com.tsi.comm.server.vo.TsiNodeVo;
  15. import com.tsi.common.utils.ByteUtils;
  16. import com.tsi.common.utils.CRC16Utils;
  17. import io.netty.channel.Channel;
  18. import lombok.Getter;
  19. import lombok.Setter;
  20. import lombok.extern.slf4j.Slf4j;
  21. import java.nio.ByteBuffer;
  22. import java.nio.ByteOrder;
  23. import java.text.SimpleDateFormat;
  24. import java.util.*;
  25. import static com.tsi.comm.server.protocol.TsiCvibProtocolSpec.*;
  26. @Slf4j
  27. @Getter
  28. @Setter
  29. public class TsiCpuPacket extends AbstractTsiPacket {
  30. protected static TsiNodeAddManager nodeAddManager;
  31. private Object obj;
  32. private int length;
  33. private byte dataVer;
  34. private int count;
  35. protected byte[] cvimData; // for cvim-raw topic
  36. protected byte[] nodeData; // for node topic
  37. protected List<TsiCpuAddPacket> addNodes;
  38. public static void setNodeAddManager(TsiNodeAddManager nodeAddManager) {
  39. TsiCpuPacket.nodeAddManager = nodeAddManager;
  40. }
  41. public TsiCpuPacket(long nodeId, long msec, long nsec, Channel channel) {
  42. super(nodeId, msec, nsec, NettyUtils.getRemoteIpAddressToLong(channel), NettyUtils.getRemotePort(channel));
  43. setOpCode(eOpCode.TSI_CPU_SIGNAL_NOTIFY.getValue());
  44. }
  45. public TsiCpuPacket(long nodeId, long msec, long nsec, long remoteIpAddressToLong, int remotePort) {
  46. super(nodeId, msec, nsec, remoteIpAddressToLong, remotePort);
  47. }
  48. // FOR CVIM packet
  49. // public TsiCpuPacket(long nodeId, byte[] value) {
  50. // super(nodeId, TimeUtils.currentTimeSeconds(), System.nanoTime(), 0, 0);
  51. // this.buf = value; // CVIM Header 를 포함한 내부 IPC 형식 데이터임
  52. // int nodeLength = this.buf.length - TsiCpuPacket.SIZE_IPC_SIZE;
  53. // this.cvimData = new byte[TsiCpuPacket.SIZE_IPC_SIZE];
  54. // System.arraycopy(this.buf, 0, this.cvimData, 0, TsiCpuPacket.SIZE_IPC_SIZE);
  55. // if (nodeLength > 0) {
  56. // this.nodeData = new byte[nodeLength];
  57. // System.arraycopy(this.buf, TsiCpuPacket.SIZE_IPC_SIZE, this.nodeData, 0, nodeLength);
  58. // }
  59. // }
  60. protected byte getStx1() {
  61. if (this.buf != null) return this.buf[INDEX_STX1];
  62. return 0x00;
  63. }
  64. protected byte getStx2() {
  65. if (this.buf != null) return this.buf[INDEX_STX2];
  66. return 0x00;
  67. }
  68. public byte[] getTestData() {
  69. return this.buf;
  70. }
  71. /*
  72. * Make cvim-raw packet
  73. */
  74. protected void makeCvimPacket() {
  75. final int packetLength = (this.buf == null) ? 0 : this.buf.length;
  76. this.cvimData = new byte[SIZE_IPC_SIZE + packetLength];
  77. // cvim-raw header
  78. System.arraycopy(this.timespec.bytes(), 0, this.cvimData, POS_IPC_TIMESPEC, SIZE_TIMESPEC);
  79. ByteUtils.setUnsignedInt(this.cvimData, POS_IPC_IPADDR, getRemoteIp());
  80. ByteUtils.setUnsignedShort(this.cvimData, POS_IPC_PORT, getRemotePort());
  81. this.cvimData[POS_IPC_CONNECT] = (opCode == (byte)eOpCode.TSI_CPU_SIGNAL_NOTIFY.getValue()) ? CONNECT : DISCONNECT;
  82. ByteUtils.setUnsignedInt(this.cvimData, POS_IPC_NODEID, this.nodeId);
  83. // cvim-raw body
  84. if (packetLength > 0) {
  85. System.arraycopy(this.buf, 0, this.cvimData, POS_IPC_PACKET, packetLength);
  86. }
  87. //log.error("CVIM: {}", HexString.fromBytes(this.cvimData));
  88. }
  89. /*
  90. * Make cvim-raw packet
  91. */
  92. protected void makeAddNodeCvimPaket(TsiCpuPacket cpuPacket, byte[] packet) {
  93. final int packetLength = (packet == null) ? 0 : packet.length;
  94. final int headSize = SIZE_IPC_SIZE + 6;
  95. cpuPacket.cvimData = new byte[headSize + packetLength + 2]; // cpu packet 6 byte(nodeid 제외), crc 2 byte
  96. // cvim-raw header
  97. System.arraycopy(timespec.bytes(), 0, cpuPacket.cvimData, POS_IPC_TIMESPEC, SIZE_TIMESPEC);
  98. ByteUtils.setUnsignedInt(cpuPacket.cvimData, POS_IPC_IPADDR, getRemoteIp());
  99. ByteUtils.setUnsignedShort(cpuPacket.cvimData, POS_IPC_PORT, getRemotePort());
  100. cpuPacket.cvimData[POS_IPC_CONNECT] = (opCode == (byte)eOpCode.TSI_CPU_SIGNAL_NOTIFY.getValue()) ? CONNECT : DISCONNECT;
  101. ByteUtils.setUnsignedInt(cpuPacket.cvimData, POS_IPC_NODEID, cpuPacket.nodeId);
  102. cpuPacket.cvimData[SIZE_IPC_SIZE+INDEX_STX1] = getStx1();
  103. cpuPacket.cvimData[SIZE_IPC_SIZE+INDEX_STX2] = getStx2();
  104. ByteUtils.setUnsignedShort(cpuPacket.cvimData, SIZE_IPC_SIZE+INDEX_LENGTH, packetLength+2);
  105. cpuPacket.cvimData[SIZE_IPC_SIZE+INDEX_OPCODE] = (byte)getOpCode();
  106. cpuPacket.cvimData[SIZE_IPC_SIZE+INDEX_VERSION] = getDataVer();
  107. // cvim-raw body
  108. if (packetLength > 0) {
  109. System.arraycopy(packet, 0, cpuPacket.cvimData, headSize, packetLength);
  110. }
  111. // 체크섬 계산하지 않음
  112. }
  113. protected int checkPacket(TsiNodeVo obj, boolean checkCrc) {
  114. // 0 단계. STX1, STX2 체크
  115. if (this.buf[INDEX_STX1] != STX1 || this.buf[INDEX_STX2] != STX2) {
  116. log.error("parsing: errno(-1), NodeId: {}, stx1: {}, stx2: {}", this.nodeId, this.buf[INDEX_STX1], this.buf[INDEX_STX2]);
  117. return -1;
  118. }
  119. // 1 단계. 패킷 길이 체크
  120. // TODO: 20240722, Protocol R28 ADDED
  121. // int reqLength = SIZE_PACKET_DATA + (SIZE_STATUS_DATA * this.count);
  122. // if (this.buf[INDEX_VERSION] == PROTOCOL_R28) {
  123. // reqLength = SIZE_PACKET_DATA + (SIZE_STATUS_DATA * this.count) + 1; // ADD CPU byte packet
  124. // }
  125. // if (this.length != reqLength ) {
  126. // return false;
  127. // }
  128. final int reqLength = SIZE_PACKET_DATA + (SIZE_STATUS_DATA * this.count);
  129. if (this.length < reqLength ) {
  130. log.error("parsing: errno(-2), NodeId: {}, reqLength: {}, recvLength: {}", this.nodeId, reqLength, this.length);
  131. return -2;
  132. }
  133. // 2단계. 체크섬
  134. final int receivedCrc = ByteUtils.getUnsignedShort(this.buf, this.buf.length-2);
  135. final int calculatedCrc = CRC16Utils.CRC16_ccitt_cvim(this.buf, INDEX_LENGTH, this.length-2); // 시작인덱스가 있으므로 전체길이로 계산
  136. if (receivedCrc != calculatedCrc) {
  137. if (checkCrc || (obj != null && obj.isDump())) {
  138. log.error("parsing: errno(-3), NodeId: {}, crc(recv/calc): {}/{}", this.nodeId, receivedCrc, calculatedCrc);
  139. }
  140. return -3;
  141. }
  142. return 0;
  143. }
  144. public int parsing(TsiNodeVo obj, boolean isCheckPacket) {
  145. if (this.buf == null || this.buf.length < INDEX_STATUS_HDR+3) {
  146. log.error("parsing: errno(-4), NodeId: {}, buf==null: {}, length: {}", this.nodeId, this.buf == null, this.buf == null ? 0 : this.buf.length);
  147. return -4;
  148. }
  149. this.opCode = this.buf[INDEX_OPCODE];
  150. this.dataVer = this.buf[INDEX_VERSION];
  151. this.length = ByteUtils.getUnsignedShort(this.buf, INDEX_LENGTH);
  152. this.count = (int)(this.buf[INDEX_STATUS_HDR+3] & 0x7F);
  153. obj.setSigCount(this.count); // 신호현시 갯수 저장
  154. // CVIM 데이터 및 TEST 데이터가 생성됨
  155. makeCvimPacket();
  156. int result = checkPacket(obj, isCheckPacket);
  157. if (0 != result) {
  158. if (-3 == result) {
  159. obj.setCrcError(true);
  160. }
  161. if (isCheckPacket) {
  162. // 20250425: CRC 체크여부에 따라 바로 리턴(기본값은 체크여부가 true 임)
  163. return result;
  164. }
  165. }
  166. TsiNodeAddVo tsiNodeAddVo = TsiCpuPacket.nodeAddManager.get(this.nodeId);
  167. if (tsiNodeAddVo == null) {
  168. // 연등지 정보가 없는 경우
  169. // R25 인 경우 마지막 CPU 제조사 코드를 복사하지 않도록 수정
  170. int addLength = this.buf.length-SIZE_NODE_DUMMY;
  171. final int r25Length = SIZE_NODE_HEAD + (this.count * SIZE_STATUS_DATA);
  172. if (addLength > r25Length) {
  173. addLength = r25Length;
  174. }
  175. this.nodeData = new byte[addLength];
  176. System.arraycopy(this.buf, INDEX_NODE_ID, this.nodeData, 0, addLength);
  177. return 0;
  178. }
  179. // 연등지 교차로 데이터 파싱
  180. byte[] head = new byte[SIZE_NODE_HEAD];
  181. List<byte[]> nodeStatus = new ArrayList<>();
  182. Map<Long, List<byte[]>> addStatus = new HashMap<>();
  183. System.arraycopy(this.buf, INDEX_NODE_ID, head, 0, SIZE_NODE_HEAD);
  184. int loop = 0;
  185. for (int ii = INDEX_STATUS_DATA; loop < this.count; ii += SIZE_STATUS_DATA, loop++) {
  186. byte[] status = new byte[SIZE_STATUS_DATA];
  187. System.arraycopy(this.buf, ii, status, 0, SIZE_STATUS_DATA);
  188. int dirAdd = status[INDEX_STATUS_DIR_ADD] & 0x0F;
  189. if (dirAdd == 0) {
  190. // 원천 노드 정보
  191. nodeStatus.add(status);
  192. }
  193. else {
  194. // 추가 노드 정보
  195. int originDirCode = status[INDEX_STATUS_DIRECTION]; // 원천방향코드
  196. int direction = originDirCode / 10; // 인천공항 노드 확인용
  197. int addNodeIdx = originDirCode % 10; // 인천공항 노드 확인용
  198. if (addNodeIdx > 4) {
  199. // 인천공항 연등지 인 경우 2개 이상이기 때문에 연등지1 = 15, 연등지2=16, ....
  200. // 즉, 일의 자리 5,6,7,8,9로 설정하고 1,2,3,4,5로 된다. 십의자리는 *10을 해서 원천방향코드가 된다.
  201. dirAdd = addNodeIdx - 4; // 인천공항이 아닌경우는 위에서 구한 dirAdd 을 그대로 사용한다(1,2 만 가능)
  202. originDirCode = direction * 10; // 15,16,17,18,19=10, 25,26,27,28,29=20, ....
  203. }
  204. status[INDEX_STATUS_DIR_ADD] = (byte) (status[INDEX_STATUS_DIR_ADD] & 0xF0); // 방향추가정보를 0 으로 초기화
  205. TsiNodeAddDetailVo detailVo = tsiNodeAddVo.getAddNodeMap().get(originDirCode * 1000 + dirAdd);
  206. if (detailVo != null && detailVo.getAddDirCode() != null) {
  207. for (int dirIdx = 0; dirIdx < detailVo.getAddDirCode().length; dirIdx++) {
  208. // if (detailVo.getAddDirCode()[dirIdx] == (byte)0x00) {
  209. // continue;
  210. // }
  211. // 연등지 방향코드를 배열에 가지고 있기 때문에
  212. List<byte[]> list = addStatus.get(detailVo.getNodeId());
  213. if (list == null) {
  214. list = new ArrayList<>();
  215. addStatus.put(detailVo.getNodeId(), list);
  216. }
  217. if (dirIdx == 0) {
  218. status[INDEX_STATUS_DIRECTION] = detailVo.getAddDirCode()[dirIdx];
  219. list.add(status);
  220. }
  221. else {
  222. byte[] status2 = new byte[SIZE_STATUS_DATA];
  223. System.arraycopy(status, 0, status2, 0, SIZE_STATUS_DATA);
  224. status2[INDEX_STATUS_DIRECTION] = detailVo.getAddDirCode()[dirIdx];
  225. list.add(status2);
  226. }
  227. }
  228. }
  229. }
  230. }
  231. byte splitFlag = 0x01;
  232. int statusCount = nodeStatus.size();
  233. this.nodeData = new byte[SIZE_NODE_HEAD + (statusCount*SIZE_STATUS_DATA)];
  234. System.arraycopy(head, 0, this.nodeData, 0, SIZE_NODE_HEAD);
  235. this.nodeData[POS_NODE_HEAD_COUNT] = (byte) (statusCount | (splitFlag << 7));
  236. for (int ii = 0; ii < statusCount; ii++) {
  237. System.arraycopy(nodeStatus.get(ii), 0, this.nodeData, SIZE_NODE_HEAD+(ii*SIZE_STATUS_DATA), SIZE_STATUS_DATA);
  238. }
  239. makeAddNodeCvimPaket(this, this.nodeData);
  240. if (addStatus.isEmpty()) {
  241. // 연등지 정보가 설정된게 없을까???
  242. return 0;
  243. }
  244. // 연등지 노드 카프카 패킷 생성
  245. this.addNodes = new ArrayList<>();
  246. for (Map.Entry<Long, List<byte[]>> entry: addStatus.entrySet()) {
  247. statusCount = entry.getValue().size();
  248. TsiCpuAddPacket addPacket = new TsiCpuAddPacket(entry.getKey(), this.timespec, this.remoteIp, this.remotePort);
  249. addPacket.setObj(TsiCpuPacket.nodeAddManager.get(entry.getKey()));
  250. addPacket.setNodeData(new byte[SIZE_NODE_HEAD + (statusCount*SIZE_STATUS_DATA)]);
  251. System.arraycopy(head, 0, addPacket.getNodeData(), 0, SIZE_NODE_HEAD);
  252. ByteUtils.setUnsignedInt(addPacket.getNodeData(), POS_NODE_HEAD_NODEID, entry.getKey());
  253. addPacket.getNodeData()[POS_NODE_HEAD_COUNT] = (byte) (statusCount | (splitFlag << 7));
  254. for (int ii = 0; ii < statusCount; ii++) {
  255. System.arraycopy(entry.getValue().get(ii), 0, addPacket.getNodeData(), SIZE_NODE_HEAD+(ii*SIZE_STATUS_DATA), SIZE_STATUS_DATA);
  256. }
  257. makeAddNodeCvimPaket(addPacket, addPacket.getNodeData());
  258. this.addNodes.add(addPacket);
  259. }
  260. /*
  261. log.error(" RAW: {}, {}", this.nodeId, HexString.fromBytes(getBuf()));
  262. log.error("NODE: {}, {}", this.nodeId, HexString.fromBytes(getNodeData()));
  263. log.error("CVIM: {}, {}", this.nodeId, HexString.fromBytes(getCvimData()));
  264. for (int ii = 0; ii < addNodes.size(); ii++) {
  265. log.error("NODE: {}, {}", addNodes.get(ii).nodeId, HexString.fromBytes(addNodes.get(ii).getNodeData()));
  266. log.error("CVIM: {}, {}", addNodes.get(ii).nodeId, HexString.fromBytes(addNodes.get(ii).getCvimData()));
  267. }*/
  268. return 0;
  269. }
  270. public TcsNodeStatus getNodeStatus() {
  271. int nodeLength = this.buf.length - SIZE_IPC_SIZE;
  272. byte[] msec = new byte[8];
  273. byte[] nsec = new byte[8];
  274. System.arraycopy(this.cvimData, 0, msec, 0, 8);
  275. System.arraycopy(this.cvimData, 8, nsec, 0, 8);
  276. ByteBuffer byteMSec = ByteBuffer.wrap(msec);
  277. ByteBuffer byteNSec = ByteBuffer.wrap(nsec);
  278. byteMSec.order(ByteOrder.LITTLE_ENDIAN);
  279. byteNSec.order(ByteOrder.LITTLE_ENDIAN);
  280. long milliSeconds = byteMSec.getLong();
  281. long nanoSeconds = byteNSec.getLong();
  282. this.remoteIp = ByteUtils.getUnsignedInt(this.cvimData, POS_IPC_IPADDR);
  283. this.remotePort = ByteUtils.getUnsignedShort(this.cvimData, POS_IPC_PORT);
  284. /////
  285. getTimespec().tv_nsec(nanoSeconds); // recv tcp,
  286. Date date = new Date(milliSeconds * 1000L);
  287. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  288. sdf.setTimeZone(java.util.TimeZone.getTimeZone("GMT+9"));
  289. String collectTime = sdf.format(date);
  290. if (this.cvimData[POS_IPC_CONNECT] == DISCONNECT) {
  291. return TcsNodeStatus.builder()
  292. ._id(this.nodeId)
  293. .nodeId(this.nodeId)
  294. .isConnect(false)
  295. .collectTime(collectTime)
  296. .build();
  297. }
  298. if (nodeLength < SIZE_HEAD + SIZE_STATUS_HDR) {
  299. // packet error
  300. return null;
  301. }
  302. String tscDateTime;
  303. int cycleElapsedTime;
  304. TsiCvimControl tscControlInfo = new TsiCvimControl();
  305. TsiCvimAbnormal tscAbnormalInfo = new TsiCvimAbnormal();
  306. int signalStatusInfoCount;
  307. int divFlag;
  308. long localTime;
  309. List<TsiCvimStatus> signalStatusInfos = new ArrayList<>();
  310. //this.opCode = this.nodeData[TsiCpuPacket.INDEX_OPCODE];
  311. //byte dataVer = this.nodeData[TsiCpuPacket.INDEX_VERSION];
  312. //int length = ByteUtils.getUnsignedShort(this.nodeData, TsiCpuPacket.INDEX_LENGTH);
  313. //int count = (int)(this.nodeData[TsiCpuPacket.INDEX_STATUS_HDR+3] & 0x7F);
  314. byte control = this.cvimData[SIZE_IPC_SIZE + INDEX_STATUS_HDR];
  315. tscControlInfo.inManualControl = ((control ) & 0x01) == 0x01; //수동;
  316. tscControlInfo.inFlashingControl = ((control >> 1) & 0x01) == 0x01; //점멸;
  317. tscControlInfo.inLightsOutControl = ((control >> 2) & 0x01) == 0x01; //소등
  318. tscControlInfo.inActuationControl = ((control >> 3) & 0x01) == 0x01; //감응;
  319. tscControlInfo.inTransitionControl = ((control >> 4) & 0x01) == 0x01; //전이;
  320. byte abnormal = this.cvimData[SIZE_IPC_SIZE + INDEX_STATUS_HDR + 1];
  321. tscAbnormalInfo.inSignalConflict = ((abnormal ) & 0x01) == 0x01; //모순상태;
  322. tscAbnormalInfo.inCenterComm = ((abnormal >> 1) & 0x01) == 0x01; //센터상태;
  323. tscAbnormalInfo.inScuComm = ((abnormal >> 2) & 0x01) == 0x01; //SCU 상태
  324. cycleElapsedTime = (int)(this.cvimData[SIZE_IPC_SIZE + INDEX_STATUS_HDR + 2] & 0xFF);
  325. byte stts = this.cvimData[SIZE_IPC_SIZE + INDEX_STATUS_HDR + 3];;
  326. signalStatusInfoCount = (int)(stts & 0x7F);
  327. //divFlag = (int)((stts >> 7) & 0x01);
  328. localTime = ByteUtils.getUnsignedInt(this.cvimData, SIZE_IPC_SIZE + INDEX_STATUS_HDR + 4);
  329. int ii = SIZE_IPC_SIZE + INDEX_STATUS_DATA;
  330. for (int idx = 0; idx < signalStatusInfoCount; idx++) {
  331. TsiCvimStatus status = new TsiCvimStatus();
  332. //int dirAdd = (buffer.get(ii)) & 0x0F; //연등지
  333. int lightsType = (int)((this.cvimData[ii ] >> 4) & 0x0F);
  334. int lightsStatus = (int)((this.cvimData[ii+1] ) & 0x07);
  335. int reliability = (int)((this.cvimData[ii+1] >> 7) & 0x01);
  336. boolean readyPedestrian = ((this.cvimData[ii+1] >> 6) & 0x01) == 0x01;
  337. boolean unProtected = ((this.cvimData[ii+1] >> 3) & 0x01) == 0x01;
  338. int totalSeconds = (int)(this.cvimData[ii+2] & 0xFF);
  339. int remainSeconds = (int)(this.cvimData[ii+3] & 0xFF);
  340. int directionCode = (int)(this.cvimData[ii+4] & 0xFF);
  341. status.setLightsType(eLightsType.getByValue(lightsType)); // 신호등정보 [직진,좌,보행]
  342. status.setLightsStatus(eLightsStatus.getByValue(lightsStatus)); //신호등상태
  343. status.setTimeReliability(eTimeReliability.getByValue(reliability)); //시간정보신뢰성
  344. status.setReadyPedestrianSignal(readyPedestrian); //보행자
  345. status.setUnProtectedSignal(unProtected); //비보호 상태
  346. status.setTotalSeconds(totalSeconds); //표출시간
  347. status.setRemainingSeconds(remainSeconds); //잔여시간
  348. status.setDirectionCode(directionCode); //방향코드
  349. signalStatusInfos.add(status);
  350. ii += SIZE_STATUS_DATA;
  351. }
  352. date = new Date(localTime * 1000L);
  353. sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  354. sdf.setTimeZone(java.util.TimeZone.getTimeZone("GMT+9"));
  355. tscDateTime = sdf.format(date);
  356. //log.error("Packet Received: NodeId: {}, {}", this.nodeId, TimeUtils.elapsedTimeStr(System.nanoTime()-nanoSeconds));
  357. return TcsNodeStatus.builder()
  358. ._id(this.nodeId)
  359. .nodeId(this.nodeId)
  360. .isConnect(true)
  361. .collectTime(collectTime)
  362. .tscDateTime(tscDateTime)
  363. .cycleElapsedTime(cycleElapsedTime)
  364. .tscControlInfo(tscControlInfo)
  365. .tscAbnormalInfo(tscAbnormalInfo)
  366. .signalStatusInfoCount(signalStatusInfoCount)
  367. .signalStatusInfos(signalStatusInfos)
  368. .build();
  369. }
  370. }