添加电子标签硬件操作的逻辑

This commit is contained in:
葛林强 2026-01-26 16:25:30 +08:00
parent b62fb0e0cd
commit 10680d7fec
24 changed files with 1688 additions and 23 deletions

View File

@ -0,0 +1,214 @@
package org.wcs.business.etag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.wcs.business.redis.EtagRedis;
import org.wcs.constant.enums.database.ETagTypeEnum;
import org.wcs.constant.enums.etag.LedBlinkingEnum;
import org.wcs.constant.enums.etag.LedColorEnum;
import org.wcs.model.bo.etag.EtagLightParams;
import org.wcs.model.po.app.AppEtagTagInfo;
/**
* 上尚电子标签操作类
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class EtagAtopOperation {
// 电子标签 redis 操作类
private final EtagRedis etagRedis;
/**
* 点亮标签
* @param params 点亮标签参数
* @return 结果
*/
public String lightTag(EtagLightParams params) {
if(params == null || params.getTagName() == null) {
return "参数错误";
}
if(EtagCommon.socketClient == null) {
return "电子标签控制器尚未初始化";
}
AppEtagTagInfo etagTag = etagRedis.getEtagTag(params.getTagName());
if(etagTag == null) {
return "未找到标签";
}
Integer tagId = etagTag.getTagId();
if(tagId == null || tagId < 0 || tagId > 127) {
return "标签ID格式不正确";
}
params.setTagId(tagId.byteValue()); // 设置标签ID进参数
Integer controllerId = etagTag.getControllerId(); // 控制器ID也是 Socket 连接的 ID
ETagTypeEnum eTagTypeEnum = ETagTypeEnum.getByCode(etagTag.getTagType());
if(eTagTypeEnum == null) {
return "未知标签种类";
}
switch (eTagTypeEnum) {
case ETagTypeEnum.NUMBER_BUTTON_3 -> {
return lightNumberButton3(controllerId, params);
}
case ETagTypeEnum.NUMBER_BUTTON_7 -> {
return lightNumberButton7(controllerId, params);
}
case ETagTypeEnum.NUMBER_ENGLISH_BUTTON_12 -> {
return lightNumberEnglishButton12(controllerId, params);
}
case ETagTypeEnum.NUMBER_CHINESE_BUTTON_6 -> {
return lightNumberChineseButton12(controllerId, params);
}
case ETagTypeEnum.LIGHT -> {
return lightTunnelLight(controllerId, params);
}
default -> {
return "不支持的标签种类";
}
}
}
/**
* 点亮带按钮3位数字标签
* @param controllerId 控制器ID
* @param params 点亮标签参数
* @return 结果
*/
public String lightNumberButton3(Integer controllerId, EtagLightParams params) {
// 检查这次标签颜色是否与上次发送相同若不同则重新发送标签颜色
LedColorEnum etagTagColor = etagRedis.getEtagTagColor(params.getTagName());
if(etagTagColor == null || etagTagColor != params.getLedColor()) {
byte[] ledColorBytes = EtagInstruction.setLedColor(params.getTagId(), params.getLedColor());
String sendLedColorBytes = EtagCommon.socketClient.sendBytes(controllerId.toString(), ledColorBytes);
if(sendLedColorBytes != null) {
// 发送成功设置标签颜色防止下次重复发送
etagRedis.setEtagTagColor(params.getTagName(), params.getLedColor());
}
}
// 检查这次闪烁要求是否和上次相同若不同则重新发送闪烁颜色
LedBlinkingEnum etagTagBlinking = etagRedis.getEtagTagBlinking(params.getTagName());
if(etagTagBlinking == null || etagTagBlinking != params.getLedBlinking()) {
byte[] ledBlinkingBytes = EtagInstruction.setLedBlinking(params.getTagId(), params.getLedBlinking());
String sendLedBlinkingBytes = EtagCommon.socketClient.sendBytes(controllerId.toString(), ledBlinkingBytes);
if(sendLedBlinkingBytes != null) {
// 发送成功设置标签闪烁防止下次重复发送
etagRedis.setEtagTagBlinking(params.getTagName(), params.getLedBlinking());
}
}
// 发送标签值
byte[] tagValueBytes = EtagInstruction.showNumber6(params.getTagId(), params.getTagValue());
String sendResult = EtagCommon.socketClient.sendBytes(controllerId.toString(), tagValueBytes);
if(sendResult != null) {
log.info("发送电子标签信息失败,标签名称:{},发送数据:{},结果:{}", params.getTagName(), params, sendResult);
}
return sendResult;
}
/**
* 点亮带按钮7位数字标签
* @param controllerId 控制器ID
* @param params 点亮标签参数
* @return 结果
*/
public String lightNumberButton7(Integer controllerId, EtagLightParams params) {
// 等遇到这种标签在看文档里面有点乱
return "不支持";
}
/**
* 点亮带按钮12位数字英文标签
* @param controllerId 控制器ID
* @param params 点亮标签参数
* @return 结果
*/
public String lightNumberEnglishButton12(Integer controllerId, EtagLightParams params) {
// 检查这次标签颜色是否与上次发送相同若不同则重新发送标签颜色
LedColorEnum etagTagColor = etagRedis.getEtagTagColor(params.getTagName());
if(etagTagColor == null || etagTagColor != params.getLedColor()) {
byte[] ledColorBytes = EtagInstruction.setLedColor(params.getTagId(), params.getLedColor());
String sendLedColorBytes = EtagCommon.socketClient.sendBytes(controllerId.toString(), ledColorBytes);
if(sendLedColorBytes != null) {
// 发送成功设置标签颜色防止下次重复发送
etagRedis.setEtagTagColor(params.getTagName(), params.getLedColor());
}
}
// 检查这次闪烁要求是否和上次相同若不同则重新发送闪烁颜色
LedBlinkingEnum etagTagBlinking = etagRedis.getEtagTagBlinking(params.getTagName());
if(etagTagBlinking == null || etagTagBlinking != params.getLedBlinking()) {
byte[] ledBlinkingBytes = EtagInstruction.setLedBlinking(params.getTagId(), params.getLedBlinking());
String sendLedBlinkingBytes = EtagCommon.socketClient.sendBytes(controllerId.toString(), ledBlinkingBytes);
if(sendLedBlinkingBytes != null) {
// 发送成功设置标签闪烁防止下次重复发送
etagRedis.setEtagTagBlinking(params.getTagName(), params.getLedBlinking());
}
}
// 发送标签值
byte[] tagValueBytes = EtagInstruction.showEnglishString12(params.getTagId(), params.getTagValue());
String sendResult = EtagCommon.socketClient.sendBytes(controllerId.toString(), tagValueBytes);
if(sendResult != null) {
log.info("发送电子标签信息失败,标签名称:{},发送数据:{},结果:{}", params.getTagName(), params, sendResult);
}
return sendResult;
}
/**
* 点亮带按钮6位数字中文标签
* @param controllerId 控制器ID
* @param params 点亮标签参数
* @return 结果
*/
public String lightNumberChineseButton12(Integer controllerId, EtagLightParams params) {
// 检查这次标签颜色是否与上次发送相同若不同则重新发送标签颜色
LedColorEnum etagTagColor = etagRedis.getEtagTagColor(params.getTagName());
if(etagTagColor == null || etagTagColor != params.getLedColor()) {
byte[] ledColorBytes = EtagInstruction.setLedColor(params.getTagId(), params.getLedColor());
String sendLedColorBytes = EtagCommon.socketClient.sendBytes(controllerId.toString(), ledColorBytes);
if(sendLedColorBytes != null) {
// 发送成功设置标签颜色防止下次重复发送
etagRedis.setEtagTagColor(params.getTagName(), params.getLedColor());
}
}
// 检查这次闪烁要求是否和上次相同若不同则重新发送闪烁颜色
LedBlinkingEnum etagTagBlinking = etagRedis.getEtagTagBlinking(params.getTagName());
if(etagTagBlinking == null || etagTagBlinking != params.getLedBlinking()) {
byte[] ledBlinkingBytes = EtagInstruction.setLedBlinking(params.getTagId(), params.getLedBlinking());
String sendLedBlinkingBytes = EtagCommon.socketClient.sendBytes(controllerId.toString(), ledBlinkingBytes);
if(sendLedBlinkingBytes != null) {
// 发送成功设置标签闪烁防止下次重复发送
etagRedis.setEtagTagBlinking(params.getTagName(), params.getLedBlinking());
}
}
String sendResult = "";
// 发送标签中文
byte[] tagStringBytes = EtagInstruction.setChineseString(params.getTagId(), params.getTagString());
sendResult += EtagCommon.socketClient.sendBytes(controllerId.toString(), tagStringBytes);
// 发送标签值
byte[] tagValueBytes = EtagInstruction.showChineseNumber6(params.getTagId(), params.getTagValue());
sendResult += EtagCommon.socketClient.sendBytes(controllerId.toString(), tagValueBytes);
if(!sendResult.isEmpty()) {
log.info("发送电子标签信息失败,标签名称:{},发送数据:{},结果:{}", params.getTagName(), params, sendResult);
}
return sendResult;
}
/**
* 点亮通道灯
* @param controllerId 控制器ID
* @param params 点亮标签参数
* @return 结果
*/
public String lightTunnelLight(Integer controllerId, EtagLightParams params) {
String lightValueBit = "0" + LedBlinkingEnum.getBlinkingBitString(params.getLedBlinking())
+ "0" + LedColorEnum.getLightColorBitString(params.getLedColor());
byte[] lightBytes = EtagInstruction.light(params.getTagId(), lightValueBit);
String sendResult = EtagCommon.socketClient.sendBytes(controllerId.toString(), lightBytes);
if(sendResult != null) {
log.info("发送电子标签信息失败,标签名称:{},发送数据:{},结果:{}", params.getTagName(), params, sendResult);
}
return sendResult;
}
}

