rev:更新

This commit is contained in:
2024-09-25 14:01:47 +08:00
parent 6288ce8347
commit 4155a2b685
40 changed files with 1853 additions and 140 deletions

View File

@@ -13,7 +13,8 @@ public enum DriverTypeEnum {
STANDARD_STORAGE(2, "standard_storage", "标准版-货架", "storage"),
PHOTOELECTRIC_DETECTION_DEVICE_DRIVER(3, "photoelectric_detection_station", "光电检测站点", "station"),
XIANGONG_AGV_DEVICE_DRIVER(4, "xg_agv", "仙工AGV", "agv"),
RGV_DEVICE_DRIVER(5, "rgv_station", "RGV", "rgv");
RGV_DEVICE_DRIVER(5, "rgv_station", "RGV", "rgv"),
ELEVATOR_DRIVER(6, "standard_elevator", "电梯", "elevator");
//驱动索引
private int index;
//驱动编码

View File

@@ -693,8 +693,8 @@ public class DeviceServiceImpl implements DeviceService, ApplicationAutoInitial
// String device_code = jo.getString("device_code");
// String device_name = jo.getString("device_name");
// Device device = appService.findDeviceByCode(device_code);
// if (device.getDeviceDriver() instanceof StandardOrdinarySiteDeviceDriver) {
// standardOrdinarySiteDeviceDriver = (StandardOrdinarySiteDeviceDriver) device.getDeviceDriver();
// if (device.getDeviceDriver() instanceof ElevatorDeviceDriver) {
// standardOrdinarySiteDeviceDriver = (ElevatorDeviceDriver) device.getDeviceDriver();
// int branchProtocol = standardOrdinarySiteDeviceDriver.getBranchProtocol();
// devicejo.put("device_code",device_code);
// devicejo.put("branchProtocol",branchProtocol);

View File

@@ -1,5 +1,6 @@
package org.nl.acs.device_driver.basedriver.agv.xg_agv;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import lombok.RequiredArgsConstructor;
@@ -11,8 +12,14 @@ import org.nl.acs.device_driver.driver.ExecutableDeviceDriver;
import org.nl.acs.instruction.service.InstructionService;
import org.nl.acs.monitor.DeviceStageMonitor;
import org.nl.acs.opc.Device;
import org.nl.acs.task.service.TaskService;
import org.nl.acs.task.service.dto.TaskDto;
import org.nl.modules.wql.util.SpringContextHolder;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
/**
* 仙工AGV
*/
@@ -26,6 +33,7 @@ public class XianGongAgvDeviceDriver extends AbstractOpcDeviceDriver implements
DeviceStageMonitor {
private final InstructionService instructionService = SpringContextHolder.getBean(InstructionService.class);
private final TaskService taskService = SpringContextHolder.getBean(TaskService.class);
/**
* 当前设备号
@@ -115,22 +123,30 @@ public class XianGongAgvDeviceDriver extends AbstractOpcDeviceDriver implements
@Override
public JSONObject getDeviceStatusName() {
DecimalFormat hisFormat = new DecimalFormat("########.###");
hisFormat.setRoundingMode(RoundingMode.DOWN);
JSONObject jo = new JSONObject();
jo.put("device_code", this.currentDeviceCode);
jo.put("device_name", this.currentDeviceCode);
jo.put("task_code", this.taskCode);
jo.put("battery_level", (this.battery_level * 100) + "%");
BigDecimal decimal = new BigDecimal(Double.toString(this.battery_level));
BigDecimal scale = decimal.setScale(2, RoundingMode.HALF_UP);
BigDecimal multiply = scale.multiply(BigDecimal.valueOf(100));
jo.put("battery_level", multiply + "%");
jo.put("angle", this.angle);
jo.put("time", this.time / 1000 / 1.0 / 3600);
jo.put("total_time", this.total_time / 1000 / 1.0 / 3600);
//jo.put("time", this.time / 1000 / 1.0 / 3600);
//jo.put("total_time", this.total_time / 1000 / 1.0 / 3600);
jo.put("today_odo", this.today_odo);
jo.put("odo", this.odo);
jo.put("x", this.x);
jo.put("y", this.y);
jo.put("status", this.statusName);
jo.put("status", this.status == 1 ? "工作中" : this.status == 2 ? "充电中" : this.status == 3 ? "故障" : this.status == 4 ? "休息中" : this.status == 5 ? "关机" : "未知状态");
//jo.put("status_name", this.statusName);
jo.put("todayTaskNum", this.todayTaskNum);
jo.put("monthTaskNum", this.monthTaskNum);
TaskDto taskDto = taskService.findByCodeFromCache(this.taskCode);
jo.put("start_loc", ObjectUtil.isEmpty(taskDto) ? "暂无" : taskDto.getStart_point_code());
jo.put("target_loc", ObjectUtil.isEmpty(taskDto) ? "暂无" : taskDto.getNext_point_code());
jo.put("message", this.message == null ? "运行正常" : "运行异常");
return jo;
}

View File

@@ -0,0 +1,49 @@
package org.nl.acs.device_driver.basedriver.elevator;
import org.nl.acs.device_driver.DeviceDriver;
import org.nl.acs.device_driver.DeviceDriverDefinition;
import org.nl.acs.opc.Device;
import org.nl.acs.opc.DeviceType;
import org.springframework.stereotype.Service;
import java.util.LinkedList;
import java.util.List;
/**
* 电梯
*/
@Service
public class ElevatorDefinition implements DeviceDriverDefinition {
@Override
public String getDriverCode() {
return "standard_elevator";
}
@Override
public String getDriverName() {
return "电梯";
}
@Override
public String getDriverDescription() {
return "电梯";
}
@Override
public DeviceDriver getDriverInstance(Device device) {
return (new ElevatorDeviceDriver()).setDevice(device).setDriverDefinition(this);
}
@Override
public Class<? extends DeviceDriver> getDeviceDriverType() {
return ElevatorDeviceDriver.class;
}
@Override
public List<DeviceType> getFitDeviceTypes() {
List<DeviceType> types = new LinkedList();
types.add(DeviceType.elevator);
return types;
}
}

View File

@@ -0,0 +1,21 @@
package org.nl.acs.device_driver.basedriver.elevator;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.nl.acs.device_driver.DeviceDriver;
import org.nl.acs.device_driver.RouteableDeviceDriver;
import org.nl.acs.device_driver.driver.AbstractDeviceDriver;
/**
* 电梯
*/
@Slf4j
@Getter
@Setter
@RequiredArgsConstructor
public class ElevatorDeviceDriver extends AbstractDeviceDriver implements DeviceDriver, RouteableDeviceDriver {
}

View File

@@ -8,20 +8,13 @@ import java.util.ArrayList;
import java.util.List;
public enum ItemProtocol implements DeviceDriverBaseReader.KeyProvider {
HEARTBEAT("heartbeat", "心跳", "DB1101.B1"),
MODE("mode", "工作模式", "DB1101.B2"),
STATUS("status", "工作状态", "DB1101.B3"),
ERROR("error", "报警信息", "DB1101.B4"),
ENERGY_LEVEL("energyLevel", "当前电量", "DB1101.D5"),
TASK_CODE("taskCode", "当前执行任务号", "DB1101.D6"),
START_DEVICE_CODE("startDeviceCode", "任务起点", "DB1101.S7"),
NEXT_DEVICE_CODE("nextDeviceCode", "任务终点", "DB1101.S8"),
VEHICLE_CODE("vehicleCode", "载具号", "DB1101.S9"),
X("x", "x坐标", "DB1101.D10"),
Y("y", "y坐标", "DB1101.D11"),
ACTION("action", "当前动作", "DB1101.B12"),
TODAY_TASK_NUM("todayTaskNum", "当天执行任务数", "DB1101.D13"),
ALL_TASK_NUM("allTaskNum", "历史执行任务数", "DB1101.D14");
HEARTBEAT("heartbeat", "心跳", "VB71"),
MODE("mode", "工作模式", "VB64"),
STATUS("status", "工作状态", "VB68"),
ERROR("error", "报警信息", "VB70"),
ENERGY_LEVEL("energyLevel", "当前电量", "VW60"),
CURRENT_POSITION("currentPosition", "当前位置", "VB14"),
TARGET_POSITION("targetPosition", "目标位置", "VB15");
private final String key;
private final String description;

View File

@@ -8,12 +8,11 @@ import lombok.extern.slf4j.Slf4j;
import org.nl.acs.device_driver.*;
import org.nl.acs.device_driver.driver.AbstractOpcDeviceDriver;
import org.nl.acs.device_driver.driver.ExecutableDeviceDriver;
import org.nl.acs.device_driver.sdk.ItemProtocol;
import org.nl.acs.device_driver.rgv.enums.PositionEnum;
import org.nl.acs.monitor.DeviceStageMonitor;
import org.nl.modules.lucene.service.LuceneExecuteLogService;
import org.nl.modules.lucene.service.dto.LuceneLogDto;
import org.nl.modules.wql.util.SpringContextHolder;
import org.springframework.util.ObjectUtils;
/**
* @author zhangjiangwei
@@ -59,62 +58,20 @@ public class RGVDeviceDriver extends AbstractOpcDeviceDriver implements
/**
* 当前电量
*/
private Double energyLevel = 0.0d;
private Double lastEnergyLevel = 0.0d;
/**
* 任务号
*/
private int taskCode = 0;
private int lastTaskCode = 0;
private int energyLevel = 0;
private int lastEnergyLevel = 0;
/**
* 起点
*/
private String startDeviceCode;
private String lastStartDeviceCode;
private int currentPosition;
private int lastCurrentPosition;
/**
* 终点
*/
private String nextDeviceCode;
private String lastNextDeviceCode;
/**
* 载具号
*/
private String vehicleCode;
private String lastVehicleCode;
/**
* x坐标
*/
private Double x;
private Double lastX;
/**
* y坐标
*/
private Double y;
private Double lastY;
/**
* 当前动作
*/
private int action = 0;
private int lastAction = 0;
/**
* 当天执行任务数
*/
private int todayTaskNum = 0;
private int lastTodayTaskNum = 0;
/**
* 历史执行任务数
*/
private int allTaskNum = 0;
private int lastAllTaskNum = 0;
private int targetPosition;
private int lastTargetPosition;
/**
* 当前设备号
@@ -175,17 +132,11 @@ public class RGVDeviceDriver extends AbstractOpcDeviceDriver implements
jo.put("mode", this.mode == 1 ? "手动" : this.mode == 2 ? "自动" : "未知");
jo.put("status", this.error > 0 ? "故障" : this.status == 0 ? "休息中" : this.status == 1 ? "工作中" : this.status == 2 ? "充电中" : "未知状态");
jo.put("error", this.error);
jo.put("battery_level", (this.energyLevel * 100) + "%");
jo.put("task_code", this.taskCode);
jo.put("current_loc", ObjectUtils.isEmpty(this.startDeviceCode) ? "0" : this.startDeviceCode);
jo.put("target_loc", ObjectUtils.isEmpty(this.nextDeviceCode) ? "0" : this.nextDeviceCode);
jo.put("vehicleCode", this.vehicleCode);
jo.put("x", this.x);
jo.put("y", this.y);
jo.put("action", this.action);
jo.put("todayTaskNum", this.todayTaskNum);
jo.put("allTaskNum", this.allTaskNum);
jo.put("message", this.message == null ? "运行正常" : "运行异常");
//1急停 2避障 0无报警
jo.put("battery_level", this.energyLevel + "%");
jo.put("current_loc", PositionEnum.getLabel(this.currentPosition));
jo.put("target_loc", PositionEnum.getLabel(this.targetPosition));
jo.put("message", this.error == 0 ? "正常" : this.error == 1 ? "急停" : this.error == 2 ? "避障" : "未知报警信息");
return jo;
}

View File

@@ -0,0 +1,38 @@
package org.nl.acs.device_driver.rgv.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @Description TODO
* @Author Gengby
* @Date 2024/4/25
*/
@Getter
@AllArgsConstructor
public enum PositionEnum {
P_1(1, "充电位"),
P_11(11, "工位1"),
P_21(21, "工位2"),
P_31(31, "工位3"),
P_41(41, "工位4"),
P_51(51, "工位5"),
P_61(61, "工位6"),
P_71(71, "充电位"),
P_81(81, "工位7"),
P_91(91, "工位8"),
P_101(101, "工位9"),
P_111(111, "工位10");
private final Integer value;
private final String label;
public static String getLabel(Integer value) {
for (PositionEnum strategy : PositionEnum.values()) {
if (strategy.getValue().equals(value)) {
return strategy.getLabel();
}
}
return "工位";
}
}

View File

@@ -37,10 +37,7 @@ import org.slf4j.MDC;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
@Service
@RequiredArgsConstructor
@@ -83,8 +80,8 @@ public class WmsToAcsServiceImpl implements WmsToAcsService {
// 双工RGV任务 后工位任务
String start_point_code2 = task.getStart_device_code2();
String next_point_code2 = task.getNext_device_code2();
String start_device_code2 = task.getStart_device_code2();
String next_device_code2 = task.getNext_device_code2();
String start_device_code2 = "";
String next_device_code2 = "";
String start_device_code = "";
String next_device_code = "";
String start_parent_code = "";
@@ -109,6 +106,17 @@ public class WmsToAcsServiceImpl implements WmsToAcsService {
next_parent_code = next_device_json.get("parent_storage_code") == null ? next_point_code : (String) next_device_json.get("parent_storage_code");
}
JSONObject start_device_json2 = WQLObject.getWQLObject("acs_storage_cell").query("parent_storage_code ='" + start_point_code2 + "'").uniqueResult(0);
if (!ObjectUtil.isEmpty(start_device_json2)) {
start_point_code2 = (String) start_device_json2.get("parent_storage_code") == null ? start_device_code2 : (String) start_device_json2.get("storage_code");
}
JSONObject next_device_json2 = WQLObject.getWQLObject("acs_storage_cell").query("parent_storage_code ='" + next_point_code2 + "'").uniqueResult(0);
if (!ObjectUtil.isEmpty(next_device_json2)) {
next_point_code2 = (String) next_device_json2.get("parent_storage_code") == null ? next_device_code2 : (String) next_device_json2.get("storage_code");
}
if (start_point_code.indexOf("-") > 0) {
String str[] = start_point_code.split("-");
start_device_code = str[0];
@@ -123,6 +131,20 @@ public class WmsToAcsServiceImpl implements WmsToAcsService {
next_device_code = next_point_code;
}
if (StrUtil.isNotEmpty(start_point_code2) && start_point_code2.indexOf("-") > 0) {
String str[] = start_point_code2.split("-");
start_device_code2 = str[0];
} else {
start_device_code2 = start_point_code2;
}
if (StrUtil.isNotEmpty(next_point_code2) && next_point_code2.indexOf("-") > 0) {
String str[] = next_point_code2.split("-");
next_device_code2 = str[0];
} else {
next_device_code2 = next_point_code2;
}
if (StrUtil.isEmpty(route_plan_code)) {
route_plan_code = "normal";
}
@@ -193,8 +215,8 @@ public class WmsToAcsServiceImpl implements WmsToAcsService {
jo.put("next_parent_code", next_parent_code);
jo.put("start_device_code", start_device_code);
jo.put("next_device_code", next_device_code);
jo.put("start_point_code2", start_device_code2);
jo.put("next_point_code2", next_device_code2);
jo.put("start_point_code2", start_point_code2);
jo.put("next_point_code2", next_point_code2);
jo.put("start_device_code2", start_device_code2);
jo.put("next_device_code2", next_device_code2);
jo.put("priority", priority);
@@ -312,7 +334,6 @@ public class WmsToAcsServiceImpl implements WmsToAcsService {
}
}
@SneakyThrows
@Override
public JSONObject agvInfo(JSONObject req) {
JSONObject resp = new JSONObject();
@@ -320,10 +341,18 @@ public class WmsToAcsServiceImpl implements WmsToAcsService {
List<JSONObject> agvInfos = new ArrayList<>();
for (Device agv : agvs) {
if (agv != null && agv.getDeviceDriver() instanceof DeviceStageMonitor) {
DeviceStageMonitor deviceStageMonitor = (DeviceStageMonitor) agv.getDeviceDriver();
agvInfos.add(deviceStageMonitor.getDeviceStatusName());
try {
log.info("查询出AGV信息不为空");
DeviceStageMonitor deviceStageMonitor = (DeviceStageMonitor) agv.getDeviceDriver();
agvInfos.add(deviceStageMonitor.getDeviceStatusName());
log.info("添加{}", deviceStageMonitor.getDeviceStatusName());
}catch (Exception e){
log.error("异常:{}",e.getMessage());
log.error("异常:{}", Arrays.toString(e.getStackTrace()));
}
}
}
log.info("响应结果:{}", agvInfos);
resp.put("status", 0);
resp.put("message", "查询成功");
resp.put("data", agvInfos);
@@ -354,9 +383,9 @@ public class WmsToAcsServiceImpl implements WmsToAcsService {
Map<String, String> map = new HashMap<>();
map.put("flag", "1");
JSONArray data = WQL.getWO("EXT_QUERY001").addParamMap(map).process().getResultJSONArray(0);
resp.put("status",0);
resp.put("message","查询成功");
resp.put("data",data);
resp.put("status", 0);
resp.put("message", "查询成功");
resp.put("data", data);
return resp;
}
}

View File

@@ -0,0 +1,51 @@
package org.nl.acs.ext.xg.rest;
import cn.dev33.satoken.annotation.SaIgnore;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.nl.acs.ext.log.OthersToInterfaceLog;
import org.nl.acs.ext.xg.service.XgToAcsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Description TODO
* @Author Gengby
* @Date 2024/8/8
*/
@RestController
@RequiredArgsConstructor
@Api(tags = "仙工调用接口")
@RequestMapping("/api/elevator")
@Slf4j
@SaIgnore
public class XgToAcsController {
@Autowired
private XgToAcsService xgToAcsService;
@PostMapping("/call")
@OthersToInterfaceLog("AGV->ACS")
public ResponseEntity<Object> call(@RequestBody JSONObject param) {
return new ResponseEntity<>(xgToAcsService.call(param), HttpStatus.OK);
}
@PostMapping("/status")
@OthersToInterfaceLog("AGV->ACS")
public ResponseEntity<Object> status(@RequestBody JSONObject param) {
return new ResponseEntity<>(xgToAcsService.status(param), HttpStatus.OK);
}
@PostMapping("/setDoor")
@OthersToInterfaceLog("AGV->ACS")
public ResponseEntity<Object> setDoor(@RequestBody JSONObject param) {
return new ResponseEntity<>(xgToAcsService.setDoor(param), HttpStatus.OK);
}
}

View File

@@ -0,0 +1,37 @@
package org.nl.acs.ext.xg.service;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
/**
* @Description TODO
* @Author Gengby
* @Date 2024/8/8
*/
public interface XgToAcsService {
/**
* 呼叫楼层
*
* @param param
* @return
*/
JSONObject call(JSONObject param);
/**
* 查看电梯状态
*
* @param param
* @return
*/
JSONArray status(JSONObject param);
/**
* 开关门
*
* @param param
* @return
*/
JSONObject setDoor(JSONObject param);
}

View File

@@ -0,0 +1,295 @@
package org.nl.acs.ext.xg.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.nl.acs.ext.xg.service.XgToAcsService;
import org.nl.acs.opc.Device;
import org.nl.acs.opc.DeviceAppService;
import org.nl.acs.opc.DeviceType;
import org.nl.modules.common.exception.BadRequestException;
import org.nl.start.auto.run.ElevatorSocketConnectionAutoRun;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @Description TODO
* @Author Gengby
* @Date 2024/8/8
*/
@Service
@RequiredArgsConstructor
@Slf4j
public class XgToAcsServiceImpl implements XgToAcsService {
@Autowired
private DeviceAppService deviceAppService;
@Override
public JSONObject call(JSONObject param) {
//电梯编号
String elevatorCode = param.getString("elevatorCode");
if (StrUtil.isEmpty(elevatorCode)) {
JSONObject resp = new JSONObject();
resp.put("code", 400);
resp.put("message", "电梯编号不能为空!");
return resp;
}
//目标楼层
Integer floor = param.getInteger("floor");
if (floor == null) {
JSONObject resp = new JSONObject();
resp.put("code", 400);
resp.put("message", "目标楼层不能为空!");
return resp;
}
String doorStatusMsg = "00110000000601039CAC0001";
int[] doorStatusRec = ElevatorSocketConnectionAutoRun.write("查询电梯门状态", doorStatusMsg);
boolean doorStatus = determineDoorStatus(doorStatusRec);
if (doorStatus) {
String currentFloorHexMsg = "00050000000601039C410001";
int[] currentFloorRec = ElevatorSocketConnectionAutoRun.write("读取楼层信息", currentFloorHexMsg);
int currentFloor = determineFloor(currentFloorRec);
if (currentFloor == floor) {
String openDoorHexMsg = "002B0000000601069C7A0001";
ElevatorSocketConnectionAutoRun.write("开门", openDoorHexMsg);
JSONObject resp = new JSONObject();
resp.put("code", 400);
resp.put("message", "电梯已开门,已继续下发开门信号");
return resp;
} else {
JSONObject resp = new JSONObject();
resp.put("code", 400);
resp.put("message", "电梯门已打开,无法呼叫楼层!");
return resp;
}
}
//下发目标楼层
String callFloorHexMsg = "";
if (floor == 1) {
callFloorHexMsg = "001A0000000601069C580001";
} else if (floor == 2) {
callFloorHexMsg = "00170000000601069C580002";
} else if (floor == 3) {
callFloorHexMsg = "00200000000601069C580004";
} else {
JSONObject resp = new JSONObject();
resp.put("code", 400);
resp.put("message", "呼叫楼层号错误!");
return resp;
}
int[] callFloorRec = ElevatorSocketConnectionAutoRun.write("呼叫楼层", callFloorHexMsg);
int callFloorRecInt = determineCallFloorRec(callFloorRec);
if (callFloorRecInt != floor) {
JSONObject resp = new JSONObject();
resp.put("code", 400);
resp.put("message", "呼叫楼层响应报文信息楼层与下发楼层信息不一致!");
return resp;
}
String currentFloorHexMsg = "00050000000601039C410001";
int[] currentFloorRec = ElevatorSocketConnectionAutoRun.write("读取楼层信息", currentFloorHexMsg);
int currentFloor = determineFloor(currentFloorRec);
if (currentFloor != floor) {
JSONObject resp = new JSONObject();
resp.put("code", 400);
resp.put("message", "当前电梯所在楼层与呼叫楼层不一致!");
return resp;
}
// String doorStatusMsg = "00110000000601039CAC0001";
doorStatusRec = ElevatorSocketConnectionAutoRun.write("查询电梯门状态", doorStatusMsg);
doorStatus = determineDoorStatus(doorStatusRec);
if (!doorStatus) {
String openDoorHexMsg = "002B0000000601069C7A0001";
ElevatorSocketConnectionAutoRun.write("开门", openDoorHexMsg);
JSONObject resp = new JSONObject();
resp.put("code", 400);
resp.put("message", "当前电梯门状态为关门中状态!");
return resp;
}
String openDoorHexMsg = "002B0000000601069C7A0001";
ElevatorSocketConnectionAutoRun.write("开门", openDoorHexMsg);
JSONObject resp = new JSONObject();
resp.put("code", 200);
resp.put("message", "ok");
return resp;
}
@Override
public JSONArray status(JSONObject param) {
JSONArray array = new JSONArray();
String elevatorCode = param.getString("elevatorCode");
if (StrUtil.isEmpty(elevatorCode)) {
JSONObject resp = new JSONObject();
resp.put("code", 400);
resp.put("message", "电梯编号不能为空");
array.add(resp);
return array;
}
if (!StrUtil.isEmpty(elevatorCode)) {
String doorStatusMsg = "00110000000601039CAC0001";
int[] doorStatusRec = ElevatorSocketConnectionAutoRun.write("查询电梯门状态", doorStatusMsg);
boolean doorStatus = determineDoorStatus(doorStatusRec);
String currentFloorHexMsg = "00050000000601039C410001";
int[] currentFloorRec = ElevatorSocketConnectionAutoRun.write("读取楼层信息", currentFloorHexMsg);
int currentFloor = determineFloor(currentFloorRec);
JSONObject resp = new JSONObject();
resp.put("elevatorCode", elevatorCode);
resp.put("floor", currentFloor);
resp.put("status", doorStatus ? 1 : 0);
resp.put("move", doorStatus ? 1 : 0);
array.add(resp);
return array;
}
List<Device> devices = deviceAppService.findDeviceByType(DeviceType.elevator);
if (CollectionUtil.isEmpty(devices)) {
return array;
}
for (Device device : devices) {
// String doorStatusMsg = "00110000000601039CAC0001";
// ElevatorSocketConnectionAutoRun.write(doorStatusMsg);
// boolean doorStatus = elevatorSocketConnectionAutoRun.isCurrentFloorStatus();
// String currentFloorHexMsg = "00050000000601039C410001";
// ElevatorSocketConnectionAutoRun.write(currentFloorHexMsg);
// int currentFloor = elevatorSocketConnectionAutoRun.getCurrentFloor();
// JSONObject resp = new JSONObject();
// resp.put("elevatorCode", elevatorCode);
// resp.put("floor", currentFloor);
// resp.put("status", doorStatus ? 1 : 0);
// resp.put("move", doorStatus ? 0 : 1);
// array.add(resp);
}
return array;
}
@Override
public JSONObject setDoor(JSONObject param) {
//电梯编号
String elevatorCode = param.getString("elevatorCode");
if (StrUtil.isEmpty(elevatorCode)) {
JSONObject resp = new JSONObject();
resp.put("code", 400);
resp.put("message", "电梯编号不能为空!");
return resp;
}
Integer status = param.getInteger("status");
if (status == null) {
JSONObject resp = new JSONObject();
resp.put("code", 400);
resp.put("message", "开关门状态不能为空!");
return resp;
}
if (status == 1) {
//开门
String openDoorHexMsg = "002B0000000601069C7A0001";
int[] openDoor = ElevatorSocketConnectionAutoRun.write("开门", openDoorHexMsg);
boolean flag = parseOpenResponse(openDoor);
if (!flag) {
JSONObject resp = new JSONObject();
resp.put("code", 400);
resp.put("message", "下发开门状态响应报文有误!");
return resp;
}
} else if (status == 0) {
//关门
String closeDoorHexMsg = "002D0000000601069C7A0008";
int[] closeDoor = ElevatorSocketConnectionAutoRun.write("关门", closeDoorHexMsg);
boolean flag = parseCloseResponse(closeDoor);
if (!flag) {
JSONObject resp = new JSONObject();
resp.put("code", 400);
resp.put("message", "下发关门状态响应报文有误!");
return resp;
}
}
JSONObject resp = new JSONObject();
resp.put("code", 200);
resp.put("message", "ok");
return resp;
}
public static boolean parseOpenResponse(int[] binaryArray) {
int keyByte = binaryArray[1];
if (keyByte == 0x2B) {
return true;
}
return false;
}
public static boolean parseCloseResponse(int[] binaryArray) {
int keyByte = binaryArray[1];
if (keyByte == 0x2D) {
return true;
}
return false;
}
/**
* 解析当前楼层
*
* @param binaryArray
* @return
*/
public static int determineFloor(int[] binaryArray) {
if (binaryArray.length < 8) {
throw new BadRequestException("结果有误!");
}
int floorByte = binaryArray[9];
if (floorByte == 0x31) {
return 1;
} else if (floorByte == 0x32) {
return 2;
} else if (floorByte == 0x33) {
return 3;
}
return -1;
}
/**
* 解析开门关门状态
*
* @param binaryArray
* @return
*/
public static boolean determineDoorStatus(int[] binaryArray) {
if (binaryArray.length < 8) {
throw new IllegalArgumentException("结果有误!");
}
int lastByte = binaryArray[binaryArray.length - 1];
if (lastByte == 0x10) {
return true;
} else if (lastByte == 0x00) {
return false;
}
return false;
}
/**
* 解析呼叫楼层
*
* @param binaryArray
* @return
*/
public static int determineCallFloorRec(int[] binaryArray) {
if (binaryArray.length < 8) {
throw new IllegalArgumentException("结果有误!");
}
int floorByte = binaryArray[1];
if (floorByte == 0x1A) {
return 1;
} else if (floorByte == 0x17) {
return 2;
} else if (floorByte == 0x20) {
return 3;
}
return -1;
}
}

View File

@@ -154,6 +154,37 @@ public class InstructionDto implements Serializable {
*/
private String to_z;
/**
* 排
*/
private String from_x2;
/**
* 列
*/
private String from_y2;
/**
* 层
*/
private String from_z2;
/**
* 排
*/
private String to_x2;
/**
* 列
*/
private String to_y2;
/**
* 层
*/
private String to_z2;
/**
* 最后一条指令标识
*/

View File

@@ -618,18 +618,24 @@ public class InstructionServiceImpl implements InstructionService, ApplicationAu
String next_point_code = inst.getNext_point_code();
String start_device_code = "";
String next_device_code = "";
String start_point_code2 = inst.getStart_point_code2();
String next_point_code2 = inst.getNext_point_code2();
String start_device_code2 = "";
String next_device_code2 = "";
if (StrUtil.contains(start_point_code, ".")) {
String[] point = start_point_code.split("\\.");
start_device_code = point[0];
} else {
start_device_code = start_point_code;
}
if (StrUtil.contains(next_point_code, ".")) {
String[] point = next_point_code.split("\\.");
next_device_code = point[0];
} else {
next_device_code = next_point_code;
}
if (StrUtil.contains(start_point_code, "-") && StrUtil.count(start_point_code, "-") == 2) {
String[] start_point = start_point_code.split("-");
inst.setFrom_x(start_point[0]);
@@ -668,6 +674,59 @@ public class InstructionServiceImpl implements InstructionService, ApplicationAu
inst.setNext_device_code(next_device_code);
}
}
if (StrUtil.isNotEmpty(start_point_code2) && StrUtil.isNotEmpty(next_point_code2)){
if (StrUtil.contains(start_point_code2, ".")) {
String[] point = start_point_code2.split("\\.");
start_device_code2 = point[0];
} else {
start_device_code2 = start_point_code2;
}
if (StrUtil.contains(next_point_code2, ".")) {
String[] point = next_point_code2.split("\\.");
next_device_code2 = point[0];
} else {
next_device_code2 = next_point_code2;
}
if (StrUtil.contains(start_point_code2, "-") && StrUtil.count(start_point_code2, "-") == 2) {
String[] start_point2 = start_point_code2.split("-");
inst.setFrom_x2(start_point2[0]);
inst.setStart_device_code2(start_point2[0]);
inst.setFrom_y2(start_point2[1]);
inst.setFrom_z2(start_point2[2]);
} else {
String start_device2 = deviceAppService.findDeviceByCode(start_device_code2).getDeviceDriverDefinition().getFitDeviceTypes().get(0).name();
if (StrUtil.equals("storage", start_device2)) {
String[] start_point2 = start_point_code2.split("-");
inst.setFrom_x2(start_point2[0]);
inst.setStart_device_code2(start_point2[0]);
inst.setFrom_y2(start_point2[1]);
inst.setFrom_z2(start_point2[2]);
} else {
inst.setStart_device_code2(start_device_code2);
}
}
if (StrUtil.contains(next_point_code2, "-") && StrUtil.count(next_point_code2, "-") == 2) {
String[] next_point2 = next_point_code2.split("-");
inst.setTo_x2(next_point2[0]);
inst.setNext_device_code2(next_point2[0]);
inst.setTo_y2(next_point2[1]);
inst.setTo_z2(next_point2[2]);
} else {
String next_device2 = deviceAppService.findDeviceByCode(next_device_code2).getDeviceDriverDefinition().getFitDeviceTypes().get(0).name();
if (StrUtil.equals("storage", next_device2)) {
String[] next_point2 = start_point_code2.split("-");
inst.setTo_x2(next_point2[0]);
inst.setNext_device_code2(next_point2[0]);
inst.setTo_y2(next_point2[1]);
inst.setTo_z2(next_point2[2]);
} else {
inst.setNext_device_code2(next_device_code2);
}
}
}
return inst;
}

View File

@@ -17,7 +17,8 @@ public enum DeviceType {
autodoor("自动门", 14),
shadow("影子设备", 20),
other("其他设备", 14),
safetydoor("安全门",17);
safetydoor("安全门", 17),
elevator("电梯", 21);
private String description;
private int order;

View File

@@ -0,0 +1,162 @@
package org.nl.acs.socket.elevator;
import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.nl.modules.common.exception.BadRequestException;
import java.io.*;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.Arrays;
/**
* @Description TODO
* @Author Gengby
* @Date 2024/8/8
*/
@Slf4j
public class ElevatorSocketUtil {
//private static Socket socket;
//private static DataOutputStream outToServer;
//private static BufferedReader inFromServer;
//private static String ipAddress = "192.168.8.236";
//private static int portNumber = 502;
public static synchronized boolean startConnection(String ip, int port) {
// try {
// ipAddress = ip;
// portNumber = port;
// Socket socket = new Socket(ip, port);
// DataOutputStream outToServer = new DataOutputStream(socket.getOutputStream());
// BufferedReader inFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// socket.setSoTimeout(10000);
// return true;
// } catch (IOException e) {
// e.printStackTrace();
// return false;
// }
return false;
}
private static synchronized boolean ensureConnection(String ip, int port) {
// if (socket == null || socket.isClosed() || !socket.isConnected()) {
// return startConnection(ip, port);
// }
// return true;
return false;
}
public static synchronized int[] sendMessageAndGetResponse(String ip, int port, String hexMessage) {
Socket socket = null;
DataOutputStream outToServer = null;
BufferedReader inFromServer = null;
String message = null;
try {
log.info("{}:{},开始连接; 下发报文:{}", ip, port, hexMessage);
socket = new Socket(ip, port);
outToServer = new DataOutputStream(socket.getOutputStream());
inFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
socket.setSoTimeout(5000);
//sendMessage(outToServer, hexMessage);
byte[] messageBytes = hexStringToByteArray(hexMessage);
outToServer.write(messageBytes);
//String message = receiveMessage(socket);
try (InputStream inputStream = socket.getInputStream();
ByteArrayOutputStream buffer = new ByteArrayOutputStream()) {
byte[] data = new byte[1024];
int nRead;
while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
if (nRead < 1024) {
break;
}
}
buffer.flush();
message = byteArrayToHexString(buffer.toByteArray());
log.info("{}:{},开始连接; 读取报文:{}", ip, port, message);
}
if (ObjectUtil.isEmpty(message)) {
return new int[]{-1};
}
return binary(message);
} catch (IOException e) {
log.error("{}:{},连接失败; 失败原因:{}", ip, port, e.getMessage());
log.error("{}:{},连接失败; 堆栈信息:{}", ip, port, Arrays.toString(e.getStackTrace()));
e.printStackTrace();
throw new BadRequestException(e.getMessage());
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException ex) {
log.error("{}:{},连接失败; 失败原因:{}", ip, port, ex.getMessage());
log.error("{}:{},连接失败; 堆栈信息:{}", ip, port, Arrays.toString(ex.getStackTrace()));
ex.printStackTrace();
}
}
}
}
private static void sendMessage(DataOutputStream out, String hexMessage) throws IOException {
byte[] messageBytes = hexStringToByteArray(hexMessage);
out.write(messageBytes);
}
private static String receiveMessage(Socket socket) throws IOException {
try (InputStream inputStream = socket.getInputStream();
ByteArrayOutputStream buffer = new ByteArrayOutputStream()) {
byte[] data = new byte[1024];
int nRead;
while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
if (nRead < 1024) {
break;
}
}
buffer.flush();
return byteArrayToHexString(buffer.toByteArray());
} catch (SocketTimeoutException e) {
e.printStackTrace();
return null;
}
}
private static byte[] hexStringToByteArray(String s) {
int length = s.length();
byte[] data = new byte[length / 2];
for (int i = 0; i < length; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i + 1), 16));
}
return data;
}
private static String byteArrayToHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02X", b));
}
return sb.toString();
}
public static int[] binary(String hexString) {
hexString = hexString.replaceAll(" ", "");
int[] intArray = new int[hexString.length() / 2];
for (int i = 0; i < hexString.length(); i += 2) {
String byteString = hexString.substring(i, i + 2);
intArray[i / 2] = Integer.parseInt(byteString, 16);
}
return intArray;
}
public static void reverseArray(int[] array) {
int temp;
int n = array.length;
for (int i = 0; i < n / 2; i++) {
temp = array[i];
array[i] = array[n - i - 1];
array[n - i - 1] = temp;
}
}
}

