OpenWeather: 気象予報, 日付を指定して取得
OpenWeather: 気象予報, 日付を指定して取得 (OpenWeather: Weather Forecast, Get by Date)
任意日付の気象予報を OpenWeather から取得します。世界中の緯度と経度を指定できます。気温、湿度、風速だけでなく、日没時刻や露点温度なども取得可能です。
Configs
  • A: API Key をセットしてください *#{EL}
  • B1: 表示単位系をセットしてください (摂氏:”metric” or 華氏:”imperial”)#{EL}
  • B2: 天気概況フィールドを翻訳したい場合、言語コードをセットしてください (例 “ja” “es”)#{EL}
  • C: 日付(現地時間)、緯度、経度を3行に分けてセットしてください *#{EL}
  • D1: 日の出時刻が格納される文字列型or時刻型データ項目を選択してください (更新)
  • D2: 日の入り時刻が格納される文字列型or時刻型データ項目を選択してください (更新)
  • E1: 最低気温が格納される数値型データ項目を選択してください (更新)
  • E2: 最高気温が格納される数値型データ項目を選択してください (更新)
  • E3: 日中体感気温が格納される数値型データ項目を選択してください (更新)
  • E4: 露点温度が格納される数値型データ項目を選択してください (更新)
  • F1: 降水確率(%)が格納される数値型データ項目を選択してください (更新)
  • F2: 湿度(%)が格納される数値型データ項目を選択してください (更新)
  • F3: 雲量(%)が格納される数値型データ項目を選択してください (更新)
  • G1: 天気区分が格納される文字列型データ項目を選択してください (更新)
  • G2: 天気概況が格納される文字列型データ項目を選択してください (更新)
  • H1: 風速が格納される数値型データ項目を選択してください (更新)
  • H2: 風向角度(0:真北 90:真東)〔風が吹いてくる方向〕が格納される数値型データ項目を選択してください (更新)
  • I1: 降水量(mm)が格納される数値型データ項目を選択してください (更新)
  • I2: 海面更正気圧(hPa)が格納される数値型データ項目を選択してください (更新)
  • I3: 最大紫外線指数が格納される数値型データ項目を選択してください (更新)
Script (click to open)
// GraalJS Script (engine type: 2)

