티스토리 뷰

데이터 출처 : 공공데이터포털

OpenAPI05

WeatherDataCollector

 

package com.yusen.i2b.openapi05

import android.os.Build
import android.util.Log
import org.json.JSONObject
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import kotlin.random.Random


class cWeatherDataCollector{
    companion object{
        const val TAG = "WeatherDataCollector"
        const val REQUESTING = 11
        const val RESPONDED = 12
        const val NEXTREQUEST = 13
        const val NEXTSTATION = 15
        const val PROCESSCOMPLETED = 19
        const val NOCOMMAND = 91
        const val IDLING= 1
        const val PREPARING = 2
    }
    private val Constants = cConstants()
    var IsStationListReady = false
    val mHandler:UploadHandler = UploadHandler()
    private val baseURL_loadWeatherData = Constants.BaseURL_requestWeatherData
    private val baseURL_BilientServer = Constants.BilientServer
    private val serviceKey:String = Constants.ServiceKey_WeatherData

    private var processID = PREPARING
    var WebAccess = cWebAccess()
    val DataManager = cDataManager()
    val Params_WeatherDataRequest: JSONObject = JSONObject()
    val Params_WeatherDataUpload: JSONObject = JSONObject()
    val Params_StationDataRequest: JSONObject = JSONObject()
    val Params_StationDataUpdate: JSONObject = JSONObject()
    val Params_removeWeatherData = JSONObject()
    val Params_loadData_Essential = JSONObject()
    var StationList = ArrayList<JSONObject>()
    var StationNumber = -1
    var StationIndex = -1
    var WeatherItems: JSONObject = JSONObject()
    var WeatherValues: JSONObject = JSONObject()
    var IsUploaded = false
    var UploadedString = "-"

    constructor(){
        SetParams_RequestWeatherData()
        SetParams_uploadData()
        SetParams_loadStations()
        SetParams_updateStationValues()
        SetWeatherItems()
    }

    public fun Start_SetStationList(){
        processID = IDLING
        this.WebAccess.ClearValues()
        CheckProcess_SetStationList()
    }

    public fun Start_CollectWeatherData(){
        processID = IDLING
        this.WebAccess.ClearValues()
        CheckProcess_CollectWeatherData()
    }

    public fun Start_LoadWeatherValues(params: JSONObject){
        processID = IDLING
        WebAccess.ClearValues()
        val keys1 = params.keys()
        for(akey in keys1){
            Params_WeatherDataRequest.put(akey, params.getString(akey))
        }
        CheckProcess_LoadWeatherValues()
    }

    public fun CheckProcess_LoadWeatherValues():Int{
        when(processID){
            IDLING->{
                this.WebAccess.Request_GET(this.baseURL_loadWeatherData, Params_WeatherDataRequest)
                this.processID = REQUESTING
                return 0
            }
            REQUESTING->{
                if(WebAccess.IsResponded) this.processID = RESPONDED
                return 0
            }
            RESPONDED->{
                this.processID = PROCESSCOMPLETED

                if(this.WebAccess.ResponseString == "-"){
                    return 0
                }
                val weatherData =ConvertResponse2WeatherData(this.WebAccess.ResponseString)
                if(weatherData == null ) return -1
                this.WeatherValues = weatherData.ItemValues.get(0)
                return 1

            }
            PROCESSCOMPLETED->{
                return 2
            }
            else->{
                return -2
            }
        }
        return 0
    }


    public fun CheckProcess_SetStationList():Int{
        when(processID){
            IDLING->{
                this.WebAccess.Request_POST(this.baseURL_BilientServer, Params_StationDataRequest)
                this.processID = REQUESTING
                return 0
            }
            REQUESTING->{
                if(WebAccess.IsResponded) this.processID = RESPONDED
                return 0
            }
            RESPONDED->{
                processID = PROCESSCOMPLETED
                val SL1s = DataManager.String2JSONArray(WebAccess.ResponseString, "Results")
                if(SL1s == null) return -1
                val StationNumber = SL1s.size
                Log.d("[Station Number]", StationNumber.toString())
                StationList = SL1s
                return 1
            }
            PROCESSCOMPLETED->{
                return 2
            }
        }
        return -1
    }

