Quality issues with Apple Watch

iPod 5th Generation

Background

I have been a big fan of Apple devices for a really long time. Right from the iPod 4th Generation (I still have it and it still works even after 14 years) with Video to iPhone 11 Pro. Over the period of time I have used a lot of devices from Apple and swear by the quality, reliability and durability of Apple products. But sadly, nowadays the quality of the products has been declining quite a bit. Apple's image even took a beating after the Antenna-gate, Bendgate and Battery-gate issues. But it weathered the storm and kept bringing great products. Although they may not have been bleeding edge or latest technology or even the most innovative, they were high quality products. But now it seems there are quality issues with Apple Watch.

The issue

I'm afraid that there may be another scandal or issue brewing with its Apple Watch line of products. It could be called as Watchgate or Screengate. This is an issue with the Apple watch where the screen just pops off.
Apple watch with popped screen
Though by far, I am not the only one facing this issue as there are threads on Apple community discusions which you can read here and here. In fact one of my friends also faced this issue. It is a known issue and Apple has also acknowledged it as it is now a separate category on Apple's support page.
Apple support options
I faced this issue with Apple Watch Series 3 twice in the last 18 months. First time around it was within warranty and Apple quietly replaced the watch for me. But now when the screen popped the watch was out of warranty and they refused to repair it without me paying a ridiculous $159 repair fee.

Frustrated!!!

I was left with a watch whose screen had popped off. The poor glue was trying in vain to keep the assembly in place. Paying $159 for repair of a watch which I expected to again face the same issue didn't seem worth it. So I kind of resigned to not use my Apple Watch again. My wife even suggested getting a Fitbit so that we could be a Fitbit family. I was really frustrated and I fired off an email to Tim Cook the text of which is below:


Hello Mr. Cook,

I have been a lifelong Apple user starting from iPod 3rd generation and the successive products. In fact i have never used any other smart phone in my entire life. It was very exciting and great feeling to buy my Apple watch 3 around 1.5 years ago but since then my experience with the renowned Apple quality has not been what I have come to expect. The screen has a tendency to come off very now and then and it appears that the glue used is of low quality. I have been using the watch as per Apple's recommendations and have never even once taken it in water.

I had it repaired once last year and it was replaced for me. Now the new watch has the same problem in less than 9-10 months and now I have been asked to pay $159 for repairing the watch which doesn't seem right to me. It clearly is either a design or a manufacturing defect resulting from usage of low quality components in the manufacturing process.

I have worked at Apple for a few years and I know the rigorous demands on quality that Apple has and working at Apple has shaped me and my career in a positive manner.

I just hope you will take the time to read this email and take the appropriate action. I really love the Apple Watch and feel really bad to stop using it because of the issue.


Tim Cook is a busy man and he is preparing for Apple's event tomorrow on Oct 13th. But I believe he should address customer issues on priority.

Viola, the solution

Anyway, I slept over the issue and in the morning had a brain wave. What if I glue the screen with super glue? I always have some kind of all purpose super glue at home and this time around I had Gorilla Glue.Gorilla Glue

So the first thing I did in the morning was to apply a little bit of Gorilla glue around the edge and put the screen back. I took care to not damage or displace the connector which connects the screen to the body. I factory reset the watch several times in the day (I don't know why it didn't start up immediately), but finally by the end of the day it started working again and now I am very happy and proud to say that I fixed the Apple Watch myself without paying the ridiculous amount as repair charges and hopefully the watch is good for another couple of years.

How to create a bootable USB drive on MacBook

Introduction

I like to tinker around with technology. I think that much will be evident from my website and the type of posts that I write here. Sometime back, I was trying to play around with a Raspberry Pi. It was a RPi zero so it didn't have a lot of capabilities, but I figured out that I could run Raspbian Buster or Debian Buster on it and also ran this website on it till recently when I migrated it to AWS. While playing around with RPi zero, I discovered and created a bootable usb drive on Mac using diskutil and dd. The same process also work for creating a bootable SD card.

The problem

For quite some time now, I have been using a MacBook as my primary computer and while it is a great machine for personal productivity and development, I didn't really dive deep on system administration. I needed to figure out how to format a USB drive and a SD card on Mac and write a bootable image on it.

I did a lot of research and I came across a site from a Microsoft engineer who had written a very nice article on this and I used that article to very easily achieve my task. But I can't find that anymore so instead of relying on someone else, I thought I will document it myself and also add some additional details so that others can benefit. I could have very easily used my Windows computer but that wouldn't be integral with my tinkerer nature.

Recently, I had revived an old 2009 laptop which refused to run any of newer OSes so I did another research on possible OSes that could run on it and figured that I could run Lubuntu on it easily. So I went ahead and downloaded the latest version of Lubuntu - Focal Fossa and set to the task of creating a bootable USB drive.

The technical details

To achieve this, I need only two tools from my MacBook

  1. diskutil
  2. dd

Let's take a look at the details now.

The first thing that needs to be done is to determine the device details of the USB drive. To do that, first insert the drive in your USB port and run the command below:

diskutil list

List all devices using diskutil

This command will show an output of the disks mounted. Determine the device details by looking at the disk size and note down the device details which will be in the form /dev/diskN where N is a number. Once the device number is determined, run the following command under root (sudo) privileges

sudo diskutil eraseDisk FAT32 LABEL MBRFormat /dev/diskN

Erase disk using diskutil

Make sure to replace the LABEL with the name you want and N with the number noted above.

It will take a few minutes to complete the process and once it is complete, run the following command:

diskutil unmountDisk /dev/diskN

Again taking care to replace N with the appropriate number.

Once the disk is unmounted, we are now ready to write the bootable image to the USB drive. To do so, run the following command:

sudo dd bs=1m if=/Path/to/fileimage.iso of=/dev/diskN

Create bootable disk using DD

Depending on the size of the image, this can take several minutes. You can check the progress of the process by pressing Ctrl+T on the screen. Once finished, run the following command to eject the disk from the computer gracefully.

diskutil eject /dev/diskN

Don't forget to replace the N!

Even more deeper details

Now that you understand the commands, let's take a detailed look at the verbs and the switches we used in the commands.

  • diskutil: We used the following verbs with this command.
    • list: This option lists all the drives that are attached and mounted on the operating system
    • eraseDisk (note the capital D): This option will erase the disk that is provided as an option. It also takes the following arguments:
      • Filesystem Type: Choose from FAT32, NTFS, EXT4 etc.
      • Label: The name to be given to the disk
      • Format: The format type of the disk. Valid Values are: APM (Apple Partition map), GPT (GUID Partition Table) and MBR (Master Boot record). Using MBR will ensure that the drive will be bootable on non-Mac machines as well.
      • Device: The device number that we noted earlier.
        Note: This option needs sudo or root privileges to run.
    • unmountDisk: This will unmount the entire disk including all the volumes that may be present on the disk. It needs the device argument to work.
    • eject: This will eject the disk from the computer and make it safe for the removable media to be removed from the computer without the risk of data corruption.
  • dd: dd stands for data duplicator and is used to copy and transform data from one device to another. It is a low level Linux command line utility which will be a great addition in any system administrator's toolkit. We used the following verbs and switches in this exercise:
    • bs: Stands for block size. The default block size for dd utility is 512 bytes and there's not one right size for setting a block size. There is a good discussion here. This operand sets both the input block size and output block size to the desired value which I have used as 1 mb.
    • if: Denotes the input file where the dd should read from instead of standard input.
    • of: Denotes the destination where dd should write to instead of standard output.

Conclusion:

That's it for now. I hope this short tutorial has been helpful to you. Instead of using the GUI tools, I have found that using these command line utilities provide a lot of flexibility and power to the system administrator but can be confusing at times and have potential to destroy data if used incorrectly.

Updating a DynamoDB attribute with a hyphen or dash (-) in the name using CLI or SDK

Background

As a part of my personal growth plan and work commitments, I am working on the AWS Certified Developer - Associate certification using the Linux Academy platform. In one of the lab exercises that I was doing on DynamoDB, there were requirements for updating DynamoDB attribute using SDK and perform conditional updates and atomic counters on the tables. Being what I am, I did not use the examples they had provided, but created by own table to create a database of books I own and proceeded to create my own attribute names for the items.

The problem

As it happened, I created attributes like book-title, book-author, book-price, etc. which in itself is not a problem. However, the lab exercise had me perform the item updates using the BOTO3 Python SDK which got me excited to learn new things. I used the example files that the trainer had provided and modified it to suit my environment and ran the script.

UpdateExpression='SET book-price = :val',
ExpressionAttributeValues={
    ':val': {'N': '15.37'},  
    ':currval': {'N': '0'} 
},
ConditionExpression='book-price = :currval',
ReturnValues="ALL_NEW"

To my dismay, I started encountering errors.

Traceback (most recent call last):
  File "conditional_write.py", line 18, in 
    ReturnValues="ALL_NEW"
  File "/usr/local/lib/python3.7/site-packages/botocore/client.py", line 316, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/usr/local/lib/python3.7/site-packages/botocore/client.py", line 626, in _make_api_call
    raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (ValidationException) when calling the UpdateItem operation: Invalid UpdateExpression: Syntax error; token: "-", near: "book-price"

The Solution

I reviewed my code to ensure that I had not introduced any bugs myself. After ensuring that I had not introduced any bugs by adding new attributes to an item without any dashes and running the script successfully, I starting practicing my Google-Fu. There I found this awesome post on stackoverflow along with a link to official AWS documentation. The official documentation however only talks about a dot being a special character and it doesn't list a dash (-). After following the instructions from the stackoverflow post, my new code looked like this:

UpdateExpression='SET #bp = :val',
ExpressionAttributeValues={
    ':val': {'N': '15.37'},  # Make sure we keep this line the same
    ':currval': {'N': '0'}  # What was the current value?
},
ExpressionAttributeNames={
    "#bp": "book-price"
    },
ConditionExpression='#bp = :currval',
ReturnValues="ALL_NEW"

And once I implemented this code it all started working correctly. I have left a feedback for the AWS documentation team and hopefully they will update the documentation. I just want to make sure that all the cases are at listed and documented so that developers and wannabes like me are not stuck.

Elections in the new world

Context:

A long running episode has just turned an important page right now. Robert Mueller finally testified in front of the congress and as I expected provided almost nothing to the lawmakers outside his report. The focus of media and most of the public was around collusion and obstruction of justice. Indeed, that was the most newsworthy story but in my opinion not the main story or threat to the democracies of the world. It was only Rep. Adam Schiff brought out the question of integrity and security of elections. Director Mueller had already highlighted it in his monologue of a press conference in May 2019. How will the elections look like in the new world?

Subtext:

It is an important aspect that all the democratically elected governments of the

Elections
Elections in India

world should be really worried about. In fact there are questions being asked of the validity of the Brexit referendum vote and even some of the assembly Elections results in India. Now defunct Cambridge Analytica is being suspected as being involved and even instrumental in altering the outcome of both the results.

Just imagine if the Pakistani intelligence agency ISI decides to engage itself in Indian politics. It can ensure a party that is sympathetic towards Pakistan comes to power. Or even worse, it can ensure that an incompetent leader becomes the prime minister of India. That would be a disaster not only for India but to the stability of the region and I daresay, even the world. I can't think of India being ruled by Congress party led by an inept leader like Rahul Gandhi.

With the world becoming more and more digital and online, governments of the world should take infinitely more care about ensuring the data security and integrity to ensure fair and correct results. We all see in day to day life how easy it is to hack any computer system and bring it down. The private companies of the world realize it and spend a fortune on securing their IT infrastructure. The governments also should realize it. The bureaucrats must eliminate of reduce bureaucracy to a large extent and actually care about the security and integrity of the election process and the integrity of the results.

Conclusion:

