添加一部分LED屏TCP通讯的代码

This commit is contained in:
葛林强 2026-02-26 15:36:34 +08:00
parent 81407e0fe4
commit f7c1f7a82d
11 changed files with 462 additions and 9 deletions

View File

@ -1,4 +1,4 @@
package org.wcs.plugin.lxLed; package com.listenvision;
/********************************************************************************************* /*********************************************************************************************
* LedServerCallback 动态库回调Java方法实时告知上下线控制卡 * LedServerCallback 动态库回调Java方法实时告知上下线控制卡

View File

@ -1,9 +1,9 @@
package org.wcs.plugin.lxLed; package com.listenvision;
public class LxLedCommunication { public class LxLedCommunication {
static{ static{
System.loadLibrary("lv_led_64"); System.loadLibrary("lv_led");
} }
/******************************************************************************************** /********************************************************************************************

Binary file not shown.

View File

@ -0,0 +1,3 @@
此软件包是灵信LED屏通讯的相关方法严禁修改包名已经上级包名修改了就调用不了了
只能64位运行32位无法运行
如连接失败请检查导入的DLL是否正确官网的依赖是否都安装官网依赖仅支持Windows系统

View File

@ -1,14 +1,11 @@
package org.wcs.business.led; package org.wcs.business.led;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.wcs.model.bo.tuple.Tuple2;
import org.wcs.model.pojo.led.LedBaseInfo;
import org.wcs.model.pojo.led.LedDataDetail; import org.wcs.model.pojo.led.LedDataDetail;
import org.wcs.model.pojo.led.LedShowData; import org.wcs.model.pojo.led.LedShowData;
import org.wcs.plugin.lxLed.LxLedCommunication; import com.listenvision.LxLedCommunication;
import java.util.List; import java.util.List;
import java.util.Optional;
/** /**
* 灵信LED屏操作类 * 灵信LED屏操作类

View File

@ -0,0 +1,224 @@
package org.wcs.plugin.lxLed;
import org.wcs.model.bo.tuple.Tuple2;
import org.wcs.plugin.lxLed.model.LedAreaData;
import org.wcs.utils.AppListUtils;
import org.wcs.utils.Converter;
import java.util.ArrayList;
import java.util.List;
/**
* 灵信LED屏数据创建器
*/
public class LedDataCreator {
/**
* 屏幕宽
*/
private short ledWight = 0;
/**
* 屏幕高
*/
private short ledHeight = 0;
/**
* 颜色类型1-单色2-双色3-三色
*/
private byte ledColorType = 1;
/**
* 区域数据列表
*/
public List<LedAreaData> areaDataList;
/**
* 设置屏幕参数
* @param ledWight 屏幕宽
* @param ledHeight 屏幕高
* @param ledColorType 颜色类型1-单色2-双色3-三色
*/
public void setLedParam(short ledWight, short ledHeight, byte ledColorType) {
this.ledWight = ledWight;
this.ledHeight = ledHeight;
this.ledColorType = ledColorType;
}
/**
* 添加区域数据
* @param areaData 区域数据
*/
public void addAreaData(LedAreaData areaData) {
if (areaDataList == null) {
areaDataList = new ArrayList<>();
}
areaDataList.add(areaData);
}
/**
* 创建数据
* @return 数据
*/
public Tuple2<String,List<Byte>> create() {
if(ledWight <= 0 || ledHeight <= 0) {
return new Tuple2<>("屏幕宽或屏幕高不能小于等于0", null);
}
Tuple2<String, List<Byte>> program = createProgram();
if(program.item1 != null) {
return program; // 创建失败
}
List<Byte> dataBytes = new ArrayList<>();
// 起始数据
dataBytes.addAll(createStartBytes());
// 控制器型号 ---- 默认全部型号
dataBytes.add((byte) 0);
dataBytes.add((byte) 0);
dataBytes.add((byte) 0);
dataBytes.add((byte) 0);
dataBytes.add((byte) 0);
dataBytes.add((byte) 0);
dataBytes.add((byte) 0);
dataBytes.add((byte) 0);
dataBytes.add((byte) 0);
dataBytes.add((byte) 0);
dataBytes.add((byte) 0);
dataBytes.add((byte) 0);
dataBytes.add((byte) 0);
dataBytes.add((byte) 0);
dataBytes.add((byte) 0);
dataBytes.add((byte) 0);
// 屏幕参数
dataBytes.addAll(AppListUtils.transfer(Converter.toBytes(ledWight)).reversed()); // 屏幕宽
dataBytes.addAll(AppListUtils.transfer(Converter.toBytes(ledHeight)).reversed()); // 屏幕高
// 颜色类型
dataBytes.add(ledColorType);
// 节目个数
dataBytes.add((byte) 1);
// 不用字节
dataBytes.add((byte) 0);
dataBytes.add((byte) 0);
dataBytes.add((byte) 0);
dataBytes.add((byte) 0);
dataBytes.add((byte) 0);
dataBytes.add((byte) 0);
dataBytes.add((byte) 0);
dataBytes.add((byte) 0);
// 节目数据
dataBytes.addAll(program.item2);
// 结束数据
dataBytes.addAll(createEndBytes());
return new Tuple2<>(null, dataBytes);
}
/**
* 创建节目
* @return 节目
*/
private Tuple2<String,List<Byte>> createProgram() {
if(areaDataList == null || areaDataList.isEmpty()) {
return new Tuple2<>("节目未添加区域", null);
}
List<Byte> bytes = new ArrayList<>();
// 节目号
bytes.add((byte) 0);
// 节目数据大小 ---- 先临时赋值
bytes.add((byte) 0);
bytes.add((byte) 0);
bytes.add((byte) 0);
bytes.add((byte) 0);
//节目中区域个数
bytes.add((byte) areaDataList.size());
// 节目循环播放数
bytes.add((byte) 0);
bytes.add((byte) 0);
// 循环播放次数
bytes.add((byte) 1);
// 节目定时属性 ---- 无效
bytes.add((byte) 0);
bytes.add((byte) 0);
bytes.add((byte) 0);
bytes.add((byte) 0);
bytes.add((byte) 0);
bytes.add((byte) 0);
bytes.add((byte) 0);
bytes.add((byte) 0);
bytes.add((byte) 0);
bytes.add((byte) 0);
bytes.add((byte) 0);
bytes.add((byte) 0);
bytes.add((byte) 0);
bytes.add((byte) 0);
bytes.add((byte) 0);
bytes.add((byte) 0);
// 区域数据
for (LedAreaData areaData : areaDataList) {
bytes.addAll(areaData.create());
}
// 节目数据大小
int size = bytes.size();
byte[] bytesSize = Converter.toBytes(size);
bytes.set(1, bytesSize[3]);
bytes.set(2, bytesSize[2]);
bytes.set(3, bytesSize[1]);
bytes.set(4, bytesSize[0]);
bytes.addAll(createEndBytes());
return new Tuple2<>(null, bytes);
}
/**
* 创建起始字节
* @return 起始字节
*/
private List<Byte> createStartBytes() {
List<Byte> bytes = new ArrayList<>();
// 起始字节
bytes.add((byte) 0x55);
bytes.add((byte) 0xAA);
bytes.add((byte) 0x00);
bytes.add((byte) 0x00);
// 地址
bytes.add((byte) 0x01);
// 标志
bytes.add((byte) 0x01);
// 操作码
bytes.add((byte) 0x00);
bytes.add((byte) 0xD9);
// 保留
bytes.add((byte) 0x00);
bytes.add((byte) 0x00);
// 帧序号
bytes.add((byte) 0x00);
bytes.add((byte) 0x00);
bytes.add((byte) 0x00);
bytes.add((byte) 0x00);
// 总长度 ---- 默认不给控制卡可自动计算
bytes.add((byte) 0x00);
bytes.add((byte) 0x00);
bytes.add((byte) 0x00);
bytes.add((byte) 0x00);
// 帧长度 ---- 默认不给控制卡可自动计算
bytes.add((byte) 0x00);
bytes.add((byte) 0x00);
return bytes;
}
/**
* 创建结束字节
* @return 结束字节
*/
private List<Byte> createEndBytes() {
List<Byte> bytes = new ArrayList<>();
// 结束字节
bytes.add((byte) 0x00);
bytes.add((byte) 0x00);
bytes.add((byte) 0x0D);
bytes.add((byte) 0x0A);
return bytes;
}
}

