fix(#80): display endpoint respects preferred bmp image format

This commit is contained in:
Benjamin Nussbaum 2025-08-18 17:53:05 +02:00
parent 4e3b47e4eb
commit 2ed3fd5ca9
3 changed files with 144 additions and 8 deletions

View file

@ -126,10 +126,25 @@ Route::get('/display', function (Request $request) {
$image_path = 'images/setup-logo.bmp'; $image_path = 'images/setup-logo.bmp';
$filename = 'setup-logo.bmp'; $filename = 'setup-logo.bmp';
} else { } else {
// Determine image format based on device settings
$preferred_format = 'png'; // Default to PNG for newer firmware
if (! $device->device_model_id) {
// No device model, use device's image_format setting
if (str_contains($device->image_format, 'bmp')) {
$preferred_format = 'bmp';
}
// For 'auto' or unknown formats, fall back to firmware version logic
if (isset($device->last_firmware_version) if (isset($device->last_firmware_version)
&& version_compare($device->last_firmware_version, '1.5.2', '<') && version_compare($device->last_firmware_version, '1.5.2', '<')
&& Storage::disk('public')->exists('images/generated/'.$image_uuid.'.bmp')) { && Storage::disk('public')->exists('images/generated/'.$image_uuid.'.bmp')) {
$image_path = 'images/generated/'.$image_uuid.'.bmp'; $preferred_format = 'bmp';
}
}
// Check if a preferred format exists, otherwise fall back
if (Storage::disk('public')->exists('images/generated/'.$image_uuid.'.'.$preferred_format)) {
$image_path = 'images/generated/'.$image_uuid.'.'.$preferred_format;
} elseif (Storage::disk('public')->exists('images/generated/'.$image_uuid.'.png')) { } elseif (Storage::disk('public')->exists('images/generated/'.$image_uuid.'.png')) {
$image_path = 'images/generated/'.$image_uuid.'.png'; $image_path = 'images/generated/'.$image_uuid.'.png';
} else { } else {
@ -422,10 +437,25 @@ Route::get('/current_screen', function (Request $request) {
$image_path = 'images/setup-logo.bmp'; $image_path = 'images/setup-logo.bmp';
$filename = 'setup-logo.bmp'; $filename = 'setup-logo.bmp';
} else { } else {
// Determine image format based on device settings
$preferred_format = 'png'; // Default to PNG for newer firmware
if (! $device->device_model_id) {
// No device model, use device's image_format setting
if (str_contains($device->image_format, 'bmp')) {
$preferred_format = 'bmp';
}
// For 'auto' or unknown formats, fall back to firmware version logic
if (isset($device->last_firmware_version) if (isset($device->last_firmware_version)
&& version_compare($device->last_firmware_version, '1.5.2', '<') && version_compare($device->last_firmware_version, '1.5.2', '<')
&& Storage::disk('public')->exists('images/generated/'.$image_uuid.'.bmp')) { && Storage::disk('public')->exists('images/generated/'.$image_uuid.'.bmp')) {
$image_path = 'images/generated/'.$image_uuid.'.bmp'; $preferred_format = 'bmp';
}
}
// Check if preferred format exists, otherwise fall back
if (Storage::disk('public')->exists('images/generated/'.$image_uuid.'.'.$preferred_format)) {
$image_path = 'images/generated/'.$image_uuid.'.'.$preferred_format;
} elseif (Storage::disk('public')->exists('images/generated/'.$image_uuid.'.png')) { } elseif (Storage::disk('public')->exists('images/generated/'.$image_uuid.'.png')) {
$image_path = 'images/generated/'.$image_uuid.'.png'; $image_path = 'images/generated/'.$image_uuid.'.png';
} else { } else {

View file

@ -1,6 +1,11 @@
<?php <?php
use App\Enums\ImageFormat;
use App\Models\Device; use App\Models\Device;
use App\Models\Playlist;
use App\Models\PlaylistItem;
use App\Models\Plugin;
use App\Models\User;
use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Storage;
uses(Illuminate\Foundation\Testing\RefreshDatabase::class); uses(Illuminate\Foundation\Testing\RefreshDatabase::class);
@ -118,3 +123,72 @@ test('device falls back to bmp when png does not exist', function () {
'filename' => 'test-image.bmp', 'filename' => 'test-image.bmp',
]); ]);
}); });
test('device without device_model_id and image_format bmp3_1bit_srgb returns bmp when plugin is rendered', function () {
// Create a user with auto-assign enabled
$user = User::factory()->create([
'assign_new_devices' => true,
]);
// Create a device without device_model_id and with bmp3_1bit_srgb format
$device = Device::factory()->create([
'user_id' => $user->id,
'mac_address' => '00:11:22:33:44:55',
'api_key' => 'test-api-key',
'device_model_id' => null, // Explicitly set to null
'image_format' => ImageFormat::BMP3_1BIT_SRGB->value,
'last_firmware_version' => '1.5.2',
]);
// Create a plugin
$plugin = Plugin::factory()->create([
'user_id' => $user->id,
'name' => 'Test Plugin',
'render_markup' => '<div>Test Content</div>',
'data_strategy' => 'static',
'markup_language' => 'blade',
'current_image' => 'test-generated-image', // Set current image directly
]);
// Create a playlist for the device
$playlist = Playlist::factory()->create([
'device_id' => $device->id,
'is_active' => true,
'refresh_time' => 900,
]);
// Create a playlist item with the plugin
$playlistItem = PlaylistItem::factory()->create([
'playlist_id' => $playlist->id,
'plugin_id' => $plugin->id,
'is_active' => true,
'order' => 1,
]);
// Mock the image generation to create both bmp and png files
$imageUuid = 'test-generated-image';
Storage::disk('public')->put('images/generated/'.$imageUuid.'.bmp', 'fake bmp content');
Storage::disk('public')->put('images/generated/'.$imageUuid.'.png', 'fake png content');
// Set the device's current screen image to the plugin's image
$device->update(['current_screen_image' => $imageUuid]);
// Test /api/display endpoint
$displayResponse = $this->withHeaders([
'id' => $device->mac_address,
'access-token' => $device->api_key,
'rssi' => -70,
'battery_voltage' => 3.8,
'fw-version' => '1.5.2',
])->get('/api/current_screen');
$displayResponse->assertOk();
$displayResponse->assertJson([
'filename' => $imageUuid.'.bmp',
]);
// Verify that the device's image_format is correctly set
$device->refresh();
expect($device->image_format)->toBe(ImageFormat::BMP3_1BIT_SRGB->value)
->and($device->device_model_id)->toBeNull();
});

View file

@ -423,3 +423,35 @@ it('determines correct image format from device model', function (): void {
expect($device3->current_screen_image)->toBe($uuid3); expect($device3->current_screen_image)->toBe($uuid3);
Storage::disk('public')->assertExists("/images/generated/{$uuid3}.png"); Storage::disk('public')->assertExists("/images/generated/{$uuid3}.png");
})->skipOnGitHubActions(); })->skipOnGitHubActions();
it('generates BMP for legacy device with bmp3_1bit_srgb format', function (): void {
// Create a device with BMP format but no DeviceModel (legacy behavior)
$device = Device::factory()->create([
'width' => 800,
'height' => 480,
'rotate' => 0,
'image_format' => ImageFormat::BMP3_1BIT_SRGB->value,
'device_model_id' => null, // Explicitly no DeviceModel
]);
$markup = '<div style="background: white; color: black; padding: 20px;">Test Content</div>';
$uuid = ImageGenerationService::generateImage($markup, $device->id);
// Assert the device was updated with a new image UUID
$device->refresh();
expect($device->current_screen_image)->toBe($uuid);
// Assert BMP file was created
Storage::disk('public')->assertExists("/images/generated/{$uuid}.bmp");
// Verify the BMP file has content and isn't blank
$imagePath = Storage::disk('public')->path("/images/generated/{$uuid}.bmp");
$imageSize = filesize($imagePath);
expect($imageSize)->toBeGreaterThan(100); // Should be at least 100 bytes for a BMP
// Verify it's a valid BMP file
$imageInfo = getimagesize($imagePath);
expect($imageInfo[0])->toBe(800); // Width
expect($imageInfo[1])->toBe(480); // Height
expect($imageInfo[2])->toBe(IMAGETYPE_BMP); // BMP type
})->skipOnGitHubActions();