Google Fit: データセット; 歩数集計

Google Fit: データセット; 歩数集計 (Google Fit: Dataset; Aggregate Step Count)

Google Fit 内の歩数データおよび移動距離データ(メートル)を集計します。様々なソースからのデータセット(手入力を含む)が集約されます。注:複数機器で同時計測した結果も合算されてしまいます。

2019-10-09 (C) Questetra, Inc. (MIT License)
https://support.questetra.com/ja/addons/google-fit-dataset-aggregate-step-count/

Configs
  • A: 通信許可の設定名([OAuth2.0設定]メニュー)を選択してください *
  • B: 抽出範囲の開始時刻が格納されている日時型データを選択してください *
  • C: 抽出範囲の終了時刻が格納されている日時型データを選択してください *
  • D: 歩数データが格納される数値型データを選択してください (更新) *
  • E: 移動距離データが格納される数値型データを選択してください (更新)
Script
// (c) 2019, Questetra, Inc. (the MIT License)

//// == OAuth2 Setting example ==
// Authorization Endpoint URL:
//  "https://accounts.google.com/o/oauth2/auth?access_type=offline&approval_prompt=force"
// Token Endpoint URL:
//  "https://accounts.google.com/o/oauth2/token"
// Scope:
//  "https://www.googleapis.com/auth/fitness.activity.read https://www.googleapis.com/auth/fitness.location.read"
// Client ID:
//  ( from https://console.developers.google.com/ )
// Consumer Secret:
//  ( from https://console.developers.google.com/ )
//  *Redirect URL of Webapp OAuth-Client-ID: "https://s.questetra.net/oauth2callback"
//  *Note: Activate your Google Fitness API


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

//// == Config Retrieving / 工程コンフィグの参照 ==
const oauth2  = configs.get( "conf_OAuth2"  ) + ""; // required
const dataIdB = configs.get( "conf_DataIdB" ) + ""; // required
const dataIdC = configs.get( "conf_DataIdC" ) + ""; // required
const dataIdD = configs.get( "conf_DataIdD" ) + ""; // required
const dataIdE = configs.get( "conf_DataIdE" ) + ""; // not required
// 'java.lang.String' (String Obj) to javascript primitive 'string'


//// == Data Retrieving / ワークフローデータの参照 ==
if( engine.findDataByNumber( dataIdB ) === null ){
  throw new Error( "\n AutomatedTask UnexpectedDatetimeError:" +
                   " Datetime {B} is null \n" );
}
if( engine.findDataByNumber( dataIdC ) === null ){
  throw new Error( "\n AutomatedTask UnexpectedDatetimeError:" +
                   " Datetime {C} is null \n" );
}
const strStart  = engine.findDataByNumber( dataIdB ) + "";
const dateStart = new Date( strStart );
const strEnd    = engine.findDataByNumber( dataIdC ) + "";
const dateEnd   = new Date( strEnd );
engine.log( " AutomatedTask Datetime: Start: " + strStart + " " + engine.getTimeZoneId() );
engine.log( " AutomatedTask Datetime: End:   " + strEnd   + " " + engine.getTimeZoneId() );
// com.questetra.bpms.core.event.scripttask.WorkflowEngine (R2300)


//// == Calculating / 演算 ==
// const numOffsetMin = engine.getTimeZoneOffsetInMinutes() - 0; // "540" "-480" etc
// // com.questetra.bpms.core.event.scripttask.WorkflowEngine (R2300)
// const numStartTimeMillis = dateStart.getTime() - numOffsetMin * 60000; // milli sec
// const numEndTimeMillis   = dateEnd.getTime()   - numOffsetMin * 60000; // milli sec
// Questetra Nashorn "getTime()" always uses UTC for time representation.
const numStartTimeMillis = dateStart.getTime(); // milli sec
const numEndTimeMillis   = dateEnd.getTime(); // milli sec
const numDurationMillis  = numEndTimeMillis - numStartTimeMillis;
engine.log( " AutomatedTask Datetime: (s-milli): " + numStartTimeMillis + " (UTC)" );
engine.log( " AutomatedTask Datetime: (e-milli): " + numEndTimeMillis   + " (UTC)" );
const dateNow = new Date();
const numNowMillis = dateNow.getTime();
engine.log( " AutomatedTask Runtime Now (milli): " + numNowMillis       + " (UTC)" );
if( numEndTimeMillis > numNowMillis ){
  engine.log( " AutomatedTask DatetimeWarning:" +
              " Time range includes future" );
}

