Compare commits

...

2 Commits

Author SHA1 Message Date
gengby fb2913c9aa add:modbus 6 months ago
gengby 6bb18a3312 rev:logo 6 months ago
  1. 65
      acs/nladmin-system/src/main/java/org/nl/acs/device_driver/shangdianke/ItemProtocol.java
  2. 64
      acs/nladmin-system/src/main/java/org/nl/acs/device_driver/shangdianke/PhotoelectricDetectionDeviceDriver.java
  3. 5
      acs/nladmin-system/src/main/java/org/nl/acs/device_driver/shangdianke/PhotoelectricDetectionStationDefinition.java
  4. 99
      acs/nladmin-system/src/main/java/org/nl/acs/modbus/TCPClient.java
  5. 96
      acs/nladmin-system/src/main/java/org/nl/acs/modbus/TCPClient2.java
  6. 2
      acs/nladmin-system/src/main/java/org/nl/acs/opc/DeviceManageDto.java
  7. 1
      acs/nladmin-system/src/main/resources/config/application-dev2.yml
  8. BIN
      acs/nladmin-ui/public/favicon.ico
  9. BIN
      acs/nladmin-ui/src/assets/images/logo.png
  10. BIN
      acs/nladmin-ui/src/assets/logo/logo.png
  11. 42
      acs/nladmin-ui/src/views/acs/device/driver/shangdianke/photoelectric_detection_station.vue
  12. 35
      acs/nladmin-ui/src/views/acs/device/driver/standard_ordinary_site.vue
  13. BIN
      lms/nladmin-ui/public/favicon.ico
  14. BIN
      lms/nladmin-ui/src/assets/images/logo.png
  15. BIN
      lms/nladmin-ui/src/assets/logo/logo.png
  16. 2
      lms/nladmin-ui/src/layout/components/Sidebar/Logo.vue

65
acs/nladmin-system/src/main/java/org/nl/acs/device_driver/shangdianke/ItemProtocol.java

@ -1,7 +1,12 @@
package org.nl.acs.device_driver.shangdianke;
import cn.hutool.core.util.StrUtil;
import lombok.Getter;
import lombok.Setter;
import org.nl.acs.modbus.TCPClient;
import org.nl.acs.modbus.TCPClient2;
import java.util.Optional;
/**
* @author zhangjiangwei
@ -10,72 +15,24 @@ import lombok.Setter;
@Setter
public class ItemProtocol {
/**
* 心跳
*/
public static final String ITEM_HEARTBEAT = "heartbeat";
/**
* 工作模式
*/
public static final String ITEM_MODE = "mode";
/**
* 光电信号
*/
public static final String ITEM_MOVE = "move";
/**
* 动作信号
*/
public static final String ITEM_ACTION = "action";
/**
* 报警信号
*/
public static final String ITEM_ERROR = "error";
/**
* 下发命令
*/
public static final String ITEM_TO_COMMAND = "to_command";
boolean isOnline;
private final PhotoelectricDetectionDeviceDriver driver;
public ItemProtocol(PhotoelectricDetectionDeviceDriver driver) {
this.driver = driver;
}
public int getOpcIntegerValue(String protocol) {
Integer value = this.driver.getIntegeregerValue(protocol);
if (value == null) {
this.isOnline = false;
return 0;
} else {
this.isOnline = true;
return value;
}
}
public int getHeartbeat() {
return this.getOpcIntegerValue(ItemProtocol.ITEM_HEARTBEAT);
}
public int getMode() {
return this.getOpcIntegerValue(ItemProtocol.ITEM_MODE);
}
public int getMove() {
return this.getOpcIntegerValue(ItemProtocol.ITEM_MOVE);
}
public int getAction() {
return this.getOpcIntegerValue(ItemProtocol.ITEM_ACTION);
String ip = Optional.ofNullable(this.getDriver().getDevice().getExtraValue().get("ipAddress")).map(Object::toString).orElse(null);
String index = Optional.ofNullable(this.getDriver().getDevice().getExtraValue().get("index")).map(Object::toString).orElse("-1");
if (StrUtil.isNotEmpty(ip) && !StrUtil.equals(index, "-1")) {
return TCPClient.startConnection(ip, 502, Integer.parseInt(index));
}
public int getError() {
return this.getOpcIntegerValue(ItemProtocol.ITEM_ERROR);
}
public int getToCommand() {
return this.getOpcIntegerValue(ItemProtocol.ITEM_TO_COMMAND);
return 0;
}
}

