From 5353617c7b2135ab00f98d8e05b2f8dfb2e096ed Mon Sep 17 00:00:00 2001
From: riku <risaku@163.com>
Date: 星期三, 30 六月 2021 09:55:40 +0800
Subject: [PATCH] 1. 新增污染权重分析功能

---
 src/main/kotlin/com/flightfeather/uav/model/BaseSection.kt          |   50 +
 src/main/kotlin/com/flightfeather/uav/model/BaseTag.kt              |   14 
 src/main/kotlin/com/flightfeather/uav/model/BaseSOP.kt              |   12 
 src/main/kotlin/com/flightfeather/uav/common/utils/ExcelUtil.kt     |  178 ++++++
 src/main/kotlin/com/flightfeather/uav/lightshare/bean/CompanySOP.kt |  218 ++++++++
 src/main/kotlin/com/flightfeather/uav/model/BaseWeight.kt           |   40 +
 src/main/kotlin/com/flightfeather/uav/model/epw/WeightType.kt       |   29 +
 src/main/kotlin/com/flightfeather/uav/model/epw/EPWModel.kt         |   42 -
 src/main/kotlin/com/flightfeather/uav/model/TimeTag.kt              |    9 
 src/main/kotlin/com/flightfeather/uav/model/epw/WindDirWeight.kt    |   28 
 src/main/kotlin/com/flightfeather/uav/model/BaseDataPrep.kt         |   19 
 src/main/kotlin/com/flightfeather/uav/model/BaseMData.kt            |   11 
 src/test/kotlin/com/flightfeather/uav/model/epw/EPWModelTest.kt     |  117 ++++
 pom.xml                                                             |  120 +++-
 src/main/kotlin/com/flightfeather/uav/lightshare/bean/DataVo.kt     |   14 
 src/main/resources/log4j2.xml                                       |  116 ++--
 src/main/kotlin/com/flightfeather/uav/model/epw/WindDisWeight.kt    |   24 
 src/main/kotlin/com/flightfeather/uav/model/epw/TimeSection.kt      |   35 +
 src/test/kotlin/com/flightfeather/uav/Test.kt                       |   19 
 src/main/kotlin/com/flightfeather/uav/model/BaseModel.kt            |  216 ++++++++
 src/main/kotlin/com/flightfeather/uav/socket/eunm/FactorType.kt     |   86 +++
 src/main/kotlin/com/flightfeather/uav/model/epw/EPWDataPrep.kt      |  138 +++++
 src/main/kotlin/com/flightfeather/uav/model/BaseEffect.kt           |   18 
 src/main/resources/application.yml                                  |   14 
 24 files changed, 1,418 insertions(+), 149 deletions(-)

diff --git a/pom.xml b/pom.xml
index 4e9ea76..f4855d6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -17,7 +17,7 @@
 
     <properties>
         <java.version>1.8</java.version>
-        <kotlin.version>1.2.71</kotlin.version>
+        <kotlin.version>1.5.0</kotlin.version>
         <!-- tk.mybatis -->
         <mapper.plugin>tk.mybatis.mapper.generator.MapperPlugin</mapper.plugin>
         <mapper.Mapper>tk.mybatis.mapper.common.Mapper</mapper.Mapper>
@@ -42,10 +42,6 @@
         <dependency>
             <groupId>org.jetbrains.kotlin</groupId>
             <artifactId>kotlin-reflect</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.jetbrains.kotlin</groupId>
-            <artifactId>kotlin-stdlib-jdk8</artifactId>
         </dependency>
 
         <dependency>
@@ -129,35 +125,61 @@
             <artifactId>fastjson</artifactId>
             <version>1.2.75</version>
         </dependency>
