如何撰寫天氣延伸模組
在本節中,您會看到撰寫您自己的天氣延伸模組的逐步指南。
什麼是天氣延伸模組
農業數據管理員中的天氣延伸是一個指令清單 (JSON) 檔案,提供 API 的完整詳細數據,以及每個 API 回應的範本(輸出)。 因此,延伸模組檔案基本上是農業數據管理員所定義的 API 範本結構,以便瞭解 API 輸入(要求)和輸出(回應)特性。
天氣延伸結構
在高層級,擴充檔案是由兩件事所組成的 JSON:
- 提供者元資料 (JSON 物件)
- API 資訊 (JSON 陣列)
提供者元數據
這是 json 物件,提供下列欄位的詳細數據,這些字段必須唯一識別延伸模組及其版本設定資訊。 延伸模組的本節中提供的詳細數據會顯示給農業數據管理員市集中的外部客戶。 因此 extensionId
, 和 extensionName
(為了容易識別) 和 description
(針對價值主張) 需要以客戶為焦點。
範例提供者元數據
"provider": {
"extensionId": "abc.weather",
"extensionName": "ABC weather",
"description": "Get Weather data from ABC weather into Azure Data Manager for Agriculture platform using this extension",
"dataCategory": "Weather",
"farmBeatsSchemaVersion": "1.0",
"extensionVersion": "1.0",
"supportUrl": "www.abc.com/support",
"supportEmail": "support@abc.com"
}
提供者元數據詳細數據
名稱 | 類型 | 描述 |
---|---|---|
extensionId | 字串 | 以組織名稱 (Contoso) 和服務 (weather) 的方式提供的識別碼,例如: org.service 。 extensionId 是延伸模組的唯一標識符,也是使用者在農業用數據管理員平臺上用來與擴充功能 API 互動的識別碼 |
extensionName | 字串 | 要用於農業延伸模組市集之數據管理員的延伸模組名稱。 |
description | 字串 | 說明延伸模組所提供的功能和服務。 |
dataCategory | 字串 | 針對天氣延伸模組,請使用 weather 。 |
farmBeatsSchemaVersion | 字串 | 農業用數據管理員上的指令清單檔版本。 現有指令清單檔的任何更新都會導致此欄位的新版本更新。 |
extensionVersion | 字串 | 擴展名檔案的版本。 從 1.0 開始。 更新 延伸模組檔案會根據主要和次要更新慣例,遞增此版本號碼。 |
supportUrl | 字串 | 引發支持查詢和常見問題的網站連結 |
supportEmail | 字串 | 在支持查詢中傳送的電子郵件。 |
API 資訊
API 資訊 JSON 陣列 (apiInfos
) 可以進一步細分成下列結構元素。
- API 中繼資料
- Authentication parameters
- API 輸入參數
- 擷取的 API 輸入參數
- 功能參數
- 單位系統
- 平臺和自定義參數
- 平臺和自定義範本
API 中繼資料
本節包含農業數據管理員用來識別 apiName
API 的基本資訊(明確由使用者呼叫),並根據適當的 requestType
將 API 要求重新導向至右側endpoint
。
範例 API 元數據
"apiInfos": [
{
"apiName": "dailyforecast",
"description": "The Daily Forecast API",
"endpoint": "https://ag.us.clearapis.com/v1.1/forecast/daily",
"requestType": "GET",
"isLoadAPI": "false",
"typeOfData": "forecast",
"granularity": "daily",
"defaultUnitSystem": "us"
}
]
API 元數據詳細數據
名稱 | 類型 | 描述 |
---|---|---|
apiInfos | 陣列 | 物件的 JSON 陣列,其中每個 API 都是陣列中的 apiInfos 物件。 |
apiName | 字串 | 延伸模組支援的 API 名稱,其確切名稱是使用者要呼叫擴充功能 API 的確切名稱。 請遵循與 API 檔中所述的相同命名慣例。 |
description | 字串 | API 描述 |
endpoint | 字串 | 要呼叫 apiName 的農業數據管理員 API 端點。 |
requestType | 字串 | GET POST PUT 或 要求類型,如 所apiName 支援。 |
isLoadAPI | boolean | apiName 如果是類似目前天氣資料的傳遞 API,請將此金鑰false 設為 。 針對所有負載 API(歷程記錄和預測),請將此欄位保留為 true 。 isLoadAPI 當密鑰為 false 時,API 回應會直接傳送給使用者,而且不會儲存在農業記憶體服務的數據管理員中。 |
typeOfData | 字串 | 目前支援的值是 Historical 和 Forecast 。 |
粒度 | 字串 | 目前支援的值是 Daily 和 Hourly 。 |
defaultUnitSystem | 字串 | 提供所支援 apiName 的預設單位系統名稱。 |
Authentication parameters
本節接受 驗證相關參數,如 所 apiName
支援。 由於農業數據管理員在 API 標頭區段中支援兩種類型的驗證相關密鑰(x-ms-farmBeats-data-provider-id
& ), x-ms-farmBeats-data-provider-key
因此擴充檔案必須明確提供其各自驗證密鑰的密鑰名稱,如 所需的 apiName
。
當農業數據管理員透過 API 標頭收集驗證資訊時(在建立天氣作業 API 中)。 驗證參數對應可確保農業用數據管理員可以視需要將金鑰據以傳遞至延伸模組。
範例驗證參數
"apiInfos": [
"authInputParameters": [
{
"farmBeatsAuthMapping": "x-ms-farmBeats-data-provider-id",
"name": "app_id",
"isRequired": "true",
"providerDataType": "string",
"description": "Provide the APP ID, username etc. that your API supports",
"location": "apiQuery"
},
{
"farmBeatsAuthMapping": "x-ms-farmBeats-data-provider-key",
"name": "app_key",
"isRequired": "true",
"providerDataType": "string",
"description": "Provide the API Key or password etc. that your API supports",
"location": "apiQuery"
}
]
]
驗證參數詳細數據
名稱 | 類型 | 描述 |
---|---|---|
authInputParameters | 陣列 | 驗證參數的 JSON 陣列,其中每個物件都表示支援的驗證類型。 根據延伸模組支援的驗證類型使用金鑰。 |
farmBeatsAuthMapping | 字串 | 目前支援兩種類型的驗證相關密鑰。 若為 API 金鑰型驗證,請只x-ms-farmBeats-data-provider-key 使用 物件,而針對應用程式識別碼和 APP 金鑰型驗證則同時使用和 x-ms-farmBeats-data-provider-id x-ms-farmBeats-data-provider-key 物件。 |
NAME | 字串 | 支援的驗證金鑰 apiName 名稱。 |
isRequired | boolean | 此名稱是否為 apiName 的必要參數? 提供 true 或 false 值。 |
providerDataType | 字串 | 提供 參數的 name 數據類型。 |
description | 字串 | 農業數據管理員會描述每個物件內每個 farmBeatsAuthMapping 的意義。 |
location | 字串 | API 中應 name 傳送參數的位置。 目前支援的值是 apiQuery 和 apiHeader 。 |
API 輸入參數
本節提供 API 簽章 (輸入參數) 的詳細數據,以成功呼叫 。apiName
範例 API 輸入參數
"apiInfos": [
"apiInputParameters": [
{
"name": "start",
"isRequired": "true",
"providerDataType": "double",
"description": "Start of time range. Valid start values range from zero to nine. Day zero represents the current day.",
"location": "apiQuery"
},
{
"name": "end",
"isRequired": "true",
"providerDataType": "double",
"description": "End of time range. Valid end values range from zero to nine.",
"location": "apiQuery"
},
{
"name": "location",
"isRequired": "true",
"providerDataType": "string",
"description": "User-provided latitude and longitude coordinates. Formatted as location=[(<lat_1>,<lon_1>)].",
"location": "apiQuery"
},
{
"name": "unitcode",
"isRequired": "false",
"providerDataType": "string",
"description": "Unit conversion set to be used. Default is us-std. Valid values are us-std, si-std.",
"location": "apiQuery"
},
]
]
API 輸入參數詳細數據
名稱 | 類型 | 描述 |
---|---|---|
apiInputParameters | 陣列 | API 輸入參數的 JSON 陣列,其中每個物件都表示 所 apiName 支援的輸入參數。 |
NAME | 字串 | 所支援的 apiName 輸入參數名稱。 |
isRequired | boolean | 此名稱是否為 apiName 的必要參數? 提供 true 或 false 值。 |
providerDataType | 字串 | 提供 參數的 name 數據類型。 |
description | 字串 | 提供參數 name 的意義描述。 |
location | 字串 | API 中應 name 傳送參數的位置。 目前支援的值是 apiQuery 和 apiHeader 。 |
擷取的 API 輸入參數
本節是讓數據管理員擷取 API 要求中傳遞的計算和記憶體輸入參數。 在此範例中,農業數據管理員會從 API 輸入要求擷取位置資訊(緯度和經度),並將其儲存為農業數據管理員中每個天氣輸出的一部分。
因此,延伸模組必須提供 HandleBars 範本 ,以瞭解如何擷取位置資訊。 下列範例建議擴充功能 API 針對 和 "longitude"
"lon"
收集位置資訊"lat"
"latitude"
。
擷取的 API 輸入參數範例
"extractedApiInputParameters": [
{
"name": "location",
"template": "{ \"latitude\": \"{{lat}}\", \"longitude\": \"{{lon}}\" } "
}
]
擷取的 API 輸入參數詳細數據
名稱 | 類型 | 描述 |
---|---|---|
extractedApiInputParameters | 陣列 | 擷取功能的 JSON 陣列,其中每個物件都表示需要擷取哪些資訊。 目前 location 是這類擷取的其中一個。 |
NAME | 字串 | 擷取的名稱,目前支援的值是 location 。 |
template | 字串 | HandleBars 範本,描述如何在 API 輸入參數中收集緯度和經度資訊。 |
功能參數
本節專用於農業數據管理員所建置的功能/功能。 對於天氣延伸,距心計算是這類功能之一。
當使用者未提供緯度/經度座標時,農業數據管理員會使用字段的主要幾何(使用者傳遞的標識符)來計算距心。 計算的心心座標會當做緯度和經度傳遞至延伸模組(數據提供者)。 因此,讓農業數據管理員能夠瞭解位置座標功能參數區段的使用方式。
若要讓農業用數據管理員瞭解輸入參數中的 apiName
緯度和經度使用方式,延伸模組會提供 name
用來收集位置資訊的索引鍵,後面接著 句柄欄範本 ,以暗示傳遞緯度和經度值的方式。
範例功能參數
"apiInfos": [
"functionalParameters": [
{
"name": "CentroidCalculation",
"description": "Provide names of the parameters used to collect latitude and longitude information",
"functionalParameterEntities": [
{
"name": "lat",
"template": "{ \"lat\": \"{{latitude}}\" } "
},
{
"name": "lon",
"template": "{ \"lon\": \"{{longitude}}\" } "
}
]
}
],
]
功能參數詳細數據
名稱 | 類型 | 描述 |
---|---|---|
functionalParameters | 陣列 | 功能的 JSON 陣列,其中每個物件都表示農業數據管理員所支援的功能。 目前 CentroidCalculation 是這類功能之一。 |
NAME | 字串 | 功能的名稱,目前支援的值是 CentroidCalculation 。 |
description | 字串 | 適用於農業的數據管理員功能描述。 |
functionalParameterEntities | 陣列 | 物件的 JSON 陣列,其中每個物件都是緯度和經度特有的。 |
單位系統
此區段由農業數據管理員用來瞭解擴充功能所支援的各種單位系統類型。 因此,延伸模組必須提供 key
用來在 API 輸入中收集單位資訊的名稱,後面接著各種單位系統名稱(例如:us-std),如 支援 apiName
。
範例單位系統
"unitSystems":
{
"key": "unitcode",
"values": [
"us-std",
"si-std",
"us-std-precise",
"si-std-precise"
]
}
單位系統詳細數據
名稱 | 類型 | 描述 |
---|---|---|
unitSystems | object | 用來收集單位系統資訊的 JSON 物件。 |
索引鍵 | 字串 | 用來收集 API 輸入中單位資訊的參數名稱。 |
值 | 字串 | 延伸模組所支援的單位系統名稱清單。 |
平臺和自定義參數
在每個天氣 API 回應中,作為輸出一部分傳送的天氣量值(例如溫度、露點等)稱為參數。
因此,在參數方面,農業數據管理員會在內部支援下列參數集,並將其視為 Platform parameters
。
- cloudCover
- dateTime
- dewPoint
- growingDegreeDay
- 降水
- 壓力
- relativeHumidity
- soilMoisture
- soilTemperature
- 溫度
- 可視性
- wetBulbTemperature
- windChill
- windDirection
- windGust
- windSpeed
因此,任何傳送天氣參數的延伸模組,都不屬於平台參數,會將其傳送為的 Custom parameters
一部分。 平臺和客戶參數之間的主要差異在於,使用農業數據管理員氣象 API 的用戶能夠查詢和篩選平台參數(例如:溫度 > 30),而不是在自定義參數上。 不過,自定義參數會作為天氣查詢輸出的一部分傳送。
在本節中,延伸模組會針對支援的每個單位系統,提供每個參數的單位資訊。 使用此適用於農業的數據管理員,會根據延伸模組本節中提供的資訊,知道每個天氣參數的基礎測量單位為何。
注意
- 對於特定參數,如果單位不適用,則不要提及這些單位的單位 (例如: weatherDescriptor)
- 對於特定參數,如果所有單位系統的單位都相同,則在所有單位系統中都提及相同。 (例如:cloudCover)
範例平臺和自定義參數
"apiInfos": [
"platformParameters": [
{
"farmBeatsName": "cloudCover",
"farmBeatsDataType": "double",
"description": "The average percentage of sky covered by clouds.",
"measurementUnits": [
{
"unitSystem": "us-std",
"unit": "%"
},
{
"unitSystem": "us-std-precise",
"unit": "%"
},
{
"unitSystem": "si-std",
"unit": "%"
},
{
"unitSystem": "si-std-precise",
"unit": "%"
}
]
},
{
"farmBeatsName": "dewPoint",
"farmBeatsDataType": "double",
"description": "The air temperature at which the air will become saturated, and dew moisture will condense into fog (or dew).",
"measurementUnits": [
{
"unitSystem": "us-std",
"unit": "F"
},
{
"unitSystem": "us-std-precise",
"unit": "F"
},
{
"unitSystem": "si-std",
"unit": "C"
},
{
"unitSystem": "si-std-precise",
"unit": "C"
}
]
},
"customParameters": [
{
"providerName": "weatherDescriptor",
"providerDataType": "string",
"description": "General weather descriptor data"
},
{
"providerName": "airTempMax",
"providerDataType": "double",
"description": "Maximum daily air temperature at two meters above ground level.",
"measurementUnits": [
{
"unitSystem": "us-std",
"unit": "F"
},
{
"unitSystem": "us-std-precise",
"unit": "F"
},
{
"unitSystem": "si-std",
"unit": "C"
},
{
"unitSystem": "si-std-precise",
"unit": "C"
}
]
},
]
平台參數詳細數據
名稱 | 類型 | 描述 |
---|---|---|
platformParameters | 陣列 | 平台參數的 JSON 陣列,其中每個物件都是一個平台參數。 |
farmBeatsName | 字串 | 由農業數據管理員提供的參數名稱。 |
farmBeatsDataType | 字串 | 由農業數據管理員提供的參數數據類型。 |
description | 字串 | 由農業數據管理員提供的參數描述。 |
measurementUnits | 字串 | 擴充功能所支援之每個單位系統的 values JSON 單位陣列。 |
unitSystem | 字串 | 延伸模組所支持的單位系統 value 。 |
單位 | 字串 | 特定天氣參數的度量單位,例如 F :d ewPoint的度量單位。 |
自定義參數詳細數據
名稱 | 類型 | 描述 |
---|---|---|
customParameters | object | 自定義參數的 JSON 陣列,其中每個物件都是一個自定義參數。 |
providerName | 字串 | 擴充功能所提供的參數名稱。 |
providerDataType | 字串 | 延伸模組所提供的參數數據類型。 |
description | 字串 | 擴充功能所提供的參數描述。 |
measurementUnits | 字串 | 擴充功能所支援之每個單位系統的 values JSON 單位陣列。 |
unitSystem | 字串 | 延伸模組所支持的單位系統 value 。 |
單位 | 字串 | 特定天氣參數的度量單位,例如: F airTempMax。 |
平臺和自定義範本
範本是延伸模組所提供的對應資訊,可將延伸模組 API 輸出 (JSON 回應) 轉換為農業數據管理員預期的格式。 使用這個不同的 API 輸出格式現在可以統一對應/轉換成單一格式。
範本解決方案是剖析擴充功能所提供 JSON 輸出的最有效方式之一。 在天氣延伸的情況下, 農業數據管理員預期會使用 HandleBars 範本來撰寫延伸模組。 HandleBars 是一種 開放原始碼 範本化語言,可使用簡單的運算式。
注意
強烈建議使用提供的範例來試用 HandleBars 範本 ,並瞭解如何使用協助程式函式,以在農業數據管理員尚未提供時建立您自己的剖析邏輯。
概括而言,這是範本的運作方式,方法是採用 API 回應作為輸入,並以農業數據管理員預期的格式產生輸出。
如上圖所示,根據個別 API 回應驗證範本,並在延伸模組中使用已驗證的範本。 以下是 API 回應及其個別平臺和自定義範本的範例。
範例 API 回應
{
"47,-97": {
"2016-12-15": {
"overall": {
"air_temp_avg": {
"unit": "F",
"value": -3.0
},
"air_temp_max": {
"unit": "F",
"value": 5.0
},
"air_temp_min": {
"unit": "F",
"value": -11.0
},
"cloud_cover_avg": {
"unit": "%",
"value": 26.4
},
"descriptors": {
"cloud_cover_descriptor": {
"code": 21107,
"icon": "https://.../cover_partlycloudyday.png",
"text": "Increasing Clouds"
},
"precipitation_descriptor": {
"code": 61113,
"icon": "https://.../precip_flurries.png",
"text": "Slight Chance of Flurries"
},
"weather_descriptor": {
"code": 61113,
"icon": "https://.../precip_flurries.png",
"text": "Slight Chance of Flurries"
},
"wind_direction_descriptor": {
"code": 51600,
"icon": "https://.../direction_sw.png",
"text": "Southwest"
},
"wind_trend_descriptor": {
"code": 10500,
"icon": "https://.../error_none.png",
"text": "None"
}
},
"dew_point_avg": {
"unit": "F",
"value": -11.0
},
"dew_point_max": {
"unit": "F",
"value": -4.0
},
"dew_point_min": {
"unit": "F",
"value": -19.0
},
"ice_acc_period": {
"unit": "in",
"value": 0.0
},
"liquid_acc_period": {
"unit": "in",
"value": 0.0
},
"long_wave_radiation_avg": {
"unit": "W/m^2",
"value": 170.0
},
"pet_period": {
"unit": "in",
"value": 0.009
},
"precip_acc_period": {
"unit": "in",
"value": 0.001
},
"precip_prob": {
"unit": "%",
"value": 10.0
},
"relative_humidity_avg": {
"unit": "%",
"value": 68.0
},
"relative_humidity_max": {
"unit": "%",
"value": 77.0
},
"relative_humidity_min": {
"unit": "%",
"value": 61.0
},
"short_wave_radiation_avg": {
"unit": "W/m^2",
"value": 70.0
},
"snow_acc_period": {
"unit": "in",
"value": 0.02
},
"sunshine_duration": {
"unit": "hours",
"value": 6
},
"wind_gust_max": {
"unit": "n/a",
"value": "n/a"
},
"wind_speed_2m_avg": {
"unit": "mph",
"value": 6.0
},
"wind_speed_2m_max": {
"unit": "mph",
"value": 8.0
},
"wind_speed_2m_min": {
"unit": "mph",
"value": 2.0
},
"wind_speed_avg": {
"unit": "mph",
"value": 8.0
},
"wind_speed_max": {
"unit": "mph",
"value": 11.0
},
"wind_speed_min": {
"unit": "mph",
"value": 3.0
}
}
}
}
}
上述 API 回應的範例平臺和自定義範本
{
"apiInfos": {
"platformTemplate": "{ {{#each .}}\"value\": [{{#each .}} {\"cloudCover\": \"{{overall.cloud_cover_avg.value}}\" ,\"dewPoint\": \"{{overall.dew_point_avg.value}}\" ,\"precipitation\": \"{{overall.precip_acc_period.value}}\" ,\"relativeHumidity\": \"{{overall.relative_humidity_avg.value}}\" ,\"dateTime\": \"{{convertDateInYYYYMMDDToDateTime @key}}\", \"temperature\": \"{{overall.air_temp_avg.value}}\" ,\"windSpeed\": \"{{overall.wind_speed_avg.value}}\" , },{{/each}}]{{/each}} }",
"customTemplate": "{ {{#each .}}\"value\": [{{#each .}} {\"air_temp_max\": \"{{overall.air_temp_max.value}}\",\"air_temp_min\": \"{{overall.air_temp_min.value}}\",\"cloudCoverDescriptor\": \"{{overall.descriptors.cloud_cover_descriptor.text}}\",\"precipitationDescriptor\": \"{{overall.descriptors.precipitation_descriptor.text}}\",\"weatherDescriptor\": \"{{overall.descriptors.weather_descriptor.text}}\",\"windDirectionDescriptor\": \"{{overall.descriptors.wind_direction_descriptor.text}}\",\"windTrendDescriptor\": \"{{overall.descriptors.wind_trend_descriptor.text}}\",\"dewPointMax\": \"{{overall.dew_point_max.value}}\",\"dewPointMin\": \"{{overall.dew_point_min.value}}\",\"iceAccPeriod\": \"{{overall.ice_acc_period.value}}\",\"liquidAccPeriod\": \"{{overall.liquid_acc_period.value}}\",\"longWaveRadiationAvg\": \"{{overall.long_wave_radiation_avg.value}}\",\"petPeriod\": \"{{overall.pet_period.value}}\",\"precipProb\": \"{{overall.precip_prob.value}}\",\"relativeHumidityMax\": \"{{overall.relative_humidity_max.value}}\",\"relativeHumidityMin\": \"{{overall.relative_humidity_min.value}}\",\"shortWaveRadiationAvg\": \"{{overall.short_wave_radiation_avg.value}}\",\"snowAccPeriod\": \"{{overall.snow_acc_period.value}}\",\"sunshineDuration\": \"{{overall.sunshine_duration.value}}\",\"windSpeed2mAvg\": \"{{overall.wind_speed_2m_avg.value}}\",\"windSpeed2mMax\": \"{{overall.wind_speed_2m_max.value}}\",\"windSpeed2mMin\": \"{{overall.wind_speed_2m_min.value}}\",\"windSpeedMax\": \"{{overall.wind_speed_max.value}}\",\"windSpeedMin\": \"{{overall.wind_speed_min.value}}\",},{{/each}}]{{/each}} }"
}
}
注意
從 HandleBars 產生的範本會藉由新增 \"<text>\"
來使其與 JSON 格式相容來字串化。
輔助函式
範本會使用協助程式函式對原生不支援的數據執行特定轉換。 以下是適用於農業的數據管理員所支援的協助程式函式。
範例協助程式函式
Handlebars.registerHelper('splitAndTake', function(title, char, index) {
var t = title.split(char);
return t[index];
});
Handlebars.registerHelper('converttime', function(timestamp) {
return new Date(timestamp);
});
Handlebars.registerHelper('convertunixtime', function(unix_timestamp) {
return new Date(unix_timestamp * 1000);
});
這些協助程式函式的作用為何?
- SplitAndTake(object valueObject, string separator, int index) - 此函式用來根據分隔符 (Ex: “47,-97”) 分割字符串(例如:“47”),並採用位於指定索引的元素 (例如: index=0 提供 “47”)
- ConvertDateInFormatToDateTime(object dateObject, string format) - 此函式用來剖析指定格式的日期(例如:2016-12-15) 至 DateTime 字符串。
- ConvertUnixTimeToDateTime(object unixTimeStamp) - 此函式可用來將 unix 時間戳 (例如: 1392267600) 轉換為 datetime 字符串。
- GetObjectFromListWithKeyValuePair(Array listOfObjects, string key, string value) - 根據索引鍵 () 值 (
type
RAIN
) 配對擷取對象的物件清單。 在下列範例中,會使用這個函式的"type": "RAIN"
降水量。
{
"precipitation": [
{
"type": "SNOW",
"amount": 0
},
{
"type": "RAIN",
"amount": 0.01
}
]
}
- GetValueFromObject(string jsonString, string key) - 假設 json 物件為字元串,它會根據索引鍵取得值。
注意
如果您要撰寫的延伸模組需要額外的協助程式函式來剖析 API 回應,請建立 支援票證來與我們連絡。