View File

@ -0,0 +1,16 @@
package org.wcs.business.etag;
import org.wcs.plugin.tcp.SocketClient;
/**
* 电子标签通用类
*/
public class EtagCommon {
/**
* Socket 客户端
*/
public static SocketClient socketClient;
}

View File

@ -0,0 +1,112 @@
package org.wcs.business.etag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.wcs.business.redis.EtagRedis;
import org.wcs.constant.enums.database.ETagTypeEnum;
import org.wcs.model.bo.etag.EtagReturnInfo;
import org.wcs.model.po.app.AppEtagTagInfo;
import org.wcs.plugin.tcp.model.SocketDataItem;
import org.wcs.utils.AppThreadUtils;
import java.util.Objects;
/**
* 电子标签数据处理类
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class EtagDataHandler {
// 电子标签 redis 操作类
private final EtagRedis etagRedis;
/**
* 接收字节数据并解析主要是解析电子标签扫码器扫描的数据和标签按下确认的数据
* @param socketDataItem Socket 数据项
* @param bytes 字节数据
* @remark 此为参照供应商C#版本的程序的数据解析方法所写看不懂请不要问我谢谢
*/
public void receiveBytes(SocketDataItem socketDataItem, byte[] bytes) {
AppThreadUtils.startNewThread(() -> {
EtagReturnInfo etagReturnInfo = new EtagReturnInfo();
etagReturnInfo.setControllerId(socketDataItem.getSocketId());
etagReturnInfo.setIp(socketDataItem.getSocketIp());
etagReturnInfo.setEtagPort(bytes[2] == 0x60 ? 1 : 2);
etagReturnInfo.setSubCommand((int)bytes[6]);
etagReturnInfo.setTagId(bytes.length > 7 ? (int)bytes[7] : 0);
if(etagReturnInfo.getSubCommand() == 6 || etagReturnInfo.getSubCommand() == 7) {
StringBuilder returnData = new StringBuilder();
for(int i = 8; i < bytes.length; i++) {
if (bytes[i] > 0) {
returnData.append((char) bytes[i]);
}
}
etagReturnInfo.setData(returnData.toString().replaceAll("\\W", ""));
}
if(etagReturnInfo.getSubCommand() == 9) {
byte[] ccb_data = new byte[250];
for (int k = 8; k < bytes.length && k < 258; k++) {
ccb_data[k - 8] = bytes[k];
}
int tmp = 0;
int mixId = 0;
StringBuilder tagStr = new StringBuilder();
for(int i = 0; i <= 250; i++) {
if ((i - 1) % 8 == 0) {
tmp = ccb_data[3 + (i - 1) / 8];
}
if (tmp % 2 != 1) {
mixId = i;
tagStr.append("1");
} else {
tagStr.append("0");
}
tmp /= 2;
}
etagReturnInfo.setData(tagStr.substring(0, mixId).replaceAll("\\W", ""));
}
try {
etagDataHandler(etagReturnInfo); // 数据处理
} catch (Exception e) {
log.error("电子标签 {} 收到信息:{}, 数据处理异常:{}", etagReturnInfo.getControllerId(), etagReturnInfo, e.getMessage());
}
});
}
/**
* 处理电子标签数据
* @param etagReturnInfo 电子标签返回信息
*/
private void etagDataHandler(EtagReturnInfo etagReturnInfo) {
log.info("电子标签 {} 收到信息:{}", etagReturnInfo.getControllerId(), etagReturnInfo);
Integer tagId = etagReturnInfo.getTagId(); // 标签号
String controllerId = etagReturnInfo.getControllerId(); // 控制器ID
AppEtagTagInfo appEtagTagInfo = etagRedis.getEtagTag(controllerId, tagId);
if(appEtagTagInfo == null) {
log.warn("电子标签信息:{},未找到标签信息,无法处理事件", etagReturnInfo);
return; // 找不到标签信息
}
Integer tagType = appEtagTagInfo.getTagType();
if(Objects.equals(tagType, ETagTypeEnum.SCAN.getCode())) {
handScanCode(etagReturnInfo);
return;
}
if(ETagTypeEnum.buttonTagList().contains(ETagTypeEnum.getByCode(tagType))) {
handleTagConfirm(etagReturnInfo);
return;
}
}
private void handScanCode(EtagReturnInfo etagReturnInfo) {
}
private void handleTagConfirm(EtagReturnInfo etagReturnInfo) {
}
}

View File

