1. 增加NB通道支持

2. 控制器通信协议更新2.0版本
3. 增加省ID,北斗通播ID配置文件
This commit is contained in:
黄昕 2023-11-09 17:10:07 +08:00
parent ad909fa569
commit a67b1840aa
15 changed files with 208 additions and 73 deletions

View File

@ -2,3 +2,6 @@ socket.server-host=localhost
socket.server-port=10001
socket.server-mode=tcp
socket.heart-timeout=60
common.provice-code = 33
common.beidou-id = 1234588

View File

@ -10,14 +10,17 @@ import com.zjyr.beidouservice.misc.HelperUtils;
import com.zjyr.beidouservice.pojo.vo.binary.BaseBinaryProtocol;
import com.zjyr.beidouservice.pojo.vo.binary.ControllerStatus;
import com.zjyr.beidouservice.pojo.vo.binary.MessageContent;
import com.zjyr.beidouservice.pojo.vo.binary.SensorId;
import com.zjyr.beidouservice.pojo.vo.binary.SensorStatusAck;
import com.zjyr.beidouservice.pojo.vo.binary.SensorStatusInfo;
import com.zjyr.beidouservice.pojo.vo.binary.SensorTaskAck;
import com.zjyr.beidouservice.pojo.vo.binary.SensorTaskStatus;
import com.zjyr.beidouservice.service.DeviceService;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@ -29,6 +32,9 @@ import java.util.List;
@RequiredArgsConstructor
@Slf4j
public class YuanRongProtocolDecode extends ByteToMessageDecoder {
@Resource
DeviceService deviceService;
@Override
protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf buf, List<Object> list) {
log.info("\n{}", ByteBufUtil.prettyHexDump(buf));
@ -46,13 +52,15 @@ public class YuanRongProtocolDecode extends ByteToMessageDecoder {
switch (cmd) {
case COMMAND_REPORT_HEART -> {
int heartSeq = buf.readInt();
SendStatusName sendStatus = CommonEnumHandler.codeOf(SendStatusName.class, buf.readByte());
SendStatusName sendStatus = SendStatusName.SEND_SUCCESS;//CommonEnumHandler.codeOf(SendStatusName.class, buf
// .readByte());
ControlChannelStatus beidouStatus = CommonEnumHandler.codeOf(ControlChannelStatus.class, buf.readByte());
byte[] beidouCommFreq = new byte[3];
buf.readBytes(beidouCommFreq, 0, 3);
byte[] beidouCommFreq = {0x00, 0x00, 0x00};
//buf.readBytes(beidouCommFreq, 0, 3);
byte[] beidouSignal = new byte[10];
buf.readBytes(beidouSignal, 0, 10);
ControlChannelStatus wireStatus = CommonEnumHandler.codeOf(ControlChannelStatus.class, buf.readByte());
buf.readByte(); // 无线信号强度暂不使用
ControlChannelStatus phoneStatus = CommonEnumHandler.codeOf(ControlChannelStatus.class, buf.readByte());
ControllerStatus status = ControllerStatus.builder()
@ -84,14 +92,25 @@ public class YuanRongProtocolDecode extends ByteToMessageDecoder {
SensorTaskAck taskAck = SensorTaskAck.builder().taskId(taskId).ackTimestamp(timeStamp).sensorStatus(new ArrayList<>(
nItem)).build();
for (int i = 0; i < nItem; i++) {
SensorId sensorId = SensorId.builder()
.countyId(buf.readByte())
.seqId(buf.readByte())
.build();
Integer beidouId = deviceService.getDeviceBeidouIdBySeqId(sensorId.getSeqId());
if (beidouId == -1) {
log.error("Can not find device by seqId: {}", sensorId.getSeqId());
continue;
}
SensorTaskStatus taskStatus = SensorTaskStatus.builder()
.sensorId(buf.readInt())
.sensorId(beidouId)
.taskResult(CommonEnumHandler.codeOf(TaskResultName.class,
buf.readByte()))
.tunnelName(CommonEnumHandler.codeOf(SensorControlTunnelName.class,
buf.readByte()))
.build();
taskAck.getSensorStatus().add(taskStatus);
}

View File

@ -1,15 +1,19 @@
package com.zjyr.beidouservice.adapter.impl.netty.encode;
import com.zjyr.beidouservice.common.impl.ControlCommandName;
import com.zjyr.beidouservice.config.CommonConfigure;
import com.zjyr.beidouservice.misc.HelperUtils;
import com.zjyr.beidouservice.pojo.vo.binary.BaseBinaryProtocol;
import com.zjyr.beidouservice.pojo.vo.binary.HeartProtocol;
import com.zjyr.beidouservice.pojo.vo.binary.QuerySensorProtocol;
import com.zjyr.beidouservice.pojo.vo.binary.SensorControlProtocol;
import com.zjyr.beidouservice.pojo.vo.binary.SensorId;
import com.zjyr.beidouservice.service.DeviceService;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@ -20,6 +24,12 @@ import java.io.UnsupportedEncodingException;
@RequiredArgsConstructor
@Slf4j
public class YuanRongProtocolEncode<T> extends MessageToByteEncoder<BaseBinaryProtocol<T>> {
@Resource
CommonConfigure commonConfigure;
@Resource
DeviceService deviceService;
@Override
protected void encode(ChannelHandlerContext channelHandlerContext,
BaseBinaryProtocol<T> baseBinaryProtocol,
@ -53,18 +63,39 @@ public class YuanRongProtocolEncode<T> extends MessageToByteEncoder<BaseBinaryPr
ttsSize = 0;
}
if (!msg.getSensorId().isEmpty()) {
// 删除无效的ID
for (var c : msg.getSensorId()) {
SensorId sensor = deviceService.getSensorIdByBeidouId(c);
if (sensor == null) {
msg.getSensorId().remove(c);
}
}
}
byteBuf.writeByte(ControlCommandName.COMMAND_SENSOR.getValue().byteValue()); // 消息类型
// 消息内容长度
byteBuf.writeShort(10 + 4 + ttsSize + msg.getCityCode().size() + msg.getDistrictsCode().size() + msg.getSensorId().size() * 4);
byteBuf.writeShort(27 + ttsSize + msg.getCityCode().size() + msg.getDistrictsCode().size() + msg.getSensorId().size() * 2);
// 任务ID, 当前长度 4
byteBuf.writeInt(msg.getTaskId());
// 警报控制, 当前长度 5
byteBuf.writeByte(msg.getAlarmMode().getValue().byteValue());
byteBuf.writeByte(msg.getAlarmMode().getValue().byteValue());
// 警报模式, 当前长度 6
byteBuf.writeByte(msg.getAlarmControlType().getValue().byteValue());
// 警报类型, 当前长度 7
byteBuf.writeByte(msg.getAlarmType().getValue().byteValue());
// 警报通道, 当前长度 8
byteBuf.writeByte(msg.getControlTunnel().byteValue());
// 警报时间, 当前长度 12
byteBuf.writeInt(msg.getTimeStamp());
// 警报重复次数, 当前长度 13
byteBuf.writeByte(msg.getRepeatTimes().byteValue());
// 北斗ID, 当前长度 21
byteBuf.writeLong(commonConfigure.getBeidouId());
// 省ID, 当前长度 22(不含可变内容长度)
byteBuf.writeByte(commonConfigure.getProviceCode().byteValue());
// TTS 内容长度, 当前长度 24
byteBuf.writeShort((short) ttsSize);
if (ttsSize > 0) {
byteBuf.writeBytes(ttsArray);
}
@ -92,7 +123,14 @@ public class YuanRongProtocolEncode<T> extends MessageToByteEncoder<BaseBinaryPr
} else {
byteBuf.writeByte(msg.getSensorId().size());
for (var c : msg.getSensorId()) {
byteBuf.writeInt(c);
SensorId sensor = deviceService.getSensorIdByBeidouId(c);
if (sensor == null) {
byteBuf.writeByte(0xFF);
byteBuf.writeByte(0xFF);
} else {
byteBuf.writeByte(sensor.getCountyId());
byteBuf.writeByte(sensor.getSeqId());
}
}
}
} else if (msgBody instanceof QuerySensorProtocol msg) {

View File

@ -3,13 +3,9 @@ package com.zjyr.beidouservice.common.impl;
import com.zjyr.beidouservice.common.EnumerationBase;
public enum AlarmControlTypeName implements EnumerationBase {
ALARM_CONTROL_TYPE_NORMAL_LOUD(0, "ALARM_CONTROL_TYPE_NORMAL_LOUD"),
ALARM_CONTROL_TYPE_TEST_QUITE(1, "ALARM_CONTROL_TYPE_TEST_QUITE"),
ALARM_CONTROL_TYPE_TEST_SHORT(2, "ALARM_CONTROL_TYPE_TEST_SHORT"),
ALARM_CONTROL_TYPE_NORMAL_QUITE(0, "警报无声"),
ALARM_CONTROL_TYPE_TEST_LOUD(3, "ALARM_CONTROL_TYPE_TEST_LOUD"),
ALARM_CONTROL_TYPE_VOICE(4, "ALARM_CONTROL_TYPE_VOICE"),
ALARM_CONTROL_TYPE_NORMAL_LOUD(1, "警报大声"),
;
private final Integer code;

View File

@ -5,17 +5,17 @@ import com.zjyr.beidouservice.constenum.AlarmTypeEnum;
public enum AlarmTypeName implements EnumerationBase {
ALARM_TYPE_INTERRUPT(0, "中断警报"),
ALARM_TYPE_PREPARE(1, "预先警报"),
ALARM_TYPE_AIRATTACK(2, "空袭警报"),
ALARM_TYPE_DISASTER(3, "灾情警报"),
ALARM_TYPE_RELIEVE_AIRATTACK(4, "解除警报"),
ALARM_TYPE_RELIEVE_DISASTER(5, "解除警报灾情"),
ALARM_TYPE_FIRE(5, "消防警报"),
SHORT_BEEP_TEST(6, "短鸣测试"),
ALARM_TYPE_VOICE_PLAY(7, "语音播报");
ALARM_TYPE_INTERRUPT(6, "中断警报"),
ALARM_TYPE_FIRE(7, "消防警报"),
SHORT_BEEP_TEST(8, "短鸣测试");
private final Integer code;
private final String desc;

View File

@ -3,14 +3,15 @@ package com.zjyr.beidouservice.common.impl;
import com.zjyr.beidouservice.common.EnumerationBase;
public enum SensorControlTunnelName implements EnumerationBase {
TUNNEL_BEIDOU(1, "BeiDou tunnel"),
TUNNEL_BEIDOU(0x01, "BeiDou tunnel"),
TUNNEL_WIRELESS(2, "Wireless tunnel"),
TUNNEL_WIRELESS(0x02, "Wireless tunnel"),
TUNNEL_TEL(4, "Telephone tunnel"),
TUNNEL_TEL(0x04, "Telephone tunnel"),
TUNNEL_ALL(7,"All")
;
TUNNEL_NB(0x08, "NB tunnel"),
TUNNEL_ALL(0x0F, "All");
private final Integer code;
private final String desc;

View File

@ -0,0 +1,22 @@
package com.zjyr.beidouservice.config;
import jakarta.annotation.PostConstruct;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Data
@ConfigurationProperties(prefix = "common")
@Configuration
@Slf4j
public class CommonConfigure {
private Integer proviceCode;
private Long beidouId;
@PostConstruct
private void initGlobalValue() {
log.info("Current: proviceCode = {}, beidouId = {}", proviceCode, beidouId);
}
}

View File

@ -51,7 +51,7 @@ public class AuthUser {
SensorControlProtocol sensorPro = adapterProtocolService.createSensorControlProtocol(1024,
AlarmModeName.ALARM_MODE_MANUALLY,
AlarmControlTypeName.ALARM_CONTROL_TYPE_TEST_QUITE,
AlarmControlTypeName.ALARM_CONTROL_TYPE_NORMAL_QUITE,
AlarmTypeName.ALARM_TYPE_AIRATTACK,
SensorControlTunnelName.TUNNEL_BEIDOU.getValue() |
SensorControlTunnelName.TUNNEL_WIRELESS.getValue(),

View File

@ -18,5 +18,9 @@ public interface DeviceMapper {
List<DeviceDO> selectDeviceByDeviceIds(@Param("ids") List<Integer> deviceIdList);
void batchUpdateDeviceAlarmStatus(@Param("ids") Set<Integer> alarmingDeviceIds, @Param("status") Integer code);
List<DeviceDO> getDeviceBySeqId(@Param("seqId") Integer seqId);
List<DeviceDO> getDeviceByBeidouId(@Param("beidouId") Integer beidouId);
}

View File

@ -2,8 +2,10 @@ package com.zjyr.beidouservice.pojo.dto.task;
import com.zjyr.beidouservice.pojo.dataobject.AlarmDeviceTaskDO;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
public class AlarmDeviceTaskDTO extends AlarmDeviceTaskDO {

View File

@ -0,0 +1,11 @@
package com.zjyr.beidouservice.pojo.vo.binary;
import lombok.Builder;
import lombok.Data;
@Builder
@Data
public class SensorId {
private int countyId;
private int seqId;
}

View File

@ -10,6 +10,5 @@ import lombok.Data;
public class SensorTaskStatus {
private int sensorId;
private TaskResultName taskResult;
private SensorControlTunnelName tunnelName;
}

View File

@ -6,6 +6,7 @@ import com.zjyr.beidouservice.pojo.dto.DeviceByIdRespDTO;
import com.zjyr.beidouservice.pojo.dto.DeviceReqDTO;
import com.zjyr.beidouservice.pojo.dto.DeviceRespDTO;
import com.zjyr.beidouservice.pojo.dto.DeviceSearchDTO;
import com.zjyr.beidouservice.pojo.vo.binary.SensorId;
import java.util.List;
@ -31,4 +32,7 @@ public interface DeviceService {
*/
void refreshDeviceAlarmStatus(List<AlarmDeviceTaskDO> deviceTaskDOS);
Integer getDeviceBeidouIdBySeqId(Integer seqId);
SensorId getSensorIdByBeidouId(Integer beidouId);
}

View File

@ -11,6 +11,7 @@ import com.zjyr.beidouservice.pojo.dto.DeviceByLocationDTO;
import com.zjyr.beidouservice.pojo.dto.DeviceReqDTO;
import com.zjyr.beidouservice.pojo.dto.DeviceRespDTO;
import com.zjyr.beidouservice.pojo.dto.DeviceSearchDTO;
import com.zjyr.beidouservice.pojo.vo.binary.SensorId;
import com.zjyr.beidouservice.service.DeviceService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
@ -60,7 +61,8 @@ public class DeviceServiceImpl implements DeviceService {
public DeviceByIdRespDTO getDeviceByDeviceId(DeviceSearchDTO deviceSearchDTO) {
log.info("get device info by deviceId: [{}]", deviceSearchDTO.getDeviceId());
List<DeviceDO> deviceDOList = deviceMapper.selectDeviceByDeviceIds(Collections.singletonList(deviceSearchDTO.getDeviceId()));
List<DeviceDO> deviceDOList =
deviceMapper.selectDeviceByDeviceIds(Collections.singletonList(deviceSearchDTO.getDeviceId()));
if (deviceDOList.isEmpty()) {
log.warn("根据deviceId未查找到设备信息");
return null;
@ -72,7 +74,8 @@ public class DeviceServiceImpl implements DeviceService {
@Override
public void refreshDeviceAlarmStatus(List<AlarmDeviceTaskDO> deviceTaskDOS) {
// 全部有告警任务的设备id
Set<Integer> deviceIdSet = deviceTaskDOS.stream().map(AlarmDeviceTaskDO::getDeviceId).collect(Collectors.toSet());
Set<Integer> deviceIdSet =
deviceTaskDOS.stream().map(AlarmDeviceTaskDO::getDeviceId).collect(Collectors.toSet());
// 告警状态为执行中的设备id
Set<Integer> alarmingDeviceIds = deviceTaskDOS.stream()
.filter(s -> TaskStatusName.TASK_EXECUTING.getValue().equals(s.getStatus()))
@ -89,4 +92,31 @@ public class DeviceServiceImpl implements DeviceService {
deviceMapper.batchUpdateDeviceAlarmStatus(deviceIdSet, DeviceAlarmStatusEnum.FINAL_STATE.getCode());
}
}
@Override
public Integer getDeviceBeidouIdBySeqId(Integer seqId) {
List<DeviceDO> devList = deviceMapper.getDeviceBySeqId(seqId);
if (devList.isEmpty()) {
return -1;
} else {
return devList.get(0).getBeidouId();
}
}
@Override
public SensorId getSensorIdByBeidouId(Integer beidouId) {
List<DeviceDO> devList = deviceMapper.getDeviceByBeidouId(beidouId);
if (devList.isEmpty()) {
return null;
} else {
DeviceDO device = devList.get(0);
return SensorId.builder()
.countyId(device.getCountyCode())
.seqId(device.getDeviceId())
.build();
}
}
}

View File

@ -69,5 +69,11 @@
</foreach>
</update>
<select id="getDeviceBySeqId" resultMap="device">
select * from device WHERE device.device_id = #{seqId}
</select>
<select id="getDeviceByBeidouId" resultMap="device">
select * from device WHERE device.beidou_id = #{beidouId}
</select>
</mapper>