Mar 14, 2018

Raspberry Pi: Send Email as your personal Notifier!


you need smtp installed, to get it, you need (smtp and mail):
    sudo apt-get install smtp mail

Setup email server configuration (edit smtp config):

into format as below:
    mailhub=mail_service_provider #for example ""

Sending Email in Plaintext

    echo "the content of the email body" | mail -s "This is the subject"


Just in case you run into Gmail authorization problems:
1. mail: cannot send message: Process exited with a non-zero status
Probably your smtp.config has it configured incorrectly

2. ssmtp: Cannot open
Check if your port number is entered correctly

3. ssmtp: Authorization failed (for Gmail, if you have 2FA activated)
You might have to follow this 2FA Gmail Solution to add an app-specified password for that particular app.

Send Email with attachment (Coming soon...)

Content coming soon... (be patient)

Jan 12, 2018

Wobbling Pokeball with SnapSVG

Creating SVG from ground up

If you've just gotten started, then the first dirty tips to answer your questions (which you might have in mind as a beginner):
  • Yes, you can import external SVG file/code into your SnapSVG Javascript code
  • SnapSVG can help writing pure SVG code from scratch (yes, for simple SVG, but I don't think this is a proper way to write your big animated SVG project from scratch)
  • (my gut tells me) For large SVG project, start SVG project with editor like Adobe Illustrator or Affinity Designer (follow your preferences) then export as SVG file
  • Yes, for every tiny movement/animation has to be coded from scratch (no shortcut, so try to reuse code if possible)
  • Speed development - utilise handy tool like CodePen to help your development!

Steps required (when you get started):

  1. (If you plan to start from scratch) Start learning adding shape/line/text into your element
  2. Animating SVG (mostly achievable by using the ELEMENT.animate())
See the Pen Wobbling pokeball (Snap.svg) by trtshen chaw (@trtshen) on CodePen.

Simple SVG Project with SnapSVG, HTML is not the first priority

As you can see from the example above, there is no HTML code available. It starts right into Javascript code with Snap() and canvas size for your svg

    var poke = Snap(230,230)

Once you are done declaring required elements, the rest of the code is written to style up your elements and properly group related elements for animating purpose.

Why Group Up Elements?
As you animate element, you have to animate related elements together, so grouping them in a "g" makes our job easier to animate them altogether and more useful for chaining a sequence of continuous animations.

Thanks SnapSVG for the great tool!

Sep 27, 2017

Mount/Unmount external drives through command on Mac (OSX)

Once you have your external device connected to your Mac, the very first step would be making sure your Mac is aware of it, by running:
    diskutil list
Sample Volumes after running diskutil list

Let's say Mounting the target external drive 1stHDD,

    diskutil mount disk4s1

To unmount, run:
    diskutil mount disk4s1

Working with WinWheel.js and GreenSock's GSAP in Angular

I was assigned a task to make a spinwheel for one of the gamification feature in an webapp which was build with Angular 4.

If you've been working with Angular in Typescript for a while, especially those require 3rd party libraries integrations, you may already experienced the pain integrating stuff which was build to fully compatible with Typescript.

This post is not about solving library integration to your typescript codebase, but how do you get Winwheel.js work in your Angular code which has cost me few amount of trial and error effort, hope my sample code saves some of your development time if you are facing the same issue as I gone through.

As you can see from the typescript code above, the integration of winwheel.js and tweenlite (GSAP) just requires:
    import * as Winwheel from 'Winwheel';
    import * as tweenlite from 'tweenlite';
Next step is to create a new instance of Winwheel object with:

    this.wheel = new Winwheel.Winwheel(/* your custom config goes here */);

In the rest of your code, you can then start using Winwheel.js API through this.wheel declared above, as the example above does not require data manipulation after the spinning is complete.

GSAP integration

Working with GSAP isn't very hard, but that's one thing I've overlooked at very first time and did aware of the existence of changing target scope to a correct one.

Most of my time spent on fixing the this scope, and found out we have an option to change the this scope with onUpdateScope and this solve most of my headache integrating tweenlite to my winwheel.js.

* In the sample code above is using tweenlite, you can use tweenmax as long as you are pointing to the correct scope.


If the spin's end result is required for further calculation, you'll need the service of NgZone to tell Angular to keep an eye on the changes of state.

To do so, you can add following enhancement to the onComplete function:
    let onComplete = () => {
      console.log('Done spinning!'); => {
        // do something with the data obtained from the spinwheel
        let prize = this.wheel.getIndicatedSegment();

Docs: getIndicatedSegment

Sep 7, 2017

Access raspberry remotely without password

Solution is simple, just 3 steps are required:

On your local machine (which you will access your remote server from)
1. Run:
ssh-keygen (and the following configurations are guided)
2. Configure your config file (~/.ssh/config) with your created public key directory location, for example:
Host # your rpi ip address
HostName # your rpi ip address
User pi
IdentityFile ~/.ssh/yourkey
3. After done creating public key, copy your public key file content
Example content of public key file
You can copy your public key content with:
cat ~/.ssh/ | pbcopy (for mac OS)

On raspberry pi (remote server)
3. Paste the copied content from step 2 into ~/.ssh/authorized_keys (it is the directory by default) or append to the file if existing content available.

Learning source: How to set up ssh so you aren't asked for a password

Feb 7, 2017

Raspberry Pi - The problem about "cannot change locale"

After having problem at configuring Internationalisation to en_US.UTF-8 with raspi-config,
error messages below keep popping up every time I login to my raspberry pi.

-bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
-bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
-bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)

pi@raspberrypi:~ $ locale -a
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_MESSAGES to default locale: No such file or directory
locale: Cannot set LC_COLLATE to default locale: No such file or directory
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
 LANGUAGE = (unset),
 LC_ALL = "en_US.UTF-8",
 LC_CTYPE = "UTF-8",
 LANG = "en_US.UTF-8"
    are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_MESSAGES to default locale: No such file or directory
locale: Cannot set LC_ALL to default locale: No such file or directory
/usr/bin/locale: Cannot set LC_CTYPE to default locale: No such file or directory
/usr/bin/locale: Cannot set LC_MESSAGES to default locale: No such file or directory
/usr/bin/locale: Cannot set LC_ALL to default locale: No such file or directory

And there are bunch of locale warning during my apt-get install which is really annoying even though I am not sure how it does affect my apt-get installation while I still get my installation successful notices.

Raspi-config internationalisation options screen
Every retry of locale change end up here in the error message below, you stuck here forever and that's it!
Change Locale Error
I've tried looking for solution, and I am lucky enough end up in the links at the bottom of this article.
The solution is simple:

  1. sudo nano /etc/locale.gen
  2. uncomment your preferred locale, for example en_US.UTF-8
  3. sudo locale-gen en_US.UTF-8
  4. sudo update-locale en_US.UTF-8

Even though it help getting rid of the annoying 'cannot change locale' or '' error message in your terminal,
it doesn't fix the "There was an error running option I1 Change Locale" issue.
As I tried reconfigure Locale changes, raspi-config will still return me to the same error as in Change Local Error screenshot above.

So until now, I'm still looking for the root cause of this problem.

Solution on StackOverflow - Unable to reconfigure locale in raspberry pi
Original solution source was blog years ago Raspberry Pi -- Fixing your Locale

Dec 30, 2016

Simplified way to get Shairport-sync works in your raspberry pi

The tutorial here is quite straight forward.
Sometimes you do need "fast-track" to get something done right away.

For deep diving purpose, please head to for full (useful) explanation about the setup.

The steps below was tested and might only work for:
- New installation (with no shairport-sync installed before)
- Raspbian (version 8, Jessie) check with cat /etc/os-release
- no external sound card attached (my case)
- tested on streaming through iTune from Macbook (macOS Sierra, 10.12.1)

I'm too will look for the simplest (easiest) approach first, so don't guilt about it, let's get start.
  1. As usual, update your rpi first
    1. sudo apt-get update & sudo apt-get upgrade
    2. sudo rpi-upgrade
  2. Install dependencies,
    1. sudo apt-get install build-essential git autoconf automake libtool libdaemon-dev libasound2-dev libpopt-dev libconfig-dev libpolarssl-dev libssl-dev avahi-daemon libavahi-client-dev
  3. Download/clone shairport-sync and configurations
    1. git clone
    2. cd shairport-sync
    3. autoreconf -i -f
    4. sudo ./configure --sysconfdir=/etc --with-alsa --with-avahi --with-ssl=openssl --with-metadata --with-systemd
    5. sudo make
    6. sudo getent group shairport-sync &>/dev/null || sudo groupadd -r shairport-sync >/dev/null
    7. sudo getent passwd shairport-sync &> /dev/null || sudo useradd -r -M -g shairport-sync -s /usr/bin/nologin -G audio shairport-sync >/dev/null
    8. sudo make install
    9. sudo systemctl enable shairport-sync
    10. sudo update-rc.d shairport-sync defaults 90 10
I've got the shairport-sync working well in my Debian build raspberry pi
And hope to add more explanation about the steps above once I manage to spend more time playing shartport-sync in the rpi.

You should visit the references below:
A guide from setting up WiFi to shairport-sync - Multiroom audio Rpi (2015)
Use of shairport (earlier version of shairport-sync) and mentioned alsamixer - hifi audio via airplay on Rpi (2013)