diff --git a/src/RESTAPI/RESTAPI_board_timepoint_handler.cpp b/src/RESTAPI/RESTAPI_board_timepoint_handler.cpp index 4188bc1..ad1d3f1 100644 --- a/src/RESTAPI/RESTAPI_board_timepoint_handler.cpp +++ b/src/RESTAPI/RESTAPI_board_timepoint_handler.cpp @@ -6,6 +6,54 @@ #include "StorageService.h" namespace OpenWifi { + static auto find_number_of_buckets(std::vector &p) { + uint32_t buckets=0,cur_buckets=0; + std::string current_serialNumber; + for(const auto &i:p) { + if(current_serialNumber.empty()) { + current_serialNumber = i.device_info.serialNumber; + cur_buckets=0; + } + if(current_serialNumber==i.device_info.serialNumber) { + cur_buckets++; + } else { + buckets = std::max(buckets,cur_buckets); + current_serialNumber=i.device_info.serialNumber; + cur_buckets=1; + } + } + return std::max(buckets,cur_buckets); + } + + typedef std::vector< std::vector> split_points; + + static void split_in_buckets(uint32_t buckets,std::vector &p,split_points &sp) { + std::string cur_sn; + uint32_t cur_bucket=0; + for(const auto &i:p) { + if(cur_sn.empty()) { + cur_bucket=1; + cur_sn=i.device_info.serialNumber; + } + if(cur_sn==i.device_info.serialNumber) { + if (cur_bucket>sp.size()) { + std::vector tmp_p; + tmp_p.push_back(i); + sp.push_back(tmp_p); + cur_bucket++; + } else { + sp[cur_bucket-1].push_back(i); + cur_bucket++; + } + } else { + cur_bucket=1; + sp[cur_bucket-1].push_back(i); + cur_bucket++; + cur_sn=i.device_info.serialNumber; + } + } + } + void RESTAPI_board_timepoint_handler::DoGet() { auto id = GetBinding("id",""); @@ -36,15 +84,32 @@ namespace OpenWifi { StorageService()->TimePointsDB().SelectRecords(fromDate, endDate, maxRecords, Points.points); // sort by timestamp & serial number. - std::sort( Points.points.begin(), Points.points.end()); - - // your first point's serial number is your separator. So you need to slice the points array - // into timestamp slots + struct { + bool operator()(const AnalyticsObjects::DeviceTimePoint &lhs, const AnalyticsObjects::DeviceTimePoint &rhs) const { + if(lhs.device_info.serialNumber < rhs.device_info.serialNumber) return true; + if(lhs.device_info.serialNumber > rhs.device_info.serialNumber) return false; + return lhs.timestamp < rhs.timestamp; + } + } custom_sort; + std::sort( Points.points.begin(), Points.points.end(), custom_sort); + auto BucketsNeeded = find_number_of_buckets(Points.points); + split_points sp; + split_in_buckets(BucketsNeeded,Points.points,sp); Poco::JSON::Object Answer; - Points.to_json(Answer); + Poco::JSON::Array Outer; + for(const auto &i:sp) { + Poco::JSON::Array InnerArray; + for(const auto &j:i) { + Poco::JSON::Object O; + j.to_json(O); + InnerArray.add(O); + } + Outer.add(InnerArray); + } + Answer.set("points",Outer); return ReturnObject(Answer); } } \ No newline at end of file