0

I am trying to access strava's API on arduino esp8266. My http.GET() using the ESP8266HTTPClient.h header is returning -1 which means that it fails to connect at some point (HTTPC_ERROR_CONNECTION_REFUSED). I am able to access other sites but am just having trouble linking up to Strava. Here is Strava's api site

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>

const char* ssid = "**SSIDNAME**";
const char* password = "**PASSWORD**";

void setup() 
{
  Serial.begin(115200);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(1000);
    Serial.println("Connecting...");
  }
}

void loop() 
{
  if (WiFi.status() == WL_CONNECTED) 
  {
    Serial.println("Connected!");
    HTTPClient http; //Object of class HTTPClient
    http.begin("https://www.strava.com/athletes/**ATHLETENUMBER**", "**MY CLIENT SECRET**");
    int httpCode = http.GET();

    if (httpCode > 0) 
    {
      const size_t bufferSize = JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(5) + JSON_OBJECT_SIZE(8) + 370;
      DynamicJsonBuffer jsonBuffer(bufferSize);
      JsonObject& root = jsonBuffer.parseObject(http.getString());

      const char* miles = root["all_run_totals"]; 

      Serial.print("Total miles:");
      Serial.println(miles);
    }
    http.end(); //Close connection
  }
  delay(60000);
}
4

1 回答 1

0

此 API 只能通过 TLS/SSL 访问。上面的代码适用于托管在不安全 http 站点上的 API,但 Strava 和大多数其他 API 现在强制使用 https。要访问 https,您需要在草图中提供所需的指纹。这个指纹不时变化(根CA证书变化的频率较低,可能每10年一次,也可以使用)。以下代码不会提供任何指纹,而是不安全地访问该安全 API。在不验证指纹的情况下访问 API 的问题是有人可以伪造服务器,但我希望在大多数用例中这不是问题。此代码将每 15 分钟从 Strava 的 API 获取一次,解析对 JSON 的响应,并打印出运动员的总跑步里程。(替换 **********'ed 项目)。

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecureBearSSL.h>
#include <ArduinoJson.h>

ESP8266WiFiMulti WiFiMulti;

void setup() {
  Serial.begin(115200);
  delay(4000); //4 seconds
  WiFi.mode(WIFI_STA);
  WiFiMulti.addAP("*****ssid name******", "*******ssid password*******");
}

void loop() {  
  Serial.print(milesRun());
  Serial.println(" miles");
  delay(900000); //wait 15 minutes
}

int milesRun() { //connect to wifi, get miles run from strava api, disconnect from wifi
  if ((WiFiMulti.run() == WL_CONNECTED)) {    
    std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
    client->setInsecure();
    HTTPClient https;
    if (https.begin(*client, "https://www.strava.com/api/v3/athletes/*****athlete#*****/stats?access_token=*****access token here *****")) {  // HTTPS
      int httpCode = https.GET();
      if (httpCode > 0) {
        if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
          String payload = https.getString();
          const size_t capacity = 6*JSON_OBJECT_SIZE(5) + 3*JSON_OBJECT_SIZE(6) + JSON_OBJECT_SIZE(11) + 1220;
          DynamicJsonBuffer jsonBuffer(capacity);
          JsonObject& root = jsonBuffer.parseObject(https.getString());
          if (!root.success()) {
            return 0; //json parsing failed
          }
          JsonObject& all_run_totals = root["all_run_totals"];
          int meters = all_run_totals["distance"];
          return meters * 0.000621371; //to miles
        }
      } else {
        return 0; //error check httpCode
      }
      https.end();
    } else {
      return 0; //error unable to connect
    }
  }
}
于 2019-08-09T17:32:35.087 回答