瀏覽了許多開放資料平台,能符合個人需求第一項資訊非天氣資訊莫屬。每天回到家裡,家人總是會聊聊最近天氣變化,明天記得多穿件衣服..等。但在偶爾要出差或參加多天活動的時候,往往會遺忘觀看氣象資訊,不是隔天下雨淋得成落湯雞,就是冷到直發抖。若機器人能即時查詢目前獲明天的氣象資訊,即能減少這些問題發生。
Step 1. 開啟中央氣象局官網 - http://www.cwb.gov.tw/V7/index.htm → 登入 → 進行註冊 (註冊流程不贅述)
Step 2. 註冊好後,我們前往氣象資料開放平台進行登入 - http://opendata.cwb.gov.tw/login
Step 3. 點選資料使用說明 → 點選取得授權碼
註:請記錄授權碼,撰寫程式時需要。
Step 4. 將頁面往下捲,使用方式是使用 HttpGet,需要的參數似乎為dataid 與 authorizationkey就足夠了,dataid 在網站上有清單。
Step 5. 如前一篇所描述的,我們透過 postman 先來測試今明36小時天氣預報。似乎是 Xml 格式且包含各地區的資料,我們可能需要找一下文件並過濾一下條件。
Step 6 下方有一個資料擷取說明的連結,可以開啟一個PDF 檔案,內部有更詳盡的使用方法:
Step 7. 雖然更詳盡但與官網上有些不同。我們整理一下參數:
呼叫位置 | http://opendata.cwb.gov.tw/api/v1/rest/datastore/F-C0032-001 |
---|---|
方法 | Get |
Authorization | APIKey |
locationName | 臺北市 |
elementName:Wx | Wx,PoP |
註: elementName:
Wx, 天氣圖示代碼+描述
PoP, 降雨機率 (Probability of Precipitation)
Step 8. 再度嘗試一下 postman,我們得到了明確的資料內容。
Step 1. 在開始撰寫程式之前,我們先安裝 RestSharp。 工具 → NuGet 封裝管理員 → 管理方案的 NuGet 套件..
Step 2. 安裝 RestSharp
Step 3. 其次,我們要思考一下取回的資料該怎麼處理:從上面 postman 的回傳結果,可以看見這一個多層的 JSON 格式資料,我們必須產生對應這個格式的 (data transfer object),比較能順利進行資料操作。 我們將剛才傳回來的 JSON 資料內容複製,貼在 json2csharp (http://json2csharp.com/) 上進行類別轉換。
Step 4. 接這些程式碼貼在 RootDialog.cs 內,你的程式碼應該如下
using System;
using System.Threading.Tasks;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Connector;
using System.Collections.Generic;
namespace BotApplication.Dialogs
{
[Serializable]
public class RootDialog : IDialog<object>
{
public Task StartAsync(IDialogContext context)
{
context.Wait(MessageReceivedAsync);
return Task.CompletedTask;
}
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
{
var activity = await result as Activity;
// calculate something for us to return
int length = (activity.Text ?? string.Empty).Length;
// return our reply to the user
await context.PostAsync($"You sent {activity.Text} which was {length} characters");
context.Wait(MessageReceivedAsync);
}
}
public class Field
{
public string id { get; set; }
public string type { get; set; }
}
public class Result
{
public string resource_id { get; set; }
public List<Field> fields { get; set; }
}
public class Parameter
{
public string parameterName { get; set; }
public string parameterValue { get; set; }
public string parameterUnit { get; set; }
}
public class Time
{
public string startTime { get; set; }
public string endTime { get; set; }
public Parameter parameter { get; set; }
}
public class WeatherElement
{
public string elementName { get; set; }
public List<Time> time { get; set; }
}
public class Location
{
public string locationName { get; set; }
public List<WeatherElement> weatherElement { get; set; }
}
public class Records
{
public string datasetDescription { get; set; }
public List<Location> location { get; set; }
}
public class RootObject
{
public string success { get; set; }
public Result result { get; set; }
public Records records { get; set; }
}
}
Step 5. 更改MessageReceivedAsync 方法內容如下:
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
{
var activity = await result as Activity;
if(activity.Text.IndexOf("weather") >=0 || activity.Text.IndexOf("天氣") >= 0)
{
var client = new RestClient("http://opendata.cwb.gov.tw");
var request = new RestRequest("api/v1/rest/datastore/F-C0032-001?Authorization=CWB-3D935FDD-1086-4C5B-86A9-F8C7EFFB42A4&locationName=臺北市&elementName=Wx,PoP", Method.GET);
var response = await client.ExecuteTaskAsync<RootObject>(request);
var weather = response.Data.records.location[0].weatherElement[0].time[1].parameter.parameterName;
var rainPercentage = response.Data.records.location[0].weatherElement[1].time[1].parameter.parameterName;
await context.PostAsync($"天氣:{weather},降雨機率{rainPercentage}");
}
context.Wait(MessageReceivedAsync);
}
Step 6. 啟動專案,我們透過模擬器輸入”天氣”
Step 7. 您可以上傳 Azure Web Applicaion,這樣你的 bot 又多會一項技能。 隨著我們服務越來越多,我們在後續某一篇會做 refactor。
https://github.com/matsurigoto/BotFrameworkExample02