generated from CubeCraft-Creations/Tracehound
Dev #26
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"camera_ssid": "GOPRO-BP-",
|
"camera_ssid": "goprosilver-1",
|
||||||
"camera_password": "goprohero",
|
"camera_password": "Bzyeatn421",
|
||||||
"camera_ip": "10.5.5.1",
|
"camera_ip": "10.5.5.9",
|
||||||
"poll_interval_sec": 30
|
"poll_interval_sec": 30
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,9 +41,11 @@
|
|||||||
// ────────────────────────────────────────────
|
// ────────────────────────────────────────────
|
||||||
|
|
||||||
struct Config {
|
struct Config {
|
||||||
String camera_ssid = "GOPRO-BP-";
|
// Defaults validated against a GoPro Hero 3 Silver. Per-camera values can
|
||||||
String camera_password = "goprohero";
|
// be overridden at runtime via the set_config command (no reflash).
|
||||||
String camera_ip = "10.5.5.1";
|
String camera_ssid = "goprosilver-1";
|
||||||
|
String camera_password = "Bzyeatn421";
|
||||||
|
String camera_ip = "10.5.5.9"; // Hero 3 HTTP API host (not .1)
|
||||||
int poll_interval_sec = 30;
|
int poll_interval_sec = 30;
|
||||||
} cfg;
|
} cfg;
|
||||||
|
|
||||||
@@ -95,27 +97,38 @@ struct CamStatus {
|
|||||||
|
|
||||||
CamStatus fetchStatus() {
|
CamStatus fetchStatus() {
|
||||||
CamStatus s;
|
CamStatus s;
|
||||||
|
|
||||||
String url = "http://" + cfg.camera_ip +
|
// READ status — must NOT be the shutter endpoint. Hero 3 status blob
|
||||||
"/bacpac/SH?t=" + cfg.camera_password + "&p=%01";
|
// (validated on a Hero 3 Silver, ~31 bytes):
|
||||||
|
// [29] recording flag (0 idle / 1 recording) — confirmed
|
||||||
|
// [19] battery level (raw; drains with charge) — calibrate on the hub
|
||||||
|
// [25..26] video-remaining (provisional)
|
||||||
|
// The body is binary and starts with 0x00, so read the stream directly —
|
||||||
|
// Arduino String truncates at the first null byte.
|
||||||
|
String url = "http://" + cfg.camera_ip + "/camera/se?t=" + cfg.camera_password;
|
||||||
|
|
||||||
HTTPClient http;
|
HTTPClient http;
|
||||||
http.useHTTP10(true);
|
http.useHTTP10(true);
|
||||||
http.begin(goproClient, url);
|
http.begin(goproClient, url);
|
||||||
http.setTimeout(5000);
|
http.setTimeout(5000);
|
||||||
int code = http.GET();
|
int code = http.GET();
|
||||||
|
|
||||||
if (code != 200) { http.end(); return s; }
|
if (code != 200) { http.end(); return s; }
|
||||||
|
|
||||||
String raw = http.getString();
|
uint8_t buf[40] = {0};
|
||||||
|
WiFiClient* stream = http.getStreamPtr();
|
||||||
|
size_t n = 0;
|
||||||
|
unsigned long t0 = millis();
|
||||||
|
while (n < sizeof(buf) && millis() - t0 < 1500) {
|
||||||
|
if (stream && stream->available()) buf[n++] = (uint8_t)stream->read();
|
||||||
|
else delay(5);
|
||||||
|
}
|
||||||
http.end();
|
http.end();
|
||||||
if (raw.length() < 58) return s;
|
if (n < 30) return s;
|
||||||
|
|
||||||
const uint8_t* buf = (const uint8_t*)raw.c_str();
|
s.valid = true;
|
||||||
s.valid = true;
|
s.recording = (buf[29] == 1);
|
||||||
|
s.battery_raw = buf[19];
|
||||||
s.video_remaining_sec = buf[25] | (buf[26] << 8);
|
s.video_remaining_sec = buf[25] | (buf[26] << 8);
|
||||||
s.recording = (buf[29] == 1);
|
|
||||||
s.battery_raw = buf[57];
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user