GG
8 months ago
commit
05ba53f444
196 changed files with 27597 additions and 0 deletions
@ -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 |
@ -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. |
|||
|
@ -0,0 +1 @@ |
|||
services: |
@ -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 "$@" |
@ -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% |
@ -0,0 +1,224 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
|||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> |
|||
<modelVersion>4.0.0</modelVersion> |
|||
<parent> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-parent</artifactId> |
|||
<version>2.7.10</version> |
|||
<relativePath/> <!-- lookup parent from repository --> |
|||
</parent> |
|||
<groupId>com.example</groupId> |
|||
<artifactId>military-hq</artifactId> |
|||
<version>0.0.1-SNAPSHOT</version> |
|||
<name>military-hq</name> |
|||
<description>military-hq</description> |
|||
<properties> |
|||
|
|||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
|||
<xxl-job-core.version>2.2.0</xxl-job-core.version> |
|||
<fastjson.version>1.2.83</fastjson.version> |
|||
<dom4j.version>1.2.83</dom4j.version> |
|||
|
|||
<java.version>1.8</java.version> |
|||
<dom4j.version>1.6.1</dom4j.version> |
|||
<qiniu-java-sdk.version>7.4.0</qiniu-java-sdk.version> |
|||
<!-- Log4j2爆雷漏洞 --> |
|||
<log4j2.version>2.17.0</log4j2.version> |
|||
<logback.version>1.2.9</logback.version> |
|||
<skipTests>true</skipTests> |
|||
<mysql-connector-java.version>8.0.21</mysql-connector-java.version> |
|||
</properties> |
|||
<dependencies> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-devtools</artifactId> |
|||
<scope>runtime</scope> |
|||
<optional>true</optional> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-configuration-processor</artifactId> |
|||
<optional>true</optional> |
|||
</dependency> |
|||
<!--<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-docker-compose</artifactId> |
|||
<scope>runtime</scope> |
|||
<optional>true</optional> |
|||
</dependency>--> |
|||
<dependency> |
|||
<groupId>org.projectlombok</groupId> |
|||
<artifactId>lombok</artifactId> |
|||
<optional>true</optional> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-test</artifactId> |
|||
<scope>test</scope> |
|||
</dependency> |
|||
<!-- json --> |
|||
<dependency> |
|||
<groupId>com.alibaba</groupId> |
|||
<artifactId>fastjson</artifactId> |
|||
<version>${fastjson.version}</version> |
|||
</dependency> |
|||
<!-- dom4j --> |
|||
<dependency> |
|||
<groupId>dom4j</groupId> |
|||
<artifactId>dom4j</artifactId> |
|||
<version>${dom4j.version}</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.zeromq</groupId> |
|||
<artifactId>jeromq</artifactId> |
|||
<version>0.5.2</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.eclipse.paho</groupId> |
|||
<artifactId>org.eclipse.paho.client.mqttv3</artifactId> |
|||
<version>1.2.5</version> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>com.fasterxml.jackson.core</groupId> |
|||
<artifactId>jackson-databind</artifactId> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>com.fasterxml.jackson.dataformat</groupId> |
|||
<artifactId>jackson-dataformat-xml</artifactId> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>com.fasterxml.jackson.core</groupId> |
|||
<artifactId>jackson-annotations</artifactId> |
|||
<version>2.13.5</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>commons-io</groupId> |
|||
<artifactId>commons-io</artifactId> |
|||
<version>2.8.0</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>com.google.protobuf</groupId> |
|||
<artifactId>protobuf-java</artifactId> |
|||
<version>3.16.1</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>io.netty</groupId> |
|||
<artifactId>netty-all</artifactId> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.apache.commons</groupId> |
|||
<artifactId>commons-lang3</artifactId> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>cn.hutool</groupId> |
|||
<artifactId>hutool-all</artifactId> |
|||
<version>5.7.22</version> |
|||
<scope>compile</scope> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>com.google.guava</groupId> |
|||
<artifactId>guava</artifactId> |
|||
<version>28.2-android</version> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-websocket</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.apache.tomcat.embed</groupId> |
|||
<artifactId>tomcat-embed-websocket</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.gavaghan</groupId> |
|||
<artifactId>geodesy</artifactId> |
|||
<version>1.1.3</version> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>com.baomidou</groupId> |
|||
<artifactId>mybatis-plus-boot-starter</artifactId> |
|||
<version>3.4.1</version> |
|||
</dependency> |
|||
|
|||
<!-- Redis --> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-data-redis</artifactId> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.apache.commons</groupId> |
|||
<artifactId>commons-pool2</artifactId> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.springframework.data</groupId> |
|||
<artifactId>spring-data-redis</artifactId> |
|||
<!--<version>2.3.5.RELEASE</version>--> |
|||
</dependency> |
|||
|
|||
<!-- onvif --> |
|||
<dependency> |
|||
<groupId>com.github.03</groupId> |
|||
<artifactId>onvif</artifactId> |
|||
<version>1.0.7</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.gavaghan</groupId> |
|||
<artifactId>geodesy</artifactId> |
|||
<version>1.1.3</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>com.dbb</groupId> |
|||
<artifactId>onvif</artifactId> |
|||
<version>1.0.0</version> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>io.lettuce</groupId> |
|||
<artifactId>lettuce-core</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>mysql</groupId> |
|||
<artifactId>mysql-connector-java</artifactId> |
|||
<version>${mysql-connector-java.version}</version> |
|||
<scope>runtime</scope> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>commons-beanutils</groupId> |
|||
<artifactId>commons-beanutils</artifactId> |
|||
<version>1.9.4</version> |
|||
</dependency> |
|||
</dependencies> |
|||
|
|||
<build> |
|||
|
|||
<plugins> |
|||
<plugin> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-maven-plugin</artifactId> |
|||
<configuration> |
|||
<excludes> |
|||
<exclude> |
|||
<groupId>org.projectlombok</groupId> |
|||
<artifactId>lombok</artifactId> |
|||
</exclude> |
|||
</excludes> |
|||
<mainClass>com.zgx.iot.SystemApplication</mainClass> |
|||
</configuration> |
|||
|
|||
</plugin> |
|||
</plugins> |
|||
</build> |
|||
|
|||
</project> |
@ -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); |
|||
} |
|||
} |
@ -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<MsDeviceInfo> 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<DtDeviceInfo> deviceInfoList =new ArrayList<>(); |
|||
deviceInfoList.add(msDeviceInfo); |
|||
|
|||
//deviceServiceUtil.startServerByDeviceInfo(deviceInfos);
|
|||
deviceServiceUtil.startServerByDeviceInfo(deviceInfoList); |
|||
} |
|||
|
|||
} |
|||
*/ |
@ -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<String, TcpClient> tcpClientMap = new HashMap<>(); |
|||
|
|||
redisUtil.del("cameraList"); |
|||
redisUtil.del("dataRecordServer"); |
|||
|
|||
QueryWrapper<DtDeviceInfo> queryWrapper = new QueryWrapper<>(); |
|||
//queryWrapper.eq("state", 1);//1-启用
|
|||
//todo 查询光电
|
|||
queryWrapper.and(wrapper -> wrapper.eq("device_type", DeviceType.PHOTOELECTRIC.getValue())); |
|||
List<DtDeviceInfo> 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<String, TcpClient> tcpClientMap = new HashMap<>(); |
|||
|
|||
redisUtil.del("cameraList"); |
|||
redisUtil.del("dataRecordServer"); |
|||
|
|||
LambdaQueryWrapper<MsCameraSetting> lambdaQueryWrapper = new LambdaQueryWrapper<>(); |
|||
//lambdaQueryWrapper.eq(MsCameraSetting::getType,3).eq(MsCameraSetting::getStatus,1);
|
|||
lambdaQueryWrapper.eq(MsCameraSetting::getType,3); |
|||
|
|||
List<MsCameraSetting> 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服务启动成功!"); |
|||
} |
|||
} |
@ -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<DtDeviceInfo> 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<DtDeviceInfo> photoelectricLambdaQueryWrapper = new LambdaQueryWrapper<>(); |
|||
photoelectricLambdaQueryWrapper.eq(DtDeviceInfo::getDeviceType, DeviceType.PHOTOELECTRIC.getValue()).eq(DtDeviceInfo::getDeviceStatus, 1); |
|||
List<DtDeviceInfo> 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<MsCameraSetting> cameraSettings = null; |
|||
LambdaQueryWrapper<MsCameraSetting> 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<RadarTrackModel> 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<MsCameraSetting> cameraSettings = null; |
|||
LambdaQueryWrapper<MsCameraSetting> 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<RadarTrackModel> 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<MsCameraSetting> cameraSettings = null; |
|||
LambdaQueryWrapper<MsCameraSetting> 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(); |
|||
} |
|||
} |
|||
} |
@ -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");
|
|||
} |
|||
} |
@ -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<DtDeviceInfo> GetALLDeviceLit(String siteid){ |
|||
|
|||
String url = Constants.APIURL.DEVICE_LIST; |
|||
HashMap<String, Object> valueMap = new HashMap<>(); |
|||
valueMap.put("device_owner_id",siteid); |
|||
valueMap.put("device_status",0); |
|||
ResultData resultData = HttpAPIHelper.doGet(url, valueMap); |
|||
List<DtDeviceInfo> jsonArray = JSON.parseArray(resultData.getResult(), DtDeviceInfo.class); |
|||
// 将JSONArray数组转为List类型
|
|||
//List<DeviceInfo> list = (List)jsonArray;
|
|||
// return JSON.parseObject(resultData.getData(), List<DeviceInfo>.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<DeviceInfo>.class);
|
|||
return deviceInfo; |
|||
}*/ |
|||
} |
@ -0,0 +1,4 @@ |
|||
package com.zgx.iot.api; |
|||
|
|||
public class ServiceAPI { |
|||
} |
@ -0,0 +1,4 @@ |
|||
package com.zgx.iot.api.mq; |
|||
|
|||
public class MQManager { |
|||
} |
@ -0,0 +1,4 @@ |
|||
package com.zgx.iot.api.mq; |
|||
|
|||
public interface MQService { |
|||
} |
@ -0,0 +1,4 @@ |
|||
package com.zgx.iot.api.mq; |
|||
|
|||
public class MQTTServiceimpl implements MQService { |
|||
} |
@ -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<String, Object> { |
|||
|
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
|
|||
public BaseMap() { |
|||
|
|||
} |
|||
|
|||
public BaseMap(Map<String, Object> 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> 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<Long> getListLong(String key) { |
|||
List<String> 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> 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<String, Object> obj) { |
|||
BaseMap map = new BaseMap(); |
|||
map.putAll(obj); |
|||
return map; |
|||
} |
|||
|
|||
|
|||
} |
@ -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<String, IClientProtocal> objectList = new HashMap<String, IClientProtocal>(); |
|||
|
|||
/** |
|||
* 根据路径新建对象 |
|||
* @param path |
|||
* @return |
|||
*/ |
|||
public static IClientProtocal getInstance(String path) { |
|||
if( objectList.containsKey(path) ){ |
|||
return objectList.get(path); |
|||
}else{ |
|||
try { |
|||
Class<IClientProtocal> classObject = (Class<IClientProtocal>) 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; |
|||
} |
|||
} |
@ -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<String, IClientProtocal> DeviceList = new HashMap<>(); |
|||
private String site_id=""; |
|||
|
|||
/** |
|||
* 登录判断并匹配协议 |
|||
*/ |
|||
public void loginClientDevices(){ |
|||
/* List<MsDeviceInfo> deviceInfoList= DeviceInfoAPI.GetALLDeviceLit(site_id); |
|||
for ( MsDeviceInfo deviceInfo :deviceInfoList) { |
|||
IClientProtocal clientProtocal = ClientProtocalFactory.CreateClient(deviceInfo); |
|||
}*/ |
|||
|
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
} |
@ -0,0 +1,30 @@ |
|||
package com.zgx.iot.client; |
|||
|
|||
/** |
|||
* 策略抽象接口类,提供客户端需要的一些公共方法 |
|||
*/ |
|||
public interface IClientProtocal { |
|||
|
|||
|
|||
/** |
|||
* 登录 |
|||
*/ |
|||
void login(); |
|||
|
|||
/** |
|||
* 数据解析 |
|||
* @param data |
|||
*/ |
|||
void analysisData( byte[] data); |
|||
|
|||
/** |
|||
* 心跳包 |
|||
*/ |
|||
void handbert(); |
|||
|
|||
|
|||
|
|||
|
|||
void logout(); |
|||
|
|||
} |
@ -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() { |
|||
|
|||
} |
|||
} |
@ -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<String, IoSession> nodeIdsessionMap = new ConcurrentHashMap<>();
|
|||
|
|||
|
|||
/** |
|||
* 定时任务轮训,主要主动请求数据 |
|||
*/ |
|||
public static Map<String, Timer > timerTaskMap = new ConcurrentHashMap<>(); |
|||
|
|||
/** |
|||
* 设备数据透传 |
|||
*/ |
|||
public static Map<String, Long > deviceMap = new ConcurrentHashMap<>(); |
|||
|
|||
|
|||
//public static Map<String, IotNodeInfoBOSocket> nodeIdsessionMapEx = new ConcurrentHashMap<>();
|
|||
|
|||
|
|||
} |
@ -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 ; |
|||
} |
|||
|
|||
} |
@ -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"; |
|||
} |
@ -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" ; |
|||
|
|||
|
|||
} |
|||
} |
@ -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; |
|||
} |
@ -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; |
|||
} |
@ -0,0 +1,4 @@ |
|||
package com.zgx.iot.config.socket.ssl; |
|||
|
|||
public class SslConfig { |
|||
} |
@ -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"; |
|||
} |
@ -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"; |
|||
} |
@ -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; |
|||
|
|||
} |
@ -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"; |
|||
} |
@ -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; |
|||
} |
|||
} |
@ -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; |
|||
} |
|||
} |
@ -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; |
|||
} |
|||
} |
@ -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; |
|||
} |
|||
} |
@ -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; |
|||
} |
|||
|
|||
} |
@ -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; |
|||
} |
|||
} |
@ -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; |
|||
} |
|||
} |
@ -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; |
|||
} |
|||
} |
@ -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; |
|||
} |
|||
} |
@ -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; |
|||
} |
|||
} |
@ -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; |
|||
} |
|||
} |
@ -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; |
|||
} |
|||
} |
@ -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; |
|||
} |
|||
} |
@ -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; |
|||
} |
|||
} |
@ -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<DtDeviceInfo> 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<DtDeviceInfo> photoelectricLambdaQueryWrapper = new LambdaQueryWrapper<>(); |
|||
photoelectricLambdaQueryWrapper.eq(DtDeviceInfo::getDeviceType, DeviceType.PHOTOELECTRIC.getValue()) //光电类型
|
|||
.eq(DtDeviceInfo::getDeviceStatus, 1);//1-启用状态
|
|||
List<DtDeviceInfo> 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<MsCameraSetting> cameraSettingLambdaQueryWrapper = new LambdaQueryWrapper<>(); |
|||
cameraSettingLambdaQueryWrapper.eq(MsCameraSetting::getType, 2)//2-球机类型
|
|||
.eq(MsCameraSetting::getStatus, 1);//1-启用状态
|
|||
List<MsCameraSetting> 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("没有可跟踪的光电"); |
|||
} |
|||
|
|||
} |
@ -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 ; // 数据
|
|||
|
|||
} |
@ -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; |
|||
} |
|||
|
|||
|
|||
} |
@ -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; |
|||
} |
|||
} |
@ -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; |
|||
} |
|||
} |
@ -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; |
|||
} |
|||
} |
@ -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; |
|||
} |
|||
} |
@ -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; |
|||
|
|||
} |
@ -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; |
|||
} |
@ -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; |
|||
|
|||
|
|||
|
|||
|
|||
} |
@ -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"; |
|||
|
|||
} |
@ -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; |
|||
} |
@ -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; |
|||
} |
@ -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; |
|||
} |
@ -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<T> 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<T> success(String message) { |
|||
this.message = message; |
|||
this.code = CommonConstant.SC_OK_200; |
|||
this.success = true; |
|||
return this; |
|||
} |
|||
|
|||
@Deprecated |
|||
public static Result<Object> ok() { |
|||
Result<Object> r = new Result<Object>(); |
|||
r.setSuccess(true); |
|||
r.setCode(CommonConstant.SC_OK_200); |
|||
r.setMessage("成功"); |
|||
return r; |
|||
} |
|||
|
|||
@Deprecated |
|||
public static Result<Object> ok(String msg) { |
|||
Result<Object> r = new Result<>(); |
|||
r.setSuccess(true); |
|||
r.setCode(CommonConstant.SC_OK_200); |
|||
r.setMessage(msg); |
|||
return r; |
|||
} |
|||
|
|||
@Deprecated |
|||
public static Result<Object> ok(Object data) { |
|||
Result<Object> r = new Result<Object>(); |
|||
r.setSuccess(true); |
|||
r.setCode(CommonConstant.SC_OK_200); |
|||
r.setResult(data); |
|||
return r; |
|||
} |
|||
|
|||
public static<T> Result<T> OK() { |
|||
Result<T> r = new Result<T>(); |
|||
r.setSuccess(true); |
|||
r.setCode(CommonConstant.SC_OK_200); |
|||
r.setMessage("成功"); |
|||
return r; |
|||
} |
|||
|
|||
public static<T> Result<T> OK(T data) { |
|||
Result<T> r = new Result<T>(); |
|||
r.setSuccess(true); |
|||
r.setCode(CommonConstant.SC_OK_200); |
|||
r.setResult(data); |
|||
return r; |
|||
} |
|||
|
|||
public static<T> Result<T> OK(String msg, T data) { |
|||
Result<T> r = new Result<T>(); |
|||
r.setSuccess(true); |
|||
r.setCode(CommonConstant.SC_OK_200); |
|||
r.setMessage(msg); |
|||
r.setResult(data); |
|||
return r; |
|||
} |
|||
|
|||
public static<T> Result<T> error(String msg, T data) { |
|||
Result<T> r = new Result<T>(); |
|||
r.setSuccess(false); |
|||
r.setCode(CommonConstant.SC_INTERNAL_SERVER_ERROR_500); |
|||
r.setMessage(msg); |
|||
r.setResult(data); |
|||
return r; |
|||
} |
|||
|
|||
public static<T> Result<T> ERROR(String msg) { |
|||
return ERROR(CommonConstant.SC_INTERNAL_SERVER_ERROR_500, msg); |
|||
} |
|||
public static<T> Result<T> ERROR(int code, String msg) { |
|||
Result<T> r = new Result<>(); |
|||
r.setCode(code); |
|||
r.setMessage(msg); |
|||
r.setSuccess(false); |
|||
return r; |
|||
} |
|||
public static Result<Object> error(String msg) { |
|||
return error(CommonConstant.SC_INTERNAL_SERVER_ERROR_500, msg); |
|||
} |
|||
public static Result<Object> error(int code, String msg) { |
|||
Result<Object> r = new Result<>(); |
|||
r.setCode(code); |
|||
r.setMessage(msg); |
|||
r.setSuccess(false); |
|||
return r; |
|||
} |
|||
|
|||
public Result<T> error500(String message) { |
|||
this.message = message; |
|||
this.code = CommonConstant.SC_INTERNAL_SERVER_ERROR_500; |
|||
this.success = false; |
|||
return this; |
|||
} |
|||
/** |
|||
* 无权限访问返回结果 |
|||
*/ |
|||
public static Result<Object> noauth(String msg) { |
|||
return error(CommonConstant.SC_JEECG_NO_AUTHZ, msg); |
|||
} |
|||
|
|||
@JsonIgnore |
|||
private String onlTable; |
|||
|
|||
} |
@ -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; |
|||
|
|||
/** |
|||
* <p> |
|||
* |
|||
* </p> |
|||
* |
|||
* @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; |
|||
|
|||
|
|||
} |
@ -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; |
|||
} |
@ -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; |
|||
} |
@ -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; |
|||
} |
@ -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; |
|||
} |
@ -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; |
|||
} |
@ -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<DtDeviceInfo> { |
|||
|
|||
} |
@ -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<MsAlarmSettings> { |
|||
|
|||
|
|||
} |
@ -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<MsCameraSetting> { |
|||
public boolean deleteByMainId(@Param("mainId") String mainId); |
|||
|
|||
public List<MsCameraSetting> selectByMainId(@Param("mainId") String mainId); |
|||
|
|||
public List<MsCameraSetting> selectAllSetting(); |
|||
|
|||
//public List<MsCameraSettingVo> selectSettingVoList();
|
|||
|
|||
//public void updateLatAndLonBySiteId(MsCameraSite msCameraSite);
|
|||
|
|||
} |
@ -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<MsModelPosition> { |
|||
|
|||
} |
@ -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<MsModelTrajectory> { |
|||
|
|||
public boolean deleteByMainId(@Param("mainId") String mainId); |
|||
|
|||
public List<MsModelTrajectory> selectByMainId(@Param("mainId") String mainId); |
|||
} |
@ -0,0 +1,6 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
|||
<mapper namespace="com.zgx.iot.mapper.DtDeviceInfoMapper"> |
|||
|
|||
|
|||
</mapper> |
@ -0,0 +1,6 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
|||
<mapper namespace="com.zgx.iot.mapper.MsAlarmSettingsMapper"> |
|||
|
|||
|
|||
</mapper> |
@ -0,0 +1,38 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
|||
<mapper namespace="com.zgx.iot.mapper.MsCameraSettingMapper"> |
|||
<delete id="deleteByMainId" parameterType="java.lang.String"> |
|||
DELETE |
|||
FROM ms_camera_setting |
|||
WHERE |
|||
site_id = #{mainId} |
|||
</delete> |
|||
|
|||
<select id="selectByMainId" parameterType="java.lang.String" |
|||
resultType="com.zgx.iot.entity.MsCameraSetting"> |
|||
SELECT * |
|||
FROM ms_camera_setting |
|||
WHERE |
|||
site_id = #{mainId} |
|||
</select> |
|||
|
|||
<select id="selectAllSetting" resultType="com.zgx.iot.entity.MsCameraSetting"> |
|||
select id, site_id, camera_name |
|||
from ms_camera_setting |
|||
</select> |
|||
|
|||
<!-- <select id="selectSettingVoList" resultType="com.zgx.modules.military.vo.MsCameraSettingVo"> |
|||
select b.sitename,a.* from ms_camera_setting a LEFT JOIN ms_camera_site b ON a.site_id = b.id |
|||
</select> |
|||
|
|||
<update id="updateLatAndLonBySiteId" parameterType="com.zgx.modules.military.entity.MsCameraSite"> |
|||
update ms_camera_setting |
|||
<set> |
|||
-- noop |
|||
id = #{id}, |
|||
<if test="latitude!= null">latitude=#{latitude},</if> |
|||
<if test="longitude!= null">longitude=#{longitude},</if> |
|||
</set> |
|||
where site_id=#{id} |
|||
</update>--> |
|||
</mapper> |
@ -0,0 +1,5 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
|||
<mapper namespace="com.zgx.iot.mapper.MsModelPositionMapper"> |
|||
|
|||
</mapper> |
@ -0,0 +1,16 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
|||
<mapper namespace="com.zgx.iot.mapper.MsModelTrajectoryMapper"> |
|||
|
|||
<delete id="deleteByMainId" parameterType="java.lang.String"> |
|||
DELETE |
|||
FROM ms_model_trajectory |
|||
WHERE |
|||
model_position_id = #{mainId} </delete> |
|||
|
|||
<select id="selectByMainId" parameterType="java.lang.String" resultType="com.zgx.iot.entity.MsModelTrajectory"> |
|||
SELECT * |
|||
FROM ms_model_trajectory |
|||
WHERE |
|||
model_position_id = #{mainId} </select> |
|||
</mapper> |
@ -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<WebSocket> webSockets = new CopyOnWriteArraySet<>(); |
|||
private static Map<String, Session> sessionPool = new HashMap<String, Session>(); |
|||
|
|||
|
|||
@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); |
|||
} |
|||
} |
|||
|
|||
} |
@ -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();*/ |
|||
} |
|||
} |
@ -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()); |
|||
} |
|||
} |
|||
} |
@ -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()); |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
|
|||
|
@ -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<DtDeviceInfo> photoelectricLambdaQueryWrapper = new LambdaQueryWrapper<>(); |
|||
photoelectricLambdaQueryWrapper.eq(DtDeviceInfo::getDeviceType, DeviceType.PHOTOELECTRIC.getValue()) //光电类型
|
|||
.eq(DtDeviceInfo::getDeviceStatus, 1);//1-启用状态
|
|||
List<DtDeviceInfo> 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<MsCameraSetting> cameraSettingLambdaQueryWrapper = new LambdaQueryWrapper<>(); |
|||
cameraSettingLambdaQueryWrapper.eq(MsCameraSetting::getType, 1)//1-球机类型
|
|||
.eq(MsCameraSetting::getStatus, 0);//0-启用状态
|
|||
List<MsCameraSetting> 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<MsCameraSetting> photoelectricLambdaQueryWrapper = new LambdaQueryWrapper<>(); |
|||
photoelectricLambdaQueryWrapper.eq(MsCameraSetting::getType, 3) //3-光电类型
|
|||
.eq(MsCameraSetting::getStatus, 1);//1-启用状态
|
|||
List<MsCameraSetting> 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<MsCameraSetting> cameraSettingLambdaQueryWrapper = new LambdaQueryWrapper<>(); |
|||
cameraSettingLambdaQueryWrapper.eq(MsCameraSetting::getType, 1)//1-球机类型
|
|||
.eq(MsCameraSetting::getStatus, 1);//1-启用状态
|
|||
List<MsCameraSetting> 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<MsCameraSetting> photoelectricLambdaQueryWrapper = new LambdaQueryWrapper<>(); |
|||
photoelectricLambdaQueryWrapper.eq(MsCameraSetting::getType, CameraType.GUANGDIAN.getValue()); //3-光电类型
|
|||
// .eq(MsCameraSetting::getStatus, 0);//0-启用状态
|
|||
List<MsCameraSetting> 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<MsCameraSetting> cameraSettingLambdaQueryWrapper = new LambdaQueryWrapper<>(); |
|||
cameraSettingLambdaQueryWrapper.eq(MsCameraSetting::getType, CameraType.QIUJI.getValue())//1-球机类型
|
|||
.eq(MsCameraSetting::getStatus, 0);//启用状态
|
|||
List<MsCameraSetting> 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<MsCameraSetting> queryWrapper = new LambdaQueryWrapper<MsCameraSetting>().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<ZSetOperations.TypedTuple<Object>> removeIds = redisUtil.zRangeByScoreWithScores("updatedIds", 0, now); |
|||
List<Integer> 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<MsCameraSetting> 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<MsCameraSetting> msCameraSettingLambdaQueryWrapper = new LambdaQueryWrapper<>(); |
|||
msCameraSettingLambdaQueryWrapper.eq(MsCameraSetting::getType, CameraType.QIUJI.getValue())//1-球机类型
|
|||
.eq(MsCameraSetting::getStatus, 0);//启用状态
|
|||
List<MsCameraSetting> 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()); |
|||
} |
|||
} |
|||
|
|||
} |
|||
} |
@ -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; |
|||
|
|||
} |
@ -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<String, NettyService<? extends NettyBaseSocket>> nettyServiceMap = new ConcurrentHashMap<>(16); |
|||
// 启动服务
|
|||
|
|||
/** |
|||
* 启动 tcp 服务端 |
|||
* |
|||
* @param deviceInfo 设备信息 {@link NettyDeviceInfo} |
|||
* @param pipelineFactoryType tcp 管道, 对传输的数据进行相关处理 |
|||
* @return udp service |
|||
*/ |
|||
public NettyService<? extends NettyBaseSocket> startupTcpService( |
|||
NettyDeviceInfo deviceInfo, |
|||
Class<? extends TcpPipelineFactory<TcpServiceByNetty>> pipelineFactoryType |
|||
) { |
|||
String key = deviceInfo.getId(); |
|||
// 判断 已经启动服务中是否已经存在
|
|||
if (nettyServiceMap.containsKey(key)) { |
|||
// 存在
|
|||
// 直接返回获取到的服务
|
|||
return nettyServiceMap.get(key); |
|||
} |
|||
// 不存在
|
|||
TcpServiceByNetty service = new TcpServiceByNetty(deviceInfo, pipelineFactoryType); |
|||
try { |
|||
service.startup(); |
|||
// 存储到 nettyServiceMap 里
|
|||
NettyService<TcpServiceByNetty> 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 <T> TcpClientByNetty startupTcpClient( |
|||
NettyDeviceInfo deviceInfo, |
|||
Class<? extends TcpPipelineFactory<TcpClientByNetty>> 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<TcpClientByNetty> 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<? extends NettyBaseSocket> startupUdpClient(NettyDeviceInfo deviceInfo, Class<? extends UdpPipelineFactory<UdpClientByNetty>> pipelineFactoryType) { |
|||
String key = deviceInfo.getId(); |
|||
// 判断 已经启动服务中是否已经存在
|
|||
if (nettyServiceMap.containsKey(key)) { |
|||
// 存在
|
|||
// 直接返回获取到的服务
|
|||
return nettyServiceMap.get(key); |
|||
} |
|||
// 不存在
|
|||
UdpClientByNetty client = new UdpClientByNetty(deviceInfo, pipelineFactoryType); |
|||
try { |
|||
// 启动服务
|
|||
client.startup(); |
|||
// 存储到 nettyServiceMap 里
|
|||
NettyService<UdpClientByNetty> 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<? extends NettyBaseSocket> startupUdpService( |
|||
NettyDeviceInfo deviceInfo, |
|||
Class<? extends UdpPipelineFactory<UdpServiceByNetty>> pipelineFactoryType |
|||
) { |
|||
String key = deviceInfo.getId(); |
|||
// 判断 已经启动服务中是否已经存在
|
|||
if (nettyServiceMap.containsKey(key)) { |
|||
// 存在
|
|||
// 直接返回获取到的服务
|
|||
return nettyServiceMap.get(key); |
|||
} |
|||
// 不存在
|
|||
UdpServiceByNetty service = new UdpServiceByNetty(pipelineFactoryType, deviceInfo); |
|||
try { |
|||
// 启动服务
|
|||
service.startup(); |
|||
// 存储到 nettyServiceMap 里
|
|||
NettyService<UdpServiceByNetty> 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<? extends NettyBaseSocket> nettyService = nettyServiceMap.get(key); |
|||
nettyService.shutdown(); |
|||
} |
|||
// 服务不存在 失败
|
|||
return false; |
|||
} |
|||
|
|||
|
|||
public boolean stopChannel(String key, InetSocketAddress address) { |
|||
if (nettyServiceMap.containsKey(key)) { |
|||
NettyService<? extends NettyBaseSocket> nettyService = nettyServiceMap.get(key); |
|||
return nettyService.stopChannel(address); |
|||
} else { |
|||
logger.error("找不到 netty service!"); |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
|
|||
public Result<NettyService<? extends NettyBaseSocket>> 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!"); |
|||
} |
|||
} |
|||
} |
@ -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; |
|||
|
|||
} |
@ -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<NettyBaseSocket> NETTY_CHANNEL_SOCKET_KEY = |
|||
AttributeKey.valueOf("netty.channel.socket"); |
|||
public static final AttributeKey<InetSocketAddress> NETTY_SERVICE_REMOTE_ADDR_KEY = |
|||
AttributeKey.valueOf("netty.service.remote.addr"); |
|||
} |
@ -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); |
|||
} |
@ -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<Integer, String> 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<Integer, String> 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<Integer, String> 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<Integer, String> 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<Integer, String> 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<Integer, List<String>> 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<String> 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(); |
|||
} |
|||
} |
@ -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; |
|||
} |
|||
} |
|||
|
|||
} |
@ -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<String> getNameAsList() { |
|||
List<String> 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<String> getNameAsList() { |
|||
List<String> list = new ArrayList<>(16); |
|||
list.add(PREFIX); |
|||
list.add(name); |
|||
return list; |
|||
} |
|||
} |
|||
} |
@ -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<Integer, deviceType> 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<Integer, faultType> 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<Integer, alarmType> 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<Integer, alarmReason> map = new HashMap<>(); |
|||
|
|||
static { |
|||
for (alarmReason alarmReason : alarmReason.values()) { |
|||
map.put(alarmReason.getValue(), alarmReason); |
|||
} |
|||
} |
|||
|
|||
public static alarmReason valueOf(int value) { |
|||
return map.get(value); |
|||
} |
|||
} |
|||
} |
@ -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); |
|||
} |
|||
} |
@ -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); |
|||
} |
|||
} |
@ -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); |
|||
} |
|||
} |
@ -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); |
|||
} |
|||
|
|||
} |
@ -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}. |
|||
* <p> |
|||
* 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
|
|||
} |
@ -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<DatagramPacket> { |
|||
private static final String LOCAL_HOST_ADDR = "127.0.0.1"; |
|||
|
|||
@Override |
|||
protected void decode(ChannelHandlerContext ctx, DatagramPacket packet, List<Object> list) { |
|||
ByteBuf byteBuf = packet.content(); |
|||
int readableBytes = byteBuf.readableBytes(); |
|||
if (readableBytes <= 0) { |
|||
return; |
|||
} |
|||
Attribute<InetSocketAddress> 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()); |
|||
}*/ |
|||
} |
|||
} |
@ -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<DatagramPacket> { |
|||
private static final String LOCAL_HOST_ADDR = "127.0.0.1"; |
|||
|
|||
@Override |
|||
protected void decode(ChannelHandlerContext ctx, DatagramPacket packet, List<Object> list) { |
|||
/* ByteBuf byteBuf = packet.content(); |
|||
int readableBytes = byteBuf.readableBytes(); |
|||
if (readableBytes <= 0) { |
|||
return; |
|||
} |
|||
Attribute<InetSocketAddress> 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()); |
|||
}*/ |
|||
} |
|||
} |
@ -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<Object> list) throws Exception { |
|||
int size = byteBuf.readableBytes(); |
|||
while (flag) { |
|||
if (byteBuf.readableBytes()<size){ |
|||
byteBuf.resetReaderIndex(); |
|||
return; |
|||
} |
|||
System.out.println(size); |
|||
byte[] data = new byte[size]; |
|||
byteBuf.readBytes(data); |
|||
this.len = data.length; |
|||
this.data = new byte[this.len]; |
|||
System.arraycopy(data, 0, this.data, 0, this.len); |
|||
RadarRESPackageModel radarRESPackageModel = this.dealProcess(this.data); |
|||
log.info("处理好的数据:"+radarRESPackageModel); |
|||
if (radarRESPackageModel!=null){ |
|||
list.add(radarRESPackageModel); |
|||
log.info("list添加了"); |
|||
} |
|||
byteBuf.skipBytes(byteBuf.readableBytes()); |
|||
byteBuf.markReaderIndex(); |
|||
this.data = null; |
|||
} |
|||
} |
|||
private RadarRESPackageModel dealProcess(final byte[] bytes) { |
|||
log.info(Arrays.toString(bytes)); |
|||
if (this.byte_buffer == null) { |
|||
this.byte_buffer = bytes; |
|||
} else if (this.byte_buffer.length > 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; |
|||
} |
|||
} |
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue