DIY Ambilight m.b.v. Raspberry pi, Arduino, Openelec en Hyperion

Ik heb op het internet al vaker iets voorbij zien komen over mensen die hun eigen Ambilight maakten. Ik vond dit altijd al een tof idee maar het is er al die tijd niet van gekomen. Laatst begon het toch weer te kriebelen en heb ik besloten er zelf ook een te bouwen.

Nadat ik alle spullen binnen had ben ik begonnen met het aansturen van de Leds. Dit lukte vrij snel.  Ik kon met behulp van de FastLed library makkelijk wat simpele effecten maken op de led strip.

Mijn TV is aan de achterkant niet mooi vlak. Ik heb daarom een frame gemaakt van aluminium strips met een randje voor extra stevigheid. Het frame heb ik op maat gezaagd en toen aan elkaar gelijmd met secondelijm. Het resultaat is een mooi stevig maar toch licht frame.

Nu was het tijd om de leds op maat te knippen en de stekkertjes er aan te solderen. Omdat ik weinig soldeer ervaring had ging het eerste stukje ging wat lastig maar daarna ging het erg gemakkelijk.

Vervolgens een laagje isolatietape aangebracht op mijn frame omdat ik niet zou willen dat de leds maar op een of andere manier contact zouden maken met het aluminium. Nadat ik de horizontale strips geplaatst had heb ik bij de soldeerpunten nog een stukje tape er overheen geplakt en toen de verticale strips aangebracht.

Daarna twee gaatjes geboord in het frame en met twee M6 bouten gemonteerd aan mijn tv met een PVC koppelstukje er tussen om het frame op zijn plaats te houden. De Arduino zit links in de hoek gemonteerd met een paar tie-wraps. Vanaf die hoek worden ook de leds gevoed / aangestuurd. Inmiddels is de blauwe USB kabel vervangen door een zwarte van 1~1.5 meter. Ik heb nu dus maar twee kabels naar mijn TV lopen, de voeding van de leds en de USB voor de Arduino. De rest van alle spullen kan ik mooi 1.5e meter verder verstoppen.

Close-up van de Arduino. Ik heb nog een simpele case besteld uit China dus de Arduino gaat straks nog wat mooier weggewerkt worden.

Dit is de rest van de opstelling (voor nu). De Pi2 word gevoed door mijn 5v voeding. Mijn oude Pi1 voeding gaf te weinig power en dit is toch weer een stekker minder. Ik heb een 100watt 16A voeding maar volgens mijn energiemeter was dat toch wel overkill. Met 4 meter leds (60 leds p.m.) kwam ik op 40 watt uit (volledige sterkte wit licht, zonder Pi). Ik heb nu 3 meter leds en met de Pi + AV-grabber, etc straks zal ik ook wel weer rond de 40 watt maximaal uit komen. De dikke zwarte kabel gaat dus naar de leds toe. In de Pi zit een netwerkkabel en de USB kabel naar de Arduino.

En dit is hoe het er nu uitziet. Ik moet de kleuren wel nog wat bij stellen omdat ze niet helemaal overeenkomen met de kleuren van de TV maar het systeem werkt echt fantastisch. Ben er echt super blij mee. Ik was toch redelijk verbaast hoe goed het werkt.

Klik verder voor een installatie handleiding die ik geschreven heb mocht je zelf ook interesse gekregen hebben om zelf een Ambilight TV te knutselen. Er zijn tegenwoordig ook meer klant en klaar oplossingen zoals Ambivision en Lightberry.

Read More

Ubuntu 15.04 pam_mount

Onder Ubuntu 15.04 merkte ik dat de snelheden die ik haalde met lezen / schrijven naar mijn netwerk shares echt enorm laag waren (30 MB/s). Na van alles getest te hebben kwam ik er achter dat het waarschijnlijk ligt aan gvfs waarmee Ubuntu standaard de shares mount. Zoekende naar een oplossing kwam ik op pam_mount terecht. Nu haal ik snelheden van +/-80 MB/s.

Met behulp van pam_mount kun je tijdens het inloggen andere schijven / netwerk shares mounten met de zelfde gebruikersnaam / wachtwoord combinatie waarmee je inlogt. Het installeren van pam_mount gaat als volgt:

Installer pam_mount en cifs-utils. Die laatste is nodig als je een netwerk share wil mounten.