/// obtain OAuth2 Access Token
const token   = httpClient.getOAuth2Token( oauth2 );

/// post Request for "com.google.step_count.delta" Google Fit REST API v1
// https://developers.google.com/fit/rest/v1/reference/users/dataset/aggregate
let requestObj = {};
    requestObj.aggregateBy = [];
    requestObj.aggregateBy[0] = {};
    requestObj.aggregateBy[0].dataTypeName = "com.google.step_count.delta";
    requestObj.endTimeMillis   = numEndTimeMillis;
    requestObj.startTimeMillis = numStartTimeMillis;
    requestObj.bucketByTime = {};
    requestObj.bucketByTime.durationMillis = numDurationMillis;
let apiRequest = httpClient.begin(); // HttpRequestWrapper
apiRequest = apiRequest.bearer( token );
apiRequest = apiRequest.body( JSON.stringify( requestObj ), "application/json" );
const apiUri = "https://www.googleapis.com/fitness/v1/users/me/dataset:aggregate";
engine.log( " AutomatedTask Trying: POST " + apiUri );
const response = apiRequest.post( apiUri );
const responseCode = response.getStatusCode() + "";
engine.log( " AutomatedTask ApiResponse: Status " + responseCode );
if( responseCode !== "200"){
  throw new Error( "\n AutomatedTask UnexpectedResponseError: " +
         responseCode + "\n" + response.getResponseAsString() + "\n" );
}
const responseStr = response.getResponseAsString() + "";
const responseObj = JSON.parse( responseStr );
engine.log( responseStr );
let intStepCount = 0;
if( responseObj.bucket[0].dataset[0].point[0] == undefined ){
  engine.log( " AutomatedTask ApiResponse: StepCount VALUE undefined" );
}else{
  intStepCount = responseObj.bucket[0].dataset[0].point[0].value[0].intVal;
  engine.log( " AutomatedTask ApiResponse: StepCount " +  intStepCount );
}

/// post Request2 for "com.google.distance.delta" Google Fit REST API v1
let requestObj2 = {};
    requestObj2.aggregateBy = [];
    requestObj2.aggregateBy[0] = {};
    requestObj2.aggregateBy[0].dataTypeName = "com.google.distance.delta";
    requestObj2.endTimeMillis   = numEndTimeMillis;
    requestObj2.startTimeMillis = numStartTimeMillis;
    requestObj2.bucketByTime = {};
    requestObj2.bucketByTime.durationMillis = numDurationMillis;
let apiRequest2 = httpClient.begin(); // HttpRequestWrapper
apiRequest2 = apiRequest.bearer( token );
apiRequest2 = apiRequest.body( JSON.stringify( requestObj2 ), "application/json" );
const apiUri2 = "https://www.googleapis.com/fitness/v1/users/me/dataset:aggregate";
engine.log( " AutomatedTask Trying: POST " + apiUri );
const response2 = apiRequest.post( apiUri2 );
const responseCode2 = response2.getStatusCode() + "";
engine.log( " AutomatedTask ApiResponse: Status " + responseCode2 );
if( responseCode !== "200"){
  throw new Error( "\n AutomatedTask UnexpectedResponseError: " +
         responseCode2 + "\n" + response2.getResponseAsString() + "\n" );
}
const responseStr2 = response2.getResponseAsString() + "";
const responseObj2 = JSON.parse( responseStr2 );
engine.log( responseStr2 );
let fpDistance = 0;
if( responseObj2.bucket[0].dataset[0].point[0] == undefined ){
  engine.log( " AutomatedTask ApiResponse: Distance VALUE undefined" );
}else{
  fpDistance = responseObj2.bucket[0].dataset[0].point[0].value[0].fpVal;
  engine.log( " AutomatedTask ApiResponse: Distance " +  fpDistance );
}


//// == Data Updating / ワークフローデータへの代入 ==
engine.setDataByNumber( dataIdD, new java.math.BigDecimal( intStepCount ) );
if ( dataIdE !== "" ){ 
  engine.setDataByNumber( dataIdE, new java.math.BigDecimal( fpDistance ) );
}


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

Download

Capture

Google Fit REST API にアクセスする自動処理工程。歩数と距離を取得する。
Google Fit は様々な Fitness Data が蓄積される。

Notes

  1. ウォーキング(アクティビティ)が継続中の場合、集計から除外される場合があります。
  2. 抽出範囲前からのウォーキング(アクティビティ)は、集計される場合があります。

See also

コメントを残す

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

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