feiyu02
2025-08-05 176d7d8283e66ccf63878c9ab823e900df94b748
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package com.flightfeather.uav.common.net
 
import com.flightfeather.uav.common.exception.BizException
import com.flightfeather.uav.common.utils.DateUtil
import com.flightfeather.uav.domain.entity.BaseRealTimeData
import com.flightfeather.uav.domain.entity.Mission
import com.flightfeather.uav.domain.entity.RealTimeDataVehicle
import org.w3c.dom.Element
import java.math.BigDecimal
import java.time.LocalDateTime
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.util.*
import javax.xml.soap.Node
 
/**
 * 申欣环保走航监测数据接口API
 * Date: 2024/08/22
 */
object ShenXinService {
 
    private const val USER = "user1"
    private const val PW = "User1@jingan"
 
    //    "
    private val soapClient = SoapClient(
        "http://tempuri.org/",
        "http://180.169.129.106:9001/WebService.asmx?wsdl",
        "WebService", "WebServiceSoap", "GetData",
        "GetDataResponse"
    )
 
    data class DataParams(
        val mn: String?,
        val dtFrom: String?,
        val dtTo: String?,
        val compUser: String = USER,
        val compPassword: String = PW,
    ) {
        fun toMap(): MutableMap<String?, String?> {
            return mutableMapOf(
                "compUser" to compUser,
                "compPassword" to compPassword,
                "mn" to mn,
                "dtFrom" to dtFrom,
                "dtTo" to dtTo,
            )
        }
    }
 
    fun fetchData(mission: Mission, updateTime: LocalDateTime): List<BaseRealTimeData> {
        val et = LocalDateTime.ofInstant(mission.endTime.toInstant(), ZoneId.systemDefault())
        if (updateTime.isAfter(et)) return emptyList()
        return fetchData(mission.deviceCode, updateTime, et)
    }
 
    fun fetchData(deviceCode: String?, startTime: LocalDateTime, endTime:LocalDateTime): List<BaseRealTimeData> {
        val st = startTime.format(DateTimeFormatter.ofPattern(DateUtil.DateStyle.YYYY_MM_DD_HH_MM_SS.value))
        val et = endTime.format(DateTimeFormatter.ofPattern(DateUtil.DateStyle.YYYY_MM_DD_HH_MM_SS.value))
        val param = DataParams(deviceCode, st, et)
        val realTimeDataVehicleList = mutableListOf<BaseRealTimeData>()
        soapClient.sendMessage(param.toMap())?.let { res ->
            try {
                // 节点GetDataResult
                val result = res.item(0).firstChild
                // 节点ReturnCode,0表示成功
                if (result.firstChild.textContent == "0") {
//                    println(result.childNodes.item(2).nodeName)
                    // 节点ListInfo内的数据列表
                    val dataNodes = result.childNodes.item(2).childNodes
                    // 遍历每个DataInfo节点,转换为 [RealTimeDataVehicle] 对象
                    for (i in 0 until dataNodes.length) {
                        val dataInfo = dataNodes.item(i)
                        if (dataInfo.nodeType == Element.ELEMENT_NODE) {
                            val element = dataInfo as Element
                            realTimeDataVehicleList.add(elementToRealTimeData(deviceCode, element))
                        }
                    }
                }
            } catch (e: Exception) {
                throw BizException("申欣环保走航监测数据接口解析失败", e)
            }
        }
        return realTimeDataVehicleList
    }
 
    /**
     * DataInfo转换为RealTimeDataVehicle
     */
    private fun elementToRealTimeData(deviceCode: String?, element: Element): BaseRealTimeData {
        return BaseRealTimeData().apply {
            this.deviceCode = deviceCode
            no = toFloatBlank(element.getElementsByTagName("NO").item(0).textContent)
            no2 = toFloatBlank(element.getElementsByTagName("NO2").item(0).textContent)
            co = toFloatBlank(element.getElementsByTagName("CO").item(0).textContent) * 1000
            pm25 = toFloatBlank(element.getElementsByTagName("PM25").item(0).textContent)
            pm10 = toFloatBlank(element.getElementsByTagName("PM10").item(0).textContent)
            longitude = toBigDecimal(element.getElementsByTagName("Lon").item(0).textContent)
            latitude = toBigDecimal(element.getElementsByTagName("Lat").item(0).textContent)
            temperature = toFloatBlank(element.getElementsByTagName("Temperature").item(0).textContent)
            velocity = toFloatBlank(element.getElementsByTagName("Speed").item(0).textContent)
            windSpeed = toFloatBlank(element.getElementsByTagName("WindSpeed").item(0).textContent)
            windDirection = toFloatBlank(element.getElementsByTagName("WindDirection").item(0).textContent)
            dataTime = DateUtil.instance.StringToDate(
                element.getElementsByTagName("PostTime").item(0).textContent,
                DateUtil.DateStyle.YYYY_MM_DD_HH_MM_SS_EN)
            createTime = Date()
        }
    }
 
    private fun toFloatBlank(str: String): Float {
        val _str = str.trim()
        return if (_str.isBlank()) {
            0f
        } else {
            _str.toFloat()
        }
    }
 
    private fun toBigDecimal(str: String): BigDecimal {
        val _str = str.trim()
        return if (_str.isBlank()) {
            BigDecimal.ZERO
        } else {
            _str.toBigDecimal()
        }
    }
}