diff --git a/database/migrations/2026_01_11_121809_make_trmnlp_id_unique_in_plugins_table.php b/database/migrations/2026_01_11_121809_make_trmnlp_id_unique_in_plugins_table.php index 9769505..3b9b1b7 100644 --- a/database/migrations/2026_01_11_121809_make_trmnlp_id_unique_in_plugins_table.php +++ b/database/migrations/2026_01_11_121809_make_trmnlp_id_unique_in_plugins_table.php @@ -1,8 +1,8 @@ select('user_id', 'trmnlp_id', DB::raw('COUNT(*) as count')) + $duplicates = Plugin::query() + ->selectRaw('user_id, trmnlp_id, COUNT(*) as duplicate_count') ->whereNotNull('trmnlp_id') ->groupBy('user_id', 'trmnlp_id') - ->having('count', '>', 1) + ->havingRaw('COUNT(*) > ?', [1]) ->get(); // For each duplicate combination, keep the first one (by id) and set others to null foreach ($duplicates as $duplicate) { - $plugins = DB::table('plugins') + $plugins = Plugin::query() ->where('user_id', $duplicate->user_id) ->where('trmnlp_id', $duplicate->trmnlp_id) ->orderBy('id') @@ -37,9 +37,7 @@ return new class extends Migration continue; } - DB::table('plugins') - ->where('id', $plugin->id) - ->update(['trmnlp_id' => null]); + $plugin->update(['trmnlp_id' => null]); } } diff --git a/database/seeders/ExampleRecipesSeeder.php b/database/seeders/ExampleRecipesSeeder.php index 5474615..890eed9 100644 --- a/database/seeders/ExampleRecipesSeeder.php +++ b/database/seeders/ExampleRecipesSeeder.php @@ -13,8 +13,8 @@ class ExampleRecipesSeeder extends Seeder public function run($user_id = 1): void { Plugin::updateOrCreate( + ['uuid' => '9e46c6cf-358c-4bfe-8998-436b3a207fec'], [ - 'uuid' => '9e46c6cf-358c-4bfe-8998-436b3a207fec', 'name' => 'ÖBB Departures', 'user_id' => $user_id, 'data_payload' => null, @@ -32,8 +32,8 @@ class ExampleRecipesSeeder extends Seeder ); Plugin::updateOrCreate( + ['uuid' => '3b046eda-34e9-4232-b935-c33b989a284b'], [ - 'uuid' => '3b046eda-34e9-4232-b935-c33b989a284b', 'name' => 'Weather', 'user_id' => $user_id, 'data_payload' => null, @@ -51,8 +51,8 @@ class ExampleRecipesSeeder extends Seeder ); Plugin::updateOrCreate( + ['uuid' => '21464b16-5f5a-4099-a967-f5c915e3da54'], [ - 'uuid' => '21464b16-5f5a-4099-a967-f5c915e3da54', 'name' => 'Zen Quotes', 'user_id' => $user_id, 'data_payload' => null, @@ -70,8 +70,8 @@ class ExampleRecipesSeeder extends Seeder ); Plugin::updateOrCreate( + ['uuid' => '8d472959-400f-46ee-afb2-4a9f1cfd521f'], [ - 'uuid' => '8d472959-400f-46ee-afb2-4a9f1cfd521f', 'name' => 'This Day in History', 'user_id' => $user_id, 'data_payload' => null, @@ -89,8 +89,8 @@ class ExampleRecipesSeeder extends Seeder ); Plugin::updateOrCreate( + ['uuid' => '4349fdad-a273-450b-aa00-3d32f2de788d'], [ - 'uuid' => '4349fdad-a273-450b-aa00-3d32f2de788d', 'name' => 'Home Assistant', 'user_id' => $user_id, 'data_payload' => null, @@ -108,8 +108,8 @@ class ExampleRecipesSeeder extends Seeder ); Plugin::updateOrCreate( + ['uuid' => 'be5f7e1f-3ad8-4d66-93b2-36f7d6dcbd80'], [ - 'uuid' => 'be5f7e1f-3ad8-4d66-93b2-36f7d6dcbd80', 'name' => 'Sunrise/Sunset', 'user_id' => $user_id, 'data_payload' => null, @@ -127,8 +127,8 @@ class ExampleRecipesSeeder extends Seeder ); Plugin::updateOrCreate( + ['uuid' => '82d3ee14-d578-4969-bda5-2bbf825435fe'], [ - 'uuid' => '82d3ee14-d578-4969-bda5-2bbf825435fe', 'name' => 'Pollen Forecast', 'user_id' => $user_id, 'data_payload' => null, @@ -146,8 +146,8 @@ class ExampleRecipesSeeder extends Seeder ); Plugin::updateOrCreate( + ['uuid' => '1d98bca4-837d-4b01-b1a1-e3b6e56eca90'], [ - 'uuid' => '1d98bca4-837d-4b01-b1a1-e3b6e56eca90', 'name' => 'Holidays (iCal)', 'user_id' => $user_id, 'data_payload' => null, diff --git a/resources/views/livewire/plugins/recipe.blade.php b/resources/views/livewire/plugins/recipe.blade.php index c9a1442..0e29e76 100644 --- a/resources/views/livewire/plugins/recipe.blade.php +++ b/resources/views/livewire/plugins/recipe.blade.php @@ -803,7 +803,7 @@ HTML; - + Fetch data now @@ -950,7 +950,7 @@ HTML; />
- Enable a public alias URL for this recipe. + Enable an Alias URL for this recipe. Your server does not need to be exposed to the internet, but your device must be able to reach the URL. Docs @if($alias) @@ -87,7 +87,7 @@ new class extends Component { readonly copyable /> - Use this URL to access the recipe image directly. Add ?device-model=name to specify a device model. + Copy this URL to your TRMNL Dashboard. By default, image is created for TRMNL OG; use parameter ?device-model= to specify a device model. @endif
diff --git a/resources/views/recipes/zen.blade.php b/resources/views/recipes/zen.blade.php index 5e01eac..0ae920f 100644 --- a/resources/views/recipes/zen.blade.php +++ b/resources/views/recipes/zen.blade.php @@ -3,11 +3,11 @@ -
{{$data[0]['a']}}
- @if (strlen($data[0]['q']) < 300 && $size != 'quadrant') -

{{ $data[0]['q'] }}

+
{{$data['data'][0]['a'] ?? ''}}
+ @if (strlen($data['data'][0]['q'] ?? '') < 300 && $size != 'quadrant') +

{{ $data['data'][0]['q'] ?? '' }}

@else -

{{ $data[0]['q'] }}

+

{{ $data['data'][0]['q'] ?? '' }}

@endif
diff --git a/routes/api.php b/routes/api.php index f3a31a1..d201312 100644 --- a/routes/api.php +++ b/routes/api.php @@ -18,15 +18,13 @@ use Illuminate\Support\Str; Route::get('/display', function (Request $request) { $mac_address = $request->header('id'); $access_token = $request->header('access-token'); - $device = Device::where('mac_address', mb_strtoupper($mac_address ?? '')) - ->where('api_key', $access_token) - ->first(); + $device = Device::where('api_key', $access_token)->first(); if (! $device) { // Check if there's a user with assign_new_devices enabled $auto_assign_user = User::where('assign_new_devices', true)->first(); - if ($auto_assign_user) { + if ($auto_assign_user && $mac_address) { // Create a new device and assign it to this user $device = Device::create([ 'mac_address' => mb_strtoupper($mac_address ?? ''), @@ -39,7 +37,7 @@ Route::get('/display', function (Request $request) { ]); } else { return response()->json([ - 'message' => 'MAC Address not registered or invalid access token', + 'message' => 'MAC Address not registered (or not set), or invalid access token', ], 404); } } diff --git a/tests/Feature/Api/DeviceEndpointsTest.php b/tests/Feature/Api/DeviceEndpointsTest.php index 2925a5e..c98cb2f 100644 --- a/tests/Feature/Api/DeviceEndpointsTest.php +++ b/tests/Feature/Api/DeviceEndpointsTest.php @@ -263,7 +263,7 @@ test('invalid device credentials return error', function (): void { ])->get('/api/display'); $response->assertNotFound() - ->assertJson(['message' => 'MAC Address not registered or invalid access token']); + ->assertJson(['message' => 'MAC Address not registered (or not set), or invalid access token']); }); test('log endpoint requires valid device credentials', function (): void {