//////// START "main()" /////////////////////////////////////////////////////////////////
main();
function main(){ 

//// == Config Retrieving / 工程コンフィグの参照 ==
const strApiKey      = configs.get( "StrConfA" ); // required
  if( strApiKey    === "" ){
    throw new Error( "\n AutomatedTask ConfigError:" +
                     " Config {A API Key} is empty \n" );
  }
const strUnitSystem  = configs.get( "StrConfB1" );
const strLangCode    = configs.get( "StrConfB2" );
const strTarget3     = configs.get( "StrConfC" ); // required
  if( strTarget3   === "" ){
    throw new Error( "\n AutomatedTask ConfigError:" +
                     " Config {C Date Latitude Longitude} is empty \n" );
  }
  const arrTarget3   = strTarget3.split("\n");
  if( arrTarget3.length < 3 ){
    throw new Error( "\n AutomatedTask ConfigError:" +
                     " Config {C Date Latitude Longitude} Set in 3 lines \n" );
  }
  const strSpecifiedDate = arrTarget3[0].slice(0, 10); // eg "2021-12-31"
  let  dateSpecified = toJsDate( strSpecifiedDate + " 23:59" ); // LastTime in Date (Platform)
  const strLat       = arrTarget3[1];
  const strLon       = arrTarget3[2];
const timePocketSunrise  = configs.getObject( "SelectConfD1" );
const timePocketSunset   = configs.getObject( "SelectConfD2" );
const numPocketMinTemp   = configs.getObject( "SelectConfE1" );
const numPocketMaxTemp   = configs.getObject( "SelectConfE2" );
const numPocketFeelTemp  = configs.getObject( "SelectConfE3" );
const numPocketDewPoint  = configs.getObject( "SelectConfE4" );
const numPocketPop       = configs.getObject( "SelectConfF1" );
const numPocketHumidity  = configs.getObject( "SelectConfF2" );
const numPocketClouds    = configs.getObject( "SelectConfF3" );
const strPocketGroup     = configs.getObject( "SelectConfG1" );
const strPocketCondition = configs.getObject( "SelectConfG2" );
const numPocketWindSpeed = configs.getObject( "SelectConfH1" );
const numPocketWindDeg   = configs.getObject( "SelectConfH2" );
const numPocketRain      = configs.getObject( "SelectConfI1" );
const numPocketPressure  = configs.getObject( "SelectConfI2" );
const numPocketUvi       = configs.getObject( "SelectConfI3" );


//// == Data Retrieving / ワークフローデータの参照 ==
// (Nothing. Retrieved via Expression Language in Config Retrieving)


//// == Calculating / 演算 ==

/// Get all essential weather data for a specific location
/// https://openweathermap.org/api/one-call-api
// request1, prepare
let getUri1  = "https://api.openweathermap.org/data/2.5/onecall";
let request1 = httpClient.begin(); // HttpRequestWrapper
    request1 = request1.queryParam( "appid", strApiKey ); 
    request1 = request1.queryParam( "lat", strLat ); 
    request1 = request1.queryParam( "lon", strLon ); 
    request1 = request1.queryParam( "exclude", "minutely,hourly" ); 
    if( strUnitSystem !== "" ){
      request1 = request1.queryParam( "units", strUnitSystem ); 
    }
    if( strLangCode !== "" ){
      request1 = request1.queryParam( "lang", strLangCode ); 
    }
// request1, try
const response1     = request1.get( getUri1 ); // HttpResponseWrapper
engine.log( " AutomatedTask ApiRequest1 Start: " + getUri1 );
const response1Code = response1.getStatusCode() + "";
const response1Body = response1.getResponseAsString() + "";
engine.log( " AutomatedTask ApiResponse1 Status: " + response1Code );
if( response1Code !== "200"){
  throw new Error( "\n AutomatedTask UnexpectedResponseError: " +
                    response1Code + "\n" + response1Body + "\n" );
}
// response1, parse
// engine.log( response1Body ); // debug
/* response sample
{
  lat: 43.0687,
  lon: 141.3508,
  timezone: "Asia/Tokyo",
  timezone_offset: 32400,
  daily: [
    {
      dt: 1613440800,
      sunrise: 1613424690,
      sunset: 1613462769,
      temp: {
        day: -1.47,
        min: -7.04,
        max: 3.61,
        night: -7.04,
        eve: -6.05,
        morn: 3.39
      },
      feels_like: {
        day: -14.13,
        night: -14.19,
        eve: -15.56,
        morn: -0.52
      },
      pressure: 976,
      humidity: 92,
      dew_point: -5.77,
      wind_speed: 14.75,
      wind_deg: 271,
      weather: [
        {
          id: 616,
          main: "Snow",
          description: "rain and snow",
          icon: "13d"
        }
      ],
      clouds: 100,
      pop: 1,
      rain: 10.85,
      snow: 6.1,
      uvi: 0.74
    },
*/
const response1Obj = JSON.parse( response1Body );
engine.log( " AutomatedTask ApiResponse1 # of Array Daily: " + response1Obj.daily.length );
engine.log( " AutomatedTask ApiResponse1 timezone: " + response1Obj.timezone );
engine.log( " AutomatedTask ApiResponse1 offset: " + (response1Obj.timezone_offset /3600) );
engine.log( " AutomatedTask Workflow Platform offset: " + (engine.getTimeZoneOffsetInMinutes() /60) );

/// Find ID of the specified date
// LastTime in Date (Workflow Platform Time) -> LastTime in Date (Weather Location Time)
dateSpecified.setSeconds( dateSpecified.getSeconds() +
  engine.getTimeZoneOffsetInMinutes() * 60 -
  response1Obj.timezone_offset
  ); 
let numDailyId = 0;
engine.log( "  Last in Date: " + dateSpecified.getTime() +
                " (" + dateSpecified.toISOString() + ")"
          );
for( let i = 0; i < response1Obj.daily.length; i++ ){ // must be sorted
  let dateTmp = new Date( response1Obj.daily[i].dt *1000 );
  if( response1Obj.daily[i].dt *1000 > dateSpecified.getTime() ){
    engine.log( "   daily[" + i + "].dt: " + response1Obj.daily[i].dt +
                " (" + dateTmp.toISOString() + ") is larger"
              );
    break;
  }else{
    engine.log( "   daily[" + i + "].dt: " + response1Obj.daily[i].dt +
                " (" + dateTmp.toISOString() + ")"
              );
    numDailyId = i;
  }
}

/// Extract weather info with Date-ID
let numMsecSunrise = response1Obj.daily[numDailyId].sunrise *1000;
let dateSunrise    = new Date( numMsecSunrise );
let strSunrise     = dateSunrise.toLocaleTimeString();
let numMsecSunset  = response1Obj.daily[numDailyId].sunset *1000;
let dateSunset     = new Date( numMsecSunset );
let strSunset      = dateSunset.toLocaleTimeString();
let numMinTemp     = response1Obj.daily[numDailyId].temp.min;
let numMaxTemp     = response1Obj.daily[numDailyId].temp.max;
let numFeelTemp    = response1Obj.daily[numDailyId].feels_like.day;
let numDewPoint    = response1Obj.daily[numDailyId].dew_point;
let numPop         = response1Obj.daily[numDailyId].pop *100; // "0.51" to "51"%
let numHumidity    = response1Obj.daily[numDailyId].humidity;
let numClouds      = response1Obj.daily[numDailyId].clouds;
let strGroup       = response1Obj.daily[numDailyId].weather[0].main;
let strCondition   = response1Obj.daily[numDailyId].weather[0].description;
let numWindSpeed   = response1Obj.daily[numDailyId].wind_speed;
let numWindDeg     = response1Obj.daily[numDailyId].wind_deg;
let numRain        = 0;
if( response1Obj.daily[numDailyId].hasOwnProperty('rain') ){
    numRain        = response1Obj.daily[numDailyId].rain;
}
let numPressure    = response1Obj.daily[numDailyId].pressure;
let numUvi         = response1Obj.daily[numDailyId].uvi;


//// == Data Updating / ワークフローデータへの代入 ==
if( timePocketSunrise  !== null ){
  if( timePocketSunrise.matchDataType( "STRING" ) ){
    engine.log( " AutomatedTask: Pocket for Sunrise is STRING type" );
    engine.setData( timePocketSunrise, strSunrise );
  }else{
    engine.log( " AutomatedTask: Pocket for Sunrise is DATETIME type" );
    engine.setData( timePocketSunrise, new java.sql.Timestamp( numMsecSunrise ) );
  }
}
if( timePocketSunset   !== null ){
  if( timePocketSunset.matchDataType( "STRING" ) ){
    engine.log( " AutomatedTask: Pocket for Sunset is STRING type" );
    engine.setData( timePocketSunset, strSunset );
  }else{
    engine.log( " AutomatedTask: Pocket for Sunset is DATETIME type" );
    engine.setData( timePocketSunset, new java.sql.Timestamp( numMsecSunset ) );
  }
}
if( numPocketMinTemp   !== null ){
  engine.setData( numPocketMinTemp,   new java.math.BigDecimal( numMinTemp ) );
}
if( numPocketMaxTemp   !== null ){
  engine.setData( numPocketMaxTemp,   new java.math.BigDecimal( numMaxTemp ) );
}
if( numPocketFeelTemp  !== null ){
  engine.setData( numPocketFeelTemp,  new java.math.BigDecimal( numFeelTemp ) );
}
if( numPocketDewPoint  !== null ){
  engine.setData( numPocketDewPoint,  new java.math.BigDecimal( numDewPoint ) );
}
if( numPocketPop       !== null ){
  engine.setData( numPocketPop,       new java.math.BigDecimal( numPop ) );
}
if( numPocketHumidity  !== null ){
  engine.setData( numPocketHumidity,  new java.math.BigDecimal( numHumidity ) );
}
if( numPocketClouds    !== null ){
  engine.setData( numPocketClouds,    new java.math.BigDecimal( numClouds ) );
}
if( strPocketGroup     !== null ){
  engine.setData( strPocketGroup,     strGroup );
}
if( strPocketCondition !== null ){
  engine.setData( strPocketCondition, strCondition );
}
if( numPocketWindSpeed !== null ){
  engine.setData( numPocketWindSpeed, new java.math.BigDecimal( numWindSpeed ) );
}
if( numPocketWindDeg   !== null ){
  engine.setData( numPocketWindDeg,   new java.math.BigDecimal( numWindDeg ) );
}
if( numPocketRain      !== null ){
  engine.setData( numPocketRain,      new java.math.BigDecimal( numRain ) );
}
if( numPocketPressure  !== null ){
  engine.setData( numPocketPressure,  new java.math.BigDecimal( numPressure ) );
}
if( numPocketUvi       !== null ){
  engine.setData( numPocketUvi,       new java.math.BigDecimal( numUvi ) );
}

} //////// END "main()" /////////////////////////////////////////////////////////////////