It is very easy to ensure the security of elections in the new world if you think about it. First of all, Government must appoint competent people to key positions with reasonable autonomy to perform their function. As a result of strong and fair oversight, it will ensure that the right policies and procedures are implemented. Politicians must be kept at more than an arms length from the entire process. State of the art technology should be implemented. Most importantly, the people involved in the process at the grass roots level should be provided training and right incentives.

This is the just the starting point. But we don't have a lot of time to get it right. The bad actors are already off the blocks and the race is on!!!

A “Brave” new browser (?)

While watching the recently concluded 2019 cricket world cup, I saw some ads for Alluva, which calls itself a prediction platform. I am not sure how it works, but that's not the point of this article. I signed up to Alluva and it had me create an account on MetaMask, to receive the Alluva tokens. There on MetaMask site, it was strongly encouraging using a new browser called Brave.

Get Brave!

The browser in itself if based on Chromium project and they state that they have "taken almost all of Google from the Chrome."

I was intrigued. I am not the one to shy away from testing out new technologies. So I decided to take it for a spin. I downloaded it and took it for a spin. The first few sites all worked fine as the browser's core code base is Chrome itself. But the moment I tried to connect to my corporate sites, it started acting up. I faced two main issues while browsing:

  1. For any SSO enabled site, it started asking for username and password instead of taking the authentication from the kerberos ticket.
  2. For any SAML federation redirects, the redirects just failed and the site failed to work.

These issues were a deal breaker for me. For all the technology evangelism I just can't see myself using two browsers for my needs. I needed to have one browser. I was about to give up and go back to tried and tested Firefox. But I refused to give up. I asked myself, if Chrome works, then why not Brave? What is different in Brave that is causing the issue. I found the answer in one of the feature request on GitHub and a Brave Community post. Looks like when the browser code was compiled the developers disabled a couple of flags that are needed for SSO integration with kerberos and SAML redirects.

  • --auth-server-whitelist
  • --auth-negotiate-delegate-whitelist

When I tried to run the browser by running from command line and passing correct arguments for these parameters, everything worked fine. But again it is not very easy to always run it from the command line and all your settings are lost. So I was looking for an answer to make the process automatic and repeatable. I searched a lot of forums and help sites and I found the answer on superuser.com. This gives a step by step explanation of how to configure command line parameters for any application.

I tried both methods, and finally settled on the second method as the best method.

I created a small application using MacOS automator. It worked well. But I always had to launch the application from wherever I had saved it. Launching it from the Dock instead of from the actual location even after pinning it to the Dock defaulted to the original application launcher. The second method modifies the application bundle so it is a little risky but with enough due diligence and case, you can do it.

You can download the brave browser by clicking here.

How to setup use NexxHome garage door opener with Google Home

After a lot of discussions and false starts, we finally took the plunge in making our home a smart home starting with smart speakers and thermostats. After we moved into our own home, we were always kind of worried about the garage door and once or twice we have left it open only for our neighbors to call us and alert us about it.

We were not sure about how to handle it when a couple of our friends told us about the smart garage door openers that operate over WiFi and are accessible over the internet from anywhere. We did some research and based on the reviews and feedback from our friends, we decided to go for the NexxHome smart garage door opener. Based on the information provided on the product page on Amazon and on the NexxHome website, the device works with Alexa as well as Google Home. While I was able to find a lot of sites that showed how it works with Alexa, I was not able to find any tutorials on how to link and enable NexxHome with Google Home. The device doesn't even come up on Google Home App when I try to add a device.

I was disappointed and stumped. But then, I found this document on the NexxHome support page that kind of gave me a direction to pursue.

Integrating NexxHome with Google Home is not very straight forward. There is a roundabout way of doing it. Before linking Nexxhome with Google Home, the Nexxhome App needs to be prepped up a little bit.

  1. Open your NexxHome App and tap on Setting (gear icon)
  2. In the next screen, tap on "Works With" menu and enable Google Assistant
  3. Once that is done, open your Google Home App and click on the user icon
  4. Tap on Explore and in the search window, type Nexx Home and select on the Nexx Home result
  5. In the next window, click on Link to link your NexxHome with Google assistant and enter your NexxHome credentials to login when prompted.
  6. Once you login, the Nexx will be linked and it will show Try it button to try the commands.