    public fun CheckProcess_CollectWeatherData():Int{
        when(this.processID){
            IDLING->{
                this.WebAccess.ClearValues()
                this.StationNumber = this.StationList.size
                if(this.StationNumber < 1){
                    processID = PROCESSCOMPLETED
                    return -1
                }
                this.StationIndex = -1
                this.processID = NEXTSTATION
                return 0
            }
            REQUESTING->{
                if(!this.WebAccess.IsResponded) return 0
                this.processID = RESPONDED
                return 0
            }
            RESPONDED->{
                this.processID = NEXTREQUEST
                if(this.WebAccess.ResponseString == "-"){
                    return 0
                }
                val weatherData =ConvertResponse2WeatherData(this.WebAccess.ResponseString)
                if(weatherData == null ) return -1
                UploadWeatherData(weatherData.ItemValues)
                val lastIndex1 = weatherData.ItemValues.lastIndex
                val stnId1 = weatherData.ItemValues.get(lastIndex1).getInt("stnId")
                val dateString1 = weatherData.ItemValues.get(lastIndex1).getString("tm")
                val finalDate = dateString1.substring(0, 4) + dateString1.substring(5, 7) + dateString1.substring(8, 10)
                UpdateStationData(stnId1, finalDate)
                IsUploaded = true
                UploadedString = weatherData.ItemValues.get(lastIndex1).getString("stnId")+" : " + finalDate
                StationList.get(StationIndex).put("LatestDate", Params_StationDataUpdate.getString("LatestDate"))
                processID = NEXTREQUEST
                return 0
            }
            NEXTREQUEST->{
                val station1: JSONObject = StationList.get(StationIndex)
                // TODO : Request weather data
                val latestDate = station1.getString("LatestDate")
                val Date_JSON = UpdateDate(latestDate, 14)
                if(Date_JSON == null){
                    Log.d(
                        "[Uploading Weather-data]",
                        "No more weather data for " + station1.getInt("StationCode")
                    )
                    processID = NEXTSTATION
//                    SendNotice(station1)
                    return 0
                }
                this.WebAccess.ClearValues()
                this.Params_WeatherDataRequest.put(
                    "stnIds",
                    station1.getInt("StationCode")
                )
                this.Params_WeatherDataRequest.put(
                    "startDt",
                    Date_JSON.getString("StartDate")
                )
                this.Params_WeatherDataRequest.put("endDt", Date_JSON.getString("EndDate"))
                this.WebAccess.Request_GET(
                    this.baseURL_loadWeatherData,
                    this.Params_WeatherDataRequest
                )
                this.processID = REQUESTING
                return 0
            }
            NEXTSTATION->{
                StationIndex++
                if (StationIndex >= StationNumber) {
                    this.processID = PROCESSCOMPLETED
                    SendNotice(JSONObject())
                    return 1
                }
                processID = NEXTREQUEST
                return 0
            }
            PROCESSCOMPLETED->{
                return 2
            }
            else->{
                return -2
            }

        }
    }

