Apple AirPods Max Are Expensive

When Apple announced the AirPods Max, I wanted to get a pair simply because it is over the ear headphones. I had the original AirPods (broke after washing my pants with them inside pocket) and the AirPods Pro. I prefer the original AirPods over the Pro. They seem to fit better for me. The Pros don’t seal well even with the smallest tips. I also hear lots of cracking when I’m on phone calls.

I recently found a pair of AirPods Max that open box for $493.99 off at Best Buy. I’m never shy from open box items so I gave these a pair. I figured, any discount is a deal.

Open box at Best Buy

I picked them up and they were in great condition. I know they are used because when I paired the headphones to my iPhone, the name is Kevin’s AirPods Max. I guess Kevin returned them.

There are already many reviews out there so I will just mention things the stood out to me (good and bad).

USB Type C to Lightning cable

The rechargeable cable that comes with the headphones are USB-C to Lightning. You will need an adapter if you don’t have a Type-C connector. They are trying to push their Macs because all newer models come with Type-C/Thunderbolt connector.

My wife and I both carry “purses” now.

This is the case it comes in. It serves two purposes from what I can tell. It is a “protective” case. It also ensures that the headphones are in a sleep state while in this case so that it consumes less energy while not in use. Many reviewers have found a significant amount of battery charge/life when out of the case and not in use. Carrying it around made me feel like I have a purse/murse.

Removable ear pads

The ear pads are removable and are held by magnets. This is by far the best feature I like on the headphones. I’ve had older headphones that still work but are very worn. It’s either hard to find/replace the ear pads or you can’t replace them. You can buy them from Apple AirPods Max Ear Cushions – Silver – Apple or you can get third party ones from elsewhere.

The verdict? Way too expensive for my taste. These sound just as much as my AirPods Pro, it’s just slightly better because my ears are well inside the pads. I also prefer over the head headphones instead of ear buds. They are also a bit heavy. I wear while working and when I do my walks. I currently have the Anker Soundcore Life 2 and are great. They are also lighter and more affordable. Why did I even consider the AirPods Max? Well, I’m deep in the Apple ecosystem. I started replacing my Amazon FireSticks with Apple TVs. I’d like to connect headphones when I watch at night so I don’t wake up my wife. I wanted something that will work seemless and the AirPods Max does. I just can’t justify the price tag. Most of it is the “Apple Tax” in my opinion. There are plenty of other noise canceling headphones at lower prices. I’m actually looking at the Sony WH-1000-XM4. We’ll see how those go.

User Roles Many to Many

In a previous post, I shared how to create user roles with one to many relationship. Another way to design user roles in your application is to create a many to many relationship. This means many users can have many roles.

It is very similar as the previous design except you won’t have foreign keys in the users or roles table. There will be a pivot table that will have a foreign key for the users and roles table. You also won’t need to have the roles table created prior to the users table. But both users and roles table need to exist before the pivot table is created.

Let’s create the migration file for the roles table.

php artisan make:migration create_roles_table

Edit this file with the following code.

public function up()
{
    Schema::create('roles', function(Blueprint $table)
    {
        $table->id();
        $table->string('name', 50)->unique();
    });
}

Again, I chose not to have the timestamps columns, but you can if you wish. If you don’t want the timestamps column, you should add some code in your Role model class to let eloquent know. Your tables should look something like below.

Remember, we don’t have foreign keys on either table. We will now create a pivot table. Following naming conventions, it will be called role_user.

php artisan make:migration create_role_user_table

The up() in your migration file will contain the following code that defines the foreign keys for users and roles.

public function up()
{
    Schema::create('role_user', function (Blueprint $table) {
        $table->id();
        $table->foreignId('role_id')
            ->constrained('roles');
        $table->foreignId('user_id')
            ->constrained('users');
        $table->timestamps();
    });
}

Your role_user table looks like the following.

As a reminder, by default, Laravel creates INT columns as BIGINT when using id() and foreignId(). You can continue to use INT but you will have to use increments() for the primary key and the “long form” to define foreign keys that uses unsignedInteger() followed by foreign().

Next, create a model class for the role_user table.

php artisan make:model RoleUser

Edit this model class and add the following.

// app/Models/RoleUser.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class RoleUser extends Model
{
    use HasFactory;

    protected $table = 'role_user';
}

