From 05ba53f44463b2cacf860ad51b863bfc024f2141 Mon Sep 17 00:00:00 2001 From: GG Date: Wed, 8 May 2024 10:32:31 +0800 Subject: [PATCH] first commit --- .gitignore | 14 + HELP.md | 30 + README.md | 0 compose.yaml | 1 + mvnw | 308 + mvnw.cmd | 205 + pom.xml | 224 + .../com/zgx/iot/MilitaryMqttApplication.java | 60 + .../com/zgx/iot/MilitaryNettyApplication.java | 58 + .../zgx/iot/MilitarySocketApplication.java | 171 + .../com/zgx/iot/MilitaryZMQApplication.java | 684 ++ .../java/com/zgx/iot/SystemApplication.java | 54 + .../java/com/zgx/iot/api/DeviceInfoAPI.java | 43 + src/main/java/com/zgx/iot/api/ServiceAPI.java | 4 + .../java/com/zgx/iot/api/mq/MQManager.java | 4 + .../java/com/zgx/iot/api/mq/MQService.java | 4 + .../com/zgx/iot/api/mq/MQTTServiceimpl.java | 4 + src/main/java/com/zgx/iot/base/BaseMap.java | 140 + .../zgx/iot/client/ClientProtocalFactory.java | 48 + .../zgx/iot/client/ClientProtocalManager.java | 34 + .../com/zgx/iot/client/IClientProtocal.java | 30 + .../zgx/iot/client/impl/ProtocalLadarYS.java | 61 + src/main/java/com/zgx/iot/common/Cache.java | 36 + src/main/java/com/zgx/iot/common/Code.java | 36 + src/main/java/com/zgx/iot/common/Config.java | 8 + .../java/com/zgx/iot/common/Constants.java | 105 + .../com/zgx/iot/config/mqtt/MQTTProps.java | 73 + .../zgx/iot/config/socket/ssl/NettyProps.java | 80 + .../zgx/iot/config/socket/ssl/SslConfig.java | 4 + .../com/zgx/iot/constant/CacheConstant.java | 94 + .../com/zgx/iot/constant/GlobalConstants.java | 14 + .../com/zgx/iot/constant/SocketConstant.java | 30 + .../com/zgx/iot/constant/WebsocketConst.java | 64 + .../com/zgx/iot/constant/enums/AlarmType.java | 33 + .../zgx/iot/constant/enums/AlarmType2.java | 27 + .../zgx/iot/constant/enums/CameraType.java | 27 + .../com/zgx/iot/constant/enums/DateType.java | 25 + .../zgx/iot/constant/enums/DeviceComp.java | 28 + .../zgx/iot/constant/enums/DeviceType.java | 29 + .../com/zgx/iot/constant/enums/FaultItem.java | 54 + .../zgx/iot/constant/enums/FaultResult.java | 37 + .../com/zgx/iot/constant/enums/FenceType.java | 38 + .../com/zgx/iot/constant/enums/Invade.java | 30 + .../com/zgx/iot/constant/enums/StateType.java | 27 + .../zgx/iot/constant/enums/TargetType.java | 27 + .../com/zgx/iot/constant/enums/WarnLevel.java | 18 + .../com/zgx/iot/constant/enums/WarnType.java | 18 + .../controller/TrackingTargetController.java | 248 + .../java/com/zgx/iot/dto/Brower2LpmDto.java | 22 + .../zgx/iot/dto/radar/NyGuideCamPosModel.java | 52 + .../iot/dto/radar/RadarRESPackageModel.java | 87 + .../zgx/iot/dto/radar/RadarStateModel.java | 101 + .../zgx/iot/dto/radar/RadarTargetModel.java | 91 + .../zgx/iot/dto/radar/RadarTrackModel.java | 225 + .../zgx/iot/dto/radar/TrackingTargetDTO.java | 29 + .../java/com/zgx/iot/dto/site/AisInfo.java | 120 + .../java/com/zgx/iot/dto/site/AlarmInfo.java | 101 + .../com/zgx/iot/dto/site/CommonConstant.java | 325 + .../com/zgx/iot/dto/site/DeveiceType.java | 66 + .../java/com/zgx/iot/dto/site/DeviceInfo.java | 133 + .../com/zgx/iot/dto/site/DeviceStatus.java | 44 + .../java/com/zgx/iot/dto/site/Result.java | 159 + .../com/zgx/iot/dto/site/SysDictItem.java | 75 + .../java/com/zgx/iot/entity/DtDeviceInfo.java | 195 + .../com/zgx/iot/entity/MsAlarmSettings.java | 67 + .../com/zgx/iot/entity/MsCameraSetting.java | 112 + .../com/zgx/iot/entity/MsModelPosition.java | 50 + .../com/zgx/iot/entity/MsModelTrajectory.java | 55 + .../zgx/iot/mapper/DtDeviceInfoMapper.java | 16 + .../zgx/iot/mapper/MsAlarmSettingsMapper.java | 18 + .../zgx/iot/mapper/MsCameraSettingMapper.java | 29 + .../zgx/iot/mapper/MsModelPositionMapper.java | 17 + .../iot/mapper/MsModelTrajectoryMapper.java | 22 + .../zgx/iot/mapper/xml/DtDeviceInfoMapper.xml | 6 + .../iot/mapper/xml/MsAlarmSettingsMapper.xml | 6 + .../iot/mapper/xml/MsCameraSettingMapper.xml | 38 + .../iot/mapper/xml/MsModelPositionMapper.xml | 5 + .../mapper/xml/MsModelTrajectoryMapper.xml | 16 + .../zgx/iot/message/websocket/WebSocket.java | 165 + .../com/zgx/iot/mq/mqtt/MessageCallback.java | 102 + .../com/zgx/iot/mq/mqtt/MessageHandler.java | 50 + .../java/com/zgx/iot/mq/mqtt/MqttService.java | 166 + .../zgx/iot/mq/mqtt/handle/RadarHandler.java | 821 ++ .../mq/mqtt/model/radar/TargetMessage.java | 20 + .../com/zgx/iot/netty/NettyServiceManage.java | 203 + .../iot/netty/config/AppServiceConfig.java | 42 + .../netty/constant/AttributeMapConstant.java | 20 + .../iot/netty/constant/CustomLogLevel.java | 21 + .../iot/netty/constant/DeviceRelations.java | 150 + .../iot/netty/constant/HandlerDataType.java | 36 + .../zgx/iot/netty/constant/SocketType.java | 74 + .../device/MicrowaveDetectorConstant.java | 239 + .../exception/CompletableFutureException.java | 12 + .../netty/exception/DeviceInfoException.java | 12 + .../NettyServiceControllerException.java | 12 + .../zgx/iot/netty/handler/ConnectHandler.java | 57 + .../iot/netty/handler/ExceptionHandler.java | 168 + ...MicrowaveDetectorMessageClientDecoder.java | 87 + ...icrowaveDetectorMessageServiceDecoder.java | 81 + .../RadarDetectorMessageServiceDecoder.java | 105 + .../MicrowaveDetectorMessageClientFilter.java | 53 + ...MicrowaveDetectorMessageServiceFilter.java | 50 + .../send/RadarDetectorMessageSend.java | 263 + .../iot/netty/model/NettyDeviceIdChannel.java | 77 + .../zgx/iot/netty/model/NettyDeviceInfo.java | 144 + .../com/zgx/iot/netty/model/NettyService.java | 71 + .../netty/model/NettySocketDataMediator.java | 41 + .../iot/netty/model/NettyStartServiceVo.java | 16 + .../dataMediator/NettyDataMediatorEvent.java | 26 + .../device/microwave/LinkThreadQueueItem.java | 15 + .../microwave/MicrowaveDetectorAlarm.java | 88 + .../microwave/MicrowaveDetectorFault.java | 64 + .../microwave/MicrowaveDetectorHeartbeat.java | 32 + .../MicrowaveAreaDetectorMaintenance.java | 42 + .../command/MicrowaveConfigurationQuery.java | 26 + .../command/MicrowaveDetectorCommand.java | 35 + .../command/MicrowaveDeviceMaintenance.java | 30 + .../command/MicrowaveIOMantenance.java | 22 + .../command/rep/MicrowaveCommonRep.java | 23 + .../command/rep/MicrowaveDetectorRep.java | 21 + .../command/rep/MicrowaveDeviceRep.java | 25 + .../microwave/command/rep/MicrowaveIORep.java | 14 + .../command/rep/MicrowaveOpcRep.java | 14 + .../command/rep/MicrowaveQueryRep.java | 34 + .../netty/pipeline/TcpPipelineFactory.java | 21 + .../netty/pipeline/UdpPipelineFactory.java | 22 + ...eDetectorUdpClientPipelineFactoryImpl.java | 40 + ...DetectorUdpServicePipelineFactoryImpl.java | 55 + ...DetectorTcpServicePipelineFactoryImpl.java | 50 + .../CommonTcpClientPipelineFactoryImpl.java | 28 + .../CommonTcpServicePipelineFactoryImpl.java | 29 + .../CommonUdpClientPipelineFactoryImpl.java | 29 + .../CommonUdpServicePipelineFactoryImpl.java | 28 + .../socket/base/NettyBaseClientImpl.java | 182 + .../socket/base/NettyBaseServiceImpl.java | 197 + .../netty/socket/base/NettyBaseSocket.java | 202 + .../netty/socket/tcp/TcpClientByNetty.java | 48 + .../netty/socket/tcp/TcpServiceByNetty.java | 72 + .../netty/socket/udp/UdpClientByNetty.java | 41 + .../netty/socket/udp/UdpServiceByNetty.java | 65 + .../com/zgx/iot/radar/RadarAcceptSocket.java | 516 + .../java/com/zgx/iot/radar/RadarServer.java | 76 + .../com/zgx/iot/radar/proto/ZCHXRadar.java | 8546 +++++++++++++++++ .../iot/redis/client/JeecgRedisClient.java | 33 + .../com/zgx/iot/redis/config/RedisConfig.java | 100 + .../zgx/iot/service/IDtDeviceInfoService.java | 15 + .../iot/service/IMsAlarmSettingsService.java | 16 + .../iot/service/IMsCameraSettingService.java | 156 + .../iot/service/IMsModelPositionService.java | 53 + .../service/impl/DtDeviceInfoServiceImpl.java | 18 + .../impl/MsAlarmSettingsServiceImpl.java | 20 + .../impl/MsCameraSettingServiceImpl.java | 792 ++ .../impl/MsModelPositionServiceImpl.java | 188 + .../java/com/zgx/iot/thread/ZMQREPServer.java | 94 + .../java/com/zgx/iot/thread/ZMQServer.java | 88 + .../java/com/zgx/iot/thread/ZmqSubThread.java | 86 + .../com/zgx/iot/utils/AlarmInfoConvert.java | 216 + .../java/com/zgx/iot/utils/DateUtils.java | 650 ++ .../com/zgx/iot/utils/DeviceServiceUtil.java | 216 + .../com/zgx/iot/utils/EventSerialNumUtil.java | 31 + .../zgx/iot/utils/GEOIntersectPointUtils.java | 395 + src/main/java/com/zgx/iot/utils/GEOUtils.java | 322 + .../java/com/zgx/iot/utils/JacksonUtil.java | 146 + src/main/java/com/zgx/iot/utils/MD5Util.java | 43 + .../com/zgx/iot/utils/NettyConfigUtil.java | 30 + .../com/zgx/iot/utils/NettyDeviceUtil.java | 36 + .../com/zgx/iot/utils/NumConvertUtil.java | 198 + .../java/com/zgx/iot/utils/RedisUtil.java | 752 ++ .../com/zgx/iot/utils/SpringContextUtils.java | 65 + .../java/com/zgx/iot/utils/SysDictUtil.java | 27 + .../com/zgx/iot/utils/hp/HPDataHandle.java | 433 + .../com/zgx/iot/utils/hp/HPDataParser.java | 98 + .../com/zgx/iot/utils/hp/HPFaultResult.java | 26 + .../com/zgx/iot/utils/hp/HPReqParamEnc.java | 220 + .../com/zgx/iot/utils/hp/HPTcpKeepAlive.java | 66 + .../com/zgx/iot/utils/hp/ThreadManager.java | 30 + .../zgx/iot/utils/https/HttpAPIHelper.java | 16 + .../com/zgx/iot/utils/https/ResultData.java | 17 + .../java/com/zgx/iot/utils/oConvertUtils.java | 668 ++ .../iot/utils/radarUtils/BitConverter.java | 132 + .../zgx/iot/utils/radarUtils/ByteIntUtil.java | 58 + .../zgx/iot/utils/radarUtils/EndianUtil.java | 133 + .../utils/radarUtils/RadarTransformUtil.java | 38 + .../com/zgx/iot/utils/socket/TcpClient.java | 126 + src/main/java/com/zgx/iot/vo/DictModel.java | 42 + .../zgx/iot/vo/DynamicDataSourceModel.java | 52 + src/main/java/com/zgx/iot/vo/LoginUser.java | 117 + src/main/java/com/zgx/iot/vo/PTZVo.java | 34 + .../java/com/zgx/iot/vo/SysUserCacheInfo.java | 69 + src/main/resources/application-dev.yml | 355 + src/main/resources/application-prod.yml | 0 src/main/resources/application-test.yml | 48 + src/main/resources/application.yml | 52 + src/main/resources/logback.xml | 129 + .../dtimp1/DtImp1ApplicationTests.java | 40 + .../com/zgx/iot/mq/mqtt/MqttServiceTest.java | 23 + 196 files changed, 27597 insertions(+) create mode 100644 .gitignore create mode 100644 HELP.md create mode 100644 README.md create mode 100644 compose.yaml create mode 100644 mvnw create mode 100644 mvnw.cmd create mode 100644 pom.xml create mode 100644 src/main/java/com/zgx/iot/MilitaryMqttApplication.java create mode 100644 src/main/java/com/zgx/iot/MilitaryNettyApplication.java create mode 100644 src/main/java/com/zgx/iot/MilitarySocketApplication.java create mode 100644 src/main/java/com/zgx/iot/MilitaryZMQApplication.java create mode 100644 src/main/java/com/zgx/iot/SystemApplication.java create mode 100644 src/main/java/com/zgx/iot/api/DeviceInfoAPI.java create mode 100644 src/main/java/com/zgx/iot/api/ServiceAPI.java create mode 100644 src/main/java/com/zgx/iot/api/mq/MQManager.java create mode 100644 src/main/java/com/zgx/iot/api/mq/MQService.java create mode 100644 src/main/java/com/zgx/iot/api/mq/MQTTServiceimpl.java create mode 100644 src/main/java/com/zgx/iot/base/BaseMap.java create mode 100644 src/main/java/com/zgx/iot/client/ClientProtocalFactory.java create mode 100644 src/main/java/com/zgx/iot/client/ClientProtocalManager.java create mode 100644 src/main/java/com/zgx/iot/client/IClientProtocal.java create mode 100644 src/main/java/com/zgx/iot/client/impl/ProtocalLadarYS.java create mode 100644 src/main/java/com/zgx/iot/common/Cache.java create mode 100644 src/main/java/com/zgx/iot/common/Code.java create mode 100644 src/main/java/com/zgx/iot/common/Config.java create mode 100644 src/main/java/com/zgx/iot/common/Constants.java create mode 100644 src/main/java/com/zgx/iot/config/mqtt/MQTTProps.java create mode 100644 src/main/java/com/zgx/iot/config/socket/ssl/NettyProps.java create mode 100644 src/main/java/com/zgx/iot/config/socket/ssl/SslConfig.java create mode 100644 src/main/java/com/zgx/iot/constant/CacheConstant.java create mode 100644 src/main/java/com/zgx/iot/constant/GlobalConstants.java create mode 100644 src/main/java/com/zgx/iot/constant/SocketConstant.java create mode 100644 src/main/java/com/zgx/iot/constant/WebsocketConst.java create mode 100644 src/main/java/com/zgx/iot/constant/enums/AlarmType.java create mode 100644 src/main/java/com/zgx/iot/constant/enums/AlarmType2.java create mode 100644 src/main/java/com/zgx/iot/constant/enums/CameraType.java create mode 100644 src/main/java/com/zgx/iot/constant/enums/DateType.java create mode 100644 src/main/java/com/zgx/iot/constant/enums/DeviceComp.java create mode 100644 src/main/java/com/zgx/iot/constant/enums/DeviceType.java create mode 100644 src/main/java/com/zgx/iot/constant/enums/FaultItem.java create mode 100644 src/main/java/com/zgx/iot/constant/enums/FaultResult.java create mode 100644 src/main/java/com/zgx/iot/constant/enums/FenceType.java create mode 100644 src/main/java/com/zgx/iot/constant/enums/Invade.java create mode 100644 src/main/java/com/zgx/iot/constant/enums/StateType.java create mode 100644 src/main/java/com/zgx/iot/constant/enums/TargetType.java create mode 100644 src/main/java/com/zgx/iot/constant/enums/WarnLevel.java create mode 100644 src/main/java/com/zgx/iot/constant/enums/WarnType.java create mode 100644 src/main/java/com/zgx/iot/controller/TrackingTargetController.java create mode 100644 src/main/java/com/zgx/iot/dto/Brower2LpmDto.java create mode 100644 src/main/java/com/zgx/iot/dto/radar/NyGuideCamPosModel.java create mode 100644 src/main/java/com/zgx/iot/dto/radar/RadarRESPackageModel.java create mode 100644 src/main/java/com/zgx/iot/dto/radar/RadarStateModel.java create mode 100644 src/main/java/com/zgx/iot/dto/radar/RadarTargetModel.java create mode 100644 src/main/java/com/zgx/iot/dto/radar/RadarTrackModel.java create mode 100644 src/main/java/com/zgx/iot/dto/radar/TrackingTargetDTO.java create mode 100644 src/main/java/com/zgx/iot/dto/site/AisInfo.java create mode 100644 src/main/java/com/zgx/iot/dto/site/AlarmInfo.java create mode 100644 src/main/java/com/zgx/iot/dto/site/CommonConstant.java create mode 100644 src/main/java/com/zgx/iot/dto/site/DeveiceType.java create mode 100644 src/main/java/com/zgx/iot/dto/site/DeviceInfo.java create mode 100644 src/main/java/com/zgx/iot/dto/site/DeviceStatus.java create mode 100644 src/main/java/com/zgx/iot/dto/site/Result.java create mode 100644 src/main/java/com/zgx/iot/dto/site/SysDictItem.java create mode 100644 src/main/java/com/zgx/iot/entity/DtDeviceInfo.java create mode 100644 src/main/java/com/zgx/iot/entity/MsAlarmSettings.java create mode 100644 src/main/java/com/zgx/iot/entity/MsCameraSetting.java create mode 100644 src/main/java/com/zgx/iot/entity/MsModelPosition.java create mode 100644 src/main/java/com/zgx/iot/entity/MsModelTrajectory.java create mode 100644 src/main/java/com/zgx/iot/mapper/DtDeviceInfoMapper.java create mode 100644 src/main/java/com/zgx/iot/mapper/MsAlarmSettingsMapper.java create mode 100644 src/main/java/com/zgx/iot/mapper/MsCameraSettingMapper.java create mode 100644 src/main/java/com/zgx/iot/mapper/MsModelPositionMapper.java create mode 100644 src/main/java/com/zgx/iot/mapper/MsModelTrajectoryMapper.java create mode 100644 src/main/java/com/zgx/iot/mapper/xml/DtDeviceInfoMapper.xml create mode 100644 src/main/java/com/zgx/iot/mapper/xml/MsAlarmSettingsMapper.xml create mode 100644 src/main/java/com/zgx/iot/mapper/xml/MsCameraSettingMapper.xml create mode 100644 src/main/java/com/zgx/iot/mapper/xml/MsModelPositionMapper.xml create mode 100644 src/main/java/com/zgx/iot/mapper/xml/MsModelTrajectoryMapper.xml create mode 100644 src/main/java/com/zgx/iot/message/websocket/WebSocket.java create mode 100644 src/main/java/com/zgx/iot/mq/mqtt/MessageCallback.java create mode 100644 src/main/java/com/zgx/iot/mq/mqtt/MessageHandler.java create mode 100644 src/main/java/com/zgx/iot/mq/mqtt/MqttService.java create mode 100644 src/main/java/com/zgx/iot/mq/mqtt/handle/RadarHandler.java create mode 100644 src/main/java/com/zgx/iot/mq/mqtt/model/radar/TargetMessage.java create mode 100644 src/main/java/com/zgx/iot/netty/NettyServiceManage.java create mode 100644 src/main/java/com/zgx/iot/netty/config/AppServiceConfig.java create mode 100644 src/main/java/com/zgx/iot/netty/constant/AttributeMapConstant.java create mode 100644 src/main/java/com/zgx/iot/netty/constant/CustomLogLevel.java create mode 100644 src/main/java/com/zgx/iot/netty/constant/DeviceRelations.java create mode 100644 src/main/java/com/zgx/iot/netty/constant/HandlerDataType.java create mode 100644 src/main/java/com/zgx/iot/netty/constant/SocketType.java create mode 100644 src/main/java/com/zgx/iot/netty/constant/device/MicrowaveDetectorConstant.java create mode 100644 src/main/java/com/zgx/iot/netty/exception/CompletableFutureException.java create mode 100644 src/main/java/com/zgx/iot/netty/exception/DeviceInfoException.java create mode 100644 src/main/java/com/zgx/iot/netty/exception/NettyServiceControllerException.java create mode 100644 src/main/java/com/zgx/iot/netty/handler/ConnectHandler.java create mode 100644 src/main/java/com/zgx/iot/netty/handler/ExceptionHandler.java create mode 100644 src/main/java/com/zgx/iot/netty/handler/codec/MicrowaveDetectorMessageClientDecoder.java create mode 100644 src/main/java/com/zgx/iot/netty/handler/codec/MicrowaveDetectorMessageServiceDecoder.java create mode 100644 src/main/java/com/zgx/iot/netty/handler/codec/RadarDetectorMessageServiceDecoder.java create mode 100644 src/main/java/com/zgx/iot/netty/handler/filter/MicrowaveDetectorMessageClientFilter.java create mode 100644 src/main/java/com/zgx/iot/netty/handler/filter/MicrowaveDetectorMessageServiceFilter.java create mode 100644 src/main/java/com/zgx/iot/netty/handler/send/RadarDetectorMessageSend.java create mode 100644 src/main/java/com/zgx/iot/netty/model/NettyDeviceIdChannel.java create mode 100644 src/main/java/com/zgx/iot/netty/model/NettyDeviceInfo.java create mode 100644 src/main/java/com/zgx/iot/netty/model/NettyService.java create mode 100644 src/main/java/com/zgx/iot/netty/model/NettySocketDataMediator.java create mode 100644 src/main/java/com/zgx/iot/netty/model/NettyStartServiceVo.java create mode 100644 src/main/java/com/zgx/iot/netty/model/dataMediator/NettyDataMediatorEvent.java create mode 100644 src/main/java/com/zgx/iot/netty/model/device/microwave/LinkThreadQueueItem.java create mode 100644 src/main/java/com/zgx/iot/netty/model/device/microwave/MicrowaveDetectorAlarm.java create mode 100644 src/main/java/com/zgx/iot/netty/model/device/microwave/MicrowaveDetectorFault.java create mode 100644 src/main/java/com/zgx/iot/netty/model/device/microwave/MicrowaveDetectorHeartbeat.java create mode 100644 src/main/java/com/zgx/iot/netty/model/device/microwave/command/MicrowaveAreaDetectorMaintenance.java create mode 100644 src/main/java/com/zgx/iot/netty/model/device/microwave/command/MicrowaveConfigurationQuery.java create mode 100644 src/main/java/com/zgx/iot/netty/model/device/microwave/command/MicrowaveDetectorCommand.java create mode 100644 src/main/java/com/zgx/iot/netty/model/device/microwave/command/MicrowaveDeviceMaintenance.java create mode 100644 src/main/java/com/zgx/iot/netty/model/device/microwave/command/MicrowaveIOMantenance.java create mode 100644 src/main/java/com/zgx/iot/netty/model/device/microwave/command/rep/MicrowaveCommonRep.java create mode 100644 src/main/java/com/zgx/iot/netty/model/device/microwave/command/rep/MicrowaveDetectorRep.java create mode 100644 src/main/java/com/zgx/iot/netty/model/device/microwave/command/rep/MicrowaveDeviceRep.java create mode 100644 src/main/java/com/zgx/iot/netty/model/device/microwave/command/rep/MicrowaveIORep.java create mode 100644 src/main/java/com/zgx/iot/netty/model/device/microwave/command/rep/MicrowaveOpcRep.java create mode 100644 src/main/java/com/zgx/iot/netty/model/device/microwave/command/rep/MicrowaveQueryRep.java create mode 100644 src/main/java/com/zgx/iot/netty/pipeline/TcpPipelineFactory.java create mode 100644 src/main/java/com/zgx/iot/netty/pipeline/UdpPipelineFactory.java create mode 100644 src/main/java/com/zgx/iot/netty/pipeline/impl/MicrowaveDetectorUdpClientPipelineFactoryImpl.java create mode 100644 src/main/java/com/zgx/iot/netty/pipeline/impl/MicrowaveDetectorUdpServicePipelineFactoryImpl.java create mode 100644 src/main/java/com/zgx/iot/netty/pipeline/impl/RadarDetectorTcpServicePipelineFactoryImpl.java create mode 100644 src/main/java/com/zgx/iot/netty/pipeline/impl/common/CommonTcpClientPipelineFactoryImpl.java create mode 100644 src/main/java/com/zgx/iot/netty/pipeline/impl/common/CommonTcpServicePipelineFactoryImpl.java create mode 100644 src/main/java/com/zgx/iot/netty/pipeline/impl/common/CommonUdpClientPipelineFactoryImpl.java create mode 100644 src/main/java/com/zgx/iot/netty/pipeline/impl/common/CommonUdpServicePipelineFactoryImpl.java create mode 100644 src/main/java/com/zgx/iot/netty/socket/base/NettyBaseClientImpl.java create mode 100644 src/main/java/com/zgx/iot/netty/socket/base/NettyBaseServiceImpl.java create mode 100644 src/main/java/com/zgx/iot/netty/socket/base/NettyBaseSocket.java create mode 100644 src/main/java/com/zgx/iot/netty/socket/tcp/TcpClientByNetty.java create mode 100644 src/main/java/com/zgx/iot/netty/socket/tcp/TcpServiceByNetty.java create mode 100644 src/main/java/com/zgx/iot/netty/socket/udp/UdpClientByNetty.java create mode 100644 src/main/java/com/zgx/iot/netty/socket/udp/UdpServiceByNetty.java create mode 100644 src/main/java/com/zgx/iot/radar/RadarAcceptSocket.java create mode 100644 src/main/java/com/zgx/iot/radar/RadarServer.java create mode 100644 src/main/java/com/zgx/iot/radar/proto/ZCHXRadar.java create mode 100644 src/main/java/com/zgx/iot/redis/client/JeecgRedisClient.java create mode 100644 src/main/java/com/zgx/iot/redis/config/RedisConfig.java create mode 100644 src/main/java/com/zgx/iot/service/IDtDeviceInfoService.java create mode 100644 src/main/java/com/zgx/iot/service/IMsAlarmSettingsService.java create mode 100644 src/main/java/com/zgx/iot/service/IMsCameraSettingService.java create mode 100644 src/main/java/com/zgx/iot/service/IMsModelPositionService.java create mode 100644 src/main/java/com/zgx/iot/service/impl/DtDeviceInfoServiceImpl.java create mode 100644 src/main/java/com/zgx/iot/service/impl/MsAlarmSettingsServiceImpl.java create mode 100644 src/main/java/com/zgx/iot/service/impl/MsCameraSettingServiceImpl.java create mode 100644 src/main/java/com/zgx/iot/service/impl/MsModelPositionServiceImpl.java create mode 100644 src/main/java/com/zgx/iot/thread/ZMQREPServer.java create mode 100644 src/main/java/com/zgx/iot/thread/ZMQServer.java create mode 100644 src/main/java/com/zgx/iot/thread/ZmqSubThread.java create mode 100644 src/main/java/com/zgx/iot/utils/AlarmInfoConvert.java create mode 100644 src/main/java/com/zgx/iot/utils/DateUtils.java create mode 100644 src/main/java/com/zgx/iot/utils/DeviceServiceUtil.java create mode 100644 src/main/java/com/zgx/iot/utils/EventSerialNumUtil.java create mode 100644 src/main/java/com/zgx/iot/utils/GEOIntersectPointUtils.java create mode 100644 src/main/java/com/zgx/iot/utils/GEOUtils.java create mode 100644 src/main/java/com/zgx/iot/utils/JacksonUtil.java create mode 100644 src/main/java/com/zgx/iot/utils/MD5Util.java create mode 100644 src/main/java/com/zgx/iot/utils/NettyConfigUtil.java create mode 100644 src/main/java/com/zgx/iot/utils/NettyDeviceUtil.java create mode 100644 src/main/java/com/zgx/iot/utils/NumConvertUtil.java create mode 100644 src/main/java/com/zgx/iot/utils/RedisUtil.java create mode 100644 src/main/java/com/zgx/iot/utils/SpringContextUtils.java create mode 100644 src/main/java/com/zgx/iot/utils/SysDictUtil.java create mode 100644 src/main/java/com/zgx/iot/utils/hp/HPDataHandle.java create mode 100644 src/main/java/com/zgx/iot/utils/hp/HPDataParser.java create mode 100644 src/main/java/com/zgx/iot/utils/hp/HPFaultResult.java create mode 100644 src/main/java/com/zgx/iot/utils/hp/HPReqParamEnc.java create mode 100644 src/main/java/com/zgx/iot/utils/hp/HPTcpKeepAlive.java create mode 100644 src/main/java/com/zgx/iot/utils/hp/ThreadManager.java create mode 100644 src/main/java/com/zgx/iot/utils/https/HttpAPIHelper.java create mode 100644 src/main/java/com/zgx/iot/utils/https/ResultData.java create mode 100644 src/main/java/com/zgx/iot/utils/oConvertUtils.java create mode 100644 src/main/java/com/zgx/iot/utils/radarUtils/BitConverter.java create mode 100644 src/main/java/com/zgx/iot/utils/radarUtils/ByteIntUtil.java create mode 100644 src/main/java/com/zgx/iot/utils/radarUtils/EndianUtil.java create mode 100644 src/main/java/com/zgx/iot/utils/radarUtils/RadarTransformUtil.java create mode 100644 src/main/java/com/zgx/iot/utils/socket/TcpClient.java create mode 100644 src/main/java/com/zgx/iot/vo/DictModel.java create mode 100644 src/main/java/com/zgx/iot/vo/DynamicDataSourceModel.java create mode 100644 src/main/java/com/zgx/iot/vo/LoginUser.java create mode 100644 src/main/java/com/zgx/iot/vo/PTZVo.java create mode 100644 src/main/java/com/zgx/iot/vo/SysUserCacheInfo.java create mode 100644 src/main/resources/application-dev.yml create mode 100644 src/main/resources/application-prod.yml create mode 100644 src/main/resources/application-test.yml create mode 100644 src/main/resources/application.yml create mode 100644 src/main/resources/logback.xml create mode 100644 src/test/java/com/example/dtimp1/DtImp1ApplicationTests.java create mode 100644 src/test/java/com/zgx/iot/mq/mqtt/MqttServiceTest.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..376a6f5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +### Example user template template +### Example user template + +# IntelliJ project files +.idea +*.iml +out +gen +/target/ +/mqttlogs/debug/debug-Arvin.log +/mqttlogs/error/error-Arvin.log +/mqttlogs/info/info-Arvin.log +mqttlogs +db \ No newline at end of file diff --git a/HELP.md b/HELP.md new file mode 100644 index 0000000..e4de249 --- /dev/null +++ b/HELP.md @@ -0,0 +1,30 @@ +# Read Me First + +The following was discovered as part of building this project: + +* No Docker Compose services found. As of now, the application won't start! Please add at least one service to + the `compose.yaml` file. +* The JVM level was changed from '1.8' to '17', review + the [JDK Version Range](https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions#jdk-version-range) + on the wiki for more details. + +# Getting Started + +### Reference Documentation + +For further reference, please consider the following sections: + +* [Official Apache Maven documentation](https://maven.apache.org/guides/index.html) +* [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/3.1.3/maven-plugin/reference/html/) +* [Create an OCI image](https://docs.spring.io/spring-boot/docs/3.1.3/maven-plugin/reference/html/#build-image) +* [Spring Boot DevTools](https://docs.spring.io/spring-boot/docs/3.1.3/reference/htmlsingle/index.html#using.devtools) +* [Docker Compose Support](https://docs.spring.io/spring-boot/docs/3.1.3/reference/htmlsingle/index.html#features.docker-compose) + +### Docker Compose support + +This project contains a Docker Compose file named `compose.yaml`. + +However, no services were found. As of now, the application won't start! + +Please make sure to add at least one service in the `compose.yaml` file. + diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..0baad47 --- /dev/null +++ b/compose.yaml @@ -0,0 +1 @@ +services: diff --git a/mvnw b/mvnw new file mode 100644 index 0000000..66df285 --- /dev/null +++ b/mvnw @@ -0,0 +1,308 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.2.0 +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "$(uname)" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME + else + JAVA_HOME="/Library/Java/Home"; export JAVA_HOME + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=$(java-config --jre-home) + fi +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$JAVA_HOME" ] && + JAVA_HOME=$(cygpath --unix "$JAVA_HOME") + [ -n "$CLASSPATH" ] && + CLASSPATH=$(cygpath --path --unix "$CLASSPATH") +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] && + JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="$(which javac)" + if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=$(which readlink) + if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then + if $darwin ; then + javaHome="$(dirname "\"$javaExecutable\"")" + javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac" + else + javaExecutable="$(readlink -f "\"$javaExecutable\"")" + fi + javaHome="$(dirname "\"$javaExecutable\"")" + javaHome=$(expr "$javaHome" : '\(.*\)/bin') + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=$(cd "$wdir/.." || exit 1; pwd) + fi + # end of workaround + done + printf '%s' "$(cd "$basedir" || exit 1; pwd)" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + # Remove \r in case we run on Windows within Git Bash + # and check out the repository with auto CRLF management + # enabled. Otherwise, we may read lines that are delimited with + # \r\n and produce $'-Xarg\r' rather than -Xarg due to word + # splitting rules. + tr -s '\r\n' ' ' < "$1" + fi +} + +log() { + if [ "$MVNW_VERBOSE" = true ]; then + printf '%s\n' "$1" + fi +} + +BASE_DIR=$(find_maven_basedir "$(dirname "$0")") +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR +log "$MAVEN_PROJECTBASEDIR" + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" +if [ -r "$wrapperJarPath" ]; then + log "Found $wrapperJarPath" +else + log "Couldn't find $wrapperJarPath, downloading it ..." + + if [ -n "$MVNW_REPOURL" ]; then + wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + else + wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + fi + while IFS="=" read -r key value; do + # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' ) + safeValue=$(echo "$value" | tr -d '\r') + case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;; + esac + done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" + log "Downloading from: $wrapperUrl" + + if $cygwin; then + wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath") + fi + + if command -v wget > /dev/null; then + log "Found wget ... using wget" + [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet" + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + else + wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + log "Found curl ... using curl" + [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent" + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" + else + curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" + fi + else + log "Falling back to using Java to download" + javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java" + javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaSource=$(cygpath --path --windows "$javaSource") + javaClass=$(cygpath --path --windows "$javaClass") + fi + if [ -e "$javaSource" ]; then + if [ ! -e "$javaClass" ]; then + log " - Compiling MavenWrapperDownloader.java ..." + ("$JAVA_HOME/bin/javac" "$javaSource") + fi + if [ -e "$javaClass" ]; then + log " - Running MavenWrapperDownloader.java ..." + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath" + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +# If specified, validate the SHA-256 sum of the Maven wrapper jar file +wrapperSha256Sum="" +while IFS="=" read -r key value; do + case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;; + esac +done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" +if [ -n "$wrapperSha256Sum" ]; then + wrapperSha256Result=false + if command -v sha256sum > /dev/null; then + if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then + wrapperSha256Result=true + fi + elif command -v shasum > /dev/null; then + if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then + wrapperSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." + echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties." + exit 1 + fi + if [ $wrapperSha256Result = false ]; then + echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2 + echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2 + echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2 + exit 1 + fi +fi + +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$JAVA_HOME" ] && + JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME") + [ -n "$CLASSPATH" ] && + CLASSPATH=$(cygpath --path --windows "$CLASSPATH") + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR") +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +# shellcheck disable=SC2086 # safe args +exec "$JAVACMD" \ + $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 0000000..95ba6f5 --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,205 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.2.0 +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* +if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %WRAPPER_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file +SET WRAPPER_SHA_256_SUM="" +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B +) +IF NOT %WRAPPER_SHA_256_SUM%=="" ( + powershell -Command "&{"^ + "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^ + "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^ + " Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^ + " Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^ + " Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^ + " exit 1;"^ + "}"^ + "}" + if ERRORLEVEL 1 goto error +) + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% ^ + %JVM_CONFIG_MAVEN_PROPS% ^ + %MAVEN_OPTS% ^ + %MAVEN_DEBUG_OPTS% ^ + -classpath %WRAPPER_JAR% ^ + "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ + %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" +if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%"=="on" pause + +if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% + +cmd /C exit /B %ERROR_CODE% diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..5a33448 --- /dev/null +++ b/pom.xml @@ -0,0 +1,224 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.7.10 + + + com.example + military-hq + 0.0.1-SNAPSHOT + military-hq + military-hq + + + UTF-8 + 2.2.0 + 1.2.83 + 1.2.83 + + 1.8 + 1.6.1 + 7.4.0 + + 2.17.0 + 1.2.9 + true + 8.0.21 + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + com.alibaba + fastjson + ${fastjson.version} + + + + dom4j + dom4j + ${dom4j.version} + + + org.zeromq + jeromq + 0.5.2 + + + org.eclipse.paho + org.eclipse.paho.client.mqttv3 + 1.2.5 + + + + com.fasterxml.jackson.core + jackson-databind + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + + + com.fasterxml.jackson.core + jackson-annotations + 2.13.5 + + + commons-io + commons-io + 2.8.0 + + + com.google.protobuf + protobuf-java + 3.16.1 + + + io.netty + netty-all + + + org.apache.commons + commons-lang3 + + + cn.hutool + hutool-all + 5.7.22 + compile + + + com.google.guava + guava + 28.2-android + + + + org.springframework.boot + spring-boot-starter-websocket + + + + org.apache.tomcat.embed + tomcat-embed-websocket + + + + org.gavaghan + geodesy + 1.1.3 + + + + com.baomidou + mybatis-plus-boot-starter + 3.4.1 + + + + + org.springframework.boot + spring-boot-starter-data-redis + + + org.apache.commons + commons-pool2 + + + org.springframework.data + spring-data-redis + + + + + + com.github.03 + onvif + 1.0.7 + + + org.gavaghan + geodesy + 1.1.3 + + + com.dbb + onvif + 1.0.0 + + + + io.lettuce + lettuce-core + + + + mysql + mysql-connector-java + ${mysql-connector-java.version} + runtime + + + + commons-beanutils + commons-beanutils + 1.9.4 + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + com.zgx.iot.SystemApplication + + + + + + + diff --git a/src/main/java/com/zgx/iot/MilitaryMqttApplication.java b/src/main/java/com/zgx/iot/MilitaryMqttApplication.java new file mode 100644 index 0000000..89a47c0 --- /dev/null +++ b/src/main/java/com/zgx/iot/MilitaryMqttApplication.java @@ -0,0 +1,60 @@ +package com.zgx.iot; + +import com.zgx.iot.config.mqtt.MQTTProps; +import com.zgx.iot.config.socket.ssl.NettyProps; +import com.zgx.iot.mq.mqtt.MqttService; +import lombok.extern.slf4j.Slf4j; + +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.core.annotation.Order; +import org.springframework.scheduling.annotation.Async; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.Arrays; + +/** + * 启动 MQTT 服务 + * 注解 @Order 执行顺序 + * + * @author AaGMixW + */ +@Slf4j +@Component +@Order(value = 1) +@EnableAsync +public class MilitaryMqttApplication implements ApplicationRunner { + + + @Resource + private MQTTProps mqttProps; + @Resource + private NettyProps nettyProps; + //@Resource + private static MqttService mqttService ; + +// public MilitaryMqttApplication() { +// // this.mqttService = mqttService; +// } + + + @Override + @Async + public void run(ApplicationArguments args) throws Exception { + try { + mqttService = new MqttService(mqttProps); + mqttService.connect(); + mqttService.subscribe(); + } catch (Exception e) { + // 尝试重新连接 + mqttService.reconnect(); + } + + } + public static void pubMessage(String message,String topic){ + log.info("msg:"+message+"--------topic:"+topic); + mqttService.pubMessage(message, topic); + } +} diff --git a/src/main/java/com/zgx/iot/MilitaryNettyApplication.java b/src/main/java/com/zgx/iot/MilitaryNettyApplication.java new file mode 100644 index 0000000..43e78b7 --- /dev/null +++ b/src/main/java/com/zgx/iot/MilitaryNettyApplication.java @@ -0,0 +1,58 @@ +/* +package com.zgx.iot; + +import com.zgx.iot.api.DeviceInfoAPI; +import com.zgx.iot.entity.DtDeviceInfo; +import com.zgx.iot.utils.DeviceServiceUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; + +*/ +/** + * 启动 Netty 服务 + * + * @author AaGMixW + *//* + + +@Slf4j +@Order(value = 3) //执行顺序 +@Component +public class MilitaryNettyApplication implements ApplicationRunner { + + + + @Resource + private final DeviceServiceUtil deviceServiceUtil; + + + public MilitaryNettyApplication(DeviceServiceUtil deviceServiceUtil) { + + this.deviceServiceUtil = deviceServiceUtil; + } + + @Override + public void run(ApplicationArguments args) throws Exception { + //List deviceInfos = DeviceInfoAPI.GetALLDeviceLit("1446644493355888641"); + DtDeviceInfo msDeviceInfo = new DtDeviceInfo(); + msDeviceInfo.setNetProtocol("1"); + msDeviceInfo.setServerType(1); + //msDeviceInfo.setIp("172.20.0.77"); + msDeviceInfo.setDeviceIp("127.0.0.1"); + msDeviceInfo.setIpPort(8899); + List deviceInfoList =new ArrayList<>(); + deviceInfoList.add(msDeviceInfo); + + //deviceServiceUtil.startServerByDeviceInfo(deviceInfos); + deviceServiceUtil.startServerByDeviceInfo(deviceInfoList); + } + +} +*/ diff --git a/src/main/java/com/zgx/iot/MilitarySocketApplication.java b/src/main/java/com/zgx/iot/MilitarySocketApplication.java new file mode 100644 index 0000000..b8d10a2 --- /dev/null +++ b/src/main/java/com/zgx/iot/MilitarySocketApplication.java @@ -0,0 +1,171 @@ +package com.zgx.iot; + + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.zgx.iot.constant.enums.DeviceType; +import com.zgx.iot.entity.DtDeviceInfo; +import com.zgx.iot.entity.MsCameraSetting; +import com.zgx.iot.service.IDtDeviceInfoService; +import com.zgx.iot.service.IMsCameraSettingService; +import com.zgx.iot.utils.RedisUtil; +import com.zgx.iot.utils.hp.HPDataParser; +import com.zgx.iot.utils.hp.HPReqParamEnc; +import com.zgx.iot.utils.hp.HPTcpKeepAlive; +import com.zgx.iot.utils.hp.ThreadManager; +import com.zgx.iot.utils.socket.TcpClient; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.core.annotation.Order; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import java.text.ParseException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 启动Socket服务 + */ +@Slf4j +@Component +@Order(value = 1) //执行顺序 +@EnableAsync +public class MilitarySocketApplication implements ApplicationRunner { + + @Autowired + private RedisUtil redisUtil; + @Autowired + private IDtDeviceInfoService msDeviceInfoService; + @Autowired + private IMsCameraSettingService msCameraSettingService; + + @PostConstruct //通过@PostConstruct实现初始化bean之前进行的操作 + public void init() { + MilitarySocketApplication socketApplication = this; + // 初使化时将已静态化的Service实例化 + socketApplication.msDeviceInfoService = this.msDeviceInfoService; + socketApplication.msCameraSettingService = this.msCameraSettingService; + } + +/* @Override + public void run(ApplicationArguments args) throws Exception { + //1.查询所有光电设备 + //2.循环建立TCP连接 + //3.设备登录(userSaltGet,userLogin) + //4.定时发送心跳保持连接(userOnlineHeart) + + //key为设备IP + Map tcpClientMap = new HashMap<>(); + + redisUtil.del("cameraList"); + redisUtil.del("dataRecordServer"); + + QueryWrapper queryWrapper = new QueryWrapper<>(); + //queryWrapper.eq("state", 1);//1-启用 + //todo 查询光电 + queryWrapper.and(wrapper -> wrapper.eq("device_type", DeviceType.PHOTOELECTRIC.getValue())); + List deviceList = msDeviceInfoService.list(queryWrapper); + for (DtDeviceInfo ms : deviceList) { + //todo 建立TCP连接并接收数据 + log.info("建立连接的设备 : "+ms.toString());//测试数据 + TcpClient tcpClient = new TcpClient(ms.getDeviceIp(), ms.getIpPort()) { + @Override + public void dealWithRecvData(byte[] data) throws ParseException { + if (ms.getDeviceType() == DeviceType.PHOTOELECTRIC.getValue()) { + HPDataParser.recv(data, this);//接收数据 + } + } + }; + tcpClient.start(); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + log.info(tcpClient.getIp() +"状态:" + String.valueOf(tcpClient.flag)+"类型"+String.valueOf(ms.getDeviceType())); + if (tcpClient.flag) { + if (ms.getDeviceType() == DeviceType.PHOTOELECTRIC.getValue()) { + redisUtil.lSet("cameraList", ms); + //获取salt + tcpClient.send(HPDataParser.send(HPReqParamEnc.userSaltGet(ms.getUsername()))); + } else if (ms.getDeviceType() == DeviceType.DATARECORD.getValue()) { + redisUtil.hset("dataRecordServer", "deviceCode", ms.getDeviceCode()); + redisUtil.hset("dataRecordServer", "ip", ms.getDeviceIp()); + redisUtil.hset("dataRecordServer", "port", ms.getIpPort()); + } + //将线程放入map + tcpClientMap.put(ms.getDeviceIp(), tcpClient); + } + } + + //将tcp线程放入管理类 + ThreadManager.setTcpClientMap(tcpClientMap); + + //发送心跳保持连接 + HPTcpKeepAlive keepAlive = new HPTcpKeepAlive(redisUtil); + keepAlive.start(); + + log.info("Socket服务启动成功!"); + }*/ + + public void run(ApplicationArguments args) throws Exception { + //1.查询所有光电设备 + //2.循环建立TCP连接 + //3.设备登录(userSaltGet,userLogin) + //4.定时发送心跳保持连接(userOnlineHeart) + + //key为设备IP + Map tcpClientMap = new HashMap<>(); + + redisUtil.del("cameraList"); + redisUtil.del("dataRecordServer"); + + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + //lambdaQueryWrapper.eq(MsCameraSetting::getType,3).eq(MsCameraSetting::getStatus,1); + lambdaQueryWrapper.eq(MsCameraSetting::getType,3); + + List deviceList = msCameraSettingService.list(lambdaQueryWrapper); + for (MsCameraSetting ms : deviceList) { + //todo 建立TCP连接并接收数据 + log.info("建立连接的设备 : "+ms.toString());//测试数据 + TcpClient tcpClient = new TcpClient(ms.getIp(), ms.getPort()) { + @Override + public void dealWithRecvData(byte[] data) throws ParseException { + if (ms.getType() == 3) { + HPDataParser.recv(data, this);//接收数据 + } + } + }; + tcpClient.start(); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + log.info(tcpClient.getIp() +"状态:" + String.valueOf(tcpClient.flag)+"类型"+String.valueOf(ms.getType())); + if (tcpClient.flag) { + if (ms.getType() == 3) { + redisUtil.lSet("cameraList", ms); + //获取salt + tcpClient.send(HPDataParser.send(HPReqParamEnc.userSaltGet(ms.getUser()))); + } + //将线程放入map + tcpClientMap.put(ms.getIp(), tcpClient); + } + } + + //将tcp线程放入管理类 + ThreadManager.setTcpClientMap(tcpClientMap); + + //发送心跳保持连接 + HPTcpKeepAlive keepAlive = new HPTcpKeepAlive(redisUtil); + keepAlive.start(); + + log.info("Socket服务启动成功!"); + } +} \ No newline at end of file diff --git a/src/main/java/com/zgx/iot/MilitaryZMQApplication.java b/src/main/java/com/zgx/iot/MilitaryZMQApplication.java new file mode 100644 index 0000000..3dcc7be --- /dev/null +++ b/src/main/java/com/zgx/iot/MilitaryZMQApplication.java @@ -0,0 +1,684 @@ +package com.zgx.iot; + + +import cn.hutool.extra.spring.SpringUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.zgx.iot.constant.enums.CameraType; +import com.zgx.iot.constant.enums.DeviceType; +import com.zgx.iot.dto.radar.RadarTrackModel; +import com.zgx.iot.entity.MsAlarmSettings; +import com.zgx.iot.entity.MsCameraSetting; +import com.zgx.iot.entity.DtDeviceInfo; +import com.zgx.iot.service.IMsAlarmSettingsService; +import com.zgx.iot.service.IMsCameraSettingService; +import com.zgx.iot.service.IDtDeviceInfoService; +import com.zgx.iot.service.impl.MsCameraSettingServiceImpl; +import com.zgx.iot.mq.mqtt.handle.RadarHandler; +import com.zgx.iot.thread.ZmqSubThread; +import com.zgx.iot.utils.*; +import com.zgx.iot.utils.hp.HPDataParser; +import com.zgx.iot.utils.hp.HPReqParamEnc; +import com.zgx.iot.utils.hp.ThreadManager; +import com.zgx.iot.utils.socket.TcpClient; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.paho.client.mqttv3.MqttException; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.context.ApplicationContext; +import org.springframework.core.annotation.Order; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +/** + * 启动ZMQ服务 + */ +@Slf4j +@Component +@Order(value = 3) //执行顺序 +@EnableAsync +public class MilitaryZMQApplication implements ApplicationRunner { + + @Autowired + RedisUtil redisUtil; + @Autowired + IDtDeviceInfoService msDeviceInfoService; + @Autowired + IMsCameraSettingService msCameraSettingService; + @Autowired + IMsAlarmSettingsService msAlarmSettingsService; + @Autowired + RadarHandler radarHandler; + + /** + * 服务发布地址 + */ + @Value(value = "${zmq.ip}") + private String address; + + /** + * 服务接收端口 + */ + @Value(value = "${zmq.recv-port}") + private int recvPort; + + + /** + * 雷达图上目标主题 + */ + @Value(value = "${zmq.topic.radar_target}") + private String radarTarget; + + /** + * 雷达目标轨迹主题 + */ + @Value(value = "${zmq.topic.target_trajectory}") + private String targetTrajectory; + + /** + * 发送前端轨迹数据主题 + */ + private final String trajectoryTopic = "/server/radar"; + + private final String trackDeviceInfo = "/track/deviceInfo"; + + /** + * 发送球机数据主题 + */ + private final String trackCameraInfo = "/track/cameraInfo"; + + @PostConstruct //通过@PostConstruct实现初始化bean之前进行的操作 + public void init() { + MilitaryZMQApplication zmqApplication = this; + // 初使化时将已静态化的Service实例化 + zmqApplication.msDeviceInfoService = this.msDeviceInfoService; + zmqApplication.msAlarmSettingsService = this.msAlarmSettingsService; + zmqApplication.msCameraSettingService = this.msCameraSettingService; + } + + @Override + public void run(ApplicationArguments args) throws Exception { + + + //判断缓存是否存在报警参数,无则从数据库查询并放入缓存 + if (!redisUtil.hasKey("alarm_settings")) { + MsAlarmSettings alarmSettings = msAlarmSettingsService.list().get(0); + redisUtil.hset("alarm_settings", "lineEffectTime", alarmSettings.getLineEffectTime()); + redisUtil.hset("alarm_settings", "alarmEffectTime", alarmSettings.getAlarmEffectTime()); + redisUtil.hset("alarm_settings", "trackEffectTime", alarmSettings.getTrackEffectTime()); + redisUtil.hset("alarm_settings", "fenceEffectTime", alarmSettings.getFenceEffectTime()); + redisUtil.hset("alarm_settings", "inOutEffectDistance", alarmSettings.getInOutEffectDistance()); + redisUtil.hset("alarm_settings", "targetHeight", alarmSettings.getTargetHeight()); + + //测试数据 +/* RadarTrackModel radarTrackModel = new RadarTrackModel(); + radarTrackModel.setLongitude(113.485085f); + radarTrackModel.setLatitude(22.050129f); + radarTrackModel.setDis(8560); + radarTrackModel.setAzimuth(158.7832f); + radarTrackModel.setCourse(169.96576f); + radarTrackModel.setSpeed(3.2160966f); + radarTrackModel.setTrackId(1); + radarTrackModel.setAltitude(5.770267f); + String trackIdKey = "trackIds:" + radarTrackModel.getTrackId(); + redisUtil.hset(trackIdKey, "targetLon", radarTrackModel.getLongitude()); + redisUtil.hset(trackIdKey, "targetLat", radarTrackModel.getLatitude()); + redisUtil.hset(trackIdKey, "targetDis", radarTrackModel.getDis()); + redisUtil.hset(trackIdKey, "targetAzimuth", radarTrackModel.getAzimuth()); + redisUtil.hset(trackIdKey, "targetCourse", radarTrackModel.getCourse()); + redisUtil.hset(trackIdKey, "targetSpeed", radarTrackModel.getSpeed()); + redisUtil.hset(trackIdKey, "trackId", radarTrackModel.getTrackId()); + redisUtil.hset(trackIdKey, "trackAltitude", radarTrackModel.getAltitude()); + + redisUtil.hset("PTZStatus", "pan", 331.0400085449219); + redisUtil.hset("PTZStatus", "tilt", 24.100000381469727); + redisUtil.hset("PTZStatus", "ptRunState", 4104);*/ + } + + + //todo 新增代码 目标位置信息 + /** + * case4 : 点击的目标数据 (只有点击雷达图上的目标时才发送) + * address : 172.20.0.77 (ZMQ发布地址) + * port : 5151 + * topic : NyGuideCamPos + */ + ZmqSubThread nyGuideCamPosThread = new ZmqSubThread(address, recvPort, radarTarget) { //todo ip为radar-gui服务运行的机器 + @Override + public void dealWithData(byte[] data) { + log.info(Thread.currentThread().getName() + "接收到数据:" + new String(data)); + JSONObject jsonObject = JSON.parseObject(new String(data)); + log.info("case4 : jsonObject:" + jsonObject.toString()); + + //查询雷达信息 雷达经纬度(113.455074,22.122197) + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("device_type", DeviceType.RADAR.getValue()) + .eq("device_status", 1);//1-启用状态 + DtDeviceInfo deviceInfo = msDeviceInfoService.getOne(queryWrapper); + log.info("雷达信息:" + deviceInfo); + if (deviceInfo == null) { + log.info("查询不到相关设备"); + return; + } + //目标相对方位角 + double azimuth = jsonObject.getDoubleValue("azimuth"); + //目标距离 + double distance = jsonObject.getDoubleValue("dis"); + //计算目标经纬度 + GEOIntersectPointUtils.LatLon targetLonLat = GEOUtils.getLocationByLocationAndAngleAndDistance(deviceInfo.getDeviceLon(), deviceInfo.getDeviceLat(), azimuth, distance);//计算目标点经纬度 + log.info("目标经纬度targetLonLat:" + targetLonLat); + + //查询光电信息 + DtDeviceInfo cameraInfo = null; + LambdaQueryWrapper photoelectricLambdaQueryWrapper = new LambdaQueryWrapper<>(); + photoelectricLambdaQueryWrapper.eq(DtDeviceInfo::getDeviceType, DeviceType.PHOTOELECTRIC.getValue()).eq(DtDeviceInfo::getDeviceStatus, 1); + List photoelectricDevices = null; + photoelectricDevices = msDeviceInfoService.list(photoelectricLambdaQueryWrapper);//查出所有光电 + cameraInfo = photoelectricDevices.get(0); + log.info("光电信息:" + cameraInfo); + + //1、若设备关联光电,则进行联动定位 + if (cameraInfo != null) { + try { + double cameraAzimuth = cameraInfo.getInitAzimuth() + Double.parseDouble(redisUtil.hget("PTZStatus", "pan").toString()); + //计算目标相对于光电的方位角 + double targetAzimuth = GEOUtils.getAzimuth(deviceInfo.getDeviceLon(), + deviceInfo.getDeviceLat(), + targetLonLat.getLon(), + targetLonLat.getLat() + ); + + //计算光电水平所需方位角 + double differAzimuth = targetAzimuth - cameraAzimuth; + + //计算方位角 + double horAngle = Double.parseDouble(redisUtil.hget("PTZStatus", "pan").toString()) + differAzimuth; + horAngle = horAngle >= 0 ? horAngle : (360 + horAngle); + + //计算俯仰角(上27000-36000中间0-9000下) + double verAngle = Math.toDegrees(Math.asin(cameraInfo.getDeviceHeight() / distance)); + verAngle = verAngle + cameraInfo.getInitPitch(); + + //根据IP获取对应光电线程 + TcpClient tcpClient = ThreadManager.getTcpClientMap().get(cameraInfo.getDeviceIp()); + + //停止跟踪 + tcpClient.send( + HPDataParser.send( + HPReqParamEnc.ivpTrackingCtrl(String.valueOf(redisUtil.get(tcpClient.getIp())), 0, false, null) + ) + ); + + + //转动光电到指定位置 + //当光电已经处于跟踪状态时,以下操作不会生效 + //根据目标位置进行定位(角度实际上送值 : 100倍整数值) + tcpClient.send( + HPDataParser.send( + HPReqParamEnc.ptzControl(String.valueOf(redisUtil.get(tcpClient.getIp())), + 0, 51, null, + null, null, 45, + (int) (horAngle * 100), (int) (verAngle * 100), null) + ) + ); + + //目标高度 平均高度 在ms_alarm_settings表中设置 船的平均高度 高度越高视场角越大 + double h = Double.parseDouble(redisUtil.hget("alarm_settings", "targetHeight").toString()); + + //计算目标距离光点的距离 + double d = GEOUtils.GetDistance(targetLonLat.getLon(), targetLonLat.getLat(), cameraInfo.getDeviceLon(), cameraInfo.getDeviceLat()); + + //计算视场角,100为分辨率/像素 + double fov = Math.toDegrees(Math.atan(h / d)) * 2 * 100; + log.info("目标平均高度:" + h + " 目标距离光电:" + d); + log.info("水平方位角:" + horAngle + " 俯仰角:" + verAngle + " 视场角:" + fov); + + tcpClient.send( + HPDataParser.send( + HPReqParamEnc.ptzControl(String.valueOf(redisUtil.get(tcpClient.getIp())), + 0, 42, null, + null, null, null, + null, null, (int) (fov * 100)) + ) + ); + + log.info("联动控制球机:"); + List cameraSettings = null; + LambdaQueryWrapper cameraSettingLambdaQueryWrapper = new LambdaQueryWrapper<>(); + cameraSettingLambdaQueryWrapper.eq(MsCameraSetting::getType, 2).eq(MsCameraSetting::getStatus, 1);//只查询球机的信息 type:2 球机 type:1 枪击 + cameraSettings = msCameraSettingService.list(cameraSettingLambdaQueryWrapper); + if (cameraSettings == null || cameraSettings.isEmpty()) { + return; + } + log.info("case4 : 遍历相机列表 寻找最近的点的球机去跟踪"); + + // 计算距离最近的球机 + MsCameraSetting msCameraSetting = null;//最近球机信息 + double nearestDistance = 0;//最近距离 + double heightDiff = 0;//最近球机的高度差 + for (MsCameraSetting cameraSetting : cameraSettings) { + // todo : 判断该球机是否满足照射范围 不满足的话还可以找第二近的球机 如果放到后面才判断高度差 就无法找第二近的去跟踪了 + BigDecimal cameraHeight = cameraSetting.getHeight();//球机高度 + BigDecimal labelHeight = new BigDecimal(h);//目标高度 + double tempHeightDiff = cameraHeight.subtract(labelHeight).doubleValue();//球机与目标高度差 + if (tempHeightDiff < 0) { + log.info("case4 :" + "ip=" + cameraSetting.getIp() + " tempHeightDiff < 0 超过球机照射范围"); + } else { + double temp = GEOUtils.GetDistance(cameraSetting.getLongitude().doubleValue(), cameraSetting.getLatitude().doubleValue(), targetLonLat.getLon(), targetLonLat.getLat()); + log.info("当前的球机" + cameraSetting.getIp() + "与目标的距离:" + temp); + // 第一次 先将第一个球机的距离作为最近距离 和 最近球机信息 + if (msCameraSetting == null) { + msCameraSetting = cameraSetting; + nearestDistance = temp; + continue; + } + // 第二次以后 如果距离更近则更新最近距离 以及 最近球机信息 + if (nearestDistance > temp) { + msCameraSetting = cameraSetting; + nearestDistance = temp; + heightDiff = tempHeightDiff; + } + } + } + + if (msCameraSetting == null) { + log.info("没有可跟踪的球机"); + return; + } + + //判断两点的距离是否超过有效距离,超过则丢掉 + if (nearestDistance > Integer.parseInt(redisUtil.hget("alarm_settings", "inOutEffectDistance").toString())) { + log.info("case4 :" + "超过跟踪的最大距离" + redisUtil.hget("alarm_settings", "inOutEffectDistance").toString()); + return; + } + + log.info("case4 :" + " 相机IP:" + msCameraSetting.getIp() + " 最短距离nearestDistance:" + nearestDistance); + log.info("case4 :" + "距离最近的相机:" + JSON.toJSONString(msCameraSetting)); + + //控制球机照射目标 + log.info("case4【尝试使用ptzControllerByLatLonAndDistance】将球机转到目标位置"); + msCameraSettingService.ptzControllerByLatLon(msCameraSetting.getIp(), + msCameraSetting.getUser(), + msCameraSetting.getPassword(), + msCameraSetting.getMaxElevation(), + msCameraSetting.getZeroAzimuth(), + heightDiff, + msCameraSetting.getZoomFactor(), + msCameraSetting.getLongitude().doubleValue(), + msCameraSetting.getLatitude().doubleValue(), + targetLonLat.getLon(), + targetLonLat.getLat(), + msCameraSetting.getFactory());//factory用于区分品牌类型 1:海康 2:宇视 + + log.info("跟踪球机的主要参数信息:"); + log.info("1.IP: " + msCameraSetting.getIp()); + log.info("2.用户名: " + msCameraSetting.getUser()); + log.info("3.密码: " + msCameraSetting.getPassword()); + log.info("4.最大俯仰角: " + msCameraSetting.getMaxElevation()); + log.info("5.初始方位角: " + msCameraSetting.getZeroAzimuth()); + log.info("6.品牌: " + (msCameraSetting.getFactory() == 1 ? "海康" : "宇视")); + + //由于只能接收到方位角和距离 并且轨迹不断更新 所以只能将方位角和距离进行 + //由于经纬度不断变化 暂时不使用经纬度进行定位 + DecimalFormat decimalFormat = new DecimalFormat("#.00");//保留两位小数 + String longitude = decimalFormat.format(targetLonLat.getLon()); + String latitude = decimalFormat.format(targetLonLat.getLat()); + + //获取轨迹信息 + //String redisKey = "tracks"+"_"+longitude+"_"+latitude; + int redisAzimuth = (int) azimuth; + int redisDis = (((int) distance + 999) / 1000) * 1000; + String redisKey = "tracks:" + redisAzimuth + "_" + redisDis; + log.info("case4 :" + "redisLongitude:" + longitude + " " + "redisLatitude:" + latitude + "redisAzimuth:" + redisAzimuth + " redisDis:" + redisDis); + log.info("case4 :" + "redisKey = " + redisKey); + + + //通过不断更新的船经纬度信息控制球机转动 + int trackId = Integer.parseInt(redisUtil.hget(redisKey, "trackId").toString());//根据方位角 找到 轨迹Id + redisUtil.hset("trackingTargetId", String.valueOf(trackId), msCameraSetting.getIp());//将该轨迹 和 定位该轨迹的球机 保存到跟踪队列中 + log.info("正在跟踪的trackId:" + trackId + "跟踪的球机" + msCameraSetting.getIp()); + + //将光电信息封装成rtspUrl返回前端 + String rtspUrl = getRtspUrl(deviceInfo.getDeviceIp(), deviceInfo.getIpPort(), deviceInfo.getUsername(), deviceInfo.getPassword()); + //轨迹数据发送mqtt给前端使用 + JSONObject jsonObject1 = new JSONObject(); + jsonObject1.put("rtspUrl", rtspUrl); + MilitaryMqttApplication.pubMessage(jsonObject1.toJSONString(), trackDeviceInfo); + log.info("发送轨迹数据给前端----------" + "消息:" + jsonObject1.toJSONString() + " 主题:" + trackDeviceInfo); + + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + } + } + + }; + new Thread(nyGuideCamPosThread).start(); + + + //todo : 新增代码 球机联动 + /** + * case3 : 船轨迹数据 (开启目标跟踪使能后 持续发送) + * address : 172.20.0.77 (ZMQ发布地址) + * port : 5151 + * topic : RadarTrack + */ +/* ZmqSubThread radarTrackThread = new ZmqSubThread(address, recvPort, targetTrajectory) { + @Override + public void dealWithData(byte[] data) { + log.info(Thread.currentThread().getName() + "接收到数据:" + new String(data)); + JSONObject jsonObject = JSON.parseObject(new String(data)); + log.info("case3 :" + "RadarTrack航迹数据:" + jsonObject.toString()); + + String radarTarcksJsonString = (String) jsonObject.get("radarTracks"); + List radarTrackModels = JSONObject.parseArray(radarTarcksJsonString, RadarTrackModel.class); + //RadarTrackModel radarTrackModel = radarTrackModels.get(0); + + for (RadarTrackModel radarTrackModel : radarTrackModels) { + log.info("case3 :" + "航迹数据:" + JSON.toJSONString(radarTrackModel)); + + log.error("时间:" + new Date(System.currentTimeMillis()) + "轨迹" + radarTrackModel.getTrackId() + "的数据 经纬度:" + radarTrackModel.getLongitude() + "_" + radarTrackModel.getLatitude()); + + //保存有轨迹的Id + redisUtil.zAdd("updatedIds", String.valueOf(radarTrackModel.getTrackId()), (double) System.currentTimeMillis()); + + + //缓存 TrackId =》 船具体信息 + String trackIdKey = "trackIds:" + radarTrackModel.getTrackId(); + redisUtil.hset(trackIdKey, "targetLon", radarTrackModel.getLongitude()); + redisUtil.hset(trackIdKey, "targetLat", radarTrackModel.getLatitude()); + redisUtil.hset(trackIdKey, "targetDis", radarTrackModel.getDis()); + redisUtil.hset(trackIdKey, "targetAzimuth", radarTrackModel.getAzimuth()); + redisUtil.hset(trackIdKey, "targetCourse", radarTrackModel.getCourse()); + redisUtil.hset(trackIdKey, "targetSpeed", radarTrackModel.getSpeed()); + redisUtil.hset(trackIdKey, "trackAltitude", radarTrackModel.getAltitude()); + + //redis中存在正在跟踪的轨迹目标信息 + String trackingTarget = (String) redisUtil.hget("trackingTargetId", String.valueOf(radarTrackModel.getTrackId()));//获取并判断雷达传过来的轨迹数据 看是否该轨迹在跟踪目标队列中 + + if (trackingTarget != null) {// 该轨迹处于跟踪状态 + log.info("当前轨迹处于跟踪列表中" + trackingTarget); + //计算最近球机 + List cameraSettings = null; + LambdaQueryWrapper cameraSettingLambdaQueryWrapper = new LambdaQueryWrapper<>(); + cameraSettingLambdaQueryWrapper.eq(MsCameraSetting::getType, 1).eq(MsCameraSetting::getStatus, 1);//只查询球机的信息 type:1 球机 type:2 枪击 type:10 故障 + + cameraSettings = msCameraSettingService.list(cameraSettingLambdaQueryWrapper); + if (cameraSettings == null || cameraSettings.isEmpty()) { + return; + } + log.info("遍历相机列表 寻找最近的点的球机去跟踪" + JSON.toJSONString(cameraSettings)); + + //最近球机信息 + MsCameraSetting msCameraSetting = null; + //最近距离 + double nearestDistance = 0; + //最近球机的高度差 + double heightDiff = 0; + //轨迹数据中有海拔(就暂时不使用目标平均高度了) + double trackAltitude = Double.parseDouble(redisUtil.hget(trackIdKey, "trackAltitude").toString()); + if (trackAltitude == 0) { + trackAltitude = Double.parseDouble(redisUtil.hget("alarm_settings", "targetHeight").toString());//没有就取平均值 + log.info("该轨迹没有传船的高度 赋予平均值"); + } + + //查找最近的相机 + for (MsCameraSetting cameraSetting : cameraSettings) { + BigDecimal cameraHeight = cameraSetting.getHeight();//球机高度 + BigDecimal labelHeight = new BigDecimal(trackAltitude);//目标高度 + double tempHeightDiff = cameraHeight.subtract(labelHeight).doubleValue();//球机与目标高度差 + if (tempHeightDiff < 0) { + log.info("case3 :" + "ip=" + cameraSetting.getIp() + " tempHeightDiff < 0 超过球机照射范围"); + } else { + double temp = GEOUtils.GetDistance(cameraSetting.getLongitude().doubleValue(), cameraSetting.getLatitude().doubleValue(), (double) redisUtil.hget("trackIds:" + radarTrackModel.getTrackId(), "targetLon"), (double) redisUtil.hget("trackIds:" + radarTrackModel.getTrackId(), "targetLat")); + // 第一次 先将第一个球机的距离作为最近距离 和 最近球机信息 + if (msCameraSetting == null) { + msCameraSetting = cameraSetting; + nearestDistance = temp; + continue; + } + // 第二次以后 如果距离更近则更新最近距离 以及 最近球机信息 + if (nearestDistance > temp) { + msCameraSetting = cameraSetting; + nearestDistance = temp; + heightDiff = tempHeightDiff; + } + } + } + + if (msCameraSetting == null) { + log.info("没有可跟踪的球机"); + return; + } + + //判断两点的距离是否超过有效距离,超过则丢掉 + if (nearestDistance > Integer.parseInt(redisUtil.hget("alarm_settings", "inOutEffectDistance").toString())) { + log.info("case3 :" + "超过跟踪的最大距离" + redisUtil.hget("alarm_settings", "inOutEffectDistance").toString()); + return; + } + + //获取跟踪目标的最新经纬度 + String trackIdKey2 = "trackIds:" + radarTrackModel.getTrackId();//获取该轨迹对应的最新数据 + double targetLon = (double) redisUtil.hget(trackIdKey2, "targetLon"); + double targetLat = (double) redisUtil.hget(trackIdKey2, "targetLat"); + + //将球机信息返回前端 + if (!trackingTarget.equals(msCameraSetting.getIp())){ + //跟踪的球机改变发送给前端 + JSONObject jsonObject2 = new JSONObject(); + jsonObject2.put("deviceId", msCameraSetting.getId()); + jsonObject2.put("rtspUrl", msCameraSetting.getPreRtsp()); + jsonObject2.put("rtcUrl", msCameraSetting.getWebcastAddress()); + MilitaryMqttApplication.pubMessage(jsonObject2.toJSONString(), trackCameraInfo); + } + redisUtil.hset("trackingTargetId", String.valueOf(radarTrackModel.getTrackId()), msCameraSetting.getIp(), 60 * 5);//更新时间 + + + //控制球机照射目标 + log.info("case3 :" + "【尝试使用ptzControllerByLatLonAndDistance】"); + msCameraSettingService.ptzControllerByLatLon(msCameraSetting.getIp(), + msCameraSetting.getUser(), + msCameraSetting.getPassword(), + msCameraSetting.getMaxElevation(), + msCameraSetting.getZeroAzimuth(), + heightDiff, + msCameraSetting.getZoomFactor(), + msCameraSetting.getLongitude().doubleValue(), + msCameraSetting.getLatitude().doubleValue(), + targetLon, + targetLat, + msCameraSetting.getFactory());//style用于区分品牌类型 1:海康 3:宇视 + + redisUtil.hset("trackingTargetId", String.valueOf(radarTrackModel.getTrackId()), msCameraSetting.getIp());//更新时间 + } + + //发送雷达轨迹数据 + JSONObject jsonObject1 = new JSONObject(); + jsonObject1.put("sourceId", "AgilTrack_cat010bsz"); + jsonObject1.put("flag", 1); + //jsonObject1.put("radarTrack", radarTrackModel); + jsonObject1.put("radarTrack", JSON.toJSONString(radarTrackModel)); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); + String dataString = simpleDateFormat.format(new Date(System.currentTimeMillis())); + jsonObject1.put("utc", dataString); + jsonObject1.put("length", 3); + MilitaryMqttApplication.pubMessage(jsonObject1.toJSONString(), trajectoryTopic); + log.info("发送轨迹数据给前端----------" + "消息:" + JSON.toJSONString(radarTrackModel) + " 主题:" + trajectoryTopic); + } + } + + }; + new Thread(radarTrackThread).start();*/ + ZmqSubThread radarTrackThread = new ZmqSubThread(address, recvPort, targetTrajectory) { + @Override + public void dealWithData(byte[] data) { + log.info(Thread.currentThread().getName() + "接收到数据:" + new String(data)); + JSONObject jsonObject = JSON.parseObject(new String(data)); + log.info("case3 :" + "RadarTrack航迹数据:" + jsonObject.toString()); + + String radarTarcksJsonString = (String) jsonObject.get("radarTracks"); + List radarTrackModels = JSONObject.parseArray(radarTarcksJsonString, RadarTrackModel.class); + //RadarTrackModel radarTrackModel = radarTrackModels.get(0); + + for (RadarTrackModel radarTrackModel : radarTrackModels) { + log.info("case3 :" + "航迹数据:" + JSON.toJSONString(radarTrackModel)); + + log.error("时间:" + new Date(System.currentTimeMillis()) + "轨迹" + radarTrackModel.getTrackId() + "的数据 经纬度:" + radarTrackModel.getLongitude() + "_" + radarTrackModel.getLatitude()); + + //保存有轨迹的Id + redisUtil.zAdd("updatedIds", String.valueOf(radarTrackModel.getTrackId()), (double) System.currentTimeMillis()); + + + //缓存 TrackId =》 船具体信息 + String trackIdKey = "trackIds:" + radarTrackModel.getTrackId(); + redisUtil.hset(trackIdKey, "targetLon", radarTrackModel.getLongitude()); + redisUtil.hset(trackIdKey, "targetLat", radarTrackModel.getLatitude()); + redisUtil.hset(trackIdKey, "targetDis", radarTrackModel.getDis()); + redisUtil.hset(trackIdKey, "targetAzimuth", radarTrackModel.getAzimuth()); + redisUtil.hset(trackIdKey, "targetCourse", radarTrackModel.getCourse()); + redisUtil.hset(trackIdKey, "targetSpeed", radarTrackModel.getSpeed()); + redisUtil.hset(trackIdKey, "trackAltitude", radarTrackModel.getAltitude()); + + //redis中存在正在跟踪的轨迹目标信息 + //String trackingCamera = (String) redisUtil.hget("trackingTargetId", String.valueOf(radarTrackModel.getTrackId()));//获取并判断雷达传过来的轨迹数据 看是否该轨迹在跟踪目标队列中 + String trackingId = (String) redisUtil.get("trackingId");//获取跟踪目标Id + String cameraIp = (String) redisUtil.get("trackingCameraIp");//获取跟踪球机的Ip + + + if (trackingId != null && trackingId.equals(String.valueOf(radarTrackModel.getTrackId()))) {// 该轨迹处于跟踪状态 + //log.info("当前轨迹处于跟踪列表中" + cameraIp); + + List cameraSettings = null; + LambdaQueryWrapper cameraSettingLambdaQueryWrapper = new LambdaQueryWrapper<>(); + cameraSettingLambdaQueryWrapper.eq(MsCameraSetting::getType,CameraType.QIUJI.getValue()).eq(MsCameraSetting::getStatus, 0);//只查询球机的信息 type:2 球机 type:1 枪击 type:10 故障 + + cameraSettings = msCameraSettingService.list(cameraSettingLambdaQueryWrapper); + + if (cameraSettings != null) { + //获取跟踪目标的最新经纬度 + String trackIdKey2 = "trackIds:" + radarTrackModel.getTrackId();//获取该轨迹对应的最新数据 + double targetLon = radarTrackModel.getLongitude(); + double targetLat = radarTrackModel.getLatitude(); + + //计算最近球机 + MsCameraSetting msCameraSetting = radarHandler.getNearestCamera(cameraSettings, targetLon, targetLat); + + //控制球机照射目标 + //radarHandler.cameraToTarget((float) targetLon, (float) targetLat, msCameraSetting); + + //控制球机照射目标2 + JSONObject jsonObject1 = new JSONObject(); + jsonObject1.put("targetLon", radarTrackModel.getLongitude()); + jsonObject1.put("targetLat", radarTrackModel.getLatitude()); + jsonObject1.put("camera", JSON.toJSONString(msCameraSetting)); + MilitaryMqttApplication.pubMessage(JSON.toJSONString(jsonObject1), "/cameraToTarget"); + + + //当前跟踪的球机与之前跟踪的球机是否一样 + if (!cameraIp.equals(msCameraSetting.getIp())) { + //跟踪的球机改变发送给前端 + JSONObject jsonObject2 = new JSONObject(); + jsonObject2.put("deviceId", msCameraSetting.getId()); + jsonObject2.put("rtspUrl", msCameraSetting.getPreRtsp()); + jsonObject2.put("rtcUrl", msCameraSetting.getWebcastAddress()); + MilitaryMqttApplication.pubMessage(jsonObject2.toJSONString(), trackCameraInfo); + redisUtil.set("trackingCameraIp", msCameraSetting.getIp(),5*60);//更新正在跟踪的球机Ip + } + //redisUtil.hset("trackingTargetId", String.valueOf(radarTrackModel.getTrackId()), msCameraSetting.getIp(), 60 * 5);//更新时间 + + log.info("轨迹-----------【参数信息】"); + log.info("相机IP:" + msCameraSetting.getIp()); + log.info("用户名:" + msCameraSetting.getUser()); + log.info("密码:" + msCameraSetting.getPassword()); + log.info("最大俯仰角:" + msCameraSetting.getMaxElevation()); + log.info("初始方位角:" + msCameraSetting.getZeroAzimuth()); + log.info("变焦倍数:" + msCameraSetting.getZoomFactor()); + log.info("相机经度:" + msCameraSetting.getLongitude().doubleValue()); + log.info("相机纬度:" + msCameraSetting.getLatitude().doubleValue()); + log.info("目标经度: " + targetLon); + log.info("目标纬度: " + targetLat); + log.info("品牌: " + (msCameraSetting.getFactory() == 1 ? "海康" : "宇视")); + log.info("轨迹-----------【已控制球机照过去 等待下一次更新的轨迹信息 在进行下次定位】"); + } + } + + //todo : 真实发送雷达轨迹数据 + JSONObject jsonObject1 = new JSONObject(); + jsonObject1.put("sourceId", "AgilTrack_cat010bsz"); + jsonObject1.put("flag", 1); + jsonObject1.put("radarTrack", JSON.toJSONString(radarTrackModel)); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); + String dataString = simpleDateFormat.format(new Date(System.currentTimeMillis())); + jsonObject1.put("utc", dataString); + jsonObject1.put("length", 3); + MilitaryMqttApplication.pubMessage(jsonObject1.toJSONString(), trajectoryTopic); + log.info("发送轨迹数据给前端----------" + "消息:" + JSON.toJSONString(radarTrackModel) + " 主题:" + trajectoryTopic); + } + } + + }; + new Thread(radarTrackThread).start(); + } + + private static String getRtspUrl(String ip, int port, String user, String password) { + String rtspUrl = String.format("rtsp://%s:%s@%s:%d/", user, password, ip, port); + return rtspUrl; + } + + + //测试 + public static void main(String[] args) { +/* double distance = GEOUtils.getDistance(113.5130050, 22.161666, 113.448686, 22.118584); + System.out.println(distance); + + BigDecimal cameraHeight = new BigDecimal(6);//球机高度 + BigDecimal labelHeight = new BigDecimal(0.28445536);//目标高度 + double tempHeightDiff = cameraHeight.subtract(labelHeight).doubleValue();//球机与目标高度差 + System.out.println(tempHeightDiff); + + double azimuth = GEOUtils.getAzimuth(113.4578, 22.8021, 113.6782, 22.6602); + System.out.println("方位角:" + azimuth); + + System.out.println(new Date(System.currentTimeMillis())); + System.out.println(getRtspUrl("192.168.1.200", 8081, "admin", "admin123!#"));//测试rtsp生成 + + for (int i = 0; i < 10; i++) { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("radarId", "1"); + jsonObject.put("radarId2", "2"); + jsonObject.put("radarId3", "3"); + jsonObject.put("radarId4", "4"); + jsonObject.put("radarId5", "5"); + //测试数据 + String filepath = "C:\\Users\\15819\\Desktop\\radarData.txt"; + try { + bufferedWriterTest(filepath, jsonObject.toString()); + } catch (IOException e) { + throw new RuntimeException(e); + } + }*/ + } + + private static void bufferedWriterTest(String filepath, String content) throws IOException { + try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filepath, true))) { + bufferedWriter.write(content); + bufferedWriter.newLine(); + } + } +} diff --git a/src/main/java/com/zgx/iot/SystemApplication.java b/src/main/java/com/zgx/iot/SystemApplication.java new file mode 100644 index 0000000..d18cd14 --- /dev/null +++ b/src/main/java/com/zgx/iot/SystemApplication.java @@ -0,0 +1,54 @@ +package com.zgx.iot; +import com.zgx.iot.config.mqtt.MQTTProps; +import com.zgx.iot.config.socket.ssl.NettyProps; +import com.zgx.iot.mq.mqtt.MqttService; +import com.zgx.iot.utils.oConvertUtils; +import lombok.extern.slf4j.Slf4j; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.boot.SpringApplication; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.Environment; +import org.springframework.scheduling.annotation.EnableScheduling; + +import javax.annotation.Resource; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +@EnableScheduling +@SpringBootApplication +@Slf4j +public class SystemApplication implements ApplicationRunner{ + @Resource + private NettyProps nettyProps; + public static ExecutorService threadPool = Executors.newFixedThreadPool(15); + + public static void main(String[] args) throws UnknownHostException { + ConfigurableApplicationContext application = SpringApplication.run(SystemApplication.class, args); + Environment env = application.getEnvironment(); + String ip = InetAddress.getLocalHost().getHostAddress(); + String port = env.getProperty("server.port"); + String path = oConvertUtils.getString(env.getProperty("server.servlet.context-path")); + log.info("\n----------------------------------------------------------\n\t" + + "周界入侵告警管控平台服务启动成功! Access URLs:\n\t" + + "Local: \t\thttp://localhost:" + port + path + "/\n\t" + + "External: \thttp://" + ip + ":" + port + path + "/\n\t" + +// "Swagger文档: \thttp://" + ip + ":" + port + path + "/doc.html\n" + + "----------------------------------------------------------"); + } + + + @Override + public void run(ApplicationArguments args) throws Exception { +// MilitaryMqttApplication.pubMessage("aaa","military"); +// System.out.println("111"); + } +} diff --git a/src/main/java/com/zgx/iot/api/DeviceInfoAPI.java b/src/main/java/com/zgx/iot/api/DeviceInfoAPI.java new file mode 100644 index 0000000..dd184a3 --- /dev/null +++ b/src/main/java/com/zgx/iot/api/DeviceInfoAPI.java @@ -0,0 +1,43 @@ +package com.zgx.iot.api; + +import com.alibaba.fastjson.JSON; + +import com.zgx.iot.common.Constants; +import com.zgx.iot.entity.DtDeviceInfo; +import com.zgx.iot.utils.https.ResultData; + +import com.zgx.iot.utils.https.HttpAPIHelper; + +import java.util.HashMap; +import java.util.List; + +public class DeviceInfoAPI { + + + public static List GetALLDeviceLit(String siteid){ + + String url = Constants.APIURL.DEVICE_LIST; + HashMap valueMap = new HashMap<>(); + valueMap.put("device_owner_id",siteid); + valueMap.put("device_status",0); + ResultData resultData = HttpAPIHelper.doGet(url, valueMap); + List jsonArray = JSON.parseArray(resultData.getResult(), DtDeviceInfo.class); + // 将JSONArray数组转为List类型 + //List list = (List)jsonArray; + // return JSON.parseObject(resultData.getData(), List.class); + for (DtDeviceInfo deviceInfo : jsonArray) { + System.out.println(deviceInfo.getDeviceName()); + + } + return jsonArray; + } +/* public static DeviceInfo GetDeviceInfo(String deviceCode){ + + String url = Constants.APIURL.DEVICE_LIST +"?deviceOwnerId=" +""; + ResultData resultData = HttpAPIHelper.doGet(url, null); + DeviceInfo deviceInfo = JSON.parseObject(resultData.getData(),DeviceInfo.class); + +// return JSON.parseObject(resultData.getData(), List.class); + return deviceInfo; + }*/ +} diff --git a/src/main/java/com/zgx/iot/api/ServiceAPI.java b/src/main/java/com/zgx/iot/api/ServiceAPI.java new file mode 100644 index 0000000..4cf2998 --- /dev/null +++ b/src/main/java/com/zgx/iot/api/ServiceAPI.java @@ -0,0 +1,4 @@ +package com.zgx.iot.api; + +public class ServiceAPI { +} diff --git a/src/main/java/com/zgx/iot/api/mq/MQManager.java b/src/main/java/com/zgx/iot/api/mq/MQManager.java new file mode 100644 index 0000000..293b326 --- /dev/null +++ b/src/main/java/com/zgx/iot/api/mq/MQManager.java @@ -0,0 +1,4 @@ +package com.zgx.iot.api.mq; + +public class MQManager { +} diff --git a/src/main/java/com/zgx/iot/api/mq/MQService.java b/src/main/java/com/zgx/iot/api/mq/MQService.java new file mode 100644 index 0000000..c6f198d --- /dev/null +++ b/src/main/java/com/zgx/iot/api/mq/MQService.java @@ -0,0 +1,4 @@ +package com.zgx.iot.api.mq; + +public interface MQService { +} diff --git a/src/main/java/com/zgx/iot/api/mq/MQTTServiceimpl.java b/src/main/java/com/zgx/iot/api/mq/MQTTServiceimpl.java new file mode 100644 index 0000000..591b6c7 --- /dev/null +++ b/src/main/java/com/zgx/iot/api/mq/MQTTServiceimpl.java @@ -0,0 +1,4 @@ +package com.zgx.iot.api.mq; + +public class MQTTServiceimpl implements MQService { +} diff --git a/src/main/java/com/zgx/iot/base/BaseMap.java b/src/main/java/com/zgx/iot/base/BaseMap.java new file mode 100644 index 0000000..74d6733 --- /dev/null +++ b/src/main/java/com/zgx/iot/base/BaseMap.java @@ -0,0 +1,140 @@ +package com.zgx.iot.base; + + +import cn.hutool.core.util.ObjectUtil; +import org.apache.commons.beanutils.ConvertUtils; + +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * 自定义Map + */ +public class BaseMap extends HashMap { + + private static final long serialVersionUID = 1L; + + + public BaseMap() { + + } + + public BaseMap(Map map) { + this.putAll(map); + } + + + @Override + public BaseMap put(String key, Object value) { + super.put(key, Optional.ofNullable(value).orElse("")); + return this; + } + + public BaseMap add(String key, Object value) { + super.put(key, Optional.ofNullable(value).orElse("")); + return this; + } + + @SuppressWarnings("unchecked") + public T get(String key) { + Object obj = super.get(key); + if (ObjectUtil.isNotEmpty(obj)) { + return (T) obj; + } else { + return null; + } + } + + @SuppressWarnings("unchecked") + public Boolean getBoolean(String key) { + Object obj = super.get(key); + if (ObjectUtil.isNotEmpty(obj)) { + return Boolean.valueOf(obj.toString()); + } else { + return false; + } + } + + public Long getLong(String key) { + Object v = get(key); + if (ObjectUtil.isNotEmpty(v)) { + return new Long(v.toString()); + } + return null; + } + + public Long[] getLongs(String key) { + Object v = get(key); + if (ObjectUtil.isNotEmpty(v)) { + return (Long[]) v; + } + return null; + } + + public List getListLong(String key) { + List list = get(key); + if (ObjectUtil.isNotEmpty(list)) { + return list.stream().map(e -> new Long(e)).collect(Collectors.toList()); + } else { + return null; + } + } + + public Long[] getLongIds(String key) { + Object ids = get(key); + if (ObjectUtil.isNotEmpty(ids)) { + return (Long[]) ConvertUtils.convert(ids.toString().split(","), Long.class); + } else { + return null; + } + } + + + public Integer getInt(String key, Integer def) { + Object v = get(key); + if (ObjectUtil.isNotEmpty(v)) { + return Integer.parseInt(v.toString()); + } else { + return def; + } + } + + public Integer getInt(String key) { + Object v = get(key); + if (ObjectUtil.isNotEmpty(v)) { + return Integer.parseInt(v.toString()); + } else { + return 0; + } + } + + public BigDecimal getBigDecimal(String key) { + Object v = get(key); + if (ObjectUtil.isNotEmpty(v)) { + return new BigDecimal(v.toString()); + } + return new BigDecimal("0"); + } + + + @SuppressWarnings("unchecked") + public T get(String key, T def) { + Object obj = super.get(key); + if (ObjectUtil.isEmpty(obj)) { + return def; + } + return (T) obj; + } + + public static BaseMap toBaseMap(Map obj) { + BaseMap map = new BaseMap(); + map.putAll(obj); + return map; + } + + +} diff --git a/src/main/java/com/zgx/iot/client/ClientProtocalFactory.java b/src/main/java/com/zgx/iot/client/ClientProtocalFactory.java new file mode 100644 index 0000000..177a96f --- /dev/null +++ b/src/main/java/com/zgx/iot/client/ClientProtocalFactory.java @@ -0,0 +1,48 @@ +package com.zgx.iot.client; + +import com.zgx.iot.client.impl.ProtocalLadarYS; +import com.zgx.iot.dto.site.DeviceInfo; + +import java.util.HashMap; +import java.util.Map; + +public class ClientProtocalFactory { + + // 对象列表 + private static Map objectList = new HashMap(); + + /** + * 根据路径新建对象 + * @param path + * @return + */ + public static IClientProtocal getInstance(String path) { + if( objectList.containsKey(path) ){ + return objectList.get(path); + }else{ + try { + Class classObject = (Class) Class.forName("com.zgx.iot.protocal.impl." + path); + IClientProtocal iprotocal = classObject.newInstance() ; + objectList.put(path,iprotocal) ; + return iprotocal ; + } catch (Exception e) { + + } + } + return null; + } + + public static IClientProtocal CreateClient(DeviceInfo deviceInfo) { + IClientProtocal clientProtocal=null; + switch (deviceInfo.getProtocol()) { + case 1: + clientProtocal = new ProtocalLadarYS(deviceInfo); + default: + clientProtocal = new ProtocalLadarYS(deviceInfo); + } + if(clientProtocal!=null){ + clientProtocal.login(); + } + return clientProtocal; + } +} diff --git a/src/main/java/com/zgx/iot/client/ClientProtocalManager.java b/src/main/java/com/zgx/iot/client/ClientProtocalManager.java new file mode 100644 index 0000000..90d2ab5 --- /dev/null +++ b/src/main/java/com/zgx/iot/client/ClientProtocalManager.java @@ -0,0 +1,34 @@ +package com.zgx.iot.client; + + +import java.util.HashMap; +import java.util.Map; + +/** + * 协议解析,入口 + * @author chenrj + * + */ +public class ClientProtocalManager { + + + // 对象列表 + private static Map DeviceList = new HashMap<>(); + private String site_id=""; + + /** + * 登录判断并匹配协议 + */ + public void loginClientDevices(){ +/* List deviceInfoList= DeviceInfoAPI.GetALLDeviceLit(site_id); + for ( MsDeviceInfo deviceInfo :deviceInfoList) { + IClientProtocal clientProtocal = ClientProtocalFactory.CreateClient(deviceInfo); + }*/ + + } + + + + + +} diff --git a/src/main/java/com/zgx/iot/client/IClientProtocal.java b/src/main/java/com/zgx/iot/client/IClientProtocal.java new file mode 100644 index 0000000..cfa3411 --- /dev/null +++ b/src/main/java/com/zgx/iot/client/IClientProtocal.java @@ -0,0 +1,30 @@ +package com.zgx.iot.client; + +/** + * 策略抽象接口类,提供客户端需要的一些公共方法 + */ +public interface IClientProtocal { + + + /** + * 登录 + */ + void login(); + + /** + * 数据解析 + * @param data + */ + void analysisData( byte[] data); + + /** + * 心跳包 + */ + void handbert(); + + + + + void logout(); + +} diff --git a/src/main/java/com/zgx/iot/client/impl/ProtocalLadarYS.java b/src/main/java/com/zgx/iot/client/impl/ProtocalLadarYS.java new file mode 100644 index 0000000..b739d7b --- /dev/null +++ b/src/main/java/com/zgx/iot/client/impl/ProtocalLadarYS.java @@ -0,0 +1,61 @@ +package com.zgx.iot.client.impl; + +import com.zgx.iot.SystemApplication; +import com.zgx.iot.client.IClientProtocal; + +import com.zgx.iot.common.Code.IOT_NODE_STATUS; +import com.zgx.iot.common.Config; +import com.zgx.iot.common.Constants; +import com.zgx.iot.dto.site.DeviceInfo; +import com.zgx.iot.radar.RadarServer; + + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Date; + +/** + * + * @author M + * HJ212 + * + */ +public class ProtocalLadarYS implements IClientProtocal { + + + + private DeviceInfo _deviceInfo; + public ProtocalLadarYS(DeviceInfo deviceInfo){ + + } + + + @Override + public void login() { + + + + + } + + @Override + public void analysisData( byte[] data ) { + try{ + + + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public void handbert( ) { + } + + + + @Override + public void logout() { + + } +} diff --git a/src/main/java/com/zgx/iot/common/Cache.java b/src/main/java/com/zgx/iot/common/Cache.java new file mode 100644 index 0000000..359fd73 --- /dev/null +++ b/src/main/java/com/zgx/iot/common/Cache.java @@ -0,0 +1,36 @@ +package com.zgx.iot.common; + + +import java.util.Map; +import java.util.Timer; +import java.util.concurrent.ConcurrentHashMap; + + +/** + * 缓存 + * + */ +public class Cache { + + + /** + * nodeId session 缓存 + */ + //public static Map nodeIdsessionMap = new ConcurrentHashMap<>(); + + + /** + * 定时任务轮训,主要主动请求数据 + */ + public static Map timerTaskMap = new ConcurrentHashMap<>(); + + /** + * 设备数据透传 + */ + public static Map deviceMap = new ConcurrentHashMap<>(); + + + //public static Map nodeIdsessionMapEx = new ConcurrentHashMap<>(); + + +} diff --git a/src/main/java/com/zgx/iot/common/Code.java b/src/main/java/com/zgx/iot/common/Code.java new file mode 100644 index 0000000..7eef22b --- /dev/null +++ b/src/main/java/com/zgx/iot/common/Code.java @@ -0,0 +1,36 @@ +package com.zgx.iot.common; + +public class Code { + + public static class IOT_NODE_STATUS { + + public static final Integer online = 16 ; + + public static final Integer offline = 17; + + } + + public static class ResponseCode{ + + public static final Integer OK = 2 ; + + public static final Integer NO_DATA = 4 ; + } + + /** + * 设备状态 + * @author chenrj + * + */ + public static class DEVICE_STATUS{ + + public static final Integer ONLINE = 16 ; + + public static final Integer OFFLINE = 17 ; + + public static final Integer UNCONTECT = 18; + + public static final Integer FAILURE = 19 ; + } + +} \ No newline at end of file diff --git a/src/main/java/com/zgx/iot/common/Config.java b/src/main/java/com/zgx/iot/common/Config.java new file mode 100644 index 0000000..2e5e829 --- /dev/null +++ b/src/main/java/com/zgx/iot/common/Config.java @@ -0,0 +1,8 @@ +package com.zgx.iot.common; + +public class Config { + public static String SITE_ID = ""; + + public static String IOT_USER_KEY ; + public static String IOT_URL="localhost:8088"; +} diff --git a/src/main/java/com/zgx/iot/common/Constants.java b/src/main/java/com/zgx/iot/common/Constants.java new file mode 100644 index 0000000..b254877 --- /dev/null +++ b/src/main/java/com/zgx/iot/common/Constants.java @@ -0,0 +1,105 @@ +package com.zgx.iot.common; + +public class Constants { + + + public final static String IOT_LPM_TYPE = "IOT_SERVER_LPM"; + + public final static String DEVICE_CODE = "deviceId"; + + public final static String DEVICE_LOGIN = "login"; + //协议类型 + public final static String PROTOCOL_CATEGORY = "protocolCategory"; + + public final static String DEVICE_PARAM = "deviceParam" ; + + public final static String DEVICE_TRANSFER = "deviceTransfer" ; + + public final static String DEVICE_FLAG = "deviceFlag" ; + + public final static String DEVICE_SESSION = "deviceSession" ; + + public final static String NODE_INFO = "nodeInfo" ; + + public final static String THREAD_HASH_CODE = "threadHashCode" ; + + public final static String DATA_CACHE = "dataCache"; + + + public static class CODE_TYPE{ + public final static String HEX = "hex"; + public final static String STR = "STR"; + } + public String API_URL=""; + public static class APIURL { + /** + * 所属站点设备列表 + */ + public static String DEVICE_LIST = Config.IOT_URL + "/dt/military/dtDeviceInfo/queryByIsland"; + } + public static class URL{ + /** + * 同步lpro和lpm数据 + */ + public static String SYNC_NODE = Config.IOT_URL + "/service/node/data/sync.json" ; + + /** + * 修改传感器的请求值,实时值 + */ + public static String SENSORS_DATA = Config.IOT_URL + "/service/sensors/realtime/update.json"; + /** + * 修改设备的状态 + */ + public static String NODE_INFO = Config.IOT_URL +"/service/node/status.json"; + /** + * 批量保存储存传感器数据 + */ + public static String SAVE_NODE_DATA = Config.IOT_URL + "/service/save/node/data.json" ; + } + public static class MQTT_TOPIC{ + /** + *雷达目标信息 + */ + public static String RadarTargetTopic = "RadarTargetTopic" ; + + /** + *AIS目标原始信息 + */ + public static String AisRawTargetTopic = "AisRawTargetTopic" ; + /** + *AIS目标信息 + */ + public static String AisTargetTopic = "AisTargetTopic" ; + + /** + *其他目标信息 + */ + public static String ExtTargetTopic = "ExtTargetTopic" ; + + /** + *融合目标信息 + */ + public static String UnionTargetTopic = "UnionTargetTopic" ; + /** + *报警信息 + */ + public static String AlarmInfoTopic = "AlarmInfoTopic" ; + + /** + *站点信息 + */ + public static String SiteTopic = "SiteTopic" ; + + /** + *设备信息 + */ + public static String DeviceInfoTopic = "DeviceInfoTopic" ; + + /** + *设备状态信息 + */ + public static String DeviceStatusTopic = "DeviceStatusTopic" ; + + + } +} diff --git a/src/main/java/com/zgx/iot/config/mqtt/MQTTProps.java b/src/main/java/com/zgx/iot/config/mqtt/MQTTProps.java new file mode 100644 index 0000000..961cfb4 --- /dev/null +++ b/src/main/java/com/zgx/iot/config/mqtt/MQTTProps.java @@ -0,0 +1,73 @@ +package com.zgx.iot.config.mqtt; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 配置文件的前缀 + */ +@Data +@Component +@ConfigurationProperties(prefix = "mqtt") +public class MQTTProps { + @Data + public static class Service { + /** + * MQTT 服务器地址 + */ + private String address; + /** + * 服务端 账号 + */ + private String username; + /** + * 认证方式 + */ + private String authentication; + /** + * 服务端 密码 + */ + private String password; + } + + @Data + public static class Retry { + /** + * 重试次数 (次) + */ + private int count; + /** + * 重试间隔(秒) + */ + private int interval; + } + + @Data + public static class Client { + + /** + * mqtt 客户端 ID + */ + private String id; + /** + * 定阅的主题 + */ + private String topics; + } + + /** + * 服务端 + */ + private Service service; + /** + * 客户端 + */ + private Client client; + /** + * 重试选项 + */ + private Retry retry; +} diff --git a/src/main/java/com/zgx/iot/config/socket/ssl/NettyProps.java b/src/main/java/com/zgx/iot/config/socket/ssl/NettyProps.java new file mode 100644 index 0000000..0ce7683 --- /dev/null +++ b/src/main/java/com/zgx/iot/config/socket/ssl/NettyProps.java @@ -0,0 +1,80 @@ +package com.zgx.iot.config.socket.ssl; + +import com.zgx.iot.config.mqtt.MQTTProps; +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Data +@Component +@ConfigurationProperties(prefix = "netty") +public class NettyProps { + + @Data + public static class tcpClient { + + /** + * netty tcp客户端地址 + */ + private String address; + /** + * netty tcp客户端端口 + */ + private String port; + } + @Data + public static class tcpService { + + /** + * netty tcp服务端地址 + */ + private String address; + /** + * netty tcp服务端端口 + */ + private String port; + } + /** + * udp + */ + @Data + public static class udpService { + + /** + * udp服务端地址 + */ + private String address; + /** + * udp服务端端口 + */ + private String port; + } + @Data + public static class udpClient { + + /** + * netty udp客户端地址 + */ + private String address; + /** + * netty udp客户端端口 + */ + private String port; + } + /** + * tcp服务端 + */ + private tcpService tcpService; + /** + * tcp客户端 + */ + private tcpClient tcpClient; + /** + * udp服务端 + */ + private tcpService udpService; + /** + * udp客户端 + */ + private tcpClient udpClient; +} diff --git a/src/main/java/com/zgx/iot/config/socket/ssl/SslConfig.java b/src/main/java/com/zgx/iot/config/socket/ssl/SslConfig.java new file mode 100644 index 0000000..ee9b64e --- /dev/null +++ b/src/main/java/com/zgx/iot/config/socket/ssl/SslConfig.java @@ -0,0 +1,4 @@ +package com.zgx.iot.config.socket.ssl; + +public class SslConfig { +} diff --git a/src/main/java/com/zgx/iot/constant/CacheConstant.java b/src/main/java/com/zgx/iot/constant/CacheConstant.java new file mode 100644 index 0000000..6b22c44 --- /dev/null +++ b/src/main/java/com/zgx/iot/constant/CacheConstant.java @@ -0,0 +1,94 @@ +package com.zgx.iot.constant; + +/** + * @author: huangxutao + * @date: 2019-06-14 + * @description: 缓存常量 + */ +public interface CacheConstant { + + /** + * 字典信息缓存 + */ + public static final String SYS_DICT_CACHE = "sys:cache:dict"; + /** + * 表字典信息缓存 + */ + public static final String SYS_DICT_TABLE_CACHE = "sys:cache:dictTable"; + public static final String SYS_DICT_TABLE_BY_KEYS_CACHE = SYS_DICT_TABLE_CACHE + "ByKeys"; + + /** + * 数据权限配置缓存 + */ + public static final String SYS_DATA_PERMISSIONS_CACHE = "sys:cache:permission:datarules"; + + /** + * 缓存用户信息 + */ + public static final String SYS_USERS_CACHE = "sys:cache:user"; + + /** + * 全部部门信息缓存 + */ + public static final String SYS_DEPARTS_CACHE = "sys:cache:depart:alldata"; + + + /** + * 全部部门ids缓存 + */ + public static final String SYS_DEPART_IDS_CACHE = "sys:cache:depart:allids"; + + + /** + * 测试缓存key + */ + public static final String TEST_DEMO_CACHE = "test:demo"; + + /** + * 字典信息缓存 + */ + public static final String SYS_DYNAMICDB_CACHE = "sys:cache:dbconnect:dynamic:"; + + /** + * gateway路由缓存 + */ + public static final String GATEWAY_ROUTES = "sys:cache:cloud:gateway_routes"; + + + /** + * gateway路由 reload key + */ + public static final String ROUTE_JVM_RELOAD_TOPIC = "gateway_jvm_route_reload_topic"; + + /** + * TODO 冗余代码 待删除 + *插件商城排行榜 + */ + public static final String PLUGIN_MALL_RANKING = "pluginMall::rankingList"; + /** + * TODO 冗余代码 待删除 + *插件商城排行榜 + */ + public static final String PLUGIN_MALL_PAGE_LIST = "pluginMall::queryPageList"; + + + /** + * online列表页配置信息缓存key + */ + public static final String ONLINE_LIST = "sys:cache:online:list"; + + /** + * online表单页配置信息缓存key + */ + public static final String ONLINE_FORM = "sys:cache:online:form"; + + /** + * online报表 + */ + public static final String ONLINE_RP = "sys:cache:online:rp"; + + /** + * online图表 + */ + public static final String ONLINE_GRAPH = "sys:cache:online:graph"; +} diff --git a/src/main/java/com/zgx/iot/constant/GlobalConstants.java b/src/main/java/com/zgx/iot/constant/GlobalConstants.java new file mode 100644 index 0000000..00e6f4d --- /dev/null +++ b/src/main/java/com/zgx/iot/constant/GlobalConstants.java @@ -0,0 +1,14 @@ +package com.zgx.iot.constant; + +public class GlobalConstants { + + /** + * 业务处理器beanName传递参数 + */ + public static final String HANDLER_NAME = "handlerName"; + + /** + * redis消息通道名称 + */ + public static final String REDIS_TOPIC_NAME="jeecg_redis_topic"; +} diff --git a/src/main/java/com/zgx/iot/constant/SocketConstant.java b/src/main/java/com/zgx/iot/constant/SocketConstant.java new file mode 100644 index 0000000..6e54458 --- /dev/null +++ b/src/main/java/com/zgx/iot/constant/SocketConstant.java @@ -0,0 +1,30 @@ +package com.zgx.iot.constant; + +/** + * @Description: Socket常量类 + * @author: bb + * @date: 2022-07-31 + */ +public class SocketConstant { + + /** + * 连接超时时间(毫秒) + */ + public static final int TIME_OUT = 3 * 1000; + + /** + * 若指定时间内无数据交互,则进行心跳探测(秒) + */ + public static final int IDLE_TIME = 15 * 1000; + + /** + * 重试次数(次) + */ + public static final int RETRY_COUNT = 5; + + /** + * 重试间隔(秒) + */ + public static final int RETRY_INTERVAL = 3; + +} diff --git a/src/main/java/com/zgx/iot/constant/WebsocketConst.java b/src/main/java/com/zgx/iot/constant/WebsocketConst.java new file mode 100644 index 0000000..4d4f821 --- /dev/null +++ b/src/main/java/com/zgx/iot/constant/WebsocketConst.java @@ -0,0 +1,64 @@ +package com.zgx.iot.constant; + +/** + * @Description: Websocket常量类 + * @author: taoyan + * @date: 2020年03月23日 + */ +public class WebsocketConst { + + + /** + * 消息json key:cmd + */ + public static final String MSG_CMD = "cmd"; + + /** + * 消息json key:msgId + */ + public static final String MSG_ID = "msgId"; + + /** + * 消息json key:msgTxt + */ + public static final String MSG_TXT = "msgTxt"; + + /** + * 消息json key:userId + */ + public static final String MSG_USER_ID = "userId"; + + /** + * 消息类型 heartcheck + */ + public static final String CMD_CHECK = "heartcheck"; + + /** + * 消息类型 user 用户消息 + */ + public static final String CMD_USER = "user"; + + /** + * 消息类型 topic 系统通知 + */ + public static final String CMD_TOPIC = "topic"; + + /** + * 消息类型 email + */ + public static final String CMD_EMAIL = "email"; + + /** + * 消息类型 meetingsign 会议签到 + */ + public static final String CMD_SIGN = "sign"; + + /** + * 消息类型 新闻发布/取消 + */ + public static final String NEWS_PUBLISH = "publish"; + /** + * 消息类型 事件通报 + */ + public static final String event_PUBLISH = "eventPublish"; +} diff --git a/src/main/java/com/zgx/iot/constant/enums/AlarmType.java b/src/main/java/com/zgx/iot/constant/enums/AlarmType.java new file mode 100644 index 0000000..5793bd5 --- /dev/null +++ b/src/main/java/com/zgx/iot/constant/enums/AlarmType.java @@ -0,0 +1,33 @@ +package com.zgx.iot.constant.enums; + +/** + * 报警类型 + */ +public enum AlarmType { + VIDEO("视频报警", 1), + RADAR("雷达报警", 2), + FENCE("电子围网报警", 3), + PATROL("巡逻人员警报", 4), + OTHERS("其他报警", 9); + + private String desc; + private int code; + + AlarmType(String desc, int code) { + this.desc = desc; + this.code = code; + } + + public int getCode() { + return this.code; + } + + public static String getDesc(int code) { + for (AlarmType alarmType : AlarmType.values()) { + if (code == alarmType.code) { + return alarmType.desc; + } + } + return null; + } +} diff --git a/src/main/java/com/zgx/iot/constant/enums/AlarmType2.java b/src/main/java/com/zgx/iot/constant/enums/AlarmType2.java new file mode 100644 index 0000000..8830859 --- /dev/null +++ b/src/main/java/com/zgx/iot/constant/enums/AlarmType2.java @@ -0,0 +1,27 @@ +package com.zgx.iot.constant.enums; + +/** + * 报警类型 + */ +public enum AlarmType2 { + + INVADE("入侵", 1), + BREAK("破坏", 2), + OTHER("其他", 3); + + private String desc; + private Integer code; + + AlarmType2(String desc, Integer value) { + this.desc = desc; + this.code = value; + } + + public String getDesc() { + return desc; + } + + public Integer getCode() { + return code; + } +} diff --git a/src/main/java/com/zgx/iot/constant/enums/CameraType.java b/src/main/java/com/zgx/iot/constant/enums/CameraType.java new file mode 100644 index 0000000..3f527a7 --- /dev/null +++ b/src/main/java/com/zgx/iot/constant/enums/CameraType.java @@ -0,0 +1,27 @@ +package com.zgx.iot.constant.enums; + +/** + * 设备类型 + */ +public enum CameraType { + QIUJI("球机", 1), + QIANGJI("枪击", 2), + GUANGDIAN("光电跟踪仪", 3), + YUNTAI("高清云台", 4); + + private final String desc; + private final Integer value; + + CameraType(String desc, Integer value) { + this.desc = desc; + this.value = value; + } + + public String getDesc() { + return desc; + } + + public Integer getValue() { + return value; + } +} diff --git a/src/main/java/com/zgx/iot/constant/enums/DateType.java b/src/main/java/com/zgx/iot/constant/enums/DateType.java new file mode 100644 index 0000000..a5f4f8a --- /dev/null +++ b/src/main/java/com/zgx/iot/constant/enums/DateType.java @@ -0,0 +1,25 @@ +package com.zgx.iot.constant.enums; + +/** + * 信息类型 + */ +public enum DateType { + ALARM_INFO("报警信息", 0), + STATE_INFO("状态信息", 1); + + private String desc; + private Integer value; + + DateType(String desc, Integer value) { + this.desc = desc; + this.value = value; + } + + public String getDesc() { + return desc; + } + + public Integer getValue() { + return value; + } +} diff --git a/src/main/java/com/zgx/iot/constant/enums/DeviceComp.java b/src/main/java/com/zgx/iot/constant/enums/DeviceComp.java new file mode 100644 index 0000000..c469aa0 --- /dev/null +++ b/src/main/java/com/zgx/iot/constant/enums/DeviceComp.java @@ -0,0 +1,28 @@ +package com.zgx.iot.constant.enums; + +/** + * 相机设备厂商 + */ +public enum DeviceComp { + HAIKAN("海康", 1), + DAHUA("大华", 2), + YUSHI("宇视", 3), + HEPU("和普", 4); + + private String desc; + private Integer value; + + DeviceComp(String desc, Integer value) { + this.desc = desc; + this.value = value; + } + + public Integer getValue() { + return value; + } + + public String getDesc(){ + return desc; + } + +} diff --git a/src/main/java/com/zgx/iot/constant/enums/DeviceType.java b/src/main/java/com/zgx/iot/constant/enums/DeviceType.java new file mode 100644 index 0000000..361827a --- /dev/null +++ b/src/main/java/com/zgx/iot/constant/enums/DeviceType.java @@ -0,0 +1,29 @@ +package com.zgx.iot.constant.enums; + +/** + * 设备类型 + */ +public enum DeviceType { + RADAR("雷达", 1), + PHOTOELECTRIC("光电", 2), + PERIMETERALARM("电子围网", 3), + PHOTOVOLTAIC("光伏", 4), + DATARECORD("数据记录设备", 5), + VIBRATECABLE("振动电缆", 6); + + private final String desc; + private final Integer value; + + DeviceType(String desc, Integer value) { + this.desc = desc; + this.value = value; + } + + public String getDesc() { + return desc; + } + + public Integer getValue() { + return value; + } +} diff --git a/src/main/java/com/zgx/iot/constant/enums/FaultItem.java b/src/main/java/com/zgx/iot/constant/enums/FaultItem.java new file mode 100644 index 0000000..35fbc9d --- /dev/null +++ b/src/main/java/com/zgx/iot/constant/enums/FaultItem.java @@ -0,0 +1,54 @@ +package com.zgx.iot.constant.enums; + +/** + * 故障诊断项 + */ +public enum FaultItem { + N(1, "系统"), + N2(2, "网络连接"), + N3(3, "串口通信"), + N4(4, "视频接口通信"), + N5(5, "视频输入"), + N6(6, "视频处理子系统"), + N7(7, "视频编码"), + N8(8, "视频解码"), + N9(9, "智能分析"), + N10(10, "云台角度定位准确性"), + N11(11, "云台速度平稳性"), + N12(12, "可见光zoom定位准确性"), + N13(13, "可见光focus定位准确性"), + N14(14, "热像zoom定位准确性"), + N15(15, "热像focus定位准确性"), + N16(16, "热像自检"), + N17(17, "云台自检"), + N18(18, "激光自检"), + N19(19, "激光测距"), + N20(20, "GPS"), + N21(21, "电子罗盘"), + N22(22, "雨刷"); + + private int code; + private String desc; + + FaultItem(int code, String desc) { + this.code = code; + this.desc = desc; + } + + public static String getDesc(int code) { + for (FaultItem fenceType : FaultItem.values()) { + if (code == fenceType.code) { + return fenceType.desc; + } + } + return null; + } + + public int getCode() { + return code; + } + + public String getDesc() { + return desc; + } +} diff --git a/src/main/java/com/zgx/iot/constant/enums/FaultResult.java b/src/main/java/com/zgx/iot/constant/enums/FaultResult.java new file mode 100644 index 0000000..93f2632 --- /dev/null +++ b/src/main/java/com/zgx/iot/constant/enums/FaultResult.java @@ -0,0 +1,37 @@ +package com.zgx.iot.constant.enums; + +/** + * 故障诊断结果 + */ +public enum FaultResult { + NORMAL(0, "正常"), + FAULT(1, "故障"), + UNSUPPORT(2, "不支持"), + POWEROFF(3, "电源关"), + UNDIAGNOSED(4, "未诊断"); + + private int code; + private String desc; + + FaultResult(int code, String desc) { + this.code = code; + this.desc = desc; + } + + public static String getDesc(int code) { + for (FaultResult fenceType : FaultResult.values()) { + if (code == fenceType.code) { + return fenceType.desc; + } + } + return null; + } + + public int getCode() { + return code; + } + + public String getDesc() { + return desc; + } +} diff --git a/src/main/java/com/zgx/iot/constant/enums/FenceType.java b/src/main/java/com/zgx/iot/constant/enums/FenceType.java new file mode 100644 index 0000000..c5bf0d3 --- /dev/null +++ b/src/main/java/com/zgx/iot/constant/enums/FenceType.java @@ -0,0 +1,38 @@ +package com.zgx.iot.constant.enums; + +/** + * 电子围栏信息类型 + */ +public enum FenceType { + BROKEN(2, "断线报警"), + INVADE(6, "入侵报警"), + OFFLINE(8, "离线报警"), + ONLINE(9, "离线报警恢复"), + TAMPER(10, "防拆报警"), + FAULT(12, "故障报警"); + + private int code; + private String desc; + + FenceType(int code, String desc) { + this.code = code; + this.desc = desc; + } + + public static String getDesc(int code) { + for (FenceType fenceType : FenceType.values()) { + if (code == fenceType.code) { + return fenceType.desc; + } + } + return null; + } + + public int getCode() { + return code; + } + + public String getDesc() { + return desc; + } +} diff --git a/src/main/java/com/zgx/iot/constant/enums/Invade.java b/src/main/java/com/zgx/iot/constant/enums/Invade.java new file mode 100644 index 0000000..27302e0 --- /dev/null +++ b/src/main/java/com/zgx/iot/constant/enums/Invade.java @@ -0,0 +1,30 @@ +package com.zgx.iot.constant.enums; + +/** + * 入侵行为 + */ +public enum Invade { + + CLIMB(1, "攀爬"), JUMP(2, "翻越"); + + private int code; + private String value; + + Invade(int code, String value) { + this.code = code; + this.value = value; + } + + public String getValue() { + return this.value; + } + + public static String getVal(int code) { + for (Invade invade : Invade.values()) { + if (code == invade.code) { + return invade.value; + } + } + return null; + } +} diff --git a/src/main/java/com/zgx/iot/constant/enums/StateType.java b/src/main/java/com/zgx/iot/constant/enums/StateType.java new file mode 100644 index 0000000..ff33ffb --- /dev/null +++ b/src/main/java/com/zgx/iot/constant/enums/StateType.java @@ -0,0 +1,27 @@ +package com.zgx.iot.constant.enums; + +/** + * 状态类型 + */ +public enum StateType { + + HEARTBEAT("心跳",1), + BREAK_LINE("断纤",2), + OTHER_FAULT("其他故障",3); + + private String desc; + private Integer code; + + StateType(String desc, Integer value) { + this.desc = desc; + this.code = value; + } + + public String getDesc() { + return desc; + } + + public Integer getCode() { + return code; + } +} diff --git a/src/main/java/com/zgx/iot/constant/enums/TargetType.java b/src/main/java/com/zgx/iot/constant/enums/TargetType.java new file mode 100644 index 0000000..f8fa217 --- /dev/null +++ b/src/main/java/com/zgx/iot/constant/enums/TargetType.java @@ -0,0 +1,27 @@ +package com.zgx.iot.constant.enums; + +/** + * 目标类型 + */ +public enum TargetType { + + PEOPLE("人", 1), + CAR("车", 2), + OTHER("其他", 3); + + private String desc; + private Integer code; + + TargetType(String desc, Integer value) { + this.desc = desc; + this.code = value; + } + + public String getDesc() { + return desc; + } + + public Integer getCode() { + return code; + } +} diff --git a/src/main/java/com/zgx/iot/constant/enums/WarnLevel.java b/src/main/java/com/zgx/iot/constant/enums/WarnLevel.java new file mode 100644 index 0000000..85c29f0 --- /dev/null +++ b/src/main/java/com/zgx/iot/constant/enums/WarnLevel.java @@ -0,0 +1,18 @@ +package com.zgx.iot.constant.enums; + +/** + * 报警等级 + */ +public enum WarnLevel { + ONE(1), TWO(2), THREE(3), FOUR(4); + + private int value; + + WarnLevel(int value) { + this.value = value; + } + + public int getValue() { + return this.value; + } +} diff --git a/src/main/java/com/zgx/iot/constant/enums/WarnType.java b/src/main/java/com/zgx/iot/constant/enums/WarnType.java new file mode 100644 index 0000000..e400fad --- /dev/null +++ b/src/main/java/com/zgx/iot/constant/enums/WarnType.java @@ -0,0 +1,18 @@ +package com.zgx.iot.constant.enums; + +/** + * 警示类型 + */ +public enum WarnType { + PRE_WARN(1), WARN(2); + + private int value; + + WarnType(int value) { + this.value = value; + } + + public int getValue() { + return this.value; + } +} diff --git a/src/main/java/com/zgx/iot/controller/TrackingTargetController.java b/src/main/java/com/zgx/iot/controller/TrackingTargetController.java new file mode 100644 index 0000000..bf24df6 --- /dev/null +++ b/src/main/java/com/zgx/iot/controller/TrackingTargetController.java @@ -0,0 +1,248 @@ +package com.zgx.iot.controller; + +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.zgx.iot.constant.enums.DeviceType; +import com.zgx.iot.dto.radar.TrackingTargetDTO; +import com.zgx.iot.dto.site.Result; +import com.zgx.iot.entity.DtDeviceInfo; +import com.zgx.iot.entity.MsCameraSetting; +import com.zgx.iot.service.IDtDeviceInfoService; +import com.zgx.iot.service.IMsAlarmSettingsService; +import com.zgx.iot.service.IMsCameraSettingService; +import com.zgx.iot.utils.GEOUtils; +import com.zgx.iot.utils.RedisUtil; +import com.zgx.iot.utils.hp.HPDataParser; +import com.zgx.iot.utils.hp.HPReqParamEnc; +import com.zgx.iot.utils.hp.ThreadManager; +import com.zgx.iot.utils.socket.TcpClient; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.CollectionUtils; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + + +import java.io.UnsupportedEncodingException; +import java.math.BigDecimal; +import java.util.List; + +/** + * 光电跟踪接口 + */ +@RestController +@RequestMapping("/tracking") +@Slf4j +public class TrackingTargetController { + + @Autowired + RedisUtil redisUtil; + @Autowired + IDtDeviceInfoService msDeviceInfoService; + @Autowired + IMsCameraSettingService msCameraSettingService; + @Autowired + IMsAlarmSettingsService msAlarmSettingsService; + + + @PostMapping(value = "/target") + public Result trackingTarget(@RequestBody TrackingTargetDTO trackingTarget) throws UnsupportedEncodingException { + + //获取目标id 和 雷达id 和是否跟踪 + String trackTargetId = String.valueOf(trackingTarget.getTrackId()); + int radarId = trackingTarget.getRadarId(); + boolean isTracking = trackingTarget.isTrackStatus();//todo : 是否跟踪 + + String trackIdKey = "trackIds:" + trackTargetId; + //目标经纬度 + float targetLon = Float.parseFloat(redisUtil.hget(trackIdKey, "targetLon").toString()); + float targetLat = Float.parseFloat(redisUtil.hget(trackIdKey, "targetLat").toString()); + //目标距离(基于雷达) + int distance = Integer.parseInt(redisUtil.hget(trackIdKey, "targetDis").toString()); + //目标方位角(基于雷达) + float azimuth = Float.parseFloat(redisUtil.hget(trackIdKey, "targetAzimuth").toString()); + + log.info("目标经纬度:" + targetLon + "," + targetLat); + + //查询雷达信息 雷达经纬度(113.455074,22.122197) + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("device_type", DeviceType.RADAR.getValue()) //雷达类型 + .eq("device_status", 1) //1-启用状态 + .eq("id", radarId); //雷达Id + DtDeviceInfo deviceInfo = msDeviceInfoService.getOne(queryWrapper); + if (deviceInfo == null) { + log.info("查询不到雷达设备"); + return Result.error("查询不到雷达设备"); + } + log.info("雷达设备信息:" + deviceInfo); + + //查询光电信息 + DtDeviceInfo cameraInfo = null; + LambdaQueryWrapper photoelectricLambdaQueryWrapper = new LambdaQueryWrapper<>(); + photoelectricLambdaQueryWrapper.eq(DtDeviceInfo::getDeviceType, DeviceType.PHOTOELECTRIC.getValue()) //光电类型 + .eq(DtDeviceInfo::getDeviceStatus, 1);//1-启用状态 + List photoelectricDevices = msDeviceInfoService.list(photoelectricLambdaQueryWrapper);//查出所有光电 + if (CollectionUtils.isEmpty(photoelectricDevices)) { + log.info("查询不到光电设备"); + return Result.error("查询不到光电设备"); + } + cameraInfo = photoelectricDevices.get(0);//todo : 是否需要计算最近的光电 + log.info("光电设备信息:" + cameraInfo); + + //1、若设备关联光电,则进行联动定位 + if (cameraInfo != null) { + double cameraAzimuth = cameraInfo.getInitAzimuth() + Double.parseDouble(redisUtil.hget("PTZStatus", "pan").toString()); + //计算目标基于光电的方位角 + double targetAzimuth = GEOUtils.getAzimuth(cameraInfo.getDeviceLon(), + deviceInfo.getDeviceLat(), + targetLon, + targetLat + ); + + //计算光电水平所需方位角 + double differAzimuth = targetAzimuth - cameraAzimuth; + + //计算方位角 + double horAngle = Double.parseDouble(redisUtil.hget("PTZStatus", "pan").toString()) + differAzimuth; + horAngle = horAngle >= 0 ? horAngle : (360 + horAngle); + + //计算俯仰角(上27000-36000中间0-9000下) + double verAngle = Math.toDegrees(Math.asin((double) cameraInfo.getDeviceHeight() / distance)); + verAngle = verAngle + cameraInfo.getInitPitch(); + + //根据IP获取对应光电线程 + TcpClient tcpClient = ThreadManager.getTcpClientMap().get(cameraInfo.getDeviceIp()); + + //停止跟踪 + tcpClient.send( + HPDataParser.send( + HPReqParamEnc.ivpTrackingCtrl(String.valueOf(redisUtil.get(tcpClient.getIp())), 0, false, null) + ) + ); + + //转动光电到指定位置 + //当光电已经处于跟踪状态时,以下操作不会生效 + //根据目标位置进行定位(角度实际上送值 : 100倍整数值) + tcpClient.send( + HPDataParser.send( + HPReqParamEnc.ptzControl(String.valueOf(redisUtil.get(tcpClient.getIp())), + 0, 51, null, + null, null, 45, + (int) (horAngle * 100), (int) (verAngle * 100), null) + ) + ); + + //目标高度 平均高度 在ms_alarm_settings表中设置 船的平均高度 高度越高视场角越大 + double h = Double.parseDouble(redisUtil.hget("alarm_settings", "targetHeight").toString()); + + //计算目标距离光点的距离 + double d = GEOUtils.GetDistance(targetLon, targetLat, cameraInfo.getDeviceLon(), cameraInfo.getDeviceLat()); + + //计算视场角,100为分辨率/像素 + double fov = Math.toDegrees(Math.atan(h / d)) * 2 * 100; + log.info("目标平均高度:" + h + " 目标距离光电:" + d); + log.info("水平方位角:" + horAngle + " 俯仰角:" + verAngle + " 视场角:" + fov); + + tcpClient.send( + HPDataParser.send( + HPReqParamEnc.ptzControl(String.valueOf(redisUtil.get(tcpClient.getIp())), + 0, 42, null, + null, null, null, + null, null, (int) (fov * 100)) + ) + ); + + //球机联动 + log.info("联动控制球机:"); + LambdaQueryWrapper cameraSettingLambdaQueryWrapper = new LambdaQueryWrapper<>(); + cameraSettingLambdaQueryWrapper.eq(MsCameraSetting::getType, 2)//2-球机类型 + .eq(MsCameraSetting::getStatus, 1);//1-启用状态 + List cameraSettings = msCameraSettingService.list(cameraSettingLambdaQueryWrapper); + if (CollectionUtils.isEmpty(cameraSettings)) { + log.info("没有可联动的球机"); + return Result.error("没有可联动的球机"); + } + log.info("case4 : 遍历相机列表 寻找最近的点的球机去跟踪"); + + // 计算距离最近的球机 + MsCameraSetting msCameraSetting = null;//最近球机信息 + double nearestDistance = 0;//最近距离 + double heightDiff = 0;//最近球机的高度差 + for (MsCameraSetting cameraSetting : cameraSettings) { + // 判断该球机是否满足照射范围 不满足的话还可以找第二近的球机 如果放到后面才判断高度差 就无法找第二近的去跟踪了 + BigDecimal cameraHeight = cameraSetting.getHeight();//球机高度 + BigDecimal labelHeight = new BigDecimal(h);//目标高度 + double tempHeightDiff = cameraHeight.subtract(labelHeight).doubleValue();//球机与目标高度差 + if (tempHeightDiff < 0) { + log.info("case4 :" + "ip=" + cameraSetting.getIp() + " tempHeightDiff < 0 超过球机照射范围"); + } else { + double temp = GEOUtils.GetDistance(cameraSetting.getLongitude().doubleValue(), cameraSetting.getLatitude().doubleValue(), targetLon, targetLat); + log.info("当前的球机" + cameraSetting.getIp() + "与目标的距离:" + temp); + // 第一次 先将第一个球机的距离作为最近距离 和 最近球机信息 + if (msCameraSetting == null) { + msCameraSetting = cameraSetting; + nearestDistance = temp; + continue; + } + // 第二次以后 如果距离更近则更新最近距离 以及 最近球机信息 + if (nearestDistance > temp) { + msCameraSetting = cameraSetting; + nearestDistance = temp; + heightDiff = tempHeightDiff; + } + } + } + + //没有找到跟踪的球机 + if (msCameraSetting == null) { + log.info("没有可跟踪的球机"); + return Result.ERROR("没有可跟踪的球机"); + } + + //判断两点的距离是否超过有效距离,超过则丢掉 + if (nearestDistance > Integer.parseInt(redisUtil.hget("alarm_settings", "inOutEffectDistance").toString())) { + log.info("case4 :" + "目标超过跟踪的最大距离" + redisUtil.hget("alarm_settings", "inOutEffectDistance").toString()); + return Result.ERROR("目标超过跟踪的最大距离"); + } + + log.info("case4 :" + " 相机IP:" + msCameraSetting.getIp() + " 最短距离nearestDistance:" + nearestDistance); + log.info("case4 :" + "距离最近的相机:" + JSON.toJSONString(msCameraSetting)); + + //控制球机照射目标 + log.info("case4【尝试使用ptzControllerByLatLonAndDistance】将球机转到目标位置"); + + msCameraSettingService.ptzControllerByLatLon(msCameraSetting.getIp(), + msCameraSetting.getUser(), + msCameraSetting.getPassword(), + msCameraSetting.getMaxElevation(), + msCameraSetting.getZeroAzimuth(), + heightDiff, + msCameraSetting.getZoomFactor(), + msCameraSetting.getLongitude().doubleValue(), + msCameraSetting.getLatitude().doubleValue(), + targetLon, + targetLat, + msCameraSetting.getFactory());//factory用于区分品牌类型 1:海康 2:宇视 + + log.info("跟踪球机的主要参数信息:"); + log.info("1.IP: " + msCameraSetting.getIp()); + log.info("2.用户名: " + msCameraSetting.getUser()); + log.info("3.密码: " + msCameraSetting.getPassword()); + log.info("4.最大俯仰角: " + msCameraSetting.getMaxElevation()); + log.info("5.初始方位角: " + msCameraSetting.getZeroAzimuth()); + log.info("6.品牌: " + (msCameraSetting.getFactory() == 1 ? "海康" : "宇视")); + + //将需要跟踪的目标进行保存 并且保存跟踪该目标的球机IP + redisUtil.hset("trackingTargetId", trackTargetId, msCameraSetting.getIp()); + log.info("正在跟踪的trackId:" + trackTargetId + "跟踪的球机" + msCameraSetting.getIp()); + + //返回当前联动跟踪的球机信息 + return Result.OK(msCameraSetting); + } + return Result.ERROR("没有可跟踪的光电"); + } + +} diff --git a/src/main/java/com/zgx/iot/dto/Brower2LpmDto.java b/src/main/java/com/zgx/iot/dto/Brower2LpmDto.java new file mode 100644 index 0000000..0ef5d02 --- /dev/null +++ b/src/main/java/com/zgx/iot/dto/Brower2LpmDto.java @@ -0,0 +1,22 @@ +package com.zgx.iot.dto; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + + +@Data +@NoArgsConstructor + +@EqualsAndHashCode(callSuper = false) +public class Brower2LpmDto { + + private Integer messageType ; // 1 连接 ,2 数据 + + private String deviceCode ; // 设备号 + + private Integer dataType ; // 数据类型 1 16进制,2 ascii + + private String data ; // 数据 + +} diff --git a/src/main/java/com/zgx/iot/dto/radar/NyGuideCamPosModel.java b/src/main/java/com/zgx/iot/dto/radar/NyGuideCamPosModel.java new file mode 100644 index 0000000..c34d7d5 --- /dev/null +++ b/src/main/java/com/zgx/iot/dto/radar/NyGuideCamPosModel.java @@ -0,0 +1,52 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package com.zgx.iot.dto.radar; + +import java.beans.ConstructorProperties; + +/** + * 引导光电位置 + */ +public class NyGuideCamPosModel +{ + /** + * 距离(单位:米) + */ + private int dis; + + /** + * 方位(相对于大地北,单位:度) + */ + private float azimuth; + + + public int getDis() { + return dis; + } + + public void setDis(int dis) { + this.dis = dis; + } + + public float getAzimuth() { + return azimuth; + } + + public void setAzimuth(float azimuth) { + this.azimuth = azimuth; + } + + public NyGuideCamPosModel() { + } + + + @ConstructorProperties({ "dis","azimuth" }) + public NyGuideCamPosModel(final int dis, final float azimuth) { + this.dis=dis; + this.azimuth=azimuth; + } + + +} diff --git a/src/main/java/com/zgx/iot/dto/radar/RadarRESPackageModel.java b/src/main/java/com/zgx/iot/dto/radar/RadarRESPackageModel.java new file mode 100644 index 0000000..1f0ed5a --- /dev/null +++ b/src/main/java/com/zgx/iot/dto/radar/RadarRESPackageModel.java @@ -0,0 +1,87 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package com.zgx.iot.dto.radar; + + + +import com.zgx.iot.utils.radarUtils.BitConverter; + +import java.beans.ConstructorProperties; + +/** + * todo 雷达总体数据 + * 1.包头标识 mark + * 2.数据类型 dataType + * 3.整包数据的长度 dataLength + * 4.数据数量 dataNum + * 5.雷达数据 allBytes + */ +public class RadarRESPackageModel +{ + private byte[] allBytes; + + public int getMark() { + final int mark = BitConverter.bytes2IntSmallEndian(this.allBytes, 0); + return mark; + } + + public int getDataType() { + final int dataType = BitConverter.bytes2IntSmallEndian(this.allBytes, 4); + return dataType; + } + + public int getDataLength() { + final int dataLength = BitConverter.bytes2IntSmallEndian(this.allBytes, 8); + return dataLength; + } + + public int getDataNum() { + final int dataNum = BitConverter.bytes2IntSmallEndian(this.allBytes, 12); + return dataNum; + } + + public boolean isIntegrated() { + boolean flag = false; + if (this.getDataLength() <= this.allBytes.length) { + flag = true; + } + return flag; + } + + public byte[] getData() { + final int len = this.getDataLength() - 16; + final byte[] bs = new byte[len]; + System.arraycopy(this.allBytes, 16, bs, 0, len); + return bs; + } + + public byte[] getRemain() { + final int len = this.getDataLength(); + byte[] bs = null; + if (len < this.allBytes.length) { + bs = new byte[this.allBytes.length - len]; + System.arraycopy(this.allBytes, len, bs, 0, this.allBytes.length - len); + } + return bs; + } + + public RadarRESPackageModel() { + this.allBytes = null; + } + + @ConstructorProperties({ "allBytes" }) + public RadarRESPackageModel(final byte[] allBytes) { + this.allBytes = null; + this.allBytes = allBytes; + } + + public void setAllBytes(final byte[] allBytes) { + this.allBytes = allBytes; + } + + public byte[] getAllBytes() { + return this.allBytes; + } +} diff --git a/src/main/java/com/zgx/iot/dto/radar/RadarStateModel.java b/src/main/java/com/zgx/iot/dto/radar/RadarStateModel.java new file mode 100644 index 0000000..d0e462c --- /dev/null +++ b/src/main/java/com/zgx/iot/dto/radar/RadarStateModel.java @@ -0,0 +1,101 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package com.zgx.iot.dto.radar; + +import java.beans.ConstructorProperties; + +/** + * 雷达状态数据 + */ +public class RadarStateModel +{ + private int radarId; + private long timestamp; + private char workState; + private char sendState; + private float temperature; + private float longitude; + private float latitude; + private float altitude; + + public void setRadarId(final int radarId) { + this.radarId = radarId; + } + + public void setTimestamp(final long timestamp) { + this.timestamp = timestamp; + } + + public void setWorkState(final char workState) { + this.workState = workState; + } + + public void setSendState(final char sendState) { + this.sendState = sendState; + } + + public void setTemperature(final float temperature) { + this.temperature = temperature; + } + + public void setLongitude(final float longitude) { + this.longitude = longitude; + } + + public void setLatitude(final float latitude) { + this.latitude = latitude; + } + + public void setAltitude(final float altitude) { + this.altitude = altitude; + } + + public int getRadarId() { + return this.radarId; + } + + public long getTimestamp() { + return this.timestamp; + } + + public char getWorkState() { + return this.workState; + } + + public char getSendState() { + return this.sendState; + } + + public float getTemperature() { + return this.temperature; + } + + public float getLongitude() { + return this.longitude; + } + + public float getLatitude() { + return this.latitude; + } + + public float getAltitude() { + return this.altitude; + } + + public RadarStateModel() { + } + + @ConstructorProperties({ "radarId", "timestamp", "workState", "sendState", "temperature", "longitude", "latitude", "altitude" }) + public RadarStateModel(final int radarId, final long timestamp, final char workState, final char sendState, final float temperature, final float longitude, final float latitude, final float altitude) { + this.radarId = radarId; + this.timestamp = timestamp; + this.workState = workState; + this.sendState = sendState; + this.temperature = temperature; + this.longitude = longitude; + this.latitude = latitude; + this.altitude = altitude; + } +} diff --git a/src/main/java/com/zgx/iot/dto/radar/RadarTargetModel.java b/src/main/java/com/zgx/iot/dto/radar/RadarTargetModel.java new file mode 100644 index 0000000..fe1d59d --- /dev/null +++ b/src/main/java/com/zgx/iot/dto/radar/RadarTargetModel.java @@ -0,0 +1,91 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package com.zgx.iot.dto.radar; + +import java.beans.ConstructorProperties; + +/** + * 雷达点迹数据 + */ +public class RadarTargetModel +{ + private int radarId; + private long timestamp; + private int dis; + private float azimuth; + private float longitude; + private float latitude; + private float altitude; + + public void setRadarId(final int radarId) { + this.radarId = radarId; + } + + public void setTimestamp(final long timestamp) { + this.timestamp = timestamp; + } + + public void setDis(final int dis) { + this.dis = dis; + } + + public void setAzimuth(final float azimuth) { + this.azimuth = azimuth; + } + + public void setLongitude(final float longitude) { + this.longitude = longitude; + } + + public void setLatitude(final float latitude) { + this.latitude = latitude; + } + + public void setAltitude(final float altitude) { + this.altitude = altitude; + } + + public int getRadarId() { + return this.radarId; + } + + public long getTimestamp() { + return this.timestamp; + } + + public int getDis() { + return this.dis; + } + + public float getAzimuth() { + return this.azimuth; + } + + public float getLongitude() { + return this.longitude; + } + + public float getLatitude() { + return this.latitude; + } + + public float getAltitude() { + return this.altitude; + } + + public RadarTargetModel() { + } + + @ConstructorProperties({ "radarId", "timestamp", "dis", "azimuth", "longitude", "latitude", "altitude" }) + public RadarTargetModel(final int radarId, final long timestamp, final int dis, final float azimuth, final float longitude, final float latitude, final float altitude) { + this.radarId = radarId; + this.timestamp = timestamp; + this.dis = dis; + this.azimuth = azimuth; + this.longitude = longitude; + this.latitude = latitude; + this.altitude = altitude; + } +} diff --git a/src/main/java/com/zgx/iot/dto/radar/RadarTrackModel.java b/src/main/java/com/zgx/iot/dto/radar/RadarTrackModel.java new file mode 100644 index 0000000..a94074c --- /dev/null +++ b/src/main/java/com/zgx/iot/dto/radar/RadarTrackModel.java @@ -0,0 +1,225 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package com.zgx.iot.dto.radar; + +import java.beans.ConstructorProperties; + +/** + * 雷达航迹数据 + */ +public class RadarTrackModel +{ + private int radarId;//设备ID + private long timestamp;//时间戳 + private int trackId;//航迹ID(目标批号) + private char trackState;//目标状态 + private int dis;//距离 + private float azimuth;//方位角 + private float speed;//速度 + private float course;//航向 + private float longitude;//经度 + private float latitude;//纬度 + private float altitude;//海拔(估算目标高度) + private char type;//目标类型 + + //todo 增加字段 + private int deviceOwnerId;//设备所属站点ID + + private int counter;//目标消息 + + private int timeoutToNext; + + public int getdeviceOwnerId() { + return deviceOwnerId; + } + + public void setdeviceOwnerId(int deviceOwnerId) { + this.deviceOwnerId = deviceOwnerId; + } + + public int getCounter() { + return counter; + } + + public void setCounter(int counter) { + this.counter = counter; + } + + public int getDeviceOwnerId() { + return deviceOwnerId; + } + + public void setDeviceOwnerId(int deviceOwnerId) { + this.deviceOwnerId = deviceOwnerId; + } + + public int getTimeoutToNext() { + return timeoutToNext; + } + + public void setTimeoutToNext(int timeoutToNext) { + this.timeoutToNext = timeoutToNext; + } + + public void setRadarId(final int radarId) { + this.radarId = radarId; + } + + public void setTimestamp(final long timestamp) { + this.timestamp = timestamp; + } + + public void setTrackId(final int trackId) { + this.trackId = trackId; + } + + public void setTrackState(final char trackState) { + this.trackState = trackState; + } + + public void setDis(final int dis) { + this.dis = dis; + } + + public void setAzimuth(final float azimuth) { + this.azimuth = azimuth; + } + + public void setSpeed(final float speed) { + this.speed = speed; + } + + public void setCourse(final float course) { + this.course = course; + } + + public void setLongitude(final float longitude) { + this.longitude = longitude; + } + + public void setLatitude(final float latitude) { + this.latitude = latitude; + } + + public void setAltitude(final float altitude) { + this.altitude = altitude; + } + + public void setType(final char type) { + this.type = type; + } + + public int getRadarId() { + return this.radarId; + } + + public long getTimestamp() { + return this.timestamp; + } + + public int getTrackId() { + return this.trackId; + } + + public char getTrackState() { + return this.trackState; + } + + public int getDis() { + return this.dis; + } + + public float getAzimuth() { + return this.azimuth; + } + + public float getSpeed() { + return this.speed; + } + + public float getCourse() { + return this.course; + } + + public float getLongitude() { + return this.longitude; + } + + public float getLatitude() { + return this.latitude; + } + + public float getAltitude() { + return this.altitude; + } + + public char getType() { + return this.type; + } + + public RadarTrackModel() { + } + + @ConstructorProperties({ "radarId", "timestamp", "trackId", "trackState", "dis", "azimuth", "speed", "course", "longitude", "latitude", "altitude", "type" }) + public RadarTrackModel(final int radarId, + final long timestamp, + final int trackId, + final char trackState, + final int dis, + final float azimuth, + final float speed, + final float course, + final float longitude, + final float latitude, + final float altitude, + final char type) { + this.radarId = radarId; + this.timestamp = timestamp; + this.trackId = trackId; + this.trackState = trackState; + this.dis = dis; + this.azimuth = azimuth; + this.speed = speed; + this.course = course; + this.longitude = longitude; + this.latitude = latitude; + this.altitude = altitude; + this.type = type; + } + + //todo : 把新增字段的加入构造函数 + @ConstructorProperties({ "radarId", "timestamp", "trackId", "trackState", "dis", "azimuth", "speed", "course", "longitude", "latitude", "altitude", "type" ,"deviceOwnerId","counter","timeoutToNext"}) + public RadarTrackModel(final int radarId, + final long timestamp, + final int trackId, + final char trackState, + final int dis, + final float azimuth, + final float speed, + final float course, + final float longitude, + final float latitude, + final float altitude, + final char type, + final int deviceOwnerId, + final int counter, + final int timeoutToNext) { + this.radarId = radarId; + this.timestamp = timestamp; + this.trackId = trackId; + this.trackState = trackState; + this.dis = dis; + this.azimuth = azimuth; + this.speed = speed; + this.course = course; + this.longitude = longitude; + this.latitude = latitude; + this.altitude = altitude; + this.type = type; + this.deviceOwnerId=deviceOwnerId; + this.counter=counter; + this.timeoutToNext=timeoutToNext; + } +} diff --git a/src/main/java/com/zgx/iot/dto/radar/TrackingTargetDTO.java b/src/main/java/com/zgx/iot/dto/radar/TrackingTargetDTO.java new file mode 100644 index 0000000..bb74767 --- /dev/null +++ b/src/main/java/com/zgx/iot/dto/radar/TrackingTargetDTO.java @@ -0,0 +1,29 @@ +package com.zgx.iot.dto.radar; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class TrackingTargetDTO { + + + + /** + * 雷达Id + */ + private int radarId; + + /** + * 轨迹Id + */ + private int trackId; + + /** + * 是否跟踪 + */ + private boolean trackStatus; + +} diff --git a/src/main/java/com/zgx/iot/dto/site/AisInfo.java b/src/main/java/com/zgx/iot/dto/site/AisInfo.java new file mode 100644 index 0000000..9148be9 --- /dev/null +++ b/src/main/java/com/zgx/iot/dto/site/AisInfo.java @@ -0,0 +1,120 @@ +package com.zgx.iot.dto.site; + + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.io.Serializable; + +/** + * @Description: 船泊AIS信息表 + * @Author: jeecg-boot + * @Date: 2021-11-01 + * @Version: V1.0 + */ +@Data + + +public class AisInfo implements Serializable { + private static final long serialVersionUID = 1L; + + /**主键*/ + + //(value = "主键") + private String id; + /**创建人*/ + //(value = "创建人") + private String createBy; + /**创建日期*/ + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + + //(value = "创建日期") + private java.util.Date createTime; + /**更新人*/ + //(value = "更新人") + private String updateBy; + /**更新日期*/ + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + + //(value = "更新日期") + private java.util.Date updateTime; + /**事件编号*/ + //(value = "事件编号") + private String eventSerialNum; + /**船名*/ + + //(value = "船名") + private String shipName; + /**MMSI*/ + + //(value = "MMSI") + private String mmsi; + /**呼号*/ + + //(value = "呼号") + private String callSign; + /**IMO*/ + + //(value = "IMO") + private String imo; + /**船首向*/ + + //(value = "船首向") + private java.math.BigDecimal bowDirection; + /**航迹向*/ + + //(value = "航迹向") + private java.math.BigDecimal trackDirection; + /**状态*/ + + //(value = "状态") + private Integer shipStatus; + /**船长*/ + + //(value = "船长") + private Double shipLength; + /**船宽*/ + + //(value = "船宽") + private Double shipWidth; + /**吃水*/ + + //(value = "吃水") + private Double draft; + /**类型*/ + + //(value = "类型") + private Integer shipType; + /**航速*/ + + //(value = "航速") + private Double shipSpeed; + /**目的地*/ + + //(value = "目的地") + private String destination; + /**经度*/ + + //(value = "经度") + private java.math.BigDecimal longitude; + /**纬度*/ + + //(value = "纬度") + private java.math.BigDecimal latitude; + /**国籍*/ + + //(value = "国籍") + private String nationality; + /**预到时间*/ + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + + //(value = "预到时间") + private java.util.Date preArrivalTime; + + //(value = "创建时间") + private Long realTime; + + //(value = "操作类型:设备增加,1;设备删减,2;设备信息变更,3;") + private int operaType; +} diff --git a/src/main/java/com/zgx/iot/dto/site/AlarmInfo.java b/src/main/java/com/zgx/iot/dto/site/AlarmInfo.java new file mode 100644 index 0000000..9a392ef --- /dev/null +++ b/src/main/java/com/zgx/iot/dto/site/AlarmInfo.java @@ -0,0 +1,101 @@ +package com.zgx.iot.dto.site; + + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.Date; + +/** + * @Description: 告警信息格式 + * @Author: lxc + * @Date: 2023-08-01 + * @Version: V1.0 + */ +@Data +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) + +public class AlarmInfo implements Serializable { + private static final long serialVersionUID = 1L; + + /**报警信息唯一标识*/ + /*@TableId(type = IdType.ASSIGN_ID)*/ + //(value = "报警信息唯一标识") + private String _id; + /**报警所属站点ID*/ + + //(value = "报警所属站点ID") + private String alarmOwnerId; + /**报警类型*/ + + //(value = "报警类型") + private Integer alarmType; + /**报警类型名称*/ + + //(value = "报警类型名称") + private String alarmTypeName; + /**报警等级*/ + + //(value = "报警等级") + private Integer alarmLevel; + /**报警信息描述*/ + + //(value = "报警信息描述") + private String alarmContent; + /**报警处置状态*/ + + //(value = "报警处置状态") + private String alarmDisposal; + /**报警开始时间*/ + + + + //(value = "报警开始时间") + private Date alarmTimeStart; + /**报警关闭时间*/ + + + //(value = "报警关闭时间") + private Date alarmTimeEnd; + /**报警点经度*/ + + //(value = "报警点经度") + private Double alarmPointLon; + /**报警点纬度*/ + + //(value = "报警点纬度") + private Double alarmPointLat; + /**报警点海拔*/ + + //(value = "报警点海拔") + private Double alarmPointAlt; + /**关联报警目标唯一标识*/ + + //(value = "关联报警目标唯一标识") + private String alarmTargetId; + /**记录目标到目前位置航迹点位*/ + + //(value = "记录目标到目前位置航迹点位") + private String targetPoint; + /**关联摄像机唯一标识*/ + + //(value = "关联摄像机唯一标识") + private String alarmCameraId; + /**创建人*/ + //(value = "创建人") + private String createBy; + /**创建时间*/ + + //(value = "创建时间") + private Long realTime; + + //(value = "操作类型:设备增加,1;设备删减,2;设备信息变更,3;") + private int operaType; + + + + +} diff --git a/src/main/java/com/zgx/iot/dto/site/CommonConstant.java b/src/main/java/com/zgx/iot/dto/site/CommonConstant.java new file mode 100644 index 0000000..c7a2e28 --- /dev/null +++ b/src/main/java/com/zgx/iot/dto/site/CommonConstant.java @@ -0,0 +1,325 @@ +package com.zgx.iot.dto.site; + +public interface CommonConstant { + + /** + * 正常状态 + */ + public static final Integer STATUS_NORMAL = 0; + + /** + * 禁用状态 + */ + public static final Integer STATUS_DISABLE = -1; + + /** + * 删除标志 + */ + public static final Integer DEL_FLAG_1 = 1; + + /** + * 未删除 + */ + public static final Integer DEL_FLAG_0 = 0; + + /** + * 系统日志类型: 登录 + */ + public static final int LOG_TYPE_1 = 1; + + /** + * 系统日志类型: 操作 + */ + public static final int LOG_TYPE_2 = 2; + + /** + * 操作日志类型: 查询 + */ + public static final int OPERATE_TYPE_1 = 1; + + /** + * 操作日志类型: 添加 + */ + public static final int OPERATE_TYPE_2 = 2; + + /** + * 操作日志类型: 更新 + */ + public static final int OPERATE_TYPE_3 = 3; + + /** + * 操作日志类型: 删除 + */ + public static final int OPERATE_TYPE_4 = 4; + + /** + * 操作日志类型: 倒入 + */ + public static final int OPERATE_TYPE_5 = 5; + + /** + * 操作日志类型: 导出 + */ + public static final int OPERATE_TYPE_6 = 6; + + + /** {@code 500 Server Error} (HTTP/1.0 - RFC 1945) */ + public static final Integer SC_INTERNAL_SERVER_ERROR_500 = 500; + /** {@code 200 OK} (HTTP/1.0 - RFC 1945) */ + public static final Integer SC_OK_200 = 200; + + /**访问权限认证未通过 510*/ + public static final Integer SC_JEECG_NO_AUTHZ=510; + + /** 登录用户Shiro权限缓存KEY前缀 */ + public static String PREFIX_USER_SHIRO_CACHE = "shiro:cache:org.jeecg.config.shiro.ShiroRealm.authorizationCache:"; + /** 登录用户Token令牌缓存KEY前缀 */ + public static final String PREFIX_USER_TOKEN = "prefix_user_token_"; + /** Token缓存时间:3600秒即一小时 */ + public static final int TOKEN_EXPIRE_TIME = 3600; + + + /** + * 0:一级菜单 + */ + public static final Integer MENU_TYPE_0 = 0; + /** + * 1:子菜单 + */ + public static final Integer MENU_TYPE_1 = 1; + /** + * 2:按钮权限 + */ + public static final Integer MENU_TYPE_2 = 2; + + /**通告对象类型(USER:指定用户,ALL:全体用户)*/ + public static final String MSG_TYPE_UESR = "USER"; + public static final String MSG_TYPE_ALL = "ALL"; + + /**发布状态(0未发布,1已发布,2已撤销)*/ + public static final String NO_SEND = "0"; + public static final String HAS_SEND = "1"; + public static final String HAS_CANCLE = "2"; + + /**阅读状态(0未读,1已读)*/ + public static final String HAS_READ_FLAG = "1"; + public static final String NO_READ_FLAG = "0"; + + /**优先级(L低,M中,H高)*/ + public static final String PRIORITY_L = "L"; + public static final String PRIORITY_M = "M"; + public static final String PRIORITY_H = "H"; + + /** + * 短信模板方式 0 .登录模板、1.注册模板、2.忘记密码模板 + */ + public static final String SMS_TPL_TYPE_0 = "0"; + public static final String SMS_TPL_TYPE_1 = "1"; + public static final String SMS_TPL_TYPE_2 = "2"; + + /** + * 状态(0无效1有效) + */ + public static final String STATUS_0 = "0"; + public static final String STATUS_1 = "1"; + + /** + * 同步工作流引擎1同步0不同步 + */ + public static final Integer ACT_SYNC_1 = 1; + public static final Integer ACT_SYNC_0 = 0; + + /** + * 消息类型1:通知公告2:系统消息 + */ + public static final String MSG_CATEGORY_1 = "1"; + public static final String MSG_CATEGORY_2 = "2"; + + /** + * 是否配置菜单的数据权限 1是0否 + */ + public static final Integer RULE_FLAG_0 = 0; + public static final Integer RULE_FLAG_1 = 1; + + /** + * 是否用户已被冻结 1正常(解冻) 2冻结 + */ + public static final Integer USER_UNFREEZE = 1; + public static final Integer USER_FREEZE = 2; + + /**字典翻译文本后缀*/ + public static final String DICT_TEXT_SUFFIX = "_dictText"; + + /** + * 表单设计器主表类型 + */ + public static final Integer DESIGN_FORM_TYPE_MAIN = 1; + + /** + * 表单设计器子表表类型 + */ + public static final Integer DESIGN_FORM_TYPE_SUB = 2; + + /** + * 表单设计器URL授权通过 + */ + public static final Integer DESIGN_FORM_URL_STATUS_PASSED = 1; + + /** + * 表单设计器URL授权未通过 + */ + public static final Integer DESIGN_FORM_URL_STATUS_NOT_PASSED = 2; + + /** + * 表单设计器新增 Flag + */ + public static final String DESIGN_FORM_URL_TYPE_ADD = "add"; + /** + * 表单设计器修改 Flag + */ + public static final String DESIGN_FORM_URL_TYPE_EDIT = "edit"; + /** + * 表单设计器详情 Flag + */ + public static final String DESIGN_FORM_URL_TYPE_DETAIL = "detail"; + /** + * 表单设计器复用数据 Flag + */ + public static final String DESIGN_FORM_URL_TYPE_REUSE = "reuse"; + /** + * 表单设计器编辑 Flag (已弃用) + */ + public static final String DESIGN_FORM_URL_TYPE_VIEW = "view"; + + /** + * online参数值设置(是:Y, 否:N) + */ + public static final String ONLINE_PARAM_VAL_IS_TURE = "Y"; + public static final String ONLINE_PARAM_VAL_IS_FALSE = "N"; + + /** + * 文件上传类型(本地:local,Minio:minio,阿里云:alioss) + */ + public static final String UPLOAD_TYPE_LOCAL = "local"; + public static final String UPLOAD_TYPE_MINIO = "minio"; + public static final String UPLOAD_TYPE_OSS = "alioss"; + + /** + * 文档上传自定义桶名称 + */ + public static final String UPLOAD_CUSTOM_BUCKET = "eoafile"; + /** + * 文档上传自定义路径 + */ + public static final String UPLOAD_CUSTOM_PATH = "eoafile"; + /** + * 文件外链接有效天数 + */ + public static final Integer UPLOAD_EFFECTIVE_DAYS = 1; + + /** + * 员工身份 (1:普通员工 2:上级) + */ + public static final Integer USER_IDENTITY_1 = 1; + public static final Integer USER_IDENTITY_2 = 2; + + /** sys_user 表 username 唯一键索引 */ + public static final String SQL_INDEX_UNIQ_SYS_USER_USERNAME = "uniq_sys_user_username"; + /** sys_user 表 work_no 唯一键索引 */ + public static final String SQL_INDEX_UNIQ_SYS_USER_WORK_NO = "uniq_sys_user_work_no"; + /** sys_user 表 phone 唯一键索引 */ + public static final String SQL_INDEX_UNIQ_SYS_USER_PHONE = "uniq_sys_user_phone"; + /** sys_user 表 email 唯一键索引 */ + public static final String SQL_INDEX_UNIQ_SYS_USER_EMAIL = "uniq_sys_user_email"; + /** sys_quartz_job 表 job_class_name 唯一键索引 */ + public static final String SQL_INDEX_UNIQ_JOB_CLASS_NAME = "uniq_job_class_name"; + /** sys_position 表 code 唯一键索引 */ + public static final String SQL_INDEX_UNIQ_CODE = "uniq_code"; + /** sys_role 表 code 唯一键索引 */ + public static final String SQL_INDEX_UNIQ_SYS_ROLE_CODE = "uniq_sys_role_role_code"; + /** sys_depart 表 code 唯一键索引 */ + public static final String SQL_INDEX_UNIQ_DEPART_ORG_CODE = "uniq_depart_org_code"; + /** + * 在线聊天 是否为默认分组 + */ + public static final String IM_DEFAULT_GROUP = "1"; + /** + * 在线聊天 图片文件保存路径 + */ + public static final String IM_UPLOAD_CUSTOM_PATH = "imfile"; + /** + * 在线聊天 用户状态 + */ + public static final String IM_STATUS_ONLINE = "online"; + + /** + * 在线聊天 SOCKET消息类型 + */ + public static final String IM_SOCKET_TYPE = "chatMessage"; + + /** + * 在线聊天 是否开启默认添加好友 1是 0否 + */ + public static final String IM_DEFAULT_ADD_FRIEND = "1"; + + /** + * 在线聊天 用户好友缓存前缀 + */ + public static final String IM_PREFIX_USER_FRIEND_CACHE = "sys:cache:im:im_prefix_user_friend_"; + + /** + * 考勤补卡业务状态 (1:同意 2:不同意) + */ + public static final String SIGN_PATCH_BIZ_STATUS_1 = "1"; + public static final String SIGN_PATCH_BIZ_STATUS_2 = "2"; + + /** + * 公文文档上传自定义路径 + */ + public static final String UPLOAD_CUSTOM_PATH_OFFICIAL = "officialdoc"; + /** + * 公文文档下载自定义路径 + */ + public static final String DOWNLOAD_CUSTOM_PATH_OFFICIAL = "officaldown"; + + /** + * WPS存储值类别(1 code文号 2 text(WPS模板还是公文发文模板)) + */ + public static final String WPS_TYPE_1="1"; + public static final String WPS_TYPE_2="2"; + + + public final static String X_ACCESS_TOKEN = "X-Access-Token"; + + /** + * 多租户 请求头 + */ + public final static String TENANT_ID = "tenant-id"; + + /** + * 微服务读取配置文件属性 服务地址 + */ + public final static String CLOUD_SERVER_KEY = "spring.cloud.nacos.discovery.server-addr"; + + /** + * 第三方登录 验证密码/创建用户 都需要设置一个操作码 防止被恶意调用 + */ + public final static String THIRD_LOGIN_CODE = "third_login_code"; + + /** + * 第三方APP同步方向:本地 --> 第三方APP + */ + String THIRD_SYNC_TO_APP = "SYNC_TO_APP"; + /** + * 第三方APP同步方向:第三方APP --> 本地 + */ + String THIRD_SYNC_TO_LOCAL = "SYNC_TO_LOCAL"; + + /** 系统通告消息状态:0=未发布 */ + String ANNOUNCEMENT_SEND_STATUS_0 = "0"; + /** 系统通告消息状态:1=已发布 */ + String ANNOUNCEMENT_SEND_STATUS_1 = "1"; + /** 系统通告消息状态:2=已撤销 */ + String ANNOUNCEMENT_SEND_STATUS_2 = "2"; + +} diff --git a/src/main/java/com/zgx/iot/dto/site/DeveiceType.java b/src/main/java/com/zgx/iot/dto/site/DeveiceType.java new file mode 100644 index 0000000..9000043 --- /dev/null +++ b/src/main/java/com/zgx/iot/dto/site/DeveiceType.java @@ -0,0 +1,66 @@ +package com.zgx.iot.dto.site; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * @Description: 设备类型表 + * @Author: lxc + * @Date: 2023-08-17 + * @Version: V1.0 + */ +@Data + +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) + +public class DeveiceType implements Serializable { + private static final long serialVersionUID = 1L; + + /**id*/ + + //(value = "id") + private String id; + /**类型编号*/ + + //(value = "类型编号") + private Integer typeNo; + /**类型名称*/ + + //(value = "类型名称") + private String typeName; + /**是否有传感器*/ + + //(value = "是否有传感器") + private Integer havesensor; + /**地图显示图片模型*/ + + //(value = "地图显示图片模型") + private String mapIco; + /**是否3D*/ + + //(value = "是否3D") + private Integer is3d; + /**默认宽度*/ + + //(value = "默认宽度") + private BigDecimal width; + /**默认长度*/ + + //(value = "默认长度") + private BigDecimal length; + /**默认高度*/ + + //(value = "默认高度") + private BigDecimal height; + + //(value = "创建时间") + private Long realTime; + + //(value = "操作类型:设备增加,1;设备删减,2;设备信息变更,3;") + private int operaType; +} diff --git a/src/main/java/com/zgx/iot/dto/site/DeviceInfo.java b/src/main/java/com/zgx/iot/dto/site/DeviceInfo.java new file mode 100644 index 0000000..fc912cb --- /dev/null +++ b/src/main/java/com/zgx/iot/dto/site/DeviceInfo.java @@ -0,0 +1,133 @@ +package com.zgx.iot.dto.site; + + +import lombok.Data; + +import java.io.Serializable; + +/** + * @Description: 设备信息表 + * @Author: jeecg-boot + * @Date: 2023-08-18 + * @Version: V1.0 + */ + +@Data +@Deprecated +public class DeviceInfo implements Serializable { + private static final long serialVersionUID = 1L; + + /**设备唯一标识*/ + + //(value = "设备唯一标识") + private String id; + /**设备所属站点ID*/ + + private String deviceOwnerId; + /**设备类型*/ + + //(value = "设备类型") + private Integer deviceType; + /**设备编码*/ + + //(value = "设备编码") + private String deviceCode; + /**设备名称*/ + + //(value = "设备名称") + private String deviceName; + /**位置描述置*/ + + //(value = "位置描述置") + private String devicePosition; + /**设备经度*/ + + //(value = "设备经度") + private Double deviceLon; + /**设备纬度*/ + + //(value = "设备纬度") + private Double deviceLat; + /**设备海拔*/ + + //(value = "设备海拔") + private Double deviceAlt; + /**设备状态*/ + + //(value = "设备状态") + private Integer deviceStatus; + /**入网许可证*/ + + //(value = "入网许可证") + private Integer isAudit; + /**设备访问路径*/ + + //(value = "设备访问路径") + private String deviceUrl; + /**设备ip地址*/ + + //(value = "设备ip地址") + private String deviceIp; + /**端口*/ + + //(value = "端口") + private Integer ipPort; + /**端口2*/ + + //(value = "端口2") + private Integer ipPort2; + /**用户名*/ + + //(value = "用户名") + private String username; + /**密码*/ + + //(value = "密码") + private String password; + /**设备子类型*/ + + //(value = "设备子类型") + private Integer subtype; + /**安装高度*/ + + //(value = "安装高度") + private Integer deviceHeight; + /**初始方位角*/ + + //(value = "初始方位角") + private Integer initAzimuth; + /**初始俯仰角*/ + + //(value = "初始俯仰角") + private Integer initPitch; + /**工作半径*/ + + //(value = "工作半径") + private Integer workingRadius; + /**水平市场角度*/ + + //(value = "水平市场角度") + private Integer horizontalAngle; + /**锤子市场角度*/ + + //(value = "锤子市场角度") + private Integer verticalAngle; + /**识别刻度*/ + + //(value = "识别刻度") + private Integer identificationScale; + /**备注*/ + + //(value = "备注") + private String remark; + /**协议类型*/ + + //(value = "协议类型") + private Integer protocol; + + //(value = "创建时间") + private Long realTime; + + //(value = "操作类型:设备增加,1;设备删减,2;设备信息变更,3;") + private int operaType; +} diff --git a/src/main/java/com/zgx/iot/dto/site/DeviceStatus.java b/src/main/java/com/zgx/iot/dto/site/DeviceStatus.java new file mode 100644 index 0000000..a7e50b2 --- /dev/null +++ b/src/main/java/com/zgx/iot/dto/site/DeviceStatus.java @@ -0,0 +1,44 @@ +package com.zgx.iot.dto.site; + + +import lombok.Data; + +import java.io.Serializable; + +/** + * @Description: 设备状态信息 + * @Author: jeecg-boot + * @Date: 2023-08-18 + * @Version: V1.0 + */ + +@Data + +public class DeviceStatus implements Serializable { + private static final long serialVersionUID = 1L; + + /**id*/ + + private String id; + /**设备唯一标识*/ + //(value = "设备唯一标识") + private String deviceId; + /**设备所属站点ID*/ + + //(value = "设备所属站点ID") + private Integer deviceOwnerId; + /**设备初始状态*/ + + //(value = "设备初始状态") + private Integer status; + /**状态补充说明*/ + + //(value = "状态补充说明") + private String remark; + + //(value = "创建时间") + private Long realTime; + + //(value = "操作类型:设备增加,1;设备删减,2;设备信息变更,3;") + private int operaType; +} diff --git a/src/main/java/com/zgx/iot/dto/site/Result.java b/src/main/java/com/zgx/iot/dto/site/Result.java new file mode 100644 index 0000000..942cb78 --- /dev/null +++ b/src/main/java/com/zgx/iot/dto/site/Result.java @@ -0,0 +1,159 @@ +package com.zgx.iot.dto.site; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Data; + +import java.io.Serializable; + + +/** + * 接口返回数据格式 + * @author scott + * @email jeecgos@163.com + * @date 2019年1月19日 + */ +@Data +public class Result implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 成功标志 + */ + + private boolean success = true; + + /** + * 返回处理消息 + */ + + private String message = "操作成功!"; + + /** + * 返回代码 + */ + + private Integer code = 0; + + /** + * 返回数据对象 data + */ + + private T result; + + /** + * 时间戳 + */ + + private long timestamp = System.currentTimeMillis(); + + public Result() { + + } + + public Result success(String message) { + this.message = message; + this.code = CommonConstant.SC_OK_200; + this.success = true; + return this; + } + + @Deprecated + public static Result ok() { + Result r = new Result(); + r.setSuccess(true); + r.setCode(CommonConstant.SC_OK_200); + r.setMessage("成功"); + return r; + } + + @Deprecated + public static Result ok(String msg) { + Result r = new Result<>(); + r.setSuccess(true); + r.setCode(CommonConstant.SC_OK_200); + r.setMessage(msg); + return r; + } + + @Deprecated + public static Result ok(Object data) { + Result r = new Result(); + r.setSuccess(true); + r.setCode(CommonConstant.SC_OK_200); + r.setResult(data); + return r; + } + + public static Result OK() { + Result r = new Result(); + r.setSuccess(true); + r.setCode(CommonConstant.SC_OK_200); + r.setMessage("成功"); + return r; + } + + public static Result OK(T data) { + Result r = new Result(); + r.setSuccess(true); + r.setCode(CommonConstant.SC_OK_200); + r.setResult(data); + return r; + } + + public static Result OK(String msg, T data) { + Result r = new Result(); + r.setSuccess(true); + r.setCode(CommonConstant.SC_OK_200); + r.setMessage(msg); + r.setResult(data); + return r; + } + + public static Result error(String msg, T data) { + Result r = new Result(); + r.setSuccess(false); + r.setCode(CommonConstant.SC_INTERNAL_SERVER_ERROR_500); + r.setMessage(msg); + r.setResult(data); + return r; + } + + public static Result ERROR(String msg) { + return ERROR(CommonConstant.SC_INTERNAL_SERVER_ERROR_500, msg); + } + public static Result ERROR(int code, String msg) { + Result r = new Result<>(); + r.setCode(code); + r.setMessage(msg); + r.setSuccess(false); + return r; + } + public static Result error(String msg) { + return error(CommonConstant.SC_INTERNAL_SERVER_ERROR_500, msg); + } + public static Result error(int code, String msg) { + Result r = new Result<>(); + r.setCode(code); + r.setMessage(msg); + r.setSuccess(false); + return r; + } + + public Result error500(String message) { + this.message = message; + this.code = CommonConstant.SC_INTERNAL_SERVER_ERROR_500; + this.success = false; + return this; + } + /** + * 无权限访问返回结果 + */ + public static Result noauth(String msg) { + return error(CommonConstant.SC_JEECG_NO_AUTHZ, msg); + } + + @JsonIgnore + private String onlTable; + +} diff --git a/src/main/java/com/zgx/iot/dto/site/SysDictItem.java b/src/main/java/com/zgx/iot/dto/site/SysDictItem.java new file mode 100644 index 0000000..4482072 --- /dev/null +++ b/src/main/java/com/zgx/iot/dto/site/SysDictItem.java @@ -0,0 +1,75 @@ +package com.zgx.iot.dto.site; + + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * + *

+ * + * @Author zhangweijian + * @since 2018-12-28 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +public class SysDictItem implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * id + */ + + private String id; + + /** + * 字典id + */ + private String dictId; + + /** + * 字典项文本 + */ + private String itemText; + + /** + * 字典项值 + */ + private String itemValue; + + /** + * 描述 + */ + private String description; + + /** + * 排序 + */ + + private Integer sortOrder; + + + /** + * 状态(1启用 0不启用) + */ + + private Integer status; + + private String createBy; + + private Date createTime; + + private String updateBy; + + private Date updateTime; + + +} diff --git a/src/main/java/com/zgx/iot/entity/DtDeviceInfo.java b/src/main/java/com/zgx/iot/entity/DtDeviceInfo.java new file mode 100644 index 0000000..c018326 --- /dev/null +++ b/src/main/java/com/zgx/iot/entity/DtDeviceInfo.java @@ -0,0 +1,195 @@ +package com.zgx.iot.entity; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.Date; + +/** + * @Description: 设备信息表 + * @Author: jeecg-boot + * @Date: 2022-08-12 + * @Version: V1.0 + */ +@Data +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +public class DtDeviceInfo implements Serializable { + private static final long serialVersionUID = 1L; + /** + * 设备唯一标识 + */ + private String id; + + /** + * 设备所属站点ID + */ + private String deviceOwnerId; + + /** + * 设备类型 + */ + private Integer deviceType; + + /** + * 设备编码 + */ + private String deviceCode; + + /** + * 设备名称 + */ + private String deviceName; + + /** + * 位置描述置 + */ + private String devicePosition; + + /** + * 设备经度 + */ + private Double deviceLon; + + /** + * 设备纬度 + */ + private Double deviceLat; + + /** + * 设备海拔 + */ + private Double deviceAlt; + + /** + * 设备状态 + */ + private Integer deviceStatus; + + /** + * 设备访问路径 + */ + private String deviceUrl; + + /** + * 设备ip地址 + */ + private String deviceIp; + + /** + * 端口 + */ + private Integer ipPort; + + /** + * 端口2 + */ + private Integer ipPort2; + + /** + * 用户名 + */ + private String username; + + /** + * 密码 + */ + private String password; + + /** + * 设备子类型 + */ + private Integer subtype; + + /** + * 安装高度 + */ + private Integer deviceHeight; + + /** + * 初始方位角 + */ + private Integer initAzimuth; + + /** + * 初始俯仰角 + */ + private Integer initPitch; + + /** + * 工作半径 + */ + private Integer workingRadius; + + /** + * 水平市场角度 + */ + private Integer horizontalAngle; + + /** + * 锤子市场角度 + */ + private Integer verticalAngle; + + /** + * 识别刻度 + */ + private Integer identificationScale; + + /** + * 网络协议类型 + */ + private String netProtocol; + + /** + * 数据协议类型 + */ + private String dataProtocol; + + /** + * 备注 + */ + private String remark; + + /** + * 创建人 + */ + private String createBy; + + /** + * 创建时间 + */ + private Date createTime; + + /** + * 修改人 + */ + private String updateBy; + + /** + * 修改时间 + */ + private Date updateTime; + + /** + * 所属区域 + */ + private String sysAreaCode; + + /** + * 所属部门 + */ + private String sysOrgCode; + + /** + * 入网许可证 + */ + private Integer isAudit; + + /** + * 设备服务器类型 + */ + private Integer serverType; +} diff --git a/src/main/java/com/zgx/iot/entity/MsAlarmSettings.java b/src/main/java/com/zgx/iot/entity/MsAlarmSettings.java new file mode 100644 index 0000000..15300d2 --- /dev/null +++ b/src/main/java/com/zgx/iot/entity/MsAlarmSettings.java @@ -0,0 +1,67 @@ +package com.zgx.iot.entity; + +import lombok.Data; + + +import java.io.Serializable; +import java.util.Date; + +/** + * @Description: 报警参数配置表 + * @Author: jeecg-boot + * @Date: 2022-09-02 + * @Version: V1.0 + */ +@Data +public class MsAlarmSettings implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + private String id; + /** + * 创建人 + */ + private String createBy; + /** + * 创建日期 + */ + private Date createTime; + /** + * 更新人 + */ + private String updateBy; + /** + * 更新日期 + */ + private Date updateTime; + /** + * 所属部门 + */ + private String sysOrgCode; + /** + * 航迹点有效时间(秒) + */ + private Integer lineEffectTime; + /** + * 报警区域有效时间(秒) + */ + private Integer alarmEffectTime; + /** + * 跟踪目标有效时间(秒) + */ + private Integer trackEffectTime; + /** + * 报警防区有效时间(秒) + */ + private Integer fenceEffectTime; + /** + * 围网外侧航迹点与内测点迹距离有效距离(米) + */ + private Integer inOutEffectDistance; + /** + * 目标平均身高(米) + */ + private Double targetHeight; +} diff --git a/src/main/java/com/zgx/iot/entity/MsCameraSetting.java b/src/main/java/com/zgx/iot/entity/MsCameraSetting.java new file mode 100644 index 0000000..7f973c1 --- /dev/null +++ b/src/main/java/com/zgx/iot/entity/MsCameraSetting.java @@ -0,0 +1,112 @@ +package com.zgx.iot.entity; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * @Description: 相机设置 + * @Author: jeecg-boot + * @Date: 2021-07-01 + * @Version: V1.0 + */ + +//todo : 少了字段 1.厂家 +@Data +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +public class MsCameraSetting implements Serializable { + private static final long serialVersionUID = 1L; + + /**主键*/ + private String id; + /**创建人*/ + private String createBy; + /**创建日期*/ + private Date createTime; + /**更新人*/ + private String updateBy; + /**更新日期*/ + private Date updateTime; + /**站点id*/ + private String siteId; + /**相机ip*/ + private String ip; + /**相机备用ip*/ + private String ip2; + /**端口*/ + private Integer port; + /**相机类型(厂家)*/ + private Integer factory; + /**认证用户名*/ + private String user; + /**认证密码*/ + private String password; + /**相机预览通道*/ + private Integer channel; + /**rtsp地址*/ + private String preRtsp; + /**分析rtsp*/ + private String analysisRtsp; + /**录像rtsp*/ + private String recordRtsp; + //todo:补充字段 1.站点名称(siteName) 2.web播放地址(webcast_address) 3.相机编号(camera_code) + /**站点名称*/ + private String siteName; + /**web播放地址*/ + private String webcastAddress; + /**相机编号*/ + private String cameraCode; + /**云台控制ip*/ + private String cloudCtrlIp; + /**云台控制端口*/ + private Integer cloudCtrlPort; + /**相机名称*/ + private String cameraName; + /**纬度*/ + private BigDecimal latitude; + /**经度*/ + private BigDecimal longitude; + /**高度*/ + private BigDecimal height; + /**类型*/ + private Integer type; + /**样式*/ + private Integer style; + /**左夹角*/ + private Double leftAngle; + /**右夹角*/ + private Double rightAngle; + /**视野中央有效距离*/ + private Double viewDistance; + /**采样帧率*/ + private Integer frameRate; + /**最大跟踪范围*/ + private Integer maxRange; + /**状态*/ + private Integer status; + /**零方位角(正北夹角)*/ + private Double zeroAzimuth; + /**安装垂直角(上下-90°~90°)*/ + private Double fixedAngle; + /**最大仰角*/ + private Double maxElevation; + /**最大可视距离*/ + private Double maxVisibleDistance; + /**变倍因子*/ + private Double zoomFactor; + /**流媒体服务器id*/ + private String streamingMediaId; + /**录像机id*/ + private String videoRecorderId; + /**白光开始时间*/ + private String dayBeginTime; + /**白光结束时间*/ + private String dayEndTime; + /**报警次数*/ + private Integer alarmNum; +} diff --git a/src/main/java/com/zgx/iot/entity/MsModelPosition.java b/src/main/java/com/zgx/iot/entity/MsModelPosition.java new file mode 100644 index 0000000..47d8b7f --- /dev/null +++ b/src/main/java/com/zgx/iot/entity/MsModelPosition.java @@ -0,0 +1,50 @@ +package com.zgx.iot.entity; + +import lombok.Data; + +import java.io.Serializable; + + +@Data +public class MsModelPosition implements Serializable { + private static final long serialVersionUID = 1L; + + /**主键*/ + private String id; + /**创建人*/ + private String createBy; + /**创建日期*/ + private java.util.Date createTime; + /**更新人*/ + private String updateBy; + /**更新日期*/ + private java.util.Date updateTime; + /**所属部门*/ + private String sysOrgCode; + /**事件编号*/ + private String eventSerialNum; + /**事件类型*/ + private Integer eventType; + /**模型id*/ + private String modelId; + /**模型类别*/ + private Integer modelType; + /**经度*/ + private java.math.BigDecimal lon; + /**纬度*/ + private java.math.BigDecimal lat; + /**高度*/ + private java.math.BigDecimal height; + /**偏航角*/ + private java.math.BigDecimal yaw; + /**俯仰角*/ + private java.math.BigDecimal pitch; + /**翻转角*/ + private java.math.BigDecimal roll; + /**开始时间*/ + private java.util.Date startTimestamp; + /**结束时间*/ + private java.util.Date endTimestamp; + /**是否展示*/ + private Integer isShow; +} diff --git a/src/main/java/com/zgx/iot/entity/MsModelTrajectory.java b/src/main/java/com/zgx/iot/entity/MsModelTrajectory.java new file mode 100644 index 0000000..304aa82 --- /dev/null +++ b/src/main/java/com/zgx/iot/entity/MsModelTrajectory.java @@ -0,0 +1,55 @@ +package com.zgx.iot.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import lombok.Data; + +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +/** + * @Description: 模型历史轨迹 + * @Author: jeecg-boot + * @Date: 2021-07-09 + * @Version: V1.0 + */ + +@Data + +public class MsModelTrajectory implements Serializable { + private static final long serialVersionUID = 1L; + + /**主键*/ + private String id; + /**创建人*/ + private String createBy; + /**创建日期*/ + private Date createTime; + /**更新人*/ + private String updateBy; + /**更新日期*/ + private Date updateTime; + /**所属部门*/ + private String sysOrgCode; + /**模型位置表id*/ + private String modelPositionId; + /**经度*/ + private java.math.BigDecimal lon; + /**纬度*/ + private java.math.BigDecimal lat; + /**高度*/ + private java.math.BigDecimal height; + /**偏航角*/ + private java.math.BigDecimal yaw; + /**俯仰角*/ + private java.math.BigDecimal pitch; + /**翻转角*/ + private java.math.BigDecimal roll; + /**当前位置时间*/ + private Date currPosTime; +} diff --git a/src/main/java/com/zgx/iot/mapper/DtDeviceInfoMapper.java b/src/main/java/com/zgx/iot/mapper/DtDeviceInfoMapper.java new file mode 100644 index 0000000..761d401 --- /dev/null +++ b/src/main/java/com/zgx/iot/mapper/DtDeviceInfoMapper.java @@ -0,0 +1,16 @@ +package com.zgx.iot.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zgx.iot.entity.DtDeviceInfo; +import org.apache.ibatis.annotations.Mapper; + +/** + * @Description: 设备信息表 + * @Author: jeecg-boot + * @Date: 2022-08-12 + * @Version: V1.0 + */ +@Mapper +public interface DtDeviceInfoMapper extends BaseMapper { + +} diff --git a/src/main/java/com/zgx/iot/mapper/MsAlarmSettingsMapper.java b/src/main/java/com/zgx/iot/mapper/MsAlarmSettingsMapper.java new file mode 100644 index 0000000..f7f7fd3 --- /dev/null +++ b/src/main/java/com/zgx/iot/mapper/MsAlarmSettingsMapper.java @@ -0,0 +1,18 @@ +package com.zgx.iot.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zgx.iot.entity.MsAlarmSettings; +import org.apache.ibatis.annotations.Mapper; + +/** + * @Description: 报警参数配置表 + * @Author: jeecg-boot + * @Date: 2022-09-02 + * @Version: V1.0 + */ +@Mapper +public interface MsAlarmSettingsMapper extends BaseMapper { + + +} diff --git a/src/main/java/com/zgx/iot/mapper/MsCameraSettingMapper.java b/src/main/java/com/zgx/iot/mapper/MsCameraSettingMapper.java new file mode 100644 index 0000000..71a0951 --- /dev/null +++ b/src/main/java/com/zgx/iot/mapper/MsCameraSettingMapper.java @@ -0,0 +1,29 @@ +package com.zgx.iot.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zgx.iot.entity.MsCameraSetting; +import io.lettuce.core.dynamic.annotation.Param; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * @Description: 相机设置 + * @Author: jeecg-boot + * @Date: 2021-07-01 + * @Version: V1.0 + */ +@Mapper +public interface MsCameraSettingMapper extends BaseMapper { + public boolean deleteByMainId(@Param("mainId") String mainId); + + public List selectByMainId(@Param("mainId") String mainId); + + public List selectAllSetting(); + + //public List selectSettingVoList(); + + //public void updateLatAndLonBySiteId(MsCameraSite msCameraSite); + +} diff --git a/src/main/java/com/zgx/iot/mapper/MsModelPositionMapper.java b/src/main/java/com/zgx/iot/mapper/MsModelPositionMapper.java new file mode 100644 index 0000000..8a8357a --- /dev/null +++ b/src/main/java/com/zgx/iot/mapper/MsModelPositionMapper.java @@ -0,0 +1,17 @@ +package com.zgx.iot.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zgx.iot.entity.MsModelPosition; +import org.apache.ibatis.annotations.Mapper; + + +/** + * @Description: 模型位置信息 + * @Author: jeecg-boot + * @Date: 2021-07-09 + * @Version: V1.0 + */ +@Mapper +public interface MsModelPositionMapper extends BaseMapper { + +} diff --git a/src/main/java/com/zgx/iot/mapper/MsModelTrajectoryMapper.java b/src/main/java/com/zgx/iot/mapper/MsModelTrajectoryMapper.java new file mode 100644 index 0000000..8aa5725 --- /dev/null +++ b/src/main/java/com/zgx/iot/mapper/MsModelTrajectoryMapper.java @@ -0,0 +1,22 @@ +package com.zgx.iot.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zgx.iot.entity.MsModelTrajectory; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * @Description: 模型历史轨迹 + * @Author: jeecg-boot + * @Date: 2021-07-09 + * @Version: V1.0 + */ +@Mapper +public interface MsModelTrajectoryMapper extends BaseMapper { + + public boolean deleteByMainId(@Param("mainId") String mainId); + + public List selectByMainId(@Param("mainId") String mainId); +} diff --git a/src/main/java/com/zgx/iot/mapper/xml/DtDeviceInfoMapper.xml b/src/main/java/com/zgx/iot/mapper/xml/DtDeviceInfoMapper.xml new file mode 100644 index 0000000..8dc1ee2 --- /dev/null +++ b/src/main/java/com/zgx/iot/mapper/xml/DtDeviceInfoMapper.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/main/java/com/zgx/iot/mapper/xml/MsAlarmSettingsMapper.xml b/src/main/java/com/zgx/iot/mapper/xml/MsAlarmSettingsMapper.xml new file mode 100644 index 0000000..fa04c70 --- /dev/null +++ b/src/main/java/com/zgx/iot/mapper/xml/MsAlarmSettingsMapper.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/main/java/com/zgx/iot/mapper/xml/MsCameraSettingMapper.xml b/src/main/java/com/zgx/iot/mapper/xml/MsCameraSettingMapper.xml new file mode 100644 index 0000000..5e50cbc --- /dev/null +++ b/src/main/java/com/zgx/iot/mapper/xml/MsCameraSettingMapper.xml @@ -0,0 +1,38 @@ + + + + + DELETE + FROM ms_camera_setting + WHERE + site_id = #{mainId} + + + + + + + + diff --git a/src/main/java/com/zgx/iot/mapper/xml/MsModelPositionMapper.xml b/src/main/java/com/zgx/iot/mapper/xml/MsModelPositionMapper.xml new file mode 100644 index 0000000..320427d --- /dev/null +++ b/src/main/java/com/zgx/iot/mapper/xml/MsModelPositionMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/main/java/com/zgx/iot/mapper/xml/MsModelTrajectoryMapper.xml b/src/main/java/com/zgx/iot/mapper/xml/MsModelTrajectoryMapper.xml new file mode 100644 index 0000000..61cc7dc --- /dev/null +++ b/src/main/java/com/zgx/iot/mapper/xml/MsModelTrajectoryMapper.xml @@ -0,0 +1,16 @@ + + + + + + DELETE + FROM ms_model_trajectory + WHERE + model_position_id = #{mainId} + + + diff --git a/src/main/java/com/zgx/iot/message/websocket/WebSocket.java b/src/main/java/com/zgx/iot/message/websocket/WebSocket.java new file mode 100644 index 0000000..4af402b --- /dev/null +++ b/src/main/java/com/zgx/iot/message/websocket/WebSocket.java @@ -0,0 +1,165 @@ +package com.zgx.iot.message.websocket; + +import com.alibaba.fastjson.JSONObject; +import com.zgx.iot.base.BaseMap; +import com.zgx.iot.constant.WebsocketConst; +import com.zgx.iot.redis.client.JeecgRedisClient; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import javax.websocket.OnClose; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * @Author scott + * @Date 2019/11/29 9:41 + * @Description: 此注解相当于设置访问URL + */ +@Component +@Slf4j +@ServerEndpoint("/websocket/{userId}") //此注解相当于设置访问URL +public class WebSocket { + + private Session session; + + private String userId; + + private static final String REDIS_TOPIC_NAME = "socketHandler"; + + @Resource + private JeecgRedisClient jeecgRedisClient; + @Value("${mqtt.orgCode}") + private String myOrgCode; + + /** + * 缓存 webSocket连接到单机服务class中(整体方案支持集群) + */ + private static CopyOnWriteArraySet webSockets = new CopyOnWriteArraySet<>(); + private static Map sessionPool = new HashMap(); + + + @OnOpen + public void onOpen(Session session, @PathParam(value = "userId") String userId) { + try { + this.session = session; + this.userId = userId; + webSockets.add(this); + sessionPool.put(userId, session); + log.info("【websocket消息】有新的连接,总数为:" + webSockets.size()); + } catch (Exception e) { + } + } + + @OnClose + public void onClose() { + try { + webSockets.remove(this); + sessionPool.remove(this.userId); + log.info("【websocket消息】连接断开,总数为:" + webSockets.size()); + } catch (Exception e) { + } + } + + + /** + * 服务端推送消息 + * + * @param userId + * @param message + */ + public void pushMessage(String userId, String message) { + Session session = sessionPool.get(userId); + if (session != null && session.isOpen()) { + try { + log.info("【websocket消息】 单点消息:" + message); + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + /** + * 服务器端推送消息 + */ + public void pushMessage(String message) { + webSockets.forEach(ws -> { + Session curSession = ws.session; + synchronized (curSession) { + if (curSession.isOpen()) { + try { + log.info("【websocket消息】广播消息:" + message); + curSession.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + }); + } + + + @OnMessage + public void onMessage(String message) { + //todo 现在有个定时任务刷,应该去掉 + log.debug("【websocket消息】收到客户端消息:" + message); + JSONObject obj = new JSONObject(); + //业务类型 + obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_CHECK); + //消息内容 + obj.put(WebsocketConst.MSG_TXT, "心跳响应"); + // 当前登录用户所属机构 + obj.put("source", myOrgCode); // 信息来源 + for (WebSocket webSocket : webSockets) { + webSocket.pushMessage(message); + } + } + + /** + * 后台发送消息到redis + * + * @param message + */ + public void sendMessage(String message) { + log.info("【websocket消息】广播消息:" + message); + BaseMap baseMap = new BaseMap(); + baseMap.put("userId", ""); + baseMap.put("message", message); + jeecgRedisClient.sendMessage(REDIS_TOPIC_NAME, baseMap); + } + + /** + * 此为单点消息 + * + * @param userId + * @param message + */ + public void sendMessage(String userId, String message) { + BaseMap baseMap = new BaseMap(); + baseMap.put("userId", userId); + baseMap.put("message", message); + jeecgRedisClient.sendMessage(REDIS_TOPIC_NAME, baseMap); + } + + /** + * 此为单点消息(多人) + * + * @param userIds + * @param message + */ + public void sendMessage(String[] userIds, String message) { + for (String userId : userIds) { + sendMessage(userId, message); + } + } + +} diff --git a/src/main/java/com/zgx/iot/mq/mqtt/MessageCallback.java b/src/main/java/com/zgx/iot/mq/mqtt/MessageCallback.java new file mode 100644 index 0000000..419a8a6 --- /dev/null +++ b/src/main/java/com/zgx/iot/mq/mqtt/MessageCallback.java @@ -0,0 +1,102 @@ +package com.zgx.iot.mq.mqtt; + + +import cn.hutool.extra.spring.SpringUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.zgx.iot.SystemApplication; +import com.zgx.iot.dto.radar.RadarTrackModel; +import com.zgx.iot.dto.radar.TrackingTargetDTO; +import com.zgx.iot.entity.MsCameraSetting; +import com.zgx.iot.mq.mqtt.handle.RadarHandler; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; +import org.eclipse.paho.client.mqttv3.MqttCallbackExtended; +import org.eclipse.paho.client.mqttv3.MqttMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.regex.Pattern; + +@Component +@Slf4j +public class MessageCallback implements MqttCallbackExtended { + +/* + @Resource + RadarHandler radarHandler; + + @Resource + MqttService mqttService;*/ + + // 定义正则表达式模式 + /** + * 雷达跟踪目标信息 + */ + private static final Pattern TRACK_TARGET_PATTERN = Pattern.compile("^/trackTarget$", Pattern.MULTILINE); + + /** + * 球机雷达跟踪目标信息 + */ + private static final Pattern CAMERA_TRACK_TARGET_PATTERN = Pattern.compile("^/cameraToTarget$", Pattern.MULTILINE); + + /** + * 正北俯仰角校正 + */ + private static final Pattern MODIFY_ANGLE = Pattern.compile("^/modifyAngle$", Pattern.MULTILINE); + + @Override + public void connectionLost(Throwable arg0) { + // TODO 连接断开,可以做重连,目前重连失败,还没有设置 + } + + @Override + public void deliveryComplete(IMqttDeliveryToken token) { + // TODO delivery 传送OK + } + + @Override + public void messageArrived(String topic, MqttMessage message) throws Exception { + log.info("【MQTT-客户端】接收消息主题 : " + topic); + log.info("【MQTT-客户端】接收消息Qos : " + message.getQos()); + log.info("【MQTT-客户端】接收消息内容 : " + new String(message.getPayload(),"UTF-8")); + String messageStr = new String(message.getPayload(),"UTF-8"); + + // 通过正则表达式匹配主题 + boolean matches = TRACK_TARGET_PATTERN.matcher(topic).matches(); + boolean matches2= CAMERA_TRACK_TARGET_PATTERN.matcher(topic).matches(); + boolean matches3= MODIFY_ANGLE.matcher(topic).matches(); + + RadarHandler radarHandler = SpringUtil.getBean(RadarHandler.class); + + if (matches){ + TrackingTargetDTO trackingTarget = JSON.parseObject(messageStr, TrackingTargetDTO.class); + radarHandler.targetHandler(trackingTarget); + }else if (matches2){ + JSONObject jsonObject = JSON.parseObject(messageStr); + Float targetLon = jsonObject.getFloatValue("targetLon"); + Float targetLat = jsonObject.getFloatValue("targetLat"); + String cameraJsonString = (String) jsonObject.get("camera"); + MsCameraSetting nearestCamera = JSON.parseObject(cameraJsonString, MsCameraSetting.class); + radarHandler.cameraToTarget(targetLon,targetLat,nearestCamera); + }else if (matches3){ + JSONObject jsonObject = JSON.parseObject(messageStr); + Float targetLon = jsonObject.getFloatValue("longitude"); + Float targetLat = jsonObject.getFloatValue("latitude"); + String ip = (String) jsonObject.get("ip"); + radarHandler.cameraToTarget2(targetLon,targetLat,ip); + } + + } + + @Override + public void connectComplete(boolean arg0, String arg1) { + // 连接成功后,重新订阅自己的主题 + //MqttService.subscribe(); +/* MqttService mqttService1 = SpringUtil.getBean(MqttService.class); + mqttService1.subscribe();*/ + } +} diff --git a/src/main/java/com/zgx/iot/mq/mqtt/MessageHandler.java b/src/main/java/com/zgx/iot/mq/mqtt/MessageHandler.java new file mode 100644 index 0000000..b864489 --- /dev/null +++ b/src/main/java/com/zgx/iot/mq/mqtt/MessageHandler.java @@ -0,0 +1,50 @@ +package com.zgx.iot.mq.mqtt; + +import com.alibaba.fastjson.JSON; +import com.zgx.iot.common.Cache; +import com.zgx.iot.dto.Brower2LpmDto; +import lombok.extern.slf4j.Slf4j; + + +import java.util.Date; +@Slf4j +public class MessageHandler implements Runnable { + + private String message ; + private String topic ; + private byte[] msg ; + + public MessageHandler(byte[] msg , String message,String topic){ + this.message = message ; + this.topic = topic; + this.msg= msg; + log.debug("topic="+topic); + log.debug("message="+message); + } + + @Override + public void run() { + try{ + if(topic.contains("RadarData-3") ){ + // 服务器发送命令 + //Protocal.execServer(null,msg,message); + log.info("接收到雷达类型3数据,准备处理RadarData-3:"+message); + + }else if(topic.contains("RadarData-1")){ + log.info("接收到雷达类型1数据,准备处理RadarData-1:"+message); +/* // 透传命令 - 入库和更新时间 + Brower2LpmDto browerDto = JSON.parseObject(message, Brower2LpmDto.class) ; + Integer messageType = browerDto.getMessageType() ; + String deviceCode = browerDto.getDeviceCode() ; + if( messageType == 1 ){ + Cache.deviceMap.put( deviceCode , new Date().getTime()) ; + }else{ + // 数据发送 + + }*/ + } + }catch(Exception e){ + log.error(e.getMessage()); + } + } +} diff --git a/src/main/java/com/zgx/iot/mq/mqtt/MqttService.java b/src/main/java/com/zgx/iot/mq/mqtt/MqttService.java new file mode 100644 index 0000000..a7ffcc1 --- /dev/null +++ b/src/main/java/com/zgx/iot/mq/mqtt/MqttService.java @@ -0,0 +1,166 @@ +package com.zgx.iot.mq.mqtt; + +import com.alibaba.fastjson.JSON; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.zgx.iot.common.Config; +import com.zgx.iot.config.mqtt.MQTTProps; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttConnectOptions; +import org.eclipse.paho.client.mqttv3.MqttException; +import org.eclipse.paho.client.mqttv3.MqttMessage; +import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; +import org.springframework.stereotype.Service; + +import java.util.concurrent.TimeUnit; + +@Data +@Component +@Slf4j +public class MqttService { + + + public MqttClient _client; + private MQTTProps _mqttProps; + /** + * 构造函数 + * @throws MqttException + */ + public MqttService(MQTTProps mqttProps) throws MqttException { + // MemoryPersistence设置 + _mqttProps=mqttProps; + System.out.println("siteid="+_mqttProps.getClient().getId()); + System.out.println("HOST="+_mqttProps.getService().getAddress()); + log.debug(JSON.toJSONString(mqttProps) ); + _client = new MqttClient(_mqttProps.getService().getAddress(), _mqttProps.getClient().getId(), new MemoryPersistence()); + + } + + /** + * 用来连接服务器 + */ + public void connect() throws MqttException { + MqttConnectOptions options = new MqttConnectOptions(); + options.setCleanSession(false); + options.setUserName(_mqttProps.getService().getUsername()); + options.setPassword(_mqttProps.getService().getPassword().toCharArray()); + // 设置超时时间 + options.setConnectionTimeout(10000); + // 设置会话心跳时间 + options.setKeepAliveInterval(2000); + // 重连 + options.setAutomaticReconnect(true); + //options.setCleanSession(true); + try { + _client.setCallback(new MessageCallback()); + _client.connect(options); + if (_client.isConnected()){ + log.info("mqtt server connect success ;"+_client); + } + log.info("mqtt server connect fail"); + } catch (Exception e) { + log.error("Error:" + e.getLocalizedMessage() +",请检查MQTT 代理是否正常启动!"); + } + } + + /** + * 重新连接 + */ + public void reconnect() { + log.info("正在重新连接 MQTT 服务"); + boolean isSuccess = false; + int retryCount = _mqttProps.getRetry().getCount(); + long retryInterval = _mqttProps.getRetry().getInterval(); + while (!isSuccess && retryCount > 0) { + try { + connect(); + isSuccess = true; + } catch (Exception e) { + log.error("MQTT 服务 连接失败: {}", e.getMessage()); + if (retryCount == 1) { + log.error("MQTT 服务 连接失败,停止重试"); + // 跳过延迟 + return; + } + try { + TimeUnit.SECONDS.sleep(retryInterval); + } catch (InterruptedException ex) { + log.error("MQTT 服务 尝试时连接时异常: {}", ex.getMessage()); + Thread.currentThread().interrupt(); + } + } + retryCount--; + } + } + + public void subscribe(String[] topic1){ + try{ + // 订阅消息 + + int[] Qos = new int[topic1.length]; + for(int i = 0; i< Qos.length ;i++ ){ + Qos[i] =1 ; + } + _client.subscribe(topic1, Qos); + }catch (Exception e) { + log.error(e.getLocalizedMessage()); + } + } + public void subscribe(){ + try{ + // 订阅消息 + String[] topic1 =_mqttProps.getClient().getTopics().split(","); + int[] Qos = new int[topic1.length]; + for(int i = 0; i< Qos.length ;i++ ){ + Qos[i] =1 ; + } + _client.subscribe(topic1, Qos); + }catch (Exception e) { + log.error(e.getLocalizedMessage()); + } + } + /** + * 消息发送 + * @param message byte + * @param topic + */ + public void pubMessage(byte[] message,String topic){ + MqttMessage mess = new MqttMessage(); + mess.setQos(1); + mess.setRetained(false); + mess.setPayload(message); + try { + System.out.println("是否连接:"+_client.isConnected()); + _client.publish(topic, mess); + } catch (Exception e) { + log.error(e.getLocalizedMessage()); + } + } + + /** + * 消息发送 + * @param message + * @param topic + */ + public void pubMessage(String message,String topic){ + MqttMessage mess = new MqttMessage(); + mess.setQos(1); + mess.setRetained(false); + mess.setPayload(message.getBytes()); + try { + _client.publish(topic, mess); + } catch (Exception e) { + log.error(e.getLocalizedMessage()); + } + } + +} + + + diff --git a/src/main/java/com/zgx/iot/mq/mqtt/handle/RadarHandler.java b/src/main/java/com/zgx/iot/mq/mqtt/handle/RadarHandler.java new file mode 100644 index 0000000..3170b71 --- /dev/null +++ b/src/main/java/com/zgx/iot/mq/mqtt/handle/RadarHandler.java @@ -0,0 +1,821 @@ +package com.zgx.iot.mq.mqtt.handle; + +import cn.hutool.extra.spring.SpringUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.zgx.iot.MilitaryMqttApplication; +import com.zgx.iot.constant.enums.CameraType; +import com.zgx.iot.constant.enums.DeviceType; +import com.zgx.iot.dto.radar.RadarTrackModel; +import com.zgx.iot.dto.radar.TrackingTargetDTO; +import com.zgx.iot.entity.DtDeviceInfo; +import com.zgx.iot.entity.MsCameraSetting; +import com.zgx.iot.service.IDtDeviceInfoService; +import com.zgx.iot.service.IMsAlarmSettingsService; +import com.zgx.iot.service.IMsCameraSettingService; +import com.zgx.iot.service.impl.MsCameraSettingServiceImpl; +import com.zgx.iot.utils.GEOUtils; +import com.zgx.iot.utils.RedisUtil; +import com.zgx.iot.utils.hp.HPDataParser; +import com.zgx.iot.utils.hp.HPReqParamEnc; +import com.zgx.iot.utils.hp.ThreadManager; +import com.zgx.iot.utils.socket.TcpClient; +import com.zgx.iot.vo.PTZVo; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.paho.client.mqttv3.MqttException; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.ZSetOperations; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.io.UnsupportedEncodingException; +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static com.fasterxml.jackson.databind.type.LogicalType.Map; + + +@Slf4j +@Component +public class RadarHandler { + + @Autowired + RedisUtil redisUtil; + + @Autowired + IDtDeviceInfoService msDeviceInfoService; + + @Autowired + IMsCameraSettingService msCameraSettingService; + + @Autowired + IMsAlarmSettingsService msAlarmSettingsService; + + //发送轨迹数据主题 + private final String trackDeviceInfoTopic = "/track/deviceInfo"; + + //发送球机数据主题 + private final String trackCameraInfoTopic = "/track/cameraInfo"; + + //发送待删除的轨迹数据主题 + private final String removeTrackIdsTopic = "/remove/trackIds"; + + + + public RadarHandler(IDtDeviceInfoService msDeviceInfoService, IMsCameraSettingService msCameraSettingService, IMsAlarmSettingsService msAlarmSettingsService, RedisUtil redisUtil) { + // 初使化时将已静态化的Service实例化 + this.msDeviceInfoService = msDeviceInfoService; + this.msCameraSettingService = msCameraSettingService; + this.msAlarmSettingsService = msAlarmSettingsService; + this.redisUtil = redisUtil; + } + +/* public void targetHandler(TrackingTargetDTO trackingTarget) throws UnsupportedEncodingException { + //获取目标id 和是否跟踪 + String trackTargetId = String.valueOf(trackingTarget.getTrackId()); + boolean trackStatus = trackingTarget.isTrackStatus(); + + String trackIdKey = "trackIds:" + trackTargetId; + //目标经纬度 + float targetLon = Float.parseFloat(redisUtil.hget(trackIdKey, "targetLon").toString()); + float targetLat = Float.parseFloat(redisUtil.hget(trackIdKey, "targetLat").toString()); + //目标距离(基于雷达) + int distance = Integer.parseInt(redisUtil.hget(trackIdKey, "targetDis").toString()); + + log.info("目标经纬度:" + targetLon + "," + targetLat); + + //查询光电信息 + DtDeviceInfo cameraInfo = null; + LambdaQueryWrapper photoelectricLambdaQueryWrapper = new LambdaQueryWrapper<>(); + photoelectricLambdaQueryWrapper.eq(DtDeviceInfo::getDeviceType, DeviceType.PHOTOELECTRIC.getValue()) //光电类型 + .eq(DtDeviceInfo::getDeviceStatus, 1);//1-启用状态 + List photoelectricDevices = msDeviceInfoService.list(photoelectricLambdaQueryWrapper);//查出所有光电 + if (CollectionUtils.isEmpty(photoelectricDevices)) { + log.info("查询不到光电设备"); + } + cameraInfo = photoelectricDevices.get(0);//todo : 是否需要计算最近的光电 + log.info("光电设备信息:" + cameraInfo); + + //1、若设备关联光电,则进行联动定位 + if (cameraInfo != null) { + //根据IP获取对应光电线程 + TcpClient tcpClient = ThreadManager.getTcpClientMap().get(cameraInfo.getDeviceIp()); + + //停止跟踪 + if (!trackStatus) { + tcpClient.send( + HPDataParser.send( + HPReqParamEnc.ivpTrackingCtrl(String.valueOf(redisUtil.get(tcpClient.getIp())), 0, false, null) + ) + ); + return; + } + + double cameraAzimuth = cameraInfo.getInitAzimuth() + Double.parseDouble(redisUtil.hget("PTZStatus", "pan").toString()); + //计算目标基于光电的方位角 + double targetAzimuth = GEOUtils.getAzimuth(cameraInfo.getDeviceLon(), + cameraInfo.getDeviceLat(), + targetLon, + targetLat + ); + + //计算光电水平所需方位角 + double differAzimuth = targetAzimuth - cameraAzimuth; + + //计算方位角 + double horAngle = Double.parseDouble(redisUtil.hget("PTZStatus", "pan").toString()) + differAzimuth; + horAngle = horAngle >= 0 ? horAngle : (360 + horAngle); + + //计算俯仰角(上27000-36000中间0-9000下) + double verAngle = Math.toDegrees(Math.asin((double) cameraInfo.getDeviceHeight() / distance)); + verAngle = verAngle + cameraInfo.getInitPitch(); + + + //停止跟踪 + tcpClient.send( + HPDataParser.send( + HPReqParamEnc.ivpTrackingCtrl(String.valueOf(redisUtil.get(tcpClient.getIp())), 0, false, null) + ) + ); + + //转动光电到指定位置 + //当光电已经处于跟踪状态时,以下操作不会生效 + //根据目标位置进行定位(角度实际上送值 : 100倍整数值) + tcpClient.send( + HPDataParser.send( + HPReqParamEnc.ptzControl(String.valueOf(redisUtil.get(tcpClient.getIp())), + 0, 51, null, + null, null, 45, + (int) (horAngle * 100), (int) (verAngle * 100), null) + ) + ); + + + //目标高度 平均高度 在ms_alarm_settings表中设置 船的平均高度 高度越高视场角越大 + double h = Double.parseDouble(redisUtil.hget("alarm_settings", "targetHeight").toString()); + + //计算目标距离光点的距离 + double d = GEOUtils.GetDistance(targetLon, targetLat, cameraInfo.getDeviceLon(), cameraInfo.getDeviceLat()); + + //计算视场角,100为分辨率/像素 + double fov = Math.toDegrees(Math.atan(h / d)) * 2 * 100; + log.info("目标平均高度:" + h + " 目标距离光电:" + d); + log.info("水平方位角:" + horAngle + " 俯仰角:" + verAngle + " 视场角:" + fov); + + tcpClient.send( + HPDataParser.send( + HPReqParamEnc.ptzControl(String.valueOf(redisUtil.get(tcpClient.getIp())), + 0, 42, null, + null, null, null, + null, null, (int) (fov * 100)) + ) + ); + + //球机联动 + log.info("联动控制球机:"); + LambdaQueryWrapper cameraSettingLambdaQueryWrapper = new LambdaQueryWrapper<>(); + cameraSettingLambdaQueryWrapper.eq(MsCameraSetting::getType, 1)//1-球机类型 + .eq(MsCameraSetting::getStatus, 0);//0-启用状态 + List cameraSettings = msCameraSettingService.list(cameraSettingLambdaQueryWrapper); + if (CollectionUtils.isEmpty(cameraSettings)) { + log.info("没有可联动的球机"); + } + + MsCameraSetting msCameraSetting = getNearestCamera(cameraSettings, (double) targetLon, (double) targetLat); + //将光电信息封装成rtspUrl返回前端 + String rtspUrl = getRtspUrl(cameraInfo.getDeviceIp(), cameraInfo.getUsername(), cameraInfo.getPassword(), 3);//光电 + //String rtspUrlTest = "rtsp://admin:hk123456@192.168.1.71:554/";//光电 + //String rtspUrl=getRtspUrl(msCameraSetting.getIp(), msCameraSetting.getUser(),msCameraSetting.getPassword(),msCameraSetting.getFactory());//球机 + //相机数据发送mqtt给前端展示 + JSONObject jsonObject1 = new JSONObject(); + jsonObject1.put("longitude", cameraInfo.getDeviceLon()); + jsonObject1.put("latitude", cameraInfo.getDeviceLat()); + jsonObject1.put("deviceName", cameraInfo.getDeviceName()); + jsonObject1.put("deviceStatus", cameraInfo.getDeviceStatus()); + jsonObject1.put("deviceType", cameraInfo.getDeviceType()); + jsonObject1.put("rtspUrl", rtspUrl); + //jsonObject1.put("rtspUrl", msCameraSetting.getPreRtsp()); + //jsonObject1.put("rtspUrl", msCameraSetting.getAnalysisRtsp()); + MilitaryMqttApplication.pubMessage(jsonObject1.toJSONString(), trackDeviceInfoTopic); + log.info("发送rtsp地址给前端----------" + "消息:" + jsonObject1.toJSONString() + " 主题:" + trackDeviceInfoTopic); + + //控制球机照射目标 + cameraToTarget(targetLon,targetLat,msCameraSetting); + + log.info("跟踪球机的主要参数信息:"); + log.info("1.IP: " + msCameraSetting.getIp()); + log.info("2.用户名: " + msCameraSetting.getUser()); + log.info("3.密码: " + msCameraSetting.getPassword()); + log.info("4.最大俯仰角: " + msCameraSetting.getMaxElevation()); + log.info("5.初始方位角: " + msCameraSetting.getZeroAzimuth()); + log.info("6.品牌: " + (msCameraSetting.getFactory() == 1 ? "海康" : "宇视")); + + //将需要跟踪的目标进行保存 并且保存跟踪该目标的球机IP + redisUtil.hset("trackingTargetId", trackTargetId, msCameraSetting.getIp()); + log.info("正在跟踪的trackId:" + trackTargetId + "跟踪的球机" + msCameraSetting.getIp()); + } + }*/ + +/* public void targetHandler(TrackingTargetDTO trackingTarget) throws UnsupportedEncodingException { + //获取目标id 和是否跟踪 + String trackTargetId = String.valueOf(trackingTarget.getTrackId()); + boolean trackStatus = trackingTarget.isTrackStatus(); + + String trackIdKey = "trackIds:" + trackTargetId; + //目标经纬度 + float targetLon = Float.parseFloat(redisUtil.hget(trackIdKey, "targetLon").toString()); + float targetLat = Float.parseFloat(redisUtil.hget(trackIdKey, "targetLat").toString()); + //目标距离(基于雷达) + int distance = Integer.parseInt(redisUtil.hget(trackIdKey, "targetDis").toString()); + + log.info("目标经纬度:" + targetLon + "," + targetLat); + + //查询光电信息 + MsCameraSetting cameraInfo = null; + LambdaQueryWrapper photoelectricLambdaQueryWrapper = new LambdaQueryWrapper<>(); + photoelectricLambdaQueryWrapper.eq(MsCameraSetting::getType, 3) //3-光电类型 + .eq(MsCameraSetting::getStatus, 1);//1-启用状态 + List photoelectricDevices = msCameraSettingService.list(photoelectricLambdaQueryWrapper);//查出所有光电 + if (CollectionUtils.isEmpty(photoelectricDevices)) { + log.info("查询不到光电设备"); + } + cameraInfo = photoelectricDevices.get(0);//todo : 是否需要计算最近的光电 + log.info("光电设备信息:" + cameraInfo); + + //1、若设备关联光电,则进行联动定位 + if (cameraInfo != null) { + //根据IP获取对应光电线程 + TcpClient tcpClient = ThreadManager.getTcpClientMap().get(cameraInfo.getIp()); + + //停止跟踪 + if (!trackStatus) { + tcpClient.send( + HPDataParser.send( + HPReqParamEnc.ivpTrackingCtrl(String.valueOf(redisUtil.get(tcpClient.getIp())), 0, false, null) + ) + ); + return; + } + + double cameraAzimuth = cameraInfo.getZeroAzimuth() + Double.parseDouble(redisUtil.hget("PTZStatus", "pan").toString()); + //计算目标基于光电的方位角 + double targetAzimuth = GEOUtils.getAzimuth(cameraInfo.getLongitude().doubleValue(), + cameraInfo.getLatitude().doubleValue(), + targetLon, + targetLat + ); + + //计算光电水平所需方位角 + double differAzimuth = targetAzimuth - cameraAzimuth; + + //计算方位角 + double horAngle = Double.parseDouble(redisUtil.hget("PTZStatus", "pan").toString()) + differAzimuth; + horAngle = horAngle >= 0 ? horAngle : (360 + horAngle); + + //计算俯仰角(上27000-36000中间0-9000下) + //double verAngle = Math.toDegrees(Math.asin((double) cameraInfo.getHeight() / distance)); + double verAngle = Math.toDegrees(Math.asin((cameraInfo.getHeight().doubleValue() / distance))); + verAngle = verAngle + cameraInfo.getFixedAngle(); + + log.info("【停止跟踪】"); + //停止跟踪 + tcpClient.send( + HPDataParser.send( + HPReqParamEnc.ivpTrackingCtrl(String.valueOf(redisUtil.get(tcpClient.getIp())), 0, false, null) + ) + ); + + //转动光电到指定位置 + //当光电已经处于跟踪状态时,以下操作不会生效 + //根据目标位置进行定位(角度实际上送值 : 100倍整数值) + log.info("【转动光电到指定位置】"); + tcpClient.send( + HPDataParser.send( + HPReqParamEnc.ptzControl(String.valueOf(redisUtil.get(tcpClient.getIp())), + 0, 51, null, + null, null, 45, + (int) (horAngle * 100), (int) (verAngle * 100), null) + ) + ); + + //目标高度 平均高度 在ms_alarm_settings表中设置 船的平均高度 高度越高视场角越大 + double h = Double.parseDouble(redisUtil.hget("alarm_settings", "targetHeight").toString()); + + //计算目标距离光点的距离 + double d = GEOUtils.GetDistance(targetLon, targetLat, cameraInfo.getLongitude().doubleValue(), cameraInfo.getLatitude().doubleValue()); + + //计算视场角,100为分辨率/像素 + double fov = Math.toDegrees(Math.atan(h / d)) * 2 * 100; + log.info("目标平均高度:" + h + " 目标距离光电:" + d); + log.info("水平方位角:" + horAngle + " 俯仰角:" + verAngle + " 视场角:" + fov); + + log.info("【调整光电视场角】"); + tcpClient.send( + HPDataParser.send( + HPReqParamEnc.ptzControl(String.valueOf(redisUtil.get(tcpClient.getIp())), + 0, 42, null, + null, null, null, + null, null, (int) (fov * 100)) + ) + ); + + //球机联动 + log.info("联动控制球机:"); + LambdaQueryWrapper cameraSettingLambdaQueryWrapper = new LambdaQueryWrapper<>(); + cameraSettingLambdaQueryWrapper.eq(MsCameraSetting::getType, 1)//1-球机类型 + .eq(MsCameraSetting::getStatus, 1);//1-启用状态 + List cameraSettings = msCameraSettingService.list(cameraSettingLambdaQueryWrapper); + if (CollectionUtils.isEmpty(cameraSettings)) { + log.info("没有可联动的球机"); + } + log.info("case4 : 遍历相机列表 寻找最近的点的球机去跟踪"); + + // 计算距离最近的球机 + MsCameraSetting msCameraSetting = null;//最近球机信息 + double nearestDistance = 0;//最近距离 + double heightDiff = 0;//最近球机的高度差 + for (MsCameraSetting cameraSetting : cameraSettings) { + // 判断该球机是否满足照射范围 不满足的话还可以找第二近的球机 如果放到后面才判断高度差 就无法找第二近的去跟踪了 + BigDecimal cameraHeight = cameraSetting.getHeight();//球机高度 + BigDecimal labelHeight = new BigDecimal(h);//目标高度 + double tempHeightDiff = cameraHeight.subtract(labelHeight).doubleValue();//球机与目标高度差 + if (tempHeightDiff < 0) { + log.info("case4 :" + "ip=" + cameraSetting.getIp() + " tempHeightDiff < 0 超过球机照射范围"); + } else { + double temp = GEOUtils.GetDistance(cameraSetting.getLongitude().doubleValue(), cameraSetting.getLatitude().doubleValue(), targetLon, targetLat); + log.info("当前的球机" + cameraSetting.getIp() + "与目标的距离:" + temp); + // 第一次 先将第一个球机的距离作为最近距离 和 最近球机信息 + if (msCameraSetting == null) { + msCameraSetting = cameraSetting; + nearestDistance = temp; + continue; + } + // 第二次以后 如果距离更近则更新最近距离 以及 最近球机信息 + if (nearestDistance > temp) { + msCameraSetting = cameraSetting; + nearestDistance = temp; + heightDiff = tempHeightDiff; + } + } + } + + //没有找到跟踪的球机 + if (msCameraSetting == null) { + log.info("没有可跟踪的球机"); + } + + //判断两点的距离是否超过有效距离,超过则丢掉 + if (nearestDistance > Integer.parseInt(redisUtil.hget("alarm_settings", "inOutEffectDistance").toString())) { + log.info("case4 :" + "目标超过跟踪的最大距离" + redisUtil.hget("alarm_settings", "inOutEffectDistance").toString()); + } + + log.info("case4 :" + " 相机IP:" + msCameraSetting.getIp() + " 最短距离nearestDistance:" + nearestDistance); + log.info("case4 :" + "距离最近的相机:" + JSON.toJSONString(msCameraSetting)); + + //控制球机照射目标 + log.info("case4【尝试使用ptzControllerByLatLonAndDistance】将球机转到目标位置"); + + //将光电信息封装成rtspUrl返回前端 + String rtspUrl = getRtspUrl(cameraInfo.getIp(), cameraInfo.getUser(), cameraInfo.getPassword(), 3);//光电 + //String rtspUrlTest = "rtsp://admin:hk123456@192.168.1.71:554/";//光电 + //String rtspUrl=getRtspUrl(msCameraSetting.getIp(), msCameraSetting.getPort(), msCameraSetting.getUser(),msCameraSetting.getPassword(),msCameraSetting.getFactory());//球机 + //轨迹数据发送mqtt给前端使用 + JSONObject jsonObject1 = new JSONObject(); + jsonObject1.put("longitude", cameraInfo.getLongitude()); + jsonObject1.put("latitude", cameraInfo.getLatitude()); + jsonObject1.put("deviceName", cameraInfo.getCameraName()); + jsonObject1.put("deviceStatus", cameraInfo.getStatus()); + jsonObject1.put("deviceType", cameraInfo.getType()); + jsonObject1.put("rtspUrl", cameraInfo.getPreRtsp()); + jsonObject1.put("videoUrl", cameraInfo.getVideoUrl()); + + //jsonObject1.put("rtspUrl", rtspUrlTest); + MilitaryMqttApplication.pubMessage(jsonObject1.toJSONString(), trackDeviceInfoTopic); + log.info("发送rtsp地址给前端----------" + "消息:" + jsonObject1.toJSONString() + " 主题:" + trackDeviceInfoTopic); + + msCameraSettingService.ptzControllerByLatLon(msCameraSetting.getIp(), + msCameraSetting.getUser(), + msCameraSetting.getPassword(), + msCameraSetting.getMaxElevation(), + msCameraSetting.getZeroAzimuth(), + heightDiff, + msCameraSetting.getZoomFactor(), + msCameraSetting.getLongitude().doubleValue(), + msCameraSetting.getLatitude().doubleValue(), + targetLon, + targetLat, + msCameraSetting.getFactory());//factory用于区分品牌类型 1:海康 2:宇视 + + + log.info("跟踪球机的主要参数信息:"); + log.info("1.IP: " + msCameraSetting.getIp()); + log.info("2.用户名: " + msCameraSetting.getUser()); + log.info("3.密码: " + msCameraSetting.getPassword()); + log.info("4.最大俯仰角: " + msCameraSetting.getMaxElevation()); + log.info("5.初始方位角: " + msCameraSetting.getZeroAzimuth()); + log.info("6.品牌: " + (msCameraSetting.getFactory() == 1 ? "海康" : "宇视")); + + //将需要跟踪的目标进行保存 并且保存跟踪该目标的球机IP 跟踪有效时间设置为1h + redisUtil.hset("trackingTargetId", trackTargetId, msCameraSetting.getIp(), 60 * 5); + log.info("正在跟踪的trackId:" + trackTargetId + "跟踪的球机" + msCameraSetting.getIp()); + + } + }*/ + +/* public void targetHandler(TrackingTargetDTO trackingTarget) throws UnsupportedEncodingException{ + angleTest(); + }*/ + + public void targetHandler(TrackingTargetDTO trackingTarget) throws UnsupportedEncodingException { + //获取目标id 和是否跟踪 + String trackTargetId = String.valueOf(trackingTarget.getTrackId()); + boolean trackStatus = trackingTarget.isTrackStatus(); + + String trackIdKey = "trackIds:" + trackTargetId; + //目标经纬度 + float targetLon = Float.parseFloat(redisUtil.hget(trackIdKey, "targetLon").toString()); + float targetLat = Float.parseFloat(redisUtil.hget(trackIdKey, "targetLat").toString()); + + + + //目标距离(基于雷达) + int distance = Integer.parseInt(redisUtil.hget(trackIdKey, "targetDis").toString()); + + log.info("目标经纬度:" + targetLon + "," + targetLat); + + //查询光电信息 + MsCameraSetting cameraInfo = null; + LambdaQueryWrapper photoelectricLambdaQueryWrapper = new LambdaQueryWrapper<>(); + photoelectricLambdaQueryWrapper.eq(MsCameraSetting::getType, CameraType.GUANGDIAN.getValue()); //3-光电类型 + // .eq(MsCameraSetting::getStatus, 0);//0-启用状态 + List photoelectricDevices = msCameraSettingService.list(photoelectricLambdaQueryWrapper);//查出所有光电 + if (CollectionUtils.isEmpty(photoelectricDevices)) { + log.info("查询不到光电设备"); + } + + //获取目标最近的光电 + cameraInfo = getNearestCamera(photoelectricDevices, (double) targetLon, (double) targetLat); + //cameraInfo = photoelectricDevices.get(0);//todo : 是否需要计算最近的光电 + log.info("光电设备信息:" + cameraInfo); + + //1、若设备关联光电,则进行联动定位 + if (cameraInfo != null) { + //根据IP获取对应光电线程 + TcpClient tcpClient = ThreadManager.getTcpClientMap().get(cameraInfo.getIp()); + + //停止跟踪 + if (!trackStatus) { + tcpClient.send( + HPDataParser.send( + HPReqParamEnc.ivpTrackingCtrl(String.valueOf(redisUtil.get(tcpClient.getIp())), 0, false, null) + ) + ); + return; + } + + double cameraAzimuth = cameraInfo.getZeroAzimuth() + Double.parseDouble(redisUtil.hget("PTZStatus", "pan").toString()); + //计算目标基于光电的方位角 + double targetAzimuth = GEOUtils.getAzimuth(cameraInfo.getLongitude().doubleValue(), + cameraInfo.getLatitude().doubleValue(), + targetLon, + targetLat + ); + + //计算光电水平所需方位角 + double differAzimuth = targetAzimuth - cameraAzimuth; + + //计算方位角 + double horAngle = Double.parseDouble(redisUtil.hget("PTZStatus", "pan").toString()) + differAzimuth; + horAngle = horAngle >= 0 ? horAngle : (360 + horAngle); + + //计算俯仰角(上27000-36000中间0-9000下) + //double verAngle = Math.toDegrees(Math.asin((double) cameraInfo.getHeight() / distance)); + double verAngle = Math.toDegrees(Math.asin((cameraInfo.getHeight().doubleValue() / distance))); + verAngle = verAngle + cameraInfo.getFixedAngle(); + + log.info("【停止跟踪】"); + //停止跟踪 + tcpClient.send( + HPDataParser.send( + HPReqParamEnc.ivpTrackingCtrl(String.valueOf(redisUtil.get(tcpClient.getIp())), 0, false, null) + ) + ); + + //转动光电到指定位置 + //当光电已经处于跟踪状态时,以下操作不会生效 + //根据目标位置进行定位(角度实际上送值 : 100倍整数值) + log.info("【转动光电到指定位置】"); + tcpClient.send( + HPDataParser.send( + HPReqParamEnc.ptzControl(String.valueOf(redisUtil.get(tcpClient.getIp())), + 0, 51, null, + null, null, 45, + (int) (horAngle * 100), (int) (verAngle * 100), null) + ) + ); + + //目标高度 平均高度 在ms_alarm_settings表中设置 船的平均高度 高度越高视场角越大 + double h = Double.parseDouble(redisUtil.hget("alarm_settings", "targetHeight").toString()); + + //计算目标距离光点的距离 + double d = GEOUtils.GetDistance(targetLon, targetLat, cameraInfo.getLongitude().doubleValue(), cameraInfo.getLatitude().doubleValue()); + + //计算视场角,100为分辨率/像素 + double fov = Math.toDegrees(Math.atan(h / d)) * 2 * 100; + log.info("目标平均高度:" + h + " 目标距离光电:" + d); + log.info("水平方位角:" + horAngle + " 俯仰角:" + verAngle + " 视场角:" + fov); + + log.info("【调整光电视场角】"); + tcpClient.send( + HPDataParser.send( + HPReqParamEnc.ptzControl(String.valueOf(redisUtil.get(tcpClient.getIp())), + 0, 42, null, + null, null, null, + null, null, (int) (fov * 100)) + ) + ); + + //将光电信息返回前端 + JSONObject jsonObject1 = new JSONObject(); + jsonObject1.put("longitude", cameraInfo.getLongitude()); + jsonObject1.put("latitude", cameraInfo.getLatitude()); + jsonObject1.put("deviceName", cameraInfo.getCameraName()); + jsonObject1.put("deviceStatus", cameraInfo.getStatus()); + jsonObject1.put("deviceType", cameraInfo.getType()); + jsonObject1.put("deviceId", cameraInfo.getId()); + jsonObject1.put("rtspUrl", cameraInfo.getPreRtsp()); + jsonObject1.put("rtcUrl", cameraInfo.getWebcastAddress()); + + MilitaryMqttApplication.pubMessage(jsonObject1.toJSONString(), trackDeviceInfoTopic); + + log.info("发送rtsp地址给前端----------" + "消息:" + jsonObject1.toJSONString() + " 主题:" + trackDeviceInfoTopic); + + //球机联动 + log.info("联动控制球机:"); + LambdaQueryWrapper cameraSettingLambdaQueryWrapper = new LambdaQueryWrapper<>(); + cameraSettingLambdaQueryWrapper.eq(MsCameraSetting::getType, CameraType.QIUJI.getValue())//1-球机类型 + .eq(MsCameraSetting::getStatus, 0);//启用状态 + List cameraSettings = msCameraSettingService.list(cameraSettingLambdaQueryWrapper); + if (CollectionUtils.isEmpty(cameraSettings)) { + log.info("没有可联动的球机"); + return; + } + + // 计算距离最近的球机 + MsCameraSetting msCameraSetting = null;//最近球机信息 + double nearestDistance = 0;//最近距离 + double heightDiff = 0;//最近球机的高度差 + for (MsCameraSetting cameraSetting : cameraSettings) { + // 判断该球机是否满足照射范围 不满足的话还可以找第二近的球机 如果放到后面才判断高度差 就无法找第二近的去跟踪了 + BigDecimal cameraHeight = cameraSetting.getHeight();//球机高度 + BigDecimal labelHeight = new BigDecimal(h);//目标高度 + double tempHeightDiff = cameraHeight.subtract(labelHeight).doubleValue();//球机与目标高度差 + if (tempHeightDiff < 0) { + log.info("case4 :" + "ip=" + cameraSetting.getIp() + " tempHeightDiff < 0 超过球机照射范围"); + } else { + double temp = GEOUtils.GetDistance(cameraSetting.getLongitude().doubleValue(), cameraSetting.getLatitude().doubleValue(), targetLon, targetLat); + log.info("当前的球机" + cameraSetting.getIp() + "与目标的距离:" + temp); + // 第一次 先将第一个球机的距离作为最近距离 和 最近球机信息 + if (msCameraSetting == null) { + msCameraSetting = cameraSetting; + nearestDistance = temp; + continue; + } + // 第二次以后 如果距离更近则更新最近距离 以及 最近球机信息 + if (nearestDistance > temp) { + msCameraSetting = cameraSetting; + nearestDistance = temp; + heightDiff = tempHeightDiff; + } + } + } + + //没有找到跟踪的球机 + if (msCameraSetting == null) { + log.info("没有可跟踪的球机"); + return; + } + + //判断两点的距离是否超过有效距离,超过则丢掉 + if (nearestDistance > Integer.parseInt(redisUtil.hget("alarm_settings", "inOutEffectDistance").toString())) { + log.info("case4 :" + "目标超过跟踪的最大距离" + redisUtil.hget("alarm_settings", "inOutEffectDistance").toString()); + } + + //将球机信息返回前端 + JSONObject jsonObject2 = new JSONObject(); + jsonObject2.put("deviceId", msCameraSetting.getId()); + jsonObject2.put("rtspUrl", msCameraSetting.getPreRtsp()); + jsonObject2.put("rtcUrl", msCameraSetting.getWebcastAddress()); + + MilitaryMqttApplication.pubMessage(jsonObject2.toJSONString(), trackCameraInfoTopic); + + log.info("发送联动跟踪的球机rtsp地址给前端----------" + "消息:" + jsonObject2.toJSONString() + " 主题:/track/cameraInfo"); + + msCameraSettingService.ptzControllerByLatLon(msCameraSetting.getIp(), + msCameraSetting.getUser(), + msCameraSetting.getPassword(), + msCameraSetting.getMaxElevation(), + msCameraSetting.getZeroAzimuth(), + heightDiff, + msCameraSetting.getZoomFactor(), + msCameraSetting.getLongitude().doubleValue(), + msCameraSetting.getLatitude().doubleValue(), + targetLon, + targetLat, + msCameraSetting.getFactory());//factory用于区分品牌类型 1:海康 3:宇视 + + + //将需要跟踪的目标进行保存 并且保存跟踪该目标的球机IP 跟踪有效时间设置为1h + //redisUtil.hset("trackingTargetId", trackTargetId, msCameraSetting.getIp(), 60 * 5); + redisUtil.set("trackingCameraIp",msCameraSetting.getIp(),60 * 5); + redisUtil.set("trackingId",trackTargetId,60 * 5); + log.info("正在跟踪的trackId:" + trackTargetId + "跟踪的球机" + msCameraSetting.getIp()); + } + } + + /** + * 相机转动到指定位置 + * @param targetLon + * @param targetLat + * @param msCameraSetting + */ + public void cameraToTarget(Float targetLon,Float targetLat,MsCameraSetting msCameraSetting){ + BigDecimal cameraHeight = msCameraSetting.getHeight();//球机高度 + double h = Double.parseDouble(redisUtil.hget("alarm_settings", "targetHeight").toString()); + BigDecimal labelHeight = new BigDecimal(h);//目标高度 + double heightDiff = cameraHeight.subtract(labelHeight).doubleValue();//球机与目标高度差 + + msCameraSettingService.ptzControllerByLatLon(msCameraSetting.getIp(), + msCameraSetting.getUser(), + msCameraSetting.getPassword(), + msCameraSetting.getMaxElevation(), + msCameraSetting.getZeroAzimuth(), + heightDiff, + msCameraSetting.getZoomFactor(), + msCameraSetting.getLongitude().doubleValue(), + msCameraSetting.getLatitude().doubleValue(), + targetLon, + targetLat, + msCameraSetting.getFactory());//factory用于区分品牌类型 1:海康 2:宇视 + } + + /** + * 相机转动到指定位置 + * @param targetLon + * @param targetLat + * @param ip + */ + public void cameraToTarget2(Float targetLon,Float targetLat,String ip){ + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper().eq(MsCameraSetting::getIp, ip); + MsCameraSetting msCameraSetting = msCameraSettingService.getOne(queryWrapper); + BigDecimal cameraHeight = msCameraSetting.getHeight();//球机高度 + double h = Double.parseDouble(redisUtil.hget("alarm_settings", "targetHeight").toString()); + BigDecimal labelHeight = new BigDecimal(h);//目标高度 + double heightDiff = cameraHeight.subtract(labelHeight).doubleValue();//球机与目标高度差 + + msCameraSettingService.ptzControllerByLatLon(msCameraSetting.getIp(), + msCameraSetting.getUser(), + msCameraSetting.getPassword(), + msCameraSetting.getMaxElevation(), + msCameraSetting.getZeroAzimuth(), + heightDiff, + msCameraSetting.getZoomFactor(), + msCameraSetting.getLongitude().doubleValue(), + msCameraSetting.getLatitude().doubleValue(), + targetLon, + targetLat, + msCameraSetting.getFactory());//factory用于区分品牌类型 1:海康 2:宇视 + } + + + /** + * 生成rtsp + * @param ip + * @param user + * @param password + * @param factory 品牌产商 + * @return + */ + private static String getRtspUrl(String ip, String user, String password, Integer factory) { + String rtspUrl = null; + switch (factory) { + //海康 + case 1: { + rtspUrl = String.format("rtsp://%s:%s@%s/Streaming/Channels/1?transportmode=unicast&profile=Profile_1", user, password, ip); + break; + } + //宇视 + case 2: { + rtspUrl = String.format("rtsp://%s:%s@%s/media/video1", user, password, ip); + break; + } + //光电 + case 3: { + rtspUrl = String.format("rtsp://%s:%s@%s/h264/ch1/main/av_stream", user, password, ip); + break; + } + } + return rtspUrl; + } + + /** + * 定时清除多次未更新的轨迹数据 任务 + */ + @Scheduled(cron="0 0/1 * * * ?") + public void scheduledCleanTask(){ + System.out.println("定时清除旧轨迹任务执行..."); + long now = System.currentTimeMillis() - 60000;//定义多久以前的数据是需要清除的轨迹 + System.out.println(now); + //得到待删除轨迹的Id + Set> removeIds = redisUtil.zRangeByScoreWithScores("updatedIds", 0, now); + List removeIdList = removeIds.stream().map(key -> Integer.valueOf(key.getValue().toString())).collect(Collectors.toList()); + + JSONObject jsonObject = new JSONObject(); + jsonObject.put("removeIds",removeIdList); + MilitaryMqttApplication.pubMessage(jsonObject.toJSONString(),removeTrackIdsTopic); + + //删除过期的轨迹Id + redisUtil.zRemoveRangeByScore("updatedIds",0,now); + } + + public MsCameraSetting getNearestCamera(List cameraSettings,Double targetLon,Double targetLat) { + // 计算距离最近的球机 + MsCameraSetting msCameraSetting = null;//最近球机信息 + double nearestDistance = 0;//最近距离 + for (MsCameraSetting cameraSetting : cameraSettings) { + double temp = GEOUtils.GetDistance(cameraSetting.getLongitude().doubleValue(), cameraSetting.getLatitude().doubleValue(), targetLon, targetLat); + // 第一次 先将第一个球机的距离作为最近距离 和 最近球机信息 + if (msCameraSetting == null) { + msCameraSetting = cameraSetting; + nearestDistance = temp; + continue; + } + // 第二次以后 如果距离更近则更新最近距离 以及 最近球机信息 + if (nearestDistance > temp) { + msCameraSetting = cameraSetting; + nearestDistance = temp; + } + + } + return msCameraSetting; + } + + public static void main(String[] args) { + RedisUtil redisUtil1 = SpringUtil.getBean(RedisUtil.class); + Object o = redisUtil1.get("allIds:"); + } + + + //用于本地测试 模拟光电 + public void test(){ + MsCameraSettingServiceImpl mscameraSettingService = new MsCameraSettingServiceImpl(); + mscameraSettingService.ptzControl( + "192.168.1.71", + "admin", + "hk123456", + new PTZVo(0.5,-0.5,0.5) + ); + } + + //todo : 正北调整(2024-4-10) + public void angleTest() { + LambdaQueryWrapper msCameraSettingLambdaQueryWrapper = new LambdaQueryWrapper<>(); + msCameraSettingLambdaQueryWrapper.eq(MsCameraSetting::getType, CameraType.QIUJI.getValue())//1-球机类型 + .eq(MsCameraSetting::getStatus, 0);//启用状态 + List msCameraSettingList = msCameraSettingService.list(msCameraSettingLambdaQueryWrapper); + +/* double targetLon=113.45166600000000; + double targetLat=22.12888800000000; */ + double targetLon=113.43722200000000; + double targetLat=22.15888800000000; + for (MsCameraSetting msCameraSetting : msCameraSettingList) { + try { + msCameraSettingService.ptzControllerByLatLon(msCameraSetting.getIp(), + msCameraSetting.getUser(), + msCameraSetting.getPassword(), + msCameraSetting.getMaxElevation(), + msCameraSetting.getZeroAzimuth(), + msCameraSetting.getHeight().doubleValue(), + msCameraSetting.getZoomFactor(), + msCameraSetting.getLongitude().doubleValue(), + msCameraSetting.getLatitude().doubleValue(), + targetLon, + targetLat, + msCameraSetting.getFactory());//factory用于区分品牌类型 1:海康 2:宇视 + }catch (Exception e){ + System.out.println("异常相机:"+msCameraSetting.getIp()); + log.info("异常相机"); + log.info(msCameraSetting.getIp()); + } + } + + } +} diff --git a/src/main/java/com/zgx/iot/mq/mqtt/model/radar/TargetMessage.java b/src/main/java/com/zgx/iot/mq/mqtt/model/radar/TargetMessage.java new file mode 100644 index 0000000..c9827e2 --- /dev/null +++ b/src/main/java/com/zgx/iot/mq/mqtt/model/radar/TargetMessage.java @@ -0,0 +1,20 @@ +package com.zgx.iot.mq.mqtt.model.radar; + +import com.zgx.iot.dto.radar.TrackingTargetDTO; +import lombok.Data; + +/** + * @author AaGMixW + */ +@Data +public class TargetMessage { + /** + * mqtt 消息体 + */ + private TrackingTargetDTO messageBody; + /** + * mqtt 主题 + */ + private String topic; + +} diff --git a/src/main/java/com/zgx/iot/netty/NettyServiceManage.java b/src/main/java/com/zgx/iot/netty/NettyServiceManage.java new file mode 100644 index 0000000..174856b --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/NettyServiceManage.java @@ -0,0 +1,203 @@ +package com.zgx.iot.netty; + + +import com.zgx.iot.dto.site.Result; +import com.zgx.iot.netty.exception.NettyServiceControllerException; +import com.zgx.iot.netty.model.NettyDeviceInfo; +import com.zgx.iot.netty.model.NettyService; +import com.zgx.iot.netty.pipeline.TcpPipelineFactory; +import com.zgx.iot.netty.pipeline.UdpPipelineFactory; +import com.zgx.iot.netty.socket.base.NettyBaseServiceImpl; +import com.zgx.iot.netty.socket.base.NettyBaseSocket; +import com.zgx.iot.netty.socket.tcp.TcpClientByNetty; +import com.zgx.iot.netty.socket.tcp.TcpServiceByNetty; +import com.zgx.iot.netty.socket.udp.UdpClientByNetty; +import com.zgx.iot.netty.socket.udp.UdpServiceByNetty; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.stereotype.Component; + +import java.net.InetSocketAddress; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author AaGMixW + */ +@Component +public class NettyServiceManage { + private static final Logger logger = LogManager.getLogger(NettyServiceManage.class); + + + private final ConcurrentHashMap> nettyServiceMap = new ConcurrentHashMap<>(16); + // 启动服务 + + /** + * 启动 tcp 服务端 + * + * @param deviceInfo 设备信息 {@link NettyDeviceInfo} + * @param pipelineFactoryType tcp 管道, 对传输的数据进行相关处理 + * @return udp service + */ + public NettyService startupTcpService( + NettyDeviceInfo deviceInfo, + Class> pipelineFactoryType + ) { + String key = deviceInfo.getId(); + // 判断 已经启动服务中是否已经存在 + if (nettyServiceMap.containsKey(key)) { + // 存在 + // 直接返回获取到的服务 + return nettyServiceMap.get(key); + } + // 不存在 + TcpServiceByNetty service = new TcpServiceByNetty(deviceInfo, pipelineFactoryType); + try { + service.startup(); + // 存储到 nettyServiceMap 里 + NettyService nettyService = new NettyService<>(service); + nettyServiceMap.put(key, nettyService); + return nettyService; + } catch (InstantiationException | IllegalAccessException e) { + logger.error("启动 {} 服务失败,{}", deviceInfo.getDeviceName(), e.getMessage()); + service.shutdown(); + return null; + } + } + + /** + * 启动 tcp 客户端 + * + * @param deviceInfo 设备信息 {@link NettyDeviceInfo} + * @param pipelineFactoryType tcp 管道, 对传输的数据进行相关处理 + * @return udp service + */ + public TcpClientByNetty startupTcpClient( + NettyDeviceInfo deviceInfo, + Class> pipelineFactoryType + ) { + String key = deviceInfo.getId(); + // 判断 已经启动服务中是否已经存在 + if (nettyServiceMap.containsKey(key)) { + // 存在 + // 直接返回获取到的服务 + return (TcpClientByNetty) nettyServiceMap.get(key).getService(); + } + // 不存在 + TcpClientByNetty client = new TcpClientByNetty(deviceInfo, pipelineFactoryType); + try { + client.startup(); + // 存储到 nettyServiceMap 里 + NettyService nettyService = new NettyService<>(client); + nettyServiceMap.put(key, nettyService); + return client; + } catch (InstantiationException | IllegalAccessException e) { + client.shutdown(); + logger.error("启动 {} 服务失败,{}", deviceInfo.getDeviceName(), e.getMessage()); + return null; + } + } + + + /** + * 启动 udp 客户端 + * + * @param deviceInfo 设备信息 {@link NettyDeviceInfo} + * @param pipelineFactoryType udp 管道, 对传输的数据进行相关处理 + * @return udp client + */ + public synchronized NettyService startupUdpClient(NettyDeviceInfo deviceInfo, Class> pipelineFactoryType) { + String key = deviceInfo.getId(); + // 判断 已经启动服务中是否已经存在 + if (nettyServiceMap.containsKey(key)) { + // 存在 + // 直接返回获取到的服务 + return nettyServiceMap.get(key); + } + // 不存在 + UdpClientByNetty client = new UdpClientByNetty(deviceInfo, pipelineFactoryType); + try { + // 启动服务 + client.startup(); + // 存储到 nettyServiceMap 里 + NettyService nettyService = new NettyService<>(client); + nettyServiceMap.put(key, nettyService); + return nettyService; + } catch (InstantiationException | IllegalAccessException e) { + logger.error("启动 {} 服务失败,{}", deviceInfo.getDeviceName(), e.getMessage()); + client.shutdown(); + return null; + } + } + + /** + * 启动 udp 服务端 + * + * @param deviceInfo 设备信息 {@link NettyDeviceInfo} + * @param pipelineFactoryType udp 管道, 对传输的数据进行相关处理 + * @return udp service + */ + public NettyService startupUdpService( + NettyDeviceInfo deviceInfo, + Class> pipelineFactoryType + ) { + String key = deviceInfo.getId(); + // 判断 已经启动服务中是否已经存在 + if (nettyServiceMap.containsKey(key)) { + // 存在 + // 直接返回获取到的服务 + return nettyServiceMap.get(key); + } + // 不存在 + UdpServiceByNetty service = new UdpServiceByNetty(pipelineFactoryType, deviceInfo); + try { + // 启动服务 + service.startup(); + // 存储到 nettyServiceMap 里 + NettyService nettyService = new NettyService<>(service); + nettyServiceMap.put(key, nettyService); + return nettyService; + } catch (InstantiationException | IllegalAccessException e) { + service.shutdown(); + logger.error("启动 {} 服务失败,{}", deviceInfo.getDeviceName(), e.getMessage()); + throw new NettyServiceControllerException("启动服务失败:" + e.getMessage()); + } + } + + /** + * 停止服务 + * + * @param deviceInfo 设备信息 {@link NettyDeviceInfo} + * @return 是否成功 + */ + public boolean stopService(NettyDeviceInfo deviceInfo) { + String key = deviceInfo.getId(); + if (nettyServiceMap.containsKey(key)) { + NettyService nettyService = nettyServiceMap.get(key); + nettyService.shutdown(); + } + // 服务不存在 失败 + return false; + } + + + public boolean stopChannel(String key, InetSocketAddress address) { + if (nettyServiceMap.containsKey(key)) { + NettyService nettyService = nettyServiceMap.get(key); + return nettyService.stopChannel(address); + } else { + logger.error("找不到 netty service!"); + return false; + } + } + + + public Result> getNettyService(NettyDeviceInfo deviceInfo) { + String key = deviceInfo.getId(); + if (nettyServiceMap.containsKey(key)) { + return Result.OK(nettyServiceMap.get(key)); + } else { + logger.error("找不到 netty service!"); + return Result.ERROR("找不到 netty service!"); + } + } +} diff --git a/src/main/java/com/zgx/iot/netty/config/AppServiceConfig.java b/src/main/java/com/zgx/iot/netty/config/AppServiceConfig.java new file mode 100644 index 0000000..c27fe96 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/config/AppServiceConfig.java @@ -0,0 +1,42 @@ +package com.zgx.iot.netty.config; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +/** + * @author AaGMixW + */ +@Component +@Getter +@Setter +public class AppServiceConfig { + + /** + * 服务重试设置 + */ + @Value("${netty.retry.interval}") + private Integer retryInterval; + @Value("${netty.retry.count}") + private Integer retryCount; + /** + * 请求设备重试设置 + */ + @Value("${netty.device.retry.interval}") + private Integer deviceRetryInterval; + @Value("${netty.device.retry.count}") + private Integer deviceRetryCount; + + /** + * 心跳包 间隔 + */ + @Value("${netty.heartbeat.interval}") + private Integer heartbeatInterval; + /** + * 心跳包 重试次数(次) + */ + @Value("${netty.heartbeat.count}") + private Integer heartbeatCount; + +} diff --git a/src/main/java/com/zgx/iot/netty/constant/AttributeMapConstant.java b/src/main/java/com/zgx/iot/netty/constant/AttributeMapConstant.java new file mode 100644 index 0000000..965d4e2 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/constant/AttributeMapConstant.java @@ -0,0 +1,20 @@ +package com.zgx.iot.netty.constant; + +import com.zgx.iot.netty.socket.base.NettyBaseSocket; +import io.netty.util.AttributeKey; + +import java.net.InetSocketAddress; + +/** + * @author AaGMixW + */ +public class AttributeMapConstant { + private AttributeMapConstant() { + throw new IllegalStateException("Constant class"); + } + + public static final AttributeKey NETTY_CHANNEL_SOCKET_KEY = + AttributeKey.valueOf("netty.channel.socket"); + public static final AttributeKey NETTY_SERVICE_REMOTE_ADDR_KEY = + AttributeKey.valueOf("netty.service.remote.addr"); +} diff --git a/src/main/java/com/zgx/iot/netty/constant/CustomLogLevel.java b/src/main/java/com/zgx/iot/netty/constant/CustomLogLevel.java new file mode 100644 index 0000000..fedcbff --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/constant/CustomLogLevel.java @@ -0,0 +1,21 @@ +package com.zgx.iot.netty.constant; + +import org.apache.logging.log4j.Level; + +/** + * @author AaGMixW + */ +public class CustomLogLevel { + + private CustomLogLevel() { + throw new IllegalStateException("Constant class"); + } + + //定义业务操作日志级别(级别越高,数字越小) + // off 0, fatal 100, error 200, warn 300, info 400, debug 500 + + /** + * 设备数据 日志 + */ + public static final Level DEVICE_DATA_LEVEL = Level.forName("DEVICE_DATA", 350); +} diff --git a/src/main/java/com/zgx/iot/netty/constant/DeviceRelations.java b/src/main/java/com/zgx/iot/netty/constant/DeviceRelations.java new file mode 100644 index 0000000..03bf251 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/constant/DeviceRelations.java @@ -0,0 +1,150 @@ +package com.zgx.iot.netty.constant; + +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; + +import java.util.*; + +/** + * @author AaGMixW + */ +public enum DeviceRelations { + ; + + private static final Map ALARM_TYPE = new HashMap<>(); + + static { + ALARM_TYPE.put(2, "断线报警"); + ALARM_TYPE.put(3, "触网报警"); + ALARM_TYPE.put(4, "短路报警"); + ALARM_TYPE.put(5, "接近预警"); + ALARM_TYPE.put(6, "入侵报警"); + ALARM_TYPE.put(7, "感应报警"); + ALARM_TYPE.put(8, "离线报警"); + ALARM_TYPE.put(9, "离线报警恢复"); + } + + private static final BiMap DEVICE_TYPE = HashBiMap.create(); + + static { + DEVICE_TYPE.put(1, "radar"); + DEVICE_TYPE.put(2, "camera"); + DEVICE_TYPE.put(3, "fence"); + DEVICE_TYPE.put(4, "photovoltaics"); + DEVICE_TYPE.put(98, "relay"); + DEVICE_TYPE.put(99, "other"); + } + + private static final BiMap DEVICE_TYPE_CHINESE = HashBiMap.create(); + + static { + DEVICE_TYPE_CHINESE.put(1, "雷达"); + DEVICE_TYPE_CHINESE.put(2, "光电"); + DEVICE_TYPE_CHINESE.put(3, "电子围网"); + DEVICE_TYPE_CHINESE.put(4, "光伏"); + DEVICE_TYPE_CHINESE.put(98, "网络继电器"); + DEVICE_TYPE_CHINESE.put(99, "其他"); + } + + private static final BiMap DEVICE_COMP = HashBiMap.create(); + + static { + DEVICE_COMP.put(1, "lei_yuan"); + DEVICE_COMP.put(2, "sine"); + DEVICE_COMP.put(3, "zhi_an"); + DEVICE_COMP.put(4, "he_pu"); + DEVICE_COMP.put(5, "shang_shang"); + DEVICE_COMP.put(98, "corx"); + DEVICE_COMP.put(99, "other"); + } + + private static final BiMap DEVICE_COMP_CHINESE = HashBiMap.create(); + + static { + DEVICE_COMP_CHINESE.put(1, "雷远"); + DEVICE_COMP_CHINESE.put(2, "赛英"); + DEVICE_COMP_CHINESE.put(3, "智安"); + DEVICE_COMP_CHINESE.put(4, "和普"); + DEVICE_COMP_CHINESE.put(5, "尚上"); + DEVICE_COMP_CHINESE.put(98, "科星"); + DEVICE_COMP_CHINESE.put(99, "其他"); + } + + private static final Map> DEVICE_SERVICE_TYPE = new HashMap<>(16); + + static { + // 雷远雷达 + DEVICE_SERVICE_TYPE.put(Objects.hash(1, 1), SocketType.UDP.SERVICE.getNameAsList()); + // 赛英雷达 + DEVICE_SERVICE_TYPE.put(Objects.hash(1, 2), SocketType.UDP.SERVICE.getNameAsList()); + // 电子围网 + DEVICE_SERVICE_TYPE.put(Objects.hash(3, 3), SocketType.TCP.CLIENT.getNameAsList()); + // 科兴网络继电器 + DEVICE_SERVICE_TYPE.put(Objects.hash(98, 98), SocketType.TCP.CLIENT.getNameAsList()); + // 振动电缆 + DEVICE_SERVICE_TYPE.put(Objects.hash(6, 3), SocketType.TCP.CLIENT.getNameAsList()); + DEVICE_SERVICE_TYPE.put(-1, new ArrayList<>()); + } + + public static String getDeviceTypeName(int deviceType) { + return DEVICE_TYPE.get(deviceType); + } + + public static String getDeviceCompName(int deviceComp) { + return DEVICE_COMP.get(deviceComp); + } + + public static String getDeviceTypeNameChinese(int deviceType) { + return DEVICE_TYPE_CHINESE.get(deviceType); + } + + public static String getDeviceCompNameChinese(int deviceComp) { + return DEVICE_COMP_CHINESE.get(deviceComp); + } + + public static int getDeviceTypeValue(String deviceType) { + return DEVICE_TYPE.inverse().get(deviceType); + } + + public static int getDeviceCompValue(String deviceComp) { + return DEVICE_COMP.inverse().get(deviceComp); + } + + public static int getDeviceTypeValueChinese(String deviceType) { + return DEVICE_TYPE_CHINESE.inverse().get(deviceType); + } + + public static int getDeviceCompValueChinese(String deviceComp) { + return DEVICE_COMP_CHINESE.inverse().get(deviceComp); + } + + + public static String getDeviceMark(int deviceType, int deviceComp, String delimiter) { + return DEVICE_TYPE.get(deviceType) + delimiter + DEVICE_COMP.get(deviceComp); + } + + public static String getDeviceNameChinese(int deviceType, int deviceComp) { + return DEVICE_COMP_CHINESE.get(deviceComp) + DEVICE_TYPE_CHINESE.get(deviceType); + } + + public static String getAlarmType(int alarmType) { + return ALARM_TYPE.get(alarmType); + } + + public static String getServiceId(int deviceType, int deviceComp, String delimiter) { + int hash = Objects.hash(deviceType, deviceComp); + List list = DEVICE_SERVICE_TYPE.getOrDefault(hash, new ArrayList<>()); + // 没有值时 + if (list.isEmpty()) { + return ""; + } + StringBuilder value = new StringBuilder(); + for (int i = 0; i < list.size(); i++) { + if (i != 0) { + value.append(delimiter); + } + value.append(list.get(i)); + } + return value.toString(); + } +} diff --git a/src/main/java/com/zgx/iot/netty/constant/HandlerDataType.java b/src/main/java/com/zgx/iot/netty/constant/HandlerDataType.java new file mode 100644 index 0000000..0491b0d --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/constant/HandlerDataType.java @@ -0,0 +1,36 @@ +package com.zgx.iot.netty.constant; + + +/** + * @author AaGMixW + */ + +public enum HandlerDataType { + ; + + public enum PerimeterDataType { + /** + * 报警数据 + */ + ALARM(0), + /** + * 操作结果数据 + */ + OPERATE_RESULT(1), + /** + * 设防/旁路 数据 + */ + DEFENCE_AREA_DATA(2), + ; + private final int value; + + PerimeterDataType(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + } + +} diff --git a/src/main/java/com/zgx/iot/netty/constant/SocketType.java b/src/main/java/com/zgx/iot/netty/constant/SocketType.java new file mode 100644 index 0000000..45bd1ea --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/constant/SocketType.java @@ -0,0 +1,74 @@ +package com.zgx.iot.netty.constant; + +import java.util.ArrayList; +import java.util.List; + +public enum SocketType { + ; + + public enum TCP { + /** + * 服务端 + */ + SERVICE("service", 1), + /** + * 客户端 + */ + CLIENT("client", 0); + private final String name; + private final Integer value; + private static final String PREFIX = "TCP"; + + TCP(String name, Integer value) { + this.name = name; + this.value = value; + } + + public String getName(String delimiter) { + return PREFIX + delimiter + name; + } + public Integer getValue() { + return value; + } + + public List getNameAsList() { + List list = new ArrayList<>(16); + list.add(PREFIX); + list.add(name); + return list; + } + } + + public enum UDP { + /** + * 服务端 + */ + SERVICE("service", 1), + /** + * 客户端 + */ + CLIENT("client", 0); + private final String name; + private final Integer value; + private static final String PREFIX = "UDP"; + + UDP(String name, Integer value) { + this.name = name; + this.value = value; + } + + public String getName(String delimiter) { + return PREFIX + delimiter + name; + } + public Integer getValue() { + return value; + } + + public List getNameAsList() { + List list = new ArrayList<>(16); + list.add(PREFIX); + list.add(name); + return list; + } + } +} diff --git a/src/main/java/com/zgx/iot/netty/constant/device/MicrowaveDetectorConstant.java b/src/main/java/com/zgx/iot/netty/constant/device/MicrowaveDetectorConstant.java new file mode 100644 index 0000000..b5aa3d8 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/constant/device/MicrowaveDetectorConstant.java @@ -0,0 +1,239 @@ +package com.zgx.iot.netty.constant.device; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author AaGMixW + */ +public enum MicrowaveDetectorConstant { + ; + + public enum deviceType { + /** + * 探测器 + */ + DETECTOR(1, "探测器"), + + /** + * 探测主机 + */ + DETECTOR_HOST(2, "探测主机"), + + /** + * 串口设备 + */ + SERIAL_DEVICE(3, "串口设备"), + + /** + * 预留 + */ + RESERVED(4, "预留"); + + + private int value; + private String name; + + deviceType(int value, String name) { + this.value = value; + this.name = name; + } + + public int getValue() { + return value; + } + + public String getName() { + return name; + } + + private static final Map map = new HashMap<>(); + + static { + for (MicrowaveDetectorConstant.deviceType deviceType : deviceType.values()) { + map.put(deviceType.getValue(), deviceType); + } + } + + public static deviceType valueOf(int value) { + return map.get(value); + } + } + + public enum faultType { + /** + * 无特定类型 + */ + NONE(0, "无特定类型"), + /** + * 离线丢失 + */ + OFFLINE(1, "离线丢失"), + /** + * 硬件故障 + */ + HARDWARE_FAULT(2, "硬件故障"), + /** + * 传感器噪声高 + */ + SENSOR_NOISE_HIGH(3, "传感器噪声高"), + /** + * 内部软件故障 + */ + INTERNAL_SOFTWARE_FAULT(4, "内部软件故障"), + /** + * 防拆报警 + */ + ANTI_DEMOLITION_ALARM(5, "防拆报警"), + /** + * 状态不明 + */ + STATUS_UNKNOWN(6, "状态不明"), + /** + * 错误消息或通信异常 + */ + ERROR_MESSAGE_OR_COMMUNICATION_EXCEPTION(7, "错误消息或通信异常"), + /** + * 剪线断线 + */ + CUT_LINE_DISCONNECT(8, "剪线断线"), + /** + * 其他预留 + */ + OTHER_RESERVED(9, "其他预留"); + + private int value; + private String name; + + faultType(int value, String name) { + this.value = value; + this.name = name; + } + + public int getValue() { + return value; + } + + public String getName() { + return name; + } + + private static final Map map = new HashMap<>(); + + static { + for (faultType faultType : faultType.values()) { + map.put(faultType.getValue(), faultType); + } + } + + public static faultType valueOf(int value) { + return map.get(value); + } + } + + public enum alarmType { + /** + * MEMS入侵报警 + */ + MEMS_INVASION_ALARM(1, "MEMS入侵报警"), + /** + * 预留; + */ + RESERVED(2, "预留"); + + private int value; + private String name; + + alarmType(int value, String name) { + this.value = value; + this.name = name; + } + + public int getValue() { + return value; + } + + public String getName() { + return name; + } + + private static final Map map = new HashMap<>(); + + static { + for (alarmType alarmType : alarmType.values()) { + map.put(alarmType.getValue(), alarmType); + } + } + + public static alarmType valueOf(int value) { + return map.get(value); + } + } + + public enum alarmReason { + // pc:0-其它(无特定原因);1-敲击;2-摇晃;3-攀爬(振动);4-倾斜;5~7:预留;8-剪切线缆; + //9-MEMS雷达报警 + /** + * 其它(无特定原因) + */ + OTHER(0, "其它(无特定原因)"), + /** + * 敲击 + */ + KNOCK(1, "敲击"), + /** + * 摇晃 + */ + SHAKE(2, "摇晃"), + /** + * 攀爬(振动) + */ + CLIMB(3, "攀爬(振动)"), + /** + * 倾斜 + */ + TILT(4, "倾斜"), + /** + * 预留 + */ + RESERVED(5, "预留"), + RESERVED_2(6, "预留"), + RESERVED_3(7, "预留"), + /** + * 剪切线缆 + */ + CUT_WIRE(8, "剪切线缆"), + /** + * MEMS雷达报警 + */ + MEMS_RADAR_ALARM(9, "MEMS雷达报警"); + + private int value; + private String name; + + alarmReason(int value, String name) { + this.value = value; + this.name = name; + } + + public int getValue() { + return value; + } + + public String getName() { + return name; + } + + private static final Map map = new HashMap<>(); + + static { + for (alarmReason alarmReason : alarmReason.values()) { + map.put(alarmReason.getValue(), alarmReason); + } + } + + public static alarmReason valueOf(int value) { + return map.get(value); + } + } +} diff --git a/src/main/java/com/zgx/iot/netty/exception/CompletableFutureException.java b/src/main/java/com/zgx/iot/netty/exception/CompletableFutureException.java new file mode 100644 index 0000000..49ced7b --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/exception/CompletableFutureException.java @@ -0,0 +1,12 @@ +package com.zgx.iot.netty.exception; + +/** + * @author AaGMixW + */ +public class CompletableFutureException extends RuntimeException { + private static final long serialVersionUID = 6898660892382632176L; + + public CompletableFutureException(String s) { + super(s); + } +} diff --git a/src/main/java/com/zgx/iot/netty/exception/DeviceInfoException.java b/src/main/java/com/zgx/iot/netty/exception/DeviceInfoException.java new file mode 100644 index 0000000..04355b7 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/exception/DeviceInfoException.java @@ -0,0 +1,12 @@ +package com.zgx.iot.netty.exception; + +/** + * @author AaGMixW + */ +public class DeviceInfoException extends RuntimeException { + private static final long serialVersionUID = 5004118888832463932L; + + public DeviceInfoException(String s) { + super(s); + } +} diff --git a/src/main/java/com/zgx/iot/netty/exception/NettyServiceControllerException.java b/src/main/java/com/zgx/iot/netty/exception/NettyServiceControllerException.java new file mode 100644 index 0000000..857b516 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/exception/NettyServiceControllerException.java @@ -0,0 +1,12 @@ +package com.zgx.iot.netty.exception; + +/** + * @author AaGMixW + */ +public class NettyServiceControllerException extends RuntimeException { + private static final long serialVersionUID = -8621535055348629709L; + + public NettyServiceControllerException(String s) { + super(s); + } +} diff --git a/src/main/java/com/zgx/iot/netty/handler/ConnectHandler.java b/src/main/java/com/zgx/iot/netty/handler/ConnectHandler.java new file mode 100644 index 0000000..1df29ca --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/handler/ConnectHandler.java @@ -0,0 +1,57 @@ +package com.zgx.iot.netty.handler; + +import com.zgx.iot.netty.constant.AttributeMapConstant; +import com.zgx.iot.netty.socket.base.NettyBaseClientImpl; +import com.zgx.iot.netty.socket.base.NettyBaseServiceImpl; +import com.zgx.iot.netty.socket.base.NettyBaseSocket; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.util.NetUtil; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.net.InetSocketAddress; + +/** + * @author AaGMixW + */ +public class ConnectHandler extends ChannelInboundHandlerAdapter { + private static final Logger logger = LogManager.getLogger(ConnectHandler.class); + + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + NettyBaseSocket socket = ctx.channel().attr(AttributeMapConstant.NETTY_CHANNEL_SOCKET_KEY).get(); + InetSocketAddress address = new InetSocketAddress(0); + String msg = ""; + if (socket instanceof NettyBaseClientImpl) { + address = (InetSocketAddress) ctx.channel().remoteAddress(); + msg = "建立连接"; + } else if (socket instanceof NettyBaseServiceImpl) { + address = (InetSocketAddress) ctx.channel().localAddress(); + msg = "监听端口"; + } + String name = socket.getDeviceInfo().getDeviceName() + "(" + NetUtil.toSocketAddressString(address) + ")"; + logger.info("{} {}", name, msg); + super.channelActive(ctx); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) { + NettyBaseSocket socket = ctx.channel().attr(AttributeMapConstant.NETTY_CHANNEL_SOCKET_KEY).get(); + InetSocketAddress address = new InetSocketAddress(0); + String msg = ""; + if (socket instanceof NettyBaseClientImpl) { + // client + address = (InetSocketAddress) ctx.channel().remoteAddress(); + msg = "断开连接"; + } else if (socket instanceof NettyBaseServiceImpl) { + // service + address = (InetSocketAddress) ctx.channel().localAddress(); + msg = "停止监听"; + } + String name = socket.getDeviceInfo().getDeviceName() + "(" + NetUtil.toSocketAddressString(address) + ")"; + logger.info("{} {}", name, msg); + } + +} diff --git a/src/main/java/com/zgx/iot/netty/handler/ExceptionHandler.java b/src/main/java/com/zgx/iot/netty/handler/ExceptionHandler.java new file mode 100644 index 0000000..1ce01fe --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/handler/ExceptionHandler.java @@ -0,0 +1,168 @@ +package com.zgx.iot.netty.handler; + +import com.zgx.iot.netty.config.AppServiceConfig; +import com.zgx.iot.netty.constant.AttributeMapConstant; +import com.zgx.iot.netty.socket.base.NettyBaseClientImpl; +import com.zgx.iot.netty.socket.base.NettyBaseServiceImpl; +import com.zgx.iot.netty.socket.base.NettyBaseSocket; +import com.zgx.iot.utils.NettyConfigUtil; +import io.netty.channel.*; +import io.netty.channel.ChannelHandler.Sharable; +import io.netty.util.NetUtil; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.PortUnreachableException; +import java.net.SocketAddress; +import java.nio.channels.ClosedChannelException; +import java.util.concurrent.TimeUnit; + +/** + * @author AaGMixW + */ +@Sharable +public class ExceptionHandler extends ChannelDuplexHandler { + + private static final Logger logger = LogManager.getLogger(ExceptionHandler.class); + + private final AppServiceConfig appServiceConfig = NettyConfigUtil.getAppServiceConfig(); + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { + // Uncaught exceptions from inbound handlers will propagate up to this handler + InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress(); + String addressStr = NetUtil.toSocketAddressString(address); + try { + if (cause instanceof IOException) { + if (cause instanceof PortUnreachableException) { + logger.error("无法发送到指定端口 {} => {}", addressStr, + cause.getMessage() != null ? cause.getMessage() : cause.getClass().getSimpleName()); + logger.error("关闭该连接"); + ctx.channel().close().sync(); + } else { + logger.error("连接 {} 异常=> {}", addressStr, + cause.getMessage() != null ? cause.getMessage() : cause.getClass().getSimpleName()); + } + } + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + /** + * client + * + * @param ctx the {@link ChannelHandlerContext} for which the connect operation is made + * @param remoteAddress the {@link SocketAddress} to which it should connect + * @param localAddress the {@link SocketAddress} which is used as source on connect + * @param promise the {@link ChannelPromise} to notify once the operation completes + */ + @Override + public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) { + NettyBaseSocket socket = ctx.channel().attr(AttributeMapConstant.NETTY_CHANNEL_SOCKET_KEY).get(); + ctx.connect(remoteAddress, localAddress, promise.addListener((ChannelFutureListener) future -> { + if (!future.isSuccess()) { + // Handle connect exception here... + Throwable failureCause = future.cause(); + InetSocketAddress address = (InetSocketAddress) remoteAddress; + String addressStr = NetUtil.toSocketAddressString(address); + String name = socket.getDeviceInfo().getDeviceName() + "(" + addressStr + ")"; + if (failureCause instanceof ClosedChannelException) { + logger.info("{} 连接已关闭", name); + return; + } + logger.error("{} 建立连接异常: {}", name, failureCause.getMessage()); + // reconnect + doConnect(ctx, address); + } + })); + } + + /** + * service + * + * @param ctx the {@link ChannelHandlerContext} for which the bind operation is made + * @param localAddress the {@link SocketAddress} to which it should bound + * @param promise the {@link ChannelPromise} to notify once the operation completes + * @throws Exception 异常 + */ + @Override + public void bind(ChannelHandlerContext ctx, SocketAddress localAddress, ChannelPromise promise) throws Exception { + NettyBaseSocket socket = ctx.channel().attr(AttributeMapConstant.NETTY_CHANNEL_SOCKET_KEY).get(); + ctx.bind(localAddress, promise.addListener((ChannelFutureListener) future -> { + if (!future.isSuccess()) { + // Handle connect exception here... + Throwable failureCause = future.cause(); + InetSocketAddress address = (InetSocketAddress) localAddress; + String addressStr = NetUtil.toSocketAddressString(address); + String name = socket.getDeviceInfo().getDeviceName() + "(" + addressStr + ")"; + logger.error("{} 监听端口异常: {}", name, failureCause.getMessage()); + // reconnect + doConnect(ctx, address); + } + })); + } + + @Override + public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) { + ctx.write(msg, promise.addListener((ChannelFutureListener) future -> { + if (!future.isSuccess()) { + // Handle write exception here... + Throwable failureCause = future.cause(); + logger.info("write exception: {}", failureCause.getMessage()); + } + })); + } + + /** + * Calls {@link ChannelHandlerContext#fireChannelUnregistered()} to forward + * to the next {@link ChannelInboundHandler} in the {@link ChannelPipeline}. + *

+ * Subclasses may override this method to change behavior. + * + * @param ctx ctx + */ + @Override + public void channelUnregistered(ChannelHandlerContext ctx) throws Exception { + NettyBaseSocket socket = ctx.channel().attr(AttributeMapConstant.NETTY_CHANNEL_SOCKET_KEY).get(); + //客户端使用过程中断线重连 + if (socket instanceof NettyBaseClientImpl) { + InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress(); + if (address != null) { + doConnect(ctx, address); + } else { + logger.error("重连时获取连接地址出错,取消连接"); + ctx.channel().close().sync(); + } + } + super.channelUnregistered(ctx); + } + + + /** + * 重试方法 + * + * @param ctx ctx + * @param address 连接地址 + */ + private void doConnect(ChannelHandlerContext ctx, InetSocketAddress address) { + NettyBaseSocket socket = ctx.channel().attr(AttributeMapConstant.NETTY_CHANNEL_SOCKET_KEY).get(); + String addressStr = NetUtil.toSocketAddressString(address); + String name = socket.getDeviceInfo().getDeviceName() + "(" + addressStr + ")"; + long nextRetryDelay = appServiceConfig.getRetryInterval(); + String msg = ""; + if (socket instanceof NettyBaseClientImpl) { + // client + msg = "连接"; + } else if (socket instanceof NettyBaseServiceImpl) { + // service + msg = "监听"; + } + logger.info("{} 正在尝试重新{}", name, msg); + ctx.channel().eventLoop().schedule(() -> socket.retry(address), nextRetryDelay, TimeUnit.MILLISECONDS); + } + + // ... override more outbound methods to handle their exceptions as well +} diff --git a/src/main/java/com/zgx/iot/netty/handler/codec/MicrowaveDetectorMessageClientDecoder.java b/src/main/java/com/zgx/iot/netty/handler/codec/MicrowaveDetectorMessageClientDecoder.java new file mode 100644 index 0000000..a0f1167 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/handler/codec/MicrowaveDetectorMessageClientDecoder.java @@ -0,0 +1,87 @@ +package com.zgx.iot.netty.handler.codec; + + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.zgx.iot.netty.constant.AttributeMapConstant; +import com.zgx.iot.netty.model.device.microwave.command.rep.MicrowaveDeviceRep; +import com.zgx.iot.netty.model.device.microwave.command.rep.MicrowaveIORep; +import com.zgx.iot.netty.model.device.microwave.command.rep.MicrowaveOpcRep; +import com.zgx.iot.netty.model.device.microwave.command.rep.MicrowaveQueryRep; +import com.zgx.iot.utils.JacksonUtil; +import com.zgx.iot.utils.NettyDeviceUtil; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.socket.DatagramPacket; +import io.netty.handler.codec.MessageToMessageDecoder; +import io.netty.util.Attribute; +import lombok.extern.slf4j.Slf4j; + +import java.net.InetSocketAddress; +import java.nio.charset.Charset; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +/** + * @author AaGMixW + */ +@Slf4j +public class MicrowaveDetectorMessageClientDecoder extends MessageToMessageDecoder { + private static final String LOCAL_HOST_ADDR = "127.0.0.1"; + + @Override + protected void decode(ChannelHandlerContext ctx, DatagramPacket packet, List list) { + ByteBuf byteBuf = packet.content(); + int readableBytes = byteBuf.readableBytes(); + if (readableBytes <= 0) { + return; + } + Attribute addrAttr = ctx.channel().attr(AttributeMapConstant.NETTY_SERVICE_REMOTE_ADDR_KEY); + InetSocketAddress address = packet.sender(); + addrAttr.set(address); + String dataStr = byteBuf.toString(Charset.forName("GB18030")); + InetSocketAddress localAddress = (InetSocketAddress) ctx.channel().localAddress(); + String deviceName = NettyDeviceUtil.getDeviceNameAndIp(ctx, localAddress, address); + + log.debug("{} 字符数据: {}", deviceName, dataStr); +/* try { + + // 判断数据类型 + String regex = "^\\s*<(\\w+:)?(\\w+)"; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(dataStr); + if (matcher.find()) { + String root = matcher.group(2); + switch (root) { + case "opcRep": + // 防区及探测器操作维护响应 + MicrowaveOpcRep opcRep = JacksonUtil.xml2Obj(dataStr, MicrowaveOpcRep.class); + list.add(opcRep); + break; + case "ioRep": + // IO操作维护响应 + MicrowaveIORep ioRep = JacksonUtil.xml2Obj(dataStr, MicrowaveIORep.class); + list.add(ioRep); + break; + case "deviceRep": + // 设备操作维护响应 + MicrowaveDeviceRep deviceRep = JacksonUtil.xml2Obj(dataStr, MicrowaveDeviceRep.class); + list.add(deviceRep); + break; + case "queryRep": + // 查询响应 + MicrowaveQueryRep queryRep = JacksonUtil.xml2Obj(dataStr, MicrowaveQueryRep.class); + list.add(queryRep); + break; + default: + log.error("{} 服务, 数据 => {}; 未匹配到数据类型, 丢弃数据", deviceName, dataStr); + } + } else { + log.error("{} 服务, 数据 => {}; 未匹配到数据类型, 丢弃数据", deviceName, dataStr); + } + } catch (JsonProcessingException e) { + log.error("{} 服务, 数据 => {}; 转换失败: {}, 丢弃数据", deviceName, dataStr, e.getMessage()); + }*/ + } +} diff --git a/src/main/java/com/zgx/iot/netty/handler/codec/MicrowaveDetectorMessageServiceDecoder.java b/src/main/java/com/zgx/iot/netty/handler/codec/MicrowaveDetectorMessageServiceDecoder.java new file mode 100644 index 0000000..0e116d6 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/handler/codec/MicrowaveDetectorMessageServiceDecoder.java @@ -0,0 +1,81 @@ +package com.zgx.iot.netty.handler.codec; + + +import com.fasterxml.jackson.core.JsonProcessingException; + +import com.zgx.iot.netty.constant.AttributeMapConstant; +import com.zgx.iot.netty.model.device.microwave.MicrowaveDetectorAlarm; +import com.zgx.iot.netty.model.device.microwave.MicrowaveDetectorFault; +import com.zgx.iot.netty.model.device.microwave.MicrowaveDetectorHeartbeat; +import com.zgx.iot.utils.JacksonUtil; +import com.zgx.iot.utils.NettyDeviceUtil; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.socket.DatagramPacket; +import io.netty.handler.codec.MessageToMessageDecoder; +import io.netty.util.Attribute; +import lombok.extern.slf4j.Slf4j; + +import java.net.InetSocketAddress; +import java.nio.charset.Charset; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +/** + * @author AaGMixW + */ +@Slf4j +public class MicrowaveDetectorMessageServiceDecoder extends MessageToMessageDecoder { + private static final String LOCAL_HOST_ADDR = "127.0.0.1"; + + @Override + protected void decode(ChannelHandlerContext ctx, DatagramPacket packet, List list) { +/* ByteBuf byteBuf = packet.content(); + int readableBytes = byteBuf.readableBytes(); + if (readableBytes <= 0) { + return; + } + Attribute addrAttr = ctx.channel().attr(AttributeMapConstant.NETTY_SERVICE_REMOTE_ADDR_KEY); + InetSocketAddress address = packet.sender(); + addrAttr.set(address); + String dataStr = byteBuf.toString(Charset.forName("GB18030")); + InetSocketAddress localAddress = (InetSocketAddress) ctx.channel().localAddress(); + String deviceName = NettyDeviceUtil.getDeviceNameAndIp(ctx, localAddress, address); + + log.debug("{} 字符数据: {}", deviceName, dataStr); + try { + // 判断数据类型 + String regex = "^\\s*<(\\w+:)?(\\w+)"; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(dataStr); + if (matcher.find()) { + String root = matcher.group(2); + switch (root) { + case "heartbeat": + // 心跳数据 + MicrowaveDetectorHeartbeat heartbeat = JacksonUtil.xml2Obj(dataStr, MicrowaveDetectorHeartbeat.class); + list.add(heartbeat); + break; + case "fault": + // 故障数据 + MicrowaveDetectorFault fault = JacksonUtil.xml2Obj(dataStr, MicrowaveDetectorFault.class); + list.add(fault); + break; + case "alarm": + // 报警数据 + MicrowaveDetectorAlarm alarm = JacksonUtil.xml2Obj(dataStr, MicrowaveDetectorAlarm.class); + list.add(alarm); + break; + default: + log.error("{} 服务, 数据 => {}; 未匹配到数据类型, 丢弃数据", deviceName, dataStr); + } + } else { + log.error("{} 服务, 数据 => {}; 未匹配到数据类型, 丢弃数据", deviceName, dataStr); + } + } catch (JsonProcessingException e) { + log.error("{} 服务, 数据 => {}; 转换失败: {}, 丢弃数据", deviceName, dataStr, e.getMessage()); + }*/ + } +} diff --git a/src/main/java/com/zgx/iot/netty/handler/codec/RadarDetectorMessageServiceDecoder.java b/src/main/java/com/zgx/iot/netty/handler/codec/RadarDetectorMessageServiceDecoder.java new file mode 100644 index 0000000..5b30d33 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/handler/codec/RadarDetectorMessageServiceDecoder.java @@ -0,0 +1,105 @@ +package com.zgx.iot.netty.handler.codec; + + +import com.zgx.iot.dto.radar.RadarRESPackageModel; +import com.zgx.iot.netty.NettyServiceManage; +import com.zgx.iot.radar.RadarAcceptSocket; +import com.zgx.iot.utils.radarUtils.ByteIntUtil; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandler; +import io.netty.channel.socket.SocketChannel; +import io.netty.handler.codec.ByteToMessageDecoder; + +import io.netty.handler.codec.FixedLengthFrameDecoder; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; +import io.netty.handler.codec.ReplayingDecoder; +import org.apache.commons.logging.Log; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.io.DataInputStream; +import java.io.InputStream; +import java.util.Arrays; +import java.util.List; + + +public class RadarDetectorMessageServiceDecoder extends ByteToMessageDecoder { + private static final Logger log = LogManager.getLogger(RadarDetectorMessageServiceDecoder.class); + private int radar_data_package_head_len=16; + public static final int PACKAGE_MAX_LENGTH = 4096; + private volatile boolean flag = true; + private volatile byte[] data; + private int len; + private byte[] byte_buffer; + + @Override + protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf,List list) throws Exception { + int size = byteBuf.readableBytes(); + while (flag) { + if (byteBuf.readableBytes() 1024000) { + this.byte_buffer = bytes; + } else { + this.byte_buffer = ByteIntUtil.byteMerger(this.byte_buffer, bytes); + } + final int byte_buffer_len = this.byte_buffer.length; + if (byte_buffer_len < this.radar_data_package_head_len) { + // 数据包头不完整,没有达到16字节长度 + log.debug("\u6570\u636e\u5305\u5934\u4e0d\u5b8c\u6574\uff0c\u6ca1\u6709\u8fbe\u523016\u5b57\u8282\u957f\u5ea6"); + return null; + } + final RadarRESPackageModel radarPackage = new RadarRESPackageModel(this.byte_buffer); + final int mark = radarPackage.getMark(); + final int dataType = radarPackage.getDataType(); + final int dataLength = radarPackage.getDataLength(); + final int dataNum = radarPackage.getDataNum(); + // 包头标识 + log.info("\u5305\u5934\u6807\u8bc6\uff1a " + mark); + // 数据类型 + log.info("\u6570\u636e\u7c7b\u578b\uff1a " + dataType); + // 整包数据的长度 + log.info("\u6574\u5305\u6570\u636e\u7684\u957f\u5ea6\uff1a " + dataLength); + // 数据数量 + log.info("\u6570\u636e\u6570\u91cf\uff1a " + dataNum); + if (!radarPackage.isIntegrated()) { + // 数据包没有发送完整,等待继续接收 + log.info("\u6570\u636e\u5305\u6ca1\u6709\u53d1\u9001\u5b8c\u6574\uff0c\u7b49\u5f85\u7ee7\u7eed\u63a5\u6536\r\n"); + return null; + } + final byte[] radardata = radarPackage.getData(); + //this.handleRadarData(mark, dataType, dataLength, dataNum, radardata); + final byte[] remainbytes = radarPackage.getRemain(); + if (remainbytes != null) { + this.byte_buffer = remainbytes; + } else { + this.byte_buffer = null; + } + return radarPackage; + } +} diff --git a/src/main/java/com/zgx/iot/netty/handler/filter/MicrowaveDetectorMessageClientFilter.java b/src/main/java/com/zgx/iot/netty/handler/filter/MicrowaveDetectorMessageClientFilter.java new file mode 100644 index 0000000..3a2cc5f --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/handler/filter/MicrowaveDetectorMessageClientFilter.java @@ -0,0 +1,53 @@ +package com.zgx.iot.netty.handler.filter; + + +import com.zgx.iot.netty.model.dataMediator.NettyDataMediatorEvent; +import com.zgx.iot.netty.model.device.microwave.command.rep.MicrowaveDeviceRep; +import com.zgx.iot.netty.model.device.microwave.command.rep.MicrowaveIORep; +import com.zgx.iot.netty.model.device.microwave.command.rep.MicrowaveOpcRep; +import com.zgx.iot.netty.model.device.microwave.command.rep.MicrowaveQueryRep; +import com.zgx.iot.utils.SpringContextUtils; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + + +/** + * @author AaGMixW + */ +@Slf4j +@Component +public class MicrowaveDetectorMessageClientFilter extends SimpleChannelInboundHandler { + + @Resource + private final ApplicationContext applicationContext = SpringContextUtils.getApplicationContext(); + + @Override + protected void channelRead0(ChannelHandlerContext ctx, Object o) throws Exception { + if (o instanceof MicrowaveOpcRep) { + MicrowaveOpcRep opcRep = (MicrowaveOpcRep) o; + NettyDataMediatorEvent event = new NettyDataMediatorEvent<>(this,opcRep); + applicationContext.publishEvent(event); + } else if (o instanceof MicrowaveIORep) { + MicrowaveIORep ioRep = (MicrowaveIORep) o; + NettyDataMediatorEvent event = new NettyDataMediatorEvent<>(this,ioRep); + applicationContext.publishEvent(event); + } else if (o instanceof MicrowaveDeviceRep) { + MicrowaveDeviceRep deviceRep = (MicrowaveDeviceRep) o; + NettyDataMediatorEvent event = new NettyDataMediatorEvent<>(this,deviceRep); + applicationContext.publishEvent(event); + } else if (o instanceof MicrowaveQueryRep) { + MicrowaveQueryRep queryRep = (MicrowaveQueryRep) o; + NettyDataMediatorEvent event = new NettyDataMediatorEvent<>(this,queryRep); + applicationContext.publishEvent(event); + } else { + log.warn("未知数据类型"); + NettyDataMediatorEvent event = new NettyDataMediatorEvent<>(this, o); + applicationContext.publishEvent(event); + } + } +} diff --git a/src/main/java/com/zgx/iot/netty/handler/filter/MicrowaveDetectorMessageServiceFilter.java b/src/main/java/com/zgx/iot/netty/handler/filter/MicrowaveDetectorMessageServiceFilter.java new file mode 100644 index 0000000..87bebf5 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/handler/filter/MicrowaveDetectorMessageServiceFilter.java @@ -0,0 +1,50 @@ +package com.zgx.iot.netty.handler.filter; + + + + +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + + +/** + * @author AaGMixW + */ +@Slf4j +@Component +public class MicrowaveDetectorMessageServiceFilter extends SimpleChannelInboundHandler { + @Override + protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object o) throws Exception { + + } + +/* private MicrowaveDetectorAlarm lastAlarm; + + private final RedisUtil redisUtil; + + public MicrowaveDetectorMessageServiceFilter(RedisUtil redisUtil) { + this.redisUtil = redisUtil; + } + + @Override + protected void channelRead0(ChannelHandlerContext ctx, Object o) throws Exception { + // 告警数据过滤 + if (o instanceof MicrowaveDetectorAlarm) { + MicrowaveDetectorAlarm alarm = (MicrowaveDetectorAlarm) o; + // 当前时间 + long now = System.currentTimeMillis(); + Object value = redisUtil.hget("alarm_settings", "delayBlindTime"); + int delayBlindTime = ObjectUtils.isEmpty(value) ? 5 : Integer.parseInt(value.toString()); + if (alarm.equals(lastAlarm) && now - lastAlarm.getTime().getTime() < (long) delayBlindTime * 60 * 1000) { + log.info("微波探测器告警数据过滤,预处理判断为同一事件"); + return; + } + // 更新最后一次告警数据 + lastAlarm = alarm; + } + // 传入下一个处理类 + ctx.fireChannelRead(o); + }*/ +} diff --git a/src/main/java/com/zgx/iot/netty/handler/send/RadarDetectorMessageSend.java b/src/main/java/com/zgx/iot/netty/handler/send/RadarDetectorMessageSend.java new file mode 100644 index 0000000..e1cf10a --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/handler/send/RadarDetectorMessageSend.java @@ -0,0 +1,263 @@ +package com.zgx.iot.netty.handler.send; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.zgx.iot.MilitaryMqttApplication; +import com.zgx.iot.dto.radar.*; +import com.zgx.iot.netty.handler.codec.RadarDetectorMessageServiceDecoder; +import com.zgx.iot.radar.proto.ZCHXRadar; +import com.zgx.iot.utils.radarUtils.BitConverter; +import com.zgx.iot.utils.radarUtils.EndianUtil; +import com.zgx.iot.utils.radarUtils.RadarTransformUtil; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class RadarDetectorMessageSend extends SimpleChannelInboundHandler { + private static final Logger log = LogManager.getLogger(RadarDetectorMessageServiceDecoder.class); + @Override + protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object o) throws Exception { + log.info("执行了RadarDetectorMessageSend:"+(o instanceof RadarRESPackageModel)); + if (o instanceof RadarRESPackageModel){ + RadarRESPackageModel radarPackage=(RadarRESPackageModel) o; + final int mark = radarPackage.getMark(); + final int dataType = radarPackage.getDataType(); + final int dataLength = radarPackage.getDataLength(); + final int dataNum = radarPackage.getDataNum(); + // 包头标识 + log.info("\u5305\u5934\u6807\u8bc6\uff1a " + mark); + // 数据类型 + log.info("\u6570\u636e\u7c7b\u578b\uff1a " + dataType); + // 整包数据的长度 + log.info("\u6574\u5305\u6570\u636e\u7684\u957f\u5ea6\uff1a " + dataLength); + // 数据数量 + log.info("\u6570\u636e\u6570\u91cf\uff1a " + dataNum); + final byte[] radardata = radarPackage.getData(); + this.handleRadarData(mark, dataType, dataLength, dataNum, radardata); + } + } + private void handleRadarData(final int mark, final int dataType, final int dataLength, final int dataNum, final byte[] radardata) { + log.info("执行了handleRadarData"); + switch (dataType) { + case 1: { + final byte[] resultdata1 = this.handleRadarState(dataNum, radardata); + //final String normal_resultdata1 = this.handleRadarTrack2String(dataNum, radardata);//在zmq中不会乱码的数据 + MilitaryMqttApplication.pubMessage(Arrays.toString(resultdata1), "RadarData-1"); + break; + } + case 2: { + this.handleRadarTarget(dataNum, radardata); + break; + } + case 3: { + // todo : 发送String类型的数据 + //final byte[] resultdata2 = this.handleRadarTrack(dataNum, radardata);//在zmq测试中会出现乱码 + final String normal_resultdata2 = this.handleRadarTrack2String(dataNum, radardata);//在zmq中不会乱码的数据 + + MilitaryMqttApplication.pubMessage(normal_resultdata2, "RadarData-3"); + break; + } + case 4: { + // todo : 新增了一个发送String类型的data数据 + //final byte[] resultdata3 = this.handleNyGuideCamPosModel(dataNum, radardata); + final String resultdata3 = this.handleNyGuideCamPosModel2String(dataNum, radardata); + //RadarHelperFrame.zmqPubServer.sendData("NyGuideCamPos", String.valueOf(System.currentTimeMillis()), resultdata3.getBytes()); + MilitaryMqttApplication.pubMessage(resultdata3, "RadarData-4"); + break; + } + } + } + private byte[] handleRadarState(final int dataNum, final byte[] radardata) { + int offset = 0; + byte[] result = null; + for (int i = 0; i < dataNum; ++i) { + final int radarId = BitConverter.bytes2IntSmallEndian(radardata, offset); + offset += 4; + final long timestamp = EndianUtil.bytes2LongSmallEndian(radardata, offset); + offset += 8; + final char workState = EndianUtil.byte2Char(radardata[offset]); + ++offset; + final char sendState = EndianUtil.byte2Char(radardata[offset]); + ++offset; + final float temperature = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float longitude = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float latitude = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float altitude = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final RadarStateModel radarState = new RadarStateModel(radarId, timestamp, workState, sendState, temperature, longitude, latitude, altitude); + final String stateString = JSON.toJSONString(radarState); + result = stateString.getBytes(); + log.info("\u96f7\u8fbe\u72b6\u6001\u6570\u636e\uff1a " + stateString); + // todo : 打印 雷达状态数据 handleRadarState + this.log.info("-------------1:RadarState 雷达状态数据---------------"); + this.log.info(stateString); + } + return result; + } + private byte[] handleRadarTarget(final int dataNum, final byte[] radardata) { + int offset = 0; + for (int i = 0; i < dataNum; ++i) { + // 接收的数据进行转码 + final int radarId = BitConverter.bytes2IntSmallEndian(radardata, offset); + offset += 4; + final long timestamp = EndianUtil.bytes2LongSmallEndian(radardata, offset); + offset += 8; + final int dis = BitConverter.bytes2IntSmallEndian(radardata, offset); + offset += 4; + final float azimuth = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float longitude = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float latitude = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float altitude = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final RadarTargetModel radarTarget = new RadarTargetModel(radarId, timestamp, dis, azimuth, longitude, latitude, altitude); + log.info("\u96f7\u8fbe\u70b9\u8ff9\u6570\u636e\uff1a " + JSON.toJSONString(radarTarget)); + // todo 打印 雷达点迹数据 handleRadarTarget + this.log.info("-------------2:RadarTarget 雷达点迹数据---------------"); + this.log.info(JSON.toJSONString(radarTarget)); + } + return null; + } + private byte[] handleRadarTrack(final int dataNum, final byte[] radardata) { + if (dataNum == 0) { + return null; + } + final ZCHXRadar.RadarSurfaceTrack.Builder rst = ZCHXRadar.RadarSurfaceTrack.newBuilder(); + rst.setFlag(1); + rst.setSourceId("AgilTrack_cat010bsz"); + rst.setUTC(System.currentTimeMillis()); + rst.setLength(dataNum); + int offset = 0; + for (int i = 0; i < dataNum; ++i) { + // 接收的数据进行转码 + final int radarId = BitConverter.bytes2IntSmallEndian(radardata, offset); + offset += 4; + final long timestamp = EndianUtil.bytes2LongSmallEndian(radardata, offset); + offset += 8; + final int trackId = BitConverter.bytes2IntSmallEndian(radardata, offset); + offset += 4; + final char trackState = EndianUtil.byte2Char(radardata[offset]); + ++offset; + final int dis = BitConverter.bytes2IntSmallEndian(radardata, offset); + offset += 4; + final float azimuth = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float speed = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float course = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float longitude = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float latitude = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float altitude = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final char type = EndianUtil.byte2Char(radardata[offset]); + ++offset; + final RadarTrackModel radarTrack = new RadarTrackModel(radarId, timestamp, trackId, trackState, dis, azimuth, speed, course, longitude, latitude, altitude, type); + log.info("\u96f7\u8fbe\u822a\u8ff9\u6570\u636e\uff1a " + JSON.toJSONString(radarTrack)); + // todo 打印雷达航迹数据 handleRadarTarck + this.log.info("-------------3:RadarTrack 雷达航迹数据---------------"); + String radarTrackJsonString = JSON.toJSONString(radarTrack); + this.log.info(radarTrackJsonString); + + final ZCHXRadar.TrackPoint buildmodel = RadarTransformUtil.modelToProtobuf(radarTrack); + rst.addTrackPoints(buildmodel); + } + return rst.build().toByteArray(); + } + // todo : 将data转为字符串返回 + private String handleNyGuideCamPosModel2String(final int dataNum, final byte[] radardata) { + int offset = 0; + byte[] result = null; + String nyGuideCamPosModelString=null; + for (int i = 0; i < dataNum; ++i) { + // todo : 数据进行处理 + final int dis = BitConverter.bytes2IntSmallEndian(radardata, offset); + offset += 4; + final float azimuth = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + + final NyGuideCamPosModel nyGuideCamPosModel = new NyGuideCamPosModel(dis, azimuth); + log.info("目标信息: " + JSON.toJSONString(nyGuideCamPosModel)); + // todo 打印光电位置数据 nyGuideCamPosModel + this.log.info("-------------4:目标信息---------------"); + nyGuideCamPosModelString = JSON.toJSONString(nyGuideCamPosModel); + result = nyGuideCamPosModelString.getBytes(); + this.log.info(nyGuideCamPosModelString); + } + return nyGuideCamPosModelString; + } + + // todo : string类型的数据 + private String handleRadarTrack2String(final int dataNum, final byte[] radardata) { + if (dataNum == 0) { + return null; + } + final ZCHXRadar.RadarSurfaceTrack.Builder rst = ZCHXRadar.RadarSurfaceTrack.newBuilder(); + rst.setFlag(1); + rst.setSourceId("AgilTrack_cat010bsz"); + rst.setUTC(System.currentTimeMillis()); + rst.setLength(dataNum); + + //todo : 手动拼接数据 + JSONObject jsonObject = new JSONObject(); + jsonObject.put("flag",1); + jsonObject.put("sourceId","AgilTrack_cat010bsz"); + jsonObject.put("utc",System.currentTimeMillis()); + jsonObject.put("length",dataNum); + + int offset = 0; + final List jsonObjectList=new ArrayList<>(); + for (int i = 0; i < dataNum; ++i) { + // 接收的数据进行转码 + final int radarId = BitConverter.bytes2IntSmallEndian(radardata, offset); + offset += 4; + final long timestamp = EndianUtil.bytes2LongSmallEndian(radardata, offset); + offset += 8; + final int trackId = BitConverter.bytes2IntSmallEndian(radardata, offset); + offset += 4; + final char trackState = EndianUtil.byte2Char(radardata[offset]); + ++offset; + final int dis = BitConverter.bytes2IntSmallEndian(radardata, offset); + offset += 4; + final float azimuth = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float speed = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float course = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float longitude = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float latitude = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float altitude = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final char type = EndianUtil.byte2Char(radardata[offset]); + ++offset; + final RadarTrackModel radarTrack = new RadarTrackModel(radarId, timestamp, trackId, trackState, dis, azimuth, speed, course, longitude, latitude, altitude, type); + log.info("\u96f7\u8fbe\u822a\u8ff9\u6570\u636e\uff1a " + JSON.toJSONString(radarTrack)); + // todo 打印雷达航迹数据 handleRadarTarck + this.log.info("-------------3:RadarTrack 雷达航迹数据---------------"); + this.log.info(JSON.toJSONString(radarTrack)); + + //final ZCHXRadar.TrackPoint buildmodel = RadarTransformUtil.modelToProtobuf(radarTrack); + + String radarTrackJsonString = JSON.toJSONString(radarTrack); //返回结果 + // todo : 手动组装数据 + jsonObject.put("radarTrack",radarTrackJsonString); + } + return JSON.toJSONString(jsonObject); + } +} diff --git a/src/main/java/com/zgx/iot/netty/model/NettyDeviceIdChannel.java b/src/main/java/com/zgx/iot/netty/model/NettyDeviceIdChannel.java new file mode 100644 index 0000000..69b9446 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/model/NettyDeviceIdChannel.java @@ -0,0 +1,77 @@ +package com.zgx.iot.netty.model; + + +import com.zgx.iot.utils.NettyConfigUtil; +import io.netty.channel.ChannelId; + +/** + * 设备id-netty.channel 关联类 + * + * @author AaGMixW + */ +public class NettyDeviceIdChannel { + /** + * channelId + */ + private ChannelId channelId; + /** + * 关闭标识 + */ + private boolean stopFlag = false; + /** + * 重试计数 + */ + private int retryCount = NettyConfigUtil.getAppServiceConfig().getRetryCount() == 0 ? -1 : + NettyConfigUtil.getAppServiceConfig().getRetryCount();; + + public NettyDeviceIdChannel() { + } + + public NettyDeviceIdChannel(ChannelId channelId) { + this.channelId = channelId; + } + + + public ChannelId getChannelId() { + return channelId; + } + + public void setChannelId(ChannelId channelId) { + this.channelId = channelId; + } + + public boolean notStop() { + return !stopFlag; + } + + public void stop() { + this.stopFlag = true; + } + + public int getRetryCount() { + return retryCount; + } + + public int getAndDecrement() { + retryCount--; + return retryCount + 1; + } + + public void setRetryCount(int retryCount) { + this.retryCount = retryCount; + } + + public void resetRetryCount() { + this.retryCount = NettyConfigUtil.getAppServiceConfig().getRetryCount() == 0 ? -1 : + NettyConfigUtil.getAppServiceConfig().getRetryCount(); + } + + @Override + public String toString() { + return "NettyDeviceIdChannel{" + + "channelId=" + channelId + + ", stopFlag=" + stopFlag + + ", retryCount=" + retryCount + + '}'; + } +} diff --git a/src/main/java/com/zgx/iot/netty/model/NettyDeviceInfo.java b/src/main/java/com/zgx/iot/netty/model/NettyDeviceInfo.java new file mode 100644 index 0000000..3ce61d4 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/model/NettyDeviceInfo.java @@ -0,0 +1,144 @@ +package com.zgx.iot.netty.model; + +import com.zgx.iot.entity.DtDeviceInfo; +import com.zgx.iot.netty.constant.SocketType; +import io.netty.util.NetUtil; +import lombok.Getter; + +import java.net.InetSocketAddress; +import java.util.Objects; + +/** + * @author AaGMixW + */ +@Getter +public class NettyDeviceInfo { + + private static final String PRIMARY_DELIMITER = ":"; + + /** + * ID + * 例子: + * tcp:server:deviceId + * > tcp -> tcp or udp + * > server -> server or client + * > tcp:server -> serverId + */ + private String id; + + /** + * 服务ID + * 例子 udp.service + * + * @see SocketType.UDP + * @see SocketType.TCP + */ + private String serviceId; + + /** + * 设备ID + * + */ + private String deviceId; + + /** + * 服务名称 + * 例子: + * udp 服务端 + */ + private String serviceName; + + + /** + * 设备名称 + * 雷远雷达 + * 雷远雷达_科星网络继电器 + */ + private String deviceName; + + /** + * 设备类型 + */ + private int deviceType; + /** + * 设备厂商 + */ + private int deviceComp; + + /** + * address + */ + private final InetSocketAddress address; + + public NettyDeviceInfo(String deviceId, String deviceName, int deviceType, int deviceComp, InetSocketAddress address, String protocol, String roleType) { + this.deviceType = deviceType; + this.deviceComp = deviceComp; + this.address = address; + this.deviceId = deviceId; + // 设置服务id + this.serviceId = protocol + PRIMARY_DELIMITER + roleType; + // 设置id + this.id = this.serviceId + PRIMARY_DELIMITER + this.deviceId; + // 设置服务名称 + this.serviceName = generateServiceName(); + // 设置设备名称 + this.deviceName = deviceName; + } + + public NettyDeviceInfo(DtDeviceInfo device, String protocol, String roleType) { + this.deviceType = device.getDeviceType() == null ? -1 : device.getDeviceType(); + String ip = device.getDeviceIp() != null ? device.getDeviceIp() : device.getDeviceUrl(); + Integer port = device.getIpPort() != null ? device.getIpPort() : device.getIpPort2(); + this.address = new InetSocketAddress(ip, port); + this.deviceId = device.getId(); + // 设置服务id + this.serviceId = protocol + PRIMARY_DELIMITER + roleType; + // 设置id + this.id = this.serviceId + PRIMARY_DELIMITER + this.deviceId; + // 设置设备名称 + this.deviceName = device.getDeviceName(); + // 设置服务名称 + this.serviceName = generateServiceName(); + } + + /** + * 设置服务名称 + * + * @return serviceName + */ + private String generateServiceName() { + int serviceIdSize = 2; + String serviceValue = "service"; + + if (serviceId.isEmpty()) { + throw new RuntimeException("serviceId is null"); + } + String[] tmp = serviceId.split(PRIMARY_DELIMITER); + String serviceSuffix = ""; + if (tmp.length >= serviceIdSize) { + if (serviceValue.equals(tmp[1])) { + serviceSuffix = "服务端"; + } else { + serviceSuffix = "客户端"; + } + } + return tmp[0] + " " + serviceSuffix; + } + + /** + * 设备名称和IP + * + * @return 设备名称和IP字符串, 如:雷远雷达——科星网络继电器(127.0.0.1:9080) + */ + public String getDeviceNameAndIpStr() { + return this.deviceName + "(" + NetUtil.toSocketAddressString(this.address) + ")"; + } + + /** + * 设备类型和厂商 hash 值 + */ + public int getDeviceTypeAndCompHash() { + return Objects.hash(this.deviceType, this.deviceComp); + } + +} diff --git a/src/main/java/com/zgx/iot/netty/model/NettyService.java b/src/main/java/com/zgx/iot/netty/model/NettyService.java new file mode 100644 index 0000000..22b6178 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/model/NettyService.java @@ -0,0 +1,71 @@ +package com.zgx.iot.netty.model; + +import com.zgx.iot.netty.socket.base.NettyBaseSocket; +import com.zgx.iot.netty.socket.tcp.TcpClientByNetty; +import com.zgx.iot.netty.socket.tcp.TcpServiceByNetty; +import com.zgx.iot.netty.socket.udp.UdpClientByNetty; +import com.zgx.iot.netty.socket.udp.UdpServiceByNetty; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.net.InetSocketAddress; + +/** + * @author AaGMixW + */ +public class NettyService { + private static final Logger logger = LogManager.getLogger(NettyService.class); + /** + * 服务 + * + * @see UdpServiceByNetty + * @see UdpClientByNetty + * @see TcpServiceByNetty + * @see TcpClientByNetty + */ + private final T service; + + public NettyService(T service) { + this.service = service; + } + + public void shutdown() { + this.service.shutdown(); + } + + private Channel getChannel(InetSocketAddress address) { + return service.getChannel(address); + } + + public boolean stopChannel(InetSocketAddress address) { + try { + return service.stopChannel(address); + } catch (InterruptedException e) { + logger.error("关闭 channel 失败: {}", e.getMessage()); + Thread.currentThread().interrupt(); + return false; + } + } + + public boolean sendData(InetSocketAddress addresses, byte[] bytes) { + ByteBuf byteBuf = Unpooled.wrappedBuffer(bytes); + Channel channel = getChannel(addresses); + if (channel == null) { + return false; + } + try { + return channel.writeAndFlush(byteBuf).sync().isSuccess(); + } catch (InterruptedException e) { + logger.error("发送数据错误:{}", e.getMessage()); + Thread.currentThread().interrupt(); + return false; + } + } + + public T getService() { + return service; + } +} diff --git a/src/main/java/com/zgx/iot/netty/model/NettySocketDataMediator.java b/src/main/java/com/zgx/iot/netty/model/NettySocketDataMediator.java new file mode 100644 index 0000000..8973f7b --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/model/NettySocketDataMediator.java @@ -0,0 +1,41 @@ +package com.zgx.iot.netty.model; + +/** + * @author AaGMixW + */ +public class NettySocketDataMediator { + + /** + * 是否已经发送指令 + * 发送指令过去时设置为true, 接收到数据后重新设置为false + */ + private boolean isSendCommand; + /** + * 数据 + */ + private T data; + + public Boolean getSendCommand() { + return isSendCommand; + } + + public void setSendCommand(Boolean sendCommand) { + isSendCommand = sendCommand; + } + + public void setSendCommand2False() { + isSendCommand = false; + } + + public void setSendCommand2True() { + isSendCommand = true; + } + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } +} diff --git a/src/main/java/com/zgx/iot/netty/model/NettyStartServiceVo.java b/src/main/java/com/zgx/iot/netty/model/NettyStartServiceVo.java new file mode 100644 index 0000000..3f68a3d --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/model/NettyStartServiceVo.java @@ -0,0 +1,16 @@ +package com.zgx.iot.netty.model; + + +import com.zgx.iot.entity.DtDeviceInfo; +import lombok.Data; + +/** + * netty 启动服务的参数 + * + * @author AaGMixW + */ +@Data +public class NettyStartServiceVo { + private DtDeviceInfo newDeviceInfo; + private DtDeviceInfo oldDeviceInfo; +} diff --git a/src/main/java/com/zgx/iot/netty/model/dataMediator/NettyDataMediatorEvent.java b/src/main/java/com/zgx/iot/netty/model/dataMediator/NettyDataMediatorEvent.java new file mode 100644 index 0000000..e3c6133 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/model/dataMediator/NettyDataMediatorEvent.java @@ -0,0 +1,26 @@ +package com.zgx.iot.netty.model.dataMediator; + +import org.springframework.context.ApplicationEvent; +import org.springframework.core.ResolvableType; +import org.springframework.core.ResolvableTypeProvider; + +public class NettyDataMediatorEvent extends ApplicationEvent implements ResolvableTypeProvider { + + + private final T data; + + public NettyDataMediatorEvent(Object source,T data) { + super(source); + this.data = data; + } + + public T getData() { + return data; + } + + @Override + public ResolvableType getResolvableType() { + return ResolvableType.forClassWithGenerics(getClass(), + ResolvableType.forInstance(data)); + } +} diff --git a/src/main/java/com/zgx/iot/netty/model/device/microwave/LinkThreadQueueItem.java b/src/main/java/com/zgx/iot/netty/model/device/microwave/LinkThreadQueueItem.java new file mode 100644 index 0000000..3f91978 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/model/device/microwave/LinkThreadQueueItem.java @@ -0,0 +1,15 @@ +package com.zgx.iot.netty.model.device.microwave; + +import lombok.Data; + +@Data +public class LinkThreadQueueItem { + /** + * 预置位 + */ + private Integer prePosition; + /** + * 微波告警数据 + */ + private MicrowaveDetectorAlarm mAlarm; +} diff --git a/src/main/java/com/zgx/iot/netty/model/device/microwave/MicrowaveDetectorAlarm.java b/src/main/java/com/zgx/iot/netty/model/device/microwave/MicrowaveDetectorAlarm.java new file mode 100644 index 0000000..0037125 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/model/device/microwave/MicrowaveDetectorAlarm.java @@ -0,0 +1,88 @@ +package com.zgx.iot.netty.model.device.microwave; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; +import lombok.Data; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; + +import java.util.Date; + +/** + * 告警数据 + * + * @author AaGMixW + */ +@Data +@JacksonXmlRootElement(localName = "alarm") +public class MicrowaveDetectorAlarm { + /** + * 域名称,固定 BD9600 + */ + String domain; + /** + * 告警流水号 + */ + String snbr; + /** + * 探测器条码 + */ + String detectorSn; + /** + * 防区序号 + */ + int areaSn; + /** + * 告警类型 + */ + int type; + /** + * 可能原因 + */ + int pc; + /** + * 告警产生时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + Date time; + /** + * 告警状态 0-新生 + */ + int status; + /** + * 探测器或传感器地址 + */ + String detectorAddr; + + /** + * 防区名称 + */ + String areaName; + + + String info; + /** + * 主机条码 + */ + String hostSn; + /** + * 主机序号 + */ + int hostSnbr; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + + if (o == null || getClass() != o.getClass()) return false; + + MicrowaveDetectorAlarm that = (MicrowaveDetectorAlarm) o; + + return new EqualsBuilder().append(areaSn, that.areaSn).append(type, that.type).append(pc, that.pc).append(detectorSn, that.detectorSn).append(detectorAddr, that.detectorAddr).append(hostSn, that.hostSn).isEquals(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder(17, 37).append(detectorSn).append(areaSn).append(type).append(pc).append(detectorAddr).append(hostSn).toHashCode(); + } +} diff --git a/src/main/java/com/zgx/iot/netty/model/device/microwave/MicrowaveDetectorFault.java b/src/main/java/com/zgx/iot/netty/model/device/microwave/MicrowaveDetectorFault.java new file mode 100644 index 0000000..97cb542 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/model/device/microwave/MicrowaveDetectorFault.java @@ -0,0 +1,64 @@ +package com.zgx.iot.netty.model.device.microwave; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; +import lombok.Data; + +import java.util.Date; + +/** + * 故障数据 + * @author AaGMixW + */ +@Data +@JacksonXmlRootElement(localName = "fault") +public class MicrowaveDetectorFault { + /** + * 域名称 固定为 DB9600 + */ + String domain; + /** + * 故障流水号 + */ + String snbr; + /** + * 设备类型 + * 1-探测器 2-探测主机 3-串口设备 4-预留 + */ + int deviceType; + /** + * 设备子类型 + */ + int deviceSubType; + /** + * 设备条码或唯一标识 + */ + String deviceSn; + /** + * 探测器或传感器地址 + */ + String deviceAddr; + /** + * 故障类型 + * 0-无特定类型 1-离线丢失 2-硬件故障 3-传感器噪声高 4-内部软件故障 5-防拆报警 6- + * 状态不明 7-错误消息或通信异常 8-剪线断线 9-其他预留 + */ + int faultType; + /** + * 故障产生时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + Date time; + /** + * 故障状态 0-恢复 1-新生 + */ + int status; + /** + * 防区名称 + */ + String areaName; + /** + * 防区编号 + */ + int areaSn; +} diff --git a/src/main/java/com/zgx/iot/netty/model/device/microwave/MicrowaveDetectorHeartbeat.java b/src/main/java/com/zgx/iot/netty/model/device/microwave/MicrowaveDetectorHeartbeat.java new file mode 100644 index 0000000..b726932 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/model/device/microwave/MicrowaveDetectorHeartbeat.java @@ -0,0 +1,32 @@ +package com.zgx.iot.netty.model.device.microwave; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; +import lombok.Data; + +import java.util.Date; + +/** + * 心跳包 + * + * @author AaGMixW + */ +@Data +@JacksonXmlRootElement(localName = "heartbeat") +public class MicrowaveDetectorHeartbeat { + /** + * 心跳时间 + */ + @JacksonXmlProperty(localName = "id") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + Date time; + /** + * USC 主机名称 + */ + String host; + /** + * USC 主机 IP 地址 + */ + String ip; +} diff --git a/src/main/java/com/zgx/iot/netty/model/device/microwave/command/MicrowaveAreaDetectorMaintenance.java b/src/main/java/com/zgx/iot/netty/model/device/microwave/command/MicrowaveAreaDetectorMaintenance.java new file mode 100644 index 0000000..9809d7c --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/model/device/microwave/command/MicrowaveAreaDetectorMaintenance.java @@ -0,0 +1,42 @@ +package com.zgx.iot.netty.model.device.microwave.command; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 防区及探测器操作维护 + * + * @author AaGMixW + */ +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +@JacksonXmlRootElement(localName = "opcReq") +public class MicrowaveAreaDetectorMaintenance extends MicrowaveDetectorCommand { + + /** + * 防区编号 + */ + private Integer areaSn; + + /** + * 探测器或传感器集合 + * 如果集合里的detectorAddr为空,则是对整个防区发起操作 + */ + @JacksonXmlElementWrapper(localName = "detectors") + @JacksonXmlProperty(localName = "detectorAddr") + private List detectors = new ArrayList<>(16); + + public void addDetectorAddr(Integer detectorAddr) { + this.detectors.add(detectorAddr); + } + + public void addDetectorAddr(List detectorList) { + this.detectors.addAll(detectorList); + } +} diff --git a/src/main/java/com/zgx/iot/netty/model/device/microwave/command/MicrowaveConfigurationQuery.java b/src/main/java/com/zgx/iot/netty/model/device/microwave/command/MicrowaveConfigurationQuery.java new file mode 100644 index 0000000..ba995b4 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/model/device/microwave/command/MicrowaveConfigurationQuery.java @@ -0,0 +1,26 @@ +package com.zgx.iot.netty.model.device.microwave.command; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; +import lombok.Data; + +/** + * 配置查询 + * + * @author AaGMixW + */ +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +@JacksonXmlRootElement(localName = "queryReq") +public class MicrowaveConfigurationQuery extends MicrowaveDetectorCommand { + + /** + * 分页编号 + */ + private Integer pageNbr; + + /** + * 主机条码或唯一标识 + */ + private String hostSn; +} diff --git a/src/main/java/com/zgx/iot/netty/model/device/microwave/command/MicrowaveDetectorCommand.java b/src/main/java/com/zgx/iot/netty/model/device/microwave/command/MicrowaveDetectorCommand.java new file mode 100644 index 0000000..0a7706c --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/model/device/microwave/command/MicrowaveDetectorCommand.java @@ -0,0 +1,35 @@ +package com.zgx.iot.netty.model.device.microwave.command; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; +import lombok.Data; + +/** + * @author AaGMixW + */ +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +@JacksonXmlRootElement(localName = "root") +public class MicrowaveDetectorCommand { + + /** + * 域名称,固定 BD9600 + */ + private String domain = "BD9600"; + /** + * 命令流水号, 12位长的数字组合 + */ + private String snbr; + /** + * 命令码 命令类型不同是代表不同的含义 + *

commandType = 1 时, 0:撤防 1:布防 10:关闭DO 11:打开DO; 10和11的DO操作针对某个防区或主机关联的IO通道发起

+ *

commandType = 2 时, 0:关闭DO 1:打开DO

+ *

commandType = 3 时, 0:撤防 1:布防 2:状态查询 3:其他预留

+ *

+ * commandType = 4 时, 1-MEMS 振动主机查询,参数为分页序号,每页固定为20个主机,返回分页总数、当前页码 + * 及主机条码,每页满载时最大包长度为514;如果分页序号为0,则连续分页返回所有主机; + * 2-MEMSz 振动探测器查询,参数为主机条码,返回该主机下所有的探测器,满载时最大包长度为1403;3-脉 + * 冲电子围栏主机查询。

+ */ + private int code; +} diff --git a/src/main/java/com/zgx/iot/netty/model/device/microwave/command/MicrowaveDeviceMaintenance.java b/src/main/java/com/zgx/iot/netty/model/device/microwave/command/MicrowaveDeviceMaintenance.java new file mode 100644 index 0000000..f896cfe --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/model/device/microwave/command/MicrowaveDeviceMaintenance.java @@ -0,0 +1,30 @@ +package com.zgx.iot.netty.model.device.microwave.command; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; +import lombok.Data; + +/** + * 设备操作维护 + * + * @author AaGMixW + */ +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +@JacksonXmlRootElement(localName = "deviceReq") +public class MicrowaveDeviceMaintenance extends MicrowaveDetectorCommand { + + /** + * 设备类型 + * 1:探测主机 2:探测器 3:串口设备 4:其它预留 + */ + private Integer deviceType; + /** + * 设备子类型,预留未使用 + */ + private Integer deviceSubType; + /** + * 设备条码或唯一标识 + */ + private String deviceSn; +} diff --git a/src/main/java/com/zgx/iot/netty/model/device/microwave/command/MicrowaveIOMantenance.java b/src/main/java/com/zgx/iot/netty/model/device/microwave/command/MicrowaveIOMantenance.java new file mode 100644 index 0000000..4e72186 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/model/device/microwave/command/MicrowaveIOMantenance.java @@ -0,0 +1,22 @@ +package com.zgx.iot.netty.model.device.microwave.command; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; +import lombok.Data; + +/** + * io 操作维护 + * + * @author AaGMixW + */ +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +@JacksonXmlRootElement(localName = "ioReq") +public class MicrowaveIOMantenance extends MicrowaveDetectorCommand { + + /** + * IO 控制器 IP地址及通道号 + */ + private String ioChannel; + +} diff --git a/src/main/java/com/zgx/iot/netty/model/device/microwave/command/rep/MicrowaveCommonRep.java b/src/main/java/com/zgx/iot/netty/model/device/microwave/command/rep/MicrowaveCommonRep.java new file mode 100644 index 0000000..e823279 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/model/device/microwave/command/rep/MicrowaveCommonRep.java @@ -0,0 +1,23 @@ +package com.zgx.iot.netty.model.device.microwave.command.rep; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; +import lombok.Data; + +/** + * @author AaGMixW + */ +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +@JacksonXmlRootElement(localName = "root") +public class MicrowaveCommonRep { + + /** + * 域名称,固定 BD9600 + */ + private String domain = "BD9600"; + /** + * 命令流水号, 12位长的数字组合 + */ + private String snbr; +} diff --git a/src/main/java/com/zgx/iot/netty/model/device/microwave/command/rep/MicrowaveDetectorRep.java b/src/main/java/com/zgx/iot/netty/model/device/microwave/command/rep/MicrowaveDetectorRep.java new file mode 100644 index 0000000..382942e --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/model/device/microwave/command/rep/MicrowaveDetectorRep.java @@ -0,0 +1,21 @@ +package com.zgx.iot.netty.model.device.microwave.command.rep; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; +import lombok.Data; + +/** + * @author AaGMixW + */ +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +@JacksonXmlRootElement(localName = "root") +public class MicrowaveDetectorRep extends MicrowaveCommonRep { + + /** + * 0 成功,-1 失败 + */ + @JacksonXmlProperty(localName = "retn") + private int success; +} diff --git a/src/main/java/com/zgx/iot/netty/model/device/microwave/command/rep/MicrowaveDeviceRep.java b/src/main/java/com/zgx/iot/netty/model/device/microwave/command/rep/MicrowaveDeviceRep.java new file mode 100644 index 0000000..92a9b54 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/model/device/microwave/command/rep/MicrowaveDeviceRep.java @@ -0,0 +1,25 @@ +package com.zgx.iot.netty.model.device.microwave.command.rep; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; +import lombok.Data; + +/** + * @author AaGMixW + */ +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +@JacksonXmlRootElement(localName = "deviceRep") +public class MicrowaveDeviceRep extends MicrowaveDetectorRep { + + /** + * -2-防拆 -1-离线 0-初始化 1-工作中,对状态查询命令有效 + */ + private int status; + + /** + * 0-撤防 1-布防,对状态查询命令有效,并且只对探测器有效,对其它设备无效 + */ + private int armStatus; +} + diff --git a/src/main/java/com/zgx/iot/netty/model/device/microwave/command/rep/MicrowaveIORep.java b/src/main/java/com/zgx/iot/netty/model/device/microwave/command/rep/MicrowaveIORep.java new file mode 100644 index 0000000..08cee8c --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/model/device/microwave/command/rep/MicrowaveIORep.java @@ -0,0 +1,14 @@ +package com.zgx.iot.netty.model.device.microwave.command.rep; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; +import lombok.Data; + +/** + * @author AaGMixW + */ +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +@JacksonXmlRootElement(localName = "ioRep") +public class MicrowaveIORep extends MicrowaveDetectorRep { +} diff --git a/src/main/java/com/zgx/iot/netty/model/device/microwave/command/rep/MicrowaveOpcRep.java b/src/main/java/com/zgx/iot/netty/model/device/microwave/command/rep/MicrowaveOpcRep.java new file mode 100644 index 0000000..6666793 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/model/device/microwave/command/rep/MicrowaveOpcRep.java @@ -0,0 +1,14 @@ +package com.zgx.iot.netty.model.device.microwave.command.rep; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; +import lombok.Data; + +/** + * @author AaGMixW + */ +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +@JacksonXmlRootElement(localName = "opcRep") +public class MicrowaveOpcRep extends MicrowaveDetectorRep { +} diff --git a/src/main/java/com/zgx/iot/netty/model/device/microwave/command/rep/MicrowaveQueryRep.java b/src/main/java/com/zgx/iot/netty/model/device/microwave/command/rep/MicrowaveQueryRep.java new file mode 100644 index 0000000..c14cd74 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/model/device/microwave/command/rep/MicrowaveQueryRep.java @@ -0,0 +1,34 @@ +package com.zgx.iot.netty.model.device.microwave.command.rep; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; +import lombok.Data; + +import java.util.List; + +/** + * @author AaGMixW + */ +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +@JacksonXmlRootElement(localName = "queryRep") +public class MicrowaveQueryRep extends MicrowaveCommonRep { + + /** + * 总页数,每页固定为 20 + */ + private Integer totalPages; + /** + * 当前页码 + */ + private Integer currentPage; + /** + * 主机集合-主机查询时 + */ + private List detectors; + /** + * 探测器或传感器-探测器或传感器查询时 + */ + private List hosts; +} + diff --git a/src/main/java/com/zgx/iot/netty/pipeline/TcpPipelineFactory.java b/src/main/java/com/zgx/iot/netty/pipeline/TcpPipelineFactory.java new file mode 100644 index 0000000..66a9f0c --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/pipeline/TcpPipelineFactory.java @@ -0,0 +1,21 @@ +package com.zgx.iot.netty.pipeline; + +import com.zgx.iot.netty.socket.base.NettyBaseSocket; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.socket.SocketChannel; + +/** + * @author AaGMixW + */ +public interface TcpPipelineFactory { + + + /** + * Socket Channel initializer + * + * @param socket netty socket {{@link NettyBaseSocket}} + * @return void + */ + ChannelInitializer createInitializer(T socket); + +} diff --git a/src/main/java/com/zgx/iot/netty/pipeline/UdpPipelineFactory.java b/src/main/java/com/zgx/iot/netty/pipeline/UdpPipelineFactory.java new file mode 100644 index 0000000..3cbf21d --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/pipeline/UdpPipelineFactory.java @@ -0,0 +1,22 @@ +package com.zgx.iot.netty.pipeline; + + +import com.zgx.iot.netty.socket.base.NettyBaseSocket; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.socket.DatagramChannel; + +/** + * @author AaGMixW + */ +public interface UdpPipelineFactory { + + + /** + * Socket Channel initializer + * + * @param socket netty socket {{@link NettyBaseSocket}} + * @return void + */ + ChannelInitializer createInitializer(T socket); + +} diff --git a/src/main/java/com/zgx/iot/netty/pipeline/impl/MicrowaveDetectorUdpClientPipelineFactoryImpl.java b/src/main/java/com/zgx/iot/netty/pipeline/impl/MicrowaveDetectorUdpClientPipelineFactoryImpl.java new file mode 100644 index 0000000..8ace0bf --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/pipeline/impl/MicrowaveDetectorUdpClientPipelineFactoryImpl.java @@ -0,0 +1,40 @@ +package com.zgx.iot.netty.pipeline.impl; + + +import com.zgx.iot.netty.constant.AttributeMapConstant; +import com.zgx.iot.netty.handler.ConnectHandler; +import com.zgx.iot.netty.handler.ExceptionHandler; +import com.zgx.iot.netty.handler.codec.MicrowaveDetectorMessageClientDecoder; +import com.zgx.iot.netty.handler.filter.MicrowaveDetectorMessageClientFilter; +import com.zgx.iot.netty.pipeline.UdpPipelineFactory; +import com.zgx.iot.netty.socket.udp.UdpClientByNetty; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.socket.DatagramChannel; + +/** + * @author AaGMixW + */ +public class MicrowaveDetectorUdpClientPipelineFactoryImpl implements UdpPipelineFactory { + + /** + * Pipeline Factory method for channel initialization + */ + @Override + public ChannelInitializer createInitializer(UdpClientByNetty socket) { + return new ChannelInitializer() { + @Override + protected void initChannel(DatagramChannel datagramChannel) { + // Create channel pipeline + ChannelPipeline pipeline = datagramChannel.pipeline(); + // add socket to attr + datagramChannel.attr(AttributeMapConstant.NETTY_CHANNEL_SOCKET_KEY).set(socket); + + pipeline.addLast("exception", new ExceptionHandler()); + pipeline.addLast("connect", new ConnectHandler()); + pipeline.addLast("decoder", new MicrowaveDetectorMessageClientDecoder()); + pipeline.addLast("filter", new MicrowaveDetectorMessageClientFilter()); + } + }; + } +} diff --git a/src/main/java/com/zgx/iot/netty/pipeline/impl/MicrowaveDetectorUdpServicePipelineFactoryImpl.java b/src/main/java/com/zgx/iot/netty/pipeline/impl/MicrowaveDetectorUdpServicePipelineFactoryImpl.java new file mode 100644 index 0000000..cfb07c3 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/pipeline/impl/MicrowaveDetectorUdpServicePipelineFactoryImpl.java @@ -0,0 +1,55 @@ +package com.zgx.iot.netty.pipeline.impl; + +import com.zgx.iot.netty.constant.AttributeMapConstant; +import com.zgx.iot.netty.handler.ConnectHandler; +import com.zgx.iot.netty.handler.ExceptionHandler; +import com.zgx.iot.netty.handler.codec.MicrowaveDetectorMessageServiceDecoder; +import com.zgx.iot.netty.handler.filter.MicrowaveDetectorMessageServiceFilter; +import com.zgx.iot.netty.pipeline.UdpPipelineFactory; +import com.zgx.iot.netty.socket.udp.UdpServiceByNetty; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.socket.DatagramChannel; +import org.springframework.stereotype.Component; + +/** + * @author AaGMixW + */ +@Component +public class MicrowaveDetectorUdpServicePipelineFactoryImpl implements UdpPipelineFactory { + /** + * Pipeline Factory method for channel initialization + */ + @Override + public ChannelInitializer createInitializer(UdpServiceByNetty socket) { + return new ChannelInitializer() { + @Override + protected void initChannel(DatagramChannel datagramChannel) { +/* // Create channel pipeline + ChannelPipeline pipeline = datagramChannel.pipeline(); + // add socket to attr + datagramChannel.attr(AttributeMapConstant.NETTY_CHANNEL_SOCKET_KEY).set(socket); + pipeline.addLast("exception", new ExceptionHandler()); + pipeline.addLast("connect", new ConnectHandler()); + pipeline.addLast("decoder", new MicrowaveDetectorMessageServiceDecoder()); + pipeline.addLast("filter", new MicrowaveDetectorMessageServiceFilter( + SpringContextUtils.getBean(RedisUtil.class) + )); + pipeline.addLast("save", new MicrowaveDetectorMessageSave( + SpringContextUtils.getBean(MsPreWarnServiceImpl.class), + SpringContextUtils.getBean(MsDeviceInfoServiceImpl.class), + SpringContextUtils.getBean(MsFaultRecordServiceImpl.class), + SpringContextUtils.getBean(MsMapLabelServiceImpl.class), + SpringContextUtils.getBean(WebSocket.class), + SpringContextUtils.getBean(MsThirdApiController.class), + SpringContextUtils.getBean(MsCameraSettingServiceImpl.class), + SpringContextUtils.getBean(MsCameraLinkageServiceImpl.class), + SpringContextUtils.getBean(MqttService.class), + SpringContextUtils.getBean(MQTTProps.class), + SpringContextUtils.getBean(MsMapLineServiceImpl.class), + SpringContextUtils.getBean(RedisUtil.class)));*/ + + } + }; + } +} diff --git a/src/main/java/com/zgx/iot/netty/pipeline/impl/RadarDetectorTcpServicePipelineFactoryImpl.java b/src/main/java/com/zgx/iot/netty/pipeline/impl/RadarDetectorTcpServicePipelineFactoryImpl.java new file mode 100644 index 0000000..8426b02 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/pipeline/impl/RadarDetectorTcpServicePipelineFactoryImpl.java @@ -0,0 +1,50 @@ +package com.zgx.iot.netty.pipeline.impl; + + +import com.zgx.iot.netty.constant.AttributeMapConstant; +import com.zgx.iot.netty.handler.ConnectHandler; +import com.zgx.iot.netty.handler.ExceptionHandler; +import com.zgx.iot.netty.handler.codec.MicrowaveDetectorMessageClientDecoder; +import com.zgx.iot.netty.handler.codec.RadarDetectorMessageServiceDecoder; +import com.zgx.iot.netty.handler.filter.MicrowaveDetectorMessageClientFilter; +import com.zgx.iot.netty.handler.send.RadarDetectorMessageSend; +import com.zgx.iot.netty.pipeline.TcpPipelineFactory; +import com.zgx.iot.netty.pipeline.UdpPipelineFactory; +import com.zgx.iot.netty.socket.base.NettyBaseSocket; +import com.zgx.iot.netty.socket.tcp.TcpServiceByNetty; +import com.zgx.iot.netty.socket.udp.UdpClientByNetty; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.socket.DatagramChannel; +import io.netty.channel.socket.SocketChannel; + +/** + * @author AaGMixW + */ +public class RadarDetectorTcpServicePipelineFactoryImpl implements TcpPipelineFactory { + + + + /** + * Socket Channel initializer + * + * @param socket netty socket {{@link NettyBaseSocket}} + * @return void + */ + @Override + public ChannelInitializer createInitializer(TcpServiceByNetty socket) { + return new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel socketChannel) throws Exception { + // Create channel pipeline + ChannelPipeline pipeline = socketChannel.pipeline(); + // add socket to attr + socketChannel.attr(AttributeMapConstant.NETTY_CHANNEL_SOCKET_KEY).set(socket); + pipeline.addLast("exception", new ExceptionHandler()); + pipeline.addLast("connect", new ConnectHandler()); + pipeline.addLast("decoder",new RadarDetectorMessageServiceDecoder()); + pipeline.addLast("send",new RadarDetectorMessageSend()); + } + }; + } +} diff --git a/src/main/java/com/zgx/iot/netty/pipeline/impl/common/CommonTcpClientPipelineFactoryImpl.java b/src/main/java/com/zgx/iot/netty/pipeline/impl/common/CommonTcpClientPipelineFactoryImpl.java new file mode 100644 index 0000000..954e106 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/pipeline/impl/common/CommonTcpClientPipelineFactoryImpl.java @@ -0,0 +1,28 @@ +package com.zgx.iot.netty.pipeline.impl.common; + + +import com.zgx.iot.netty.constant.AttributeMapConstant; +import com.zgx.iot.netty.handler.ConnectHandler; +import com.zgx.iot.netty.handler.ExceptionHandler; +import com.zgx.iot.netty.pipeline.TcpPipelineFactory; +import com.zgx.iot.netty.socket.tcp.TcpClientByNetty; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.socket.SocketChannel; + +public class CommonTcpClientPipelineFactoryImpl implements TcpPipelineFactory { + @Override + public ChannelInitializer createInitializer(TcpClientByNetty socket) { + return new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel socketChannel) throws Exception { + // Create channel pipeline + ChannelPipeline pipeline = socketChannel.pipeline(); + // add socket to attr + socketChannel.attr(AttributeMapConstant.NETTY_CHANNEL_SOCKET_KEY).set(socket); + pipeline.addLast("exception", new ExceptionHandler()); + pipeline.addLast("connect", new ConnectHandler()); + } + }; + } +} diff --git a/src/main/java/com/zgx/iot/netty/pipeline/impl/common/CommonTcpServicePipelineFactoryImpl.java b/src/main/java/com/zgx/iot/netty/pipeline/impl/common/CommonTcpServicePipelineFactoryImpl.java new file mode 100644 index 0000000..c0f4ceb --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/pipeline/impl/common/CommonTcpServicePipelineFactoryImpl.java @@ -0,0 +1,29 @@ +package com.zgx.iot.netty.pipeline.impl.common; + + +import com.zgx.iot.netty.constant.AttributeMapConstant; +import com.zgx.iot.netty.handler.ConnectHandler; +import com.zgx.iot.netty.handler.ExceptionHandler; +import com.zgx.iot.netty.pipeline.TcpPipelineFactory; +import com.zgx.iot.netty.socket.tcp.TcpServiceByNetty; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.socket.SocketChannel; + +public class CommonTcpServicePipelineFactoryImpl implements TcpPipelineFactory { + @Override + public ChannelInitializer createInitializer(TcpServiceByNetty socket) { + return new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel socketChannel) throws Exception { + // Create channel pipeline + ChannelPipeline pipeline = socketChannel.pipeline(); + // add socket to attr + socketChannel.attr(AttributeMapConstant.NETTY_CHANNEL_SOCKET_KEY).set(socket); + pipeline.addLast("exception", new ExceptionHandler()); + pipeline.addLast("connect", new ConnectHandler()); + + } + }; + } +} diff --git a/src/main/java/com/zgx/iot/netty/pipeline/impl/common/CommonUdpClientPipelineFactoryImpl.java b/src/main/java/com/zgx/iot/netty/pipeline/impl/common/CommonUdpClientPipelineFactoryImpl.java new file mode 100644 index 0000000..bb8dcac --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/pipeline/impl/common/CommonUdpClientPipelineFactoryImpl.java @@ -0,0 +1,29 @@ +package com.zgx.iot.netty.pipeline.impl.common; + +import com.zgx.iot.netty.constant.AttributeMapConstant; +import com.zgx.iot.netty.handler.ConnectHandler; +import com.zgx.iot.netty.handler.ExceptionHandler; +import com.zgx.iot.netty.pipeline.UdpPipelineFactory; +import com.zgx.iot.netty.socket.udp.UdpClientByNetty; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.socket.DatagramChannel; + +public class CommonUdpClientPipelineFactoryImpl implements UdpPipelineFactory { + @Override + public ChannelInitializer createInitializer(UdpClientByNetty socket) { + return new ChannelInitializer() { + @Override + protected void initChannel(DatagramChannel datagramChannel) throws Exception { + + // Create channel pipeline + ChannelPipeline pipeline = datagramChannel.pipeline(); + // add socket to attr + datagramChannel.attr(AttributeMapConstant.NETTY_CHANNEL_SOCKET_KEY).set(socket); + pipeline.addLast("exception", new ExceptionHandler()); + pipeline.addLast("connect", new ConnectHandler()); + + } + }; + } +} diff --git a/src/main/java/com/zgx/iot/netty/pipeline/impl/common/CommonUdpServicePipelineFactoryImpl.java b/src/main/java/com/zgx/iot/netty/pipeline/impl/common/CommonUdpServicePipelineFactoryImpl.java new file mode 100644 index 0000000..871cfa2 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/pipeline/impl/common/CommonUdpServicePipelineFactoryImpl.java @@ -0,0 +1,28 @@ +package com.zgx.iot.netty.pipeline.impl.common; + + +import com.zgx.iot.netty.constant.AttributeMapConstant; +import com.zgx.iot.netty.handler.ConnectHandler; +import com.zgx.iot.netty.handler.ExceptionHandler; +import com.zgx.iot.netty.pipeline.UdpPipelineFactory; +import com.zgx.iot.netty.socket.udp.UdpServiceByNetty; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.socket.DatagramChannel; + +public class CommonUdpServicePipelineFactoryImpl implements UdpPipelineFactory { + @Override + public ChannelInitializer createInitializer(UdpServiceByNetty socket) { + return new ChannelInitializer() { + @Override + protected void initChannel(DatagramChannel datagramChannel) throws Exception { + // Create channel pipeline + ChannelPipeline pipeline = datagramChannel.pipeline(); + // add socket to attr + datagramChannel.attr(AttributeMapConstant.NETTY_CHANNEL_SOCKET_KEY).set(socket); + pipeline.addLast("exception", new ExceptionHandler()); + pipeline.addLast("connect", new ConnectHandler()); + } + }; + } +} diff --git a/src/main/java/com/zgx/iot/netty/socket/base/NettyBaseClientImpl.java b/src/main/java/com/zgx/iot/netty/socket/base/NettyBaseClientImpl.java new file mode 100644 index 0000000..c618f6b --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/socket/base/NettyBaseClientImpl.java @@ -0,0 +1,182 @@ +package com.zgx.iot.netty.socket.base; + + +import com.zgx.iot.dto.site.Result; +import com.zgx.iot.netty.exception.NettyServiceControllerException; +import com.zgx.iot.netty.model.NettyDeviceIdChannel; +import com.zgx.iot.netty.model.NettyDeviceInfo; +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelId; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.group.ChannelGroup; +import io.netty.channel.group.DefaultChannelGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.util.concurrent.GlobalEventExecutor; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.net.InetSocketAddress; +import java.util.HashMap; +import java.util.Map; + +/** + * @author AaGMixW + */ +public class NettyBaseClientImpl implements NettyBaseSocket { + + private static final Logger logger = LogManager.getLogger(NettyBaseClientImpl.class); + /** + * 客户端 线程组 + */ + protected final EventLoopGroup workerLoopGroup = new NioEventLoopGroup(); + /** + * channel 组, 管理注册的 channel, 会自动删除已经关闭的channel + */ + protected final ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); + + /** + * bootstrap 用于创建连接 channel + */ + protected final Bootstrap bootstrap = new Bootstrap(); + /** + * 设备信息 + * + * @see NettyDeviceInfo + */ + protected final NettyDeviceInfo deviceInfo; + + /** + * id{@link #generateIdByAddress(InetSocketAddress)} -> {@link NettyDeviceIdChannel} Map + */ + Map idChannelMap = new HashMap<>(16); + + public NettyBaseClientImpl(NettyDeviceInfo deviceInfo) { + this.deviceInfo = deviceInfo; + } + + + @Override + public void startup() throws InstantiationException, IllegalAccessException { + throw new UnsupportedOperationException(); + } + + /** + * 连接服务 + * + * @param address 地址 + * @return channelFuture + */ + public Result connect(InetSocketAddress address) { + NettyDeviceIdChannel nettyDeviceIdChannel = new NettyDeviceIdChannel(); + try { + ChannelFuture channelFuture = bootstrap.connect(address).sync(); + Channel channel = channelFuture.channel(); + nettyDeviceIdChannel.setChannelId(channel.id()); + // 重置重试次数 + nettyDeviceIdChannel.resetRetryCount(); + add2IdChannelMap(address, nettyDeviceIdChannel); + channels.add(channel); + return Result.OK(channelFuture); + } catch (InterruptedException e) { + shutdown(); + Thread.currentThread().interrupt(); + return Result.ERROR("错误" + e.getMessage()); + } catch (NettyServiceControllerException e) { + logger.error(e.getMessage()); + return Result.ERROR("已经启动过服务!"); + } catch (Exception e) { + return Result.ERROR("错误" + e.getMessage()); + } + } + + /** + * 关闭 socket + */ + @Override + public void shutdown() { + try { + channels.close().sync(); + workerLoopGroup.shutdownGracefully(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + logger.error("close() error: ", e); + } + } + + /** + * 重新连接 + * + * @param address 地址 + */ + @Override + public void retry(InetSocketAddress address) { + NettyDeviceIdChannel deviceIdChannel = getDeviceIdChannel(address); + // 如果等于0,无限重试 + boolean infinite = deviceIdChannel.getRetryCount() <= -1; + boolean retry = deviceIdChannel.getAndDecrement() > 0 || infinite; + // 该连接没有关闭,并且重试次数大于零或是不是无限重试 + String name = generateDeviceNameAndIp(deviceInfo, address); + if (deviceIdChannel.notStop() && retry) { + // 重新连接 + connect(address); + } else { + removeIdChannel(address); + logger.info("{} 停止重新连接", name); + } + } + + /** + * 设备信息 + */ + @Override + public NettyDeviceInfo getDeviceInfo() { + return deviceInfo; + } + + /** + * 通过 address 获取 netty channel + * + * @param channelId {@link ChannelId} + * @return channel + */ + @Override + public Channel getChannel(ChannelId channelId) { + if (channelId == null) { + return null; + } + return channels.find(channelId); + } + + /** + * 通过 address 关闭 netty channel连接 + * + * @param address 网络地址 + * @return boolean 是否成功 + * @throws InterruptedException netty sync() 异常 + */ + @Override + public boolean stopChannel(InetSocketAddress address) throws InterruptedException { + Channel channel = getChannel(address); + String key = generateIdByAddress(address); + if (channel == null) { + NettyDeviceIdChannel deviceIdChannel = getDeviceIdChannel(key); + deviceIdChannel.stop(); + logger.info("以标记为停止服务"); + return true; + } + ChannelFuture channelFuture = channel.close(); + if (channelFuture.sync().isSuccess()) { + idChannelMap.remove(key); + return true; + } else { + return false; + } + } + + @Override + public Map getIdChannelMap() { + return idChannelMap; + } +} diff --git a/src/main/java/com/zgx/iot/netty/socket/base/NettyBaseServiceImpl.java b/src/main/java/com/zgx/iot/netty/socket/base/NettyBaseServiceImpl.java new file mode 100644 index 0000000..d515db8 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/socket/base/NettyBaseServiceImpl.java @@ -0,0 +1,197 @@ +package com.zgx.iot.netty.socket.base; + + + +import com.zgx.iot.dto.site.Result; +import com.zgx.iot.netty.exception.NettyServiceControllerException; +import com.zgx.iot.netty.model.NettyDeviceIdChannel; +import com.zgx.iot.netty.model.NettyDeviceInfo; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelId; +import io.netty.channel.group.ChannelGroup; +import io.netty.channel.group.DefaultChannelGroup; +import io.netty.util.NetUtil; +import io.netty.util.concurrent.GlobalEventExecutor; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.net.InetSocketAddress; +import java.util.HashMap; +import java.util.Map; + +/** + * @author AaGMixW + */ +public class NettyBaseServiceImpl implements NettyBaseSocket { + + private static final Logger logger = LogManager.getLogger(NettyBaseServiceImpl.class); + + ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); + + /** + * id{@link #generateIdByAddress(InetSocketAddress)} -> {@link NettyDeviceIdChannel} Map + */ + Map idChannelMap = new HashMap<>(16); + + protected final NettyDeviceInfo deviceInfo; + + public NettyBaseServiceImpl(NettyDeviceInfo deviceInfo) { + this.deviceInfo = deviceInfo; + } + + /** + * 绑定服务 + * + * @param address 地址 + * @return channelFuture + */ + public Result bind(InetSocketAddress address) { + Result result = new Result<>(); + NettyDeviceIdChannel nettyDeviceIdChannel = new NettyDeviceIdChannel(); + try { + add2IdChannelMap(address, nettyDeviceIdChannel); + ChannelFuture channelFuture = bindBefore(address).sync(); + Channel channel = channelFuture.channel(); + + nettyDeviceIdChannel.setChannelId(channel.id()); + // 重置重试次数 + nettyDeviceIdChannel.resetRetryCount(); + + channels.add(channel); + return Result.OK(channelFuture); + } catch (InterruptedException e) { + logger.warn(e.getMessage()); + shutdown(); + Thread.currentThread().interrupt(); + return result.error500("错误" + e.getMessage()); + } catch (NettyServiceControllerException e) { + logger.error(e.getMessage()); + return result.error500("已经启动过服务!"); + } catch (Exception e) { + return result.error500("错误" + e.getMessage()); + } + } + + /** + * 绑定之前处理, 用于返回真正的 bind 方法 + * + * @param address 地址 + * @return {@link ChannelFuture} + */ + protected ChannelFuture bindBefore(InetSocketAddress address) { + throw new UnsupportedOperationException(); + } + + /** + * 初始化 + * + * @throws InstantiationException exception + * @throws IllegalAccessException exception + */ + @Override + public void startup() throws InstantiationException, IllegalAccessException { + throw new UnsupportedOperationException(); + } + + /** + * 关闭 socket + */ + @Override + public void shutdown() { + try { + channels.close().sync(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + logger.error("close() error: ", e); + } + } + + /** + * 重新连接 + * + * @param address 地址 + */ + @Override + public void retry(InetSocketAddress address) throws NettyServiceControllerException { + NettyDeviceIdChannel deviceIdChannel = getDeviceIdChannel(address); + // 如果等于0,无限重试 + boolean infinite = deviceIdChannel.getRetryCount() <= -1; + boolean retry = deviceIdChannel.getAndDecrement() > 0 || infinite; + // 该连接没有关闭,并且重试次数大于零或是不是无限重试 + String name = generateDeviceNameAndIp(deviceInfo, address); + if (deviceIdChannel.notStop() && retry) { + // 重新连接 + bind(address); + } else { + removeIdChannel(address); + logger.info("{} 停止重新监听", name); + } + } + + /** + * 设备信息 + */ + @Override + public NettyDeviceInfo getDeviceInfo() { + return deviceInfo; + } + + /** + * 通过 address 获取 netty channel + * + * @param channelId {@link ChannelId} + * @return channel + */ + @Override + public Channel getChannel(ChannelId channelId) { + if (channelId == null) { + return null; + } + return channels.find(channelId); + } + + /** + * 通过 address 关闭 netty channel连接 + * + * @param address 网络地址 + * @return boolean 是否成功 + * @throws InterruptedException netty sync() 异常 + */ + @Override + public boolean stopChannel(InetSocketAddress address) throws InterruptedException { + String key = generateIdByAddress(address); + Channel channel = getChannel(key); + if (channel == null) { + logger.error("获取 Channel 失败!"); + return false; + } + ChannelFuture future = channel.close().sync(); + if (future.sync().isSuccess()) { + idChannelMap.remove(key); + return true; + } else { + return false; + } + } + + @Override + public Map getIdChannelMap() { + return idChannelMap; + } + + + /** + * 通过 address 生成 id 用于 {@link #idChannelMap} stopServiceList 等 + * + * @param address 地址 + * @return key String + */ + @Override + public String generateIdByAddress(InetSocketAddress address) { + // service 不需要 ip, 只需要端口, 清空 address 的 ip,防止重连时生成的 key 不一致的问题 + address = new InetSocketAddress(address.getPort()); + return NetUtil.toSocketAddressString(address); + } + +} diff --git a/src/main/java/com/zgx/iot/netty/socket/base/NettyBaseSocket.java b/src/main/java/com/zgx/iot/netty/socket/base/NettyBaseSocket.java new file mode 100644 index 0000000..cc324e8 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/socket/base/NettyBaseSocket.java @@ -0,0 +1,202 @@ +package com.zgx.iot.netty.socket.base; + + +import com.zgx.iot.netty.exception.NettyServiceControllerException; +import com.zgx.iot.netty.model.NettyDeviceIdChannel; +import com.zgx.iot.netty.model.NettyDeviceInfo; +import com.zgx.iot.netty.model.NettySocketDataMediator; +import io.netty.channel.Channel; +import io.netty.channel.ChannelId; +import io.netty.util.Attribute; +import io.netty.util.AttributeKey; +import io.netty.util.NetUtil; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.io.Serializable; +import java.net.InetSocketAddress; +import java.util.Map; + +/** + * @author AaGMixW + */ +public interface NettyBaseSocket { + + Logger logger = LogManager.getLogger(NettyBaseSocket.class); + + /** + * 初始化 + * + * @throws InstantiationException exception + * @throws IllegalAccessException exception + */ + void startup() throws InstantiationException, IllegalAccessException; + + /** + * 关闭 socket + */ + void shutdown(); + + /** + * 重新尝试连接/监听 + * + * @param address 地址 + */ + void retry(InetSocketAddress address); + + /** + * 设备信息 + * + * @return {@link NettyDeviceInfo} + */ + NettyDeviceInfo getDeviceInfo(); + + /** + * 通过 address 获取 netty channel + * + * @param channelId {@link ChannelId} + * @return channel + */ + Channel getChannel(ChannelId channelId); + + /** + * 通过 address 获取 netty channel + * + * @param key 使用{@link #generateIdByAddress(InetSocketAddress)} 生成 + * @return channel + */ + default Channel getChannel(String key) { + NettyDeviceIdChannel deviceIdChannel = getDeviceIdChannel(key); + return getChannel(deviceIdChannel.getChannelId()); + } + + + /** + * 通过 address 获取 netty channel + * + * @param address 网络地址 + * @return channel + */ + default Channel getChannel(InetSocketAddress address) { + NettyDeviceIdChannel deviceIdChannel = getDeviceIdChannel(address); + return getChannel(deviceIdChannel.getChannelId()); + } + + /** + * 通过 address 关闭 netty channel连接 + * + * @param address 网络地址 + * @return boolean 是否成功 + * @throws InterruptedException netty sync() 异常 + */ + boolean stopChannel(InetSocketAddress address) throws InterruptedException; + + Map getIdChannelMap(); + + + /** + * 获取 data mediator + * + * @param address 地址 用于获取 channel + * @param attributeKey key 获取 attribute + * @return attribute data mediator + */ + default Attribute> getDataMediator( + InetSocketAddress address, AttributeKey> attributeKey) { + Channel channel = getChannel(address); + if (channel == null) { + logger.error("获取 channel 失败"); + return null; + } + return channel.attr(attributeKey); + } + + /** + * 添加 channelId 到 idMap + * + * @param address 网络地址 + * @param nettyDeviceIdChannel {@link NettyDeviceIdChannel} + * @throws NettyServiceControllerException 已经启动过服务异常 + */ + default void add2IdChannelMap(InetSocketAddress address, NettyDeviceIdChannel nettyDeviceIdChannel) throws NettyServiceControllerException { + // 如果 idChannelMap 已经存在该数据 + String key = generateIdByAddress(address); + Map idChannelMap = getIdChannelMap(); + if (idChannelMap.containsKey(key)) { + NettyDeviceIdChannel deviceIdChannel = getDeviceIdChannel(key); + ChannelId channelId = deviceIdChannel.getChannelId(); + if (channelId != null) { + Channel channel = getChannel(channelId); + getChannel(channelId); + if (channel != null && channel.isActive()) { + throw new NettyServiceControllerException("已经启动过服务!"); + } + } + // channelId == null + // 将上次的重试的数据保存 + nettyDeviceIdChannel.setRetryCount(deviceIdChannel.getRetryCount()); + } + idChannelMap.put(key, nettyDeviceIdChannel); + } + + /** + * 通过 address 生成 id 用于 idMap, stopServiceList 等 + * + * @param address 地址 + * @return key String + */ + default String generateIdByAddress(InetSocketAddress address) { + return NetUtil.toSocketAddressString(address); + } + + /** + * 通过 address 生成 deviceNameAndIp + * + * @param deviceInfo 设备信息 + * @param address 地址 + * @return String -> deviceName(ip:port) + */ + default String generateDeviceNameAndIp(NettyDeviceInfo deviceInfo, InetSocketAddress address) { + return deviceInfo.getDeviceName() + "(" + generateIdByAddress(address) + ")"; + } + + /** + * 通过 key 获取 NettyDeviceIdChannel + * + * @param key 使用{@link #generateIdByAddress(InetSocketAddress)} 生成 + * @return {@link NettyDeviceIdChannel} + */ + default NettyDeviceIdChannel getDeviceIdChannel(String key) { + Map idChannelMap = getIdChannelMap(); + return idChannelMap.getOrDefault(key, new NettyDeviceIdChannel()); + } + + /** + * 通过 key 删除 id_channel_map 的值 + * + * @param key 使用{@link #generateIdByAddress(InetSocketAddress)} 生成 + */ + default void removeIdChannel(String key) { + Map idChannelMap = getIdChannelMap(); + idChannelMap.remove(key); + } + + /** + * 通过 address 获取 NettyDeviceIdChannel + * + * @param address 地址 + * @return {@link NettyDeviceIdChannel} + */ + default NettyDeviceIdChannel getDeviceIdChannel(InetSocketAddress address) { + return getDeviceIdChannel(generateIdByAddress(address)); + } + + /** + * 通过 address 删除 id_channel_map 的值 + * + * @param address 地址 + */ + default void removeIdChannel(InetSocketAddress address) { + removeIdChannel(generateIdByAddress(address)); + } +} diff --git a/src/main/java/com/zgx/iot/netty/socket/tcp/TcpClientByNetty.java b/src/main/java/com/zgx/iot/netty/socket/tcp/TcpClientByNetty.java new file mode 100644 index 0000000..59cd299 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/socket/tcp/TcpClientByNetty.java @@ -0,0 +1,48 @@ +package com.zgx.iot.netty.socket.tcp; + + +import com.zgx.iot.netty.model.NettyDeviceInfo; +import com.zgx.iot.netty.pipeline.TcpPipelineFactory; +import com.zgx.iot.netty.socket.base.NettyBaseClientImpl; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; + +/** + * @author AaGMixW + */ +public class TcpClientByNetty extends NettyBaseClientImpl { + + private final Class> pipelineFactoryClass; + + + public TcpClientByNetty( + NettyDeviceInfo deviceInfo, + Class> pipelineFactoryType + ) { + super(deviceInfo); + this.pipelineFactoryClass = pipelineFactoryType; + } + + + /** + * startup the tcp server + */ + @Override + public final void startup() throws InstantiationException, IllegalAccessException { + + bootstrap.group(workerLoopGroup); + + bootstrap.channel(NioSocketChannel.class); + + bootstrap.option(ChannelOption.SO_KEEPALIVE, true); + + TcpPipelineFactory pipelineFactory = pipelineFactoryClass.newInstance(); + + ChannelInitializer initializer = pipelineFactory.createInitializer(this); + + bootstrap.handler(initializer); + } + +} diff --git a/src/main/java/com/zgx/iot/netty/socket/tcp/TcpServiceByNetty.java b/src/main/java/com/zgx/iot/netty/socket/tcp/TcpServiceByNetty.java new file mode 100644 index 0000000..be28812 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/socket/tcp/TcpServiceByNetty.java @@ -0,0 +1,72 @@ +package com.zgx.iot.netty.socket.tcp; + + +import com.zgx.iot.netty.model.NettyDeviceInfo; +import com.zgx.iot.netty.pipeline.TcpPipelineFactory; +import com.zgx.iot.netty.socket.base.NettyBaseServiceImpl; +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioServerSocketChannel; + +import java.net.InetSocketAddress; + +/** + * @author AaGMixW + */ +public class TcpServiceByNetty extends NettyBaseServiceImpl { + private final Class> pipelineFactoryClass; + + private final ServerBootstrap bootstrap = new ServerBootstrap(); + private final EventLoopGroup bossLoopGroup = new NioEventLoopGroup(); + private final EventLoopGroup workerLoopGroup = new NioEventLoopGroup(); + + public TcpServiceByNetty(NettyDeviceInfo deviceInfo, Class> pipelineFactoryType) { + super(deviceInfo); + this.pipelineFactoryClass = pipelineFactoryType; + } + + /** + * startup the tcp server + */ + @Override + public final void startup() throws InstantiationException, IllegalAccessException { + + bootstrap.group(bossLoopGroup, workerLoopGroup); + + bootstrap.channel(NioServerSocketChannel.class); + + bootstrap.option(ChannelOption.SO_BACKLOG, 1024) + .option(ChannelOption.AUTO_CLOSE, true) + .option(ChannelOption.SO_REUSEADDR, true); + + bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true) + .childOption(ChannelOption.TCP_NODELAY, true); + + TcpPipelineFactory pipelineFactory = pipelineFactoryClass.newInstance(); + + ChannelInitializer initializer = pipelineFactory.createInitializer(this); + + bootstrap.childHandler(initializer); + System.out.println("Tcp服务端启动成功"); + } + + /** + * 关闭 socket + */ + @Override + public void shutdown() { + super.shutdown(); + bossLoopGroup.shutdownGracefully(); + workerLoopGroup.shutdownGracefully(); + } + + @Override + protected ChannelFuture bindBefore(InetSocketAddress address) { + return bootstrap.bind(address.getPort()); + } +} diff --git a/src/main/java/com/zgx/iot/netty/socket/udp/UdpClientByNetty.java b/src/main/java/com/zgx/iot/netty/socket/udp/UdpClientByNetty.java new file mode 100644 index 0000000..f6499c5 --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/socket/udp/UdpClientByNetty.java @@ -0,0 +1,41 @@ +package com.zgx.iot.netty.socket.udp; + + +import com.zgx.iot.netty.model.NettyDeviceInfo; +import com.zgx.iot.netty.pipeline.UdpPipelineFactory; +import com.zgx.iot.netty.socket.base.NettyBaseClientImpl; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.socket.DatagramChannel; +import io.netty.channel.socket.nio.NioDatagramChannel; + +/** + * @author AaGMixW + */ +public class UdpClientByNetty extends NettyBaseClientImpl { + + + private final Class> pipelineFactoryClass; + + public UdpClientByNetty(NettyDeviceInfo deviceInfo, + Class> pipelineFactoryClass) { + super(deviceInfo); + this.pipelineFactoryClass = pipelineFactoryClass; + } + + /** + * startup the tcp server + */ + @Override + public final void startup() throws InstantiationException, IllegalAccessException { + bootstrap.group(workerLoopGroup); + + bootstrap.channel(NioDatagramChannel.class); + + UdpPipelineFactory pipelineFactory = pipelineFactoryClass.newInstance(); + + ChannelInitializer initializer = pipelineFactory.createInitializer(this); + + bootstrap.handler(initializer); + } + +} diff --git a/src/main/java/com/zgx/iot/netty/socket/udp/UdpServiceByNetty.java b/src/main/java/com/zgx/iot/netty/socket/udp/UdpServiceByNetty.java new file mode 100644 index 0000000..56f920b --- /dev/null +++ b/src/main/java/com/zgx/iot/netty/socket/udp/UdpServiceByNetty.java @@ -0,0 +1,65 @@ +package com.zgx.iot.netty.socket.udp; + + +import com.zgx.iot.netty.model.NettyDeviceInfo; +import com.zgx.iot.netty.pipeline.UdpPipelineFactory; +import com.zgx.iot.netty.socket.base.NettyBaseServiceImpl; +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.DatagramChannel; +import io.netty.channel.socket.nio.NioDatagramChannel; + +import java.net.InetSocketAddress; + +/** + * @author AaGMixW + */ +public class UdpServiceByNetty extends NettyBaseServiceImpl { + + private final Class> pipelineFactoryClass; + + private final EventLoopGroup group = new NioEventLoopGroup(); + private final Bootstrap bootstrap = new Bootstrap(); + + public UdpServiceByNetty(Class> pipelineFactoryType, NettyDeviceInfo deviceInfo) { + super(deviceInfo); + this.pipelineFactoryClass = pipelineFactoryType; + } + + /** + * startup the tcp server + */ + @Override + public final void startup() throws InstantiationException, IllegalAccessException { + bootstrap.group(group); + + bootstrap.channel(NioDatagramChannel.class); + + bootstrap.option(ChannelOption.AUTO_CLOSE, true) + .option(ChannelOption.SO_BROADCAST, true); + + UdpPipelineFactory pipelineFactory = pipelineFactoryClass.newInstance(); + + ChannelInitializer initializer = pipelineFactory.createInitializer(this); + + bootstrap.handler(initializer); + } + + @Override + protected ChannelFuture bindBefore(InetSocketAddress address) { + return bootstrap.bind(address.getPort()); + } + + /** + * 关闭 socket + */ + @Override + public void shutdown() { + super.shutdown(); + group.shutdownGracefully(); + } +} diff --git a/src/main/java/com/zgx/iot/radar/RadarAcceptSocket.java b/src/main/java/com/zgx/iot/radar/RadarAcceptSocket.java new file mode 100644 index 0000000..7a05d9e --- /dev/null +++ b/src/main/java/com/zgx/iot/radar/RadarAcceptSocket.java @@ -0,0 +1,516 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package com.zgx.iot.radar; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.zgx.iot.MilitaryMqttApplication; +import com.zgx.iot.dto.radar.*; +import com.zgx.iot.radar.proto.ZCHXRadar; +import com.zgx.iot.utils.radarUtils.BitConverter; +import com.zgx.iot.utils.radarUtils.ByteIntUtil; +import com.zgx.iot.utils.radarUtils.EndianUtil; +import com.zgx.iot.utils.radarUtils.RadarTransformUtil; +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.DataInputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.Socket; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +@Deprecated +public class RadarAcceptSocket extends Thread { + private Log log; + public static int PACKAGE_MAX_LENGTH; + public static int PACKET_HEAD_LENGTH; + private DataInputStream dataInput; + private OutputStream output; + public String address; + private volatile byte[] data; + private volatile boolean flag; + private Socket socket; + private static int CONS_ZERO; + private int len; + private int clientType; + private int radar_data_package_head_len; + private int radar_data_max_buffer_limit; + private byte[] byte_buffer; + + static { + RadarAcceptSocket.PACKAGE_MAX_LENGTH = 4096; + RadarAcceptSocket.PACKET_HEAD_LENGTH = 2; + RadarAcceptSocket.CONS_ZERO = 0; + } + + public RadarAcceptSocket(final Socket socket) { + this.log = LogFactory.getLog(RadarAcceptSocket.class); + this.dataInput = null; + this.output = null; + this.address = null; + this.data = null; + this.flag = true; + this.socket = null; + this.len = RadarAcceptSocket.CONS_ZERO; + this.clientType = 0; + this.radar_data_package_head_len = 16; + this.radar_data_max_buffer_limit = 1024000; + this.byte_buffer = null; + this.socket = socket; + final InetAddress inetAddress = socket.getInetAddress(); + this.address = inetAddress.getHostAddress(); + final String res = "\u96f7\u8fbe\u6570\u636e\u4e0a\u62a5\u5ba2\u6237\u7aef\u8fde\u63a5\u4e0a: " + this.address; + this.log.info(res); + } + + @Override + public void run() { + try { + this.dataInput = new DataInputStream(this.socket.getInputStream()); + this.output = this.socket.getOutputStream(); + while (this.flag) { + final byte[] theData = new byte[RadarAcceptSocket.PACKAGE_MAX_LENGTH]; + this.len = this.dataInput.read(theData); + if (this.len < RadarAcceptSocket.CONS_ZERO) { + this.nowClose(); + } else { + if (this.len < RadarAcceptSocket.PACKET_HEAD_LENGTH) { + continue; + } + this.data = new byte[this.len]; + System.arraycopy(theData, RadarAcceptSocket.CONS_ZERO, this.data, RadarAcceptSocket.CONS_ZERO, this.len); + this.dealProcess(this.data); + this.data = null; + } + } + } catch (IOException e) { + if (this.isclientClose(this.socket)) { + this.nowClose(); + } else { + this.log.error(e.getMessage(), e); + } + } + /** + * 测试消息发送是否出现问题 + */ +/* try { + while (this.flag) { + final byte[] theData = new byte[RadarAcceptSocket.PACKAGE_MAX_LENGTH]; + this.dataInput = new DataInputStream(this.socket.getInputStream()); + int length = this.dataInput.read(theData); + String str = new String(theData, 0, length); + log.info(str); + if (str.contains("testtopic")) { + MilitaryMqttApplication.pubMessage(str, "testtopic"); + } else if (str.contains("testtopic2")) { + MilitaryMqttApplication.pubMessage(str, "testtopic2"); + } + } + + } catch (IOException e) { + throw new RuntimeException(e); + }*/ + + } + + private void dealProcess(final byte[] bytes) { + log.info(Arrays.toString(bytes)); + if (this.byte_buffer == null) { + this.byte_buffer = bytes; + } else if (this.byte_buffer.length > this.radar_data_max_buffer_limit) { + this.byte_buffer = bytes; + } else { + this.byte_buffer = ByteIntUtil.byteMerger(this.byte_buffer, bytes); + } + final int byte_buffer_len = this.byte_buffer.length; + if (byte_buffer_len < this.radar_data_package_head_len) { + // 数据包头不完整,没有达到16字节长度 + log.debug("\u6570\u636e\u5305\u5934\u4e0d\u5b8c\u6574\uff0c\u6ca1\u6709\u8fbe\u523016\u5b57\u8282\u957f\u5ea6"); + return; + } + final RadarRESPackageModel radarPackage = new RadarRESPackageModel(this.byte_buffer); + final int mark = radarPackage.getMark(); + final int dataType = radarPackage.getDataType(); + final int dataLength = radarPackage.getDataLength(); + final int dataNum = radarPackage.getDataNum(); + // 包头标识 + log.info("\u5305\u5934\u6807\u8bc6\uff1a " + mark); + // 数据类型 + log.info("\u6570\u636e\u7c7b\u578b\uff1a " + dataType); + // 整包数据的长度 + log.info("\u6574\u5305\u6570\u636e\u7684\u957f\u5ea6\uff1a " + dataLength); + // 数据数量 + log.info("\u6570\u636e\u6570\u91cf\uff1a " + dataNum); + if (!radarPackage.isIntegrated()) { + // 数据包没有发送完整,等待继续接收 + log.info("\u6570\u636e\u5305\u6ca1\u6709\u53d1\u9001\u5b8c\u6574\uff0c\u7b49\u5f85\u7ee7\u7eed\u63a5\u6536\r\n"); + return; + } + final byte[] radardata = radarPackage.getData(); + this.handleRadarData(mark, dataType, dataLength, dataNum, radardata); + final byte[] remainbytes = radarPackage.getRemain(); + if (remainbytes != null) { + this.byte_buffer = remainbytes; + } else { + this.byte_buffer = null; + } + } + + // todo : 处理雷达数据 + private void handleRadarData(final int mark, final int dataType, final int dataLength, final int dataNum, final byte[] radardata) { + switch (dataType) { + case 1: { + final byte[] resultdata1 = this.handleRadarState(dataNum, radardata); + //final String normal_resultdata1 = this.handleRadarTrack2String(dataNum, radardata);//在zmq中不会乱码的数据 + MilitaryMqttApplication.pubMessage(Arrays.toString(resultdata1), "RadarData-1"); + break; + } + case 2: { + this.handleRadarTarget(dataNum, radardata); + break; + } + case 3: { + // todo : 发送String类型的数据 + final byte[] resultdata2 = this.handleRadarTrack(dataNum, radardata);//在zmq测试中会出现乱码 + //final String normal_resultdata2 = this.handleRadarTrack2String2(dataNum, radardata);//在zmq中不会乱码的数据 + + MilitaryMqttApplication.pubMessage(Arrays.toString(resultdata2), "RadarData-3"); + break; + } + case 4: { + // todo : 新增了一个发送String类型的data数据 + //final byte[] resultdata3 = this.handleNyGuideCamPosModel(dataNum, radardata); + final String resultdata3 = this.handleNyGuideCamPosModel2String(dataNum, radardata); + //RadarHelperFrame.zmqPubServer.sendData("NyGuideCamPos", String.valueOf(System.currentTimeMillis()), resultdata3.getBytes()); + MilitaryMqttApplication.pubMessage(resultdata3, "RadarData-4"); + break; + } + } + } + + private byte[] handleRadarState(final int dataNum, final byte[] radardata) { + int offset = 0; + byte[] result = null; + for (int i = 0; i < dataNum; ++i) { + final int radarId = BitConverter.bytes2IntSmallEndian(radardata, offset); + offset += 4; + final long timestamp = EndianUtil.bytes2LongSmallEndian(radardata, offset); + offset += 8; + final char workState = EndianUtil.byte2Char(radardata[offset]); + ++offset; + final char sendState = EndianUtil.byte2Char(radardata[offset]); + ++offset; + final float temperature = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float longitude = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float latitude = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float altitude = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final RadarStateModel radarState = new RadarStateModel(radarId, timestamp, workState, sendState, temperature, longitude, latitude, altitude); + final String stateString = JSON.toJSONString(radarState); + result = stateString.getBytes(); + log.info("\u96f7\u8fbe\u72b6\u6001\u6570\u636e\uff1a " + stateString); + // todo : 打印 雷达状态数据 handleRadarState + this.log.info("-------------1:RadarState 雷达状态数据---------------"); + this.log.info(stateString); + } + return result; + } + + private byte[] handleRadarTarget(final int dataNum, final byte[] radardata) { + int offset = 0; + for (int i = 0; i < dataNum; ++i) { + // 接收的数据进行转码 + final int radarId = BitConverter.bytes2IntSmallEndian(radardata, offset); + offset += 4; + final long timestamp = EndianUtil.bytes2LongSmallEndian(radardata, offset); + offset += 8; + final int dis = BitConverter.bytes2IntSmallEndian(radardata, offset); + offset += 4; + final float azimuth = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float longitude = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float latitude = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float altitude = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final RadarTargetModel radarTarget = new RadarTargetModel(radarId, timestamp, dis, azimuth, longitude, latitude, altitude); + log.info("\u96f7\u8fbe\u70b9\u8ff9\u6570\u636e\uff1a " + JSON.toJSONString(radarTarget)); + // todo 打印 雷达点迹数据 handleRadarTarget + this.log.info("-------------2:RadarTarget 雷达点迹数据---------------"); + this.log.info(JSON.toJSONString(radarTarget)); + } + return null; + } + + // todo : 多了一个关电位置 + private byte[] handleNyGuideCamPosModel(final int dataNum, final byte[] radardata) { + int offset = 0; + byte[] result = null; + for (int i = 0; i < dataNum; ++i) { + // todo : 增加字段 + final int dis = BitConverter.bytes2IntSmallEndian(radardata, offset); + offset += 4; + final float azimuth = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + + final NyGuideCamPosModel nyGuideCamPosModel = new NyGuideCamPosModel(dis, azimuth); + log.info("光电位置: " + JSON.toJSONString(nyGuideCamPosModel)); + // todo 打印光电位置数据 nyGuideCamPosModel + this.log.info("-------------4:光电位置---------------"); + final String nyGuideCamPosModelString = JSON.toJSONString(nyGuideCamPosModel); + result = nyGuideCamPosModelString.getBytes(); + this.log.info(nyGuideCamPosModelString); + } + return result; + } + + + private byte[] handleRadarTrack(final int dataNum, final byte[] radardata) { + if (dataNum == 0) { + return null; + } + final ZCHXRadar.RadarSurfaceTrack.Builder rst = ZCHXRadar.RadarSurfaceTrack.newBuilder(); + rst.setFlag(1); + rst.setSourceId("AgilTrack_cat010bsz"); + rst.setUTC(System.currentTimeMillis()); + rst.setLength(dataNum); + int offset = 0; + for (int i = 0; i < dataNum; ++i) { + // 接收的数据进行转码 + final int radarId = BitConverter.bytes2IntSmallEndian(radardata, offset); + offset += 4; + final long timestamp = EndianUtil.bytes2LongSmallEndian(radardata, offset); + offset += 8; + final int trackId = BitConverter.bytes2IntSmallEndian(radardata, offset); + offset += 4; + final char trackState = EndianUtil.byte2Char(radardata[offset]); + ++offset; + final int dis = BitConverter.bytes2IntSmallEndian(radardata, offset); + offset += 4; + final float azimuth = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float speed = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float course = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float longitude = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float latitude = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float altitude = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final char type = EndianUtil.byte2Char(radardata[offset]); + ++offset; + final RadarTrackModel radarTrack = new RadarTrackModel(radarId, timestamp, trackId, trackState, dis, azimuth, speed, course, longitude, latitude, altitude, type); + log.info("\u96f7\u8fbe\u822a\u8ff9\u6570\u636e\uff1a " + JSON.toJSONString(radarTrack)); + // todo 打印雷达航迹数据 handleRadarTarck + this.log.info("-------------3:RadarTrack 雷达航迹数据---------------"); + String radarTrackJsonString = JSON.toJSONString(radarTrack); + this.log.info(radarTrackJsonString); + + final ZCHXRadar.TrackPoint buildmodel = RadarTransformUtil.modelToProtobuf(radarTrack); + rst.addTrackPoints(buildmodel); + } + return rst.build().toByteArray(); + } + + + + // todo : string类型的数据 + private String handleRadarTrack2String(final int dataNum, final byte[] radardata) { + if (dataNum == 0) { + return null; + } + final ZCHXRadar.RadarSurfaceTrack.Builder rst = ZCHXRadar.RadarSurfaceTrack.newBuilder(); + rst.setFlag(1); + rst.setSourceId("AgilTrack_cat010bsz"); + rst.setUTC(System.currentTimeMillis()); + rst.setLength(dataNum); + + //todo : 手动拼接数据 + JSONObject jsonObject = new JSONObject(); + jsonObject.put("flag",1); + jsonObject.put("sourceId","AgilTrack_cat010bsz"); + jsonObject.put("utc",System.currentTimeMillis()); + jsonObject.put("length",dataNum); + + int offset = 0; + final List jsonObjectList=new ArrayList<>(); + for (int i = 0; i < dataNum; ++i) { + // 接收的数据进行转码 + final int radarId = BitConverter.bytes2IntSmallEndian(radardata, offset); + offset += 4; + final long timestamp = EndianUtil.bytes2LongSmallEndian(radardata, offset); + offset += 8; + final int trackId = BitConverter.bytes2IntSmallEndian(radardata, offset); + offset += 4; + final char trackState = EndianUtil.byte2Char(radardata[offset]); + ++offset; + final int dis = BitConverter.bytes2IntSmallEndian(radardata, offset); + offset += 4; + final float azimuth = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float speed = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float course = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float longitude = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float latitude = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float altitude = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final char type = EndianUtil.byte2Char(radardata[offset]); + ++offset; + final RadarTrackModel radarTrack = new RadarTrackModel(radarId, timestamp, trackId, trackState, dis, azimuth, speed, course, longitude, latitude, altitude, type); + log.info("\u96f7\u8fbe\u822a\u8ff9\u6570\u636e\uff1a " + JSON.toJSONString(radarTrack)); + // todo 打印雷达航迹数据 handleRadarTarck + this.log.info("-------------3:RadarTrack 雷达航迹数据---------------"); + this.log.info(JSON.toJSONString(radarTrack)); + + //final ZCHXRadar.TrackPoint buildmodel = RadarTransformUtil.modelToProtobuf(radarTrack); + + String radarTrackJsonString = JSON.toJSONString(radarTrack); //返回结果 + // todo : 手动组装数据 + jsonObject.put("radarTrack",radarTrackJsonString); + } + return JSON.toJSONString(jsonObject); + } + + + private String handleRadarTrack2String2(final int dataNum, final byte[] radardata) { + if (dataNum == 0) { + return null; + } + //todo : 手动拼接数据 + JSONObject jsonObject = new JSONObject(); + jsonObject.put("flag",1); + jsonObject.put("sourceId","AgilTrack_cat010bsz"); + jsonObject.put("utc",System.currentTimeMillis()); + jsonObject.put("length",dataNum); + + int offset = 0; + final List radarTracks=new ArrayList<>(); + for (int i = 0; i < dataNum; ++i) { + // 接收的数据进行转码 + final int radarId = BitConverter.bytes2IntSmallEndian(radardata, offset); + offset += 4; + final long timestamp = EndianUtil.bytes2LongSmallEndian(radardata, offset); + offset += 8; + final int trackId = BitConverter.bytes2IntSmallEndian(radardata, offset); + offset += 4; + final char trackState = EndianUtil.byte2Char(radardata[offset]); + ++offset; + final int dis = BitConverter.bytes2IntSmallEndian(radardata, offset); + offset += 4; + final float azimuth = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float speed = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float course = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float longitude = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float latitude = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final float altitude = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + final char type = EndianUtil.byte2Char(radardata[offset]); + ++offset; + + + //todo : 雷达没有发送 新增的字段deviceOwnerId 和 counter 和 timeoutToNext + int deviceOwnerId=0; + int counter=0; + int timeoutToNext=0; + final RadarTrackModel radarTrack = new RadarTrackModel(radarId, timestamp, trackId, trackState, dis, azimuth, speed, course, longitude, latitude, altitude, type,deviceOwnerId,counter,timeoutToNext); + //final RadarTrackModel radarTrack = new RadarTrackModel(radarId, timestamp, trackId, trackState, dis, azimuth, speed, course, longitude, latitude, altitude, type); + + log.info("\u96f7\u8fbe\u822a\u8ff9\u6570\u636e\uff1a " + JSON.toJSONString(radarTrack)); + // todo 打印雷达航迹数据 handleRadarTarck + //this.log.info("-------------3:RadarTrack 雷达航迹数据---------------"); + //this.log.info(JSON.toJSONString(radarTrack)); + + //final ZCHXRadar.TrackPoint buildmodel = RadarTransformUtil.modelToProtobuf(radarTrack); + //String radarTrackJsonString = JSON.toJSONString(radarTrack); //返回结果 + radarTracks.add(radarTrack); + } + this.log.info(JSON.toJSONString(jsonObject)); + // todo : 手动组装数据 + jsonObject.put("radarTracks",JSON.toJSONString(radarTracks)); + return JSON.toJSONString(jsonObject); + } + // todo : 将data转为字符串返回 + private String handleNyGuideCamPosModel2String(final int dataNum, final byte[] radardata) { + int offset = 0; + byte[] result = null; + String nyGuideCamPosModelString=null; + for (int i = 0; i < dataNum; ++i) { + // todo : 数据进行处理 + final int dis = BitConverter.bytes2IntSmallEndian(radardata, offset); + offset += 4; + final float azimuth = EndianUtil.byte2floatSmallEndian(radardata, offset); + offset += 4; + + final NyGuideCamPosModel nyGuideCamPosModel = new NyGuideCamPosModel(dis, azimuth); + log.info("目标信息: " + JSON.toJSONString(nyGuideCamPosModel)); + // todo 打印光电位置数据 nyGuideCamPosModel + this.log.info("-------------4:目标信息---------------"); + nyGuideCamPosModelString = JSON.toJSONString(nyGuideCamPosModel); + result = nyGuideCamPosModelString.getBytes(); + this.log.info(nyGuideCamPosModelString); + } + return nyGuideCamPosModelString; + } + + + public boolean send(final byte[] data) { + boolean sendflag = false; + if (this.socket != null && this.socket.isConnected() && !this.socket.isClosed()) { + try { + this.output.write(data); + sendflag = true; + } catch (IOException e) { + this.nowClose(); + } + } + return sendflag; + } + + private boolean isclientClose(final Socket socket) { + try { + socket.sendUrgentData(255); + return false; + } catch (Exception se) { + return true; + } + } + + public void nowClose() { + this.flag = false; + // 雷达数据上报客户端断开了 + final String res = "\u96f7\u8fbe\u6570\u636e\u4e0a\u62a5\u5ba2\u6237\u7aef\u65ad\u5f00\u4e86: " + this.address; + log.info(String.valueOf(res) + "\r\n"); + IOUtils.closeQuietly(this.dataInput); + IOUtils.closeQuietly(this.output); + IOUtils.closeQuietly(this.socket); + this.dataInput = null; + this.output = null; + this.socket = null; + RadarServer.socketHandles.remove(this); + this.log.info(res); + // 雷达数据上报客户端当前连接数 + this.log.info("\u96f7\u8fbe\u6570\u636e\u4e0a\u62a5\u5ba2\u6237\u7aef\u5f53\u524d\u8fde\u63a5\u6570: " + RadarServer.socketHandles.size()); + } +} diff --git a/src/main/java/com/zgx/iot/radar/RadarServer.java b/src/main/java/com/zgx/iot/radar/RadarServer.java new file mode 100644 index 0000000..0d4ab1a --- /dev/null +++ b/src/main/java/com/zgx/iot/radar/RadarServer.java @@ -0,0 +1,76 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package com.zgx.iot.radar; + + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.commons.io.IOUtils; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Iterator; +import java.util.concurrent.CopyOnWriteArrayList; + +@Deprecated +public class RadarServer extends Thread +{ + private static final Log log; + public static CopyOnWriteArrayList socketHandles; + private String ip; + private int port; + private boolean flag; + private ServerSocket server; + + static { + log = LogFactory.getLog(RadarServer.class); + RadarServer.socketHandles = new CopyOnWriteArrayList(); + } + + public RadarServer(final String ip, final int port) { + this.flag = true; + this.server = null; + this.ip = ip; + this.port = port; + } + + @Override + public void run() { + try { + RadarServer.log.info("雷达服务启动..............."); + + (this.server = new ServerSocket()).bind(new InetSocketAddress(this.ip, this.port)); + log.info("\u96f7\u8fbe\u670d\u52a1\u542f\u52a8\u6210\u529f \r\n"); + while (this.flag) { + // todo 等待连接的到来 + final Socket socket = this.server.accept(); + final RadarAcceptSocket socketHandle = new RadarAcceptSocket(socket); + socketHandle.start(); + RadarServer.socketHandles.add(socketHandle); + } + IOUtils.closeQuietly(this.server); + } + catch (Exception e) { + RadarServer.socketHandles.clear(); + RadarServer.log.error(e.getMessage(), e); + } + } + + public void close() { + this.flag = false; + Socket testSocket = null; + try { + testSocket = new Socket(); + testSocket.connect(new InetSocketAddress(this.ip, this.port)); + } + catch (Exception ex) {} + IOUtils.closeQuietly(testSocket); + final Iterator it = RadarServer.socketHandles.iterator(); + while (it.hasNext()) { + it.next().nowClose(); + } + RadarServer.socketHandles.clear(); + } +} diff --git a/src/main/java/com/zgx/iot/radar/proto/ZCHXRadar.java b/src/main/java/com/zgx/iot/radar/proto/ZCHXRadar.java new file mode 100644 index 0000000..25f162e --- /dev/null +++ b/src/main/java/com/zgx/iot/radar/proto/ZCHXRadar.java @@ -0,0 +1,8546 @@ +package com.zgx.iot.radar.proto; + +import com.google.protobuf.*; + +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectStreamException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public final class ZCHXRadar { + public static void registerAllExtensions(ExtensionRegistry registry) {} + + public enum MSGTYP implements ProtocolMessageEnum { + MSGTYP_UNDEFINED( + + 0, 0), + TARGET_REPORT( + + 1, 1), + START_OF_UPDATE_CYCLE( + + 2, 2), + PERIODIC_STATUS( + + 3, 3), + EVENT_TRIGGERED_STATUS( + + 4, 4); + + public static final int MSGTYP_UNDEFINED_VALUE = 0; + + public static final int TARGET_REPORT_VALUE = 1; + + public static final int START_OF_UPDATE_CYCLE_VALUE = 2; + + public static final int PERIODIC_STATUS_VALUE = 3; + + public static final int EVENT_TRIGGERED_STATUS_VALUE = 4; + + private static Internal.EnumLiteMap internalValueMap = new Internal.EnumLiteMap() { + public MSGTYP findValueByNumber(int number) { + return MSGTYP.valueOf(String.valueOf(number)); + } + }; + + private static final MSGTYP[] VALUES = values(); + + private final int index; + + private final int value; + + public final int getNumber() { + return this.value; + } + + public static Internal.EnumLiteMap internalGetValueMap() { + return internalValueMap; + } + + static { + + } + + public final Descriptors.EnumValueDescriptor getValueDescriptor() { + return getDescriptor().getValues().get(this.index); + } + + public final Descriptors.EnumDescriptor getDescriptorForType() { + return getDescriptor(); + } + + public static final Descriptors.EnumDescriptor getDescriptor() { + return ZCHXRadar.getDescriptor().getEnumTypes().get(0); + } + + MSGTYP(int index, int value) { + this.index = index; + this.value = value; + } + } + + public enum CNF implements ProtocolMessageEnum { + CONFIRMED_TRACK( + + 0, 0), + TENTATIVE_TRACK( + + 1, 1), + UNKNOWN_TRACK( + + 2, 2); + + public static final int CONFIRMED_TRACK_VALUE = 0; + + public static final int TENTATIVE_TRACK_VALUE = 1; + + public static final int UNKNOWN_TRACK_VALUE = 2; + + private static Internal.EnumLiteMap internalValueMap = new Internal.EnumLiteMap() { + public CNF findValueByNumber(int number) { + return CNF.valueOf(String.valueOf(number)); + } + }; + + private static final CNF[] VALUES = values(); + + private final int index; + + private final int value; + + public final int getNumber() { + return this.value; + } + + public static Internal.EnumLiteMap internalGetValueMap() { + return internalValueMap; + } + + static { + + } + + public final Descriptors.EnumValueDescriptor getValueDescriptor() { + return getDescriptor().getValues().get(this.index); + } + + public final Descriptors.EnumDescriptor getDescriptorForType() { + return getDescriptor(); + } + + public static final Descriptors.EnumDescriptor getDescriptor() { + return ZCHXRadar.getDescriptor().getEnumTypes().get(1); + } + + CNF(int index, int value) { + this.index = index; + this.value = value; + } + } + + public enum CST implements ProtocolMessageEnum { + CST_UNDEFINED( + + 0, 0), + PREDICTABLE_EXTRAPOLATION_DUE_PERIOD( + + 1, 1), + PREDICTABLE_EXTRAPOLATION_IN_AREA( + + 2, 2), + EXTRAPOLATION_DUE_UNPREDICTABLE_DETECTION( + + 3, 3); + + public static final int CST_UNDEFINED_VALUE = 0; + + public static final int PREDICTABLE_EXTRAPOLATION_DUE_PERIOD_VALUE = 1; + + public static final int PREDICTABLE_EXTRAPOLATION_IN_AREA_VALUE = 2; + + public static final int EXTRAPOLATION_DUE_UNPREDICTABLE_DETECTION_VALUE = 3; + + private static Internal.EnumLiteMap internalValueMap = new Internal.EnumLiteMap() { + public CST findValueByNumber(int number) { + return CST.valueOf(String.valueOf(number)); + } + }; + + private static final CST[] VALUES = values(); + + private final int index; + + private final int value; + + public final int getNumber() { + return this.value; + } + + public static Internal.EnumLiteMap internalGetValueMap() { + return internalValueMap; + } + + static { + + } + + public final Descriptors.EnumValueDescriptor getValueDescriptor() { + return getDescriptor().getValues().get(this.index); + } + + public final Descriptors.EnumDescriptor getDescriptorForType() { + return getDescriptor(); + } + + public static final Descriptors.EnumDescriptor getDescriptor() { + return ZCHXRadar.getDescriptor().getEnumTypes().get(2); + } + + CST(int index, int value) { + this.index = index; + this.value = value; + } + } + + public enum STH implements ProtocolMessageEnum { + MEASURED_POSITION( + + 0, 0), + SMOOTHED_POSITION( + + 1, 1); + + public static final int MEASURED_POSITION_VALUE = 0; + + public static final int SMOOTHED_POSITION_VALUE = 1; + + private static Internal.EnumLiteMap internalValueMap = new Internal.EnumLiteMap() { + public STH findValueByNumber(int number) { + return STH.valueOf(String.valueOf(number)); + } + }; + + private static final STH[] VALUES = values(); + + private final int index; + + private final int value; + + public final int getNumber() { + return this.value; + } + + public static Internal.EnumLiteMap internalGetValueMap() { + return internalValueMap; + } + + static { + + } + + public final Descriptors.EnumValueDescriptor getValueDescriptor() { + return getDescriptor().getValues().get(this.index); + } + + public final Descriptors.EnumDescriptor getDescriptorForType() { + return getDescriptor(); + } + + public static final Descriptors.EnumDescriptor getDescriptor() { + return ZCHXRadar.getDescriptor().getEnumTypes().get(3); + } + + STH(int index, int value) { + this.index = index; + this.value = value; + } + } + + public static final class RadarHistoryTrack extends GeneratedMessage implements RadarHistoryTrackOrBuilder { + private static final RadarHistoryTrack defaultInstance = new RadarHistoryTrack(true); + + private final UnknownFieldSet unknownFields; + + private RadarHistoryTrack(GeneratedMessage.Builder builder) { + super(builder); + this.memoizedIsInitialized = -1; + this.memoizedSerializedSize = -1; + this.unknownFields = builder.getUnknownFields(); + } + + private RadarHistoryTrack(boolean noInit) { + this.memoizedIsInitialized = -1; + this.memoizedSerializedSize = -1; + this.unknownFields = UnknownFieldSet.getDefaultInstance(); + } + + public static RadarHistoryTrack getDefaultInstance() { + return defaultInstance; + } + + public RadarHistoryTrack getDefaultInstanceForType() { + return defaultInstance; + } + + public final UnknownFieldSet getUnknownFields() { + return this.unknownFields; + } + + private RadarHistoryTrack(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + this.memoizedIsInitialized = -1; + this.memoizedSerializedSize = -1; + initFields(); + int mutable_bitField0_ = 0; + UnknownFieldSet.Builder unknownFields = UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int rawValue; + CNF cNF; + CST cST; + STH value; + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: + this.bitField0_ |= 0x1; + this.trackNumber_ = input.readUInt32(); + break; + case 17: + this.bitField0_ |= 0x2; + this.wgs84PosLat_ = input.readDouble(); + break; + case 25: + this.bitField0_ |= 0x4; + this.wgs84PosLong_ = input.readDouble(); + break; + case 37: + this.bitField0_ |= 0x8; + this.timeOfDay_ = input.readFloat(); + break; + case 40: + rawValue = input.readEnum(); + cNF = CNF.valueOf(String.valueOf(rawValue)); + if (cNF == null) { + unknownFields.mergeVarintField(5, rawValue); + break; + } + this.bitField0_ |= 0x10; + this.trackType_ = cNF; + break; + case 48: + this.bitField0_ |= 0x20; + this.trackLastReport_ = input.readBool(); + break; + case 56: + rawValue = input.readEnum(); + cST = CST.valueOf(String.valueOf(rawValue)); + if (cST == null) { + unknownFields.mergeVarintField(7, rawValue); + break; + } + this.bitField0_ |= 0x40; + this.extrapolation_ = cST; + break; + case 64: + rawValue = input.readEnum(); + value = STH.valueOf(String.valueOf(rawValue)); + if (value == null) { + unknownFields.mergeVarintField(8, rawValue); + break; + } + this.bitField0_ |= 0x80; + this.trackPositionCode_ = value; + break; + case 73: + this.bitField0_ |= 0x100; + this.cog_ = input.readDouble(); + break; + case 81: + this.bitField0_ |= 0x200; + this.sog_ = input.readDouble(); + break; + case 88: + this.bitField0_ |= 0x400; + this.uTC_ = input.readUInt64(); + break; + } + } + } catch (InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (IOException e) { + throw (new InvalidProtocolBufferException(e.getMessage())).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + + public static final Descriptors.Descriptor getDescriptor() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_RadarHistoryTrack_descriptor; + } + + protected FieldAccessorTable internalGetFieldAccessorTable() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_RadarHistoryTrack_fieldAccessorTable.ensureFieldAccessorsInitialized(RadarHistoryTrack.class, Builder.class); + } + + public static Parser PARSER = (Parser)new AbstractParser() { + public RadarHistoryTrack parsePartialFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + return new RadarHistoryTrack(input, extensionRegistry); + } + }; + + private int bitField0_; + + public static final int TRACKNUMBER_FIELD_NUMBER = 1; + + private int trackNumber_; + + public static final int WGS84POSLAT_FIELD_NUMBER = 2; + + private double wgs84PosLat_; + + public static final int WGS84POSLONG_FIELD_NUMBER = 3; + + private double wgs84PosLong_; + + public static final int TIMEOFDAY_FIELD_NUMBER = 4; + + private float timeOfDay_; + + public static final int TRACKTYPE_FIELD_NUMBER = 5; + + private CNF trackType_; + + public static final int TRACKLASTREPORT_FIELD_NUMBER = 6; + + private boolean trackLastReport_; + + public static final int EXTRAPOLATION_FIELD_NUMBER = 7; + + private CST extrapolation_; + + public static final int TRACKPOSITIONCODE_FIELD_NUMBER = 8; + + private STH trackPositionCode_; + + public static final int COG_FIELD_NUMBER = 9; + + private double cog_; + + public static final int SOG_FIELD_NUMBER = 10; + + private double sog_; + + public static final int UTC_FIELD_NUMBER = 11; + + private long uTC_; + + private byte memoizedIsInitialized; + + private int memoizedSerializedSize; + + private static final long serialVersionUID = 0L; + + public Parser getParserForType() { + return PARSER; + } + + public boolean hasTrackNumber() { + return ((this.bitField0_ & 0x1) == 1); + } + + public int getTrackNumber() { + return this.trackNumber_; + } + + public boolean hasWgs84PosLat() { + return ((this.bitField0_ & 0x2) == 2); + } + + public double getWgs84PosLat() { + return this.wgs84PosLat_; + } + + public boolean hasWgs84PosLong() { + return ((this.bitField0_ & 0x4) == 4); + } + + public double getWgs84PosLong() { + return this.wgs84PosLong_; + } + + public boolean hasTimeOfDay() { + return ((this.bitField0_ & 0x8) == 8); + } + + public float getTimeOfDay() { + return this.timeOfDay_; + } + + public boolean hasTrackType() { + return ((this.bitField0_ & 0x10) == 16); + } + + public CNF getTrackType() { + return this.trackType_; + } + + public boolean hasTrackLastReport() { + return ((this.bitField0_ & 0x20) == 32); + } + + public boolean getTrackLastReport() { + return this.trackLastReport_; + } + + public boolean hasExtrapolation() { + return ((this.bitField0_ & 0x40) == 64); + } + + public CST getExtrapolation() { + return this.extrapolation_; + } + + public boolean hasTrackPositionCode() { + return ((this.bitField0_ & 0x80) == 128); + } + + public STH getTrackPositionCode() { + return this.trackPositionCode_; + } + + public boolean hasCog() { + return ((this.bitField0_ & 0x100) == 256); + } + + public double getCog() { + return this.cog_; + } + + public boolean hasSog() { + return ((this.bitField0_ & 0x200) == 512); + } + + public double getSog() { + return this.sog_; + } + + public boolean hasUTC() { + return ((this.bitField0_ & 0x400) == 1024); + } + + public long getUTC() { + return this.uTC_; + } + + private void initFields() { + this.trackNumber_ = 0; + this.wgs84PosLat_ = 0.0D; + this.wgs84PosLong_ = 0.0D; + this.timeOfDay_ = 0.0F; + this.trackType_ = CNF.CONFIRMED_TRACK; + this.trackLastReport_ = false; + this.extrapolation_ = CST.CST_UNDEFINED; + this.trackPositionCode_ = STH.MEASURED_POSITION; + this.cog_ = 0.0D; + this.sog_ = 0.0D; + this.uTC_ = 0L; + } + + public final boolean isInitialized() { + byte isInitialized = this.memoizedIsInitialized; + if (isInitialized == 1) + return true; + if (isInitialized == 0) + return false; + if (!hasTrackNumber()) { + this.memoizedIsInitialized = 0; + return false; + } + if (!hasWgs84PosLat()) { + this.memoizedIsInitialized = 0; + return false; + } + if (!hasWgs84PosLong()) { + this.memoizedIsInitialized = 0; + return false; + } + if (!hasTimeOfDay()) { + this.memoizedIsInitialized = 0; + return false; + } + if (!hasCog()) { + this.memoizedIsInitialized = 0; + return false; + } + if (!hasSog()) { + this.memoizedIsInitialized = 0; + return false; + } + if (!hasUTC()) { + this.memoizedIsInitialized = 0; + return false; + } + this.memoizedIsInitialized = 1; + return true; + } + + public void writeTo(CodedOutputStream output) throws IOException { + getSerializedSize(); + if ((this.bitField0_ & 0x1) == 1) + output.writeUInt32(1, this.trackNumber_); + if ((this.bitField0_ & 0x2) == 2) + output.writeDouble(2, this.wgs84PosLat_); + if ((this.bitField0_ & 0x4) == 4) + output.writeDouble(3, this.wgs84PosLong_); + if ((this.bitField0_ & 0x8) == 8) + output.writeFloat(4, this.timeOfDay_); + if ((this.bitField0_ & 0x10) == 16) + output.writeEnum(5, this.trackType_.getNumber()); + if ((this.bitField0_ & 0x20) == 32) + output.writeBool(6, this.trackLastReport_); + if ((this.bitField0_ & 0x40) == 64) + output.writeEnum(7, this.extrapolation_.getNumber()); + if ((this.bitField0_ & 0x80) == 128) + output.writeEnum(8, this.trackPositionCode_.getNumber()); + if ((this.bitField0_ & 0x100) == 256) + output.writeDouble(9, this.cog_); + if ((this.bitField0_ & 0x200) == 512) + output.writeDouble(10, this.sog_); + if ((this.bitField0_ & 0x400) == 1024) + output.writeUInt64(11, this.uTC_); + getUnknownFields().writeTo(output); + } + + public int getSerializedSize() { + int size = this.memoizedSerializedSize; + if (size != -1) + return size; + size = 0; + if ((this.bitField0_ & 0x1) == 1) + size += CodedOutputStream.computeUInt32Size(1, this.trackNumber_); + if ((this.bitField0_ & 0x2) == 2) + size += CodedOutputStream.computeDoubleSize(2, this.wgs84PosLat_); + if ((this.bitField0_ & 0x4) == 4) + size += CodedOutputStream.computeDoubleSize(3, this.wgs84PosLong_); + if ((this.bitField0_ & 0x8) == 8) + size += CodedOutputStream.computeFloatSize(4, this.timeOfDay_); + if ((this.bitField0_ & 0x10) == 16) + size += CodedOutputStream.computeEnumSize(5, this.trackType_.getNumber()); + if ((this.bitField0_ & 0x20) == 32) + size += CodedOutputStream.computeBoolSize(6, this.trackLastReport_); + if ((this.bitField0_ & 0x40) == 64) + size += CodedOutputStream.computeEnumSize(7, this.extrapolation_.getNumber()); + if ((this.bitField0_ & 0x80) == 128) + size += CodedOutputStream.computeEnumSize(8, this.trackPositionCode_.getNumber()); + if ((this.bitField0_ & 0x100) == 256) + size += CodedOutputStream.computeDoubleSize(9, this.cog_); + if ((this.bitField0_ & 0x200) == 512) + size += CodedOutputStream.computeDoubleSize(10, this.sog_); + if ((this.bitField0_ & 0x400) == 1024) + size += CodedOutputStream.computeUInt64Size(11, this.uTC_); + size += getUnknownFields().getSerializedSize(); + this.memoizedSerializedSize = size; + return size; + } + + protected Object writeReplace() throws ObjectStreamException { + return super.writeReplace(); + } + + public static RadarHistoryTrack parseFrom(ByteString data) throws InvalidProtocolBufferException { + return (RadarHistoryTrack)PARSER.parseFrom(data); + } + + public static RadarHistoryTrack parseFrom(ByteString data, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + return (RadarHistoryTrack)PARSER.parseFrom(data, extensionRegistry); + } + + public static RadarHistoryTrack parseFrom(byte[] data) throws InvalidProtocolBufferException { + return (RadarHistoryTrack)PARSER.parseFrom(data); + } + + public static RadarHistoryTrack parseFrom(byte[] data, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + return (RadarHistoryTrack)PARSER.parseFrom(data, extensionRegistry); + } + + public static RadarHistoryTrack parseFrom(InputStream input) throws IOException { + return (RadarHistoryTrack)PARSER.parseFrom(input); + } + + public static RadarHistoryTrack parseFrom(InputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + return (RadarHistoryTrack)PARSER.parseFrom(input, extensionRegistry); + } + + public static RadarHistoryTrack parseDelimitedFrom(InputStream input) throws IOException { + return (RadarHistoryTrack)PARSER.parseDelimitedFrom(input); + } + + public static RadarHistoryTrack parseDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + return (RadarHistoryTrack)PARSER.parseDelimitedFrom(input, extensionRegistry); + } + + public static RadarHistoryTrack parseFrom(CodedInputStream input) throws IOException { + return (RadarHistoryTrack)PARSER.parseFrom(input); + } + + public static RadarHistoryTrack parseFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + return (RadarHistoryTrack)PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { + return Builder.create(); + } + + public Builder newBuilderForType() { + return newBuilder(); + } + + public static Builder newBuilder(RadarHistoryTrack prototype) { + return newBuilder().mergeFrom(prototype); + } + + public Builder toBuilder() { + return newBuilder(this); + } + + protected Builder newBuilderForType(BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + + public static final class Builder extends GeneratedMessage.Builder implements RadarHistoryTrackOrBuilder { + private int bitField0_; + + private int trackNumber_; + + private double wgs84PosLat_; + + private double wgs84PosLong_; + + private float timeOfDay_; + + private CNF trackType_; + + private boolean trackLastReport_; + + private CST extrapolation_; + + private STH trackPositionCode_; + + private double cog_; + + private double sog_; + + private long uTC_; + + public static final Descriptors.Descriptor getDescriptor() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_RadarHistoryTrack_descriptor; + } + + protected FieldAccessorTable internalGetFieldAccessorTable() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_RadarHistoryTrack_fieldAccessorTable.ensureFieldAccessorsInitialized(RadarHistoryTrack.class, Builder.class); + } + + private Builder() { + this.trackType_ = CNF.CONFIRMED_TRACK; + this.extrapolation_ = CST.CST_UNDEFINED; + this.trackPositionCode_ = STH.MEASURED_POSITION; + maybeForceBuilderInitialization(); + } + + private Builder(BuilderParent parent) { + super(parent); + this.trackType_ = CNF.CONFIRMED_TRACK; + this.extrapolation_ = CST.CST_UNDEFINED; + this.trackPositionCode_ = STH.MEASURED_POSITION; + maybeForceBuilderInitialization(); + } + + private void maybeForceBuilderInitialization() { + boolean b = RadarHistoryTrack.alwaysUseFieldBuilders; + } + + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + this.trackNumber_ = 0; + this.bitField0_ &= 0xFFFFFFFE; + this.wgs84PosLat_ = 0.0D; + this.bitField0_ &= 0xFFFFFFFD; + this.wgs84PosLong_ = 0.0D; + this.bitField0_ &= 0xFFFFFFFB; + this.timeOfDay_ = 0.0F; + this.bitField0_ &= 0xFFFFFFF7; + this.trackType_ = CNF.CONFIRMED_TRACK; + this.bitField0_ &= 0xFFFFFFEF; + this.trackLastReport_ = false; + this.bitField0_ &= 0xFFFFFFDF; + this.extrapolation_ = CST.CST_UNDEFINED; + this.bitField0_ &= 0xFFFFFFBF; + this.trackPositionCode_ = STH.MEASURED_POSITION; + this.bitField0_ &= 0xFFFFFF7F; + this.cog_ = 0.0D; + this.bitField0_ &= 0xFFFFFEFF; + this.sog_ = 0.0D; + this.bitField0_ &= 0xFFFFFDFF; + this.uTC_ = 0L; + this.bitField0_ &= 0xFFFFFBFF; + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public Descriptors.Descriptor getDescriptorForType() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_RadarHistoryTrack_descriptor; + } + + public RadarHistoryTrack getDefaultInstanceForType() { + return RadarHistoryTrack.getDefaultInstance(); + } + + public RadarHistoryTrack build() { + RadarHistoryTrack result = buildPartial(); + if (!result.isInitialized()) + throw newUninitializedMessageException(result); + return result; + } + + public RadarHistoryTrack buildPartial() { + RadarHistoryTrack result = new RadarHistoryTrack(this); + int from_bitField0_ = this.bitField0_; + int to_bitField0_ = 0; + if ((from_bitField0_ & 0x1) == 1) + to_bitField0_ |= 0x1; + result.trackNumber_ = this.trackNumber_; + if ((from_bitField0_ & 0x2) == 2) + to_bitField0_ |= 0x2; + result.wgs84PosLat_ = this.wgs84PosLat_; + if ((from_bitField0_ & 0x4) == 4) + to_bitField0_ |= 0x4; + result.wgs84PosLong_ = this.wgs84PosLong_; + if ((from_bitField0_ & 0x8) == 8) + to_bitField0_ |= 0x8; + result.timeOfDay_ = this.timeOfDay_; + if ((from_bitField0_ & 0x10) == 16) + to_bitField0_ |= 0x10; + result.trackType_ = this.trackType_; + if ((from_bitField0_ & 0x20) == 32) + to_bitField0_ |= 0x20; + result.trackLastReport_ = this.trackLastReport_; + if ((from_bitField0_ & 0x40) == 64) + to_bitField0_ |= 0x40; + result.extrapolation_ = this.extrapolation_; + if ((from_bitField0_ & 0x80) == 128) + to_bitField0_ |= 0x80; + result.trackPositionCode_ = this.trackPositionCode_; + if ((from_bitField0_ & 0x100) == 256) + to_bitField0_ |= 0x100; + result.cog_ = this.cog_; + if ((from_bitField0_ & 0x200) == 512) + to_bitField0_ |= 0x200; + result.sog_ = this.sog_; + if ((from_bitField0_ & 0x400) == 1024) + to_bitField0_ |= 0x400; + result.uTC_ = this.uTC_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(Message other) { + if (other instanceof RadarHistoryTrack) + return mergeFrom((RadarHistoryTrack)other); + super.mergeFrom(other); + return this; + } + + public Builder mergeFrom(RadarHistoryTrack other) { + if (other == RadarHistoryTrack.getDefaultInstance()) + return this; + if (other.hasTrackNumber()) + setTrackNumber(other.getTrackNumber()); + if (other.hasWgs84PosLat()) + setWgs84PosLat(other.getWgs84PosLat()); + if (other.hasWgs84PosLong()) + setWgs84PosLong(other.getWgs84PosLong()); + if (other.hasTimeOfDay()) + setTimeOfDay(other.getTimeOfDay()); + if (other.hasTrackType()) + setTrackType(other.getTrackType()); + if (other.hasTrackLastReport()) + setTrackLastReport(other.getTrackLastReport()); + if (other.hasExtrapolation()) + setExtrapolation(other.getExtrapolation()); + if (other.hasTrackPositionCode()) + setTrackPositionCode(other.getTrackPositionCode()); + if (other.hasCog()) + setCog(other.getCog()); + if (other.hasSog()) + setSog(other.getSog()); + if (other.hasUTC()) + setUTC(other.getUTC()); + mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasTrackNumber()) + return false; + if (!hasWgs84PosLat()) + return false; + if (!hasWgs84PosLong()) + return false; + if (!hasTimeOfDay()) + return false; + if (!hasCog()) + return false; + if (!hasSog()) + return false; + if (!hasUTC()) + return false; + return true; + } + + public Builder mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + RadarHistoryTrack parsedMessage = null; + try { + parsedMessage = (RadarHistoryTrack) RadarHistoryTrack.PARSER.parsePartialFrom(input, extensionRegistry); + } catch (InvalidProtocolBufferException e) { + parsedMessage = (RadarHistoryTrack)e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) + mergeFrom(parsedMessage); + } + return this; + } + + public boolean hasTrackNumber() { + return ((this.bitField0_ & 0x1) == 1); + } + + public int getTrackNumber() { + return this.trackNumber_; + } + + public Builder setTrackNumber(int value) { + this.bitField0_ |= 0x1; + this.trackNumber_ = value; + onChanged(); + return this; + } + + public Builder clearTrackNumber() { + this.bitField0_ &= 0xFFFFFFFE; + this.trackNumber_ = 0; + onChanged(); + return this; + } + + public boolean hasWgs84PosLat() { + return ((this.bitField0_ & 0x2) == 2); + } + + public double getWgs84PosLat() { + return this.wgs84PosLat_; + } + + public Builder setWgs84PosLat(double value) { + this.bitField0_ |= 0x2; + this.wgs84PosLat_ = value; + onChanged(); + return this; + } + + public Builder clearWgs84PosLat() { + this.bitField0_ &= 0xFFFFFFFD; + this.wgs84PosLat_ = 0.0D; + onChanged(); + return this; + } + + public boolean hasWgs84PosLong() { + return ((this.bitField0_ & 0x4) == 4); + } + + public double getWgs84PosLong() { + return this.wgs84PosLong_; + } + + public Builder setWgs84PosLong(double value) { + this.bitField0_ |= 0x4; + this.wgs84PosLong_ = value; + onChanged(); + return this; + } + + public Builder clearWgs84PosLong() { + this.bitField0_ &= 0xFFFFFFFB; + this.wgs84PosLong_ = 0.0D; + onChanged(); + return this; + } + + public boolean hasTimeOfDay() { + return ((this.bitField0_ & 0x8) == 8); + } + + public float getTimeOfDay() { + return this.timeOfDay_; + } + + public Builder setTimeOfDay(float value) { + this.bitField0_ |= 0x8; + this.timeOfDay_ = value; + onChanged(); + return this; + } + + public Builder clearTimeOfDay() { + this.bitField0_ &= 0xFFFFFFF7; + this.timeOfDay_ = 0.0F; + onChanged(); + return this; + } + + public boolean hasTrackType() { + return ((this.bitField0_ & 0x10) == 16); + } + + public CNF getTrackType() { + return this.trackType_; + } + + public Builder setTrackType(CNF value) { + if (value == null) + throw new NullPointerException(); + this.bitField0_ |= 0x10; + this.trackType_ = value; + onChanged(); + return this; + } + + public Builder clearTrackType() { + this.bitField0_ &= 0xFFFFFFEF; + this.trackType_ = CNF.CONFIRMED_TRACK; + onChanged(); + return this; + } + + public boolean hasTrackLastReport() { + return ((this.bitField0_ & 0x20) == 32); + } + + public boolean getTrackLastReport() { + return this.trackLastReport_; + } + + public Builder setTrackLastReport(boolean value) { + this.bitField0_ |= 0x20; + this.trackLastReport_ = value; + onChanged(); + return this; + } + + public Builder clearTrackLastReport() { + this.bitField0_ &= 0xFFFFFFDF; + this.trackLastReport_ = false; + onChanged(); + return this; + } + + public boolean hasExtrapolation() { + return ((this.bitField0_ & 0x40) == 64); + } + + public CST getExtrapolation() { + return this.extrapolation_; + } + + public Builder setExtrapolation(CST value) { + if (value == null) + throw new NullPointerException(); + this.bitField0_ |= 0x40; + this.extrapolation_ = value; + onChanged(); + return this; + } + + public Builder clearExtrapolation() { + this.bitField0_ &= 0xFFFFFFBF; + this.extrapolation_ = CST.CST_UNDEFINED; + onChanged(); + return this; + } + + public boolean hasTrackPositionCode() { + return ((this.bitField0_ & 0x80) == 128); + } + + public STH getTrackPositionCode() { + return this.trackPositionCode_; + } + + public Builder setTrackPositionCode(STH value) { + if (value == null) + throw new NullPointerException(); + this.bitField0_ |= 0x80; + this.trackPositionCode_ = value; + onChanged(); + return this; + } + + public Builder clearTrackPositionCode() { + this.bitField0_ &= 0xFFFFFF7F; + this.trackPositionCode_ = STH.MEASURED_POSITION; + onChanged(); + return this; + } + + public boolean hasCog() { + return ((this.bitField0_ & 0x100) == 256); + } + + public double getCog() { + return this.cog_; + } + + public Builder setCog(double value) { + this.bitField0_ |= 0x100; + this.cog_ = value; + onChanged(); + return this; + } + + public Builder clearCog() { + this.bitField0_ &= 0xFFFFFEFF; + this.cog_ = 0.0D; + onChanged(); + return this; + } + + public boolean hasSog() { + return ((this.bitField0_ & 0x200) == 512); + } + + public double getSog() { + return this.sog_; + } + + public Builder setSog(double value) { + this.bitField0_ |= 0x200; + this.sog_ = value; + onChanged(); + return this; + } + + public Builder clearSog() { + this.bitField0_ &= 0xFFFFFDFF; + this.sog_ = 0.0D; + onChanged(); + return this; + } + + public boolean hasUTC() { + return ((this.bitField0_ & 0x400) == 1024); + } + + public long getUTC() { + return this.uTC_; + } + + public Builder setUTC(long value) { + this.bitField0_ |= 0x400; + this.uTC_ = value; + onChanged(); + return this; + } + + public Builder clearUTC() { + this.bitField0_ &= 0xFFFFFBFF; + this.uTC_ = 0L; + onChanged(); + return this; + } + } + + static { + defaultInstance.initFields(); + } + } + + public static final class RadarHistoryTracks extends GeneratedMessage implements RadarHistoryTracksOrBuilder { + private static final RadarHistoryTracks defaultInstance = new RadarHistoryTracks(true); + + private final UnknownFieldSet unknownFields; + + private RadarHistoryTracks(GeneratedMessage.Builder builder) { + super(builder); + this.memoizedIsInitialized = -1; + this.memoizedSerializedSize = -1; + this.unknownFields = builder.getUnknownFields(); + } + + private RadarHistoryTracks(boolean noInit) { + this.memoizedIsInitialized = -1; + this.memoizedSerializedSize = -1; + this.unknownFields = UnknownFieldSet.getDefaultInstance(); + } + + public static RadarHistoryTracks getDefaultInstance() { + return defaultInstance; + } + + public RadarHistoryTracks getDefaultInstanceForType() { + return defaultInstance; + } + + public final UnknownFieldSet getUnknownFields() { + return this.unknownFields; + } + + private RadarHistoryTracks(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + this.memoizedIsInitialized = -1; + this.memoizedSerializedSize = -1; + initFields(); + int mutable_bitField0_ = 0; + UnknownFieldSet.Builder unknownFields = UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: + if ((mutable_bitField0_ & 0x1) != 1) { + this.tracks_ = new ArrayList(); + mutable_bitField0_ |= 0x1; + } + this.tracks_.add((RadarHistoryTrack)input.readMessage(RadarHistoryTrack.PARSER, extensionRegistry)); + break; + } + } + } catch (InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (IOException e) { + throw (new InvalidProtocolBufferException(e.getMessage())).setUnfinishedMessage(this); + } finally { + if ((mutable_bitField0_ & 0x1) == 1) + this.tracks_ = Collections.unmodifiableList(this.tracks_); + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + + public static final Descriptors.Descriptor getDescriptor() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_RadarHistoryTracks_descriptor; + } + + protected FieldAccessorTable internalGetFieldAccessorTable() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_RadarHistoryTracks_fieldAccessorTable.ensureFieldAccessorsInitialized(RadarHistoryTracks.class, Builder.class); + } + + public static Parser PARSER = (Parser)new AbstractParser() { + public RadarHistoryTracks parsePartialFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + return new RadarHistoryTracks(input, extensionRegistry); + } + }; + + public static final int TRACKS_FIELD_NUMBER = 1; + + private List tracks_; + + private byte memoizedIsInitialized; + + private int memoizedSerializedSize; + + private static final long serialVersionUID = 0L; + + public Parser getParserForType() { + return PARSER; + } + + public List getTracksList() { + return this.tracks_; + } + + public List getTracksOrBuilderList() { + return (List)this.tracks_; + } + + public int getTracksCount() { + return this.tracks_.size(); + } + + public RadarHistoryTrack getTracks(int index) { + return this.tracks_.get(index); + } + + public RadarHistoryTrackOrBuilder getTracksOrBuilder(int index) { + return this.tracks_.get(index); + } + + private void initFields() { + this.tracks_ = Collections.emptyList(); + } + + public final boolean isInitialized() { + byte isInitialized = this.memoizedIsInitialized; + if (isInitialized == 1) + return true; + if (isInitialized == 0) + return false; + for (int i = 0; i < getTracksCount(); i++) { + if (!getTracks(i).isInitialized()) { + this.memoizedIsInitialized = 0; + return false; + } + } + this.memoizedIsInitialized = 1; + return true; + } + + public void writeTo(CodedOutputStream output) throws IOException { + getSerializedSize(); + for (int i = 0; i < this.tracks_.size(); i++) + output.writeMessage(1, (MessageLite)this.tracks_.get(i)); + getUnknownFields().writeTo(output); + } + + public int getSerializedSize() { + int size = this.memoizedSerializedSize; + if (size != -1) + return size; + size = 0; + for (int i = 0; i < this.tracks_.size(); i++) + size += CodedOutputStream.computeMessageSize(1, (MessageLite)this.tracks_.get(i)); + size += getUnknownFields().getSerializedSize(); + this.memoizedSerializedSize = size; + return size; + } + + protected Object writeReplace() throws ObjectStreamException { + return super.writeReplace(); + } + + public static RadarHistoryTracks parseFrom(ByteString data) throws InvalidProtocolBufferException { + return (RadarHistoryTracks)PARSER.parseFrom(data); + } + + public static RadarHistoryTracks parseFrom(ByteString data, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + return (RadarHistoryTracks)PARSER.parseFrom(data, extensionRegistry); + } + + public static RadarHistoryTracks parseFrom(byte[] data) throws InvalidProtocolBufferException { + return (RadarHistoryTracks)PARSER.parseFrom(data); + } + + public static RadarHistoryTracks parseFrom(byte[] data, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + return (RadarHistoryTracks)PARSER.parseFrom(data, extensionRegistry); + } + + public static RadarHistoryTracks parseFrom(InputStream input) throws IOException { + return (RadarHistoryTracks)PARSER.parseFrom(input); + } + + public static RadarHistoryTracks parseFrom(InputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + return (RadarHistoryTracks)PARSER.parseFrom(input, extensionRegistry); + } + + public static RadarHistoryTracks parseDelimitedFrom(InputStream input) throws IOException { + return (RadarHistoryTracks)PARSER.parseDelimitedFrom(input); + } + + public static RadarHistoryTracks parseDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + return (RadarHistoryTracks)PARSER.parseDelimitedFrom(input, extensionRegistry); + } + + public static RadarHistoryTracks parseFrom(CodedInputStream input) throws IOException { + return (RadarHistoryTracks)PARSER.parseFrom(input); + } + + public static RadarHistoryTracks parseFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + return (RadarHistoryTracks)PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { + return Builder.create(); + } + + public Builder newBuilderForType() { + return newBuilder(); + } + + public static Builder newBuilder(RadarHistoryTracks prototype) { + return newBuilder().mergeFrom(prototype); + } + + public Builder toBuilder() { + return newBuilder(this); + } + + protected Builder newBuilderForType(BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + + public static final class Builder extends GeneratedMessage.Builder implements RadarHistoryTracksOrBuilder { + private int bitField0_; + + private List tracks_; + + private RepeatedFieldBuilder tracksBuilder_; + + public static final Descriptors.Descriptor getDescriptor() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_RadarHistoryTracks_descriptor; + } + + protected FieldAccessorTable internalGetFieldAccessorTable() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_RadarHistoryTracks_fieldAccessorTable.ensureFieldAccessorsInitialized(RadarHistoryTracks.class, Builder.class); + } + + private Builder() { + this.tracks_ = Collections.emptyList(); + maybeForceBuilderInitialization(); + } + + private Builder(BuilderParent parent) { + super(parent); + this.tracks_ = Collections.emptyList(); + maybeForceBuilderInitialization(); + } + + private void maybeForceBuilderInitialization() { + if (RadarHistoryTracks.alwaysUseFieldBuilders) + getTracksFieldBuilder(); + } + + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + if (this.tracksBuilder_ == null) { + this.tracks_ = Collections.emptyList(); + this.bitField0_ &= 0xFFFFFFFE; + } else { + this.tracksBuilder_.clear(); + } + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public Descriptors.Descriptor getDescriptorForType() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_RadarHistoryTracks_descriptor; + } + + public RadarHistoryTracks getDefaultInstanceForType() { + return RadarHistoryTracks.getDefaultInstance(); + } + + public RadarHistoryTracks build() { + RadarHistoryTracks result = buildPartial(); + if (!result.isInitialized()) + throw newUninitializedMessageException(result); + return result; + } + + public RadarHistoryTracks buildPartial() { + RadarHistoryTracks result = new RadarHistoryTracks(this); + int from_bitField0_ = this.bitField0_; + if (this.tracksBuilder_ == null) { + if ((this.bitField0_ & 0x1) == 1) { + this.tracks_ = Collections.unmodifiableList(this.tracks_); + this.bitField0_ &= 0xFFFFFFFE; + } + result.tracks_ = this.tracks_; + } else { + result.tracks_ = this.tracksBuilder_.build(); + } + onBuilt(); + return result; + } + + public Builder mergeFrom(Message other) { + if (other instanceof RadarHistoryTracks) + return mergeFrom((RadarHistoryTracks)other); + super.mergeFrom(other); + return this; + } + + public Builder mergeFrom(RadarHistoryTracks other) { + if (other == RadarHistoryTracks.getDefaultInstance()) + return this; + if (this.tracksBuilder_ == null) { + if (!other.tracks_.isEmpty()) { + if (this.tracks_.isEmpty()) { + this.tracks_ = other.tracks_; + this.bitField0_ &= 0xFFFFFFFE; + } else { + ensureTracksIsMutable(); + this.tracks_.addAll(other.tracks_); + } + onChanged(); + } + } else if (!other.tracks_.isEmpty()) { + if (this.tracksBuilder_.isEmpty()) { + this.tracksBuilder_.dispose(); + this.tracksBuilder_ = null; + this.tracks_ = other.tracks_; + this.bitField0_ &= 0xFFFFFFFE; + this.tracksBuilder_ = RadarHistoryTracks.alwaysUseFieldBuilders ? getTracksFieldBuilder() : null; + } else { + this.tracksBuilder_.addAllMessages(other.tracks_); + } + } + mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + for (int i = 0; i < getTracksCount(); i++) { + if (!getTracks(i).isInitialized()) + return false; + } + return true; + } + + public Builder mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + RadarHistoryTracks parsedMessage = null; + try { + parsedMessage = (RadarHistoryTracks) RadarHistoryTracks.PARSER.parsePartialFrom(input, extensionRegistry); + } catch (InvalidProtocolBufferException e) { + parsedMessage = (RadarHistoryTracks)e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) + mergeFrom(parsedMessage); + } + return this; + } + + private void ensureTracksIsMutable() { + if ((this.bitField0_ & 0x1) != 1) { + this.tracks_ = new ArrayList(this.tracks_); + this.bitField0_ |= 0x1; + } + } + + public List getTracksList() { + if (this.tracksBuilder_ == null) + return Collections.unmodifiableList(this.tracks_); + return this.tracksBuilder_.getMessageList(); + } + + public int getTracksCount() { + if (this.tracksBuilder_ == null) + return this.tracks_.size(); + return this.tracksBuilder_.getCount(); + } + + public RadarHistoryTrack getTracks(int index) { + if (this.tracksBuilder_ == null) + return this.tracks_.get(index); + return (RadarHistoryTrack)this.tracksBuilder_.getMessage(index); + } + + public Builder setTracks(int index, RadarHistoryTrack value) { + if (this.tracksBuilder_ == null) { + if (value == null) + throw new NullPointerException(); + ensureTracksIsMutable(); + this.tracks_.set(index, value); + onChanged(); + } else { + this.tracksBuilder_.setMessage(index, value); + } + return this; + } + + public Builder setTracks(int index, RadarHistoryTrack.Builder builderForValue) { + if (this.tracksBuilder_ == null) { + ensureTracksIsMutable(); + this.tracks_.set(index, builderForValue.build()); + onChanged(); + } else { + this.tracksBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + + public Builder addTracks(RadarHistoryTrack value) { + if (this.tracksBuilder_ == null) { + if (value == null) + throw new NullPointerException(); + ensureTracksIsMutable(); + this.tracks_.add(value); + onChanged(); + } else { + this.tracksBuilder_.addMessage(value); + } + return this; + } + + public Builder addTracks(int index, RadarHistoryTrack value) { + if (this.tracksBuilder_ == null) { + if (value == null) + throw new NullPointerException(); + ensureTracksIsMutable(); + this.tracks_.add(index, value); + onChanged(); + } else { + this.tracksBuilder_.addMessage(index, value); + } + return this; + } + + public Builder addTracks(RadarHistoryTrack.Builder builderForValue) { + if (this.tracksBuilder_ == null) { + ensureTracksIsMutable(); + this.tracks_.add(builderForValue.build()); + onChanged(); + } else { + this.tracksBuilder_.addMessage(builderForValue.build()); + } + return this; + } + + public Builder addTracks(int index, RadarHistoryTrack.Builder builderForValue) { + if (this.tracksBuilder_ == null) { + ensureTracksIsMutable(); + this.tracks_.add(index, builderForValue.build()); + onChanged(); + } else { + this.tracksBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + + public Builder addAllTracks(Iterable values) { + if (this.tracksBuilder_ == null) { + ensureTracksIsMutable(); + AbstractMessageLite.Builder.addAll(values, this.tracks_); + onChanged(); + } else { + this.tracksBuilder_.addAllMessages(values); + } + return this; + } + + public Builder clearTracks() { + if (this.tracksBuilder_ == null) { + this.tracks_ = Collections.emptyList(); + this.bitField0_ &= 0xFFFFFFFE; + onChanged(); + } else { + this.tracksBuilder_.clear(); + } + return this; + } + + public Builder removeTracks(int index) { + if (this.tracksBuilder_ == null) { + ensureTracksIsMutable(); + this.tracks_.remove(index); + onChanged(); + } else { + this.tracksBuilder_.remove(index); + } + return this; + } + + public RadarHistoryTrack.Builder getTracksBuilder(int index) { + return (RadarHistoryTrack.Builder)getTracksFieldBuilder().getBuilder(index); + } + + public RadarHistoryTrackOrBuilder getTracksOrBuilder(int index) { + if (this.tracksBuilder_ == null) + return this.tracks_.get(index); + return (RadarHistoryTrackOrBuilder)this.tracksBuilder_.getMessageOrBuilder(index); + } + + public List getTracksOrBuilderList() { + if (this.tracksBuilder_ != null) + return this.tracksBuilder_.getMessageOrBuilderList(); + return Collections.unmodifiableList((List)this.tracks_); + } + + public RadarHistoryTrack.Builder addTracksBuilder() { + return (RadarHistoryTrack.Builder)getTracksFieldBuilder().addBuilder(RadarHistoryTrack.getDefaultInstance()); + } + + public RadarHistoryTrack.Builder addTracksBuilder(int index) { + return (RadarHistoryTrack.Builder)getTracksFieldBuilder().addBuilder(index, RadarHistoryTrack.getDefaultInstance()); + } + + public List getTracksBuilderList() { + return getTracksFieldBuilder().getBuilderList(); + } + + private RepeatedFieldBuilder getTracksFieldBuilder() { + if (this.tracksBuilder_ == null) { + this.tracksBuilder_ = new RepeatedFieldBuilder(this.tracks_, ((this.bitField0_ & 0x1) == 1), getParentForChildren(), isClean()); + this.tracks_ = null; + } + return this.tracksBuilder_; + } + } + + static { + defaultInstance.initFields(); + } + } + + public static final class TrackPoint extends GeneratedMessage implements TrackPointOrBuilder { + private static final TrackPoint defaultInstance = new TrackPoint(true); + + private final UnknownFieldSet unknownFields; + + private TrackPoint(GeneratedMessage.Builder builder) { + super(builder); + this.memoizedIsInitialized = -1; + this.memoizedSerializedSize = -1; + this.unknownFields = builder.getUnknownFields(); + } + + private TrackPoint(boolean noInit) { + this.memoizedIsInitialized = -1; + this.memoizedSerializedSize = -1; + this.unknownFields = UnknownFieldSet.getDefaultInstance(); + } + + public static TrackPoint getDefaultInstance() { + return defaultInstance; + } + + public TrackPoint getDefaultInstanceForType() { + return defaultInstance; + } + + public final UnknownFieldSet getUnknownFields() { + return this.unknownFields; + } + + private TrackPoint(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + this.memoizedIsInitialized = -1; + this.memoizedSerializedSize = -1; + initFields(); + int mutable_bitField0_ = 0; + int mutable_bitField1_ = 0; + UnknownFieldSet.Builder unknownFields = UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int rawValue; + RadarHistoryTracks.Builder subBuilder; + ByteString bs; + MSGTYP mSGTYP; + CNF cNF; + CST cST; + STH value; + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: + this.bitField0_ |= 0x1; + this.systemAreaCode_ = input.readInt32(); + break; + case 16: + this.bitField0_ |= 0x2; + this.systemIdentificationCode_ = input.readInt32(); + break; + case 24: + rawValue = input.readEnum(); + mSGTYP = MSGTYP.valueOf(String.valueOf(rawValue)); + if (mSGTYP == null) { + unknownFields.mergeVarintField(3, rawValue); + break; + } + this.bitField0_ |= 0x4; + this.messageType_ = mSGTYP; + break; + case 32: + this.bitField0_ |= 0x8; + this.trackNumber_ = input.readUInt32(); + break; + case 45: + this.bitField0_ |= 0x10; + this.cartesianPosX_ = input.readFloat(); + break; + case 53: + this.bitField0_ |= 0x20; + this.cartesianPosY_ = input.readFloat(); + break; + case 57: + this.bitField0_ |= 0x40; + this.wgs84PosLat_ = input.readDouble(); + break; + case 65: + this.bitField0_ |= 0x80; + this.wgs84PosLong_ = input.readDouble(); + break; + case 77: + this.bitField0_ |= 0x100; + this.timeOfDay_ = input.readFloat(); + break; + case 80: + rawValue = input.readEnum(); + cNF = CNF.valueOf(String.valueOf(rawValue)); + if (cNF == null) { + unknownFields.mergeVarintField(10, rawValue); + break; + } + this.bitField0_ |= 0x200; + this.trackType_ = cNF; + break; + case 88: + this.bitField0_ |= 0x400; + this.trackLastReport_ = input.readBool(); + break; + case 96: + rawValue = input.readEnum(); + cST = CST.valueOf(String.valueOf(rawValue)); + if (cST == null) { + unknownFields.mergeVarintField(12, rawValue); + break; + } + this.bitField0_ |= 0x800; + this.extrapolation_ = cST; + break; + case 104: + rawValue = input.readEnum(); + value = STH.valueOf(String.valueOf(rawValue)); + if (value == null) { + unknownFields.mergeVarintField(13, rawValue); + break; + } + this.bitField0_ |= 0x1000; + this.trackPositionCode_ = value; + break; + case 117: + this.bitField0_ |= 0x2000; + this.sigmaX_ = input.readFloat(); + break; + case 125: + this.bitField0_ |= 0x4000; + this.sigmaY_ = input.readFloat(); + break; + case 133: + this.bitField0_ |= 0x8000; + this.sigmaXY_ = input.readFloat(); + break; + case 141: + this.bitField0_ |= 0x10000; + this.ampOfPriPlot_ = input.readFloat(); + break; + case 145: + this.bitField0_ |= 0x20000; + this.cartesianTrkVelVx_ = input.readDouble(); + break; + case 153: + this.bitField0_ |= 0x40000; + this.cartesianTrkVelVy_ = input.readDouble(); + break; + case 161: + this.bitField0_ |= 0x80000; + this.cog_ = input.readDouble(); + break; + case 169: + this.bitField0_ |= 0x100000; + this.sog_ = input.readDouble(); + break; + case 178: + subBuilder = null; + if ((this.bitField0_ & 0x200000) == 2097152) + subBuilder = this.tracks_.toBuilder(); + this.tracks_ = (RadarHistoryTracks)input.readMessage(RadarHistoryTracks.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(this.tracks_); + this.tracks_ = subBuilder.buildPartial(); + } + this.bitField0_ |= 0x200000; + break; + case 184: + this.bitField0_ |= 0x400000; + this.status_ = input.readInt32(); + break; + case 192: + this.bitField0_ |= 0x800000; + this.isSmuggle_ = input.readInt32(); + break; + case 201: + this.bitField0_ |= 0x1000000; + this.distance_ = input.readDouble(); + break; + case 210: + bs = input.readBytes(); + this.bitField0_ |= 0x2000000; + this.warnColor_ = bs; + break; + case 216: + this.bitField0_ |= 0x4000000; + this.targetType_ = input.readInt32(); + break; + case 224: + this.bitField0_ |= 0x8000000; + this.signWindow_ = input.readInt32(); + break; + case 232: + this.bitField0_ |= 0x10000000; + this.isWarn_ = input.readInt32(); + break; + case 242: + bs = input.readBytes(); + this.bitField0_ |= 0x20000000; + this.rtsp_ = bs; + break; + case 248: + this.bitField0_ |= 0x40000000; + this.fllow_ = input.readInt32(); + break; + case 256: + this.bitField0_ |= Integer.MIN_VALUE; + this.mode_ = input.readInt32(); + break; + case 264: + this.bitField1_ |= 0x1; + this.timeStamp_ = input.readInt64(); + break; + case 274: + bs = input.readBytes(); + this.bitField1_ |= 0x2; + this.trackby_ = bs; + break; + case 280: + this.bitField1_ |= 0x4; + this.cameraId_ = input.readInt32(); + break; + } + } + } catch (InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (IOException e) { + throw (new InvalidProtocolBufferException(e.getMessage())).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + + public static final Descriptors.Descriptor getDescriptor() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_TrackPoint_descriptor; + } + + protected FieldAccessorTable internalGetFieldAccessorTable() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_TrackPoint_fieldAccessorTable.ensureFieldAccessorsInitialized(TrackPoint.class, Builder.class); + } + + public static Parser PARSER = (Parser)new AbstractParser() { + public TrackPoint parsePartialFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + return new TrackPoint(input, extensionRegistry); + } + }; + + private int bitField0_; + + private int bitField1_; + + public static final int SYSTEMAREACODE_FIELD_NUMBER = 1; + + private int systemAreaCode_; + + public static final int SYSTEMIDENTIFICATIONCODE_FIELD_NUMBER = 2; + + private int systemIdentificationCode_; + + public static final int MESSAGETYPE_FIELD_NUMBER = 3; + + private MSGTYP messageType_; + + public static final int TRACKNUMBER_FIELD_NUMBER = 4; + + private int trackNumber_; + + public static final int CARTESIANPOSX_FIELD_NUMBER = 5; + + private float cartesianPosX_; + + public static final int CARTESIANPOSY_FIELD_NUMBER = 6; + + private float cartesianPosY_; + + public static final int WGS84POSLAT_FIELD_NUMBER = 7; + + private double wgs84PosLat_; + + public static final int WGS84POSLONG_FIELD_NUMBER = 8; + + private double wgs84PosLong_; + + public static final int TIMEOFDAY_FIELD_NUMBER = 9; + + private float timeOfDay_; + + public static final int TRACKTYPE_FIELD_NUMBER = 10; + + private CNF trackType_; + + public static final int TRACKLASTREPORT_FIELD_NUMBER = 11; + + private boolean trackLastReport_; + + public static final int EXTRAPOLATION_FIELD_NUMBER = 12; + + private CST extrapolation_; + + public static final int TRACKPOSITIONCODE_FIELD_NUMBER = 13; + + private STH trackPositionCode_; + + public static final int SIGMAX_FIELD_NUMBER = 14; + + private float sigmaX_; + + public static final int SIGMAY_FIELD_NUMBER = 15; + + private float sigmaY_; + + public static final int SIGMAXY_FIELD_NUMBER = 16; + + private float sigmaXY_; + + public static final int AMPOFPRIPLOT_FIELD_NUMBER = 17; + + private float ampOfPriPlot_; + + public static final int CARTESIANTRKVEL_VX_FIELD_NUMBER = 18; + + private double cartesianTrkVelVx_; + + public static final int CARTESIANTRKVEL_VY_FIELD_NUMBER = 19; + + private double cartesianTrkVelVy_; + + public static final int COG_FIELD_NUMBER = 20; + + private double cog_; + + public static final int SOG_FIELD_NUMBER = 21; + + private double sog_; + + public static final int TRACKS_FIELD_NUMBER = 22; + + private RadarHistoryTracks tracks_; + + public static final int STATUS_FIELD_NUMBER = 23; + + private int status_; + + public static final int ISSMUGGLE_FIELD_NUMBER = 24; + + private int isSmuggle_; + + public static final int DISTANCE_FIELD_NUMBER = 25; + + private double distance_; + + public static final int WARN_COLOR_FIELD_NUMBER = 26; + + private Object warnColor_; + + public static final int TARGETTYPE_FIELD_NUMBER = 27; + + private int targetType_; + + public static final int SIGN_WINDOW_FIELD_NUMBER = 28; + + private int signWindow_; + + public static final int IS_WARN_FIELD_NUMBER = 29; + + private int isWarn_; + + public static final int RTSP_FIELD_NUMBER = 30; + + private Object rtsp_; + + public static final int FLLOW_FIELD_NUMBER = 31; + + private int fllow_; + + public static final int MODE_FIELD_NUMBER = 32; + + private int mode_; + + public static final int TIMESTAMP_FIELD_NUMBER = 33; + + private long timeStamp_; + + public static final int TRACKBY_FIELD_NUMBER = 34; + + private Object trackby_; + + public static final int CAMERAID_FIELD_NUMBER = 35; + + private int cameraId_; + + private byte memoizedIsInitialized; + + private int memoizedSerializedSize; + + private static final long serialVersionUID = 0L; + + public Parser getParserForType() { + return PARSER; + } + + public boolean hasSystemAreaCode() { + return ((this.bitField0_ & 0x1) == 1); + } + + public int getSystemAreaCode() { + return this.systemAreaCode_; + } + + public boolean hasSystemIdentificationCode() { + return ((this.bitField0_ & 0x2) == 2); + } + + public int getSystemIdentificationCode() { + return this.systemIdentificationCode_; + } + + public boolean hasMessageType() { + return ((this.bitField0_ & 0x4) == 4); + } + + public MSGTYP getMessageType() { + return this.messageType_; + } + + public boolean hasTrackNumber() { + return ((this.bitField0_ & 0x8) == 8); + } + + public int getTrackNumber() { + return this.trackNumber_; + } + + public boolean hasCartesianPosX() { + return ((this.bitField0_ & 0x10) == 16); + } + + public float getCartesianPosX() { + return this.cartesianPosX_; + } + + public boolean hasCartesianPosY() { + return ((this.bitField0_ & 0x20) == 32); + } + + public float getCartesianPosY() { + return this.cartesianPosY_; + } + + public boolean hasWgs84PosLat() { + return ((this.bitField0_ & 0x40) == 64); + } + + public double getWgs84PosLat() { + return this.wgs84PosLat_; + } + + public boolean hasWgs84PosLong() { + return ((this.bitField0_ & 0x80) == 128); + } + + public double getWgs84PosLong() { + return this.wgs84PosLong_; + } + + public boolean hasTimeOfDay() { + return ((this.bitField0_ & 0x100) == 256); + } + + public float getTimeOfDay() { + return this.timeOfDay_; + } + + public boolean hasTrackType() { + return ((this.bitField0_ & 0x200) == 512); + } + + public CNF getTrackType() { + return this.trackType_; + } + + public boolean hasTrackLastReport() { + return ((this.bitField0_ & 0x400) == 1024); + } + + public boolean getTrackLastReport() { + return this.trackLastReport_; + } + + public boolean hasExtrapolation() { + return ((this.bitField0_ & 0x800) == 2048); + } + + public CST getExtrapolation() { + return this.extrapolation_; + } + + public boolean hasTrackPositionCode() { + return ((this.bitField0_ & 0x1000) == 4096); + } + + public STH getTrackPositionCode() { + return this.trackPositionCode_; + } + + public boolean hasSigmaX() { + return ((this.bitField0_ & 0x2000) == 8192); + } + + public float getSigmaX() { + return this.sigmaX_; + } + + public boolean hasSigmaY() { + return ((this.bitField0_ & 0x4000) == 16384); + } + + public float getSigmaY() { + return this.sigmaY_; + } + + public boolean hasSigmaXY() { + return ((this.bitField0_ & 0x8000) == 32768); + } + + public float getSigmaXY() { + return this.sigmaXY_; + } + + public boolean hasAmpOfPriPlot() { + return ((this.bitField0_ & 0x10000) == 65536); + } + + public float getAmpOfPriPlot() { + return this.ampOfPriPlot_; + } + + public boolean hasCartesianTrkVelVx() { + return ((this.bitField0_ & 0x20000) == 131072); + } + + public double getCartesianTrkVelVx() { + return this.cartesianTrkVelVx_; + } + + public boolean hasCartesianTrkVelVy() { + return ((this.bitField0_ & 0x40000) == 262144); + } + + public double getCartesianTrkVelVy() { + return this.cartesianTrkVelVy_; + } + + public boolean hasCog() { + return ((this.bitField0_ & 0x80000) == 524288); + } + + public double getCog() { + return this.cog_; + } + + public boolean hasSog() { + return ((this.bitField0_ & 0x100000) == 1048576); + } + + public double getSog() { + return this.sog_; + } + + public boolean hasTracks() { + return ((this.bitField0_ & 0x200000) == 2097152); + } + + public RadarHistoryTracks getTracks() { + return this.tracks_; + } + + public RadarHistoryTracksOrBuilder getTracksOrBuilder() { + return this.tracks_; + } + + public boolean hasStatus() { + return ((this.bitField0_ & 0x400000) == 4194304); + } + + public int getStatus() { + return this.status_; + } + + public boolean hasIsSmuggle() { + return ((this.bitField0_ & 0x800000) == 8388608); + } + + public int getIsSmuggle() { + return this.isSmuggle_; + } + + public boolean hasDistance() { + return ((this.bitField0_ & 0x1000000) == 16777216); + } + + public double getDistance() { + return this.distance_; + } + + public boolean hasWarnColor() { + return ((this.bitField0_ & 0x2000000) == 33554432); + } + + public String getWarnColor() { + Object ref = this.warnColor_; + if (ref instanceof String) + return (String)ref; + ByteString bs = (ByteString)ref; + String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) + this.warnColor_ = s; + return s; + } + + public ByteString getWarnColorBytes() { + Object ref = this.warnColor_; + if (ref instanceof String) { + ByteString b = ByteString.copyFromUtf8((String)ref); + this.warnColor_ = b; + return b; + } + return (ByteString)ref; + } + + public boolean hasTargetType() { + return ((this.bitField0_ & 0x4000000) == 67108864); + } + + public int getTargetType() { + return this.targetType_; + } + + public boolean hasSignWindow() { + return ((this.bitField0_ & 0x8000000) == 134217728); + } + + public int getSignWindow() { + return this.signWindow_; + } + + public boolean hasIsWarn() { + return ((this.bitField0_ & 0x10000000) == 268435456); + } + + public int getIsWarn() { + return this.isWarn_; + } + + public boolean hasRtsp() { + return ((this.bitField0_ & 0x20000000) == 536870912); + } + + public String getRtsp() { + Object ref = this.rtsp_; + if (ref instanceof String) + return (String)ref; + ByteString bs = (ByteString)ref; + String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) + this.rtsp_ = s; + return s; + } + + public ByteString getRtspBytes() { + Object ref = this.rtsp_; + if (ref instanceof String) { + ByteString b = ByteString.copyFromUtf8((String)ref); + this.rtsp_ = b; + return b; + } + return (ByteString)ref; + } + + public boolean hasFllow() { + return ((this.bitField0_ & 0x40000000) == 1073741824); + } + + public int getFllow() { + return this.fllow_; + } + + public boolean hasMode() { + return ((this.bitField0_ & Integer.MIN_VALUE) == Integer.MIN_VALUE); + } + + public int getMode() { + return this.mode_; + } + + public boolean hasTimeStamp() { + return ((this.bitField1_ & 0x1) == 1); + } + + public long getTimeStamp() { + return this.timeStamp_; + } + + public boolean hasTrackby() { + return ((this.bitField1_ & 0x2) == 2); + } + + public String getTrackby() { + Object ref = this.trackby_; + if (ref instanceof String) + return (String)ref; + ByteString bs = (ByteString)ref; + String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) + this.trackby_ = s; + return s; + } + + public ByteString getTrackbyBytes() { + Object ref = this.trackby_; + if (ref instanceof String) { + ByteString b = ByteString.copyFromUtf8((String)ref); + this.trackby_ = b; + return b; + } + return (ByteString)ref; + } + + public boolean hasCameraId() { + return ((this.bitField1_ & 0x4) == 4); + } + + public int getCameraId() { + return this.cameraId_; + } + + private void initFields() { + this.systemAreaCode_ = 0; + this.systemIdentificationCode_ = 0; + this.messageType_ = MSGTYP.MSGTYP_UNDEFINED; + this.trackNumber_ = 0; + this.cartesianPosX_ = 0.0F; + this.cartesianPosY_ = 0.0F; + this.wgs84PosLat_ = 0.0D; + this.wgs84PosLong_ = 0.0D; + this.timeOfDay_ = 0.0F; + this.trackType_ = CNF.CONFIRMED_TRACK; + this.trackLastReport_ = false; + this.extrapolation_ = CST.CST_UNDEFINED; + this.trackPositionCode_ = STH.MEASURED_POSITION; + this.sigmaX_ = 0.0F; + this.sigmaY_ = 0.0F; + this.sigmaXY_ = 0.0F; + this.ampOfPriPlot_ = 0.0F; + this.cartesianTrkVelVx_ = 0.0D; + this.cartesianTrkVelVy_ = 0.0D; + this.cog_ = 0.0D; + this.sog_ = 0.0D; + this.tracks_ = RadarHistoryTracks.getDefaultInstance(); + this.status_ = 0; + this.isSmuggle_ = 0; + this.distance_ = 0.0D; + this.warnColor_ = ""; + this.targetType_ = 0; + this.signWindow_ = 0; + this.isWarn_ = 0; + this.rtsp_ = ""; + this.fllow_ = 0; + this.mode_ = 0; + this.timeStamp_ = 0L; + this.trackby_ = ""; + this.cameraId_ = 0; + } + + public final boolean isInitialized() { + byte isInitialized = this.memoizedIsInitialized; + if (isInitialized == 1) + return true; + if (isInitialized == 0) + return false; + if (!hasSystemAreaCode()) { + this.memoizedIsInitialized = 0; + return false; + } + if (!hasSystemIdentificationCode()) { + this.memoizedIsInitialized = 0; + return false; + } + if (!hasMessageType()) { + this.memoizedIsInitialized = 0; + return false; + } + if (!hasTrackNumber()) { + this.memoizedIsInitialized = 0; + return false; + } + if (!hasCartesianPosX()) { + this.memoizedIsInitialized = 0; + return false; + } + if (!hasCartesianPosY()) { + this.memoizedIsInitialized = 0; + return false; + } + if (!hasWgs84PosLat()) { + this.memoizedIsInitialized = 0; + return false; + } + if (!hasWgs84PosLong()) { + this.memoizedIsInitialized = 0; + return false; + } + if (!hasTimeOfDay()) { + this.memoizedIsInitialized = 0; + return false; + } + if (!hasCartesianTrkVelVx()) { + this.memoizedIsInitialized = 0; + return false; + } + if (!hasCartesianTrkVelVy()) { + this.memoizedIsInitialized = 0; + return false; + } + if (!hasCog()) { + this.memoizedIsInitialized = 0; + return false; + } + if (!hasSog()) { + this.memoizedIsInitialized = 0; + return false; + } + if (hasTracks() && !getTracks().isInitialized()) { + this.memoizedIsInitialized = 0; + return false; + } + this.memoizedIsInitialized = 1; + return true; + } + + public void writeTo(CodedOutputStream output) throws IOException { + getSerializedSize(); + if ((this.bitField0_ & 0x1) == 1) + output.writeInt32(1, this.systemAreaCode_); + if ((this.bitField0_ & 0x2) == 2) + output.writeInt32(2, this.systemIdentificationCode_); + if ((this.bitField0_ & 0x4) == 4) + output.writeEnum(3, this.messageType_.getNumber()); + if ((this.bitField0_ & 0x8) == 8) + output.writeUInt32(4, this.trackNumber_); + if ((this.bitField0_ & 0x10) == 16) + output.writeFloat(5, this.cartesianPosX_); + if ((this.bitField0_ & 0x20) == 32) + output.writeFloat(6, this.cartesianPosY_); + if ((this.bitField0_ & 0x40) == 64) + output.writeDouble(7, this.wgs84PosLat_); + if ((this.bitField0_ & 0x80) == 128) + output.writeDouble(8, this.wgs84PosLong_); + if ((this.bitField0_ & 0x100) == 256) + output.writeFloat(9, this.timeOfDay_); + if ((this.bitField0_ & 0x200) == 512) + output.writeEnum(10, this.trackType_.getNumber()); + if ((this.bitField0_ & 0x400) == 1024) + output.writeBool(11, this.trackLastReport_); + if ((this.bitField0_ & 0x800) == 2048) + output.writeEnum(12, this.extrapolation_.getNumber()); + if ((this.bitField0_ & 0x1000) == 4096) + output.writeEnum(13, this.trackPositionCode_.getNumber()); + if ((this.bitField0_ & 0x2000) == 8192) + output.writeFloat(14, this.sigmaX_); + if ((this.bitField0_ & 0x4000) == 16384) + output.writeFloat(15, this.sigmaY_); + if ((this.bitField0_ & 0x8000) == 32768) + output.writeFloat(16, this.sigmaXY_); + if ((this.bitField0_ & 0x10000) == 65536) + output.writeFloat(17, this.ampOfPriPlot_); + if ((this.bitField0_ & 0x20000) == 131072) + output.writeDouble(18, this.cartesianTrkVelVx_); + if ((this.bitField0_ & 0x40000) == 262144) + output.writeDouble(19, this.cartesianTrkVelVy_); + if ((this.bitField0_ & 0x80000) == 524288) + output.writeDouble(20, this.cog_); + if ((this.bitField0_ & 0x100000) == 1048576) + output.writeDouble(21, this.sog_); + if ((this.bitField0_ & 0x200000) == 2097152) + output.writeMessage(22, (MessageLite)this.tracks_); + if ((this.bitField0_ & 0x400000) == 4194304) + output.writeInt32(23, this.status_); + if ((this.bitField0_ & 0x800000) == 8388608) + output.writeInt32(24, this.isSmuggle_); + if ((this.bitField0_ & 0x1000000) == 16777216) + output.writeDouble(25, this.distance_); + if ((this.bitField0_ & 0x2000000) == 33554432) + output.writeBytes(26, getWarnColorBytes()); + if ((this.bitField0_ & 0x4000000) == 67108864) + output.writeInt32(27, this.targetType_); + if ((this.bitField0_ & 0x8000000) == 134217728) + output.writeInt32(28, this.signWindow_); + if ((this.bitField0_ & 0x10000000) == 268435456) + output.writeInt32(29, this.isWarn_); + if ((this.bitField0_ & 0x20000000) == 536870912) + output.writeBytes(30, getRtspBytes()); + if ((this.bitField0_ & 0x40000000) == 1073741824) + output.writeInt32(31, this.fllow_); + if ((this.bitField0_ & Integer.MIN_VALUE) == Integer.MIN_VALUE) + output.writeInt32(32, this.mode_); + if ((this.bitField1_ & 0x1) == 1) + output.writeInt64(33, this.timeStamp_); + if ((this.bitField1_ & 0x2) == 2) + output.writeBytes(34, getTrackbyBytes()); + if ((this.bitField1_ & 0x4) == 4) + output.writeInt32(35, this.cameraId_); + getUnknownFields().writeTo(output); + } + + public int getSerializedSize() { + int size = this.memoizedSerializedSize; + if (size != -1) + return size; + size = 0; + if ((this.bitField0_ & 0x1) == 1) + size += CodedOutputStream.computeInt32Size(1, this.systemAreaCode_); + if ((this.bitField0_ & 0x2) == 2) + size += CodedOutputStream.computeInt32Size(2, this.systemIdentificationCode_); + if ((this.bitField0_ & 0x4) == 4) + size += CodedOutputStream.computeEnumSize(3, this.messageType_.getNumber()); + if ((this.bitField0_ & 0x8) == 8) + size += CodedOutputStream.computeUInt32Size(4, this.trackNumber_); + if ((this.bitField0_ & 0x10) == 16) + size += CodedOutputStream.computeFloatSize(5, this.cartesianPosX_); + if ((this.bitField0_ & 0x20) == 32) + size += CodedOutputStream.computeFloatSize(6, this.cartesianPosY_); + if ((this.bitField0_ & 0x40) == 64) + size += CodedOutputStream.computeDoubleSize(7, this.wgs84PosLat_); + if ((this.bitField0_ & 0x80) == 128) + size += CodedOutputStream.computeDoubleSize(8, this.wgs84PosLong_); + if ((this.bitField0_ & 0x100) == 256) + size += CodedOutputStream.computeFloatSize(9, this.timeOfDay_); + if ((this.bitField0_ & 0x200) == 512) + size += CodedOutputStream.computeEnumSize(10, this.trackType_.getNumber()); + if ((this.bitField0_ & 0x400) == 1024) + size += CodedOutputStream.computeBoolSize(11, this.trackLastReport_); + if ((this.bitField0_ & 0x800) == 2048) + size += CodedOutputStream.computeEnumSize(12, this.extrapolation_.getNumber()); + if ((this.bitField0_ & 0x1000) == 4096) + size += CodedOutputStream.computeEnumSize(13, this.trackPositionCode_.getNumber()); + if ((this.bitField0_ & 0x2000) == 8192) + size += CodedOutputStream.computeFloatSize(14, this.sigmaX_); + if ((this.bitField0_ & 0x4000) == 16384) + size += CodedOutputStream.computeFloatSize(15, this.sigmaY_); + if ((this.bitField0_ & 0x8000) == 32768) + size += CodedOutputStream.computeFloatSize(16, this.sigmaXY_); + if ((this.bitField0_ & 0x10000) == 65536) + size += CodedOutputStream.computeFloatSize(17, this.ampOfPriPlot_); + if ((this.bitField0_ & 0x20000) == 131072) + size += CodedOutputStream.computeDoubleSize(18, this.cartesianTrkVelVx_); + if ((this.bitField0_ & 0x40000) == 262144) + size += CodedOutputStream.computeDoubleSize(19, this.cartesianTrkVelVy_); + if ((this.bitField0_ & 0x80000) == 524288) + size += CodedOutputStream.computeDoubleSize(20, this.cog_); + if ((this.bitField0_ & 0x100000) == 1048576) + size += CodedOutputStream.computeDoubleSize(21, this.sog_); + if ((this.bitField0_ & 0x200000) == 2097152) + size += CodedOutputStream.computeMessageSize(22, (MessageLite)this.tracks_); + if ((this.bitField0_ & 0x400000) == 4194304) + size += CodedOutputStream.computeInt32Size(23, this.status_); + if ((this.bitField0_ & 0x800000) == 8388608) + size += CodedOutputStream.computeInt32Size(24, this.isSmuggle_); + if ((this.bitField0_ & 0x1000000) == 16777216) + size += CodedOutputStream.computeDoubleSize(25, this.distance_); + if ((this.bitField0_ & 0x2000000) == 33554432) + size += CodedOutputStream.computeBytesSize(26, getWarnColorBytes()); + if ((this.bitField0_ & 0x4000000) == 67108864) + size += CodedOutputStream.computeInt32Size(27, this.targetType_); + if ((this.bitField0_ & 0x8000000) == 134217728) + size += CodedOutputStream.computeInt32Size(28, this.signWindow_); + if ((this.bitField0_ & 0x10000000) == 268435456) + size += CodedOutputStream.computeInt32Size(29, this.isWarn_); + if ((this.bitField0_ & 0x20000000) == 536870912) + size += CodedOutputStream.computeBytesSize(30, getRtspBytes()); + if ((this.bitField0_ & 0x40000000) == 1073741824) + size += CodedOutputStream.computeInt32Size(31, this.fllow_); + if ((this.bitField0_ & Integer.MIN_VALUE) == Integer.MIN_VALUE) + size += CodedOutputStream.computeInt32Size(32, this.mode_); + if ((this.bitField1_ & 0x1) == 1) + size += CodedOutputStream.computeInt64Size(33, this.timeStamp_); + if ((this.bitField1_ & 0x2) == 2) + size += CodedOutputStream.computeBytesSize(34, getTrackbyBytes()); + if ((this.bitField1_ & 0x4) == 4) + size += CodedOutputStream.computeInt32Size(35, this.cameraId_); + size += getUnknownFields().getSerializedSize(); + this.memoizedSerializedSize = size; + return size; + } + + protected Object writeReplace() throws ObjectStreamException { + return super.writeReplace(); + } + + public static TrackPoint parseFrom(ByteString data) throws InvalidProtocolBufferException { + return (TrackPoint)PARSER.parseFrom(data); + } + + public static TrackPoint parseFrom(ByteString data, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + return (TrackPoint)PARSER.parseFrom(data, extensionRegistry); + } + + public static TrackPoint parseFrom(byte[] data) throws InvalidProtocolBufferException { + return (TrackPoint)PARSER.parseFrom(data); + } + + public static TrackPoint parseFrom(byte[] data, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + return (TrackPoint)PARSER.parseFrom(data, extensionRegistry); + } + + public static TrackPoint parseFrom(InputStream input) throws IOException { + return (TrackPoint)PARSER.parseFrom(input); + } + + public static TrackPoint parseFrom(InputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + return (TrackPoint)PARSER.parseFrom(input, extensionRegistry); + } + + public static TrackPoint parseDelimitedFrom(InputStream input) throws IOException { + return (TrackPoint)PARSER.parseDelimitedFrom(input); + } + + public static TrackPoint parseDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + return (TrackPoint)PARSER.parseDelimitedFrom(input, extensionRegistry); + } + + public static TrackPoint parseFrom(CodedInputStream input) throws IOException { + return (TrackPoint)PARSER.parseFrom(input); + } + + public static TrackPoint parseFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + return (TrackPoint)PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { + return Builder.create(); + } + + public Builder newBuilderForType() { + return newBuilder(); + } + + public static Builder newBuilder(TrackPoint prototype) { + return newBuilder().mergeFrom(prototype); + } + + public Builder toBuilder() { + return newBuilder(this); + } + + protected Builder newBuilderForType(BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + + public static final class Builder extends GeneratedMessage.Builder implements TrackPointOrBuilder { + private int bitField0_; + + private int bitField1_; + + private int systemAreaCode_; + + private int systemIdentificationCode_; + + private MSGTYP messageType_; + + private int trackNumber_; + + private float cartesianPosX_; + + private float cartesianPosY_; + + private double wgs84PosLat_; + + private double wgs84PosLong_; + + private float timeOfDay_; + + private CNF trackType_; + + private boolean trackLastReport_; + + private CST extrapolation_; + + private STH trackPositionCode_; + + private float sigmaX_; + + private float sigmaY_; + + private float sigmaXY_; + + private float ampOfPriPlot_; + + private double cartesianTrkVelVx_; + + private double cartesianTrkVelVy_; + + private double cog_; + + private double sog_; + + private RadarHistoryTracks tracks_; + + private SingleFieldBuilder tracksBuilder_; + + private int status_; + + private int isSmuggle_; + + private double distance_; + + private Object warnColor_; + + private int targetType_; + + private int signWindow_; + + private int isWarn_; + + private Object rtsp_; + + private int fllow_; + + private int mode_; + + private long timeStamp_; + + private Object trackby_; + + private int cameraId_; + + public static final Descriptors.Descriptor getDescriptor() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_TrackPoint_descriptor; + } + + protected FieldAccessorTable internalGetFieldAccessorTable() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_TrackPoint_fieldAccessorTable.ensureFieldAccessorsInitialized(TrackPoint.class, Builder.class); + } + + private Builder() { + this.messageType_ = MSGTYP.MSGTYP_UNDEFINED; + this.trackType_ = CNF.CONFIRMED_TRACK; + this.extrapolation_ = CST.CST_UNDEFINED; + this.trackPositionCode_ = STH.MEASURED_POSITION; + this.tracks_ = RadarHistoryTracks.getDefaultInstance(); + this.warnColor_ = ""; + this.rtsp_ = ""; + this.trackby_ = ""; + maybeForceBuilderInitialization(); + } + + private Builder(BuilderParent parent) { + super(parent); + this.messageType_ = MSGTYP.MSGTYP_UNDEFINED; + this.trackType_ = CNF.CONFIRMED_TRACK; + this.extrapolation_ = CST.CST_UNDEFINED; + this.trackPositionCode_ = STH.MEASURED_POSITION; + this.tracks_ = RadarHistoryTracks.getDefaultInstance(); + this.warnColor_ = ""; + this.rtsp_ = ""; + this.trackby_ = ""; + maybeForceBuilderInitialization(); + } + + private void maybeForceBuilderInitialization() { + if (TrackPoint.alwaysUseFieldBuilders) + getTracksFieldBuilder(); + } + + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + this.systemAreaCode_ = 0; + this.bitField0_ &= 0xFFFFFFFE; + this.systemIdentificationCode_ = 0; + this.bitField0_ &= 0xFFFFFFFD; + this.messageType_ = MSGTYP.MSGTYP_UNDEFINED; + this.bitField0_ &= 0xFFFFFFFB; + this.trackNumber_ = 0; + this.bitField0_ &= 0xFFFFFFF7; + this.cartesianPosX_ = 0.0F; + this.bitField0_ &= 0xFFFFFFEF; + this.cartesianPosY_ = 0.0F; + this.bitField0_ &= 0xFFFFFFDF; + this.wgs84PosLat_ = 0.0D; + this.bitField0_ &= 0xFFFFFFBF; + this.wgs84PosLong_ = 0.0D; + this.bitField0_ &= 0xFFFFFF7F; + this.timeOfDay_ = 0.0F; + this.bitField0_ &= 0xFFFFFEFF; + this.trackType_ = CNF.CONFIRMED_TRACK; + this.bitField0_ &= 0xFFFFFDFF; + this.trackLastReport_ = false; + this.bitField0_ &= 0xFFFFFBFF; + this.extrapolation_ = CST.CST_UNDEFINED; + this.bitField0_ &= 0xFFFFF7FF; + this.trackPositionCode_ = STH.MEASURED_POSITION; + this.bitField0_ &= 0xFFFFEFFF; + this.sigmaX_ = 0.0F; + this.bitField0_ &= 0xFFFFDFFF; + this.sigmaY_ = 0.0F; + this.bitField0_ &= 0xFFFFBFFF; + this.sigmaXY_ = 0.0F; + this.bitField0_ &= 0xFFFF7FFF; + this.ampOfPriPlot_ = 0.0F; + this.bitField0_ &= 0xFFFEFFFF; + this.cartesianTrkVelVx_ = 0.0D; + this.bitField0_ &= 0xFFFDFFFF; + this.cartesianTrkVelVy_ = 0.0D; + this.bitField0_ &= 0xFFFBFFFF; + this.cog_ = 0.0D; + this.bitField0_ &= 0xFFF7FFFF; + this.sog_ = 0.0D; + this.bitField0_ &= 0xFFEFFFFF; + if (this.tracksBuilder_ == null) { + this.tracks_ = RadarHistoryTracks.getDefaultInstance(); + } else { + this.tracksBuilder_.clear(); + } + this.bitField0_ &= 0xFFDFFFFF; + this.status_ = 0; + this.bitField0_ &= 0xFFBFFFFF; + this.isSmuggle_ = 0; + this.bitField0_ &= 0xFF7FFFFF; + this.distance_ = 0.0D; + this.bitField0_ &= 0xFEFFFFFF; + this.warnColor_ = ""; + this.bitField0_ &= 0xFDFFFFFF; + this.targetType_ = 0; + this.bitField0_ &= 0xFBFFFFFF; + this.signWindow_ = 0; + this.bitField0_ &= 0xF7FFFFFF; + this.isWarn_ = 0; + this.bitField0_ &= 0xEFFFFFFF; + this.rtsp_ = ""; + this.bitField0_ &= 0xDFFFFFFF; + this.fllow_ = 0; + this.bitField0_ &= 0xBFFFFFFF; + this.mode_ = 0; + this.bitField0_ &= Integer.MAX_VALUE; + this.timeStamp_ = 0L; + this.bitField1_ &= 0xFFFFFFFE; + this.trackby_ = ""; + this.bitField1_ &= 0xFFFFFFFD; + this.cameraId_ = 0; + this.bitField1_ &= 0xFFFFFFFB; + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public Descriptors.Descriptor getDescriptorForType() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_TrackPoint_descriptor; + } + + public TrackPoint getDefaultInstanceForType() { + return TrackPoint.getDefaultInstance(); + } + + public TrackPoint build() { + TrackPoint result = buildPartial(); + if (!result.isInitialized()) + throw newUninitializedMessageException(result); + return result; + } + + public TrackPoint buildPartial() { + TrackPoint result = new TrackPoint(this); + int from_bitField0_ = this.bitField0_; + int from_bitField1_ = this.bitField1_; + int to_bitField0_ = 0; + int to_bitField1_ = 0; + if ((from_bitField0_ & 0x1) == 1) + to_bitField0_ |= 0x1; + result.systemAreaCode_ = this.systemAreaCode_; + if ((from_bitField0_ & 0x2) == 2) + to_bitField0_ |= 0x2; + result.systemIdentificationCode_ = this.systemIdentificationCode_; + if ((from_bitField0_ & 0x4) == 4) + to_bitField0_ |= 0x4; + result.messageType_ = this.messageType_; + if ((from_bitField0_ & 0x8) == 8) + to_bitField0_ |= 0x8; + result.trackNumber_ = this.trackNumber_; + if ((from_bitField0_ & 0x10) == 16) + to_bitField0_ |= 0x10; + result.cartesianPosX_ = this.cartesianPosX_; + if ((from_bitField0_ & 0x20) == 32) + to_bitField0_ |= 0x20; + result.cartesianPosY_ = this.cartesianPosY_; + if ((from_bitField0_ & 0x40) == 64) + to_bitField0_ |= 0x40; + result.wgs84PosLat_ = this.wgs84PosLat_; + if ((from_bitField0_ & 0x80) == 128) + to_bitField0_ |= 0x80; + result.wgs84PosLong_ = this.wgs84PosLong_; + if ((from_bitField0_ & 0x100) == 256) + to_bitField0_ |= 0x100; + result.timeOfDay_ = this.timeOfDay_; + if ((from_bitField0_ & 0x200) == 512) + to_bitField0_ |= 0x200; + result.trackType_ = this.trackType_; + if ((from_bitField0_ & 0x400) == 1024) + to_bitField0_ |= 0x400; + result.trackLastReport_ = this.trackLastReport_; + if ((from_bitField0_ & 0x800) == 2048) + to_bitField0_ |= 0x800; + result.extrapolation_ = this.extrapolation_; + if ((from_bitField0_ & 0x1000) == 4096) + to_bitField0_ |= 0x1000; + result.trackPositionCode_ = this.trackPositionCode_; + if ((from_bitField0_ & 0x2000) == 8192) + to_bitField0_ |= 0x2000; + result.sigmaX_ = this.sigmaX_; + if ((from_bitField0_ & 0x4000) == 16384) + to_bitField0_ |= 0x4000; + result.sigmaY_ = this.sigmaY_; + if ((from_bitField0_ & 0x8000) == 32768) + to_bitField0_ |= 0x8000; + result.sigmaXY_ = this.sigmaXY_; + if ((from_bitField0_ & 0x10000) == 65536) + to_bitField0_ |= 0x10000; + result.ampOfPriPlot_ = this.ampOfPriPlot_; + if ((from_bitField0_ & 0x20000) == 131072) + to_bitField0_ |= 0x20000; + result.cartesianTrkVelVx_ = this.cartesianTrkVelVx_; + if ((from_bitField0_ & 0x40000) == 262144) + to_bitField0_ |= 0x40000; + result.cartesianTrkVelVy_ = this.cartesianTrkVelVy_; + if ((from_bitField0_ & 0x80000) == 524288) + to_bitField0_ |= 0x80000; + result.cog_ = this.cog_; + if ((from_bitField0_ & 0x100000) == 1048576) + to_bitField0_ |= 0x100000; + result.sog_ = this.sog_; + if ((from_bitField0_ & 0x200000) == 2097152) + to_bitField0_ |= 0x200000; + if (this.tracksBuilder_ == null) { + result.tracks_ = this.tracks_; + } else { + result.tracks_ = (RadarHistoryTracks)this.tracksBuilder_.build(); + } + if ((from_bitField0_ & 0x400000) == 4194304) + to_bitField0_ |= 0x400000; + result.status_ = this.status_; + if ((from_bitField0_ & 0x800000) == 8388608) + to_bitField0_ |= 0x800000; + result.isSmuggle_ = this.isSmuggle_; + if ((from_bitField0_ & 0x1000000) == 16777216) + to_bitField0_ |= 0x1000000; + result.distance_ = this.distance_; + if ((from_bitField0_ & 0x2000000) == 33554432) + to_bitField0_ |= 0x2000000; + result.warnColor_ = this.warnColor_; + if ((from_bitField0_ & 0x4000000) == 67108864) + to_bitField0_ |= 0x4000000; + result.targetType_ = this.targetType_; + if ((from_bitField0_ & 0x8000000) == 134217728) + to_bitField0_ |= 0x8000000; + result.signWindow_ = this.signWindow_; + if ((from_bitField0_ & 0x10000000) == 268435456) + to_bitField0_ |= 0x10000000; + result.isWarn_ = this.isWarn_; + if ((from_bitField0_ & 0x20000000) == 536870912) + to_bitField0_ |= 0x20000000; + result.rtsp_ = this.rtsp_; + if ((from_bitField0_ & 0x40000000) == 1073741824) + to_bitField0_ |= 0x40000000; + result.fllow_ = this.fllow_; + if ((from_bitField0_ & Integer.MIN_VALUE) == Integer.MIN_VALUE) + to_bitField0_ |= Integer.MIN_VALUE; + result.mode_ = this.mode_; + if ((from_bitField1_ & 0x1) == 1) + to_bitField1_ |= 0x1; + result.timeStamp_ = this.timeStamp_; + if ((from_bitField1_ & 0x2) == 2) + to_bitField1_ |= 0x2; + result.trackby_ = this.trackby_; + if ((from_bitField1_ & 0x4) == 4) + to_bitField1_ |= 0x4; + result.cameraId_ = this.cameraId_; + result.bitField0_ = to_bitField0_; + result.bitField1_ = to_bitField1_; + onBuilt(); + return result; + } + + public Builder mergeFrom(Message other) { + if (other instanceof TrackPoint) + return mergeFrom((TrackPoint)other); + super.mergeFrom(other); + return this; + } + + public Builder mergeFrom(TrackPoint other) { + if (other == TrackPoint.getDefaultInstance()) + return this; + if (other.hasSystemAreaCode()) + setSystemAreaCode(other.getSystemAreaCode()); + if (other.hasSystemIdentificationCode()) + setSystemIdentificationCode(other.getSystemIdentificationCode()); + if (other.hasMessageType()) + setMessageType(other.getMessageType()); + if (other.hasTrackNumber()) + setTrackNumber(other.getTrackNumber()); + if (other.hasCartesianPosX()) + setCartesianPosX(other.getCartesianPosX()); + if (other.hasCartesianPosY()) + setCartesianPosY(other.getCartesianPosY()); + if (other.hasWgs84PosLat()) + setWgs84PosLat(other.getWgs84PosLat()); + if (other.hasWgs84PosLong()) + setWgs84PosLong(other.getWgs84PosLong()); + if (other.hasTimeOfDay()) + setTimeOfDay(other.getTimeOfDay()); + if (other.hasTrackType()) + setTrackType(other.getTrackType()); + if (other.hasTrackLastReport()) + setTrackLastReport(other.getTrackLastReport()); + if (other.hasExtrapolation()) + setExtrapolation(other.getExtrapolation()); + if (other.hasTrackPositionCode()) + setTrackPositionCode(other.getTrackPositionCode()); + if (other.hasSigmaX()) + setSigmaX(other.getSigmaX()); + if (other.hasSigmaY()) + setSigmaY(other.getSigmaY()); + if (other.hasSigmaXY()) + setSigmaXY(other.getSigmaXY()); + if (other.hasAmpOfPriPlot()) + setAmpOfPriPlot(other.getAmpOfPriPlot()); + if (other.hasCartesianTrkVelVx()) + setCartesianTrkVelVx(other.getCartesianTrkVelVx()); + if (other.hasCartesianTrkVelVy()) + setCartesianTrkVelVy(other.getCartesianTrkVelVy()); + if (other.hasCog()) + setCog(other.getCog()); + if (other.hasSog()) + setSog(other.getSog()); + if (other.hasTracks()) + mergeTracks(other.getTracks()); + if (other.hasStatus()) + setStatus(other.getStatus()); + if (other.hasIsSmuggle()) + setIsSmuggle(other.getIsSmuggle()); + if (other.hasDistance()) + setDistance(other.getDistance()); + if (other.hasWarnColor()) { + this.bitField0_ |= 0x2000000; + this.warnColor_ = other.warnColor_; + onChanged(); + } + if (other.hasTargetType()) + setTargetType(other.getTargetType()); + if (other.hasSignWindow()) + setSignWindow(other.getSignWindow()); + if (other.hasIsWarn()) + setIsWarn(other.getIsWarn()); + if (other.hasRtsp()) { + this.bitField0_ |= 0x20000000; + this.rtsp_ = other.rtsp_; + onChanged(); + } + if (other.hasFllow()) + setFllow(other.getFllow()); + if (other.hasMode()) + setMode(other.getMode()); + if (other.hasTimeStamp()) + setTimeStamp(other.getTimeStamp()); + if (other.hasTrackby()) { + this.bitField1_ |= 0x2; + this.trackby_ = other.trackby_; + onChanged(); + } + if (other.hasCameraId()) + setCameraId(other.getCameraId()); + mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasSystemAreaCode()) + return false; + if (!hasSystemIdentificationCode()) + return false; + if (!hasMessageType()) + return false; + if (!hasTrackNumber()) + return false; + if (!hasCartesianPosX()) + return false; + if (!hasCartesianPosY()) + return false; + if (!hasWgs84PosLat()) + return false; + if (!hasWgs84PosLong()) + return false; + if (!hasTimeOfDay()) + return false; + if (!hasCartesianTrkVelVx()) + return false; + if (!hasCartesianTrkVelVy()) + return false; + if (!hasCog()) + return false; + if (!hasSog()) + return false; + if (hasTracks() && !getTracks().isInitialized()) + return false; + return true; + } + + public Builder mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + TrackPoint parsedMessage = null; + try { + parsedMessage = (TrackPoint) TrackPoint.PARSER.parsePartialFrom(input, extensionRegistry); + } catch (InvalidProtocolBufferException e) { + parsedMessage = (TrackPoint)e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) + mergeFrom(parsedMessage); + } + return this; + } + + public boolean hasSystemAreaCode() { + return ((this.bitField0_ & 0x1) == 1); + } + + public int getSystemAreaCode() { + return this.systemAreaCode_; + } + + public Builder setSystemAreaCode(int value) { + this.bitField0_ |= 0x1; + this.systemAreaCode_ = value; + onChanged(); + return this; + } + + public Builder clearSystemAreaCode() { + this.bitField0_ &= 0xFFFFFFFE; + this.systemAreaCode_ = 0; + onChanged(); + return this; + } + + public boolean hasSystemIdentificationCode() { + return ((this.bitField0_ & 0x2) == 2); + } + + public int getSystemIdentificationCode() { + return this.systemIdentificationCode_; + } + + public Builder setSystemIdentificationCode(int value) { + this.bitField0_ |= 0x2; + this.systemIdentificationCode_ = value; + onChanged(); + return this; + } + + public Builder clearSystemIdentificationCode() { + this.bitField0_ &= 0xFFFFFFFD; + this.systemIdentificationCode_ = 0; + onChanged(); + return this; + } + + public boolean hasMessageType() { + return ((this.bitField0_ & 0x4) == 4); + } + + public MSGTYP getMessageType() { + return this.messageType_; + } + + public Builder setMessageType(MSGTYP value) { + if (value == null) + throw new NullPointerException(); + this.bitField0_ |= 0x4; + this.messageType_ = value; + onChanged(); + return this; + } + + public Builder clearMessageType() { + this.bitField0_ &= 0xFFFFFFFB; + this.messageType_ = MSGTYP.MSGTYP_UNDEFINED; + onChanged(); + return this; + } + + public boolean hasTrackNumber() { + return ((this.bitField0_ & 0x8) == 8); + } + + public int getTrackNumber() { + return this.trackNumber_; + } + + public Builder setTrackNumber(int value) { + this.bitField0_ |= 0x8; + this.trackNumber_ = value; + onChanged(); + return this; + } + + public Builder clearTrackNumber() { + this.bitField0_ &= 0xFFFFFFF7; + this.trackNumber_ = 0; + onChanged(); + return this; + } + + public boolean hasCartesianPosX() { + return ((this.bitField0_ & 0x10) == 16); + } + + public float getCartesianPosX() { + return this.cartesianPosX_; + } + + public Builder setCartesianPosX(float value) { + this.bitField0_ |= 0x10; + this.cartesianPosX_ = value; + onChanged(); + return this; + } + + public Builder clearCartesianPosX() { + this.bitField0_ &= 0xFFFFFFEF; + this.cartesianPosX_ = 0.0F; + onChanged(); + return this; + } + + public boolean hasCartesianPosY() { + return ((this.bitField0_ & 0x20) == 32); + } + + public float getCartesianPosY() { + return this.cartesianPosY_; + } + + public Builder setCartesianPosY(float value) { + this.bitField0_ |= 0x20; + this.cartesianPosY_ = value; + onChanged(); + return this; + } + + public Builder clearCartesianPosY() { + this.bitField0_ &= 0xFFFFFFDF; + this.cartesianPosY_ = 0.0F; + onChanged(); + return this; + } + + public boolean hasWgs84PosLat() { + return ((this.bitField0_ & 0x40) == 64); + } + + public double getWgs84PosLat() { + return this.wgs84PosLat_; + } + + public Builder setWgs84PosLat(double value) { + this.bitField0_ |= 0x40; + this.wgs84PosLat_ = value; + onChanged(); + return this; + } + + public Builder clearWgs84PosLat() { + this.bitField0_ &= 0xFFFFFFBF; + this.wgs84PosLat_ = 0.0D; + onChanged(); + return this; + } + + public boolean hasWgs84PosLong() { + return ((this.bitField0_ & 0x80) == 128); + } + + public double getWgs84PosLong() { + return this.wgs84PosLong_; + } + + public Builder setWgs84PosLong(double value) { + this.bitField0_ |= 0x80; + this.wgs84PosLong_ = value; + onChanged(); + return this; + } + + public Builder clearWgs84PosLong() { + this.bitField0_ &= 0xFFFFFF7F; + this.wgs84PosLong_ = 0.0D; + onChanged(); + return this; + } + + public boolean hasTimeOfDay() { + return ((this.bitField0_ & 0x100) == 256); + } + + public float getTimeOfDay() { + return this.timeOfDay_; + } + + public Builder setTimeOfDay(float value) { + this.bitField0_ |= 0x100; + this.timeOfDay_ = value; + onChanged(); + return this; + } + + public Builder clearTimeOfDay() { + this.bitField0_ &= 0xFFFFFEFF; + this.timeOfDay_ = 0.0F; + onChanged(); + return this; + } + + public boolean hasTrackType() { + return ((this.bitField0_ & 0x200) == 512); + } + + public CNF getTrackType() { + return this.trackType_; + } + + public Builder setTrackType(CNF value) { + if (value == null) + throw new NullPointerException(); + this.bitField0_ |= 0x200; + this.trackType_ = value; + onChanged(); + return this; + } + + public Builder clearTrackType() { + this.bitField0_ &= 0xFFFFFDFF; + this.trackType_ = CNF.CONFIRMED_TRACK; + onChanged(); + return this; + } + + public boolean hasTrackLastReport() { + return ((this.bitField0_ & 0x400) == 1024); + } + + public boolean getTrackLastReport() { + return this.trackLastReport_; + } + + public Builder setTrackLastReport(boolean value) { + this.bitField0_ |= 0x400; + this.trackLastReport_ = value; + onChanged(); + return this; + } + + public Builder clearTrackLastReport() { + this.bitField0_ &= 0xFFFFFBFF; + this.trackLastReport_ = false; + onChanged(); + return this; + } + + public boolean hasExtrapolation() { + return ((this.bitField0_ & 0x800) == 2048); + } + + public CST getExtrapolation() { + return this.extrapolation_; + } + + public Builder setExtrapolation(CST value) { + if (value == null) + throw new NullPointerException(); + this.bitField0_ |= 0x800; + this.extrapolation_ = value; + onChanged(); + return this; + } + + public Builder clearExtrapolation() { + this.bitField0_ &= 0xFFFFF7FF; + this.extrapolation_ = CST.CST_UNDEFINED; + onChanged(); + return this; + } + + public boolean hasTrackPositionCode() { + return ((this.bitField0_ & 0x1000) == 4096); + } + + public STH getTrackPositionCode() { + return this.trackPositionCode_; + } + + public Builder setTrackPositionCode(STH value) { + if (value == null) + throw new NullPointerException(); + this.bitField0_ |= 0x1000; + this.trackPositionCode_ = value; + onChanged(); + return this; + } + + public Builder clearTrackPositionCode() { + this.bitField0_ &= 0xFFFFEFFF; + this.trackPositionCode_ = STH.MEASURED_POSITION; + onChanged(); + return this; + } + + public boolean hasSigmaX() { + return ((this.bitField0_ & 0x2000) == 8192); + } + + public float getSigmaX() { + return this.sigmaX_; + } + + public Builder setSigmaX(float value) { + this.bitField0_ |= 0x2000; + this.sigmaX_ = value; + onChanged(); + return this; + } + + public Builder clearSigmaX() { + this.bitField0_ &= 0xFFFFDFFF; + this.sigmaX_ = 0.0F; + onChanged(); + return this; + } + + public boolean hasSigmaY() { + return ((this.bitField0_ & 0x4000) == 16384); + } + + public float getSigmaY() { + return this.sigmaY_; + } + + public Builder setSigmaY(float value) { + this.bitField0_ |= 0x4000; + this.sigmaY_ = value; + onChanged(); + return this; + } + + public Builder clearSigmaY() { + this.bitField0_ &= 0xFFFFBFFF; + this.sigmaY_ = 0.0F; + onChanged(); + return this; + } + + public boolean hasSigmaXY() { + return ((this.bitField0_ & 0x8000) == 32768); + } + + public float getSigmaXY() { + return this.sigmaXY_; + } + + public Builder setSigmaXY(float value) { + this.bitField0_ |= 0x8000; + this.sigmaXY_ = value; + onChanged(); + return this; + } + + public Builder clearSigmaXY() { + this.bitField0_ &= 0xFFFF7FFF; + this.sigmaXY_ = 0.0F; + onChanged(); + return this; + } + + public boolean hasAmpOfPriPlot() { + return ((this.bitField0_ & 0x10000) == 65536); + } + + public float getAmpOfPriPlot() { + return this.ampOfPriPlot_; + } + + public Builder setAmpOfPriPlot(float value) { + this.bitField0_ |= 0x10000; + this.ampOfPriPlot_ = value; + onChanged(); + return this; + } + + public Builder clearAmpOfPriPlot() { + this.bitField0_ &= 0xFFFEFFFF; + this.ampOfPriPlot_ = 0.0F; + onChanged(); + return this; + } + + public boolean hasCartesianTrkVelVx() { + return ((this.bitField0_ & 0x20000) == 131072); + } + + public double getCartesianTrkVelVx() { + return this.cartesianTrkVelVx_; + } + + public Builder setCartesianTrkVelVx(double value) { + this.bitField0_ |= 0x20000; + this.cartesianTrkVelVx_ = value; + onChanged(); + return this; + } + + public Builder clearCartesianTrkVelVx() { + this.bitField0_ &= 0xFFFDFFFF; + this.cartesianTrkVelVx_ = 0.0D; + onChanged(); + return this; + } + + public boolean hasCartesianTrkVelVy() { + return ((this.bitField0_ & 0x40000) == 262144); + } + + public double getCartesianTrkVelVy() { + return this.cartesianTrkVelVy_; + } + + public Builder setCartesianTrkVelVy(double value) { + this.bitField0_ |= 0x40000; + this.cartesianTrkVelVy_ = value; + onChanged(); + return this; + } + + public Builder clearCartesianTrkVelVy() { + this.bitField0_ &= 0xFFFBFFFF; + this.cartesianTrkVelVy_ = 0.0D; + onChanged(); + return this; + } + + public boolean hasCog() { + return ((this.bitField0_ & 0x80000) == 524288); + } + + public double getCog() { + return this.cog_; + } + + public Builder setCog(double value) { + this.bitField0_ |= 0x80000; + this.cog_ = value; + onChanged(); + return this; + } + + public Builder clearCog() { + this.bitField0_ &= 0xFFF7FFFF; + this.cog_ = 0.0D; + onChanged(); + return this; + } + + public boolean hasSog() { + return ((this.bitField0_ & 0x100000) == 1048576); + } + + public double getSog() { + return this.sog_; + } + + public Builder setSog(double value) { + this.bitField0_ |= 0x100000; + this.sog_ = value; + onChanged(); + return this; + } + + public Builder clearSog() { + this.bitField0_ &= 0xFFEFFFFF; + this.sog_ = 0.0D; + onChanged(); + return this; + } + + public boolean hasTracks() { + return ((this.bitField0_ & 0x200000) == 2097152); + } + + public RadarHistoryTracks getTracks() { + if (this.tracksBuilder_ == null) + return this.tracks_; + return (RadarHistoryTracks)this.tracksBuilder_.getMessage(); + } + + public Builder setTracks(RadarHistoryTracks value) { + if (this.tracksBuilder_ == null) { + if (value == null) + throw new NullPointerException(); + this.tracks_ = value; + onChanged(); + } else { + this.tracksBuilder_.setMessage(value); + } + this.bitField0_ |= 0x200000; + return this; + } + + public Builder setTracks(RadarHistoryTracks.Builder builderForValue) { + if (this.tracksBuilder_ == null) { + this.tracks_ = builderForValue.build(); + onChanged(); + } else { + this.tracksBuilder_.setMessage(builderForValue.build()); + } + this.bitField0_ |= 0x200000; + return this; + } + + public Builder mergeTracks(RadarHistoryTracks value) { + if (this.tracksBuilder_ == null) { + if ((this.bitField0_ & 0x200000) == 2097152 && this.tracks_ != RadarHistoryTracks.getDefaultInstance()) { + this.tracks_ = RadarHistoryTracks.newBuilder(this.tracks_).mergeFrom(value).buildPartial(); + } else { + this.tracks_ = value; + } + onChanged(); + } else { + this.tracksBuilder_.mergeFrom(value); + } + this.bitField0_ |= 0x200000; + return this; + } + + public Builder clearTracks() { + if (this.tracksBuilder_ == null) { + this.tracks_ = RadarHistoryTracks.getDefaultInstance(); + onChanged(); + } else { + this.tracksBuilder_.clear(); + } + this.bitField0_ &= 0xFFDFFFFF; + return this; + } + + public RadarHistoryTracks.Builder getTracksBuilder() { + this.bitField0_ |= 0x200000; + onChanged(); + return (RadarHistoryTracks.Builder)getTracksFieldBuilder().getBuilder(); + } + + public RadarHistoryTracksOrBuilder getTracksOrBuilder() { + if (this.tracksBuilder_ != null) + return (RadarHistoryTracksOrBuilder)this.tracksBuilder_.getMessageOrBuilder(); + return this.tracks_; + } + + private SingleFieldBuilder getTracksFieldBuilder() { + if (this.tracksBuilder_ == null) { + this.tracksBuilder_ = new SingleFieldBuilder(getTracks(), getParentForChildren(), isClean()); + this.tracks_ = null; + } + return this.tracksBuilder_; + } + + public boolean hasStatus() { + return ((this.bitField0_ & 0x400000) == 4194304); + } + + public int getStatus() { + return this.status_; + } + + public Builder setStatus(int value) { + this.bitField0_ |= 0x400000; + this.status_ = value; + onChanged(); + return this; + } + + public Builder clearStatus() { + this.bitField0_ &= 0xFFBFFFFF; + this.status_ = 0; + onChanged(); + return this; + } + + public boolean hasIsSmuggle() { + return ((this.bitField0_ & 0x800000) == 8388608); + } + + public int getIsSmuggle() { + return this.isSmuggle_; + } + + public Builder setIsSmuggle(int value) { + this.bitField0_ |= 0x800000; + this.isSmuggle_ = value; + onChanged(); + return this; + } + + public Builder clearIsSmuggle() { + this.bitField0_ &= 0xFF7FFFFF; + this.isSmuggle_ = 0; + onChanged(); + return this; + } + + public boolean hasDistance() { + return ((this.bitField0_ & 0x1000000) == 16777216); + } + + public double getDistance() { + return this.distance_; + } + + public Builder setDistance(double value) { + this.bitField0_ |= 0x1000000; + this.distance_ = value; + onChanged(); + return this; + } + + public Builder clearDistance() { + this.bitField0_ &= 0xFEFFFFFF; + this.distance_ = 0.0D; + onChanged(); + return this; + } + + public boolean hasWarnColor() { + return ((this.bitField0_ & 0x2000000) == 33554432); + } + + public String getWarnColor() { + Object ref = this.warnColor_; + if (!(ref instanceof String)) { + ByteString bs = (ByteString)ref; + String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) + this.warnColor_ = s; + return s; + } + return (String)ref; + } + + public ByteString getWarnColorBytes() { + Object ref = this.warnColor_; + if (ref instanceof String) { + ByteString b = ByteString.copyFromUtf8((String)ref); + this.warnColor_ = b; + return b; + } + return (ByteString)ref; + } + + public Builder setWarnColor(String value) { + if (value == null) + throw new NullPointerException(); + this.bitField0_ |= 0x2000000; + this.warnColor_ = value; + onChanged(); + return this; + } + + public Builder clearWarnColor() { + this.bitField0_ &= 0xFDFFFFFF; + this.warnColor_ = TrackPoint.getDefaultInstance().getWarnColor(); + onChanged(); + return this; + } + + public Builder setWarnColorBytes(ByteString value) { + if (value == null) + throw new NullPointerException(); + this.bitField0_ |= 0x2000000; + this.warnColor_ = value; + onChanged(); + return this; + } + + public boolean hasTargetType() { + return ((this.bitField0_ & 0x4000000) == 67108864); + } + + public int getTargetType() { + return this.targetType_; + } + + public Builder setTargetType(int value) { + this.bitField0_ |= 0x4000000; + this.targetType_ = value; + onChanged(); + return this; + } + + public Builder clearTargetType() { + this.bitField0_ &= 0xFBFFFFFF; + this.targetType_ = 0; + onChanged(); + return this; + } + + public boolean hasSignWindow() { + return ((this.bitField0_ & 0x8000000) == 134217728); + } + + public int getSignWindow() { + return this.signWindow_; + } + + public Builder setSignWindow(int value) { + this.bitField0_ |= 0x8000000; + this.signWindow_ = value; + onChanged(); + return this; + } + + public Builder clearSignWindow() { + this.bitField0_ &= 0xF7FFFFFF; + this.signWindow_ = 0; + onChanged(); + return this; + } + + public boolean hasIsWarn() { + return ((this.bitField0_ & 0x10000000) == 268435456); + } + + public int getIsWarn() { + return this.isWarn_; + } + + public Builder setIsWarn(int value) { + this.bitField0_ |= 0x10000000; + this.isWarn_ = value; + onChanged(); + return this; + } + + public Builder clearIsWarn() { + this.bitField0_ &= 0xEFFFFFFF; + this.isWarn_ = 0; + onChanged(); + return this; + } + + public boolean hasRtsp() { + return ((this.bitField0_ & 0x20000000) == 536870912); + } + + public String getRtsp() { + Object ref = this.rtsp_; + if (!(ref instanceof String)) { + ByteString bs = (ByteString)ref; + String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) + this.rtsp_ = s; + return s; + } + return (String)ref; + } + + public ByteString getRtspBytes() { + Object ref = this.rtsp_; + if (ref instanceof String) { + ByteString b = ByteString.copyFromUtf8((String)ref); + this.rtsp_ = b; + return b; + } + return (ByteString)ref; + } + + public Builder setRtsp(String value) { + if (value == null) + throw new NullPointerException(); + this.bitField0_ |= 0x20000000; + this.rtsp_ = value; + onChanged(); + return this; + } + + public Builder clearRtsp() { + this.bitField0_ &= 0xDFFFFFFF; + this.rtsp_ = TrackPoint.getDefaultInstance().getRtsp(); + onChanged(); + return this; + } + + public Builder setRtspBytes(ByteString value) { + if (value == null) + throw new NullPointerException(); + this.bitField0_ |= 0x20000000; + this.rtsp_ = value; + onChanged(); + return this; + } + + public boolean hasFllow() { + return ((this.bitField0_ & 0x40000000) == 1073741824); + } + + public int getFllow() { + return this.fllow_; + } + + public Builder setFllow(int value) { + this.bitField0_ |= 0x40000000; + this.fllow_ = value; + onChanged(); + return this; + } + + public Builder clearFllow() { + this.bitField0_ &= 0xBFFFFFFF; + this.fllow_ = 0; + onChanged(); + return this; + } + + public boolean hasMode() { + return ((this.bitField0_ & Integer.MIN_VALUE) == Integer.MIN_VALUE); + } + + public int getMode() { + return this.mode_; + } + + public Builder setMode(int value) { + this.bitField0_ |= Integer.MIN_VALUE; + this.mode_ = value; + onChanged(); + return this; + } + + public Builder clearMode() { + this.bitField0_ &= Integer.MAX_VALUE; + this.mode_ = 0; + onChanged(); + return this; + } + + public boolean hasTimeStamp() { + return ((this.bitField1_ & 0x1) == 1); + } + + public long getTimeStamp() { + return this.timeStamp_; + } + + public Builder setTimeStamp(long value) { + this.bitField1_ |= 0x1; + this.timeStamp_ = value; + onChanged(); + return this; + } + + public Builder clearTimeStamp() { + this.bitField1_ &= 0xFFFFFFFE; + this.timeStamp_ = 0L; + onChanged(); + return this; + } + + public boolean hasTrackby() { + return ((this.bitField1_ & 0x2) == 2); + } + + public String getTrackby() { + Object ref = this.trackby_; + if (!(ref instanceof String)) { + ByteString bs = (ByteString)ref; + String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) + this.trackby_ = s; + return s; + } + return (String)ref; + } + + public ByteString getTrackbyBytes() { + Object ref = this.trackby_; + if (ref instanceof String) { + ByteString b = ByteString.copyFromUtf8((String)ref); + this.trackby_ = b; + return b; + } + return (ByteString)ref; + } + + public Builder setTrackby(String value) { + if (value == null) + throw new NullPointerException(); + this.bitField1_ |= 0x2; + this.trackby_ = value; + onChanged(); + return this; + } + + public Builder clearTrackby() { + this.bitField1_ &= 0xFFFFFFFD; + this.trackby_ = TrackPoint.getDefaultInstance().getTrackby(); + onChanged(); + return this; + } + + public Builder setTrackbyBytes(ByteString value) { + if (value == null) + throw new NullPointerException(); + this.bitField1_ |= 0x2; + this.trackby_ = value; + onChanged(); + return this; + } + + public boolean hasCameraId() { + return ((this.bitField1_ & 0x4) == 4); + } + + public int getCameraId() { + return this.cameraId_; + } + + public Builder setCameraId(int value) { + this.bitField1_ |= 0x4; + this.cameraId_ = value; + onChanged(); + return this; + } + + public Builder clearCameraId() { + this.bitField1_ &= 0xFFFFFFFB; + this.cameraId_ = 0; + onChanged(); + return this; + } + } + + static { + defaultInstance.initFields(); + } + } + + public static final class FllowVo extends GeneratedMessage implements FllowVoOrBuilder { + private static final FllowVo defaultInstance = new FllowVo(true); + + private final UnknownFieldSet unknownFields; + + private FllowVo(GeneratedMessage.Builder builder) { + super(builder); + this.memoizedIsInitialized = -1; + this.memoizedSerializedSize = -1; + this.unknownFields = builder.getUnknownFields(); + } + + private FllowVo(boolean noInit) { + this.memoizedIsInitialized = -1; + this.memoizedSerializedSize = -1; + this.unknownFields = UnknownFieldSet.getDefaultInstance(); + } + + public static FllowVo getDefaultInstance() { + return defaultInstance; + } + + public FllowVo getDefaultInstanceForType() { + return defaultInstance; + } + + public final UnknownFieldSet getUnknownFields() { + return this.unknownFields; + } + + private FllowVo(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + this.memoizedIsInitialized = -1; + this.memoizedSerializedSize = -1; + initFields(); + int mutable_bitField0_ = 0; + UnknownFieldSet.Builder unknownFields = UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: + this.bitField0_ |= 0x1; + this.flag_ = input.readBool(); + break; + case 16: + this.bitField0_ |= 0x2; + this.fllow_ = input.readBool(); + break; + case 26: + if ((mutable_bitField0_ & 0x4) != 4) { + this.trackPoints_ = new ArrayList(); + mutable_bitField0_ |= 0x4; + } + this.trackPoints_.add((TrackPoint)input.readMessage(TrackPoint.PARSER, extensionRegistry)); + break; + case 32: + this.bitField0_ |= 0x4; + this.mode_ = input.readInt32(); + break; + } + } + } catch (InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (IOException e) { + throw (new InvalidProtocolBufferException(e.getMessage())).setUnfinishedMessage(this); + } finally { + if ((mutable_bitField0_ & 0x4) == 4) + this.trackPoints_ = Collections.unmodifiableList(this.trackPoints_); + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + + public static final Descriptors.Descriptor getDescriptor() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_FllowVo_descriptor; + } + + protected FieldAccessorTable internalGetFieldAccessorTable() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_FllowVo_fieldAccessorTable.ensureFieldAccessorsInitialized(FllowVo.class, Builder.class); + } + + public static Parser PARSER = (Parser)new AbstractParser() { + public FllowVo parsePartialFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + return new FllowVo(input, extensionRegistry); + } + }; + + private int bitField0_; + + public static final int FLAG_FIELD_NUMBER = 1; + + private boolean flag_; + + public static final int FLLOW_FIELD_NUMBER = 2; + + private boolean fllow_; + + public static final int TRACKPOINTS_FIELD_NUMBER = 3; + + private List trackPoints_; + + public static final int MODE_FIELD_NUMBER = 4; + + private int mode_; + + private byte memoizedIsInitialized; + + private int memoizedSerializedSize; + + private static final long serialVersionUID = 0L; + + public Parser getParserForType() { + return PARSER; + } + + public boolean hasFlag() { + return ((this.bitField0_ & 0x1) == 1); + } + + public boolean getFlag() { + return this.flag_; + } + + public boolean hasFllow() { + return ((this.bitField0_ & 0x2) == 2); + } + + public boolean getFllow() { + return this.fllow_; + } + + public List getTrackPointsList() { + return this.trackPoints_; + } + + public List getTrackPointsOrBuilderList() { + return (List)this.trackPoints_; + } + + public int getTrackPointsCount() { + return this.trackPoints_.size(); + } + + public TrackPoint getTrackPoints(int index) { + return this.trackPoints_.get(index); + } + + public TrackPointOrBuilder getTrackPointsOrBuilder(int index) { + return this.trackPoints_.get(index); + } + + public boolean hasMode() { + return ((this.bitField0_ & 0x4) == 4); + } + + public int getMode() { + return this.mode_; + } + + private void initFields() { + this.flag_ = false; + this.fllow_ = false; + this.trackPoints_ = Collections.emptyList(); + this.mode_ = 0; + } + + public final boolean isInitialized() { + byte isInitialized = this.memoizedIsInitialized; + if (isInitialized == 1) + return true; + if (isInitialized == 0) + return false; + if (!hasFlag()) { + this.memoizedIsInitialized = 0; + return false; + } + if (!hasFllow()) { + this.memoizedIsInitialized = 0; + return false; + } + if (!hasMode()) { + this.memoizedIsInitialized = 0; + return false; + } + for (int i = 0; i < getTrackPointsCount(); i++) { + if (!getTrackPoints(i).isInitialized()) { + this.memoizedIsInitialized = 0; + return false; + } + } + this.memoizedIsInitialized = 1; + return true; + } + + public void writeTo(CodedOutputStream output) throws IOException { + getSerializedSize(); + if ((this.bitField0_ & 0x1) == 1) + output.writeBool(1, this.flag_); + if ((this.bitField0_ & 0x2) == 2) + output.writeBool(2, this.fllow_); + for (int i = 0; i < this.trackPoints_.size(); i++) + output.writeMessage(3, (MessageLite)this.trackPoints_.get(i)); + if ((this.bitField0_ & 0x4) == 4) + output.writeInt32(4, this.mode_); + getUnknownFields().writeTo(output); + } + + public int getSerializedSize() { + int size = this.memoizedSerializedSize; + if (size != -1) + return size; + size = 0; + if ((this.bitField0_ & 0x1) == 1) + size += CodedOutputStream.computeBoolSize(1, this.flag_); + if ((this.bitField0_ & 0x2) == 2) + size += CodedOutputStream.computeBoolSize(2, this.fllow_); + for (int i = 0; i < this.trackPoints_.size(); i++) + size += CodedOutputStream.computeMessageSize(3, (MessageLite)this.trackPoints_.get(i)); + if ((this.bitField0_ & 0x4) == 4) + size += CodedOutputStream.computeInt32Size(4, this.mode_); + size += getUnknownFields().getSerializedSize(); + this.memoizedSerializedSize = size; + return size; + } + + protected Object writeReplace() throws ObjectStreamException { + return super.writeReplace(); + } + + public static FllowVo parseFrom(ByteString data) throws InvalidProtocolBufferException { + return (FllowVo)PARSER.parseFrom(data); + } + + public static FllowVo parseFrom(ByteString data, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + return (FllowVo)PARSER.parseFrom(data, extensionRegistry); + } + + public static FllowVo parseFrom(byte[] data) throws InvalidProtocolBufferException { + return (FllowVo)PARSER.parseFrom(data); + } + + public static FllowVo parseFrom(byte[] data, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + return (FllowVo)PARSER.parseFrom(data, extensionRegistry); + } + + public static FllowVo parseFrom(InputStream input) throws IOException { + return (FllowVo)PARSER.parseFrom(input); + } + + public static FllowVo parseFrom(InputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + return (FllowVo)PARSER.parseFrom(input, extensionRegistry); + } + + public static FllowVo parseDelimitedFrom(InputStream input) throws IOException { + return (FllowVo)PARSER.parseDelimitedFrom(input); + } + + public static FllowVo parseDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + return (FllowVo)PARSER.parseDelimitedFrom(input, extensionRegistry); + } + + public static FllowVo parseFrom(CodedInputStream input) throws IOException { + return (FllowVo)PARSER.parseFrom(input); + } + + public static FllowVo parseFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + return (FllowVo)PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { + return Builder.create(); + } + + public Builder newBuilderForType() { + return newBuilder(); + } + + public static Builder newBuilder(FllowVo prototype) { + return newBuilder().mergeFrom(prototype); + } + + public Builder toBuilder() { + return newBuilder(this); + } + + protected Builder newBuilderForType(BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + + public static final class Builder extends GeneratedMessage.Builder implements FllowVoOrBuilder { + private int bitField0_; + + private boolean flag_; + + private boolean fllow_; + + private List trackPoints_; + + private RepeatedFieldBuilder trackPointsBuilder_; + + private int mode_; + + public static final Descriptors.Descriptor getDescriptor() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_FllowVo_descriptor; + } + + protected FieldAccessorTable internalGetFieldAccessorTable() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_FllowVo_fieldAccessorTable.ensureFieldAccessorsInitialized(FllowVo.class, Builder.class); + } + + private Builder() { + this.trackPoints_ = Collections.emptyList(); + maybeForceBuilderInitialization(); + } + + private Builder(BuilderParent parent) { + super(parent); + this.trackPoints_ = Collections.emptyList(); + maybeForceBuilderInitialization(); + } + + private void maybeForceBuilderInitialization() { + if (FllowVo.alwaysUseFieldBuilders) + getTrackPointsFieldBuilder(); + } + + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + this.flag_ = false; + this.bitField0_ &= 0xFFFFFFFE; + this.fllow_ = false; + this.bitField0_ &= 0xFFFFFFFD; + if (this.trackPointsBuilder_ == null) { + this.trackPoints_ = Collections.emptyList(); + this.bitField0_ &= 0xFFFFFFFB; + } else { + this.trackPointsBuilder_.clear(); + } + this.mode_ = 0; + this.bitField0_ &= 0xFFFFFFF7; + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public Descriptors.Descriptor getDescriptorForType() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_FllowVo_descriptor; + } + + public FllowVo getDefaultInstanceForType() { + return FllowVo.getDefaultInstance(); + } + + public FllowVo build() { + FllowVo result = buildPartial(); + if (!result.isInitialized()) + throw newUninitializedMessageException(result); + return result; + } + + public FllowVo buildPartial() { + FllowVo result = new FllowVo(this); + int from_bitField0_ = this.bitField0_; + int to_bitField0_ = 0; + if ((from_bitField0_ & 0x1) == 1) + to_bitField0_ |= 0x1; + result.flag_ = this.flag_; + if ((from_bitField0_ & 0x2) == 2) + to_bitField0_ |= 0x2; + result.fllow_ = this.fllow_; + if (this.trackPointsBuilder_ == null) { + if ((this.bitField0_ & 0x4) == 4) { + this.trackPoints_ = Collections.unmodifiableList(this.trackPoints_); + this.bitField0_ &= 0xFFFFFFFB; + } + result.trackPoints_ = this.trackPoints_; + } else { + result.trackPoints_ = this.trackPointsBuilder_.build(); + } + if ((from_bitField0_ & 0x8) == 8) + to_bitField0_ |= 0x4; + result.mode_ = this.mode_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(Message other) { + if (other instanceof FllowVo) + return mergeFrom((FllowVo)other); + super.mergeFrom(other); + return this; + } + + public Builder mergeFrom(FllowVo other) { + if (other == FllowVo.getDefaultInstance()) + return this; + if (other.hasFlag()) + setFlag(other.getFlag()); + if (other.hasFllow()) + setFllow(other.getFllow()); + if (this.trackPointsBuilder_ == null) { + if (!other.trackPoints_.isEmpty()) { + if (this.trackPoints_.isEmpty()) { + this.trackPoints_ = other.trackPoints_; + this.bitField0_ &= 0xFFFFFFFB; + } else { + ensureTrackPointsIsMutable(); + this.trackPoints_.addAll(other.trackPoints_); + } + onChanged(); + } + } else if (!other.trackPoints_.isEmpty()) { + if (this.trackPointsBuilder_.isEmpty()) { + this.trackPointsBuilder_.dispose(); + this.trackPointsBuilder_ = null; + this.trackPoints_ = other.trackPoints_; + this.bitField0_ &= 0xFFFFFFFB; + this.trackPointsBuilder_ = FllowVo.alwaysUseFieldBuilders ? getTrackPointsFieldBuilder() : null; + } else { + this.trackPointsBuilder_.addAllMessages(other.trackPoints_); + } + } + if (other.hasMode()) + setMode(other.getMode()); + mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasFlag()) + return false; + if (!hasFllow()) + return false; + if (!hasMode()) + return false; + for (int i = 0; i < getTrackPointsCount(); i++) { + if (!getTrackPoints(i).isInitialized()) + return false; + } + return true; + } + + public Builder mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + FllowVo parsedMessage = null; + try { + parsedMessage = (FllowVo) FllowVo.PARSER.parsePartialFrom(input, extensionRegistry); + } catch (InvalidProtocolBufferException e) { + parsedMessage = (FllowVo)e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) + mergeFrom(parsedMessage); + } + return this; + } + + public boolean hasFlag() { + return ((this.bitField0_ & 0x1) == 1); + } + + public boolean getFlag() { + return this.flag_; + } + + public Builder setFlag(boolean value) { + this.bitField0_ |= 0x1; + this.flag_ = value; + onChanged(); + return this; + } + + public Builder clearFlag() { + this.bitField0_ &= 0xFFFFFFFE; + this.flag_ = false; + onChanged(); + return this; + } + + public boolean hasFllow() { + return ((this.bitField0_ & 0x2) == 2); + } + + public boolean getFllow() { + return this.fllow_; + } + + public Builder setFllow(boolean value) { + this.bitField0_ |= 0x2; + this.fllow_ = value; + onChanged(); + return this; + } + + public Builder clearFllow() { + this.bitField0_ &= 0xFFFFFFFD; + this.fllow_ = false; + onChanged(); + return this; + } + + private void ensureTrackPointsIsMutable() { + if ((this.bitField0_ & 0x4) != 4) { + this.trackPoints_ = new ArrayList(this.trackPoints_); + this.bitField0_ |= 0x4; + } + } + + public List getTrackPointsList() { + if (this.trackPointsBuilder_ == null) + return Collections.unmodifiableList(this.trackPoints_); + return this.trackPointsBuilder_.getMessageList(); + } + + public int getTrackPointsCount() { + if (this.trackPointsBuilder_ == null) + return this.trackPoints_.size(); + return this.trackPointsBuilder_.getCount(); + } + + public TrackPoint getTrackPoints(int index) { + if (this.trackPointsBuilder_ == null) + return this.trackPoints_.get(index); + return (TrackPoint)this.trackPointsBuilder_.getMessage(index); + } + + public Builder setTrackPoints(int index, TrackPoint value) { + if (this.trackPointsBuilder_ == null) { + if (value == null) + throw new NullPointerException(); + ensureTrackPointsIsMutable(); + this.trackPoints_.set(index, value); + onChanged(); + } else { + this.trackPointsBuilder_.setMessage(index, value); + } + return this; + } + + public Builder setTrackPoints(int index, TrackPoint.Builder builderForValue) { + if (this.trackPointsBuilder_ == null) { + ensureTrackPointsIsMutable(); + this.trackPoints_.set(index, builderForValue.build()); + onChanged(); + } else { + this.trackPointsBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + + public Builder addTrackPoints(TrackPoint value) { + if (this.trackPointsBuilder_ == null) { + if (value == null) + throw new NullPointerException(); + ensureTrackPointsIsMutable(); + this.trackPoints_.add(value); + onChanged(); + } else { + this.trackPointsBuilder_.addMessage(value); + } + return this; + } + + public Builder addTrackPoints(int index, TrackPoint value) { + if (this.trackPointsBuilder_ == null) { + if (value == null) + throw new NullPointerException(); + ensureTrackPointsIsMutable(); + this.trackPoints_.add(index, value); + onChanged(); + } else { + this.trackPointsBuilder_.addMessage(index, value); + } + return this; + } + + public Builder addTrackPoints(TrackPoint.Builder builderForValue) { + if (this.trackPointsBuilder_ == null) { + ensureTrackPointsIsMutable(); + this.trackPoints_.add(builderForValue.build()); + onChanged(); + } else { + this.trackPointsBuilder_.addMessage(builderForValue.build()); + } + return this; + } + + public Builder addTrackPoints(int index, TrackPoint.Builder builderForValue) { + if (this.trackPointsBuilder_ == null) { + ensureTrackPointsIsMutable(); + this.trackPoints_.add(index, builderForValue.build()); + onChanged(); + } else { + this.trackPointsBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + + public Builder addAllTrackPoints(Iterable values) { + if (this.trackPointsBuilder_ == null) { + ensureTrackPointsIsMutable(); + AbstractMessageLite.Builder.addAll(values, this.trackPoints_); + onChanged(); + } else { + this.trackPointsBuilder_.addAllMessages(values); + } + return this; + } + + public Builder clearTrackPoints() { + if (this.trackPointsBuilder_ == null) { + this.trackPoints_ = Collections.emptyList(); + this.bitField0_ &= 0xFFFFFFFB; + onChanged(); + } else { + this.trackPointsBuilder_.clear(); + } + return this; + } + + public Builder removeTrackPoints(int index) { + if (this.trackPointsBuilder_ == null) { + ensureTrackPointsIsMutable(); + this.trackPoints_.remove(index); + onChanged(); + } else { + this.trackPointsBuilder_.remove(index); + } + return this; + } + + public TrackPoint.Builder getTrackPointsBuilder(int index) { + return (TrackPoint.Builder)getTrackPointsFieldBuilder().getBuilder(index); + } + + public TrackPointOrBuilder getTrackPointsOrBuilder(int index) { + if (this.trackPointsBuilder_ == null) + return this.trackPoints_.get(index); + return (TrackPointOrBuilder)this.trackPointsBuilder_.getMessageOrBuilder(index); + } + + public List getTrackPointsOrBuilderList() { + if (this.trackPointsBuilder_ != null) + return this.trackPointsBuilder_.getMessageOrBuilderList(); + return Collections.unmodifiableList((List)this.trackPoints_); + } + + public TrackPoint.Builder addTrackPointsBuilder() { + return (TrackPoint.Builder)getTrackPointsFieldBuilder().addBuilder(TrackPoint.getDefaultInstance()); + } + + public TrackPoint.Builder addTrackPointsBuilder(int index) { + return (TrackPoint.Builder)getTrackPointsFieldBuilder().addBuilder(index, TrackPoint.getDefaultInstance()); + } + + public List getTrackPointsBuilderList() { + return getTrackPointsFieldBuilder().getBuilderList(); + } + + private RepeatedFieldBuilder getTrackPointsFieldBuilder() { + if (this.trackPointsBuilder_ == null) { + this.trackPointsBuilder_ = new RepeatedFieldBuilder(this.trackPoints_, ((this.bitField0_ & 0x4) == 4), getParentForChildren(), isClean()); + this.trackPoints_ = null; + } + return this.trackPointsBuilder_; + } + + public boolean hasMode() { + return ((this.bitField0_ & 0x8) == 8); + } + + public int getMode() { + return this.mode_; + } + + public Builder setMode(int value) { + this.bitField0_ |= 0x8; + this.mode_ = value; + onChanged(); + return this; + } + + public Builder clearMode() { + this.bitField0_ &= 0xFFFFFFF7; + this.mode_ = 0; + onChanged(); + return this; + } + } + + static { + defaultInstance.initFields(); + } + } + + public static final class RadarSurfaceTrack extends GeneratedMessage implements RadarSurfaceTrackOrBuilder { + private static final RadarSurfaceTrack defaultInstance = new RadarSurfaceTrack(true); + + private final UnknownFieldSet unknownFields; + + private RadarSurfaceTrack(GeneratedMessage.Builder builder) { + super(builder); + this.memoizedIsInitialized = -1; + this.memoizedSerializedSize = -1; + this.unknownFields = builder.getUnknownFields(); + } + + private RadarSurfaceTrack(boolean noInit) { + this.memoizedIsInitialized = -1; + this.memoizedSerializedSize = -1; + this.unknownFields = UnknownFieldSet.getDefaultInstance(); + } + + public static RadarSurfaceTrack getDefaultInstance() { + return defaultInstance; + } + + public RadarSurfaceTrack getDefaultInstanceForType() { + return defaultInstance; + } + + public final UnknownFieldSet getUnknownFields() { + return this.unknownFields; + } + + private RadarSurfaceTrack(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + this.memoizedIsInitialized = -1; + this.memoizedSerializedSize = -1; + initFields(); + int mutable_bitField0_ = 0; + UnknownFieldSet.Builder unknownFields = UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + ByteString bs; + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: + this.bitField0_ |= 0x1; + this.flag_ = input.readInt32(); + break; + case 18: + bs = input.readBytes(); + this.bitField0_ |= 0x2; + this.sourceId_ = bs; + break; + case 24: + this.bitField0_ |= 0x4; + this.uTC_ = input.readUInt64(); + break; + case 32: + this.bitField0_ |= 0x8; + this.length_ = input.readInt32(); + break; + case 42: + if ((mutable_bitField0_ & 0x10) != 16) { + this.trackPoints_ = new ArrayList(); + mutable_bitField0_ |= 0x10; + } + this.trackPoints_.add((TrackPoint)input.readMessage(TrackPoint.PARSER, extensionRegistry)); + break; + } + } + } catch (InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (IOException e) { + throw (new InvalidProtocolBufferException(e.getMessage())).setUnfinishedMessage(this); + } finally { + if ((mutable_bitField0_ & 0x10) == 16) + this.trackPoints_ = Collections.unmodifiableList(this.trackPoints_); + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + + public static final Descriptors.Descriptor getDescriptor() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_RadarSurfaceTrack_descriptor; + } + + protected FieldAccessorTable internalGetFieldAccessorTable() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_RadarSurfaceTrack_fieldAccessorTable.ensureFieldAccessorsInitialized(RadarSurfaceTrack.class, Builder.class); + } + + public static Parser PARSER = (Parser)new AbstractParser() { + public RadarSurfaceTrack parsePartialFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + return new RadarSurfaceTrack(input, extensionRegistry); + } + }; + + private int bitField0_; + + public static final int FLAG_FIELD_NUMBER = 1; + + private int flag_; + + public static final int SOURCEID_FIELD_NUMBER = 2; + + private Object sourceId_; + + public static final int UTC_FIELD_NUMBER = 3; + + private long uTC_; + + public static final int LENGTH_FIELD_NUMBER = 4; + + private int length_; + + public static final int TRACKPOINTS_FIELD_NUMBER = 5; + + private List trackPoints_; + + private byte memoizedIsInitialized; + + private int memoizedSerializedSize; + + private static final long serialVersionUID = 0L; + + public Parser getParserForType() { + return PARSER; + } + + public boolean hasFlag() { + return ((this.bitField0_ & 0x1) == 1); + } + + public int getFlag() { + return this.flag_; + } + + public boolean hasSourceId() { + return ((this.bitField0_ & 0x2) == 2); + } + + public String getSourceId() { + Object ref = this.sourceId_; + if (ref instanceof String) + return (String)ref; + ByteString bs = (ByteString)ref; + String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) + this.sourceId_ = s; + return s; + } + + public ByteString getSourceIdBytes() { + Object ref = this.sourceId_; + if (ref instanceof String) { + ByteString b = ByteString.copyFromUtf8((String)ref); + this.sourceId_ = b; + return b; + } + return (ByteString)ref; + } + + public boolean hasUTC() { + return ((this.bitField0_ & 0x4) == 4); + } + + public long getUTC() { + return this.uTC_; + } + + public boolean hasLength() { + return ((this.bitField0_ & 0x8) == 8); + } + + public int getLength() { + return this.length_; + } + + public List getTrackPointsList() { + return this.trackPoints_; + } + + public List getTrackPointsOrBuilderList() { + return (List)this.trackPoints_; + } + + public int getTrackPointsCount() { + return this.trackPoints_.size(); + } + + public TrackPoint getTrackPoints(int index) { + return this.trackPoints_.get(index); + } + + public TrackPointOrBuilder getTrackPointsOrBuilder(int index) { + return this.trackPoints_.get(index); + } + + private void initFields() { + this.flag_ = 0; + this.sourceId_ = ""; + this.uTC_ = 0L; + this.length_ = 0; + this.trackPoints_ = Collections.emptyList(); + } + + public final boolean isInitialized() { + byte isInitialized = this.memoizedIsInitialized; + if (isInitialized == 1) + return true; + if (isInitialized == 0) + return false; + if (!hasFlag()) { + this.memoizedIsInitialized = 0; + return false; + } + if (!hasSourceId()) { + this.memoizedIsInitialized = 0; + return false; + } + if (!hasUTC()) { + this.memoizedIsInitialized = 0; + return false; + } + if (!hasLength()) { + this.memoizedIsInitialized = 0; + return false; + } + for (int i = 0; i < getTrackPointsCount(); i++) { + if (!getTrackPoints(i).isInitialized()) { + this.memoizedIsInitialized = 0; + return false; + } + } + this.memoizedIsInitialized = 1; + return true; + } + + public void writeTo(CodedOutputStream output) throws IOException { + getSerializedSize(); + if ((this.bitField0_ & 0x1) == 1) + output.writeInt32(1, this.flag_); + if ((this.bitField0_ & 0x2) == 2) + output.writeBytes(2, getSourceIdBytes()); + if ((this.bitField0_ & 0x4) == 4) + output.writeUInt64(3, this.uTC_); + if ((this.bitField0_ & 0x8) == 8) + output.writeInt32(4, this.length_); + for (int i = 0; i < this.trackPoints_.size(); i++) + output.writeMessage(5, (MessageLite)this.trackPoints_.get(i)); + getUnknownFields().writeTo(output); + } + + public int getSerializedSize() { + int size = this.memoizedSerializedSize; + if (size != -1) + return size; + size = 0; + if ((this.bitField0_ & 0x1) == 1) + size += CodedOutputStream.computeInt32Size(1, this.flag_); + if ((this.bitField0_ & 0x2) == 2) + size += CodedOutputStream.computeBytesSize(2, getSourceIdBytes()); + if ((this.bitField0_ & 0x4) == 4) + size += CodedOutputStream.computeUInt64Size(3, this.uTC_); + if ((this.bitField0_ & 0x8) == 8) + size += CodedOutputStream.computeInt32Size(4, this.length_); + for (int i = 0; i < this.trackPoints_.size(); i++) + size += CodedOutputStream.computeMessageSize(5, (MessageLite)this.trackPoints_.get(i)); + size += getUnknownFields().getSerializedSize(); + this.memoizedSerializedSize = size; + return size; + } + + protected Object writeReplace() throws ObjectStreamException { + return super.writeReplace(); + } + + public static RadarSurfaceTrack parseFrom(ByteString data) throws InvalidProtocolBufferException { + return (RadarSurfaceTrack)PARSER.parseFrom(data); + } + + public static RadarSurfaceTrack parseFrom(ByteString data, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + return (RadarSurfaceTrack)PARSER.parseFrom(data, extensionRegistry); + } + + public static RadarSurfaceTrack parseFrom(byte[] data) throws InvalidProtocolBufferException { + return (RadarSurfaceTrack)PARSER.parseFrom(data); + } + + public static RadarSurfaceTrack parseFrom(byte[] data, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + return (RadarSurfaceTrack)PARSER.parseFrom(data, extensionRegistry); + } + + public static RadarSurfaceTrack parseFrom(InputStream input) throws IOException { + return (RadarSurfaceTrack)PARSER.parseFrom(input); + } + + public static RadarSurfaceTrack parseFrom(InputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + return (RadarSurfaceTrack)PARSER.parseFrom(input, extensionRegistry); + } + + public static RadarSurfaceTrack parseDelimitedFrom(InputStream input) throws IOException { + return (RadarSurfaceTrack)PARSER.parseDelimitedFrom(input); + } + + public static RadarSurfaceTrack parseDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + return (RadarSurfaceTrack)PARSER.parseDelimitedFrom(input, extensionRegistry); + } + + public static RadarSurfaceTrack parseFrom(CodedInputStream input) throws IOException { + return (RadarSurfaceTrack)PARSER.parseFrom(input); + } + + public static RadarSurfaceTrack parseFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + return (RadarSurfaceTrack)PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { + return Builder.create(); + } + + public Builder newBuilderForType() { + return newBuilder(); + } + + public static Builder newBuilder(RadarSurfaceTrack prototype) { + return newBuilder().mergeFrom(prototype); + } + + public Builder toBuilder() { + return newBuilder(this); + } + + protected Builder newBuilderForType(BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + + public static final class Builder extends GeneratedMessage.Builder implements RadarSurfaceTrackOrBuilder { + private int bitField0_; + + private int flag_; + + private Object sourceId_; + + private long uTC_; + + private int length_; + + private List trackPoints_; + + private RepeatedFieldBuilder trackPointsBuilder_; + + public static final Descriptors.Descriptor getDescriptor() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_RadarSurfaceTrack_descriptor; + } + + protected FieldAccessorTable internalGetFieldAccessorTable() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_RadarSurfaceTrack_fieldAccessorTable.ensureFieldAccessorsInitialized(RadarSurfaceTrack.class, Builder.class); + } + + private Builder() { + this.sourceId_ = ""; + this.trackPoints_ = Collections.emptyList(); + maybeForceBuilderInitialization(); + } + + private Builder(BuilderParent parent) { + super(parent); + this.sourceId_ = ""; + this.trackPoints_ = Collections.emptyList(); + maybeForceBuilderInitialization(); + } + + private void maybeForceBuilderInitialization() { + if (RadarSurfaceTrack.alwaysUseFieldBuilders) + getTrackPointsFieldBuilder(); + } + + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + this.flag_ = 0; + this.bitField0_ &= 0xFFFFFFFE; + this.sourceId_ = ""; + this.bitField0_ &= 0xFFFFFFFD; + this.uTC_ = 0L; + this.bitField0_ &= 0xFFFFFFFB; + this.length_ = 0; + this.bitField0_ &= 0xFFFFFFF7; + if (this.trackPointsBuilder_ == null) { + this.trackPoints_ = Collections.emptyList(); + this.bitField0_ &= 0xFFFFFFEF; + } else { + this.trackPointsBuilder_.clear(); + } + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public Descriptors.Descriptor getDescriptorForType() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_RadarSurfaceTrack_descriptor; + } + + public RadarSurfaceTrack getDefaultInstanceForType() { + return RadarSurfaceTrack.getDefaultInstance(); + } + + public RadarSurfaceTrack build() { + RadarSurfaceTrack result = buildPartial(); + if (!result.isInitialized()) + throw newUninitializedMessageException(result); + return result; + } + + public RadarSurfaceTrack buildPartial() { + RadarSurfaceTrack result = new RadarSurfaceTrack(this); + int from_bitField0_ = this.bitField0_; + int to_bitField0_ = 0; + if ((from_bitField0_ & 0x1) == 1) + to_bitField0_ |= 0x1; + result.flag_ = this.flag_; + if ((from_bitField0_ & 0x2) == 2) + to_bitField0_ |= 0x2; + result.sourceId_ = this.sourceId_; + if ((from_bitField0_ & 0x4) == 4) + to_bitField0_ |= 0x4; + result.uTC_ = this.uTC_; + if ((from_bitField0_ & 0x8) == 8) + to_bitField0_ |= 0x8; + result.length_ = this.length_; + if (this.trackPointsBuilder_ == null) { + if ((this.bitField0_ & 0x10) == 16) { + this.trackPoints_ = Collections.unmodifiableList(this.trackPoints_); + this.bitField0_ &= 0xFFFFFFEF; + } + result.trackPoints_ = this.trackPoints_; + } else { + result.trackPoints_ = this.trackPointsBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(Message other) { + if (other instanceof RadarSurfaceTrack) + return mergeFrom((RadarSurfaceTrack)other); + super.mergeFrom(other); + return this; + } + + public Builder mergeFrom(RadarSurfaceTrack other) { + if (other == RadarSurfaceTrack.getDefaultInstance()) + return this; + if (other.hasFlag()) + setFlag(other.getFlag()); + if (other.hasSourceId()) { + this.bitField0_ |= 0x2; + this.sourceId_ = other.sourceId_; + onChanged(); + } + if (other.hasUTC()) + setUTC(other.getUTC()); + if (other.hasLength()) + setLength(other.getLength()); + if (this.trackPointsBuilder_ == null) { + if (!other.trackPoints_.isEmpty()) { + if (this.trackPoints_.isEmpty()) { + this.trackPoints_ = other.trackPoints_; + this.bitField0_ &= 0xFFFFFFEF; + } else { + ensureTrackPointsIsMutable(); + this.trackPoints_.addAll(other.trackPoints_); + } + onChanged(); + } + } else if (!other.trackPoints_.isEmpty()) { + if (this.trackPointsBuilder_.isEmpty()) { + this.trackPointsBuilder_.dispose(); + this.trackPointsBuilder_ = null; + this.trackPoints_ = other.trackPoints_; + this.bitField0_ &= 0xFFFFFFEF; + this.trackPointsBuilder_ = RadarSurfaceTrack.alwaysUseFieldBuilders ? getTrackPointsFieldBuilder() : null; + } else { + this.trackPointsBuilder_.addAllMessages(other.trackPoints_); + } + } + mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasFlag()) + return false; + if (!hasSourceId()) + return false; + if (!hasUTC()) + return false; + if (!hasLength()) + return false; + for (int i = 0; i < getTrackPointsCount(); i++) { + if (!getTrackPoints(i).isInitialized()) + return false; + } + return true; + } + + public Builder mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + RadarSurfaceTrack parsedMessage = null; + try { + parsedMessage = (RadarSurfaceTrack) RadarSurfaceTrack.PARSER.parsePartialFrom(input, extensionRegistry); + } catch (InvalidProtocolBufferException e) { + parsedMessage = (RadarSurfaceTrack)e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) + mergeFrom(parsedMessage); + } + return this; + } + + public boolean hasFlag() { + return ((this.bitField0_ & 0x1) == 1); + } + + public int getFlag() { + return this.flag_; + } + + public Builder setFlag(int value) { + this.bitField0_ |= 0x1; + this.flag_ = value; + onChanged(); + return this; + } + + public Builder clearFlag() { + this.bitField0_ &= 0xFFFFFFFE; + this.flag_ = 0; + onChanged(); + return this; + } + + public boolean hasSourceId() { + return ((this.bitField0_ & 0x2) == 2); + } + + public String getSourceId() { + Object ref = this.sourceId_; + if (!(ref instanceof String)) { + ByteString bs = (ByteString)ref; + String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) + this.sourceId_ = s; + return s; + } + return (String)ref; + } + + public ByteString getSourceIdBytes() { + Object ref = this.sourceId_; + if (ref instanceof String) { + ByteString b = ByteString.copyFromUtf8((String)ref); + this.sourceId_ = b; + return b; + } + return (ByteString)ref; + } + + public Builder setSourceId(String value) { + if (value == null) + throw new NullPointerException(); + this.bitField0_ |= 0x2; + this.sourceId_ = value; + onChanged(); + return this; + } + + public Builder clearSourceId() { + this.bitField0_ &= 0xFFFFFFFD; + this.sourceId_ = RadarSurfaceTrack.getDefaultInstance().getSourceId(); + onChanged(); + return this; + } + + public Builder setSourceIdBytes(ByteString value) { + if (value == null) + throw new NullPointerException(); + this.bitField0_ |= 0x2; + this.sourceId_ = value; + onChanged(); + return this; + } + + public boolean hasUTC() { + return ((this.bitField0_ & 0x4) == 4); + } + + public long getUTC() { + return this.uTC_; + } + + public Builder setUTC(long value) { + this.bitField0_ |= 0x4; + this.uTC_ = value; + onChanged(); + return this; + } + + public Builder clearUTC() { + this.bitField0_ &= 0xFFFFFFFB; + this.uTC_ = 0L; + onChanged(); + return this; + } + + public boolean hasLength() { + return ((this.bitField0_ & 0x8) == 8); + } + + public int getLength() { + return this.length_; + } + + public Builder setLength(int value) { + this.bitField0_ |= 0x8; + this.length_ = value; + onChanged(); + return this; + } + + public Builder clearLength() { + this.bitField0_ &= 0xFFFFFFF7; + this.length_ = 0; + onChanged(); + return this; + } + + private void ensureTrackPointsIsMutable() { + if ((this.bitField0_ & 0x10) != 16) { + this.trackPoints_ = new ArrayList(this.trackPoints_); + this.bitField0_ |= 0x10; + } + } + + public List getTrackPointsList() { + if (this.trackPointsBuilder_ == null) + return Collections.unmodifiableList(this.trackPoints_); + return this.trackPointsBuilder_.getMessageList(); + } + + public int getTrackPointsCount() { + if (this.trackPointsBuilder_ == null) + return this.trackPoints_.size(); + return this.trackPointsBuilder_.getCount(); + } + + public TrackPoint getTrackPoints(int index) { + if (this.trackPointsBuilder_ == null) + return this.trackPoints_.get(index); + return (TrackPoint)this.trackPointsBuilder_.getMessage(index); + } + + public Builder setTrackPoints(int index, TrackPoint value) { + if (this.trackPointsBuilder_ == null) { + if (value == null) + throw new NullPointerException(); + ensureTrackPointsIsMutable(); + this.trackPoints_.set(index, value); + onChanged(); + } else { + this.trackPointsBuilder_.setMessage(index, value); + } + return this; + } + + public Builder setTrackPoints(int index, TrackPoint.Builder builderForValue) { + if (this.trackPointsBuilder_ == null) { + ensureTrackPointsIsMutable(); + this.trackPoints_.set(index, builderForValue.build()); + onChanged(); + } else { + this.trackPointsBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + + public Builder addTrackPoints(TrackPoint value) { + if (this.trackPointsBuilder_ == null) { + if (value == null) + throw new NullPointerException(); + ensureTrackPointsIsMutable(); + this.trackPoints_.add(value); + onChanged(); + } else { + this.trackPointsBuilder_.addMessage(value); + } + return this; + } + + public Builder addTrackPoints(int index, TrackPoint value) { + if (this.trackPointsBuilder_ == null) { + if (value == null) + throw new NullPointerException(); + ensureTrackPointsIsMutable(); + this.trackPoints_.add(index, value); + onChanged(); + } else { + this.trackPointsBuilder_.addMessage(index, value); + } + return this; + } + + public Builder addTrackPoints(TrackPoint.Builder builderForValue) { + if (this.trackPointsBuilder_ == null) { + ensureTrackPointsIsMutable(); + this.trackPoints_.add(builderForValue.build()); + onChanged(); + } else { + this.trackPointsBuilder_.addMessage(builderForValue.build()); + } + return this; + } + + public Builder addTrackPoints(int index, TrackPoint.Builder builderForValue) { + if (this.trackPointsBuilder_ == null) { + ensureTrackPointsIsMutable(); + this.trackPoints_.add(index, builderForValue.build()); + onChanged(); + } else { + this.trackPointsBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + + public Builder addAllTrackPoints(Iterable values) { + if (this.trackPointsBuilder_ == null) { + ensureTrackPointsIsMutable(); + AbstractMessageLite.Builder.addAll(values, this.trackPoints_); + onChanged(); + } else { + this.trackPointsBuilder_.addAllMessages(values); + } + return this; + } + + public Builder clearTrackPoints() { + if (this.trackPointsBuilder_ == null) { + this.trackPoints_ = Collections.emptyList(); + this.bitField0_ &= 0xFFFFFFEF; + onChanged(); + } else { + this.trackPointsBuilder_.clear(); + } + return this; + } + + public Builder removeTrackPoints(int index) { + if (this.trackPointsBuilder_ == null) { + ensureTrackPointsIsMutable(); + this.trackPoints_.remove(index); + onChanged(); + } else { + this.trackPointsBuilder_.remove(index); + } + return this; + } + + public TrackPoint.Builder getTrackPointsBuilder(int index) { + return (TrackPoint.Builder)getTrackPointsFieldBuilder().getBuilder(index); + } + + public TrackPointOrBuilder getTrackPointsOrBuilder(int index) { + if (this.trackPointsBuilder_ == null) + return this.trackPoints_.get(index); + return (TrackPointOrBuilder)this.trackPointsBuilder_.getMessageOrBuilder(index); + } + + public List getTrackPointsOrBuilderList() { + if (this.trackPointsBuilder_ != null) + return this.trackPointsBuilder_.getMessageOrBuilderList(); + return Collections.unmodifiableList((List)this.trackPoints_); + } + + public TrackPoint.Builder addTrackPointsBuilder() { + return (TrackPoint.Builder)getTrackPointsFieldBuilder().addBuilder(TrackPoint.getDefaultInstance()); + } + + public TrackPoint.Builder addTrackPointsBuilder(int index) { + return (TrackPoint.Builder)getTrackPointsFieldBuilder().addBuilder(index, TrackPoint.getDefaultInstance()); + } + + public List getTrackPointsBuilderList() { + return getTrackPointsFieldBuilder().getBuilderList(); + } + + private RepeatedFieldBuilder getTrackPointsFieldBuilder() { + if (this.trackPointsBuilder_ == null) { + this.trackPointsBuilder_ = new RepeatedFieldBuilder(this.trackPoints_, ((this.bitField0_ & 0x10) == 16), getParentForChildren(), isClean()); + this.trackPoints_ = null; + } + return this.trackPointsBuilder_; + } + } + + static { + defaultInstance.initFields(); + } + } + + public static final class Spectrum extends GeneratedMessage implements SpectrumOrBuilder { + private static final Spectrum defaultInstance = new Spectrum(true); + + private final UnknownFieldSet unknownFields; + + private Spectrum(GeneratedMessage.Builder builder) { + super(builder); + this.memoizedIsInitialized = -1; + this.memoizedSerializedSize = -1; + this.unknownFields = builder.getUnknownFields(); + } + + private Spectrum(boolean noInit) { + this.memoizedIsInitialized = -1; + this.memoizedSerializedSize = -1; + this.unknownFields = UnknownFieldSet.getDefaultInstance(); + } + + public static Spectrum getDefaultInstance() { + return defaultInstance; + } + + public Spectrum getDefaultInstanceForType() { + return defaultInstance; + } + + public final UnknownFieldSet getUnknownFields() { + return this.unknownFields; + } + + private Spectrum(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + this.memoizedIsInitialized = -1; + this.memoizedSerializedSize = -1; + initFields(); + int mutable_bitField0_ = 0; + UnknownFieldSet.Builder unknownFields = UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 9: + this.bitField0_ |= 0x1; + this.longitude_ = input.readDouble(); + break; + case 17: + this.bitField0_ |= 0x2; + this.latitude_ = input.readDouble(); + break; + case 24: + this.bitField0_ |= 0x4; + this.amplitude_ = input.readInt32(); + break; + } + } + } catch (InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (IOException e) { + throw (new InvalidProtocolBufferException(e.getMessage())).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + + public static final Descriptors.Descriptor getDescriptor() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_Spectrum_descriptor; + } + + protected FieldAccessorTable internalGetFieldAccessorTable() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_Spectrum_fieldAccessorTable.ensureFieldAccessorsInitialized(Spectrum.class, Builder.class); + } + + public static Parser PARSER = (Parser)new AbstractParser() { + public Spectrum parsePartialFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + return new Spectrum(input, extensionRegistry); + } + }; + + private int bitField0_; + + public static final int LONGITUDE_FIELD_NUMBER = 1; + + private double longitude_; + + public static final int LATITUDE_FIELD_NUMBER = 2; + + private double latitude_; + + public static final int AMPLITUDE_FIELD_NUMBER = 3; + + private int amplitude_; + + private byte memoizedIsInitialized; + + private int memoizedSerializedSize; + + private static final long serialVersionUID = 0L; + + public Parser getParserForType() { + return PARSER; + } + + public boolean hasLongitude() { + return ((this.bitField0_ & 0x1) == 1); + } + + public double getLongitude() { + return this.longitude_; + } + + public boolean hasLatitude() { + return ((this.bitField0_ & 0x2) == 2); + } + + public double getLatitude() { + return this.latitude_; + } + + public boolean hasAmplitude() { + return ((this.bitField0_ & 0x4) == 4); + } + + public int getAmplitude() { + return this.amplitude_; + } + + private void initFields() { + this.longitude_ = 0.0D; + this.latitude_ = 0.0D; + this.amplitude_ = 0; + } + + public final boolean isInitialized() { + byte isInitialized = this.memoizedIsInitialized; + if (isInitialized == 1) + return true; + if (isInitialized == 0) + return false; + if (!hasLongitude()) { + this.memoizedIsInitialized = 0; + return false; + } + if (!hasLatitude()) { + this.memoizedIsInitialized = 0; + return false; + } + if (!hasAmplitude()) { + this.memoizedIsInitialized = 0; + return false; + } + this.memoizedIsInitialized = 1; + return true; + } + + public void writeTo(CodedOutputStream output) throws IOException { + getSerializedSize(); + if ((this.bitField0_ & 0x1) == 1) + output.writeDouble(1, this.longitude_); + if ((this.bitField0_ & 0x2) == 2) + output.writeDouble(2, this.latitude_); + if ((this.bitField0_ & 0x4) == 4) + output.writeInt32(3, this.amplitude_); + getUnknownFields().writeTo(output); + } + + public int getSerializedSize() { + int size = this.memoizedSerializedSize; + if (size != -1) + return size; + size = 0; + if ((this.bitField0_ & 0x1) == 1) + size += CodedOutputStream.computeDoubleSize(1, this.longitude_); + if ((this.bitField0_ & 0x2) == 2) + size += CodedOutputStream.computeDoubleSize(2, this.latitude_); + if ((this.bitField0_ & 0x4) == 4) + size += CodedOutputStream.computeInt32Size(3, this.amplitude_); + size += getUnknownFields().getSerializedSize(); + this.memoizedSerializedSize = size; + return size; + } + + protected Object writeReplace() throws ObjectStreamException { + return super.writeReplace(); + } + + public static Spectrum parseFrom(ByteString data) throws InvalidProtocolBufferException { + return (Spectrum)PARSER.parseFrom(data); + } + + public static Spectrum parseFrom(ByteString data, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + return (Spectrum)PARSER.parseFrom(data, extensionRegistry); + } + + public static Spectrum parseFrom(byte[] data) throws InvalidProtocolBufferException { + return (Spectrum)PARSER.parseFrom(data); + } + + public static Spectrum parseFrom(byte[] data, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + return (Spectrum)PARSER.parseFrom(data, extensionRegistry); + } + + public static Spectrum parseFrom(InputStream input) throws IOException { + return (Spectrum)PARSER.parseFrom(input); + } + + public static Spectrum parseFrom(InputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + return (Spectrum)PARSER.parseFrom(input, extensionRegistry); + } + + public static Spectrum parseDelimitedFrom(InputStream input) throws IOException { + return (Spectrum)PARSER.parseDelimitedFrom(input); + } + + public static Spectrum parseDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + return (Spectrum)PARSER.parseDelimitedFrom(input, extensionRegistry); + } + + public static Spectrum parseFrom(CodedInputStream input) throws IOException { + return (Spectrum)PARSER.parseFrom(input); + } + + public static Spectrum parseFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + return (Spectrum)PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { + return Builder.create(); + } + + public Builder newBuilderForType() { + return newBuilder(); + } + + public static Builder newBuilder(Spectrum prototype) { + return newBuilder().mergeFrom(prototype); + } + + public Builder toBuilder() { + return newBuilder(this); + } + + protected Builder newBuilderForType(BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + + public static final class Builder extends GeneratedMessage.Builder implements SpectrumOrBuilder { + private int bitField0_; + + private double longitude_; + + private double latitude_; + + private int amplitude_; + + public static final Descriptors.Descriptor getDescriptor() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_Spectrum_descriptor; + } + + protected FieldAccessorTable internalGetFieldAccessorTable() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_Spectrum_fieldAccessorTable.ensureFieldAccessorsInitialized(Spectrum.class, Builder.class); + } + + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder(BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + + private void maybeForceBuilderInitialization() { + boolean b = Spectrum.alwaysUseFieldBuilders; + } + + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + this.longitude_ = 0.0D; + this.bitField0_ &= 0xFFFFFFFE; + this.latitude_ = 0.0D; + this.bitField0_ &= 0xFFFFFFFD; + this.amplitude_ = 0; + this.bitField0_ &= 0xFFFFFFFB; + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public Descriptors.Descriptor getDescriptorForType() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_Spectrum_descriptor; + } + + public Spectrum getDefaultInstanceForType() { + return Spectrum.getDefaultInstance(); + } + + public Spectrum build() { + Spectrum result = buildPartial(); + if (!result.isInitialized()) + throw newUninitializedMessageException(result); + return result; + } + + public Spectrum buildPartial() { + Spectrum result = new Spectrum(this); + int from_bitField0_ = this.bitField0_; + int to_bitField0_ = 0; + if ((from_bitField0_ & 0x1) == 1) + to_bitField0_ |= 0x1; + result.longitude_ = this.longitude_; + if ((from_bitField0_ & 0x2) == 2) + to_bitField0_ |= 0x2; + result.latitude_ = this.latitude_; + if ((from_bitField0_ & 0x4) == 4) + to_bitField0_ |= 0x4; + result.amplitude_ = this.amplitude_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(Message other) { + if (other instanceof Spectrum) + return mergeFrom((Spectrum)other); + super.mergeFrom(other); + return this; + } + + public Builder mergeFrom(Spectrum other) { + if (other == Spectrum.getDefaultInstance()) + return this; + if (other.hasLongitude()) + setLongitude(other.getLongitude()); + if (other.hasLatitude()) + setLatitude(other.getLatitude()); + if (other.hasAmplitude()) + setAmplitude(other.getAmplitude()); + mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasLongitude()) + return false; + if (!hasLatitude()) + return false; + if (!hasAmplitude()) + return false; + return true; + } + + public Builder mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + Spectrum parsedMessage = null; + try { + parsedMessage = (Spectrum) Spectrum.PARSER.parsePartialFrom(input, extensionRegistry); + } catch (InvalidProtocolBufferException e) { + parsedMessage = (Spectrum)e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) + mergeFrom(parsedMessage); + } + return this; + } + + public boolean hasLongitude() { + return ((this.bitField0_ & 0x1) == 1); + } + + public double getLongitude() { + return this.longitude_; + } + + public Builder setLongitude(double value) { + this.bitField0_ |= 0x1; + this.longitude_ = value; + onChanged(); + return this; + } + + public Builder clearLongitude() { + this.bitField0_ &= 0xFFFFFFFE; + this.longitude_ = 0.0D; + onChanged(); + return this; + } + + public boolean hasLatitude() { + return ((this.bitField0_ & 0x2) == 2); + } + + public double getLatitude() { + return this.latitude_; + } + + public Builder setLatitude(double value) { + this.bitField0_ |= 0x2; + this.latitude_ = value; + onChanged(); + return this; + } + + public Builder clearLatitude() { + this.bitField0_ &= 0xFFFFFFFD; + this.latitude_ = 0.0D; + onChanged(); + return this; + } + + public boolean hasAmplitude() { + return ((this.bitField0_ & 0x4) == 4); + } + + public int getAmplitude() { + return this.amplitude_; + } + + public Builder setAmplitude(int value) { + this.bitField0_ |= 0x4; + this.amplitude_ = value; + onChanged(); + return this; + } + + public Builder clearAmplitude() { + this.bitField0_ &= 0xFFFFFFFB; + this.amplitude_ = 0; + onChanged(); + return this; + } + } + + static { + defaultInstance.initFields(); + } + } + + public static final class LineSpectrum extends GeneratedMessage implements LineSpectrumOrBuilder { + private static final LineSpectrum defaultInstance = new LineSpectrum(true); + + private final UnknownFieldSet unknownFields; + + private LineSpectrum(GeneratedMessage.Builder builder) { + super(builder); + this.memoizedIsInitialized = -1; + this.memoizedSerializedSize = -1; + this.unknownFields = builder.getUnknownFields(); + } + + private LineSpectrum(boolean noInit) { + this.memoizedIsInitialized = -1; + this.memoizedSerializedSize = -1; + this.unknownFields = UnknownFieldSet.getDefaultInstance(); + } + + public static LineSpectrum getDefaultInstance() { + return defaultInstance; + } + + public LineSpectrum getDefaultInstanceForType() { + return defaultInstance; + } + + public final UnknownFieldSet getUnknownFields() { + return this.unknownFields; + } + + private LineSpectrum(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + this.memoizedIsInitialized = -1; + this.memoizedSerializedSize = -1; + initFields(); + int mutable_bitField0_ = 0; + UnknownFieldSet.Builder unknownFields = UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 9: + this.bitField0_ |= 0x1; + this.azimuth_ = input.readDouble(); + break; + case 18: + if ((mutable_bitField0_ & 0x2) != 2) { + this.spectrums_ = new ArrayList(); + mutable_bitField0_ |= 0x2; + } + this.spectrums_.add((Spectrum)input.readMessage(Spectrum.PARSER, extensionRegistry)); + break; + } + } + } catch (InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (IOException e) { + throw (new InvalidProtocolBufferException(e.getMessage())).setUnfinishedMessage(this); + } finally { + if ((mutable_bitField0_ & 0x2) == 2) + this.spectrums_ = Collections.unmodifiableList(this.spectrums_); + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + + public static final Descriptors.Descriptor getDescriptor() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_LineSpectrum_descriptor; + } + + protected FieldAccessorTable internalGetFieldAccessorTable() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_LineSpectrum_fieldAccessorTable.ensureFieldAccessorsInitialized(LineSpectrum.class, Builder.class); + } + + public static Parser PARSER = (Parser)new AbstractParser() { + public LineSpectrum parsePartialFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + return new LineSpectrum(input, extensionRegistry); + } + }; + + private int bitField0_; + + public static final int AZIMUTH_FIELD_NUMBER = 1; + + private double azimuth_; + + public static final int SPECTRUMS_FIELD_NUMBER = 2; + + private List spectrums_; + + private byte memoizedIsInitialized; + + private int memoizedSerializedSize; + + private static final long serialVersionUID = 0L; + + public Parser getParserForType() { + return PARSER; + } + + public boolean hasAzimuth() { + return ((this.bitField0_ & 0x1) == 1); + } + + public double getAzimuth() { + return this.azimuth_; + } + + public List getSpectrumsList() { + return this.spectrums_; + } + + public List getSpectrumsOrBuilderList() { + return (List)this.spectrums_; + } + + public int getSpectrumsCount() { + return this.spectrums_.size(); + } + + public Spectrum getSpectrums(int index) { + return this.spectrums_.get(index); + } + + public SpectrumOrBuilder getSpectrumsOrBuilder(int index) { + return this.spectrums_.get(index); + } + + private void initFields() { + this.azimuth_ = 0.0D; + this.spectrums_ = Collections.emptyList(); + } + + public final boolean isInitialized() { + byte isInitialized = this.memoizedIsInitialized; + if (isInitialized == 1) + return true; + if (isInitialized == 0) + return false; + if (!hasAzimuth()) { + this.memoizedIsInitialized = 0; + return false; + } + for (int i = 0; i < getSpectrumsCount(); i++) { + if (!getSpectrums(i).isInitialized()) { + this.memoizedIsInitialized = 0; + return false; + } + } + this.memoizedIsInitialized = 1; + return true; + } + + public void writeTo(CodedOutputStream output) throws IOException { + getSerializedSize(); + if ((this.bitField0_ & 0x1) == 1) + output.writeDouble(1, this.azimuth_); + for (int i = 0; i < this.spectrums_.size(); i++) + output.writeMessage(2, (MessageLite)this.spectrums_.get(i)); + getUnknownFields().writeTo(output); + } + + public int getSerializedSize() { + int size = this.memoizedSerializedSize; + if (size != -1) + return size; + size = 0; + if ((this.bitField0_ & 0x1) == 1) + size += CodedOutputStream.computeDoubleSize(1, this.azimuth_); + for (int i = 0; i < this.spectrums_.size(); i++) + size += CodedOutputStream.computeMessageSize(2, (MessageLite)this.spectrums_.get(i)); + size += getUnknownFields().getSerializedSize(); + this.memoizedSerializedSize = size; + return size; + } + + protected Object writeReplace() throws ObjectStreamException { + return super.writeReplace(); + } + + public static LineSpectrum parseFrom(ByteString data) throws InvalidProtocolBufferException { + return (LineSpectrum)PARSER.parseFrom(data); + } + + public static LineSpectrum parseFrom(ByteString data, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + return (LineSpectrum)PARSER.parseFrom(data, extensionRegistry); + } + + public static LineSpectrum parseFrom(byte[] data) throws InvalidProtocolBufferException { + return (LineSpectrum)PARSER.parseFrom(data); + } + + public static LineSpectrum parseFrom(byte[] data, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + return (LineSpectrum)PARSER.parseFrom(data, extensionRegistry); + } + + public static LineSpectrum parseFrom(InputStream input) throws IOException { + return (LineSpectrum)PARSER.parseFrom(input); + } + + public static LineSpectrum parseFrom(InputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + return (LineSpectrum)PARSER.parseFrom(input, extensionRegistry); + } + + public static LineSpectrum parseDelimitedFrom(InputStream input) throws IOException { + return (LineSpectrum)PARSER.parseDelimitedFrom(input); + } + + public static LineSpectrum parseDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + return (LineSpectrum)PARSER.parseDelimitedFrom(input, extensionRegistry); + } + + public static LineSpectrum parseFrom(CodedInputStream input) throws IOException { + return (LineSpectrum)PARSER.parseFrom(input); + } + + public static LineSpectrum parseFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + return (LineSpectrum)PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { + return Builder.create(); + } + + public Builder newBuilderForType() { + return newBuilder(); + } + + public static Builder newBuilder(LineSpectrum prototype) { + return newBuilder().mergeFrom(prototype); + } + + public Builder toBuilder() { + return newBuilder(this); + } + + protected Builder newBuilderForType(BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + + public static final class Builder extends GeneratedMessage.Builder implements LineSpectrumOrBuilder { + private int bitField0_; + + private double azimuth_; + + private List spectrums_; + + private RepeatedFieldBuilder spectrumsBuilder_; + + public static final Descriptors.Descriptor getDescriptor() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_LineSpectrum_descriptor; + } + + protected FieldAccessorTable internalGetFieldAccessorTable() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_LineSpectrum_fieldAccessorTable.ensureFieldAccessorsInitialized(LineSpectrum.class, Builder.class); + } + + private Builder() { + this.spectrums_ = Collections.emptyList(); + maybeForceBuilderInitialization(); + } + + private Builder(BuilderParent parent) { + super(parent); + this.spectrums_ = Collections.emptyList(); + maybeForceBuilderInitialization(); + } + + private void maybeForceBuilderInitialization() { + if (LineSpectrum.alwaysUseFieldBuilders) + getSpectrumsFieldBuilder(); + } + + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + this.azimuth_ = 0.0D; + this.bitField0_ &= 0xFFFFFFFE; + if (this.spectrumsBuilder_ == null) { + this.spectrums_ = Collections.emptyList(); + this.bitField0_ &= 0xFFFFFFFD; + } else { + this.spectrumsBuilder_.clear(); + } + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public Descriptors.Descriptor getDescriptorForType() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_LineSpectrum_descriptor; + } + + public LineSpectrum getDefaultInstanceForType() { + return LineSpectrum.getDefaultInstance(); + } + + public LineSpectrum build() { + LineSpectrum result = buildPartial(); + if (!result.isInitialized()) + throw newUninitializedMessageException(result); + return result; + } + + public LineSpectrum buildPartial() { + LineSpectrum result = new LineSpectrum(this); + int from_bitField0_ = this.bitField0_; + int to_bitField0_ = 0; + if ((from_bitField0_ & 0x1) == 1) + to_bitField0_ |= 0x1; + result.azimuth_ = this.azimuth_; + if (this.spectrumsBuilder_ == null) { + if ((this.bitField0_ & 0x2) == 2) { + this.spectrums_ = Collections.unmodifiableList(this.spectrums_); + this.bitField0_ &= 0xFFFFFFFD; + } + result.spectrums_ = this.spectrums_; + } else { + result.spectrums_ = this.spectrumsBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(Message other) { + if (other instanceof LineSpectrum) + return mergeFrom((LineSpectrum)other); + super.mergeFrom(other); + return this; + } + + public Builder mergeFrom(LineSpectrum other) { + if (other == LineSpectrum.getDefaultInstance()) + return this; + if (other.hasAzimuth()) + setAzimuth(other.getAzimuth()); + if (this.spectrumsBuilder_ == null) { + if (!other.spectrums_.isEmpty()) { + if (this.spectrums_.isEmpty()) { + this.spectrums_ = other.spectrums_; + this.bitField0_ &= 0xFFFFFFFD; + } else { + ensureSpectrumsIsMutable(); + this.spectrums_.addAll(other.spectrums_); + } + onChanged(); + } + } else if (!other.spectrums_.isEmpty()) { + if (this.spectrumsBuilder_.isEmpty()) { + this.spectrumsBuilder_.dispose(); + this.spectrumsBuilder_ = null; + this.spectrums_ = other.spectrums_; + this.bitField0_ &= 0xFFFFFFFD; + this.spectrumsBuilder_ = LineSpectrum.alwaysUseFieldBuilders ? getSpectrumsFieldBuilder() : null; + } else { + this.spectrumsBuilder_.addAllMessages(other.spectrums_); + } + } + mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasAzimuth()) + return false; + for (int i = 0; i < getSpectrumsCount(); i++) { + if (!getSpectrums(i).isInitialized()) + return false; + } + return true; + } + + public Builder mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + LineSpectrum parsedMessage = null; + try { + parsedMessage = (LineSpectrum) LineSpectrum.PARSER.parsePartialFrom(input, extensionRegistry); + } catch (InvalidProtocolBufferException e) { + parsedMessage = (LineSpectrum)e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) + mergeFrom(parsedMessage); + } + return this; + } + + public boolean hasAzimuth() { + return ((this.bitField0_ & 0x1) == 1); + } + + public double getAzimuth() { + return this.azimuth_; + } + + public Builder setAzimuth(double value) { + this.bitField0_ |= 0x1; + this.azimuth_ = value; + onChanged(); + return this; + } + + public Builder clearAzimuth() { + this.bitField0_ &= 0xFFFFFFFE; + this.azimuth_ = 0.0D; + onChanged(); + return this; + } + + private void ensureSpectrumsIsMutable() { + if ((this.bitField0_ & 0x2) != 2) { + this.spectrums_ = new ArrayList(this.spectrums_); + this.bitField0_ |= 0x2; + } + } + + public List getSpectrumsList() { + if (this.spectrumsBuilder_ == null) + return Collections.unmodifiableList(this.spectrums_); + return this.spectrumsBuilder_.getMessageList(); + } + + public int getSpectrumsCount() { + if (this.spectrumsBuilder_ == null) + return this.spectrums_.size(); + return this.spectrumsBuilder_.getCount(); + } + + public Spectrum getSpectrums(int index) { + if (this.spectrumsBuilder_ == null) + return this.spectrums_.get(index); + return (Spectrum)this.spectrumsBuilder_.getMessage(index); + } + + public Builder setSpectrums(int index, Spectrum value) { + if (this.spectrumsBuilder_ == null) { + if (value == null) + throw new NullPointerException(); + ensureSpectrumsIsMutable(); + this.spectrums_.set(index, value); + onChanged(); + } else { + this.spectrumsBuilder_.setMessage(index, value); + } + return this; + } + + public Builder setSpectrums(int index, Spectrum.Builder builderForValue) { + if (this.spectrumsBuilder_ == null) { + ensureSpectrumsIsMutable(); + this.spectrums_.set(index, builderForValue.build()); + onChanged(); + } else { + this.spectrumsBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + + public Builder addSpectrums(Spectrum value) { + if (this.spectrumsBuilder_ == null) { + if (value == null) + throw new NullPointerException(); + ensureSpectrumsIsMutable(); + this.spectrums_.add(value); + onChanged(); + } else { + this.spectrumsBuilder_.addMessage(value); + } + return this; + } + + public Builder addSpectrums(int index, Spectrum value) { + if (this.spectrumsBuilder_ == null) { + if (value == null) + throw new NullPointerException(); + ensureSpectrumsIsMutable(); + this.spectrums_.add(index, value); + onChanged(); + } else { + this.spectrumsBuilder_.addMessage(index, value); + } + return this; + } + + public Builder addSpectrums(Spectrum.Builder builderForValue) { + if (this.spectrumsBuilder_ == null) { + ensureSpectrumsIsMutable(); + this.spectrums_.add(builderForValue.build()); + onChanged(); + } else { + this.spectrumsBuilder_.addMessage(builderForValue.build()); + } + return this; + } + + public Builder addSpectrums(int index, Spectrum.Builder builderForValue) { + if (this.spectrumsBuilder_ == null) { + ensureSpectrumsIsMutable(); + this.spectrums_.add(index, builderForValue.build()); + onChanged(); + } else { + this.spectrumsBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + + public Builder addAllSpectrums(Iterable values) { + if (this.spectrumsBuilder_ == null) { + ensureSpectrumsIsMutable(); + AbstractMessageLite.Builder.addAll(values, this.spectrums_); + onChanged(); + } else { + this.spectrumsBuilder_.addAllMessages(values); + } + return this; + } + + public Builder clearSpectrums() { + if (this.spectrumsBuilder_ == null) { + this.spectrums_ = Collections.emptyList(); + this.bitField0_ &= 0xFFFFFFFD; + onChanged(); + } else { + this.spectrumsBuilder_.clear(); + } + return this; + } + + public Builder removeSpectrums(int index) { + if (this.spectrumsBuilder_ == null) { + ensureSpectrumsIsMutable(); + this.spectrums_.remove(index); + onChanged(); + } else { + this.spectrumsBuilder_.remove(index); + } + return this; + } + + public Spectrum.Builder getSpectrumsBuilder(int index) { + return (Spectrum.Builder)getSpectrumsFieldBuilder().getBuilder(index); + } + + public SpectrumOrBuilder getSpectrumsOrBuilder(int index) { + if (this.spectrumsBuilder_ == null) + return this.spectrums_.get(index); + return (SpectrumOrBuilder)this.spectrumsBuilder_.getMessageOrBuilder(index); + } + + public List getSpectrumsOrBuilderList() { + if (this.spectrumsBuilder_ != null) + return this.spectrumsBuilder_.getMessageOrBuilderList(); + return Collections.unmodifiableList((List)this.spectrums_); + } + + public Spectrum.Builder addSpectrumsBuilder() { + return (Spectrum.Builder)getSpectrumsFieldBuilder().addBuilder(Spectrum.getDefaultInstance()); + } + + public Spectrum.Builder addSpectrumsBuilder(int index) { + return (Spectrum.Builder)getSpectrumsFieldBuilder().addBuilder(index, Spectrum.getDefaultInstance()); + } + + public List getSpectrumsBuilderList() { + return getSpectrumsFieldBuilder().getBuilderList(); + } + + private RepeatedFieldBuilder getSpectrumsFieldBuilder() { + if (this.spectrumsBuilder_ == null) { + this.spectrumsBuilder_ = new RepeatedFieldBuilder(this.spectrums_, ((this.bitField0_ & 0x2) == 2), getParentForChildren(), isClean()); + this.spectrums_ = null; + } + return this.spectrumsBuilder_; + } + } + + static { + defaultInstance.initFields(); + } + } + + public static final class SectorSpectrum extends GeneratedMessage implements SectorSpectrumOrBuilder { + private static final SectorSpectrum defaultInstance = new SectorSpectrum(true); + + private final UnknownFieldSet unknownFields; + + private SectorSpectrum(GeneratedMessage.Builder builder) { + super(builder); + this.memoizedIsInitialized = -1; + this.memoizedSerializedSize = -1; + this.unknownFields = builder.getUnknownFields(); + } + + private SectorSpectrum(boolean noInit) { + this.memoizedIsInitialized = -1; + this.memoizedSerializedSize = -1; + this.unknownFields = UnknownFieldSet.getDefaultInstance(); + } + + public static SectorSpectrum getDefaultInstance() { + return defaultInstance; + } + + public SectorSpectrum getDefaultInstanceForType() { + return defaultInstance; + } + + public final UnknownFieldSet getUnknownFields() { + return this.unknownFields; + } + + private SectorSpectrum(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + this.memoizedIsInitialized = -1; + this.memoizedSerializedSize = -1; + initFields(); + int mutable_bitField0_ = 0; + UnknownFieldSet.Builder unknownFields = UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: + this.bitField0_ |= 0x1; + this.sectorIndex_ = input.readInt32(); + break; + case 18: + if ((mutable_bitField0_ & 0x2) != 2) { + this.lineSpectrums_ = new ArrayList(); + mutable_bitField0_ |= 0x2; + } + this.lineSpectrums_.add((LineSpectrum)input.readMessage(LineSpectrum.PARSER, extensionRegistry)); + break; + } + } + } catch (InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (IOException e) { + throw (new InvalidProtocolBufferException(e.getMessage())).setUnfinishedMessage(this); + } finally { + if ((mutable_bitField0_ & 0x2) == 2) + this.lineSpectrums_ = Collections.unmodifiableList(this.lineSpectrums_); + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + + public static final Descriptors.Descriptor getDescriptor() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_SectorSpectrum_descriptor; + } + + protected FieldAccessorTable internalGetFieldAccessorTable() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_SectorSpectrum_fieldAccessorTable.ensureFieldAccessorsInitialized(SectorSpectrum.class, Builder.class); + } + + public static Parser PARSER = (Parser)new AbstractParser() { + public SectorSpectrum parsePartialFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + return new SectorSpectrum(input, extensionRegistry); + } + }; + + private int bitField0_; + + public static final int SECTORINDEX_FIELD_NUMBER = 1; + + private int sectorIndex_; + + public static final int LINESPECTRUMS_FIELD_NUMBER = 2; + + private List lineSpectrums_; + + private byte memoizedIsInitialized; + + private int memoizedSerializedSize; + + private static final long serialVersionUID = 0L; + + public Parser getParserForType() { + return PARSER; + } + + public boolean hasSectorIndex() { + return ((this.bitField0_ & 0x1) == 1); + } + + public int getSectorIndex() { + return this.sectorIndex_; + } + + public List getLineSpectrumsList() { + return this.lineSpectrums_; + } + + public List getLineSpectrumsOrBuilderList() { + return (List)this.lineSpectrums_; + } + + public int getLineSpectrumsCount() { + return this.lineSpectrums_.size(); + } + + public LineSpectrum getLineSpectrums(int index) { + return this.lineSpectrums_.get(index); + } + + public LineSpectrumOrBuilder getLineSpectrumsOrBuilder(int index) { + return this.lineSpectrums_.get(index); + } + + private void initFields() { + this.sectorIndex_ = 0; + this.lineSpectrums_ = Collections.emptyList(); + } + + public final boolean isInitialized() { + byte isInitialized = this.memoizedIsInitialized; + if (isInitialized == 1) + return true; + if (isInitialized == 0) + return false; + if (!hasSectorIndex()) { + this.memoizedIsInitialized = 0; + return false; + } + for (int i = 0; i < getLineSpectrumsCount(); i++) { + if (!getLineSpectrums(i).isInitialized()) { + this.memoizedIsInitialized = 0; + return false; + } + } + this.memoizedIsInitialized = 1; + return true; + } + + public void writeTo(CodedOutputStream output) throws IOException { + getSerializedSize(); + if ((this.bitField0_ & 0x1) == 1) + output.writeInt32(1, this.sectorIndex_); + for (int i = 0; i < this.lineSpectrums_.size(); i++) + output.writeMessage(2, (MessageLite)this.lineSpectrums_.get(i)); + getUnknownFields().writeTo(output); + } + + public int getSerializedSize() { + int size = this.memoizedSerializedSize; + if (size != -1) + return size; + size = 0; + if ((this.bitField0_ & 0x1) == 1) + size += CodedOutputStream.computeInt32Size(1, this.sectorIndex_); + for (int i = 0; i < this.lineSpectrums_.size(); i++) + size += CodedOutputStream.computeMessageSize(2, (MessageLite)this.lineSpectrums_.get(i)); + size += getUnknownFields().getSerializedSize(); + this.memoizedSerializedSize = size; + return size; + } + + protected Object writeReplace() throws ObjectStreamException { + return super.writeReplace(); + } + + public static SectorSpectrum parseFrom(ByteString data) throws InvalidProtocolBufferException { + return (SectorSpectrum)PARSER.parseFrom(data); + } + + public static SectorSpectrum parseFrom(ByteString data, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + return (SectorSpectrum)PARSER.parseFrom(data, extensionRegistry); + } + + public static SectorSpectrum parseFrom(byte[] data) throws InvalidProtocolBufferException { + return (SectorSpectrum)PARSER.parseFrom(data); + } + + public static SectorSpectrum parseFrom(byte[] data, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + return (SectorSpectrum)PARSER.parseFrom(data, extensionRegistry); + } + + public static SectorSpectrum parseFrom(InputStream input) throws IOException { + return (SectorSpectrum)PARSER.parseFrom(input); + } + + public static SectorSpectrum parseFrom(InputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + return (SectorSpectrum)PARSER.parseFrom(input, extensionRegistry); + } + + public static SectorSpectrum parseDelimitedFrom(InputStream input) throws IOException { + return (SectorSpectrum)PARSER.parseDelimitedFrom(input); + } + + public static SectorSpectrum parseDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + return (SectorSpectrum)PARSER.parseDelimitedFrom(input, extensionRegistry); + } + + public static SectorSpectrum parseFrom(CodedInputStream input) throws IOException { + return (SectorSpectrum)PARSER.parseFrom(input); + } + + public static SectorSpectrum parseFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + return (SectorSpectrum)PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { + return Builder.create(); + } + + public Builder newBuilderForType() { + return newBuilder(); + } + + public static Builder newBuilder(SectorSpectrum prototype) { + return newBuilder().mergeFrom(prototype); + } + + public Builder toBuilder() { + return newBuilder(this); + } + + protected Builder newBuilderForType(BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + + public static final class Builder extends GeneratedMessage.Builder implements SectorSpectrumOrBuilder { + private int bitField0_; + + private int sectorIndex_; + + private List lineSpectrums_; + + private RepeatedFieldBuilder lineSpectrumsBuilder_; + + public static final Descriptors.Descriptor getDescriptor() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_SectorSpectrum_descriptor; + } + + protected FieldAccessorTable internalGetFieldAccessorTable() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_SectorSpectrum_fieldAccessorTable.ensureFieldAccessorsInitialized(SectorSpectrum.class, Builder.class); + } + + private Builder() { + this.lineSpectrums_ = Collections.emptyList(); + maybeForceBuilderInitialization(); + } + + private Builder(BuilderParent parent) { + super(parent); + this.lineSpectrums_ = Collections.emptyList(); + maybeForceBuilderInitialization(); + } + + private void maybeForceBuilderInitialization() { + if (SectorSpectrum.alwaysUseFieldBuilders) + getLineSpectrumsFieldBuilder(); + } + + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + this.sectorIndex_ = 0; + this.bitField0_ &= 0xFFFFFFFE; + if (this.lineSpectrumsBuilder_ == null) { + this.lineSpectrums_ = Collections.emptyList(); + this.bitField0_ &= 0xFFFFFFFD; + } else { + this.lineSpectrumsBuilder_.clear(); + } + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public Descriptors.Descriptor getDescriptorForType() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_SectorSpectrum_descriptor; + } + + public SectorSpectrum getDefaultInstanceForType() { + return SectorSpectrum.getDefaultInstance(); + } + + public SectorSpectrum build() { + SectorSpectrum result = buildPartial(); + if (!result.isInitialized()) + throw newUninitializedMessageException(result); + return result; + } + + public SectorSpectrum buildPartial() { + SectorSpectrum result = new SectorSpectrum(this); + int from_bitField0_ = this.bitField0_; + int to_bitField0_ = 0; + if ((from_bitField0_ & 0x1) == 1) + to_bitField0_ |= 0x1; + result.sectorIndex_ = this.sectorIndex_; + if (this.lineSpectrumsBuilder_ == null) { + if ((this.bitField0_ & 0x2) == 2) { + this.lineSpectrums_ = Collections.unmodifiableList(this.lineSpectrums_); + this.bitField0_ &= 0xFFFFFFFD; + } + result.lineSpectrums_ = this.lineSpectrums_; + } else { + result.lineSpectrums_ = this.lineSpectrumsBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(Message other) { + if (other instanceof SectorSpectrum) + return mergeFrom((SectorSpectrum)other); + super.mergeFrom(other); + return this; + } + + public Builder mergeFrom(SectorSpectrum other) { + if (other == SectorSpectrum.getDefaultInstance()) + return this; + if (other.hasSectorIndex()) + setSectorIndex(other.getSectorIndex()); + if (this.lineSpectrumsBuilder_ == null) { + if (!other.lineSpectrums_.isEmpty()) { + if (this.lineSpectrums_.isEmpty()) { + this.lineSpectrums_ = other.lineSpectrums_; + this.bitField0_ &= 0xFFFFFFFD; + } else { + ensureLineSpectrumsIsMutable(); + this.lineSpectrums_.addAll(other.lineSpectrums_); + } + onChanged(); + } + } else if (!other.lineSpectrums_.isEmpty()) { + if (this.lineSpectrumsBuilder_.isEmpty()) { + this.lineSpectrumsBuilder_.dispose(); + this.lineSpectrumsBuilder_ = null; + this.lineSpectrums_ = other.lineSpectrums_; + this.bitField0_ &= 0xFFFFFFFD; + this.lineSpectrumsBuilder_ = SectorSpectrum.alwaysUseFieldBuilders ? getLineSpectrumsFieldBuilder() : null; + } else { + this.lineSpectrumsBuilder_.addAllMessages(other.lineSpectrums_); + } + } + mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasSectorIndex()) + return false; + for (int i = 0; i < getLineSpectrumsCount(); i++) { + if (!getLineSpectrums(i).isInitialized()) + return false; + } + return true; + } + + public Builder mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + SectorSpectrum parsedMessage = null; + try { + parsedMessage = (SectorSpectrum) SectorSpectrum.PARSER.parsePartialFrom(input, extensionRegistry); + } catch (InvalidProtocolBufferException e) { + parsedMessage = (SectorSpectrum)e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) + mergeFrom(parsedMessage); + } + return this; + } + + public boolean hasSectorIndex() { + return ((this.bitField0_ & 0x1) == 1); + } + + public int getSectorIndex() { + return this.sectorIndex_; + } + + public Builder setSectorIndex(int value) { + this.bitField0_ |= 0x1; + this.sectorIndex_ = value; + onChanged(); + return this; + } + + public Builder clearSectorIndex() { + this.bitField0_ &= 0xFFFFFFFE; + this.sectorIndex_ = 0; + onChanged(); + return this; + } + + private void ensureLineSpectrumsIsMutable() { + if ((this.bitField0_ & 0x2) != 2) { + this.lineSpectrums_ = new ArrayList(this.lineSpectrums_); + this.bitField0_ |= 0x2; + } + } + + public List getLineSpectrumsList() { + if (this.lineSpectrumsBuilder_ == null) + return Collections.unmodifiableList(this.lineSpectrums_); + return this.lineSpectrumsBuilder_.getMessageList(); + } + + public int getLineSpectrumsCount() { + if (this.lineSpectrumsBuilder_ == null) + return this.lineSpectrums_.size(); + return this.lineSpectrumsBuilder_.getCount(); + } + + public LineSpectrum getLineSpectrums(int index) { + if (this.lineSpectrumsBuilder_ == null) + return this.lineSpectrums_.get(index); + return (LineSpectrum)this.lineSpectrumsBuilder_.getMessage(index); + } + + public Builder setLineSpectrums(int index, LineSpectrum value) { + if (this.lineSpectrumsBuilder_ == null) { + if (value == null) + throw new NullPointerException(); + ensureLineSpectrumsIsMutable(); + this.lineSpectrums_.set(index, value); + onChanged(); + } else { + this.lineSpectrumsBuilder_.setMessage(index, value); + } + return this; + } + + public Builder setLineSpectrums(int index, LineSpectrum.Builder builderForValue) { + if (this.lineSpectrumsBuilder_ == null) { + ensureLineSpectrumsIsMutable(); + this.lineSpectrums_.set(index, builderForValue.build()); + onChanged(); + } else { + this.lineSpectrumsBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + + public Builder addLineSpectrums(LineSpectrum value) { + if (this.lineSpectrumsBuilder_ == null) { + if (value == null) + throw new NullPointerException(); + ensureLineSpectrumsIsMutable(); + this.lineSpectrums_.add(value); + onChanged(); + } else { + this.lineSpectrumsBuilder_.addMessage(value); + } + return this; + } + + public Builder addLineSpectrums(int index, LineSpectrum value) { + if (this.lineSpectrumsBuilder_ == null) { + if (value == null) + throw new NullPointerException(); + ensureLineSpectrumsIsMutable(); + this.lineSpectrums_.add(index, value); + onChanged(); + } else { + this.lineSpectrumsBuilder_.addMessage(index, value); + } + return this; + } + + public Builder addLineSpectrums(LineSpectrum.Builder builderForValue) { + if (this.lineSpectrumsBuilder_ == null) { + ensureLineSpectrumsIsMutable(); + this.lineSpectrums_.add(builderForValue.build()); + onChanged(); + } else { + this.lineSpectrumsBuilder_.addMessage(builderForValue.build()); + } + return this; + } + + public Builder addLineSpectrums(int index, LineSpectrum.Builder builderForValue) { + if (this.lineSpectrumsBuilder_ == null) { + ensureLineSpectrumsIsMutable(); + this.lineSpectrums_.add(index, builderForValue.build()); + onChanged(); + } else { + this.lineSpectrumsBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + + public Builder addAllLineSpectrums(Iterable values) { + if (this.lineSpectrumsBuilder_ == null) { + ensureLineSpectrumsIsMutable(); + AbstractMessageLite.Builder.addAll(values, this.lineSpectrums_); + onChanged(); + } else { + this.lineSpectrumsBuilder_.addAllMessages(values); + } + return this; + } + + public Builder clearLineSpectrums() { + if (this.lineSpectrumsBuilder_ == null) { + this.lineSpectrums_ = Collections.emptyList(); + this.bitField0_ &= 0xFFFFFFFD; + onChanged(); + } else { + this.lineSpectrumsBuilder_.clear(); + } + return this; + } + + public Builder removeLineSpectrums(int index) { + if (this.lineSpectrumsBuilder_ == null) { + ensureLineSpectrumsIsMutable(); + this.lineSpectrums_.remove(index); + onChanged(); + } else { + this.lineSpectrumsBuilder_.remove(index); + } + return this; + } + + public LineSpectrum.Builder getLineSpectrumsBuilder(int index) { + return (LineSpectrum.Builder)getLineSpectrumsFieldBuilder().getBuilder(index); + } + + public LineSpectrumOrBuilder getLineSpectrumsOrBuilder(int index) { + if (this.lineSpectrumsBuilder_ == null) + return this.lineSpectrums_.get(index); + return (LineSpectrumOrBuilder)this.lineSpectrumsBuilder_.getMessageOrBuilder(index); + } + + public List getLineSpectrumsOrBuilderList() { + if (this.lineSpectrumsBuilder_ != null) + return this.lineSpectrumsBuilder_.getMessageOrBuilderList(); + return Collections.unmodifiableList((List)this.lineSpectrums_); + } + + public LineSpectrum.Builder addLineSpectrumsBuilder() { + return (LineSpectrum.Builder)getLineSpectrumsFieldBuilder().addBuilder(LineSpectrum.getDefaultInstance()); + } + + public LineSpectrum.Builder addLineSpectrumsBuilder(int index) { + return (LineSpectrum.Builder)getLineSpectrumsFieldBuilder().addBuilder(index, LineSpectrum.getDefaultInstance()); + } + + public List getLineSpectrumsBuilderList() { + return getLineSpectrumsFieldBuilder().getBuilderList(); + } + + private RepeatedFieldBuilder getLineSpectrumsFieldBuilder() { + if (this.lineSpectrumsBuilder_ == null) { + this.lineSpectrumsBuilder_ = new RepeatedFieldBuilder(this.lineSpectrums_, ((this.bitField0_ & 0x2) == 2), getParentForChildren(), isClean()); + this.lineSpectrums_ = null; + } + return this.lineSpectrumsBuilder_; + } + } + + static { + defaultInstance.initFields(); + } + } + + public static final class RadarVideo extends GeneratedMessage implements RadarVideoOrBuilder { + private static final RadarVideo defaultInstance = new RadarVideo(true); + + private final UnknownFieldSet unknownFields; + + private RadarVideo(GeneratedMessage.Builder builder) { + super(builder); + this.memoizedIsInitialized = -1; + this.memoizedSerializedSize = -1; + this.unknownFields = builder.getUnknownFields(); + } + + private RadarVideo(boolean noInit) { + this.memoizedIsInitialized = -1; + this.memoizedSerializedSize = -1; + this.unknownFields = UnknownFieldSet.getDefaultInstance(); + } + + public static RadarVideo getDefaultInstance() { + return defaultInstance; + } + + public RadarVideo getDefaultInstanceForType() { + return defaultInstance; + } + + public final UnknownFieldSet getUnknownFields() { + return this.unknownFields; + } + + private RadarVideo(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + this.memoizedIsInitialized = -1; + this.memoizedSerializedSize = -1; + initFields(); + int mutable_bitField0_ = 0; + UnknownFieldSet.Builder unknownFields = UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + ByteString bs; + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: + this.bitField0_ |= 0x1; + this.flag_ = input.readInt32(); + break; + case 18: + bs = input.readBytes(); + this.bitField0_ |= 0x2; + this.sourceId_ = bs; + break; + case 24: + this.bitField0_ |= 0x4; + this.uTC_ = input.readUInt64(); + break; + case 32: + this.bitField0_ |= 0x8; + this.length_ = input.readInt32(); + break; + case 42: + if ((mutable_bitField0_ & 0x10) != 16) { + this.sectorSpectrums_ = new ArrayList(); + mutable_bitField0_ |= 0x10; + } + this.sectorSpectrums_.add((SectorSpectrum)input.readMessage(SectorSpectrum.PARSER, extensionRegistry)); + break; + } + } + } catch (InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (IOException e) { + throw (new InvalidProtocolBufferException(e.getMessage())).setUnfinishedMessage(this); + } finally { + if ((mutable_bitField0_ & 0x10) == 16) + this.sectorSpectrums_ = Collections.unmodifiableList(this.sectorSpectrums_); + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + + public static final Descriptors.Descriptor getDescriptor() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_RadarVideo_descriptor; + } + + protected FieldAccessorTable internalGetFieldAccessorTable() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_RadarVideo_fieldAccessorTable.ensureFieldAccessorsInitialized(RadarVideo.class, Builder.class); + } + + public static Parser PARSER = (Parser)new AbstractParser() { + public RadarVideo parsePartialFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + return new RadarVideo(input, extensionRegistry); + } + }; + + private int bitField0_; + + public static final int FLAG_FIELD_NUMBER = 1; + + private int flag_; + + public static final int SOURCEID_FIELD_NUMBER = 2; + + private Object sourceId_; + + public static final int UTC_FIELD_NUMBER = 3; + + private long uTC_; + + public static final int LENGTH_FIELD_NUMBER = 4; + + private int length_; + + public static final int SECTORSPECTRUMS_FIELD_NUMBER = 5; + + private List sectorSpectrums_; + + private byte memoizedIsInitialized; + + private int memoizedSerializedSize; + + private static final long serialVersionUID = 0L; + + public Parser getParserForType() { + return PARSER; + } + + public boolean hasFlag() { + return ((this.bitField0_ & 0x1) == 1); + } + + public int getFlag() { + return this.flag_; + } + + public boolean hasSourceId() { + return ((this.bitField0_ & 0x2) == 2); + } + + public String getSourceId() { + Object ref = this.sourceId_; + if (ref instanceof String) + return (String)ref; + ByteString bs = (ByteString)ref; + String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) + this.sourceId_ = s; + return s; + } + + public ByteString getSourceIdBytes() { + Object ref = this.sourceId_; + if (ref instanceof String) { + ByteString b = ByteString.copyFromUtf8((String)ref); + this.sourceId_ = b; + return b; + } + return (ByteString)ref; + } + + public boolean hasUTC() { + return ((this.bitField0_ & 0x4) == 4); + } + + public long getUTC() { + return this.uTC_; + } + + public boolean hasLength() { + return ((this.bitField0_ & 0x8) == 8); + } + + public int getLength() { + return this.length_; + } + + public List getSectorSpectrumsList() { + return this.sectorSpectrums_; + } + + public List getSectorSpectrumsOrBuilderList() { + return (List)this.sectorSpectrums_; + } + + public int getSectorSpectrumsCount() { + return this.sectorSpectrums_.size(); + } + + public SectorSpectrum getSectorSpectrums(int index) { + return this.sectorSpectrums_.get(index); + } + + public SectorSpectrumOrBuilder getSectorSpectrumsOrBuilder(int index) { + return this.sectorSpectrums_.get(index); + } + + private void initFields() { + this.flag_ = 0; + this.sourceId_ = ""; + this.uTC_ = 0L; + this.length_ = 0; + this.sectorSpectrums_ = Collections.emptyList(); + } + + public final boolean isInitialized() { + byte isInitialized = this.memoizedIsInitialized; + if (isInitialized == 1) + return true; + if (isInitialized == 0) + return false; + if (!hasFlag()) { + this.memoizedIsInitialized = 0; + return false; + } + if (!hasSourceId()) { + this.memoizedIsInitialized = 0; + return false; + } + if (!hasUTC()) { + this.memoizedIsInitialized = 0; + return false; + } + if (!hasLength()) { + this.memoizedIsInitialized = 0; + return false; + } + for (int i = 0; i < getSectorSpectrumsCount(); i++) { + if (!getSectorSpectrums(i).isInitialized()) { + this.memoizedIsInitialized = 0; + return false; + } + } + this.memoizedIsInitialized = 1; + return true; + } + + public void writeTo(CodedOutputStream output) throws IOException { + getSerializedSize(); + if ((this.bitField0_ & 0x1) == 1) + output.writeInt32(1, this.flag_); + if ((this.bitField0_ & 0x2) == 2) + output.writeBytes(2, getSourceIdBytes()); + if ((this.bitField0_ & 0x4) == 4) + output.writeUInt64(3, this.uTC_); + if ((this.bitField0_ & 0x8) == 8) + output.writeInt32(4, this.length_); + for (int i = 0; i < this.sectorSpectrums_.size(); i++) + output.writeMessage(5, (MessageLite)this.sectorSpectrums_.get(i)); + getUnknownFields().writeTo(output); + } + + public int getSerializedSize() { + int size = this.memoizedSerializedSize; + if (size != -1) + return size; + size = 0; + if ((this.bitField0_ & 0x1) == 1) + size += CodedOutputStream.computeInt32Size(1, this.flag_); + if ((this.bitField0_ & 0x2) == 2) + size += CodedOutputStream.computeBytesSize(2, getSourceIdBytes()); + if ((this.bitField0_ & 0x4) == 4) + size += CodedOutputStream.computeUInt64Size(3, this.uTC_); + if ((this.bitField0_ & 0x8) == 8) + size += CodedOutputStream.computeInt32Size(4, this.length_); + for (int i = 0; i < this.sectorSpectrums_.size(); i++) + size += CodedOutputStream.computeMessageSize(5, (MessageLite)this.sectorSpectrums_.get(i)); + size += getUnknownFields().getSerializedSize(); + this.memoizedSerializedSize = size; + return size; + } + + protected Object writeReplace() throws ObjectStreamException { + return super.writeReplace(); + } + + public static RadarVideo parseFrom(ByteString data) throws InvalidProtocolBufferException { + return (RadarVideo)PARSER.parseFrom(data); + } + + public static RadarVideo parseFrom(ByteString data, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + return (RadarVideo)PARSER.parseFrom(data, extensionRegistry); + } + + public static RadarVideo parseFrom(byte[] data) throws InvalidProtocolBufferException { + return (RadarVideo)PARSER.parseFrom(data); + } + + public static RadarVideo parseFrom(byte[] data, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { + return (RadarVideo)PARSER.parseFrom(data, extensionRegistry); + } + + public static RadarVideo parseFrom(InputStream input) throws IOException { + return (RadarVideo)PARSER.parseFrom(input); + } + + public static RadarVideo parseFrom(InputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + return (RadarVideo)PARSER.parseFrom(input, extensionRegistry); + } + + public static RadarVideo parseDelimitedFrom(InputStream input) throws IOException { + return (RadarVideo)PARSER.parseDelimitedFrom(input); + } + + public static RadarVideo parseDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + return (RadarVideo)PARSER.parseDelimitedFrom(input, extensionRegistry); + } + + public static RadarVideo parseFrom(CodedInputStream input) throws IOException { + return (RadarVideo)PARSER.parseFrom(input); + } + + public static RadarVideo parseFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + return (RadarVideo)PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { + return Builder.create(); + } + + public Builder newBuilderForType() { + return newBuilder(); + } + + public static Builder newBuilder(RadarVideo prototype) { + return newBuilder().mergeFrom(prototype); + } + + public Builder toBuilder() { + return newBuilder(this); + } + + protected Builder newBuilderForType(BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + + public static final class Builder extends GeneratedMessage.Builder implements RadarVideoOrBuilder { + private int bitField0_; + + private int flag_; + + private Object sourceId_; + + private long uTC_; + + private int length_; + + private List sectorSpectrums_; + + private RepeatedFieldBuilder sectorSpectrumsBuilder_; + + public static final Descriptors.Descriptor getDescriptor() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_RadarVideo_descriptor; + } + + protected FieldAccessorTable internalGetFieldAccessorTable() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_RadarVideo_fieldAccessorTable.ensureFieldAccessorsInitialized(RadarVideo.class, Builder.class); + } + + private Builder() { + this.sourceId_ = ""; + this.sectorSpectrums_ = Collections.emptyList(); + maybeForceBuilderInitialization(); + } + + private Builder(BuilderParent parent) { + super(parent); + this.sourceId_ = ""; + this.sectorSpectrums_ = Collections.emptyList(); + maybeForceBuilderInitialization(); + } + + private void maybeForceBuilderInitialization() { + if (RadarVideo.alwaysUseFieldBuilders) + getSectorSpectrumsFieldBuilder(); + } + + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + this.flag_ = 0; + this.bitField0_ &= 0xFFFFFFFE; + this.sourceId_ = ""; + this.bitField0_ &= 0xFFFFFFFD; + this.uTC_ = 0L; + this.bitField0_ &= 0xFFFFFFFB; + this.length_ = 0; + this.bitField0_ &= 0xFFFFFFF7; + if (this.sectorSpectrumsBuilder_ == null) { + this.sectorSpectrums_ = Collections.emptyList(); + this.bitField0_ &= 0xFFFFFFEF; + } else { + this.sectorSpectrumsBuilder_.clear(); + } + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public Descriptors.Descriptor getDescriptorForType() { + return ZCHXRadar.internal_static_com_zhichenhaixin_proto_RadarVideo_descriptor; + } + + public RadarVideo getDefaultInstanceForType() { + return RadarVideo.getDefaultInstance(); + } + + public RadarVideo build() { + RadarVideo result = buildPartial(); + if (!result.isInitialized()) + throw newUninitializedMessageException(result); + return result; + } + + public RadarVideo buildPartial() { + RadarVideo result = new RadarVideo(this); + int from_bitField0_ = this.bitField0_; + int to_bitField0_ = 0; + if ((from_bitField0_ & 0x1) == 1) + to_bitField0_ |= 0x1; + result.flag_ = this.flag_; + if ((from_bitField0_ & 0x2) == 2) + to_bitField0_ |= 0x2; + result.sourceId_ = this.sourceId_; + if ((from_bitField0_ & 0x4) == 4) + to_bitField0_ |= 0x4; + result.uTC_ = this.uTC_; + if ((from_bitField0_ & 0x8) == 8) + to_bitField0_ |= 0x8; + result.length_ = this.length_; + if (this.sectorSpectrumsBuilder_ == null) { + if ((this.bitField0_ & 0x10) == 16) { + this.sectorSpectrums_ = Collections.unmodifiableList(this.sectorSpectrums_); + this.bitField0_ &= 0xFFFFFFEF; + } + result.sectorSpectrums_ = this.sectorSpectrums_; + } else { + result.sectorSpectrums_ = this.sectorSpectrumsBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(Message other) { + if (other instanceof RadarVideo) + return mergeFrom((RadarVideo)other); + super.mergeFrom(other); + return this; + } + + public Builder mergeFrom(RadarVideo other) { + if (other == RadarVideo.getDefaultInstance()) + return this; + if (other.hasFlag()) + setFlag(other.getFlag()); + if (other.hasSourceId()) { + this.bitField0_ |= 0x2; + this.sourceId_ = other.sourceId_; + onChanged(); + } + if (other.hasUTC()) + setUTC(other.getUTC()); + if (other.hasLength()) + setLength(other.getLength()); + if (this.sectorSpectrumsBuilder_ == null) { + if (!other.sectorSpectrums_.isEmpty()) { + if (this.sectorSpectrums_.isEmpty()) { + this.sectorSpectrums_ = other.sectorSpectrums_; + this.bitField0_ &= 0xFFFFFFEF; + } else { + ensureSectorSpectrumsIsMutable(); + this.sectorSpectrums_.addAll(other.sectorSpectrums_); + } + onChanged(); + } + } else if (!other.sectorSpectrums_.isEmpty()) { + if (this.sectorSpectrumsBuilder_.isEmpty()) { + this.sectorSpectrumsBuilder_.dispose(); + this.sectorSpectrumsBuilder_ = null; + this.sectorSpectrums_ = other.sectorSpectrums_; + this.bitField0_ &= 0xFFFFFFEF; + this.sectorSpectrumsBuilder_ = RadarVideo.alwaysUseFieldBuilders ? getSectorSpectrumsFieldBuilder() : null; + } else { + this.sectorSpectrumsBuilder_.addAllMessages(other.sectorSpectrums_); + } + } + mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasFlag()) + return false; + if (!hasSourceId()) + return false; + if (!hasUTC()) + return false; + if (!hasLength()) + return false; + for (int i = 0; i < getSectorSpectrumsCount(); i++) { + if (!getSectorSpectrums(i).isInitialized()) + return false; + } + return true; + } + + public Builder mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { + RadarVideo parsedMessage = null; + try { + parsedMessage = (RadarVideo) RadarVideo.PARSER.parsePartialFrom(input, extensionRegistry); + } catch (InvalidProtocolBufferException e) { + parsedMessage = (RadarVideo)e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) + mergeFrom(parsedMessage); + } + return this; + } + + public boolean hasFlag() { + return ((this.bitField0_ & 0x1) == 1); + } + + public int getFlag() { + return this.flag_; + } + + public Builder setFlag(int value) { + this.bitField0_ |= 0x1; + this.flag_ = value; + onChanged(); + return this; + } + + public Builder clearFlag() { + this.bitField0_ &= 0xFFFFFFFE; + this.flag_ = 0; + onChanged(); + return this; + } + + public boolean hasSourceId() { + return ((this.bitField0_ & 0x2) == 2); + } + + public String getSourceId() { + Object ref = this.sourceId_; + if (!(ref instanceof String)) { + ByteString bs = (ByteString)ref; + String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) + this.sourceId_ = s; + return s; + } + return (String)ref; + } + + public ByteString getSourceIdBytes() { + Object ref = this.sourceId_; + if (ref instanceof String) { + ByteString b = ByteString.copyFromUtf8((String)ref); + this.sourceId_ = b; + return b; + } + return (ByteString)ref; + } + + public Builder setSourceId(String value) { + if (value == null) + throw new NullPointerException(); + this.bitField0_ |= 0x2; + this.sourceId_ = value; + onChanged(); + return this; + } + + public Builder clearSourceId() { + this.bitField0_ &= 0xFFFFFFFD; + this.sourceId_ = RadarVideo.getDefaultInstance().getSourceId(); + onChanged(); + return this; + } + + public Builder setSourceIdBytes(ByteString value) { + if (value == null) + throw new NullPointerException(); + this.bitField0_ |= 0x2; + this.sourceId_ = value; + onChanged(); + return this; + } + + public boolean hasUTC() { + return ((this.bitField0_ & 0x4) == 4); + } + + public long getUTC() { + return this.uTC_; + } + + public Builder setUTC(long value) { + this.bitField0_ |= 0x4; + this.uTC_ = value; + onChanged(); + return this; + } + + public Builder clearUTC() { + this.bitField0_ &= 0xFFFFFFFB; + this.uTC_ = 0L; + onChanged(); + return this; + } + + public boolean hasLength() { + return ((this.bitField0_ & 0x8) == 8); + } + + public int getLength() { + return this.length_; + } + + public Builder setLength(int value) { + this.bitField0_ |= 0x8; + this.length_ = value; + onChanged(); + return this; + } + + public Builder clearLength() { + this.bitField0_ &= 0xFFFFFFF7; + this.length_ = 0; + onChanged(); + return this; + } + + private void ensureSectorSpectrumsIsMutable() { + if ((this.bitField0_ & 0x10) != 16) { + this.sectorSpectrums_ = new ArrayList(this.sectorSpectrums_); + this.bitField0_ |= 0x10; + } + } + + public List getSectorSpectrumsList() { + if (this.sectorSpectrumsBuilder_ == null) + return Collections.unmodifiableList(this.sectorSpectrums_); + return this.sectorSpectrumsBuilder_.getMessageList(); + } + + public int getSectorSpectrumsCount() { + if (this.sectorSpectrumsBuilder_ == null) + return this.sectorSpectrums_.size(); + return this.sectorSpectrumsBuilder_.getCount(); + } + + public SectorSpectrum getSectorSpectrums(int index) { + if (this.sectorSpectrumsBuilder_ == null) + return this.sectorSpectrums_.get(index); + return (SectorSpectrum)this.sectorSpectrumsBuilder_.getMessage(index); + } + + public Builder setSectorSpectrums(int index, SectorSpectrum value) { + if (this.sectorSpectrumsBuilder_ == null) { + if (value == null) + throw new NullPointerException(); + ensureSectorSpectrumsIsMutable(); + this.sectorSpectrums_.set(index, value); + onChanged(); + } else { + this.sectorSpectrumsBuilder_.setMessage(index, value); + } + return this; + } + + public Builder setSectorSpectrums(int index, SectorSpectrum.Builder builderForValue) { + if (this.sectorSpectrumsBuilder_ == null) { + ensureSectorSpectrumsIsMutable(); + this.sectorSpectrums_.set(index, builderForValue.build()); + onChanged(); + } else { + this.sectorSpectrumsBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + + public Builder addSectorSpectrums(SectorSpectrum value) { + if (this.sectorSpectrumsBuilder_ == null) { + if (value == null) + throw new NullPointerException(); + ensureSectorSpectrumsIsMutable(); + this.sectorSpectrums_.add(value); + onChanged(); + } else { + this.sectorSpectrumsBuilder_.addMessage(value); + } + return this; + } + + public Builder addSectorSpectrums(int index, SectorSpectrum value) { + if (this.sectorSpectrumsBuilder_ == null) { + if (value == null) + throw new NullPointerException(); + ensureSectorSpectrumsIsMutable(); + this.sectorSpectrums_.add(index, value); + onChanged(); + } else { + this.sectorSpectrumsBuilder_.addMessage(index, value); + } + return this; + } + + public Builder addSectorSpectrums(SectorSpectrum.Builder builderForValue) { + if (this.sectorSpectrumsBuilder_ == null) { + ensureSectorSpectrumsIsMutable(); + this.sectorSpectrums_.add(builderForValue.build()); + onChanged(); + } else { + this.sectorSpectrumsBuilder_.addMessage(builderForValue.build()); + } + return this; + } + + public Builder addSectorSpectrums(int index, SectorSpectrum.Builder builderForValue) { + if (this.sectorSpectrumsBuilder_ == null) { + ensureSectorSpectrumsIsMutable(); + this.sectorSpectrums_.add(index, builderForValue.build()); + onChanged(); + } else { + this.sectorSpectrumsBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + + public Builder addAllSectorSpectrums(Iterable values) { + if (this.sectorSpectrumsBuilder_ == null) { + ensureSectorSpectrumsIsMutable(); + AbstractMessageLite.Builder.addAll(values, this.sectorSpectrums_); + onChanged(); + } else { + this.sectorSpectrumsBuilder_.addAllMessages(values); + } + return this; + } + + public Builder clearSectorSpectrums() { + if (this.sectorSpectrumsBuilder_ == null) { + this.sectorSpectrums_ = Collections.emptyList(); + this.bitField0_ &= 0xFFFFFFEF; + onChanged(); + } else { + this.sectorSpectrumsBuilder_.clear(); + } + return this; + } + + public Builder removeSectorSpectrums(int index) { + if (this.sectorSpectrumsBuilder_ == null) { + ensureSectorSpectrumsIsMutable(); + this.sectorSpectrums_.remove(index); + onChanged(); + } else { + this.sectorSpectrumsBuilder_.remove(index); + } + return this; + } + + public SectorSpectrum.Builder getSectorSpectrumsBuilder(int index) { + return (SectorSpectrum.Builder)getSectorSpectrumsFieldBuilder().getBuilder(index); + } + + public SectorSpectrumOrBuilder getSectorSpectrumsOrBuilder(int index) { + if (this.sectorSpectrumsBuilder_ == null) + return this.sectorSpectrums_.get(index); + return (SectorSpectrumOrBuilder)this.sectorSpectrumsBuilder_.getMessageOrBuilder(index); + } + + public List getSectorSpectrumsOrBuilderList() { + if (this.sectorSpectrumsBuilder_ != null) + return this.sectorSpectrumsBuilder_.getMessageOrBuilderList(); + return Collections.unmodifiableList((List)this.sectorSpectrums_); + } + + public SectorSpectrum.Builder addSectorSpectrumsBuilder() { + return (SectorSpectrum.Builder)getSectorSpectrumsFieldBuilder().addBuilder(SectorSpectrum.getDefaultInstance()); + } + + public SectorSpectrum.Builder addSectorSpectrumsBuilder(int index) { + return (SectorSpectrum.Builder)getSectorSpectrumsFieldBuilder().addBuilder(index, SectorSpectrum.getDefaultInstance()); + } + + public List getSectorSpectrumsBuilderList() { + return getSectorSpectrumsFieldBuilder().getBuilderList(); + } + + private RepeatedFieldBuilder getSectorSpectrumsFieldBuilder() { + if (this.sectorSpectrumsBuilder_ == null) { + this.sectorSpectrumsBuilder_ = new RepeatedFieldBuilder(this.sectorSpectrums_, ((this.bitField0_ & 0x10) == 16), getParentForChildren(), isClean()); + this.sectorSpectrums_ = null; + } + return this.sectorSpectrumsBuilder_; + } + } + + static { + defaultInstance.initFields(); + } + } + + public static Descriptors.FileDescriptor getDescriptor() { + return descriptor; + } + + static { + String[] descriptorData = { "\n\017ZCHXRadar.proto\022\027com.com.zhichenhaixin.proto\"Å\002\n\021RadarHistoryTrack\022\023\n\013trackNumber\030\001 \002(\r\022\023\n\013wgs84PosLat\030\002 \002(\001\022\024\n\fwgs84PosLong\030\003 \002(\001\022\021\n\ttimeOfDay\030\004 \002(\002\022/\n\ttrackType\030\005 \001(\0162\034.com.com.zhichenhaixin.proto.CNF\022\027\n\017trackLastReport\030\006 \001(\b\0223\n\rextrapolation\030\007 \001(\0162\034.com.com.zhichenhaixin.proto.CST\0227\n\021trackPositionCode\030\b \001(\0162\034.com.com.zhichenhaixin.proto.STH\022\013\n\003cog\030\t \002(\001\022\013\n\003sog\030\n \002(\001\022\013\n\003UTC\030\013 \002(\004\"P\n\022RadarHistoryTracks\022:\n\006trac", "ks\030\001 \003(\0132*.com.com.zhichenhaixin.proto.RadarHistoryTrack\"ï\006\n\nTrackPoint\022\026\n\016systemAreaCode\030\001 \002(\005\022 \n\030systemIdentificationCode\030\002 \002(\005\0224\n\013messageType\030\003 \002(\0162\037.com.com.zhichenhaixin.proto.MSGTYP\022\023\n\013trackNumber\030\004 \002(\r\022\025\n\rcartesianPosX\030\005 \002(\002\022\025\n\rcartesianPosY\030\006 \002(\002\022\023\n\013wgs84PosLat\030\007 \002(\001\022\024\n\fwgs84PosLong\030\b \002(\001\022\021\n\ttimeOfDay\030\t \002(\002\022/\n\ttrackType\030\n \001(\0162\034.com.com.zhichenhaixin.proto.CNF\022\027\n\017trackLastReport\030\013 \001(\b\0223\n\rextrapolation\030", "\f \001(\0162\034.com.com.zhichenhaixin.proto.CST\0227\n\021trackPositionCode\030\r \001(\0162\034.com.com.zhichenhaixin.proto.STH\022\016\n\006sigmaX\030\016 \001(\002\022\016\n\006sigmaY\030\017 \001(\002\022\017\n\007sigmaXY\030\020 \001(\002\022\024\n\fampOfPriPlot\030\021 \001(\002\022\032\n\022cartesianTrkVel_vx\030\022 \002(\001\022\032\n\022cartesianTrkVel_vy\030\023 \002(\001\022\013\n\003cog\030\024 \002(\001\022\013\n\003sog\030\025 \002(\001\022;\n\006tracks\030\026 \001(\0132+.com.com.zhichenhaixin.proto.RadarHistoryTracks\022\016\n\006status\030\027 \001(\005\022\021\n\tisSmuggle\030\030 \001(\005\022\020\n\bdistance\030\031 \001(\001\022\022\n\nwarn_color\030\032 \001(\t\022\022\n\ntargetType\030\033 \001(\005\022", "\023\n\013sign_window\030\034 \001(\005\022\017\n\007is_warn\030\035 \001(\005\022\f\n\004rtsp\030\036 \001(\t\022\r\n\005fllow\030\037 \001(\005\022\f\n\004mode\030 \001(\005\022\021\n\ttimeStamp\030! \001(\003\022\017\n\007trackby\030\" \001(\t\022\020\n\bcameraId\030# \001(\005\"n\n\007FllowVo\022\f\n\004flag\030\001 \002(\b\022\r\n\005fllow\030\002 \002(\b\0228\n\013trackPoints\030\003 \003(\0132#.com.com.zhichenhaixin.proto.TrackPoint\022\f\n\004mode\030\004 \002(\005\"Š\001\n\021RadarSurfaceTrack\022\f\n\004flag\030\001 \002(\005\022\020\n\bsourceId\030\002 \002(\t\022\013\n\003UTC\030\003 \002(\004\022\016\n\006length\030\004 \002(\005\0228\n\013trackPoints\030\005 \003(\0132#.com.com.zhichenhaixin.proto.TrackPoint\"B\n\bSpectrum\022", "\021\n\tlongitude\030\001 \002(\001\022\020\n\blatitude\030\002 \002(\001\022\021\n\tamplitude\030\003 \002(\005\"U\n\fLineSpectrum\022\017\n\007azimuth\030\001 \002(\001\0224\n\tspectrums\030\002 \003(\0132!.com.com.zhichenhaixin.proto.Spectrum\"c\n\016SectorSpectrum\022\023\n\013sectorIndex\030\001 \002(\005\022<\n\rlineSpectrums\030\002 \003(\0132%.com.com.zhichenhaixin.proto.LineSpectrum\"‹\001\n\nRadarVideo\022\f\n\004flag\030\001 \002(\005\022\020\n\bsourceId\030\002 \002(\t\022\013\n\003UTC\030\003 \002(\004\022\016\n\006length\030\004 \002(\005\022@\n\017sectorSpectrums\030\005 \003(\0132'.com.com.zhichenhaixin.proto.SectorSpectrum*}\n\006MSGTYP\022\024\n\020M", "SGTYP_UNDEFINED\020\000\022\021\n\rTARGET_REPORT\020\001\022\031\n\025START_OF_UPDATE_CYCLE\020\002\022\023\n\017PERIODIC_STATUS\020\003\022\032\n\026EVENT_TRIGGERED_STATUS\020\004*B\n\003CNF\022\023\n\017CONFIRMED_TRACK\020\000\022\023\n\017TENTATIVE_TRACK\020\001\022\021\n\rUNKNOWN_TRACK\020\002*˜\001\n\003CST\022\021\n\rCST_UNDEFINED\020\000\022(\n$PREDICTABLE_EXTRAPOLATION_DUE_PERIOD\020\001\022%\n!PREDICTABLE_EXTRAPOLATION_IN_AREA\020\002\022-\n)EXTRAPOLATION_DUE_UNPREDICTABLE_DETECTION\020\003*3\n\003STH\022\025\n\021MEASURED_POSITION\020\000\022\025\n\021SMOOTHED_POSITION\020\001" }; + Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new Descriptors.FileDescriptor.InternalDescriptorAssigner() { + public ExtensionRegistry assignDescriptors(Descriptors.FileDescriptor root) { + ZCHXRadar.descriptor = root; + return null; + } + }; + Descriptors.FileDescriptor.internalBuildGeneratedFileFrom(descriptorData, new Descriptors.FileDescriptor[0], assigner); + } + + private static final Descriptors.Descriptor internal_static_com_zhichenhaixin_proto_RadarHistoryTrack_descriptor = getDescriptor().getMessageTypes().get(0); + + private static GeneratedMessage.FieldAccessorTable internal_static_com_zhichenhaixin_proto_RadarHistoryTrack_fieldAccessorTable = new GeneratedMessage.FieldAccessorTable(internal_static_com_zhichenhaixin_proto_RadarHistoryTrack_descriptor, new String[] { + "TrackNumber", "Wgs84PosLat", "Wgs84PosLong", "TimeOfDay", "TrackType", "TrackLastReport", "Extrapolation", "TrackPositionCode", "Cog", "Sog", + "UTC" }); + + private static final Descriptors.Descriptor internal_static_com_zhichenhaixin_proto_RadarHistoryTracks_descriptor = getDescriptor().getMessageTypes().get(1); + + private static GeneratedMessage.FieldAccessorTable internal_static_com_zhichenhaixin_proto_RadarHistoryTracks_fieldAccessorTable = new GeneratedMessage.FieldAccessorTable(internal_static_com_zhichenhaixin_proto_RadarHistoryTracks_descriptor, new String[] { "Tracks" }); + + private static final Descriptors.Descriptor internal_static_com_zhichenhaixin_proto_TrackPoint_descriptor = getDescriptor().getMessageTypes().get(2); + + private static GeneratedMessage.FieldAccessorTable internal_static_com_zhichenhaixin_proto_TrackPoint_fieldAccessorTable = new GeneratedMessage.FieldAccessorTable(internal_static_com_zhichenhaixin_proto_TrackPoint_descriptor, new String[] { + "SystemAreaCode", "SystemIdentificationCode", "MessageType", "TrackNumber", "CartesianPosX", "CartesianPosY", "Wgs84PosLat", "Wgs84PosLong", "TimeOfDay", "TrackType", + "TrackLastReport", "Extrapolation", "TrackPositionCode", "SigmaX", "SigmaY", "SigmaXY", "AmpOfPriPlot", "CartesianTrkVelVx", "CartesianTrkVelVy", "Cog", + "Sog", "Tracks", "Status", "IsSmuggle", "Distance", "WarnColor", "TargetType", "SignWindow", "IsWarn", "Rtsp", + "Fllow", "Mode", "TimeStamp", "Trackby", "CameraId" }); + + private static final Descriptors.Descriptor internal_static_com_zhichenhaixin_proto_FllowVo_descriptor = getDescriptor().getMessageTypes().get(3); + + private static GeneratedMessage.FieldAccessorTable internal_static_com_zhichenhaixin_proto_FllowVo_fieldAccessorTable = new GeneratedMessage.FieldAccessorTable(internal_static_com_zhichenhaixin_proto_FllowVo_descriptor, new String[] { "Flag", "Fllow", "TrackPoints", "Mode" }); + + private static final Descriptors.Descriptor internal_static_com_zhichenhaixin_proto_RadarSurfaceTrack_descriptor = getDescriptor().getMessageTypes().get(4); + + private static GeneratedMessage.FieldAccessorTable internal_static_com_zhichenhaixin_proto_RadarSurfaceTrack_fieldAccessorTable = new GeneratedMessage.FieldAccessorTable(internal_static_com_zhichenhaixin_proto_RadarSurfaceTrack_descriptor, new String[] { "Flag", "SourceId", "UTC", "Length", "TrackPoints" }); + + private static final Descriptors.Descriptor internal_static_com_zhichenhaixin_proto_Spectrum_descriptor = getDescriptor().getMessageTypes().get(5); + + private static GeneratedMessage.FieldAccessorTable internal_static_com_zhichenhaixin_proto_Spectrum_fieldAccessorTable = new GeneratedMessage.FieldAccessorTable(internal_static_com_zhichenhaixin_proto_Spectrum_descriptor, new String[] { "Longitude", "Latitude", "Amplitude" }); + + private static final Descriptors.Descriptor internal_static_com_zhichenhaixin_proto_LineSpectrum_descriptor = getDescriptor().getMessageTypes().get(6); + + private static GeneratedMessage.FieldAccessorTable internal_static_com_zhichenhaixin_proto_LineSpectrum_fieldAccessorTable = new GeneratedMessage.FieldAccessorTable(internal_static_com_zhichenhaixin_proto_LineSpectrum_descriptor, new String[] { "Azimuth", "Spectrums" }); + + private static final Descriptors.Descriptor internal_static_com_zhichenhaixin_proto_SectorSpectrum_descriptor = getDescriptor().getMessageTypes().get(7); + + private static GeneratedMessage.FieldAccessorTable internal_static_com_zhichenhaixin_proto_SectorSpectrum_fieldAccessorTable = new GeneratedMessage.FieldAccessorTable(internal_static_com_zhichenhaixin_proto_SectorSpectrum_descriptor, new String[] { "SectorIndex", "LineSpectrums" }); + + private static final Descriptors.Descriptor internal_static_com_zhichenhaixin_proto_RadarVideo_descriptor = getDescriptor().getMessageTypes().get(8); + + private static GeneratedMessage.FieldAccessorTable internal_static_com_zhichenhaixin_proto_RadarVideo_fieldAccessorTable = new GeneratedMessage.FieldAccessorTable(internal_static_com_zhichenhaixin_proto_RadarVideo_descriptor, new String[] { "Flag", "SourceId", "UTC", "Length", "SectorSpectrums" }); + + private static Descriptors.FileDescriptor descriptor; + + public static interface FllowVoOrBuilder extends MessageOrBuilder { + boolean hasFlag(); + + boolean getFlag(); + + boolean hasFllow(); + + boolean getFllow(); + + List getTrackPointsList(); + + TrackPoint getTrackPoints(int param1Int); + + int getTrackPointsCount(); + + List getTrackPointsOrBuilderList(); + + TrackPointOrBuilder getTrackPointsOrBuilder(int param1Int); + + boolean hasMode(); + + int getMode(); + } + + public static interface LineSpectrumOrBuilder extends MessageOrBuilder { + boolean hasAzimuth(); + + double getAzimuth(); + + List getSpectrumsList(); + + Spectrum getSpectrums(int param1Int); + + int getSpectrumsCount(); + + List getSpectrumsOrBuilderList(); + + SpectrumOrBuilder getSpectrumsOrBuilder(int param1Int); + } + + public static interface RadarHistoryTrackOrBuilder extends MessageOrBuilder { + boolean hasTrackNumber(); + + int getTrackNumber(); + + boolean hasWgs84PosLat(); + + double getWgs84PosLat(); + + boolean hasWgs84PosLong(); + + double getWgs84PosLong(); + + boolean hasTimeOfDay(); + + float getTimeOfDay(); + + boolean hasTrackType(); + + CNF getTrackType(); + + boolean hasTrackLastReport(); + + boolean getTrackLastReport(); + + boolean hasExtrapolation(); + + CST getExtrapolation(); + + boolean hasTrackPositionCode(); + + STH getTrackPositionCode(); + + boolean hasCog(); + + double getCog(); + + boolean hasSog(); + + double getSog(); + + boolean hasUTC(); + + long getUTC(); + } + + public static interface RadarHistoryTracksOrBuilder extends MessageOrBuilder { + List getTracksList(); + + RadarHistoryTrack getTracks(int param1Int); + + int getTracksCount(); + + List getTracksOrBuilderList(); + + RadarHistoryTrackOrBuilder getTracksOrBuilder(int param1Int); + } + + public static interface RadarSurfaceTrackOrBuilder extends MessageOrBuilder { + boolean hasFlag(); + + int getFlag(); + + boolean hasSourceId(); + + String getSourceId(); + + ByteString getSourceIdBytes(); + + boolean hasUTC(); + + long getUTC(); + + boolean hasLength(); + + int getLength(); + + List getTrackPointsList(); + + TrackPoint getTrackPoints(int param1Int); + + int getTrackPointsCount(); + + List getTrackPointsOrBuilderList(); + + TrackPointOrBuilder getTrackPointsOrBuilder(int param1Int); + } + + public static interface RadarVideoOrBuilder extends MessageOrBuilder { + boolean hasFlag(); + + int getFlag(); + + boolean hasSourceId(); + + String getSourceId(); + + ByteString getSourceIdBytes(); + + boolean hasUTC(); + + long getUTC(); + + boolean hasLength(); + + int getLength(); + + List getSectorSpectrumsList(); + + SectorSpectrum getSectorSpectrums(int param1Int); + + int getSectorSpectrumsCount(); + + List getSectorSpectrumsOrBuilderList(); + + SectorSpectrumOrBuilder getSectorSpectrumsOrBuilder(int param1Int); + } + + public static interface SectorSpectrumOrBuilder extends MessageOrBuilder { + boolean hasSectorIndex(); + + int getSectorIndex(); + + List getLineSpectrumsList(); + + LineSpectrum getLineSpectrums(int param1Int); + + int getLineSpectrumsCount(); + + List getLineSpectrumsOrBuilderList(); + + LineSpectrumOrBuilder getLineSpectrumsOrBuilder(int param1Int); + } + + public static interface SpectrumOrBuilder extends MessageOrBuilder { + boolean hasLongitude(); + + double getLongitude(); + + boolean hasLatitude(); + + double getLatitude(); + + boolean hasAmplitude(); + + int getAmplitude(); + } + + public static interface TrackPointOrBuilder extends MessageOrBuilder { + boolean hasSystemAreaCode(); + + int getSystemAreaCode(); + + boolean hasSystemIdentificationCode(); + + int getSystemIdentificationCode(); + + boolean hasMessageType(); + + MSGTYP getMessageType(); + + boolean hasTrackNumber(); + + int getTrackNumber(); + + boolean hasCartesianPosX(); + + float getCartesianPosX(); + + boolean hasCartesianPosY(); + + float getCartesianPosY(); + + boolean hasWgs84PosLat(); + + double getWgs84PosLat(); + + boolean hasWgs84PosLong(); + + double getWgs84PosLong(); + + boolean hasTimeOfDay(); + + float getTimeOfDay(); + + boolean hasTrackType(); + + CNF getTrackType(); + + boolean hasTrackLastReport(); + + boolean getTrackLastReport(); + + boolean hasExtrapolation(); + + CST getExtrapolation(); + + boolean hasTrackPositionCode(); + + STH getTrackPositionCode(); + + boolean hasSigmaX(); + + float getSigmaX(); + + boolean hasSigmaY(); + + float getSigmaY(); + + boolean hasSigmaXY(); + + float getSigmaXY(); + + boolean hasAmpOfPriPlot(); + + float getAmpOfPriPlot(); + + boolean hasCartesianTrkVelVx(); + + double getCartesianTrkVelVx(); + + boolean hasCartesianTrkVelVy(); + + double getCartesianTrkVelVy(); + + boolean hasCog(); + + double getCog(); + + boolean hasSog(); + + double getSog(); + + boolean hasTracks(); + + RadarHistoryTracks getTracks(); + + RadarHistoryTracksOrBuilder getTracksOrBuilder(); + + boolean hasStatus(); + + int getStatus(); + + boolean hasIsSmuggle(); + + int getIsSmuggle(); + + boolean hasDistance(); + + double getDistance(); + + boolean hasWarnColor(); + + String getWarnColor(); + + ByteString getWarnColorBytes(); + + boolean hasTargetType(); + + int getTargetType(); + + boolean hasSignWindow(); + + int getSignWindow(); + + boolean hasIsWarn(); + + int getIsWarn(); + + boolean hasRtsp(); + + String getRtsp(); + + ByteString getRtspBytes(); + + boolean hasFllow(); + + int getFllow(); + + boolean hasMode(); + + int getMode(); + + boolean hasTimeStamp(); + + long getTimeStamp(); + + boolean hasTrackby(); + + String getTrackby(); + + ByteString getTrackbyBytes(); + + boolean hasCameraId(); + + int getCameraId(); + } +} diff --git a/src/main/java/com/zgx/iot/redis/client/JeecgRedisClient.java b/src/main/java/com/zgx/iot/redis/client/JeecgRedisClient.java new file mode 100644 index 0000000..2a1c465 --- /dev/null +++ b/src/main/java/com/zgx/iot/redis/client/JeecgRedisClient.java @@ -0,0 +1,33 @@ +package com.zgx.iot.redis.client; + + +import com.zgx.iot.base.BaseMap; +import com.zgx.iot.constant.GlobalConstants; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.core.RedisTemplate; + +import javax.annotation.Resource; + +/** + * redis客户端 + */ +@Configuration +public class JeecgRedisClient { + + @Resource + private RedisTemplate redisTemplate; + + + /** + * 发送消息 + * + * @param handlerName + * @param params + */ + public void sendMessage(String handlerName, BaseMap params) { + params.put(GlobalConstants.HANDLER_NAME, handlerName); + redisTemplate.convertAndSend(GlobalConstants.REDIS_TOPIC_NAME, params); + } + + +} diff --git a/src/main/java/com/zgx/iot/redis/config/RedisConfig.java b/src/main/java/com/zgx/iot/redis/config/RedisConfig.java new file mode 100644 index 0000000..0136473 --- /dev/null +++ b/src/main/java/com/zgx/iot/redis/config/RedisConfig.java @@ -0,0 +1,100 @@ +package com.zgx.iot.redis.config; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.cache.CacheManager; +import org.springframework.cache.annotation.CachingConfigurerSupport; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.cache.RedisCacheConfiguration; +import org.springframework.data.redis.cache.RedisCacheManager; +import org.springframework.data.redis.cache.RedisCacheWriter; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.listener.ChannelTopic; +import org.springframework.data.redis.listener.RedisMessageListenerContainer; +import org.springframework.data.redis.listener.adapter.MessageListenerAdapter; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.RedisSerializationContext; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +import javax.annotation.Resource; +import java.time.Duration; + +import static java.util.Collections.singletonMap; + +/** +* 开启缓存支持 +* @author zyf + * @Return: +*/ +@Slf4j +@EnableCaching +@Configuration +public class RedisConfig extends CachingConfigurerSupport { + + @Resource + private LettuceConnectionFactory lettuceConnectionFactory; + +// /** +// * @description 自定义的缓存key的生成策略 若想使用这个key +// * 只需要讲注解上keyGenerator的值设置为keyGenerator即可
+// * @return 自定义策略生成的key +// */ +// @Override +// @Bean +// public KeyGenerator keyGenerator() { +// return new KeyGenerator() { +// @Override +// public Object generate(Object target, Method method, Object... params) { +// StringBuilder sb = new StringBuilder(); +// sb.append(target.getClass().getName()); +// sb.append(method.getDeclaringClass().getName()); +// Arrays.stream(params).map(Object::toString).forEach(sb::append); +// return sb.toString(); +// } +// }; +// } + + /** + * RedisTemplate配置 + * @param lettuceConnectionFactory + * @return + */ + @Bean + public RedisTemplate redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) { + log.info(" --- redis config init --- "); + Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = jacksonSerializer(); + RedisTemplate redisTemplate = new RedisTemplate(); + redisTemplate.setConnectionFactory(lettuceConnectionFactory); + RedisSerializer stringSerializer = new StringRedisSerializer(); + + // key序列化 + redisTemplate.setKeySerializer(stringSerializer); + // value序列化 + redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); + // Hash key序列化 + redisTemplate.setHashKeySerializer(stringSerializer); + // Hash value序列化 + redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); + redisTemplate.afterPropertiesSet(); + return redisTemplate; + } + + private Jackson2JsonRedisSerializer jacksonSerializer() { + Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); + jackson2JsonRedisSerializer.setObjectMapper(objectMapper); + return jackson2JsonRedisSerializer; + } + + +} diff --git a/src/main/java/com/zgx/iot/service/IDtDeviceInfoService.java b/src/main/java/com/zgx/iot/service/IDtDeviceInfoService.java new file mode 100644 index 0000000..a51a3d5 --- /dev/null +++ b/src/main/java/com/zgx/iot/service/IDtDeviceInfoService.java @@ -0,0 +1,15 @@ +package com.zgx.iot.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.zgx.iot.entity.DtDeviceInfo; + + +/** + * @Description: 设备信息表 + * @Author: jeecg-boot + * @Date: 2022-08-12 + * @Version: V1.0 + */ +public interface IDtDeviceInfoService extends IService { + +} diff --git a/src/main/java/com/zgx/iot/service/IMsAlarmSettingsService.java b/src/main/java/com/zgx/iot/service/IMsAlarmSettingsService.java new file mode 100644 index 0000000..73fc08f --- /dev/null +++ b/src/main/java/com/zgx/iot/service/IMsAlarmSettingsService.java @@ -0,0 +1,16 @@ +package com.zgx.iot.service; + + +import com.baomidou.mybatisplus.extension.service.IService; +import com.zgx.iot.entity.MsAlarmSettings; + +/** + * @Description: 报警参数配置表 + * @Author: jeecg-boot + * @Date: 2022-09-02 + * @Version: V1.0 + */ +public interface IMsAlarmSettingsService extends IService { + + +} diff --git a/src/main/java/com/zgx/iot/service/IMsCameraSettingService.java b/src/main/java/com/zgx/iot/service/IMsCameraSettingService.java new file mode 100644 index 0000000..1f84a00 --- /dev/null +++ b/src/main/java/com/zgx/iot/service/IMsCameraSettingService.java @@ -0,0 +1,156 @@ +package com.zgx.iot.service; + + +import com.baomidou.mybatisplus.extension.service.IService; +import com.zgx.iot.entity.MsCameraSetting; +import com.zgx.iot.dto.site.Result; +import com.zgx.iot.vo.PTZVo; + +import java.util.List; + +/** + * @Description: 相机设置 + * @Author: jeecg-boot + * @Date: 2021-07-01 + * @Version: V1.0 + */ +public interface IMsCameraSettingService extends IService { + + public List selectByMainId(String mainId); + + public List getSettingForTree(); + + //public List getSettingVoList(); + + //public void updateLatAndLonBySiteId(MsCameraSite msCameraSite); + + void deleteByMainId(String siteId); + + /** + * 控制相机镜头偏转至指定目标点 + * + * @param cameraIP 相机IP + * @param cameraUser 认证用户名 + * @param cameraPassword 认证密码 + * @param yOffsetAngle 最大仰角 + * @param zOffsetAngle 水平初始角 + * @param yHeight 相机相对目标点高度 + * @param lon1 相机经度 + * @param lat1 相机纬度 + * @param lon2 目标点经度 + * @param lat2 目标点纬度 + */ + void doCameraLensToTarget(String cameraIP, + String cameraUser, + String cameraPassword, + double yOffsetAngle, + double zOffsetAngle, + double yHeight, + double factor, + double lon1, + double lat1, + double lon2, + double lat2); + + /** + * 控制相机镜头偏转至某个PTZ + * + * @param ptzVo + */ + void moveCameraByPTZ(String cameraIP, String cameraUser, String cameraPassword, PTZVo ptzVo); + + /** + * 获取相机当前位置状态 + */ + void getStatus(); + + /** + * 云台控制 + * + * @param cameraIP 相机IP + * @param cameraUser 认证用户名 + * @param cameraPassword 认证密码 + * @param instruct 方向指令 + * @param speed 转动速度 + */ + Result ptzControl(String cameraIP, String cameraUser, String cameraPassword, String instruct, float speed); + + //todo : 重载一个自定义ptz的方法 + Result ptzControl(String cameraIP, String cameraUser, String cameraPassword, PTZVo ptzVo); + + + /** + * 相机聚焦 + * + * @param cameraIP 相机IP + * @param cameraUser 认证用户名 + * @param cameraPassword 认证密码 + * @param instruct 方向指令 + * @param speed 转动速度 + */ + Result moveFocus(String cameraIP, String cameraUser, String cameraPassword, String instruct, float speed); + + /** + * 抓拍实时照片 + * + * @param cameraIP 相机IP + * @param cameraUser 认证用户名 + * @param cameraPassword 认证密码 + */ +/* void screenSnap(String cameraId, String cameraName, String cameraIP, String cameraUser, String cameraPassword, + String snapshotUrl, String operator);*/ + + /** + * 添加一对多 + * @param msCameraSetting msCameraSetting + * @param msCameraScreenshotsList msCameraScreenshotsList + */ + // public void saveMain(MsCameraSetting msCameraSetting,List msCameraScreenshotsList) ; + + /** + * 修改一对多 + * @param msCameraSetting msCameraSetting + * @param msCameraScreenshotsList msCameraScreenshotsList + */ + // public void updateMain(MsCameraSetting msCameraSetting,List msCameraScreenshotsList); + + /** + * 删除一对多 + * @param id id + */ + // public void delMain (String id); + + /** + * 批量删除一对多 + * @param idList idList + */ + // public void delBatchMain (Collection idList); + + //todo : 新增代码 + public void ptzControllerByLatLon(String cameraIP, + String cameraUser, + String cameraPassword, + double yOffsetAngle, + double zOffsetAngle, + double yHeight, + double factor, + double lon1, + double lat1, + double lon2, + double lat2, + int style); + + + public void test(String cameraIP, + String cameraUser, + String cameraPassword, + double yOffsetAngle,//最大俯仰角 + double zOffsetAngle,//初始水平角度 + double yHeight,//球机高度 + double factor,//聚焦因子 + double lon1,//相机经度 + double lat1,//相机纬度 + double lon2,//目标经度 + double lat2,//目标纬度 + int factory); +} diff --git a/src/main/java/com/zgx/iot/service/IMsModelPositionService.java b/src/main/java/com/zgx/iot/service/IMsModelPositionService.java new file mode 100644 index 0000000..0cef37b --- /dev/null +++ b/src/main/java/com/zgx/iot/service/IMsModelPositionService.java @@ -0,0 +1,53 @@ +package com.zgx.iot.service; + + + +import com.baomidou.mybatisplus.extension.service.IService; +import com.zgx.iot.entity.MsModelPosition; +import com.zgx.iot.entity.MsModelTrajectory; + +import java.io.Serializable; +import java.util.Collection; +import java.util.List; + +/** + * @Description: 模型位置信息 + * @Author: jeecg-boot + * @Date: 2021-07-09 + * @Version: V1.0 + */ +public interface IMsModelPositionService extends IService { + + /** + * 添加一对多 + * + */ + public void saveMain(MsModelPosition msModelPosition,List msModelTrajectoryList) ; + + /** + * 修改一对多 + * + */ + public void updateMain(MsModelPosition msModelPosition,List msModelTrajectoryList); + + /** + * 删除一对多 + */ + public void delMain (String id); + + /** + * 通过 delByEventSerialNum 删除 + */ + public void delByEventSerialNumMain (String eventSerialNum); + + /** + * 批量删除一对多 + */ + public void delBatchMain (Collection idList); + + /** + * 添加模型位置及历史轨迹数据 + * + */ + public int addModelInfo(MsModelPosition msModelPosition) ; +} diff --git a/src/main/java/com/zgx/iot/service/impl/DtDeviceInfoServiceImpl.java b/src/main/java/com/zgx/iot/service/impl/DtDeviceInfoServiceImpl.java new file mode 100644 index 0000000..5434551 --- /dev/null +++ b/src/main/java/com/zgx/iot/service/impl/DtDeviceInfoServiceImpl.java @@ -0,0 +1,18 @@ +package com.zgx.iot.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.zgx.iot.entity.DtDeviceInfo; +import com.zgx.iot.mapper.DtDeviceInfoMapper; +import com.zgx.iot.service.IDtDeviceInfoService; +import org.springframework.stereotype.Service; + +/** + * @Description: 设备信息表 + * @Author: jeecg-boot + * @Date: 2022-08-12 + * @Version: V1.0 + */ +@Service +public class DtDeviceInfoServiceImpl extends ServiceImpl implements IDtDeviceInfoService { + +} diff --git a/src/main/java/com/zgx/iot/service/impl/MsAlarmSettingsServiceImpl.java b/src/main/java/com/zgx/iot/service/impl/MsAlarmSettingsServiceImpl.java new file mode 100644 index 0000000..a66900c --- /dev/null +++ b/src/main/java/com/zgx/iot/service/impl/MsAlarmSettingsServiceImpl.java @@ -0,0 +1,20 @@ +package com.zgx.iot.service.impl; + + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.zgx.iot.entity.MsAlarmSettings; +import com.zgx.iot.mapper.MsAlarmSettingsMapper; +import com.zgx.iot.service.IMsAlarmSettingsService; +import org.springframework.stereotype.Service; + +/** + * @Description: 报警参数配置表 + * @Author: jeecg-boot + * @Date: 2022-09-02 + * @Version: V1.0 + */ +@Service +public class MsAlarmSettingsServiceImpl extends ServiceImpl implements IMsAlarmSettingsService { + + +} diff --git a/src/main/java/com/zgx/iot/service/impl/MsCameraSettingServiceImpl.java b/src/main/java/com/zgx/iot/service/impl/MsCameraSettingServiceImpl.java new file mode 100644 index 0000000..f0f783c --- /dev/null +++ b/src/main/java/com/zgx/iot/service/impl/MsCameraSettingServiceImpl.java @@ -0,0 +1,792 @@ +package com.zgx.iot.service.impl; + +import be.teletask.onvif.OnvifManager; +import be.teletask.onvif.listeners.OnvifMediaProfilesListener; +import be.teletask.onvif.listeners.OnvifResponseListener; +import be.teletask.onvif.models.OnvifDevice; +import be.teletask.onvif.models.OnvifMediaProfile; +import be.teletask.onvif.responses.OnvifResponse; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.zgx.iot.constant.enums.DeviceComp; +import com.zgx.iot.entity.MsCameraSetting; +import com.zgx.iot.dto.site.Result; +import com.zgx.iot.mapper.MsCameraSettingMapper; +import com.zgx.iot.service.IMsCameraSettingService; +import com.zgx.iot.utils.GEOUtils; +import com.zgx.iot.vo.PTZVo; +import de.onvif.soap.devices.MediaDevices; +import de.onvif.soap.devices.PtzDevices; +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; +import org.onvif.ver10.schema.ContinuousFocus; +import org.onvif.ver10.schema.FocusMove; +import org.onvif.ver10.schema.PTZPreset; +import org.onvif.ver10.schema.PTZStatus; +import org.onvif.ver20.imaging.wsdl.Move; +import org.onvif.ver20.imaging.wsdl.MoveResponse; +import org.onvif.ver20.imaging.wsdl.Stop; +import org.onvif.ver20.imaging.wsdl.StopResponse; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import javax.xml.soap.SOAPException; +import java.net.ConnectException; +import java.util.List; + + +/** + * @Description: 相机设置 + * @Author: jeecg-boot + * @Date: 2021-07-01 + * @Version: V1.0 + */ +@Service +@Slf4j +public class MsCameraSettingServiceImpl extends ServiceImpl implements IMsCameraSettingService, OnvifResponseListener { + + @Resource + private MsCameraSettingMapper msCameraSettingMapper; + +/* private final MsCameraScreenshotsMapper msCameraScreenshotsMapper;*/ + + private OnvifDevice device; + private OnvifManager onvifManager; + private de.onvif.soap.OnvifDevice onvifDevice; + @Value(value = "${jeecg.path.upload}") + private String uploadPath; + +/* public MsCameraSettingServiceImpl(MsCameraScreenshotsMapper msCameraScreenshotsMapper) { + this.msCameraScreenshotsMapper = msCameraScreenshotsMapper; + }*/ + + @Override + public List selectByMainId(String mainId) { + return msCameraSettingMapper.selectByMainId(mainId); + } + + @Override + public List getSettingForTree() { + return msCameraSettingMapper.selectAllSetting(); + } + +/* @Override + public List getSettingVoList() { + return msCameraSettingMapper.selectSettingVoList(); + } + + @Override + public void updateLatAndLonBySiteId(MsCameraSite msCameraSite) { + msCameraSettingMapper.updateLatAndLonBySiteId(msCameraSite); + }*/ + + @Override + public void deleteByMainId(String siteId) { + msCameraSettingMapper.deleteByMainId(siteId); + } + + @Override + public void doCameraLensToTarget(String cameraIP, + String cameraUser, + String cameraPassword, + double yOffsetAngle, + double zOffsetAngle, + double yHeight, + double factor, + double lon1, + double lat1, + double lon2, + double lat2) { + // 登录设备 + onvifManager = new OnvifManager(); + onvifManager.setOnvifResponseListener(this); + device = new OnvifDevice(cameraIP, cameraUser, cameraPassword); + onvifManager.getMediaProfiles(device, new OnvifMediaProfilesListener() { + @Override + public void onMediaProfilesReceived(@NonNull OnvifDevice device, + @NonNull List mediaProfiles) { + double zAngle = GEOUtils.position(lon1, lat1, lon2, lat2); + double zDis = GEOUtils.GetDistance(lon1, lat1, lon2, lat2); + double yAngle = GEOUtils.upAngle(yHeight, zDis); + double focusDis = Math.sqrt(yHeight * yHeight + zDis * zDis); + System.out.println(zAngle); + System.out.println(yAngle); + System.out.println(focusDis); + log.info("【doCameraLensToTarget onMediaProfilesReceived】"); + log.info("zAngle:"+zAngle); + log.info("zDis:"+zDis); + log.info("yAngle:"+yAngle); + log.info("focusDis:"+focusDis); + moveToPointer(device, mediaProfiles.get(0), focusDis, yOffsetAngle, zOffsetAngle, yAngle, zAngle, factor); + } + }); + } + + //todo : 新增球机联动代码 + @Override + public void ptzControllerByLatLon(String cameraIP, + String cameraUser, + String cameraPassword, + double yOffsetAngle,//最大俯仰角 + double zOffsetAngle,//初始水平角度 + double yHeight,//球机高度 + double factor,//聚焦因子 + double lon1,//相机经度 + double lat1,//相机纬度 + double lon2,//目标经度 + double lat2,//目标纬度 + int factory){ //相机产商类型 + try { + // 登录设备 + onvifDevice = new de.onvif.soap.OnvifDevice(cameraIP, cameraUser, cameraPassword); + PtzDevices ptzDevices = onvifDevice.getPtz(); + String token = onvifDevice.getDevices().getProfiles().get(0).getToken(); + + //初步计算 + double zAngle = GEOUtils.position(lon1, lat1, lon2, lat2);//计算球机需要转动的水平角度 + double zDis = GEOUtils.GetDistance(lon1, lat1, lon2, lat2); + double yAngle = GEOUtils.upAngle(yHeight, zDis);//计算球机需要转动的垂直角度 + double focusDis = Math.sqrt(yHeight * yHeight + zDis * zDis);//计算球机距离目标的距离 + + log.info("【ptzControllerByLatLon 初步计算的值(未调整)】"); + log.info("zAngle:"+zAngle); + log.info("zDis:"+zDis); + log.info("yAngle:"+yAngle); + log.info("focusDis:"+focusDis); + + //计算PTZ值(根据数据库设置的初始值进行进一步计算) -1 mediaProfiles) { + onvifManager.absoluteMove(device, mediaProfiles.get(0), ptzVo.getPanValue(), ptzVo.getTileValue(), ptzVo.getZoomValue()); + } + }); + } + + /** + * test + */ + @Override + public void getStatus() { + /*onvifManager = new OnvifManager(); + onvifManager.setOnvifResponseListener(this); + device = new OnvifDevice("192.168.1.65", "admin", "hk123456"); + onvifManager.getMediaProfiles(device, new OnvifMediaProfilesListener() { + @Override + public void onMediaProfilesReceived(@NonNull OnvifDevice device, + @NonNull List mediaProfiles) { + getStatus(device, mediaProfiles.get(0)); + } + });*/ + try { + // 登录设备 + //onvifDevice = new de.onvif.soap.OnvifDevice("192.168.1.65", "admin", "hk123456"); + onvifDevice = new de.onvif.soap.OnvifDevice("192.168.20.65", "admin", "hk123456"); + PtzDevices ptzDevices = onvifDevice.getPtz(); + String token = onvifDevice.getDevices().getProfiles().get(0).getToken(); + // 获取预置点 + List ptzPresets = ptzDevices.getPresets(token); + System.out.println("ptzPresets=" + ptzPresets.toString()); + // 判断当前是否静止 + PTZStatus ptzStatus = ptzDevices.getStatus(token); + System.out.println("getPanTilt=" + ptzStatus.getMoveStatus().getPanTilt()); + System.out.println("getZoom=" + ptzStatus.getMoveStatus().getZoom()); + + log.info("ptzPresets=" + ptzPresets.toString()); + log.info("getPanTilt=" + ptzStatus.getMoveStatus().getPanTilt()); + log.info("getZoom=" + ptzStatus.getMoveStatus().getZoom()); + + } catch (ConnectException | SOAPException e) { + e.printStackTrace(); + } + } + + @Override + public Result ptzControl(String cameraIP, String cameraUser, String cameraPassword, PTZVo ptzVo) { + Result result = new Result<>(); + try { + // 登录设备 + onvifDevice = new de.onvif.soap.OnvifDevice(cameraIP, cameraUser, cameraPassword); + PtzDevices ptzDevices = onvifDevice.getPtz(); + String token = onvifDevice.getDevices().getProfiles().get(0).getToken(); + ptzDevices.continuousMove(token, (float) ptzVo.getPanValue(), (float) ptzVo.getTileValue(), (float) ptzVo.getZoomValue()); + } catch (ConnectException | SOAPException e) { + e.printStackTrace(); + result.setSuccess(false); + } + return result; + } + @Override + public Result ptzControl(String cameraIP, String cameraUser, String cameraPassword, String instruct, float speed) { + Result result = new Result<>(); + PTZVo ptzVo = null; + try { + // 登录设备 + onvifDevice = new de.onvif.soap.OnvifDevice(cameraIP, cameraUser, cameraPassword); + PtzDevices ptzDevices = onvifDevice.getPtz(); + String token = onvifDevice.getDevices().getProfiles().get(0).getToken(); + switch (instruct) { + case "up": + //上 + ptzVo = new PTZVo(0, 1, 0); + break; + case "upLeft": + //左上 + ptzVo = new PTZVo(-1, 1, 0); + break; + case "upRight": + //右上 + ptzVo = new PTZVo(1, 1, 0); + break; + case "left": + //左 + ptzVo = new PTZVo(-1, 0, 0); + break; + case "right": + //右 + ptzVo = new PTZVo(1, 0, 0); + break; + case "down": + //下 + ptzVo = new PTZVo(0, -1, 0); + break; + case "downLeft": + //左下 + ptzVo = new PTZVo(-1, -1, 0); + break; + case "downRight": + //右下 + ptzVo = new PTZVo(1, -1, 0); + break; + case "zoomIn": + //放大 + ptzVo = new PTZVo(0, 0, 1); + break; + case "zoomOut": + //缩小 + ptzVo = new PTZVo(0, 0, -1); + break; + case "stop": + //停止 + ptzDevices.stopMove(token); + return result; + default: + result.setCode(501); + result.setMessage("指令有误"); + return result; + } + float x = (float) ptzVo.getPanValue() * speed; + float y = (float) ptzVo.getTileValue() * speed; + float z = (float) ptzVo.getZoomValue() * speed; + log.info("token:"+token); + log.info("x:"+x+" "+"y:"+y+" "+"z:"+z); + ptzDevices.continuousMove(token, x, y, z); + + } catch (ConnectException | SOAPException e) { + e.printStackTrace(); + result.setSuccess(false); + } + return result; + } + + @Override + public Result moveFocus(String cameraIP, String cameraUser, String cameraPassword, String instruct, float speed) { + Result result = new Result<>(); + try { + // 登录设备 + onvifDevice = new de.onvif.soap.OnvifDevice(cameraIP, cameraUser, cameraPassword); + onvifDevice.getDevices().getProfiles().get(0).getToken(); + MediaDevices mediaDevices = onvifDevice.getMedia(); + String videoSourceToken = mediaDevices.getVideoSources().get(0).getToken(); + + if (videoSourceToken == null) { + result.setSuccess(false); + return result; + } + switch (instruct) { + case "focusIn": + //聚焦+ + speed = speed * 1; + break; + case "focusOut": + //聚焦- + speed = speed * -1; + break; + case "stop": + //停止 + Stop request = new Stop(); + request.setVideoSourceToken(videoSourceToken); + StopResponse response = new StopResponse(); + response = (StopResponse) onvifDevice.getSoap().createSOAPPtzRequest(request, response, true); + if (response == null) { + result.setCode(501); + result.setMessage("相机响应失败"); + } + return result; + default: + result.setCode(501); + result.setMessage("指令有误"); + return result; + } + //聚焦 + Move request = new Move(); + MoveResponse response = new MoveResponse(); + ContinuousFocus continuousFocus = new ContinuousFocus(); + continuousFocus.setSpeed(speed); + FocusMove focusMove = new FocusMove(); + focusMove.setContinuous(continuousFocus); + request.setVideoSourceToken(videoSourceToken); + request.setFocus(focusMove); + response = (MoveResponse) onvifDevice.getSoap().createSOAPImagingRequest(request, response, true); + if (response == null) { + result.setCode(501); + result.setMessage("相机响应失败"); + } + + } catch (ConnectException | SOAPException e) { + e.printStackTrace(); + result.setSuccess(false); + } + return result; + } + +/* *//** + * 相机截图并保存 + * + * @param cameraIP 相机IP + * @param cameraUser 认证用户名 + * @param cameraPassword 认证密码 + *//* + @Override + public void screenSnap(String cameraId, String cameraName, + String cameraIP, String cameraUser, String cameraPassword, + String snapshotUrl, String operator) { + //图片名称 + String time = DateUtil.format(new Date(), "yyyyMMddHHmmss"); + int randomSeed = new Random().nextInt(90) + 10; + String filename = StrUtil.format("p_{}{}", time, randomSeed); + //验证账号密码 + String authInfo = StrUtil.format("{}:{}", cameraUser, cameraPassword); + //通过http下载图片并保存至本地 + CommonUtils.downloadHTTP(snapshotUrl, filename, authInfo, uploadPath); + + // 插入数据库 + MsCameraScreenshots msCameraScreenshots = new MsCameraScreenshots(); + msCameraScreenshots.setCameraId(cameraId); + msCameraScreenshots.setCameraName(cameraName); + msCameraScreenshots.setCreateBy(operator); + msCameraScreenshots.setImgUrl("screen" + File.separator + filename + ".jpg"); + msCameraScreenshotsMapper.insert(msCameraScreenshots); + }*/ + +/* @Override + @Transactional(rollbackFor = Exception.class) + public void saveMain(MsCameraSetting msCameraSetting, List msCameraScreenshotsList) { + msCameraSettingMapper.insert(msCameraSetting); + + if (msCameraScreenshotsList != null && !msCameraScreenshotsList.isEmpty()) { + for (MsCameraScreenshots entity : msCameraScreenshotsList) { + // 外键设置 + entity.setCameraId(msCameraSetting.getId()); + msCameraScreenshotsMapper.insert(entity); + } + } + }*/ + +/* @Override + @Transactional(rollbackFor = Exception.class) + public void updateMain(MsCameraSetting msCameraSetting, List msCameraScreenshotsList) { + msCameraSettingMapper.updateById(msCameraSetting); + + // 删除子表数据 + msCameraScreenshotsMapper.deleteByMainId(msCameraSetting.getId()); + // 字表数据重新插入 + if (msCameraScreenshotsList != null && !msCameraScreenshotsList.isEmpty()) { + for (MsCameraScreenshots entity : msCameraScreenshotsList) { + // 外键设置 + entity.setCameraId(msCameraSetting.getId()); + msCameraScreenshotsMapper.insert(entity); + } + } + }*/ + +/* @Override + @Transactional(rollbackFor = Exception.class) + public void delMain(String id) { + msCameraScreenshotsMapper.selectByMainId(id); + msCameraSettingMapper.deleteById(id); + } + + @Override + public void delBatchMain(Collection idList) { + for (Serializable id : idList) { + msCameraScreenshotsMapper.deleteByMainId(id.toString()); + msCameraSettingMapper.deleteById(id); + } + }*/ + + /** + * 相机镜头绝对定位偏转 + * + * @param device + * @param profile + * @param distance 相机与目标距离 + * @param yOffsetAngle 最大仰角 + * @param zOffsetAngle 水平初始角 + * @param yAngle 相机与视野垂直夹角(垂直移动角度) + * @param zAngle 相机与视野水平夹角(水平移动角度) + * @param factor 变倍因子 + */ + private void moveToPointer(OnvifDevice device, + OnvifMediaProfile profile, + double distance, + double yOffsetAngle, + double zOffsetAngle, + double yAngle, + double zAngle, + double factor) { + PTZVo ptzVo = ptzCal(yOffsetAngle, zOffsetAngle, distance, yAngle, zAngle, factor); + System.out.println(ptzVo.toString()); + log.info("ptzVo:"+ptzVo); + onvifManager.absoluteMove(device, profile, ptzVo.getPanValue(), ptzVo.getTileValue(), ptzVo.getZoomValue()); + } + + /** + * 计算ptz的值 + * + * @param yOffsetAngle 最大仰角 + * @param zOffsetAngle 水平初始角 + * @param distance 相机与目标距离 + * @param yAngle 相机与视野垂直夹角(垂直移动角度) + * @param zAngle 相机与视野水平夹角(水平移动角度) + * @param factor 变倍因子 + * @return + */ + private PTZVo ptzCal(double yOffsetAngle,//最大仰角 + double zOffsetAngle, + double distance, + double yAngle,//球机需要转动的垂直角度 + double zAngle, + double factor) { + PTZVo ptzVo = new PTZVo(); + double zReal = (zAngle + 360 - zOffsetAngle) % 360; + double panValue = 0f; + double tiltValue = 0f; + double commonAngle = 180.00f; + double commonAngle1 = (yOffsetAngle + 90.00f) / 2.00f; //55 或者 90 + if (zReal < 180) { + if (zReal <= 0) { + panValue = 0f; + } else { + panValue = zReal / commonAngle; + } + } else { + panValue = (zReal - commonAngle) / commonAngle - 1; + } + if (yAngle > commonAngle1) { + if (yAngle > commonAngle1 * 2) { + tiltValue = 1; + } else { + tiltValue = (yAngle - commonAngle1) / commonAngle1; + } + } else { + tiltValue = (yAngle - commonAngle1) / commonAngle1; + } + ptzVo.setPanValue(panValue); + ptzVo.setTileValue(tiltValue); + double zoomValue = factor * distance; + if (zoomValue > 1) { + zoomValue = 1; + } + if (zoomValue < factor) { + zoomValue = factor; + } + ptzVo.setZoomValue(zoomValue); + return ptzVo; + } + + + + /** + * 基于某个零方位角查询相机当前的PTZ值 + */ + private void getStatus(OnvifDevice device, + OnvifMediaProfile mediaProfile) { + PTZVo ptzVo = new PTZVo(); + onvifManager.getStatus(device, mediaProfile, (onvifDevice, profile, status) -> { + ptzVo.setPanValue(status.getPan()); + ptzVo.setTileValue(status.getTilt()); + ptzVo.setZoomValue(status.getZoom()); + System.out.println("当前PTZ:" + ptzVo.toString()); + }); + } + + @Override + public void onResponse(OnvifDevice onvifDevice, OnvifResponse onvifResponse) { + + } + + @Override + public void onError(OnvifDevice onvifDevice, int i, String s) { + + } + + + /** + * 计算宇视ptz的值 + * @param yOffsetAngle 最大仰角 + * @param zOffsetAngle 水平初始角 + * @param distance 相机与目标距离 + * @param yAngle 相机与视野垂直夹角(垂直移动角度) + * @param zAngle 相机与视野水平夹角(水平移动角度) + * @param factor 变倍因子 + * @return + */ + public PTZVo YSPTZCal(double yOffsetAngle,//最大仰角 + double zOffsetAngle,//水平初始角 + double distance, + double yAngle,//球机需要转动的垂直角度 + double zAngle,//球机需要转动的水平角度 + double factor) { + PTZVo ptzVo = new PTZVo(); + double zReal = (zAngle + 360 - zOffsetAngle) % 360; + double panValue = 0f; + double tiltValue = 0f; + double commonAngle = 180.00f; + double commonAngle1 = (yOffsetAngle + 90.00f) / 2.00f; + + //P算法 + if (zReal < 180) { + if (zReal <= 0) { + panValue = 0f; + } else { + panValue = zReal / commonAngle; + } + } else { + panValue = (zReal - commonAngle) / commonAngle - 1; + } + + + if (yAngle > commonAngle1) { + if (yAngle > commonAngle1 * 2) { // yAngle < 90 yOffsetAngle < + tiltValue = 1; + } else { + tiltValue = ((yAngle - commonAngle1) / commonAngle1) * (-1); + } + } else { + tiltValue = (yAngle - commonAngle1) / commonAngle1; + } + + //T算法 + //tiltValue=((90-yAngle)-30)/commonAngle1; + + //Z算法 + double zoomValue = factor * distance * 0.01; + if (zoomValue > 1) { + zoomValue = 1; + } + if (zoomValue < factor) { + zoomValue = factor; + } + + ptzVo.setPanValue(panValue); + ptzVo.setTileValue(tiltValue); + ptzVo.setZoomValue(zoomValue); + + return ptzVo; + } + + + + /** + * 计算海康球机的ptz的值 + * @param yOffsetAngle 最大仰角 + * @param zOffsetAngle 水平初始角 + * @param distance 相机与目标距离 + * @param yAngle 相机与视野垂直夹角(垂直移动角度) + * @param zAngle 相机与视野水平夹角(水平移动角度) + * @param factor 变倍因子 + * @return + */ + public PTZVo HKPTZCal(double yOffsetAngle,//最大仰角 + double zOffsetAngle,//水平初始角 + double distance, + double yAngle,//球机需要转动的垂直角度 + double zAngle,//根据球机经纬度和目标经纬度计算得出水平角 + double factor) { + PTZVo ptzVo = new PTZVo(); + double zReal = (zAngle + 360 - zOffsetAngle) % 360; + double panValue = 0f; + double tiltValue= 0f; + double commonAngle = 180.00f; + double commonAngle1 = 45.00f; + + //P算法 + if (zReal < 180) { + if (zReal <= 0) { + panValue = 0f; + } else { + panValue = zReal / commonAngle;//p的取值范围在0-1之间 + } + } else { + panValue = (zReal - commonAngle) / commonAngle - 1; + } + + //T算法 (yAngle-45)/45 * (-1) + tiltValue=(-1)*(yAngle-commonAngle1)/commonAngle1; //yAngle的取值范围是0-90 一般是 86~89度左右 + + //Z算法 + double zoomValue = factor * distance * 0.01; //可以通过数据库factor去控制聚焦 + + if (zoomValue > 1) { + zoomValue = 1; + } + if (zoomValue < factor) { + zoomValue = factor; + } + + ptzVo.setPanValue(panValue); + ptzVo.setTileValue(tiltValue); + ptzVo.setZoomValue(zoomValue); + return ptzVo; + } + + public PTZVo YSPTZCal2(double yOffsetAngle,//最大仰角 + double zOffsetAngle,//水平初始角 + double distance, + double yAngle,//球机需要转动的垂直角度 + double zAngle,//球机需要转动的水平角度 + double factor) { + PTZVo ptzVo = new PTZVo(); + double zReal = (zAngle + zOffsetAngle) % 360; + double panValue = 0f; + double tiltValue = 0f; + double commonAngle = 180.00f; + double commonAngle1 = (yOffsetAngle + 90.00f) / 2.00f; + + //P算法 + if (zReal < 180) { + if (zReal <= 0) { + panValue = 0f; + } else { + panValue = zReal / commonAngle; + } + } else { + panValue = (zReal - commonAngle) / commonAngle - 1; + } + + + if (yAngle > commonAngle1) { + if (yAngle > commonAngle1 * 2) { // yAngle < 90 yOffsetAngle < + tiltValue = 1; + } else { + tiltValue = ((yAngle - commonAngle1) / commonAngle1) * (-1); + } + } else { + tiltValue = (yAngle - commonAngle1) / commonAngle1; + } + + //Z算法 + double zoomValue = factor * distance * 0.01; + if (zoomValue > 1) { + zoomValue = 1; + } + if (zoomValue < factor) { + zoomValue = factor; + } + + ptzVo.setPanValue(panValue); + ptzVo.setTileValue(tiltValue); + ptzVo.setZoomValue(zoomValue); + +/* ptzVo.setPanValue(factor); + ptzVo.setTileValue(tiltValue); + ptzVo.setZoomValue(zoomValue);*/ + + return ptzVo; + } + + //测试数据 用于模拟光电跟踪 + public void test(String cameraIP, + String cameraUser, + String cameraPassword, + double yOffsetAngle,//最大俯仰角 + double zOffsetAngle,//初始水平角度 + double yHeight,//球机高度 + double factor,//聚焦因子 + double lon1,//相机经度 + double lat1,//相机纬度 + double lon2,//目标经度 + double lat2,//目标纬度 + int factory){ //相机产商类型 + try { + // 登录设备 + onvifDevice = new de.onvif.soap.OnvifDevice(cameraIP, cameraUser, cameraPassword); + PtzDevices ptzDevices = onvifDevice.getPtz(); + String token = onvifDevice.getDevices().getProfiles().get(0).getToken(); + + //初步计算 + double zAngle = GEOUtils.position(lon1, lat1, lon2, lat2);//计算球机需要转动的水平角度 + double zDis = GEOUtils.GetDistance(lon1, lat1, lon2, lat2);//todo : 计算距离(前面已经计算过 重复计算问题) + double yAngle = GEOUtils.upAngle(yHeight, zDis);//计算球机需要转动的垂直角度 + double focusDis = Math.sqrt(yHeight * yHeight + zDis * zDis);//计算球机距离目标的距离 + + log.info("【ptzControllerByLatLon 初步计算的值(未调整)】"); + log.info("zAngle:"+zAngle); + log.info("zDis:"+zDis); + log.info("yAngle:"+yAngle); + log.info("focusDis:"+focusDis); + + //计算PTZ值(根据数据库设置的初始值进行进一步计算) -1 implements IMsModelPositionService { + + @Autowired + private MsModelPositionMapper msModelPositionMapper; + @Autowired + private MsModelTrajectoryMapper msModelTrajectoryMapper; + @Resource + private WebSocket webSocket; + + @Value("${mqtt.orgCode}") + private String myOrgCode; + + public MsModelPositionServiceImpl() { + } + + @Override + @Transactional + public void saveMain(MsModelPosition msModelPosition, List msModelTrajectoryList) { + msModelPositionMapper.insert(msModelPosition); + if (msModelTrajectoryList != null && msModelTrajectoryList.size() > 0) { + for (MsModelTrajectory entity : msModelTrajectoryList) { + //外键设置 + entity.setModelPositionId(msModelPosition.getId()); + msModelTrajectoryMapper.insert(entity); + } + } + } + + @Override + @Transactional + public void updateMain(MsModelPosition msModelPosition, List msModelTrajectoryList) { + msModelPositionMapper.updateById(msModelPosition); + + //1.先删除子表数据 + msModelTrajectoryMapper.deleteByMainId(msModelPosition.getId()); + + //2.子表数据重新插入 + if (msModelTrajectoryList != null && msModelTrajectoryList.size() > 0) { + for (MsModelTrajectory entity : msModelTrajectoryList) { + //外键设置 + entity.setModelPositionId(msModelPosition.getId()); + msModelTrajectoryMapper.insert(entity); + } + } + } + + @Override + @Transactional + public void delMain(String id) { + msModelTrajectoryMapper.deleteByMainId(id); + msModelPositionMapper.deleteById(id); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delByEventSerialNumMain(String eventSerialNum) { + String id = msModelPositionMapper.selectList(new QueryWrapper().eq("event_serial_num", + eventSerialNum)).get(0).getId(); + msModelTrajectoryMapper.deleteById(id); + msModelPositionMapper.deleteById(id); + } + + @Override + @Transactional + public void delBatchMain(Collection idList) { + for (Serializable id : idList) { + msModelTrajectoryMapper.deleteByMainId(id.toString()); + msModelPositionMapper.deleteById(id); + } + } + + @Override + @Transactional + public int addModelInfo(MsModelPosition msModelPosition) { +// int result = 0; +// //先用事件编号判断该记录是否存在 +// QueryWrapper queryWrapper = new QueryWrapper<>(); +// queryWrapper.eq("event_serial_num", msModelPosition.getEventSerialNum()); +// List modelPositionList = msModelPositionMapper.selectList(queryWrapper); +// if (!CollectionUtils.isEmpty(modelPositionList)) { +// //记录存在,则判断【经度、纬度、高度、偏航角、俯仰角、翻转角】其中是否有变化,有的话则更新 +// if (msModelPosition.getLon().compareTo(modelPositionList.get(0).getLon()) != 0 +// || msModelPosition.getLat().compareTo(modelPositionList.get(0).getLat()) != 0 +// || msModelPosition.getHeight().compareTo(modelPositionList.get(0).getHeight()) != 0 +// || msModelPosition.getYaw().compareTo(modelPositionList.get(0).getYaw()) != 0 +// || msModelPosition.getPitch().compareTo(modelPositionList.get(0).getPitch()) != 0 +// || msModelPosition.getRoll().compareTo(modelPositionList.get(0).getRoll()) != 0) { +// msModelPosition.setId(modelPositionList.get(0).getId()); +// msModelPositionMapper.updateById(msModelPosition); +// } else { +// //无变化,则不做处理 +// return result; +// } +// } else { +// //记录不存在 +// msModelPositionMapper.insert(msModelPosition); +// } +// //插入历史轨迹表 +// MsModelTrajectory modelTrajectory = new MsModelTrajectory(); +// modelTrajectory.setModelPositionId(msModelPosition.getId());//外键设置 +// modelTrajectory.setCurrPosTime(new Date()); +// BeanUtils.copyProperties(msModelPosition, modelTrajectory, new String[]{"id", "createTime", "createBy", "updateTime", "updateBy", "sysOrgCode"}); +// result = msModelTrajectoryMapper.insert(modelTrajectory); +// + // 当新增或者轨迹发生变化时,websocket通知前端刷新数据 +// JSONObject obj = new JSONObject(); +// obj.put("cmd", "earthMap_model_realtime_info");//业务类型 +// obj.put("eventSerialNum", msModelPosition.getEventSerialNum());//事件编号 +// obj.put("modelId", msModelPosition.getModelId()); // 模型Id (轨迹ID 用来判断是否是同一个目标) +// obj.put("modelType", msModelPosition.getModelType());//模型类型 +// obj.put("content", modelTrajectory);//轨迹信息 +// //全体发送 +// webSocket.pushMessage(obj.toJSONString()); + + return 1; + } + + public int addModelInfo(MsModelPosition msModelPosition, Boolean isMainTarget,BigDecimal dis,BigDecimal speed) { + MsModelTrajectory modelTrajectory = new MsModelTrajectory(); + modelTrajectory.setModelPositionId(msModelPosition.getId());//外键设置 + modelTrajectory.setCurrPosTime(new Date()); + BeanUtils.copyProperties(msModelPosition, modelTrajectory, "id", "createTime", "createBy", "updateTime", "updateBy", "sysOrgCode"); + + // 当新增或者轨迹发生变化时,websocket通知前端刷新数据 + JSONObject obj = new JSONObject(); + obj.put("cmd", "earthMap_model_realtime_info");//业务类型 + obj.put("eventSerialNum", msModelPosition.getEventSerialNum());//事件编号 + obj.put("modelId", msModelPosition.getModelId()); // 模型Id (轨迹ID 用来判断是否是同一个目标) + obj.put("modelType", msModelPosition.getModelType());//模型类型 + obj.put("mainTarget", isMainTarget);//是否是主目标 + obj.put("content", modelTrajectory);//轨迹信息 + if (dis != null && speed !=null) { + DecimalFormat df = new DecimalFormat("0.00"); + String speedStr = df.format(speed); + df.applyPattern("#"); + String disStr = df.format(dis); + obj.put("speed", speedStr);//轨迹速度 + obj.put("dis", disStr);//距离 + } + // 当前登录用户所属机构 + obj.put("source",myOrgCode); + //全体发送 + + webSocket.pushMessage(obj.toJSONString()); +/* + SpringContextUtils.getBean(MqttService.class) + .pubMessage("master",obj.toJSONString().getBytes(),"military/trajectory"); +*/ + + return 1; + } + +} diff --git a/src/main/java/com/zgx/iot/thread/ZMQREPServer.java b/src/main/java/com/zgx/iot/thread/ZMQREPServer.java new file mode 100644 index 0000000..1bcf74e --- /dev/null +++ b/src/main/java/com/zgx/iot/thread/ZMQREPServer.java @@ -0,0 +1,94 @@ +package com.zgx.iot.thread; + +import com.alibaba.fastjson.JSON; +import com.zgx.iot.dto.site.Result; +import lombok.extern.slf4j.Slf4j; +import org.zeromq.SocketType; +import org.zeromq.ZContext; +import org.zeromq.ZMQ; + + +import java.text.ParseException; +import java.util.List; + +/** + * @Description: 【ZMQ发布端】请求-响应模式(REP-REQ) + * @Author: bb + * @Date: 2021-08-17 + */ +@Slf4j +public abstract class ZMQREPServer { + /** + * ZMQ启动线程数 + */ + private static int ZMQThreadCount = 1; + /** + * 服务发布地址 + */ + private String address; + /** + * 服务发布端口 + */ + private int port; + + private static ZContext context = null; + private static ZMQ.Socket socket = null; + + public ZMQREPServer(String address, int port) throws InterruptedException { + this.address = address; + this.port = port; + initZMQ(); + } + + /** + * 初始化ZMQ对象 + */ + private void initZMQ() throws InterruptedException { + log.info("【ZMQ】服务启动中......"); + if (context == null) { + context = new ZContext(ZMQThreadCount); + } + if (socket == null) { + socket = context.createSocket(SocketType.REP); + } + String addr = "tcp://" + this.address + ":" + this.port; + socket.bind(addr); + log.info("【ZMQ】服务启动成功!"); + + try { + while (!Thread.currentThread().isInterrupted()) { + //接收消息 + byte[] reply = socket.recv(0); + Result result = dealWithData(reply); + //接收到后回复 + List resList = (List) result.getResult(); + String response = JSON.toJSONString(resList); + socket.send(response.getBytes(ZMQ.CHARSET), 0); + } + //关闭套接字和上下文 + this.close(); + } catch (ParseException e) { + e.printStackTrace(); + } + } + + /** + * 处理接收到的数据 + */ + public abstract Result dealWithData(byte[] data) throws ParseException; + + /** + * 关闭套接字和上下文 + */ + public void close() { + if (socket != null) { + socket.close(); + socket = null; + } + if (context != null) { + context.close(); + context = null; + } + log.error("【ZMQ】服务已停止!"); + } +} diff --git a/src/main/java/com/zgx/iot/thread/ZMQServer.java b/src/main/java/com/zgx/iot/thread/ZMQServer.java new file mode 100644 index 0000000..f1f617d --- /dev/null +++ b/src/main/java/com/zgx/iot/thread/ZMQServer.java @@ -0,0 +1,88 @@ +package com.zgx.iot.thread; + +import lombok.extern.slf4j.Slf4j; +import org.zeromq.ZMQ; + + +/** + * @Description: 【ZMQ发布端】发布-订阅模式(PUB-SUB) + * @Author: bb + * @Date: 2021-07-15 + */ +@Slf4j +public class ZMQServer { + /** + * ZMQ启动线程数 + */ + private static int ZMQThreadCount = 1; + /** + * 服务发布地址 + */ + private String address; + /** + * 服务发布端口 + */ + private int port; + + private static ZMQ.Context context = null; + private static ZMQ.Socket socket = null; + + public ZMQServer(String address, int port) throws InterruptedException { + this.address = address; + this.port = port; + initZMQ(); + } + + /** + * 初始化ZMQ对象 + */ + private void initZMQ() throws InterruptedException { + log.info("【ZMQ】服务启动中......"); + if (context == null) { + context = ZMQ.context(ZMQThreadCount); + } + if (socket == null) { + socket = context.socket(ZMQ.PUB); + } + String addr = "tcp://" + this.address + ":" + this.port; + socket.bind(addr); + //正常发布者使用bind(),这里由于连接ZMQ服务端中心因此把自己当订阅者所以使用connect + //socket.connect(addr); + log.info("【ZMQ】服务启动成功!"); + } + + /** + * 发送数据 + * send() — ZMQ.DONTWAIT(异步非阻塞模式),ZMQ.SNDMORE(多帧消息) + * + * @param sign 主题 + * @param data 数据 + */ + public synchronized void sendData(String sign, byte[] data) { + try { + if (socket != null) { + socket.send(sign.getBytes(), ZMQ.SNDMORE); + socket.send(data); + log.info("【ZMQ】数据发布成功!"); + } + } catch (Exception e) { + log.error("【ZMQ】数据发送异常!"); + } + } + + /** + * 关闭套接字和上下文 + */ + public void close() { + if (socket != null) { + socket.close(); + socket = null; + } + if (context != null) { + context.term(); + context = null; + } + log.error("【ZMQ】服务已停止!"); + } + +} diff --git a/src/main/java/com/zgx/iot/thread/ZmqSubThread.java b/src/main/java/com/zgx/iot/thread/ZmqSubThread.java new file mode 100644 index 0000000..c5e80a6 --- /dev/null +++ b/src/main/java/com/zgx/iot/thread/ZmqSubThread.java @@ -0,0 +1,86 @@ +package com.zgx.iot.thread; + +import lombok.extern.slf4j.Slf4j; +import org.zeromq.ZMQ; + +import java.text.ParseException; + +/** + * @Description: 【ZMQ接收线程】 + * @Author: bb + * @Date: 2021-07-15 + */ +@Slf4j +public abstract class ZmqSubThread implements Runnable { + /** + * ZMQ启动线程数 + */ + private static int ZMQThreadCount = 1; + /** + * 服务接收地址 + */ + private String address; + /** + * 服务接收端口 + */ + private int port; + /** + * 服务接收主题 + */ + private String topic; + + private ZMQ.Context context = null; + private ZMQ.Socket socket = null; + + public ZmqSubThread(String address, int port, String topic) throws InterruptedException { + this.address = address; + this.port = port; + this.topic = topic; + initZMQ(); + } + + /** + * 初始化ZMQ对象 + */ + private void initZMQ() throws InterruptedException { + if (this.address == null || "".equals(this.address)) { + throw new RuntimeException("IP null!"); + } + if (this.port == 0) { + throw new RuntimeException("Port null!"); + } + + context = ZMQ.context(ZMQThreadCount); + socket = context.socket(ZMQ.SUB); + String addr = "tcp://" + this.address + ":" + this.port; + socket.connect(addr); + + //设置订阅条件topic + socket.subscribe(this.topic.getBytes()); + } + + @Override + public void run() { + while (!Thread.currentThread().isInterrupted()) { + try { + byte[] sign = socket.recv(ZMQ.SUB); + //若主题为空,后面消息也丢掉 + if (sign == null) { + break; + } + System.out.println("[" + this.toString() + "] " + "sign: " + new String(sign)); + byte[] data = socket.recv(ZMQ.SUB); + + dealWithData(data); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + /** + * 处理接收到的数据 + */ + public abstract void dealWithData(byte[] data) throws ParseException; + +} diff --git a/src/main/java/com/zgx/iot/utils/AlarmInfoConvert.java b/src/main/java/com/zgx/iot/utils/AlarmInfoConvert.java new file mode 100644 index 0000000..f47270f --- /dev/null +++ b/src/main/java/com/zgx/iot/utils/AlarmInfoConvert.java @@ -0,0 +1,216 @@ +package com.zgx.iot.utils; + +import lombok.Data; + +import java.text.SimpleDateFormat; + +/** + * 线性告警识别系统小规模验证通信协议 + */ +@Data +public class AlarmInfoConvert { + + /** + * 固定帧头 + */ + private static String fixFrameHead = "EB90"; + + /** + * 数据长度 + */ + private Integer dataLong; + + /** + * 设备编号 + */ + private Integer deviceNum; + + /** + * 接收者编号 + */ + private Integer recipientNum; + + /** + * 信息类型 + * 0:报警信息 + * 1:状态信息 + */ + private Integer dataType; + + /** + * 入侵位置距起点距离 + */ + private Integer distance; + + /** + * 目标类型 + * 1:人 + * 2:车 + * 3:其他 + */ + private Integer targetType; + + /** + * 报警类型: + * 1:入侵 + * 2:破坏 + * 3:其他 + * 状态类型: + * 1:心跳 + * 2:断纤 + * 3:其他故障 + */ + private Integer alarmType; + + /** + * 置信度 + */ + private Integer degreeOfConfidence; + + /** + * 年 + */ + private Integer year; + + /** + * 月 + */ + private Integer month; + + /** + * 日 + */ + private Integer day; + + /** + * 时 + */ + private Integer hour; + + /** + * 分 + */ + private Integer minute; + + /** + * 秒 + */ + private Integer second; + + /** + * 毫秒 + */ + private Integer milliSecond; + + /** + * 报警信息数据长度 + */ + private static final int ALARM_DATA_LEN = 28; + /** + * 状态信息数据长度 + */ + private static final int STATUS_DATA_LEN = 19; + + /** + * int8 + */ + public static String getInt_8(int data) { + return String.format("%02x", data).toUpperCase(); + } + + /** + * int16 + */ + public static String getInt_16(int data) { + return String.format("%04x", data).toUpperCase(); + } + + /** + * int + */ + public static String getInt(int data) { + return String.format("%08x", data).toUpperCase(); + } + + /** + * 根据时间戳获取具体的年/月/日/时/分/秒/毫秒 + * + * @param time + */ + private static String getHexTime(Long time) { + SimpleDateFormat yearSdf = new SimpleDateFormat("yyyy"); + SimpleDateFormat monthSdf = new SimpleDateFormat("MM"); + SimpleDateFormat daySdf = new SimpleDateFormat("dd"); + SimpleDateFormat hourSdf = new SimpleDateFormat("HH"); + SimpleDateFormat minuteSdf = new SimpleDateFormat("mm"); + SimpleDateFormat secondSdf = new SimpleDateFormat("ss"); + SimpleDateFormat milliSecondSdf = new SimpleDateFormat("SSS"); + + return getInt_16(Integer.parseInt(yearSdf.format(time))) + getInt_8(Integer.parseInt(monthSdf.format(time))) + getInt_8(Integer.parseInt(daySdf.format(time))) + + getInt_8(Integer.parseInt(hourSdf.format(time))) + getInt_8(Integer.parseInt(minuteSdf.format(time))) + getInt_8(Integer.parseInt(secondSdf.format(time))) + + getInt_16(Integer.parseInt(milliSecondSdf.format(time))); + } + + /** + * 发送报警信息 + * + * @param deviceNum 设备编号 + * @param recipientNum 接收者编号 + * @param dataType 信息类型 + * @param distance 入侵位置距起点距离 + * @param targetType 目标类型 + * @param alarmType 报警类型 + * @param degreeOfConfidence 置信度 + * @param time 时间戳 + * @return + */ + public static byte[] getAlarmInformationData(Integer deviceNum, Integer recipientNum, Integer dataType, Integer distance, Integer targetType, + Integer alarmType, Integer degreeOfConfidence, Long time) { + String dataStr = fixFrameHead + getInt_16(ALARM_DATA_LEN) + getInt_16(deviceNum) + getInt_16(recipientNum) + + getInt_8(dataType) + getInt(distance) + getInt_8(targetType) + getInt_8(alarmType) + + getInt(degreeOfConfidence) + getHexTime(time); + return NumConvertUtil.hexToByte(dataStr); + } + + /** + * 发送状态信息 + * + * @param deviceNum 设备编号 + * @param recipientNum 接收者编号 + * @param dataType 信息类型 + * @param alarmType 报警类型 + * @param time 时间戳 + * @return + */ + public static byte[] getStateInformationData(Integer deviceNum, Integer recipientNum, Integer dataType, Integer alarmType, Long time) { + String dataStr = fixFrameHead + getInt_16(STATUS_DATA_LEN) + getInt_16(deviceNum) + getInt_16(recipientNum) + getInt_8(dataType) + getInt_8(alarmType) + getHexTime(time); + return NumConvertUtil.hexToByte(dataStr); + } + +} + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/zgx/iot/utils/DateUtils.java b/src/main/java/com/zgx/iot/utils/DateUtils.java new file mode 100644 index 0000000..5dbdda9 --- /dev/null +++ b/src/main/java/com/zgx/iot/utils/DateUtils.java @@ -0,0 +1,650 @@ +package com.zgx.iot.utils; + +import org.springframework.util.StringUtils; + +import java.beans.PropertyEditorSupport; +import java.sql.Timestamp; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; + +/** + * 类描述:时间操作定义类 + * + * @Author: 张代浩 + * @Date:2012-12-8 12:15:03 + * @Version 1.0 + */ +public class DateUtils extends PropertyEditorSupport { + + public static ThreadLocal date_sdf = new ThreadLocal() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("yyyy-MM-dd"); + } + }; + public static ThreadLocal yyyyMMdd = new ThreadLocal() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("yyyyMMdd"); + } + }; + public static ThreadLocal date_sdf_wz = new ThreadLocal() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("yyyy年MM月dd日"); + } + }; + public static ThreadLocal time_sdf = new ThreadLocal() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("yyyy-MM-dd HH:mm"); + } + }; + public static ThreadLocal yyyymmddhhmmss = new ThreadLocal() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("yyyyMMddHHmmss"); + } + }; + public static ThreadLocal short_time_sdf = new ThreadLocal() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("HH:mm"); + } + }; + public static ThreadLocal datetimeFormat = new ThreadLocal() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + } + }; + + // 以毫秒表示的时间 + private static final long DAY_IN_MILLIS = 24 * 3600 * 1000; + private static final long HOUR_IN_MILLIS = 3600 * 1000; + private static final long MINUTE_IN_MILLIS = 60 * 1000; + private static final long SECOND_IN_MILLIS = 1000; + + // 指定模式的时间格式 + private static SimpleDateFormat getSDFormat(String pattern) { + return new SimpleDateFormat(pattern); + } + + /** + * 当前日历,这里用中国时间表示 + * + * @return 以当地时区表示的系统当前日历 + */ + public static Calendar getCalendar() { + return Calendar.getInstance(); + } + + /** + * 指定毫秒数表示的日历 + * + * @param millis 毫秒数 + * @return 指定毫秒数表示的日历 + */ + public static Calendar getCalendar(long millis) { + Calendar cal = Calendar.getInstance(); + // --------------------cal.setTimeInMillis(millis); + cal.setTime(new Date(millis)); + return cal; + } + + // //////////////////////////////////////////////////////////////////////////// + // getDate + // 各种方式获取的Date + // //////////////////////////////////////////////////////////////////////////// + + /** + * 当前日期 + * + * @return 系统当前时间 + */ + public static Date getDate() { + return new Date(); + } + + /** + * 指定毫秒数表示的日期 + * + * @param millis 毫秒数 + * @return 指定毫秒数表示的日期 + */ + public static Date getDate(long millis) { + return new Date(millis); + } + + /** + * 时间戳转换为字符串 + * + * @param time + * @return + */ + public static String timestamptoStr(Timestamp time) { + Date date = null; + if (null != time) { + date = new Date(time.getTime()); + } + return date2Str(date_sdf.get()); + } + + /** + * 字符串转换时间戳 + * + * @param str + * @return + */ + public static Timestamp str2Timestamp(String str) { + Date date = str2Date(str, date_sdf.get()); + return new Timestamp(date.getTime()); + } + + /** + * 字符串转换成日期 + * + * @param str + * @param sdf + * @return + */ + public static Date str2Date(String str, SimpleDateFormat sdf) { + if (null == str || "".equals(str)) { + return null; + } + Date date = null; + try { + date = sdf.parse(str); + return date; + } catch (ParseException e) { + e.printStackTrace(); + } + return null; + } + + /** + * 日期转换为字符串 + * + * @param date_sdf 日期格式 + * @return 字符串 + */ + public static String date2Str(SimpleDateFormat date_sdf) { + Date date = getDate(); + if (null == date) { + return null; + } + return date_sdf.format(date); + } + + /** + * 格式化时间 + * + * @param date + * @param format + * @return + */ + public static String dateformat(String date, String format) { + SimpleDateFormat sformat = new SimpleDateFormat(format); + Date _date = null; + try { + _date = sformat.parse(date); + } catch (ParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return sformat.format(_date); + } + + /** + * 日期转换为字符串 + * + * @param date 日期 + * @param date_sdf 日期格式 + * @return 字符串 + */ + public static String date2Str(Date date, SimpleDateFormat date_sdf) { + if (null == date) { + return null; + } + return date_sdf.format(date); + } + + /** + * 日期转换为字符串 + * + * @param format 日期格式 + * @return 字符串 + */ + public static String getDate(String format) { + Date date = new Date(); + if (null == date) { + return null; + } + SimpleDateFormat sdf = new SimpleDateFormat(format); + return sdf.format(date); + } + + /** + * 指定毫秒数的时间戳 + * + * @param millis 毫秒数 + * @return 指定毫秒数的时间戳 + */ + public static Timestamp getTimestamp(long millis) { + return new Timestamp(millis); + } + + /** + * 以字符形式表示的时间戳 + * + * @param time 毫秒数 + * @return 以字符形式表示的时间戳 + */ + public static Timestamp getTimestamp(String time) { + return new Timestamp(Long.parseLong(time)); + } + + /** + * 系统当前的时间戳 + * + * @return 系统当前的时间戳 + */ + public static Timestamp getTimestamp() { + return new Timestamp(System.currentTimeMillis()); + } + + /** + * 当前时间,格式 yyyy-MM-dd HH:mm:ss + * + * @return 当前时间的标准形式字符串 + */ + public static String now() { + return datetimeFormat.get().format(getCalendar().getTime()); + } + + /** + * 指定日期的时间戳 + * + * @param date 指定日期 + * @return 指定日期的时间戳 + */ + public static Timestamp getTimestamp(Date date) { + return new Timestamp(date.getTime()); + } + + /** + * 指定日历的时间戳 + * + * @param cal 指定日历 + * @return 指定日历的时间戳 + */ + public static Timestamp getCalendarTimestamp(Calendar cal) { + // ---------------------return new Timestamp(cal.getTimeInMillis()); + return new Timestamp(cal.getTime().getTime()); + } + + public static Timestamp gettimestamp() { + Date dt = new Date(); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String nowTime = df.format(dt); + Timestamp buydate = Timestamp.valueOf(nowTime); + return buydate; + } + + // //////////////////////////////////////////////////////////////////////////// + // getMillis + // 各种方式获取的Millis + // //////////////////////////////////////////////////////////////////////////// + + /** + * 系统时间的毫秒数 + * + * @return 系统时间的毫秒数 + */ + public static long getMillis() { + return System.currentTimeMillis(); + } + + /** + * 指定日历的毫秒数 + * + * @param cal 指定日历 + * @return 指定日历的毫秒数 + */ + public static long getMillis(Calendar cal) { + // --------------------return cal.getTimeInMillis(); + return cal.getTime().getTime(); + } + + /** + * 指定日期的毫秒数 + * + * @param date 指定日期 + * @return 指定日期的毫秒数 + */ + public static long getMillis(Date date) { + return date.getTime(); + } + + /** + * 指定时间戳的毫秒数 + * + * @param ts 指定时间戳 + * @return 指定时间戳的毫秒数 + */ + public static long getMillis(Timestamp ts) { + return ts.getTime(); + } + + // //////////////////////////////////////////////////////////////////////////// + // formatDate + // 将日期按照一定的格式转化为字符串 + // //////////////////////////////////////////////////////////////////////////// + + /** + * 默认方式表示的系统当前日期,具体格式:年-月-日 + * + * @return 默认日期按“年-月-日“格式显示 + */ + public static String formatDate() { + return date_sdf.get().format(getCalendar().getTime()); + } + + /** + * 默认方式表示的系统当前日期,具体格式:yyyy-MM-dd HH:mm:ss + * + * @return 默认日期按“yyyy-MM-dd HH:mm:ss“格式显示 + */ + public static String formatDateTime() { + return datetimeFormat.get().format(getCalendar().getTime()); + } + + /** + * 获取时间字符串 + */ + public static String getDataString(SimpleDateFormat formatstr) { + return formatstr.format(getCalendar().getTime()); + } + + /** + * 指定日期的默认显示,具体格式:年-月-日 + * + * @param cal 指定的日期 + * @return 指定日期按“年-月-日“格式显示 + */ + public static String formatDate(Calendar cal) { + return date_sdf.get().format(cal.getTime()); + } + + /** + * 指定日期的默认显示,具体格式:年-月-日 + * + * @param date 指定的日期 + * @return 指定日期按“年-月-日“格式显示 + */ + public static String formatDate(Date date) { + return date_sdf.get().format(date); + } + + /** + * 指定毫秒数表示日期的默认显示,具体格式:年-月-日 + * + * @param millis 指定的毫秒数 + * @return 指定毫秒数表示日期按“年-月-日“格式显示 + */ + public static String formatDate(long millis) { + return date_sdf.get().format(new Date(millis)); + } + + /** + * 默认日期按指定格式显示 + * + * @param pattern 指定的格式 + * @return 默认日期按指定格式显示 + */ + public static String formatDate(String pattern) { + return getSDFormat(pattern).format(getCalendar().getTime()); + } + + /** + * 指定日期按指定格式显示 + * + * @param cal 指定的日期 + * @param pattern 指定的格式 + * @return 指定日期按指定格式显示 + */ + public static String formatDate(Calendar cal, String pattern) { + return getSDFormat(pattern).format(cal.getTime()); + } + + /** + * 指定日期按指定格式显示 + * + * @param date 指定的日期 + * @param pattern 指定的格式 + * @return 指定日期按指定格式显示 + */ + public static String formatDate(Date date, String pattern) { + return getSDFormat(pattern).format(date); + } + + // //////////////////////////////////////////////////////////////////////////// + // formatTime + // 将日期按照一定的格式转化为字符串 + // //////////////////////////////////////////////////////////////////////////// + + /** + * 默认方式表示的系统当前日期,具体格式:年-月-日 时:分 + * + * @return 默认日期按“年-月-日 时:分“格式显示 + */ + public static String formatTime() { + return time_sdf.get().format(getCalendar().getTime()); + } + + /** + * 指定毫秒数表示日期的默认显示,具体格式:年-月-日 时:分 + * + * @param millis 指定的毫秒数 + * @return 指定毫秒数表示日期按“年-月-日 时:分“格式显示 + */ + public static String formatTime(long millis) { + return time_sdf.get().format(new Date(millis)); + } + + /** + * 指定日期的默认显示,具体格式:年-月-日 时:分 + * + * @param cal 指定的日期 + * @return 指定日期按“年-月-日 时:分“格式显示 + */ + public static String formatTime(Calendar cal) { + return time_sdf.get().format(cal.getTime()); + } + + /** + * 指定日期的默认显示,具体格式:年-月-日 时:分 + * + * @param date 指定的日期 + * @return 指定日期按“年-月-日 时:分“格式显示 + */ + public static String formatTime(Date date) { + return time_sdf.get().format(date); + } + + // //////////////////////////////////////////////////////////////////////////// + // formatShortTime + // 将日期按照一定的格式转化为字符串 + // //////////////////////////////////////////////////////////////////////////// + + /** + * 默认方式表示的系统当前日期,具体格式:时:分 + * + * @return 默认日期按“时:分“格式显示 + */ + public static String formatShortTime() { + return short_time_sdf.get().format(getCalendar().getTime()); + } + + /** + * 指定毫秒数表示日期的默认显示,具体格式:时:分 + * + * @param millis 指定的毫秒数 + * @return 指定毫秒数表示日期按“时:分“格式显示 + */ + public static String formatShortTime(long millis) { + return short_time_sdf.get().format(new Date(millis)); + } + + /** + * 指定日期的默认显示,具体格式:时:分 + * + * @param cal 指定的日期 + * @return 指定日期按“时:分“格式显示 + */ + public static String formatShortTime(Calendar cal) { + return short_time_sdf.get().format(cal.getTime()); + } + + /** + * 指定日期的默认显示,具体格式:时:分 + * + * @param date 指定的日期 + * @return 指定日期按“时:分“格式显示 + */ + public static String formatShortTime(Date date) { + return short_time_sdf.get().format(date); + } + + // //////////////////////////////////////////////////////////////////////////// + // parseDate + // parseCalendar + // parseTimestamp + // 将字符串按照一定的格式转化为日期或时间 + // //////////////////////////////////////////////////////////////////////////// + + /** + * 根据指定的格式将字符串转换成Date 如输入:2003-11-19 11:20:20将按照这个转成时间 + * + * @param src 将要转换的原始字符窜 + * @param pattern 转换的匹配格式 + * @return 如果转换成功则返回转换后的日期 + * @throws ParseException + */ + public static Date parseDate(String src, String pattern) throws ParseException { + return getSDFormat(pattern).parse(src); + + } + + /** + * 根据指定的格式将字符串转换成Date 如输入:2003-11-19 11:20:20将按照这个转成时间 + * + * @param src 将要转换的原始字符窜 + * @param pattern 转换的匹配格式 + * @return 如果转换成功则返回转换后的日期 + * @throws ParseException + */ + public static Calendar parseCalendar(String src, String pattern) throws ParseException { + + Date date = parseDate(src, pattern); + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + return cal; + } + + public static String formatAddDate(String src, String pattern, int amount) throws ParseException { + Calendar cal; + cal = parseCalendar(src, pattern); + cal.add(Calendar.DATE, amount); + return formatDate(cal); + } + + /** + * 根据指定的格式将字符串转换成Date 如输入:2003-11-19 11:20:20将按照这个转成时间 + * + * @param src 将要转换的原始字符窜 + * @param pattern 转换的匹配格式 + * @return 如果转换成功则返回转换后的时间戳 + * @throws ParseException + */ + public static Timestamp parseTimestamp(String src, String pattern) throws ParseException { + Date date = parseDate(src, pattern); + return new Timestamp(date.getTime()); + } + + // //////////////////////////////////////////////////////////////////////////// + // dateDiff + // 计算两个日期之间的差值 + // //////////////////////////////////////////////////////////////////////////// + + /** + * 计算两个时间之间的差值,根据标志的不同而不同 + * + * @param flag 计算标志,表示按照年/月/日/时/分/秒等计算 + * @param calSrc 减数 + * @param calDes 被减数 + * @return 两个日期之间的差值 + */ + public static int dateDiff(char flag, Calendar calSrc, Calendar calDes) { + + long millisDiff = getMillis(calSrc) - getMillis(calDes); + + if (flag == 'y') { + return (calSrc.get(Calendar.YEAR) - calDes.get(Calendar.YEAR)); + } + + if (flag == 'd') { + return (int) (millisDiff / DAY_IN_MILLIS); + } + + if (flag == 'h') { + return (int) (millisDiff / HOUR_IN_MILLIS); + } + + if (flag == 'm') { + return (int) (millisDiff / MINUTE_IN_MILLIS); + } + + if (flag == 's') { + return (int) (millisDiff / SECOND_IN_MILLIS); + } + + return 0; + } + + /** + * String类型 转换为Date, 如果参数长度为10 转换格式”yyyy-MM-dd“ 如果参数长度为19 转换格式”yyyy-MM-dd + * HH:mm:ss“ * @param text String类型的时间值 + */ + @Override + public void setAsText(String text) throws IllegalArgumentException { + if (StringUtils.hasText(text)) { + try { + if (text.indexOf(":") == -1 && text.length() == 10) { + setValue(DateUtils.date_sdf.get().parse(text)); + } else if (text.indexOf(":") > 0 && text.length() == 19) { + setValue(DateUtils.datetimeFormat.get().parse(text)); + } else { + throw new IllegalArgumentException("Could not parse date, date format is error "); + } + } catch (ParseException ex) { + IllegalArgumentException iae = new IllegalArgumentException("Could not parse date: " + ex.getMessage()); + iae.initCause(ex); + throw iae; + } + } else { + setValue(null); + } + } + + public static int getYear() { + GregorianCalendar calendar = new GregorianCalendar(); + calendar.setTime(getDate()); + return calendar.get(Calendar.YEAR); + } + +} \ No newline at end of file diff --git a/src/main/java/com/zgx/iot/utils/DeviceServiceUtil.java b/src/main/java/com/zgx/iot/utils/DeviceServiceUtil.java new file mode 100644 index 0000000..c39509c --- /dev/null +++ b/src/main/java/com/zgx/iot/utils/DeviceServiceUtil.java @@ -0,0 +1,216 @@ +package com.zgx.iot.utils; + +import com.zgx.iot.entity.DtDeviceInfo; +import com.zgx.iot.dto.site.Result; +import com.zgx.iot.netty.NettyServiceManage; +import com.zgx.iot.netty.model.NettyDeviceInfo; +import com.zgx.iot.netty.model.NettyService; +import com.zgx.iot.netty.pipeline.impl.MicrowaveDetectorUdpClientPipelineFactoryImpl; +import com.zgx.iot.netty.pipeline.impl.MicrowaveDetectorUdpServicePipelineFactoryImpl; +import com.zgx.iot.netty.pipeline.impl.RadarDetectorTcpServicePipelineFactoryImpl; +import com.zgx.iot.netty.pipeline.impl.common.CommonTcpClientPipelineFactoryImpl; +import com.zgx.iot.netty.socket.base.NettyBaseSocket; +import com.zgx.iot.netty.socket.tcp.TcpClientByNetty; +import com.zgx.iot.netty.socket.tcp.TcpServiceByNetty; +import com.zgx.iot.netty.socket.udp.UdpClientByNetty; +import com.zgx.iot.netty.socket.udp.UdpServiceByNetty; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import lombok.extern.slf4j.Slf4j; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.net.InetSocketAddress; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author AaGMixW + * 更简单的调用 netty service + */ +@Slf4j +@Component +public class DeviceServiceUtil { + + private static final Logger logger = LogManager.getLogger(DeviceServiceUtil.class); + + @Resource + private NettyServiceManage nettyServiceController; + + // 启动设备 + + /** + * 微波探测器 接收端 + * + * @param deviceInfo {@link NettyDeviceInfo} + * @return socket + */ + public Result> startMicrowaveDetectorServer(NettyDeviceInfo deviceInfo) { + NettyService nettyService = nettyServiceController.startupUdpService(deviceInfo, + MicrowaveDetectorUdpServicePipelineFactoryImpl.class); + UdpServiceByNetty service = (UdpServiceByNetty) nettyService.getService(); + Channel channel = service.getChannel(deviceInfo.getAddress()); + if (channel != null && channel.isActive()) { + return Result.OK(nettyService); + } + Result result = service.bind(deviceInfo.getAddress()); + if (result.isSuccess()) { + return Result.OK(nettyService); + } else { + return Result.ERROR("连接失败"); + } + } + + public Result> startMicrowaveDetectorClient(NettyDeviceInfo deviceInfo) { + // 重复时不连接 + NettyService nettyService = nettyServiceController.startupUdpClient(deviceInfo, + MicrowaveDetectorUdpClientPipelineFactoryImpl.class); + UdpClientByNetty client = (UdpClientByNetty) nettyService.getService(); + Channel channel = client.getChannel(deviceInfo.getAddress()); + if (channel != null && channel.isActive()) { + return Result.OK(nettyService); + } + Result futureResult = client.connect(deviceInfo.getAddress()); + if (futureResult.isSuccess()) { + return Result.OK(nettyService); + } else { + return Result.ERROR("连接失败"); + } + } + + // 停止设备 + + public boolean stopDeviceServer(NettyDeviceInfo deviceInfo) { + // main device + String mDeviceId = deviceInfo.getId(); + InetSocketAddress mDeviceAddress = deviceInfo.getAddress(); + boolean status; + // 停止连接 + status = nettyServiceController.stopChannel(mDeviceId, mDeviceAddress); + return status; + } + /** + * TCP服务端 + * + * @param deviceInfo {@link NettyDeviceInfo} + * @return socket + */ + public Result> startTcpServer(NettyDeviceInfo deviceInfo) { + NettyService nettyService = nettyServiceController.startupTcpService(deviceInfo, RadarDetectorTcpServicePipelineFactoryImpl.class); + TcpServiceByNetty service = (TcpServiceByNetty)nettyService.getService(); + Channel channel = service.getChannel(deviceInfo.getAddress()); + if (channel != null && channel.isActive()) { + return Result.OK(nettyService); + } + Result result = service.bind(deviceInfo.getAddress()); + if (result.isSuccess()) { + return Result.OK(nettyService); + } else { + return Result.ERROR("连接失败"); + } + } + public Result> startTcpClient(NettyDeviceInfo deviceInfo) { + // 重复时不连接 + TcpClientByNetty client = nettyServiceController.startupTcpClient(deviceInfo, + CommonTcpClientPipelineFactoryImpl.class); + Channel channel = client.getChannel(deviceInfo.getAddress()); + if (channel != null && channel.isActive()) { + return Result.OK(); + } + Result futureResult = client.connect(deviceInfo.getAddress()); + if (futureResult.isSuccess()) { + return Result.OK(); + } else { + return Result.ERROR("连接失败"); + } + } + /** + * 根据获取的设备列表启动服务 + * + * @param deviceInfoList 设备列表 + */ + public void startServerByDeviceInfo(List deviceInfoList) { + // 协议类型 + Map protocolTypeMap = getProtocolTypeMap(); + // 角色类型 + Map roleTypeMap = getRoleTypeMap(); + for (DtDeviceInfo deviceInfo : deviceInfoList) { + NettyDeviceInfo nettyDeviceInfo = new NettyDeviceInfo(deviceInfo, protocolTypeMap.get(Integer.valueOf(deviceInfo.getNetProtocol())), roleTypeMap.get(deviceInfo.getServerType())); + startDevice(nettyDeviceInfo); + } + } + + + public Map getRoleTypeMap() { + // 角色类型字典 + // 转成 value -> text 形式的 Map + Map roleTypeMap = new HashMap<>(); + roleTypeMap.put(1,"client"); + roleTypeMap.put(2,"service"); + return roleTypeMap; + } + + + public Map getProtocolTypeMap() { + // 协议类型字典 + // 转成 value -> text 形式的 Map + Map protocolTypeMap = new HashMap<>(); + protocolTypeMap.put(1,"TCP"); + protocolTypeMap.put(2,"UDP"); + return protocolTypeMap; + } + + + + + + public String getProtocolTypeText(Integer protocolType) { + return getProtocolTypeMap().get(protocolType); + } + + public String getRoleTypeText(Integer roleType) { + return getRoleTypeMap().get(roleType); + } + + public Result> startDevice(NettyDeviceInfo deviceInfo) { + int MICROWAVE_DETECTOR_HASH = deviceInfo.getDeviceTypeAndCompHash(); + switch (deviceInfo.getServiceId()) { + case "TCP:service": + if (deviceInfo.getDeviceTypeAndCompHash() == MICROWAVE_DETECTOR_HASH) { + log.info("{}({}) 服务启动", deviceInfo.getServiceId(), deviceInfo.getDeviceName()); + return startTcpServer(deviceInfo); + } + break; + + case "TCP:client": + if (deviceInfo.getDeviceTypeAndCompHash() == MICROWAVE_DETECTOR_HASH) { + // 微波探测器 + log.info("{}({}) 客户端启动", deviceInfo.getServiceId(), deviceInfo.getDeviceName()); + return startTcpClient(deviceInfo); + } + break; + case "UDP:service": + if (deviceInfo.getDeviceTypeAndCompHash() == MICROWAVE_DETECTOR_HASH) { + // 微波探测器 + log.info("{}({}) 服务启动", deviceInfo.getServiceId(), deviceInfo.getDeviceName()); + return startMicrowaveDetectorServer(deviceInfo); + } + break; + case "UDP:client": + if (deviceInfo.getDeviceTypeAndCompHash() == MICROWAVE_DETECTOR_HASH) { + log.info("{}({}) 客户端启动", deviceInfo.getServiceId(), deviceInfo.getDeviceName()); + return startMicrowaveDetectorClient(deviceInfo); + } + break; + default: + log.error("{}({}) 服务启动失败,找不到有效的启动方式。", deviceInfo.getServiceId(), deviceInfo.getDeviceName()); + return Result.ERROR(String.format("{}({}) 服务启动失败,找不到有效的启动方式。", deviceInfo.getServiceId(), deviceInfo.getDeviceName())); + } + return Result.ERROR(String.format("{}({}) 服务启动失败!!", deviceInfo.getServiceId(), deviceInfo.getDeviceName())); + } + +} diff --git a/src/main/java/com/zgx/iot/utils/EventSerialNumUtil.java b/src/main/java/com/zgx/iot/utils/EventSerialNumUtil.java new file mode 100644 index 0000000..04a2b30 --- /dev/null +++ b/src/main/java/com/zgx/iot/utils/EventSerialNumUtil.java @@ -0,0 +1,31 @@ +package com.zgx.iot.utils; + +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * 生成事件编号 + * 格式:年月日时分秒 + 4位随机数 + */ +public class EventSerialNumUtil { + + public static String getEventSerialNum() { + return getStringDate() + String.valueOf(Getnum()); + } + + private static String getStringDate() { + Date currentTime = new Date(); + SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss"); + String dateString = formatter.format(currentTime); + return dateString; + } + + private static int Getnum() { + return (int) (Math.random() * 9000) + 100; + } + + + public static void main(String[] args) { + System.out.println(getEventSerialNum()); + } +} diff --git a/src/main/java/com/zgx/iot/utils/GEOIntersectPointUtils.java b/src/main/java/com/zgx/iot/utils/GEOIntersectPointUtils.java new file mode 100644 index 0000000..d0a67d7 --- /dev/null +++ b/src/main/java/com/zgx/iot/utils/GEOIntersectPointUtils.java @@ -0,0 +1,395 @@ +package com.zgx.iot.utils; + +import lombok.extern.slf4j.Slf4j; + +/** + * 获取两条直线相交点的经纬度 + */ +@Slf4j +public class GEOIntersectPointUtils { + /** + * 地球周长 + */ + private static double L = 6381372 * Math.PI * 2; + /** + * 平面展开后,x轴等于周长 + */ + private static double W = L; + /** + * y轴约等于周长一半 + */ + private static double H = L / 2; + /** + * 米勒投影中的一个常数,范围大约在正负2.3之间 + */ + private static double mill = 2.3; + + /** + * 将经纬度转换成X和Y轴 + * 米勒投影算法 + * + * @param lat 纬度 + * @param lon 经度 + * @return + */ + public static Point millierConvertion(double lat, double lon) { + // 将经度从度数转换为弧度 + double x = lon * Math.PI / 180; + // 将纬度从度数转换为弧度 + double y = lat * Math.PI / 180; + // 米勒投影的转换 + y = 1.25 * Math.log(Math.tan(0.25 * Math.PI + 0.4 * y)); + // 弧度转为实际距离 + x = (W / 2) + (W / (2 * Math.PI)) * x; + y = (H / 2) - (H / (2 * mill)) * y; + return new Point(x, y); + } + + /** + * xy轴转坐标 + * + * @param x + * @param y + * @return 坐标点 + */ + public static LatLon xyToLatLon(double x, double y) { + //实际距离 转为弧度 + x = (x - (W / 2)) / (W / (2 * Math.PI)); + y = -1 * (y - (H / 2)) / (H / (2 * mill)); + // 米勒投影的转换反转 + y = (Math.atan(Math.pow(Math.E, y / 1.25)) - 0.25 * Math.PI) / 0.4; + //将经度从弧度转换为度数 + double lon = 180 / Math.PI * x; + //将纬度从弧度转换为度数 + double lat = 180 / Math.PI * y; + return new LatLon(lon, lat); + } + + + /** + * 获取两条直线相交的点 + * + * @param segmentLatLonOne 线段一 + * @param segmentLatLonTwo 线段二 + * @return 相交点坐标 为null 不相交 + */ + public static LatLon getIntersectPoint(SegmentLatLon segmentLatLonOne, SegmentLatLon segmentLatLonTwo) { + //先判断有没有相交 (延长线不算) 不相交返回null 相交执行获取交点坐标 (如需获取延长线交点注释此方法)---- + if (!segIntersect(segmentLatLonOne, segmentLatLonTwo)) { + return null; + } + //转换对象 + Point[] points = segmentLatLonToPoint(segmentLatLonOne, segmentLatLonTwo); + //获取两条直线相交的点 + Point latLon = getIntersectPoint(points[0], points[1], points[2], points[3]); + if (latLon != null) { + return xyToLatLon(latLon.x, latLon.y); + } + return null; + } + + /** + * 获取两条直线相交的点 + * + * @param p1 线段一 开始点 + * @param p2 线段一 结束点 + * @param p3 线段二 开始点 + * @param p4 线段二 结束点 + */ + public static Point getIntersectPoint(Point p1, Point p2, Point p3, Point p4) { + + double A1 = p1.getY() - p2.getY(); + double B1 = p2.getX() - p1.getX(); + double C1 = A1 * p1.getX() + B1 * p1.getY(); + + double A2 = p3.getY() - p4.getY(); + double B2 = p4.getX() - p3.getX(); + double C2 = A2 * p3.getX() + B2 * p3.getY(); + + double det_k = A1 * B2 - A2 * B1; + + if (Math.abs(det_k) < 0.00001) { + return null; + } + + double a = B2 / det_k; + double b = -1 * B1 / det_k; + double c = -1 * A2 / det_k; + double d = A1 / det_k; + + double x = a * C1 + b * C2; + double y = c * C1 + d * C2; + + return new Point(x, y); + } + + /** + * 验证两条线有没有相交 + * + * @param segmentLatLonOne 线段1 + * @param segmentLatLonTwo 线段2 + * @return true 相交 + */ + public static boolean segIntersect(SegmentLatLon segmentLatLonOne, SegmentLatLon segmentLatLonTwo) { + //转换对象 + Point[] points = segmentLatLonToPoint(segmentLatLonOne, segmentLatLonTwo); + //验证两条线有没有相交 + return segIntersect(points[0], points[1], points[2], points[3]) > 0; + } + + /** + * 线段转换为点对象 + * + * @param segmentLatLonOne 线段一 + * @param segmentLatLonTwo 线段二 + * @return 点对象数组 + */ + private static Point[] segmentLatLonToPoint(SegmentLatLon segmentLatLonOne, SegmentLatLon segmentLatLonTwo) { + //线段1 + Double oneStartLat = segmentLatLonOne.getStartLatLon().getLat(); + Double oneStartLon = segmentLatLonOne.getStartLatLon().getLon(); + Double oneEndLat = segmentLatLonOne.getEndLatLon().getLat(); + Double oneEndLon = segmentLatLonOne.getEndLatLon().getLon(); + // 线段2 + Double twoStartLat = segmentLatLonTwo.getStartLatLon().getLat(); + Double twoStartLon = segmentLatLonTwo.getStartLatLon().getLon(); + Double twoEndLat = segmentLatLonTwo.getEndLatLon().getLat(); + Double twoEndLon = segmentLatLonTwo.getEndLatLon().getLon(); + Point[] points = new Point[4]; + //将经纬度转换成X和Y轴 + points[0] = millierConvertion(oneStartLat, oneStartLon); + points[1] = millierConvertion(oneEndLat, oneEndLon); + points[2] = millierConvertion(twoStartLat, twoStartLon); + points[3] = millierConvertion(twoEndLat, twoEndLon); + + return points; + } + + /** + * 验证两条线有没有相交 + * + * @param A 线段一 开始点 + * @param B 线段一 结束点 + * @param C 线段二 开始点 + * @param D 线段二 结束点 + * @return + */ + public static int segIntersect(Point A, Point B, Point C, Point D) { + Point intersection = new Point(); + + if (Math.abs(B.getY() - A.getY()) + Math.abs(B.getX() - A.getX()) + Math.abs(D.getY() - C.getY()) + + Math.abs(D.getX() - C.getX()) == 0) { + if ((C.getX() - A.getX()) + (C.getY() - A.getY()) == 0) { + log.warn("ABCD是同一个点!"); + } else { + log.warn("AB是一个点,CD是一个点,且AC不同!"); + } + return 0; + } + + if (Math.abs(B.getY() - A.getY()) + Math.abs(B.getX() - A.getX()) == 0) { + if ((A.getX() - D.getX()) * (C.getY() - D.getY()) - (A.getY() - D.getY()) * (C.getX() - D.getX()) == 0) { + log.warn("A、B是一个点,且在CD线段上!"); + } else { + log.warn("A、B是一个点,且不在CD线段上!"); + } + return 0; + } + if (Math.abs(D.getY() - C.getY()) + Math.abs(D.getX() - C.getX()) == 0) { + if ((D.getX() - B.getX()) * (A.getY() - B.getY()) - (D.getY() - B.getY()) * (A.getX() - B.getX()) == 0) { + log.warn("C、D是一个点,且在AB线段上!"); + } else { + log.warn("C、D是一个点,且不在AB线段上!"); + } + return 0; + } + + if ((B.getY() - A.getY()) * (C.getX() - D.getX()) - (B.getX() - A.getX()) * (C.getY() - D.getY()) == 0) { + log.warn("线段平行,无交点!"); + return 0; + } + + intersection + .setX(((B.getX() - A.getX()) * (C.getX() - D.getX()) + * (C.getY() - A.getY()) - C.getX() + * (B.getX() - A.getX()) * (C.getY() - D.getY()) + A + .getX() * (B.getY() - A.getY()) * (C.getX() - D.getX())) + / ((B.getY() - A.getY()) * (C.getX() - D.getX()) - (B + .getX() - A.getX()) * (C.getY() - D.getY()))); + intersection + .setY(((B.getY() - A.getY()) * (C.getY() - D.getY()) + * (C.getX() - A.getX()) - C.getY() + * (B.getY() - A.getY()) * (C.getX() - D.getX()) + A + .getY() * (B.getX() - A.getX()) * (C.getY() - D.getY())) + / ((B.getX() - A.getX()) * (C.getY() - D.getY()) - (B + .getY() - A.getY()) * (C.getX() - D.getX()))); + + if ((intersection.getX() - A.getX()) * (intersection.getX() - B.getX()) <= 0 + && (intersection.getX() - C.getX()) + * (intersection.getX() - D.getX()) <= 0 + && (intersection.getY() - A.getY()) + * (intersection.getY() - B.getY()) <= 0 + && (intersection.getY() - C.getY()) + * (intersection.getY() - D.getY()) <= 0) { + + if ((A.getX() == C.getX() && A.getY() == C.getY()) || (A.getX() == D.getX() && A.getY() == D.getY()) + || (B.getX() == C.getX() && B.getY() == C.getY()) || (B.getX() == D.getX() && B.getY() == D.getY())) { + + log.warn("线段相交于端点上"); + return 2; + } else { + //相交 + return 1; + } + } else { + log.warn("线段相交于虚交点(" + intersection.getX() + "," + intersection.getY() + ")"); + //相交但不在线段上 + return -1; + } + } + + /** + * 点对象 + */ + public static class Point { + private double x; + private double y; + + public Point() { + } + + public Point(double x, double y) { + this.x = x; + this.y = y; + } + + @Override + public String toString() { + return x + "," + y; + } + + public double getX() { + return x; + } + + public void setX(double x) { + this.x = x; + } + + public double getY() { + return y; + } + + public void setY(double y) { + this.y = y; + } + } + + /** + * @program: Wys + * @description 经纬度实体 + * @author: wys + * @create: 2020-11-26 10:44 + **/ + public static class LatLon { + + /** + * 经度 + */ + private Double lon; + + /** + * 纬度 + */ + private Double lat; + + public LatLon() { + } + + public LatLon(Double lon, Double lat) { + this.lon = lon; + this.lat = lat; + log.info(String.valueOf(lon) + String.valueOf(lat)); + } + + public Double getLon() { + return lon; + } + + public void setLon(Double lon) { + this.lon = lon; + } + + public Double getLat() { + return lat; + } + + public void setLat(Double lat) { + this.lat = lat; + } + + @Override + public String toString() { + return lon + "," + lat; + } + } + + /** + * @program: Wys + * @description 线段坐标实体 + * @author: wys + * @create: 2020-11-27 10:44 + **/ + public static class SegmentLatLon { + /** + * 开始点的坐标 + */ + private LatLon startLatLon; + /** + * 结束点的坐标 + */ + private LatLon endLatLon; + + public SegmentLatLon(LatLon startLatLon, LatLon endLatLon) { + this.startLatLon = startLatLon; + this.endLatLon = endLatLon; + } + + public SegmentLatLon() { + } + + public LatLon getStartLatLon() { + return startLatLon; + } + + public void setStartLatLon(LatLon startLatLon) { + this.startLatLon = startLatLon; + } + + public LatLon getEndLatLon() { + return endLatLon; + } + + public void setEndLatLon(LatLon endLatLon) { + this.endLatLon = endLatLon; + } + } + + public static void main(String[] args) { + SegmentLatLon LatLonOne = new SegmentLatLon();//线段一 + LatLonOne.setStartLatLon(new LatLon(117.23756, 31.8047)); + LatLonOne.setEndLatLon(new LatLon(117.236945, 31.803893)); + + SegmentLatLon LatLonTwo = new SegmentLatLon();//线段二 + LatLonTwo.setStartLatLon(new LatLon(117.237103, 31.804627)); + LatLonTwo.setEndLatLon(new LatLon(117.237692, 31.804319)); + + //交点坐标(延长线相交不算) + LatLon intersectPoint = GEOIntersectPointUtils.getIntersectPoint(LatLonOne, LatLonTwo); + if (intersectPoint != null) { + System.out.println("线段相交于点(" + intersectPoint.getLon() + "," + intersectPoint.getLat() + ")"); + } + + } + +} diff --git a/src/main/java/com/zgx/iot/utils/GEOUtils.java b/src/main/java/com/zgx/iot/utils/GEOUtils.java new file mode 100644 index 0000000..28892ec --- /dev/null +++ b/src/main/java/com/zgx/iot/utils/GEOUtils.java @@ -0,0 +1,322 @@ +package com.zgx.iot.utils; + +import org.gavaghan.geodesy.Ellipsoid; +import org.gavaghan.geodesy.GeodeticCalculator; +import org.gavaghan.geodesy.GeodeticCurve; +import org.gavaghan.geodesy.GlobalCoordinates; + +import java.awt.geom.Point2D; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.util.List; + +import static com.zgx.iot.utils.GEOIntersectPointUtils.millierConvertion; +import static com.zgx.iot.utils.GEOIntersectPointUtils.xyToLatLon; + +/** + * 计算经纬度工具类 + */ +public class GEOUtils { + //平均半径(单位m),不是赤道半径,赤道为6378左右 + public static final double EARTH_RADIUS = 6371e3; + //格式化 + private static final DecimalFormat df = new DecimalFormat("0.000000"); + + + /** + * @param lon1 第一点的精度 + * @param lat1 第一点的纬度 + * @param lon2 第二点的精度 + * @param lat2 第二点的纬度 + * @return 返回的距离,单位m + */ + public static double GetDistance(double lon1, double lat1, double lon2, double lat2) { + GlobalCoordinates source = new GlobalCoordinates(lat1, lon1); + GlobalCoordinates target = new GlobalCoordinates(lat2, lon2); + + double meter = getDistanceMeter(source, target, Ellipsoid.WGS84); + return meter; + } + + + public static double getDistanceMeter(GlobalCoordinates gpsFrom, GlobalCoordinates gpsTo, Ellipsoid ellipsoid) { + //创建GeodeticCalculator,调用计算方法,传入坐标系、经纬度用于计算距离 + GeodeticCurve geoCurve = new GeodeticCalculator().calculateGeodeticCurve(ellipsoid, gpsFrom, gpsTo); + return geoCurve.getEllipsoidalDistance(); + } + + /** + * 以(lon1,lat1)为固定点,计算(lon2,lat2)的位置 + * 正北为y轴,东为x轴 + * + * @param lat1 固定点经度 + * @param lon1 固定点纬度 + * @param lat2 目标经度 + * @param lon2 目标纬度 + * @return + */ + public static double position(double lon1, double lat1, double lon2, double lat2) { + double longitude1 = lon1; + double longitude2 = lon2; + double latitude1 = Math.toRadians(lat1); + double latitude2 = Math.toRadians(lat2); + double longDiff = Math.toRadians(longitude2 - longitude1); + double y = Math.sin(longDiff) * Math.cos(latitude2); + double x = Math.cos(latitude1) * Math.sin(latitude2) - Math.sin(latitude1) * Math.cos(latitude2) * Math.cos(longDiff); + return (Math.toDegrees(Math.atan2(y, x)) + 360) % 360; + } + + + /** + * 已知直角三角形的两直边长度 + * 计算上角度(直线b所对应的角度) + */ + public static double upAngle(double a, double b) { + double c = Math.sqrt(a * a + b * b); + double angle = Math.toDegrees(Math.acos((a * a + c * c - b * b) / (2.0 * a * c))); + BigDecimal bg = new BigDecimal(angle); + return bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(); + } + + /** + * 根据一点的坐标,角度,距离,计算另外一点的位置 + * + * @param startLong 起始点经度 + * @param startLat 起始点纬度 + * @param angle 角度,从正北顺时针方向开始计算 + * @param distance 距离,单位m + * @return + */ + public static GEOIntersectPointUtils.LatLon getLocationByLocationAndAngleAndDistance(double startLong, double startLat, double angle, double distance) { + //将距离转换成经度的计算公式 + double δ = distance / EARTH_RADIUS; + // 转换为radian,否则结果会不正确 + angle = Math.toRadians(angle); + startLong = Math.toRadians(startLong); + startLat = Math.toRadians(startLat); + double lat = Math.asin(Math.sin(startLat) * Math.cos(δ) + Math.cos(startLat) * Math.sin(δ) * Math.cos(angle)); + double lon = startLong + Math.atan2(Math.sin(angle) * Math.sin(δ) * Math.cos(startLat), Math.cos(δ) - Math.sin(startLat) * Math.sin(lat)); + // 转为正常的10进制经纬度 + lon = Math.toDegrees(lon); + lat = Math.toDegrees(lat); +// String[] result = new String[2]; +// result[0] = df.format(lon); +// result[1] = df.format(lat); + return new GEOIntersectPointUtils.LatLon(new BigDecimal(lon).setScale(6, BigDecimal.ROUND_HALF_UP).doubleValue(), new BigDecimal(lat).setScale(6, BigDecimal.ROUND_HALF_UP).doubleValue()); + } + + + /** + * 经纬度方位角计算(该方法在某些方向上计算结果有问题,弃用!) + * + * @param lat_a 起点纬度 + * @param lng_a 起点经度 + * @param lat_b 终点纬度 + * @param lng_b 终点经度 + * @return 方位角度数 + */ + public static double azimuth(double lat_a, double lng_a, double lat_b, double lng_b) { + double d = 0; + lat_a = lat_a * Math.PI / 180; + lng_a = lng_a * Math.PI / 180; + lat_b = lat_b * Math.PI / 180; + lng_b = lng_b * Math.PI / 180; + d = Math.sin(lat_a) * Math.sin(lat_b) + Math.cos(lat_a) * Math.cos(lat_b) * Math.cos(lng_b - lng_a); + d = Math.sqrt(1 - d * d); + d = Math.cos(lat_b) * Math.sin(lng_b - lng_a) / d; + d = Math.asin(d) * 180 / Math.PI; + return d; + } + + /** + * 根据2个经纬度点计算方位角(注意先后顺序会导致方向不一样) + * + * @param lon1 第一点的经度 + * @param lat1 第一点的纬度 + * @param lon2 第二点的经度 + * @param lat2 第二点的纬度 + * @return 方位角度数 + */ + public static double getAzimuth(double lon1, double lat1, double lon2, double lat2) { + double RAD_ANGLE = 180 / Math.PI; + //四个轴上 + if (lon2 == lon1) { + if (lat2 >= lat1) + return 0; + else + return 180; + } + if (lat1 == lat2) { + if (lon2 >= lon1) + return 90; + else + return 270; + } + + lon1 = lon1 / RAD_ANGLE; + lon2 = lon2 / RAD_ANGLE; + lat1 = lat1 / RAD_ANGLE; + lat2 = lat2 / RAD_ANGLE; + + double cosinc = Math.sin(lat2) * Math.sin(lat1) + Math.cos(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1); + double sinc = Math.sqrt(1 - cosinc * cosinc); + double sina = Math.cos(lat2) * Math.sin(lon2 - lon1) / sinc; + double a = Math.asin(sina) * RAD_ANGLE; + //假设A点固定于原点,B点在第一象限,Azimuth=A; + //B在第二象限,Azimuth=360+A; + //B在第三四象限,Azimuth=180-A。 + if (lon2 - lon1 > 0 && lat2 - lat1 > 0) + return a; + if (lon2 - lon1 < 0 && lat2 - lat1 > 0) + return 360 + a; + else + return 180 - a; + } + + /** + * 计算两个经纬度之间的距离 + * + * @param lon1 第一点的经度 + * @param lat1 第一点的纬度 + * @param lon2 第二点的经度 + * @param lat2 第二点的纬度 + * @return 返回距离,单位m + */ + public static double getDistance(double lon1, double lat1, double lon2, double lat2) { + // 经纬度(角度)转弧度。弧度用作参数,以调用Math.cos和Math.sin + double radiansAX = Math.toRadians(lon1); // A经弧度 + double radiansAY = Math.toRadians(lat1); // A纬弧度 + double radiansBX = Math.toRadians(lon2); // B经弧度 + double radiansBY = Math.toRadians(lat2); // B纬弧度 + + // 公式中“cosβ1cosβ2cos(α1-α2)+sinβ1sinβ2”的部分,得到∠AOB的cos值 + double cos = Math.cos(radiansAY) * Math.cos(radiansBY) * Math.cos(radiansAX - radiansBX) + + Math.sin(radiansAY) * Math.sin(radiansBY); + double acos = Math.acos(cos); // 反余弦值 + return EARTH_RADIUS * acos; + } + + /** + * 判断点是否在多边形内 + * + * @param point 目标点 + * @param pts 多边形的点(需有顺序地按顺时针或逆时针) + * @return boolean + */ + public static boolean isInPolygon(Point2D.Double point, List pts) { + int N = pts.size(); + boolean boundOrVertex = true; + int intersectCount = 0;//交叉点数量 + double precision = 2e-10; //浮点类型计算时候与0比较时候的容差 + Point2D.Double p1, p2;//临近顶点 + Point2D.Double p = point; //当前点 + + p1 = pts.get(0); + for (int i = 1; i <= N; ++i) { + if (p.equals(p1)) { + return boundOrVertex; + } + + p2 = pts.get(i % N); + if (p.x < Math.min(p1.x, p2.x) || p.x > Math.max(p1.x, p2.x)) { + p1 = p2; + continue; + } + + //射线穿过算法 + if (p.x > Math.min(p1.x, p2.x) && p.x < Math.max(p1.x, p2.x)) { + if (p.y <= Math.max(p1.y, p2.y)) { + if (p1.x == p2.x && p.y >= Math.min(p1.y, p2.y)) { + return boundOrVertex; + } + + if (p1.y == p2.y) { + if (p1.y == p.y) { + return boundOrVertex; + } else { + ++intersectCount; + } + } else { + double xinters = (p.x - p1.x) * (p2.y - p1.y) / (p2.x - p1.x) + p1.y; + if (Math.abs(p.y - xinters) < precision) { + return boundOrVertex; + } + + if (p.y < xinters) { + ++intersectCount; + } + } + } + } else { + if (p.x == p2.x && p.y <= p2.y) { + Point2D.Double p3 = pts.get((i + 1) % N); + if (p.x >= Math.min(p1.x, p3.x) && p.x <= Math.max(p1.x, p3.x)) { + ++intersectCount; + } else { + intersectCount += 2; + } + } + } + p1 = p2; + } + if (intersectCount % 2 == 0) {//偶数在多边形外 + return false; + } else { //奇数在多边形内 + return true; + } + } + + /** + * 计算2个经纬度点的中点 + * + * @param lon1 + * @param lat1 + * @param lon2 + * @param lat2 + * @return + */ + public static GEOIntersectPointUtils.LatLon getMidPoint(double lon1, double lat1, double lon2, double lat2) { + GEOIntersectPointUtils.Point point = millierConvertion(lat1, lon1); + GEOIntersectPointUtils.Point point2 = millierConvertion(lat2, lon2); + GEOIntersectPointUtils.Point point3 = new GEOIntersectPointUtils.Point((point.getX() + point2.getX()) / 2, (point.getY() + point2.getY()) / 2); + GEOIntersectPointUtils.LatLon latLon = xyToLatLon(point3.getX(), point3.getY()); + latLon.setLon(new BigDecimal(latLon.getLon()).setScale(6, BigDecimal.ROUND_HALF_UP).doubleValue()); + latLon.setLat(new BigDecimal(latLon.getLat()).setScale(6, BigDecimal.ROUND_HALF_UP).doubleValue()); + return latLon; + } + + + public static void main(String[] args) { + /* System.out.println(getLocationByLocationAndAngleAndDistance(117.220661, 31.813009, 89.2, 20)); + System.out.println(getDistance(86.728421, 48.658950, 86.725752, 48.658587)); + System.out.println(getAzimuth(86.728421, 48.658950, 86.725752, 48.658587)); + System.out.println(GetMidPoint(117.220661, 31.813009, 117.221084, 31.813015)); + */ + +// System.out.println((float) Math.sin(Math.toRadians(30))); +// System.out.println(Math.cos(Math.toRadians(60))); +// System.out.println(Math.toDegrees(Math.asin(0.5))); +// System.out.println(Math.toDegrees(Math.acos(0.5))); +// System.out.println((int) Math.ceil((double) 106.00000 / 40)); + + /*Point2D.Double point = new Point2D.Double(); + point.setLocation(86.729527,48.654794);//内 + point.setLocation(86.729529,48.654835);//边 + point.setLocation(86.729319, 48.655331);//外 + List pts = new ArrayList<>(); + Point2D.Double point1 = new Point2D.Double(); + point1.setLocation(86.726081, 48.654102); + Point2D.Double point2 = new Point2D.Double(); + point2.setLocation(86.732653, 48.655502); + Point2D.Double point3 = new Point2D.Double(); + point3.setLocation(86.734964, 48.653977); + Point2D.Double point4 = new Point2D.Double(); + point4.setLocation(86.726157, 48.650518); + pts.add(point1); + pts.add(point2); + pts.add(point3); + pts.add(point4); + boolean inPolygon = isInPolygon(point, pts); + System.out.println(inPolygon);*/ + } +} diff --git a/src/main/java/com/zgx/iot/utils/JacksonUtil.java b/src/main/java/com/zgx/iot/utils/JacksonUtil.java new file mode 100644 index 0000000..5c6c379 --- /dev/null +++ b/src/main/java/com/zgx/iot/utils/JacksonUtil.java @@ -0,0 +1,146 @@ +package com.zgx.iot.utils; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.xml.XmlMapper; + +import java.io.IOException; + +/** + * Jackson 工具类 + * + * @author AaGMixW + */ +public class JacksonUtil { + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final XmlMapper OBJECT_MAPPER_XML = new XmlMapper(); + + static { + //忽略在json字符串中存在,但是在java对象中不存在对应属性的情况。防止错误 + OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + } + + private JacksonUtil() { + throw new AssertionError(); + } + + /** + * instance + * + * @return jackson ObjectMapper + */ + public static ObjectMapper getInstance() { + return OBJECT_MAPPER; + } + + /** + * instance xml + * + * @return jackson ObjectMapper + */ + public static ObjectMapper getObjectMapperXml() { + return OBJECT_MAPPER_XML; + } + + /** + * 对象转 json 字符串 + * + * @param obj 需要转换的对象 + * @return json 字符串 + * @throws JsonProcessingException jackson 异常 + */ + public static String obj2json(Object obj) throws JsonProcessingException { + return OBJECT_MAPPER.writeValueAsString(obj); + } + + /** + * @param json 需要转换的字符串 + * @param type 自定义class对象 + * @param 自定义对象 + * @return 自定义对象 + * @throws JsonProcessingException jackson 异常 + */ + public static T json2Obj(String json, Class type) throws JsonProcessingException { + return OBJECT_MAPPER.readValue(json, type); + } + + /** + * @param json 需要转换的字符串 + * @param type TypeReference 自定义class类型 + * @param 自定义对象 + * @return 自定义对象 + * @throws JsonProcessingException jackson 异常 + */ + public static T json2Obj(String json, TypeReference type) throws JsonProcessingException { + return OBJECT_MAPPER.readValue(json, type); + } + + /** + * json to obj + * + * @param jsonNode jsonNode + * @param type class + * @param class type + * @return T + * @throws JsonProcessingException jackson 异常 + */ + public static T json2Obj(JsonNode jsonNode, Class type) throws JsonProcessingException { + return OBJECT_MAPPER.treeToValue(jsonNode, type); + } + + public static T json2Obj(JsonNode jsonNode, TypeReference type) throws IOException { + return OBJECT_MAPPER.readValue(OBJECT_MAPPER.treeAsTokens(jsonNode), type); + } + + /** + * json to string + * + * @param jsonNode jsonNode + * @return string + * @throws JsonProcessingException jackson 异常 + */ + public static String json2str(JsonNode jsonNode) throws JsonProcessingException { + return OBJECT_MAPPER.writeValueAsString(jsonNode); + } + + /* xml function */ + + /** + * xml to obj + * + * @param xml xml + * @param type class + * @param class type + * @return T + * @throws JsonProcessingException jackson 异常 + */ + public static T xml2Obj(String xml, Class type) throws JsonProcessingException { + return OBJECT_MAPPER_XML.readValue(xml, type); + } + + /** + * 对象转 xml 字符串 + * + * @param obj 需要转换的对象 + * @return json 字符串 + * @throws JsonProcessingException jackson 异常 + */ + public static String obj2xml(Object obj) throws JsonProcessingException { + return OBJECT_MAPPER_XML.writeValueAsString(obj); + } + + /** + * xml to jsonNode + * + * @param xml xml string + * @return jsonNode + * @throws JsonProcessingException jackson 异常 + */ + public static JsonNode xml2JsonNode(String xml) throws JsonProcessingException { + return OBJECT_MAPPER_XML.readTree(xml); + } + +} diff --git a/src/main/java/com/zgx/iot/utils/MD5Util.java b/src/main/java/com/zgx/iot/utils/MD5Util.java new file mode 100644 index 0000000..bae6d0b --- /dev/null +++ b/src/main/java/com/zgx/iot/utils/MD5Util.java @@ -0,0 +1,43 @@ +package com.zgx.iot.utils; + +import java.security.MessageDigest; + +public class MD5Util { + + public static String byteArrayToHexString(byte b[]) { + StringBuffer resultSb = new StringBuffer(); + for (int i = 0; i < b.length; i++) { + resultSb.append(byteToHexString(b[i])); + } + return resultSb.toString(); + } + + private static String byteToHexString(byte b) { + int n = b; + if (n < 0) { + n += 256; + } + int d1 = n / 16; + int d2 = n % 16; + return hexDigits[d1] + hexDigits[d2]; + } + + public static String MD5Encode(String origin, String charsetname) { + String resultString = null; + try { + resultString = new String(origin); + MessageDigest md = MessageDigest.getInstance("MD5"); + if (charsetname == null || "".equals(charsetname)) { + resultString = byteArrayToHexString(md.digest(resultString.getBytes())); + } else { + resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname))); + } + } catch (Exception exception) { + } + return resultString; + } + + private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5", + "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}; + +} diff --git a/src/main/java/com/zgx/iot/utils/NettyConfigUtil.java b/src/main/java/com/zgx/iot/utils/NettyConfigUtil.java new file mode 100644 index 0000000..618199e --- /dev/null +++ b/src/main/java/com/zgx/iot/utils/NettyConfigUtil.java @@ -0,0 +1,30 @@ +package com.zgx.iot.utils; + + +import com.zgx.iot.netty.config.AppServiceConfig; +import org.springframework.context.ApplicationContext; + +/** + * @author AaGMixW + */ +public class NettyConfigUtil { + + private static final AppServiceConfig APP_SERVICE_CONFIG; + + static { + ApplicationContext context = SpringContextUtils.getApplicationContext(); + if (context != null) { + APP_SERVICE_CONFIG = context.getBean(AppServiceConfig.class); + } else { + throw new IllegalStateException("set config error"); + } + } + + private NettyConfigUtil() { + throw new IllegalStateException("Utility class"); + } + + public static AppServiceConfig getAppServiceConfig() { + return APP_SERVICE_CONFIG; + } +} diff --git a/src/main/java/com/zgx/iot/utils/NettyDeviceUtil.java b/src/main/java/com/zgx/iot/utils/NettyDeviceUtil.java new file mode 100644 index 0000000..03359b7 --- /dev/null +++ b/src/main/java/com/zgx/iot/utils/NettyDeviceUtil.java @@ -0,0 +1,36 @@ +package com.zgx.iot.utils; + + +import com.zgx.iot.netty.constant.AttributeMapConstant; +import com.zgx.iot.netty.socket.base.NettyBaseSocket; +import io.netty.channel.ChannelHandlerContext; +import io.netty.util.NetUtil; + + +import java.net.InetSocketAddress; + +/** + * @author AaGMixW + */ +public class NettyDeviceUtil { + private NettyDeviceUtil() { + throw new IllegalStateException("Utility class"); + } + + public static String getDeviceNameAndIp(ChannelHandlerContext ctx, InetSocketAddress address) { + NettyBaseSocket socket = ctx.channel().attr(AttributeMapConstant.NETTY_CHANNEL_SOCKET_KEY).get(); + String addressStr = NetUtil.toSocketAddressString(address); + return socket.getDeviceInfo().getDeviceName() + "(" + addressStr + ")"; + } + + public static String getDeviceNameAndIp( + ChannelHandlerContext ctx, + InetSocketAddress localAddress, + InetSocketAddress remoteAddress + ) { + NettyBaseSocket socket = ctx.channel().attr(AttributeMapConstant.NETTY_CHANNEL_SOCKET_KEY).get(); + String localAddressStr = NetUtil.toSocketAddressString(localAddress); + String remoteAddressStr = NetUtil.toSocketAddressString(remoteAddress); + return socket.getDeviceInfo().getDeviceName() + "(L: " + localAddressStr + ", R: " + remoteAddressStr + ")"; + } +} diff --git a/src/main/java/com/zgx/iot/utils/NumConvertUtil.java b/src/main/java/com/zgx/iot/utils/NumConvertUtil.java new file mode 100644 index 0000000..1e64e04 --- /dev/null +++ b/src/main/java/com/zgx/iot/utils/NumConvertUtil.java @@ -0,0 +1,198 @@ +package com.zgx.iot.utils; + +import java.nio.ByteBuffer; +import java.util.zip.CRC32; + +/** + * @Description: 数据类型转换工具类 + * @Author: bb + * @Date: 2022-08-02 + */ +public class NumConvertUtil { + + /** + * byte数组转hex + * + * @param bytes + * @return + */ + public static String byteToHex(byte[] bytes) { + String strHex = ""; + StringBuilder sb = new StringBuilder(""); + for (int n = 0; n < bytes.length; n++) { + strHex = Integer.toHexString(bytes[n] & 0xFF); + sb.append((strHex.length() == 1) ? "0" + strHex : strHex); // 每个字节由两个字符表示,位数不够,高位补0 + } + return sb.toString().trim(); + } + + /** + * hex转byte数组 + * + * @param hex + * @return + */ + public static byte[] hexToByte(String hex) { + int m = 0, n = 0; + int byteLen = hex.length() / 2; // 每两个字符描述一个字节 + byte[] ret = new byte[byteLen]; + for (int i = 0; i < byteLen; i++) { + m = i * 2 + 1; + n = m + 1; + int intVal = Integer.decode("0x" + hex.substring(i * 2, m) + hex.substring(m, n)); + ret[i] = Byte.valueOf((byte) intVal); + } + return ret; + } + + /** + * byte数组转hex + * + * @param bytes + * @return + */ + public static String byteToHex(byte[] bytes, boolean separate) { + String strHex = ""; + StringBuilder sb = new StringBuilder(""); + for (int n = 0; n < bytes.length; n++) { + strHex = Integer.toHexString(bytes[n] & 0xFF); + sb.append((strHex.length() == 1) ? "0" + strHex : strHex); // 每个字节由两个字符表示,位数不够,高位补0 + } + String sbUpperCase = sb.toString().trim().toUpperCase(); + if (separate) { + return sbUpperCase.replaceAll("(.{2})", " $1").substring(1); + } + return sbUpperCase; + } + + /** + * 将int数值转换为占四个字节的byte数组,本方法适用于(低位在前,高位在后)的顺序 + * + * @param value 要转换的int值 + * @return byte数组 + */ + public static byte[] intToBytes(int value) { + byte[] src = new byte[4]; + src[3] = (byte) ((value >> 24) & 0xFF); + src[2] = (byte) ((value >> 16) & 0xFF); + src[1] = (byte) ((value >> 8) & 0xFF); + src[0] = (byte) (value & 0xFF); + return src; + } + + /** + * byte数组转int + * + * @param src + * @return + */ + public static int byteToInt(byte[] src) { + int value = 0; + for (int i = 0; i < src.length; i++) { + value += (src[i] & 0xff) << i * 8; + } + return value; + } + + /** + * 数组合并 + * + * @param bt1 + * @param bt2 + * @return + */ + public static byte[] byteMerger(byte[] bt1, byte[] bt2) { + byte[] bt3 = new byte[bt1.length + bt2.length]; + System.arraycopy(bt1, 0, bt3, 0, bt1.length); + System.arraycopy(bt2, 0, bt3, bt1.length, bt2.length); + return bt3; + } + + /** + * CRC32校验 + * + * @param b + * @return + */ + public static byte[] toCRC32(byte[] b) { + CRC32 crc = new CRC32(); + crc.update(b); + //取4位有效值 + byte[] crcByte = new byte[4]; + System.arraycopy(longToBytes(crc.getValue()), 4, crcByte, 0, 4); + return crcByte; + } + + /** + * long转byte数组 + * + * @param x + * @return + */ + public static byte[] longToBytes(long x) { + ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES); + buffer.putLong(x); + return buffer.array(); + } + + /** + * byte数组转long + * + * @param bytes + * @return + */ + public static long bytesToLong(byte[] bytes) { + ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES); + buffer.put(bytes); + buffer.flip();//need flip + return buffer.getLong(); + } + + /** + * int转字节16进制数组 + * + * @param i + * @return + */ + public static byte[] intToByte(int i) { + int byte1 = i & 0XFF; + int byte2 = (i & 0XFFFF) >>> 8; + int byte3 = (i & 0XFFFFFF) >>> 16; + int byte4 = (i & 0XFFFFFFFF) >>> 24; + return new byte[]{(byte) byte4, (byte) byte3, (byte) byte2, (byte) byte1}; + } + + /** + * 按" "分割字符串,获取下标 + * 例如 String s={00 00 00 0C} 获取第num个字符串 + * + * @return + */ + public static String getByte(String bytes, int num) { + String[] s = bytes.split(" "); + if (0 > num || num - 1 > s.length) { + return null; + } + return s[num - 1]; + } + + /** + * 16进制表示的字符串转换为字节数组 + * 返回的字节数组表示为十进制 + * + * @param hexString 16进制表示的字符串 + * @return byte[] 字节数组 + */ + public static byte[] hexStringToByteArray(String hexString) { + hexString = hexString.replaceAll(" ", ""); + int len = hexString.length(); + byte[] bytes = new byte[len / 2]; + for (int i = 0; i < len; i += 2) { + // 两位一组,表示一个字节,把这样表示的16进制字符串,还原成一个字节 + bytes[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + Character + .digit(hexString.charAt(i + 1), 16)); + } + return bytes; + } + +} diff --git a/src/main/java/com/zgx/iot/utils/RedisUtil.java b/src/main/java/com/zgx/iot/utils/RedisUtil.java new file mode 100644 index 0000000..7fd5059 --- /dev/null +++ b/src/main/java/com/zgx/iot/utils/RedisUtil.java @@ -0,0 +1,752 @@ +package com.zgx.iot.utils; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.geo.*; +import org.springframework.data.redis.connection.RedisGeoCommands; +import org.springframework.data.redis.core.*; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import javax.annotation.Resource; +import java.util.*; +import java.util.concurrent.TimeUnit; + +/** + * redis 工具类 + * + * @Author Scott + */ +@Component +public class RedisUtil { + + @Resource + private RedisTemplate redisTemplate; + @Autowired + private StringRedisTemplate stringRedisTemplate; + + /** + * 指定缓存失效时间 + * + * @param key 键 + * @param time 时间(秒) + * @return + */ + public boolean expire(String key, long time) { + try { + if (time > 0) { + redisTemplate.expire(key, time, TimeUnit.SECONDS); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 根据key 获取过期时间 + * + * @param key 键 不能为null + * @return 时间(秒) 返回0代表为永久有效 + */ + public long getExpire(String key) { + return redisTemplate.getExpire(key, TimeUnit.SECONDS); + } + + /** + * 判断key是否存在 + * + * @param key 键 + * @return true 存在 false不存在 + */ + public boolean hasKey(String key) { + try { + return redisTemplate.hasKey(key); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 删除缓存 + * + * @param key 可以传一个值 或多个 + */ + @SuppressWarnings("unchecked") + public void del(String... key) { + if (key != null && key.length > 0) { + if (key.length == 1) { + redisTemplate.delete(key[0]); + } else { + redisTemplate.delete((Collection) CollectionUtils.arrayToList(key)); + } + } + } + + // ============================String============================= + + /** + * 普通缓存获取 + * + * @param key 键 + * @return 值 + */ + public Object get(String key) { + return key == null ? null : redisTemplate.opsForValue().get(key); + } + + /** + * 普通缓存放入 + * + * @param key 键 + * @param value 值 + * @return true成功 false失败 + */ + public boolean set(String key, Object value) { + try { + redisTemplate.opsForValue().set(key, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + /** + * 普通缓存放入并设置时间 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 + * @return true成功 false 失败 + */ + public boolean set(String key, Object value, long time) { + try { + if (time > 0) { + redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); + } else { + set(key, value); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 递增 + * + * @param key 键 + * @return + */ + public long incr(String key, long delta) { + if (delta < 0) { + throw new RuntimeException("递增因子必须大于0"); + } + return redisTemplate.opsForValue().increment(key, delta); + } + + /** + * 递减 + * + * @param key 键 + * @return + */ + public long decr(String key, long delta) { + if (delta < 0) { + throw new RuntimeException("递减因子必须大于0"); + } + return redisTemplate.opsForValue().increment(key, -delta); + } + + // ================================Map================================= + + /** + * HashGet + * + * @param key 键 不能为null + * @param item 项 不能为null + * @return 值 + */ + public Object hget(String key, String item) { + return redisTemplate.opsForHash().get(key, item); + } + + /** + * 获取hashKey对应的所有键值 + * + * @param key 键 + * @return 对应的多个键值 + */ + public Map hmget(String key) { + return redisTemplate.opsForHash().entries(key); + } + + /** + * HashSet + * + * @param key 键 + * @param map 对应多个键值 + * @return true 成功 false 失败 + */ + public boolean hmset(String key, Map map) { + try { + redisTemplate.opsForHash().putAll(key, map); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * HashSet 并设置时间 + * + * @param key 键 + * @param map 对应多个键值 + * @param time 时间(秒) + * @return true成功 false失败 + */ + public boolean hmset(String key, Map map, long time) { + try { + redisTemplate.opsForHash().putAll(key, map); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 向一张hash表中放入数据,如果不存在将创建 + * + * @param key 键 + * @param item 项 + * @param value 值 + * @return true 成功 false失败 + */ + public boolean hset(String key, String item, Object value) { + try { + redisTemplate.opsForHash().put(key, item, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 向一张hash表中放入数据,如果不存在将创建 + * + * @param key 键 + * @param item 项 + * @param value 值 + * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 + * @return true 成功 false失败 + */ + public boolean hset(String key, String item, Object value, long time) { + try { + redisTemplate.opsForHash().put(key, item, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 删除hash表中的值 + * + * @param key 键 不能为null + * @param item 项 可以使多个 不能为null + */ + public void hdel(String key, Object... item) { + redisTemplate.opsForHash().delete(key, item); + } + + /** + * 判断hash表中是否有该项的值 + * + * @param key 键 不能为null + * @param item 项 不能为null + * @return true 存在 false不存在 + */ + public boolean hHasKey(String key, String item) { + return redisTemplate.opsForHash().hasKey(key, item); + } + + /** + * hash递增 如果不存在,就会创建一个 并把新增后的值返回 + * + * @param key 键 + * @param item 项 + * @param by 要增加几(大于0) + * @return + */ + public double hincr(String key, String item, double by) { + return redisTemplate.opsForHash().increment(key, item, by); + } + + /** + * hash递减 + * + * @param key 键 + * @param item 项 + * @param by 要减少记(小于0) + * @return + */ + public double hdecr(String key, String item, double by) { + return redisTemplate.opsForHash().increment(key, item, -by); + } + + // ============================set============================= + + /** + * 根据key获取Set中的所有值 + * + * @param key 键 + * @return + */ + public Set sGet(String key) { + try { + return redisTemplate.opsForSet().members(key); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 根据value从一个set中查询,是否存在 + * + * @param key 键 + * @param value 值 + * @return true 存在 false不存在 + */ + public boolean sHasKey(String key, Object value) { + try { + return redisTemplate.opsForSet().isMember(key, value); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 将数据放入set缓存 + * + * @param key 键 + * @param values 值 可以是多个 + * @return 成功个数 + */ + public long sSet(String key, Object... values) { + try { + return redisTemplate.opsForSet().add(key, values); + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 将set数据放入缓存 + * + * @param key 键 + * @param time 时间(秒) + * @param values 值 可以是多个 + * @return 成功个数 + */ + public long sSetAndTime(String key, long time, Object... values) { + try { + Long count = redisTemplate.opsForSet().add(key, values); + if (time > 0) { + expire(key, time); + } + return count; + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 获取set缓存的长度 + * + * @param key 键 + * @return + */ + public long sGetSetSize(String key) { + try { + return redisTemplate.opsForSet().size(key); + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 移除值为value的 + * + * @param key 键 + * @param values 值 可以是多个 + * @return 移除的个数 + */ + public long setRemove(String key, Object... values) { + try { + Long count = redisTemplate.opsForSet().remove(key, values); + return count; + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + // ===============================list================================= + + /** + * 获取list缓存的内容 + * + * @param key 键 + * @param start 开始 + * @param end 结束 0 到 -1代表所有值 + * @return + */ + public List lGet(String key, long start, long end) { + try { + return redisTemplate.opsForList().range(key, start, end); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 获取list缓存的长度 + * + * @param key 键 + * @return + */ + public long lGetListSize(String key) { + try { + return redisTemplate.opsForList().size(key); + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 通过索引 获取list中的值 + * + * @param key 键 + * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 + * @return + */ + public Object lGetIndex(String key, long index) { + try { + return redisTemplate.opsForList().index(key, index); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @return + */ + public boolean lSet(String key, Object value) { + try { + redisTemplate.opsForList().rightPush(key, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, Object value, long time) { + try { + redisTemplate.opsForList().rightPush(key, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @return + */ + public boolean lSet(String key, List value) { + try { + redisTemplate.opsForList().rightPushAll(key, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, List value, long time) { + try { + redisTemplate.opsForList().rightPushAll(key, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 根据索引修改list中的某条数据 + * + * @param key 键 + * @param index 索引 + * @param value 值 + * @return + */ + public boolean lUpdateIndex(String key, long index, Object value) { + try { + redisTemplate.opsForList().set(key, index, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 移除N个值为value + * + * @param key 键 + * @param count 移除多少个 + * @param value 值 + * @return 移除的个数 + */ + public long lRemove(String key, long count, Object value) { + try { + Long remove = redisTemplate.opsForList().remove(key, count, value); + return remove; + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 获取指定前缀的一系列key + * 使用scan命令代替keys, Redis是单线程处理,keys命令在KEY数量较多时, + * 操作效率极低【时间复杂度为O(N)】,该命令一旦执行会严重阻塞线上其它命令的正常请求 + * + * @param keyPrefix + * @return + */ +/* + public Set keys(String keyPrefix) { + String realKey = keyPrefix + "*"; + + try { + return redisTemplate.execute((RedisCallback>) connection -> { + Set binaryKeys = new HashSet<>(); + Cursor cursor = connection.scan(new ScanOptions.ScanOptionsBuilder().match(realKey).count(Integer.MAX_VALUE).build()); + while (cursor.hasNext()) { + binaryKeys.add(new String(cursor.next())); + } + + return binaryKeys; + }); + } catch (Throwable e) { + e.printStackTrace(); + } + + return null; + } +*/ + + /** + * 删除指定前缀的一系列key + * + * @param keyPrefix + */ +/* public void removeAll(String keyPrefix) { + try { + Set keys = keys(keyPrefix); + redisTemplate.delete(keys); + } catch (Throwable e) { + e.printStackTrace(); + } + }*/ + + /*** + * 将指定的地理空间位置(纬度、经度、名称)添加到指定的key中。 + * @param key redis的key + * @param longitude 经度 + * @param latitude 纬度 + * @param name 该坐标的名称(标识) + * @return + */ + public Long geoAdd(String key, double longitude, double latitude, String name) { +// Long addedNum = redisTemplate.opsForGeo().add("citygeo", new Point(116.405285, 39.904989), "beijing"); + Long addedNum = redisTemplate.opsForGeo().add(key, new Point(longitude, latitude), name); + return addedNum; + } + + /*** + * 从key里返回所有给定位置元素的位置(经度和纬度)。 + * @param key redis的key + */ + public List geoGet(String key, Object... ms) { + List points = redisTemplate.opsForGeo().position(key,ms); + return points; + } + + + /*** + * 【获取两个坐标之间的距离】 + * 根据redis中键名(key)中,名字为 name1 和 name2 两个坐标的距离 + * @param key redis的key + * @param name1 坐标名称(标识)1 + * @param name2 坐标名称(标识)2 + * @return distance(单位米) + */ + public double geoGetDistance(String key, String name1, String name2) { + double distance = redisTemplate.opsForGeo() + .distance(key, name1, name2, RedisGeoCommands.DistanceUnit.METERS).getValue(); + return distance; + } + + /*** + * 【获取指定范围内的坐标】 + * 以给定的经纬度为中心画圆, 返回键(key)包含的位置元素当中, + * 与中心的距离不超过给定最大距离的所有位置元素,并给出所有位置元素与中心的平均距离。 + * @param key redis的key + * @param longitude 经度 + * @param latitude 纬度 + * @param distance 距离(单位:米) + * @param count 如果 count > 0 则最多返回count个坐标, 否则返回所有 + * @return + */ + public GeoResults> geoGetCoordinatesWithinRange(String key, + double longitude, + double latitude, + Integer distance, + Integer count) { + //以当前坐标为中心画圆,标识当前坐标覆盖的distance的范围, Point(经度, 纬度) Distance(距离量, 距离单位) + Circle circle = new Circle(new Point(longitude, latitude), new Distance(distance, RedisGeoCommands.DistanceUnit.METERS)); + // 从redis获取的信息包含:距离中心坐标的距离、当前的坐标、并且升序排序,如果count > 0 则只取count个坐标,否则返回所有 + RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs + .newGeoRadiusArgs().includeDistance().includeCoordinates().sortAscending(); + if (count > 0) { + args.limit(count); + } + GeoResults> radius = redisTemplate.opsForGeo().radius(key, circle, args); + return radius; + } + + /*** + * 【获取指定范围内的坐标】 + * 以给定的键(key)中的坐标名字(标识)name为中心画圆, 返回键包含的位置元素当中, + * 与中心的距离不超过给定最大距离的所有位置元素,并给出所有位置元素与中心的平均距离。 + * @param key redis的key + * @param name 坐标名称(标识) + * @param distance 距离 + * @param count 如果 count > 0 则最多返回count个坐标, 否则返回所有 + * @return + */ + public GeoResults> geoGetCoordinatesWithinRange(String key, + String name, + Integer distance, + Integer count) { + // 创建距离对象 + Distance distances = new Distance(distance, RedisGeoCommands.DistanceUnit.METERS); + // 需要从redis获取的参数 + RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs + .newGeoRadiusArgs().includeDistance().includeCoordinates().sortAscending(); + if (count > 0) { + args.limit(count); + } + GeoResults> radius = redisTemplate.opsForGeo() + .radius(key, name, distances, args); + return radius; + } + + // ------------------ zSet 相关操作 ------------------ + + /** + * 添加元素,有序集合是按照元素的score值由小到大排列 + * + * @param key key + * @param value 值 + * @param score 权值 + * + * @return 是否成功 + */ + public Boolean zAdd(String key, String value, double score) { + return redisTemplate.opsForZSet().add(key, value, score); + } + + + /** + * 根据 Score 值查询集合元素, 从小到大排序 + * + * @param key key + * @param min 最小值 + * @param max 最大值 + * @return 值集合 + */ + public Set> zRangeByScoreWithScores(String key, + double min, double max) { + return redisTemplate.opsForZSet().rangeByScoreWithScores(key, min, max); + } + + /** + * 根据指定的score值的范围来移除成员 + * + * @param key key + * @param min 最小值 + * @param max 最大值 + * + * @return 剩余数量 + */ + public Long zRemoveRangeByScore(String key, double min, double max) { + return redisTemplate.opsForZSet().removeRangeByScore(key, min, max); + } +} diff --git a/src/main/java/com/zgx/iot/utils/SpringContextUtils.java b/src/main/java/com/zgx/iot/utils/SpringContextUtils.java new file mode 100644 index 0000000..4a1ef48 --- /dev/null +++ b/src/main/java/com/zgx/iot/utils/SpringContextUtils.java @@ -0,0 +1,65 @@ +package com.zgx.iot.utils; + + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + + +@Component +public class SpringContextUtils implements ApplicationContextAware { + + /** + * 上下文对象实例 + */ + private static ApplicationContext applicationContext; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + SpringContextUtils.applicationContext = applicationContext; + } + + /** + * 获取applicationContext + * + * @return + */ + public static ApplicationContext getApplicationContext() { + return applicationContext; + } + + + /** + * 通过name获取 Bean. + * + * @param name + * @return + */ + public static Object getBean(String name) { + return getApplicationContext().getBean(name); + } + + /** + * 通过class获取Bean. + * + * @param clazz + * @param + * @return + */ + public static T getBean(Class clazz) { + return getApplicationContext().getBean(clazz); + } + + /** + * 通过name,以及Clazz返回指定的Bean + * + * @param name + * @param clazz + * @param + * @return + */ + public static T getBean(String name, Class clazz) { + return getApplicationContext().getBean(name, clazz); + } +} diff --git a/src/main/java/com/zgx/iot/utils/SysDictUtil.java b/src/main/java/com/zgx/iot/utils/SysDictUtil.java new file mode 100644 index 0000000..80c89ec --- /dev/null +++ b/src/main/java/com/zgx/iot/utils/SysDictUtil.java @@ -0,0 +1,27 @@ +package com.zgx.iot.utils; + + + +import com.zgx.iot.dto.site.SysDictItem; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author AaGMixW + */ +public class SysDictUtil { + private SysDictUtil() { + throw new IllegalStateException("Utility class"); + } + + public static Map DictList2Map(List list) { + Map map = new HashMap<>(16); + for (SysDictItem sysDictItem : list) { + map.put(Integer.valueOf(sysDictItem.getItemValue()), sysDictItem.getDescription()); + } + return map; + } + +} diff --git a/src/main/java/com/zgx/iot/utils/hp/HPDataHandle.java b/src/main/java/com/zgx/iot/utils/hp/HPDataHandle.java new file mode 100644 index 0000000..f06168b --- /dev/null +++ b/src/main/java/com/zgx/iot/utils/hp/HPDataHandle.java @@ -0,0 +1,433 @@ +package com.zgx.iot.utils.hp; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.zgx.iot.constant.enums.FaultItem; +import com.zgx.iot.constant.enums.FaultResult; +import com.zgx.iot.entity.DtDeviceInfo; +import com.zgx.iot.entity.MsCameraSetting; +import com.zgx.iot.service.IDtDeviceInfoService; +import com.zgx.iot.utils.MD5Util; +import com.zgx.iot.utils.RedisUtil; +import com.zgx.iot.utils.socket.TcpClient; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import java.io.UnsupportedEncodingException; +import java.util.Date; +import java.util.List; + +/** + * 接收数据处理工具类 + * + * @Author: bb + * @Date: 2022-08-03 + */ +@Component +@Slf4j +public class HPDataHandle { + + @Autowired + private IDtDeviceInfoService ds; + @Autowired + private RedisUtil ru; + + private static IDtDeviceInfoService msDeviceInfoService; + private static RedisUtil redisUtil; + + @PostConstruct + public void init() { + msDeviceInfoService = ds; + redisUtil = ru; + } + + public static void deal2(byte[] data, TcpClient tcpClient) { + try { + //转成JSON对象 + JSONObject recvData = JSON.parseObject(new String(data, "UTF-8")); + if (recvData == null) { + return; + } + String cmd = recvData.getString("cmd"); + JSONObject param = recvData.getJSONObject("param"); + //log.info("HPDataHandle:cmd"+cmd); + switch (cmd) { + case "userSaltGet": + if (param.getInteger("ackvalue") == 100) { + List cameraList = redisUtil.lGet("cameraList", 0, -1); + for (Object o : cameraList) { + DtDeviceInfo deviceInfo = (DtDeviceInfo) o; + log.info("需要连接的光电数据:"+deviceInfo); + if (tcpClient.getIp().equals(deviceInfo.getDeviceIp())) { + //psw+salt 哈希32位小写 + String origin = deviceInfo.getPassword() + param.getString("salt"); + String psw = MD5Util.MD5Encode(origin, "utf-8"); + //设备登录 + tcpClient.send(HPDataParser.send(HPReqParamEnc.userLogin(deviceInfo.getUsername(), psw))); + } + } + } + break; + case "userLogin": + if (param.getInteger("ackvalue") == 100) { + log.info(tcpClient.getIp() + "===设备登陆成功"); + log.info("2---"+cmd+" param"+param.toString()); + redisUtil.set(tcpClient.getIp(), param.getString("token")); + } + break; + case "userOnlineHeart": + //心跳数据,更新设备心跳时间 + if (param.getInteger("ackvalue") == 100) { + List cameraList = redisUtil.lGet("cameraList", 0, -1); + for (Object o : cameraList) { + DtDeviceInfo deviceInfo = (DtDeviceInfo) o; + log.info("当前光电设备:"+deviceInfo.getDeviceIp()); + if (tcpClient.getIp().equals(deviceInfo.getDeviceIp())) { + msDeviceInfoService.update( + new UpdateWrapper().eq("id", deviceInfo.getId()).set("alive_time", new Date()) + ); + } + } + } + break; + case "PTZStatusReport": + //将云台PTZ状态放入缓存 + redisUtil.hset("PTZStatus", "pan", param.getDoubleValue("pan")); + redisUtil.hset("PTZStatus", "tilt", param.getDoubleValue("tilt")); + redisUtil.hset("PTZStatus", "ptRunState", param.getIntValue("ptRunState")); + break; + case "ivpReport": //todo : 智能分析上报消息 + //log.info(tcpClient.getIp() + "======" + new String(data, "UTF-8"));//todo : 先不打印 + JSONArray targets = param.getJSONArray("targets"); + for (int i = 0; i < targets.size(); i++) { + //检测到目标为人 + if (targets.getJSONObject(i).getIntValue("targetType") == 2) { + //将目标ID放入缓存,用來与雷达信息结合判断是否报警,有效期?分钟 + redisUtil.sSetAndTime(tcpClient.getIp() + "_cameraTrackTargetID", Integer.parseInt(redisUtil.hget("alarm_settings", "trackEffectTime").toString()), targets.getJSONObject(i).getIntValue("ID")); + + //todo : 注释的代码 + /*//暂时取第一个发现的目标,记录目标ID,有效时间60s + redisUtil.set(tcpClient.getIp() + "_trackTarget", targets.getJSONObject(i).getIntValue("ID"), 60); + //查询当前跟踪状态 + tcpClient.send( + HPDataParser.send( + HPReqParamEnc.ivpTrackingStatusGet(String.valueOf(redisUtil.get(tcpClient.getIp())), 0) + ) + );*/ + break; + //todo : 新增代码 检测到目标为船 + } else if (targets.getJSONObject(i).getIntValue("targetType") == 3) { + //log.info("2.接收到数据targets中的targetType=="+targets.getJSONObject(i).getIntValue("targetType")); + //将目标ID放入缓存,用來与雷达信息结合判断是否报警,有效期?分钟 + //redisUtil.sSetAndTime(tcpClient.getIp() + "_cameraTrackTargetID", Integer.parseInt(redisUtil.hget("alarm_settings", "trackEffectTime").toString()), targets.getJSONObject(i).getIntValue("ID")); + // todo : release-v2使用光电ai识别的第一个船只信息进行保存 并用与后续跟踪船只id跟踪使用 + //暂时取第一个发现的目标,记录目标ID,有效时间60s + redisUtil.set(tcpClient.getIp() + "_trackTarget", targets.getJSONObject(i).getIntValue("ID"), 60); + // todo : 是否要手动获取跟踪状态 + //查询当前跟踪状态 + tcpClient.send( + HPDataParser.send( + HPReqParamEnc.ivpTrackingStatusGet(String.valueOf(redisUtil.get(tcpClient.getIp())), 0) //获取目标跟踪状态 ivpTrackingStatusGet + ) + ); + break; + } + } + break; + case "ivpTrackingStatusGet": //todo : 获取目标跟踪状态 + //判断当前光电是否正在跟踪,否的话判断是否存在目标ID,有的话让其跟踪 + //log.info("3.ivpTrackingStatusGet:ackvalue="+param.getInteger("ackvalue").toString()); + if (param.getInteger("ackvalue") == 100) { + boolean bTracking = param.getBooleanValue("bTracking"); + if (bTracking) { + System.out.println("【正在跟踪...】"); + //log.info("正在跟踪..."); + //如果正在跟踪,判断当前是否已经丢失了目标 + tcpClient.send( + HPDataParser.send( + //todo : 获取智能分析结果 + HPReqParamEnc.ivpGetResult(String.valueOf(redisUtil.get(tcpClient.getIp())), 0, 14) + ) + ); + } else { + System.out.println("【当前不在跟踪状态】"); + //log.info("当前不在跟踪状态..."); + if (redisUtil.get(tcpClient.getIp() + "_trackTarget") != null) { + //System.out.println("跟踪目标ID" + Integer.parseInt(String.valueOf(redisUtil.get(tcpClient.getIp() + "_trackTarget")))); + //跟踪目标 + tcpClient.send( + HPDataParser.send( + //todo : 目标ID跟踪控制 + HPReqParamEnc.ivpTrackingTargetID(String.valueOf(redisUtil.get(tcpClient.getIp())), true, 0, Integer.parseInt(String.valueOf(redisUtil.get(tcpClient.getIp() + "_trackTarget")))) + ) + ); + } + } + } + break; + case "ivpGetResult": //todo : 获取智能分析结果 + if (param.getInteger("ackvalue") == 100) { + //若目标丢失了,则停止跟踪 + //System.out.println("【智能分析結果-】" + param.getJSONArray("targets")); + if (param.getJSONArray("targets").size() == 0) { + System.out.println("目标已经丢失,停止跟踪"); + tcpClient.send( + HPDataParser.send( + HPReqParamEnc.ivpTrackingCtrl(String.valueOf(redisUtil.get(tcpClient.getIp())), 0, false, null) + ) + ); + } + } + break; + //开始故障诊断 + case "FaultDiagnoseStart": + case "FaultDiagnoseStop": + if (param.getInteger("ackvalue") == 100) { + //每次开始或停止诊断清空之前的记录 + HPFaultResult.getInstance().status = 0; + HPFaultResult.getInstance().statusMax = 0; + HPFaultResult.getInstance().faultResult.clear(); + } + break; + //获取故障诊断结果 + case "FaultDiagnoseGetResult": + if (param.getInteger("ackvalue") == 100) { + if (HPFaultResult.getInstance().status == param.getIntValue("status")) { + break; + } + HPFaultResult.getInstance().status = param.getIntValue("status"); + HPFaultResult.getInstance().statusMax = param.getIntValue("statusMax"); + JSONArray diagInfo = param.getJSONArray("diagInfo"); + for (int i = 0; i < diagInfo.size(); i++) { + if (((i + 1) == FaultItem.N16.getCode() || (i + 1) == FaultItem.N17.getCode()) && (param.getIntValue("type") == 0)) { + HPFaultResult.getInstance().faultResult.put(FaultItem.getDesc(i + 1), FaultResult.UNDIAGNOSED.getDesc()); + continue; + } + String faultMsg = FaultResult.getDesc(diagInfo.getJSONObject(i).getIntValue("res")); + if (diagInfo.getJSONObject(i).getIntValue("res") == 1) { + faultMsg += diagInfo.getJSONObject(i).getString("errInfo"); + } + HPFaultResult.getInstance().faultResult.put(FaultItem.getDesc(i + 1), faultMsg); + } + } + break; + /*//云台自检状态上报消息 + case "ptNetParaState": + System.out.println("云台自检======" + new String(data, "UTF-8")); + break; + //可见光自检状态上报消息 + case "visibleLensState": + System.out.println("可见光自检======" + new String(data, "UTF-8")); + break; + //热像自检状态上报消息 + case "imgLensState": + System.out.println("热像自检======" + new String(data, "UTF-8")); + break;*/ + default: + break; + } + } catch (UnsupportedEncodingException e) { + log.error(e.getMessage(), e); + } catch (JSONException e) { + log.error("【json解析失败】" + e.getMessage(), e); + } + } + + public static void deal(byte[] data, TcpClient tcpClient) { + try { + //转成JSON对象 + JSONObject recvData = JSON.parseObject(new String(data, "UTF-8")); + if (recvData == null) { + return; + } + String cmd = recvData.getString("cmd"); + JSONObject param = recvData.getJSONObject("param"); + //log.info("HPDataHandle:cmd"+cmd); + switch (cmd) { + case "userSaltGet": + if (param.getInteger("ackvalue") == 100) { + List cameraList = redisUtil.lGet("cameraList", 0, -1); + for (Object o : cameraList) { + //DtDeviceInfo deviceInfo = (DtDeviceInfo) o; + MsCameraSetting deviceInfo = (MsCameraSetting) o; + log.info("需要连接的光电数据:"+deviceInfo); + if (tcpClient.getIp().equals(deviceInfo.getIp())) { + //psw+salt 哈希32位小写 + String origin = deviceInfo.getPassword() + param.getString("salt"); + String psw = MD5Util.MD5Encode(origin, "utf-8"); + //设备登录 + tcpClient.send(HPDataParser.send(HPReqParamEnc.userLogin(deviceInfo.getUser(), psw))); + } + } + } + break; + case "userLogin": + if (param.getInteger("ackvalue") == 100) { + log.info(tcpClient.getIp() + "===设备登陆成功"); + log.info("2---"+cmd+" param"+param.toString()); + redisUtil.set(tcpClient.getIp(), param.getString("token")); + } + break; + case "userOnlineHeart": + //心跳数据,更新设备心跳时间 + if (param.getInteger("ackvalue") == 100) { + List cameraList = redisUtil.lGet("cameraList", 0, -1); + for (Object o : cameraList) { + DtDeviceInfo deviceInfo = (DtDeviceInfo) o; + log.info("当前光电设备:"+deviceInfo.getDeviceIp()); + if (tcpClient.getIp().equals(deviceInfo.getDeviceIp())) { + msDeviceInfoService.update( + new UpdateWrapper().eq("id", deviceInfo.getId()).set("alive_time", new Date()) + ); + } + } + } + break; + case "PTZStatusReport": + //将云台PTZ状态放入缓存 + redisUtil.hset("PTZStatus", "pan", param.getDoubleValue("pan")); + redisUtil.hset("PTZStatus", "tilt", param.getDoubleValue("tilt")); + redisUtil.hset("PTZStatus", "ptRunState", param.getIntValue("ptRunState")); + break; + case "ivpReport": //todo : 智能分析上报消息 + //log.info(tcpClient.getIp() + "======" + new String(data, "UTF-8"));//todo : 先不打印 + JSONArray targets = param.getJSONArray("targets"); + for (int i = 0; i < targets.size(); i++) { + //检测到目标为人 + if (targets.getJSONObject(i).getIntValue("targetType") == 2) { + //将目标ID放入缓存,用來与雷达信息结合判断是否报警,有效期?分钟 + redisUtil.sSetAndTime(tcpClient.getIp() + "_cameraTrackTargetID", Integer.parseInt(redisUtil.hget("alarm_settings", "trackEffectTime").toString()), targets.getJSONObject(i).getIntValue("ID")); + + //todo : 注释的代码 + /*//暂时取第一个发现的目标,记录目标ID,有效时间60s + redisUtil.set(tcpClient.getIp() + "_trackTarget", targets.getJSONObject(i).getIntValue("ID"), 60); + //查询当前跟踪状态 + tcpClient.send( + HPDataParser.send( + HPReqParamEnc.ivpTrackingStatusGet(String.valueOf(redisUtil.get(tcpClient.getIp())), 0) + ) + );*/ + break; + //todo : 新增代码 检测到目标为船 + } else if (targets.getJSONObject(i).getIntValue("targetType") == 3) { + //log.info("2.接收到数据targets中的targetType=="+targets.getJSONObject(i).getIntValue("targetType")); + //将目标ID放入缓存,用來与雷达信息结合判断是否报警,有效期?分钟 + //redisUtil.sSetAndTime(tcpClient.getIp() + "_cameraTrackTargetID", Integer.parseInt(redisUtil.hget("alarm_settings", "trackEffectTime").toString()), targets.getJSONObject(i).getIntValue("ID")); + // todo : release-v2使用光电ai识别的第一个船只信息进行保存 并用与后续跟踪船只id跟踪使用 + //暂时取第一个发现的目标,记录目标ID,有效时间60s + redisUtil.set(tcpClient.getIp() + "_trackTarget", targets.getJSONObject(i).getIntValue("ID"), 60); + // todo : 是否要手动获取跟踪状态 + //查询当前跟踪状态 + tcpClient.send( + HPDataParser.send( + HPReqParamEnc.ivpTrackingStatusGet(String.valueOf(redisUtil.get(tcpClient.getIp())), 0) //获取目标跟踪状态 ivpTrackingStatusGet + ) + ); + break; + } + } + break; + case "ivpTrackingStatusGet": //todo : 获取目标跟踪状态 + //判断当前光电是否正在跟踪,否的话判断是否存在目标ID,有的话让其跟踪 + //log.info("3.ivpTrackingStatusGet:ackvalue="+param.getInteger("ackvalue").toString()); + if (param.getInteger("ackvalue") == 100) { + boolean bTracking = param.getBooleanValue("bTracking"); + if (bTracking) { + System.out.println("【正在跟踪...】"); + //log.info("正在跟踪..."); + //如果正在跟踪,判断当前是否已经丢失了目标 + tcpClient.send( + HPDataParser.send( + //todo : 获取智能分析结果 + HPReqParamEnc.ivpGetResult(String.valueOf(redisUtil.get(tcpClient.getIp())), 0, 14) + ) + ); + } else { + System.out.println("【当前不在跟踪状态】"); + //log.info("当前不在跟踪状态..."); + if (redisUtil.get(tcpClient.getIp() + "_trackTarget") != null) { + //System.out.println("跟踪目标ID" + Integer.parseInt(String.valueOf(redisUtil.get(tcpClient.getIp() + "_trackTarget")))); + //跟踪目标 + tcpClient.send( + HPDataParser.send( + //todo : 目标ID跟踪控制 + HPReqParamEnc.ivpTrackingTargetID(String.valueOf(redisUtil.get(tcpClient.getIp())), true, 0, Integer.parseInt(String.valueOf(redisUtil.get(tcpClient.getIp() + "_trackTarget")))) + ) + ); + } + } + } + break; + case "ivpGetResult": //todo : 获取智能分析结果 + if (param.getInteger("ackvalue") == 100) { + //若目标丢失了,则停止跟踪 + //System.out.println("【智能分析結果-】" + param.getJSONArray("targets")); + if (param.getJSONArray("targets").size() == 0) { + System.out.println("目标已经丢失,停止跟踪"); + tcpClient.send( + HPDataParser.send( + HPReqParamEnc.ivpTrackingCtrl(String.valueOf(redisUtil.get(tcpClient.getIp())), 0, false, null) + ) + ); + } + } + break; + //开始故障诊断 + case "FaultDiagnoseStart": + case "FaultDiagnoseStop": + if (param.getInteger("ackvalue") == 100) { + //每次开始或停止诊断清空之前的记录 + HPFaultResult.getInstance().status = 0; + HPFaultResult.getInstance().statusMax = 0; + HPFaultResult.getInstance().faultResult.clear(); + } + break; + //获取故障诊断结果 + case "FaultDiagnoseGetResult": + if (param.getInteger("ackvalue") == 100) { + if (HPFaultResult.getInstance().status == param.getIntValue("status")) { + break; + } + HPFaultResult.getInstance().status = param.getIntValue("status"); + HPFaultResult.getInstance().statusMax = param.getIntValue("statusMax"); + JSONArray diagInfo = param.getJSONArray("diagInfo"); + for (int i = 0; i < diagInfo.size(); i++) { + if (((i + 1) == FaultItem.N16.getCode() || (i + 1) == FaultItem.N17.getCode()) && (param.getIntValue("type") == 0)) { + HPFaultResult.getInstance().faultResult.put(FaultItem.getDesc(i + 1), FaultResult.UNDIAGNOSED.getDesc()); + continue; + } + String faultMsg = FaultResult.getDesc(diagInfo.getJSONObject(i).getIntValue("res")); + if (diagInfo.getJSONObject(i).getIntValue("res") == 1) { + faultMsg += diagInfo.getJSONObject(i).getString("errInfo"); + } + HPFaultResult.getInstance().faultResult.put(FaultItem.getDesc(i + 1), faultMsg); + } + } + break; + /*//云台自检状态上报消息 + case "ptNetParaState": + System.out.println("云台自检======" + new String(data, "UTF-8")); + break; + //可见光自检状态上报消息 + case "visibleLensState": + System.out.println("可见光自检======" + new String(data, "UTF-8")); + break; + //热像自检状态上报消息 + case "imgLensState": + System.out.println("热像自检======" + new String(data, "UTF-8")); + break;*/ + default: + break; + } + } catch (UnsupportedEncodingException e) { + log.error(e.getMessage(), e); + } catch (JSONException e) { + log.error("【json解析失败】" + e.getMessage(), e); + } + } +} diff --git a/src/main/java/com/zgx/iot/utils/hp/HPDataParser.java b/src/main/java/com/zgx/iot/utils/hp/HPDataParser.java new file mode 100644 index 0000000..3c9b5ed --- /dev/null +++ b/src/main/java/com/zgx/iot/utils/hp/HPDataParser.java @@ -0,0 +1,98 @@ +package com.zgx.iot.utils.hp; + + +import com.zgx.iot.utils.NumConvertUtil; +import com.zgx.iot.utils.socket.TcpClient; +import lombok.extern.slf4j.Slf4j; + +import java.io.UnsupportedEncodingException; + +/** + * 和普数据协议解析 + * + * @Author: bb + * @Date: 2022-08-02 + */ +@Slf4j +public class HPDataParser { + + //消息ID最大值 0xFFFFFFFF,超过则循环 + private static final long MaxId = 4294967295L; + //消息ID + private volatile static long mId = 1; + + /** + * 组装发送数据 + * + * @param msgJSON + * @return + * @throws UnsupportedEncodingException + */ + public static byte[] send(String msgJSON) throws UnsupportedEncodingException { + //消息ID + byte[] msgId = NumConvertUtil.longToBytes(mId); + //消息内容 + byte[] msg = msgJSON.getBytes(); + //数据长度 + int len = msg.length; + byte[] dataLen = NumConvertUtil.intToBytes(len); + // 发送数据 + byte[] data; + if (len == 0) {//消息内容为空,则发送的是心跳 + data = new byte[]{(byte) 0xA5, (byte) 0xA5, (byte) 0xA5, (byte) 0xA5, msgId[0], msgId[1], msgId[2], msgId[3], 0x00, 0x00, 0x00, 0x00, dataLen[0], dataLen[1], dataLen[2], dataLen[3]}; + } else { + data = new byte[]{(byte) 0xA5, (byte) 0xA5, (byte) 0xA5, (byte) 0xA5, msgId[0], msgId[1], msgId[2], msgId[3], 0x01, 0x00, 0x00, 0x00, dataLen[0], dataLen[1], dataLen[2], dataLen[3]}; + } + // 合并消息内容 + data = NumConvertUtil.byteMerger(data, msg); + // CRC32校验 + byte[] crcArr = NumConvertUtil.toCRC32(data); + // 合并校验位 + data = NumConvertUtil.byteMerger(data, crcArr); + + mId++; + if (mId == MaxId) { + mId = 0; + } + System.out.println("发送数据:" + NumConvertUtil.byteToHex(data).replaceAll("(.{2})", " $1").substring(1)); + //System.out.println(new String(NumConvertUtil.hexToByte("7B22636D64223A227573657253616C74476574222C22706172616D223A7B2261636B76616C7565223A3130302C2273616C74223A22344734323678536A42434B57506B7948222C226C6F67696E456E63223A302C2274696D657374616D70223A313635393333393236363037347D7D"), "UTF-8")); + + return data; + } + + /** + * 解析接收数据 + * + * @param data + * @param tcpClient + * @throws UnsupportedEncodingException + */ + public static void recv(byte[] data, TcpClient tcpClient) { + try { + //消息头 + //消息ID + //消息类型 + //分包标志 + //保留 + //数据长度 + byte[] dataLen = new byte[4]; + System.arraycopy(data, 12, dataLen, 0, 4); + int len = NumConvertUtil.byteToInt(dataLen); + //消息内容 + byte[] msg = new byte[len]; + System.arraycopy(data, 16, msg, 0, len); + //校验位 + + //数据处理 + HPDataHandle.deal(msg, tcpClient); + } catch (Exception e) { + try { + log.error(tcpClient.getIp() + "======光电数据解析异常", new String(data, "UTF-8")); + } catch (UnsupportedEncodingException unsupportedEncodingException) { + unsupportedEncodingException.printStackTrace(); + } + } + + } + +} diff --git a/src/main/java/com/zgx/iot/utils/hp/HPFaultResult.java b/src/main/java/com/zgx/iot/utils/hp/HPFaultResult.java new file mode 100644 index 0000000..30fe661 --- /dev/null +++ b/src/main/java/com/zgx/iot/utils/hp/HPFaultResult.java @@ -0,0 +1,26 @@ +package com.zgx.iot.utils.hp; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * 存放光电故障诊断结果 + */ +public class HPFaultResult { + + public int status = 0; + public int statusMax = 0; + public Map faultResult = new LinkedHashMap<>(); + + private HPFaultResult() { + } + + //私有静态内部类 + private static class HPFaultResultInstance { + private static final HPFaultResult INSTANCE = new HPFaultResult(); + } + + public static HPFaultResult getInstance() { + return HPFaultResultInstance.INSTANCE; + } +} diff --git a/src/main/java/com/zgx/iot/utils/hp/HPReqParamEnc.java b/src/main/java/com/zgx/iot/utils/hp/HPReqParamEnc.java new file mode 100644 index 0000000..0320212 --- /dev/null +++ b/src/main/java/com/zgx/iot/utils/hp/HPReqParamEnc.java @@ -0,0 +1,220 @@ +package com.zgx.iot.utils.hp; + +import com.alibaba.fastjson.JSONObject; + +/** + * 和普请求参数封装 + * + * @Author: bb + * @Date: 2022-08-02 + */ +public class HPReqParamEnc { + + /** + * Salt获取 + * + * @param name + * @return + */ + public static String userSaltGet(String name) { + JSONObject paramJB = new JSONObject(); + paramJB.put("username", name); + return getReqJB("userSaltGet", paramJB); + } + + /** + * 用户登录 + * + * @param name + * @param psw + * @return + */ + public static String userLogin(String name, String psw) { + JSONObject paramJB = new JSONObject(); + paramJB.put("username", name); + paramJB.put("password", psw); + return getReqJB("userLogin", paramJB); + } + + /** + * 在线用户心跳 + * + * @param token + * @return + */ + public static String userOnlineHeart(String token) { + JSONObject paramJB = new JSONObject(); + paramJB.put("token", token); + return getReqJB("userOnlineHeart", paramJB); + } + + /** + * 云台控制 + * + * @param token + * @param channelid + * @param actionid + * @param presetid + * @param ptzxspeed + * @param ptzyspeed + * @param locSpeed + * @param locHorPos 水平角 + * @param locVerPos 俯仰角 + * @param locIrViewPos 视场角 * 100(分辨率/目标像素) + * @return + */ + public static String ptzControl(String token, + Integer channelid, Integer actionid, Integer presetid, + Integer ptzxspeed, Integer ptzyspeed, Integer locSpeed, + Integer locHorPos, Integer locVerPos, Integer locIrViewPos) { + JSONObject paramJB = new JSONObject(); + paramJB.put("token", token); + paramJB.put("channelid", channelid); + paramJB.put("actionid", actionid); + if (presetid != null) { + paramJB.put("presetid", presetid); + } + if (ptzxspeed != null) { + paramJB.put("ptzxspeed", ptzxspeed); + } + if (ptzyspeed != null) { + paramJB.put("ptzyspeed", ptzyspeed); + } + if (locSpeed != null) { + paramJB.put("locSpeed", locSpeed); + } + if (locHorPos != null) { + paramJB.put("locHorPos", locHorPos); + } + if (locVerPos != null) { + paramJB.put("locVerPos", locVerPos); + } + if (locIrViewPos != null) { + paramJB.put("locIrViewPos", locIrViewPos); + } + return getReqJB("ptzControl", paramJB); + } + + /** + * 根据报警目标ID跟踪 + * + * @param token + * @param bTracking + * @param channelid + * @param ID + * @return + */ + public static String ivpTrackingTargetID(String token, boolean bTracking, int channelid, int ID) { + JSONObject paramJB = new JSONObject(); + paramJB.put("token", token); + paramJB.put("bTracking", bTracking); + paramJB.put("channelid", channelid); + paramJB.put("ID", ID); + return getReqJB("ivpTrackingTargetID", paramJB); + } + + /** + * 目标跟踪控制 + * + * @param token + * @param channelid + * @param bTracking + * @param trackingRect + * @return + */ + public static String ivpTrackingCtrl(String token, int channelid, boolean bTracking, JSONObject trackingRect) { + JSONObject paramJB = new JSONObject(); + paramJB.put("token", token); + paramJB.put("channelid", channelid); + paramJB.put("bTracking", bTracking); + paramJB.put("trackingRect", trackingRect); + return getReqJB("ivpTrackingCtrl", paramJB); + } + + /** + * 获取目标跟踪状态 + * + * @param token + * @param channelid + * @return + */ + public static String ivpTrackingStatusGet(String token, int channelid) { + JSONObject paramJB = new JSONObject(); + paramJB.put("token", token); + paramJB.put("channelid", channelid); + return getReqJB("ivpTrackingStatusGet", paramJB); + } + + /** + * 获取智能分析结果 + * + * @param token + * @param channelid + * @param type + * @return + */ + public static String ivpGetResult(String token, int channelid, int type) { + JSONObject paramJB = new JSONObject(); + paramJB.put("token", token); + paramJB.put("channelid", channelid); + paramJB.put("type", type); + return getReqJB("ivpGetResult", paramJB); + } + + /** + * 开始故障诊断 + * + * @param token + * @param type 0-普通诊断,1-深度诊断 + * @return + */ + public static String FaultDiagnoseStart(String token, int type) { + JSONObject paramJB = new JSONObject(); + paramJB.put("token", token); + paramJB.put("type", type); + return getReqJB("FaultDiagnoseStart", paramJB); + } + + /** + * 停止故障诊断 + * + * @param token + * @return + */ + public static String FaultDiagnoseStop(String token) { + JSONObject paramJB = new JSONObject(); + paramJB.put("token", token); + return getReqJB("FaultDiagnoseStop", paramJB); + } + + /** + * 获取故障诊断结果 + * + * @param token + * @return + */ + public static String FaultDiagnoseGetResult(String token) { + JSONObject paramJB = new JSONObject(); + paramJB.put("token", token); + return getReqJB("FaultDiagnoseGetResult", paramJB); + } + + /** + * 设备重启 + * + * @param token + * @return + */ + public static String reboot(String token) { + JSONObject paramJB = new JSONObject(); + paramJB.put("token", token); + return getReqJB("reboot", paramJB); + } + + private static String getReqJB(String cmd, JSONObject jb) { + JSONObject reqJB = new JSONObject(); + reqJB.put("cmd", cmd); + reqJB.put("param", jb); + return reqJB.toJSONString(); + } +} diff --git a/src/main/java/com/zgx/iot/utils/hp/HPTcpKeepAlive.java b/src/main/java/com/zgx/iot/utils/hp/HPTcpKeepAlive.java new file mode 100644 index 0000000..d957ce9 --- /dev/null +++ b/src/main/java/com/zgx/iot/utils/hp/HPTcpKeepAlive.java @@ -0,0 +1,66 @@ +package com.zgx.iot.utils.hp; + + +import com.zgx.iot.constant.SocketConstant; +import com.zgx.iot.constant.enums.DateType; +import com.zgx.iot.constant.enums.StateType; +import com.zgx.iot.utils.AlarmInfoConvert; +import com.zgx.iot.utils.RedisUtil; +import com.zgx.iot.utils.socket.TcpClient; +import lombok.extern.slf4j.Slf4j; + +import java.io.UnsupportedEncodingException; +import java.util.Map; + +/** + * 心跳线程 + */ +@Slf4j +public class HPTcpKeepAlive extends Thread { + + private RedisUtil redisUtil; + + public HPTcpKeepAlive(RedisUtil redisUtil) { + this.redisUtil = redisUtil; + } + + @Override + public synchronized void run() { + byte[] data; + + while (true) { + if (ThreadManager.getTcpClientMap().size() > 0) { + try { + for (Map.Entry entity : ThreadManager.getTcpClientMap().entrySet()) { + if (entity.getValue().isConnected()) { + //log.info(entity.getKey() + "===发送心跳"); + if (entity.getKey().equals(String.valueOf(redisUtil.hget("dataRecordServer", "ip")))) { + data = AlarmInfoConvert.getStateInformationData( + Integer.valueOf(redisUtil.hget("dataRecordServer", "deviceCode").toString()), + 1, + DateType.STATE_INFO.getValue(), + StateType.HEARTBEAT.getCode(), + System.currentTimeMillis()); + } else { + data = HPDataParser.send(HPReqParamEnc.userOnlineHeart(String.valueOf(redisUtil.get(entity.getKey())))); + //查询当前跟踪状态 + /*entity.getValue().send( + HPDataParser.send( + HPReqParamEnc.ivpTrackingStatusGet(String.valueOf(redisUtil.get(entity.getKey())), 0) + ) + );*/ + } + entity.getValue().send(data); + } + } + wait(SocketConstant.IDLE_TIME); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + e.printStackTrace(); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + } + } + } +} diff --git a/src/main/java/com/zgx/iot/utils/hp/ThreadManager.java b/src/main/java/com/zgx/iot/utils/hp/ThreadManager.java new file mode 100644 index 0000000..8009cdb --- /dev/null +++ b/src/main/java/com/zgx/iot/utils/hp/ThreadManager.java @@ -0,0 +1,30 @@ +package com.zgx.iot.utils.hp; +import com.zgx.iot.utils.socket.TcpClient; + +import java.util.HashMap; +import java.util.Map; + +public class ThreadManager { + + static Map tcpClientMap = new HashMap<>(); + + private ThreadManager() { + } + + public static Map getTcpClientMap() { + return tcpClientMap; + } + + public static void setTcpClientMap(Map tcpClientMap) { + ThreadManager.tcpClientMap = tcpClientMap; + } + + //私有静态内部类 + private static class ThreadManagerInstance { + private static final ThreadManager INSTANCE = new ThreadManager(); + } + + public static ThreadManager getInstance() { + return ThreadManagerInstance.INSTANCE; + } +} diff --git a/src/main/java/com/zgx/iot/utils/https/HttpAPIHelper.java b/src/main/java/com/zgx/iot/utils/https/HttpAPIHelper.java new file mode 100644 index 0000000..f0b6342 --- /dev/null +++ b/src/main/java/com/zgx/iot/utils/https/HttpAPIHelper.java @@ -0,0 +1,16 @@ +package com.zgx.iot.utils.https; + +import cn.hutool.http.HttpUtil; +import com.alibaba.fastjson.JSON; +import com.zgx.iot.utils.JacksonUtil; + +import java.util.Map; + +public class HttpAPIHelper { + public static ResultData doGet(String url, Map map) { + + String res = HttpUtil.createGet(url).form(map).execute().body(); + ResultData resultData = JSON.parseObject(res, ResultData.class); + return resultData; + } +} diff --git a/src/main/java/com/zgx/iot/utils/https/ResultData.java b/src/main/java/com/zgx/iot/utils/https/ResultData.java new file mode 100644 index 0000000..5402b00 --- /dev/null +++ b/src/main/java/com/zgx/iot/utils/https/ResultData.java @@ -0,0 +1,17 @@ +package com.zgx.iot.utils.https; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + + +@Data +@NoArgsConstructor +@EqualsAndHashCode(callSuper = false) +public class ResultData { + + public boolean success; + public int code; + public String message; + public String result; +} diff --git a/src/main/java/com/zgx/iot/utils/oConvertUtils.java b/src/main/java/com/zgx/iot/utils/oConvertUtils.java new file mode 100644 index 0000000..c5f085b --- /dev/null +++ b/src/main/java/com/zgx/iot/utils/oConvertUtils.java @@ -0,0 +1,668 @@ +package com.zgx.iot.utils; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.IOUtils; +import org.springframework.beans.BeanUtils; + +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Field; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.sql.Date; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * + * @Author 张代浩 + * + */ +@Slf4j +public class oConvertUtils { + public static boolean isEmpty(Object object) { + if (object == null) { + return (true); + } + if ("".equals(object)) { + return (true); + } + if ("null".equals(object)) { + return (true); + } + return (false); + } + + public static boolean isNotEmpty(Object object) { + if (object != null && !object.equals("") && !object.equals("null")) { + return (true); + } + return (false); + } + + public static String decode(String strIn, String sourceCode, String targetCode) { + String temp = code2code(strIn, sourceCode, targetCode); + return temp; + } + + public static String StrToUTF(String strIn, String sourceCode, String targetCode) { + strIn = ""; + try { + strIn = new String(strIn.getBytes("ISO-8859-1"), "GBK"); + } catch (UnsupportedEncodingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return strIn; + + } + + private static String code2code(String strIn, String sourceCode, String targetCode) { + String strOut = null; + if (strIn == null || (strIn.trim()).equals("")) { + return strIn; + } + try { + byte[] b = strIn.getBytes(sourceCode); + for (int i = 0; i < b.length; i++) { + System.out.print(b[i] + " "); + } + strOut = new String(b, targetCode); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + return strOut; + } + + public static int getInt(String s, int defval) { + if (s == null || s == "") { + return (defval); + } + try { + return (Integer.parseInt(s)); + } catch (NumberFormatException e) { + return (defval); + } + } + + public static int getInt(String s) { + if (s == null || s == "") { + return 0; + } + try { + return (Integer.parseInt(s)); + } catch (NumberFormatException e) { + return 0; + } + } + + public static int getInt(String s, Integer df) { + if (s == null || s == "") { + return df; + } + try { + return (Integer.parseInt(s)); + } catch (NumberFormatException e) { + return 0; + } + } + + public static Integer[] getInts(String[] s) { + Integer[] integer = new Integer[s.length]; + if (s == null) { + return null; + } + for (int i = 0; i < s.length; i++) { + integer[i] = Integer.parseInt(s[i]); + } + return integer; + + } + + public static double getDouble(String s, double defval) { + if (s == null || s == "") { + return (defval); + } + try { + return (Double.parseDouble(s)); + } catch (NumberFormatException e) { + return (defval); + } + } + + public static double getDou(Double s, double defval) { + if (s == null) { + return (defval); + } + return s; + } + + /*public static Short getShort(String s) { + if (StringUtil.isNotEmpty(s)) { + return (Short.parseShort(s)); + } else { + return null; + } + }*/ + + public static int getInt(Object object, int defval) { + if (isEmpty(object)) { + return (defval); + } + try { + return (Integer.parseInt(object.toString())); + } catch (NumberFormatException e) { + return (defval); + } + } + + public static Integer getInt(Object object) { + if (isEmpty(object)) { + return null; + } + try { + return (Integer.parseInt(object.toString())); + } catch (NumberFormatException e) { + return null; + } + } + + public static int getInt(BigDecimal s, int defval) { + if (s == null) { + return (defval); + } + return s.intValue(); + } + + public static Integer[] getIntegerArry(String[] object) { + int len = object.length; + Integer[] result = new Integer[len]; + try { + for (int i = 0; i < len; i++) { + result[i] = new Integer(object[i].trim()); + } + return result; + } catch (NumberFormatException e) { + return null; + } + } + + public static String getString(String s) { + return (getString(s, "")); + } + + /** + * 转义成Unicode编码 + * @param s + * @return + */ + /*public static String escapeJava(Object s) { + return StringEscapeUtils.escapeJava(getString(s)); + }*/ + + public static String getString(Object object) { + if (isEmpty(object)) { + return ""; + } + return (object.toString().trim()); + } + + public static String getString(int i) { + return (String.valueOf(i)); + } + + public static String getString(float i) { + return (String.valueOf(i)); + } + + public static String getString(String s, String defval) { + if (isEmpty(s)) { + return (defval); + } + return (s.trim()); + } + + public static String getString(Object s, String defval) { + if (isEmpty(s)) { + return (defval); + } + return (s.toString().trim()); + } + + public static long stringToLong(String str) { + Long test = new Long(0); + try { + test = Long.valueOf(str); + } catch (Exception e) { + } + return test.longValue(); + } + + /** + * 获取本机IP + */ + public static String getIp() { + String ip = null; + try { + InetAddress address = InetAddress.getLocalHost(); + ip = address.getHostAddress(); + + } catch (UnknownHostException e) { + e.printStackTrace(); + } + return ip; + } + + /** + * 判断一个类是否为基本数据类型。 + * + * @param clazz + * 要判断的类。 + * @return true 表示为基本数据类型。 + */ + private static boolean isBaseDataType(Class clazz) throws Exception { + return (clazz.equals(String.class) || clazz.equals(Integer.class) || clazz.equals(Byte.class) || clazz.equals(Long.class) || clazz.equals(Double.class) || clazz.equals(Float.class) || clazz.equals(Character.class) || clazz.equals(Short.class) || clazz.equals(BigDecimal.class) || clazz.equals(BigInteger.class) || clazz.equals(Boolean.class) || clazz.equals(Date.class) || clazz.isPrimitive()); + } + + /** + * @param request + * IP + * @return IP Address + */ + public static String getIpAddrByRequest(HttpServletRequest request) { + String ip = request.getHeader("x-forwarded-for"); + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + return ip; + } + + /** + * @return 本机IP + * @throws SocketException + */ + public static String getRealIp() throws SocketException { + String localip = null;// 本地IP,如果没有配置外网IP则返回它 + String netip = null;// 外网IP + + Enumeration netInterfaces = NetworkInterface.getNetworkInterfaces(); + InetAddress ip = null; + boolean finded = false;// 是否找到外网IP + while (netInterfaces.hasMoreElements() && !finded) { + NetworkInterface ni = netInterfaces.nextElement(); + Enumeration address = ni.getInetAddresses(); + while (address.hasMoreElements()) { + ip = address.nextElement(); + if (!ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && ip.getHostAddress().indexOf(":") == -1) {// 外网IP + netip = ip.getHostAddress(); + finded = true; + break; + } else if (ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && ip.getHostAddress().indexOf(":") == -1) {// 内网IP + localip = ip.getHostAddress(); + } + } + } + + if (netip != null && !"".equals(netip)) { + return netip; + } else { + return localip; + } + } + + /** + * java去除字符串中的空格、回车、换行符、制表符 + * + * @param str + * @return + */ + public static String replaceBlank(String str) { + String dest = ""; + if (str != null) { + Pattern p = Pattern.compile("\\s*|\t|\r|\n"); + Matcher m = p.matcher(str); + dest = m.replaceAll(""); + } + return dest; + + } + + /** + * 判断元素是否在数组内 + * + * @param substring + * @param source + * @return + */ + public static boolean isIn(String substring, String[] source) { + if (source == null || source.length == 0) { + return false; + } + for (int i = 0; i < source.length; i++) { + String aSource = source[i]; + if (aSource.equals(substring)) { + return true; + } + } + return false; + } + + /** + * 获取Map对象 + */ + public static Map getHashMap() { + return new HashMap(); + } + + /** + * SET转换MAP + * + * @param str + * @return + */ + public static Map SetToMap(Set setobj) { + Map map = getHashMap(); + for (Iterator iterator = setobj.iterator(); iterator.hasNext();) { + Map.Entry entry = (Map.Entry) iterator.next(); + map.put(entry.getKey().toString(), entry.getValue() == null ? "" : entry.getValue().toString().trim()); + } + return map; + + } + + public static boolean isInnerIP(String ipAddress) { + boolean isInnerIp = false; + long ipNum = getIpNum(ipAddress); + /** + * 私有IP:A类 10.0.0.0-10.255.255.255 B类 172.16.0.0-172.31.255.255 C类 192.168.0.0-192.168.255.255 当然,还有127这个网段是环回地址 + **/ + long aBegin = getIpNum("10.0.0.0"); + long aEnd = getIpNum("10.255.255.255"); + long bBegin = getIpNum("172.16.0.0"); + long bEnd = getIpNum("172.31.255.255"); + long cBegin = getIpNum("192.168.0.0"); + long cEnd = getIpNum("192.168.255.255"); + isInnerIp = isInner(ipNum, aBegin, aEnd) || isInner(ipNum, bBegin, bEnd) || isInner(ipNum, cBegin, cEnd) || ipAddress.equals("127.0.0.1"); + return isInnerIp; + } + + private static long getIpNum(String ipAddress) { + String[] ip = ipAddress.split("\\."); + long a = Integer.parseInt(ip[0]); + long b = Integer.parseInt(ip[1]); + long c = Integer.parseInt(ip[2]); + long d = Integer.parseInt(ip[3]); + + long ipNum = a * 256 * 256 * 256 + b * 256 * 256 + c * 256 + d; + return ipNum; + } + + private static boolean isInner(long userIp, long begin, long end) { + return (userIp >= begin) && (userIp <= end); + } + + /** + * 将下划线大写方式命名的字符串转换为驼峰式。 + * 如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。
+ * 例如:hello_world->helloWorld + * + * @param name + * 转换前的下划线大写方式命名的字符串 + * @return 转换后的驼峰式命名的字符串 + */ + public static String camelName(String name) { + StringBuilder result = new StringBuilder(); + // 快速检查 + if (name == null || name.isEmpty()) { + // 没必要转换 + return ""; + } else if (!name.contains("_")) { + // 不含下划线,仅将首字母小写 + //update-begin--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能 + //update-begin--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能 + return name.substring(0, 1).toLowerCase() + name.substring(1).toLowerCase(); + //update-end--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能 + } + // 用下划线将原始字符串分割 + String camels[] = name.split("_"); + for (String camel : camels) { + // 跳过原始字符串中开头、结尾的下换线或双重下划线 + if (camel.isEmpty()) { + continue; + } + // 处理真正的驼峰片段 + if (result.length() == 0) { + // 第一个驼峰片段,全部字母都小写 + result.append(camel.toLowerCase()); + } else { + // 其他的驼峰片段,首字母大写 + result.append(camel.substring(0, 1).toUpperCase()); + result.append(camel.substring(1).toLowerCase()); + } + } + return result.toString(); + } + + /** + * 将下划线大写方式命名的字符串转换为驼峰式。 + * 如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。
+ * 例如:hello_world,test_id->helloWorld,testId + * + * @param name + * 转换前的下划线大写方式命名的字符串 + * @return 转换后的驼峰式命名的字符串 + */ + public static String camelNames(String names) { + if(names==null||names.equals("")){ + return null; + } + StringBuffer sf = new StringBuffer(); + String[] fs = names.split(","); + for (String field : fs) { + field = camelName(field); + sf.append(field + ","); + } + String result = sf.toString(); + return result.substring(0, result.length() - 1); + } + + //update-begin--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能 + /** + * 将下划线大写方式命名的字符串转换为驼峰式。(首字母写) + * 如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。
+ * 例如:hello_world->HelloWorld + * + * @param name + * 转换前的下划线大写方式命名的字符串 + * @return 转换后的驼峰式命名的字符串 + */ + public static String camelNameCapFirst(String name) { + StringBuilder result = new StringBuilder(); + // 快速检查 + if (name == null || name.isEmpty()) { + // 没必要转换 + return ""; + } else if (!name.contains("_")) { + // 不含下划线,仅将首字母小写 + return name.substring(0, 1).toUpperCase() + name.substring(1).toLowerCase(); + } + // 用下划线将原始字符串分割 + String camels[] = name.split("_"); + for (String camel : camels) { + // 跳过原始字符串中开头、结尾的下换线或双重下划线 + if (camel.isEmpty()) { + continue; + } + // 其他的驼峰片段,首字母大写 + result.append(camel.substring(0, 1).toUpperCase()); + result.append(camel.substring(1).toLowerCase()); + } + return result.toString(); + } + //update-end--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能 + + /** + * 将驼峰命名转化成下划线 + * @param para + * @return + */ + public static String camelToUnderline(String para){ + if(para.length()<3){ + return para.toLowerCase(); + } + StringBuilder sb=new StringBuilder(para); + int temp=0;//定位 + //从第三个字符开始 避免命名不规范 + for(int i=2;i clazz = object.getClass(); + List fieldList = new ArrayList<>(); + while (clazz != null) { + fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields()))); + clazz = clazz.getSuperclass(); + } + Field[] fields = new Field[fieldList.size()]; + fieldList.toArray(fields); + return fields; + } + + /** + * 将map的key全部转成小写 + * @param list + * @return + */ + public static List> toLowerCasePageList(List> list){ + List> select = new ArrayList<>(); + for (Map row : list) { + Map resultMap = new HashMap<>(); + Set keySet = row.keySet(); + for (String key : keySet) { + String newKey = key.toLowerCase(); + resultMap.put(newKey, row.get(key)); + } + select.add(resultMap); + } + return select; + } + + /** + * 将entityList转换成modelList + * @param fromList + * @param tClass + * @param + * @param + * @return + */ + public static List entityListToModelList(List fromList, Class tClass){ + if(fromList == null || fromList.isEmpty()){ + return null; + } + List tList = new ArrayList<>(); + for(F f : fromList){ + T t = entityToModel(f, tClass); + tList.add(t); + } + return tList; + } + + public static T entityToModel(F entity, Class modelClass) { + log.debug("entityToModel : Entity属性的值赋值到Model"); + Object model = null; + if (entity == null || modelClass ==null) { + return null; + } + + try { + model = modelClass.newInstance(); + } catch (InstantiationException e) { + log.error("entityToModel : 实例化异常", e); + } catch (IllegalAccessException e) { + log.error("entityToModel : 安全权限异常", e); + } + BeanUtils.copyProperties(entity, model); + return (T)model; + } + + /** + * 判断 list 是否为空 + * + * @param list + * @return true or false + * list == null : true + * list.size() == 0 : true + */ + public static boolean listIsEmpty(Collection list) { + return (list == null || list.size() == 0); + } + + /** + * 判断 list 是否不为空 + * + * @param list + * @return true or false + * list == null : false + * list.size() == 0 : false + */ + public static boolean listIsNotEmpty(Collection list) { + return !listIsEmpty(list); + } + + /** + * 读取静态文本内容 + * @param url + * @return + */ + public static String readStatic(String url) { + String json = ""; + try { + //换个写法,解决springboot读取jar包中文件的问题 + InputStream stream = oConvertUtils.class.getClassLoader().getResourceAsStream(url.replace("classpath:", "")); + json = IOUtils.toString(stream,"UTF-8"); + } catch (IOException e) { + log.error(e.getMessage(),e); + } + return json; + } +} diff --git a/src/main/java/com/zgx/iot/utils/radarUtils/BitConverter.java b/src/main/java/com/zgx/iot/utils/radarUtils/BitConverter.java new file mode 100644 index 0000000..c742325 --- /dev/null +++ b/src/main/java/com/zgx/iot/utils/radarUtils/BitConverter.java @@ -0,0 +1,132 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package com.zgx.iot.utils.radarUtils; + +public class BitConverter +{ + public static short ToInt16(final byte[] bytes, final int offset) { + short result = (short)(bytes[offset] & 0xFF); + result |= (short)((bytes[offset + 1] & 0xFF) << 8); + return (short)(result & 0xFFFF); + } + + public static int ToUInt16(final byte[] bytes, final int offset) { + int result = bytes[offset + 1] & 0xFF; + result |= (bytes[offset] & 0xFF) << 8; + return result & 0xFFFF; + } + + public static int ToInt32(final byte[] bytes, final int offset) { + final int byte3 = bytes[offset + 3] & 0xFF; + final int byte4 = (bytes[offset + 2] & 0xFF) << 8; + final int byte5 = (bytes[offset + 1] & 0xFF) << 16; + final int byte6 = (bytes[offset] & 0xFF) << 24; + return byte6 | byte5 | byte4 | byte3; + } + + public static int bytes2IntSmallEndian(final byte[] bytes, final int offset) { + return (bytes[offset + 3] & 0xFF) << 24 | (bytes[offset + 2] & 0xFF) << 16 | (bytes[offset + 1] & 0xFF) << 8 | (bytes[offset] & 0xFF); + } + + public static long ToUInt32(final byte[] bytes, final int offset) { + long result = bytes[offset] & 0xFF; + result |= (bytes[offset + 1] & 0xFF) << 8; + result |= (bytes[offset + 2] & 0xFF) << 16; + result |= (bytes[offset + 3] & 0xFF) << 24; + return result & 0xFFFFFFFFL; + } + + public static long ToInt64(final byte[] buffer, final int offset) { + long values = 0L; + for (int i = 0; i < 8; ++i) { + values <<= 8; + values |= (buffer[offset + i] & 0xFF); + } + return values; + } + + public static long ToUInt64(final byte[] bytes, int offset) { + long result = 0L; + for (int i = 0; i <= 56; i += 8) { + result |= (bytes[offset++] & 0xFF) << i; + } + return result; + } + + public static float ToFloat(final byte[] bs, final int index) { + return Float.intBitsToFloat(ToInt32(bs, index)); + } + + public static double ToDouble(final byte[] arr, final int offset) { + return Double.longBitsToDouble(ToUInt64(arr, offset)); + } + + public static boolean ToBoolean(final byte[] bytes, final int offset) { + return bytes[offset] != 0; + } + + public static byte[] GetBytes(final short value) { + final byte[] bytes = { (byte)(value & 0xFF), (byte)((value & 0xFF00) >> 8) }; + return bytes; + } + + public static byte[] GetBytes(final int value) { + final byte[] bytes = { (byte)(value & 0xFF), (byte)(value >> 8 & 0xFF), (byte)(value >> 16 & 0xFF), (byte)(value >>> 24) }; + return bytes; + } + + public static byte[] GetBytes(final long values) { + final byte[] buffer = new byte[8]; + for (int i = 0; i < 8; ++i) { + final int offset = 64 - (i + 1) * 8; + buffer[i] = (byte)(values >> offset & 0xFFL); + } + return buffer; + } + + public static byte[] GetBytes(final float value) { + return GetBytes(Float.floatToIntBits(value)); + } + + public static byte[] GetBytes(final double val) { + final long value = Double.doubleToLongBits(val); + return GetBytes(value); + } + + public static byte[] GetBytes(final boolean value) { + return new byte[] { (byte)(value ? 1 : 0) }; + } + + public static byte IntToByte(final int x) { + return (byte)x; + } + + public static int ByteToInt(final byte b) { + return b & 0xFF; + } + + public static char ToChar(final byte[] bs, final int offset) { + return (char)((bs[offset] & 0xFF) << 8 | (bs[offset + 1] & 0xFF)); + } + + public static byte[] GetBytes(final char value) { + final byte[] b = { (byte)((value & '\uff00') >> 8), (byte)(value & '\u00ff') }; + return b; + } + + public static byte[] Concat(final byte[]... bs) { + int len = 0; + int idx = 0; + for (final byte[] b : bs) { + len += b.length; + } + final byte[] buffer = new byte[len]; + for (final byte[] b2 : bs) { + System.arraycopy(b2, 0, buffer, idx, b2.length); + idx += b2.length; + } + return buffer; + } +} diff --git a/src/main/java/com/zgx/iot/utils/radarUtils/ByteIntUtil.java b/src/main/java/com/zgx/iot/utils/radarUtils/ByteIntUtil.java new file mode 100644 index 0000000..87087cc --- /dev/null +++ b/src/main/java/com/zgx/iot/utils/radarUtils/ByteIntUtil.java @@ -0,0 +1,58 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package com.zgx.iot.utils.radarUtils; + +public class ByteIntUtil +{ + public static byte[] i2b(final int i) { + return new byte[] { (byte)(i >> 24 & 0xFF), (byte)(i >> 16 & 0xFF), (byte)(i >> 8 & 0xFF), (byte)(i & 0xFF) }; + } + + public static int b2i(final byte[] b) { + int value = 0; + for (int i = 0; i < 4; ++i) { + final int shift = (3 - i) * 8; + value += (b[i] & 0xFF) << shift; + } + return value; + } + + public static byte[] byteMerger(final byte[] byte_1, final byte[] byte_2) { + final byte[] byte_3 = new byte[byte_1.length + byte_2.length]; + System.arraycopy(byte_1, 0, byte_3, 0, byte_1.length); + System.arraycopy(byte_2, 0, byte_3, byte_1.length, byte_2.length); + return byte_3; + } + + public static byte[] byteToBit(byte b) { + final byte[] array = new byte[8]; + for (int i = 7; i >= 0; --i) { + array[i] = (byte)(b & 0x1); + b >>= 1; + } + return array; + } + + public static String byteToBitStr(final byte b) { + return new StringBuilder().append((byte)(b >> 7 & 0x1)).append((byte)(b >> 6 & 0x1)).append((byte)(b >> 5 & 0x1)).append((byte)(b >> 4 & 0x1)).append((byte)(b >> 3 & 0x1)).append((byte)(b >> 2 & 0x1)).append((byte)(b >> 1 & 0x1)).append((byte)(b >> 0 & 0x1)).toString(); + } + + public static int charToAscii(final char ch) { + return ch; + } + + public static String asciiToStr(final int ascii) { + final char ch = (char)ascii; + return String.valueOf(ch); + } + + public static byte[] changeLittleEndianBytes(final byte[] a) { + final byte[] b = new byte[a.length]; + for (int i = 0; i < b.length; ++i) { + b[i] = a[b.length - i - 1]; + } + return b; + } +} diff --git a/src/main/java/com/zgx/iot/utils/radarUtils/EndianUtil.java b/src/main/java/com/zgx/iot/utils/radarUtils/EndianUtil.java new file mode 100644 index 0000000..1e36446 --- /dev/null +++ b/src/main/java/com/zgx/iot/utils/radarUtils/EndianUtil.java @@ -0,0 +1,133 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package com.zgx.iot.utils.radarUtils; + +public class EndianUtil +{ + public static byte[] short2LittleEndianBytes(final short val) { + return short2Bytes(short2LittleEndian(val)); + } + + public static byte[] int2LittleEndianBytes(final int val) { + return int2Bytes(int2LittleEndian(val)); + } + + public static byte[] long2LittleEndianBytes(final long val) { + return long2Bytes(long2LittleEndian(val)); + } + + public static short short2LittleEndian(final short val) { + return (short)(((val & 0xFF00) >>> 8) + ((val & 0xFF) << 8)); + } + + public static int int2LittleEndian(final int val) { + return ((val & 0xFF000000) >>> 24) + ((val & 0xFF0000) >>> 16 << 8) + ((val & 0xFF00) >>> 8 << 16) + ((val & 0xFF) << 24); + } + + public static long long2LittleEndian(final long val) { + return ((val & 0xFF00000000000000L) >>> 56) + ((val & 0xFF000000000000L) >>> 48 << 8) + ((val & 0xFF0000000000L) >>> 40 << 16) + ((val & 0xFF00000000L) >>> 32 << 24) + ((val & 0xFF000000L) >>> 24 << 32) + ((val & 0xFF0000L) >>> 16 << 40) + ((val & 0xFF00L) >>> 8 << 48) + ((val & 0xFFL) << 56); + } + + public static int intFromLittleEndian(final int val) { + return int2LittleEndian(val); + } + + public static short shortFromLittleEndian(final short val) { + return short2LittleEndian(val); + } + + public static long longFromLittleEndian(final long val) { + return long2LittleEndian(val); + } + + public static byte[] long2Bytes(final long a) { + return new byte[] { (byte)(a >> 56 & 0xFFL), (byte)(a >> 48 & 0xFFL), (byte)(a >> 40 & 0xFFL), (byte)(a >> 32 & 0xFFL), (byte)(a >> 24 & 0xFFL), (byte)(a >> 16 & 0xFFL), (byte)(a >> 8 & 0xFFL), (byte)(a & 0xFFL) }; + } + + public static byte[] int2Bytes(final int a) { + return new byte[] { (byte)(a >> 24 & 0xFF), (byte)(a >> 16 & 0xFF), (byte)(a >> 8 & 0xFF), (byte)(a & 0xFF) }; + } + + public static byte[] short2Bytes(final short a) { + return new byte[] { (byte)(a >> 8 & 0xFF), (byte)(a & 0xFF) }; + } + + public static long bytes2Long(final byte[] bytes, final int offset) { + return (0xFFL & (long)bytes[offset + 7]) | (0xFF00L & (long)bytes[offset + 6] << 8) | (0xFF0000L & (long)bytes[offset + 5] << 16) | (0xFF000000L & (long)bytes[offset + 4] << 24) | (0xFF00000000L & (long)bytes[offset + 3] << 32) | (0xFF0000000000L & (long)bytes[offset + 2] << 40) | (0xFF000000000000L & (long)bytes[offset + 1] << 48) | (0xFF00000000000000L & (long)bytes[offset] << 56); + } + + public static long bytes2LongSmallEndian(final byte[] bytes, final int offset) { + return (0xFFL & (long)bytes[offset]) | (0xFF00L & (long)bytes[offset + 1] << 8) | (0xFF0000L & (long)bytes[offset + 2] << 16) | (0xFF000000L & (long)bytes[offset + 3] << 24) | (0xFF00000000L & (long)bytes[offset + 4] << 32) | (0xFF0000000000L & (long)bytes[offset + 5] << 40) | (0xFF000000000000L & (long)bytes[offset + 6] << 48) | (0xFF00000000000000L & (long)bytes[offset + 7] << 56); + } + + public static int bytes2Int(final byte[] bytes, final int offset) { + return (bytes[offset] & 0xFF) << 24 | (bytes[offset + 1] & 0xFF) << 16 | (bytes[offset + 2] & 0xFF) << 8 | (bytes[offset + 3] & 0xFF); + } + + public static int bytes2IntSmallEndian(final byte[] bytes, final int offset) { + return (bytes[offset + 3] & 0xFF) << 24 | (bytes[offset + 2] & 0xFF) << 16 | (bytes[offset + 1] & 0xFF) << 8 | (bytes[offset] & 0xFF); + } + + public static char bytes2Char(final byte[] bytes, final int offset) { + if (bytes.length < 2) { + return '\uffff'; + } + int iRst = bytes[offset] & 0xFF; + iRst |= (bytes[offset + 1] & 0xFF) << 8; + return (char)iRst; + } + + public static char bytes2CharSmallEndian(final byte[] bytes, final int offset) { + if (bytes.length < 2) { + return '\uffff'; + } + int iRst = bytes[offset] << 8 & 0xFF; + iRst |= (bytes[offset + 1] & 0xFF); + return (char)iRst; + } + + public static char byte2Char(final byte bytedata) { + if (bytedata > 32 && bytedata < 127) { + return (char)bytedata; + } + return '0'; + } + + public static short bytes2Short(final byte[] bytes, final int offset) { + return (short)((bytes[offset] & 0xFF) << 8 | (bytes[offset + 1] & 0xFF)); + } + + public static short bytes2ShortSmallEndian(final byte[] bytes, final int offset) { + return (short)((bytes[offset + 1] & 0xFF) << 8 | (bytes[offset] & 0xFF)); + } + + public static float byte2float(final byte[] bytes, final int offset) { + final int FF = 255; + final int b0 = bytes[offset] & FF; + final int b2 = bytes[offset + 1] & FF; + final int b3 = bytes[offset + 2] & FF; + final int b4 = bytes[offset + 3] & FF; + final int h0 = b0 << 24; + final int h2 = b2 << 16; + final int h3 = b3 << 8; + final int h4 = b4; + final int h5 = h0 | h2 | h3 | h4; + return Float.intBitsToFloat(h5); + } + + public static float byte2floatSmallEndian(final byte[] bytes, final int offset) { + final int FF = 255; + final int b0 = bytes[offset + 3] & FF; + final int b2 = bytes[offset + 2] & FF; + final int b3 = bytes[offset + 1] & FF; + final int b4 = bytes[offset] & FF; + final int h0 = b0 << 24; + final int h2 = b2 << 16; + final int h3 = b3 << 8; + final int h4 = b4; + final int h5 = h0 | h2 | h3 | h4; + return Float.intBitsToFloat(h5); + } +} diff --git a/src/main/java/com/zgx/iot/utils/radarUtils/RadarTransformUtil.java b/src/main/java/com/zgx/iot/utils/radarUtils/RadarTransformUtil.java new file mode 100644 index 0000000..ad36b51 --- /dev/null +++ b/src/main/java/com/zgx/iot/utils/radarUtils/RadarTransformUtil.java @@ -0,0 +1,38 @@ +// +// Decompiled by Procyon v0.5.36 +// + +package com.zgx.iot.utils.radarUtils; + + + +import com.zgx.iot.dto.radar.RadarTrackModel; +import com.zgx.iot.radar.proto.ZCHXRadar; + +import java.util.Calendar; + +public class RadarTransformUtil +{ + public static ZCHXRadar.TrackPoint modelToProtobuf(final RadarTrackModel radarTrack) { + final ZCHXRadar.TrackPoint.Builder point = ZCHXRadar.TrackPoint.newBuilder(); + point.setSystemAreaCode(1); + point.setSystemIdentificationCode(1); + point.setMessageType(ZCHXRadar.MSGTYP.TARGET_REPORT); + point.setTrackNumber(radarTrack.getTrackId()); + point.setCartesianPosX(1.0f); + point.setCartesianPosY(1.0f); + point.setWgs84PosLong(radarTrack.getLongitude()); + point.setWgs84PosLat(radarTrack.getLatitude()); + final Calendar cal = Calendar.getInstance(); + point.setTimeOfDay((float)cal.getTimeInMillis()); + point.setTrackType(ZCHXRadar.CNF.CONFIRMED_TRACK); + point.setTrackLastReport(false); + point.setCartesianTrkVelVx(1.0); + point.setCartesianTrkVelVy(1.0); + point.setCog(radarTrack.getCourse()); + point.setSog(radarTrack.getSpeed()); + point.setStatus(1); + return point.build(); + } + +} diff --git a/src/main/java/com/zgx/iot/utils/socket/TcpClient.java b/src/main/java/com/zgx/iot/utils/socket/TcpClient.java new file mode 100644 index 0000000..5f79d00 --- /dev/null +++ b/src/main/java/com/zgx/iot/utils/socket/TcpClient.java @@ -0,0 +1,126 @@ +package com.zgx.iot.utils.socket; + + +import com.zgx.iot.constant.SocketConstant; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.IOUtils; + +import java.io.IOException; +import java.io.InputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.text.ParseException; + +/** + * TCP连接客户端 + */ +@Slf4j +public abstract class TcpClient extends Thread { + + private String ip; + private int port; + private Socket socket; + private InputStream is = null; + public volatile boolean flag = false; + + public String getIp() { + return ip; + } + + public int getPort() { + return port; + } + + public TcpClient(String ip, int port) { + this.ip = ip; + this.port = port; + } + + @Override + public void run() { + init(); + } + + private void init() { + try { + this.socket = new Socket(); + this.socket.setKeepAlive(true); + //绑定一个本地地址和端口并设置连接超时时间为3秒 + this.socket.connect(new InetSocketAddress(this.ip, this.port), SocketConstant.TIME_OUT); + log.info(this.ip + "===TCP连接成功"); + flag = true; + + //监听数据 + recv(); + + } catch (Exception e) { + log.error(this.ip + "===TCP连接失败,请检查服务端是否开启"); + e.printStackTrace(); + } + } + + public void send(byte[] bOutArray) { + try { + if (isConnected()) { + this.socket.getOutputStream().write(bOutArray); + } + } catch (IOException e) { + init(); + } + } + + private void recv() { + try { + //!Thread.currentThread().isInterrupted() + while (flag) { + this.is = this.socket.getInputStream(); + //接收服务端发送的数据的输入流 + if (this.is == null) { + return; + } + int line = 0; + byte[] buffer = new byte[1024 * 65]; + while ((line = this.is.read(buffer)) != -1) { + //System.out.println("接收内容:" + new String(buffer, 0, line)); + try { + dealWithRecvData(buffer); + } catch (Exception e) { + log.error("【接收数据解析发生异常】" + e.getMessage(), e); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + if (this.is != null) { + this.is.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + public boolean isConnected() { + try { + this.socket.sendUrgentData(0xFF); + return true; + } catch (Exception se) { + // 捕获到异常说明连接已断开 + return false; + } + } + + public void close() { + flag = false; + IOUtils.closeQuietly(this.socket); + this.socket = null; + log.info(this.ip + "===TCP连接已断开"); + } + + /** + * 处理接收到的数据 + */ + public abstract void dealWithRecvData(byte[] data) throws ParseException; +} diff --git a/src/main/java/com/zgx/iot/vo/DictModel.java b/src/main/java/com/zgx/iot/vo/DictModel.java new file mode 100644 index 0000000..29cdc5c --- /dev/null +++ b/src/main/java/com/zgx/iot/vo/DictModel.java @@ -0,0 +1,42 @@ +package com.zgx.iot.vo; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@JsonIgnoreProperties(ignoreUnknown = true) +public class DictModel implements Serializable{ + private static final long serialVersionUID = 1L; + + public DictModel() { + } + + public DictModel(String value, String text) { + this.value = value; + this.text = text; + } + + /** + * 字典value + */ + private String value; + /** + * 字典文本 + */ + private String text; + + /** + * 特殊用途: JgEditableTable + * @return + */ + public String getTitle() { + return this.text; + } + +} diff --git a/src/main/java/com/zgx/iot/vo/DynamicDataSourceModel.java b/src/main/java/com/zgx/iot/vo/DynamicDataSourceModel.java new file mode 100644 index 0000000..5b38f0e --- /dev/null +++ b/src/main/java/com/zgx/iot/vo/DynamicDataSourceModel.java @@ -0,0 +1,52 @@ +package com.zgx.iot.vo; + +import lombok.Data; +import org.springframework.beans.BeanUtils; + +@Data +public class DynamicDataSourceModel { + + public DynamicDataSourceModel() { + + } + + public DynamicDataSourceModel(Object dbSource) { + if (dbSource != null) { + BeanUtils.copyProperties(dbSource, this); + } + } + + /** + * id + */ + private String id; + /** + * 数据源编码 + */ + private String code; + /** + * 数据库类型 + */ + private String dbType; + /** + * 驱动类 + */ + private String dbDriver; + /** + * 数据源地址 + */ + private String dbUrl; + /** + * 数据库名称 + */ + private String dbName; + /** + * 用户名 + */ + private String dbUsername; + /** + * 密码 + */ + private String dbPassword; + +} \ No newline at end of file diff --git a/src/main/java/com/zgx/iot/vo/LoginUser.java b/src/main/java/com/zgx/iot/vo/LoginUser.java new file mode 100644 index 0000000..2033e17 --- /dev/null +++ b/src/main/java/com/zgx/iot/vo/LoginUser.java @@ -0,0 +1,117 @@ +package com.zgx.iot.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; + +/** + *

+ * 在线用户信息 + *

+ * + * @Author scott + * @since 2018-12-20 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +public class LoginUser { + + /** + * 登录人id + */ + private String id; + + /** + * 登录人账号 + */ + private String username; + + /** + * 登录人名字 + */ + private String realname; + + /** + * 登录人密码 + */ + private String password; + + /** + * 当前登录部门code + */ + private String orgCode; + /** + * 头像 + */ + private String avatar; + + /** + * 生日 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private Date birthday; + + /** + * 性别(1:男 2:女) + */ + private Integer sex; + + /** + * 电子邮件 + */ + private String email; + + /** + * 电话 + */ + private String phone; + + /** + * 状态(1:正常 2:冻结 ) + */ + private Integer status; + + private Integer delFlag; + /** + * 同步工作流引擎1同步0不同步 + */ + private Integer activitiSync; + + /** + * 创建时间 + */ + private Date createTime; + + /** + * 身份(1 普通员工 2 上级) + */ + private Integer userIdentity; + + /** + * 管理部门ids + */ + private String departIds; + + /** + * 职务,关联职务表 + */ + private String post; + + /** + * 座机号 + */ + private String telephone; + + /**多租户id配置,编辑用户的时候设置*/ + private String relTenantIds; + + /**设备id uniapp推送用*/ + private String clientId; + +} diff --git a/src/main/java/com/zgx/iot/vo/PTZVo.java b/src/main/java/com/zgx/iot/vo/PTZVo.java new file mode 100644 index 0000000..cfa3f3a --- /dev/null +++ b/src/main/java/com/zgx/iot/vo/PTZVo.java @@ -0,0 +1,34 @@ +package com.zgx.iot.vo; + +import lombok.Data; + +/** + * @Description: 相机PTZ值 + * @Author: bb + * @Date: 2021-08-16 + * @Version: V1.0 + */ +@Data +public class PTZVo { + /** + * 相机水平旋转值 + */ + private double panValue; + /** + * 相机垂直旋转值 + */ + private double tileValue; + /** + * 镜头焦距 + */ + private double zoomValue; + + public PTZVo() { + } + + public PTZVo(double panValue, double tileValue, double zoomValue) { + this.panValue = panValue; + this.tileValue = tileValue; + this.zoomValue = zoomValue; + } +} diff --git a/src/main/java/com/zgx/iot/vo/SysUserCacheInfo.java b/src/main/java/com/zgx/iot/vo/SysUserCacheInfo.java new file mode 100644 index 0000000..47d90dc --- /dev/null +++ b/src/main/java/com/zgx/iot/vo/SysUserCacheInfo.java @@ -0,0 +1,69 @@ +package com.zgx.iot.vo; + + + +import com.zgx.iot.utils.DateUtils; + +import java.util.List; + +public class SysUserCacheInfo { + + private String sysUserCode; + + private String sysUserName; + + private String sysOrgCode; + + private List sysMultiOrgCode; + + private boolean oneDepart; + + public boolean isOneDepart() { + return oneDepart; + } + + public void setOneDepart(boolean oneDepart) { + this.oneDepart = oneDepart; + } + + public String getSysDate() { + return DateUtils.formatDate(); + } + + public String getSysTime() { + return DateUtils.now(); + } + + public String getSysUserCode() { + return sysUserCode; + } + + public void setSysUserCode(String sysUserCode) { + this.sysUserCode = sysUserCode; + } + + public String getSysUserName() { + return sysUserName; + } + + public void setSysUserName(String sysUserName) { + this.sysUserName = sysUserName; + } + + public String getSysOrgCode() { + return sysOrgCode; + } + + public void setSysOrgCode(String sysOrgCode) { + this.sysOrgCode = sysOrgCode; + } + + public List getSysMultiOrgCode() { + return sysMultiOrgCode; + } + + public void setSysMultiOrgCode(List sysMultiOrgCode) { + this.sysMultiOrgCode = sysMultiOrgCode; + } + +} diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml new file mode 100644 index 0000000..52e3e45 --- /dev/null +++ b/src/main/resources/application-dev.yml @@ -0,0 +1,355 @@ +# .0.0/+/up/request,/v1.0.0/+/up/fault,/v1.0.0/+/up/alarm,/v1.0.0/+/up/cmd,/v1.0.0/+/down/heartbeat,RadarData-1,RadarData-3 +server: + port: 11111 + tomcat: + max-swallow-size: -1 + error: + include-exception: true + include-stacktrace: ALWAYS + include-message: ALWAYS + servlet: + context-path: /military + compression: + enabled: true + min-response-size: 1024 + mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/* + +management: + endpoints: + web: + exposure: + include: metrics,httptrace + +spring: + servlet: + multipart: + max-file-size: 10MB + max-request-size: 10MB + mail: + host: smtp.163.com + username: jeecgos@163.com + password: ?? + properties: + mail: + smtp: + auth: true + starttls: + enable: true + required: true + ## quartz定时任务,采用数据库方式 + quartz: + job-store-type: jdbc + initialize-schema: embedded + #设置自动启动,默认为 true + auto-startup: true + #启动时更新己存在的Job + overwrite-existing-jobs: true + properties: + org: + quartz: + scheduler: + instanceName: MyScheduler + instanceId: AUTO + jobStore: + class: org.quartz.impl.jdbcjobstore.JobStoreTX + driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate + tablePrefix: QRTZ_ + isClustered: true + misfireThreshold: 60000 + clusterCheckinInterval: 10000 + threadPool: + class: org.quartz.simpl.SimpleThreadPool + threadCount: 10 + threadPriority: 5 + threadsInheritContextClassLoaderOfInitializingThread: true + #json 时间戳统一转换 + jackson: + date-format: yyyy-MM-dd HH:mm:ss + time-zone: GMT+8 + jpa: + open-in-view: false + activiti: + check-process-definitions: false + #启用作业执行器 + async-executor-activate: false + #启用异步执行器 + job-executor-activate: false + aop: + proxy-target-class: true + #配置freemarker + freemarker: + # 设置模板后缀名 + suffix: .ftl + # 设置文档类型 + content-type: text/html + # 设置页面编码格式 + charset: UTF-8 + # 设置页面缓存 + cache: false + prefer-file-system-access: false + # 设置ftl文件路径 + template-loader-path: + - classpath:/templates + # 设置静态文件路径,js,css等 + mvc: + static-path-pattern: /** + resource: + static-locations: classpath:/static/,classpath:/public/ + autoconfigure: + exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure + datasource: + druid: + stat-view-servlet: + enabled: true + loginUsername: admin + loginPassword: 123456 + allow: + web-stat-filter: + enabled: true + dynamic: + druid: # 全局druid参数,绝大部分值和默认保持一致。(现已支持的参数如下,不清楚含义不要乱设置) + # 连接池的配置信息 + # 初始化大小,最小,最大 + initial-size: 5 + min-idle: 5 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + validationQuery: SELECT 1 FROM DUAL + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + # 打开PSCache,并且指定每个连接上PSCache的大小 + poolPreparedStatements: true + maxPoolPreparedStatementPerConnectionSize: 20 + # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 + filters: stat,wall,slf4j + # 通过connectProperties属性来打开mergeSql功能;慢SQL记录 + connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000 + datasource: + master: + # url: jdbc:mysql://military-mysql:3308/military_ml?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai + # url: jdbc:mysql://localhost:3306/military_ml?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai + # url: jdbc:mysql://localhost:3306/dt-military?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai + username: root + password: root + # password: Admin@789! + driver-class-name: com.mysql.cj.jdbc.Driver + name: test +# url: jdbc:mysql://localhost:3306/military_ml?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai +# username: root +# password: root +# url: jdbc:mysql://172.20.0.55:3306/dt-military?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai + url: jdbc:mysql://172.20.0.55:3306/dt_db_test?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai +# url: jdbc:mysql://172.20.0.55:3306/dt-military?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai #测试发送mqtt + username: root + password: 123456 +# password: 123456 + driver-class-name: com.mysql.cj.jdbc.Driver + + #redis 配置 + redis: + database : 0 + # host: 192.168.1.200 + host: 127.0.0.1 + #host: 172.20.0.55 #测试发送mqtt + # host: military-redis + lettuce: + pool: + max-active: 8 #最大连接数据库连接数,设 -1 为没有限制 + max-idle: 8 #最大等待连接中的数量,设 0 为没有限制 + max-wait: -1ms #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。 + min-idle: 0 #最小等待连接中的数量,设 0 为没有限制 + shutdown-timeout: 100ms + password: '' + port: 6379 + #MongoDB 配置 +# data: +# mongodb: +# uri: mongodb://admin:mongodb@127.0.0.1:27017/earthMap?authSource=admin&authMechanism=SCRAM-SHA-1 + +#mybatis plus 设置 +mybatis-plus: + mapper-locations: classpath*:com/zgx/iot/**/xml/*Mapper.xml + global-config: + # 关闭MP3.0自带的banner + banner: false + db-config: + #主键类型 0:"数据库ID自增",1:"该类型为未设置主键类型", 2:"用户输入ID",3:"全局唯一ID (数字类型唯一ID)", 4:"全局唯一ID UUID",5:"字符串全局唯一ID (idWorker 的字符串表示)"; + id-type: ASSIGN_ID + # 默认数据库表下划线命名 + table-underline: true + configuration: + # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用 + log-impl: org.apache.ibatis.logging.stdout.StdOutImpl + # 返回类型为Map,显示null对应的字段 + call-setters-on-nulls: true +#jeecg专用配置 +minidao: + base-package: org.jeecg.modules.jmreport.* + #DB类型(mysql | postgresql | oracle | sqlserver| other) + db-type: mysql +jeecg: + # 本地:local\Minio:minio\阿里云:alioss + uploadType: local + path: + #文件上传根目录 设置 + upload: /opt/upFiles + #webapp文件路径 + webapp: /opt/webapp + shiro: + excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/** + #阿里云oss存储和大鱼短信秘钥配置 + oss: + accessKey: ?? + secretKey: ?? + endpoint: oss-cn-beijing.aliyuncs.com + bucketName: ?? + # ElasticSearch 6设置 + elasticsearch: + cluster-name: jeecg-ES + cluster-nodes: 127.0.0.1:9200 + check-enabled: false + # 表单设计器配置 + desform: + # 主题颜色(仅支持 16进制颜色代码) + theme-color: "#1890ff" + # 文件、图片上传方式,可选项:qiniu(七牛云)、system(跟随系统配置) + upload-type: system + map: + # 配置百度地图的AK,申请地址:https://lbs.baidu.com/apiconsole/key?application=key#/home + baidu: ?? + # 在线预览文件服务器地址配置 + file-view-domain: 127.0.0.1:8012 + # minio文件上传 + minio: + minio_url: http://minio.jeecg.com + minio_name: ?? + minio_pass: ?? + bucketName: otatest + #大屏报表参数设置 + jmreport: + mode: dev + #数据字典是否进行saas数据隔离,自己看自己的字典 + saas: false + #是否需要校验token + is_verify_token: true + #必须校验方法 + verify_methods: remove,delete,save,add,update + #Wps在线文档 + wps: + domain: https://wwo.wps.cn/office/ + appid: ?? + appsecret: ?? + #xxl-job配置 + xxljob: + enabled: false + adminAddresses: http://127.0.0.1:9080/xxl-job-admin + appname: ${spring.application.name} + accessToken: '' + address: 127.0.0.1:30007 + ip: 127.0.0.1 + port: 30007 + logPath: logs/jeecg/job/jobhandler/ + logRetentionDays: 30 + #自定义路由配置 yml nacos database + route: + config: + data-id: jeecg-gateway-router + group: DEFAULT_GROUP + data-type: yml + #分布式锁配置 + redisson: + address: 127.0.0.1:6379 + password: + type: STANDALONE + enabled: true +#cas单点登录 +cas: + prefixUrl: http://cas.example.org:8443/cas +#Mybatis输出sql日志 +logging: + level: + com.zgx.modules.system.mapper: info +#swagger +knife4j: + production: false + basic: + enable: true + username: jeecg + password: jeecg1314 +#第三方登录 +justauth: + enabled: true + type: + GITHUB: + client-id: ?? + client-secret: ?? + redirect-uri: http://sso.test.com:8080/jeecg-boot/sys/thirdLogin/github/callback + WECHAT_ENTERPRISE: + client-id: ?? + client-secret: ?? + redirect-uri: http://sso.test.com:8080/jeecg-boot/sys/thirdLogin/wechat_enterprise/callback + agent-id: ?? + DINGTALK: + client-id: ?? + client-secret: ?? + redirect-uri: http://sso.test.com:8080/jeecg-boot/sys/thirdLogin/dingtalk/callback + WECHAT_OPEN: + client-id: ?? + client-secret: ?? + redirect-uri: http://sso.test.com:8080/jeecg-boot/sys/thirdLogin/wechat_open/callback + cache: + type: default + prefix: 'demo::' + timeout: 1h +#第三方APP对接1 +third-app: + enabled: false + type: + #企业微信 + WECHAT_ENTERPRISE: + enabled: false + #CORP_ID + client-id: ?? + #SECRET + client-secret: ?? + #自建应用id + agent-id: ?? + #自建应用秘钥(新版企微需要配置) + # agent-app-secret: ?? + #钉钉 + DINGTALK: + enabled: false + # appKey + client-id: ?? + # appSecret + client-secret: ?? + agent-id: ?? +#zmq配置 +zmq: + # ip: 192.168.1.86 + ip: 172.20.0.77 #zmq服务地址 + send-port: 5001 + # recv-port: 5000 + recv-port: 5151 + rep-port: 5004 + topic: + radar-ly: radar_ly + radar_sy: radar_sy + fence_za: fence_za + radar_target: NyGuideCamPos + target_trajectory: RadarTrack + flag: + move-type: true + radar: true + wzd: false + video: false + model: false +ffmpeg: + path: classpath:bin/ffmpeg.exe + videoTime: 10 diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml new file mode 100644 index 0000000..b3e564d --- /dev/null +++ b/src/main/resources/application-test.yml @@ -0,0 +1,48 @@ +#zmq配置 +zmq: + ip: 127.0.0.1 + send-port: 5001 + recv-port: 5000 + rep-port: 5004 + topic: + radar-ly: radar_ly + radar_sy: radar_sy + fence_za: fence_za + flag: + move-type: true + radar: true + wzd: false + video: false + model: false +# ffmpeg 配置 +ffmpeg: + path: classpath:bin/ffmpeg.exe + videoTime: 10 +# netty配置 +netty: + retry: + count: 3 + interval: 3000 + heartbeat: + interval: 30000 + count: 3 + device: + retry: + count: 3 + interval: 3000 +# mqtt配置 +mqtt: + client: + id: military_iot_platform + topics: + - web/PPS/RadarAlarmMessage + - PPS/RadarTargetTrajectory/+ + service: + # 认证方式 password or toekn + authentication: token + username: loadmin + password: public + address: tcp://192.168.1.200:1883 + retry: + count: 5 + interval: 3 diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..eea3986 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,52 @@ +app: + siteid: 00001-00001-00002 +spring: + application: + name: military-system + profiles: + active: dev + +#mqtt配置 +mqtt: + orgCode: A0405 + client: + id: test + retry: + count: 5 + interval: 3 + topics: /v1.0.0/+/up/request,/v1.0.0/+/up/fault,/v1.0.0/+/up/alarm,/v1.0.0/+/up/cmd,/v1.0.0/+/down/heartbeat,RadarData-1,RadarData-3,/trackTarget,/cameraToTarget,/modifyAngle, + service: + username: admin + # password: public + password: 123456 + # address: tcp://192.168.1.200:1883 + address: tcp://172.20.0.55:1883 +# slf4j日志配置 +logging: + config: classpath:logback.xml +#netty: +# tcp-service: +# address: 127.0.0.1 +# port: 6929 +# tcp-client: +# address: 127.0.0.1 +# port: 6929 +# udp-service: +# address: 127.0.0.1 +# port: 9999 +# udp-client: +# address: 127.0.0.1 +# port: 9999 + +# netty配置 +netty: + retry: + count: 3 + interval: 3000 + heartbeat: + interval: 30000 + count: 3 + device: + retry: + count: 3 + interval: 3000 \ No newline at end of file diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml new file mode 100644 index 0000000..0fd2575 --- /dev/null +++ b/src/main/resources/logback.xml @@ -0,0 +1,129 @@ + + + + + + + ./mqttlogs/info/info-${HOSTNAME}.log + true + + + ./mqttlogs/info/archive/info-${HOSTNAME}-%d.%i.log + + 30 + + + 10MB + + + + + %date %level [%thread] %logger{10} %msg%n + UTF-8 + + + + + + 512 + + + + + + + ./mqttlogs/debug/debug-${HOSTNAME}.log + true + + + ./mqttlogs/debug/archive/debug-${HOSTNAME}-%d.%i.log + + 30 + + + 10MB + + + + + %date %level [%thread] %logger{10} %msg%n + UTF-8 + + + + + + 512 + + + + + + + ./mqttlogs/error/error-${HOSTNAME}.log + true + + + ./mqttlogs/error/archive/error-${HOSTNAME}-%d.%i.log + + 30 + + + 10MB + + + + + %date %level [%thread] %logger{10} %msg%n + UTF-8 + + + + + + 512 + + + + + + + + %date %level [%thread] %logger{10} [%file:%line] %msg%n + + + + + + 512 + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/java/com/example/dtimp1/DtImp1ApplicationTests.java b/src/test/java/com/example/dtimp1/DtImp1ApplicationTests.java new file mode 100644 index 0000000..a39e83a --- /dev/null +++ b/src/test/java/com/example/dtimp1/DtImp1ApplicationTests.java @@ -0,0 +1,40 @@ +package com.example.dtimp1; + +import com.zgx.iot.SystemApplication; +import com.zgx.iot.mq.mqtt.MqttService; +import com.zgx.iot.radar.RadarServer; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import javax.annotation.Resource; +import javax.sql.DataSource; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.sql.SQLException; + +@SpringBootTest +class DtImp1ApplicationTests { + InetAddress localHost; + + @Autowired + DataSource dataSource; + @Test + void contextLoads() throws SQLException { + System.out.println("获取的数据库连接为:"+dataSource.getConnection()); + } + + @Test + void testRa(){ + try { + localHost = InetAddress.getLocalHost(); + } catch (UnknownHostException e) { + throw new RuntimeException(e); + } + if (localHost!=null){ + SystemApplication.threadPool.execute(new RadarServer(localHost.getHostAddress(),8899)); + } + + } + +} diff --git a/src/test/java/com/zgx/iot/mq/mqtt/MqttServiceTest.java b/src/test/java/com/zgx/iot/mq/mqtt/MqttServiceTest.java new file mode 100644 index 0000000..e62487d --- /dev/null +++ b/src/test/java/com/zgx/iot/mq/mqtt/MqttServiceTest.java @@ -0,0 +1,23 @@ +package com.zgx.iot.mq.mqtt; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +import javax.annotation.Resource; + +import static org.junit.jupiter.api.Assertions.*; + +@SpringBootTest +class MqttServiceTest { + + + @Resource + MqttService mqttService; + + @Test + void pubMessageTest() { + mqttService.pubMessage("radarTrack","military"); + } + + +} \ No newline at end of file