Commit 3227dcd082454a1bf85ee623b8d62bbd47d10420

Authored by 648540858
1 parent 91bfbc36

添加兼容接口预置位添加调用删除,列表查询

src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
@@ -1137,7 +1137,6 @@ public class SIPCommander implements ISIPCommander { @@ -1137,7 +1137,6 @@ public class SIPCommander implements ISIPCommander {
1137 } 1137 }
1138 cmdXml.append("</Query>\r\n"); 1138 cmdXml.append("</Query>\r\n");
1139 1139
1140 -  
1141 1140
1142 Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); 1141 Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()));
1143 sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent); 1142 sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent);
src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiControlController.java
1 package com.genersoft.iot.vmp.web.gb28181; 1 package com.genersoft.iot.vmp.web.gb28181;
2 2
3 -import com.alibaba.fastjson2.JSONObject;  
4 import com.genersoft.iot.vmp.conf.exception.ControllerException; 3 import com.genersoft.iot.vmp.conf.exception.ControllerException;
5 import com.genersoft.iot.vmp.gb28181.bean.Device; 4 import com.genersoft.iot.vmp.gb28181.bean.Device;
6 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; 5 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
@@ -9,7 +8,9 @@ import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; @@ -9,7 +8,9 @@ import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
9 import org.slf4j.Logger; 8 import org.slf4j.Logger;
10 import org.slf4j.LoggerFactory; 9 import org.slf4j.LoggerFactory;
11 import org.springframework.beans.factory.annotation.Autowired; 10 import org.springframework.beans.factory.annotation.Autowired;
12 -import org.springframework.web.bind.annotation.*; 11 +import org.springframework.web.bind.annotation.RequestMapping;
  12 +import org.springframework.web.bind.annotation.RequestParam;
  13 +import org.springframework.web.bind.annotation.RestController;
13 14
14 import javax.sip.InvalidArgumentException; 15 import javax.sip.InvalidArgumentException;
15 import javax.sip.SipException; 16 import javax.sip.SipException;
@@ -102,4 +103,53 @@ public class ApiControlController { @@ -102,4 +103,53 @@ public class ApiControlController {
102 throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage()); 103 throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
103 } 104 }
104 } 105 }
  106 +
  107 + /**
  108 + * 设备控制 - 预置位控制
  109 + * @param serial 设备编号
  110 + * @param code 通道编号,通过 /api/v1/device/channellist 获取的 ChannelList.ID, 该参数和 channel 二选一传递即可
  111 + * @param channel 通道序号, 默认值: 1
  112 + * @param command 控制指令 允许值: set, goto, remove
  113 + * @param preset 预置位编号(1~255)
  114 + * @param name 预置位名称, command=set 时有效
  115 + * @return
  116 + */
  117 + @RequestMapping(value = "/preset")
  118 + private void list(String serial,String command,
  119 + @RequestParam(required = false)Integer channel,
  120 + @RequestParam(required = false)String code,
  121 + @RequestParam(required = false)String name,
  122 + @RequestParam(required = false)Integer preset){
  123 +
  124 + if (logger.isDebugEnabled()) {
  125 + logger.debug("模拟接口> 预置位控制 API调用,deviceId:{} ,channelId:{} ,command:{} ,name:{} ,preset:{} ",
  126 + serial, code, command, name, preset);
  127 + }
  128 +
  129 + if (channel == null) {channel = 0;}
  130 + Device device = storager.queryVideoDevice(serial);
  131 + if (device == null) {
  132 + throw new ControllerException(ErrorCode.ERROR100.getCode(), "device[ " + serial + " ]未找到");
  133 + }
  134 + int cmdCode = 0;
  135 + switch (command){
  136 + case "set":
  137 + cmdCode = 129;
  138 + break;
  139 + case "goto":
  140 + cmdCode = 130;
  141 + break;
  142 + case "remove":
  143 + cmdCode = 131;
  144 + break;
  145 + default:
  146 + break;
  147 + }
  148 + try {
  149 + cmder.frontEndCmd(device, code, cmdCode, 0, preset, 0);
  150 + } catch (SipException | InvalidArgumentException | ParseException e) {
  151 + logger.error("[命令发送失败] 预置位控制: {}", e.getMessage());
  152 + throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
  153 + }
  154 + }
