Browse Source

first commit

xieshengjie 3 years ago
commit
13246c612e
54 changed files with 3668 additions and 0 deletions
  1. 33 0
      .gitignore
  2. 117 0
      .mvn/wrapper/MavenWrapperDownloader.java
  3. BIN
      .mvn/wrapper/maven-wrapper.jar
  4. 2 0
      .mvn/wrapper/maven-wrapper.properties
  5. 310 0
      mvnw
  6. 182 0
      mvnw.cmd
  7. 100 0
      pom.xml
  8. 19 0
      src/main/java/com/gyee/wisdom/adapter/WisdomAdapterApplication.java
  9. 18 0
      src/main/java/com/gyee/wisdom/adapter/backwork/BackWorkApplication.java
  10. 74 0
      src/main/java/com/gyee/wisdom/adapter/common/config/HiveConfiguration.java
  11. 100 0
      src/main/java/com/gyee/wisdom/adapter/common/config/TaosConfiguration.java
  12. 56 0
      src/main/java/com/gyee/wisdom/adapter/common/config/ThreadPoolTaskConfig.java
  13. 16 0
      src/main/java/com/gyee/wisdom/adapter/common/constant/Constant.java
  14. 8 0
      src/main/java/com/gyee/wisdom/adapter/common/constant/Interpolation.java
  15. 59 0
      src/main/java/com/gyee/wisdom/adapter/common/exception/AdviceException.java
  16. 19 0
      src/main/java/com/gyee/wisdom/adapter/common/exception/CustomException.java
  17. 22 0
      src/main/java/com/gyee/wisdom/adapter/common/exception/WisdomException.java
  18. 60 0
      src/main/java/com/gyee/wisdom/adapter/common/result/JsonResult.java
  19. 74 0
      src/main/java/com/gyee/wisdom/adapter/common/result/ResultCode.java
  20. 37 0
      src/main/java/com/gyee/wisdom/adapter/common/util/DataUtil.java
  21. 40 0
      src/main/java/com/gyee/wisdom/adapter/common/util/TaosCovertUtil.java
  22. 231 0
      src/main/java/com/gyee/wisdom/adapter/controller/TsDataController.java
  23. 359 0
      src/main/java/com/gyee/wisdom/adapter/dao/TaosHistoryDao.java
  24. 287 0
      src/main/java/com/gyee/wisdom/adapter/dao/TaosLatestDao.java
  25. 94 0
      src/main/java/com/gyee/wisdom/adapter/dao/TaskCallable.java
  26. 71 0
      src/main/java/com/gyee/wisdom/adapter/model/TsPointEntity.java
  27. 46 0
      src/main/java/com/gyee/wisdom/adapter/model/adapter/BaseTsQuery.java
  28. 38 0
      src/main/java/com/gyee/wisdom/adapter/model/adapter/BasicTsData.java
  29. 55 0
      src/main/java/com/gyee/wisdom/adapter/model/adapter/BasicTsPoint.java
  30. 19 0
      src/main/java/com/gyee/wisdom/adapter/model/adapter/BooleanTsData.java
  31. 30 0
      src/main/java/com/gyee/wisdom/adapter/model/adapter/DoubleStatData.java
  32. 33 0
      src/main/java/com/gyee/wisdom/adapter/model/adapter/DoubleTsData.java
  33. 27 0
      src/main/java/com/gyee/wisdom/adapter/model/adapter/GeneralTsData.java
  34. 18 0
      src/main/java/com/gyee/wisdom/adapter/model/adapter/IntegerTsData.java
  35. 24 0
      src/main/java/com/gyee/wisdom/adapter/model/adapter/LongTsData.java
  36. 24 0
      src/main/java/com/gyee/wisdom/adapter/model/adapter/StringTsData.java
  37. 5 0
      src/main/java/com/gyee/wisdom/adapter/model/adapter/ToData.java
  38. 15 0
      src/main/java/com/gyee/wisdom/adapter/model/adapter/TsData.java
  39. 14 0
      src/main/java/com/gyee/wisdom/adapter/model/adapter/TsDataType.java
  40. 18 0
      src/main/java/com/gyee/wisdom/adapter/model/adapter/TsPoint.java
  41. 41 0
      src/main/java/com/gyee/wisdom/adapter/model/adapter/TsPointData.java
  42. 23 0
      src/main/java/com/gyee/wisdom/adapter/model/adapter/TsPointDataList.java
  43. 23 0
      src/main/java/com/gyee/wisdom/adapter/model/adapter/TsQuery.java
  44. 273 0
      src/main/java/com/gyee/wisdom/adapter/server/taos/ThingsPointService.java
  45. 211 0
      src/main/java/com/gyee/wisdom/adapter/server/taos/TsDataService.java
  46. 193 0
      src/main/java/com/gyee/wisdom/adapter/server/taos/TsPointService.java
  47. 7 0
      src/main/java/com/gyee/wisdom/adapter/timeseries/TaosDao.java
  48. 17 0
      src/main/java/com/gyee/wisdom/adapter/timeseries/dao/IDataChangeDao.java
  49. 26 0
      src/main/java/com/gyee/wisdom/adapter/timeseries/dao/IHistoryDao.java
  50. 25 0
      src/main/java/com/gyee/wisdom/adapter/timeseries/dao/ILatestDao.java
  51. 18 0
      src/main/java/com/gyee/wisdom/adapter/timeseries/dao/IThingsPointDao.java
  52. 44 0
      src/main/resources/application.yml
  53. BIN
      src/main/resources/lib/ImpalaJDBC41.jar
  54. 13 0
      src/test/java/com/gyee/wisdom/adapter/WisdomAdapterApplicationTests.java

+ 33 - 0
.gitignore

@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/

+ 117 - 0
.mvn/wrapper/MavenWrapperDownloader.java

@@ -0,0 +1,117 @@
+/*
+ * Copyright 2007-present the original author or authors.
+ *
+ * Licensed 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.
+ */
+import java.net.*;
+import java.io.*;
+import java.nio.channels.*;
+import java.util.Properties;
+
+public class MavenWrapperDownloader {
+
+    private static final String WRAPPER_VERSION = "0.5.6";
+    /**
+     * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
+     */
+    private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
+        + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
+
+    /**
+     * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
+     * use instead of the default one.
+     */
+    private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
+            ".mvn/wrapper/maven-wrapper.properties";
+
+    /**
+     * Path where the maven-wrapper.jar will be saved to.
+     */
+    private static final String MAVEN_WRAPPER_JAR_PATH =
+            ".mvn/wrapper/maven-wrapper.jar";
+
+    /**
+     * Name of the property which should be used to override the default download url for the wrapper.
+     */
+    private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
+
+    public static void main(String args[]) {
+        System.out.println("- Downloader started");
+        File baseDirectory = new File(args[0]);
+        System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
+
+        // If the maven-wrapper.properties exists, read it and check if it contains a custom
+        // wrapperUrl parameter.
+        File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
+        String url = DEFAULT_DOWNLOAD_URL;
+        if(mavenWrapperPropertyFile.exists()) {
+            FileInputStream mavenWrapperPropertyFileInputStream = null;
+            try {
+                mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
+                Properties mavenWrapperProperties = new Properties();
+                mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
+                url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
+            } catch (IOException e) {
+                System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
+            } finally {
+                try {
+                    if(mavenWrapperPropertyFileInputStream != null) {
+                        mavenWrapperPropertyFileInputStream.close();
+                    }
+                } catch (IOException e) {
+                    // Ignore ...
+                }
+            }
+        }
+        System.out.println("- Downloading from: " + url);
+
+        File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
+        if(!outputFile.getParentFile().exists()) {
+            if(!outputFile.getParentFile().mkdirs()) {
+                System.out.println(
+                        "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
+            }
+        }
+        System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
+        try {
+            downloadFileFromURL(url, outputFile);
+            System.out.println("Done");
+            System.exit(0);
+        } catch (Throwable e) {
+            System.out.println("- Error downloading");
+            e.printStackTrace();
+            System.exit(1);
+        }
+    }
+
+    private static void downloadFileFromURL(String urlString, File destination) throws Exception {
+        if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
+            String username = System.getenv("MVNW_USERNAME");
+            char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
+            Authenticator.setDefault(new Authenticator() {
+                @Override
+                protected PasswordAuthentication getPasswordAuthentication() {
+                    return new PasswordAuthentication(username, password);
+                }
+            });
+        }
+        URL website = new URL(urlString);
+        ReadableByteChannel rbc;
+        rbc = Channels.newChannel(website.openStream());
+        FileOutputStream fos = new FileOutputStream(destination);
+        fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
+        fos.close();
+        rbc.close();
+    }
+
+}

BIN
.mvn/wrapper/maven-wrapper.jar


+ 2 - 0
.mvn/wrapper/maven-wrapper.properties

@@ -0,0 +1,2 @@
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.1/apache-maven-3.8.1-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar

+ 310 - 0
mvnw

@@ -0,0 +1,310 @@
+#!/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.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+#   JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+#   M2_HOME - location of maven2's installed home dir
+#   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 /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
+        export JAVA_HOME="`/usr/libexec/java_home`"
+      else
+        export JAVA_HOME="/Library/Java/Home"
+      fi
+    fi
+    ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+  if [ -r /etc/gentoo-release ] ; then
+    JAVA_HOME=`java-config --jre-home`
+  fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+  ## resolve links - $0 may be a link to maven's home
+  PRG="$0"
+
+  # need this for relative symlinks
+  while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+      PRG="$link"
+    else
+      PRG="`dirname "$PRG"`/$link"
+    fi
+  done
+
+  saveddir=`pwd`
+
+  M2_HOME=`dirname "$PRG"`/..
+
+  # make it fully qualified
+  M2_HOME=`cd "$M2_HOME" && pwd`
+
+  cd "$saveddir"
+  # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME=`cygpath --unix "$M2_HOME"`
+  [ -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 "$M2_HOME" ] &&
+    M2_HOME="`(cd "$M2_HOME"; pwd)`"
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME="`(cd "$JAVA_HOME"; 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="`which 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
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# 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/.."; pwd`
+    fi
+    # end of workaround
+  done
+  echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+  if [ -f "$1" ]; then
+    echo "$(tr -s '\n' ' ' < "$1")"
+  fi
+}
+
+BASE_DIR=`find_maven_basedir "$(pwd)"`
+if [ -z "$BASE_DIR" ]; then
+  exit 1;
+fi
+
+##########################################################################################
+# 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.
+##########################################################################################
+if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Found .mvn/wrapper/maven-wrapper.jar"
+    fi
+else
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
+    fi
+    if [ -n "$MVNW_REPOURL" ]; then
+      jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+    else
+      jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+    fi
+    while IFS="=" read key value; do
+      case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
+      esac
+    done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Downloading from: $jarUrl"
+    fi
+    wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
+    if $cygwin; then
+      wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
+    fi
+
+    if command -v wget > /dev/null; then
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Found wget ... using wget"
+        fi
+        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+            wget "$jarUrl" -O "$wrapperJarPath"
+        else
+            wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
+        fi
+    elif command -v curl > /dev/null; then
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Found curl ... using curl"
+        fi
+        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+            curl -o "$wrapperJarPath" "$jarUrl" -f
+        else
+            curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+        fi
+
+    else
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Falling back to using Java to download"
+        fi
+        javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+        # For Cygwin, switch paths to Windows format before running javac
+        if $cygwin; then
+          javaClass=`cygpath --path --windows "$javaClass"`
+        fi
+        if [ -e "$javaClass" ]; then
+            if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+                if [ "$MVNW_VERBOSE" = true ]; then
+                  echo " - Compiling MavenWrapperDownloader.java ..."
+                fi
+                # Compiling the Java class
+                ("$JAVA_HOME/bin/javac" "$javaClass")
+            fi
+            if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+                # Running the downloader
+                if [ "$MVNW_VERBOSE" = true ]; then
+                  echo " - Running MavenWrapperDownloader.java ..."
+                fi
+                ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
+            fi
+        fi
+    fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
+if [ "$MVNW_VERBOSE" = true ]; then
+  echo $MAVEN_PROJECTBASEDIR
+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 "$M2_HOME" ] &&
+    M2_HOME=`cygpath --path --windows "$M2_HOME"`
+  [ -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
+
+exec "$JAVACMD" \
+  $MAVEN_OPTS \
+  -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+  "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+  ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"

+ 182 - 0
mvnw.cmd

@@ -0,0 +1,182 @@
+@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 Maven Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@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 "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
+if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\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 DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+
+FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+    IF "%%A"=="wrapperUrl" SET DOWNLOAD_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 DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+    )
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Couldn't find %WRAPPER_JAR%, downloading it ...
+        echo Downloading from: %DOWNLOAD_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('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
+		"}"
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Finished downloading %WRAPPER_JAR%
+    )
+)
+@REM End of extension
+
+@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 "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
+if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\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%
+
+exit /B %ERROR_CODE%

+ 100 - 0
pom.xml

@@ -0,0 +1,100 @@
+<?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.5.1</version>
+        <relativePath/> <!-- lookup parent from repository -->
+    </parent>
+    <groupId>com.gyee.wisdom.adapter</groupId>
+    <artifactId>WisdomAdapter</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <name>WisdomAdapter</name>
+    <description>Big data adapter project for Spring Boot</description>
+    <properties>
+        <java.version>1.8</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-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-devtools</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>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-cache</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.taosdata.jdbc</groupId>
+            <artifactId>taos-jdbcdriver</artifactId>
+            <version>2.0.18</version>
+        </dependency>
+        <!-- 模板引擎 -->
+        <dependency>
+            <groupId>org.apache.velocity</groupId>
+            <artifactId>velocity-engine-core</artifactId>
+            <version>2.0</version>
+        </dependency>
+
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid-spring-boot-starter</artifactId>
+            <version>1.2.5</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.76</version>
+        </dependency>
+
+        <!--加载lib下的包-->
+        <dependency>
+            <groupId>ImpalaJDBC</groupId>
+            <artifactId>ImpalaJDBC</artifactId>
+            <version>41</version>
+            <scope>system</scope>
+            <systemPath>${project.basedir}/src/main/resources/lib/ImpalaJDBC41.jar</systemPath>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <includeSystemScope>true</includeSystemScope>
+                    <excludes>
+                        <exclude>
+                            <groupId>org.projectlombok</groupId>
+                            <artifactId>lombok</artifactId>
+                        </exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 19 - 0
src/main/java/com/gyee/wisdom/adapter/WisdomAdapterApplication.java