sudo apt-get install libpam-mount cifs-utils

Nu moeten we in het onderstaande bestand enkele wijzigingen doorvoeren.

sudo nano /etc/security/pam_mount.conf.xml

Haal de commentaar regels om de volgende regel weg.

<luserconf name=".pam_mount.conf.xml" />

Hiermee zorg je dat elke gebruiker zijn eigen configuratie bestand voor pam_mount kan maken. Indien je voor iedereen dezelfde configuratie wilt gebruiken kun je de betreffende regels ook onder aan in dit bestand kwijt.

Voor extra beveiliging kun je de opties file_mode en dir_mode toevoegen aan mntoptions

<mntoptions allow="nosuid,nodev,loop,encryption,fsck,nonempty,allow_root,allow_other,dir_mode,file_mode" />

Optioneel
Indien je home-dir encrypted is moeten we nog een extra aanpassing doen. Standaard word pam_mount namelijk uitgevoerd voordat je home-dir gedecrypt is. Hierdoor kan het configuratie bestand niet gelezen worden en word er dus ook niets gemount.

Wijzig de volgende twee bestanden.

/etc/pam.d/common-auth
/etc/pam.d/common-session

Zorg er in deze bestanden voor dat de pam_moun.so regel onder de pam_encryptfs.so regel staat.

auth    optional       pam_ecryptfs.so unwrap
auth    optional       pam_mount.so

Als laatste moeten we pam_mount vertellen wat hij precies moet gaan mounten en waar. Dit doen we met een bestandje in je home-dir. Zet hier de onderstaande xml code in en wijzig deze naar jouw eigen voorkeuren. Indien je dir_mode en file_mode in de eerdere stap toegevoegd hebt dien je die hier ook weer te gebruiken. De mode 0700 zorgt er voor dat jij de enige bent die in de gemounte share kan lezen / schrijven.

nano ~/.pam_mount.conf.xml
<?xml version="1.0" encoding="utf-8" ?>
<pam_mount>
    <volume
        options="nodev,nosuid,file_mode=0700,dir_mode=0700"
        user="*"
        mountpoint="/media/%(USER)/websites"
        server="nas"
        path="websites"
        fstype="cifs" />
</pam_mount>
  • user=”*” Geeft aan welke gebruikers de share mogen mounten. * is een wildcard voor alle gebruikers.
  • mountpoint=”” is het pad waar je schijf / share gemount wordt. Ik heb hier de variabele %(USER) gebruikt. Deze wordt gevuld met je ingevulde gebruikersnaam. In mijn geval wordt het dus /media/roy/websites
  • server=”” nas is het adres van mijn server. Hier kan ook een ip adres staan.
  • fstype=”cifs” cifs geeft aan dat het om een netwerk share gaat.

Reboot je PC en als het goed is zijn je schijven direct gemount na het inloggen. Mocht het niet zo zijn kun je de debug functie inschakelen in /etc/security/pam_mount.conf.xml . De logs worden dan geschreven naar /var/log/auth.log .

Samba performance

Er is veel te vinden over de performance van samba verbeteren. De volgende instellingen werken voor mij het beste. Plaats de volgende instellingen onder de [global] sectie van /etc/samba/smb.conf

# performance tuning
socket options = TCP_NODELAY IPTOS_LOWDELAY SO_RCVBUF=65536 SO_SNDBUF=65536
use sendfile = Yes
getwd cache = Yes
min receivefile size = 16384
use sendfile = true
aio read size = 16384
aio write size = 16384

CakePHP en gigabyte vs gibibyte

Iedereen kent het wel. Je koopt een harde schijf van 3 TB, je stopt hem in je PC en ineens is hij nog maar +/-2.7 TB. Wanneer fabrikanten / besturingssystemen de juiste eenheden zouden gebruiken zou dit al een stuk duidelijker zijn.  Voor meer informatie hierover zie Wikipedia.

CakePHP haalt GB en GiB helaas ook door elkaar in de CakeNumber en de NumberHelper class en ik stoorde me daaraan. De oplossing is simpel maar het werkt perfect.

In app/Lib/ van je CakePHP project maak je een nieuw bestand aan genaamd FixedCakeNumber.php. Hierin plaats je de volgende code:

<?php
App::uses('CakeNumber', 'Utility');

class FixedCakeNumber extends CakeNumber {
    
