Raspberry Pi Wifi hotspot

I need my Raspberry Pi to create its own private dedicated Wi-Fi network so that people can connect on it an access some service it provide (like camera broadcast).

To do so I’ve done some search and find out several tutorial to do it (see links at the end of the post). This post is just a sum up of what worked in my case (in case I need to redo it). I strongly suggest to check the links at the end of the article.

The solution rely on 2 software:

  • hostapd
    HostAPD is a user space daemon for access point and authentication servers. That means it can will turn your Raspberry Pi into an access point that other computers can connect to. It will also handle security such that you can setup a WiFi password.
  • isc-dhcp-server
    isc-dhcp-server is the Internet Systems Consortium’s implementation of a DHCP server. A DHCP server is responsible for assigning addresses to computers and devices connection to the WiFi access point.
    Some people use udhcpd which is lighter version

The first thing to do is install the software :

sudo apt-get update
sudo apt-get install isc-dhcp-server hostapd

DHCP configuration

Then configure the DHCP server with 2 files :

  • /etc/default/isc-dhcp-server
#This will make the DHCP server hand out network addresses on the wireless interface
Change “INTERFACES=""” to “INTERFACES="wlan0"”
  • /etc/dhcp/dhcpd.conf

comment the following lines :

option domain-name "example.org";
option domain-name-servers ns1.example.org, ns2.example.org;

make the DHCP as master on the domain by removing the comment at lines


define a network and dhcp config by adding the following block (This configuration will use the Google DNS servers at and )