@@ -0,0 +1,19 @@
+package com.gyee.wisdom.adapter;
+
+import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+@EnableCaching
+@EnableScheduling
+@SpringBootApplication(exclude={DataSourceAutoConfiguration.class,  DruidDataSourceAutoConfigure.class})
+public class WisdomAdapterApplication {
+
+	public static void main(String[] args) {
+		SpringApplication.run(WisdomAdapterApplication.class, args);
+	}
+
+}

+ 18 - 0
src/main/java/com/gyee/wisdom/adapter/backwork/BackWorkApplication.java

@@ -0,0 +1,18 @@
+package com.gyee.wisdom.adapter.backwork;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.stereotype.Component;
+
+
+@Slf4j
+@Component
+public class BackWorkApplication implements ApplicationRunner {
+
+
+    @Override
+    public void run(ApplicationArguments args) throws Exception {
+
+    }
+}

+ 74 - 0
src/main/java/com/gyee/wisdom/adapter/common/config/HiveConfiguration.java

@@ -0,0 +1,74 @@
+package com.gyee.wisdom.adapter.common.config;
+
+
+import com.cloudera.impala.jdbc41.DataSource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.stereotype.Component;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+
+@Slf4j
+@Configuration
+@Component
+public class HiveConfiguration {
+
+    @Value("${windturbine.point.table_name:gyee_tspoint}")
+    public String tableName;
+
+    @Value("${hive.url:jdbc:impala://192.168.1.61:21050/default}")
+    private String url;
+
+    @Value("${hive.jdbc_driver:com.cloudera.impala.jdbc41.Driver}")
+    private String driverClass;
+
+
+//    private static DataSource dataSource = null;
+//
+//
+//    public Connection getConnect() {
+//        if (null == dataSource) {
+//            dataSource = getDataSource();
+//        }
+//
+//        try {
+//            return dataSource.getConnection();
+//        } catch (SQLException e) {
+//            e.printStackTrace();
+//        }
+//
+//        return null;
+//    }
+//
+//
+//    private DataSource getDataSource() {
+//        DataSource dataSource = new DataSource();
+//        dataSource.setURL(url);
+//
+//        log.info("Hive数据源初始化成功……");
+//
+//        return dataSource;
+//    }
+
+
+    public Connection getConnection() {
+
+        Connection conn = null;
+
+        if (conn == null)
+            try {
+                Class.forName(driverClass);
+
+                conn = DriverManager.getConnection(url);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+
+        return conn;
+    }
+}

+ 100 - 0
src/main/java/com/gyee/wisdom/adapter/common/config/TaosConfiguration.java

@@ -0,0 +1,100 @@
+package com.gyee.wisdom.adapter.common.config;
+
+import com.alibaba.druid.pool.DruidDataSource;
+import com.taosdata.jdbc.TSDBDriver;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.stereotype.Component;
+
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Properties;
+
+
+@Slf4j
+@Configuration
+@Component
+public class TaosConfiguration {
+
+    @Value("${taos.server_ip:127.0.0.1}")
+    private String serverIp;
+
+    @Value("${taos.server_port:6030}")
+    private int serverPort;
+
+    @Value("${taos.user_name:root}")
+    private String userName;
+
+    @Value("${taos.password:taosdata}")
+    private String password;
+
+    @Value("${taos.pool_size:2}")
+    private int poolSize;
+
+    @Value("${taos.max_pool_size:3}")
+    private int maxPoolSize;
+
+    private static DataSource dataSource = null;
+
+
+    public Connection getConnect() {
+        if (null == dataSource) {
+            dataSource = getDataSource();
+        }
+
+        try {
+            return dataSource.getConnection();
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+
+
+//    private Connection getConnection(){
+//        Connection connection = null;
+//
+//        try {
+//            Class.forName("com.taosdata.jdbc.TSDBDriver");
+//            String jdbcUrl = "jdbc:TAOS://" + serverIp + ":" + serverPort + "/test?user=" + userName + "&password=" + password;
+//            Properties connProps = new Properties();
+//            connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
+//            connProps.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
+//            connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
+//            connection = DriverManager.getConnection(jdbcUrl, connProps);
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//        }
+//
+//        log.info("涛思数据库已连接.....");
+//        return connection;
+//    }
+
+
+    private DataSource getDataSource() {
+        final String url = "jdbc:TAOS://" + serverIp + ":" + serverPort;
+
+        DruidDataSource dataSource = new DruidDataSource();
+        // jdbc properties
+        dataSource.setDriverClassName("com.taosdata.jdbc.TSDBDriver");
+        dataSource.setUrl(url);
+        dataSource.setUsername(userName);
+        dataSource.setPassword(password);
+        // pool configurations
+        dataSource.setInitialSize(poolSize);
+        dataSource.setMinIdle(poolSize);
+        dataSource.setMaxActive(maxPoolSize);
+        dataSource.setMaxWait(30000);
+        dataSource.setRemoveAbandoned(true);
+        dataSource.setRemoveAbandonedTimeoutMillis(60000);
+        dataSource.setValidationQuery("select server_status()");
+
+        log.info("涛思数据源初始化成功……");
+
+        return dataSource;
+    }
+}

+ 56 - 0
src/main/java/com/gyee/wisdom/adapter/common/config/ThreadPoolTaskConfig.java

@@ -0,0 +1,56 @@
+package com.gyee.wisdom.adapter.common.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.ThreadPoolExecutor;
+
+@Configuration
+public class ThreadPoolTaskConfig {
+    /**
+     *   默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,
+     *	当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中;
+     *  当队列满了,就继续创建线程,当线程数量大于等于maxPoolSize后,开始使用拒绝策略拒绝
+     */
+
+    /** 核心线程数(默认线程数) */
+    private static final int corePoolSize = 40;
+    /** 最大线程数 */
+    private static final int maxPoolSize = 80;
+    /** 允许线程空闲时间(单位:默认为秒) */
+    private static final int keepAliveTime = 60;
+    /** 缓冲队列大小 */
+    private static final int queueCapacity = 300;
+    /** 允许等待最长时间 */
+    private static final int awaitTime = 15;
+    /** 线程池名前缀 */
+    private static final String threadNamePrefix = "GYEE-Thread-";
+
+    private ThreadPoolTaskExecutor executor;
+
+    public ThreadPoolTaskExecutor getExecutor(){
+        if (executor == null)
+            executor = taskExecutor();
+
+        return executor;
+    }
+
+
+    private ThreadPoolTaskExecutor taskExecutor(){
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        executor.setCorePoolSize(corePoolSize);
+        executor.setMaxPoolSize(maxPoolSize);
+        executor.setQueueCapacity(queueCapacity);
+        executor.setKeepAliveSeconds(keepAliveTime);
+        executor.setThreadNamePrefix(threadNamePrefix);
+        executor.setAwaitTerminationSeconds(awaitTime);
+
+        // 线程池对拒绝任务的处理策略
+        // CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务
+        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
+        // 初始化
+        executor.initialize();
+        return executor;
+    }
+
+}

+ 16 - 0
src/main/java/com/gyee/wisdom/adapter/common/constant/Constant.java

@@ -0,0 +1,16 @@
+package com.gyee.wisdom.adapter.common.constant;
+
+/**
+ * 字符串常量池
+ */
+public class Constant {
+
+    private Constant() {
+    }
+
+    public static final String THING_TYPE = "thing_type";//主题表
+    public static final String THING_ID = "thing_id";
+
+    public static final String UNIFORM_CODE = "uniform_code";
+    public static final String DATA_TYPE = "data_type";
+}

+ 8 - 0
src/main/java/com/gyee/wisdom/adapter/common/constant/Interpolation.java

@@ -0,0 +1,8 @@
+package com.gyee.wisdom.adapter.common.constant;
+
+
+public enum Interpolation {
+    SNAP,   // 历史快照数据
+    INTERPOLATION, //插值
+    RAW    //原始数据
+}

+ 59 - 0
src/main/java/com/gyee/wisdom/adapter/common/exception/AdviceException.java

@@ -0,0 +1,59 @@
+package com.gyee.wisdom.adapter.common.exception;
+
+import com.alibaba.fastjson.JSONObject;
+import com.gyee.wisdom.adapter.common.result.JsonResult;
+import com.gyee.wisdom.adapter.common.result.ResultCode;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+
+@RestControllerAdvice
+public class AdviceException {
+
+    private static Logger logger = LogManager.getLogger(AdviceException.class);
+
+
+    /**
+     * 拦截未知的运行时异常
+     */
+    @ExceptionHandler(Exception.class)
+    public JSONObject runException(Exception e)
+    {
+        logger.error(e.getMessage());
+        return JsonResult.error(ResultCode.ERROR);
+    }
+
+
+    /**
+     * 拦截未知的运行时异常
+     */
+    @ExceptionHandler(NullPointerException.class)
+    public JSONObject nullPointerException(Exception e)
+    {
+        logger.error(e.getMessage());
+        return JsonResult.error(ResultCode.ERROR);
+    }
+
+
+    /**
+     * 拦截自定义异常
+     */
+    @ExceptionHandler(CustomException.class)
+    public JSONObject customException(CustomException e)
+    {
+        logger.error(e.getMessage());
+        return JsonResult.error(e.getCode(), e.getMessage());
+    }
+
+    /**
+     * 拦截自定义异常
+     */
+    @ExceptionHandler(WisdomException.class)
+    public String wisdomException(WisdomException e)
+    {
+        logger.error(e.getMessage());
+        return e.getMessage();
+    }
+}

+ 19 - 0
src/main/java/com/gyee/wisdom/adapter/common/exception/CustomException.java

@@ -0,0 +1,19 @@
+package com.gyee.wisdom.adapter.common.exception;
+
+import com.gyee.wisdom.adapter.common.result.ResultCode;
+import lombok.Data;
+
+@Data
+public class CustomException extends RuntimeException {
+
+    private Integer code;
+    private String message;
+
+    public CustomException(){}
+
+    public CustomException(ResultCode result){
+        super();
+        this.code = result.getCode();
+        this.message = result.getMessage();
+    }
+}

+ 22 - 0
src/main/java/com/gyee/wisdom/adapter/common/exception/WisdomException.java

@@ -0,0 +1,22 @@
+package com.gyee.wisdom.adapter.common.exception;
+
+public class WisdomException extends RuntimeException {
+    public WisdomException() {
+    }
+
+    public WisdomException(String message) {
+        super(message);
+    }
+
+    public WisdomException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public WisdomException(Throwable cause) {
+        super(cause);
+    }
+
+    public WisdomException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+        super(message, cause, enableSuppression, writableStackTrace);
+    }
+}

+ 60 - 0
src/main/java/com/gyee/wisdom/adapter/common/result/JsonResult.java

@@ -0,0 +1,60 @@
+package com.gyee.wisdom.adapter.common.result;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.HashMap;
+
+@Data
+public class JsonResult extends HashMap<String, Object> implements Serializable {
+
+    private Integer code;
+    private String message;
+    private Object data;
+    private ResultCode resultCode;
+
+    public static JSONObject error(){
+        JSONObject json = new JSONObject();
+        json.put("code", ResultCode.SUCCESS.getCode());
+        json.put("msg", ResultCode.SUCCESS.getMessage());
+        return json;
+    }
+
+    public static JSONObject error(ResultCode resultCode){
+        JSONObject json = new JSONObject();
+        json.put("code", resultCode.getCode());
+        json.put("msg", resultCode.getMessage());
+        return json;
+    }
+
+    public static JSONObject error(int code, String message){
+        JSONObject json = new JSONObject();
+        json.put("code", code);
+        json.put("msg", message);
+        return json;
+    }
+
+    public static JSONObject success(){
+        JSONObject json = new JSONObject();
+        json.put("code", ResultCode.SUCCESS.getCode());
+        json.put("msg", ResultCode.SUCCESS.getMessage());
+        return json;
+    }
+
+    public static JSONObject success(ResultCode resultCode){
+        JSONObject json = new JSONObject();
+        json.put("code", resultCode.getCode());
+        json.put("msg", resultCode.getMessage());
+        return json;
+    }
+
+    public static JSONObject successData(ResultCode code, Object data){
+        JSONObject json = new JSONObject();
+        json.put("code", code.getCode());
+        json.put("msg", code.getMessage());
+        json.put("data", data);
+        return json;
+    }
+
+}

+ 74 - 0
src/main/java/com/gyee/wisdom/adapter/common/result/ResultCode.java

@@ -0,0 +1,74 @@
+package com.gyee.wisdom.adapter.common.result;
+
+/*
+ * #1001~1999 区间表示参数错误
+ * #2001~2999 区间表示用户错误
+ * #3001~3999 区间表示权限异常
+ */
+
+public enum ResultCode {
+    /* 成功 */
+    SUCCESS(2000, "成功"),
+
+    /* 默认失败 */
+    ERROR(4004, "失败"),
+    ERROR_CONNECT(4005, "数据库连接异常"),
+    ERROR_DATA(4006, "数据查询失败"),
+
+    /* 参数错误:1000~1999 */
+    PARAM_NOT_VALID(1001, "参数无效"),
+    PARAM_IS_BLANK(1002, "参数为空"),
+    PARAM_TYPE_ERROR(1003, "参数类型错误"),
+    PARAM_NOT_COMPLETE(1004, "参数缺失"),
+
+    /* 用户错误 */
+    USER_NOT_LOGIN(2001, "用户未登录"),
+    USER_ACCOUNT_ERROR(2002, "账号或密码错误"),
+    USER_FAIL_LOGIN(2003, "登录失败"),
+
+    /* 业务错误 */
+    NO_PERMISSION(3001, "没有权限");
+
+    private Integer code;
+    private String message;
+
+    ResultCode(Integer code) {
+        this.code = code;
+    }
+
+    ResultCode(Integer code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    /**
+     * 根据code获取message
+     *
+     * @param code
+     * @return
+     */
+    public static String getMessageByCode(Integer code) {
+        for (ResultCode ele : values()) {
+            if (ele.getCode().equals(code)) {
+                return ele.getMessage();
+            }
+        }
+        return null;
+    }
+}

+ 37 - 0
src/main/java/com/gyee/wisdom/adapter/common/util/DataUtil.java

@@ -0,0 +1,37 @@
+package com.gyee.wisdom.adapter.common.util;
+
+import com.gyee.wisdom.adapter.model.adapter.ToData;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+public abstract class DataUtil {
+
+    private DataUtil() {
+    }
+
+    public static <T> List<T> convertDataList(Collection<? extends ToData<T>> toDataList) {
+        return toDataList.stream().map(ToData::toData).collect(Collectors.toList());
+    }
+
+    public static <T> T getData(ToData<T> data) {
+        return Optional.ofNullable(data).isPresent() ? data.toData() : null;
+    }
+
+    public static String convertStringToSql(String ...content){
+        if (content == null)
+            return null;
+
+        StringBuilder sb = new StringBuilder();
+        for (String data : content){
+            sb.append("'").append(data).append("',");
+        }
+
+        String sql = sb.toString();
+
+        return sql.substring(0, sql.length() - 1);
+    }
+
+}

+ 40 - 0
src/main/java/com/gyee/wisdom/adapter/common/util/TaosCovertUtil.java

@@ -0,0 +1,40 @@
+package com.gyee.wisdom.adapter.common.util;
+
+public class TaosCovertUtil {
+
+    /**
+     * 根据传过来的点分析出场站名
+     * @param point
+     * @return
+     */
+    public static String coverStationPrefix(String point) {
+        String station = null;
+
+        if(point.toUpperCase().startsWith("SBQ"))
+            station = "new_sbq";
+        else if(point.toUpperCase().startsWith("MHS"))
+            station = "new_mhs";
+        else if(point.toUpperCase().startsWith("NSS"))
+            station = "new_nss";
+        else if(point.toUpperCase().startsWith("XS"))
+            station = "new_xs";
+        else if(point.toUpperCase().startsWith("QS"))
+            station = "new_qs";
+        else if(point.toUpperCase().startsWith("DWK"))
+            station = "dwk";
+        else if(point.toUpperCase().startsWith("PL"))
+            station = "pl";
+        else if(point.toUpperCase().startsWith("MCH"))
+            station = "mch";
+        else if(point.toUpperCase().startsWith("JSFW"))
+            station = "jsfw";
+        else if(point.toUpperCase().startsWith("SH"))
+            station = "sh";
+        else if(point.toUpperCase().startsWith("XH"))
+            station = "xh";
+        else if(point.toUpperCase().startsWith("NXDQ"))
+            station = "nxdq";
+
+        return station;
+    }
+}

+ 231 - 0
src/main/java/com/gyee/wisdom/adapter/controller/TsDataController.java

@@ -0,0 +1,231 @@
+package com.gyee.wisdom.adapter.controller;
+
+import com.gyee.wisdom.adapter.model.adapter.DoubleStatData;
+import com.gyee.wisdom.adapter.model.adapter.TsData;
+import com.gyee.wisdom.adapter.model.adapter.TsPointData;
+import com.gyee.wisdom.adapter.model.adapter.TsPointDataList;
+import com.gyee.wisdom.adapter.server.taos.TsDataService;
+import com.gyee.wisdom.adapter.server.taos.TsPointService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.*;
+
+
+@RestController
+@RequestMapping("/ts")
+@CrossOrigin
+public class TsDataController {
+
+    @Autowired
+    protected TsDataService tsDataService;
+
+    @Autowired
+    protected TsPointService tsPointService;
+
+    @GetMapping("/test")
+    public String test(){
+        return "ss";
+    }
+
+
+    //thingId:具体设施Id
+    //thingType:场站(station),风机(windturbine),升压站(electrical)
+    //uniformCode:统一编码
+    @GetMapping("/latest")
+    public Map<String, TsData> getLatest(
+            @RequestParam(value = "keys", required = false) Optional<String> keyStr,
+            @RequestParam(value = "thingType", required = false) Optional<String> thingType,
+            @RequestParam(value = "thingId", required = false) Optional<String> thingId,
+            @RequestParam(value = "uniformCodes", required = false) Optional<String> uniformCodes
+    ) {
+        if (keyStr.isPresent()) {
+            String[] tagNames = keyStr.get().split(",");
+            Map<String, TsData> data = tsDataService.getLatest(tagNames);
+            if (data == null) {
+                Map<String, TsData> nullData = new HashMap<>();
+                return nullData;
+            } else {
+                return data;
+            }
+        } else if (thingType.isPresent() && thingId.isPresent() && uniformCodes.isPresent()) {
+            String[] uCodes = uniformCodes.get().split(",");
+            return tsDataService.getLatestByUniformCodes(thingType.get(), thingId.get(), uCodes);
+        } else {
+            Map<String, TsData> nullData = new HashMap<>();
+            return nullData;
+        }
+    }
+
+    @GetMapping("/history/raw")
+    public List<TsData> getHistoryRaw(@RequestParam(value = "tagName", required = false) Optional<String> tagName,
+                                      @RequestParam(value = "thingType", required = false) Optional<String> thingType,
+                                      @RequestParam(value = "thingId", required = false) Optional<String> thingId,
+                                      @RequestParam(value = "uniformCode", required = false) Optional<String> uniformCode,
+                                      @RequestParam(value = "startTs", required = false) Optional<Long> startTs,
+                                      @RequestParam(value = "endTs", required = false) Optional<Long> endTs) {
+        if (tagName.isPresent() && startTs.isPresent() && endTs.isPresent()) {
+            List<TsData> list = tsDataService.getHistoryRaw(tagName.get(), startTs.get(), endTs.get());
+            if (list == null)
+                list = new ArrayList<>();
+            return list;
+        }
+
+        if (thingType.isPresent() && thingId.isPresent() && uniformCode.isPresent() && startTs.isPresent() && endTs.isPresent()) {
+            List<TsData> list = tsDataService.getHistoryRaw(thingType.get(), thingId.get(), uniformCode.get(), startTs.get(), endTs.get());
+            if (list == null)
+                list = new ArrayList<>();
+            return list;
+        } else {
+            List<TsData> list = new ArrayList<>();
+            return list;
+        }
+
+    }
+
+    @GetMapping("/history/snap")
+    public List<TsData> getHistorySnap(@RequestParam(value = "tagName", required = false) Optional<String> tagName,
+                                       @RequestParam(value = "thingId", required = false) Optional<String> thingId,
+                                       @RequestParam(value = "thingType", required = false) Optional<String> thingType,
+                                       @RequestParam(value = "uniformCode", required = false) Optional<String> uniformCode,
+                                       @RequestParam(value = "startTs", required = false) Optional<Long> startTs,
+                                       @RequestParam(value = "endTs", required = false) Optional<Long> endTs,
+                                       @RequestParam(value = "interval", required = false) Optional<Integer> interval) {
+        if (tagName.isPresent() && startTs.isPresent() && endTs.isPresent()) {
+            int intVal = interval.isPresent()?interval.get():60;
+            List<TsData> resultMap = tsDataService.getHistorySnap(tagName.get(), startTs.get(), endTs.get(), intVal);
+            if (resultMap == null)
+                resultMap = new ArrayList<>();
+            return resultMap;
+        } else if (thingId.isPresent() && thingType.isPresent() && uniformCode.isPresent() && startTs.isPresent() && endTs.isPresent()) {
+            int intVal = interval.isPresent()?interval.get():60;
+            List<TsData> resultMap = tsDataService.getHistorySnap(thingType.get(), thingId.get(), uniformCode.get(), startTs.get(), endTs.get(), intVal);
+            if (resultMap == null)
+                resultMap = new ArrayList<>();
+            return resultMap;
+        } else {
+            List<TsData> resultMap = new ArrayList<>();
+            return resultMap;
+        }
+    }
+
+    @GetMapping("/history/stat")
+    public List<DoubleStatData> getHistoryStat(@RequestParam(value = "tagName", required = false) Optional<String> tagName,
+                                               @RequestParam(value = "thingType", required = false) Optional<String> thingType,
+                                               @RequestParam(value = "thingId", required = false) Optional<String> thingId,
+                                               @RequestParam(value = "uniformCode", required = false) Optional<String> uniformCode,
+                                               @RequestParam(value = "startTs", required = false) Optional<Long> startTs,
+                                               @RequestParam(value = "endTs", required = false) Optional<Long> endTs,
+                                               @RequestParam(value = "interval", required = false) Optional<Integer> interval) {
+        if (tagName.isPresent() && startTs.isPresent() && endTs.isPresent()) {
+            int intVal = interval.isPresent()?interval.get():60;
+            List<DoubleStatData> list = tsDataService.getHistoryStat(tagName.get(), startTs.get(), endTs.get(), intVal);
+            if (list == null)
+                list = new ArrayList<>();
+            return list;
+        } else if (thingType.isPresent() && thingId.isPresent() && uniformCode.isPresent() && startTs.isPresent() && endTs.isPresent()) {
+            int intVal = interval.isPresent()?interval.get():60;
+            List<DoubleStatData> list = tsDataService.getHistoryStat(thingType.get(), thingId.get(), uniformCode.get(), startTs.get(), endTs.get(), intVal);
+            if (list == null)
+                list = new ArrayList<>();
+            return list;
+        } else {
+            List<DoubleStatData> list = new ArrayList<>();
+            return list;
+        }
+    }
+
+    @GetMapping("/history/section")
+    public Map<String, TsData> getHistorySection(@RequestParam(value = "tagNames", required = false) Optional<String> tagNames,
+                                                 @RequestParam(value = "thingType", required = false) Optional<String> thingType,
+                                                 @RequestParam(value = "thingId", required = false) Optional<String> thingId,
+                                                 @RequestParam(value = "uniformCodes", required = false) Optional<String> uniformCodes,
+                                                 @RequestParam(value = "ts", required = false) Optional<Long> ts) throws Exception {
+        try {
+            if (tagNames.isPresent() && ts.isPresent()) {
+                String[] tagNameArr = tagNames.get().split(",");
+                Map<String, TsData> map = tsDataService.getHistorySection(ts.get(), tagNameArr);
+                if (map == null)
+                    map = new HashMap<>();
+                return map;
+            } else if (thingType.isPresent() && thingId.isPresent() && uniformCodes.isPresent() && ts.isPresent()) {
+                String[] unifromCodeArray = uniformCodes.get().split(",");
+                Map<String, TsData> map = tsDataService.getHistorySection(ts.get(), thingId.get(), thingType.get(), unifromCodeArray);
+                if (map == null)
+                    map = new HashMap<>();
+                return map;
+            } else {
+                Map<String, TsData> map = new HashMap<>();
+                return map;
+            }
+
+        } catch (Exception e) {
+            Map<String, TsData> map = new HashMap<>();
+            return map;
+        }
+
+    }
+
+    @PostMapping("/history/batch")
+    //@ResponseBody
+    public boolean writeHistoryBatch(@RequestBody List<TsPointData> tsDataList) {
+        try {
+            tsDataService.writeHistory(tsDataList);
+            return true;
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    @PostMapping("/history")
+    //@ResponseBody
+    public boolean writeHistory(@RequestBody TsPointData tsData) {
+        try {
+            List<TsPointData> list = new ArrayList<>();
+            list.add(tsData);
+            tsDataService.writeHistory(list);
+            return true;
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    @PostMapping("/history/list")
+    //@ResponseBody
+    public boolean writeHistoryList(@RequestBody TsPointDataList tsData) {
+        try {
+            List<TsPointData> tsDataList = new ArrayList<>();
+            if (tsData != null) {
+                for (int i = 0; i < tsData.getTsDataList().size(); i++) {
+                    TsPointData data = new TsPointData();
+                    data.setTagName(tsData.getTagName());
+                    data.setTsData(tsData.getTsDataList().get(i));
+                    tsDataList.add(data);
+                }
+                tsDataService.writeHistory(tsDataList);
+                return true;
+            } else {
+                return false;
+            }
+        } catch (Exception e) {
+            return false;
+        }
+
+    }
+
+    @PostMapping("/latest/batch")
+    //@ResponseBody
+    public boolean writeLatestBatch(@RequestBody List<TsPointData> tsDataList) throws Exception {
+        return tsDataService.writeLatest(tsDataList);
+    }
+
+    @PostMapping("/latest")
+    //@ResponseBody
+    public boolean writeLatest(@RequestBody TsPointData tsData) throws Exception {
+        List<TsPointData> tsDataList = new ArrayList<>();
+        tsDataList.add(tsData);
+        return tsDataService.writeLatest(tsDataList);
+    }
+
+}
+

+ 359 - 0
src/main/java/com/gyee/wisdom/adapter/dao/TaosHistoryDao.java

@@ -0,0 +1,359 @@
+package com.gyee.wisdom.adapter.dao;
+
+import com.cloudera.impala.jdbc41.internal.com.cloudera.altus.shaded.org.apache.commons.lang3.time.DateFormatUtils;
+import com.gyee.wisdom.adapter.common.config.TaosConfiguration;
+import com.gyee.wisdom.adapter.common.config.ThreadPoolTaskConfig;
+import com.gyee.wisdom.adapter.common.exception.WisdomException;
+import com.gyee.wisdom.adapter.common.util.TaosCovertUtil;
+import com.gyee.wisdom.adapter.model.adapter.*;
+import com.gyee.wisdom.adapter.timeseries.dao.IHistoryDao;
+import com.gyee.wisdom.adapter.common.constant.Interpolation;
+import com.gyee.wisdom.adapter.timeseries.TaosDao;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.sql.*;
+import java.util.*;
+import java.util.concurrent.Future;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Component
+@TaosDao
+public class TaosHistoryDao implements IHistoryDao {
+
+    private long day_time = 86400000L;
+    private long month_time = 2592000000L;
+    private long half_year_time = 15552000000L;
+    private long year_time = 31536000000L;
+
+    @Autowired
+    private TaosConfiguration config;
+    @Autowired
+    private ThreadPoolTaskConfig taskConfig;
+
+
+    /**
+     * 查询单个测点历史数据
+     * @param tsQuery
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public List<TsData> getTsDataHistory(TsQuery tsQuery) throws Exception {
+        if (tsQuery.getTsPoint().getTsDataType() == TsDataType.DOUBLE) {
+            return getDoubleTsDataHistory(tsQuery);
+        } else if (tsQuery.getTsPoint().getTsDataType() == TsDataType.BOOLEAN) {
+            return getBooleanTsDataHistory(tsQuery);
+        } else if (tsQuery.getTsPoint().getTsDataType() == TsDataType.STRING) {
+            return getStringTsDataHistory(tsQuery);
+        } else if (tsQuery.getTsPoint().getTsDataType() == TsDataType.LONG) {
+            return getLongTsDataHistory(tsQuery);
+        }else{
+            return getDoubleTsDataHistory(tsQuery);
+        }
+
+//        return null;
+    }
+
+
+    /**
+     * 查询单测点min、max、avg值
+     * @param tsQuery
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public List<DoubleStatData> getDoubleStatDataHistory(TsQuery tsQuery) throws Exception {
+        if (tsQuery.getTsPoint().getTsDataType() != TsDataType.DOUBLE) {
+            throw new WisdomException("无效的数据类型:" + tsQuery.getTsPoint().getTsDataType());
+        }
+
+        List<DoubleStatData> result = new ArrayList<>();
+        Connection connect = config.getConnect();
+
+        try {
+            Statement st = connect.createStatement();
+            String point = tsQuery.getTsPoint().getId();
+
+            StringBuilder sb = new StringBuilder();
+            sb.append("select avg(value_double),max(value_double),min(value_double) from ");
+            sb.append(TaosCovertUtil.coverStationPrefix(point) + "." + point.replace(".", "_"));
+            sb.append(" where point_time>='").append(DateFormatUtils.format(tsQuery.getStartTs(), "yyyy-MM-dd HH:mm:ss:SSS"));
+            sb.append("' and point_time<='").append(DateFormatUtils.format(tsQuery.getEndTs(), "yyyy-MM-dd HH:mm:ss:SSS"));
+            sb.append("' interval(").append(tsQuery.getInterval()).append("s)");
+
+            ResultSet rs = st.executeQuery(sb.toString());
+            while (rs.next()) {
+                DoubleTsData avgData = new DoubleTsData(rs.getLong(1), (short) 1, rs.getDouble(2));
+                DoubleTsData maxData = new DoubleTsData(rs.getLong(1), (short) 1, rs.getDouble(3));
+                DoubleTsData minData = new DoubleTsData(rs.getLong(1), (short) 1, rs.getDouble(4));
+                DoubleStatData statData = new DoubleStatData(avgData, maxData, minData);
+                result.add(statData);
+            }
+
+        } catch (Exception e) {
+        } finally {
+            if (connect != null)
+                connect.close();
+        }
+
+        return result;
+    }
+
+    @Override
+    public boolean writeHistoryValue(List<TsPointData> dataList) throws Exception {
+        boolean flag = false;
+        Connection connect = config.getConnect();
+
+        try {
+            Statement st = connect.createStatement();
+
+            StringBuilder sb = new StringBuilder();
+            sb.append("insert into ");
+            for (TsPointData obj : dataList) {
+                long time = obj.getTsData().getTs();
+                String point = obj.getTagName();
+                double value = obj.getTsData().getDoubleValue().get();
+                sb.append(TaosCovertUtil.coverStationPrefix(point)).append(".");
+                sb.append(point).append(" values (");
+                sb.append(time).append(",").append(value).append(")");
+            }
+
+            flag = st.execute(sb.toString());
+
+        } catch (Exception e) {
+        } finally {
+            if (connect != null)
+                connect.close();
+        }
+
+        return flag;
+    }
+
+    /**
+     * 查询多测点某个时间点的数值
+     * @param tsPoints 标签点
+     * @param ts       时间点(秒级)
+     *                 上一个最近的数据
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public Map<String, TsData> getHistorySection(List<TsPoint> tsPoints, Long ts) throws Exception {
+        Map<String, TsData> result = new HashMap<>();
+        Map<TsDataType, List<TsPoint>> pointGroup = tsPoints.stream().collect(Collectors.groupingBy(TsPoint::getTsDataType));
+
+        //存储线程的返回值
+        List<Future<Map<String, TsData>>> results = new LinkedList<>();
+        for (Map.Entry<TsDataType, List<TsPoint>> entry : pointGroup.entrySet()) {
+            String[] tagNames = entry.getValue().stream().map(TsPoint::getId).toArray(String[]::new);
+            if (entry.getKey() == TsDataType.DOUBLE)
+                for (String tag : tagNames) {
+                    String sql = getSectionSql(tag, ts);
+                    TaskCallable task = new TaskCallable(config.getConnect(), sql, ts, tag, TsDataType.DOUBLE);
+                    Future<Map<String, TsData>> submit = taskConfig.getExecutor().submit(task);
+                    results.add(submit);
+                }
+            if (entry.getKey() == TsDataType.BOOLEAN) {
+                for (String tag : tagNames) {
+                    String sql = getSectionSql(tag, ts);
+                    TaskCallable task = new TaskCallable(config.getConnect(), sql, ts, tag, TsDataType.BOOLEAN);
+                    Future<Map<String, TsData>> submit = taskConfig.getExecutor().submit(task);
+                    results.add(submit);
+                }
+            }
+        }
+        //返回结果
+        for (int i = 0; i < results.size(); i++) {
+            result.putAll(results.get(i).get());
+        }
+
+//        for (Map.Entry<TsDataType, List<TsPoint>> entry : pointGroup.entrySet()) {
+//            String[] tagNames = tsPoints.stream().map(TsPoint::getId).toArray(String[]::new);
+//            for (String tag : tagNames) {
+//                TsData tsData = null;
+//                String point = TaosCovertUtil.coverStationPrefix(tag) + "." + tag.replace(".", "_");
+//                String sql = "select last_row(*) from " + point + " where point_time>='"
+//                        + DateFormatUtils.format(ts - year_time, "yyyy-MM-dd HH:mm:ss:SSS") + "'"
+//                        + " and point_time <='" + DateFormatUtils.format(ts, "yyyy-MM-dd HH:mm:ss:SSS") + "'";
+//                ResultSet rs = config.getConnect().createStatement().executeQuery(sql);
+//                while (rs.next()) {
+//                    if (entry.getKey() == TsDataType.DOUBLE)
+//                        tsData = new DoubleTsData(ts, (short) 0, rs.getDouble(2));
+//                    if (entry.getKey() == TsDataType.BOOLEAN)
+//                        tsData = new BooleanTsData(ts, (short) 0, rs.getBoolean(2));
+//                    result.put(tag, tsData);
+//                }
+//            }
+//        }
+
+        return result;
+    }
+
+    public List<TsData> getDoubleTsDataHistory(TsQuery tsQuery) throws Exception {
+        List<TsData> tsDataList = new ArrayList<>();
+        Connection connect = config.getConnect();
+
+        try {
+            Statement st = connect.createStatement();
+            String sql = getHistory(tsQuery);
+            ResultSet rs = st.executeQuery(sql);
+            while (rs.next()) {
+                tsDataList.add(new DoubleTsData(rs.getLong(1), (short) 0, rs.getDouble(2)));
+            }
+        } catch (Exception e) {
+        } finally {
+            if (connect != null)
+                connect.close();
+        }
+
+        return tsDataList;
+    }
+
+
+    public List<TsData> getLongTsDataHistory(TsQuery tsQuery) throws Exception {
+        List<TsData> tsDataList = new ArrayList<>();
+        Connection connect = config.getConnect();
+
+        try {
+            Statement st = connect.createStatement();
+            String sql = getHistory(tsQuery);
+            ResultSet rs = st.executeQuery(sql);
+            while (rs.next()) {
+                tsDataList.add(new LongTsData(rs.getLong(1), (short) 0, rs.getLong(2)));
+            }
+        } catch (Exception e) {
+        } finally {
+            if (connect != null)
+                connect.close();
+        }
+
+        return tsDataList;
+    }
+
+
+
+    public List<TsData> getBooleanTsDataHistory(TsQuery tsQuery) throws Exception {
+        List<TsData> tsDataList = new ArrayList<>();
+        Connection connect = config.getConnect();
+
+        try {
+            Statement st = connect.createStatement();
+            String sql = getHistory(tsQuery);
+            ResultSet rs = st.executeQuery(sql);
+            while (rs.next()) {
+                tsDataList.add(new BooleanTsData(rs.getLong(1), (short) 0, rs.getBoolean(2)));
+            }
+        } catch (Exception e) {
+        } finally {
+            if (connect != null)
+                connect.close();
+        }
+
+        return tsDataList;
+    }
+
+
+    public List<TsData> getStringTsDataHistory(TsQuery tsQuery) throws Exception {
+        List<TsData> tsDataList = new ArrayList<>();
+        Connection connect = config.getConnect();
+
+        try {
+            Statement st = connect.createStatement();
+            String sql = getHistory(tsQuery);
+            ResultSet rs = st.executeQuery(sql);
+            while (rs.next()) {
+                tsDataList.add(new StringTsData(rs.getLong(1), (short) 0, rs.getString(2)));
+            }
+        } catch (Exception e) {
+        } finally {
+            if (connect != null)
+                connect.close();
+        }
+
+        return tsDataList;
+    }
+
+
+    /**
+     * 拼接sql
+     *
+     * @param tsQuery
+     * @return
+     * @throws WisdomException
+     */
+    private String getHistory(TsQuery tsQuery) throws WisdomException {
+        String point = tsQuery.getTsPoint().getId();
+        StringBuilder sb = new StringBuilder();
+        if (tsQuery.getInterpolation() == Interpolation.RAW) {
+            sb.append("select * from ");
+            sb.append(TaosCovertUtil.coverStationPrefix(point) + "." + point.replace(".", "_"));
+            sb.append(" where point_time>='").append(DateFormatUtils.format(tsQuery.getStartTs(), "yyyy-MM-dd HH:mm:ss:SSS"));
+            sb.append("' and point_time<='").append(DateFormatUtils.format(tsQuery.getEndTs(), "yyyy-MM-dd HH:mm:ss:SSS"));
+            sb.append("'");
+        } else if (tsQuery.getInterpolation() == Interpolation.SNAP) {
+            if (tsQuery.getDateArray() != null && tsQuery.getDateArray().length > 0) {
+                sb.append("select last(value_double) from ");
+                sb.append(TaosCovertUtil.coverStationPrefix(point) + "." + point.replace(".", "_"));
+                sb.append(" where point_time>='").append(DateFormatUtils.format(tsQuery.getStartTs(), "yyyy-MM-dd HH:mm:ss:SSS"));
+                sb.append("' and point_time<'").append(DateFormatUtils.format(tsQuery.getEndTs(), "yyyy-MM-dd HH:mm:ss:SSS"));
+                sb.append("' interval(").append(tsQuery.getInterval()).append("s) fill(next)");
+            } else {
+                throw new WisdomException("无效的查询条件!");
+            }
+        } else {
+            throw new WisdomException("Golden不支持历史数据插值方法:" + tsQuery.getInterpolation());
+        }
+
+        return sb.toString();
+    }
+
+
+    /**
+     * 拼接sql
+     *
+     * @param tag
+     * @param ts
+     * @return
+     */
+    private String getSectionSql(String tag, long ts) {
+        String point = TaosCovertUtil.coverStationPrefix(tag) + "." + tag.replace(".", "_");
+
+        StringBuilder sb = new StringBuilder();
+        sb.append("select last_row(*) from ").append(point);
+        sb.append(" where point_time>='");
+        sb.append(DateFormatUtils.format(ts - half_year_time, "yyyy-MM-dd HH:mm:ss:SSS") + "'");
+        sb.append(" and point_time <='" + DateFormatUtils.format(ts, "yyyy-MM-dd HH:mm:ss:SSS") + "'");
+
+        return sb.toString();
+    }
+
+
+    /**
+     * 将blob转化为byte[]
+     *
+     * @param blob
+     * @return
+     */
+    private byte[] getBytes(Blob blob) {
+        try {
+            InputStream ins = blob.getBinaryStream();
+            byte[] b = new byte[1024];
+            int num = 0;
+            String res = "";
+            while ((num = ins.read(b)) != -1) {
+                res += new String(b, 0, num);
+            }
+            return res.getBytes();
+        } catch (SQLException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+}

+ 287 - 0
src/main/java/com/gyee/wisdom/adapter/dao/TaosLatestDao.java

@@ -0,0 +1,287 @@
+package com.gyee.wisdom.adapter.dao;
+
+import com.gyee.wisdom.adapter.common.config.TaosConfiguration;
+import com.gyee.wisdom.adapter.common.config.ThreadPoolTaskConfig;
+import com.gyee.wisdom.adapter.common.exception.WisdomException;
+import com.gyee.wisdom.adapter.common.util.TaosCovertUtil;
+import com.gyee.wisdom.adapter.model.adapter.*;
+import com.gyee.wisdom.adapter.timeseries.dao.ILatestDao;
+import com.gyee.wisdom.adapter.timeseries.TaosDao;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.sql.Connection;
+import java.sql.Statement;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Future;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Component
+@TaosDao
+public class TaosLatestDao implements ILatestDao {
+
+    @Autowired
+    private TaosConfiguration config;
+    @Autowired
+    private ThreadPoolTaskConfig taskConfig;
+
+
+    /**
+     * 查询多测点最新数据
+     * @param tsPoints
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public Map<String, TsData> getTsDataLatest(List<TsPoint> tsPoints) throws Exception {
+        Map<String, TsData> result = new HashMap<>();
+        Map<TsDataType, List<TsPoint>> pointGroup = tsPoints.stream().collect(Collectors.groupingBy(TsPoint::getTsDataType));
+        for (Map.Entry<TsDataType, List<TsPoint>> entry : pointGroup.entrySet()) {
+            String[] tagNames = entry.getValue().stream().map(TsPoint::getId).toArray(String[]::new);
+            if (entry.getKey() == TsDataType.DOUBLE) {
+                result.putAll(getDoubleTsDataSnapshots(tagNames));
+            } else if (entry.getKey() == TsDataType.LONG) {
+                result.putAll(getLongTsDataSnapshots(tagNames));
+            } else if (entry.getKey() == TsDataType.BOOLEAN) {
+                result.putAll(getBooleanTsDataSnapshots(tagNames));
+            } else {
+                throw new WisdomException("Taos不支持数据类型:" + entry.getKey());
+            }
+        }
+
+        return result;
+    }
+
+
+    @Override
+    public int writeDoubleLatest(List<TsPointData> list) throws Exception {
+        boolean flag = false;
+        Connection connection = config.getConnect();
+
+        try {
+            Statement st = connection.createStatement();
+
+            StringBuilder sb = new StringBuilder();
+            sb.append("insert into ");
+            for (TsPointData obj : list) {
+                long time = obj.getTsData().getTs();
+                String point = obj.getTagName();
+                double value = obj.getTsData().getDoubleValue().get();
+                sb.append(TaosCovertUtil.coverStationPrefix(point)).append(".");
+                sb.append(point).append(" values (");
+                sb.append(time).append(",").append(value).append(")");
+            }
+
+            flag = st.execute(sb.toString());
+
+        } catch (Exception e) {
+        } finally {
+            if (connection != null)
+                connection.close();
+        }
+
+        return flag == true ? list.size() : 0;
+    }
+
+    @Override
+    public int writeStringLatest(List<TsPointData> list) throws Exception {
+        boolean flag = false;
+        Connection connection = config.getConnect();
+
+        try {
+            Statement st = connection.createStatement();
+
+            StringBuilder sb = new StringBuilder();
+            sb.append("insert into ");
+            for (TsPointData obj : list) {
+                long time = obj.getTsData().getTs();
+                String point = obj.getTagName();
+                String value = obj.getTsData().getStringValue().get();
+                sb.append(TaosCovertUtil.coverStationPrefix(point)).append(".");
+                sb.append(point).append(" values (");
+                sb.append(time).append(",'").append(value).append("') ");
+            }
+
+            flag = st.execute(sb.toString());
+
+        } catch (Exception e) {
+        } finally {
+            if (connection != null)
+                connection.close();
+        }
+
+        return flag == true ? list.size() : 0;
+    }
+
+    @Override
+    public int writeBooleanLatest(List<TsPointData> list) throws Exception {
+        boolean flag = false;
+        Connection connection = config.getConnect();
+
+        try {
+            Statement st = connection.createStatement();
+
+            StringBuilder sb = new StringBuilder();
+            sb.append("insert into ");
+            for (TsPointData obj : list) {
+                long time = obj.getTsData().getTs();
+                String point = obj.getTagName();
+                boolean value = obj.getTsData().getBooleanValue().get();
+                sb.append(TaosCovertUtil.coverStationPrefix(point)).append(".");
+                sb.append(point).append(" values (");
+                sb.append(time).append(",").append(value).append(")");
+            }
+
+            flag = st.execute(sb.toString());
+
+        } catch (Exception e) {
+        } finally {
+            if (connection != null)
+                connection.close();
+        }
+
+        return flag == true ? list.size() : 0;
+    }
+
+    @Override
+    public int writeLongLatest(List<TsPointData> list) throws Exception {
+        boolean flag = false;
+        Connection connection = config.getConnect();
+
+        try {
+            Statement st = connection.createStatement();
+
+            StringBuilder sb = new StringBuilder();
+            sb.append("insert into ");
+            for (TsPointData obj : list) {
+                long time = obj.getTsData().getTs();
+                String point = obj.getTagName();
+                long value = obj.getTsData().getLongValue().get();
+                sb.append(TaosCovertUtil.coverStationPrefix(point)).append(".");
+                sb.append(point).append(" values (");
+                sb.append(time).append(",").append(value).append(")");
+            }
+
+            flag = st.execute(sb.toString());
+
+        } catch (Exception e) {
+        } finally {
+            if (connection != null)
+                connection.close();
+        }
+
+        return flag == true ? list.size() : 0;
+    }
+
+
+    /**
+     * 由于taos数据库中全部是DOUBLE类型,故不需要区分类型
+     *
+     * @param dataList
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public boolean writeLatest(List<TsPointData> dataList) throws Exception {
+        int writeCount = 0;
+
+        Map<TsDataType, List<TsPointData>> pointGroup = dataList.stream().collect(Collectors.groupingBy(TsPointData::findDataType));
+        for (Map.Entry<TsDataType, List<TsPointData>> entry : pointGroup.entrySet()) {
+            List<TsPointData> pointDataList = entry.getValue();
+//            if (entry.getKey() == TsDataType.DOUBLE) {
+            int count = writeDoubleLatest(pointDataList);
+            writeCount = writeCount + count;
+//            } else if (entry.getKey() == TsDataType.BOOLEAN) {
+//                int count = writeBooleanLatest(pointDataList);
+//                writeCount = writeCount + count;
+//            } else if (entry.getKey() == TsDataType.STRING) {
+//                int count = writeStringLatest(pointDataList);
+//                writeCount = writeCount + count;
+//            } else if (entry.getKey() == TsDataType.BLOB) {
+//                int count = writeBlobLatest(pointDataList);
+//                writeCount = writeCount + count;
+//            } else if (entry.getKey() == TsDataType.COORDINATE) {
+//                int count = writeCoordinateLatest(pointDataList);
+//                writeCount = writeCount + count;
+//            } else if (entry.getKey() == TsDataType.LONG) {
+//                int count = writeLongLatest(pointDataList);
+//                writeCount = writeCount + count;
+//            }
+        }
+        return writeCount > 0 ? true : false;
+    }
+
+
+    public Map<String, TsData> getDoubleTsDataSnapshots(String... tagNames) throws Exception {
+        Map<String, TsData> tsDataMap = new HashMap<>();
+
+        //存储线程的返回值
+        List<Future<Map<String, TsData>>> results = new LinkedList<>();
+
+        for (String tag : tagNames) {
+            String point = TaosCovertUtil.coverStationPrefix(tag) + "." + tag.replace(".", "_");
+            String sql = "select last_row(*) from " + point;
+            TaskCallable task = new TaskCallable(config.getConnect(), sql, 0, tag, TsDataType.DOUBLE);
+            Future<Map<String, TsData>> submit = taskConfig.getExecutor().submit(task);
+            results.add(submit);
+        }
+
+        //返回结果
+        for (int i = 0; i < results.size(); i++) {
+            tsDataMap.putAll(results.get(i).get());
+        }
+
+        return tsDataMap;
+    }
+
+    public Map<String, TsData> getLongTsDataSnapshots(String... tagNames) throws Exception {
+        Map<String, TsData> tsDataMap = new HashMap<>();
+
+        //存储线程的返回值
+        List<Future<Map<String, TsData>>> results = new LinkedList<>();
+
+        for (String tag : tagNames) {
+            String point = TaosCovertUtil.coverStationPrefix(tag) + "." + tag.replace(".", "_");
+            String sql = "select last_row(*) from " + point;
+            TaskCallable task = new TaskCallable(config.getConnect(), sql, 0, tag, TsDataType.LONG);
+            Future<Map<String, TsData>> submit = taskConfig.getExecutor().submit(task);
+            results.add(submit);
+        }
+
+        //返回结果
+        for (int i = 0; i < results.size(); i++) {
+            tsDataMap.putAll(results.get(i).get());
+        }
+
+        return tsDataMap;
+    }
+
+
+    public Map<String, TsData> getBooleanTsDataSnapshots(String... tagNames) throws Exception {
+        Map<String, TsData> tsDataMap = new HashMap<>();
+
+        //存储线程的返回值
+        List<Future<Map<String, TsData>>> results = new LinkedList<>();
+
+        for (String tag : tagNames) {
+            String point = TaosCovertUtil.coverStationPrefix(tag) + "." + tag.replace(".", "_");
+            String sql = "select last_row(*) from " + point;
+            TaskCallable task = new TaskCallable(config.getConnect(), sql, 0, tag, TsDataType.BOOLEAN);
+            Future<Map<String, TsData>> submit = taskConfig.getExecutor().submit(task);
+            results.add(submit);
+        }
+
+        //返回结果
+        for (int i = 0; i < results.size(); i++) {
+            tsDataMap.putAll(results.get(i).get());
+        }
+
+        return tsDataMap;
+    }
+
+}

+ 94 - 0
src/main/java/com/gyee/wisdom/adapter/dao/TaskCallable.java

@@ -0,0 +1,94 @@
+package com.gyee.wisdom.adapter.dao;
+
+import com.cloudera.impala.jdbc41.internal.com.cloudera.altus.shaded.org.apache.commons.lang3.time.DateFormatUtils;
+import com.gyee.wisdom.adapter.common.util.TaosCovertUtil;
+import com.gyee.wisdom.adapter.model.adapter.*;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.util.StringUtils;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+@Slf4j
+public class TaskCallable implements Callable {
+
+    private Connection connection;
+    private String sql;
+    private long time;
+    private String tagName;
+    private TsDataType type;
+
+    public TaskCallable(Connection connection, String sql, long time, String tagName, TsDataType type) {
+        this.connection = connection;
+        this.sql = sql;
+        this.time = time;
+        this.tagName = tagName;
+        this.type = type;
+    }
+
+
+    @Override
+    public Map<String, TsData> call() throws SQLException {
+        TsData tsData = null;
+        Statement st = null;
+        ResultSet rs = null;
+        Map<String, TsData> result = new HashMap<>();
+
+        if (!StringUtils.hasText(tagName))
+            return result;
+
+        try {
+//            st = this.connection.createStatement();
+////            String point = TaosCovertUtil.coverStationPrefix(this.tagName) + "." + this.tagName.replace(".", "_");
+////            String sql = "select last_row(*) from " + point + " where point_time>='"
+////                    + DateFormatUtils.format(this.time - month_time, "yyyy-MM-dd HH:mm:ss:SSS") + "'"
+////                    + " and point_time <='" + DateFormatUtils.format(this.time, "yyyy-MM-dd HH:mm:ss:SSS") + "'";
+//////            log.info(sql);
+////            rs = st.executeQuery(sql);
+////            if (rs.next()) {
+////                if (this.type == TsDataType.DOUBLE)
+////                    tsData = new DoubleTsData(this.time, (short) 0, rs.getDouble(2));
+////                else if (this.type == TsDataType.BOOLEAN)
+////                    tsData = new BooleanTsData(this.time, (short) 0, rs.getBoolean(2));
+////            }
+////
+////            result.put(this.tagName, tsData);
+
+
+            st = this.connection.createStatement();
+            rs = st.executeQuery(this.sql);
+
+            if (rs.next()) {
+                if (this.time <= 0)
+                    this.time = rs.getLong(1);
+
+                if (this.type == TsDataType.DOUBLE)
+                    tsData = new DoubleTsData(this.time, (short) 0, rs.getDouble(2));
+                else if (this.type == TsDataType.BOOLEAN)
+                    tsData = new BooleanTsData(this.time, (short) 0, rs.getBoolean(2));
+                else if (this.type == TsDataType.STRING)
+                    tsData = new StringTsData(this.time, (short) 0, rs.getString(2));
+                else if (this.type == TsDataType.LONG)
+                    tsData = new LongTsData(this.time, (short) 0, rs.getLong(2));
+            }
+
+            result.put(this.tagName, tsData);
+
+        } catch (Exception e) {
+        } finally {
+            if (rs != null)
+                rs.close();
+            if (st != null)
+                st.close();
+            if (this.connection != null)
+                this.connection.close();
+        }
+
+        return result;
+    }
+}

+ 71 - 0
src/main/java/com/gyee/wisdom/adapter/model/TsPointEntity.java

@@ -0,0 +1,71 @@
+package com.gyee.wisdom.adapter.model;
+
+import com.gyee.wisdom.adapter.model.adapter.BasicTsPoint;
+import com.gyee.wisdom.adapter.model.adapter.ToData;
+import com.gyee.wisdom.adapter.model.adapter.TsDataType;
+import com.gyee.wisdom.adapter.model.adapter.TsPoint;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springframework.cache.annotation.Cacheable;
+
+import java.io.Serializable;
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+//@TableName("gyee_test.view_tspoint")
+@Cacheable
+public class TsPointEntity implements ToData<TsPoint> {
+
+    private static final long serialVersionUID=1L;
+
+    /**
+     * 主键ID
+     */
+//    @TableId(value = "id")
+    private String id;
+    /**
+     * 设备类型
+     */
+//    @TableField(value = "thing_type")
+    private String thingType;
+    /**
+     * 设备Id
+     */
+//    @TableField(value = "thing_id")
+    private String thingId;
+    /**
+     * 统一编码
+     */
+//    @TableField(value = "uniform_code")
+    private String uniformCode;
+    /**
+     * 点类型
+     */
+//    @TableField(value = "data_type")
+    private String dataType;
+
+    @Override
+    public TsPoint toData() {
+        TsDataType tsDataType = TsDataType.DOUBLE;
+        if ("bool".equals(this.dataType))
+            tsDataType = TsDataType.BOOLEAN;
+        else if (this.dataType == null)
+            tsDataType = TsDataType.DOUBLE;
+        else if (this.dataType.contains("INT"))
+            tsDataType = TsDataType.LONG;
+
+        BasicTsPoint data = new BasicTsPoint(this.id, tsDataType);
+        if (!"".equals(thingId))
+            data.setThingId(this.thingId);
+        if (!"".equals(thingType))
+            data.setThingType(this.thingType);
+        if (!"".equals(uniformCode))
+            data.setUniformCode(this.uniformCode);
+        return data;
+    }
+
+//    @Override
+//    protected Serializable pkVal() {
+//        return null;
+//    }
+}

+ 46 - 0
src/main/java/com/gyee/wisdom/adapter/model/adapter/BaseTsQuery.java

@@ -0,0 +1,46 @@
+package com.gyee.wisdom.adapter.model.adapter;
+
+import com.gyee.wisdom.adapter.common.constant.Interpolation;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class BaseTsQuery implements TsQuery{
+    private final TsPoint tsPoint;
+    private final long startTs;
+    private final long endTs;
+    private final int interval;
+    private final int limit ;
+    private final Interpolation interpolation;
+
+
+    public BaseTsQuery(TsPoint tsPoint, long startTs, long endTs, int interval, int limit, Interpolation interpolation) {
+        this.tsPoint = tsPoint;
+        this.startTs = startTs;
+        this.endTs = endTs;
+        this.interval = interval;
+        this.limit = limit;
+        this.interpolation = interpolation;
+    }
+
+    public BaseTsQuery(TsPoint tsPoint, long startTs, long endTs) {
+        this(tsPoint, startTs, endTs, 1, 1, Interpolation.RAW);
+    }
+    @Override
+    public Date[] getDateArray() {
+        if (interpolation == Interpolation.SNAP && startTs > 0 && endTs >0 && interval > 0 && endTs > startTs ) {
+            int count = Math.round ((endTs - startTs)/interval/1000);
+            int length = count;// <= limit ? count : limit;
+            Date[] result = new Date[length];
+            for (int i=0;i<length;i++) {
+                long ts = startTs + (long)i*interval*1000;
+                result[i] = new Date(ts);
+            }
+
+            return result;
+        }
+        return  null;
+    }
+
+}

+ 38 - 0
src/main/java/com/gyee/wisdom/adapter/model/adapter/BasicTsData.java

@@ -0,0 +1,38 @@
+package com.gyee.wisdom.adapter.model.adapter;
+
+/**
+ * @author songwb<songwb@aliyun.com>
+ */
+public abstract class BasicTsData implements TsData, Comparable<BasicTsData>{
+
+    private final long ts;
+
+    private final short status;
+
+    public BasicTsData(long ts, short status) {
+        this.ts = ts;
+        this.status = status;
+    }
+    @Override
+    public long getTs() {
+        return ts;
+    }
+    @Override
+    public short getStatus() {
+        return status;
+    }
+
+    @Override
+    public int compareTo(BasicTsData o) {
+        return Long.compare(ts, o.ts);
+    }
+
+    @Override
+    public String toString() {
+        return "BasicTsData{ts='" + ts +
+                "', status='" + this.getStatus() +
+                "'}";
+    }
+
+}
+

+ 55 - 0
src/main/java/com/gyee/wisdom/adapter/model/adapter/BasicTsPoint.java

@@ -0,0 +1,55 @@
+package com.gyee.wisdom.adapter.model.adapter;
+
+import lombok.Data;
+
+/**
+ * @author songwb<songwb@aliyun.com>
+ */
+@Data
+public class BasicTsPoint implements TsPoint{
+
+    private final String id;
+
+    private  TsDataType tsDataType;
+
+    private  String thingId;
+
+    private  String thingType;
+
+    private  String uniformCode;
+
+    public BasicTsPoint(String id, TsDataType tsDataType) {
+        this.id = id;
+        this.tsDataType = tsDataType;
+    }
+    @Override
+    public String getId() { return id; }
+    @Override
+    public TsDataType getTsDataType() {return tsDataType; }
+
+    @Override
+    public String getUniformCode(){
+       return uniformCode;
+    }
+
+
+    @Override
+    public String getThingId(){
+        return thingId;
+    }
+
+    @Override
+    public String getThingType(){
+        return getThingType();
+    }
+    @Override
+    public String toString() {
+        return "BasicTsPoint{id='" + id +
+                "', dataType='" + this.getTsDataType() +
+                "'}";
+    }
+
+
+
+}
+

+ 19 - 0
src/main/java/com/gyee/wisdom/adapter/model/adapter/BooleanTsData.java

@@ -0,0 +1,19 @@
+package com.gyee.wisdom.adapter.model.adapter;
+
+/**
+ * @author songwb<songwb@aliyun.com>
+ */
+public class BooleanTsData extends BasicTsData {
+
+    private final boolean actualValue;
+
+    public BooleanTsData(long ts, short status, boolean actualValue) {
+        super(ts, status);
+        this.actualValue = actualValue;
+    }
+    public boolean getBooleanValue() {
+        return actualValue;
+    }
+
+}
+

+ 30 - 0
src/main/java/com/gyee/wisdom/adapter/model/adapter/DoubleStatData.java

@@ -0,0 +1,30 @@
+package com.gyee.wisdom.adapter.model.adapter;
+
+/**
+ * @author songwb<songwb@aliyun.com>
+ */
+public class DoubleStatData {
+
+    private DoubleTsData avg;
+    private DoubleTsData max;
+    private DoubleTsData min;
+
+    public DoubleStatData(DoubleTsData avg, DoubleTsData max, DoubleTsData min) {
+        this.avg = avg;
+        this.max = max;
+        this.min = min;
+    }
+
+    public DoubleTsData getAvg() {
+        return avg;
+    }
+
+    public DoubleTsData getMax() {
+        return max;
+    }
+
+    public DoubleTsData getMin() {
+        return min;
+    }
+}
+

+ 33 - 0
src/main/java/com/gyee/wisdom/adapter/model/adapter/DoubleTsData.java

@@ -0,0 +1,33 @@
+package com.gyee.wisdom.adapter.model.adapter;
+
+/**
+ * @author songwb<songwb@aliyun.com>
+ */
+public class DoubleTsData extends BasicTsData {
+
+    private final double actualValue;
+
+    public DoubleTsData(long ts, short status, double actualValue) {
+        super(ts, status);
+        this.actualValue = actualValue;
+    }
+
+
+    public double getDoubleValue() {
+        return actualValue;
+    }
+
+//    public String getValue() {
+//        return Double.toString(actualValue);
+//    }
+
+    @Override
+    public String toString() {
+        return "DoubleTsData{ts='" + this.getTs() +
+                "', status='" + this.getStatus() +
+                "', value='" + this.getDoubleValue() +
+                "'}";
+    }
+
+}
+

+ 27 - 0
src/main/java/com/gyee/wisdom/adapter/model/adapter/GeneralTsData.java

@@ -0,0 +1,27 @@
+package com.gyee.wisdom.adapter.model.adapter;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Optional;
+
+/**
+ * @author songwb<songwb@aliyun.com>
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class GeneralTsData implements TsData {
+
+    private long ts;
+    private short status;
+    private Optional<Double> doubleValue;
+    private Optional<Long> longValue;
+    private Optional<Boolean> booleanValue;
+    private Optional<String> stringValue;
+    private Optional<String> blobValue;
+
+
+}
+

+ 18 - 0
src/main/java/com/gyee/wisdom/adapter/model/adapter/IntegerTsData.java

@@ -0,0 +1,18 @@
+package com.gyee.wisdom.adapter.model.adapter;
+
+/**
+ * @Auther: ruyuan
+ * @Date: 2019-05-04 17:26
+ * @Description:
+ */
+public class IntegerTsData extends BasicTsData {
+
+    private final Integer actualValue;
+    public IntegerTsData(long ts, short status, Integer actualValue) {
+        super(ts, status);
+        this.actualValue = actualValue;
+    }
+    public Integer getIntegerValue() {
+        return actualValue;
+    }
+}

+ 24 - 0
src/main/java/com/gyee/wisdom/adapter/model/adapter/LongTsData.java

@@ -0,0 +1,24 @@
+package com.gyee.wisdom.adapter.model.adapter;
+
+/**
+ * @author songwb<songwb@aliyun.com>
+ */
+public class LongTsData extends BasicTsData {
+
+    private final long actualValue;
+
+    public LongTsData(long ts, short status, long actualValue) {
+        super(ts, status);
+        this.actualValue = actualValue;
+    }
+
+    public long getLongValue() {
+        return actualValue;
+    }
+
+//    public String getValue() {
+//        return Long.toString(actualValue);
+//    }
+
+}
+

+ 24 - 0
src/main/java/com/gyee/wisdom/adapter/model/adapter/StringTsData.java

@@ -0,0 +1,24 @@
+package com.gyee.wisdom.adapter.model.adapter;
+
+/**
+ * @author songwb<songwb@aliyun.com>
+ */
+public class StringTsData extends BasicTsData {
+
+    private final String actualValue;
+
+    public StringTsData(long ts, short status, String actualValue) {
+        super(ts, status);
+        this.actualValue = actualValue;
+    }
+
+//    public String getActualValue() {
+//        return actualValue;
+//    }
+
+    public String getStringValue() {
+        return actualValue;
+    }
+
+}
+

+ 5 - 0
src/main/java/com/gyee/wisdom/adapter/model/adapter/ToData.java

@@ -0,0 +1,5 @@
+package com.gyee.wisdom.adapter.model.adapter;
+
+public interface ToData<T> {
+    T toData();
+}

+ 15 - 0
src/main/java/com/gyee/wisdom/adapter/model/adapter/TsData.java

@@ -0,0 +1,15 @@
+package com.gyee.wisdom.adapter.model.adapter;
+
+/**
+ * @author songwb<songwb@aliyun.com>
+ */
+public interface TsData {
+
+    long getTs();
+
+    short getStatus();
+
+    //double getValue();
+
+}
+

+ 14 - 0
src/main/java/com/gyee/wisdom/adapter/model/adapter/TsDataType.java

@@ -0,0 +1,14 @@
+package com.gyee.wisdom.adapter.model.adapter;
+
+/**
+ * @author songwb<songwb@aliyun.com>
+ */
+public enum TsDataType {
+    LONG,
+    DOUBLE,
+    BOOLEAN,
+    STRING,
+    BLOB,
+    COORDINATE
+}
+

+ 18 - 0
src/main/java/com/gyee/wisdom/adapter/model/adapter/TsPoint.java

@@ -0,0 +1,18 @@
+package com.gyee.wisdom.adapter.model.adapter;
+
+/**
+ * @author songwb<songwb @ aliyun.com>
+ */
+public interface TsPoint {
+
+    String getId();
+
+    String getThingId();
+
+    String getThingType();
+
+    String getUniformCode();
+
+    TsDataType getTsDataType();
+}
+

+ 41 - 0
src/main/java/com/gyee/wisdom/adapter/model/adapter/TsPointData.java

@@ -0,0 +1,41 @@
+package com.gyee.wisdom.adapter.model.adapter;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author songwb<songwb@aliyun.com>
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class TsPointData {
+
+    private String tagName;
+    private GeneralTsData tsData;
+
+    public TsDataType findDataType() {
+        if (tsData.getDoubleValue().isPresent()){
+            return TsDataType.DOUBLE;
+        }
+        else if (tsData.getBooleanValue().isPresent()){
+            return TsDataType.BOOLEAN;
+        }
+        else if (tsData.getLongValue().isPresent()){
+            return TsDataType.LONG;
+        }
+
+        else if (tsData.getStringValue().isPresent()){
+            return TsDataType.STRING;
+        }
+
+        else if (tsData.getBlobValue().isPresent()){
+            return TsDataType.BLOB;
+        }
+
+        return TsDataType.DOUBLE;
+    }
+}
+

+ 23 - 0
src/main/java/com/gyee/wisdom/adapter/model/adapter/TsPointDataList.java

@@ -0,0 +1,23 @@
+package com.gyee.wisdom.adapter.model.adapter;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * @author songwb<songwb@aliyun.com>
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class TsPointDataList {
+
+    private String tagName;
+
+    private List<GeneralTsData> tsDataList;
+
+}
+

+ 23 - 0
src/main/java/com/gyee/wisdom/adapter/model/adapter/TsQuery.java

@@ -0,0 +1,23 @@
+package com.gyee.wisdom.adapter.model.adapter;
+
+import com.gyee.wisdom.adapter.common.constant.Interpolation;
+
+import java.util.Date;
+
+public interface TsQuery {
+
+    TsPoint getTsPoint();
+
+    long getStartTs();
+
+    long getEndTs();
+
+    // 单位秒
+    int getInterval();
+
+    int getLimit();
+
+    Interpolation getInterpolation();
+
+    Date[] getDateArray();
+}

+ 273 - 0
src/main/java/com/gyee/wisdom/adapter/server/taos/ThingsPointService.java

@@ -0,0 +1,273 @@
+package com.gyee.wisdom.adapter.server.taos;
+
+
+import com.gyee.wisdom.adapter.common.config.HiveConfiguration;
+import com.gyee.wisdom.adapter.common.constant.Constant;
+import com.gyee.wisdom.adapter.common.util.DataUtil;
+import com.gyee.wisdom.adapter.model.TsPointEntity;
+import com.gyee.wisdom.adapter.model.adapter.TsPoint;
+import com.gyee.wisdom.adapter.timeseries.dao.IThingsPointDao;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheConfig;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Service;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+@CacheConfig(cacheNames = "TsPoints")
+public class ThingsPointService implements IThingsPointDao {
+
+    @Autowired
+    private HiveConfiguration config;
+
+    @Cacheable
+    @Override
+    public List<TsPoint> findTsPointByUniformCodes(String thingType, String thingId, String... uCodes) {
+//        QueryWrapper<TsPointEntity> wrapper = new QueryWrapper<>();
+//        wrapper.eq("THING_TYPE", thingType);
+//        wrapper.eq("THING_ID", thingId);
+//        wrapper.in("UNIFORM_CODE",uCodes);
+//        return DataUtil.convertDataList(baseMapper.selectList(wrapper));
+
+        List<TsPointEntity> list = new ArrayList<>();
+
+        Connection conn = null;
+        Statement st = null;
+        try {
+            conn = config.getConnection();
+            st = conn.createStatement();
+
+            StringBuilder sb = new StringBuilder();
+            sb.append("select * from ").append(config.tableName);
+            sb.append(" where thing_type ='");
+            sb.append(thingType).append("' and 'thing_id = '");
+            sb.append(thingId).append("' and uniform_code in (");
+            sb.append(DataUtil.convertStringToSql(uCodes)).append(")");
+            ResultSet rs = st.executeQuery(sb.toString());
+
+            while (rs.next()) {
+                TsPointEntity entity = new TsPointEntity();
+                entity.setId(rs.getString("id"));
+                entity.setThingType(rs.getString("thing_type"));
+                entity.setThingId(rs.getString("thing_id"));
+                entity.setUniformCode(rs.getString("uniform_code"));
+                entity.setDataType(rs.getString("data_type"));
+
+                list.add(entity);
+            }
+
+            return DataUtil.convertDataList(list);
+
+        } catch (SQLException e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (st != null)
+                    st.close();
+                if (conn != null)
+                    conn.close();
+            } catch (SQLException e) {
+                e.printStackTrace();
+            }
+        }
+
+        return null;
+    }
+
+    @Cacheable
+    @Override
+    public List<TsPoint> findTsPointByIds(String... tagNames) {
+//        return DataUtil.convertDataList(baseMapper.selectBatchIds(Arrays.asList(tagNames)));
+
+        List<TsPointEntity> list = new ArrayList<>();
+
+        Connection conn = null;
+        Statement st = null;
+        try {
+            conn = config.getConnection();
+            st = conn.createStatement();
+
+            StringBuilder sb = new StringBuilder();
+            sb.append("select * from ").append(config.tableName);
+            sb.append(" where id in (");
+            sb.append(DataUtil.convertStringToSql(tagNames)).append(")");
+            String sql = sb.toString();
+            ResultSet rs = st.executeQuery(sql);
+
+            while (rs.next()) {
+                TsPointEntity entity = new TsPointEntity();
+                entity.setId(rs.getString("id"));
+                entity.setThingType(rs.getString("thing_type"));
+                entity.setThingId(rs.getString("thing_id"));
+                entity.setUniformCode(rs.getString("uniform_code"));
+                entity.setDataType(rs.getString("data_type"));
+
+                list.add(entity);
+            }
+
+            return DataUtil.convertDataList(list);
+
+        } catch (SQLException e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (st != null)
+                    st.close();
+                if (conn != null)
+                    conn.close();
+            } catch (SQLException e) {
+                e.printStackTrace();
+            }
+        }
+
+        return null;
+    }
+
+    @Cacheable
+    @Override
+    public List<TsPoint> findTsPointByThingIds(String thingType, String uniformCode, String... thingIds) {
+//        QueryWrapper<TsPointEntity> wrapper = new QueryWrapper<>();
+//        wrapper.eq("THING_TYPE", thingType);
+//        wrapper.eq("UNIFORM_CODE", uniformCode);
+//        wrapper.in("THING_ID",thingIds);
+//        return DataUtil.convertDataList(baseMapper.selectList(wrapper));
+
+        List<TsPointEntity> list = new ArrayList<>();
+
+        Connection conn = null;
+        Statement st = null;
+        try {
+            conn = config.getConnection();
+            st = conn.createStatement();
+
+            StringBuilder sb = new StringBuilder();
+            sb.append("select * from ").append(config.tableName);
+            sb.append(" where thing_type ='");
+            sb.append(thingType).append("' and uniform_code = '");
+            sb.append(uniformCode).append("' and thing_id in (");
+            sb.append(DataUtil.convertStringToSql(thingIds)).append(")");
+            ResultSet rs = st.executeQuery(sb.toString());
+
+            while (rs.next()) {
+                TsPointEntity entity = new TsPointEntity();
+                entity.setId(rs.getString("id"));
+                entity.setThingType(rs.getString("thing_type"));
+                entity.setThingId(rs.getString("thing_id"));
+                entity.setUniformCode(rs.getString("uniform_code"));
+                entity.setDataType(rs.getString("data_type"));
+
+                list.add(entity);
+            }
+
+            return DataUtil.convertDataList(list);
+
+        } catch (SQLException e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (st != null)
+                    st.close();
+                if (conn != null)
+                    conn.close();
+            } catch (SQLException e) {
+                e.printStackTrace();
+            }
+        }
+
+        return null;
+    }
+
+    @Cacheable
+    @Override
+    public TsPoint findTsPointById(String tagName) {
+//        TsPointEntity obj = baseMapper.selectById(tagName);
+//        return obj == null ? null : obj.toData();
+
+        Connection conn = null;
+        Statement st = null;
+        try {
+            conn = config.getConnection();
+            st = conn.createStatement();
+
+            String sql = "select * from " + config.tableName + " where id ='" + tagName + "'";
+            ResultSet rs = st.executeQuery(sql);
+
+            TsPointEntity entity = new TsPointEntity();
+            while (rs.next()) {
+                entity.setId(rs.getString("id"));
+                entity.setThingType(rs.getString("thing_type"));
+                entity.setThingId(rs.getString("thing_id"));
+                entity.setUniformCode(rs.getString("uniform_code"));
+                entity.setDataType(rs.getString("data_type"));
+            }
+
+            return entity.toData();
+
+        } catch (SQLException e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (st != null)
+                    st.close();
+                if (conn != null)
+                    conn.close();
+            } catch (SQLException e) {
+                e.printStackTrace();
+            }
+        }
+
+        return null;
+    }
+
+    @Cacheable
+    @Override
+    public List<TsPoint> getAllTsPoint() {
+//        return DataUtil.convertDataList(baseMapper.selectList(null));
+
+        List<TsPointEntity> list = new ArrayList<>();
+
+        Connection conn = null;
+        Statement st = null;
+        try {
+            conn = config.getConnection();
+            st = conn.createStatement();
+
+            String sql = "select * from " + config.tableName;
+
+            ResultSet rs = st.executeQuery(sql);
+
+            while (rs.next()) {
+                TsPointEntity entity = new TsPointEntity();
+                entity.setId(rs.getString("id"));
+                entity.setThingType(rs.getString("thing_type"));
+                entity.setThingId(rs.getString("thing_id"));
+                entity.setUniformCode(rs.getString("uniform_code"));
+                entity.setDataType(rs.getString("data_type"));
+
+                list.add(entity);
+            }
+
+            return DataUtil.convertDataList(list);
+
+        } catch (SQLException e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (st != null)
+                    st.close();
+                if (conn != null)
+                    conn.close();
+            } catch (SQLException e) {
+                e.printStackTrace();
+            }
+        }
+
+        return null;
+    }
+}

+ 211 - 0
src/main/java/com/gyee/wisdom/adapter/server/taos/TsDataService.java

@@ -0,0 +1,211 @@
+package com.gyee.wisdom.adapter.server.taos;
+
+import com.gyee.wisdom.adapter.common.exception.WisdomException;
+import com.gyee.wisdom.adapter.model.adapter.*;
+import com.gyee.wisdom.adapter.timeseries.dao.IHistoryDao;
+import com.gyee.wisdom.adapter.timeseries.dao.ILatestDao;
+import com.gyee.wisdom.adapter.common.constant.Interpolation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@Service
+public class TsDataService {
+
+    @Autowired
+    private ILatestDao latestDao;
+
+    @Autowired
+    private IHistoryDao historyDao;
+
+    @Autowired
+    private TsPointService tsPointService;
+
+
+    public Map<String, TsData> getLatest(String... tagNames) {
+        try {
+            List<TsPoint> tsPoints = tsPointService.getTsPoint(tagNames);
+            Map<String, TsData> result = latestDao.getTsDataLatest(tsPoints);
+            return result;
+        } catch (WisdomException e) {
+            log.error(e.getMessage());
+        } catch (Exception e) {
+            log.error(e.getMessage());
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * @param thingType
+     * @param thingId
+     * @param uniformCodes
+     * @return 返回值Map中key为统一编码,value为TsData
+     * @author wanghs
+     * @date 2018-10-23
+     */
+    public Map<String, TsData> getLatestByUniformCodes(String thingType, String thingId, String... uniformCodes) {
+        try {
+            List<TsPoint> pointList = tsPointService.getTsPoint(thingType, thingId, uniformCodes);
+            Map<String, TsData> dataMap = latestDao.getTsDataLatest(pointList);
+            Map<String, TsData> resultMap = new HashMap<>();
+            for (Map.Entry<String, TsData> entry : dataMap.entrySet()) {
+                for (int i = 0; i < pointList.size(); i++) {
+                    if (entry.getKey() == pointList.get(i).getId())
+                        resultMap.put(pointList.get(i).getUniformCode(), entry.getValue());
+                }
+            }
+            return resultMap;
+        } catch (WisdomException e) {
+            log.error(e.getMessage());
+        } catch (Exception e) {
+            log.error(e.getMessage());
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    public List<TsData> getHistoryRaw(String tagName, long startTs, long endTs) {
+        try {
+            TsPoint tsPoint = tsPointService.getTsPoint(tagName);
+            TsQuery tsQuery = new BaseTsQuery(tsPoint, startTs, endTs);
+            //long t1 = new Date().getTime();
+            List<TsData> obj = historyDao.getTsDataHistory(tsQuery);
+            //long t2 = new Date().getTime();
+            //System.out.println("tsxxxxxxxxxxxxx=" + (t2-t1));
+            return obj;
+        } catch (WisdomException e) {
+            log.error(e.getMessage());
+        } catch (Exception e) {
+            log.error(e.getMessage());
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+
+    public List<TsData> getHistoryRaw(String thingType, String thingId, String uniformCode, long startTs, long endTs) {
+        try {
+            TsPoint tsPoint = tsPointService.getTsPoint(thingType, thingId, uniformCode);
+            TsQuery tsQuery = new BaseTsQuery(tsPoint, startTs, endTs);
+            return historyDao.getTsDataHistory(tsQuery);
+        } catch (WisdomException e) {
+            log.error(e.getMessage());
+        } catch (Exception e) {
+            log.error(e.getMessage());
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+
+    public List<TsData> getHistorySnap(String tagName, long startTs, long endTs, int interval) {
+        try {
+            TsPoint tsPoint = tsPointService.getTsPoint(tagName);
+            System.out.println(tsPoint);
+            TsQuery tsQuery = new BaseTsQuery(tsPoint, startTs, endTs, interval, 0, Interpolation.SNAP);
+            return historyDao.getTsDataHistory(tsQuery);
+        } catch (WisdomException e) {
+            log.error(e.getMessage());
+        } catch (Exception e) {
+            log.error(e.getMessage());
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+
+    public List<TsData> getHistorySnap(String thingType, String thingId, String uniformCode, long startTs, long endTs, int interval) {
+        try {
+            TsPoint tsPoint = tsPointService.getTsPoint(thingType, thingId, uniformCode);
+            TsQuery tsQuery = new BaseTsQuery(tsPoint, startTs, endTs, interval, 0, Interpolation.SNAP);
+            return historyDao.getTsDataHistory(tsQuery);
+        } catch (WisdomException e) {
+            log.error(e.getMessage());
+        } catch (Exception e) {
+            log.error(e.getMessage());
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    public List<DoubleStatData> getHistoryStat(String tagName, long startTs, long endTs, int interval) {
+        try {
+            TsPoint tsPoint = tsPointService.getTsPoint(tagName);
+            TsQuery tsQuery = new BaseTsQuery(tsPoint, startTs, endTs, interval, 0, Interpolation.SNAP);
+            return historyDao.getDoubleStatDataHistory(tsQuery);
+        } catch (WisdomException e) {
+            log.error(e.getMessage());
+        } catch (Exception e) {
+            log.error(e.getMessage());
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+
+    public List<DoubleStatData> getHistoryStat(String thingType, String thingId, String uniformCode, long startTs, long endTs, int interval) {
+        try {
+            TsPoint tsPoint = tsPointService.getTsPoint(thingType, thingId, uniformCode);
+            TsQuery tsQuery = new BaseTsQuery(tsPoint, startTs, endTs, interval, 0, Interpolation.SNAP);
+            return historyDao.getDoubleStatDataHistory(tsQuery);
+        } catch (WisdomException e) {
+            log.error(e.getMessage());
+        } catch (Exception e) {
+            log.error(e.getMessage());
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+
+    public boolean writeHistory(List<TsPointData> dataList) throws Exception {
+        return historyDao.writeHistoryValue(dataList);
+    }
+
+    public boolean writeLatest(List<TsPointData> dataList) throws Exception {
+        return latestDao.writeLatest(dataList);
+    }
+
+    public Map<String, TsData> getHistorySection(long ts, String... tagNames) {
+        try {
+            List<TsPoint> tsPoints = tsPointService.getTsPoint(tagNames);
+            Map<String, TsData> result = historyDao.getHistorySection(tsPoints, ts);
+            return result;
+        } catch (WisdomException e) {
+            log.error(e.getMessage());
+        } catch (Exception e) {
+            log.error(e.getMessage());
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    public Map<String, TsData> getHistorySection(long ts, String thingId,String thingType,String...uniformCode) throws Exception {
+        try {
+            List<TsPoint>  pointList = tsPointService.getTsPoint(thingType,thingId,uniformCode);
+            Map<String, TsData> dataMap = historyDao.getHistorySection(pointList, ts);
+            Map<String, TsData> resultMap = new HashMap<>();
+            for (Map.Entry<String, TsData> entry : dataMap.entrySet()) {
+                for (int i = 0; i < pointList.size(); i++) {
+                    if (entry.getKey() == pointList.get(i).getId())
+                        resultMap.put(pointList.get(i).getUniformCode(), entry.getValue());
+                }
+            }
+            return resultMap;
+        } catch (WisdomException e) {
+            log.error(e.getMessage());
+        } catch (Exception e) {
+            log.error(e.getMessage());
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+
+}

+ 193 - 0
src/main/java/com/gyee/wisdom/adapter/server/taos/TsPointService.java

@@ -0,0 +1,193 @@
+package com.gyee.wisdom.adapter.server.taos;
+
+import com.gyee.wisdom.adapter.model.adapter.TsPoint;
+import com.gyee.wisdom.adapter.timeseries.dao.IThingsPointDao;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.*;
+
+
+@Service
+@Slf4j
+public class TsPointService {
+
+    //key:测点
+    private Map<String, TsPoint> tagMap = new HashMap<>();
+
+    //key1 风机编号,key2:风机统一编码
+    private Map<String, Map<String, TsPoint>> windturbineTagMap = new HashMap<>();
+
+    @Resource
+    private IThingsPointDao thingsPointDao;
+
+    public List<TsPoint> getTsPoint(String... tagNames) {
+        List<TsPoint> selectList = new ArrayList<>();
+        //先从缓存中获取
+
+       /* Map<String, TsPoint> tMap = tagMap.entrySet().stream()
+                .filter(s -> tagNameList.contains(s.getKey()))
+                .collect(Collectors.toMap(e -> (String) e.getKey(), e -> e.getValue()));*/
+
+        for (int i=0;i<tagNames.length;i++){
+            if(tagMap.containsKey(tagNames[i])){
+
+                selectList.add(tagMap.get(tagNames[i]));
+            }
+
+        }
+
+        if (selectList.size() > 0) {
+            return selectList;
+        }
+
+        if (tagNames.length > 1000) {
+
+            int selectCount = tagNames.length / 1000;
+            int remainder = tagNames.length % 1000;
+
+            if (remainder == 0) {
+
+                for (int i = 0; i < selectCount; i++) {
+                    String[] subTagName = Arrays.copyOfRange(tagNames, 1000 * i, 1000 * (i + 1));
+                    List<TsPoint> subList = thingsPointDao.findTsPointByIds(subTagName);
+                    selectList.addAll(subList);
+                }
+            } else {
+
+                for (int i = 0; i < selectCount; i++) {
+                    String[] subTagName = Arrays.copyOfRange(tagNames, 1000 * i, 1000 * (i + 1));
+                    List<TsPoint> subList = thingsPointDao.findTsPointByIds(subTagName);
+                    selectList.addAll(subList);
+                }
+                //将数组剩余元素进行查询
+                String[] lastTagName = Arrays.copyOfRange(tagNames, tagNames.length - remainder, tagNames.length);
+                List<TsPoint> lastSubList = thingsPointDao.findTsPointByIds(lastTagName);
+                selectList.addAll(lastSubList);
+            }
+        } 
+        else if(tagNames.length == 1){
+            TsPoint point = thingsPointDao.findTsPointById(tagNames[0]);
+            selectList.add(point);
+        }
+        else {
+            selectList = thingsPointDao.findTsPointByIds(tagNames);
+        }
+        return selectList;
+    }
+
+    public TsPoint getTsPoint(String tagName) {
+
+        TsPoint tsPoint = null;
+        if (this.tagMap.containsKey(tagName)) {
+            tsPoint = tagMap.get(tagName);
+        }
+        if (tsPoint != null) {
+            return tsPoint;
+        }
+        tsPoint = thingsPointDao.findTsPointById(tagName);
+        return tsPoint;
+    }
+
+    public List<TsPoint> getTsPoint(String thingsType, String thingsId, String... uniformCodes) {
+
+        List<TsPoint> selectList = new ArrayList<>();
+
+        //先从缓存中获取相关测点
+        Map<String, TsPoint> thingsUniformCodeMap = null;
+        if (windturbineTagMap.containsKey(thingsId)) {
+            thingsUniformCodeMap = this.windturbineTagMap.get(thingsId);
+        }
+        if (thingsUniformCodeMap != null) {
+
+            for (int i=0;i<uniformCodes.length;i++){
+                if(thingsUniformCodeMap.containsKey(uniformCodes[i])){
+                    selectList.add(thingsUniformCodeMap.get(uniformCodes[i]));
+                }
+            }
+        }
+        //如果缓存中的数据大于0 则直接返回数据不进行数据库查询
+        if (selectList.size() > 0) {
+            return selectList;
+        }
+        if (uniformCodes.length > 1000) {
+            int selectCount = uniformCodes.length / 1000;
+            int remainder = uniformCodes.length % 1000;
+
+            if (remainder == 0) {
+
+                for (int i = 0; i < selectCount; i++) {
+                    String[] uniformCodeArr = Arrays.copyOfRange(uniformCodes, 1000 * i, 1000 * (i + 1));
+                    List<TsPoint> subList = thingsPointDao.findTsPointByUniformCodes(thingsType, thingsId, uniformCodeArr);
+                    selectList.addAll(subList);
+                }
+            } else {
+
+                for (int i = 0; i < selectCount; i++) {
+                    String[] uniformCodeArr = Arrays.copyOfRange(uniformCodes, 1000 * i, 1000 * (i + 1));
+                    List<TsPoint> subList = thingsPointDao.findTsPointByUniformCodes(thingsType, thingsId, uniformCodeArr);
+                    selectList.addAll(subList);
+                }
+                //将数组剩余元素进行查询
+                String[] lastUniformCode = Arrays.copyOfRange(uniformCodes, uniformCodes.length - remainder, uniformCodes.length);
+                List<TsPoint> lastSubList = thingsPointDao.findTsPointByUniformCodes(thingsType, thingsId, lastUniformCode);
+                selectList.addAll(lastSubList);
+            }
+        } else {
+            selectList = thingsPointDao.findTsPointByUniformCodes(thingsType, thingsId, uniformCodes);
+        }
+        return selectList;
+
+    }
+
+    public TsPoint getTsPoint(String thingsType, String thingsId, String uniformCode) {
+
+        TsPoint tsPoint=null;
+
+        if(windturbineTagMap.containsKey(thingsId)){
+
+            Map<String,TsPoint> mp=windturbineTagMap.get(thingsId);
+
+            if(mp.containsKey(uniformCode)){
+                tsPoint=mp.get(uniformCode);
+            }
+        }
+        if(tsPoint!=null)
+        {
+            return tsPoint;
+        }
+
+        List<TsPoint> list = thingsPointDao.findTsPointByUniformCodes(thingsType, thingsId, uniformCode);
+        return list.size() > 0 ? list.get(0) : null;
+    }
+
+    public void getAllTsPointToCache() {
+
+        try {
+            List<TsPoint> lst = thingsPointDao.getAllTsPoint();
+            for (TsPoint point : lst) {
+                if (!tagMap.containsKey(point.getId())) {
+                    tagMap.put(point.getId(), point);
+                }
+                if (!windturbineTagMap.containsKey(point.getThingId())) {
+                    Map<String, TsPoint> uniformCodeMap = new HashMap<>();
+                    uniformCodeMap.put(point.getUniformCode(), point);
+                    windturbineTagMap.put(point.getThingId(), uniformCodeMap);
+                } else {
+                    Map<String, TsPoint> uniformCodeMap = windturbineTagMap.get(point.getThingId());
+
+                    if (!uniformCodeMap.containsKey(point.getUniformCode())) {
+                        uniformCodeMap.put(point.getUniformCode(), point);
+                    }
+                }
+            }
+        } catch (Exception ex) {
+            System.out.println("缓存所有测点发生异常");
+        }
+        System.out.println("测点缓存完毕");
+
+    }
+
+}

+ 7 - 0
src/main/java/com/gyee/wisdom/adapter/timeseries/TaosDao.java

@@ -0,0 +1,7 @@
+package com.gyee.wisdom.adapter.timeseries;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+
+@ConditionalOnProperty(prefix = "timeseries", value = "db-type", havingValue = "taos")
+public @interface TaosDao {
+}

+ 17 - 0
src/main/java/com/gyee/wisdom/adapter/timeseries/dao/IDataChangeDao.java

@@ -0,0 +1,17 @@
+package com.gyee.wisdom.adapter.timeseries.dao;
+
+import com.gyee.wisdom.adapter.model.adapter.TsData;
+import com.gyee.wisdom.adapter.model.adapter.TsPoint;
+
+import java.util.List;
+import java.util.Map;
+
+public interface IDataChangeDao {
+
+    void registerTopic(String topic, List<TsPoint> tsPoints);
+
+    void unRegisterTopic(String topic);
+
+    Map<String, TsData> getTopicDataChange(String topic);
+
+}

+ 26 - 0
src/main/java/com/gyee/wisdom/adapter/timeseries/dao/IHistoryDao.java

@@ -0,0 +1,26 @@
+package com.gyee.wisdom.adapter.timeseries.dao;
+
+import com.gyee.wisdom.adapter.model.adapter.*;
+
+import java.util.List;
+import java.util.Map;
+
+
+public interface IHistoryDao {
+
+    List<TsData> getTsDataHistory(TsQuery tsQuery) throws Exception;
+
+    List<DoubleStatData> getDoubleStatDataHistory(TsQuery tsQuery) throws Exception;
+
+    boolean writeHistoryValue(List<TsPointData> dataList) throws Exception;
+
+    /**
+     * @param tsPoints 标签点
+     * @param ts       时间点(秒级)
+     *                 上一个最近的数据
+     * @return
+     * @throws Exception
+     */
+    Map<String, TsData> getHistorySection(List<TsPoint> tsPoints, Long ts) throws Exception;
+
+}

+ 25 - 0
src/main/java/com/gyee/wisdom/adapter/timeseries/dao/ILatestDao.java

@@ -0,0 +1,25 @@
+package com.gyee.wisdom.adapter.timeseries.dao;
+
+import com.gyee.wisdom.adapter.model.adapter.TsData;
+import com.gyee.wisdom.adapter.model.adapter.TsPoint;
+import com.gyee.wisdom.adapter.model.adapter.TsPointData;
+
+import java.util.List;
+import java.util.Map;
+
+public interface ILatestDao {
+
+
+    Map<String, TsData> getTsDataLatest(List<TsPoint> tsPoints) throws Exception;
+
+    int writeDoubleLatest(List<TsPointData> list) throws Exception;
+
+    int writeStringLatest(List<TsPointData> list) throws Exception;
+
+    int writeBooleanLatest(List<TsPointData> list) throws Exception;
+
+    int writeLongLatest(List<TsPointData> list) throws Exception;
+
+    boolean writeLatest(List<TsPointData> dataList) throws Exception;
+
+}

+ 18 - 0
src/main/java/com/gyee/wisdom/adapter/timeseries/dao/IThingsPointDao.java

@@ -0,0 +1,18 @@
+package com.gyee.wisdom.adapter.timeseries.dao;
+
+import com.gyee.wisdom.adapter.model.adapter.TsPoint;
+
+import java.util.List;
+
+public interface IThingsPointDao {
+
+    List<TsPoint> findTsPointByUniformCodes(String thingType, String thingId, String... uCodes);
+
+    List<TsPoint> findTsPointByIds(String... tagNames);
+
+    List<TsPoint> findTsPointByThingIds(String thingType, String uniformCode, String... thingIds);
+
+    TsPoint findTsPointById(String tagName);
+
+    List<TsPoint> getAllTsPoint();
+}

+ 44 - 0
src/main/resources/application.yml

@@ -0,0 +1,44 @@
+server:
+  port: 8019
+  netty:
+    connection-timeout: 8000
+
+spring:
+  #热启动
+  devtools:
+    restart:
+      enabled: true
+      additional-paths: src/main/java
+      exclude: test/**
+
+timeseries:
+  db-type: taos #"${DATABASE_TYPE:sql}" # cassandra/kairosDB/hbase/opentsDB/influxDB/TiDB
+
+#taos数据库
+taos:
+  server_ip: 10.65.80.11
+  server_port: 6030
+  user_name: root
+  password: taosdata
+  pool_size: 5
+  max_pool_size: 20
+
+#hive数据库
+hive:
+  jdbc_driver: com.cloudera.impala.jdbc41.Driver
+  url: jdbc:impala://10.65.80.5:21050/gyee_kudu   #改这个ip和端口就行
+  pool_size: 5
+  max_pool_size: 10
+
+#适配器测点表
+windturbine.point.table_name: gyee_kudu.tspoint
+
+#备注
+#1、安装taos数据库客户端
+#2、配置C:\TDengine\cfg\taos.cfg文件
+#3、配置hosts文件
+#4、修改pom.xml文件的涛思数据库版本
+#5、修改application.yaml文件hive、taos的ip、port等
+#6、涛思数据库的版本要与服务器保持一致
+#7、部署时在服务器安装taos数据库客户端
+

BIN
src/main/resources/lib/ImpalaJDBC41.jar


+ 13 - 0
src/test/java/com/gyee/wisdom/adapter/WisdomAdapterApplicationTests.java

@@ -0,0 +1,13 @@
+package com.gyee.wisdom.adapter;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class WisdomAdapterApplicationTests {
+
+	@Test
+	void contextLoads() {
+	}
+
+}