+        <dependency>
+            <groupId>org.jetbrains.kotlin</groupId>
+            <artifactId>kotlin-stdlib-jdk8</artifactId>
+            <version>${kotlin.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.jetbrains.kotlin</groupId>
+            <artifactId>kotlin-test-junit</artifactId>
+            <version>${kotlin.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/org.jetbrains.kotlin/kotlin-maven-plugin -->
+        <dependency>
+            <groupId>org.jetbrains.kotlin</groupId>
+            <artifactId>kotlin-maven-plugin</artifactId>
+            <version>${kotlin.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <!-- https://mvnrepository.com/artifact/org.jetbrains.kotlin/kotlin-maven-allopen -->
+        <dependency>
+            <groupId>org.jetbrains.kotlin</groupId>
+            <artifactId>kotlin-maven-allopen</artifactId>
+            <version>${kotlin.version}</version>
+        </dependency>
+
     </dependencies>
 
     <build>
-        <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
-        <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
+        <sourceDirectory>src/main/kotlin</sourceDirectory>
+        <testSourceDirectory>src/test/kotlin</testSourceDirectory>
         <plugins>
 <!--            <plugin>-->
 <!--                <groupId>org.springframework.boot</groupId>-->
 <!--                <artifactId>spring-boot-maven-plugin</artifactId>-->
 <!--            </plugin>-->
-<!--            <plugin>-->
-<!--                <groupId>org.jetbrains.kotlin</groupId>-->
-<!--                <artifactId>kotlin-maven-plugin</artifactId>-->
-<!--                <configuration>-->
-<!--                    <args>-->
-<!--                        <arg>-Xjsr305=strict</arg>-->
-<!--                    </args>-->
-<!--                    <compilerPlugins>-->
-<!--                        <plugin>spring</plugin>-->
-<!--                    </compilerPlugins>-->
-<!--                </configuration>-->
-<!--                <dependencies>-->
-<!--                    <dependency>-->
-<!--                        <groupId>org.jetbrains.kotlin</groupId>-->
-<!--                        <artifactId>kotlin-maven-allopen</artifactId>-->
-<!--                        <version>${kotlin.version}</version>-->
-<!--                    </dependency>-->
-<!--                </dependencies>-->
-<!--            </plugin>-->
+            <plugin>
+                <groupId>org.jetbrains.kotlin</groupId>
+                <artifactId>kotlin-maven-plugin</artifactId>
+                <configuration>
+                    <args>
+                        <arg>-Xjsr305=strict</arg>
+                    </args>
+                    <compilerPlugins>
+                        <plugin>spring</plugin>
+                    </compilerPlugins>
+                </configuration>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.jetbrains.kotlin</groupId>
+                        <artifactId>kotlin-maven-allopen</artifactId>
+                        <version>${kotlin.version}</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
             <!-- mybatis generator 鑷姩鐢熸垚浠g爜鎻掍欢 -->
             <plugin>
                 <groupId>org.mybatis.generator</groupId>
@@ -178,6 +200,50 @@
                     </dependency>
                 </dependencies>
             </plugin>
+<!--            <plugin>-->
+<!--                <groupId>org.jetbrains.kotlin</groupId>-->
+<!--                <artifactId>kotlin-maven-plugin</artifactId>-->
+<!--                <version>${kotlin.version}</version>-->
+<!--                <executions>-->
+<!--                    <execution>-->
+<!--                        <id>compile</id>-->
+<!--                        <phase>compile</phase>-->
+<!--                        <goals>-->
+<!--                            <goal>compile</goal>-->
+<!--                        </goals>-->
+<!--                    </execution>-->
+<!--                    <execution>-->
+<!--                        <id>test-compile</id>-->
+<!--                        <phase>test-compile</phase>-->
+<!--                        <goals>-->
+<!--                            <goal>test-compile</goal>-->
+<!--                        </goals>-->
+<!--                    </execution>-->
+<!--                </executions>-->
+<!--                <configuration>-->
+<!--                    <jvmTarget>1.8</jvmTarget>-->
+<!--                </configuration>-->
+<!--            </plugin>-->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>compile</id>
+                        <phase>compile</phase>
+                        <goals>
+                            <goal>compile</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>testCompile</id>
+                        <phase>test-compile</phase>
+                        <goals>
+                            <goal>testCompile</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
         </plugins>
     </build>
 
@@ -186,7 +252,7 @@
         <repository>
             <id>alimaven</id>
             <name>aliyun maven</name>
-            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
+            <url>https://maven.aliyun.com/repository/public</url>
         </repository>
         <repository>
             <id>spring-snapshots</id>
diff --git a/src/main/kotlin/com/flightfeather/uav/common/utils/ExcelUtil.kt b/src/main/kotlin/com/flightfeather/uav/common/utils/ExcelUtil.kt
index 0d41d40..c9c6086 100644
--- a/src/main/kotlin/com/flightfeather/uav/common/utils/ExcelUtil.kt
+++ b/src/main/kotlin/com/flightfeather/uav/common/utils/ExcelUtil.kt
@@ -12,9 +12,13 @@
  */
 object ExcelUtil {
 
+    private const val isLog = false
+
     class MyCell(
             var text: String,
-            var rowSpan: Int = 1
+            var rowSpan: Int = 1,
+            var colSpan: Int = 1,
+            var fontColor: Short? = null
     )
 
     /**
@@ -56,7 +60,7 @@
                                 rowspan = c.rowSpan
                             }
                             if (rowspan > 1) {
-                                println("鍚堝苟1-1锛�$rowIndex;${rowIndex + rowspan - 1};$i")
+                                log("鍚堝苟1-1锛�$rowIndex;${rowIndex + rowspan - 1};$i")
                                 sheet.addMergedRegion(CellRangeAddress(rowIndex, rowIndex + rowspan - 1, i, i))
                             }
                             if (cell.isEmpty()) {
@@ -67,7 +71,7 @@
                         } else {
                             //褰撴暟鎹笉鏄暟缁勬椂锛岄渶瑕佹寜鏈�澶ц鏁板悎骞跺崟鍏冩牸
                             if (rowspan > 1) {
-                                println("鍚堝苟1-2锛�$rowIndex;${rowIndex + rowspan - 1};$i")
+                                log("鍚堝苟1-2锛�$rowIndex;${rowIndex + rowspan - 1};$i")
                                 sheet.addMergedRegion(CellRangeAddress(rowIndex, rowIndex + rowspan - 1, i, i))
                             }
                             cell
@@ -75,11 +79,11 @@
                 when (c) {
                     is MyCell -> {
                         rows.createCell(i).setCellValue(c.text)
-                        println("write1-1: ${c.text};($rowIndex, ${i})")
+                        log("write1-1: ${c.text};($rowIndex, ${i})")
                     }
                     is String -> {
                         rows.createCell(i).setCellValue(c)
-                        println("write1-2: ${c};($rowIndex, ${i})")
+                        log("write1-2: ${c};($rowIndex, ${i})")
                     }
                     is Double -> rows.createCell(i).setCellValue(c)
                     is Boolean -> rows.createCell(i).setCellValue(c)
@@ -114,18 +118,170 @@
                             rows = sheet.getRow(_rowIndex) ?: sheet.createRow(_rowIndex)
                         }
                         if (rowspan > 1) {
-                            println("鍚堝苟2锛�${index};${index + rowspan - 1};$i")
+                            log("鍚堝苟2锛�${index};${index + rowspan - 1};$i")
                             sheet.addMergedRegion(CellRangeAddress(index, index + rowspan - 1, i, i))
                         }
 
                         when (c) {
                             is MyCell -> {
                                 rows.createCell(map.key).setCellValue(c.text)
-                                println("write2-1: ${c.text};($_rowIndex, ${map.key})")
+                                log("write2-1: ${c.text};($_rowIndex, ${map.key})")
                             }
                             is String -> {
                                 rows.createCell(map.key).setCellValue(c)
-                                println("write2-2: ${c};($_rowIndex, ${map.key})")
+                                log("write2-2: ${c};($_rowIndex, ${map.key})")
+                            }
+                            is Double -> rows.createCell(map.key).setCellValue(c)
+                            is Boolean -> rows.createCell(map.key).setCellValue(c)
+                            is Date -> rows.createCell(map.key).setCellValue(c)
+                            is Calendar -> rows.createCell(map.key).setCellValue(c)
+                            is LocalDate -> rows.createCell(map.key).setCellValue(c)
+                        }
+                    }
+                }
+            }
+
+            rowIndex++
+        }
+//        workbook.write(out)
+//        workbook.close()
+//        out.flush()
+//        out.close()
+    }
+
+    /**
+     * 鑷姩澶勭悊琛屽悎骞舵暟鎹�
+     */
+    fun write(heads: List<Array<String>>, contents: List<Array<Any>>, workbook: HSSFWorkbook, sheetName: String = "sheet1") {
+
+        val sheet = workbook.createSheet(sheetName)
+        println("sheet: $sheetName")
+
+        var rowIndex = 0
+
+        heads.forEach {
+            val rows = sheet.createRow(rowIndex)
+            for (i in it.indices) {
+                rows.createCell(i).setCellValue(it[i])
+            }
+            rowIndex++
+        }
+
+        contents.forEach {
+            val maxRow = getMaxRows(it)
+
+            var rows = sheet.getRow(rowIndex) ?: sheet.createRow(rowIndex)
+
+            val arrayMap = mutableMapOf<Int, Array<*>>()
+
+            //鍒楀簭鍙�
+            var col = 0
+            for (i in it.indices) {
+                val cell = it[i]
+
+                var rowspan = maxRow//鍚堝苟鐨勮鐨勮法搴�
+                var colSpan = 1
+
+                val c =
+                    if (cell is Array<*>) {
+                        //褰撴暟鎹负鏁扮粍鏃讹紝闇�瑕佹牴鎹渶澶ц鏁伴噸鏂拌绠楄鍗曞厓鏍肩殑琛岃法搴�
+                        arrayMap[col] = cell
+                        rowspan = maxRow / if (cell.size == 0) 1 else cell.size
+                        val c = cell[0]
+                        if (c is MyCell) {
+                            rowspan = c.rowSpan
+                            colSpan = c.colSpan
+                        }
+                        if (rowspan > 1 || colSpan > 1) {
+                            log("鍚堝苟1-1锛�$rowIndex;${rowIndex + rowspan - 1};$col")
+                            sheet.addMergedRegion(CellRangeAddress(rowIndex, rowIndex + rowspan - 1, col, col + colSpan - 1))
+                        }
+                        if (cell.isEmpty()) {
+                            ""
+                        } else {
+                            cell[0]
+                        }
+                    } else {
+                        //褰撴暟鎹笉鏄暟缁勬椂锛岄渶瑕佹寜鏈�澶ц鏁板悎骞跺崟鍏冩牸
+                        if (cell is MyCell) {
+                            rowspan = cell.rowSpan
+                            colSpan = cell.colSpan
+                        }
+                        if (rowspan > 1 || colSpan > 1) {
+                            log("鍚堝苟1-2锛�$rowIndex;${rowIndex + rowspan - 1};$col")
+                            sheet.addMergedRegion(CellRangeAddress(rowIndex, rowIndex + rowspan - 1, col, col + colSpan - 1))
+                        }
+                        cell
+                    }
+                when (c) {
+                    is MyCell -> {
+                        rows.createCell(col).apply {
+                            c.fontColor?.let {fC ->
+                                val font = workbook.createFont()
+                                val cellStyle = workbook.createCellStyle()
+
+                                font.color = fC
+                                cellStyle.setFont(font)
+                                setCellStyle(cellStyle)
+                            }
+                            setCellValue(c.text)
+                        }
+                        log("write1-1: ${c.text};($rowIndex, ${col})")
+                    }
+                    is String -> {
+                        rows.createCell(col).setCellValue(c)
+                        log("write1-2: ${c};($rowIndex, ${col})")
+                    }
+                    is Double -> rows.createCell(col).setCellValue(c)
+                    is Int -> rows.createCell(col).setCellValue(c.toDouble())
+                    is Boolean -> rows.createCell(col).setCellValue(c)
+                    is Date -> rows.createCell(col).setCellValue(c)
+                    is Calendar -> rows.createCell(col).setCellValue(c)
+                    is LocalDate -> rows.createCell(col).setCellValue(c)
+                }
+
+                col += colSpan
+            }
+
+            for (i in 1 until maxRow) {
+                rowIndex++
+                arrayMap.forEach { map ->
+                    rows = sheet.getRow(rowIndex) ?: sheet.createRow(rowIndex)
+                    val array = map.value
+                    if (i < array.size) {
+//                        var rowspan = maxRow / array.size
+                        var lastRowSpan = 1
+                        var rowspan = 1
+                        var colSpan = 1
+                        val c = array[i]
+                        if (c is MyCell) {
+                            rowspan = c.rowSpan
+                            colSpan = c.colSpan
+                        }
+                        val _c = array[i - 1]
+                        if (_c is MyCell) {
+                            lastRowSpan = _c.rowSpan
+                        }
+                        var _rowIndex = rowIndex
+                        var index = rowIndex
+                        if (lastRowSpan > 1) {
+                            index = rowIndex + (i * lastRowSpan) - 1
+                            _rowIndex = index
+                            rows = sheet.getRow(_rowIndex) ?: sheet.createRow(_rowIndex)
+                        }
+                        if (rowspan > 1 || colSpan > 1) {
+                            log("鍚堝苟2锛�${index};${index + rowspan - 1};${map.key}")
+                            sheet.addMergedRegion(CellRangeAddress(index, index + rowspan - 1, map.key, map.key + colSpan - 1))
+                        }
+
+                        when (c) {
+                            is MyCell -> {
+                                rows.createCell(map.key).setCellValue(c.text)
+                                log("write2-1: ${c.text};($_rowIndex, ${map.key})")
+                            }
+                            is String -> {
+                                rows.createCell(map.key).setCellValue(c)
+                                log("write2-2: ${c};($_rowIndex, ${map.key})")
                             }
                             is Double -> rows.createCell(map.key).setCellValue(c)
                             is Boolean -> rows.createCell(map.key).setCellValue(c)
@@ -154,4 +310,10 @@
         }
         return maxRows
     }
+
+    private fun log(log: String) {
+        if (isLog) {
+            println(log)
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/bean/CompanySOP.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/bean/CompanySOP.kt
new file mode 100644
index 0000000..46329d7
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/bean/CompanySOP.kt
@@ -0,0 +1,218 @@
+package com.flightfeather.uav.lightshare.bean
+
+import com.flightfeather.uav.model.BaseSOP
+import java.math.BigDecimal
+import java.util.*
+
+/**
+ * 宸ヤ笟浼佷笟姹℃煋婧愪俊鎭�
+ */
+class CompanySOP(sourceId: String, sourceName: String, index:String) : BaseSOP(sourceId, sourceName, index) {
+
+    /**
+     * 涓昏浠庝簨涓氬姟
+     */
+
+    var ciMainBusiness: String? = null
+
+    /**
+     * 鎵�灞為泦鍥�
+     */
+
+    var ciMemberGroup: String? = null
+
+    /**
+     * 鐪佷唤缂栫爜
+     */
+
+    var ciProvinceCode: String? = null
+
+    /**
+     * 鐪佷唤鍚嶇О
+     */
+
+    var ciProvinceName: String? = null
+
+    /**
+     * 鍦板競缂栫爜
+     */
+
+    var ciCityCode: String? = null
+
+    /**
+     * 鍦板競鍚嶇О
+     */
+
+    var ciCityName: String? = null
+
+    /**
+     * 鍖哄幙缂栧彿
+     */
+
+    var ciDistrictCode: String? = null
+
+    /**
+     * 鍖哄幙鍚嶇О
+     */
+
+    var ciDistrictName: String? = null
+
+    /**
+     * 琛楅晣缂栫爜
+     */
+
+    var ciTownCode: String? = null
+
+    /**
+     * 琛楅晣鍚嶇О
+     */
+
+    var ciTownName: String? = null
+
+    /**
+     * 鎵�鍦ㄥ伐涓氬尯
+     */
+
+    var ciIndDistrict: String? = null
+
+    /**
+     * 鍗曚綅鍦板潃
+     */
+
+    var ciAddress: String? = null
+
+    /**
+     * 涓績缁忓害
+     */
+
+    var ciLongitude: BigDecimal? = null
+
+    /**
+     * 涓績绾害
+     */
+
+    var ciLatitude: BigDecimal? = null
+
+    /**
+     * 缁勭粐鏈烘瀯浠g爜
+     */
+
+    var ciOrgCode: String? = null
+
+    /**
+     * 娉曚汉
+     */
+
+    var ciJuridicalPerson: String? = null
+
+    /**
+     * 琛屼笟绫诲埆
+     */
+
+    var ciIndClassification: String? = null
+
+    /**
+     * 琛屼笟浠g爜
+     */
+
+    var ciIndustryCode: String? = null
+
+    /**
+     * 鐧昏娉ㄥ唽绫诲瀷
+     */
+
+    var ciRegistrationType: String? = null
+
+    /**
+     * 娉ㄥ唽璧勬湰锛堜竾鍏冿級
+     */
+
+    var ciRegisteredCapital: Int? = null
+
+    /**
+     * 寤哄巶骞存湀
+     */
+
+    var ciBuildDate: Date? = null
+
+    /**
+     * 鏈�鏂版敼鎵╁缓骞存湀
+     */
+
+    var ciExpansionDate: Date? = null
+
+    /**
+     * 鑱屽伐浜烘暟
+     */
+
+    var ciWorkersNumber: Int? = null
+
+    /**
+     * 浼佷笟瑙勬ā
+     */
+
+    var ciScale: Byte? = null
+
+    /**
+     * 鍘嗘鐜瘎瀹℃壒骞存湀
+     */
+
+    var ciEiaApprovarDate: String? = null
+
+    /**
+     * 鎺掓薄璁稿彲璇佺紪鍙�
+     */
+
+    var ciPltPermitCode: String? = null
+
+    /**
+     * 鎺掓薄鏉冧氦鏄撴枃浠�
+     */
+
+    var ciTradingFiles: String? = null
+
+    /**
+     * 閭斂缂栫爜
+     */
+
+    var ciPostalCode: String? = null
+
+    /**
+     * 鑱旂郴浜哄鍚�
+     */
+
+    var ciContactName: String? = null
+
+    /**
+     * 鑱旂郴鐢佃瘽
+     */
+
+    var ciTelephone: String? = null
+
+    /**
+     * 鑱旂郴寰俊鍙�
+     */
+
+    var ciContactsWx: String? = null
+
+    /**
+     * 浼犵湡
+     */
+
+    var ciFax: String? = null
+
+    /**
+     * 鐢靛瓙閭
+     */
+
+    var ciEmail: String? = null
+
+
+    var ciExtension2: String? = null
+
+
+    var ciExtension3: String? = null
+
+
+    var ciRemark: String? = null
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/bean/DataVo.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/bean/DataVo.kt
index c3b6f14..832df5a 100644
--- a/src/main/kotlin/com/flightfeather/uav/lightshare/bean/DataVo.kt
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/bean/DataVo.kt
@@ -1,7 +1,9 @@
 package com.flightfeather.uav.lightshare.bean
 
 import com.fasterxml.jackson.annotation.JsonInclude
+import com.flightfeather.uav.model.BaseMData
 import com.flightfeather.uav.socket.bean.AirData
+import com.flightfeather.uav.socket.eunm.FactorType
 
 /**
  * @author riku
@@ -19,4 +21,14 @@
         var lng: Double? = null,
         //绾害
         var lat: Double? = null
-)
\ No newline at end of file
+) : BaseMData() {
+        override fun getFactorData(type: FactorType): Double? {
+                if (values == null) throw IllegalStateException(this.javaClass.name + ": 鐩戞祴鏁版嵁鏁扮粍涓簄ull")
+                for (d in values!!) {
+                        if (d.factorName == type.name) {
+                                return d.factorData
+                        }
+                }
+                return null
+        }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/model/BaseDataPrep.kt b/src/main/kotlin/com/flightfeather/uav/model/BaseDataPrep.kt
new file mode 100644
index 0000000..749ea18
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/model/BaseDataPrep.kt
@@ -0,0 +1,19 @@
+package com.flightfeather.uav.model
+
+/**
+ * 鏁版嵁棰勫鐞嗘ā鍧�
+ * 瀵逛簬[BaseModel]杩涜妯″瀷鍒嗘瀽鏃讹紝瀵瑰師鏁版嵁闇�瑕佽繘琛屽紓甯稿�煎墧闄ゅ強缂哄け鏁版嵁琛ュ厖绛夐澶勭悊鎿嶄綔锛�
+ * 浣垮師濮嬫暟鎹浉瀵规洿鍔犳帴杩戠湡瀹炴儏鍐�
+ */
+abstract class BaseDataPrep<M : BaseMData, S : BaseSOP> {
+
+    /**
+     * 鐩戞祴鏁版嵁棰勫鐞�
+     */
+    abstract fun mDataPrep(mDataList: List<M>): List<M>
+
+    /**
+     * 姹℃煋婧愰澶勭悊
+     */
+    abstract fun sopPrep(sopList: List<S>): List<S>
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/model/BaseEffect.kt b/src/main/kotlin/com/flightfeather/uav/model/BaseEffect.kt
new file mode 100644
index 0000000..305395d
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/model/BaseEffect.kt
@@ -0,0 +1,18 @@
+package com.flightfeather.uav.model
+
+import com.flightfeather.uav.socket.eunm.FactorType
+
+/**
+ * 鍗曚釜姹℃煋婧愬鏌愭潯鐩戞祴鏁版嵁浜х敓鐨勫奖鍝嶇粨鏋�
+ */
+class BaseEffect(
+//    姹℃煋婧愭爣璇�
+    val sourceId: String,
+    val sourceName: String,
+    val index: String
+){
+    //    褰卞搷缁撴灉鍊�
+    val value = mutableListOf<Pair<FactorType, Double>>()
+    //    鍒嗙被鏍囩
+    val tag = mutableListOf<BaseTag>()
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/model/BaseMData.kt b/src/main/kotlin/com/flightfeather/uav/model/BaseMData.kt
new file mode 100644
index 0000000..a017bcc
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/model/BaseMData.kt
@@ -0,0 +1,11 @@
+package com.flightfeather.uav.model
+
+import com.flightfeather.uav.socket.eunm.FactorType
+
+/**
+ * Monitoring data
+ * 鐩戞祴鏁版嵁 鍩虹被
+ */
+abstract class BaseMData {
+    abstract fun getFactorData(type: FactorType): Double?
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/model/BaseModel.kt b/src/main/kotlin/com/flightfeather/uav/model/BaseModel.kt
new file mode 100644
index 0000000..dc24be6
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/model/BaseModel.kt
@@ -0,0 +1,216 @@
+package com.flightfeather.uav.model
+
+import com.flightfeather.uav.common.utils.DateUtil
+import com.flightfeather.uav.common.utils.ExcelUtil
+import com.flightfeather.uav.socket.eunm.FactorType
+import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook
+import org.apache.poi.hssf.usermodel.HSSFWorkbook
+import java.io.File
+import java.io.FileOutputStream
+import java.util.*
+import kotlin.math.round
+
+/**
+ * 姹℃煋婧愬奖鍝嶇▼搴︽潈閲嶅垎鏋愭ā鍨�
+ * 鍩虹被
+ */
+abstract class BaseModel<M : BaseMData, S : BaseSOP> {
+
+    abstract var dataPrep: BaseDataPrep<M, S>
+
+    // 鏉冮噸鍥犲瓙锛屽湪杩涜璁$畻鍒嗘瀽鏃朵娇鐢ㄧ殑鐩戞祴鍥犲瓙
+    abstract var factorTypes: List<FactorType>
+
+    // 鏉冮噸鍊硷紝澶氱鏉冮噸杩涜涔樼Н璁$畻
+    abstract var weights: List<BaseWeight<M, S>>
+
+    // 璁$畻缁撴灉
+    private val result = mutableSetOf<BaseEffect>()
+
+    // 缁撴灉绛涢�夋柟寮�
+    abstract var sections: List<BaseSection<M, S>>
+
+    /**
+     * 姹℃煋婧愬奖鍝嶇▼搴﹁绠�
+     * @param mDataList 鐩戞祴鏁版嵁闆嗗悎
+     * @param sopList 姹℃煋婧愰泦鍚�
+     */
+    fun execute(mDataList: List<M>, sopList: List<S>) {
+        result.clear()
+
+        //1. 鏁版嵁棰勫鐞�
+        val mList = dataPrep.mDataPrep(mDataList)
+        val sList = dataPrep.sopPrep(sopList)
+
+        mList.forEach m@{ m ->
+            if (!mDataCheck(m)) return@m
+            sList.forEach s@{ s ->
+                if (!sopCheck(s)) return@s
+                weightCompute(m, s)
+            }
+        }
+    }
+
+    /**
+     * 鍗曠偣鏉冮噸璁$畻
+     * 璁$畻姹℃煋婧愬鍗曟鐩戞祴鏁版嵁浜х敓鐨勫奖鍝嶆晥鏋�
+     * @param mData 鐩戞祴鏁版嵁
+     * @param sop 姹℃煋婧�
+     */
+    private fun weightCompute(mData: M, sop: S) {
+        val effect = BaseEffect(sop.sourceId, sop.sourceName, sop.index)
+
+        // 灏嗗師鐩戞祴鏁版嵁鎸夌収鏉冮噸璁$畻鍑虹粨鏋滃��
+        factorTypes.forEach { type ->
+            var result = mData.getFactorData(type) ?: return@forEach
+            weights.forEach {
+                result *= it.getWeight(mData, sop)?: return
+            }
+            effect.value.add(Pair(type, result))
+        }
+
+        // 鍚戠粨鏋滃�兼坊鍔犵瓫閫夋爣绛�
+        sections.forEach { it.filter(mData, sop, effect) }
+
+        // 淇濆瓨缁撴灉
+        result.add(effect)
+    }
+
+    fun outputToExcel(
+        fName: String? = null,
+        _workbook: HSSFWorkbook? = null,
+        _out: FileOutputStream? = null,
+        sheetName: String = "sheet1",
+        done: Boolean = true
+    ): Pair<HSSFWorkbook, FileOutputStream>? {
+        val rMap = formatConversion()
+
+        val workbook = _workbook ?: HSSFWorkbook()
+        val fileName = fName ?: "姹℃煋婧簮鏉冮噸妯″瀷${DateUtil().DateToString(Date(), "yyyy-MM-ddHHmmss")}.xls"
+//        val filePath = "E:\\work\\export\\$fileName"
+//        val filePath = "E:\\宸ヤ綔\\寮�鍙慭\璧拌埅鐩戞祴\\绠楁硶鐩稿叧\\鑷姩杈撳嚭\\$fileName"
+        val filePath = "E:\\宸ヤ綔\\寮�鍙慭\璧拌埅鐩戞祴\\绠楁硶鐩稿叧\\鑷姩杈撳嚭\\缃戞牸鍖朶\$fileName"
+        val out = _out ?: FileOutputStream(File(filePath))
+
+        // 琛ㄥご缁勶紙澶氳琛ㄥご锛�
+        val heads = mutableListOf<Array<String>>()
+        // 琛ㄥご琛�
+        val h1 = mutableListOf<String>()
+        h1.add("缂栧彿")
+        h1.add("姹℃煋婧�")
+//        arrayOf("鏃╀笂", "涓婂崍", "涓崍", "涓嬪崍", "鍌嶆櫄", "澶滈棿")
+
+        val contents = mutableListOf<Array<Any>>()
+        var isFirst = true
+        rMap.forEach { (source, tMap) ->
+            // 鏂板缓涓�琛�
+            val contentList = mutableListOf<Any>()
+            // 娣诲姞姹℃煋婧愬悕绉�
+            val l = source.split("(")
+            val index = l[1].substring(0, l[1].lastIndex)
+            contentList.add(index.toIntOrNull() ?: 0)
+            contentList.add(l[0])
+            tMap.forEach { (factorType, lMap) ->
+                sections.forEach {
+                    val types = mutableListOf<String>().apply {
+                        addAll(it.sectionType)
+                        addAll(it.constType)
+                    }
+                    var max = 0.0
+                    var maxP = types[0]
+                    types.forEach {se ->
+                        val lKey = "$se($factorType)"
+                        if (lMap.containsKey(lKey)) {
+                            val dataList = lMap[lKey]
+                            val size = dataList?.size
+                            // 娣诲姞璇ュ垎绫讳綔涓鸿〃澶�
+                            val h = lKey
+//                            val h = "$lKey($size)"
+                            if (!h1.contains(h)) {
+                                h1.add(h)
+                            }
+
+                            // 灏嗗師濮嬬殑鏁版嵁鎹㈢畻寰楀嚭缁撴灉锛屽彲浠ユ槸姹傚嚭鍧囧�笺�佹�诲拰绛夌瓑锛屽悗缁慨鏀逛负鍙敱鐢ㄦ埛璁惧畾
+                            // FIXME: 2021/6/23 姝ゅ鍏堥粯璁や负姹傚潎鍊�
+                            val average = dataList?.average()
+
+                            if (average ?: 0.0 > max) {
+                                max = average ?: 0.0
+                                maxP = se
+                            }
+
+                            // 褰撳墠琛屾坊鍔犺鍒嗙被涓嬬殑缁撴灉鍊�
+                            contentList.add(average ?: 0.0)
+                        }
+                    }
+                    if (isFirst) {
+                        h1.add("鏈�楂樻椂娈�")
+                        h1.add("鏈�楂樻椂娈靛��")
+                    }
+                    contentList.add(maxP)
+                    contentList.add(max)
+                }
+            }
+            isFirst = false
+            contents.add(contentList.toTypedArray())
+        }
+
+        contents.sortByDescending {
+            val i = it[0]
+            if (i is Int) {
+                i
+            } else {
+                0
+            }
+        }
+
+        heads.add(h1.toTypedArray())
+        ExcelUtil.write(heads, contents, workbook, sheetName)
+        return if (!done) {
+            Pair(workbook, out)
+        } else {
+            workbook.write(out)
+            workbook.close()
+            out.flush()
+            out.close()
+            null
+        }
+    }
+
+    private fun formatConversion(): Map<String, Map<String, Map<String?, MutableList<Double>>>> {
+        val rMap = mutableMapOf<String, MutableMap<String, MutableMap<String?, MutableList<Double>>>>()
+        println("缁撴灉闀垮害锛�${result.size}")
+        result.forEach { e ->
+            val rKey = "${e.sourceName}(${e.index})"
+            if (!rMap.containsKey(rKey)) {
+                rMap[rKey] = mutableMapOf()
+            }
+            val lMap = rMap[rKey]!!
+            e.value.forEach { v ->
+                if (!lMap.containsKey(v.first.des)) {
+                    lMap[v.first.des] = mutableMapOf()
+                }
+                val tMap = lMap[v.first.des]!!
+                e.tag.forEach { t ->
+                    val factorName = v.first.des
+                    val lKey = t.levelName + "($factorName)"
+                    if (!tMap.containsKey(lKey)) {
+                        tMap[lKey] = mutableListOf()
+                    }
+                    tMap[lKey]?.add(v.second)
+                }
+            }
+        }
+        return rMap
+    }
+
+    /**
+     * 鐩戞祴鏁版嵁鍚堟硶鎬ф鏌�
+     */
+    abstract fun mDataCheck(m: M): Boolean
+
+    /**
+     * 姹℃煋婧愭暟鎹悎娉曟�ф鏌�
+     */
+    abstract fun sopCheck(s: S): Boolean
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/model/BaseSOP.kt b/src/main/kotlin/com/flightfeather/uav/model/BaseSOP.kt
new file mode 100644
index 0000000..2c7d1d8
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/model/BaseSOP.kt
@@ -0,0 +1,12 @@
+package com.flightfeather.uav.model
+
+/**
+ * Source of pollution
+ * 姹℃煋婧� 鍩虹被
+ */
+open class BaseSOP(
+    // 姹℃煋婧愭爣璇�
+    var sourceId: String,
+    var sourceName: String,
+    var index: String
+)
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/model/BaseSection.kt b/src/main/kotlin/com/flightfeather/uav/model/BaseSection.kt
index 01a3310..71deb4c 100644
--- a/src/main/kotlin/com/flightfeather/uav/model/BaseSection.kt
+++ b/src/main/kotlin/com/flightfeather/uav/model/BaseSection.kt
@@ -1,9 +1,55 @@
 package com.flightfeather.uav.model
 
+import com.flightfeather.uav.lightshare.bean.DataVo
+
 /**
- * 缁熻鍒嗘鎴潰
+ * 缁熻鍒嗙被
  * 鍚屼竴绫诲瀷鐨勭洃娴嬪洜瀛愭寜鐓ф煇涓�灞炴�ц繘琛屽垎娈电患鍚堢粺璁★紝杈撳嚭缁熻缁撴灉锛�
  * 甯歌鐨勫鎸夌収鏃堕棿杩涜鍒嗘缁熻
  */
-abstract class BaseSection {
+abstract class BaseSection<M : BaseMData, S : BaseSOP> {
+
+    // 鍖洪棿闃堝��
+    abstract val sectionValues: List<Double>
+
+    // 鍖洪棿瀵瑰簲绫诲瀷
+    abstract val sectionType: List<String>
+
+    // 甯搁┗鏍囩
+    open val constType = listOf<String>()
+
+    abstract val tagClz: Class<out BaseTag>
+
+    fun filter(mData: M, sop: S, effect: BaseEffect) {
+        val v = onSectionValue(mData, sop, effect)
+        val type = sectionCal(v)
+        val tag = tagClz.newInstance()
+        tag.level = type.first
+        tag.levelName = type.second
+        effect.tag.add(tag)
+
+        var level = sectionType.size
+        constType.forEach {
+            val cTag = tagClz.newInstance()
+            cTag.level = level
+            cTag.levelName = it
+            effect.tag.add(cTag)
+            level++
+        }
+    }
+
+    abstract fun onSectionValue(mData: M, sop: S, effect: BaseEffect): Double
+
+    /**
+     * 绫诲瀷绛涢��
+     * @param value 褰卞搷鍥犵礌鐨勫��
+     */
+    private fun sectionCal(value: Double): Pair<Int, String> {
+        for (i in sectionValues.indices) {
+            if (value < sectionValues[i]) {
+                return Pair(i, sectionType[i])
+            }
+        }
+        return Pair(sectionType.lastIndex, sectionType.last())
+    }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/model/BaseTag.kt b/src/main/kotlin/com/flightfeather/uav/model/BaseTag.kt
new file mode 100644
index 0000000..42673b3
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/model/BaseTag.kt
@@ -0,0 +1,14 @@
+package com.flightfeather.uav.model
+
+/**
+ * 姹℃煋婧愬奖鍝嶇粨鏋滅瓫閫夌被鍨�
+ */
+abstract class BaseTag {
+
+    // 绛涢�夌被鍨嬪悕绉�
+    abstract var name: String
+    // 褰撳墠绛涢�夌骇鍒�
+    var level: Int = 0
+    // 褰撳墠绛涢�夌骇鍒悕绉�
+    var levelName: String? = null
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/model/BaseWeight.kt b/src/main/kotlin/com/flightfeather/uav/model/BaseWeight.kt
index 247845c..82e258b 100644
--- a/src/main/kotlin/com/flightfeather/uav/model/BaseWeight.kt
+++ b/src/main/kotlin/com/flightfeather/uav/model/BaseWeight.kt
@@ -1,21 +1,53 @@
 package com.flightfeather.uav.model
 
+import com.flightfeather.uav.lightshare.bean.DataVo
+
 /**
  * 鏉冮噸
  * 鏌愮褰卞搷鍥犵礌鍦ㄤ笉鍚屾儏鍐典笅瀵规煇绉嶇洃娴嬫暟鎹骇鐢熺殑鏉冮噸褰卞搷
  */
-abstract class BaseWeight {
+abstract class BaseWeight <M: BaseMData, S : BaseSOP> {
 
-//    鍖洪棿闃堝��
+    abstract val tag:String
+
+    // 鍖洪棿闃堝��
     abstract val sectionValues: List<Double>
-//    鍖洪棿瀵瑰簲鏉冮噸
+
+    // 鍖洪棿瀵瑰簲鏉冮噸
     abstract val weights: List<Double>
+
+    // 涓婃璁$畻鐨勬潈閲嶅��
+    private var lastWeight = -1.0
+
+    // 鏉冮噸鏄惁鍙樺寲
+    var isChange = true
+
+    fun getWeight(mData: M, sop: S): Double? {
+        if (!isChange) {
+            if (lastWeight < 0) {
+                val v = onWeightFactor(mData, sop) ?: return null
+                lastWeight = weightCal(v)
+            }
+//            println("$tag: $lastWeight")
+            return lastWeight
+        } else {
+            val v = onWeightFactor(mData, sop) ?: return null
+            lastWeight = weightCal(v)
+//            println("$tag: $lastWeight")
+            return lastWeight
+        }
+    }
+
+    /**
+     * 鑾峰彇鏉冮噸鍥犲瓙鍊�
+     */
+    abstract fun onWeightFactor(mData: M, sop: S): Double?
 
     /**
      * 鏉冮噸璁$畻
      * @param value 褰卞搷鍥犵礌鐨勫��
      */
-    fun weightCal(value: Double): Double {
+    private fun weightCal(value: Double): Double {
         for (i in sectionValues.indices) {
             if (value < sectionValues[i]) {
                 return weights[i]
diff --git a/src/main/kotlin/com/flightfeather/uav/model/TimeTag.kt b/src/main/kotlin/com/flightfeather/uav/model/TimeTag.kt
new file mode 100644
index 0000000..677fe4c
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/model/TimeTag.kt
@@ -0,0 +1,9 @@
+package com.flightfeather.uav.model
+
+/**
+ * 鏃舵鏍囩
+ * [6,9,12,14,17,20]; [6,9)涓烘棭涓婏紝涔嬪悗渚濇涓轰笂鍗堬紝涓崍锛屼笅鍗堬紝鍌嶆櫄鍜屾櫄涓�
+ */
+class TimeTag :BaseTag() {
+    override var name: String = "鏃舵"
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/model/epw/EPWDataPrep.kt b/src/main/kotlin/com/flightfeather/uav/model/epw/EPWDataPrep.kt
new file mode 100644
index 0000000..ed0a404
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/model/epw/EPWDataPrep.kt
@@ -0,0 +1,138 @@
+package com.flightfeather.uav.model.epw
+
+import com.flightfeather.uav.lightshare.bean.CompanySOP
+import com.flightfeather.uav.lightshare.bean.DataVo
+import com.flightfeather.uav.model.BaseDataPrep
+import com.flightfeather.uav.socket.eunm.FactorType
+import kotlin.math.max
+import kotlin.math.min
+import kotlin.math.sqrt
+
+class EPWDataPrep : BaseDataPrep<DataVo, CompanySOP>() {
+
+    // 鍚戝墠妫�绱㈢殑鏁版嵁璁板綍鏁�
+    private val ncal = 15
+    // 鏍囧噯宸�嶆暟鍙傛暟
+    private val nstd = 3
+    // 鍧囧�煎�嶆暟鍙傛暟
+    private val xratio = 3
+    // 闇�瑕佸鐞嗙殑鍥犲瓙绫诲瀷
+    private val calTypes =
+//        emptyList<String>()
+        WeightType.prep
+
+    override fun mDataPrep(mDataList: List<DataVo>): List<DataVo> {
+        mDataList.forEach {
+            it.values?.forEach v@{a ->
+                if (!calTypes.contains(a.factorName)) return@v
+
+                val range = FactorType.getRange(a.factorName) ?: return@v
+                // 鍒ゆ柇鏁版嵁鏄惁鍦ㄥ悎鐞嗚寖鍥村唴
+                if (a.factorData ?: 0.0 < range.first || a.factorData ?: 0.0 > range.second) {
+                    a.factorData = null
+                }
+            }
+        }
+
+//        val newDataList = mutableListOf<DataVo>()
+//        mDataList.forEach {
+//            newDataList.add(it.copy())
+//        }
+
+        var i = ncal
+        while (i < mDataList.size) {
+            for (y in mDataList[i].values?.indices ?: 0..0) {
+                val it = mDataList[i].values?.get(y) ?: continue
+
+                if (!calTypes.contains(it.factorName)) continue
+                val vMax = FactorType.getVMax(it.factorName) ?: continue
+                it.factorData ?: continue
+
+                if (it.factorData!! > vMax) {
+                    val list = mDataList.subList(i - ncal, i)
+                    // 鍘婚櫎鏃犳晥鍊肩殑骞冲潎
+                    val avg = average(list, it.factorName)
+                    // 鍘婚櫎鏃犳晥鍊肩殑鏍囧噯宸�
+                    val std = standardDeviation(avg.first, list, it.factorName)
+                    // 鍚堢悊鏈�澶у��
+                    val max = max(avg.first + std * nstd, avg.first + avg.first * xratio)
+                    // 鍚堢悊鏈�灏忓��
+                    val min = min(avg.first - std * nstd, avg.first / (1 + xratio))
+
+                    // 鏁版嵁涓嶅浜庡悎鐞嗚寖鍥村苟涓旀湁鏁堜釜鏁拌揪鏍囨椂锛岄噰鐢ㄨ绠楁墍寰楀潎鍊间唬鏇垮師濮嬪��
+                    if (avg.second > max(ncal / 5, 2)
+                        && (it.factorData!! < min || it.factorData!! > max)
+                    ) {
+                        // 鍘熷鏁版嵁
+                        it.factorData = null
+//                        newDataList[i].values?.get(y)?.factorData = avg.first
+                    }
+                }
+            }
+
+            i++
+        }
+
+        return mDataList
+    }
+
+    override fun sopPrep(sopList: List<CompanySOP>): List<CompanySOP> {
+        return sopList
+    }
+
+    /**
+     * 鍘婚櫎鏃犳晥鍊肩殑骞冲潎
+     * @param list 鐩戞祴鏁版嵁
+     * @return 鍧囧�煎拰鏈夋晥鏁版嵁涓暟
+     */
+    private fun average(list: List<DataVo>, factorName:String?): Pair<Double, Int> {
+        var t = 0.0
+        var c = 0
+        list.forEach {
+            for (i in it.values?.indices ?: 0..0) {
+                val f = it.values?.get(i)
+                if (f?.factorName == factorName) {
+                    if (f?.factorData != null) {
+                        t += f.factorData!!
+                        c++
+                    }
+                    break
+                }
+            }
+        }
+
+        val avg = if (c == 0) {
+            0.0
+        } else {
+            t / c
+        }
+
+        return Pair(avg, c)
+    }
+
+    /**
+     * 鍘婚櫎鏃犳晥鍊肩殑鏍囧噯宸�
+     */
+    private fun standardDeviation(avg: Double, list: List<DataVo>, factorName: String?): Double {
+        var t = 0.0
+        var c = 0
+        list.forEach {
+            for (i in it.values?.indices ?: 0..0) {
+                val f = it.values?.get(i)
+                if (f?.factorName == factorName) {
+                    if (f?.factorData != null) {
+                        t += (f.factorData!! - avg) * (f.factorData!! - avg)
+                        c++
+                    }
+                    break
+                }
+            }
+        }
+
+        return if (c <= 1) {
+            0.0
+        } else {
+            sqrt(t / (c - 1))
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/model/epw/EPWModel.kt b/src/main/kotlin/com/flightfeather/uav/model/epw/EPWModel.kt
index e3cb9cd..b12dd82 100644
--- a/src/main/kotlin/com/flightfeather/uav/model/epw/EPWModel.kt
+++ b/src/main/kotlin/com/flightfeather/uav/model/epw/EPWModel.kt
@@ -1,7 +1,9 @@
 package com.flightfeather.uav.model.epw
 
-import com.flightfeather.uav.domain.entity.Company
+import com.flightfeather.uav.lightshare.bean.CompanySOP
 import com.flightfeather.uav.lightshare.bean.DataVo
+import com.flightfeather.uav.model.*
+import com.flightfeather.uav.socket.eunm.FactorType
 import java.math.BigDecimal
 
 /**
@@ -9,41 +11,19 @@
  * 鏍规嵁璧拌埅鐩戞祴鏁版嵁锛岀粨鍚堥閫熴�侀鍚戙�佺洃娴嬬偣涓庝紒涓氱殑鐩稿浣嶇疆绛夊洜绱狅紝璁$畻浼佷笟瀵圭洃娴嬪尯鍩熺殑褰卞搷绋嬪害
  * @author riku
  */
-class EPWModel {
+class EPWModel : BaseModel<DataVo, CompanySOP>() {
 
-    private val windDirWeight = WindDirWeight()
-    private val windDisWeight = WindDisWeight()
+    override var dataPrep: BaseDataPrep<DataVo, CompanySOP> = EPWDataPrep()
 
-    private lateinit var datas: List<DataVo>
-    private lateinit var sources: List<Company>
+    override var factorTypes: List<FactorType> = WeightType.weightType
 
-    fun execute() {
-        datas.forEach d@{d ->
-            if (d.lng == null || d.lng == 0.0 || d.lat == null || d.lat == 0.0) {
-                return@d
-            }
+    override var weights: List<BaseWeight<DataVo, CompanySOP>> = listOf(WindDirWeight(), WindDisWeight())
 
-            var con = 0
-            var ws = 0.0
-            var wd = 0
-            var hr = 0
-            val lng = d.lng
-            val lat = d.lat
+    override var sections: List<BaseSection<DataVo, CompanySOP>> = listOf(TimeSection())
 
-            sources.forEach s@ { s ->
-                // 缁忕含搴︽湁鏁堟�у垽鏂�
-                if (s.ciLongitude == null || s.ciLongitude == BigDecimal(0) || s.ciLatitude == null || s.ciLatitude == BigDecimal(0)) {
-                    return@s
-                }
+    override fun mDataCheck(m: DataVo): Boolean = !(m.lng == null || m.lng == 0.0 || m.lat == null || m.lat == 0.0)
 
-                val p1 = Pair(lng!!, lat!!)
-                val p2 = Pair(s.ciLongitude.toDouble(), s.ciLatitude.toDouble())
-                windDirWeight.getWeight(p1, p2, wd)
+    override fun sopCheck(s: CompanySOP): Boolean =
+        !(s.ciLongitude == null || s.ciLongitude == BigDecimal(0) || s.ciLatitude == null || s.ciLatitude == BigDecimal(0))
 
-                windDisWeight.getWeight(p1, p2, ws)
-
-
-            }
-        }
-    }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/model/epw/TimeSection.kt b/src/main/kotlin/com/flightfeather/uav/model/epw/TimeSection.kt
new file mode 100644
index 0000000..2b5f476
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/model/epw/TimeSection.kt
@@ -0,0 +1,35 @@
+package com.flightfeather.uav.model.epw
+
+import com.flightfeather.uav.lightshare.bean.CompanySOP
+import com.flightfeather.uav.lightshare.bean.DataVo
+import com.flightfeather.uav.model.BaseEffect
+import com.flightfeather.uav.model.BaseSection
+import com.flightfeather.uav.model.BaseTag
+import com.flightfeather.uav.model.TimeTag
+
+/**
+ * 鏃舵鍒嗙被缁熻
+ * [6,9,12,14,17,20]; [6,9)涓烘棭涓婏紝涔嬪悗渚濇涓轰笂鍗堬紝涓崍锛屼笅鍗堬紝鍌嶆櫄鍜屾櫄涓�
+ */
+class TimeSection : BaseSection<DataVo, CompanySOP>() {
+
+    override val sectionValues: List<Double> = listOf(6.0, 9.0, 12.0, 14.0, 17.0, 20.0)
+
+    override val sectionType: List<String> = listOf("鍑屾櫒", "鏃╀笂", "涓婂崍", "涓崍", "涓嬪崍", "鍌嶆櫄", "澶滈棿")
+
+    override val tagClz: Class<out BaseTag> = TimeTag::class.java
+
+    override val constType: List<String> = listOf("缁煎悎")
+
+    override fun onSectionValue(mData: DataVo, sop: CompanySOP, effect: BaseEffect): Double {
+        return getHour(mData.time!!)
+    }
+
+    private fun getHour(time: String): Double {
+        return if (time.length >= 13) {
+            time.substring(11, 13).toDoubleOrNull() ?: 0.0
+        } else {
+            0.0
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/model/epw/WeightType.kt b/src/main/kotlin/com/flightfeather/uav/model/epw/WeightType.kt
new file mode 100644
index 0000000..0211d8b
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/model/epw/WeightType.kt
@@ -0,0 +1,29 @@
+package com.flightfeather.uav.model.epw
+
+import com.flightfeather.uav.socket.eunm.FactorType
+
+object WeightType {
+
+    val prep = listOf(
+        FactorType.NO2.des,
+        FactorType.CO.des,
+        FactorType.H2S.des,
+        FactorType.SO2.des,
+        FactorType.O3.des,
+        FactorType.PM25.des,
+        FactorType.PM10.des,
+        FactorType.VOC.des,
+        FactorType.WIND_SPEED.des
+    )
+
+    val weightType = listOf(
+        FactorType.NO2,
+        FactorType.CO,
+        FactorType.H2S,
+        FactorType.SO2,
+        FactorType.O3,
+        FactorType.PM25,
+        FactorType.PM10,
+        FactorType.VOC,
+    )
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/model/epw/WindDirWeight.kt b/src/main/kotlin/com/flightfeather/uav/model/epw/WindDirWeight.kt
index 16baf70..1ede99c 100644
--- a/src/main/kotlin/com/flightfeather/uav/model/epw/WindDirWeight.kt
+++ b/src/main/kotlin/com/flightfeather/uav/model/epw/WindDirWeight.kt
@@ -1,23 +1,33 @@
 package com.flightfeather.uav.model.epw
 
+import com.flightfeather.uav.lightshare.bean.CompanySOP
+import com.flightfeather.uav.lightshare.bean.DataVo
 import com.flightfeather.uav.model.BaseWeight
+import com.flightfeather.uav.socket.eunm.FactorType
 import kotlin.math.PI
 import kotlin.math.abs
 import kotlin.math.atan2
-import kotlin.math.sqrt
 
 /**
- *
+ * 椋庡悜鏉冮噸
  */
-class WindDirWeight : BaseWeight() {
+class WindDirWeight : BaseWeight<DataVo, CompanySOP>() {
+
+    override val tag: String = "椋庡悜鏉冮噸"
+
     override val sectionValues: List<Double> = listOf(22.5, 67.5, 112.5, 157.5, 180.0)
+
     override val weights: List<Double> = listOf(1.0, 0.8, 0.5, 0.2, 0.1)
 
-    fun getWeight(deg: Double):Double {
-        return weightCal(deg)
+    override fun onWeightFactor(mData: DataVo, sop: CompanySOP): Double? {
+        val p1 = Pair(mData.lng!!, mData.lat!!)
+        val p2 = Pair(sop.ciLongitude!!.toDouble(), sop.ciLatitude!!.toDouble())
+        val wd = mData.getFactorData(FactorType.WIND_DIRECTION) ?: 0.0
+        return getAngle(p1, p2, wd)
     }
 
-    fun getWeight(p1: Pair<Double, Double>, p2: Pair<Double, Double>, wd: Int): Double {
+
+    private fun getAngle(p1: Pair<Double, Double>, p2: Pair<Double, Double>, wd: Double): Double {
         val dx = p2.first - p1.first
         val dy = p2.second - p1.second
         var x1 = atan2(dy, dx) * 180 / PI
@@ -25,8 +35,8 @@
         var x2 = 270 - wd
         if (x2 < 0) x2 += 360
         x1 = abs(x2 - x1)
-        if (x1>180) x1 = 360 - x1
-
-        return weightCal(x1)
+        if (x1 > 180) x1 = 360 - x1
+//        println("澶硅锛�$x1")
+        return x1
     }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/model/epw/WindDisWeight.kt b/src/main/kotlin/com/flightfeather/uav/model/epw/WindDisWeight.kt
index 41a58f4..c2add4a 100644
--- a/src/main/kotlin/com/flightfeather/uav/model/epw/WindDisWeight.kt
+++ b/src/main/kotlin/com/flightfeather/uav/model/epw/WindDisWeight.kt
@@ -1,27 +1,39 @@
 package com.flightfeather.uav.model.epw
 
+import com.flightfeather.uav.lightshare.bean.CompanySOP
+import com.flightfeather.uav.lightshare.bean.DataVo
 import com.flightfeather.uav.model.BaseWeight
+import com.flightfeather.uav.socket.eunm.FactorType
 import kotlin.math.abs
+import kotlin.math.max
 import kotlin.math.sqrt
 
 /**
  * 椋庨�熻窛绂绘潈閲�
  * 鐩戞祴鐐逛笌姹℃煋婧愪箣闂寸殑鐗╃悊璺濈涓庡綋鍓嶉閫熷緱鍑虹殑鏉冮噸
  */
-class WindDisWeight : BaseWeight() {
+class WindDisWeight : BaseWeight<DataVo, CompanySOP>() {
+
+    override val tag: String = "椋庨�熻窛绂绘潈閲�"
 
     override val sectionValues: List<Double> = listOf(2.0, 5.0, 8.0, 12.0, 20.0, 30.0)
+
     override val weights: List<Double> = listOf(1.0, 0.8, 0.6, 0.5, 0.3, 0.0)
 
-    fun getWeight(dis: Double, ws: Double): Double {
-        val value = dis / 1000 / ws / 60
-        return weightCal(value)
+    override fun onWeightFactor(mData: DataVo, sop: CompanySOP): Double? {
+        val p1 = Pair(mData.lng!!, mData.lat!!)
+        val p2 = Pair(sop.ciLongitude!!.toDouble(), sop.ciLatitude!!.toDouble())
+        val ws = mData.getFactorData(FactorType.WIND_SPEED)
+        return if (ws == null) null else getWindSpeed(p1, p2, ws)
     }
 
-    fun getWeight(p1: Pair<Double, Double>, p2: Pair<Double, Double>, ws: Double): Double {
+    private fun getWindSpeed(p1: Pair<Double, Double>, p2: Pair<Double, Double>, ws: Double): Double {
         val dx = p2.first - p1.first
         val dy = p2.second - p1.second
         val dis = sqrt(abs(dx * dx) + abs(dy * dy)) * 100
-        return getWeight(dis, ws)
+//        println("璺濈锛�$dis")
+        val min = dis * 1000 / max(ws, 1.0) / 60
+//        println("璺濈杞负椋庨�熷垎閽熸暟锛�$min")
+        return min
     }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/socket/eunm/FactorType.kt b/src/main/kotlin/com/flightfeather/uav/socket/eunm/FactorType.kt
index a2f5f43..572420e 100644
--- a/src/main/kotlin/com/flightfeather/uav/socket/eunm/FactorType.kt
+++ b/src/main/kotlin/com/flightfeather/uav/socket/eunm/FactorType.kt
@@ -47,5 +47,91 @@
             HEIGHT.value -> HEIGHT
             else -> null
         }
+
+        fun getByName(name: String?): FactorType? = when (name) {
+            NO2.des -> NO2
+            CO.des -> CO
+            H2S.des -> H2S
+            SO2.des -> SO2
+            O3.des -> O3
+            PM25.des -> PM25
+            PM10.des -> PM10
+            TEMPERATURE.des -> TEMPERATURE
+            HUMIDITY.des -> HUMIDITY
+            VOC.des -> VOC
+            NOI.des -> NOI
+            LNG.des -> LNG
+            LAT.des -> LAT
+            VELOCITY.des -> VELOCITY
+            TIME.des -> TIME
+            WIND_SPEED.des -> WIND_SPEED
+            WIND_DIRECTION.des -> WIND_DIRECTION
+            HEIGHT.des -> HEIGHT
+            else -> null
+        }
+
+        fun getRange(name: String?): Pair<Double, Double>? {
+            getByName(name)?.let {
+                return getRange(it)
+            }
+            return null
+        }
+
+        /**
+         * 鑾峰彇鐩戞祴鍥犲瓙鐨勫悎鐞嗚寖鍥�
+         */
+        fun getRange(type: FactorType): Pair<Double, Double>? = when (type) {
+            NO2 -> Pair(0.1, 1000.0)
+            CO -> Pair(1.0, 5000.0)
+            H2S -> Pair(0.1, 1000.0)
+            SO2 -> Pair(0.1, 1000.0)
+            O3 -> Pair(0.1, 2000.0)
+            PM25 -> Pair(0.1, 5000.0)
+            PM10 -> Pair(0.1, 10000.0)
+            TEMPERATURE -> Pair(-20.0, 70.0)
+            HUMIDITY -> Pair(0.0, 110.0)
+            VOC -> Pair(1.0, 5000.0)
+            NOI -> Pair(0.1, 1000.0)
+            LNG -> Pair(0.0, 180.0)
+            LAT -> Pair(0.0, 90.0)
+            VELOCITY -> Pair(0.0, 500.0)
+            TIME -> null
+            WIND_SPEED -> Pair(0.0, 100.0)
+            WIND_DIRECTION -> Pair(0.0, 360.0)
+            HEIGHT -> Pair(0.0, 1000.0)
+            else -> null
+        }
+
+        fun getVMax(name: String?): Double? {
+            getByName(name)?.let {
+                return getVMax(it)
+            }
+            return null
+        }
+
+        /**
+         * 涓嶅鐞嗕綆浜庢鍊肩殑鍊�
+         */
+        fun getVMax(type: FactorType): Double? = when (type) {
+            NO2 -> 10.0
+            CO -> 100.0
+            H2S -> 10.0
+            SO2 -> 10.0
+            O3 -> 10.0
+            PM25 -> 10.0
+            PM10 -> 10.0
+            TEMPERATURE -> 10.0
+            HUMIDITY -> 10.0
+            VOC -> 10.0
+            NOI -> 10.0
+            LNG -> 0.0
+            LAT -> 0.0
+            VELOCITY -> 0.0
+            TIME -> 0.0
+            WIND_SPEED -> 2.0
+            WIND_DIRECTION -> 0.0
+            HEIGHT -> 0.0
+            else -> null
+        }
     }
 }
\ No newline at end of file
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index b083e00..7a28b65 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -1,17 +1,25 @@
 spring:
   datasource:
     driver-class-name: com.mysql.cj.jdbc.Driver
+#    灞�鍩熺綉鏈嶅姟鍣�
 #    url: jdbc:mysql://192.168.0.200:3306/dronemonitor?serverTimezone=Asia/Shanghai&prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
 #    username: root
 #    password: cn.FLIGHTFEATHER
 
-    url: jdbc:mysql://localhost:3306/dronemonitor?serverTimezone=Asia/Shanghai&prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
-    username: dronemonitor
-    password: dronemonitor_hackxrnomxm
+#    绾夸笂鏈嶅姟鍣�
+#    url: jdbc:mysql://localhost:3306/dronemonitor?serverTimezone=Asia/Shanghai&prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
+#    username: dronemonitor
+#    password: dronemonitor_hackxrnomxm
 
+#    寮�鍙戞湰鍦版湇鍔″櫒
 #    url: jdbc:mysql://localhost:3306/dronemonitor?serverTimezone=Asia/Shanghai&prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
 #    username: root
 #    password: 123456
+
+#   寮�鍙戣繙绋嬫湇鍔″櫒
+    url: jdbc:mysql://47.100.191.150:3306/dronemonitor?serverTimezone=Asia/Shanghai&prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
+    username: remoteU1
+    password: eSoF8DnzfGTlhAjE
     hikari:
       maximum-pool-size: 500
       minimum-idle: 20
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
index a77f22e..1a3f1e5 100644
--- a/src/main/resources/log4j2.xml
+++ b/src/main/resources/log4j2.xml
@@ -1,67 +1,67 @@
-<!--<?xml version="1.0" encoding="UTF-8"?>-->
-<!--&lt;!&ndash;-->
-    <!--6涓紭鍏堢骇浠庨珮鍒颁綆渚濇涓猴細OFF銆丗ATAL銆丒RROR銆乄ARN銆両NFO銆丏EBUG銆乀RACE銆� ALL銆�-->
-    <!--濡傛灉璁剧疆浼樺厛绾т负WARN锛岄偅涔圤FF銆丗ATAL銆丒RROR銆乄ARN 4涓骇鍒殑log鑳芥甯歌緭鍑�-->
-    <!--璁剧疆涓篛FF 琛ㄧず涓嶈褰昹og4j2鏈韩鐨勬棩蹇楋紝-->
- <!--&ndash;&gt;-->
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    6涓紭鍏堢骇浠庨珮鍒颁綆渚濇涓猴細OFF銆丗ATAL銆丒RROR銆乄ARN銆両NFO銆丏EBUG銆乀RACE銆� ALL銆�
+    濡傛灉璁剧疆浼樺厛绾т负WARN锛岄偅涔圤FF銆丗ATAL銆丒RROR銆乄ARN 4涓骇鍒殑log鑳芥甯歌緭鍑�
+    璁剧疆涓篛FF 琛ㄧず涓嶈褰昹og4j2鏈韩鐨勬棩蹇楋紝
+ -->
 
-<!--&lt;!&ndash; status锛氱敤鏉ユ寚瀹歭og4j鏈韩鐨勬墦鍗版棩蹇楃骇鍒�,monitorInterval:鎸囧畾log4j鑷姩閲嶆柊閰嶇疆鐨勭洃娴嬮棿闅旀椂闂� &ndash;&gt;-->
-<!--<configuration status="INFO" monitorInterval="30">-->
-	<!--&lt;!&ndash; 鑷繁璁剧疆灞炴�э紝鍚庨潰閫氳繃${}鏉ヨ闂� &ndash;&gt;-->
-	<!--<properties>-->
-		<!--<property name="LOG_HOME">../obdLogs</property>-->
-	<!--</properties>-->
+<!-- status锛氱敤鏉ユ寚瀹歭og4j鏈韩鐨勬墦鍗版棩蹇楃骇鍒�,monitorInterval:鎸囧畾log4j鑷姩閲嶆柊閰嶇疆鐨勭洃娴嬮棿闅旀椂闂� -->
+<configuration status="INFO" monitorInterval="30">
+	<!-- 鑷繁璁剧疆灞炴�э紝鍚庨潰閫氳繃${}鏉ヨ闂� -->
+	<properties>
+		<property name="LOG_HOME">../uavLogs</property>
+	</properties>
 
-	<!--<appenders>-->
-		<!--&lt;!&ndash;Appender 1. 杈撳嚭鍒癈onsole鎺у埗鍙帮紝鎸囧畾杈撳嚭鏍煎紡鍜岃繃婊ゅ櫒绛夌骇涓篒NFO &ndash;&gt;-->
-		<!--<Console name="Console" target="SYSTEM_OUT">-->
-			<!--&lt;!&ndash;ThresholdFilter鎸囧畾鏃ュ織娑堟伅鐨勮緭鍑烘渶浣庡眰娆�&ndash;&gt;-->
-			<!--<ThresholdFilter level="ALL" onMatch="ACCEPT" onMismatch="DENY"/>-->
-			<!--<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>-->
-		<!--</Console>-->
+	<appenders>
+		<!--Appender 1. 杈撳嚭鍒癈onsole鎺у埗鍙帮紝鎸囧畾杈撳嚭鏍煎紡鍜岃繃婊ゅ櫒绛夌骇涓篒NFO -->
+		<Console name="Console" target="SYSTEM_OUT">
+			<!--ThresholdFilter鎸囧畾鏃ュ織娑堟伅鐨勮緭鍑烘渶浣庡眰娆�-->
+			<ThresholdFilter level="ALL" onMatch="ACCEPT" onMismatch="DENY"/>
+			<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
+		</Console>
 
-		<!--&lt;!&ndash;Appender 2. 杈撳嚭鍒版粴鍔ㄤ繚瀛樼殑鏂囦欢, 瑙﹀彂淇濆瓨鏃ュ織鏂囦欢鐨勬潯浠舵槸鏃ュ織鏂囦欢澶т簬3KB锛屽彧淇濆瓨鏈�鏂扮殑10涓棩蹇�&ndash;&gt;-->
-		<!--<File name="allLog" fileName="${LOG_HOME}/all.log">-->
-			<!--<ThresholdFilter level="ALL" onMatch="ACCEPT" onMismatch="DENY"/>-->
-			<!--<PatternLayout charset="UTF-8" pattern="%d{yyyy.MM.dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/>-->
-		<!--</File>-->
+		<!--Appender 2. 杈撳嚭鍒版粴鍔ㄤ繚瀛樼殑鏂囦欢, 瑙﹀彂淇濆瓨鏃ュ織鏂囦欢鐨勬潯浠舵槸鏃ュ織鏂囦欢澶т簬3KB锛屽彧淇濆瓨鏈�鏂扮殑10涓棩蹇�-->
+		<File name="allLog" fileName="${LOG_HOME}/all.log">
+			<ThresholdFilter level="ALL" onMatch="ACCEPT" onMismatch="DENY"/>
+			<PatternLayout charset="UTF-8" pattern="%d{yyyy.MM.dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/>
+		</File>
 
 
-		<!--&lt;!&ndash;Appender 3. 杈撳嚭鍒版粴鍔ㄤ繚瀛樼殑鏂囦欢, 瑙﹀彂淇濆瓨鏃ュ織鏂囦欢鐨勬潯浠舵槸鏃ュ織鏂囦欢澶т簬3KB锛屽彧淇濆瓨鏈�鏂扮殑10涓棩蹇�&ndash;&gt;-->
-		<!--<RollingFile name="debugLog" fileName="${LOG_HOME}/debug.log" filePattern="${LOG_HOME}/debug-%i.log">-->
-			<!--<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>-->
-			<!--<PatternLayout charset="UTF-8" pattern="[%-5level][%d{yyyy-MM-dd HH:mm:ss}][%F:%L] - %m%n"/>-->
-			<!--<SizeBasedTriggeringPolicy size="3KB"/>-->
-			<!--&lt;!&ndash; DefaultRolloverStrategy 涓殑鍙傛暟max锛屽彲浠ラ檺鍒� SizeBasedTriggeringPolicy涓璼ize瓒呭嚭鍚庯紝鍙繚鐣檓ax涓瓨妗�&ndash;&gt;-->
-			<!--<DefaultRolloverStrategy max="10"/>-->
-		<!--</RollingFile>-->
+		<!--Appender 3. 杈撳嚭鍒版粴鍔ㄤ繚瀛樼殑鏂囦欢, 瑙﹀彂淇濆瓨鏃ュ織鏂囦欢鐨勬潯浠舵槸鏃ュ織鏂囦欢澶т簬3KB锛屽彧淇濆瓨鏈�鏂扮殑10涓棩蹇�-->
+		<RollingFile name="debugLog" fileName="${LOG_HOME}/debug.log" filePattern="${LOG_HOME}/debug-%i.log">
+			<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
+			<PatternLayout charset="UTF-8" pattern="[%-5level][%d{yyyy-MM-dd HH:mm:ss}][%F:%L] - %m%n"/>
+			<SizeBasedTriggeringPolicy size="3KB"/>
+			<!-- DefaultRolloverStrategy 涓殑鍙傛暟max锛屽彲浠ラ檺鍒� SizeBasedTriggeringPolicy涓璼ize瓒呭嚭鍚庯紝鍙繚鐣檓ax涓瓨妗�-->
+			<DefaultRolloverStrategy max="10"/>
+		</RollingFile>
 
-		<!--&lt;!&ndash;Appender 4. 杈撳嚭鍒版粴鍔ㄤ繚瀛樼殑鏂囦欢, 瑙﹀彂淇濆瓨鏃ュ織鏂囦欢鐨勬潯浠舵槸姣忓垎閽熺涓�娆$殑鏃ュ織浜嬩欢銆侲RROR鏃ュ織鏄寜鍒嗛挓浜х敓鏃ュ織 &ndash;&gt;-->
-		<!--<RollingFile name="errorLog" fileName="${LOG_HOME}/error.log" filePattern="${LOG_HOME}/error-%d{yyyy-MM-dd_HH-mm}.log">-->
-			<!--<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>-->
-			<!--<PatternLayout charset="UTF-8" pattern="[%-5level][%d{yyyy-MM-dd HH:mm:ss}][%C:%F:%L] - %m%n"/>-->
-			<!--<TimeBasedTriggeringPolicy/>-->
-		<!--</RollingFile>-->
+		<!--Appender 4. 杈撳嚭鍒版粴鍔ㄤ繚瀛樼殑鏂囦欢, 瑙﹀彂淇濆瓨鏃ュ織鏂囦欢鐨勬潯浠舵槸姣忓垎閽熺涓�娆$殑鏃ュ織浜嬩欢銆侲RROR鏃ュ織鏄寜鍒嗛挓浜х敓鏃ュ織 -->
+		<RollingFile name="errorLog" fileName="${LOG_HOME}/error.log" filePattern="${LOG_HOME}/error-%d{yyyy-MM-dd_HH-mm}.log">
+			<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
+			<PatternLayout charset="UTF-8" pattern="[%-5level][%d{yyyy-MM-dd HH:mm:ss}][%C:%F:%L] - %m%n"/>
+			<TimeBasedTriggeringPolicy/>
+		</RollingFile>
 
-		<!--<RollingFile name="RollingFile" fileName="${LOG_HOME}/rar.log" filePattern="${LOG_HOME}/$${date:yyyy-MM}/${FILE_NAME}-%d{MM-dd-yyyy}-%i.log.gz">-->
-			<!--<PatternLayout charset="UTF-8" pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/>-->
-			<!--&lt;!&ndash;鏃ュ織鏂囦欢鏈�澶у�� 绗簩澶╁帇缂�&ndash;&gt;-->
-			<!--<Policies>-->
-				<!--<TimeBasedTriggeringPolicy/>-->
-				<!--<SizeBasedTriggeringPolicy size="10 MB"/>-->
-			<!--</Policies>-->
-		<!--</RollingFile>-->
+		<RollingFile name="RollingFile" fileName="${LOG_HOME}/rar.log" filePattern="${LOG_HOME}/$${date:yyyy-MM}/${FILE_NAME}-%d{MM-dd-yyyy}-%i.log.gz">
+			<PatternLayout charset="UTF-8" pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/>
+			<!--鏃ュ織鏂囦欢鏈�澶у�� 绗簩澶╁帇缂�-->
+			<Policies>
+				<TimeBasedTriggeringPolicy/>
+				<SizeBasedTriggeringPolicy size="10 MB"/>
+			</Policies>
+		</RollingFile>
 
 
-	<!--</appenders>-->
-	<!--&lt;!&ndash;root 榛樿鍔犺浇&ndash;&gt;-->
-	<!--<loggers>-->
-		<!--<root level="INFO">-->
-			<!--<appender-ref ref="Console"/>-->
-			<!--&lt;!&ndash;<appender-ref ref="allLog"/>&ndash;&gt;-->
-			<!--<appender-ref ref="debugLog"/>-->
-			<!--<appender-ref ref="errorLog"/>-->
-			<!--<appender-ref ref="RollingFile"/>-->
-		<!--</root>-->
-	<!--</loggers>-->
-<!--</configuration>-->
\ No newline at end of file
+	</appenders>
+	<!--root 榛樿鍔犺浇-->
+	<loggers>
+		<root level="INFO">
+<!--			<appender-ref ref="Console"/>-->
+<!--			<appender-ref ref="allLog"/>-->
+<!--			<appender-ref ref="debugLog"/>-->
+<!--			<appender-ref ref="errorLog"/>-->
+<!--			<appender-ref ref="RollingFile"/>-->
+		</root>
+	</loggers>
+</configuration>
\ No newline at end of file
diff --git a/src/test/kotlin/com/flightfeather/uav/Test.kt b/src/test/kotlin/com/flightfeather/uav/Test.kt
index 38e6067..456ec0c 100644
--- a/src/test/kotlin/com/flightfeather/uav/Test.kt
+++ b/src/test/kotlin/com/flightfeather/uav/Test.kt
@@ -1,6 +1,7 @@
 package com.flightfeather.uav
 
 import com.flightfeather.uav.common.utils.FileExchange
+import com.flightfeather.uav.domain.entity.Company
 import com.flightfeather.uav.socket.bean.DataUnit
 import com.flightfeather.uav.socket.decoder.AirDataDecoder
 import com.flightfeather.uav.socket.eunm.AirCommandUnit
@@ -47,4 +48,22 @@
     fun dataChange() {
         FileExchange().doTask2()
     }
+
+    @Test
+    fun listCopy() {
+        val l1 = listOf(Company().apply { ciGuid = "a" }, Company().apply { ciGuid = "b" }, Company().apply { ciGuid = "c" })
+        val l2 = mutableListOf<Company>().apply { addAll(l1) }
+        l2[1].ciGuid = "d"
+        println(l1)
+        println(l2)
+    }
+
+    @Test
+    fun average() {
+        for (i in 0..2) {
+            println(i)
+        }
+        val list = listOf(1, 2, 3, 4, 5, 0)
+        println(list.average())
+    }
 }
\ No newline at end of file
diff --git a/src/test/kotlin/com/flightfeather/uav/model/epw/EPWModelTest.kt b/src/test/kotlin/com/flightfeather/uav/model/epw/EPWModelTest.kt
new file mode 100644
index 0000000..6503d9c
--- /dev/null
+++ b/src/test/kotlin/com/flightfeather/uav/model/epw/EPWModelTest.kt
@@ -0,0 +1,117 @@
+package com.flightfeather.uav.model.epw
+
+import com.flightfeather.uav.common.utils.DateUtil
+import com.flightfeather.uav.domain.entity.Company
+import com.flightfeather.uav.domain.mapper.CompanyMapper
+import com.flightfeather.uav.lightshare.bean.CompanySOP
+import com.flightfeather.uav.lightshare.bean.DataVo
+import com.flightfeather.uav.lightshare.service.RealTimeDataService
+import org.apache.poi.hssf.usermodel.HSSFWorkbook
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.springframework.beans.BeanUtils
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.test.context.junit4.SpringRunner
+import tk.mybatis.mapper.entity.Example
+import java.io.FileOutputStream
+import java.util.*
+
+@RunWith(SpringRunner::class)
+@SpringBootTest
+class EPWModelTest {
+
+    @Autowired
+    lateinit var realTimeDataService: RealTimeDataService
+
+    @Autowired
+    lateinit var companyMapper: CompanyMapper
+
+    @Test
+    fun test1() {
+        val company = companyMapper
+            .selectAll()
+//            .selectByExample(Example(Company::class.java).apply {
+//            createCriteria()
+//                .orEqualTo("ciGuid", "Dp5iDYfKY7qi04Ze")
+//                .orEqualTo("ciGuid", "C9ZzWbc49AHuxa0U")
+//                .orEqualTo("ciGuid", "15xCtnjxa9pfmDSj")
+//                .orEqualTo("ciGuid", "mbd8mRmpRtcUsT61")
+//                .orEqualTo("ciGuid", "xh7fpulnFQDQjb3e")
+//                .orEqualTo("ciGuid", "mXef1NeDZyguGDLN")
+//                .orEqualTo("ciGuid", "LEU330ksO54BEH8A")
+//                .orEqualTo("ciGuid", "aZpHXOktTEuzUcTX")
+//                .orEqualTo("ciGuid", "dNDMoJfresNn5hPU")
+//                .orEqualTo("ciGuid", "J3euwNl19WZvH7iE")
+//                .orEqualTo("ciGuid", "eb2kbFjhCZN2s9If")
+//                .orEqualTo("ciGuid", "0PjZXFkpp1KT6hEM")
+//                .orEqualTo("ciGuid", "ymXoupcbVMa1bBF1")
+//        })
+        val companySOPList = mutableListOf<CompanySOP>()
+        company.forEach {
+            val companySOP = CompanySOP(it.ciGuid, it.ciName, it.ciExtension1)
+            BeanUtils.copyProperties(it, companySOP)
+            companySOPList.add(companySOP)
+        }
+
+        val dataSet = mutableListOf<DataVo>()
+        val timeSet = listOf(
+            Pair("2021-06-18 15:00:00", "2021-06-18 23:59:59"),
+            Pair("2021-06-19 00:00:00", "2021-06-19 23:59:59"),
+            Pair("2021-06-20 00:00:00", "2021-06-20 23:59:59"),
+            Pair("2021-06-21 00:00:00", "2021-06-21 23:59:59"),
+            Pair("2021-06-22 00:00:00", "2021-06-22 23:59:59"),
+            Pair("2021-06-23 00:00:00", "2021-06-23 23:59:59"),
+            Pair("2021-06-24 00:00:00", "2021-06-24 23:59:59"),
+            Pair("2021-06-25 00:00:00", "2021-06-25 23:59:59"),
+            Pair("2021-06-26 00:00:00", "2021-06-26 23:59:59"),
+            Pair("2021-06-27 00:00:00", "2021-06-27 23:59:59"),
+            Pair("2021-06-28 00:00:00", "2021-06-28 23:59:59"),
+            Pair("2021-06-29 00:00:00", "2021-06-29 23:59:59"),
+            Pair("2021-06-30 00:00:00", "2021-06-30 08:00:00"),
+//            Pair("2021-03-26 11:28:12", "2021-03-26 21:30:00"),
+//            Pair("2021-04-09 07:18:12", "2021-04-09 22:04:39"),
+//            Pair("2021-04-10 08:00:02", "2021-04-10 09:44:18"),
+//            Pair("2021-04-21 16:46:12", "2021-04-21 21:18:35"),
+//            Pair("2021-05-24 11:10:12", "2021-05-24 19:31:02"),
+//            Pair("2021-06-04 09:02:40", "2021-06-04 20:14:18"),
+        )
+
+        val epwModel = EPWModel()
+        var workbook: HSSFWorkbook? = null
+        var out: FileOutputStream? = null
+
+        for (i in timeSet.indices) {
+            val it = timeSet[i]
+            val dataList =
+                realTimeDataService.getSecondData("0d0000000001", it.first, it.second, 1, 100000).data ?: emptyList()
+            dataList.forEach {
+                if (it.lng == 0.0 && it.lat == 0.0) {
+                    it.lng = 121.235813
+                    it.lat = 30.835898
+                }
+            }
+            dataSet.addAll(dataList)
+            println()
+            println("[${it.first}]鏁版嵁閲�: ${dataList.size}")
+
+            epwModel.execute(dataList, companySOPList)
+            val p = epwModel.outputToExcel(
+//                "姹℃煋鏉冮噸鍒嗘瀽缁撴灉-缁煎悎-${DateUtil().DateToString(Date(), "yyyy-MM-ddHHmmss")}.xls",
+//                "姹℃煋鏉冮噸鍒嗘瀽缁撴灉-${it.first.substring(0, 10)}.xls",
+                "姹℃煋鏉冮噸鍒嗘瀽缁撴灉-缃戞牸鍖�-${it.first.substring(0, 10)}.xls",
+                workbook,
+                out,
+                it.first.substring(0, 10),
+//                false
+//                i == timeSet.size - 1
+            )
+//            p?.first?.let { workbook = it }
+//            p?.second?.let { out = it }
+        }
+
+        println(dataSet.size)
+        epwModel.execute(dataSet, companySOPList)
+        epwModel.outputToExcel("姹℃煋鏉冮噸鍒嗘瀽缁撴灉-缁煎悎-${DateUtil().DateToString(Date(), "yyyy-MM-ddHHmmss")}.xls", workbook, out, "缁煎悎")
+    }
+}
\ No newline at end of file

--
Gitblit v1.9.3