    private fun SendNotice(stationInfo:JSONObject){
        val webAccess = cWebAccess()
        val mailParam = JSONObject()
        val sender = Constants.SenderEmail
        val receiver = Constants.ReceiverEmail
        mailParam.accumulate("RequestType", "sendNotice")
        mailParam.accumulate("MailTo", receiver)
        val theNow: LocalDateTime = LocalDateTime.now()
        val timeString = theNow.format(DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss"))

        val mailSubject = "[Weather-data] Update Completed"
//        val mailSubject = "[Weather-data] "+stationInfo.getString("StationCode")+" completed"
        mailParam.accumulate("MailSubject", mailSubject)
        val mailBody = "Weather-Data update completed @ "+ timeString +
                " with " + Build.DEVICE
        mailParam.accumulate("MailBody", mailBody)
        webAccess.Request_POST(baseURL_BilientServer, mailParam)
    }

    private fun ConvertResponse2WeatherData(ResponseString:String):cWeatherData?{

        val Response_XML = this.DataManager.String2XMLList(ResponseString, "response")
        if(Response_XML == null){
            return null
        }
        val WeatherHeader_XML = this.DataManager.FindtheNodeList(Response_XML, "header")
        if(WeatherHeader_XML == null){
            return null
        }
        val weatherHeader_JSON = this.DataManager.XMLList2JSON(WeatherHeader_XML)
        if(weatherHeader_JSON == null){
            return null
        }
        Log.d("[Header]", weatherHeader_JSON.getString("resultCode")+", "+weatherHeader_JSON.getString("resultMsg"))
        when(weatherHeader_JSON.getString("resultCode")) {
            "00" -> {
                val Items_XML = DataManager.FindtheNodeList(Response_XML, "items")
                if (Items_XML == null) {
                    return null
                }
                val ItemNumber = Items_XML.length
                val ItemArray_JSON = ArrayList<JSONObject>()
                for (Index1 in 0..(ItemNumber - 1)) {
                    val Item1 = Items_XML.item(Index1)
                    if (Item1.nodeName == "item") {
                        val Items_JSON = this.DataManager.XMLList2JSON(Item1.childNodes)
                        if (Items_JSON == null) continue
                        try{
                            Log.d("[Item-" + Index1 + "]", Items_JSON.getString("maxTa"))
                        }catch(e: Exception){
                            Log.d("[Item-" + Index1 + "]", "None of MaxTa")
                        }
                        val dateString1 = Items_JSON.getString("tm")
                        if (dateString1.length != 10) return null
                        ItemArray_JSON.add(Items_JSON)
                    }
                }
                return cWeatherData(weatherHeader_JSON, ItemArray_JSON)
            }
            else->{
                return null
            }
        }
    }

    private fun UploadWeatherData(WeatherData_JSON:ArrayList<JSONObject>){
        for(JSON1 in WeatherData_JSON ){
            //val JSON1 = JSONObject(WeatherData_JSON.get(Index1).toString())
            if(JSON1 == null) return
            Log.d("[UploadWeatherData()]", JSON1.getString("stnId"))
            val msg1 = mHandler.obtainMessage(UploadHandler.MSG_UPLOADWEATHERDATA)
            JSON1.accumulate("RequestType", "uploadWeatherData")
            val RequestInfo = cRequestInfo(baseURL_BilientServer, JSON1)
//            val RequestInfo = cRequestInfo(baseURL_uploadTest, JSON1)
            msg1.obj = RequestInfo
            mHandler.sendMessage(msg1)
        }
    }

    private fun UpdateStationData(stnId:Int, dateString:String){
        val msg1 = mHandler.obtainMessage(UploadHandler.MSG_UPLOADWEATHERDATA)
        val Station_JSON = JSONObject(StationList.get(StationIndex).toString())
        Params_StationDataUpdate.put("SNo", Station_JSON.getInt("SNo"))
        Params_StationDataUpdate.put("StationCode", stnId)
        Params_StationDataUpdate.put("LatestDate", dateString)
        val RequestInfo = cRequestInfo(baseURL_BilientServer, Params_StationDataUpdate)
        msg1.obj = RequestInfo
        mHandler.sendMessage(msg1)
    }

    private fun UpdateDate(DateString0:String, DayIncrement:Long): JSONObject?{
        val theBeginning: LocalDate = LocalDate.of(2010, 1, 1)
        val theNow: LocalDate = LocalDate.now()
        val Rst_JSON = JSONObject()
        if(DateString0 == null){
            val Start0String = theBeginning.format(DateTimeFormatter.ofPattern("yyyyMMdd"))
            val End0String = theBeginning.plusDays(DayIncrement).format(DateTimeFormatter.ofPattern("yyyyMMdd"))
            Rst_JSON.accumulate("StartDate", Start0String.toString())
            Rst_JSON.accumulate("EndDate", End0String.toString())
            return Rst_JSON
        }
        val Year0 = DateString0.substring(0, 4).toInt()
        val Month0 = DateString0.substring(4, 6).toInt()
        val Day0 = DateString0.substring(6).toInt()
        val Date1: LocalDate = LocalDate.of(Year0, Month0, Day0).plusDays(1)
        if(Date1.compareTo(theNow) >= 0) return null
        var Date2: LocalDate = Date1.plusDays(DayIncrement)
        if(Date2.compareTo(theNow) >= 0){
            Date2 = theNow.minusDays(1)
        }
        if(Date1.compareTo(Date2) > 0) return null
        val Date1String = Date1.format(DateTimeFormatter.ofPattern("yyyyMMdd"))
        val Date2String = Date2.format(DateTimeFormatter.ofPattern("yyyyMMdd"))
        Rst_JSON.accumulate("StartDate", Date1String)
        Rst_JSON.accumulate("EndDate", Date2String)
        return Rst_JSON
    }

    private fun SetParams_RequestWeatherData(){
        Params_WeatherDataRequest.accumulate("serviceKey", serviceKey)
        Params_WeatherDataRequest.accumulate("numOfRows", 20)
        Params_WeatherDataRequest.accumulate("pageNo", 1)
        Params_WeatherDataRequest.accumulate("dataCd", "ASOS")
        Params_WeatherDataRequest.accumulate("dateCd", "DAY")
        Params_WeatherDataRequest.accumulate("startDt", "20100103")
        Params_WeatherDataRequest.accumulate("endDt", "20100103")
        Params_WeatherDataRequest.accumulate("stnIds", 100)
    }
    private fun SetParams_updateStationValues(){
        Params_StationDataUpdate.accumulate("SNo", -1)
        Params_StationDataUpdate.accumulate("StationCode", -1)
        Params_StationDataUpdate.accumulate("RequestType", "updateWeatherStation")
    }
    private fun SetParams_loadStations(DataNumber:Int=200){
        Params_StationDataRequest.accumulate("DataNumber", DataNumber)
        Params_StationDataRequest.accumulate("RequestType", "loadWeatherStations")
    }
    private fun SetParams_uploadData(){
        Params_WeatherDataUpload.accumulate("RequestType", "uploadWeatherData")
    }
    private fun SetParams_loadDatas(){
        Params_WeatherDataUpload.accumulate("RequestType", "loadWeatherDatas")
        Params_WeatherDataUpload.accumulate("DataNumber", 100)
    }
    private fun SetParams_removeData(){
        Params_removeWeatherData.accumulate("RequestType", "removeWeatherData")
        Params_removeWeatherData.accumulate("SNo", "-1")
        Params_removeWeatherData.accumulate("MMSI_CODE", "-1")
    }
    private fun SetParams_loadData_Essential(){
        Params_loadData_Essential.accumulate("RequestType", "loadEssentialDatas_WeatherData")
        Params_loadData_Essential.accumulate("StartDate", "2010-01-01")
        Params_loadData_Essential.accumulate("EndDate", "2010-01-31")
    }

    private fun SetWeatherItems(){
        WeatherItems.accumulate("stnId", "지점 번호")
        WeatherItems.accumulate("tm", "일자")
        WeatherItems.accumulate("avgTa", "평균 기온")
        WeatherItems.accumulate("minTa", "최저 기온")
        WeatherItems.accumulate("minTaHrmt", "최저 기온 시각")
        WeatherItems.accumulate("maxTa", "최고 기온")
        WeatherItems.accumulate("maxTaHrmt", "최대 기온 시각")
        WeatherItems.accumulate("mi10MaxRnHrmt", "10분 최다강수량 시각")
        WeatherItems.accumulate("hr1MaxRn", "1시간 최다강수량")
        WeatherItems.accumulate("hr1MaxRnHrmt", "1시간 최다 강수량 시각")
        WeatherItems.accumulate("sumRn", "일강수량")
        WeatherItems.accumulate("maxInsWs", "최대 순간풍속")
        WeatherItems.accumulate("maxInsWsWd", "최대 순간 풍속 풍향")
        WeatherItems.accumulate("maxInsWsHrmt", "최대 순간풍속 시각")
        WeatherItems.accumulate("maxWs", "최대 풍속")
        WeatherItems.accumulate("maxWsWd", "최대 풍속 풍향")
        WeatherItems.accumulate("maxWsHrmt", "최대 풍속 시각")
        WeatherItems.accumulate("avgWs", "평균 풍속")
        WeatherItems.accumulate("hr24SumRws", "풍정합")
        WeatherItems.accumulate("maxWd", "최대 풍향")
        WeatherItems.accumulate("avgTd", "평균 이슬점온도")
        WeatherItems.accumulate("minRhm", "최소 상대습도")
        WeatherItems.accumulate("minRhmHrmt", "평균 상대습도 시각")
        WeatherItems.accumulate("avgRhm", "평균 상대습도")
        WeatherItems.accumulate("avgPv", "평균 증기압")
        WeatherItems.accumulate("avgPa", "평균 현지기압")
        WeatherItems.accumulate("maxPs", "최고 해면 기압")
        WeatherItems.accumulate("maxPsHrmt", "최고 해면기압 시각")
        WeatherItems.accumulate("minPs", "최저 해면기압")
        WeatherItems.accumulate("minPsHrmt", "최저 해면기압 시각")
        WeatherItems.accumulate("avgPs", "평균 해면기압")
        WeatherItems.accumulate("ssDur", "가조시간")
        WeatherItems.accumulate("sumSsHr", "합계 일조 시간")
        WeatherItems.accumulate("hr1MaxIcsrHrmt", "1시간 최다 일사량 시각")
        WeatherItems.accumulate("hr1MaxIcsr", "1시간 최다 일사량")
        WeatherItems.accumulate("sumGsr", "합계 일사")
        WeatherItems.accumulate("ddMefs", "일 최심신적설")
        WeatherItems.accumulate("ddMefsHrmt", "일 최심신적설 시각")
        WeatherItems.accumulate("ddMes", "일 최심적설")
        WeatherItems.accumulate("ddMesHrmt", "일 최심적설 시각")
        WeatherItems.accumulate("sumDpthFhsc", "합계 3시간 신적설")
        WeatherItems.accumulate("avgTca", "평균 전운량")
        WeatherItems.accumulate("avgLmac", "평균 중하층운량")
        WeatherItems.accumulate("avgTs", "평균 지면온도")
        WeatherItems.accumulate("minTg", "최저 초상온도")
        WeatherItems.accumulate("avgCm5Te", "평균 5cm 지중온도")
        WeatherItems.accumulate("avgCm10Te", "평균10cm 지중온도")
        WeatherItems.accumulate("avgCm20Te", "평균 20cm 지중온도")
        WeatherItems.accumulate("avgCm30Te", "평균 30cm 지중온도")
        WeatherItems.accumulate("avgM05Te", "0.5m 지중온도")
        WeatherItems.accumulate("avgM10Te", "1.0m 지중온도")
        WeatherItems.accumulate("avgM15Te", "1.5m 지중온도")
        WeatherItems.accumulate("avgM30Te", "3.0m 지중온도")
        WeatherItems.accumulate("avgM50Te", "5.0m 지중온도")
        WeatherItems.accumulate("sumLrgEv", "합계 대형증발량")
        WeatherItems.accumulate("sumSmlEv", "합계 소형증발량")
        WeatherItems.accumulate("n99Rn", "9-9강수")
        WeatherItems.accumulate("iscs", "일기현상")
        WeatherItems.accumulate("sumFogDur", "안개 계속 시간")
    }
}

 

반응형