View File

@@ -139,6 +139,36 @@ public class TaskDto implements Serializable {
*/
private String to_z;
/**
* 排
*/
private String from_x2;
/**
* 列
*/
private String from_y2;
/**
* 层
*/
private String from_z2;
/**
* 排
*/
private String to_x2;
/**
* 列
*/
private String to_y2;
/**
* 层
*/
private String to_z2;
/**
* 路由方案名称
*/

View File

@@ -526,6 +526,14 @@ public class TaskServiceImpl implements TaskService, ApplicationAutoInitial {
String from_z = null;
String to_y = null;
String to_z = null;
String start_point_code2 = task.getStart_point_code2();
String next_point_code2 = task.getNext_point_code2();
String from_y2 = null;
String from_z2 = null;
String to_y2 = null;
String to_z2 = null;
if (StrUtil.contains(start_point_code, "-") && StrUtil.count(start_point_code, "-") == 2) {
String[] start_point = start_point_code.split("-");
task.setFrom_x(start_point[0]);
@@ -577,6 +585,60 @@ public class TaskServiceImpl implements TaskService, ApplicationAutoInitial {
}
}
if (StrUtil.isNotEmpty(start_point_code2)){
if (StrUtil.contains(start_point_code2, "-") && StrUtil.count(start_point_code2, "-") == 2) {
String[] start_point2 = start_point_code2.split("-");
task.setFrom_x2(start_point2[0]);
task.setStart_device_code2(start_point2[0]);
if (Integer.parseInt(start_point2[1]) < 10 && start_point2[1].length() == 1) {
from_y2 = "0" + start_point2[1];
task.setFrom_y2(from_y2);
} else {
from_y2 = start_point2[1];
task.setFrom_y2(from_y2);
}
if (Integer.parseInt(start_point2[2]) < 10 && start_point2[2].length() == 1) {
from_z2 = "0" + start_point2[2];
task.setFrom_z2(from_z2);
} else {
from_z2 = start_point2[2];
}
task.setStart_point_code2(task.getStart_device_code2() + "-" + from_y2 + "-" + from_z2);
task.setStart_device_code2(task.getStart_device_code2());
} else {
String start_device2 = deviceAppService.findDeviceByCode(start_point_code2).getDeviceDriverDefinition().getFitDeviceTypes().get(0).name();
//如果point_device为货架则不包含列层信息需要重新拼接
if (StrUtil.equals("storage", start_device2)) {
if (StrUtil.isEmpty(task.getFrom_x2())) {
throw new BadRequestException("货位信息起点需要包含列信息");
}
if (StrUtil.isEmpty(task.getFrom_y2())) {
throw new BadRequestException("货位信息起点需要包含层信息");
}
if (Integer.parseInt(task.getFrom_y2()) < 10 && task.getFrom_y2().length() == 1) {
from_y2 = "0" + task.getFrom_y2();
task.setFrom_y2(from_y2);
} else {
from_y2 = task.getFrom_y2();
}
if (Integer.parseInt(task.getFrom_z2()) < 10 && task.getFrom_z2().length() == 1) {
from_z2 = "0" + task.getFrom_z2();
task.setFrom_z2(from_z2);
} else {
from_z2 = task.getFrom_z2();
}
task.setFrom_x2(start_point_code);
task.setStart_point_code2(start_point_code2 + "-" + from_y2 + "-" + from_z2);
task.setStart_device_code2(start_point_code2);
} else {
task.setStart_point_code2(start_point_code2);
task.setStart_device_code2(start_point_code2);
}
}
}
if (StrUtil.contains(next_point_code, "-") && StrUtil.count(next_point_code, "-") == 2) {
String[] next_point = next_point_code.split("-");
task.setNext_device_code(next_point[0]);
@@ -629,6 +691,62 @@ public class TaskServiceImpl implements TaskService, ApplicationAutoInitial {
}
}
if (StrUtil.isNotEmpty(task.getNext_point_code2())){
if (StrUtil.contains(next_point_code2, "-") && StrUtil.count(next_point_code2, "-") == 2) {
String[] next_point2 = next_point_code2.split("-");
task.setNext_device_code2(next_point2[0]);
task.setTo_x2(next_point2[0]);
if (Integer.parseInt(next_point2[1]) < 10 && next_point2[1].length() == 1) {
to_y2 = "0" + next_point2[1];
task.setTo_y2(to_y2);
} else {
to_y2 = next_point2[1];
task.setTo_y2(to_y2);
}
if (Integer.parseInt(next_point2[2]) < 10 && next_point2[2].length() == 1) {
to_z2 = "0" + next_point2[2];
task.setTo_z2(to_z2);
} else {
to_z2 = next_point2[2];
task.setTo_z2(to_z2);
}
task.setNext_point_code2(task.getNext_device_code2() + "-" + to_y2 + "-" + to_z2);
task.setNext_device_code2(task.getNext_device_code2());
} else {
String next_device2 = deviceAppService.findDeviceByCode(next_point_code2).getDeviceDriverDefinition().getFitDeviceTypes().get(0).name();
if (StrUtil.equals("storage", next_device2)) {
if (StrUtil.isEmpty(task.getTo_x2())) {
throw new BadRequestException("货位信息终点需要包含列信息");
}
if (StrUtil.isEmpty(task.getTo_y2())) {
throw new BadRequestException("货位信息终点需要包含层信息");
}
if (Integer.parseInt(task.getTo_y2()) < 10 && task.getTo_y2().length() == 1) {
to_y2 = "0" + task.getTo_y2();
task.setTo_y2(to_y2);
} else {
to_y2 = task.getTo_y2();
}
if (Integer.parseInt(task.getTo_z2()) < 10 && task.getTo_z2().length() == 1) {
to_z2 = "0" + task.getTo_z2();
task.setTo_z2(to_z2);
} else {
to_z2 = task.getTo_z2();
}
task.setTo_x2(next_point_code2);
task.setNext_point_code2(next_point_code2 + "-" + to_y2 + "-" + to_z2);
task.setNext_device_code2(next_point_code2);
} else {
task.setNext_point_code2(next_point_code2);
task.setNext_device_code2(next_point_code2);
}
}
}
return task;
}

View File

@@ -46,6 +46,8 @@ public class AutoCreateInst {
String priority = acsTask.getPriority();
String start_point_code = acsTask.getStart_point_code();
String start_device_code = acsTask.getStart_device_code();
String start_point_code2 = acsTask.getStart_point_code2();
String start_device_code2 = acsTask.getStart_device_code2();
String route_plan_code = acsTask.getRoute_plan_code();
String vehicleType = acsTask.getVehicle_type();
//是否复合任务 =0非复合任务
@@ -53,6 +55,8 @@ public class AutoCreateInst {
String compound_task_data = null;
String next_point_code = acsTask.getNext_point_code();
String next_device_code = acsTask.getNext_device_code();
String next_point_code2 = acsTask.getNext_point_code2();
String next_device_code2 = acsTask.getNext_device_code2();
if (StrUtil.isEmpty(start_device_code)) {
log.info("任务 [" + taskcode + "] 起点设备为空,无法生成指令。");
acsTask.setRemark("任务 [" + taskcode + "] 起点设备为空,无法生成指令。");
@@ -151,6 +155,10 @@ public class AutoCreateInst {
instdto.setNext_device_code(next_device_code);
instdto.setStart_point_code(start_point_code);
instdto.setNext_point_code(next_point_code);
instdto.setStart_device_code2(start_device_code2);
instdto.setStart_point_code2(start_point_code2);
instdto.setNext_device_code2(next_device_code2);
instdto.setNext_point_code2(next_point_code2);
instdto.setCompound_inst_data(compound_task_data);
instdto.setPriority(priority);
instdto.setInstruction_status("0");

View File

@@ -0,0 +1,30 @@
package org.nl.modules.quartz.task;
import lombok.extern.slf4j.Slf4j;
import org.nl.acs.auto.run.AutoRunService;
import org.nl.modules.system.service.ParamService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 电梯自动重连
*/
@Slf4j
@Component
public class ElevatorAutoReconnection {
@Autowired
ParamService paramService;
@Autowired
AutoRunService autoRunService;
public void run(String threadCode) throws Exception {
String[] threadCodes = threadCode.split(",");
for (String code : threadCodes) {
if (!autoRunService.getThreadByCode(code).isAlive()) {
autoRunService.startThread(code);
}
}
}
}

View File

@@ -72,6 +72,7 @@ public class QueryXZAgvDeviceStatus {
}
DecimalFormat hisFormat = new DecimalFormat("########.###");
hisFormat.setRoundingMode(RoundingMode.DOWN);
//x坐标
Double x = rbk_report.getDouble("x");
//y坐标
@@ -102,7 +103,7 @@ public class QueryXZAgvDeviceStatus {
if (device != null && device.getDeviceDriver() instanceof XianGongAgvDeviceDriver) {
XianGongAgvDeviceDriver xgAGV = (XianGongAgvDeviceDriver) device.getDeviceDriver();
xgAGV.setTaskCode(taskCode);
xgAGV.setBattery_level(battery_level);
xgAGV.setBattery_level(Double.valueOf(hisFormat.format(battery_level)));
xgAGV.setAngle(angle);
xgAGV.setTime(time);
xgAGV.setTotal_time(total_time);

View File

@@ -0,0 +1,156 @@
package org.nl.start.auto.run;
import cn.hutool.core.util.ObjectUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.nl.acs.auto.run.AbstractAutoRunnable;
import org.nl.modules.system.service.ParamService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.*;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Arrays;
import java.util.Date;
@Slf4j
@Component
@Data
public class ElevatorSocketConnectionAutoRun extends AbstractAutoRunnable {
private int recordTimeOut = 10000;
private Date recordTime;
private static Socket socket;
private static DataOutputStream dos;
private static BufferedReader dis;
private boolean bConnected = true;
@Autowired
private ParamService paramService;
public ElevatorSocketConnectionAutoRun() {
this.recordTime = new Date((new Date()).getTime() - (long) this.recordTimeOut);
}
@Override
public String getCode() {
return ElevatorSocketConnectionAutoRun.class.getSimpleName();
}
@Override
public String getName() {
return "电梯在线Socket连接";
}
@Override
public void autoRun() throws IOException, InterruptedException {
System.out.println("电梯链接开始");
String ip = "192.168.8.236";
int port = 502;
InetSocketAddress socketAddress = new InetSocketAddress(ip, port);
socket = new Socket();
socket.connect(socketAddress, 2 * 1000);
socket.setKeepAlive(true);
dos = new DataOutputStream(socket.getOutputStream());
dis = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while (bConnected) {
String heartbeat = "00060000000601039C430001";
int[] heartRec = write("心跳", heartbeat);
if (heartRec.length < 8) {
log.error("PLC端开连接......");
throw new IllegalArgumentException("PLC端开连接!");
}
Thread.sleep(5000);
}
}
@Override
public void stop() {
super.after();
try {
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static synchronized int[] write(String name, String hexMessage) {
String message = null;
try {
log.info("下发{}报文:{}", name, hexMessage);
dos = new DataOutputStream(socket.getOutputStream());
dis = new BufferedReader(new InputStreamReader(socket.getInputStream()));
socket.setSoTimeout(5000);
byte[] messageBytes = hexStringToByteArray(hexMessage);
dos.write(messageBytes);
dos.flush();
InputStream inputStream = socket.getInputStream();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
byte[] data = new byte[1024];
int nRead;
while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
if (nRead < 1024) {
break;
}
}
buffer.flush();
message = byteArrayToHexString(buffer.toByteArray());
log.info("读取{}报文:{}", name, message);
if (ObjectUtil.isEmpty(message)) {
return new int[]{-1};
}
return binary(message);
} catch (IOException e) {
log.error("失败原因:{}", e.getMessage());
log.error("堆栈信息:{}", Arrays.toString(e.getStackTrace()));
e.printStackTrace();
if (ObjectUtil.isNotEmpty(socket)) {
try {
dis.close();
dos.close();
socket.close();
log.error("连接出现异常,已关闭连接");
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
return new int[]{-1};
}
private static byte[] hexStringToByteArray(String s) {
int length = s.length();
byte[] data = new byte[length / 2];
for (int i = 0; i < length; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i + 1), 16));
}
return data;
}
private static String byteArrayToHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02X", b));
}
return sb.toString();
}
public static int[] binary(String hexString) {
hexString = hexString.replaceAll(" ", "");
int[] intArray = new int[hexString.length() / 2];
for (int i = 0; i < hexString.length(); i += 2) {
String byteString = hexString.substring(i, i + 2);
intArray[i / 2] = Integer.parseInt(byteString, 16);
}
return intArray;
}
}

View File

@@ -2,7 +2,7 @@ spring:
freemarker:
check-template-location: false
profiles:
active: dev2
active: prod
jackson:
time-zone: GMT+8
data:

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<included>
<springProperty scope="context" name="logPath" source="logging.file.path" defaultValue="logs"/>
<property name="LOG_HOME" value="${logPath}"/>
<!-- 按照每天生成日志文件 -->
<appender name="Elevator" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>${LOG_HOME}/电梯/%d{yyyy-MM-dd}.%i.log</FileNamePattern>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
<!--单个日志最大容量 至少10MB才能看得出来-->
<maxFileSize>200MB</maxFileSize>
<!--所有日志最多占多大容量-->
<totalSizeCap>2GB</totalSizeCap>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期%thread表示线程名%-5level级别从左显示5个字符宽度%msg日志消息%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>${log.charset}</charset>
</encoder>
</appender>
<appender name="asyncFileAppender" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="Elevator"/>
<!-- 设置队列大小,根据您的需求调整 -->
<queueSize>512</queueSize>
</appender>
<logger name="org.nl.start.auto.run.ElevatorSocketConnectionAutoRun" level="info" additivity="true">
<appender-ref ref="asyncFileAppender"/>
</logger>
</included>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<included>
<springProperty scope="context" name="logPath" source="logging.file.path" defaultValue="logs"/>
<property name="LOG_HOME" value="${logPath}"/>
<!-- 按照每天生成日志文件 -->
<appender name="ElevatorSocketUtil" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>${LOG_HOME}/电梯请求报文信息/%d{yyyy-MM-dd}.%i.log</FileNamePattern>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
<!--单个日志最大容量 至少10MB才能看得出来-->
<maxFileSize>200MB</maxFileSize>
<!--所有日志最多占多大容量-->
<totalSizeCap>2GB</totalSizeCap>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期%thread表示线程名%-5level级别从左显示5个字符宽度%msg日志消息%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>${log.charset}</charset>
</encoder>
</appender>
<appender name="asyncFileAppender" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="ElevatorSocketUtil"/>
<!-- 设置队列大小,根据您的需求调整 -->
<queueSize>512</queueSize>
</appender>
<logger name="org.nl.acs.socket.elevator.ElevatorSocketUtil" level="info" additivity="true">
<appender-ref ref="asyncFileAppender"/>
</logger>
</included>

View File

@@ -21,9 +21,11 @@ https://juejin.cn/post/6844903775631572999
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<property name="LOG_HOME" value="${logPath}"/>
<!--引入默认的一些设置-->
<include resource="log/AutoCreateInst.xml"/>
<include resource="log/AcsToWms.xml"/>
<include resource="log/WmsToAcs.xml"/>
<include resource="log/AutoCreateInst.xml"/>
<include resource="log/AcsToWms.xml"/>
<include resource="log/WmsToAcs.xml"/>
<include resource="log/ElevatorSocketUtil.xml"/>
<include resource="log/Elevator.xml"/>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${log.pattern}</pattern>