From 74a6f1b66e12c8eca98188b4b5c7f39c23401319 Mon Sep 17 00:00:00 2001 From: dev02 Date: Fri, 5 May 2023 16:46:26 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9weather=20api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Quartz/Jobs/WeatherAPIJob.cs | 55 +- .../Implement/ProcEletricMeterService.cs | 4 +- .../Services/Implement/Quicktype.cs | 640 ++++++++++++++++++ BackendWorkerService/root/PowerfulRain.xml | 192 ++++++ BackendWorkerService/root/Typhoon.xml | 197 ++++++ 5 files changed, 1064 insertions(+), 24 deletions(-) create mode 100644 BackendWorkerService/Services/Implement/Quicktype.cs create mode 100644 BackendWorkerService/root/PowerfulRain.xml create mode 100644 BackendWorkerService/root/Typhoon.xml diff --git a/BackendWorkerService/Quartz/Jobs/WeatherAPIJob.cs b/BackendWorkerService/Quartz/Jobs/WeatherAPIJob.cs index 2885318..8cf37f2 100644 --- a/BackendWorkerService/Quartz/Jobs/WeatherAPIJob.cs +++ b/BackendWorkerService/Quartz/Jobs/WeatherAPIJob.cs @@ -83,7 +83,18 @@ namespace BackendWorkerService.Quartz.Jobs Task_Detail task_Detail = new Task_Detail(loggers, backendRepository); try { + var obixApiConfig = new ObixApiConfig(); + string encoded = string.Empty; + #region 取得obix 設定 + var sqlObix = $@"SELECT system_value as Value, system_key as Name FROM variable WHERE deleted = 0 AND system_type = 'obixConfig'"; + var variableObix = await backgroundServiceRepository.GetAllAsync(sqlObix); + obixApiConfig.ApiBase = variableObix.Where(x => x.Name == "ApiBase").Select(x => x.Value).FirstOrDefault(); + obixApiConfig.UserName = variableObix.Where(x => x.Name == "UserName").Select(x => x.Value).FirstOrDefault(); + obixApiConfig.Password = variableObix.Where(x => x.Name == "Password").Select(x => x.Value).FirstOrDefault(); + + encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(obixApiConfig.UserName + ":" + obixApiConfig.Password)); + #endregion 取得obix 設定 //取得氣象預報 if (await task_Detail.GetNeedWorkTask("WeatherAPI", "api_weateher")) { @@ -212,7 +223,7 @@ namespace BackendWorkerService.Quartz.Jobs var val = RainValue(observation.Alert.MsgType, observation.Alert.Info[0].Headline); if (val < 5) { - var ReStr = Fetch_PostWithJSONFormat("http://60.251.164.125:8080/obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_MET1/SeverityLEVL_RAIN/set", val.ToString()); + var ReStr = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_MET1/SeverityLEVL_RAIN/set", val.ToString()); UpdatedNiagara("api_rain", ReStr, id); } } @@ -244,7 +255,7 @@ namespace BackendWorkerService.Quartz.Jobs var val = RainValue(observation.Alert.MsgType, observation.Alert.Info.Headline); if (val < 5) { - var ReStr = Fetch_PostWithJSONFormat("http://60.251.164.125:8080/obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_MET1/SeverityLEVL_RAIN/set", val.ToString()); + var ReStr = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_MET1/SeverityLEVL_RAIN/set", val.ToString()); UpdatedNiagara("api_rain", ReStr, id); } } @@ -297,7 +308,7 @@ namespace BackendWorkerService.Quartz.Jobs if (observation.Alert.Info[0].Urgency != null && observation.Alert.Info[0].Urgency != "Expected") { - var ReStr = Fetch_PostWithJSONFormat("http://60.251.164.125:8080/obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_MET2/SeverityLEVL_Typhoon/set", observation.Alert.Info[0].Urgency); + var ReStr = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_MET2/SeverityLEVL_Typhoon/set", observation.Alert.Info[0].Urgency); UpdatedNiagara("api_typhoon", ReStr, id); } } @@ -329,7 +340,7 @@ namespace BackendWorkerService.Quartz.Jobs if (observation.Alert.Info.Urgency != null && observation.Alert.Info.Urgency != "Expected") { - var ReStr = Fetch_PostWithJSONFormat("http://60.251.164.125:8080/obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_MET2/SeverityLEVL_Typhoon/set", observation.Alert.Info.Urgency); + var ReStr = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_MET2/SeverityLEVL_Typhoon/set", observation.Alert.Info.Urgency); UpdatedNiagara("api_typhoon", ReStr, id); } } @@ -354,8 +365,8 @@ namespace BackendWorkerService.Quartz.Jobs var UVUri = "https://opendata.cwb.gov.tw/api/v1/rest/datastore/E-A0015-001?Authorization=CWB-EA24220B-DDCC-4188-84E5-AD37A0E03F80&format=JSON&areaName=%E8%87%BA%E5%8C%97%E5%B8%82"; HttpResponseMessage response = client.GetAsync(UVUri).Result; String jsonUVs = response.Content.ReadAsStringAsync().Result.ToString(); - var observation = JsonConvert.DeserializeObject(jsonUVs); - if (observation.Success != "true") + var observation = QuickType.Welcome.FromJson(jsonUVs); + if (!observation.Success) { logger.LogInformation("【WeatherAPIJob】【取得地震觀測資料不正確】"); } @@ -363,7 +374,7 @@ namespace BackendWorkerService.Quartz.Jobs { logger.LogInformation("【WeatherAPIJob】【開始存入地震觀測到資料庫】"); List> EarthquakeAPIdbS = new List>(); - var nowNo = await backendRepository.GetOneAsync("select iif( Max(earthquakeNo) is null ,0,Max(earthquakeNo)) earthquakeNo from api_earthquake where newEarthquake = 1"); + var nowNo = await backendRepository.GetOneAsync("select if( Max(earthquakeNo) is null ,0,Max(earthquakeNo)) earthquakeNo from api_earthquake where newEarthquake = 1"); foreach (var a in observation.Records.Earthquake) { if (a.EarthquakeNo <= nowNo) @@ -372,8 +383,8 @@ namespace BackendWorkerService.Quartz.Jobs { { "@earthquakeNo", a.EarthquakeNo}, { "@newEarthquake", 0}, - { "@originTime", a.EarthquakeInfo.OriginTime}, - { "@magnitudeValue", a.EarthquakeInfo.Magnitude.MagnitudeValue}, + { "@originTime", DateTime.Parse(a.EarthquakeInfo.OriginTime.ToString(), System.Globalization.CultureInfo.CurrentCulture)}, + { "@magnitudeValue", a.EarthquakeInfo.EarthquakeMagnitude.MagnitudeValue}, { "@areaName", null}, { "@areaIntensity", null}, { "@created_by", "system"}, @@ -384,22 +395,22 @@ namespace BackendWorkerService.Quartz.Jobs } else { - if (a.Intensity.ShakingArea.Count > 0) + if (a.Intensity.ShakingArea.Length > 0) { Dictionary EarthquakeAPIdb = new Dictionary() { { "@earthquakeNo", a.EarthquakeNo}, { "@newEarthquake", 1}, - { "@originTime", a.EarthquakeInfo.OriginTime}, - { "@magnitudeValue", a.EarthquakeInfo.Magnitude.MagnitudeValue}, - { "@areaName", a.Intensity.ShakingArea[0].AreaName}, - { "@areaIntensity", a.Intensity.ShakingArea[0].AreaIntensity.Value}, + { "@originTime", DateTime.Parse(a.EarthquakeInfo.OriginTime.ToString(), System.Globalization.CultureInfo.CurrentCulture)}, + { "@magnitudeValue", a.EarthquakeInfo.EarthquakeMagnitude.MagnitudeValue}, + { "@areaName", a.Intensity.ShakingArea[0].CountyName}, + { "@areaIntensity", a.Intensity.ShakingArea[0].AreaIntensity}, { "@created_by", "system"}, { "@created_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}, }; - var Nag = Fetch_PostWithJSONFormat("http://60.251.164.125:8080/obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_GEO/SeverityLEVL_LMI/set", a.Intensity.ShakingArea[0].AreaIntensity.Value.ToString()); + var Nag = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_GEO/SeverityLEVL_LMI/set", a.Intensity.ShakingArea[0].AreaIntensity.ToString()); if (Nag.Contains("err")) { @@ -419,15 +430,15 @@ namespace BackendWorkerService.Quartz.Jobs { { "@earthquakeNo", a.EarthquakeNo}, { "@newEarthquake", 1}, - { "@originTime", a.EarthquakeInfo.OriginTime}, - { "@magnitudeValue", a.EarthquakeInfo.Magnitude.MagnitudeValue}, + { "@originTime", DateTime.Parse(a.EarthquakeInfo.OriginTime.ToString(), System.Globalization.CultureInfo.CurrentCulture)}, + { "@magnitudeValue", a.EarthquakeInfo.EarthquakeMagnitude.MagnitudeValue}, { "@areaName", null}, { "@areaIntensity", null}, { "@created_by", "system"}, { "@created_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}, }; - var Nag = Fetch_PostWithJSONFormat("http://60.251.164.125:8080/obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_GEO/SeverityLEVL_LMI/set", "NULL"); + var Nag = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_GEO/SeverityLEVL_LMI/set", "NULL"); if (Nag.Contains("err")) { EarthquakeAPIdb.Add("@niagara", Nag); @@ -463,19 +474,19 @@ namespace BackendWorkerService.Quartz.Jobs order by start_time desc"; var types = await backendRepository.GetAllAsync(sql); var T = types.Where(a => a.weather_type == "T").FirstOrDefault(); - var RbT = Fetch_PostWithJSONFormat("http://60.251.164.125:8080/obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/T/set", T.get_value); + var RbT = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/T/set", T.get_value); UpdatedNiagara("api_weateher", RbT, T.id); var RH = types.Where(a => a.weather_type == "RH").FirstOrDefault(); - var RHT = Fetch_PostWithJSONFormat("http://60.251.164.125:8080/obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/RH/set", RH.get_value); + var RHT = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/RH/set", RH.get_value); UpdatedNiagara("api_weateher", RHT, RH.id); var PoP12h = types.Where(a => a.weather_type == "PoP12h").FirstOrDefault(); - var PoP12hT = Fetch_PostWithJSONFormat("http://60.251.164.125:8080/obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/PoP6h/set", PoP12h.get_value); + var PoP12hT = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/PoP6h/set", PoP12h.get_value); UpdatedNiagara("api_weateher", PoP12hT, PoP12h.id); var Wx = types.Where(a => a.weather_type == "Wx").FirstOrDefault(); - var WxT = Fetch_PostWithJSONFormat("http://60.251.164.125:8080/obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/Wx/set", Wx.get_value); + var WxT = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/Wx/set", Wx.get_value); UpdatedNiagara("api_weateher", WxT, Wx.id); await task_Detail.InsertWorkTime_End("WeatherAPI", "set_weather"); } diff --git a/BackendWorkerService/Services/Implement/ProcEletricMeterService.cs b/BackendWorkerService/Services/Implement/ProcEletricMeterService.cs index 43edb68..21c01fd 100644 --- a/BackendWorkerService/Services/Implement/ProcEletricMeterService.cs +++ b/BackendWorkerService/Services/Implement/ProcEletricMeterService.cs @@ -58,8 +58,8 @@ namespace BackendWorkerService.Services.Implement var variableObix = await backgroundServiceRepository.GetAllAsync(sqlObix); obixApiConfig.ApiBase = variableObix.Where(x => x.Name == "ApiBase").Select(x => x.Value).FirstOrDefault(); - obixApiConfig.UserName = ed.AESDecrypt(variableObix.Where(x => x.Name == "UserName").Select(x => x.Value).FirstOrDefault()); - obixApiConfig.Password = ed.AESDecrypt(variableObix.Where(x => x.Name == "Password").Select(x => x.Value).FirstOrDefault()); + obixApiConfig.UserName = variableObix.Where(x => x.Name == "UserName").Select(x => x.Value).FirstOrDefault(); + obixApiConfig.Password = variableObix.Where(x => x.Name == "Password").Select(x => x.Value).FirstOrDefault(); encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(obixApiConfig.UserName + ":" + obixApiConfig.Password)); #endregion 取得obix 設定 diff --git a/BackendWorkerService/Services/Implement/Quicktype.cs b/BackendWorkerService/Services/Implement/Quicktype.cs new file mode 100644 index 0000000..35dab94 --- /dev/null +++ b/BackendWorkerService/Services/Implement/Quicktype.cs @@ -0,0 +1,640 @@ +using System; +using System.Collections.Generic; +using System.Text; + +// +// +// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do: +// +// using QuickType; +// +// var welcome = Welcome.FromJson(jsonString); + +namespace QuickType +{ + using System; + using System.Collections.Generic; + + using System.Globalization; + using Newtonsoft.Json; + using Newtonsoft.Json.Converters; + + public partial class Welcome + { + [JsonProperty("success")] + [JsonConverter(typeof(ParseStringConverter))] + public bool Success { get; set; } + + [JsonProperty("result")] + public Result Result { get; set; } + + [JsonProperty("records")] + public Records Records { get; set; } + } + + public partial class Records + { + [JsonProperty("datasetDescription")] + public DatasetDescription DatasetDescription { get; set; } + + [JsonProperty("Earthquake")] + public Earthquake[] Earthquake { get; set; } + } + + public partial class Earthquake + { + [JsonProperty("EarthquakeNo")] + public long EarthquakeNo { get; set; } + + [JsonProperty("ReportType")] + public DatasetDescription ReportType { get; set; } + + [JsonProperty("ReportColor")] + public ReportColor ReportColor { get; set; } + + [JsonProperty("ReportContent")] + public string ReportContent { get; set; } + + [JsonProperty("ReportImageURI")] + public Uri ReportImageUri { get; set; } + + [JsonProperty("ReportRemark")] + public ReportRemark ReportRemark { get; set; } + + [JsonProperty("Web")] + public Uri Web { get; set; } + + [JsonProperty("ShakemapImageURI")] + public Uri ShakemapImageUri { get; set; } + + [JsonProperty("EarthquakeInfo")] + public EarthquakeInfo EarthquakeInfo { get; set; } + + [JsonProperty("Intensity")] + public Intensity Intensity { get; set; } + } + + public partial class EarthquakeInfo + { + [JsonProperty("OriginTime")] + public DateTimeOffset OriginTime { get; set; } + + [JsonProperty("Source")] + public Source Source { get; set; } + + [JsonProperty("FocalDepth")] + public double FocalDepth { get; set; } + + [JsonProperty("Epicenter")] + public Epicenter Epicenter { get; set; } + + [JsonProperty("EarthquakeMagnitude")] + public EarthquakeMagnitude EarthquakeMagnitude { get; set; } + } + + public partial class EarthquakeMagnitude + { + [JsonProperty("MagnitudeType")] + public MagnitudeType MagnitudeType { get; set; } + + [JsonProperty("MagnitudeValue")] + public double MagnitudeValue { get; set; } + } + + public partial class Epicenter + { + [JsonProperty("Location")] + public string Location { get; set; } + + [JsonProperty("EpicenterLatitude")] + public double EpicenterLatitude { get; set; } + + [JsonProperty("EpicenterLongitude")] + public double EpicenterLongitude { get; set; } + } + + public partial class Intensity + { + [JsonProperty("ShakingArea")] + public ShakingArea[] ShakingArea { get; set; } + } + + public partial class ShakingArea + { + [JsonProperty("AreaDesc")] + public string AreaDesc { get; set; } + + [JsonProperty("CountyName")] + public string CountyName { get; set; } + + [JsonProperty("InfoStatus", NullValueHandling = NullValueHandling.Ignore)] + public InfoStatus? InfoStatus { get; set; } + + [JsonProperty("AreaIntensity")] + public AreaIntensityEnum AreaIntensity { get; set; } + + [JsonProperty("EqStation")] + public EqStation[] EqStation { get; set; } + } + + public partial class EqStation + { + [JsonProperty("pga", NullValueHandling = NullValueHandling.Ignore)] + public Pga Pga { get; set; } + + [JsonProperty("pgv", NullValueHandling = NullValueHandling.Ignore)] + public Pga Pgv { get; set; } + + [JsonProperty("StationName")] + public string StationName { get; set; } + + [JsonProperty("StationID")] + public string StationId { get; set; } + + [JsonProperty("InfoStatus", NullValueHandling = NullValueHandling.Ignore)] + public InfoStatus? InfoStatus { get; set; } + + [JsonProperty("BackAzimuth")] + public double BackAzimuth { get; set; } + + [JsonProperty("EpicenterDistance")] + public double EpicenterDistance { get; set; } + + [JsonProperty("SeismicIntensity")] + public AreaIntensityEnum SeismicIntensity { get; set; } + + [JsonProperty("StationLatitude")] + public double StationLatitude { get; set; } + + [JsonProperty("StationLongitude")] + public double StationLongitude { get; set; } + + [JsonProperty("WaveImageURI", NullValueHandling = NullValueHandling.Ignore)] + public Uri WaveImageUri { get; set; } + } + + public partial class Pga + { + [JsonProperty("unit")] + public Unit Unit { get; set; } + + [JsonProperty("EWComponent")] + public double EwComponent { get; set; } + + [JsonProperty("NSComponent")] + public double NsComponent { get; set; } + + [JsonProperty("VComponent")] + public double VComponent { get; set; } + + [JsonProperty("IntScaleValue")] + public double IntScaleValue { get; set; } + } + + public partial class Result + { + [JsonProperty("resource_id")] + public string ResourceId { get; set; } + + [JsonProperty("fields")] + public Field[] Fields { get; set; } + } + + public partial class Field + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("type")] + public TypeEnum Type { get; set; } + } + + public enum DatasetDescription { 地震報告 }; + + public enum MagnitudeType { 芮氏規模 }; + + public enum Source { 中央氣象局 }; + + public enum AreaIntensityEnum { The1級, The2級, The3級, The4級 }; + + public enum InfoStatus { Observe }; + + public enum Unit { Gal, Kine }; + + public enum ReportColor { 綠色 }; + + public enum ReportRemark { 本報告係中央氣象局地震觀測網即時地震資料地震速報之結果 }; + + public enum TypeEnum { Float, Integer, String, Timestamp }; + + public partial class Welcome + { + public static Welcome FromJson(string json) => JsonConvert.DeserializeObject(json, QuickType.Converter.Settings); + } + + public static class Serialize + { + public static string ToJson(this Welcome self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings); + } + + internal static class Converter + { + public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings + { + MetadataPropertyHandling = MetadataPropertyHandling.Ignore, + DateParseHandling = DateParseHandling.None, + Converters = + { + MagnitudeTypeConverter.Singleton, + SourceConverter.Singleton, + AreaIntensityEnumConverter.Singleton, + InfoStatusConverter.Singleton, + UnitConverter.Singleton, + ReportColorConverter.Singleton, + ReportRemarkConverter.Singleton, + DatasetDescriptionConverter.Singleton, + TypeEnumConverter.Singleton, + new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal } + }, + }; + } + + internal class MagnitudeTypeConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(MagnitudeType) || t == typeof(MagnitudeType?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize(reader); + if (value == "芮氏規模") + { + return MagnitudeType.芮氏規模; + } + throw new Exception("Cannot unmarshal type MagnitudeType"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (MagnitudeType)untypedValue; + if (value == MagnitudeType.芮氏規模) + { + serializer.Serialize(writer, "芮氏規模"); + return; + } + throw new Exception("Cannot marshal type MagnitudeType"); + } + + public static readonly MagnitudeTypeConverter Singleton = new MagnitudeTypeConverter(); + } + + internal class SourceConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(Source) || t == typeof(Source?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize(reader); + if (value == "中央氣象局") + { + return Source.中央氣象局; + } + throw new Exception("Cannot unmarshal type Source"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (Source)untypedValue; + if (value == Source.中央氣象局) + { + serializer.Serialize(writer, "中央氣象局"); + return; + } + throw new Exception("Cannot marshal type Source"); + } + + public static readonly SourceConverter Singleton = new SourceConverter(); + } + + internal class AreaIntensityEnumConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(AreaIntensityEnum) || t == typeof(AreaIntensityEnum?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize(reader); + switch (value) + { + case "1級": + return AreaIntensityEnum.The1級; + case "2級": + return AreaIntensityEnum.The2級; + case "3級": + return AreaIntensityEnum.The3級; + case "4級": + return AreaIntensityEnum.The4級; + } + throw new Exception("Cannot unmarshal type AreaIntensityEnum"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (AreaIntensityEnum)untypedValue; + switch (value) + { + case AreaIntensityEnum.The1級: + serializer.Serialize(writer, "1級"); + return; + case AreaIntensityEnum.The2級: + serializer.Serialize(writer, "2級"); + return; + case AreaIntensityEnum.The3級: + serializer.Serialize(writer, "3級"); + return; + case AreaIntensityEnum.The4級: + serializer.Serialize(writer, "4級"); + return; + } + throw new Exception("Cannot marshal type AreaIntensityEnum"); + } + + public static readonly AreaIntensityEnumConverter Singleton = new AreaIntensityEnumConverter(); + } + + internal class InfoStatusConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(InfoStatus) || t == typeof(InfoStatus?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize(reader); + if (value == "observe") + { + return InfoStatus.Observe; + } + throw new Exception("Cannot unmarshal type InfoStatus"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (InfoStatus)untypedValue; + if (value == InfoStatus.Observe) + { + serializer.Serialize(writer, "observe"); + return; + } + throw new Exception("Cannot marshal type InfoStatus"); + } + + public static readonly InfoStatusConverter Singleton = new InfoStatusConverter(); + } + + internal class UnitConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(Unit) || t == typeof(Unit?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize(reader); + switch (value) + { + case "gal": + return Unit.Gal; + case "kine": + return Unit.Kine; + } + throw new Exception("Cannot unmarshal type Unit"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (Unit)untypedValue; + switch (value) + { + case Unit.Gal: + serializer.Serialize(writer, "gal"); + return; + case Unit.Kine: + serializer.Serialize(writer, "kine"); + return; + } + throw new Exception("Cannot marshal type Unit"); + } + + public static readonly UnitConverter Singleton = new UnitConverter(); + } + + internal class ReportColorConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(ReportColor) || t == typeof(ReportColor?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize(reader); + if (value == "綠色") + { + return ReportColor.綠色; + } + throw new Exception("Cannot unmarshal type ReportColor"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (ReportColor)untypedValue; + if (value == ReportColor.綠色) + { + serializer.Serialize(writer, "綠色"); + return; + } + throw new Exception("Cannot marshal type ReportColor"); + } + + public static readonly ReportColorConverter Singleton = new ReportColorConverter(); + } + + internal class ReportRemarkConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(ReportRemark) || t == typeof(ReportRemark?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize(reader); + if (value == "本報告係中央氣象局地震觀測網即時地震資料地震速報之結果。") + { + return ReportRemark.本報告係中央氣象局地震觀測網即時地震資料地震速報之結果; + } + throw new Exception("Cannot unmarshal type ReportRemark"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (ReportRemark)untypedValue; + if (value == ReportRemark.本報告係中央氣象局地震觀測網即時地震資料地震速報之結果) + { + serializer.Serialize(writer, "本報告係中央氣象局地震觀測網即時地震資料地震速報之結果。"); + return; + } + throw new Exception("Cannot marshal type ReportRemark"); + } + + public static readonly ReportRemarkConverter Singleton = new ReportRemarkConverter(); + } + + internal class DatasetDescriptionConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(DatasetDescription) || t == typeof(DatasetDescription?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize(reader); + if (value == "地震報告") + { + return DatasetDescription.地震報告; + } + throw new Exception("Cannot unmarshal type DatasetDescription"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (DatasetDescription)untypedValue; + if (value == DatasetDescription.地震報告) + { + serializer.Serialize(writer, "地震報告"); + return; + } + throw new Exception("Cannot marshal type DatasetDescription"); + } + + public static readonly DatasetDescriptionConverter Singleton = new DatasetDescriptionConverter(); + } + + internal class TypeEnumConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(TypeEnum) || t == typeof(TypeEnum?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize(reader); + switch (value) + { + case "Float": + return TypeEnum.Float; + case "Integer": + return TypeEnum.Integer; + case "String": + return TypeEnum.String; + case "Timestamp": + return TypeEnum.Timestamp; + } + throw new Exception("Cannot unmarshal type TypeEnum"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (TypeEnum)untypedValue; + switch (value) + { + case TypeEnum.Float: + serializer.Serialize(writer, "Float"); + return; + case TypeEnum.Integer: + serializer.Serialize(writer, "Integer"); + return; + case TypeEnum.String: + serializer.Serialize(writer, "String"); + return; + case TypeEnum.Timestamp: + serializer.Serialize(writer, "Timestamp"); + return; + } + throw new Exception("Cannot marshal type TypeEnum"); + } + + public static readonly TypeEnumConverter Singleton = new TypeEnumConverter(); + } + + internal class ParseStringConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(bool) || t == typeof(bool?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize(reader); + bool b; + if (Boolean.TryParse(value, out b)) + { + return b; + } + throw new Exception("Cannot unmarshal type bool"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (bool)untypedValue; + var boolString = value ? "true" : "false"; + serializer.Serialize(writer, boolString); + return; + } + + public static readonly ParseStringConverter Singleton = new ParseStringConverter(); + } +} diff --git a/BackendWorkerService/root/PowerfulRain.xml b/BackendWorkerService/root/PowerfulRain.xml new file mode 100644 index 0000000..6f49241 --- /dev/null +++ b/BackendWorkerService/root/PowerfulRain.xml @@ -0,0 +1,192 @@ + + + + CWB-Weather_extremely-rain_202304300430001 + weather@cwb.gov.tw + 2023-04-30T04:34:49+08:00 + Actual + Cancel + Public + weather@cwb.gov.tw,CWB-Weather_extremely-rain_202304292135001,2023-04-29T21:44:03+08:00 + + zh-TW + Met + 降雨 + Past + Minor + Observed + + profile:CAP-TWP:Event:1.0 + rainfall + + 2023-04-30T04:30:00+08:00 + 2023-04-30T04:30:00+08:00 + 2023-04-30T04:44:49+08:00 + 中央氣象局 + 解除大雨特報 + +由於降雨趨於緩和,發生大雨的機率降低,故解除大雨特報;今日綠島及蘭嶼仍有局部較大雨勢發生的機率,請注意。 + + + https://www.cwb.gov.tw/V8/C/P/Warning/FIFOWS.html + + alert_title + 大雨特報 + + + + 基隆市 + + Taiwan_Geocode_103 + 10017 + + + + 臺北市 + + Taiwan_Geocode_103 + 63 + + + + 新北市 + + Taiwan_Geocode_103 + 65 + + + + 桃園市 + + Taiwan_Geocode_103 + 68 + + + + 新竹市 + + Taiwan_Geocode_103 + 10018 + + + + 新竹縣 + + Taiwan_Geocode_103 + 10004 + + + + 苗栗縣 + + Taiwan_Geocode_103 + 10005 + + + + 臺中市 + + Taiwan_Geocode_103 + 66 + + + + 彰化縣 + + Taiwan_Geocode_103 + 10007 + + + + 雲林縣 + + Taiwan_Geocode_103 + 10009 + + + + 南投縣 + + Taiwan_Geocode_103 + 10008 + + + + 嘉義縣 + + Taiwan_Geocode_103 + 10010 + + + + 嘉義市 + + Taiwan_Geocode_103 + 10020 + + + + 臺南市 + + Taiwan_Geocode_103 + 67 + + + + 高雄市 + + Taiwan_Geocode_103 + 64 + + + + 屏東縣 + + Taiwan_Geocode_103 + 10013 + + + + 宜蘭縣 + + Taiwan_Geocode_103 + 10002 + + + + 花蓮縣 + + Taiwan_Geocode_103 + 10015 + + + + 臺東縣 + + Taiwan_Geocode_103 + 10014 + + + + 澎湖縣 + + Taiwan_Geocode_103 + 10016 + + + + 金門縣 + + Taiwan_Geocode_103 + 09020 + + + + 連江縣 + + Taiwan_Geocode_103 + 09007 + + + + \ No newline at end of file diff --git a/BackendWorkerService/root/Typhoon.xml b/BackendWorkerService/root/Typhoon.xml new file mode 100644 index 0000000..6098d81 --- /dev/null +++ b/BackendWorkerService/root/Typhoon.xml @@ -0,0 +1,197 @@ + + + + CWB-Weather_typhoon-warning_202210162030001 + weather@cwb.gov.tw + 2022-10-16T20:20:41+08:00 + Actual + Cancel + Public + weather@cwb.gov.tw,CWB-Weather_typhoon-warning_202210161730001,2022-10-16T17:20:00+08:00 + + zh-TW + Met + 颱風 + Past + Minor + Observed + + profile:CAP-TWP:Event:1.0 + typhoon + + 2022-10-16T20:30:00+08:00 + 2022-10-16T20:30:00+08:00 + 2022-10-16T20:40:00+08:00 + 中央氣象局 + 解除颱風警報 + +[颱風動態] +根據最新資料顯示,第20號颱風已增強為中度颱風,中心目前在鵝鑾鼻西南方海面,向西南西移動,對巴士海峽近海的威脅已解除。 + +[注意事項] +*今(16日)晚至明(17)日巴士海峽及臺灣附近各海面風浪仍偏大,各沿海地區(含蘭嶼、綠島)及澎湖、金門、馬祖有長浪發生的機率,請避免前往海邊活動。*今(16日)晚雲林以北、恆春半島沿海空曠地區及澎湖、馬祖易有9至10級強陣風,東半部、嘉義、臺南沿海空曠地區及蘭嶼、綠島、金門亦有較強陣風;明(17)日臺南以北沿海空曠地區、蘭嶼、綠島、澎湖、金門、馬祖易有9至12級強陣風,東半部沿海地區及西半部地區有8至9級強陣風,路樹、懸掛物、招牌等物品宜加強固定,外出活動、機車騎士行車或行經高架橋車輛,請特別注意安全。*自15日0時至16日20時出現較大累積雨量如下:臺北市擎天崗989.0毫米,宜蘭縣樂水分校973.5毫米,新北市汐止579.5毫米,基隆市五堵578.0毫米,桃園市嘎拉賀555.0毫米,新竹縣西丘斯山478.0毫米,臺中市南湖圈谷394.5毫米,花蓮縣和平林道361.0毫米。*本警報單之颱風半徑為平均半徑,第20號颱風之7級風暴風半徑北半象限約220公里,南半象限約180公里,平均半徑約為200公里。颱風詳細特性請參考本局颱風輔助說明(https://www.cwb.gov.tw/Data/typhoon/TY_ PDF.pdf)。*此為第20號颱風警報最後一次報告。 + + + + https://www.cwb.gov.tw/V8/C/P/Warning/FIFOWS.html + + alert_title + 颱風警報 + + + + 基隆市 + + Taiwan_Geocode_103 + 10017 + + + + 臺北市 + + Taiwan_Geocode_103 + 63 + + + + 新北市 + + Taiwan_Geocode_103 + 65 + + + + 桃園市 + + Taiwan_Geocode_103 + 68 + + + + 新竹市 + + Taiwan_Geocode_103 + 10018 + + + + 新竹縣 + + Taiwan_Geocode_103 + 10004 + + + + 苗栗縣 + + Taiwan_Geocode_103 + 10005 + + + + 臺中市 + + Taiwan_Geocode_103 + 66 + + + + 彰化縣 + + Taiwan_Geocode_103 + 10007 + + + + 雲林縣 + + Taiwan_Geocode_103 + 10009 + + + + 南投縣 + + Taiwan_Geocode_103 + 10008 + + + + 嘉義縣 + + Taiwan_Geocode_103 + 10010 + + + + 嘉義市 + + Taiwan_Geocode_103 + 10020 + + + + 臺南市 + + Taiwan_Geocode_103 + 67 + + + + 高雄市 + + Taiwan_Geocode_103 + 64 + + + + 屏東縣 + + Taiwan_Geocode_103 + 10013 + + + + 宜蘭縣 + + Taiwan_Geocode_103 + 10002 + + + + 花蓮縣 + + Taiwan_Geocode_103 + 10015 + + + + 臺東縣 + + Taiwan_Geocode_103 + 10014 + + + + 澎湖縣 + + Taiwan_Geocode_103 + 10016 + + + + 金門縣 + + Taiwan_Geocode_103 + 09020 + + + + 連江縣 + + Taiwan_Geocode_103 + 09007 + + + + \ No newline at end of file