function toJsDate( bpmsDateOrDatetimeStr ){
  // BPMS Date:     "2020-04-01"  (subtype "Y/M" "M/D" "Y", not supported)
  // BPMS Datetime: "2020-04-01 23:59"
  let year       = 0;
  let monthIndex = 0;
  let day        = 0;
  let hours      = 0;
  let minutes    = 0;

  //  The ECMA/JavaScript Date object has a large number of methods.
  // "Date.parse" is danger (strongly discouraged)
  // - new Date("2014-11-10") // Mon Nov 10 2014 09:00:00 GMT+0900 (JST)
  // - new Date(2014, 10, 10) // Mon Nov 10 2014 00:00:00 GMT+0900 (JST)
  let arrDatetime = bpmsDateOrDatetimeStr.split(" ");
  if( arrDatetime.length === 1 ){
    let arrDateParts = arrDatetime[0].split("-");
    year       = parseInt(arrDateParts[0], 10);
    monthIndex = parseInt(arrDateParts[1], 10) - 1;
    day        = parseInt(arrDateParts[2], 10);
  }
  if( arrDatetime.length === 2 ){
    let arrDateParts = arrDatetime[0].split("-");
    let arrTimeParts = arrDatetime[1].split(":");
    year       = parseInt(arrDateParts[0], 10);
    monthIndex = parseInt(arrDateParts[1], 10) - 1;
    day        = parseInt(arrDateParts[2], 10);
    hours      = parseInt(arrTimeParts[0], 10);
    minutes    = parseInt(arrTimeParts[1], 10);
  }
  return new Date( year, monthIndex, day, hours, minutes );
}