64
acs/nladmin-system/src/main/java/org/nl/acs/device_driver/shangdianke/PhotoelectricDetectionDeviceDriver.java

@ -1,6 +1,7 @@
package org.nl.acs.device_driver.shangdianke;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.Getter;
@ -15,6 +16,7 @@ import org.nl.acs.ext.wms.data.BaseRequest;
import org.nl.acs.ext.wms.data.BaseResponse;
import org.nl.acs.ext.wms.service.AcsToWmsService;
import org.nl.acs.log.service.DeviceExecuteLogService;
import org.nl.acs.modbus.TCPClient;
import org.nl.acs.monitor.DeviceStageMonitor;
import org.nl.acs.opc.DeviceAppService;
import org.nl.acs.task.service.TaskService;
@ -25,6 +27,7 @@ import org.nl.modules.wql.util.SpringContextHolder;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
/**
* @author zhangjiangwei
@ -35,47 +38,15 @@ import java.util.Map;
@RequiredArgsConstructor
public class PhotoelectricDetectionDeviceDriver extends AbstractOpcDeviceDriver implements DeviceDriver, ExecutableDeviceDriver, RouteableDeviceDriver, DeviceStageMonitor, StandardRequestMethod, HeartbeatableDeviceDriver {
/**
* 心跳
*/
private int heartbeat = 0;
private int lastHeartbeat = this.heartbeat;
/**
* 工作模式
*/
private int mode = 0;
private int lastMode = this.mode;
/**
* 光电信号
*/
private int move = 0;
private int lastMove = this.move;
/**
* 动作信号
*/
private int action = 0;
private int lastAction = this.action;
/**
* 报警信号
*/
private int error = 0;
private int lastError = this.error;
/**
* 下发命令
*/
private int toCommand = 0;
private int lastToCommand = this.toCommand;
private static final int MODE = 3;
private String currentDeviceCode = null;
private boolean isOnline = false;
private boolean isError = false;
private String message = "";
private final ItemProtocol itemProtocol = new ItemProtocol(this);
@ -84,7 +55,7 @@ public class PhotoelectricDetectionDeviceDriver extends AbstractOpcDeviceDriver
private long requireTime = System.currentTimeMillis();
private long requireTimeOut = 10000L;
private final DeviceExecuteLogService deviceExecuteLogService = SpringContextHolder.getBean(DeviceExecuteLogService.class);
//private final DeviceExecuteLogService deviceExecuteLogService = SpringContextHolder.getBean(DeviceExecuteLogService.class);
private final DeviceAppService deviceAppService = SpringContextHolder.getBean(DeviceAppService.class);
private final TaskService taskService = SpringContextHolder.getBean(TaskService.class);
private final DeviceService deviceService = SpringContextHolder.getBean(DeviceService.class);
@ -97,20 +68,19 @@ public class PhotoelectricDetectionDeviceDriver extends AbstractOpcDeviceDriver
try {
this.currentDeviceCode = this.getDeviceCode();
this.heartbeat = this.itemProtocol.getHeartbeat();
this.mode = this.itemProtocol.getMode();
this.move = this.itemProtocol.getMove();
this.action = this.itemProtocol.getAction();
this.error = this.itemProtocol.getError();
this.toCommand = this.itemProtocol.getToCommand();
if (this.move != this.lastMove) {
this.lucene.deviceExecuteLog(new LuceneLogDto(this.currentDeviceCode, "信号, move发生变化, 由" + lastMove + " ->" + move));
if (move == 0) {
requireSuccess = false;
}
}
if (mode > 0 && !requireSuccess) {
String applyFlag = Optional.ofNullable(this.getDevice().getExtraValue().get("applyFlag")).map(Object::toString).orElse("false");
if (StrUtil.equals(applyFlag, "true") && !requireSuccess) {
Object methodName = this.device.getExtraValue().get(String.valueOf(MODE));
if (ObjectUtil.isNotEmpty(methodName)) {
try {
@ -120,13 +90,13 @@ public class PhotoelectricDetectionDeviceDriver extends AbstractOpcDeviceDriver
log.error(e.getMessage(), e);
String message = "执行工作模式对应方法 " + methodName + " 错误!错误信息:" + e.getMessage();
this.message = message;
this.deviceExecuteLogService.deviceExecuteLog(this.currentDeviceCode, "", "", message);
this.isError = true;
this.lucene.deviceExecuteLog(new LuceneLogDto(this.currentDeviceCode, message));
}
} else {
String message = "未知工作模式,驱动未配置对应方法。";
this.message = message;
this.deviceExecuteLogService.deviceExecuteLog(this.currentDeviceCode, "", "", message);
this.lucene.deviceExecuteLog(new LuceneLogDto(this.currentDeviceCode, message));
// this.deviceExecuteLogService.deviceExecuteLog(this.currentDeviceCode, "", "", message);
}
}
@ -135,12 +105,8 @@ public class PhotoelectricDetectionDeviceDriver extends AbstractOpcDeviceDriver
log.error(e.getMessage(), e);
return;
}
this.lastHeartbeat = this.heartbeat;
this.lastMode = this.mode;
this.lastMove = this.move;
this.lastAction = this.action;
this.lastError = this.error;
this.lastToCommand = this.toCommand;
}
private void executionMethodByMode(String methodName) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
@ -160,14 +126,14 @@ public class PhotoelectricDetectionDeviceDriver extends AbstractOpcDeviceDriver
*/
@Override
public boolean apply_put_empty_vehicle() {
if (move == 0) {
if (this.move == 0) {
BaseRequest request = new BaseRequest();
request.setDevice_code(this.currentDeviceCode);
request.setRequest_medthod_code(Thread.currentThread().getStackTrace()[1].getMethodName());
request.setRequest_medthod_name(RequestMethodEnum.getName(Thread.currentThread().getStackTrace()[1].getMethodName()));
BaseResponse resp = JSON.toJavaObject(JSONObject.parseObject(acsToWmsService.applyTask(request)), BaseResponse.class);
message = RequestMethodEnum.getName("apply_put_empty_vehicle") + "apply_put_empty_vehicle 接口请求LMS...";
lucene.deviceExecuteLog(new LuceneLogDto(this.currentDeviceCode, message + "参数:" + JSON.toJSONString(request)));
this.lucene.deviceExecuteLog(new LuceneLogDto(this.currentDeviceCode, message + "参数:" + JSON.toJSONString(request)));
if (resp.isOk()) {
this.requireSuccess = true;
}

5
acs/nladmin-system/src/main/java/org/nl/acs/device_driver/shangdianke/PhotoelectricDetectionStationDefinition.java

@ -52,18 +52,13 @@ public class PhotoelectricDetectionStationDefinition implements OpcDeviceDriverD
@Override
public List<ItemDTO> getReadableItemDTOs() {
ArrayList<ItemDTO> itemDTOs = new ArrayList<>();
itemDTOs.add(new ItemDTO(ItemProtocol.ITEM_HEARTBEAT, "心跳", ""));
itemDTOs.add(new ItemDTO(ItemProtocol.ITEM_MODE, "工作模式", ""));
itemDTOs.add(new ItemDTO(ItemProtocol.ITEM_MOVE, "光电信号", ""));
itemDTOs.add(new ItemDTO(ItemProtocol.ITEM_ACTION, "动作信号", ""));
itemDTOs.add(new ItemDTO(ItemProtocol.ITEM_ERROR, "报警信号", ""));
return itemDTOs;
}
@Override
public List<ItemDTO> getWriteableItemDTOs() {
ArrayList<ItemDTO> itemDTOs = new ArrayList<>();
itemDTOs.add(new ItemDTO(ItemProtocol.ITEM_TO_COMMAND, "下发命令", ""));
return itemDTOs;
}
}

99
acs/nladmin-system/src/main/java/org/nl/acs/modbus/TCPClient.java

@ -0,0 +1,99 @@
package org.nl.acs.modbus;
import java.io.*;
import java.net.Socket;
import java.net.SocketTimeoutException;
public class TCPClient {
public static synchronized int startConnection(String ip, int port, int index) {
String hexMessage = "000600000006010200000008";
try (Socket socket = new Socket(ip, port);
DataOutputStream outToServer = new DataOutputStream(socket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {
socket.setSoTimeout(10000);
sendMessage(outToServer, hexMessage);
String message = receiveMessage(socket);
int[] binary = binary(message);
// for (int bit : binary) {
// System.out.println(bit);
// }
return binary[index - 1];
} catch (IOException e) {
e.printStackTrace();
}
return -1;
}
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) {
String lastFourHex = hexString.substring(hexString.length() - 4);
int decimal = Integer.parseInt(lastFourHex, 16);
String binaryString = Integer.toBinaryString(decimal);
System.out.println("length:" + binaryString.length());
int[] binaryArray = new int[binaryString.length()];
for (int i = 0; i < binaryString.length(); i++) {
binaryArray[i] = Character.getNumericValue(binaryString.charAt(i));
}
reverseArray(binaryArray);
return binaryArray;
}
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;
}
}
public static void main(String[] args) {
int move = startConnection("192.168.1.12", 502, 2);
System.out.println(move);
}
}

96
acs/nladmin-system/src/main/java/org/nl/acs/modbus/TCPClient2.java

@ -0,0 +1,96 @@
package org.nl.acs.modbus;
import lombok.SneakyThrows;
import java.io.*;
import java.net.Socket;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
import static oshi.util.ParseUtil.byteArrayToHexString;
import static oshi.util.ParseUtil.hexStringToByteArray;
public class TCPClient2 {
private static final ConcurrentHashMap<String, Socket> connectionPools = new ConcurrentHashMap<>();
private static final ReentrantLock lock = new ReentrantLock();
private static final String hexMessage = "000600000006010200000008";
@SneakyThrows
public static int startConnection(String ip, int port, int index) {
String key = ip + ":" + port;
Socket socket = getSocketFromPool(key, ip, port);
if (socket == null) return -1;
DataOutputStream outToServer = new DataOutputStream(socket.getOutputStream());
sendMessage(outToServer, hexMessage);
String message = receiveMessage(socket);
int[] binary = binary(message);
return binary[index - 1];
}
//@SneakyThrows
private static Socket getSocketFromPool(String key, String ip, int port) {
lock.lock();
try {
if (connectionPools.keySet().contains(key) && connectionPools.get(key).isConnected()) {
return connectionPools.get(key);
} else {
connectionPools.remove(key);
Socket socket = new Socket(ip, port);
socket.setKeepAlive(true);
socket.setSoTimeout(10000);
connectionPools.put(key, socket);
return socket;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
return null;
}
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 {
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());
}
private static int[] binary(String hexString) {
if (hexString == null) {
hexString = "00060000000401020100";
}
String lastFourHex = hexString.substring(hexString.length() - 4);
int decimal = Integer.parseInt(lastFourHex, 16);
String binaryString = Integer.toBinaryString(decimal);
int[] binaryArray = new int[binaryString.length()];
for (int i = 0; i < binaryString.length(); i++) {
binaryArray[i] = Character.getNumericValue(binaryString.charAt(i));
}
reverseArray(binaryArray);
return binaryArray;
}
private static void reverseArray(int[] array) {
for (int i = 0, j = array.length - 1; i < j; i++, j--) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}

2
acs/nladmin-system/src/main/java/org/nl/acs/opc/DeviceManageDto.java

@ -73,7 +73,7 @@ public class DeviceManageDto {
DeviceExtraManageDto dto = (DeviceExtraManageDto) var2.next();
// result.put(dto.getExtra_code(), dto.parseName());
if(ObjectUtil.isEmpty( dto.getExtra_value())){
result.put(dto.getExtra_code(), dto.getExtra_name());
result.put(dto.getExtra_code(), dto.parseName());
} else {
result.put(dto.getExtra_code(), dto.parseName());
}

1
acs/nladmin-system/src/main/resources/config/application-dev2.yml

@ -1,5 +1,6 @@
server:
port: 8010
max-http-header-size: 65536
#配置数据源
spring:
datasource:

BIN
acs/nladmin-ui/public/favicon.ico

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

After

Width:  |  Height:  |  Size: 125 KiB

BIN
acs/nladmin-ui/src/assets/images/logo.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

After

Width:  |  Height:  |  Size: 125 KiB

BIN
acs/nladmin-ui/src/assets/logo/logo.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

After

Width:  |  Height:  |  Size: 125 KiB

42
acs/nladmin-ui/src/views/acs/device/driver/shangdianke/photoelectric_detection_station.vue

@ -49,6 +49,28 @@
</div>
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="78px">
<el-row>
<el-col :span="8">
<el-tooltip class="item" effect="dark" content="设备含有光电时,需配置Ip地址" placement="bottom-end">
<el-form-item label="IP地址" label-width="150px">
<el-input v-model="form.ipAddress" />
</el-form-item>
</el-tooltip>
</el-col>
<el-col :span="8">
<el-tooltip class="item" effect="dark" content="设备含有光电时,需配置,一个IP对应8个PLC信号" placement="bottom-end">
<el-form-item label="索引号" label-width="150px">
<el-input
v-model.number="form.index"
:maxlength="1"
type="number"
@input="validateInput"
/>
</el-form-item>
</el-tooltip>
</el-col>
<el-col :span="8">
<el-form-item label="电气调度号" label-width="150px">
<el-input v-model="form.OPCServer" />
@ -98,6 +120,13 @@
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="申请空托">
<el-switch v-model="form.applyFlag" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
@ -332,7 +361,10 @@ export default {
manual_create_task: true,
is_pickup: true,
is_release: true,
link_device_code: []
link_device_code: [],
ipAddress: '',
index: '',
applyFlag: ''
},
rules: {}
}
@ -541,6 +573,14 @@ export default {
item.code = this.opc_code + '.' + this.plc_code + '.' + this.device_code + '.' + item.code
}
})
},
validateInput(value) {
const num = parseInt(value, 10)
if (num < 1 || num > 8) {
this.form.index = 1
} else {
this.form.index = num
}
}
}
}

