feat(sis):

- 优化电梯控制逻辑,支持外部按键触发
This commit is contained in:
2025-08-09 23:22:06 +08:00
parent e47a13c214
commit 054a8590ea
14 changed files with 312 additions and 163 deletions

View File

@@ -33,31 +33,35 @@ public class CleanLiftAuthRocketConsumer implements RocketMQListener<MessageExt>
public void onMessage(MessageExt ext) {
log.info("【消费者】接收消息:消息体 => {}", new String(ext.getBody()));
Long deviceId = Long.parseLong(ext.getUserProperty("deviceId"));
Long groupId = Long.parseLong(ext.getUserProperty("groupId"));
Long deviceFloorId = Long.parseLong(ext.getUserProperty("deviceFloorId"));
// 获取当前电梯信息
SisElevatorInfoVo ele = sisElevatorInfoService.queryById(deviceId);
// 获取权限组下电梯⇄楼层关联信息
List<SisElevatorFloorRefVo> groupRef = sisElevatorFloorRefService.queryByAuthGroupId(groupId);
// 取出当前电梯的楼层授权信息
List<SisElevatorFloorRefVo> eleRef = groupRef.stream().filter(o -> Objects.equals(o.getElevatorId(), deviceId)).toList();
for (SisElevatorFloorRefVo ref : eleRef){
if (ref.getUpChannel() != null && Objects.equals(ref.getFloorId(), deviceFloorId)){
HikApiService.getInstance().controlGateway(ele.getControlIp(), ref.getUpChannel().intValue(), 3);
}
if (ref.getDownChannel() != null && Objects.equals(ref.getFloorId(), deviceFloorId)){
HikApiService.getInstance().controlGateway(ele.getControlIp(), ref.getDownChannel().intValue(), 3);
}
if (ref.getInChannel() != null && Objects.equals(ref.getFloorId(), deviceFloorId)){
HikApiService.getInstance().controlGateway(ele.getControlIp(), ref.getInChannel().intValue(), 3);
}
// Long deviceId = Long.parseLong(ext.getUserProperty("deviceId"));
// Long groupId = Long.parseLong(ext.getUserProperty("groupId"));
// Long deviceFloorId = Long.parseLong(ext.getUserProperty("deviceFloorId"));
//
// // 获取当前电梯信息
// SisElevatorInfoVo ele = sisElevatorInfoService.queryById(deviceId);
//
// // 获取权限组下电梯⇄楼层关联信息
// List<SisElevatorFloorRefVo> groupRef = sisElevatorFloorRefService.queryByAuthGroupId(groupId);
//
// // 取出当前电梯的楼层授权信息
// List<SisElevatorFloorRefVo> eleRef = groupRef.stream().filter(o -> Objects.equals(o.getElevatorId(), deviceId)).toList();
//
// for (SisElevatorFloorRefVo ref : eleRef){
// if (ref.getUpChannel() != null && Objects.equals(ref.getFloorId(), deviceFloorId)){
// HikApiService.getInstance().controlGateway(ele.getControlIp(), ref.getUpChannel().intValue(), 3);
// }
//
// if (ref.getDownChannel() != null && Objects.equals(ref.getFloorId(), deviceFloorId)){
// HikApiService.getInstance().controlGateway(ele.getControlIp(), ref.getDownChannel().intValue(), 3);
// }
//
// if (ref.getInChannel() != null && Objects.equals(ref.getFloorId(), deviceFloorId)){
// HikApiService.getInstance().controlGateway(ele.getControlIp(), ref.getInChannel().intValue(), 3);
// }
// }
// todo 暂时应急处理,后续调整业务逻辑
for (int i = 1; i < 20; i++) {
HikApiService.getInstance().controlGateway("192.168.24.150", i, 3);
}
log.info("梯控清除权限完成");
}

View File

@@ -85,4 +85,9 @@ public class SisDeviceManage extends BaseEntity {
*/
private Long floorId;
/**
* 是否支持人脸比对
*/
private Boolean isComparison;
}

View File

@@ -83,6 +83,11 @@ public class SisDeviceManageBo extends BaseEntity {
*/
private Long groupId;
/**
* 是否支持人脸比对
*/
private Boolean isComparison;
private String tenantId;
}

View File

@@ -95,4 +95,9 @@ public class SisDeviceManageVo implements Serializable {
private Long groupId;
private String groupName;
/**
* 是否支持人脸比对
*/
private Boolean isComparison;
}

View File

@@ -107,9 +107,12 @@ public class RemoteSisAuthServiceImpl implements RemoteSisAuthService {
public Long syncHuaweiBox(RemotePersonAuth person, byte[] imgByte) {
Long pId;
try {
SisPersonLibImgVo vo = sisPersonLibImgService.queryByPersonId(person.getId());
AddHWPersonReq req = new AddHWPersonReq();
req.setIndex(CodePrefixConstants.PERSON_LIB_IMAGE_CODE_PREFIX + IdUtil.getSnowflakeNextIdStr());
req.setName(person.getName());
req.setCredentialType("5");
req.setCredentialNumber(vo.getId().toString());
req.setGender(person.getSex() == 1 ? "0" : person.getSex() == 2 ? "1" : "-1");
ArrayList<String> pictures = new ArrayList<>();

View File

@@ -1,7 +1,7 @@
package org.dromara.sis.runner;
import lombok.extern.slf4j.Slf4j;
import org.dromara.sis.sdk.smartDevices.utils.ElevatorControlUtil;
import org.dromara.sis.sdk.smartDevices.utils.ElevatorControlTcpUtil;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
@@ -19,22 +19,35 @@ public class ElevatorTcpRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) {
// 获取单例实例并启动服务
ElevatorControlUtil instance = ElevatorControlUtil.getInstance();
// 获取单例实例
ElevatorControlTcpUtil elevatorHelper = ElevatorControlTcpUtil.getInstance();
try{
// 设置连接监听器
elevatorHelper.setConnectionListener(new ElevatorControlTcpUtil.ConnectionListener() {
@Override
public void onConnected() {
log.info("梯控设备已连接");
}
@Override
public void onDisconnected() {
log.info("梯控设备已断开");
}
});
try {
// 启动服务
instance.start(23);
log.info("启动电梯控制服务成功");
elevatorHelper.start(23);
log.info("电梯控制TCP服务启动成功");
// 添加关闭钩子
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
// 停止服务
log.info("应用关闭中,停止电梯服务...");
instance.stop();
log.info("应用关闭中停止电梯控制TCP服务...");
elevatorHelper.stop();
}));
} catch (IOException e) {
log.info("启动电梯控制服务失败");
System.err.println("无法启动电梯控制TCP服务: " + e.getMessage());
}
}
}