/*
Notes:
- For agriculture, transportation, retail, hotel, restaurant service, etc.
- Weather data in OpenWeatherMap is calculated mechanically based on public info or airport observations.
    - There is a difference from the weather data provided by the weather company.
- The acquired forecast data and historical data can be freely used under the Open Database License.
    - https://openweathermap.org/full-price#licenses
- Dates up to 7 days in advance are valid.
    - If a date outside the range is specified, it will be updated with the data 7 days ahead.
    - Specify with a string starting with "YYYY-MM-DD". (DateTime type is also acceptable)

Notes-ja:
- 農業・運送業の稼働判断や小売・宿泊・飲食における仕入業務の自動化省力化等に活用されます。
- OpenWeatherMap の気象データは、公的情報や空港観測値などを元に機械的に算出されています。
    - 気象会社による気象データとは、違いがあります。
- 取得した予報データや履歴データは、Open Database License 下で自由に利用できます。
    - https://openweathermap.org/full-price#licenses
- 7日先までの日付が指定可能です。
    - 範囲外の日付が指定された場合、7日先のデータで更新されます。
    - "YYYY-MM-DD" で始まる文字列で指定します。(時刻型データでも構いません)
*/


/*
APPENDIX
- Create an API key on the "API keys" page of your personal account beforehand.
    - https://home.openweathermap.org/api_keys
- In this Addon, the weather data is acquired via "One Call API".
    - Available in OpenWeather Free subscription.
- Sunrise and sunset times are displayed with Workflow platform timezone.
    - The UTC offset of weather location time can be confirmed in the log.
    - Storing in string type data, the time format depends on toLocaleTimeString().
    - eg. "06:40:06", "6:40:06 AM", etc
    - https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleTimeString
- Units of measurement in response
    - (default): temperature in Kelvin and wind speed in meter/sec
    - "metric": temperature in Celsius and wind speed in meter/sec
    - "imperial": temperature in Fahrenheit and wind speed in miles/hour
- Translation samples of weather description field, corresponding language codes
    - eg. "broken clouds: muy nuboso", "overcast clouds: nubes", "light snow: nevada ligera"
    - https://openweathermap.org/api/one-call-api#multi
    - https://openweathermap.org/weather-conditions
- Wind Direction degrees
    - 0 to 11, 349 to 359: N
    - 12 to 33: NNE
    - 34 to 56: NE
    - 57 to 78: ENE
    - 79 to 101: E
    - 102 to 123: ESE
    - 124 to 146: SE
    - 147 to 168: SSE
    - 169 to 191: S
    - 192 to 213: SSW
    - 214 to 236: SW
    - 237 to 258: WSW
    - 259 to 281: W
    - 282 to 303: WNW
    - 304 to 326: NW
    - 327 to 348: NNW
- Latitude Longitude sample
    - Metropolitan Government Building, Tokyo: 35.689472, 139.69175
    - Kiyomizu-dera Temple, Kyoto: 34.994831, 135.785003
    - Waikiki Beach, Hawaii: 21.275278, -157.825
    - Oymyakon, Russia: 63.25, 143.15 (the coldest permanently inhabited settlement on Earth)
    - Use Google Maps, Wikipedia, etc. to obtain the latitude and longitude of any point.
        - https://www.google.co.jp/maps/

APPENDIX-ja
- 個人アカウントの "API keys" ページにて、あらかじめ API Key を生成しておく必要があります。
    - https://home.openweathermap.org/api_keys
- このAddonで、気象データは "One Call API" 経由で取得されます。
    - OpenWeather Free subscription(無料)で利用可能です。
- 日の出、日の入り時刻は、ワークフロー基盤のタイムゾーンで表示されます。
    - 現地時間のUTCオフセット(協定世界時との差)は、ログにて確認可能です。
    - 文字列型データに格納する場合、時刻書式は toLocaleTimeString() に依存します。
    - 例 "06:40:06", "6:40:06 AM", etc (秒まで出力されます)
    - https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleTimeString
- レスポンス数値の物理単位系
    - (デフォルト): 気温は「ケルビン(絶対温度)」にて、風速は「メートル毎秒」にて表示されます
    - "metric": 気温は「摂氏」、風速は「メートル毎秒」にて表示されます
    - "imperial": 気温は「華氏」、風速は「マイル毎時」にて表示されます
- 天気概況フィールドの翻訳サンプル、および対応言語コード
    - 例 "broken clouds: 曇りがち"、"overcast clouds: 厚い雲"、"light snow: 小雪"
    - https://openweathermap.org/api/one-call-api#multi
    - https://openweathermap.org/weather-conditions
- 風向と角度
    - 0 to 11, 349 to 359: 北の風、北風
    - 12 to 33: 北北東の風
    - 34 to 56: 北東の風
    - 57 to 78: 東北東の風
    - 79 to 101: 東の風
    - 102 to 123: 東南東の風
    - 124 to 146: 南東の風
    - 147 to 168: 南南東の風
    - 169 to 191: 南の風
    - 192 to 213: 南南西の風
    - 214 to 236: 南西の風
    - 237 to 258: 西南西の風
    - 259 to 281: 西の風
    - 282 to 303: 西北西の風
    - 304 to 326: 北西の風
    - 327 to 348: 北北西の風
- 緯度経度サンプル
    - 東京都庁: 35.689472, 139.69175
    - 京都 清水寺: 34.994831, 135.785003
    - ハワイ ワイキキビーチ: 21.275278, -157.825
    - ロシア オイミャコン: 63.25, 143.15 (世界で最も寒い定住地)
    - 任意地点の緯度経度は Google マップや Wikipedia 等で取得してください
        - https://www.google.co.jp/maps/
*/


