Commit 3227dcd082454a1bf85ee623b8d62bbd47d10420
1 parent
91bfbc36
添加兼容接口预置位添加调用删除,列表查询
Showing
3 changed files
with
144 additions
and
12 deletions
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
| ... | ... | @@ -1137,7 +1137,6 @@ public class SIPCommander implements ISIPCommander { |
| 1137 | 1137 | } |
| 1138 | 1138 | cmdXml.append("</Query>\r\n"); |
| 1139 | 1139 | |
| 1140 | - | |
| 1141 | 1140 | |
| 1142 | 1141 | Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); |
| 1143 | 1142 | sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent); | ... | ... |
src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiControlController.java
| 1 | 1 | package com.genersoft.iot.vmp.web.gb28181; |
| 2 | 2 | |
| 3 | -import com.alibaba.fastjson2.JSONObject; | |
| 4 | 3 | import com.genersoft.iot.vmp.conf.exception.ControllerException; |
| 5 | 4 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 6 | 5 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; |
| ... | ... | @@ -9,7 +8,9 @@ import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; |
| 9 | 8 | import org.slf4j.Logger; |
| 10 | 9 | import org.slf4j.LoggerFactory; |
| 11 | 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 | 15 | import javax.sip.InvalidArgumentException; |
| 15 | 16 | import javax.sip.SipException; |
| ... | ... | @@ -102,4 +103,53 @@ public class ApiControlController { |
| 102 | 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 | 2 | |
| 3 | 3 | import com.alibaba.fastjson2.JSONArray; |
| 4 | 4 | import com.alibaba.fastjson2.JSONObject; |
| 5 | +import com.genersoft.iot.vmp.conf.exception.ControllerException; | |
| 5 | 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 | 11 | import com.genersoft.iot.vmp.service.IDeviceService; |
| 7 | 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 | 15 | import com.genersoft.iot.vmp.web.gb28181.dto.DeviceChannelExtend; |
| 9 | 16 | import com.github.pagehelper.PageInfo; |
| 10 | 17 | import org.slf4j.Logger; |
| 11 | 18 | import org.slf4j.LoggerFactory; |
| 12 | 19 | import org.springframework.beans.factory.annotation.Autowired; |
| 20 | +import org.springframework.util.ObjectUtils; | |
| 13 | 21 | import org.springframework.util.StringUtils; |
| 14 | 22 | import org.springframework.web.bind.annotation.RequestMapping; |
| 15 | 23 | import org.springframework.web.bind.annotation.RequestParam; |
| 16 | 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 | 33 | * API兼容:设备信息 |
| ... | ... | @@ -31,17 +42,15 @@ public class ApiDeviceController { |
| 31 | 42 | |
| 32 | 43 | @Autowired |
| 33 | 44 | private IVideoManagerStorage storager; |
| 45 | + | |
| 46 | + @Autowired | |
| 47 | + private SIPCommander cmder; | |
| 34 | 48 | @Autowired |
| 35 | 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 | 180 | result.put("ChannelList", channleJSONList); |
| 172 | 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 | } | ... | ... |