Skip to content

Commit 46c3c5d

Browse files
committed
use measurements endpoint for bulk upload
1 parent c651e22 commit 46c3c5d

File tree

4 files changed

+56
-18
lines changed

4 files changed

+56
-18
lines changed

noisemeter-device/api.cpp

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,17 @@ API::Request::Request(const char endpoint[])
3434

3535
API::Request& API::Request::addParam(const char param[], String value)
3636
{
37-
params.concat('&');
37+
if (!params.isEmpty())
38+
params.concat('&');
39+
3840
params.concat(param);
3941
params.concat('=');
4042
params.concat(urlEncode(value));
4143
return *this;
4244
}
4345

44-
std::optional<JsonDocument> API::sendAuthorizedRequest(const API::Request& req)
46+
std::optional<JsonDocument> API::sendAuthorizedRequest(
47+
const API::Request& req, String ctype)
4548
{
4649
WiFiClientSecure client;
4750
client.setCACert(rootCertificate());
@@ -53,10 +56,10 @@ std::optional<JsonDocument> API::sendAuthorizedRequest(const API::Request& req)
5356

5457
HTTPClient https;
5558
if (https.begin(client, req.url)) {
56-
https.addHeader("Content-Type", "application/x-www-form-urlencoded");
59+
https.addHeader("Content-Type", ctype);
5760
https.addHeader("Authorization", String("Token ") + token);
5861
https.addHeader("X-Tracket-Device", id);
59-
return sendHttpPOST(https, req.params.substring(1));
62+
return sendHttpPOST(https, req.params);
6063
#ifdef API_VERBOSE
6164
} else {
6265
SERIAL.println("[api] Failed to https.begin()");
@@ -80,7 +83,7 @@ std::optional<JsonDocument> API::sendNonauthorizedRequest(const API::Request& re
8083
if (https.begin(client, req.url)) {
8184
https.addHeader("Content-Type", "application/x-www-form-urlencoded");
8285
https.addHeader("X-Tracket-Device", id);
83-
return sendHttpPOST(https, req.params.substring(1));
86+
return sendHttpPOST(https, req.params);
8487
#ifdef API_VERBOSE
8588
} else {
8689
SERIAL.println("[api] Failed to https.begin()");
@@ -165,6 +168,34 @@ std::optional<JsonDocument> API::responseToJson(const String& response)
165168
API::API(UUID id_, String token_):
166169
id(id_), token(token_) {}
167170

171+
bool API::sendMeasurements(const std::list<DataPacket>& pkts)
172+
{
173+
String send;
174+
JsonDocument doc;
175+
auto data = doc["data"].to<JsonArray>();
176+
177+
for (const auto& packet : pkts) {
178+
auto entry = data.add<JsonObject>();
179+
entry["timestamp"] = String(packet.timestamp);
180+
entry["min"] = std::lround(packet.minimum);
181+
entry["max"] = std::lround(packet.maximum);
182+
entry["mean"] = std::lround(packet.average);
183+
}
184+
185+
const auto size = serializeJson(data, send);
186+
187+
if (size == 0) {
188+
SERIAL.println("sendMeasurements: serializeJson: failed!");
189+
return false;
190+
} else {
191+
auto request = Request("measurements");
192+
request.params = send;
193+
194+
const auto resp = sendAuthorizedRequest(request, "application/json");
195+
return resp && (*resp)["result"] == "ok";
196+
}
197+
}
198+
168199
bool API::sendMeasurement(const DataPacket& packet)
169200
{
170201
const auto request = Request("measurement")
@@ -210,7 +241,7 @@ std::optional<API::LatestSoftware> API::getLatestSoftware()
210241
WiFiClientSecure client;
211242
client.setCACert(rootCertificate());
212243

213-
String endpoint = request.url + '?' + request.params.substring(1);
244+
String endpoint = request.url + '?' + request.params;
214245

215246
#ifdef API_VERBOSE
216247
SERIAL.print("[api] Non-authorized request: ");

noisemeter-device/api.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <ArduinoJson.h>
2626
#include <WString.h>
2727

28+
#include <list>
2829
#include <optional>
2930

3031
class HTTPClient;
@@ -47,7 +48,6 @@ class API
4748

4849
/**
4950
* Adds a parameter to the given request.
50-
* Resulting URL e.g. "https://host/endpoint?parm1=123&parm2=456&"
5151
* @param param Name of parameter to add.
5252
* @param value Value of the added parameter.
5353
* @return *this
@@ -83,6 +83,8 @@ class API
8383
*/
8484
bool sendMeasurement(const DataPacket& packet);
8585

86+
bool sendMeasurements(const std::list<DataPacket>& pkts);
87+
8688
/**
8789
* Sends diagnostic/analytic data to the server along with a DataPacket.
8890
* This request requires authentication.
@@ -120,7 +122,8 @@ class API
120122
/** Converts response string into JSON. */
121123
std::optional<JsonDocument> responseToJson(const String& response);
122124
/** Attempts the given request and returns the JSON response on success. */
123-
std::optional<JsonDocument> sendAuthorizedRequest(const Request& req);
125+
std::optional<JsonDocument> sendAuthorizedRequest(
126+
const Request& req, String ctype = "application/x-www-form-urlencoded");
124127
/** Attempts the given request and returns the JSON response on success. */
125128
std::optional<JsonDocument> sendNonauthorizedRequest(const Request& req);
126129

noisemeter-device/board.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ extern HWCDC USBSerial;
6969

7070
#define SERIAL Serial
7171

72+
#elif defined(BOARD_TESTING)
73+
7274
#else
7375
#error "Please select a board from the list in board.h!"
7476
#endif

noisemeter-device/noisemeter-device.ino

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -192,20 +192,22 @@ void loop() {
192192
API api (buildDeviceId(), Creds.get(Storage::Entry::Token));
193193

194194
if (firstSend) {
195-
if (api.sendMeasurementWithDiagnostics(packets.back(), NOISEMETER_VERSION, lastUpload)) {
196-
packets.pop_back();
195+
const bool success = api.sendMeasurementWithDiagnostics(
196+
packets.front(), NOISEMETER_VERSION, lastUpload);
197+
198+
if (success) {
199+
packets.pop_front();
197200
firstSend = false;
198201
}
199-
} else {
200-
std::optional<Blinker> bl;
202+
}
201203

202-
// Only blink if there's multiple packets to send
203-
if (++packets.cbegin() != packets.cend())
204-
bl.emplace(200);
204+
if (!packets.empty()) {
205+
const bool success = (++packets.cbegin() != packets.cend())
206+
? api.sendMeasurements(packets)
207+
: api.sendMeasurement(packets.front());
205208

206-
packets.remove_if([&api](const auto& pkt) {
207-
return pkt.count <= 0 || api.sendMeasurement(pkt);
208-
});
209+
if (success)
210+
packets.clear();
209211
}
210212

211213
#if defined(BOARD_ESP32_PCB)

0 commit comments

Comments
 (0)