subnet netmask {
option broadcast-address;
option routers;
default-lease-time 600;
max-lease-time 7200;
option domain-name "local-network";
option domain-name-servers,;

Network interface

Now that the DHCP server is configured we will setup the network card (wifi dongle in our case) with static IP

edit the file :


remove everything related to “wlan0” and past :

allow-hotplug wlan0

iface wlan0 inet static

and now the last configuration step is the hostapd server


create new file:


past :


Be aware of the driver choice : nl8021.

Then the last file to configure :


Find the line #DAEMON_CONF=”” and edit it so it says DAEMON_CONF=”/etc/hostapd/hostapd.conf”

Don’t forget to remove the # in front to activate it!

Then you can test with :

sudo /usr/sbin/hostapd /etc/hostapd/hostapd.conf

If it does not works with an error related to the driver….you need to DL the one made by adafruit (see llinks at the end)


To start the 2 services :

sudo service isc-dhcp-server start
sudo service hostapd-server start

and if you want to start them at boot time :

sudo update-rc.d isc-dhcp-server enable
sudo update-rc.d hostapd enable

Useful links found in my research:

Broadcast Raspberry Pi camera

I need to broadcast the stream of my Raspberry pi camera mounted in front of the train. More info on the “train” project here (part1) and here TODO


This is the results of my search on the possible solutions :


more for security or motion detection

with VLC

The camera stream is send to vlc which forward it over the network

raspivid -o - -t 0 -hf -w 640 -h 360 -fps 25 | cvlc -vvv stream:///dev/stdin --sout '#rtp{sdp=rtsp://:8554}' :demux=h264

-Slow, Delay


Direct capture with the new recent v4l2 driver

cvlc v4l2:///dev/video0 --v4l2-width 1920 --v4l2-height 1080 --v4l2-chroma h264 --sout '#standard{access=http,mux=ts,dst=}'


-Require VLC

with ffmpeg//ffserver


A complete, cross-platform solution to record, convert and stream audio and video.

–The stream is capture and stream by ffmpeg

raspivid -n -vf -hf -t 0 -w 960 -h 540 -fps 25 -b 500000 -o - | ffmpeg -i - -vcodec copy -an -metadata title="Streaming from raspberry pi camera" -f flv $RTMP_URL/$STREAM_KEY

with MJPG streamer

MJPG-streamer takes JPGs from Linux-UVC compatible webcams, file system or other input plugins and streams them as M-JPEG via HTTP to web browsers


with gstreamer

GStreamer is a library for constructing graphs of media-handling components. The applications it supports range from simple Ogg/Vorbis playback, audio/video streaming to complex audio (mixing) and video (non-linear editing) processing.


RPi caminterface

RaspiMJPEG is an OpenMAX-Application based on the mmal-library, which is comparable to RaspiVid. Both applications save the recording formated as H264 into a file



WebRTC is a very powerful standard, modern protocol and gives a number of nicefeatures


-only works with pi2


The project consists primarily of a class (PiCamera) which is a re-implementation of high-level bits of the raspistill and raspivid commands using the ctypes based libmmal header conversion, plus a set of encoder classes which re-implement the encoder callback configuration in the aforementioned binaries. Various classes for specialized applications also exist (PiCameraCircularIO, PiBayerArray, etc.)



avconv is a very fast video and audio converter that can also grab from a live audio/video source. It can also convert between arbitrary sample rates and resize video on the fly with a high quality polyphase filter.



crtmpserver it is a high performance streaming server able to stream (live or recorded)



Not tested



Not tested

Finally I decided to use “RPi caminterface” which has the best feedback. I confirms it works out of the box (which save me lot of times).
I could maybe migrate to “WebRTC UV4L” if I decide to go to a Pi2 in the future…


Here are the links I find during my search :

Electric train hack proto

This will be a very quick post since there is nothing new on this project….except maybe the use of openscad to do the design of the train structure.

Original goal is to have a small electric train running all over the office hanging on the celling. This is the prototype 😉


I simply buy an electric train on Amazon :


Then I rip it apart to understand how it works to be able to hack it.

Train principle

The train itself is very very stupid and is just some metal structure (pretty heavy by the way) with a motor.


The power for the motor comes directly from the rail through the wheels:


The rails on the other side are smarter since there is a control panel to change the train speed/direction.


The principle is thus very simple…..The command panel generate a different tension in the rail to increase/decrease the speed. It can also invert the tension to go revert.

Hack it

I wanted several things:

  • Possibiility to control the train from phone
  • Train should works without a close circuit (in the office we only have one straigt way).

I decided to put the logic in the train rather than the rail. To do so I used an Arduino Micro (same as leonardo but smaller) with a motor controller and a BT receiver. There is nothing new here that I already done/explain in previous project except the motor controller.

The Bluetooth communication with an Android APP is the same software that the one used in this previous project : http://djynet.net/?p=639

The motor controller is the one of Sparkfun (HERE) and can control up to 2 motors. I used it to be able to change the motor rotation direction and speed (with PWM from arduino). This is indeed mandatory because the train will have to go in the 2 directions due to the linear rail circuit (one strait line).

The rails have now a constant tension of 12V from a AC/DC converter which power all the cards. The train is equipped with 2 sensors at front and rear. They are used to detect collision at the end of rail road and change the motor direction to go reverse


The program is pretty simple since it just monitor collision sensor to change direction and serial bus for incoming Bluetooth message.

Finally I needed to put all that on the top of the train base with a nice 3D printed support. This was the good opportunity to try 3D printing. I done the design with OpenScad

Thus it might be the application you are looking for when you are planning to create 3D models of machine parts but pretty sure is not what you are looking for when you are more interested in creating computer-animated movies.

OpenSCAD is not an interactive modeller. Instead it is something like a 3D-compiler that reads in a script file that describes the object and renders the 3D model from this script file.

To sum up….you code your design and then compile it to generate the STL file 😉

I just created a basic shape with the place for the sensor at both end and then upload it on shapeways (a cloud 3D printing service).


It fit perfectly the train and here is the final result once everything is mounted on it:


All the code (Arduino, Android, OpenScad) is available on my bitbucket account here.

Next step…..why not a camera on the train streaming live 😉

Bluetooth Low Energy device and Android communication

Long time I didn’t post an article since I was busy with my move to Boston…..

I was so tired of having to type my Android Password all the time I wanted to use my phone (when listening to music for example) that I decided to do something about it….. Nevertheless I didn’t want to remove the password protection on my phone since it contains lot of important information.

First I decided to have a look on NFC communication to be able to unlock the phone with a NFC card. I didn’t have lot of success with this lead since the NFC module is stop when the device is locked (as far as I understand).

Then I thought about using Bluetooth communication since I already had some experience on BT communication under android (link). I also wanted to have a look on Bluetooth last version “Bluetooth low energy”. It seems a promising technology (Apple Ibeacon, Smartwatch, Activity tracker…). I finally decided to create a service on Android which will detect the BLE devices in range and depending on that can remove/reset the android security policy. Basically if my BLE device is in range the service will remove the android security policy so the phone will no longer require a password. Moreover as soon as the BLE device is no longer in range the service will revert to the previous security policy (see video for concrete example).

I didn’t focus too much on the hardware part which is simply composed of a BLE beacon. To do it I simply used a Arduino Leonardo and a BLE Arduino shield: http://redbearlab.com/bleshield/


The Arduino code is the example provided in the shield library available here

The Android part of the project is composed of 2 parts: BLE interface and Android Device Policy interface.

BLE interface

The first important thing to understand is that the support of BLE is only working fine with Android > 4.4 (the official doc mentioned 4.3 but some people report issue when trying to use 4.3 and BLE). Be sure to use the API >= 4.4.

There is pretty good tutorial on Google Android Website available here : https://developer.android.com/guide/topics/connectivity/bluetooth-le.html

I mainly follow it (with lot of simplification to kept the only necessary step) to dialogue with my BLE device. It would be useless to describe it here but the process is pretty straightforward :

  • Declare valid permission (some website indicate that the BLUETOOTH_ADMIN is only necessary to turn on/off the BT and thus you don’t need it if the BT is already ON….this is correct for BT but not for BLE. )
  • Activate BT if necessary. Similar to the BT process
  • Scan for BLE devices : Don t forget to stop scanning ASAP otherwise it will empty your phone battery. Implement the scan callback (called every time that the scan finds a device
  • Connect to the BLE : BLE connection is different from the usual BT. There is more granularity in the association process due to the fact that the BLE device can expose several different services with different access level. For example the device could let you access public information without any access check and offer private functionality (like administration) with user access control.
  • Register to BLE change : Once connected we also reegister to the BLE device status changes. This will be used by the process to activate (or not) the Android security policy. This is done by implementing the callback “onConnectionStateChange”
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
                Log.i("MyActivity", "onConnectionStateChange");
                if(newState ==  BluetoothProfile.STATE_CONNECTED) {
                    aDeviceInRange = true;
                    Log.i("MyActivity", "Device is in range");
                else {
                    aDeviceInRange = false;
                    Log.i("MyActivity", "Device is not in range");
                runOnUiThread(new Runnable() {
                    public void run() {
                        Log.i("MyActivity", "scanning");
                        TextView t = (TextView)findViewById(R.id.textView4);
                        t.setText("Status : " + String.valueOf(aDeviceInRange));

 Android Device Policy changes

Unlike the BLE connection there is no clear documentation about “how to change android security setting”. If you look for it you will find 2 things : KeyguardManager/KeyguardLock and WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD.

So let’s be clear …. There is no way to do it with the “layout flag”. The best you will achieve is to be able to turn on the phone and display your application but you will not be able to exit your application. If you try to exit your application the OS will ask for the password. That is the best you can do today with this solution.

The other one “KeyguardManager/KeyguardLock” could (or could not) work depending on your luck ! Indeed it has been deprecated since API 13 as explained on the official documentation here : http://developer.android.com/reference/android/app/KeyguardManager.KeyguardLock.html

Hopefully it works fine in my case so I didn’t dig too much for another solution but if it doesn’t works for you I suggest to check the android device administration class available here (but continue reading) : http://developer.android.com/guide/topics/admin/device-admin.html

The lock/unlock code is thus pretty simple with the 2 following functions :

    public void activate_lock() {
        Log.i("MyActivity", "click on activate lock button");
        boolean isAdmin = mDevicePolicyManager.isAdminActive(mComponentName);
        if (isAdmin) {
            boolean result = mDevicePolicyManager.resetPassword("test",DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY);
            KeyguardManager kgManager = (KeyguardManager)getSystemService(Activity.KEYGUARD_SERVICE);
            KeyguardManager.KeyguardLock lock = kgManager.newKeyguardLock(Context.KEYGUARD_SERVICE);
            Toast.makeText(getApplicationContext(), "Not Registered as admin", Toast.LENGTH_SHORT).show();

    public void deactivate_lock() {
        Log.i("MyActivity", "click on remove lock button");
        boolean isAdmin = mDevicePolicyManager.isAdminActive(mComponentName);
        if (isAdmin) {
            KeyguardManager kgManager = (KeyguardManager)getSystemService(Activity.KEYGUARD_SERVICE);
            KeyguardManager.KeyguardLock lock = kgManager.newKeyguardLock(Context.KEYGUARD_SERVICE);
            Toast.makeText(getApplicationContext(), "Not Registered as admin", Toast.LENGTH_SHORT).show();

The full code (not sure it include the last changes done just before I move to Boston) available on my BitBucket account here and a demo video is available on youtube here.

Next steps

None ! indeed I just read an article about android 5.0 and this exact functionality has been integrated on the OS itself so my app is no longer useful. The full article is available on TC : http://techcrunch.com/2014/10/28/android-5-lollipop-security-features/ but it solve the exact same problem as you can see from the abstract below :

Lollipop adds some new lock methods that make it easier to keep your 
device secure, which is a huge boon to the overall integrity of the 
platform. The biggest roadblock to mobile device security is actually 
user apathy, which sees people skipping basic security practices like 
implementing a lock screen pin code because it’s inconvenient when 
you’re checking your device every few minutes. Lollipop offers Smart 
Lock to help address this, which uses paired devices to let you tell 
your device it’s okay to open up without requiring a password or 
other means of authentication.

Bluetooth Arduino for moisture sensor

This WE I wanted to try BT communication with an Arduino…. To have a real project I decided to use a moisture sensor to detect from my phone if my green plant needs some water.



Arduino Board

To do so I bought a sparkfun BT module “Bluetooth Mate Silver” available following this direct link : https://www.sparkfun.com/products/12576

The moisture sensor is pretty standard : http://www.dfrobot.com/index.php?route=product/product&product_id=599#.U8JDQbE39b0

The connection to the BT module is pretty easy with Power (+3.3V, Gnd) and serial Data (Rx BT – Tx Leonardo and Tx BT – Rx Leonardo). As soon as the BT module is powered up it will be visible as a BT module.


On the Arduino side I done a very simple program which will listen on the serial link established with the BT module. Once the Leonardo received a char ‘h’ it will read the humidity sensor value (analog read) and send it back on the BT link. Here is the code :

Created by Charles Walker (charles.walker.37@gmail.com)
 Test program for bluetooth communication
 Tested with Arduino Leonardo and BT module Mate Silver (sparkfun)

void setup()
  //USB Serial port
  //BT module serial port

void loop()
    //We received something on BT module
    char aReceived;
    aReceived = (char)Serial1.read();
    Serial.print("Receveid from BT module :");

    // if we received a read humidity request
    if (aReceived=='h')
      // Reading humidity
      unsigned int aHumidityValue;
      Serial.print("Moisture Sensor Value:");
      // Sending it to the BT module
    //We received something on USB serial line - We will send it to the BT module
    char aToBeSend;
    aToBeSend = (char)Serial.read();
    Serial.print("Going to send :");

    //Sending it to the BT module

The last version is available on bitbucket HERE.

The second part is the Android application which will be able to interact with the Arduino module through BT communication. Before starting coding it I wanted to verify that the Arduino part is working fine.

To do so I download a Arduino App able to communicate over BT. I tried few of them and the best one I find is :


I installed it and then try sending some commands to the Leonardo board.


The application properly connects to the BT module and then we are able to send some commands. The Leonardo only respond to the ‘h’ command which trig moisture read and send it back to the phone.

Android application

First step….. Fix android Studio Beta 0.8 issue….. See : http://djynet.net/?p=652
Android APP creation in a dedicated thread….. See : http://djynet.net/?p=658

Conclusion :

The results with the sensor in moist earth (or not) with the Arduino and Android output.



The whole code for the project (Android and Arduino) is on my bitbucket account here.

EnOcean library example

Following my last article on EnOcean library for Arduino I received some email because the usage example was not good. Indeed I probably didn’t copy past the last version of code so I decided to do a new example (and also improve the library).

This time I will command 1 LED strip using an EnOcean button PTM210. A short click on the button will change the LED strip color to a random one. A long click (more than 2s) turns it off.

Here is the result:

The system requires a strip RGB led, an Arduino Leonardo, an EnOcean TCM 310 receiver and an EnOcean PTM210 emitter (button).

A made few modifications to my first EnOcean library by adding a new variable to check if a message were received on the TCM310. I also add a method to clean the “message” object. The EnOcean library is still available on my bitbucket repo (HERE)

The code is pretty simple. On each loop we check if a new message is available on the TCM310.

void loop() 
  if (_Msg.dataAvailable() == true)

If yes we will either start a timer if it is a button press or take an action if it is a button release. The action depend if the timer is finish or not (to determine if it is a long or short click).

void actionTaker()
  if (_Msg.getPayload() == 0x70)
    Serial.println("The user push the button. Nothing to do appart starting the timer");
    _TimerExpire = false;
    MsTimer2::start(); // active Timer 2 
  else if (_Msg.getPayload() == 0x00)
    Serial.println("The user stop pushing the enocean button");
    if (_TimerExpire == true)
      Serial.println("The user push was more than the timer (long push)");
      Serial.println("The user push was quick (short push)");
    Serial.print("Received an unsupported command : ");

There is also some extra function to determine a rand color and send it to the LED. The whole code is available on bitbucket (HERE)

Librarie EnOcean pour TCM 310 sur Arduino

Suite a mon article sur le décodeur EnOcean j’ai décidé de créer une libraire pour Arduino pour le TCM310.

Le code est extrêmement simple avec une classe “EnOcean” reprenant les éléments de la trame envoyé par le TCM310.

  _dataLength1 = 0;
  _dataLength2 = 0;
  _optLength = 0;
  _packetType = 0;
  _headerCrc8 = 0;
  _org = 0;
  _payload = 0;
  _senderId1 = 0;
  _senderId2 = 0;
  _senderId3 = 0;
  _senderId4 = 0;

Cette classe possède une méthode “decode” qui utilise la lib software de l’arduino pour décoder ce qui arrive sur l USART :

void EnOceanMsg::decode()
while(Serial1.available() > 0)
    uint8_t aChar = Serial1.read();
        case 0:
        if (aChar == START_BYTE) 

        case 1:
        // length msb
        //Serial.print("length msb:");
        //Serial.println(_dataLength1, HEX);

La classe offre également une méthode “pretty print” pour afficher ses éléments (et donc les informations reçu du TCM 310) :

void EnOceanMsg::prettyPrint()
Serial.println("Pretty print start");

char buf1[9];
sprintf(buf1, "%04x", getPacketLength());

Serial.print("Optional length:");

Serial.print("Packet type:0x");
Serial.println(_packetType, HEX);

La dernière version du code de la librairie est disponible sur BitBucket :

Voila un exemple d’utilisation de la lib avec mon interrupteur EnOcean :


EnOceanMsg aMsg;

void setup()
  //Pin 0/1

void loop()
  if (aMsg.getPayload() == 0x50)

Ce qui produira le résultat suivant sur le moniteur série :

Pretty print start
Optional length:7
Packet type:0x1
Sender Id:8ba977
Pretty print end
Pretty print start
Optional length:7
Packet type:0x1
Sender Id:8ba977
Pretty print end

Test Analyseur logique Scanalogic-2 de IKA-LOGIC

Suite a la comparaison des analyseurs logiques realise le mois dernier et disponibles ici :

J’ai décidé de présenter plus précisément le Scanalogic-2 que je me suis offert pour noël. Pour ce test j’ai choisit d’analyser les échanges entre un Arduino Leonardo et un récepteur TCM310 EnOcean.


EnOcean est un groupement industriel qui développe des capteurs fonctionnant sans fils et sans batterie (le capteur utilise l’énergie de son environnement).

Capture du 2014-01-19 11:01:15

Je vous conseil de visiter le site web officiel :

Pour ce test j’ai également acheter un interrupteur compatible EnOcean : le VITA 1001 de VITEC


L’interrupteur est un peu plus “dure” a enfoncer qu’un interrupteur standard car la force de notre appuie va également créer l’énergie nécessaire au circuit embarque qui enverra un signal radio au récepteur TCM310. Le TCM310 enverra ensuite un signal a l’Arduino que nous voulons analyser dans cet article.

Voila le montage complet :


Les branchements entre l’analyseur logique et le système sont :

  • Masse – Masse
  • Ch3 (rouge) – Arduino Rx – TCM310 Tx
  • Ch1 (vert) – Arduino Tx – TCM310 Rx

L’installation de l’analyseur logique est extrêmement simple sous Windows et ne nécessite aucun drivers. Une fois lance il est assez simple d’utilisation puisqu’il suffit de choisir la fréquence échantillonnage et le critère de start (front descendant par exemple). Voila le résultat lors d’un appuie sur l’interrupteur :


On constate donc une communication du module 310 vers l’Arduino lors de l’appuie sur l’interrupteur. Il existe une fonction assez pratique dans le logiciel scanlogic pour afficher les valeur hexa de chaque bytes échangés (visible sur la photo ci dessus). Dans notre exemple la communication commence par 0x55.

Pour mieux comprendre la trame il suffit de jeter un œil a la documentation du protocole EnOcean disponible sur internet et ci dessous :

On trouvera notamment le format standard d’une trame copier ci-dessous :


“As soon as a Sync.-Byte (value 0x55) is identified….” confirme également que nous analysons la bonne trame.

Voila la trame complète récupérée et sa signification obtenue grâce a la documentation :

Value (Hexa) Note
Sync Byte 0x55
Header Data Length 1 0x00
Data Length 2 0x07 Data payload is 7 Bytes
Optional Length 0x07 Opt Data Payload is 7 Bytes
Packet Type 0x01 Type : Radio
CRC8 Header 0x7A OK
Data ORG F6
Sender ID 1 0 Module ID : 008BA977
Sender ID 2 8B
Sender ID 3 A9
Sender ID 4 77
Status 30
Optional Data Number of sub telegram 1 1 sub telegram
Destination (4 bytes) FF Broadcast message
dBm 2D 45 for best RSSI
Security level 0 No encryption
CRC8 Data 3F OK

l’étape suivante est la création d’une libraire Arduino pour décoder la trame et interagir avec le TCM310…… dans un autre post !

Analyseur logique

Je cherche un analyseur logique “pas chère” pour debugger mes montages électroniques. j’ai trouve 3 bons candidats :

Scanalogic-2 de IKA-LOGIC

Prix : 60E

Open Workbench Logic Sniffer de Dangerous Prototypes

Prix : 50$

Logic de Saleae

Prix : 120E

Le Logic semble être un très bon choix mais hors budget 😉 Il existe des clones a 50E mais ils semble que le logiciel officiel les détectes et change leur firmware pour les rendre inutilisables….

Le scanalogic et l OWLS sont sensiblement équivalent (en tout cas pour mes besoins) et j’ai décidé d’essayer la version française 😉

Update des que j’essaye la bête.

Test nouvelle API freebox OS pour arret automatique Wifi

Avec le déploiement du Freebox OS depuis Juin 2013 l’API pour dialoguer avec la Freebox évolue. Heureusement Free offre une très bonne documentation pour utiliser cette nouvelle API :


La documentation est plutôt claire et comporte beaucoup d’exemple.

J’ai décidé de tester cette nouvelle API pour 2 raisons :

  1. Mon système de domotique actuel utilise la Freebox pour le control de la Télé. Pour le moment il utilise la vieille API :
    def sendMsgToFreebox(self,key):
    url = "http://hd1.freebox.fr/pub/remote_control?" + "key=" + key + "&code=59999459"
    logging.error("sending : " + url)
    reponse = urllib.urlopen(url)
    logging.error("reponse : " + str(reponse))

    Cette API sera peut-être remplace par la nouvelle version et je serais donc obliger de migrer

  2. Je veux ajouter le control du wifi sur le système domotique pour pouvoir allumer ou éteindre le wifi. Le but final étant un poil plus complexe.

Je veux créer une application android qui allume le wifi de l’appartement en même temps que le wifi de la tablette. Plus exactement l’application android devra envoyer un message au système domotique pour allumer le wifi. Le système allumera le wifi s’il n’est pas déjà en route.

Ensuite le système domotique monitor le nombre de client utilisant le wifi en temps réel. Il peut également prendre la décision de couper le wifi si aucun client est connecte depuis un certain temps. Le but de cette application est de couper le wifi quand il n’est pas utilisé pour réduire les ondes présentes dans l’appartement.

Dans un second temps je souhaite ajouter un bouton prêt de la Freebox pour pourvoir effectuer une demande d’allumage du wifi (comme le fait l’application android) pour les tablettes qui n’ont pas de connexion 3G et ne peuvent donc pas envoyer la demande d’allumage wifi par la 3G.

L’image ci-dessous résume le flow :


1 – L’utilisateur active le wifi sur sa tablette Wifi/3G. L’application envoie une demande d’activation Wifi au Raspberry Pi en utilisant le réseau 3G


1bis – L’utilisateur appuie sur le bouton d’activation du wifi sur le Raspberry Pi

2 – Le système domotique héberge sur le Raspberry Pi envoie une demande à la Freebox d’activation du wifi si le wifi n’est pas déjà actif

3 – L’utilisateur se connecte automatiquement au wifi et peut maintenant utilise le réseau wifi pour aller sur internet

4 – Le système domotique monitor régulièrement le nombre d’utilisateur wifi. Si le nombre de device est de 0 depuis plus de X temps (1 heure par défaut) le système éteint le wifi de la Freebox en utilisant l’API.

Le système complet ne fonctionne pas encore. Pour le moment j’arrive uniquement à me logger sur la Freebox (système de challenge avec token). Je continuerai les étapes suivantes les WE prochains et j’updaterai l’article. Voila le code actuel :

# -*- coding: utf-8 -*-

import requests
import logging
import time
import itertools
import json
import os
import sys

from hashlib import sha1
import hmac

class FreeboxApplication:
'''Represents an application which interact with freebox server
API doc : http://dev.freebox.fr/sdk/os/'''

def __init__(self):
#I kept the same parameter name than the one use in freebox API for more readability
#To know if the APP is register on freeboxOS side
#Registration parameters

def __repr__(self):
aRetString = ""
aRetString = aRetString + "self.app_id: " + str(self.app_id)
aRetString = aRetString + "self.app_name: " + str(self.app_name)
aRetString = aRetString + "self.app_version: " + str(self.app_version)
aRetString = aRetString + "self.device_name: " + str(self.device_name)
aRetString = aRetString + "self.registerIntoFreeboxServer: " + str(self.registerIntoFreeboxServer)
aRetString = aRetString + "self.app_token: " + str(self.app_token)
aRetString = aRetString + "self.track_id: " + str(self.track_id)
aRetString = aRetString + "self.challenge: " + str(self.challenge)
return aRetString

def getataForRequests(self):
return json.dumps({"app_id": self.app_id,"app_name": self.app_name,"app_version": self.app_version,"device_name": self.device_name})

def loadAppTokenFromFile(self):
if (os.path.isfile("AppToken.txt")):
aAppTokenBackupFile = open("AppToken.txt", "r")
self.app_token = aAppTokenBackupFile.read()
logging.info("APP token read from file. New APP token is : " + str(self.app_token))
logging.info("No file for APP token - request a new one")
#Fin Degeu

def initialLogging(self):
#only once. Register the APP on freebox side
logging.info("Starting initial registration")
aRequestUrl = "http://mafreebox.freebox.fr/api/v1/login/authorize/"
aHeaders = {'Content-type': 'application/json', 'Accept': 'application/json'}

logging.debug("URL used : " + aRequestUrl)
logging.debug("Datas used : " + str(self.getataForRequests()))

aRequestResult = requests.post(aRequestUrl, data=self.getataForRequests(), headers=aHeaders)
logging.debug("Request result : " + str(aRequestResult))
logging.debug("Request result : " + str(aRequestResult.json()))
logging.debug("Registration result : " + str(aRequestResult.json()['success']))

#if (aRequestResult.status_code != "200") or (aRequestResult.json()['success'] != True):
if (aRequestResult.status_code != requests.codes.ok) or (aRequestResult.json()['success'] != True):
logging.critical("Error during intial registration into Freebox Server")
logging.debug("Please go to your Freebox. There should be a message saying that an application request access to freebox API. Please validate the request using the front display")
self.app_token = aRequestResult.json()['result']['app_token']
self.track_id = aRequestResult.json()['result']['track_id']
logging.debug("app_token : " + str(self.app_token))
logging.debug("track_id : " + str(self.track_id))
logging.info("Ending initial registration")

aLoopInd = 0
while ((self.registerIntoFreeboxServer != True) and (aLoopInd < 10)):
time.sleep(15) # Delay for 1 minute (60 seconds)
aLoopInd = aLoopInd + 1
if (self.registerIntoFreeboxServer != True):
logging.critical("Initial registration fails - Exiting with error")
aAppTokenBackupFile = open("AppToken.txt", "w")
#Fin Degeu

def trackRegristration(self):
logging.info("Starting trackRegristration")
aRequestUrl = "http://mafreebox.freebox.fr/api/v1/login/authorize/" + str(self.track_id)
aHeaders = {'Content-type': 'application/json', 'Accept': 'application/json'}

logging.debug("URL used : " + aRequestUrl)

aRequestResult = requests.get(aRequestUrl, headers=aHeaders)
logging.debug("Request result : " + str(aRequestResult))
logging.debug("Request result : " + str(aRequestResult.json()))
if (aRequestResult.status_code != requests.codes.ok):
logging.critical("Error during trackRegristration")
if (aRequestResult.json()['result']['status'] == "granted"):
logging.debug("OK during trackRegristration")
logging.info("APP is correclty registered")
logging.info("Ending trackRegristration")

def logWithPassword(self, iPassword):
#only once. Register the APP on freebox side
logging.info("Starting logWithPassword")
aRequestUrl = "http://mafreebox.freebox.fr/api/v1/login/session/"
aHeaders = {'Content-type': 'application/json', 'Accept': 'application/json'}

logging.debug("URL used : " + aRequestUrl)

aDataToLog = json.dumps({"app_id": self.app_id,"password": iPassword})

logging.debug("Datas used : " + str(aDataToLog))

aRequestResult = requests.post(aRequestUrl, data=aDataToLog, headers=aHeaders)
logging.debug("Request result : " + str(aRequestResult))
logging.debug("Request result : " + str(aRequestResult.json()))
logging.debug("Registration result : " + str(aRequestResult.json()['success']))

#if (aRequestResult.status_code != "200") or (aRequestResult.json()['success'] != True):
if (aRequestResult.status_code != requests.codes.ok) or (aRequestResult.json()['success'] != True):
logging.critical("Error during intial registration into Freebox Server")
logging.debug("You re log")
logging.info("Ending logWithPassword")

def loginProcedure(self):
logging.info("Starting loginProcedure")
aRequestUrl = "http://mafreebox.freebox.fr/api/v1/login/"
aHeaders = {'Content-type': 'application/json', 'Accept': 'application/json'}

logging.debug("URL used : " + aRequestUrl)

aRequestResult = requests.get(aRequestUrl, headers=aHeaders)
logging.debug("Request result : " + str(aRequestResult))
logging.debug("Request result : " + str(aRequestResult.json()))
if (aRequestResult.status_code != requests.codes.ok):
logging.critical("Error during loginProcedure")
if (aRequestResult.json()['success'] == True):
logging.debug("OK during loginProcedure")
logging.info("We have the challenge : " + str(achallenge))
return achallenge
logging.critical("Error during loginProcedure")
logging.info("Ending loginProcedure")

def computePassword(self, iChallenge):
hashed = hmac.new(self.app_token, iChallenge, sha1)
logging.info("Password computed : " + str(hashed.digest().encode('hex')))
return hashed.digest().encode('hex')

def loginfull(self):
aNewChallenge = self.loginProcedure()
#password = hmac-sha1(app_token, challenge)
#voir http://stackoverflow.com/questions/8338661/implementaion-hmac-sha1-in-python
aPassword = self.computePassword(aNewChallenge)

print ("Starting")


#Clean previous log file
with open(aLogFileToUse, 'w'):

logging.basicConfig(filename=aLogFileToUse,level=logging.DEBUG,format='%(asctime)s - %(levelname)s - %(message)s')

aMyApp = FreeboxApplication()


print ("Ending")

L’ensemble du code est dispo sur mon dépôt de domotique.

Update 3 octobre :

Une fois logger on peut utiliser l’API mais il n’y a pas bcp de permission setter a ON par défaut. Il faut mieux aller dans l OS freebox et tout autoriser avant de poursuivre les tests :

FreeboxOs permissions

Ensuite on verifie que les permissions sont bien prise en compte. Pour cela on refait une demande de login et on regarde la reponse :

2013-10-03 19:40:08,070 - DEBUG - Request result : {u'result': 
{u'challenge': u'7IxxxxxxxxxxxwP+cb', u'password_salt': u'uALF+MxxxxxxxxqYi',
 u'permissions': {u'contacts': True, u'settings': True, u'explorer': True,
 u'calls': True, u'downloader': True}, u'session_token': u'K6jjKxxxxxxxxxxxxxxxxxxxxxWCq'}, u'success': True}

Maintenant les permissions sont toutes a True….. On peut continuer. J’ai changer le script pour récupérer la liste des appareils connecte au wifi. J’ai beaucoup de chance car il y a également des infos sur les dernières connexion et je pourrai donc faire un système un peu plus intelligent pour couper le wifi même si il y a des appareil connecte du moment qu ils n’utilisent pas réellement le wifi.

La dernière version est dispo sur mon dépôt de domotique et liste les appareils wifi connecte (et leur nombre). Elle ne coupe/active pas encore le wifi….a suivre