Add Frame admin panel with full remote config
- New frame_config API endpoint (GET/POST) stores all frame display settings in frame-config.json on the BirdNET server - Frame menu item in the admin drawer opens a full settings panel with sections: Display, Titles, Collage, Hardware, Source, Auth - Changes auto-save via debounced POST; the frame Pi picks them up on its next 15-min timer cycle - TODAY window button in the time picker with configurable start hour (localStorage bird:todayStart, adjustable in Settings) Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
This commit is contained in:
@@ -184,6 +184,64 @@ switch ($action) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 'frame_config': {
|
||||
$cfg_path = __DIR__ . '/frame-config.json';
|
||||
$defaults = [
|
||||
'mode' => 'today',
|
||||
'hours' => 24,
|
||||
'start_time' => '06:00',
|
||||
'hold_overnight' => true,
|
||||
'species_source' => '',
|
||||
'zip' => '',
|
||||
'bw_days' => 7,
|
||||
'bw_country' => 'us',
|
||||
'image_url' => '',
|
||||
'shoot' => true,
|
||||
'shoot_title' => 'avian visitors',
|
||||
'shoot_subtitle' => 'Heard Today',
|
||||
'shoot_headline_px' => 42,
|
||||
'shoot_eyebrow_px' => 18,
|
||||
'shoot_lowercase' => false,
|
||||
'shoot_mat' => 0.04,
|
||||
'shoot_small_floor' => 0.04,
|
||||
'shoot_count_exp' => 0.65,
|
||||
'mat' => 0.0,
|
||||
'mat_opening_w' => 0,
|
||||
'mat_opening_h' => 0,
|
||||
'rotate' => 90,
|
||||
'saturation' => 0.6,
|
||||
'panel' => '',
|
||||
'quiet_start' => 22,
|
||||
'quiet_end' => 6,
|
||||
'heal_hours' => 24,
|
||||
'timeout' => 45,
|
||||
'basic_user' => '',
|
||||
'basic_pass' => '',
|
||||
];
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$input = json_decode(file_get_contents('php://input'), true);
|
||||
if (!is_array($input)) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['error' => 'invalid JSON']);
|
||||
break;
|
||||
}
|
||||
$current = file_exists($cfg_path) ? json_decode(file_get_contents($cfg_path), true) : $defaults;
|
||||
if (!is_array($current)) $current = $defaults;
|
||||
$allowed = array_keys($defaults);
|
||||
foreach ($input as $k => $v) {
|
||||
if (in_array($k, $allowed, true)) $current[$k] = $v;
|
||||
}
|
||||
file_put_contents($cfg_path, json_encode($current, JSON_PRETTY_PRINT) . "\n");
|
||||
echo json_encode($current);
|
||||
} else {
|
||||
$current = file_exists($cfg_path) ? json_decode(file_get_contents($cfg_path), true) : $defaults;
|
||||
if (!is_array($current)) $current = $defaults;
|
||||
echo json_encode(array_merge($defaults, $current));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
http_response_code(404);
|
||||
echo json_encode(['error' => 'unknown action']);
|
||||
|
||||
Reference in New Issue
Block a user