feat: add deep sleep batch caching, wake log, and log viewer tools
- Batch-fetch asset IDs in deep sleep mode with NVS caching to reduce network calls and improve battery life (configurable batch size 1-50) - Add wake_log module: persistent CSV log of each photo cycle surviving reboots and deep sleep, with download/clear via web UI - Add browser-based log viewer and log comparison tools (tools/) - Update .gitignore to exclude .cursor/, chat-summaries/, wake_*.csv, and .DS_Store Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -273,6 +273,69 @@ String ImmichClient::fetchOneRandomAssetId(const RandomFetchFilter& filter) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::vector<String> ImmichClient::fetchFilteredBatch(const RandomFetchFilter& filter, int count) {
|
||||
std::vector<String> results;
|
||||
String url = buildUrl("/api/search/random");
|
||||
|
||||
JsonDocument reqDoc;
|
||||
reqDoc["size"] = count;
|
||||
reqDoc["type"] = "IMAGE";
|
||||
|
||||
if (!filter.albumIds.empty()) {
|
||||
JsonArray arr = reqDoc["albumIds"].to<JsonArray>();
|
||||
for (auto& id : filter.albumIds) arr.add(id);
|
||||
}
|
||||
if (filter.favoriteOnly) {
|
||||
reqDoc["isFavorite"] = true;
|
||||
}
|
||||
if (filter.takenAfter.length() > 0) {
|
||||
reqDoc["takenAfter"] = filter.takenAfter;
|
||||
}
|
||||
if (filter.takenBefore.length() > 0) {
|
||||
reqDoc["takenBefore"] = filter.takenBefore;
|
||||
}
|
||||
|
||||
String body;
|
||||
serializeJson(reqDoc, body);
|
||||
|
||||
Serial.printf("[immich] fetchBatch(%d): %s\n", count, body.c_str());
|
||||
|
||||
String response = httpPost(url, body);
|
||||
if (response.isEmpty()) {
|
||||
Serial.println("[immich] fetchBatch: empty response");
|
||||
return results;
|
||||
}
|
||||
|
||||
JsonDocument doc;
|
||||
DeserializationError err = deserializeJson(doc, response);
|
||||
if (err) {
|
||||
Serial.printf("[immich] fetchBatch JSON error: %s\n", err.c_str());
|
||||
return results;
|
||||
}
|
||||
|
||||
JsonArray arr = doc.as<JsonArray>();
|
||||
for (JsonObject asset : arr) {
|
||||
String id = asset["id"].as<String>();
|
||||
if (id.length() == 0) continue;
|
||||
|
||||
// Skip RAW files
|
||||
String filename = asset["originalFileName"] | "";
|
||||
filename.toLowerCase();
|
||||
if (filename.endsWith(".dng") || filename.endsWith(".raw") ||
|
||||
filename.endsWith(".cr2") || filename.endsWith(".cr3") ||
|
||||
filename.endsWith(".nef") || filename.endsWith(".arw") ||
|
||||
filename.endsWith(".orf") || filename.endsWith(".rw2") ||
|
||||
filename.endsWith(".raf") || filename.endsWith(".srw")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
results.push_back(id);
|
||||
}
|
||||
|
||||
Serial.printf("[immich] fetchBatch: got %d usable assets\n", (int)results.size());
|
||||
return results;
|
||||
}
|
||||
|
||||
AssetInfo ImmichClient::fetchAssetInfo(const String& assetId) {
|
||||
AssetInfo info;
|
||||
info.id = assetId;
|
||||
|
||||
Reference in New Issue
Block a user