整体修改iot

泸州-视觉+扫码-昆船
LAPTOP-S9HJSOEB\昊天 2 months ago
parent 9b3360404e
commit 2613bb16b5

@ -0,0 +1,25 @@
@echo off
chcp 65001 >nul
setlocal enabledelayedexpansion
echo ============================================
echo 将当前目录下所有文件夹的子文件夹提取到外层
echo ============================================
echo.
set "ROOT=%cd%"
for /d %%P in ("%ROOT%\*") do (
echo [处理] %%P
for /d %%S in ("%%P\*") do (
set "SUBNAME=%%~nxS"
echo 提取子文件夹: !SUBNAME!
robocopy "%%S" "%ROOT%\!SUBNAME!" /E /IS /IT >nul
)
)
echo.
echo ============================================
echo 完成!
echo ============================================
pause

@ -0,0 +1,152 @@
{"001":
{
"deviceName": "非动碰盘点1号巷道盘点系统",
"time": "2026-06-26 09:30:00",
"warehouseRunStatus": 1,
"warehouseNetworkStatus": 1,
"leftScannerNetworkStatus": 1,
"leftScannerScanResult": 1,
"rightScannerNetworkStatus": 1,
"rightScannerScanResult": 1,
"cameraNetworkStatus": 1,
"cameraErrorCode": 0,
"apNetworkStatus": 1,
"cpeNetworkStatus": 1,
"visionControllerNetworkStatus": 1,
"communicationData": {
}
},
"002": {
"deviceName": "一号仓库动碰盘点系统",
"time": "2026-06-26 09:30:00",
"warehouseRunStatus": 1,
"warehouseNetworkStatus": 1,
"leftScannerNetworkStatus": 1,
"leftScannerScanResult": 1,
"rightScannerNetworkStatus": 1,
"rightScannerScanResult": 1,
"leftDepthScannerNetworkStatus": 1,
"leftDepthScannerScanResult": 1,
"rightDepthScannerNetworkStatus": 1,
"rightDepthScannerScanResult": 1,
"cameraNetworkStatus": 1,
"cameraErrorCode": 0,
"apNetworkStatus": 1,
"cpeNetworkStatus": 1,
"visionControllerNetworkStatus": 1,
"communicationData": {
}
},
"003": {
"deviceName": "一号仓库动碰盘点系统",
"time": "2026-06-26 09:30:00",
"warehouseRunStatus": 1,
"warehouseNetworkStatus": 1,
"leftScannerNetworkStatus": 1,
"leftScannerScanResult": 1,
"rightScannerNetworkStatus": 1,
"rightScannerScanResult": 1,
"leftDepthScannerNetworkStatus": 1,
"leftDepthScannerScanResult": 1,
"rightDepthScannerNetworkStatus": 1,
"rightDepthScannerScanResult": 1,
"cameraNetworkStatus": 1,
"cameraErrorCode": 0,
"apNetworkStatus": 1,
"cpeNetworkStatus": 1,
"visionControllerNetworkStatus": 1,
"communicationData": {
}
},
"004": {
"deviceName": "一号仓库动碰盘点系统",
"time": "2026-06-26 09:30:00",
"warehouseRunStatus": 1,
"warehouseNetworkStatus": 1,
"leftScannerNetworkStatus": 1,
"leftScannerScanResult": 1,
"rightScannerNetworkStatus": 1,
"rightScannerScanResult": 1,
"cameraNetworkStatus": 1,
"cameraErrorCode": 1,
"apNetworkStatus": 1,
"cpeNetworkStatus": 1,
"visionControllerNetworkStatus": 1,
"communicationData": {
}
},
"005": {
"deviceName": "一号仓库动碰盘点系统",
"time": "2026-06-26 09:30:00",
"warehouseRunStatus": 1,
"warehouseNetworkStatus": 1,
"leftScannerNetworkStatus": 1,
"leftScannerScanResult": 1,
"rightScannerNetworkStatus": 1,
"rightScannerScanResult": 1,
"cameraNetworkStatus": 1,
"cameraErrorCode": 0,
"apNetworkStatus": 1,
"cpeNetworkStatus": 1,
"visionControllerNetworkStatus": 1,
"communicationData": {
}
},
"006": {
"deviceName": "一号仓库动碰盘点系统",
"time": "2026-06-26 09:30:00",
"warehouseRunStatus": 1,
"warehouseNetworkStatus": 1,
"leftScannerNetworkStatus": 1,
"leftScannerScanResult": 1,
"rightScannerNetworkStatus": 1,
"rightScannerScanResult": 1,
"rightDepthScannerNetworkStatus": 1,
"rightDepthScannerScanResult": 1,
"cameraNetworkStatus": 1,
"cameraErrorCode": 0,
"apNetworkStatus": 1,
"cpeNetworkStatus": 1,
"visionControllerNetworkStatus": 1,
"communicationData": {
}
},
"007": {
"deviceName": "一号仓库动碰盘点系统",
"time": "2026-06-26 09:30:00",
"warehouseRunStatus": 1,
"warehouseNetworkStatus": 1,
"leftScannerNetworkStatus": 1,
"leftScannerScanResult": 1,
"rightScannerNetworkStatus": 1,
"rightScannerScanResult": 1,
"leftDepthScannerNetworkStatus": 1,
"leftDepthScannerScanResult": 1,
"rightDepthScannerNetworkStatus": 1,
"rightDepthScannerScanResult": 1,
"cameraNetworkStatus": 1,
"cameraErrorCode": 0,
"apNetworkStatus": 1,
"cpeNetworkStatus": 1,
"visionControllerNetworkStatus": 1,
"communicationData": {
}
},
"008": {
"deviceName": "一号仓库动碰盘点系统",
"time": "2026-06-26 09:30:00",
"warehouseRunStatus": 1,
"warehouseNetworkStatus": 1,
"leftScannerNetworkStatus": 1,
"leftScannerScanResult": 1,
"rightScannerNetworkStatus": 1,
"rightScannerScanResult": 1,
"cameraNetworkStatus": 1,
"cameraErrorCode": 0,
"apNetworkStatus": 1,
"cpeNetworkStatus": 1,
"visionControllerNetworkStatus": 1,
"communicationData": {
}
}
}

@ -0,0 +1,7 @@
"192.168.42.11"=zt:industrialCamera1NetworkStatus
"192.168.43.11"=zt:industrialCamera2NetworkStatus
"192.168.44.11"=zt:industrialCamera3NetworkStatus
"192.168.45.11"=zt:industrialCamera4NetworkStatus
"192.168.46.11"=zt:industrialCamera5NetworkStatus
"192.168.47.11"=zt:industrialCamera6NetworkStatus
"192.168.48.11"=zt:camera3dNetworkStatus

@ -0,0 +1,17 @@
@echo off
chcp 65001 >nul
echo ===== 测试 KSEC 接口 =====
echo 目标: http://10.100.81.10:8000/ksecwcs/tinventoryinfo
echo.
curl -v -X POST "http://10.100.81.10:8000/ksecwcs/tinventoryinfo" ^
-H "Content-Type: application/json" ^
-H "User-Agent: Mozilla/5.0" ^
--connect-timeout 5 ^
--max-time 10 ^
-d "{\"code\":200,\"msg\":\"图像识别完成\",\"data\":{\"trayCode\":\"75759\",\"wmsTrayCode\":\"75759\",\"flag\":1,\"count\":null}}"
echo.
echo.
echo ===== 测试完成 =====
pause