@ -0,0 +1,305 @@
package org.wcs.business.etag;
import org.wcs.constant.enums.etag.LedBlinkingEnum;
import org.wcs.constant.enums.etag.LedColorEnum;
import org.wcs.utils.AppStringUtils;
import org.wcs.utils.Converter;
import java.util.Arrays;
/**
* 电子标签的指令集
*/
public class EtagInstruction {
/**
* 标签自检
* @return 命令字节数组
* @remark 向控制器发送此命令将强制标签自检测试通过
*/
public static byte[] checkAllTag() {
byte[] data = new byte[7];
data[0] = 7;
data[1] = 0;
data[2] = 0x60;
data[6] = 0x09;
return data;
}
/**
* 显示标签ID
* @param tagId 标签号
* @return 命令字节数组
* @remark 向控制器的某一个标签发送此命令将显示标签ID测试通过
*/
public static byte[] showTagId(byte tagId) {
byte[] data = new byte[8];
data[0] = 8;
data[1] = 0;
data[2] = 0x60;
data[6] = 0x13;
data[7] = tagId;
return data;
}
/**
* 重启标签
* @param tagId 标签号
* @return 命令字节数组
* @remark 向控制器的某一个标签发送此命令将重启标签未测试
*/
public static byte[] restartTag(byte tagId) {
byte[] data = new byte[8];
data[0] = 8;
data[1] = 0;
data[2] = 0x60;
data[6] = 0x14;
data[7] = tagId;
return data;
}
/**
* 关闭标签
* @param tagId 标签号
* @return 命令字节数组
* @remark 向控制器的某一个标签发送此命令将关闭标签测试通过
*/
public static byte[] turnOffTag(byte tagId) {
byte[] data = new byte[8];
data[0] = 8;
data[1] = 0;
data[2] = 0x60;
data[6] = 1;
data[7] = tagId;
return data;
}
/**
* 设置标签颜色
* @param tagId 标签号
* @param ledColor 颜色
* @return 命令字节数组
* @remark 向控制器的某一个标签发送此命令将设置标签颜色测试通过
*/
public static byte[] setLedColor(byte tagId, LedColorEnum ledColor) {
byte[] data = new byte[10];
data[0] = 0x0A;
data[1] = 0;
data[2] = 0x60;
data[6] = 0x1F;
data[7] = tagId;
data[8] = 0;
data[9] = ledColor.getCode().byteValue();
return data;
}
/**
* 设置LED闪烁模式
* @param tagId 标签号
* @param ledBlinkingEnum 闪烁模式
* @return 命令字节数组
* @remark 向控制器的某一个标签发送此命令将设置LED闪烁模式测试通过
*/
public static byte[] setLedBlinking(byte tagId, LedBlinkingEnum ledBlinkingEnum) {
byte[] data = new byte[10];
data[0] = 0x0A;
data[1] = 0;
data[2] = 0x60;
data[6] = 0x1F;
data[7] = tagId;
data[8] = 4;
data[9] = ledBlinkingEnum.getCode().byteValue();
return data;
}
/**
* 显示数字
* @param tagId 标签号
* @param number 显示的数字
* @return 命令字节数组
* @remark 向控制器的某一个标签发送此命令将显示数字三位标签测试通过其他未测试
*/
public static byte[] showNumber6(byte tagId, String number) {
if(AppStringUtils.isEmpty(number.trim())) {
return turnOffTag(tagId);
}
if(!AppStringUtils.isNumber(number.trim())) {
number = "ERR";
}
if(number.length() < 6) {
number = AppStringUtils.padLeft(number, " ", 6);
}
else {
number = number.substring(0, 6);
}
byte[] data = new byte[15];
data[0] = 0x0f;
data[1] = 0;
data[2] = 0x60;
data[6] = 0x00;
data[7] = tagId;
for (int i = 0; i < number.length(); i++) {
char c = number.charAt(i);
if(c == ' ') {
continue;
}
data[8 + i] = (byte)c;
}
data[14] = 0x00;
return data;
}
/**
* 点亮巷道灯
* @param tagId 标签号
* @param value 显示的数字
* @return 命令字节数组
* @remark 测试通过
*/
public static byte[] light(byte tagId, String value) {
byte[] data = new byte[17];
data[0] = 0x11;
data[1] = 0;
data[2] = 0x61;
data[3] = 0;
data[4] = 0;
data[5] = 0;
data[6] = 0x41;
data[7] = tagId;
data[8] = 0;
data[9] = 0;
String lightStatus = "00010001"; // 默认常亮绿色
if(AppStringUtils.isNotEmpty(value)) {
lightStatus = value;
}
//data[9] = Converter.toByte(lightStatus);
data[10] = Converter.toByte(lightStatus);
data[11] = 0;
data[12] = 0;
data[13] = 0;
data[14] = 0;
data[15] = 0;
data[16] = 0;
return data;
}
/**
* 点亮英文数字标签
* @param tagId 标签号
* @param value 显示的字符串
* @return 消息字节
*/
public static byte[] showEnglishString12(byte tagId, String value) {
if(AppStringUtils.isEmpty(value.trim())) {
return turnOffTag(tagId);
}
byte[] data = new byte[20];
data[0] = 0x0f;
data[1] = 0;
data[2] = 0x60;
data[3] = 0x0f;
data[4] = 0;
data[5] = 0;
data[6] = 0;
data[7] = tagId;
for (int i = 0; i < value.length(); i++) {
char c = value.charAt(i);
if(c == ' ') {
continue;
}
data[8 + i] = (byte)c;
}
return data;
}
/**
* 设置中文数字标签的中文 ---- 调用 showChineseNumber6 显示数字才会显示
* @param tagId 标签ID
* @param chinese 中文
* @return 消息字节
* @remark 测试通过
*/
public static byte[] setChineseString(byte tagId, String chinese) {
if(AppStringUtils.isEmpty(chinese.trim())) {
return turnOffTag(tagId);
}
byte[] result = AppStringUtils.toByteArrayGBK(chinese);
if (result != null && result.length > 48) {
result = Arrays.copyOf(result, 48);
}
if(result != null) {
byte[] data = new byte[0x0a + (byte)result.length];
data[0] = (byte) (0x0a + (byte)result.length);
data[1] = 0;
data[2] = 0x60;
data[3] = 0;
data[4] = 0;
data[5] = 0;
data[6] = 0x39;
data[7] = tagId;
data[8] = 0x0c;
System.arraycopy(result, 0, data, 9, result.length);
return data;
}
return new byte[0];
}
/**
* 清理中文标签缓存
* @param tagId 标签ID
* @return 结果
*/
public static byte[] cleanChineseString(byte tagId) {
byte[] data = new byte[8];
data[0] = (byte)8;
data[1] = 0;
data[2] = 0x60;
data[3] = 0;
data[4] = 0;
data[5] = 0;
data[6] = 0x01;
data[7] = tagId;
return data;
}
/**
* 显示中文标签的数字 ---- 调用此方法才会显示
* @param tagId 标签ID
* @param number 数字
* @return 命令字节
* @remark 测试通过
*/
public static byte[] showChineseNumber6(byte tagId, String number) {
if(AppStringUtils.isEmpty(number.trim())) {
return turnOffTag(tagId);
}
if(!AppStringUtils.isNumber(number.trim())) {
number = "ERR";
}
if(number.length() < 6) {
number = AppStringUtils.padLeft(number, "0", 6);
}
else {
number = number.substring(0, 6);
}
byte[] data = new byte[14];
data[0] = 0x0e;
data[1] = 0;
data[2] = 0x60;
data[3] = 0;
data[4] = 0;
data[5] = 0;
data[6] = 0x00;
data[7] = tagId;
for (int i = 0; i < number.length(); i++) {
char c = number.charAt(i);
if(c == ' ') {
continue;
}
data[8 + i] = (byte)c;
}
return data;
}
}