105 } 155 }
src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiDeviceController.java
@@ -2,21 +2,32 @@ package com.genersoft.iot.vmp.web.gb28181; @@ -2,21 +2,32 @@ package com.genersoft.iot.vmp.web.gb28181;
2 2
3 import com.alibaba.fastjson2.JSONArray; 3 import com.alibaba.fastjson2.JSONArray;
4 import com.alibaba.fastjson2.JSONObject; 4 import com.alibaba.fastjson2.JSONObject;
  5 +import com.genersoft.iot.vmp.conf.exception.ControllerException;
5 import com.genersoft.iot.vmp.gb28181.bean.Device; 6 import com.genersoft.iot.vmp.gb28181.bean.Device;
  7 +import com.genersoft.iot.vmp.gb28181.bean.PresetQuerySipReq;
  8 +import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
  9 +import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
  10 +import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
6 import com.genersoft.iot.vmp.service.IDeviceService; 11 import com.genersoft.iot.vmp.service.IDeviceService;
7 import com.genersoft.iot.vmp.storager.IVideoManagerStorage; 12 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
  13 +import com.genersoft.iot.vmp.vmanager.bean.DeferredResultEx;
  14 +import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
8 import com.genersoft.iot.vmp.web.gb28181.dto.DeviceChannelExtend; 15 import com.genersoft.iot.vmp.web.gb28181.dto.DeviceChannelExtend;
9 import com.github.pagehelper.PageInfo; 16 import com.github.pagehelper.PageInfo;
10 import org.slf4j.Logger; 17 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory; 18 import org.slf4j.LoggerFactory;
12 import org.springframework.beans.factory.annotation.Autowired; 19 import org.springframework.beans.factory.annotation.Autowired;
  20 +import org.springframework.util.ObjectUtils;
13 import org.springframework.util.StringUtils; 21 import org.springframework.util.StringUtils;
14 import org.springframework.web.bind.annotation.RequestMapping; 22 import org.springframework.web.bind.annotation.RequestMapping;
15 import org.springframework.web.bind.annotation.RequestParam; 23 import org.springframework.web.bind.annotation.RequestParam;
16 import org.springframework.web.bind.annotation.RestController; 24 import org.springframework.web.bind.annotation.RestController;
  25 +import org.springframework.web.context.request.async.DeferredResult;
17 26
18 -import java.util.Arrays;  
19 -import java.util.List; 27 +import javax.sip.InvalidArgumentException;
  28 +import javax.sip.SipException;
  29 +import java.text.ParseException;
  30 +import java.util.*;