@ -5,6 +5,7 @@ import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component
@ -23,6 +24,7 @@ public class ConfigProperties {
public static Integer JOYWARE_CAMERA = 0;
private String ComConfig;
private List<String> comTofConfig = new ArrayList<>();
private CameraConfig cameraConfig;
@ -111,7 +113,7 @@ public class ConfigProperties {
public Integer verticalAdjustmentTime = 2;
private List<String> industrialCamera;
private List<String> industrialCamera = new ArrayList<>();
private String camera3D;
private String sickIp;

@ -1,27 +1,81 @@
package com.zhehekeji.web.config;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.apache.http.HeaderElement;
import org.apache.http.HeaderElementIterator;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeaderElementIterator;
import org.apache.http.protocol.HTTP;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.time.Duration;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
@EnableAsync
@EnableScheduling
@Configuration
public class FusionDesignApplication {
@Resource
//RestTemplateBuilder
private RestTemplateBuilder builder;
// 使用RestTemplateBuilder来实例化RestTemplate对象,spring默认已经注入了RestTemplateBuilder实例
@Bean
public RestTemplate restTemplate() {
return builder.setConnectTimeout(Duration.ofMinutes(10)) // 设置连接超时时间,单位分钟
.setReadTimeout(Duration.ofMinutes(20)) // 设置读取超时时间,单位分钟
// 连接池:空闲 15 秒回收,防止复用被服务端关闭的死连接(NoHttpResponseException)
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(15, TimeUnit.SECONDS);
connManager.setMaxTotal(100); // 最大连接数
connManager.setDefaultMaxPerRoute(20); // 每路由最大连接数
// 每 5 秒清理一次过期/空闲连接
connManager.setValidateAfterInactivity(3000); // 3秒未活动的连接,使用前先验证有效性
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(5000) // 连接超时 5 秒
.setSocketTimeout(30000) // 读取超时 30 秒
.setConnectionRequestTimeout(3000) // 从池里取连接超时 3 秒
.build();
// Keep-Alive 策略:默认存活 5 秒,避免使用已被服务端关闭的死连接
ConnectionKeepAliveStrategy keepAliveStrategy = (response, context) -> {
HeaderElementIterator it = new BasicHeaderElementIterator(
response.headerIterator(HTTP.CONN_KEEP_ALIVE));
while (it.hasNext()) {
HeaderElement he = it.nextElement();
String param = he.getName();
String value = he.getValue();
if (value != null && "timeout".equalsIgnoreCase(param)) {
return Long.parseLong(value) * 1000;
}
}
return 5000; // 默认 5 秒
};
CloseableHttpClient httpClient = HttpClientBuilder.create()
.setConnectionManager(connManager)
.setDefaultRequestConfig(requestConfig)
.setKeepAliveStrategy(keepAliveStrategy)
.evictIdleConnections(15, TimeUnit.SECONDS) // 15 秒回收空闲连接
.setRetryHandler((exception, executionCount, context) -> {
// 对 NoHttpResponseException 进行重试(服务端关闭连接未响应,
// 此时请求未送达,重试是安全的)
if (executionCount > 2) {
return false;
}
if (exception instanceof NoHttpResponseException) {
return true;
}
// 其他 IOException 也重试一次
return executionCount <= 1 && exception instanceof IOException;
})
.build();
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
return new RestTemplate(factory);
}
}

@ -32,8 +32,6 @@ public class CameraControlController {
@Resource
private CameraControlModule cameraControlModule;
@Resource
private CameraControlLoginModule loginControlModule;
@PostMapping("/{id}")
@ApiOperation(value = "球机登录")

@ -1,20 +1,21 @@
package com.zhehekeji.web.controller;
import com.baomidou.mybatisplus.extension.api.R;
import com.github.pagehelper.PageInfo;
import com.zhehekeji.common.util.ValidatorUtil;
import com.zhehekeji.core.pojo.Result;
import com.zhehekeji.web.entity.CheckLog;
import com.zhehekeji.web.entity.ReadOCR;
import com.zhehekeji.web.entity.SensorGun;
import com.zhehekeji.web.entity.StockLog;
import com.zhehekeji.web.entity.*;
import com.zhehekeji.web.pojo.stock.CheckLogSearch;
import com.zhehekeji.web.pojo.stock.StockLogSearch;
import com.zhehekeji.web.service.CheckLogService;
import com.zhehekeji.web.service.SensorService;
import com.zhehekeji.web.service.StockLogService;
import com.zhehekeji.web.service.StreetService;
import com.zhehekeji.web.service.sick.CognexSocket;
import com.zhehekeji.web.service.sick.SickSocket;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@ -25,6 +26,7 @@ import javax.annotation.Resource;
@Api(tags = "盘点历史")
@RequestMapping("/checkLog")
@RestController
@Slf4j
public class CheckLogController {
@Resource
@ -34,6 +36,9 @@ public class CheckLogController {
@Resource
private SensorService sensorService;
@Resource
private StreetService streetService;
@ApiOperation("盘点历史")
@PostMapping("")
public Result<PageInfo<CheckLog>> list(@RequestBody CheckLogSearch checkLogSearch){
@ -41,21 +46,35 @@ public class CheckLogController {
}
@ApiOperation("深货位扫码")
@PostMapping("CognexSocket")
public Result<String> CognexSocket(@RequestBody CheckLogSearch checkLogSearch){
@ApiOperation("扫码抢")
@PostMapping("scanSocket")
public Result<String> scanSocket(@RequestBody CheckLogSearch checkLogSearch){
String pointIdentification = "ScannerScanResult";
//使用sick扫码枪
int leftRight = checkLogSearch.getLeftRight();
if(checkLogSearch.getSide()==2) {
pointIdentification = "Depth"+ pointIdentification;
leftRight=leftRight+2;
}
if(checkLogSearch.getLeftRight()==1) {
pointIdentification = "left"+ pointIdentification;
}else {
pointIdentification = "right"+ pointIdentification;
}
Street street = streetService.getStreetByPlcId(checkLogSearch.getStreetPlc());
//托盘使用sick扫码枪
SensorGun sensorGun = sensorService.getSensorByPlc(street.getId(), leftRight);
ReadOCR trayCode = new ReadOCR();
SensorGun sensorGun = sensorService.getSensorByPlc(checkLogSearch.getStreetId(),leftRight);
if (sensorGun == null) {
trayCode.setCode("扫码枪未配置");
log.error("no sensor gun config in database ,street id:{},direction:{}", street.getId(), checkLogSearch.getLeftRight());
} else {
if (leftRight > 2) {
trayCode = CognexSocket.readOCR(sensorGun.getIp(), sensorGun.getPort());
trayCode = CognexSocket.readOCR(sensorGun.getIp(), sensorGun.getPort(), pointIdentification, street.getPlcId());
} else {
trayCode = SickSocket.readOCR(sensorGun.getIp(), sensorGun.getPort(), pointIdentification, street.getPlcId());
}
}
return Result.success(trayCode.getCode());

@ -180,7 +180,7 @@ public class IndustrialCameraController {
try {
Thread.sleep(400);
readOCR = SickSocket.readOCR(configProperties.getCameraConfig().getSickIp(), configProperties.getCameraConfig().getSickPort());
readOCR = SickSocket.readOCR(configProperties.getCameraConfig().getSickIp(), configProperties.getCameraConfig().getSickPort(),"scannerScanResult","zt");
log.info("sick识别结果:"+readOCR);
if(readOCR.getStatus()!=1){
code = "0";

@ -0,0 +1,154 @@
package com.zhehekeji.web.controller;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageInfo;
import com.zhehekeji.core.pojo.Result;
import com.zhehekeji.web.entity.KuKou;
import com.zhehekeji.web.pojo.OrderSearch;
import com.zhehekeji.web.service.iotService.IotServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Api(tags = "iot查询管理")
@RequestMapping("/IotController")
@RestController
@Slf4j
public class IotController {
@Resource
private IotServiceImpl iotService;
@PostMapping("/list")
@ApiOperation(value = "查询")
//@SessionHandler
public Result<List<Object>> list() {
//validatorUtil.validate(orderSearch);
return Result.success(iotService.get());
}
@PostMapping("/listOne")
@ApiOperation(value = "查询")
//@SessionHandler
public Result<Map<String,Object>> listOne(@RequestParam("type") String type) {
//validatorUtil.validate(orderSearch);
return Result.success(iotService.get(type));
}
@PostMapping("/listZT")
@ApiOperation(value = "查询")
//@SessionHandler
public Result<Map<String,Object>> listZT() {
Map<String,Object> map = iotService.get("zt");
//validatorUtil.validate(orderSearch);
return Result.success(map);
}
private final ObjectMapper objectMapper = new ObjectMapper();
/**
* 接收报警服务器推送的 Webhook 报警
*/
@PostMapping("/receive")
public Map<String, Object> receiveAlarm(
@RequestBody String rawJson) {
log.info("====== 收到报警服务器推送 ======");
// log.debug("原始 JSON: {}", rawJson); // 调试时打开,正式环境建议关闭以防日志爆满
Map<String, Object> response = new HashMap<>();
try {
// 1. 【安全校验】(如果平台配置了 Token 或签名,在这里校验)
// String token = headers.getFirst("Authorization");
// if (!"your_secret_token".equals(token)) {
// response.put("code", 401); response.put("msg", "Unauthorized");
// return response;
// }
// 2. 解析原始 JSON (这里以海康/大华常见的通用结构为例,具体需看平台文档)
JsonNode rootNode = objectMapper.readTree(rawJson);
// 3. 转换为内部标准 DTO (防腐层核心逻辑)
StandardAlarmDTO standardAlarm = convertToStandardDTO(rootNode);
System.out.println(standardAlarm);
// 4. 【核心】异步处理报警 (发 MQTT、存数据库、推 WebSocket 等)
// 注意:千万不要在这里同步执行耗时操作,必须异步!
// alarmProcessService.processAsync(standardAlarm);
// 5. 返回成功响应 (必须返回平台要求的成功格式,否则平台会认为推送失败并疯狂重试)
response.put("code", 0); // 或 "code": "200",具体看平台文档要求
response.put("msg", "success");
} catch (Exception e) {
log.error("处理报警服务器推送数据异常", e);
response.put("code", 500);
response.put("msg", "Internal Server Error");
}
return response;
}
/**
* 将平台原始 JSON 转换为内部标准 DTO
* (注:以下字段映射为模拟,请根据实际报警服务器的 JSON 结构进行修改)
*/
private StandardAlarmDTO convertToStandardDTO(JsonNode rootNode) {
StandardAlarmDTO dto = new StandardAlarmDTO();
// 提取唯一ID (防重放攻击/重复消费的关键)
dto.setAlarmId(rootNode.path("eventId").asText(rootNode.path("alarmId").asText("")));
// 提取设备信息
JsonNode deviceNode = rootNode.path("deviceInfo");
dto.setDeviceName(deviceNode.path("deviceName").asText("未知设备"));
dto.setDeviceIp(deviceNode.path("ip").asText(""));
// 提取报警业务信息
dto.setAlarmType(rootNode.path("eventType").asText("未知报警"));
dto.setAlarmLevel(rootNode.path("level").asText("一般"));
dto.setDescription(rootNode.path("description").asText(""));
// 提取时间 (注意时区和格式转换)
String timeStr = rootNode.path("happenTime").asText();
if (!timeStr.isEmpty()) {
dto.setOccurTime(LocalDateTime.parse(timeStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
} else {
dto.setOccurTime(LocalDateTime.now());
}
// 提取图片 URL (如果有)
JsonNode picNode = rootNode.path("pictureUrl");
if (!picNode.isMissingNode()) {
dto.setImageUrl(picNode.asText());
}
return dto;
}
}
@Data
class StandardAlarmDTO {
private String alarmId; // 平台报警唯一ID (用于防重)
private String deviceName; // 设备名称 (如:1号门摄像机)
private String deviceIp; // 设备IP
private String alarmType; // 报警类型 (如:区域入侵、未戴安全帽)
private String alarmLevel; // 报警等级 (如:紧急、一般)
private LocalDateTime occurTime;// 发生时间
private String imageUrl; // 抓拍图片URL (注意:只传URL,不传Base64)
private String description; // 报警描述
}

@ -4,6 +4,6 @@ import com.zhehekeji.web.lib.joyware.NetSDKLib;
public interface CameraControlLoginModule {
NetSDKLib.LLong login(String ip, int port, String user, String password);
NetSDKLib.LLong login(Integer id,String ip, int port, String user, String password);
}

@ -10,6 +10,7 @@ import com.zhehekeji.web.lib.CameraConnMap;
import com.zhehekeji.web.lib.CameraControlModule;
import com.zhehekeji.web.lib.joyware.NetSDKLib;
import com.zhehekeji.web.pojo.camera.CameraPtzPojo;
import com.zhehekeji.web.service.iotService.IotServiceImpl;
import lombok.extern.slf4j.Slf4j;
import java.io.*;
@ -17,9 +18,7 @@ import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.*;
import static com.zhehekeji.web.lib.hik.HCNetSDK.NET_DVR_GET_PTZPOS;
import static com.zhehekeji.web.lib.hik.HCNetSDK.NET_DVR_SET_TIMECFG;
@ -31,10 +30,26 @@ import static com.zhehekeji.web.lib.hik.HCNetSDK.NET_DVR_SET_TIMECFG;
@Slf4j
public class HikCameraControlModuleImpl implements CameraControlModule {
/**
* 云台控制结果写入IOT状态:成功写0,失败写错误码
*/
private boolean writeCameraStatus(Integer cameraId, boolean ok) {
if (ok) {
IotServiceImpl.set(IotServiceImpl.cameraToStreetMap.get(cameraId), "cameraErrorCode", 0);
} else {
int errorCode = HikLoginModuleImpl.hcNetsdk.NET_DVR_GetLastError();
log.error("ptz error:{},cameraId:{}", errorCode, cameraId);
IotServiceImpl.set(IotServiceImpl.cameraToStreetMap.get(cameraId), "cameraErrorCode", errorCode);
}
return ok;
}
public boolean connectStatus(Integer cameraId){
NetSDKLib.LLong userId = CameraConnMap.getConnId(cameraId);
return HikLoginModuleImpl.hcNetsdk.NET_DVR_RemoteControl(userId.intValue(),20005,null,0);
boolean ok = HikLoginModuleImpl.hcNetsdk.NET_DVR_RemoteControl(userId.intValue(),20005,null,0);
return writeCameraStatus(cameraId, ok);
}
@ -44,13 +59,13 @@ public class HikCameraControlModuleImpl implements CameraControlModule {
public boolean ptzControlUpStart(Integer cameraId, int nChannelID, int dwPTZCommand,int dwStop)
{
int lUserId = CameraConnMap.getConnId(cameraId).intValue();
return HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.TILT_UP, 0);
return writeCameraStatus(cameraId, HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.TILT_UP, 0));
}
public boolean ptzControlUpEnd(Integer cameraId, int nChannelID)
{
int lUserId = CameraConnMap.getConnId(cameraId).intValue();
return HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.TILT_UP, 1);
return writeCameraStatus(cameraId, HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.TILT_UP, 1));
}
/**
@ -59,13 +74,13 @@ public class HikCameraControlModuleImpl implements CameraControlModule {
public boolean ptzControlDownStart(Integer cameraId, int nChannelID, int dwPTZCommand, int dwStop)
{
int lUserId = CameraConnMap.getConnId(cameraId).intValue();
return HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.TILT_DOWN, 0);
return writeCameraStatus(cameraId, HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.TILT_DOWN, 0));
}
public boolean ptzControlDownEnd(Integer cameraId, int nChannelID)
{
int lUserId = CameraConnMap.getConnId(cameraId).intValue();
return HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.TILT_DOWN, 1);
return writeCameraStatus(cameraId, HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.TILT_DOWN, 1));
}
/**
@ -74,13 +89,13 @@ public class HikCameraControlModuleImpl implements CameraControlModule {
public boolean ptzControlLeftStart(Integer cameraId, int nChannelID, int dwPTZCommand, int dwStop)
{
int lUserId = CameraConnMap.getConnId(cameraId).intValue();
return HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.PAN_LEFT, 0);
return writeCameraStatus(cameraId, HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.PAN_LEFT, 0));
}
public boolean ptzControlLeftEnd(Integer cameraId, int nChannelID)
{
int lUserId = CameraConnMap.getConnId(cameraId).intValue();
return HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.PAN_LEFT, 1);
return writeCameraStatus(cameraId, HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.PAN_LEFT, 1));
}
@Override
@ -93,11 +108,14 @@ public class HikCameraControlModuleImpl implements CameraControlModule {
IntByReference intByReference = new IntByReference(1);
boolean b_GetPTZ = HikLoginModuleImpl.hcNetsdk.NET_DVR_GetDVRConfig(lUserId, NET_DVR_GET_PTZPOS,1,pointer,netDvrPtzpos.size(),intByReference);
if (b_GetPTZ == false) {
System.out.println("获取PTZ坐标信息失败,错误码:" +HikLoginModuleImpl.hcNetsdk.NET_DVR_GetLastError());
int errorCode = HikLoginModuleImpl.hcNetsdk.NET_DVR_GetLastError();
System.out.println("获取PTZ坐标信息失败,错误码:" + errorCode);
IotServiceImpl.set(IotServiceImpl.cameraToStreetMap.get(lUserID),"cameraErrorCode",errorCode);
cameraPtzPojo.setGetSuccess(false);
}else {
cameraPtzPojo.setGetSuccess(true);
IotServiceImpl.set(IotServiceImpl.cameraToStreetMap.get(lUserID),"cameraErrorCode",0);
netDvrPtzpos.read();
cameraPtzPojo.setWPanPos(hexToDegree(netDvrPtzpos.wPanPos));
cameraPtzPojo.setWTiltPos(hexToDegree(netDvrPtzpos.wTiltPos));
@ -122,13 +140,13 @@ public class HikCameraControlModuleImpl implements CameraControlModule {
public boolean ptzControlRightStart(Integer cameraId, int nChannelID, int dwPTZCommand, int dwStop)
{
int lUserId = CameraConnMap.getConnId(cameraId).intValue();
return HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.PAN_RIGHT, 0);
return writeCameraStatus(cameraId, HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.PAN_RIGHT, 0));
}
public boolean ptzControlRightEnd(Integer cameraId, int nChannelID)
{
int lUserId = CameraConnMap.getConnId(cameraId).intValue();
return HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.PAN_RIGHT, 1);
return writeCameraStatus(cameraId, HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.PAN_RIGHT, 1));
}
/**
* 向左上
@ -136,13 +154,13 @@ public class HikCameraControlModuleImpl implements CameraControlModule {
public boolean ptzControlLeftUpStart(Integer cameraId, int nChannelID, int dwPTZCommand, int dwStop)
{
int lUserId = CameraConnMap.getConnId(cameraId).intValue();
return HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.UP_LEFT, 0);
return writeCameraStatus(cameraId, HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.UP_LEFT, 0));
}
public boolean ptzControlLeftUpEnd(Integer cameraId, int nChannelID)
{
int lUserId = CameraConnMap.getConnId(cameraId).intValue();
return HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.UP_LEFT, 1);
return writeCameraStatus(cameraId, HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.UP_LEFT, 1));
}
/**
@ -151,14 +169,14 @@ public class HikCameraControlModuleImpl implements CameraControlModule {
public boolean ptzControlRightUpStart(Integer cameraId, int nChannelID, int dwPTZCommand, int dwStop)
{
int lUserId = CameraConnMap.getConnId(cameraId).intValue();
return HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.UP_RIGHT, 0);
return writeCameraStatus(cameraId, HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.UP_RIGHT, 0));
}
public boolean ptzControlRightUpEnd(Integer cameraId, int nChannelID)
{
int lUserId = CameraConnMap.getConnId(cameraId).intValue();
return HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.UP_RIGHT, 1);
return writeCameraStatus(cameraId, HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.UP_RIGHT, 1));
}
/**
* 向左下
@ -167,15 +185,12 @@ public class HikCameraControlModuleImpl implements CameraControlModule {
{
int lUserId = CameraConnMap.getConnId(cameraId).intValue();
Boolean ok = HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.DOWN_LEFT, 0);
if(!ok){
log.error("error:{},cameraId:{}", HikLoginModuleImpl.hcNetsdk.NET_DVR_GetLastError(),cameraId);
}
return ok;
return writeCameraStatus(cameraId, ok);
}
public boolean ptzControlLeftDownEnd(Integer cameraId, int nChannelID)
{
int lUserId = CameraConnMap.getConnId(cameraId).intValue();
return HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.DOWN_LEFT, 1);
return writeCameraStatus(cameraId, HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.DOWN_LEFT, 1));
}
/**
* 向右下
@ -183,13 +198,13 @@ public class HikCameraControlModuleImpl implements CameraControlModule {
public boolean ptzControlRightDownStart(Integer cameraId, int nChannelID, int dwPTZCommand, int dwStop)
{
int lUserId = CameraConnMap.getConnId(cameraId).intValue();
return HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.DOWN_RIGHT, 0);
return writeCameraStatus(cameraId, HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.DOWN_RIGHT, 0));
}
public boolean ptzControlRightDownEnd(Integer cameraId, int nChannelID)
{
int lUserId = CameraConnMap.getConnId(cameraId).intValue();
return HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.DOWN_RIGHT, 1);
return writeCameraStatus(cameraId, HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.DOWN_RIGHT, 1));
}
/**
@ -198,13 +213,13 @@ public class HikCameraControlModuleImpl implements CameraControlModule {
public boolean ptzControlZoomAddStart(Integer cameraId, int nChannelID, int dwPTZCommand)
{
int lUserId = CameraConnMap.getConnId(cameraId).intValue();
return HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.ZOOM_IN, 0);
return writeCameraStatus(cameraId, HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.ZOOM_IN, 0));
}
public boolean ptzControlZoomAddEnd(Integer cameraId, int nChannelID)
{
int lUserId = CameraConnMap.getConnId(cameraId).intValue();
return HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.ZOOM_IN, 1);
return writeCameraStatus(cameraId, HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.ZOOM_IN, 1));
}
/**
@ -213,13 +228,13 @@ public class HikCameraControlModuleImpl implements CameraControlModule {
public boolean ptzControlZoomDecStart(Integer cameraId, int nChannelID, int dwPTZCommand)
{
int lUserId = CameraConnMap.getConnId(cameraId).intValue();
return HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.ZOOM_OUT, 0);
return writeCameraStatus(cameraId, HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.ZOOM_OUT, 0));
}
public boolean ptzControlZoomDecEnd(Integer cameraId, int nChannelID)
{
int lUserId = CameraConnMap.getConnId(cameraId).intValue();
return HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.ZOOM_OUT, 1);
return writeCameraStatus(cameraId, HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.ZOOM_OUT, 1));
}
/**
* 变焦+
@ -227,13 +242,13 @@ public class HikCameraControlModuleImpl implements CameraControlModule {
public boolean ptzControlFocusAddStart(Integer cameraId, int nChannelID, int dwPTZCommand)
{
int lUserId = CameraConnMap.getConnId(cameraId).intValue();
return HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.FOCUS_NEAR, 0);
return writeCameraStatus(cameraId, HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.FOCUS_NEAR, 0));
}
public boolean ptzControlFocusAddEnd(Integer cameraId, int nChannelID)
{
int lUserId = CameraConnMap.getConnId(cameraId).intValue();
return HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.FOCUS_NEAR, 1);
return writeCameraStatus(cameraId, HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.FOCUS_NEAR, 1));
}
/**
* 变焦-
@ -241,13 +256,13 @@ public class HikCameraControlModuleImpl implements CameraControlModule {
public boolean ptzControlFocusDecStart(Integer cameraId, int nChannelID, int dwPTZCommand)
{
int lUserId = CameraConnMap.getConnId(cameraId).intValue();
return HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.FOCUS_FAR, 0);
return writeCameraStatus(cameraId, HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.FOCUS_FAR, 0));
}
public boolean ptzControlFocusDecEnd(Integer cameraId, int nChannelID)
{
int lUserId = CameraConnMap.getConnId(cameraId).intValue();
return HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.FOCUS_FAR, 1);
return writeCameraStatus(cameraId, HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.FOCUS_FAR, 1));
}
/**
@ -256,13 +271,13 @@ public class HikCameraControlModuleImpl implements CameraControlModule {
public boolean ptzControlIrisAddStart(Integer cameraId, int nChannelID, int dwPTZCommand)
{
int lUserId = CameraConnMap.getConnId(cameraId).intValue();
return HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.IRIS_OPEN, 0);
return writeCameraStatus(cameraId, HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.IRIS_OPEN, 0));
}
public boolean ptzControlIrisAddEnd(Integer cameraId, int nChannelID)
{
int lUserId = CameraConnMap.getConnId(cameraId).intValue();
return HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.IRIS_OPEN, 1);
return writeCameraStatus(cameraId, HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.IRIS_OPEN, 1));
}
/**
@ -271,14 +286,14 @@ public class HikCameraControlModuleImpl implements CameraControlModule {
public boolean ptzControlIrisDecStart(Integer cameraId, int nChannelID, int dwPTZCommand)
{
int lUserId = CameraConnMap.getConnId(cameraId).intValue();
return HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.IRIS_CLOSE, 0);
return writeCameraStatus(cameraId, HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.IRIS_CLOSE, 0));
}
public boolean ptzControlIrisDecEnd(Integer cameraId, int nChannelID)
{
int lUserId = CameraConnMap.getConnId(cameraId).intValue();
Boolean ok = HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZControl_Other(lUserId, 1, HCNetSDK.IRIS_CLOSE, 1);
return ok;
return writeCameraStatus(cameraId, ok);
}
public boolean pic(Integer cameraId, int nChannelID, String path)
@ -290,7 +305,12 @@ public class HikCameraControlModuleImpl implements CameraControlModule {
HCNetSDK.NET_DVR_JPEGPARA jpegpara = new HCNetSDK.NET_DVR_JPEGPARA(wPicSize, wPicQuality);
boolean picResult = HikLoginModuleImpl.hcNetsdk.NET_DVR_CaptureJPEGPicture(lUserId, 1, jpegpara, path);
if (!picResult) {
log.error("pic error:{},cameraId:{},lUserId{}", HikLoginModuleImpl.hcNetsdk.NET_DVR_GetLastError(),cameraId,lUserId);
int errorCode = HikLoginModuleImpl.hcNetsdk.NET_DVR_GetLastError();
log.error("pic error:{},cameraId:{},lUserId{}",errorCode ,cameraId,lUserId);
IotServiceImpl.set(IotServiceImpl.cameraToStreetMap.get(cameraId),"cameraErrorCode",errorCode);
}else{
IotServiceImpl.set(IotServiceImpl.cameraToStreetMap.get(cameraId),"cameraErrorCode",0);
}
return picResult;
@ -309,12 +329,16 @@ public class HikCameraControlModuleImpl implements CameraControlModule {
int result = HikLoginModuleImpl.hcNetsdk.NET_DVR_GetFileByTime(lUserID, 1, startTime, endTime, path);
if (result == -1) {
log.error("downloadMp4 error code:{},cameraId:{},path:{}", HikLoginModuleImpl.hcNetsdk.NET_DVR_GetLastError(),cameraId,path);
int errorCode = HikLoginModuleImpl.hcNetsdk.NET_DVR_GetLastError();
log.error("downloadMp4 error code:{},cameraId:{},path:{}", errorCode,cameraId,path);
IotServiceImpl.set(IotServiceImpl.cameraToStreetMap.get(cameraId),"cameraErrorCode",errorCode);
} else {
HikLoginModuleImpl.hcNetsdk.NET_DVR_PlayBackControl(result, HikLoginModuleImpl.hcNetsdk.NET_DVR_PLAYSTART,0,null);
Timer downloadtimer = new Timer();
downloadtimer.schedule(new DownloadTask(result,downloadtimer,path,cameraId), 0, 5000);
IotServiceImpl.set(IotServiceImpl.cameraToStreetMap.get(cameraId),"cameraErrorCode",0);
}
}
class DownloadTask extends java.util.TimerTask {
@ -421,7 +445,11 @@ public class HikCameraControlModuleImpl implements CameraControlModule {
int dwzCommand = HCNetSDK.SET_PRESET;
Boolean ok = HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZPreset_Other(CameraConnMap.getConnId(cameraId).intValue(), 1, dwzCommand, ptzId.intValue());
if(!ok){
log.error("ptz error:{},cameraId:{}", HikLoginModuleImpl.hcNetsdk.NET_DVR_GetLastError(),cameraId);
int errorCode = HikLoginModuleImpl.hcNetsdk.NET_DVR_GetLastError();
log.error("ptz error:{},cameraId:{}", errorCode,cameraId);
IotServiceImpl.set(IotServiceImpl.cameraToStreetMap.get(cameraId),"cameraErrorCode",errorCode);
}else {
IotServiceImpl.set(IotServiceImpl.cameraToStreetMap.get(cameraId),"cameraErrorCode",0);
}
Assert.isTrue(ok, "设置失败");
}
@ -436,7 +464,11 @@ public class HikCameraControlModuleImpl implements CameraControlModule {
int dwPTZCommand = HCNetSDK.GOTO_PRESET;
Boolean ok = HikLoginModuleImpl.hcNetsdk.NET_DVR_PTZPreset_Other(CameraConnMap.getConnId(cameraId).intValue(), 1, dwPTZCommand, ptzId);
if(!ok){
log.error("toPtz error:{},cameraId:{}", HikLoginModuleImpl.hcNetsdk.NET_DVR_GetLastError(),cameraId);
int errorCode = HikLoginModuleImpl.hcNetsdk.NET_DVR_GetLastError();
log.error("ptz error:{},cameraId:{}", errorCode,cameraId);
IotServiceImpl.set(IotServiceImpl.cameraToStreetMap.get(cameraId),"cameraErrorCode",errorCode);
}else {
IotServiceImpl.set(IotServiceImpl.cameraToStreetMap.get(cameraId),"cameraErrorCode",0);
}
}
@ -459,7 +491,11 @@ public class HikCameraControlModuleImpl implements CameraControlModule {
Boolean ok = HikLoginModuleImpl.netsdk.CLIENT_DHPTZControlEx2(CameraConnMap.getConnId(cameraId), 0, dwPTZCommand,
0, 0, 0, 0, absolutely.getPointer());
if(!ok){
log.error("toPtzSlow error:{},cameraId:{}", HikLoginModuleImpl.hcNetsdk.NET_DVR_GetLastError(),cameraId);
int errorCode = HikLoginModuleImpl.hcNetsdk.NET_DVR_GetLastError();
log.error("ptz error:{},cameraId:{}", errorCode,cameraId);
IotServiceImpl.set(IotServiceImpl.cameraToStreetMap.get(cameraId),"cameraErrorCode",errorCode);
}else {
IotServiceImpl.set(IotServiceImpl.cameraToStreetMap.get(cameraId),"cameraErrorCode",0);
}
}
@ -470,8 +506,8 @@ public class HikCameraControlModuleImpl implements CameraControlModule {
LocalDateTime localDateTime = LocalDateTime.now();
time.setTime(localDateTime.getYear(),localDateTime.getMonthValue(),localDateTime.getDayOfMonth(),localDateTime.getHour(),localDateTime.getMinute(),localDateTime.getSecond());
time.write();
return HikLoginModuleImpl.hcNetsdk.NET_DVR_SetDVRConfig(lUserId, NET_DVR_SET_TIMECFG, 0,time.getPointer(), time.size());
boolean ok = HikLoginModuleImpl.hcNetsdk.NET_DVR_SetDVRConfig(lUserId, NET_DVR_SET_TIMECFG, 0,time.getPointer(), time.size());
return writeCameraStatus(cameraId, ok);
}
}

@ -3,6 +3,7 @@ package com.zhehekeji.web.lib.hik;
import com.sun.jna.Pointer;
import com.zhehekeji.web.lib.CameraConnMap;
import com.zhehekeji.web.lib.joyware.NetSDKLib;
import com.zhehekeji.web.service.iotService.IotServiceImpl;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@ -16,9 +17,11 @@ public class HikExceptionCallBack implements HCNetSDK.FExceptionCallBack {
if(dwType == 32768){
log.error("hik disconnect,cameraId:{}", cameraId);
IotServiceImpl.set(IotServiceImpl.cameraToStreetMap.get(cameraId),"cameraErrorCode",dwType);
}else if(dwType == 32791){
log.info("hik reconnect,cameraId:{}", cameraId);
IotServiceImpl.set(IotServiceImpl.cameraToStreetMap.get(cameraId),"cameraErrorCode",0);
if(!lLong.equals(CameraConnMap.getConnId(cameraId))) {
log.error("hik reconnect,cameraId:{},lUserId:{}", cameraId,lLong);

@ -1,16 +1,24 @@
package com.zhehekeji.web.lib.hik;
import com.sun.jna.Pointer;
import com.zhehekeji.web.config.ConfigProperties;
import com.zhehekeji.web.lib.CameraControlLoginModule;
import com.zhehekeji.web.lib.joyware.NetSDKLib;
import com.zhehekeji.web.service.iotService.IotServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* 海康 登陆接口实现
* 主要有 :初始化、登陆、登出功能
*/
@Slf4j
@Component
public class HikLoginModuleImpl implements CameraControlLoginModule {
@Resource
private IotServiceImpl iotService;
@ -69,7 +77,7 @@ public class HikLoginModuleImpl implements CameraControlLoginModule {
* 登录设备
* \endif
*/
public NetSDKLib.LLong login(String m_strIp, int m_nPort, String m_strUser, String m_strPassword) {
public NetSDKLib.LLong login(Integer id,String m_strIp, int m_nPort, String m_strUser, String m_strPassword) {
init();
HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();//设备登录信息
@ -97,7 +105,9 @@ public class HikLoginModuleImpl implements CameraControlLoginModule {
int tryTimes = 0;
while(m_lUserID < 0 && tryTimes < MAX_RECONNET_TIME){
log.error("hik login error,ip:{},port:{},errorCode:{}",m_strIp,m_nPort,hcNetsdk.NET_DVR_GetLastError());
int errorCode = hcNetsdk.NET_DVR_GetLastError();
log.error("hik login error,ip:{},port:{},errorCode:{}",m_strIp,m_nPort,errorCode);
IotServiceImpl.set(IotServiceImpl.cameraToStreetMap.get(id),"cameraErrorCode",errorCode);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
@ -108,6 +118,7 @@ public class HikLoginModuleImpl implements CameraControlLoginModule {
}
if(m_lUserID >= 0){
log.info("hik login success");
IotServiceImpl.set(IotServiceImpl.cameraToStreetMap.get(id),"cameraErrorCode",0);
//此id是用来保存视频的 且id不是固定的
int lDChannel = (int)m_strDeviceInfo.struDeviceV30.byStartDChan + lChannel -1;

@ -121,7 +121,7 @@ public class JoywareLoginModuleImpl implements CameraControlLoginModule {
* 登录设备
* \endif
*/
public LLong login(String m_strIp, int m_nPort, String m_strUser, String m_strPassword) {
public LLong login(Integer id,String m_strIp, int m_nPort, String m_strUser, String m_strPassword) {
//IntByReference nError = new IntByReference(0);
//入参
init(disConnectCallBack, haveReConnect);

@ -136,7 +136,7 @@ public class JoywarePlaybackTest {
if (password.isEmpty()) password = "admin123";
try {
LLong loginId = joywareLogin.login(ip, port, username, password);
LLong loginId = joywareLogin.login(1,ip, port, username, password);
if (loginId != null && loginId.longValue() != 0) {
loginIdMap.put(ip, loginId);

@ -19,7 +19,7 @@ public class IndustrialCameraVO implements Delayed {
private String trayCode;
private String wmsTrayCode;
private int flag;
private int flag = 12;
private String streetId;
private int sentCount;

@ -19,6 +19,7 @@ public class CheckLogSearch {
private LocalDateTime endTimestamp;
private Integer streetId;
private String streetPlc;
@ApiModelProperty("左右 1:左 2:右")
private Integer leftRight;

@ -322,7 +322,7 @@ public class CameraService {
}
public void cameraLogin(Camera camera){
NetSDKLib.LLong lLong = cameraControlLoginModule.login(camera.getIp(),camera.getPort(),camera.getUser(),camera.getPassword());
NetSDKLib.LLong lLong = cameraControlLoginModule.login(camera.getId(),camera.getIp(),camera.getPort(),camera.getUser(),camera.getPassword());
if(lLong != null){
log.info("camera login success,cameraId:{},ip:{}",camera.getId(),camera.getIp());
CameraConnMap.conn(camera.getId(),lLong);

@ -10,9 +10,12 @@ package com.zhehekeji.web.service.IndustrialCamera; /***************************
**************************************************************************************************/
import MvCameraControlWrapper.*;
import com.zhehekeji.web.config.ConfigProperties;
import com.zhehekeji.web.service.iotService.IotServiceImpl;
import org.springframework.stereotype.Service;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
@ -30,6 +33,17 @@ import static MvCameraControlWrapper.MvCameraControlDefines.*;
@Service
public class HikSaveImage implements CameraSaveUtil{
@Resource
ConfigProperties configProperties;
void setCameraErrorStatus(String sn,int status){
for (int i = 1; i <= configProperties.getCameraConfig().getIndustrialCamera().size(); i++){
if (configProperties.getCameraConfig().getIndustrialCamera().get(i-1).equals(sn)){
IotServiceImpl.set("zt","industrialCamera"+i+"ErrorCode",status);
break;
}
}
}
// 设备句柄保存
static Map<String,Handle> handleMap = new ConcurrentHashMap<>();
private static void printDeviceInfo(MV_CC_DEVICE_INFO stDeviceInfo)
@ -167,80 +181,144 @@ public class HikSaveImage implements CameraSaveUtil{
@Override
public boolean saveImage(String sn, String path,String type) {
int nRet = MV_OK;
int maxRetry = 3;
System.out.println("SDK Version " + MvCameraControl.MV_CC_GetSDKVersion());
// Enuerate GigE and USB devices
System.out.println("SDK Version " + MvCameraControl.MV_CC_GetSDKVersion());
// choose camera
// 重试循环:任何一步失败都会清理旧句柄、重新连接后重试
for (int attempt = 1; attempt <= maxRetry; attempt++) {
try {
Handle hCamera = null;
if (handleMap.containsKey(sn) && handleMap.get(sn) != null) {
//已经获得句柄
hCamera = handleMap.get(sn);
}else {
// 没有连接,重新连接设备
System.out.println("未找到句柄,尝试重新连接设备: " + sn);
hCamera = reconnect(sn, type);
if (hCamera == null) {
System.out.println("重新连接设备失败: " + sn);
continue;
}
System.out.println("重新连接设备成功: " + sn);
}
// Get payload size
MVCC_INTVALUE stParam = new MVCC_INTVALUE();
nRet = MvCameraControl.MV_CC_GetIntValue(hCamera, "PayloadSize", stParam);
if (MV_OK != nRet)
{
System.err.printf("Get PayloadSize fail, errcode: [%#x]\n", nRet);
setCameraErrorStatus(sn, nRet);
// 句柄可能已失效,重新连接后重试
reconnect(sn, type);
continue;
}
Handle hCamera = null;
if (handleMap.containsKey(sn) && handleMap.get(sn) != null) {
//已经获得句柄
hCamera = handleMap.get(sn);
}else {
System.out.println("未找到句柄");
}
// Create handle
// Get one frame
MV_FRAME_OUT_INFO stImageInfo = new MV_FRAME_OUT_INFO();
byte[] pData = new byte[(int)stParam.curValue];
nRet = MvCameraControl.MV_CC_GetOneFrameTimeout(hCamera, pData, stImageInfo, 1000);
if (MV_OK != nRet)
{
System.err.printf("GetOneFrameTimeout fail, errcode:[%#x]\n", nRet);
setCameraErrorStatus(sn, nRet);
reconnect(sn, type);
continue;
}
while(stImageInfo.height <= 0 || stImageInfo.width <= 0){
nRet = MvCameraControl.MV_CC_GetOneFrameTimeout(hCamera, pData, stImageInfo, 1000);
if (MV_OK != nRet)
{
System.err.printf("GetOneFrameTimeout fail, errcode:[%#x]\n", nRet);
setCameraErrorStatus(sn, nRet);
break;
}
}
if (MV_OK != nRet)
{
reconnect(sn, type);
continue;
}
System.out.println("GetOneFrame: ");
printFrameInfo(stImageInfo);
int imageLen = stImageInfo.width * stImageInfo.height * 3; // Every RGB pixel takes 3 bytes
byte[] imageBuffer = new byte[imageLen];
// Call MV_CC_SaveImage to save image as JPEG
MV_SAVE_IMAGE_PARAM stSaveParam = new MV_SAVE_IMAGE_PARAM();
stSaveParam.width = stImageInfo.width; // image width
stSaveParam.height = stImageInfo.height; // image height
stSaveParam.data = pData; // image data
stSaveParam.dataLen = stImageInfo.frameLen; // image data length
stSaveParam.pixelType = stImageInfo.pixelType; // image pixel format
stSaveParam.imageBuffer = imageBuffer; // output image buffer
stSaveParam.imageType = MV_SAVE_IAMGE_TYPE.MV_Image_Jpeg; // output image pixel format
stSaveParam.methodValue = 0; // Interpolation method that converts Bayer format to RGB24. 0-Neareast 1-double linear 2-Hamilton
stSaveParam.jpgQuality = 99; // JPG endoding quality(50-99]
nRet = MvCameraControl.MV_CC_SaveImage(hCamera, stSaveParam);
setCameraErrorStatus(sn, nRet);
if (MV_OK != nRet)
{
System.err.printf("SaveImage fail, errcode: [%#x]\n", nRet);
reconnect(sn, type);
continue;
}
// Save buffer content to file
saveDataToFile(imageBuffer, imageLen, path);
// Get payload size
MVCC_INTVALUE stParam = new MVCC_INTVALUE();
nRet = MvCameraControl.MV_CC_GetIntValue(hCamera, "PayloadSize", stParam);
if (MV_OK != nRet)
{
System.err.printf("Get PayloadSize fail, errcode: [%#x]\n", nRet);
return false;
setCameraErrorStatus(sn, MV_OK);
return true;
} catch (Exception e) {
System.err.println("第 " + attempt + " 次拍照异常: " + e.getMessage());
e.printStackTrace();
setCameraErrorStatus(sn, -1);
reconnect(sn, type);
}
}
System.out.println("重试 " + maxRetry + " 次后拍照失败: " + sn);
setCameraErrorStatus(sn, nRet);
return false;
}
// Get one frame
MV_FRAME_OUT_INFO stImageInfo = new MV_FRAME_OUT_INFO();
byte[] pData = new byte[(int)stParam.curValue];
nRet = MvCameraControl.MV_CC_GetOneFrameTimeout(hCamera, pData, stImageInfo, 1000);
while(true){
if(stImageInfo.height >0 && stImageInfo.width >0){
break;
}
/**
* 重新连接设备:清理旧句柄后,重新枚举并初始化
* @param sn 设备序列号
* @param type 匹配方式(sn/ip)
* @return 新句柄,失败返回null
*/
private Handle reconnect(String sn, String type) {
System.out.println("尝试重新连接设备: " + sn);
// 清理旧句柄
Handle oldHandle = handleMap.remove(sn);
if (oldHandle != null) {
try {
MvCameraControl.MV_CC_StopGrabbing(oldHandle);
} catch (Exception ignore) {
}
if (MV_OK != nRet)
{
System.err.printf("GetOneFrameTimeout fail, errcode:[%#x]\n", nRet);
return false;
try {
MvCameraControl.MV_CC_DestroyHandle(oldHandle);
} catch (Exception ignore) {
}
System.out.println("GetOneFrame: ");
printFrameInfo(stImageInfo);
int imageLen = stImageInfo.width * stImageInfo.height * 3; // Every RGB pixel takes 3 bytes
byte[] imageBuffer = new byte[imageLen];
// Call MV_CC_SaveImage to save image as JPEG
MV_SAVE_IMAGE_PARAM stSaveParam = new MV_SAVE_IMAGE_PARAM();
stSaveParam.width = stImageInfo.width; // image width
stSaveParam.height = stImageInfo.height; // image height
stSaveParam.data = pData; // image data
stSaveParam.dataLen = stImageInfo.frameLen; // image data length
stSaveParam.pixelType = stImageInfo.pixelType; // image pixel format
stSaveParam.imageBuffer = imageBuffer; // output image buffer
stSaveParam.imageType = MV_SAVE_IAMGE_TYPE.MV_Image_Jpeg; // output image pixel format
stSaveParam.methodValue = 0; // Interpolation method that converts Bayer format to RGB24. 0-Neareast 1-double linear 2-Hamilton
stSaveParam.jpgQuality = 99; // JPG endoding quality(50-99]
nRet = MvCameraControl.MV_CC_SaveImage(hCamera, stSaveParam);
if (MV_OK != nRet)
{
System.err.printf("SaveImage fail, errcode: [%#x]\n", nRet);
return false;
}
try {
ArrayList<MV_CC_DEVICE_INFO> stDeviceList = MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE);
if (stDeviceList == null || stDeviceList.size() <= 0) {
System.out.println("未枚举到任何设备");
setCameraErrorStatus(sn, -1);
return null;
}
// Save buffer content to file
saveDataToFile(imageBuffer, imageLen, path);
return true;
return init(sn, stDeviceList, type);
} catch (CameraControlException e) {
System.err.println("枚举设备失败!" + e.toString());
e.printStackTrace();
setCameraErrorStatus(sn, -1);
return null;
}
}
public void init(List<String> sns,String type){
ArrayList<MV_CC_DEVICE_INFO> stDeviceList = new ArrayList<>();
@ -281,6 +359,7 @@ public class HikSaveImage implements CameraSaveUtil{
nRet = MvCameraControl.MV_CC_OpenDevice(hCamera);
if (MV_OK != nRet) {
System.err.printf("Connect to camera failed, errcode: [%#x]\n", nRet);
setCameraErrorStatus(sn, nRet);
}
@ -288,6 +367,7 @@ public class HikSaveImage implements CameraSaveUtil{
nRet = MvCameraControl.MV_CC_SetEnumValueByString(hCamera, "TriggerMode", "Off");
if (MV_OK != nRet) {
System.err.printf("SetTriggerMode failed, errcode: [%#x]\n", nRet);
setCameraErrorStatus(sn, nRet);
}
// Get payload size
@ -295,6 +375,8 @@ public class HikSaveImage implements CameraSaveUtil{
// Start grabbing
nRet = MvCameraControl.MV_CC_StartGrabbing(hCamera);
setCameraErrorStatus(sn, nRet);
if (MV_OK != nRet) {
System.err.printf("Start Grabbing fail, errcode: [%#x]\n", nRet);
@ -324,6 +406,7 @@ public class HikSaveImage implements CameraSaveUtil{
if (camIndex == -1)
{
System.out.println("未找到摄像头");
setCameraErrorStatus(sn, -1);
return null;
}
//未获得句柄并初始化
@ -335,6 +418,7 @@ public class HikSaveImage implements CameraSaveUtil{
if (MV_OK != nRet)
{
System.err.printf("Connect to camera failed, errcode: [%#x]\n", nRet);
setCameraErrorStatus(sn, nRet);
return null;
}
@ -344,6 +428,7 @@ public class HikSaveImage implements CameraSaveUtil{
if (MV_OK != nRet)
{
System.err.printf("SetTriggerMode failed, errcode: [%#x]\n", nRet);
setCameraErrorStatus(sn, nRet);
return null;
}
@ -355,6 +440,7 @@ public class HikSaveImage implements CameraSaveUtil{
if (MV_OK != nRet)
{
System.err.printf("Start Grabbing fail, errcode: [%#x]\n", nRet);
setCameraErrorStatus(sn, nRet);
return null;
}
@ -364,6 +450,7 @@ public class HikSaveImage implements CameraSaveUtil{
{
System.err.println("Create handle failed!" + e.toString());
e.printStackTrace();
setCameraErrorStatus(sn, -1);
return null;

@ -3,6 +3,7 @@ package com.zhehekeji.web.service.IndustrialCamera;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.PointerByReference;
import com.zhehekeji.web.service.iotService.IotServiceImpl;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
@ -146,6 +147,7 @@ public class LxPointCloudSaveImage {
return handleRef;
} else {
log.error("设备 {} 初始化失败,错误码: {}", sn, result);
IotServiceImpl.set("zt","camera3dErrorCode",result);
return null;
}
}
@ -163,6 +165,7 @@ public class LxPointCloudSaveImage {
PointerByReference handleRef, DcLibrary.LxDeviceInfo info, int maxRetries) {
int result = INSTANCE.DcOpenDevice(1, sn, handleRef, info);
log.debug("设备 {} 首次打开结果: {}", sn, result);
IotServiceImpl.set("zt","camera3dErrorCode",result);
if (result == 0) {
return result;
@ -175,6 +178,7 @@ public class LxPointCloudSaveImage {
log.info("设备 {} 打开失败,第 {} 次重试,错误码: {}", sn, retryCount.get(), result);
Thread.sleep(RETRY_INTERVAL_MS);
result = INSTANCE.DcOpenDevice(1, sn, handleRef, info);
IotServiceImpl.set("zt","camera3dErrorCode",result);
if (result == 0) {
log.info("设备 {} 第 {} 次重试成功", sn, retryCount.get());
return result;
@ -183,11 +187,13 @@ public class LxPointCloudSaveImage {
} catch (InterruptedException e) {
log.error("设备 {} 重试被中断", sn, e);
Thread.currentThread().interrupt();
IotServiceImpl.set("zt","camera3dErrorCode",result);
return result;
}
}
log.error("设备 {} 重试 {} 次后仍然失败", sn, maxRetries);
IotServiceImpl.set("zt","camera3dErrorCode",result);
return result;
}
@ -226,6 +232,7 @@ public class LxPointCloudSaveImage {
// 尝试重新打开设备,设置新的句柄
int result = openDeviceWithRetry(INSTANCER, sn, handleRef, info, MAX_RETRY_COUNT);
IotServiceImpl.set("zt","camera3dErrorCode",result);
if (result == 0) {
// 更新设备信息
DeviceInfo deviceInfo = new DeviceInfo(handleRef, info, type);
@ -370,6 +377,7 @@ public class LxPointCloudSaveImage {
PointerByReference handleRef = getHandle(sn, type, INSTANCE);
if (handleRef == null) {
log.error("设备 {} 获取句柄失败", sn);
IotServiceImpl.set("zt","camera3dErrorCode",-3);
return -3;
}
@ -384,12 +392,15 @@ public class LxPointCloudSaveImage {
// 设置命令码
result = INSTANCE.DcSetCmd(handleRef.getValue(), 5001);
IotServiceImpl.set("zt","camera3dErrorCode",result);
if (result != 0 && result != 25) {
log.error("设备 {} 设置命令失败,错误码: {}", sn, result);
return -3;
}
} else {
log.error("设备 {} 流启动失败,错误码: {}", sn, result);
IotServiceImpl.set("zt","camera3dErrorCode",result);
return -3;
}
}
@ -409,11 +420,13 @@ public class LxPointCloudSaveImage {
if (saveResult != 0 && saveResult != 25) {
log.error("设备 {} 保存点云失败,错误码: {}", sn, saveResult);
IotServiceImpl.set("zt","camera3dErrorCode",saveResult);
return -1;
}
// 不再每次都停止流,流保持运行状态
log.info("设备 {} 保存成功", sn);
IotServiceImpl.set("zt","camera3dErrorCode",0);
return 0;
}
@ -445,6 +458,7 @@ public class LxPointCloudSaveImage {
if (handleRef == null) {
log.warn("设备 {} 第 {} 次拍照获取句柄失败,尝试重新设置句柄", sn, retryCount);
lastError = -3;
IotServiceImpl.set("zt","camera3dErrorCode",lastError);
// 尝试重新设置句柄
boolean reconnectSuccess = reDevice(sn);
@ -485,6 +499,9 @@ public class LxPointCloudSaveImage {
int result = INSTANCER.DcSetCmd(handleRef.getValue(), 5001);
log.info("设备 {} 3dCamera set cmd: {}, result: {}", sn, 5001, result);
if (result != 0 && result != 25) {
IotServiceImpl.set("zt","camera3dErrorCode",result);
}
// 保存点云数据
int saveResult = INSTANCER.DcSaveXYZ(handleRef.getValue(), path);
log.info("设备 {} 3dCamera save pcd: {}, result: {}", sn, path, saveResult);
@ -492,6 +509,7 @@ public class LxPointCloudSaveImage {
if (saveResult != 0 && saveResult != 25) {
log.warn("设备 {} 第 {} 次拍照保存点云失败,错误码: {},尝试重新设置句柄", sn, retryCount, saveResult);
lastError = -1;
IotServiceImpl.set("zt","camera3dErrorCode",saveResult);
// 尝试重新设置句柄
boolean reconnectSuccess = reconnect(sn, type);
@ -509,6 +527,7 @@ public class LxPointCloudSaveImage {
// 拍照成功
log.info("设备 {} 第 {} 次拍照成功", sn, retryCount);
IotServiceImpl.set("zt","camera3dErrorCode",0);
return 0;
} catch (InterruptedException e) {

@ -10,6 +10,7 @@ import com.zhehekeji.web.lib.joyware.JoywareCameraControlModuleImpl;
import com.zhehekeji.web.lib.joyware.JoywareLoginModuleImpl;
import com.zhehekeji.web.mapper.CameraMapper;
import com.zhehekeji.web.mapper.StreetMapper;
import com.zhehekeji.web.pojo.street.StreetVO;
import com.zhehekeji.web.service.IndustrialCamera.HikSaveImage;
import com.zhehekeji.web.service.algorithm.InventoryService;
import com.zhehekeji.web.service.client.ClientChanel;
@ -29,6 +30,8 @@ import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import static com.zhehekeji.web.service.iotService.IotServiceImpl.cameraToStreetMap;
/**
* 服务初始化
* 上位机、 plc、球机 连接
@ -100,10 +103,14 @@ public class InitService implements ApplicationRunner {
CommandQueue.sentHttp(restTemplate, configProperties);
if (configProperties.getCameraConfig()!=null
&& configProperties.getCameraConfig().getIndustrialCamera()!=null
&& !configProperties.getCameraConfig().getIndustrialCamera().isEmpty()
&& !configProperties.getCameraConfig().getIndustrialCamera().equals(""))
hikSaveImage.init(configProperties.getCameraConfig().getIndustrialCamera(),"sn");
if(ksec != null&& ksec.getIp()!=null&& !ksec.getIp().equals("")){
List<StreetVO> streetList = streetMapper.list();
for (StreetVO street : streetList) {
cameraToStreetMap.put(street.getCamera1Id(), street.getPlcId());
}
TaskDelayExecutor.runMp4DownloadExecutor();
// nettyServer.CreateNettyServer(configProperties.getServerPort());

@ -17,6 +17,7 @@ import com.zhehekeji.web.entity.EmptyCheckPic;
import com.zhehekeji.web.service.algorithm.InventoryService;
import com.zhehekeji.web.service.client.ClientChanel;
import com.zhehekeji.web.service.client.TransmissionPojo;
import com.zhehekeji.web.service.iotService.IotServiceImpl;
import com.zhehekeji.web.service.ksec.KsecDataInfo;
import com.zhehekeji.web.service.ksec.KsecInfo;
import com.zhehekeji.web.service.lbScanCode.ReentrantLockExample;
@ -98,6 +99,9 @@ public class PlcService {
@Resource
private CheckStreetSummaryMapper checkStreetSummaryMapper;
@Resource
private IotServiceImpl iotService;
@Resource
private InventoryService inventoryService;
@ -375,12 +379,20 @@ public class PlcService {
ReadOCR scan(PlcCmdInfo plcCmdInfo,Street street,String wmsTrayCode){
Boolean trayCheck = Boolean.FALSE;
ReadOCR trayCode = new ReadOCR();
String pointIdentification = "ScannerScanResult";
log.info("扫码类型:" + configProperties.getScanCodeMode().getTray());
//使用sick扫码枪
int leftRight = plcCmdInfo.getLeftRight1();
if(plcCmdInfo.getSeparation1()==2) {
pointIdentification = "Depth"+ pointIdentification;
leftRight=leftRight+2;
}
if(plcCmdInfo.getLeftRight1()==1) {
pointIdentification = "left"+ pointIdentification;
}else {
pointIdentification = "right"+ pointIdentification;
}
//托盘使用sick扫码枪
SensorGun sensorGun = sensorService.getSensorByPlc(street.getId(), leftRight);
if (sensorGun == null) {
@ -391,9 +403,9 @@ public class PlcService {
} else {
if (leftRight > 2) {
trayCode = CognexSocket.readOCR(sensorGun.getIp(), sensorGun.getPort());
trayCode = CognexSocket.readOCR(sensorGun.getIp(), sensorGun.getPort(),pointIdentification,street.getPlcId());
} else {
trayCode = SickSocket.readOCR(sensorGun.getIp(), sensorGun.getPort());
trayCode = SickSocket.readOCR(sensorGun.getIp(), sensorGun.getPort(),pointIdentification,street.getPlcId());
}
log.info("sensor tray code:{}", trayCode);
@ -1246,4 +1258,7 @@ public class PlcService {
return ksecInfo;
}
public void setPlcData(KsecInfo dataInfo, String srmNumber) {
iotService.set(srmNumber,"communicationData", dataInfo);
}
}

@ -32,6 +32,24 @@ public class SerialPortManager {
return portNameList;
}
/**
* 判断 COM 端口是否被占用(有其他进程在使用)
* @param portName 端口名,如 "COM1", "COM3"
* @return true=被占用,false=空闲可用
*/
public static boolean isComPortInUse(String portName) {
SerialPort port = SerialPort.getCommPort(portName);
if (port == null) {
return false; // 端口不存在,当作未占用
}
if (port.openPort(500)) {
// 能打开说明空闲,立即关闭释放
port.closePort();
return false;
}
return true; // 打不开说明被占用
}
// 连接串口
public static void connectSerialPort(String portName){
try {

@ -0,0 +1,264 @@
package com.zhehekeji.web.service.iotService;
import com.alibaba.fastjson.JSON;
import com.zhehekeji.core.pojo.Result;
import com.zhehekeji.web.config.ConfigProperties;
import com.zhehekeji.web.entity.KuKou;
import com.zhehekeji.web.entity.Street;
import com.zhehekeji.web.pojo.IndustrialCameraVO;
import com.zhehekeji.web.pojo.street.StreetVO;
import com.zhehekeji.web.service.StreetService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@Service
public class IotServiceImpl {
private static final Logger iotLog = LoggerFactory.getLogger("iot");
private static final ConcurrentHashMap<String, Map<String, Object>> map = new ConcurrentHashMap<>();
private static final ConcurrentHashMap<String, Object> ztMap = new ConcurrentHashMap<>();
// 并行 ping 的线程池(核心线程数 20,最大 50,闲置 60s 回收)
private static final ExecutorService pingPool = Executors.newFixedThreadPool(20);
public static Map<Integer, String> cameraToStreetMap = new HashMap<>();
// ping 超时时间(毫秒),局域网 1 秒足够
private static final int PING_TIMEOUT = 1000;
@Resource
StreetService streetService;
@Resource
ConfigProperties configProperties;
@Resource
RestTemplate restTemplate;
/**
* 初始化:读取 default.txt
*/
@PostConstruct
public void init() {
try {
String jsonStr = new String(Files.readAllBytes(Paths.get("default.txt")), StandardCharsets.UTF_8);
Map<String, Object> data = JSON.parseObject(jsonStr);
for (Map.Entry<String, Object> entry : data.entrySet()) {
for (Map.Entry<String, Object> entry1 : ((Map<String, Object>) entry.getValue()).entrySet()) {
set(entry.getKey(), entry1.getKey(), entry1.getValue());
}
}
System.out.println("初始化完成,数据: " + map.size());
} catch (IOException e) {
e.printStackTrace();
}
}
@Scheduled(cron = "0/5 * * * * ?")
/** 定时任务:每5秒拉取网络状态并更新(并行 ping) */
private void refreshNetwork() {
try {
List<String> lines = Files.readAllLines(Paths.get("network.txt"), StandardCharsets.UTF_8);
// 收集所有异步任务
List<CompletableFuture<Void>> futures = new ArrayList<>();
for (String line : lines) {
line = line.trim();
if (line.isEmpty()) continue;
String[] parts = line.split("=");
if (parts.length != 2) continue;
String ip = parts[0].trim().replace("\"", "");
String[] keyField = parts[1].split(":");
if (keyField.length != 2) continue;
String deviceKey = keyField[0].trim();
String fieldName = keyField[1].trim();
// 异步提交 ping 任务
int status = ping(ip) ? 1 : 2;
set(deviceKey, fieldName,status );
}
String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
for (String entry : map.keySet()) {
set(entry, "time", timestamp);
}
set("zt", "time", timestamp);
} catch (Exception e) {
iotLog.error("网络状态刷新异常", e);
}
getZT();
}
/**
* 将当前数据状态数据推送给远端 IoT 控制器
*/
// @Scheduled(cron = "0/5 * * * * ?")
public void getZT() {
if (!configProperties.getComTofConfig().isEmpty()) {
// 判断TOF设备连接状态:访问 10.0.0.1 的 502 端口(Modbus TCP)
boolean isComPortInUse = isTcpPortInUse("10.0.0.1", 502);
for (int i = 0; i < configProperties.getComTofConfig().size(); i++) {
set("zt", "tofDevice0" + (i+1) + "RunStatus", isComPortInUse ? 1 : 2);
// System.out.println("1111");
}
}else {
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "application/json");
headers.set("User-Agent", "Mozilla/5.0");
// 从 map 构建传输对象
IndustrialCameraVO scTransmission = new IndustrialCameraVO();
// TODO: 根据实际需要填充 scTransmission 的字段
// 例如:scTransmission.setDeviceList(new ArrayList<>(map.values()));
String URL = "http://" + configProperties.getSiteInventoryIp() + ":8099" + "/api/IotController/listZT";
iotLog.info("获取站台数据: {} 路径: {}", scTransmission.toString(), URL);
// 创建 HttpEntity 对象
HttpEntity<IndustrialCameraVO> entity = new HttpEntity<>(scTransmission, headers);
try {
// 发送 POST 请求
ResponseEntity<Map<String, Object>> response = restTemplate.exchange(
URL,
HttpMethod.POST,
entity,
new ParameterizedTypeReference<Map<String, Object>>() {
}
);
iotLog.info("请求成功,响应:{}", response.getBody());
set("zt", "inventoryServerOnlineStatus", 1);
if (response.getBody() != null && response.getBody().get("data") != null) {
Map<String, Object> data = (Map<String, Object>) response.getBody().get("data");
for (Map.Entry<String, Object> entry : data.entrySet()) {
// iotLog.info("数据键: {}, 值: {}", entry.getKey(), entry.getValue());
set("zt", entry.getKey(), entry.getValue());
}
}
}catch (Exception e)
{
set("zt", "inventoryServerOnlineStatus", 2);
iotLog.error("请求失败", e);
}
}
}
/**
* 获取:返回 map 的 values 列表
*/
public List<Object> get() {
return new ArrayList<>(map.values());
}
public Map<String, Object> get(String deviceKey) {
if(deviceKey.equals("zt")){
return ztMap;
}
return map.get(deviceKey);
}
public static void set(String deviceKey, String key, Object value) {
if (deviceKey == null){
iotLog.error("数据不存在{} 数据key: {} 数据value: {}新增数据类型", deviceKey, key, value.toString());
return;
}
if (deviceKey.equals("zt")) {
Object oldValue = ztMap.get(key);
if (oldValue != null && oldValue.equals(value)) {
// 数据无变化,不记录日志
return;
}
iotLog.info("更新站台数据key: {} 数据value: {}", key, value.toString());
ztMap.put(key, value);
} else {
Map<String, Object> deviceMap = map.get(deviceKey);
if (deviceMap == null) {
iotLog.warn("数据不存在{} 数据key: {} 数据value: {}新增数据类型", deviceKey, key, value.toString());
deviceMap = new HashMap<>();
deviceMap.put(key, value);
map.put(deviceKey, deviceMap);
return;
}
Object oldValue = deviceMap.get(key);
if (oldValue != null && oldValue.equals(value)) {
// 数据无变化,不记录日志
return;
}
iotLog.info("更新巷道号{} 数据key: {} 数据value: {}", deviceKey, key, value.toString());
deviceMap.put(key, value);
}
}
private boolean ping(String ip) {
try {
return InetAddress.getByName(ip).isReachable(PING_TIMEOUT);
} catch (IOException e) {
return false;
}
}
/**
* 检测TCP端口是否可连接
*/
private boolean isTcpPortInUse(String ip, int port) {
try (Socket socket = new Socket()) {
socket.connect(new InetSocketAddress(ip, port), 1000);
return true;
} catch (IOException e) {
return false;
}
}
/**
* 应用关闭时释放线程池(可选,建议配合 @PreDestroy)
*/
@PreDestroy
public void destroy() {
pingPool.shutdown();
}
}

@ -0,0 +1,38 @@
package com.zhehekeji.web.service.iotService;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
//@Configuration
//public class ScheduleConfig implements SchedulingConfigurer {
//
// @Override
// public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
// taskRegistrar.addTriggerTask(
// // 要定时执行的任务
// () -> refreshNetwork(),
// // 每次执行前动态读取 cron
// triggerContext -> {
// String cron = null;
// try {
// cron = new String(
// Files.readAllBytes(Paths.get("cron.txt")), StandardCharsets.UTF_8).trim();
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
// return new CronTrigger(cron).nextExecutionTime(triggerContext);
// }
// );
// }
//
// private void refreshNetwork() {
//
// }
//}

@ -103,7 +103,7 @@ public class CommandQueue {
if (response.getStatusCode().is2xxSuccessful()) {
log.info("请求成功,响应:{}", response.getBody());
} else {
log.warn("请求未成功,状态码:{}", response.getStatusCode());
log.error("请求未成功,返回:{}状态码:{}", response, response.getStatusCode());
addCommand(scTransmission);
}

@ -1,6 +1,7 @@
package com.zhehekeji.web.service.ksec;
import com.zhehekeji.web.service.*;
import com.zhehekeji.web.service.iotService.IotServiceImpl;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelInitializer;
@ -23,12 +24,13 @@ public class KescFilter extends ChannelInitializer<SocketChannel> {
private PlcService plcService;
private KsecNettyClient nettyClient;
private IotServiceImpl iotService;
public KescFilter(KsecInfo ksecInfo, PlcService plcService, KsecNettyClient nettyClient){
public KescFilter(KsecInfo ksecInfo, PlcService plcService, KsecNettyClient nettyClient,IotServiceImpl iotService){
this.ksecInfo = ksecInfo;
this.plcService = plcService;
this.nettyClient = nettyClient;
this.iotService = iotService;
}
@Override
@ -37,7 +39,7 @@ public class KescFilter extends ChannelInitializer<SocketChannel> {
//4秒发一次心跳
ph.addLast(new IdleStateHandler(0, 4, 0, TimeUnit.SECONDS));
ByteBuf byteBuf = Unpooled.copiedBuffer(">".getBytes());
ph.addLast(new KsecDecoder(10000,byteBuf,plcService));
ph.addLast(new KsecDecoder(10000,byteBuf,plcService,iotService));
ph.addLast(new KescEncoder());
ph.addLast(new KescNettyHandler(ksecInfo,nettyClient));
}

@ -6,6 +6,7 @@ import com.zhehekeji.web.pojo.Cmd;
import com.zhehekeji.web.service.GoodsActionTimes;
import com.zhehekeji.web.service.PlcCmdInfo;
import com.zhehekeji.web.service.PlcService;
import com.zhehekeji.web.service.iotService.IotServiceImpl;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
@ -38,10 +39,12 @@ public class KsecDecoder extends DelimiterBasedFrameDecoder {
private static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(7,21,30, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<>(20000));
private PlcService plcService;
private IotServiceImpl iotService;
public KsecDecoder(int maxFrameLength, ByteBuf delimiter, PlcService plcService) {
public KsecDecoder(int maxFrameLength, ByteBuf delimiter, PlcService plcService,IotServiceImpl iotService) {
super(maxFrameLength, delimiter);
this.plcService = plcService;
this.iotService = iotService;
}
@Override
@ -51,7 +54,7 @@ public class KsecDecoder extends DelimiterBasedFrameDecoder {
log.debug("no data");
return null;
}
KescRunnable kescRunnable = new KescRunnable(in,ctx,plcService);
KescRunnable kescRunnable = new KescRunnable(in,ctx,plcService,iotService);
threadPoolExecutor.execute(kescRunnable);
return null;
}
@ -63,11 +66,13 @@ public class KsecDecoder extends DelimiterBasedFrameDecoder {
private ChannelHandlerContext ctx;
private PlcService plcService;
private IotServiceImpl iotService;
public KescRunnable(ByteBuf body,ChannelHandlerContext ctx,PlcService plcService){
public KescRunnable(ByteBuf body,ChannelHandlerContext ctx,PlcService plcService,IotServiceImpl iotService){
this.in = body;
this.ctx = ctx;
this.plcService = plcService;
this.iotService = iotService;
}
@Override
@ -82,8 +87,16 @@ public class KsecDecoder extends DelimiterBasedFrameDecoder {
in.release();
return ;
}
ksecInfo.setHeader("LP");
KsecDataInfo dataInfo = ksecInfo.getData();
String lotnum = dataInfo.getLotnum();
String lotnum = null;
if (dataInfo != null){
lotnum = dataInfo.getLotnum();
}else {
log.error("dataInfo is null{}",body);
return;
}
PlcCmdInfo plcCmdInfo = null;
String srmNumber = null;
String cmdName = null;
@ -104,46 +117,49 @@ public class KsecDecoder extends DelimiterBasedFrameDecoder {
srmNumber = dataInfo.getSRMNumber();
cmdName = dataInfo.getCmdName();
}
//数据上传
plcService.setPlcData(ksecInfo, srmNumber);
if (Cmd.A.name().equals(ksecInfo.getType())) {
//心跳
log.debug("receieve heart ");
} else if (Cmd.B.name().equals(ksecInfo.getType())) {
IotServiceImpl.set(srmNumber,"communicationData",ksecInfo);
//任务
if (Cmd.B1.name().equals(cmdName)) {
IotServiceImpl.set(srmNumber,"warehouseRunStatus",1);
//昆船盘点模式下也会发B1 ,但是不会发送B2
//这里判断下,是否存在盘点批次号 若存在,既是盘点的B1,无需处理;若不存在lotnum,则是随行的B1
if(StringUtils.isEmpty(dataInfo.getLotnum())){
//任务开始 旋转到原点位
plcService.gyrateCamera(plcCmdInfo,Cmd.C5.name());
plcService.orderStart(plcCmdInfo);
}else {
log.info("check move");
}
} else if (Cmd.B2.name().equals(cmdName)) {
//B2 C4 一起发的,需要停止等B2
//这里判断是不是双伸
if(plcCmdInfo.getSeparation2() == 2){
//深测货架延迟
try {
Thread.sleep(plcService.getConfigProperties().getCameraConfig().getB2OutDelayTime());
} catch (InterruptedException e) {
e.printStackTrace();
}
//没有B2了,收到B1后一分钟后自动执行B2的停止逻辑
//线程中引用的局部变量需为final
final PlcCmdInfo finalPlcCmdInfo = plcCmdInfo;
final String finalSrmNumber = srmNumber;
threadPoolExecutor.execute(() -> {
try {
//延迟一分钟
Thread.sleep(60 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
//赋值cmdName为B2
ksecInfo.getData().setCmdName(Cmd.B2.name());
plcService.gyrateCamera(finalPlcCmdInfo,Cmd.C5.name());
plcService.orderStop(finalPlcCmdInfo);
IotServiceImpl.set(finalSrmNumber,"warehouseRunStatus",3);
});
}else {
//浅侧延迟
try {
Thread.sleep(plcService.getConfigProperties().getCameraConfig().getB2DelayTime());
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("check move");
}
plcService.gyrateCamera(plcCmdInfo,Cmd.C5.name());
plcService.orderStop(plcCmdInfo);
}
} else if (Cmd.C.name().equals(ksecInfo.getType())) {
IotServiceImpl.set(srmNumber,"communicationData",ksecInfo);
//动作
String code = dataInfo.getCmdName();
@ -182,7 +198,9 @@ public class KsecDecoder extends DelimiterBasedFrameDecoder {
// log.info("other D code :{}",code);
// }
} else if (Cmd.E.name().equals(ksecInfo.getType())) {
IotServiceImpl.set(srmNumber,"communicationData",ksecInfo);
IotServiceImpl.set(srmNumber,"warehouseRunStatus",2);
//盘点
//转球机到盘点位 然后拍照
@ -219,9 +237,18 @@ public class KsecDecoder extends DelimiterBasedFrameDecoder {
log.error("sleep error",e);
}
ctx.channel().writeAndFlush(ksecInfo);
plcService.setPlcData(ksecInfo, srmNumber);
log.info("盘点结束:"+ksecInfo.getData().toString());
IotServiceImpl.set(srmNumber,"warehouseRunStatus",3);
IotServiceImpl.set(srmNumber,"communicationData",ksecInfo);
}else if (Cmd.SC.name().equals(ksecInfo.getType())) {
IotServiceImpl.set("zt","warehouseRunStatus",2);
IotServiceImpl.set("zt","communicationData",ksecInfo);
int flag = plcService.checkVision(dataInfo,true);
ksecInfo.getData().setCmdName("SC02");
@ -232,6 +259,9 @@ public class KsecDecoder extends DelimiterBasedFrameDecoder {
log.error("sleep error",e);
}
ctx.channel().writeAndFlush(ksecInfo);
IotServiceImpl.set("zt","communicationData",ksecInfo);
IotServiceImpl.set("zt","warehouseRunStatus",3);
}
//找到该货位的最后一张照片与现在的照片比照
//plcService.recordStock(plcCmdInfo, dataInfo.getCode(), 0, 0);

@ -3,6 +3,7 @@ package com.zhehekeji.web.service.ksec;
import com.zhehekeji.common.util.FileUtil;
import com.zhehekeji.web.config.ConfigProperties;
import com.zhehekeji.web.service.PlcService;
import com.zhehekeji.web.service.iotService.IotServiceImpl;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.EventLoopGroup;
@ -25,6 +26,9 @@ public class KsecNettyClient {
@Resource
private ConfigProperties configProperties;
@Resource
private IotServiceImpl iotService;
/**
* 重连最大次数
*/
@ -54,7 +58,7 @@ public class KsecNettyClient {
c.group(group);
c.channel(NioSocketChannel.class);
KsecInfo heart = KsecInfo.heart();
c.handler(new KescFilter(heart, plcService, this));
c.handler(new KescFilter(heart, plcService, this,iotService));
client = c;
}

@ -1,6 +1,7 @@
package com.zhehekeji.web.service.sick;
import com.zhehekeji.web.entity.ReadOCR;
import com.zhehekeji.web.service.iotService.IotServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -15,11 +16,8 @@ public class CognexSocket {
private static final Logger tcpLogger = LoggerFactory.getLogger("sick");
public static void main(String[] args) {
ReadOCR readOCR = readOCR("127.0.0.1", 2001);
System.out.println(readOCR);
}
public static ReadOCR readOCR(String ip, int port){
public static ReadOCR readOCR(String ip, int port,String key,String cmd ){
ReadOCR readOCR = new ReadOCR();
Socket socket = new Socket();
String code = "NOREAD";
@ -45,10 +43,12 @@ public class CognexSocket {
}else {
readOCR.setStatus(1);
}
IotServiceImpl.set(cmd,key,1);
} catch (IOException e) {
tcpLogger.error("sick time out,ip:{},info:{}",ip,e);
log.error("sick time out,ip:{},info:{}",ip,e);
readOCR.setStatus(0);
IotServiceImpl.set(cmd,key,2);
}finally {
if(os != null){
try {

@ -1,6 +1,7 @@
package com.zhehekeji.web.service.sick;
import com.zhehekeji.web.entity.ReadOCR;
import com.zhehekeji.web.service.iotService.IotServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -19,7 +20,7 @@ public class SickSocket {
private static final Logger tcpLogger = LoggerFactory.getLogger("sick");
public static ReadOCR readOCR(String ip, int port){
public static ReadOCR readOCR(String ip, int port, String key,String cmd ){
ReadOCR readOCR = new ReadOCR();
Socket socket = new Socket();
String code = "NoRead";
@ -45,10 +46,13 @@ public class SickSocket {
}else {
readOCR.setStatus(1);
}
IotServiceImpl.set(cmd,key,1);
} catch (Exception e) {
tcpLogger.error("sick time out,ip:{},info:{}",ip,e);
log.error("sick time out,ip:{},info:{}",ip,e);
readOCR.setStatus(0);
IotServiceImpl.set(cmd,key,2);
}finally {
if(os != null){
try {

@ -130,4 +130,9 @@ template:
code: "a1123"
# 光源串口
comConfig: "COM2"
comConfig: "COM2"
siteInventoryIp: "127.0.0.1"
#
#comTofConfig:
# - "COM1"
# - "COM2"

@ -125,6 +125,25 @@
</filter>
</appender>
<!-- IoT 设备状态日志 -->
<appender name="iotAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${LOG_HOME}/${logName}-iot.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/${logName}-iot-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxHistory>30</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>%d %p (%file:%line\)- %m%n</pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
</appender>
<!-- additivity属性为false,表示此logger的打印信息不再向上级传递(注:该值默认为true,logger的日志信息会依次向上级传递,最高级logger为root,如果不加则至少打印2次,本身一次,root一次)-->
<logger name="tcp" additivity="false" level="INFO">
<appender-ref ref="tcpAppender"/>
@ -135,6 +154,11 @@
<appender-ref ref="sickTcpAppender"/>
</logger>
<logger name="iot" additivity="false" level="INFO">
<appender-ref ref="iotAppender"/>
<appender-ref ref="CONSOLE"/>
</logger>
<logger name="com.zhehekeji.web.mapper" level="DEBUG" />
<!--info和error分开打印,注:ERROR > WARN > INFO > DEBUG > TRACE-->

@ -0,0 +1,10 @@
顺序
1.先从default.txt中获取默认值
2.每5s根据network拿数据更新网络值
"192.168.1.2"=002:warehouseNetworkStatus
前面是ip,后面是default.txt的对应
站台
1.zt作为站台default.txt的key,只有zt!network也是只有zt!
2.定时给主服务器发送
Loading…
Cancel
Save