    public static function toReadableSize($size, $si = false) {
        $units = array(1 => 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y');
        
        // defaut values
        $divider = ($si) ? 1000: 1024;
        $binString = ($si) ? '' : 'i';
        
        // exception for byte(s)
        if ($size < pow($divider, $power)) {
            return __dn('cake', '%d Byte', '%d Bytes', $size, $size);
        }

        // caculate size
        $size = max($size, 0); 
        $power = floor(($size ? log($size) : 0) / log($divider)); 
        $power = min($power, count($units) - 1);
        $size = round($size / pow($divider, $power), 2);

        return __d('cake', '%s ' . $units[$power] . $binString . 'B', $size);
    }
}

Nu moeten we een nieuwe Helper aanmaken die gebruikt maakt van de bovenstaande class. Maak een nieuw bestand aan in app/View/Helper/ genaamt FixedNumberHelper.php. Plaats daar de volgende code in:

<?php
App::uses('FixedCakeNumber', 'Lib');
App::uses('NumberHelper', 'View/Helper');

class FixedNumberHelper extends NumberHelper {

    public function __construct(View $View, $settings = array()) {
        parent::__construct($View, $settings);
        $this->_engine = new FixedCakeNumber($settings);
    }
    
    public function toReadableSize($size, $si = false) {
        return $this->_engine->toReadableSize($size, $si);
    }
}

Vervolgens kun je in je controller de helper aanroepen met de volgende regel:

<?php
public $helpers = array('FixedNumber', 'Html', 'Etc');

In je view blijft niets veranderd en kun je de (Fixed)NumberHelper op de normale manier blijven gebruiken. Eventueel kun je, wanneer je dat zou willen. Gebruik maken van de SI eenheid door als tweede parameter true mee te geven.

<?php 
$size = 1000 * 1000 * 1000 * 1000; // 1 TB
echo $this->Number->toReadableSize($size); // output: 931.32 GiB
echo $this->Number->toReadableSize($size, true); // output: 1.00 TB

Automatisch SASS compilen

SASS heeft veel weg van LESS wat vooral door Twitter gebruikt wordt maar het schijnt iets beter te zijn.  Het is een manier van CSS code schrijven waarbij de CSS syntax gevolgd wordt maar waarmee je ineens toegang krijgt tot variabelen, functies en meer. Het enige nadeel is dat je SASS (.scss) bestanden wel nog moet omzetten naar CSS.  Daar is een handig programmaatje voor maar die moet je dan nog steeds elke keer dat je een aanpassing doet handmatig uitvoeren. Om dat op te lossen heb ik een klein Bash script gemaakt.

Dit script maakt gebruik van inotify en sassc en is getest onder Ubuntu 14.04. Om inotify te installeren voer je het volgende uit:

sudo apt-get install inotify-tools

sassc installeren is iets moeilijker want die moet je zelf compilen. Voor zover ik me herinner heb ik daar deze tutorial voor gevolgd.

Dit is het script wat ik gemaakt hebt. Deze kun je in principe overal neerzetten. Sla dit script op als scss2css.sh en voer een "chmod +x scss2css.sh" uit. Pas de dir= regel aan naar de map waar je sass/css code in staat.

#!/bin/bash
dir='/var/www/http_docs/'
sassc='/usr/local/bin/sassc'

inotifywait -m -r -e modify,close_write,create,moved_to,move --format %w%f $dir | while read scss_filepath; do 
    filename=$(basename "$scss_filepath")
    extension="${filename##*.}"

    if [[ "$extension" == "scss" ]]; then
        if  [[ ! $filename =~ ^_ ]]; then
            css_filepath=${scss_filepath/.scss/.css}
            $("$sassc" "$scss_filepath" "$css_filepath")
        else
            filename=${filename:1}
            filename=${filename/.scss/}
            files=$(grep -clRE --include=*.scss "import.*$filename" "$dir")

            for scss_filepath in $files; do
                css_filepath=${scss_filepath/.scss/.css}
                $("$sassc" "$scss_filepath" "$css_filepath")
            done

        fi
    fi
done

exit 0

Als laatste is het natuurlijk handig als het script tijdens het booten gestart word. Dit kan door een aanpassing in /etc/rc.local. Voeg daar deze regel aan toe:

su www-data --shell=/bin/bash -c '/var/www/scss2css.sh  > /dev/null 2>&1 &'