Defining $table is not necessary if you follow naming conventions but I tend to add it anyway.

Now we will add the many to many relationship between users and roles. To do this, add the following methods to the users and roles model classes.

// app/Models/Role.php

public function users()
{
    return $this->belongsToMany(User::class, 'role_user', 'role_id', 'user_id');
}

// app/Models/User.php

public function roles()
{
    return $this->belongsToMany(Role::class, 'role_user', 'user_id', 'role_id');
}

You can read more about many to many relationships at https://laravel.com/docs/master/eloquent-relationships#many-to-many. Your tables should look something like this.

With this design, users can have more than one role. For example, user1 can have an admin role and staff. User2 can be admin, staff, and manager. And so on.

Vagrant and Laravel Timed Out While Waiting for the Machine to Boot

I have been able to develop Laravel applications on my Windows 10 environment for quite some time using Homestead. Recently, I have been getting errors when loading up the dev environment. The following error is happening.

Timed out while waiting for the machine to boot. This means that
Vagrant was unable to communicate with the guest machine within
the configured (“config.vm.boot_timeout” value) time period.

If you look above, you should be able to see the error(s) that
Vagrant had when attempting to connect to the machine. These errors
are usually good hints as to what may be wrong.

If you’re using a custom box, make sure that networking is properly
working and you’re able to connect to the machine. It is a common
problem that networking isn’t setup properly in these boxes.
Verify that authentication configurations are also setup properly,
as well.

If the box appears to be booting properly, you may want to increase
the timeout (“config.vm.boot_timeout”) value.

Sometimes the project would load on the browser, sometimes it won’t. Sometimes I can SSH into the VM sometimes, it would time out with this error.

ssh_exchange_identification: read: Connection reset

I use the same environment settings on Linux and macOS and have no issues running the environment. I’m guessing it could be permissions as Windows is different than *nix OS.

A solution I found was to enable GUI mode so that you can see what the VM is doing. If it’s getting stuck somewhere or if the system is waiting for a prompt to be answered. Here is a link that describes how to enable it https://stackoverflow.com/a/23742373/3893181. In my case, my config file did not have it commented out. I had to add it inside the Vagrant.configure block, at the bottom.

This window will open. So if there are any errors during boot, hopefully it will show here.

Now I’m able to see a message that may be causing my issue.

Spectre mitigation: LFENCE not serializing to generic retpoline?

Restarting vagrant/homestead seems to work… sometimes. But what could be causing it is having Docker Desktop installed alongside Virtualbox. I feel that’s when the errors started.

Luckily, Laravel has a new tool in version 8 called Laravel Sail. This uses Windows 10 WSL2 and Docker Desktop. I have uninstalled vagrant and virtualbox and have been using Laravel Sail. It has been working flawlessly on Windows. Finally, I can now have a stable dev environment in Windows. Even NPM commands work.

User Roles One to Many

There are many ways to handle user roles in an application. One way is to create a role(s) that have many user(s) or a one to many relationship. In this scenario, we can create a role called admin and many users can have this role. We can create another role called staff and this role can belong to more than one user. Now a user cannot have more than one role so the inverse relatationship is many to one.

By default, Laravel comes with a migration file to create a users table. Running the migration file, you will get a table with the following structure.

In more recent Laravel versions, the primary key is now a BIGINT datatype. If you open the migration file, it uses $table->id();. Previously, it uses $table->increments(‘id’); and that creates a primary key that uses INT datatype. You can still use either one as of Laravel v8. Just make sure when creating foreign keys, both columns matches up. I have been using the id() to simplify creating migration files. I’m not too concerned with data size.

Next, we need to create a migration file for the roles table.

php artisan make:migration create_roles_table

This will create a migration file. The file name is prefixed with the current timestamp. The roles table has to be created prior to the users table. Migration files are run in alphabetical order. You can either rename the roles migration file to have a timestamp before the user migration file or create another migration to add the foreign after both users and roles table are created. For me, the quickest is to rename the roles migration file so that it appears “above” the user migration file when alphabetized.

Edit the roles migration class with the following code.

public function up()
{
    Schema::create('roles', function(Blueprint $table)
    {
        $table->id();
        $table->string('name', 50)->unique();
    });
}

I chose not to keep the timestamp columns but you can keep them if you want. The migration file will create the following table.

