mirror of
https://gitee.com/pan648540858/wvp-GB28181-pro.git
synced 2026-06-25 03:57:49 +08:00
增加看守位控制
This commit is contained in:
parent
b71a057b23
commit
391fdf4660
@ -0,0 +1,24 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.conf;
|
||||||
|
|
||||||
|
import gov.nist.javax.sip.stack.CustomNioTcpMessageProcessor;
|
||||||
|
import gov.nist.javax.sip.stack.MessageProcessor;
|
||||||
|
import gov.nist.javax.sip.stack.NioMessageProcessorFactory;
|
||||||
|
import gov.nist.javax.sip.stack.SIPTransactionStack;
|
||||||
|
|
||||||
|
import javax.sip.ListeningPoint;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
|
||||||
|
public class CustomMessageProcessorFactory extends NioMessageProcessorFactory {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MessageProcessor createMessageProcessor(
|
||||||
|
SIPTransactionStack sipStack, InetAddress ipAddress,
|
||||||
|
int port, String transport) throws IOException {
|
||||||
|
if (transport.equalsIgnoreCase(ListeningPoint.TCP)) {
|
||||||
|
return new CustomNioTcpMessageProcessor(ipAddress, sipStack, port);
|
||||||
|
}
|
||||||
|
return super.createMessageProcessor(sipStack, ipAddress, port, transport);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -51,7 +51,7 @@ public class DefaultProperties {
|
|||||||
// 如果为 true(默认作),则堆栈将保持套接字打开,以便以牺牲线程和内存资源为代价来最大化性能 - 使自身容易受到 DOS 攻击。
|
// 如果为 true(默认作),则堆栈将保持套接字打开,以便以牺牲线程和内存资源为代价来最大化性能 - 使自身容易受到 DOS 攻击。
|
||||||
properties.setProperty("gov.nist.javax.sip.CACHE_SERVER_CONNECTIONS", String.valueOf(sipCacheServerConnections));
|
properties.setProperty("gov.nist.javax.sip.CACHE_SERVER_CONNECTIONS", String.valueOf(sipCacheServerConnections));
|
||||||
|
|
||||||
properties.setProperty("gov.nist.javax.sip.MESSAGE_PROCESSOR_FACTORY", "gov.nist.javax.sip.stack.NioMessageProcessorFactory");
|
properties.setProperty("gov.nist.javax.sip.MESSAGE_PROCESSOR_FACTORY", "com.genersoft.iot.vmp.gb28181.conf.CustomMessageProcessorFactory");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sip_server_log.log 和 sip_debug_log.log ERROR, INFO, WARNING, OFF, DEBUG, TRACE
|
* sip_server_log.log 和 sip_debug_log.log ERROR, INFO, WARNING, OFF, DEBUG, TRACE
|
||||||
|
|||||||
@ -134,7 +134,7 @@ public class DeviceControl {
|
|||||||
deviceService.iFrame(device, channelId);
|
deviceService.iFrame(device, channelId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "看守位控制", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
@Operation(summary = "看守位设置", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||||
@Parameter(name = "channelId", description = "通道国标编号", required = true)
|
@Parameter(name = "channelId", description = "通道国标编号", required = true)
|
||||||
@Parameter(name = "enabled", description = "是否开启看守位", required = true)
|
@Parameter(name = "enabled", description = "是否开启看守位", required = true)
|
||||||
@ -145,7 +145,7 @@ public class DeviceControl {
|
|||||||
@RequestParam(required = false) Integer resetTime,
|
@RequestParam(required = false) Integer resetTime,
|
||||||
@RequestParam(required = false) Integer presetIndex) {
|
@RequestParam(required = false) Integer presetIndex) {
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("看守位控制API调用");
|
log.debug("看守位设置API调用");
|
||||||
}
|
}
|
||||||
Device device = deviceService.getDeviceByDeviceId(deviceId);
|
Device device = deviceService.getDeviceByDeviceId(deviceId);
|
||||||
Assert.notNull(device, "设备不存在");
|
Assert.notNull(device, "设备不存在");
|
||||||
@ -154,7 +154,7 @@ public class DeviceControl {
|
|||||||
result.setResult(new WVPResult<>(code, msg, data));
|
result.setResult(new WVPResult<>(code, msg, data));
|
||||||
});
|
});
|
||||||
result.onTimeout(() -> {
|
result.onTimeout(() -> {
|
||||||
log.warn("[看守位控制] 操作超时, 设备未返回应答指令, {}", deviceId);
|
log.warn("[看守位设置] 操作超时, 设备未返回应答指令, {}", deviceId);
|
||||||
result.setResult(WVPResult.fail(ErrorCode.ERROR100.getCode(), "操作超时, 设备未应答"));
|
result.setResult(WVPResult.fail(ErrorCode.ERROR100.getCode(), "操作超时, 设备未应答"));
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@ -1294,7 +1294,7 @@ public class DeviceServiceImpl implements IDeviceService {
|
|||||||
try {
|
try {
|
||||||
sipCommander.homePositionCmd(device, channelId, enabled, resetTime, presetIndex, callback);
|
sipCommander.homePositionCmd(device, channelId, enabled, resetTime, presetIndex, callback);
|
||||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
log.error("[命令发送失败] 看守位控制: {}", e.getMessage());
|
log.error("[命令发送失败] 看守位设置: {}", e.getMessage());
|
||||||
callback.run(ErrorCode.ERROR100.getCode(), "命令发送: " + e.getMessage(), null);
|
callback.run(ErrorCode.ERROR100.getCode(), "命令发送: " + e.getMessage(), null);
|
||||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -778,7 +778,7 @@ public class SIPCommander implements ISIPCommander {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 看守位控制命令
|
* 看守位设置
|
||||||
*
|
*
|
||||||
* @param device 视频设备
|
* @param device 视频设备
|
||||||
* @param channelId 通道id,非通道则是设备本身
|
* @param channelId 通道id,非通道则是设备本身
|
||||||
|
|||||||
@ -0,0 +1,34 @@
|
|||||||
|
package gov.nist.javax.sip.stack;
|
||||||
|
|
||||||
|
import gov.nist.core.HostPort;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
|
||||||
|
public class CustomNioTcpMessageProcessor extends NioTcpMessageProcessor {
|
||||||
|
|
||||||
|
public CustomNioTcpMessageProcessor(InetAddress ipAddress,
|
||||||
|
SIPTransactionStack sipStack, int port) {
|
||||||
|
super(ipAddress, sipStack, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MessageChannel createMessageChannel(HostPort targetHostPort) throws IOException {
|
||||||
|
MessageChannel retval = null;
|
||||||
|
try {
|
||||||
|
String key = MessageChannel.getKey(targetHostPort, transport);
|
||||||
|
retval = messageChannels.get(key);
|
||||||
|
//here we use double-checked locking trying to reduce contention
|
||||||
|
} finally {
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MessageChannel createMessageChannel(InetAddress targetHost, int port) throws IOException {
|
||||||
|
String key = MessageChannel.getKey(targetHost, port, transport);
|
||||||
|
MessageChannel retval = messageChannels.get(key);
|
||||||
|
//here we use double-checked locking trying to reduce contention
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -16,6 +16,10 @@
|
|||||||
<i class="iconfont icon-slider-right" style="margin-right: 6px" />
|
<i class="iconfont icon-slider-right" style="margin-right: 6px" />
|
||||||
<span>线性扫描</span>
|
<span>线性扫描</span>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
|
<el-menu-item index="guard">
|
||||||
|
<i class="el-icon-s-home" style="margin-right: 6px" />
|
||||||
|
<span>看守位</span>
|
||||||
|
</el-menu-item>
|
||||||
<el-menu-item index="switch">
|
<el-menu-item index="switch">
|
||||||
<i class="el-icon-s-tools" style="margin-right: 6px" />
|
<i class="el-icon-s-tools" style="margin-right: 6px" />
|
||||||
<span>辅助开关</span>
|
<span>辅助开关</span>
|
||||||
@ -30,6 +34,7 @@
|
|||||||
<ptzPresetConfig v-if="activeTab === 'preset'" :device-id="deviceId" :channel-device-id="channelDeviceId" />
|
<ptzPresetConfig v-if="activeTab === 'preset'" :device-id="deviceId" :channel-device-id="channelDeviceId" />
|
||||||
<ptzCruiseConfig v-if="activeTab === 'cruise'" :device-id="deviceId" :channel-device-id="channelDeviceId" />
|
<ptzCruiseConfig v-if="activeTab === 'cruise'" :device-id="deviceId" :channel-device-id="channelDeviceId" />
|
||||||
<ptzScanConfig v-if="activeTab === 'scan'" :device-id="deviceId" :channel-device-id="channelDeviceId" />
|
<ptzScanConfig v-if="activeTab === 'scan'" :device-id="deviceId" :channel-device-id="channelDeviceId" />
|
||||||
|
<ptzGuardConfig v-if="activeTab === 'guard'" :device-id="deviceId" :channel-device-id="channelDeviceId" />
|
||||||
<ptzSwitchConfig v-if="activeTab === 'switch'" :device-id="deviceId" :channel-device-id="channelDeviceId" />
|
<ptzSwitchConfig v-if="activeTab === 'switch'" :device-id="deviceId" :channel-device-id="channelDeviceId" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -43,10 +48,11 @@ import ptzPresetConfig from '../common/ptzPresetConfig.vue'
|
|||||||
import ptzCruiseConfig from '../common/ptzCruiseConfig.vue'
|
import ptzCruiseConfig from '../common/ptzCruiseConfig.vue'
|
||||||
import ptzScanConfig from '../common/ptzScanConfig.vue'
|
import ptzScanConfig from '../common/ptzScanConfig.vue'
|
||||||
import ptzSwitchConfig from '../common/ptzSwitchConfig.vue'
|
import ptzSwitchConfig from '../common/ptzSwitchConfig.vue'
|
||||||
|
import ptzGuardConfig from '../common/ptzGuardConfig.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PtzConfigPage',
|
name: 'PtzConfigPage',
|
||||||
components: { playerPtzPanel, ptzPresetConfig, ptzCruiseConfig, ptzScanConfig, ptzSwitchConfig },
|
components: { playerPtzPanel, ptzPresetConfig, ptzCruiseConfig, ptzScanConfig, ptzSwitchConfig, ptzGuardConfig },
|
||||||
props: {
|
props: {
|
||||||
deviceId: { type: String, default: null },
|
deviceId: { type: String, default: null },
|
||||||
channelDeviceId: { type: String, default: null }
|
channelDeviceId: { type: String, default: null }
|
||||||
|
|||||||
102
web/src/views/device/common/ptzGuardConfig.vue
Normal file
102
web/src/views/device/common/ptzGuardConfig.vue
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-form label-width="120px" class="guard-form">
|
||||||
|
<el-form-item label="启用">
|
||||||
|
<el-switch v-model="enabled" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="预置位">
|
||||||
|
<el-select v-model="presetIndex" style="width: 180px" placeholder="选择预置位">
|
||||||
|
<el-option v-for="p in allPresetList" :key="p.presetId"
|
||||||
|
:label="p.presetId + '-' + (p.presetName || ('预置点' + p.presetId))"
|
||||||
|
:value="Number(p.presetId)" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="自动归位(秒)">
|
||||||
|
<el-input-number v-model="resetTime" :min="1" :max="999999" controls-position="right" style="width: 180px" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<div class="guard-actions">
|
||||||
|
<el-button @click="loadPresets">刷新</el-button>
|
||||||
|
<el-button type="primary" :loading="submitting" :disabled="submitting" @click="confirmSave">保存</el-button>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'PtzGuardConfig',
|
||||||
|
props: {
|
||||||
|
deviceId: { type: String, default: null },
|
||||||
|
channelDeviceId: { type: String, default: null }
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
enabled: false,
|
||||||
|
presetIndex: null,
|
||||||
|
resetTime: 10,
|
||||||
|
allPresetList: [],
|
||||||
|
submitting: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.loadPresets()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
loadPresets() {
|
||||||
|
this.$store.dispatch('frontEnd/queryPreset', [this.deviceId, this.channelDeviceId])
|
||||||
|
.then(data => {
|
||||||
|
this.allPresetList = data || []
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.log('[看守位] 加载预置点列表失败', error)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
confirmSave() {
|
||||||
|
if (!this.enabled && !this.presetIndex) {
|
||||||
|
this.$message({ showClose: true, message: '请选择预置位编号', type: 'warning' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.resetTime == null || this.resetTime < 1) {
|
||||||
|
this.$message({ showClose: true, message: '请输入有效的归位时间', type: 'warning' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.submitting = true
|
||||||
|
const params = {
|
||||||
|
deviceId: this.deviceId,
|
||||||
|
channelId: this.channelDeviceId,
|
||||||
|
enabled: this.enabled
|
||||||
|
}
|
||||||
|
if (this.presetIndex != null) {
|
||||||
|
params.presetIndex = this.presetIndex
|
||||||
|
}
|
||||||
|
if (this.resetTime != null) {
|
||||||
|
params.resetTime = this.resetTime
|
||||||
|
}
|
||||||
|
this.$store.dispatch('device/homePosition', params)
|
||||||
|
.then(() => {
|
||||||
|
this.$message({ showClose: true, message: '保存成功', type: 'success' })
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
this.$message({ showClose: true, message: error || '保存失败', type: 'error' })
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.submitting = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.guard-form {
|
||||||
|
padding: 16px 12px;
|
||||||
|
max-width: 420px;
|
||||||
|
}
|
||||||
|
.guard-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Loading…
Reference in New Issue
Block a user