共用方式為


如何撰寫天氣延伸模組

在本節中,您會看到撰寫您自己的天氣延伸模組的逐步指南。

什麼是天氣延伸模組

農業數據管理員中的天氣延伸是一個指令清單 (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 字串 GETPOST PUT 或 要求類型,如 所apiName支援。
isLoadAPI boolean apiName如果是類似目前天氣資料的傳遞 API,請將此金鑰false設為 。 針對所有負載 API(歷程記錄和預測),請將此欄位保留為 trueisLoadAPI當密鑰為 false時,API 回應會直接傳送給使用者,而且不會儲存在農業記憶體服務的數據管理員中。
typeOfData 字串 目前支援的值是 HistoricalForecast
粒度 字串 目前支援的值是 DailyHourly
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-idx-ms-farmBeats-data-provider-key 物件。
NAME 字串 支援的驗證金鑰 apiName名稱。
isRequired boolean 此名稱是否為 apiName 的必要參數? 提供 true 或 false 值。
providerDataType 字串 提供 參數的 name 數據類型。
description 字串 農業數據管理員會描述每個物件內每個 farmBeatsAuthMapping 的意義。
location 字串 API 中應 name 傳送參數的位置。 目前支援的值是 apiQueryapiHeader

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 傳送參數的位置。 目前支援的值是 apiQueryapiHeader

擷取的 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) - 根據索引鍵 () 值 (typeRAIN) 配對擷取對象的物件清單。 在下列範例中,會使用這個函式的 "type": "RAIN" 降水量。
{
"precipitation": [
      {
        "type": "SNOW",
        "amount": 0
      },
      {
        "type": "RAIN",
        "amount": 0.01
      }
    ]
}
  • GetValueFromObject(string jsonString, string key) - 假設 json 物件為字元串,它會根據索引鍵取得值。

注意

如果您要撰寫的延伸模組需要額外的協助程式函式來剖析 API 回應,請建立 支援票證來與我們連絡。