35
acs/nladmin-ui/src/views/acs/device/driver/standard_ordinary_site.vue

@ -7,8 +7,31 @@
</div>
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="78px">
<el-row>
<el-col :span="8">
<el-tooltip class="item" effect="dark" content="设备含有光电时,需配置Ip地址" placement="bottom-end">
<el-form-item label="IP地址" label-width="150px">
<el-input v-model="form.ipAddress" />
</el-form-item>
</el-tooltip>
</el-col>
<el-col :span="8">
<el-tooltip class="item" effect="dark" content="设备含有光电时,需配置,一个IP对应8个PLC信号" placement="bottom-end">
<el-form-item label="索引号" label-width="150px">
<el-input
v-model.number="form.index"
:maxlength="1"
type="number"
@input="validateInput"
/>
</el-form-item>
</el-tooltip>
</el-col>
<el-col :span="8">
<el-tooltip class="item" effect="dark" content="设备为输送机或者NDC系统时需为数字" placement="bottom-end">
<el-form-item label="电气调度号" label-width="150px">
<el-input v-model="form.address" />
</el-form-item>
@ -168,7 +191,9 @@ export default {
is_release: true,
station_manager: true,
auto_clean_task: true,
input_material: true
input_material: true,
ipAddress: '',
index: ''
},
rules: {}
}
@ -210,6 +235,14 @@ export default {
})
}
})
},
validateInput(value) {
const num = parseInt(value, 10)
if (num < 1 || num > 8) {
this.form.index = 1
} else {
this.form.index = num
}
}
}
}

BIN
lms/nladmin-ui/public/favicon.ico

Binary file not shown.

Before

Width:  |  Height:  |  Size: 277 KiB

After

Width:  |  Height:  |  Size: 125 KiB

BIN
lms/nladmin-ui/src/assets/images/logo.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 275 KiB

After

Width:  |  Height:  |  Size: 125 KiB

BIN
lms/nladmin-ui/src/assets/logo/logo.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

After

Width:  |  Height:  |  Size: 125 KiB

2
lms/nladmin-ui/src/layout/components/Sidebar/Logo.vue

@ -14,7 +14,7 @@
</template>
<script>
import Logo from '@/assets/images/logo2.png'
import Logo from '@/assets/images/logo.png'
import variables from '@/assets/styles/variables.scss'
export default {
name: 'SidebarLogo',

Loading…
Cancel
Save