View File

@ -0,0 +1,31 @@
package org.wcs.business.etag;
import org.springframework.stereotype.Component;
/**
* 电子标签任务执行类
*/
@Component
public class EtagTaskExecute {
/**
* 点亮汇总标签
*/
public void lightSummaryTag() {
}
/**
* 点亮小标签
*/
public void lightSmallTag() {
}
/**
* 点亮通道灯
*/
public void lightTunnelLight() {
}
}

View File

@ -0,0 +1,259 @@
package org.wcs.business.redis;
import com.alibaba.fastjson2.JSONObject;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.wcs.constant.ConstantData;
import org.wcs.constant.enums.etag.LedBlinkingEnum;
import org.wcs.constant.enums.etag.LedColorEnum;
import org.wcs.model.po.app.AppEtagTagInfo;
import org.wcs.model.po.app.AppEtagTagLocation;
import org.wcs.model.po.app.AppEtagTask;
import org.wcs.utils.AppStringUtils;
import java.util.Set;
/**
* 电子标签Redis操作类
*/
@Component
@RequiredArgsConstructor
public class EtagRedis {
/**
* Redis操作类
*/
private final StringRedisTemplate stringRedisTemplate;
// 电子标签小标签信息
private static final String ETAG_TAG_KEY = ConstantData.SYSTEM_NAME + ":Etag:Tag";
// 电子标签小标签ID信息key 是用控制器编号拼接而成
private static final String ETAG_TAG_ID_KEY = ConstantData.SYSTEM_NAME + ":Etag:TagId";
// 电子标签位置信息
private static final String ETAG_LOCATION_KEY = ConstantData.SYSTEM_NAME + ":Etag:Location";
// 电子标签小标签绑定的任务信息
private static final String ETAG_TAG_TASK_KEY = ConstantData.SYSTEM_NAME + ":Etag:TagTask";
// 电子标签区域绑定的用户信息
private static final String ETAG_AREA_USER_KEY = ConstantData.SYSTEM_NAME + ":Etag:AreaUser";
// 电子标签小标签颜色信息 ---- 存储上次的颜色防止重复发送颜色命令
private static final String ETAG_TAG_COLOR_KEY = ConstantData.SYSTEM_NAME + ":Etag:TagColor";
// 电子标签小标签闪烁信息 ---- 存储上次的闪烁信息防止重复发送闪烁命令
private static final String ETAG_TAG_BLINKING_KEY = ConstantData.SYSTEM_NAME + ":Etag:TagBlinking";
/* ******************** 电子标签小标签信息 *********************** */
/**
* 清空电子标签小标签信息
*/
public void clearEtagTag() {
Set<String> keys = stringRedisTemplate.keys(ETAG_TAG_KEY + ":*");
stringRedisTemplate.delete(keys);
Set<String> idKeys = stringRedisTemplate.keys(ETAG_TAG_ID_KEY + ":*");
stringRedisTemplate.delete(keys);
}
/**
* 设置电子标签小标签信息
* @param tagName 标签名称
* @param tagInfo 标签信息
*/
public void setEtagTag(String tagName, AppEtagTagInfo tagInfo) {
stringRedisTemplate.opsForValue().set(ETAG_TAG_KEY + ":" + tagName, AppStringUtils.objectToString(tagInfo));
stringRedisTemplate.opsForValue().set(ETAG_TAG_ID_KEY + ":" + tagInfo.getControllerId() + "@" + tagInfo.getTagId(), tagName);
}
/**
* 获取电子标签小标签信息
* @param tagName 标签名称
* @return 电子标签小标签信息
*/
public AppEtagTagInfo getEtagTag(String tagName) {
String tagInfo = stringRedisTemplate.opsForValue().get(ETAG_TAG_KEY + ":" + tagName);
if(AppStringUtils.isEmpty(tagInfo)) {
return null;
}
return JSONObject.parseObject(tagInfo, AppEtagTagInfo.class);
}
/**
* 获取电子标签小标签信息
* @param controllerId 控制器编号
* @param tagId 标签编号
* @return 电子标签小标签信息
*/
public AppEtagTagInfo getEtagTag(String controllerId, Integer tagId) {
String tagInfo = stringRedisTemplate.opsForValue().get(ETAG_TAG_ID_KEY + ":" + controllerId + "@" + tagId);
if(AppStringUtils.isEmpty(tagInfo)) {
return null;
}
return JSONObject.parseObject(tagInfo, AppEtagTagInfo.class);
}
/* ******************** 电子标签货位信息 *********************** */
/**
* 清空电子标签货位信息
*/
public void clearEtagLocation() {
Set<String> keys = stringRedisTemplate.keys(ETAG_LOCATION_KEY + ":*");
stringRedisTemplate.delete(keys);
}
/**
* 设置电子标签货位信息
* @param locationId 货位ID
* @param locationInfo 货位信息
*/
public void setEtagLocation(String locationId, AppEtagTagLocation locationInfo) {
stringRedisTemplate.opsForValue().set(ETAG_LOCATION_KEY + ":" + locationId, AppStringUtils.objectToString(locationInfo));
}
/**
* 获取电子标签货位信息
* @param locationId 货位ID
* @return 货位信息
*/
public AppEtagTagLocation getEtagLocation(String locationId) {
String locationInfo = stringRedisTemplate.opsForValue().get(ETAG_LOCATION_KEY + ":" + locationId);
if(AppStringUtils.isEmpty(locationInfo)) {
return null;
}
return JSONObject.parseObject(locationInfo, AppEtagTagLocation.class);
}
/* ******************** 电子标签绑定的任务信息 *********************** */
/**
* 设置电子标签绑定的任务信息
* @param tagName 标签名称
* @param task 任务信息
*/
public void setEtagTagTask(String tagName, AppEtagTask task) {
stringRedisTemplate.opsForValue().set(ETAG_TAG_TASK_KEY + ":" + tagName, AppStringUtils.objectToString(task));
}
/**
* 获取电子标签绑定的任务信息
* @param tagName 标签名称
* @return 任务信息
*/
public AppEtagTask getEtagTagTask(String tagName) {
String task = stringRedisTemplate.opsForValue().get(ETAG_TAG_TASK_KEY + ":" + tagName);
if(AppStringUtils.isEmpty(task)) {
return null;
}
return JSONObject.parseObject(task, AppEtagTask.class);
}
/**
* 删除电子标签绑定的任务信息
* @param tagName 标签名称
*/
public void removeEtagTagTask(String tagName) {
stringRedisTemplate.delete(ETAG_TAG_TASK_KEY + ":" + tagName);
}
/**
* 清空电子标签绑定的任务信息
*/
public void clearEtagTagTask() {
Set<String> keys = stringRedisTemplate.keys(ETAG_TAG_TASK_KEY + ":*");
stringRedisTemplate.delete(keys);
}
/**
* 判断电子标签绑定的任务信息是否存在
* @param tagName 标签名称
* @return 是否存在
*/
public boolean existsEtagTagTask(String tagName) {
return stringRedisTemplate.hasKey(ETAG_TAG_TASK_KEY + ":" + tagName);
}
/* ******************** 电子标签区域绑定的用户信息 *********************** */
/**
* 清空电子标签区域绑定的用户信息
*/
public void clearEtagAreaUser() {
Set<String> keys = stringRedisTemplate.keys(ETAG_AREA_USER_KEY + ":*");
stringRedisTemplate.delete(keys);
}
/**
* 获取电子标签区域绑定的用户信息
* @param areaId 区域ID
* @return 区域用户信息
*/
public String getEtagAreaUser(String areaId) {
String areaUser = stringRedisTemplate.opsForValue().get(ETAG_AREA_USER_KEY + ":" + areaId);
if(AppStringUtils.isEmpty(areaUser)) {
return null;
}
return areaUser;
}
/**
* 设置电子标签区域绑定的用户信息
* @param areaId 区域ID
* @param userId 用户ID
*/
public void setEtagAreaUser(String areaId, String userId) {
stringRedisTemplate.opsForValue().set(ETAG_AREA_USER_KEY + ":" + areaId, userId);
}
/* ******************** 电子标签颜色信息 *********************** */
/**
* 设置电子标签颜色信息
* @param tagName 标签名称
* @param ledColor 颜色
*/
public void setEtagTagColor(String tagName, LedColorEnum ledColor) {
stringRedisTemplate.opsForValue().set(ETAG_TAG_COLOR_KEY + ":" + tagName, String.valueOf(ledColor.getCode()));
}
/**
* 获取电子标签颜色信息
* @param tagName 标签名称
* @return 颜色
*/
public LedColorEnum getEtagTagColor(String tagName) {
String ledColor = stringRedisTemplate.opsForValue().get(ETAG_TAG_COLOR_KEY + ":" + tagName);
if(AppStringUtils.isEmpty(ledColor)) {
return null;
}
return LedColorEnum.getByCode(Integer.valueOf(ledColor));
}
/* ******************** 电子标签闪烁信息 *********************** */
/**
* 设置电子标签闪烁信息
* @param tagName 标签名称
* @param ledBlinkingEnum 闪烁模式
*/
public void setEtagTagBlinking(String tagName, LedBlinkingEnum ledBlinkingEnum) {
stringRedisTemplate.opsForValue().set(ETAG_TAG_BLINKING_KEY + ":" + tagName, String.valueOf(ledBlinkingEnum.getCode()));
}
/**
* 获取电子标签闪烁信息
* @param tagName 标签名称
* @return 闪烁模式
*/
public LedBlinkingEnum getEtagTagBlinking(String tagName) {
String ledBlinking = stringRedisTemplate.opsForValue().get(ETAG_TAG_BLINKING_KEY + ":" + tagName);
if(AppStringUtils.isEmpty(ledBlinking)) {
return null;
}
return LedBlinkingEnum.getByCode(Integer.valueOf(ledBlinking));
}
}

