commit 05ba53f44463b2cacf860ad51b863bfc024f2141 Author: GG Date: Wed May 8 10:32:31 2024 +0800 first commit 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