View File

@ -0,0 +1,21 @@
package org.wcs.plugin.lxLed.enums;
import lombok.Getter;
/**
* LED屏显示的文字颜色枚举
*/
@Getter
public enum TextColorEnum {
RED(128, "红色"), // 红色
GREEN(64, "绿色"), // 绿色
BLUE(32, "蓝色"); // 蓝色
private final int value;
private final String name;
TextColorEnum(int value, String name) {
this.value = value;
this.name = name;
}
}

View File

@ -0,0 +1,30 @@
package org.wcs.plugin.lxLed.enums;
import lombok.Getter;
/**
* 灵信LED屏文字滚动效果枚举
*/
@Getter
public enum TextEffectEnum {
SHOW_IMMEDIATELY(1, "立即显示"),
TO_LEFT(2, "向左滚动"),
TO_RIGHT(4, "向右滚动"),
TO_UP(3, "向上滚动"),
TO_DOWN(5, "向下滚动"),
TO_UP_CONTINUOUS(94, "向上滚动不间断"),
TO_DOWN_CONTINUOUS(95, "向下滚动不间断"),
TO_LEFT_CONTINUOUS(97, "向左滚动不间断"),
TO_RIGHT_CONTINUOUS(96, "向右滚动不间断"),
BLINK(6, "闪烁");
private final int code;
private final String name;
TextEffectEnum(int code, String name) {
this.code = code;
this.name = name;
}
}

View File

