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)
and

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
C
C.UTF-8
POSIX
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 even when the installation is successful.

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.

TL; DR
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 https://github.com/mikebrady/shairport-sync 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 https://github.com/mikebrady/shairport-sync.git
    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)

Oct 27, 2016

Apache not loading PHP after SierraOS upgrade (Homebrew way)

Had a hard time dealing with Apache Server + PHP on my Mac right after SierraOS upgrade.

I use homebrew to get my Mac run with latest PHP7 version instead of directly messing around with the original library come with the SierraOS.

Firstly, the latest update of homebrew, PHP module has no longer installed with Apache.
You need:
brew install php70 --with-apache
in order to download the PHP with libphp7.so 
(this is the file you need when you use apache to load php module)

2nd, after you have Apache downloaded with your PHP through homebrew.
All the manual configurations, by default,
have to be done inside /usr/local/etc/apache2/2.4 (yours might be 2.2, based on your installed version).
Remember those httpd.conf, httpd-vhost.conf, etc... they're all inside the /usr/local/etc/apache2/2.4 folder?

and add a missing media type to your mime_module which it's the most obscure step (to a beginner like me) to missed out during configuration.
AddType application/x-httpd-php .php
Symptom check (whether or not to add the line above):
- php module is loaded correctly, but plain php code still showing in your localhost, for instance, php_info() doesn't work

- your sudo apachectl configtest show nothing wrong "Syntax OK"

Apr 21, 2016

Unit test for Directive with template - AngularJs

As we are adding unit test for directive, its implementation can vary from simple to very complex.
The complex implementation require more knowledge about how to write deeper test in order to get better tested coverage.

To start testing you'll need to start with $compile of DOM element, link function, to angular's controller or anonymous function controller, to template...  

Here are the sources to learn about writing directive's unit test.

  • very interactive and straight forward Directive Unit Testing Guide
  • covered topics
    • "setup karma.config.js"
    • "how to start testing directive", 
    • "working with template" (ng-html2js processor)
  • has more thorough coverage of possible solutions required for Directive unit testing

2) Testing AngularJS directive controllers with Jasmine and Karma (1st tutorial) (2nd tutorial
  • Covered
    • setup sample karma.config.js
    • unit test of anonymous function as controller
    • make use of ng-html2js process
  • The best part of this tutorial is in "2nd tutorial" link, it provided sample of Directive using anonymous function as its controller
    • Testing with anonymous function as controller
      
      angular.directive('myDirective', function() {
        return {
          restrict: 'a',
          controller: function() {} // <--- anonymous controller
        };
      });
      

    • Alternative beside anonymous function as controller
      
      angular
      .controller('myCtrl', function() {})
      .directive('myDirective', function() {
        return {
          restrict: 'a',
          controller: 'myCtrl'
        };
      });
      
3) Testing AngularJS Directives

  • covered simple test of directive on
    • utilise jQlite 
    • unit test of directive's controller from one of the defined angular controller


Possible issue to overcome:

  1. To test a custom validation angular directive
    • unit test of form changes detection

Apr 8, 2016

AngularJs 2 Component: manually bind event listener to element

Sample code of binding element to an onchange event.

import {Directive, ElementRef, Output, EventEmitter, Renderer} from 'angular2/core';

@Directive({
  selector: 'my-comp'
})
export class myComp {
  constructor(el: ElementRef, renderer: Renderer) {
    renderer.listen(el.nativeElement, 'change', event => console.log(event));
  }
}

Stuff you need:
  • directive decorator
  • ElementRef.nativeElement
  • Renderer.listen()

Directive decorator
For my case here, I use directive decorator, because I do not need any template update.
If you are familiar with AngularJs 1.x, this is same as the directive with empty template like short example below:
eg.

angular.directive('myApp', function() {
  return {
    restrict: 'A',
    template: '',
    link: function() { ... }
  };
);


And of course you can choose to import Page, and use it with template like:

import {Page, ElementRef, Output, EventEmitter, Renderer} from 'angular2/core';

@Page({
  selector: 'my-app',
  template: 'Your template goes here'
})

// more code...


ElementRef.nativeElement
The similarity of ElementRef.nativeElement in AngularJs 2 with element parameter in Link() in AngularJs 1.x directive.


angular.directive('myApp', function() {
  return {
    restrict: 'A',
    template: '',
    link: function(scope, element, attributes) {
      // `ElementRef.nativeElement` is almost similar with
      // the `element` parameter in this link() function
    }
  };
);

Renderer.listen() - Angular2 beta 13
Add custom listener to keep track of an event fired, this helps at emitting or initiating additional action.
It works just like how AngularJs 1.x bind an event and initiate its parent's controller function in the scope.
Example AngularJs 1.x below:

angular
.controller('myCtrl', function() {
  scope.onClick = function(event) {
    console.log(event);
  };
})
.directive('myApp', function() {
  return {
    restrict: 'A',
    link: function(scope, element, attributes) {
      // it bind event to element as in Angular 1.x
      $(element).bind('click', function(event) {
        scope.onClick(event);
      });
    }
  };
);


In AngularJs 2, more complete version of the sample code from top which indicate the use of Renderer.listen()

import {
  Directive, 
  ElementRef, 
  Output, 
  EventEmitter, 
  Renderer, 
  Component,
  bootstrap
} from 'angular2/core';

@Directive({
  selector: '[my-comp]'
})
class myComp {
  @Output() click = new EventEmitter();
  constructor(el: ElementRef, renderer: Renderer) { 
    renderer.listen(el.nativeElement, 'click', (event) => {
      this.onClick(event);
    });
  }

  onClick(event){
    this.click.emit({
      value: event
    });
  }
}

@Component({
  template: '<button (click)="showclick($event)" my-comp></button>',
  directives: [myComp]
})
class myApp {
  showClick($event) {
   console.log('changes::', $event);
  }
}
bootstrap(myApp);



Reference/learning source: Dynamically add event listener in Angular 2