View File

@ -2,6 +2,8 @@ package org.wcs.constant.enums.database;
import lombok.Getter;
import java.util.List;
/**
* 电子标签种类
*/
@ -13,7 +15,7 @@ public enum ETagTypeEnum {
SCAN(3, "扫描枪"),
LIGHT(4, "单色灯"),
NUMBER_ENGLISH_BUTTON_12(5, "12位数字英文带按钮"),
NUMBER_CHINESE_BUTTON_12(6, "12位数字中文带按钮");
NUMBER_CHINESE_BUTTON_6(6, "6位数字中文带按钮");
private final Integer code;
private final String desc;
@ -23,4 +25,21 @@ public enum ETagTypeEnum {
this.desc = desc;
}
public static ETagTypeEnum getByCode(Integer code) {
for (ETagTypeEnum value : values()) {
if (value.code.equals(code)) {
return value;
}
}
return null;
}
/**
* 按钮标签列表
* @return 按钮标签列表
*/
public static List<ETagTypeEnum> buttonTagList() {
return List.of(NUMBER_BUTTON_3, NUMBER_BUTTON_7, NUMBER_ENGLISH_BUTTON_12, NUMBER_CHINESE_BUTTON_6);
}
}

View File

@ -0,0 +1,25 @@
package org.wcs.constant.enums.etag;
import lombok.Getter;
/**
* 电子标签数据提交的类型枚举
*/
@Getter
public enum EtagSubCommandEnum {
CONFIRM_COMMAND(6, "确认键按下提交"),
OUT_STOCK(7, "缺货"), // 注意当用户修改数据低于发送的数据时会返回此状态
CONNECT_TIMEOUT(10, "通讯超时"),
BUTTON_STUCK(13, "按键卡死"),
ERR_INSTRUCTION(12, "指令错误");
private Integer code;
private String desc;
EtagSubCommandEnum(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
}

View File

@ -0,0 +1,50 @@
package org.wcs.constant.enums.etag;
import lombok.Getter;
/**
* 标签闪烁频率
*/
@Getter
public enum LedBlinkingEnum {
LED_OFF(0, "关闭"),
LED_ON(1, "打开,常亮"),
BLINKING_2(2, "2秒闪烁一次"),
BLINKING_1(3, "1秒闪烁一次"),
BLINKING_0_5(4, "0.5秒闪烁一次"),
BLINKING_0_25(5, "0.25秒闪烁一次");
private final Integer code;
private final String desc;
LedBlinkingEnum(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
public static LedBlinkingEnum getByCode(Integer code) {
for (LedBlinkingEnum value : LedBlinkingEnum.values()) {
if (value.code.equals(code)) {
return value;
}
}
return null;
}
/**
* 获取闪烁频率对应的二进制字符串
* @param ledBlinking 闪烁频率
* @return 二进制字符串
*/
public static String getBlinkingBitString(LedBlinkingEnum ledBlinking) {
return switch (ledBlinking) {
case LED_OFF -> "000";
case LED_ON -> "001";
case BLINKING_2 -> "010";
case BLINKING_1 -> "011";
case BLINKING_0_5 -> "100";
case BLINKING_0_25 -> "101";
};
}
}

View File

@ -0,0 +1,54 @@
package org.wcs.constant.enums.etag;
import lombok.Getter;
/**
* 电子标签灯按钮颜色
*/
@Getter
public enum LedColorEnum {
RED(0, "红色"),
GREEN(1, "绿色"),
ORANGE(2, "橙色"),
BLUE(3, "蓝色"),
PINK(4, "粉色"),
CYAN(5, "青色");
private final Integer code;
private final String desc;
LedColorEnum(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
public static LedColorEnum getByCode(Integer code) {
for (LedColorEnum value : LedColorEnum.values()) {
if (value.code.equals(code)) {
return value;
}
}
return null;
}
/**
* 获取灯颜色对应的二进制字符串 ---- 仅适用于单色灯需要和其他字符串拼接使用
* @param ledColor 灯颜色
* @return 二进制字符串
*/
public static String getLightColorBitString(LedColorEnum ledColor) {
return switch (ledColor) {
case RED -> "000";
case GREEN -> "001";
case ORANGE -> "010";
case BLUE -> "011";
case PINK -> "100";
case CYAN -> "101";
};
}
}

View File

@ -65,6 +65,23 @@ public class AppEtagControllerInfoDao extends ServiceImpl<AppEtagControllerInfoM
}
}
/**
* 根据状态查询电子标签控制器基础数据
* @param status 状态
* @return 响应
*/
@Override
public List<AppEtagControllerInfo> queryEtagControllerInfoByStatus(Integer status) {
try {
LambdaQueryWrapper<AppEtagControllerInfo> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(AppEtagControllerInfo::getControllerStatus, status);
queryWrapper.orderByAsc(AppEtagControllerInfo::getControllerId);
return baseMapper.selectList(queryWrapper);
} catch (Exception e) {
return null;
}
}
/**
* 添加电子标签控制器基础数据
* @param appEtagControllerInfo 添加参数

View File

@ -67,6 +67,19 @@ public class AppEtagTagInfoDao extends ServiceImpl<AppEtagTagInfoMapper, AppEtag
}
}
/**
* 查询所有电子标签小标签信息
* @return 响应
*/
@Override
public List<AppEtagTagInfo> queryAll() {
try {
return super.list();
} catch (Exception e) {
return null;
}
}
/**
* 添加电子标签小标签信息
* @param appEtagTagInfo 添加参数

View File

@ -103,6 +103,19 @@ public class AppEtagTagLocationDao extends ServiceImpl<AppEtagTagLocationMapper,
}
}
/**
* 查询所有电子标签库位信息
* @return 响应
*/
@Override
public List<AppEtagTagLocation> queryAll() {
try {
return super.list();
} catch (Exception e) {
return null;
}
}
/**
* 修改电子标签库位信息
* @param appEtagTagLocation 修改参数

View File

@ -11,6 +11,7 @@ public interface AppEtagControllerInfoService extends IService<AppEtagController
Tuple2<Long, List<AppEtagControllerInfo>> queryEtagControllerInfo(EtagControllerQueryReq request, Integer pageSize, Integer pageIndex);
List<AppEtagControllerInfo> queryEtagControllerInfoById(Integer etagControllerId);
List<AppEtagControllerInfo> queryEtagControllerInfoByStatus(Integer status);
int insertEtagControllerInfo(AppEtagControllerInfo appEtagControllerInfo); // 添加电子标签控制器基础数据
int updateEtagControllerInfo(AppEtagControllerInfo appEtagControllerInfo); // 修改电子标签控制器基础数据
int deleteEtagControllerInfoById(Integer etagControllerId); // 删除电子标签控制器基础数据

View File

@ -15,6 +15,7 @@ public interface AppEtagTagInfoService extends IService<AppEtagTagInfo> {
Tuple2<Long, List<AppEtagTagInfo>> queryEtagTagInfo(EtagTagInfoQueryReq request, Integer pageSize, Integer pageIndex);
List<AppEtagTagInfo> queryEtagTagInfoByTagName(String tagName); // 通过标签名称查询
List<AppEtagTagInfo> queryAll(); // 查询所有
DataBaseActionResult<Integer> insert(AppEtagTagInfo appEtagTagInfo); // 添加电子标签小标签基础信息
DataBaseActionResult<Integer> update(AppEtagTagInfo appEtagTagInfo); // 修改电子标签小标签基础信息
DataBaseActionResult<Integer> deleteByTagName(String tagName); // 删除电子标签小标签基础信息

View File

@ -14,6 +14,7 @@ public interface AppEtagTagLocationService extends IService<AppEtagTagLocation>
List<AppEtagTagLocation> queryWithLocationAndType(String location, Integer locationType); // 查询指定货位和货位类型的数据
DataBaseActionResult<Integer> insert(AppEtagTagLocation appEtagTagLocation); // 插入一条数据
List<AppEtagTagLocation> queryWithRecordId(String recordId); // 查询指定记录ID的数据
List<AppEtagTagLocation> queryAll(); // 查询所有数据
DataBaseActionResult<Integer> updateAll(AppEtagTagLocation appEtagTagLocation); // 更新一条数据
DataBaseActionResult<Integer> deleteWithRecordId(String recordId); // 删除指定记录ID的数据
}

View File

@ -0,0 +1,137 @@
package org.wcs.model.bo.etag;
import lombok.Getter;
import lombok.Setter;
import org.wcs.constant.enums.etag.LedBlinkingEnum;
import org.wcs.constant.enums.etag.LedColorEnum;
/**
* 点亮标签参数
*/
@Getter
public class EtagLightParams {
/**
* 标签种类
*/
private String tagName;
/**
* 标签ID
*/
@Setter
private byte tagId;
/**
* 标签值
*/
private String tagValue;
/**
* 显示标签字符串
*/
private String tagString;
/**
* 闪烁频率
*/
private LedBlinkingEnum ledBlinking;
/**
* 灯颜色
*/
private LedColorEnum ledColor;
/**
* 构建开始
* @return 新实例
*/
public static EtagLightParams buildStart() {
return new EtagLightParams();
}
/**
* 设置标签名称
* @param tagName 标签名称
* @return 设置结果
*/
public EtagLightParams tagName(String tagName) {
this.tagName = tagName;
return this;
}
/**
* 设置标签值
* @param tagValue 标签值
* @return 设置结果
*/
public EtagLightParams tagValue(String tagValue) {
this.tagValue = tagValue;
return this;
}
/**
* 显示标签字符串
* @param tagString 标签字符串
* @return 设置结果
*/
public EtagLightParams tagString(String tagString) {
this.tagString = tagString;
return this;
}
/**
* 闪烁频率
* @param ledBlinking 闪烁频率
* @return 设置结果
*/
public EtagLightParams ledBlinking(LedBlinkingEnum ledBlinking) {
this.ledBlinking = ledBlinking;
return this;
}
/**
* 灯颜色
* @param ledColor led颜色
* @return 设置结果
*/
public EtagLightParams ledColor(LedColorEnum ledColor) {
this.ledColor = ledColor;
return this;
}
/**
* 构建结束
* @return 构建结果
*/
public EtagLightParams buildEnd() {
if(this.tagValue == null) {
this.tagValue = "888";
}
if(this.tagString == null) {
this.tagString = "未设置文本";
}
if(this.ledBlinking == null) {
this.ledBlinking = LedBlinkingEnum.BLINKING_0_25;
}
if(this.ledColor == null) {
this.ledColor = LedColorEnum.GREEN;
}
return this;
}
@Override
public String toString() {
return "EtagLightParams{" +
"tagName='" + tagName + '\'' +
", tagId=" + tagId +
", tagValue='" + tagValue + '\'' +
", tagString='" + tagString + '\'' +
", ledBlinking=" + ledBlinking +
", ledColor=" + ledColor +
'}';
}
}

View File

@ -0,0 +1,73 @@
package org.wcs.model.bo.etag;
import lombok.Data;
/**
* 电子标签数据返回类
*/
@Data
public class EtagReturnInfo {
/**
* 控制器 id
*/
private String controllerId;
/**
* 按键类型
* @remark Data(1)= 16H confirmatin key pressed
* /// 43H shotage button/down-count button pressed
* /// 25H function button/up-count button pressed.
*/
private Integer keyType;
/**
* 消息类型
* @remark 01H:Tag busy,04H 功能键
*/
private Integer msgType;
/**
* 提交命令
* @remark 13卡键
* /// 10 通讯超时
*/
private Integer subCommand;
/**
* ip
*/
private String ip;
/**
* 标签 id
*/
private Integer tagId;
/**
* 端口注意这里端口使标签提交的端口不是控制器的ip端口
*/
private Integer etagPort;
/**
* 返回的数据
*/
private String data;
@Override
public String toString() {
return "EtagReturnInfo{" +
"controllerId=" + controllerId +
", keyType=" + keyType +
", msgType=" + msgType +
", subCommand=" + subCommand +
", ip='" + ip + '\'' +
", tagId=" + tagId +
", etagPort=" + etagPort +
", data='" + data + '\'' +
'}';
}
}

View File

@ -46,7 +46,7 @@ public class SocketClient {
*/
public synchronized void addSocketDataItem(SocketDataItem socketDataItem) {
if (socketDataItemList == null) {
socketDataItemList = new java.util.ArrayList<>();
socketDataItemList = new ArrayList<>();
}
List<SocketDataItem> checkExist = socketDataItemList.stream().filter(item -> item.getSocketId().equals(socketDataItem.getSocketId())).toList();
if (!checkExist.isEmpty()) {
@ -113,7 +113,7 @@ public class SocketClient {
* 连接Socket
* @param socketDataItemList Socket数据项列表
*/
public void connect(List<SocketDataItem> socketDataItemList) {
private void connect(List<SocketDataItem> socketDataItemList) {
for (SocketDataItem socketDataItem : socketDataItemList) {
Thread thread = new Thread(() -> {
connect(socketDataItem);
@ -126,7 +126,7 @@ public class SocketClient {
* 连接Socket
* @param socketDataItem Socket数据项
*/
public void connect(SocketDataItem socketDataItem) {
private void connect(SocketDataItem socketDataItem) {
Socket socket = socketDataItem.getSocket();
if(socket != null) {
try {
@ -150,10 +150,11 @@ public class SocketClient {
while (true) {
try {
InputStream inputStream = socket.getInputStream();
byte[] bytes =inputStream.readAllBytes();
String message = new String(bytes, StandardCharsets.US_ASCII);
byte[] bytes = inputStream.readAllBytes();
socketDataItem.setLastReceiveMessageTime(LocalDateTime.now());
if(socketClientEvent != null) {
socketClientEvent.onBytes(socketDataItem, bytes);
String message = new String(bytes, StandardCharsets.US_ASCII);
socketClientEvent.onMessage(socketDataItem, message); // 触发收到数据事件
}
} catch (Exception e) {
@ -178,11 +179,22 @@ public class SocketClient {
}
}
/**
* 检查并重新连接
*/
public void checkAndReconnect() {
List<SocketDataItem> disConnectSocketDataItems = getDisConnectSocket();
if (disConnectSocketDataItems != null) {
connect(disConnectSocketDataItems);
}
}
/**
* 获取断开的Socket数据项
* @return 断开的Socket数据项
*/
public synchronized List<SocketDataItem> getDisConnectSocket() {
private synchronized List<SocketDataItem> getDisConnectSocket() {
if(socketDataItemList == null) {
return null;
}
@ -205,7 +217,10 @@ public class SocketClient {
* @param socketDataItem Socket数据项
* @return 是否连接
*/
public boolean isConnected(SocketDataItem socketDataItem) {
private boolean isConnected(SocketDataItem socketDataItem) {
if(socketDataItem.getSocketStatus() == SocketStatusEnum.CONNECTING || socketDataItem.getSocketStatus() == SocketStatusEnum.CREATE) {
return true; // 正在连接或者新创建的视为已连接
}
if(socketDataItem.getSocketStatus() != SocketStatusEnum.CONNECTED || socketDataItem.getSocket() == null) {
socketDataItem.setSocketStatus(SocketStatusEnum.DISCONNECTED);
return false;
@ -287,15 +302,22 @@ public class SocketClient {
if(socketDataItem == null || socketDataItem.getSocket() == null) {
return "Socket连接不存在或者未连接";
}
Socket socket = socketDataItem.getSocket();
synchronized (socket) {
try(OutputStream outputStream = socket.getOutputStream()) {
try {
byte[] bytes = message.getBytes(StandardCharsets.US_ASCII);
OutputStream outputStream = socketDataItem.getSocket().getOutputStream();
outputStream.write(bytes);
outputStream.flush();
return null;
} catch (Exception e) {
return "发送失败,异常信息:" + e.getMessage();
}
} catch (IOException e) {
return "发送失败,异常信息:" + e.getMessage();
}
}
}
/**
@ -326,14 +348,20 @@ public class SocketClient {
if(socketDataItem == null || socketDataItem.getSocket() == null) {
return "Socket连接不存在或者未连接";
}
Socket socket = socketDataItem.getSocket();
synchronized (socket) {
try (OutputStream outputStream = socket.getOutputStream()) {
try {
OutputStream outputStream = socketDataItem.getSocket().getOutputStream();
outputStream.write(bytes);
outputStream.flush();
return null;
} catch (Exception e) {
return "发送失败,异常信息:" + e.getMessage();
}
} catch (Exception e) {
return "发送失败,异常信息:" + e.getMessage();
}
}
}

View File

@ -23,6 +23,13 @@ public interface ISocketClientEvent {
*/
void onMessage(SocketDataItem socketDataItem, String message);
/**
* 接收到字节
* @param socketDataItem SocketDataItem
* @param bytes 字节
*/
void onBytes(SocketDataItem socketDataItem, byte[] bytes);
/**
* 错误
* @param socketDataItem SocketDataItem

View File

@ -76,6 +76,68 @@ public class SocketDataItem {
return socketDataItem;
}
/**
* 设置SocketId
* @param socketId SocketId
* @return SocketDataItem
*/
public SocketDataItem setSocketId(String socketId) {
this.socketId = socketId;
return this;
}
/**
* 设置Socket IP
* @param ip Socket IP
* @return SocketDataItem
*/
public SocketDataItem setIp(String ip) {
this.socketIp = ip;
return this;
}
/**
* 端口
* @param port 端口
* @return SocketDataItem
*/
public SocketDataItem setPort(int port) {
this.socketPort = port;
return this;
}
/**
* 标记
* @param tag 标记
* @return SocketDataItem
*/
public SocketDataItem setTag(String tag) {
this.socketTag = tag;
return this;
}
/**
* 心跳包内容
* @param heartBeatString 心跳包内容
* @return SocketDataItem
*/
public SocketDataItem setHeartBeatString(String heartBeatString) {
this.heartBeatString = heartBeatString;
return this;
}
/**
* 自动重连
* @param autoReconnect 自动重连
* @return SocketDataItem
*/
public SocketDataItem setAutoReconnect(boolean autoReconnect) {
this.autoReconnect = autoReconnect;
return this;
}
/**
* 构建结束
* @return SocketDataItem

View File

@ -0,0 +1,146 @@
package org.wcs.quartzJob;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.wcs.business.etag.EtagCommon;
import org.wcs.business.etag.EtagDataHandler;
import org.wcs.business.redis.EtagRedis;
import org.wcs.constant.enums.common.OnOrOffEnum;
import org.wcs.constant.enums.common.TrueOrFalseEnum;
import org.wcs.mapper.intf.AppEtagControllerInfoService;
import org.wcs.mapper.intf.AppEtagTagInfoService;
import org.wcs.mapper.intf.AppEtagTagLocationService;
import org.wcs.model.po.app.AppEtagControllerInfo;
import org.wcs.model.po.app.AppEtagTagInfo;
import org.wcs.model.po.app.AppEtagTagLocation;
import org.wcs.plugin.tcp.SocketClient;
import org.wcs.plugin.tcp.intf.ISocketClientEvent;
import org.wcs.plugin.tcp.model.SocketDataItem;
import java.util.List;
/**
* 电子标签定时任务类
*/
@Slf4j
@DisallowConcurrentExecution
@RequiredArgsConstructor
public class EtagJob implements Job {
private final EtagRedis etagRedis; // 电子标签 redis 操作类
private final EtagDataHandler etagDataHandler; // 电子标签数据处理类
private final AppEtagControllerInfoService etagControllerInfoService; // 控制器信息数据表操作类
private final AppEtagTagInfoService etagTagInfoService; // 电子标签小标信息数据表操作类
private final AppEtagTagLocationService etagTagLocationService; // 电子标签位置信息数据表操作类
// 是否正在加载基础数据
private static boolean isLoadingBaseData = false;
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
loadBaseData(); // 加载基础资料
connectController(); // 连接电子标签控制器
if(EtagCommon.socketClient == null || !isLoadingBaseData) {
return;
}
}
/**
* 点亮小标签
*/
private void lightSmallTag() {
}
/**
* 加载基础资料
*/
private void loadBaseData() {
if(isLoadingBaseData) {
return;
}
// 加载基础小标签信息
List<AppEtagTagInfo> etagTagInfos = etagTagInfoService.queryAll();
if(etagTagInfos == null) {
return;
}
etagRedis.clearEtagTag();
for (AppEtagTagInfo etagTagInfo : etagTagInfos) {
etagRedis.setEtagTag(etagTagInfo.getTagName(), etagTagInfo);
}
// 加载基础标签位置信息
List<AppEtagTagLocation> etagTagLocations = etagTagLocationService.queryAll();
if(etagTagLocations == null) {
return;
}
etagRedis.clearEtagLocation();
for (AppEtagTagLocation etagTagLocation : etagTagLocations) {
etagRedis.setEtagLocation(etagTagLocation.getLocation(), etagTagLocation);
}
isLoadingBaseData = true;
}
/**
* 连接电子标签控制器
*/
private void connectController() {
if(EtagCommon.socketClient != null) {
EtagCommon.socketClient.checkAndReconnect();
return;
}
List<AppEtagControllerInfo> etagControllerInfoList = etagControllerInfoService.queryEtagControllerInfoByStatus(OnOrOffEnum.TRUE.getCode());
if(etagControllerInfoList == null) {
return;
}
EtagCommon.socketClient = new SocketClient();
EtagCommon.socketClient.setSocketClientEvent(new ISocketClientEvent() {
@Override
public void onConnect(SocketDataItem socketDataItem) {
log.info("电子标签控制器:{} 连接成功IP{},端口:{}", socketDataItem.getSocketId(), socketDataItem.getSocketIp(), socketDataItem.getSocketPort());
// TODO 连接成功后应当重新点亮这个控制器下的标签
}
@Override
public void onDisconnect(SocketDataItem socketDataItem) {
log.info("电子标签控制器:{} 断开连接IP{},端口:{}", socketDataItem.getSocketId(), socketDataItem.getSocketIp(), socketDataItem.getSocketPort());
}
@Override
public void onMessage(SocketDataItem socketDataItem, String message) {
}
@Override
public void onBytes(SocketDataItem socketDataItem, byte[] bytes) {
etagDataHandler.receiveBytes(socketDataItem, bytes);
}
@Override
public void onError(SocketDataItem socketDataItem, Throwable throwable) {
log.error("电子标签控制器:{} 连接异常IP{},端口:{}", socketDataItem.getSocketId(), socketDataItem.getSocketIp(), socketDataItem.getSocketPort(), throwable);
}
});
for (AppEtagControllerInfo etagControllerInfo : etagControllerInfoList) {
EtagCommon.socketClient.addSocketDataItem(SocketDataItem.buildStart()
.setSocketId(etagControllerInfo.getControllerId().toString())
.setIp(etagControllerInfo.getIp())
.setPort(etagControllerInfo.getPort())
.setTag(etagControllerInfo.getControllerName())
.setHeartBeatString("")
.buildEnd());
}
EtagCommon.socketClient.connectAll();
}
}

View File

@ -5,6 +5,7 @@ import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import org.wcs.model.bo.tuple.Tuple2;
import java.io.UnsupportedEncodingException;
import java.util.Base64;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -217,4 +218,45 @@ public class AppStringUtils {
}
/**
* 将字符串以GBK方式转换
* @param string 字符串
* @return 转换结果
*/
public static byte[] toByteArrayGBK(String string) {
try {
return string.getBytes("GBK");
} catch (UnsupportedEncodingException e) {
return null;
}
}
/**
* 在左边补充字符到指定长度
* @param str 要补充的字符串
* @param c 补充的字符
* @param length 长度
* @return 结果
*/
public static String padLeft(String str, String c, int length) {
if(isEmpty(str)) {
return c.repeat(length);
}
return c.repeat(Math.max(0, length - str.length())) + str;
}
/**
* 在右边补充字符到指定长度
* @param str 要补充的字符串
* @param c 补充的字符
* @param length 长度
* @return 结果
*/
public static String padRight(String str, String c, int length) {
if(isEmpty(str)) {
return c.repeat(length);
}
return str + c.repeat(Math.max(0, length - str.length()));
}
}

View File

@ -0,0 +1,39 @@
package org.wcs.utils;
/**
* 数据转换类
*/
public class Converter {
/**
* int转byte
* @param value int值
* @return byte值
*/
public static byte toByte(int value) {
if(value < Byte.MIN_VALUE || value > Byte.MAX_VALUE){
throw new IllegalArgumentException("value is not in byte range");
}
return (byte) value;
}
/**
* 二进制字符串转 byte
* @param value 二进制字符串
* @return byte值
*/
public static byte toByte(String value) {
int intValue = Integer.parseInt(value, 2);
return toByte(intValue);
}
/**
* byte转二进制字符串
* @param value byte值
* @return 转换过后的二进制字符串
*/
public static String toBinaryString(byte value) {
String binaryString = Integer.toBinaryString(value & 0xFF);
return String.format("%8s", binaryString).replace(' ', '0');
}
}