View File

@@ -1,9 +1,14 @@
package org.dromara.sis.sdk.hik.calback;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.sun.jna.Pointer;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.sis.domain.SisDeviceManage;
import org.dromara.sis.sdk.hik.HCNetSDK;
import org.dromara.sis.sdk.hik.HikApiService;
import org.dromara.sis.service.ISisDeviceManageService;
import org.dromara.sis.service.IZeroSensationPassageService;
import org.springframework.stereotype.Component;
@@ -11,6 +16,7 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;
@@ -21,6 +27,7 @@ import static org.dromara.sis.sdk.hik.HCNetSDK.*;
@RequiredArgsConstructor
public class HikAlarmCallBack implements HCNetSDK.FMSGCallBack_V31 {
private final ISisDeviceManageService sisDeviceManageService;
private final IZeroSensationPassageService zeroSensationPassageService;
@Override
@@ -243,12 +250,9 @@ public class HikAlarmCallBack implements HCNetSDK.FMSGCallBack_V31 {
Pointer pFaceSnapMatch = strFaceSnapMatch.getPointer();
pFaceSnapMatch.write(0, pAlarmInfo.getByteArray(0, strFaceSnapMatch.size()), 0, strFaceSnapMatch.size());
strFaceSnapMatch.read();
//比对结果0-保留1-比对成功2-比对失败
String sFaceSnapMatchInfo = "比对结果:" + strFaceSnapMatch.byContrastStatus + ",相似度:" + strFaceSnapMatch.fSimilarity;
handleFaceComparison(strFaceSnapMatch, pAlarmer);
break;
}
default: {
}
@@ -262,9 +266,8 @@ public class HikAlarmCallBack implements HCNetSDK.FMSGCallBack_V31 {
*
* @param result 人脸数据
* @param pAlarmer 设备数据
* @return 返回是否处理成功
*/
private boolean handleFaceSnap(HCNetSDK.NET_VCA_FACESNAP_RESULT result, HCNetSDK.NET_DVR_ALARMER pAlarmer) {
private void handleFaceSnap(HCNetSDK.NET_VCA_FACESNAP_RESULT result, HCNetSDK.NET_DVR_ALARMER pAlarmer) {
// 读取人脸小图
ByteBuffer buffers = result.pBuffer1.getByteBuffer(0, result.dwFacePicLen);
byte[] smallImg = new byte[result.dwFacePicLen];
@@ -279,8 +282,48 @@ public class HikAlarmCallBack implements HCNetSDK.FMSGCallBack_V31 {
//设备ip
String sAlarmInfo = new String(pAlarmer.sDeviceIP).trim();
log.info("海康设备告警信息上传,设备={}, 人脸图片大小={} 背景图片大小={}", sAlarmInfo, smallImg.length, bigImg.length);
zeroSensationPassageService.pass(sAlarmInfo, smallImg, bigImg);
return false;
SisDeviceManage device = sisDeviceManageService.queryByDeviceIp(sAlarmInfo);
if (!device.getIsComparison()) {
log.info("设备不支持人脸比对");
zeroSensationPassageService.pass(sAlarmInfo, smallImg, bigImg);
}
}
/**
* 处理人脸比对上报
*/
private void handleFaceComparison(HCNetSDK.NET_VCA_FACESNAP_MATCH_ALARM result, HCNetSDK.NET_DVR_ALARMER pAlarmer) {
// 读取比对结果比对结果0-保留1-比对成功2-比对失败
int compareResults = result.byContrastStatus;
// 比对不成功,不处理
if (compareResults != 1) {
log.info("前置人脸比对失败,设备:{}", new String(pAlarmer.sDeviceIP).trim());
return;
}
// 获取相似度
float similarity = result.fSimilarity;
// 相似度小于70不处理
if (similarity < 0.7) {
log.info("前置人脸比对相似度小于70设备{}", new String(pAlarmer.sDeviceIP).trim());
return;
}
// 读取名字
String name = new String(result.struBlockListInfo.struBlockListInfo.struAttribute.byName, Charset.forName("GBK")).trim();
// 人员id为空不处理
if (result.struBlockListInfo.pPID == null) return;
// 读取人员id
ByteBuffer buffers = result.struBlockListInfo.pPID.getByteBuffer(0, result.struBlockListInfo.dwPIDLen);
byte[] pidByte = new byte[result.struBlockListInfo.dwPIDLen];
buffers.rewind();
buffers.get(pidByte);
int pid = Integer.parseInt(new String(pidByte));
log.info("比对结果:{},相似度:{},人员:{}id:{}", compareResults, similarity, name, pid);
zeroSensationPassageService.handleEleOut(new String(pAlarmer.sDeviceIP).trim());
}

View File

@@ -1,7 +1,7 @@
package org.dromara.sis.sdk.smartDevices.utils;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.io.InputStream;
@@ -9,53 +9,63 @@ import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* @author lsm
* @apiNote ElevatorControlUtil
* @apiNote ElevatorControlTcpUtil
* @since 2025/8/8
*/
@Service
public class ElevatorControlUtil {
@Slf4j
public class ElevatorControlTcpUtil {
private static final int FRAME_LENGTH = 10;
private static final byte FIXED_ADDRESS = 0x00;
private static final byte MANUAL_COMMAND = (byte) 0xD1;
private static final byte AUTO_COMMAND = (byte) 0xD2;
private static final byte MANUAL_RESPONSE = (byte) 0xC1;
private static final byte AUTO_RESPONSE = (byte) 0xC2;
private static final byte HEARTBEAT_COMMAND = (byte) 0xD0;
private static ElevatorControlUtil instance;
private static ElevatorControlTcpUtil instance;
private ServerSocket serverSocket;
private Socket clientSocket;
private InputStream inputStream;
private OutputStream outputStream;
private final Object lock = new Object();
private ScheduledExecutorService heartbeatScheduler;
private volatile boolean isRunning = false;
/**
* -- SETTER --
* 设置连接状态监听器
*/
// 连接状态监听器
@Setter
private ConnectionListener connectionListener;
// 线程池处理连接
private final ExecutorService executor = Executors.newCachedThreadPool();
// 私有构造函数
private ElevatorControlUtil() {}
private ElevatorControlTcpUtil() {
}
/**
* 获取单例实例
*/
public static synchronized ElevatorControlUtil getInstance() {
public static synchronized ElevatorControlTcpUtil getInstance() {
if (instance == null) {
instance = new ElevatorControlUtil();
instance = new ElevatorControlTcpUtil();
}
return instance;
}
/**
* 启动TCP服务
*
* @param port 监听端口
*/
public void start(Integer port) throws IOException {
public void start(int port) throws IOException {
if (isRunning) {
throw new IllegalStateException("服务已在运行中");
}
@@ -64,8 +74,8 @@ public class ElevatorControlUtil {
isRunning = true;
// 启动连接监听线程
new Thread(this::acceptConnections, "TCP-Acceptor").start();
System.out.println("电梯控制服务已启动,监听端口: " + port);
executor.execute(this::acceptConnections);
log.info("电梯控制TCP服务已启动,监听端口: {}", port);
}
/**
@@ -74,98 +84,71 @@ public class ElevatorControlUtil {
public void stop() {
isRunning = false;
// 停止心跳
if (heartbeatScheduler != null) {
heartbeatScheduler.shutdown();
}
// 关闭连接
// 关闭客户端连接
closeClientResources();
// 关闭服务器
if (serverSocket != null && !serverSocket.isClosed()) {
try {
serverSocket.close();
System.out.println("服务已停止");
log.info("电梯控制TCP服务已停止");
} catch (IOException e) {
System.err.println("停止服务时出错: " + e.getMessage());
log.error("停止电梯控制TCP服务时出错: {}", e.getMessage());
}
}
// 关闭线程池
executor.shutdown();
}
/**
* 接受客户端连接
*/
private void acceptConnections() {
while (isRunning) {
while (isRunning && !serverSocket.isClosed()) {
try {
clientSocket = serverSocket.accept();
clientSocket.setKeepAlive(true);
inputStream = clientSocket.getInputStream();
outputStream = clientSocket.getOutputStream();
log.info("等待梯控设备连接...");
Socket newClient = serverSocket.accept();
System.out.println("梯控设备已连接: " + clientSocket.getRemoteSocketAddress());
synchronized (lock) {
// 关闭现有连接如果有
closeClientResources();
// 启动心跳机制
startHeartbeat();
// 接受新连接
clientSocket = newClient;
inputStream = clientSocket.getInputStream();
outputStream = clientSocket.getOutputStream();
log.info("梯控设备已连接: {}", clientSocket.getRemoteSocketAddress());
// 通知连接状态变化
if (connectionListener != null) {
connectionListener.onConnected();
}
}
} catch (IOException e) {
if (isRunning) {
System.err.println("接受连接时出错: " + e.getMessage());
try {
Thread.sleep(5000); // 5秒后重试
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
}
log.error("接受连接时出错: {}", e.getMessage());
}
}
}
}
/**
* 启动心跳机制
*/
private void startHeartbeat() {
if (heartbeatScheduler != null && !heartbeatScheduler.isShutdown()) {
heartbeatScheduler.shutdown();
}
heartbeatScheduler = Executors.newSingleThreadScheduledExecutor();
heartbeatScheduler.scheduleAtFixedRate(() -> {
if (isClientConnected()) {
try {
sendHeartbeat();
} catch (IOException e) {
System.err.println("心跳包发送失败: " + e.getMessage());
closeClientResources();
}
}
}, 30, 30, TimeUnit.SECONDS);
}
/**
* 发送心跳包
*/
private void sendHeartbeat() throws IOException {
synchronized (lock) {
if (!isClientConnected()) return;
byte[] heartbeatData = new byte[7];
byte[] frame = buildFrame(HEARTBEAT_COMMAND, heartbeatData);
outputStream.write(frame);
outputStream.flush();
}
}
/**
* 检查客户端是否连接
*/
public boolean isClientConnected() {
return clientSocket != null && clientSocket.isConnected() && !clientSocket.isClosed();
synchronized (lock) {
return clientSocket != null &&
clientSocket.isConnected() &&
!clientSocket.isClosed();
}
}
/**
* 发送手动选层命令
*
* @param floors 要开放的楼层列表
* @return 是否成功
*/
@@ -175,6 +158,7 @@ public class ElevatorControlUtil {
/**
* 发送自动选层命令
*
* @param floors 要开放的楼层列表
* @return 是否成功
*/
@@ -195,18 +179,24 @@ public class ElevatorControlUtil {
private boolean sendCommand(byte command, byte expectedResponse, byte[] floorData) {
if (!isClientConnected()) {
System.err.println("发送命令失败:未连接梯控设备");
log.info("发送命令失败:未连接梯控设备");
return false;
}
if (floorData == null || floorData.length != 7) {
System.err.println("发送命令失败:无效的楼层数据");
log.info("发送命令失败:无效的楼层数据");
return false;
}
synchronized (lock) {
for (int attempt = 0; attempt < 2; attempt++) {
try {
// 检查连接是否仍然有效
if (!isClientConnected()) {
log.info("连接在发送前已断开");
return false;
}
byte[] frame = buildFrame(command, floorData);
outputStream.write(frame);
outputStream.flush();
@@ -219,19 +209,23 @@ public class ElevatorControlUtil {
while (bytesRead < FRAME_LENGTH) {
int read = inputStream.read(response, bytesRead, FRAME_LENGTH - bytesRead);
if (read == -1) {
throw new IOException("连接关闭");
// 连接关闭
handleConnectionClosed();
return false;
}
bytesRead += read;
}
if (validateResponse(response, expectedResponse)) {
return true;
} else {
log.info("响应验证失败,尝试重试");
}
} catch (java.net.SocketTimeoutException e) {
System.err.println("命令响应超时,尝试重试");
log.info("命令响应超时,尝试重试");
} catch (IOException e) {
System.err.println("发送命令时出错: " + e.getMessage());
closeClientResources();
log.error("发送命令时出错: {}", e.getMessage());
handleConnectionClosed();
return false;
}
}
@@ -239,6 +233,17 @@ public class ElevatorControlUtil {
}
}
/**
* 处理连接关闭
*/
private void handleConnectionClosed() {
log.info("检测到连接已关闭");
closeClientResources();
if (connectionListener != null) {
connectionListener.onDisconnected();
}
}
/**
* 生成楼层数据
*/
@@ -276,34 +281,61 @@ public class ElevatorControlUtil {
}
private boolean validateResponse(byte[] response, byte expectedHeader) {
if (response[0] != expectedHeader) return false;
if (response[1] != FIXED_ADDRESS) return false;
if (response[0] != expectedHeader) {
log.info("响应帧头错误,期望: {},实际:{}", expectedHeader, response[0]);
return false;
}
if (response[1] != FIXED_ADDRESS) {
log.info("响应地址错误");
return false;
}
byte checksum = 0;
for (int i = 0; i < 9; i++) {
checksum = (byte) (checksum + response[i]);
}
return response[9] == checksum;
if (response[9] != checksum) {
log.info("校验和错误,期望: {},实际: {}", checksum, response[9]);
return false;
}
return true;
}
/**
* 关闭客户端资源
*/
private void closeClientResources() {
try {
if (inputStream != null) inputStream.close();
if (outputStream != null) outputStream.close();
if (clientSocket != null && !clientSocket.isClosed()) {
clientSocket.close();
synchronized (lock) {
try {
if (inputStream != null) inputStream.close();
if (outputStream != null) outputStream.close();
if (clientSocket != null && !clientSocket.isClosed()) {
clientSocket.close();
}
log.info("客户端连接已关闭");
} catch (IOException e) {
log.error("关闭连接时出错: {}", e.getMessage());
} finally {
clientSocket = null;
inputStream = null;
outputStream = null;
// 通知连接断开
if (connectionListener != null) {
connectionListener.onDisconnected();
}
}
System.out.println("客户端连接已关闭");
} catch (IOException e) {
System.err.println("关闭连接时出错: " + e.getMessage());
} finally {
clientSocket = null;
inputStream = null;
outputStream = null;
}
}
/**
* 连接状态监听接口
*/
public interface ConnectionListener {
void onConnected();
void onDisconnected();
}
}

View File

@@ -70,21 +70,18 @@ public interface ISisDeviceManageService {
/**
* 通过设备ip查询设备信息
*
* @param deviceIp 设备编码
* @param deviceIp 设备ip
* @return 设备信息
*/
SisDeviceManageVo queryVoByDeviceIp(String deviceIp);
SisDeviceManage queryByDeviceIp(String deviceIp);
SisDeviceManage queryByDeviceIp(String deviceId);
/**
* 查询设备数
*
* @return
* @return tree
*/
List<TreeNode<Long>> tree();
/**
* 通过设备id列表查询设备信息
* @param deviceIds 设备id列表

View File

@@ -11,4 +11,11 @@ public interface IZeroSensationPassageService {
*/
void pass(String deviceIp, byte[] smallImp, byte[] bigImg);
/**
* 电梯外部按键触发
*
* @param deviceIp 设备ip
*/
void handleEleOut(String deviceIp);
}

View File

@@ -177,18 +177,15 @@ public class SisDeviceManageServiceImpl implements ISisDeviceManageService {
log.info("删除设备通道完成,num={}", num);
}
/**
* 通过设备ip查询设备信息
* @param deviceIp 设备ip
* @return 设备信息
*/
@Override
public SisDeviceManageVo queryVoByDeviceIp(String deviceIp) {
public SisDeviceManage queryByDeviceIp(String deviceIp) {
LambdaQueryWrapper<SisDeviceManage> lqw = Wrappers.lambdaQuery();
lqw.eq(SisDeviceManage::getDeviceIp, deviceIp);
return baseMapper.selectVoOne(lqw);
}
@Override
public SisDeviceManage queryByDeviceIp(String deviceId) {
LambdaQueryWrapper<SisDeviceManage> lqw = Wrappers.lambdaQuery();
lqw.eq(SisDeviceManage::getDeviceIp, deviceId);
return baseMapper.selectOne(lqw);
}

View File

@@ -202,6 +202,9 @@ public class SisElevatorFloorRefServiceImpl implements ISisElevatorFloorRefServi
lqw.in(SisElevatorFloorRef::getFloorId, info.stream().map(SisElevatorFloorChannelRef::getFloorId).toList());
List<SisElevatorFloorRef> list = baseMapper.selectList(lqw);
// list为空不需要冗余数据返回true
if(list.isEmpty()) return true;
// 创建Map提高查找效率避免在循环中重复流操作
Map<Long, SisElevatorFloorChannelRef> floorInfoMap = info.stream()
.collect(Collectors.toMap(SisElevatorFloorChannelRef::getFloorId, Function.identity()));

View File

@@ -252,7 +252,7 @@ public class SisElevatorInfoServiceImpl implements ISisElevatorInfoService {
// 冗余数据到电梯⇄楼层关联表
Boolean update = elevatorFloorRefService.batchUpdateChannel(channelRefs);
Assert.isTrue(update, "冗余数据到电梯⇄楼层关联表失败!");
}
/**

View File

@@ -10,6 +10,7 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.dromara.property.api.RemoteFloorService;
import org.dromara.property.api.domain.vo.RemoteFloorVo;
import org.dromara.sis.domain.SisElevatorFloorChannelRef;
import org.dromara.sis.domain.enums.ControlTypeEnum;
import org.dromara.sis.domain.enums.RosterTypeEnum;
import org.dromara.sis.domain.vo.*;
@@ -19,7 +20,7 @@ import org.dromara.sis.sdk.e8.domain.accessControl.req.RemoteOpenDoorReq;
import org.dromara.sis.sdk.hik.HikApiService;
import org.dromara.sis.sdk.huawei.HuaWeiBoxApi;
import org.dromara.sis.sdk.huawei.domain.HWResult;
import org.dromara.sis.sdk.smartDevices.utils.ElevatorControlUtil;
import org.dromara.sis.sdk.smartDevices.utils.ElevatorControlTcpUtil;
import org.dromara.sis.service.*;
import org.springframework.stereotype.Service;
@@ -46,6 +47,7 @@ public class ZeroSensationPassageServiceImpl implements IZeroSensationPassageSer
private final ISisDeviceBindRefService deviceBindRefService;
private final ISisAccessControlService accessControlService;
private final ISisElevatorFloorRefService elevatorFloorRefService;
private final ISisElevatorFloorChannelRefService elevatorFloorChannelRefService;
private final E8PlatformApi e8PlatformApi;
private final ISisAlarmEventsService alarmEventsService;
@@ -115,11 +117,11 @@ public class ZeroSensationPassageServiceImpl implements IZeroSensationPassageSer
}
// 判断绑定设备类型,走不同的处理方法
if (Objects.equals(item.getControlType(), ControlTypeEnum.ACCESS_CONTROL.getCode())) { // 门禁
handleAc(item.getDeviceId());
handleAc(item.getBindId());
} else if (item.getControlType().equals(ControlTypeEnum.ELEVATOR_OUT_CONTROL.getCode())) { // 电梯外面面板权限
handleEle(item.getDeviceId(), r.getAuthGroupId(), ControlTypeEnum.ELEVATOR_OUT_CONTROL.getCode(), item.getDeviceFloorId());
handleEle(item.getBindId(), r.getAuthGroupId(), ControlTypeEnum.ELEVATOR_OUT_CONTROL.getCode(), item.getDeviceFloorId());
} else if (item.getControlType().equals(ControlTypeEnum.ELEVATOR_IN_CONTROL.getCode())) { // 电梯里面的面板
handleEle(item.getDeviceId(), r.getAuthGroupId(), ControlTypeEnum.ELEVATOR_IN_CONTROL.getCode(), item.getDeviceFloorId());
handleEle(item.getBindId(), r.getAuthGroupId(), ControlTypeEnum.ELEVATOR_IN_CONTROL.getCode(), item.getDeviceFloorId());
} else {
log.info("设备绑定了未知的控制类型[{}],不处理", item.getControlType());
}
@@ -127,6 +129,39 @@ public class ZeroSensationPassageServiceImpl implements IZeroSensationPassageSer
log.info("权限下发执行完成,耗时:{}ms", interval.intervalMs());
}
/**
* 电梯外部按键触发
*
* @param deviceIp 设备ip
*/
@Override
public void handleEleOut(String deviceIp) {
// 获取当前设备的绑定设备信息
List<SisDeviceBindRefVo> bindRefList = deviceBindRefService.queryByDeviceIp(deviceIp);
bindRefList.forEach(item -> {
// 只处理外部按键
if (Objects.equals(item.getControlType(), ControlTypeEnum.ELEVATOR_OUT_CONTROL.getCode())) {
// 获取当前电梯信息
SisElevatorInfoVo ele = elevatorInfoService.queryById(item.getBindId());
List<SisElevatorFloorChannelRefVo> channelRef = elevatorFloorChannelRefService.queryByFloorIds(List.of(item.getDeviceFloorId()));
SisElevatorFloorChannelRefVo channelRefVo = channelRef.stream().filter(o -> Objects.equals(o.getElevatorId(), item.getBindId())).findFirst().orElse(null);
if (channelRefVo != null) {
if (channelRefVo.getDownChannel() != null) {
HikApiService.getInstance().controlGateway(ele.getControlIp(), channelRefVo.getDownChannel().intValue(), 2);
}
if (channelRefVo.getUpChannel() != null) {
HikApiService.getInstance().controlGateway(ele.getControlIp(), channelRefVo.getUpChannel().intValue(), 2);
}
}
}
cleanLiftAuthRocketProducer.sendMessage(item.getBindId(), 0L, item.getDeviceFloorId(), "清除电梯" + item.getBindId() + "梯控权限", 3);
});
}
/**
* 生成告警事件
*/
@@ -192,7 +227,7 @@ public class ZeroSensationPassageServiceImpl implements IZeroSensationPassageSer
for (int i = 1; i < floorList.size(); i++) {
int finalI = i;
// 取出权限楼层id与实际楼层id相等的数据
vo = eleRef.stream().filter(o -> Objects.equals(o.getFloorId(), floorList.get(finalI-1).getId())).findFirst().orElse(null);
vo = eleRef.stream().filter(o -> Objects.equals(o.getFloorId(), floorList.get(finalI - 1).getId())).findFirst().orElse(null);
// 存在权限楼层添加到num中梯控模块从1开始
if (vo != null) {
num.add(i);
@@ -200,11 +235,11 @@ public class ZeroSensationPassageServiceImpl implements IZeroSensationPassageSer
}
if (CollUtil.isEmpty(num)) return;
if (!ElevatorControlUtil.getInstance().isClientConnected()){
if (!ElevatorControlTcpUtil.getInstance().isClientConnected()) {
log.info("梯控模块未连接,请检查梯控模块是否启动");
return;
}
ElevatorControlUtil.getInstance().sendManualCommand(num);
ElevatorControlTcpUtil.getInstance().sendManualCommand(num);
}
log.info("梯控下发权限完成");