20 31
21 /** 32 /**
22 * API兼容:设备信息 33 * API兼容:设备信息
@@ -31,17 +42,15 @@ public class ApiDeviceController { @@ -31,17 +42,15 @@ public class ApiDeviceController {
31 42
32 @Autowired 43 @Autowired
33 private IVideoManagerStorage storager; 44 private IVideoManagerStorage storager;
  45 +
  46 + @Autowired
  47 + private SIPCommander cmder;
34 @Autowired 48 @Autowired
35 private IDeviceService deviceService; 49 private IDeviceService deviceService;
36 50
37 - // @Autowired  
38 - // private SIPCommander cmder;  
39 -  
40 - // @Autowired  
41 - // private DeferredResultHolder resultHolder; 51 + @Autowired
  52 + private DeferredResultHolder resultHolder;
42 53
43 - // @Autowired  
44 - // private DeviceOffLineDetector offLineDetector;  
45 54
46 /** 55 /**
47 * 分页获取设备列表 现在直接返回,尚未实现分页 56 * 分页获取设备列表 现在直接返回,尚未实现分页
@@ -171,4 +180,78 @@ public class ApiDeviceController { @@ -171,4 +180,78 @@ public class ApiDeviceController {
171 result.put("ChannelList", channleJSONList); 180 result.put("ChannelList", channleJSONList);
172 return result; 181 return result;
173 } 182 }
  183 +
  184 + /**
  185 + * 设备信息 - 获取下级通道预置位
  186 + * @param serial 设备编号
  187 + * @param code 通道编号,通过 /api/v1/device/channellist 获取的 ChannelList.ID, 该参数和 channel 二选一传递即可
  188 + * @param channel 通道序号, 默认值: 1
  189 + * @param fill 是否填充空置预置位,当下级返回预置位,但不够255个时,自动填充空置预置位到255个, 默认值: true, 允许值: true, false
  190 + * @param timeout 超时时间(秒) 默认值: 15
  191 + * @return
  192 + */
  193 + @RequestMapping(value = "/fetchpreset")
  194 + private DeferredResult<Object> list(String serial,
  195 + @RequestParam(required = false)Integer channel,
  196 + @RequestParam(required = false)String code,
  197 + @RequestParam(required = false)Boolean fill,
  198 + @RequestParam(required = false)Integer timeout){
  199 +
  200 + if (logger.isDebugEnabled()) {
  201 + logger.debug("<模拟接口> 获取下级通道预置位 API调用,deviceId:{} ,channel:{} ,code:{} ,fill:{} ,timeout:{} ",
  202 + serial, channel, code, fill, timeout);
  203 + }
  204 +
  205 + Device device = storager.queryVideoDevice(serial);
  206 + String uuid = UUID.randomUUID().toString();
  207 + String key = DeferredResultHolder.CALLBACK_CMD_PRESETQUERY + (ObjectUtils.isEmpty(code) ? serial : code);
  208 + DeferredResult<Object> result = new DeferredResult<> (timeout * 1000L);
  209 + DeferredResultEx<Object> deferredResultEx = new DeferredResultEx<>(result);
  210 + result.onTimeout(()->{
  211 + logger.warn("<模拟接口> 获取设备预置位超时");
  212 + // 释放rtpserver
  213 + RequestMessage msg = new RequestMessage();
  214 + msg.setId(uuid);
  215 + msg.setKey(key);
  216 + msg.setData("wait for presetquery timeout["+timeout+"s]");
  217 + resultHolder.invokeResult(msg);
  218 + });
  219 + if (resultHolder.exist(key, null)) {
  220 + return result;
  221 + }
  222 +
  223 + deferredResultEx.setFilter(filterResult->{
  224 + List<PresetQuerySipReq> presetQuerySipReqList = (List<PresetQuerySipReq>)filterResult;
  225 + HashMap<String, Object> resultMap = new HashMap<>();
  226 + resultMap.put("DeviceID", code);
  227 + resultMap.put("Result", "OK");
  228 + resultMap.put("SumNum", presetQuerySipReqList.size());
  229 + ArrayList<Map<String, Object>> presetItemList = new ArrayList<>(presetQuerySipReqList.size());
  230 + for (PresetQuerySipReq presetQuerySipReq : presetQuerySipReqList) {
  231 + Map<String, Object> item = new HashMap<>();
  232 + item.put("PresetID", presetQuerySipReq.getPresetId());
  233 + item.put("PresetName", presetQuerySipReq.getPresetName());
  234 + item.put("PresetEnable", true);
  235 + presetItemList.add(item);
  236 + }
  237 + resultMap.put("PresetItemList",presetItemList );
  238 + return resultMap;
  239 + });
  240 +
  241 + resultHolder.put(key, uuid, deferredResultEx);
  242 +
  243 + try {
  244 + cmder.presetQuery(device, code, event -> {
  245 + RequestMessage msg = new RequestMessage();
  246 + msg.setId(uuid);
  247 + msg.setKey(key);
  248 + msg.setData(String.format("获取设备预置位失败,错误码: %s, %s", event.statusCode, event.msg));
  249 + resultHolder.invokeResult(msg);
  250 + });
  251 + } catch (InvalidArgumentException | SipException | ParseException e) {
  252 + logger.error("[命令发送失败] 获取设备预置位: {}", e.getMessage());
  253 + throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
  254 + }
  255 + return result;
  256 + }
174 } 257 }