@ -0,0 +1,129 @@
package org.wcs.plugin.lxLed.model;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import org.wcs.plugin.lxLed.enums.TextColorEnum;
import org.wcs.plugin.lxLed.enums.TextEffectEnum;
import org.wcs.utils.AppListUtils;
import org.wcs.utils.AppStringUtils;
import org.wcs.utils.Converter;
import java.util.ArrayList;
import java.util.List;
/**
* 灵信LED屏每个区域的数据
*/
@Getter
@Setter
@Builder
public class LedAreaData {
/**
* 区域的起始X坐标
*/
private short startX;
/**
* 区域的起始Y坐标
*/
private short startY;
/**
* 区域的结束X坐标
*/
private short endX;
/**
* 区域的结束Y坐标
*/
private short endY;
/**
* 区域的文字颜色
*/
@Builder.Default
private TextColorEnum textColor = TextColorEnum.RED;
/**
* 区域的文字效果
*/
@Builder.Default
private TextEffectEnum textEffect = TextEffectEnum.SHOW_IMMEDIATELY;
/**
* 区域的文字效果速度越小越快范围 1-64
*/
@Builder.Default
private byte effectSpeed = 10;
/**
* 区域的文字每页显示时间
*/
@Builder.Default
private short showTime = 2;
/**
* 区域的文字大小
*/
@Builder.Default
private byte textSize = 12;
/**
* 区域的文字内容
*/
private String text;
/**
* 创建区域数据
* @return 区域数据
*/
public List<Byte> create() {
List<Byte> bytes = new ArrayList<>();
// 区域用途
bytes.add((byte) 1);
// 区域数据大小 ---- 先临时赋值
bytes.add((byte) 0);
bytes.add((byte) 0);
bytes.add((byte) 0);
bytes.add((byte) 0);
// 区域类型
bytes.add((byte) 0x0E);
// 坐标
bytes.addAll(AppListUtils.transfer(Converter.toBytes(startX)).reversed());
bytes.addAll(AppListUtils.transfer(Converter.toBytes(startY)).reversed());
bytes.addAll(AppListUtils.transfer(Converter.toBytes(endX)).reversed());
bytes.addAll(AppListUtils.transfer(Converter.toBytes(endY)).reversed());
// 文字颜色
bytes.add((byte) textColor.getValue());
bytes.add((byte) 0);
bytes.add((byte) 0);
bytes.add((byte) 0);
// 文字效果
bytes.add((byte) textEffect.getCode());
// 效果速度
bytes.add(effectSpeed);
// 显示时间
bytes.addAll(AppListUtils.transfer(Converter.toBytes(showTime)).reversed());
// 文字大小
bytes.add(textSize);
// 文本字符串
byte[] byteArrayGBK = AppStringUtils.toByteArrayGBK(text);
if (byteArrayGBK != null) {
// 文本字符串字节数
bytes.addAll(AppListUtils.transfer(Converter.toBytes(byteArrayGBK.length)).reversed());
// 文本字符串字节
bytes.addAll(AppListUtils.transfer(byteArrayGBK).reversed());
}
int bytesLength = bytes.size();
byte[] bytesLengthBytes = Converter.toBytes(bytesLength);
bytes.set(1, bytesLengthBytes[3]);
bytes.set(2, bytesLengthBytes[2]);
bytes.set(3, bytesLengthBytes[1]);
bytes.set(4, bytesLengthBytes[0]);
return bytes;
}
}

View File

@ -17,6 +17,54 @@ public class Converter {
return (byte) value; return (byte) value;
} }
/**
* int转byte数组
* @param value int值
* @return byte数组
*/
public static byte[] toBytes(int value) {
return new byte[]{
(byte) (value >>> 24),
(byte) (value >>> 16),
(byte) (value >>> 8),
(byte) value
};
}
/**
* byte数组转int
* @param bytes byte数组
* @return int值
*/
public static int bytesToInt(byte[] bytes) {
return (bytes[0] & 0xFF) << 24 |
(bytes[1] & 0xFF) << 16 |
(bytes[2] & 0xFF) << 8 |
(bytes[3] & 0xFF);
}
/**
* short转byte数组
* @param value short值
* @return byte数组
*/
public static byte[] toBytes(short value) {
return new byte[]{
(byte) (value >>> 8),
(byte) value
};
}
/**
* byte数组转short
* @param bytes byte数组
* @return short值
*/
public static short bytesToShort(byte[] bytes) {
return (short) ((bytes[0] & 0xFF) << 8 |
(bytes[1] & 0xFF));
}
/** /**
* 二进制字符串转 byte * 二进制字符串转 byte
* @param value 二进制字符串 * @param value 二进制字符串

View File

@ -21,11 +21,12 @@
const response = JSON.parse(JSON.stringify(res.data)) as AppServeResponse; const response = JSON.parse(JSON.stringify(res.data)) as AppServeResponse;
if (response && response.code == AppServeResponseCodeEnum.SUCCESS) { if (response && response.code == AppServeResponseCodeEnum.SUCCESS) {
MessageUtils.successMessage(t('baseTip.success')); MessageUtils.successMessage(t('baseTip.success'));
router.push({name:'login'});
} else { } else {
MessageUtils.warningMessageBox(response.msg); MessageUtils.warningMessageBox(response.msg);
} }
}).catch(() => {}); }).catch(() => {}).finally(() => {
router.push({name:'login'});
});
}).catch(() => {}) }).catch(() => {})
}; };
// //