// JK BMS Web Gateway — minimal REST API console client. // // Fetches GET /api/realtime from the gateway and prints pack voltage, // current, and state of charge. Demonstrates the smallest useful client: // one HTTP GET, one JSON parse. See the full endpoint list and JSON field // reference on the site's #api section. // // Build (Linux/macOS, needs libcurl + nlohmann/json): // g++ -std=c++17 jkbms_client_example.cpp -lcurl -o jkbms_client_example // Run: // ./jkbms_client_example http://jkbms.local #include #include #include #include #include using nlohmann::json; // libcurl calls this once per received chunk of the HTTP response body; // appending to a std::string is the standard way to buffer a small response. static size_t appendToBuffer(char *data, size_t size, size_t count, void *userData) { auto *buffer = static_cast(userData); buffer->append(data, size * count); return size * count; } // Performs one blocking HTTP GET and returns the response body. // Throws std::runtime_error if the transfer itself fails (not on HTTP // error status — the caller is expected to check the JSON's own "error" field). static std::string httpGet(const std::string &url) { CURL *curl = curl_easy_init(); if (!curl) { throw std::runtime_error("curl_easy_init failed"); } std::string body; curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, appendToBuffer); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &body); curl_easy_setopt(curl, CURLOPT_TIMEOUT, 5L); CURLcode result = curl_easy_perform(curl); curl_easy_cleanup(curl); if (result != CURLE_OK) { throw std::runtime_error(curl_easy_strerror(result)); } return body; } int main(int argc, char *argv[]) { // Default to the gateway's mDNS name; override with a bare IP if mDNS // isn't reachable on your network (e.g. "http://192.168.1.50"). std::string baseUrl = (argc > 1) ? argv[1] : "http://jkbms.local"; std::string body; try { body = httpGet(baseUrl + "/api/realtime"); } catch (const std::exception &ex) { std::fprintf(stderr, "request failed: %s\n", ex.what()); return 1; } json realtime = json::parse(body, /*cb*/ nullptr, /*allow_exceptions*/ false); if (realtime.is_discarded()) { std::fprintf(stderr, "invalid JSON response: %s\n", body.c_str()); return 1; } if (realtime.contains("error")) { std::fprintf(stderr, "gateway error: %s\n", realtime["error"].get().c_str()); return 1; } std::printf("Pack voltage: %.2f V\n", realtime.value("totalVoltage", 0.0)); std::printf("Current: %.2f A\n", realtime.value("current", 0.0)); std::printf("SOC: %d %%\n", realtime.value("soc", 0)); return 0; }