That's it. This successfully links NexxHome with your Google Home and Google assistant.

Note: Although it links successfully, the linkage is not very reliable and you may not get the desired results every time. However, for me, it has worked as expected 8 out of 10 times. Hope this helps others as well.

Troubleshooting and fixing 404 errors on a self hosted WordPress

After hosting my website on Plone and attempting to host it on plain HTML5 I decided that time has come for me to use a CMS. As I wrote in the Hello World post (i.e. the first post) I chose to use WordPress. I installed it and as my work and life made me busier and busier, I kind of ignored. It is very apparent from the irregularity of the posts and blank periods in the posting.

Anyhow, the point is that I didn't realize that the permalinks, categories and tags were not working. When I clicked on a particular post or tags or categories, it showed me a 404 error. So essentially I had a broken site on my hands. And here I was wondering why my site was not coming up in searches and why I was not getting any traffic. SEO helps Google to crawl and index the website most effectively when permalinks, tags and categories are setup correctly.

Apparently, it is a very common error in WordPress with a very straight forward solution. A simple google search most likely leads you to the right solution. My objective is not to add to the burgeoning posts of "How to fix 404 errors on WordPress". The objective of this how-to is to address one edge case that will occur when you are trying to host WordPress on your own server/computer.

I followed a lot of posts and almost all of them told me the same thing.

  • Re-save the permalink settings and
  • Ensure you have the .htaccess in your WordPress directory (some of them don't tell that you should have it in the WordPress directory though).

I was at my wits end on what to do to solve the problem. I was about to give up and try and reinstall WordPress when I came across this site and the how-to. That how-to does address the edge case of people like me who like to run their own web servers instead of buying managed hosting. In fact, I am running my site in containers. In fact re-installing WordPress would have added work and would have broken my site. Thankfully I stayed away from it.

The rewrite module of Apache is not automatically enabled. This was the "A-HA" moment for me. I checked out the modules that were loaded by running sudo apachectl -L and sure enough there was no rewrite module enabled there. I double checked that I had the rewrite module binary in the mods-available directory in my Apache distribution.

At this point, I was ready to enable the module by running sudo a2enmod rewrite and sudo service apache2 restart on my server and enable the module. After that, I was able to reset the permalinks to whatever I wanted it to be. This fix also worked tags and categories.

I hope this helps whoever is facing this issue.

Slyly yours, Netflix

Dear Netflix,

Did you really think that you could increase your revenue by surreptitiously increasing the subscription price by upgrading the plan without my permission (and several hundred thousands others) to premium.


Well, now the rant is out of the way, I think I can get down to business.

This all started a couple of days ago, when I got an email from Netflix on Apr 21 telling me that my plan price was going to increase to $10.99 from $9.99 and the updated pricing is part of Netflix's commitment to improve Netflix. Ok. So far so good. I understand the prices are going up and I am willing to pay more for better service and I didn't think twice about it.

A week later on April 29th, I received another email from Netflix telling me that they have updated my plan to premium allegedly as "I had asked" and the price had gone up to $13.99. I don't remember asking or even logging in to Netflix account to update / upgrade my plan so where did this come from? I promptly went to the account settings and reverted the plan to standard which is 2 screens at a time with HD content as opposed to 4 screens at a time with HD and Ultra HD content. I don't even own a TV that support U-HD content. Why will I use that service?

In perfect honesty, my family and I don't even get to watch Netflix twice a week. What would make us upgrade to 4 screens and Ultra-HD content? This doesn't seem right and honest behaviour to me. And now I am stuck with a service I don't want to use and will not use till the next billing cycle.

I would still like to see where I have requested this change to the account plan.

Netflix, are you listening?

Rock, Paper, Scissors… in Python

For a long, long time, I have been an enthusiast of Python programming language. I am embarrassed to say that I have been trying to learn it fully for the past 10 or so years. In this much time with proper focus and dedication, I would have been a guru. But here I am, still a novice. But that's beside the point.

Now that summer vacation is here, I have decided to teach my kids Python programming as much as I know. I want to show them the path and take them with me as far as I can go and then I hope they will go further from there. While Some time ago (maybe a couple of years ago) I had given myself a challenge to create a program that I had no source or coaching. So I had decided to create a game in Python. I chose the simple game of Rock, Paper, Scissors.  Over time, I changed computers and somehow I lost the source code of the program.

When my daughter started learning, she reminded me of the program and wanted to play the game. So I got started to write the program again. I'm happy to report that I have successfully re-written program. I'm sure there is a lot of scope of improvement in the coding style, code, and overall structure. But I am just starting and hope to improve. I'm posting the source code of my program and I will welcome all constructive criticism of the code and suggestions for improvement.

# An all-time favorite game of Rock Paper Scissors.
# An all-time favorite game of Rock Paper Scissors.
# Programmer: Mukul Dharwadkar
# Date: June 27 2017

import random

def instructions():
"""Displays the game instructions"""
print \ """ Today we will play the perennial favorite game of... Rock! Paper!! Scissors!!!.
The objective of the game is to outthink your opponent (in this case me) and defeat.
The rules are very simple
1.Paper covers the Rock
2.Rock breaks the Scissors
3.Scissors cut the Paper
Choose your move from the following:
1. Paper (p)
2. Rock (r)
3. Scissors (s)
Are you ready? Alright then, let's play... """

def get_name():
"""Get player's name"""
print \
"""First of all, let's get to know each other a little better.
My name is Compy...
What's yours?
"""
player_name = raw_input("What is your name: ")
return player_name

def greet_player(name):
"""Let's be polite and greet each other properly"""
print "How are are you doing %s?" % name

def legal_moves():
"""Define the legal moves"""
legal_moves = ("r", "p", "s")
return legal_moves

def player_move():
"""Players choose their move"""
move = None
while move not in moves:
move = raw_input("What is your move %s? --> " % name)
return move

def computer_move():
"""The computer will choose its move in this function"""
move = random.choice(moves)
print "Computer's move is %s" % move
return move

def compare_moves(p_move, c_move):
"""We will now compare the moves the human and computer make and then take the output to declare the winner"""
#This is a very crude way of writing this comparison code. Is there a better way to do this?
#TODO: Find out optimized way of writing this block of code.
if p_move == "r" and c_move == "p":
return "computer"
elif p_move == "r" and c_move == "s":
return "human"
elif p_move == "p" and c_move == "s":
return "computer"
elif p_move == "p" and c_move == "r":
return "human"
elif p_move == "s" and c_move == "r":
return "computer"
elif p_move == "s" and c_move == "p":
return "human"

def declare_winner(winner):

if winner == "human":
print "%s wins. Congratulations and well played!!!" % name
elif winner == "computer":
print "Computer wins. Better luck next time %s." % name
else: print "It's a tie"

#main body of the program
instructions()
name = get_name()
moves = legal_moves()
greet_player(name)
p_move = player_move()
c_move = computer_move()
winner = compare_moves(p_move, c_move)
declare_winner(winner)

Note: The indentation of the code is lost.
To do: Create a GUI interface for the program if I can.

Running WordPress site in distinct containers

I have been running my site on Plone for a long time, but the maintenance required was too high and I ran into several issues with bloated data file, unsupported plugins to name a few. Plus the instance was not very portable in case my server died or I had to move.

Then I was thinking about creating my own content management system, but time was a factor and the I thought I was losing my focus. What do I really want to do? Publish my thoughts, or develop something new. Actually it is both, but I don't want it to become dependent on each other. So I decided to use prebuilt software. I very quickly evaluated Drupal, WordPress, Movable Type and decided that WordPress looks to be the best at this time. More on the evaluation later.

Second challenge was to make it completely portable by using containers and not just VMs.

To be continued...