Download

2021-02-16 (C) Questetra, Inc. (MIT License)
https://support.questetra.com/ja/addons/openweather-weather-forecast-get-by-date/
Addonファイルのインポートは Professional もしくは Enterprise でのみご利用いただけます

Notes

  • 農業・運送業の稼働判断や小売・宿泊・飲食における仕入業務の自動化省力化等に活用されます。
  • OpenWeatherMap の気象データは、公的情報や空港観測値などを元に機械的に算出されています。
    • 気象会社による気象データとは、違いがあります。
  • 取得した予報データや履歴データは、Open Database License 下で自由に利用できます。
  • 7日先までの日付が指定可能です。
    • 範囲外の日付が指定された場合、7日先のデータで更新されます。
    • “YYYY-MM-DD” で始まる文字列で指定します。(時刻型データでも構いません)

Capture

任意日付の気象予報を OpenWeather から取得します。世界中の緯度と経度を指定できます。気温、湿度、風速だけでなく、日没時刻や露点温度なども取得可能です。

Appendix

  • 個人アカウントの “API keys” ページにて、あらかじめ API Key を生成しておく必要があります。
  • このAddonで、気象データは “One Call API” 経由で取得されます。
    • OpenWeather Free subscription(無料)で利用可能です。
  • 日の出、日の入り時刻は、ワークフロー基盤のタイムゾーンで表示されます。
  • レスポンス数値の物理単位系
    • (デフォルト): 気温は「ケルビン(絶対温度)」にて、風速は「メートル毎秒」にて表示されます
    • “metric”: 気温は「摂氏」、風速は「メートル毎秒」にて表示されます
    • “imperial”: 気温は「華氏」、風速は「マイル毎時」にて表示されます
  • 天気概況フィールドの翻訳サンプル、および対応言語コード
  • 風向と角度
    • 0 to 11, 349 to 359: 北の風、北風
    • 12 to 33: 北北東の風
    • 34 to 56: 北東の風
    • 57 to 78: 東北東の風
    • 79 to 101: 東の風
    • 102 to 123: 東南東の風
    • 124 to 146: 南東の風
    • 147 to 168: 南南東の風
    • 169 to 191: 南の風
    • 192 to 213: 南南西の風
    • 214 to 236: 南西の風
    • 237 to 258: 西南西の風
    • 259 to 281: 西の風
    • 282 to 303: 西北西の風
    • 304 to 326: 北西の風
    • 327 to 348: 北北西の風
  • 緯度経度サンプル
    • 東京都庁: 35.689472, 139.69175
    • 京都 清水寺: 34.994831, 135.785003
    • ハワイ ワイキキビーチ: 21.275278, -157.825
    • ロシア オイミャコン: 63.25, 143.15 (世界で最も寒い定住地)
    • 任意地点の緯度経度は Google マップや Wikipedia 等で取得してください

See also

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

%d人のブロガーが「いいね」をつけました。