Next, edit the users migration file and add the role_id foreign key. Add the code below within the up(). I normally place my foreign keys under the primary key.

// CreateUsersTable class
public function up()
{
    Schema::create('users', function (Blueprint $table) {
        $table->id();
        $table->foreignId('agency_id')->constrained('agencies');
        $table->string('name');
        $table->string('email')->unique();
        $table->timestamp('email_verified_at')->nullable();
        $table->string('password');
        $table->rememberToken();
        $table->timestamps();
    });
}

This will create the foreign key constraint between the users and roles table.

It is a good idea to create the relationships in your model classes as well. Create a model class for your roles table.

php artisan make:model Role

Edit the Role.php model class file.

// app/Models/Role.php

class Role extends Model
{
    use HasFactory;

    protected $table = 'roles';              // defines table name
    public $timestamps = false;         // no created_at or updated_at columns

    /**
     * Has many users.
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function users()
    {
        return $this->hasMany(User::class);
    }
}

You will need to define the relationship in your User model class.

// app/Models/User.php

/**
 * Relationship to role.
 * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
 */
public function role()
{
        return $this->belongsTo(Role::class);
}

That’s all you need to do in terms of create users and roles relationship. The next step is to create a way to authorize users based on roles. You can either use Laravel’s Gates and Policies. Or you can create your own middleware.

3D Printing Is Not For Me

I have been curious about 3D printers for some time but the cost did not justify to quench my curiousity. Recently, the Creality Ender 3 Pro went on sale for $199.99 at Micro Center. I decided to pick one up and some PLA filament. The first print I tried is the dog demo that came with the printer.

At first, things were looking good. The first couple of layers look rough but I thought it was fine and it’ll straighten out. This print is supposed to take about 5 hours. More than halfway through it fell apart.

I should have leveled the bed

As you can see the first few layers were all over the place. The bed should have been leveld. The print failed because the level was off. Not sure why it took that long.

I downloaded a file to help level the bed and started to print the dog again. Another failed attempt.

The filament spool got tangled

This time the filament spool got tangled up. This was the starter spool. Instead of running into the issue again, I opened a new spool – one of the 1 kg spools I bought.

Okay, attempt number 3 on the dog. This time the nozzle got clogged after 2 hours of printing.

I am striking out with all these attempts. I took it apart, which was a good exercise. It helped me get more familiar with the printer. Cleaning wasn’t too difficult, just time consuming. I cleaned out the filament and put the printer back together. Here we go, attempt 4.

Success!

I finally got a successful print. It took several tries and many hours of waiting. Long filaments but the cost isn’t that bad. It’s mainly the time and power consumption. Even with this print, there is a stain on the right leg – may have been due to excessive heat/burn during the print. I was pretty excited to finally get one print done so I printed another and it completed without any issues.

The one I tried is the pig demo. It came out fine. This was a long print – around 6 hours. I am getting the hang of it and tried to print a knob for the printer. It failed a few times but finally printed correctly. Next was the cat demo. This failed. After that failure, I decided that 3D printing is not for me.

Just some of the failed attempts
Successful attempts

After some thing, I decided to return the printer before the return period expires. I just can’t get the hang of it. You invest a lot of time and electricity and from my experience, it gave me a low success rate. I also found many 3D printed items being sold on Etsy.

Noctua Is Too Big

I have been having bad luck with closed loop water coolers so I decided to try an air cooler. I also picked up new case, the Lian Li 011 Dynamic. Noctua fans are great so I went ahead and got the Noctua NH-D15 Chromax Black.

Noctua NH-D15 Chromax Black

Installation is fairly simple and the packaging is outstanding. Reminds me of opening up an Apple device. I was very excited to get this up and running and see improvements of noise and possibly lower temps. Unfotunately, my excitement was met with disappointment. It’s too tall. I cannot close the side panel.

The cooler is too tall

I should’ve read the reviews/comments. This cooler does not fit the Lian Li case. I didn’t want to get another case just to use the cooler. I opted to keep the Lian Li case and returned the Noctua cooler. If it weren’t for the spikes, I believe this cooler would fit. I couldn’t remove them.

I’m really contemplating on using this Noctua cooler on my next build and use a bigger case. Maybe look into another Fractal Design Define series or Corsair Obsidian series.

Apple Trade In With Phobio

I currently have a 2016 MacBook Pro. It’s been great but my biggest complaint is the keyboard. Fortunately, it doesn’t malfunction. It works as intended but that’s the problem. The butterfly keys are terrible and for a laptop, the keyboard and monitor are pretty much everything. I can plug in an USB keyboard but it won’t make it portable.

I paid $2799 for my 2016 MBP and the trade in value is only $710. I decided to bite the bullet and take a loss and trade in for the 2019 16″ MacBook Pro. Three things I’m after: the bigger screen (vs 15″), 8 cores (vs 4 cores), and “magic” keyboard AKA the old keyboard that shouldn’t have changed to begin with (vs butterfly keyboard). I bought the 2019 MBP online and started the process for the trade in. Phobio is the company that Apple uses for trade in. The plan is to pay for the 2019 laptop and once the trade in is completed, get the refund for $710 back on the card.

IMG_0398.JPG
2016 MBP (top), 2019 MBP (bottom)

Phobio sent out a box with shipping labels for me to pack up my old laptop and send it off for inspection and trade in. I took several pictures during the factory reset and noted the condition of the laptop. I am very careful with my stuff. These devices are expensive!

A few weeks later, I get an email from Phobio informing me that my trade value has been reduced from $710 to $250. They said they detected some screen damages during their inspection. Here is the photo they took and sent to me.

trade_asset-20484507130-5796d829f4cc4322999b30fd79cc00a1
Phobio found screen defects… can you see it?

I don’t see it and I also took photos before shipping my old laptop to them.

This slideshow requires JavaScript.

Do you see any imperfections on the screen? I don’t either. I declined the new trade in offer. I called Apple and Phobio for additional options. Phobio is firm with their decision. They say that the damage they saw could not have happened during transit but more of wear and tear damage. I told them that there is no damage when I sent it to them, could the damage occur while they were inspecting and testing – of course not.

They shipped the laptop back free of charge. After receiving it back, I inspected the laptop and did not find any screen damage as they described and photographed (I still don’t see it on the photo). I contacted Apple and they suggested to bring it into the store to do the trade in – but with COVID19, the stores are closed. I was nearing the return/refund deadline – which was extended from 14 days to 30 days due to the current situation. I didn’t want to risk not being able to get the trade in amount and/or get a refund on the new laptop so I just returned it and got a refund.

Working from home, I don’t need to be portable with the laptop so I just docked it with a keyboard and monitor – problem solved until the new ARM Macs come out and I’ll revisit the trade in option.

After this experience, I would definitely suggest to do your trade in inside the Apple store. Any screen damage will tremendously reduce the value. But at least when doing it in the store, you will know right away of the value. And they may be more lenient with imperfections.

Fix Your Favorite Headphones

I have a pair of Bose SoundTrue headphones I got back in 2015 and it has seen better days. I don’t want to throw them away since they work. The only problem it has is the worn earpads.

DSC00240.jpg
Bose SoundTrue

I called Bose to see if they could help me. They have cushion kits for sale but at the cost of $34. They have the black ones (329586-0010) or white ones (626655-0040). I got these headphones during Black Friday for $60. Getting those replacement pads for that price is not a good idea.

I searched on Amazon and found them cheaper for $29.95 but it’s still too expensive. I might as well get new headphones. I found an alternative for a lower cost from Amazon.

DSC00242
Earpad Replacement

They are easy to replace. The pads are held with clips. You just remove and replace.

DSC00244.jpg
Clips hold the pads in place

The fit is good. You just have to go around and make sure the edges are under the clips.

DSC00246
Nice fit, good as new

I decided not to use the L and R dust-proof scrim. I kept the blue ones in. It’s easy to determine which is left and which is right. Just put them on and you’ll feel it. Otherwise, the cable is always on the left side ear. Now to find a headband replacement. The support is still there but the fabric is getting worn as well.

My other headphones, Audio Technica M50 headband is worn. Again, I called the company and was told to send them the headphones and pay a fee for them to replace it.

DSC00248.jpg
Audio Technica M50

I found a zipped up cover and it solved my problem.

DSC00250
Zipped up cover

Make sure the zipper is on top or it will head our head when you’re using it. It fits snug.

DSC00253.jpg
What a mess

As I was fitting the cover, all the headband material started coming off. This is why I wanted a cover. Now I can continue to use and enjoy my old headphones.