Une interface web pour contrôler le bus KNX sur Raspberry Pi

Raspberry Pi logo

Raspberry Pi logo

Pour reprendre mes différents articles sur le bus KNX, j’ai décidé de passer mon projet sur Raspberry pour vérifier que mes lignes de commandes sont toujours d’actualitées, effectuer un point sur ce que j’ai fait, pouvoir partager le schmilblick.

En plus d’être à la mode, le Raspberry Pi a un très belle avenir dans la domotique !

Comme ce blog est rédigé au fil de mes découvertes du KNX, j’ai essayé de synthétiser mon article sur la prise de contrôle du bus via jQuery.
A savoir que ce qui suit peut également être refait sur du i386…

Objectif

Re-partir de zéro et d’arriver à une interface web permettant d’allumer/éteindre une lumière et de régler sa luminosité (TXA213).
Pouvoir lire et écrire à tout va sur le bus KNX ; l’état des élèments soit lisible et modifiable, un max de souplesse !

La base

Dans un premier temps, je pars sur une base de Raspbian wheezy (sans démarrage de X11) – de très bon tutoriaux existent sur la toile – puis c’est parti pour l’installation d’eibnetmux sur Raspberry.
Pourquoi eibnetmux et pas eibd ? Parce qu’au fur et à mesure de l’utilisation je trouve personnellement qu’eibnetmux est plus simple d’utilisation, plus complet, mieux fini.

# sudo passwd
# su
# apt-get update
# apt-get dist-upgrade
# apt-get install build-essential

Coté Raspberry Pi, je fais tout en root, ajoutez vos outils préférés, nano, vim, alias, etc…

Coté KNX je dispose simplement d’un module HAGER TXA213 : 3 sorties variables 300W
Deux groupes d’adresses :
0/0/1 : sortie 1 → On/Off + indication d’état
0/0/2 : sortie 1 → Valeur d’éclairement + indicateur valeur d’éclairement.

Note : C’est un exemple de groupe d’adresses, apriori, j’ai lu qu’il est préférable de séparer l’indication d’état de  la commande on/off, sans savoir pour quelle raison.

Ainsi que du classique : une alimentation KNX, un routeur IP/KNX et son alimentation dédiée.

Schéma de base KNX

Schéma de base KNX

Téléchargement et installation de Zlogger

Quelques libraires nécessaires pour l’installation :

# apt-get install libpth20 libpth-dev libpolarssl0 pkg-config pth-dbg

Zlogger 1.5.0 est nécessaire au fonctionnement d’eibnetmux.

# cd /usr/src/
# wget "http://downloads.sourceforge.net/project/zlogger/zlogger/1.5.0/zlogger-1.5.0.tar.bz2?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fzlogger%2F&ts=1334692716&use_mirror=freefr" -O zlogger-1.5.0.tar.bz2
# tar xfv zlogger-1.5.0.tar.bz2
# cd zlogger-1.5.0
# ./configure --with-plugins --enable-pth-plugins
# make
# make install
# ldconfig

Télechargement et installation d’eibnetmux

Plus de détails dans l’article dédié à eibnetmux et eibd.
La version d’eibnetmux est la dernière disponible selon le site de son auteur via sourceforge.

Pour utliser eibnetmux avec php, celui-ci est nécessaire*.

# apt-get install php5 php5-dev php-pear

* Merci à jjay pour ces infos en commentaires

Puis on installe eibnetmux

# cd /usr/src/
# wget "http://downloads.sourceforge.net/project/eibnetmux/eibnetmux/2.0.1/eibnetmux-2.0.1.tar.gz?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Feibnetmux%2Ffiles%2Feibnetmux%2F2.0.1%2F&ts=1334739400&use_mirror=netcologne" -O eibnetmux-2.0.1.tar.gz
# tar zxvf eibnetmux-2.0.1.tar.gz
# cd eibnetmux-2.0.1
# ./configure --enable-php
# make
# make install
# ldconfig

On récupère et installe le « Sample client applications » ; ce package contient les fichiers PHP nécessaires pour un lire et écrire sur le bus KNX..

Il contient également les commandes de bases équivalentes à groupread, groupwrite, groupswrite, groupsocketlisten, etc…

# cd /usr/src/
# wget "http://downloads.sourceforge.net/project/eibnetmux/Sample%20client%20applications/1.7.1/eibnetmuxclientsamples-1.7.1.tar.gz?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Feibnetmux%2Ffiles%2FSample%2520client%2520applications%2F1.7.1%2F&ts=1361557458&use_mirror=freefr" -O eibnetmuxclientsamples-1.7.1.tar
# tar xvf eibnetmuxclientsamples-1.7.1.tar
# cd eibnetmuxclientsamples-1.7.1

Pause !
Une grosse modification apportée à un fichier, il s’agit du fichier eibtrace/eibtrace.c :
J’ai modifié le fichier pour retourner à une syntaxe plus simple à traiter :

eibtrace.c

J’ai également ajouté un « fflush(stdout);« , sans cet ajout, eibtrace ne parvient pas à rediriger stdout vers un fichier. Et comme le C++ et moi, ça fait deux, je me contente de cette rustine…

Et on compile les scripts d’exemples d’eibnetmux.

# ./configure
# make
# make install

Le petit souci étant que je n’ai pas trouvé l’astuce pour compiler directement dans /usr/local/bin ou équivalent.
Alors en attendant …

# cp eibcommand/eibcommand /usr/local/bin/
# cp eibmultiread/eibmultiread /usr/local/bin/
# cp eibread/eibread /usr/local/bin/
# cp eibstatus/eibstatus /usr/local/bin/
# cp eibtrace/eibtrace /usr/local/bin/
# cp firereads/firereads /usr/local/bin/
# cp readmemory/readmemory /usr/local/bin/
# cp resetdevice/resetdevice /usr/local/bin/
# cp search/search /usr/local/bin/
# cp writememory/writememory /usr/local/bin/

eibtrace est l’équivalent de groupsocketlisten d’eibd.
eibcommand est l’équivalent groupwrite d’eibd.
eibread est l’équivalent groupread d’eibd.
A noter que groupread, groupwrite, groupswrite, groupsocketlisten et compagnie sont compatible avec eibnetmux.

La librairie PHP se trouve /usr/src/eibnetmux-2.0.1/client_lib/php/eibnetmux.php et les commandes getstatus.php readgroup.php writegroup.php dans /usr/src/eibnetmuxclientsamples-1.7.1/php , je me garde ça sous le coude pour l’instant.

Test intermédiaire de lecture du bus KNX

Il est temps de tester eibnetmux, et ses commandes.
L’IP de mon interface IP/KNX est 192.168.0.51.

# eibnetmux -s -t -u -e -d --pidfile=/var/run/eibnetmux.pid 192.168.0.51 
# ps aux | grep eibnetmux
root 1993 0.0 0.0 3152 912 ? Ss 17:02 0:00 eibnetmux -s -t -u -e -d --pidfile=/var/run/eibnetmux.pid 192.168.0.51
root 2067 0.0 0.0 4060 820 pts/0 S+ 17:20 0:00 grep eibnetmux

Tâchons d’écouter ce qu’il se passe sur le bus :

# eibtrace 127.0.0.1
Connection to eibnetmux '127.0.0.1' established

Puis dans un autre shell, allumons et éteignons la lumière (groupe d’adresse 0/0/1 comme indiqué au début) :

# eibcommand -s 127.0.0.1 0/0/1 1 1
# eibcommand -s 127.0.0.1 0/0/1 1 0

Ce qui renvoit dans notre eibtrace :

2013/04/18 22:38:45:640 – phys addr: 0.2.189 – IND low W group addr: 0/0/1 – value: 1 | 1 | 1 | 1 (81 – eis types: 1, 2, 7, 8)
2013/04/18 22:38:45:686 – phys addr: 1.1.2 – IND low W group addr: 0/0/1 – value: 1 | 1 | 1 | 1 (81 – eis types: 1, 2, 7, 8)
2013/04/18 22:38:45:741 – phys addr: 1.1.2 – IND low W group addr: 0/0/2 – value: 65 | 168 (a8 – eis types: 6, 14)

Puis

2013/04/18 22:38:54:278 – phys addr: 0.2.189 – IND low W group addr: 0/0/1 – value: 0 | 0 | 0 | 0 (80 – eis types: 1, 2, 7, 8)
2013/04/18 22:38:54:366 – phys addr: 1.1.2 – IND low W group addr: 0/0/1 – value: 0 | 0 | 0 | 0 (80 – eis types: 1, 2, 7, 8)
2013/04/18 22:38:54:432 – phys addr: 1.1.2 – IND low W group addr: 0/0/2 – value: 0 | 0 (00 – eis types: 6, 14)

A noter, que sans modifier le ficher eibtrace.c avant sa compilation, nous aurions eu ceci :

2013/04/14 17:28:43:570 – 0.2.189 IND low W 0/0/1 : on | 1 | 1 | 1 (81 – eis types: 1, 2, 7, 8)
2013/04/14 17:28:43:614 – 1.1.2 IND low W 0/0/1 : on | 1 | 1 | 1 (81 – eis types: 1, 2, 7, 8)
2013/04/14 17:28:43:671 – 1.1.2 IND low W 0/0/2 : 65% | 168 (a8 – eis types: 6, 14)

Puis

2013/04/14 17:29:07:316 – 0.2.189 IND low W 0/0/1 : off | 0 | 0 | 0 (80 – eis types: 1, 2, 7, 8)
2013/04/14 17:29:07:403 – 1.1.2 IND low W 0/0/1 : off | 0 | 0 | 0 (80 – eis types: 1, 2, 7, 8)
2013/04/14 17:29:07:480 – 1.1.2 IND low W 0/0/2 : 0% | 0 (00 – eis types: 6, 14)

Pensez à faire un killall eibnetmux.
Bravo, on vient de faire un groupswrite : eibcommand -s <serveur> <group address> <type eis> <valeur>

Avec eibtrace, on trace les valeurs lues sur le bus KNX, lampe allumée, variateur à 65%, puis lampe éteinte, variateur à 0%.
0.2.189 correspond à ma passerelle IP/KNX, 1.1.2 à mon TXA213.
Si l’ordre provient d’un interrupteur, le phénomène est identique.

Ecoute du bus avec eibtrace

Ecoute du bus avec eibtrace

La suite consiste à avaler puis digérer ces valeurs.

Absorbtion des valeurs du bux KNX

J’ai besoin de php5 + mysql-server et tant qu’à faire, apache 2 pour la visualisation des lumières :

# apt-get install php5 php5-cli php5-mysql libapache2-mod-php5 php5-dev apache2 mysql-server php-pear

Normalement, une partie de ces paquets devraient déjà être installé avec l’installation d’eibnetmux.

Mon mot de passe mysql pour suivre cet article : dbpass

Pour les plus « doués », je conseille quelque chose de plus léger qu’Apache2 sur Raspberry Pi, genre Lighttpd, Cherokee, Hiawatha.

Le script d’ init.d pour eibnetmux s’illustre d’une particularité à la ligne 41, en plus de démarrer eibnetmux sur mon interface IP Siemens N146 5WG1 146-1AB01 (192.168.0.51), il lance en fond de tâche un « eibtrace 127.0.0.1 » vers le fichier /tmp/eibtrace . Tout ce qui se passera à partir de l’exécution d’eibnetmux sera loggé dans le fichier /tmp/eibtrace .
Note : sans l’ajout de « fflush(stdout); » sans eibtrace.c, la redirection stdout ne fonctionne pas.

# vi /etc/init.d/eibnetmux

Qui contient :

#! /bin/sh
### BEGIN INIT INFO
# Provides: eibnetmux
# Required-Start: mysql
# Required-Stop: mysql
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start eibnetmux service at the end of boot
# Description: This services is for communications with knx/eib.
### END INIT INFO

# by Lionel @ domolio.fr

PATH=/sbin:/usr/sbin:/bin:/usr/bin
NAME=eibnetmux
DAEMON=/usr/local/bin/eibnetmux
DAEMON_ARGS="-s -t -u -e -d --pidfile=/var/run/eibnetmux.pid 192.168.0.51"
PIDFILE=/var/run/eibnetmux.pid

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions

if [ ! -x $DAEMON ]; then
 echo "eibnetmux appears to be uninstalled."
fi

#
# Function that starts the daemon/service
#
do_start()
{
echo -n "Starting eibnetmux"
/usr/local/bin/eibnetmux $DAEMON_ARGS
echo " done"
sleep 2
echo -n "Starting eibtrace"
/usr/local/bin/eibtrace 127.0.0.1 > /tmp/eibtrace &
echo " done"
}

do_stop()
{
echo -n "Stoping eibnetmux"
PID=`cat $PIDFILE`
kill $PID &> /dev/null
echo " done"
}

#
# Function that stops the daemon/service
#

case "$1" in
 start)
 do_start
 ;;
 stop)
 do_stop
 ;;
 restart)
 do_stop
 sleep 1
 do_start
 ;;
 status)
 pid=$(pidofproc -p $PIDFILE $DAEMON)
 ret=$?
 pid=${pid% } # pidofproc() supplies a trailing space, strip it

if [ $ret -eq 0 ]; then
 echo "eibnetmux is running (PID: $pid)"
 exit 0
 elif [ $ret -eq 1 ] || [ $ret -eq 2 ]; then
 echo "eibnetmux is dead, although $PIDFILE exists."
 exit 1
 elif [ $ret -eq 3 ]; then
 echo "eibnetmux is not running."
 exit 3
 fi
 echo "sais pas"
 ;;
 *)
 echo "usage: $0 {start|stop|restart|status}"
 exit 1
esac
# chmod +x /etc/init.d/eibnetmux
# insserv eibnetmux

A ce stade, j’ai un raspberry capable d’écouter et de commander mon bus KNX, je vais y rajouter ma sauce « home made » pour lire et écrire comme je l’entends.
Je le fais en PHP, parce que c’est un des seuls languages que je connais 🙂
J’installe le paquet php-pear afin d’installer System_Daemon pour me permettre de daemoniser un script PHP et d’avoir des logs.

# pear install -f System_Daemon

Lire le très bon article de Kevin van Zonneveld : Create daemon in PHP.

Le principe

Une fonction forte utile : tail ; bien connue des utilisateurs UNIX, mais pour l’utiliser en PHP, j’utilise le script dispo sur le book php : http://php.net/manual/fr/function.inotify-init.php
Comme signalé dans le premier commentaire, le résultat est identique à un « tail -f » exécuté dans un shell.
J’avais déjà utilisé la commande unix logtail pour arriver à mes fins dans un script permettant de commander un bandeau LED RGB via KNX, toujours en exploitant les logs.
Communication entre un bus KNX et un serveur linux, avec cette fonction PHP, c’est plus propre.

Ces deux outils vont me permettre de faire de mon script un vrai « service » sur mon Rapsberry Pi.
Il va me permettre d’avoir des logs, un service propre à la communication KNX ↔ Raspberry Pi.

Le but étant d’écouter tout ce qui se passe sur le bus (via eibtrace) et de l’écrire dans un fichier.

Eibtrace log dans un fichier

Eibtrace log dans un fichier

Puis, de « parser » ce fichier pour que chaque action qui nous intéresse soit retranscrite dans une table MySQL.
Vient enfin une page qui consulte cette base MySQL, donc : l’état de mes intervenants KNX.

Nous devons installer l’extention php inotify, puis l’activer :

# pecl install inotify
# vi /etc/php5/conf.d/30-inotify.ini

Pour y insérer :

extension=inotify.so

Mise en place

Structure de la base de données

Pourquoi faire simple quand on peut faire compliquer ?
Par souplesse, je split mes données en 2 tables :
– La première regroupe les Group Address → knx_ga .
– La secondes regroupe les EIS possible → knx_eis.

Ma base s’appelle domy.
Un mysqldump :

--
-- Table structure for table `knx_ga`
--

DROP TABLE IF EXISTS `knx_ga`;
CREATE TABLE `knx_ga` (
  `ga_id` int(3) NOT NULL AUTO_INCREMENT,
  `ga_groupaddress` tinytext NOT NULL,
  `ga_eis_id` int(3) NOT NULL,
  `ga_name` mediumtext NOT NULL,
  `ga_value` text NOT NULL,
  `ga_comment` text NOT NULL,
  PRIMARY KEY (`ga_id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;

--
-- Table structure for table `knx_eis`
--

DROP TABLE IF EXISTS `knx_eis`;
CREATE TABLE `knx_eis` (
  `eis_id` int(3) NOT NULL AUTO_INCREMENT,
  `eis_code` tinytext NOT NULL,
  `eis_num` int(3) NOT NULL,
  `eis_type` tinytext NOT NULL,
  PRIMARY KEY (`eis_id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
--
-- Dumping data for table `knx_eis`
--

LOCK TABLES `knx_eis` WRITE;
/*!40000 ALTER TABLE `knx_eis` DISABLE KEYS */;
INSERT INTO `knx_eis` VALUES (1,'1.001',1,'Off / Off'),(2,'5.001',2,'Pourcentage');
/*!40000 ALTER TABLE `knx_eis` ENABLE KEYS */;
UNLOCK TABLES;

La table knx_eis contient le numéro de type d’eis, le type de datapoint, et un petit commentaire.
Une fois importé, je renseigne mon premier Group Address du bux KNX, le 0/0/1, correspondant au On/Off + indicateur d’état.

INSERT INTO `domy`.`knx_ga` (`ga_id`, `ga_groupaddress`, `ga_eis_id`, `ga_name`, `ga_value`, `ga_comment`) VALUES (NULL, '0/0/1', '1', 'lampe1_onoff', '0', 'Lampe 1');

Idem avec mon GA 0/0/2, correspondant à la valeur d’éclairage, pour rappel, il s’agit d’un variateur TXA213.

INSERT INTO `domy`.`knx_ga` (`ga_id`, `ga_groupaddress`, `ga_eis_id`, `ga_name`, `ga_value`, `ga_comment`) VALUES (NULL, '0/0/2', '2', 'lampe1_eclairage', '0', 'Lampe 1 : valeur éclairement');

Le champs de la table qui va changer, c’est ga_value, il passera à 1 lorsque la lumière est allumée, à 0 lorsqu’elle est éteinte.
Pour l’éclairage, une valeur entre 0 et 100.
Et voila, les racines sont là, il reste à remplir ces données et les exploiter.

knx-tail2mysql : parcourir l’activité du bus KNX vers table MySQL

Vous mélangez le script System_Daemon + Log Tail + un peu de MySQL pour obtenir ce script (pensez à cliquer pour tout dérouler)

# touch /usr/local/bin/knx-tail2mysql
# chmod +x /usr/local/bin/knx-tail2mysql
# vi /usr/local/bin/knx-tail2mysql

Script qui contient :

#!/usr/bin/php -q
<?php
// --------------------------------------
// --       Daemonise PHP script       --
// --------------------------------------
// D'après http://kvz.io/blog/2009/01/09/create-daemons-in-php/
// Allowed arguments & their defaults
 
$runmode = array(
    'no-daemon' => false,
    'help' => false,
    'write-initd' => false,
);
 
// Scan command line attributes for allowed arguments
foreach ($argv as $k=>$arg) {
    if (substr($arg, 0, 2) == '--' && isset($runmode[substr($arg, 2)])) {
        $runmode[substr($arg, 2)] = true;
    }
}

// Help mode. Shows allowed argumentents and quit directly
if ($runmode['help'] == true) {
    echo 'Usage: '.$argv[0].' [runmode]' . "\n";
    echo 'Available runmodes:' . "\n";
    foreach ($runmode as $runmod=>$val) {
        echo ' --'.$runmod . "\n";
    }
    die();
}

// Make it possible to test in source directory
// This is for PEAR developers only
ini_set('include_path', ini_get('include_path').':..');

// Include Class
error_reporting(E_STRICT);
require_once 'System/Daemon.php';

// Setup
$options = array(
    'appName' => 'knx-tail2mysql',
    'appDir' => dirname(__FILE__),
    'appDescription' => 'Parses KNX logfiles and stores them in MySQL',
    'authorName' => 'Lionel',
    'authorEmail' => 'lionel@chocolio.com',
    'sysMaxExecutionTime' => '0',
    'sysMaxInputTime' => '0',
    'sysMemoryLimit' => '1024M',
    'appRunAsGID' => 0,
    'appRunAsUID' => 0,
);

System_Daemon::setOptions($options);

// This program can also be run in the forground with runmode --no-daemon
if (!$runmode['no-daemon']) {
    // Spawn Daemon
    System_Daemon::start();
}

// With the runmode --write-initd, this program can automatically write a
// system startup file called: 'init.d'
// This will make sure your daemon will be started on reboot
if (!$runmode['write-initd']) {
    System_Daemon::info('not writing an init.d script this time');
} else {
    if (($initd_location = System_Daemon::writeAutoRun()) === false) {
        System_Daemon::notice('unable to write init.d script');
    } else {
        System_Daemon::info(
            'sucessfully written startup script: %s',
            $initd_location
        );
    }
}

// --------------------------------------
// --            function tail         --
// --------------------------------------

// D'après http://php.net/manual/fr/function.inotify-init.php

function tail($file,&$pos) {
    // get the size of the file
    if(!$pos) $pos = filesize($file);
    // Open an inotify instance
    $fd = inotify_init();
    // Watch $file for changes.
    $watch_descriptor = inotify_add_watch($fd, $file, IN_ALL_EVENTS);
    // Loop forever (breaks are below)
    while (true) {
        // Read events (inotify_read is blocking!)
        $events = inotify_read($fd);
        // Loop though the events which occured
        foreach ($events as $event=>$evdetails) {
            // React on the event type
            switch (true) {
                // File was modified
                case ($evdetails['mask'] & IN_MODIFY):
                    // Stop watching $file for changes
                    inotify_rm_watch($fd, $watch_descriptor);
                    // Close the inotify instance
                    fclose($fd);
                    // open the file
                    $fp = fopen($file,'r');
                    if (!$fp) return false;
                    // seek to the last EOF position
                    fseek($fp,$pos);
                    // read until EOF
                    while (!feof($fp)) {
                        $buf .= fread($fp,8192);
                    }
                    // save the new EOF to $pos
                    $pos = ftell($fp); // (remember: $pos is called by reference)
                    // close the file pointer
                    fclose($fp);
                    // return the new data and leave the function
                    return $buf;
                    // be a nice guy and program good code <img class="wp-smiley" alt=";-)" src="https://www.domolio.fr/wp-includes/images/smilies/icon_wink.gif" />
                    break;
                    // File was moved or deleted
                case ($evdetails['mask'] & IN_MOVE):
                case ($evdetails['mask'] & IN_MOVE_SELF):
                case ($evdetails['mask'] & IN_DELETE):
                case ($evdetails['mask'] & IN_DELETE_SELF):
                    // Stop watching $file for changes
                    inotify_rm_watch($fd, $watch_descriptor);
                    // Close the inotify instance
                    fclose($fd);
                    // Return a failure
                    return false;
                    break;
            }
        }
    }
}

// ------------------------------------------
// --      MON CODE PERSO COMMENCE ICI     --
// ------------------------------------------

// Connexion avec la base de données mysql
// Egalement possible de faire un include
$MYSQLHOST      = "localhost";
$MYSQLLOGIN     = "root";
$MYSQLPWD       = "dbpass";
$MYSQLBASE      = "domy";
$db = mysql_connect($MYSQLHOST, $MYSQLLOGIN, $MYSQLPWD);
$mysql=mysql_select_db($MYSQLBASE,$db);

if ($mysql!=1) {
  System_Daemon::notice('La connection avec la base de données a échoué.');
  exit();
}

// ---
// D'après http://stackoverflow.com/questions/9668299/extract-part-of-string-with-php
function get_string_between($string, $start, $end){
    $string = " ".$string;
    $ini = strpos($string,$start);
    if ($ini == 0) return "";
    $ini += strlen($start);
    $len = strpos($string,$end,$ini) - $ini;
    return trim(substr($string,$ini,$len));
}

// ---
// Quels sont les GA à surveiller ?

$req_sel_ga     = "SELECT ga_id,ga_groupaddress FROM knx_ga";
$qur_sel_ga     = mysql_query($req_sel_ga) or die (mysql_error());
$ga_bdd         = array();
while($dat_sel_ga = mysql_fetch_array($qur_sel_ga)) {
        $ga_id          = $dat_sel_ga['ga_id'];
        $ga_groupaddress        = $dat_sel_ga['ga_groupaddress'];
        $ga_bdd[$ga_groupaddress]       = $ga_id;
}
// ---

// ---
// parse/tail du fichier du eibtrace
$lastpos = 0;
while (true) {
	// On tail le fichier de log
	$knxlisten = tail("/tmp/eibtrace",$lastpos);
	// On réagit dès qu'on a un Write
	// Pour chaque ligne, on récupère le Groupe d'Addresse et de la valeur qu'on converti
	System_Daemon::notice($knxlisten);
	$groupaddr	= get_string_between($knxlisten,'group addr: ',' -');
	$value		= get_string_between($knxlisten,'value: ',' |');
	System_Daemon::notice("GA : ".$groupaddr." | VALUE : ".$value);
	// on regarde si ca fait partit des elements à surveiller
	if (array_key_exists($groupaddr, $ga_bdd)) {
                        // la valeur associé = l'id dans la BDD
                        $ga_id_update   = $ga_bdd[$groupaddr];
                        //System_Daemon::info($groupaddr." est à surveiller. Mise à jour de sa valeur dans la BDD");
                        System_Daemon::info($groupaddr." -> ".$value);
                        $req_sel_ga_update      = "UPDATE knx_ga SET ga_value = '$value' WHERE ga_id = $ga_id_update";
                        //System_Daemon::info("Requete SQL -> ".$req_sel_ga_update);
                        // Et on update la BDD
                        mysql_query($req_sel_ga_update);
                }
}

?>

Ici, les informations de connexion à la base MySQL sont en dur, à partir de la ligne 143.
On notera le chemin du fichier à parser à la ligne 186.

Egalement ici, on se rend compte de modifier eibtrace, par simplicité, en effet, une ligne de log se présente ainsi :
2013/04/18 22:38:45:741 – phys addr:    1.1.2 – IND low    W group addr:    0/0/2 value: 65 | 168 (a8  – eis types: 6, 14)
Le script récupère ce qu’il y’a entre « group addr » et « « , puis entre « value: » et « |« . Plus simple …

Un petit test … Il est nécessaire d’avoir le script init.d/eibnetmux de lancé avec eibtrace qui redirige vers /tmp/eibtrace.

# knx-tail2mysql
[Apr 14 22:53:22] notice: Starting knx-tail2mysql daemon, output in: '/var/log/knx-tail2mysql.log'
# cat /var/log/knx-tail2mysql.log
[Apr 14 22:53:22] notice: Starting knx-tail2mysql daemon, output in: '/var/log/knx-tail2mysql.log'
[Apr 14 22:53:22] info: Changed identify to 'root':'root'
[Apr 14 22:53:22] info: not writing an init.d script this time

Tout va bien … Tuez le processus si il est en fond de tâche.

Script de démarrage

Le script se lance en tant que daemon, pour ne pas oublier, faisons un petit init.d script et le logrotate:

# knx-tail2mysql --write-initd

Et il vous pond un script init.d ! magique !

# vi /etc/init.d/knx-tail2mysql

Une petite modification malgré tout, afin de s’assurer que le parse du fichier de traces se lance après que la connexion au bus soit effective, et donc fichier crée.
Sans quoi, il se lance avant même que mysql ne soit lancé…

# Required-Start:    $remote_fs
# Required-Stop:     $remote_fs

Deviens :

# Required-Start:    eibnetmux
# Required-Stop:     eibnetmux

Et on l’installe en tant que script de démarrage :

# insserv knx-tail2mysql

Logrotate

Coté logrotate, l’on crée un script dans le dossier /etc/logrotate.d/ qui sera automatiquement traité quotidiennement, généralement à 06h25.

# vi /etc/logrotate.d/knx-tail2mysql

Contient :

/var/log/knx-tail2mysql.log {
        weekly
        missingok
        rotate 12
        compress
        delaycompress
        notifempty
        sharedscripts
        postrotate
                /etc/init.d/knx-tail2mysql restart > /dev/null
        endscript
}
# ls -lh /var/log/knx-tail2mysql.log*
-rw-r--r-- 1 root root 449 févr. 21 00:20 /var/log/knx-tail2mysql.log
# logrotate -f /etc/logrotate.d/knx-tail2mysql
# ls -lh /var/log/knx-tail2mysql.log*
-rw-r--r-- 1 root root 306 févr. 21 00:21 /var/log/knx-tail2mysql.log
-rw-r--r-- 1 root root 449 févr. 21 00:20 /var/log/knx-tail2mysql.log.1

L’on passe d’un fichier à deux fichiers, les suivants seront compressés, ce logrotate fonctionne.

Essai d’exécution

Eibtrace doit être en route en fond de tâche (les scripts précédents le lance en même temps qu ‘eibnetmux), avec écriture de la trace dans le fichier /tmp/eibtrace .
Un petit init 6 c’est bien aussi.
On lance knx-tail2mysql et on vérifie qu’un processus tourne en fond de tâche :

# knx-tail2mysql
[Apr 14 23:33:27] notice: Starting knx-tail2mysql daemon, output in: '/var/log/knx-tail2mysql.log'
# ps aux | grep knx-tail2mysql
root 3163 0.2 0.4 39608 5004 pts/0 S 23:33 0:00 /usr/bin/php -q /usr/local/bin/knx-tail2mysql
root 3168 0.0 0.0 4060 816 pts/0 S+ 23:33 0:00 grep knx-tail2mysql

Process en fond de tâche : OK

Si ce n’est pas le cas, et que aucune erreur n’est donnée dans le fichier de log, c’est peut-être que vous n’avez pas activé l’extension inotify.ini.
Pour débugger davantage, placer des System_Daemon::notice(« bla bla bla »);

J’allume ma lampe, en ligne de commande, via un interupteur, le résultat est le même.

# eibcommand -s 127.0.0.1 0/0/1 1 1
# cat /tmp/eibtrace
2013/04/18 22:58:57:598 - phys addr: 0.2.189 - IND low W group addr: 0/0/1 - value: 1 | 1 | 1 | 1 (81 - eis types: 1, 2, 7, 8)
2013/04/18 22:58:57:651 - phys addr: 1.1.2 - IND low W group addr: 0/0/1 - value: 1 | 1 | 1 | 1 (81 - eis types: 1, 2, 7, 8)
2013/04/18 22:58:57:708 - phys addr: 1.1.2 - IND low W group addr: 0/0/2 - value: 65 | 168 (a8 - eis types: 6, 14)

Trace dans le fichier : OK

Normalement, la table s’est mise à jour.

# mysql -pdbpass domy -e "SELECT ga_groupaddress,ga_value FROM knx_ga;"
+-------------------+-------------+
| ga_groupaddress   | ga_value   |
+-------------------+-------------+
| 0/0/1             | 1          |
| 0/0/2             | 65         |
+-------------------+-------------+

Trace dans le fichier : OK

Si la table MySQL ne se met pas à jour, mais que le fichier /tmp/eibtrace est à jour, consulter le fichier de log /var/log/knx-tail2mysql.log :

warning: [PHP Warning] filesize(): stat failed for /tmp/eibtrace [l:86]
warning: [PHP Warning] inotify_add_watch(): No such file or directory [l:90]

Alors que le fichier existe et que knx-tail2mysql tourne.
C’est probablement que l’ordre initialisation des scripts est incorrect.

OK, OK, OK ! L’extinction de la lampe, même effet, parfait, on continue !

Schema avec knx-tail2mysql

Schema avec knx-tail2mysql

Visualisation et contrôle par interface web

A ce stade, on a une table MySQL qui se met à jour selon l’état des actionneurs.
Qu’est-ce qui permet d’afficher en quasi-instantanné le contenu des champs MySQL ?
L’ajax voyons ! Tant mieux, je suis nul en AJAX !

Dans le cadre de gestion du lumière, il y’a 3 actions principales, donc 3 scripts vitaux :
– Récupérer l’état on/off ou la valeur d’éclairage.
– Envoyer un toggle on/off.
– Envoyer une valeur d’éclairage.

Je n’ai pas de volet roulant ou de gestion de chauffage, évidemment, plus il y’a de types d’élements, plus ça se complique ; j’ai voulu séparer dans une autre table les EIS pour cette raison , mais pour l’instant on va s’appliquer à allumer, éteindre et changer la valeur d’éclairage de mon ampoule sur le Hager TXA213.

J’ai choisi d’utiliser jQuery pour communiquer en AJAX, et ainsi profiter de la librairie JQuery-UI pour ce qui est graphique, slider, etc…
jQuery me permettra de travailler avec des noms pour appeler mes lumière, lamp1_onoff, lampe1_eclairage, lampe2cuisine_onoff, etc.. d’où le champs ga_name dans la table knx_ga.
Puis jQuery me permettra également d’utiliser JQuery Mobile pour les mêmes fonctions mais sur mobile.
J’utilise une classe PHP pour débugger, c’est écrit par Joe Fallon et ça s’appel PopupPhpDebug.

Deux div ID, l’un pour une image on/off, l’autre pour un slider avec la valeur d’éclairage.

Les fichiers sont téléchargables ici :
– Pensez à supprimer votre index.html dans /var/www/
– Conservez les droits www-data:www-data sur les fichiers et répertoires.

Telecharger

Je ne vais pas faire de cours de PHP, juste expliquer les grandes lignes du fonctionnement de mon interface web.

De l’AJAX pour piloter une lumière

Un simple div pour une simple lumière :

<img id="toggle_light-lampe1_onoff" alt="chargement" src="images/loading.gif" />

Dans l’attribut id :
toggle_ : sert de préfixe, tout ce qui est toggle_ correspond à une lumière.
lampe1_onoff : nom de la correspondance via ma table MySQL -> 0/0/1 dans ce cas.
Ainsi, autant toggle_* qu’il a de lumière.

Dans le même principe :

<div id="slider-lampe1_eclairage"></div>
<div id="text-lampe1_eclairage" align="center"></div>

slider-* pour un slider à les valeurs variables.
text-* pour afficher la valeur.

Interface jQuery pour KNX

Interface jQuery pour KNX

Et pour contrôler tout ça :


$(function() {
var intervalrefresh = 1000;

// fonction qui recupere la valeur d'un objet selon le nom du GA
$.get_light_value = function(light_name) {
 var result = null
 $.ajax({
 url: 'ajax/knx-get_light_value.php',
 data: 'ga_name='+light_name,
 dataType: 'json',
 async: false,
 success: function(data) {
 result = data['value'];
 //console.log("Valeur de : "+light_name+" -> "+result );
 }
 });
 return result;
}

// fonction qui toggle la valeur d'un object son le nom du GA (on/off)
$.set_light_toggle = function(light_name) {
 $.ajax({
 url: 'ajax/knx-set_light_toggle.php',
 data: 'ga_name='+light_name,
 dataType: 'json',
 async: false,
 success: function(data) {
 //console.log("Mise à jour de : "+light_name);
 }
 });
}

// fonction qui envois une valeur à un GA
$.set_light_value = function(light_name,value) {
 $.ajax({
 url: 'ajax/knx-set_light_value.php',
 data: 'ga_name='+light_name+'&ga_value='+value,
 dataType: 'json',
 async: false,
 success: function(data) {
 //console.log("Mise à jour de : "+light_name);
 }
 });
}

$(document).ready(function(){
 var refreshId = setInterval( function(){

// Refresh des lights
 $('[id^="toggle_light-"]').each(function() {
 var light_name_split = $(this).attr('id').split('-');
 var light_name = light_name_split[1];
 var light_value = $.get_light_value(light_name);
 if (light_value == 1) $('#toggle_light-'+light_name).attr('src',"images/lampes-on.png");
 if (light_value == 0) $('#toggle_light-'+light_name).attr('src',"images/lampes-off.png");
 });

// Refresh des sliders
 $('[id^="slider-"]').each(function() {
 var light_name_split = $(this).attr('id').split('-');
 var light_name = light_name_split[1];
 var light_value = $.get_light_value(light_name);
 $(this).slider( "option", "value", light_value);
 $('#text-'+light_name).html(light_value+"%");

});

}, intervalrefresh);
});

// mise à jour du bus KNX après mouvement du slider
 $('[id^="slider-"]').each(function() {
 var light_name_split = $(this).attr('id').split('-');
 var light_name = light_name_split[1];
 $(this).slider({
 max: 100,
 min: 0,
 stop: function(event,ui) {
 //console.log("nouvelle valeur du slider : "+ui.value);
 $.set_light_value(light_name,ui.value);
 }
 });
 });

// mise à jour des lumières après un click
 $('[id^="toggle_light-"]').click(function() {
 var light_name_split = $(this).attr('id').split('-');
 var light_name = light_name_split[1];
 $.set_light_toggle(light_name);
 });

// fin
});

Oula !
En gros, ça dit que toutes les 1000 ms secondes (1 seconde), pour chaque div qui commence par toggle_ d’executer le fichier ajax/knx-get_light_value.php , qui lui contient (via des includes et functions) une requête MySQL pour chercher la valeur correspondante en base.
Si c’est égal à 1, ça affiche une ampoule jaune, si c’est égal à 0, ça affiche une ampoule grise.
Idem pour le slider, on place le curseur à la valeur correspondante avec affichage sous forme texte.

Tandis qu’un click sur une ampoule, donc un div, a pour action d’exécuter le fichier ajax/knx-set_light_toggle.php , qui lui contient une récupèration de la valeur en base, il l’inverse, et l’applique sur le bus KNX.
Il l’applique sur le bus KNX via la librairie eibnetmux.php, souvenez vous, nous avions compilé eibnetmux avec les librairies PHP, c’est justement là qu’elle nous sert !

Le retour d’état de l’actionneur se fait par le cheminement eibtrace, knx-tail2mysql, ajax ; pas de « mise à jour directe », on évite ainsi les erreurs possibles, mais du coup, l’image s’actualise au pire qu’une seconde plus tard (+ temps de traitement de l’info), d’où le « quasi-instantanné ».

Schéma interaction KNX avec PHP

Schéma interaction KNX avec PHP

Ca marche bien !

Firebug pour surveiller l'AJAX

Firebug pour surveiller l’AJAX

La console firebug permet de visualiser les transactions AJAX -> MySQL, rajoutez des debugs si nécessaire.
Il est possible de diminuer les 1000ms pour obtenir plus de réactivité, c’est au serveur MySQL de pouvoir encaisser.

On peut également faire de l’image mapping sur une photo, grace à des outils tel que http://www.image-maps.com on définit un rectangle sur une lampe, modifie le code HTML pour placer notre « id ».

Créez votre map

Créez votre map

L’outil sert surtout pour créer la zonne au bon endroit.
Le code modifié :

<img id="Image-Maps_8201304191538462" alt="" src="http://www.image-maps.com/uploaded_files/8201304191538462_sketchup.png" usemap="#Image-Maps_8201304191538462" width="716" height="531" border="0" />
<map id="_Image-Maps_8201304191538462" name="Image-Maps_8201304191538462">
<area id="toggle_light-lampe1_onoff" title="Allumer/eteindre" alt="Allumer/eteindre" coords="510,143,579,266" shape="rect" />
</map>

Et un clique sur l’abat-jour de l’image éteind/allume la lumière.

Click pour allumer/eteindre

Click pour allumer/eteindre

Il doit certaiement être possible de modifier l’image de cette petite lampe pour qu’elle paraisse allumée.
Un autre exemple plus généraliste des maps sur image en CSS : cssplay.co.uk .

Les limites de la gestion de la maison deviennent celles du graphisme web, du moment où on a accès à l’état des éléments KNX, qu’on peut les piloter, techniquement c’est presque sans limite ; il faut savoir s’y faire ergonomiquement, c’est essentiel.

Interface mobile pour téléphone et tablette

Pour l’instant, c’est très brouillon, pas d’AJAX, je pars du principe que si je contrôle ma maison avec mon smartphone, c’est parce que je ne suis pas chez moi, donc pas de rafraichissement instantanné.
J’utilise jQuery Mobile, une demo est disponible sur le site officiel.
Mon utilisation est celle d’un formulaire traité en PHP classique, pas très au point pour l’instant, mais fonctionnel pour un début.

Il me semble qu’il est possible de convertir un site web en application iphone/android, il faut que je retrouve le nom de cet outil.
A terme, le tout protégé par htacces ou authentification php.

Inteface mobile

Inteface mobile

Rendu et réactivité

Une vidéo afin de se rendre compte de la réactivité du click et de la remonté d ‘infos, malgré l’utilisation d’une webcam de piètre qualité, avec une mise à niveau de la luminosité catastrophique, je n’ai pas trouvé mieux pour filmer la réaction du click sur la lampe.

Conclusion

Mon but étant d’arriver à contrôler l’installation domotique depuis un serveur par une interface web, c’est en bonne voie  !

Quelques points à approfondir lorsque j’aurai une installation KNX réele et complète :
– Groupe d’adresse différente entre l’état et l’action ? Vraiment ? Reste à voir comment gérer ça.
– Gestion des autres EIS : volets, BSO, chauffage, etc…
– Ajout d’intelligence avec du 1-wire.
– Une interface web ergonomiquement parfaite.

C’est relativement réactif, j’en attends pas plus pour l’instant.

Je n’utilise aucun cache EIBD, voir les commentaires sur l’article Se passer de linknx et webknx2 une fausse bonne idee ?

C’est donc une bonne base pour une plateforme de contrôle et supervision du bus KNX, j’ai hâte d’approfondir sur une installation réel .

Téléchargement

Je met à disposition une image de la carte SD de mon Raspberry Pi.
Attention, c’est très lourd : 7,42 Go. Sauvegardé avec Win32DiskImager, vous devriez pouvoir restaurer avec le même outil.

Mot de passe root : pi
Mot de passe MySQL : dbpass

Telechargerraspberry-domolio-knx.img : 7,42 Go
MD5 : 81a8df6724fea6c8916f6a8e814b908f

Have fun !

Ce billet est posté dans Debian, KNX, php, Web. Mettre en favoris le permalien.

47 réponses à Une interface web pour contrôler le bus KNX sur Raspberry Pi

  1. Arsiesis says:

    Hello,

    J’ai la réponse à ceci :

    Note : C’est un exemple de groupe d’adresses, apriori, j’ai lu qu’il est préférable de séparer l’indication d’état de la commande on/off, sans savoir pour quelle raison.

    Car tu double le nombre de télégramme qui circule sur le bus…
    ex: si tu envoi un télégramme pour allumer une lampe (télégramme ON) la lampe te renvoi un télégramme car elle a changer d’état… jusque la, cela ne semble pas gênant ?!

    Mais imagine à présent ce qu’il ce passe lorsque tu utilise la même configuration pour toute les lampes de la maison et que tu fait un all off ?!
    Tu envoi un télégramme de commande off, tu as 40 lampes qui s’éteigne et donc qui renvoi chacune un télégramme car elle ont changé d’état … en fonction du nombre de lampe et de ta topologie, tu pourrais rapidement saturer ton bus …

    Encore bravo pour ce que tu fais, je suis fan !

    • olvs says:

      salut moi qui fait beaucoup de knx, mais pas de raspberry encore, la séparation des adresses de groupe permet de faire ce que l’on en veut, exemple l’adresse on/off permet de transmettre l’ordre a la lampe de s’allumer ou pas, son indication d’état (I on/off), permet de savoir en fait si elle est allumer ou pas sans être dans la pièce, et donc permet sur un voyant d’un interrupteur ou sur un smartphone, pc ou tablette, de les mettre a l’état d’allumer ou pas, très pratique lorsque va se coucher d’avoir un témoin lumineux sur un inter de tête de lit si un volet, une lampe ou une porte de garage est encore ouvert ou allumé et la on éteint et ferme tout avec une seule touche.

  2. Jean-Marc says:

    Bravo pour le travail et les tutos ! Vraiment du splendide boulot dont je vais m’inspirer pour faire mon outil de visualisation

    P.S. On dit schmilblick 🙂

  3. seb says:

    Bonjour,

    Super tuto, merci pour le partag.
    Etant allergique aux lignes de cmd j’aimerai télecharger l’image de 7Gà mais le lien ne fonctionne pas, le fichier fait 0ko.

    Peux tu reposter? Merci

  4. Lionel says:

    Hello,

    Merci pour le retour, et désolé pour l’attente, le lien de téléchargement est corrigé.

    • Baptiste says:

      Salut Lionel j’ai testé ton tutoriel et il marche nickel pour l’installation domotique que j’ai à faire, j’aurai voulu savoir au niveau de la base Mysql si il y avait possibilité que la table se mette a jour toute seule et qu’on ne soit pas obliger de rentrer les composants a la main ou si cela est obligé ?
      Autre information dans ton tuto tu dit que l’utilisation d’ETS3 est obligatoire, cela marche aussi avec ETS4 =)

      Merci d’avance

      • Lionel says:

        Salut,

        Content que l’article t’ai servi, ce n’est pas evident de partager quelque chose de technique dans ce domaine, une simple installation devient vite une usine à gaz, trop personnalisée pour être partagée.

        Au niveau de la BDD, humm, perso je n’ai rien prévu pour un remplissage auto, c’est vrai qu’avec le peu de module dont je dispose actuellement, je n’ai pas 200 GA à saisir.
        Je ne verrais même pas trop comment faire.
        Peut-être en exploitant un export d’un projet ETS.
        Cool si ça marche avec ETS4 ! C’est vraiment une bonne nouvelle ! Je vais essayer ça cette semaine 😉

        • Baptiste says:

          C’est vrai qu’une installation comme ça devient vite un bordel si on n’est pas organisé. Moi non plus je n’ai pas tellement de modules et il est vrai que une fois la syntaxe rentrée il est facile de rajouter des participants, mais une possibilité de remplissage auto ne serait pas de refus =)
          Après j’avais une question au niveau de l’Ajax, es ce compliqué ou dur à mettre en place où es ce que avec tes données je peux facilement l’adapté aux miennes ?

          Merci d’avance

          • Lionel says:

            Compliqué, non, enfin ça dépend de ce que tu souhaites adapter.

            Par exemple, pour l’icone d’une lampe à cliquer pour allumer/éteindre.
            J’ai mis ce jquery :

            # <img id="toggle_light-lampe1_onoff" alt="chargement" src="images/loading.gif" />

            Dans l’attribut id :
            – toggle_ : sert de préfixe, tout ce qui est toggle_ correspond à une lumière.
            – lampe1_onoff : nom de la correspondance via ma table MySQL -> 0/0/1 dans ce cas.
            Ainsi, autant toggle_* qu’il a de lumière.

          • Baptiste says:

            Je vois le principe tu associe un bouton lampe a ta table mysql qui va chercher l’état de ta lampe et le retranscrit en web, et y’a moyen d’interagir dessus ?
            Dans mon cas c’est une supervision d’une salle de réunion j’aurai des lampes, des volets de la clim ..
            Je pense que c’est sur le même principe que les lampes.

            Je vais tester ça rapidement et te tien au courant =)
            Merci à toi

          • Baptiste says:

            Je viens de tester de faire un icône de type lampe comme le tiens pour un bandeau, il est sous la GA 1/1/5 mais quand je remplace les champs dans l’index.php sur le site j’ai un chargement continuel, j’aimerai déjà faire le test avec ce bandeau lumineux de type on/off une solution ? ou idée ?

  5. seb says:

    Merci pour le nouveau lien.
    Image dl et installée. Raspberry demarré, accés via putty-> login et psw trouvé 🙂
    serveur web fonctionnel.
    Bref les débuts sont prometteurs, nickel.

    • seb says:

      Une question de base:
      Quel est le fichier (avec le chemin) à modifier pour changer le GA de la lumière?
      Merci.

      • Lionel says:

        C’est en base de donnée MySQL.

        Le mieux est d’installer phpmyadmin, le mot de passe root de cette image de raspberry : pi
        Le mot de passe mysql : dbpass

        su
        apt-get update
        apt-get install phpmyadmin
        durant l’installation, cocher « apache2 ».
        saisir le mot de passe « dbpass » lorsque demandé.
        http://ipduraspberry/phpmyadmin/
        login : root
        mdp : dbpass
        aller dans la database domy, table knx_ga, afficher et modifier les champs souhaité

        Ou directement en ligne de commande :
        mysql -pdbpass domy -e « UPDATE knx_ga SET ga_groupaddress=’0/45/126′ where ga_id=1; »
        Où 0/45/126 est le numéro de GA souhaité.

        Je rencontre pas mal de difficulté avec cette image de Raspberry Pi en raison du peu de place qu’il reste. :-/

        • Ishika says:

          yes,not sure if i should post code here but while ($row = mysql_fetch_assoc($res)){ $sql= slecet count(*) as num_replies from `forum_replies` where `tid`=’ .$row[‘id’]. ;is what looks like the important part that could be screwing it up.

  6. steph says:

    salut,

    la question qui me reste en tête est la question des lampes type SPOT LED.
    -Il y a celles qui sont en 12V par le biais d’un tranfo.
    -Il y a celles qui sont en 220V.

    Si on souhaite varier la lumière pour ces deux cas, comment procède t-on ?
    aurais-tu déjà essayé ?

    En plus aujourd’hui les SPOT LED dimmable 220V se démocratisent..
    merci

    • Lionel says:

      Salut,

      Pour le spots LED à faire varier, c’est le TXA213N.
      TXA213 (donc non ‘N’) est incompatible avec les LED.

      J’en ai parlé récement avec l’electricien, si je ne me trompe pas :
      – Dans le cas de LED en 12V, on fait varier l’entrée du transfo 220V qui fait varier le 12V.
      – Dans le cas de LEV en 220V, on fait varier le 220V, comme si c’était du filament.
      Tant que la LED est certifiée dimmable, bien sûr.

      Pas encore essayé, je n’ai pas de TXA213N (arghh!) que tu TXA213.
      Ma construction avance doucement, j’aurai enfin du concret domotique en mars/avril.

  7. wxop says:

    J’ai lu pas mal d’article sur ton blog, et je pense utiliser pas mal de tes idees notamment pour le bus 1-Wire.. Merci pour le partage !

    Comme je vois que tu fais aussi dans l’interface Web en php, je voulais te faire part de phpMyDomo que j’ai justement créé pour ca: c’est prévu pour fonctionner avec n’importe quelle Serveur domotique, et c’est a priori tres simple de developper un plugin pour causer avec un serveur HomeMade. En gros tu fait ton serveur perso qui cause en json, et hop phpMydomo te fournit une interface propre, facilement customizable, et tout de suite fonctionnelle.. Si ca peut t’aider dans ton projet… 😉

    Bonne continuation

  8. maarten says:

    First of all, thx for the tutorial. It is very clear and easy to follow.

    Because I had the problem I wasn’t able to read the output fast enough with the php service i piped the output of eibtrace directly to php so no need for the whole tail and php service section.

    Instead of using:
    echo ‐n "Starting eibtrace"
    /usr/local/bin/eibtrace 127.0.0.1 > /tmp/eibtrace &

    in the /etc/init.d/eibnetmux file I use:
    echo ‐n "Starting eibtrace"
    /usr/local/bin/eibtrace 127.0.0.1 | php -F /var/www/log.php &

    This way I can catch the output directly in php and update the db.

    The code in /var/www/log.php is:

    #!/usr/bin/php -q


    « get_string_between » & « updateGroup » are in the file commandInclude.php. You must check if they already exist because the -F parameter runs the script for every command and otherwise you get the « cannot redeclare function » error.
    « updateGroup » is the function where I do my db insertion.

    Mabey this is usefull for someone who is having the same problems as me.

    Greetings.

    • maarten says:

      something went wrong with my previsous post: here is the code of /var/www/log.php

      #!/usr/bin/php -q

      <php

      //eibtrace 127.0.0.1 | php -F /var/www/log.php

      if( !function_exists('get_string_between') ){
      require("commandInclude.php");
      }
      //print_r($argn);

      $groupaddr = get_string_between($argn,'group addr: ',' -');
      $value = get_string_between($argn,'value: ',' |');
      updateGroup($groupaddr,$value);

  9. Baptiste says:

    Hello j’ai un problème je viens de rajouter un participant dans ma table mysql qui est état d’un store et il ne me le met pas a jour sachant que dans le /tmp il est a jour et que quand je fais un eibread il me renvoi la bonne valeur, une solution ?

    • Lionel says:

      Hello,

      Redemarre le script knx-tail2mysql ( /etc/init.d/knx-tail2mysql restart )
      Les GA a mettre à jour dans la BDD MySQL sont récupérés uniquement au démarrage de ce script (a améliorer)

      Tu peux surveiller ton log : /var/log/knx-tail2mysql.log
      Et si toujours pas bon, rendre le script un peu plus bavard en décommantant les « System_Daemon::info »

  10. Baptiste says:

    Super ça marche nikel, ben je l’ai rajouté dans mon script pour avoir un rendu visuel de ce tableau dans un de mes partages, classé avec la date d’aujourd’hui si ça intéresse quelqu’un

  11. Baptiste says:

    Sous ma raspberry j’ai changé le nom de la machine dans Hostname mais au redémarrage mon eibnetmux ne se lance plus:

    Connect to eibnetmux failed (-15): EIBnetmux not running on host (or socketserver not activated)

    Quelqu’un peut m’aider ?

  12. Migui says:

    Bonjour

    J’aimerrai tester mais
    Je n’arrive pas a telecharger l’image domolio pour raspberry

    Merci d’avance

  13. fred says:

    Bonjour lionel

    tres neophite sur linux, php, etc. Mais ça parait un super boulot.

    par contre je m’y connais pas trop mal en knx pour en avoir fait professionnellement.

    je serais interressé par l’image pour monter ça sur un raspberry, mais le lien est vide.

    Pourrais tu faire quelque chose pour moi

    je t’en remercie d’avance

  14. François says:

    Bonjour.

    Merci pour ce tutoriel, très riche.

    Tout d’abord je ne suis en aucun spécialiste en knx mais en génie climatique..

    J’ai suivi ce tutoriel mais j’essaye de récupérer une « Value » d’un régulateur knx.
    Son adresse de bus est 15.15.230, soit ETS v4.0.6 j’ai accès à la configuration du participant.
    J’ai une ligne 49: Input [°c], type de données (propriétés) 9.* 2-byte float value 9.001 temperature (°c)
    et c’est cette valeur que j’aimerai récupérer.

    Quand je fais un eibcommand -s 127.0.0.1 15/15/230 2 49
    Voici la réponse:

    2014/02/13 04:11:38:353 – phys addr: 15.15.255 – IND low W group addr: 15/7/230 – value: 1 | 1 | 1 | 1 (81 – eis types: 1, 2, 7, 8)

    Que dois je faire pour pouvoir connaître la valeur de température (qui sera stocké dans la base SQL ultérieurement) ?

    Ai je mal programmé quelques chose sous ETS, ou sur le raspberry ?

    Merci d’avance.
    Je suis bloqué à ce niveau et je ne peux pas poursuivre le tuto ??

    • Lionel says:

      Bonjour,

      Merci pour le feedback !
      Je crois comprendre ton problème et j’aimerai lever un premier doute.
      L’adresse physique sur ton bus est 15.15.230.

      Et tu intéroges avec eibcommand cette adresse.
      Mais je crois que ton problème est là.
      Tu n’as pas crée de Groupe d’Adresse (GA).
      Sous ETS, il faut que tu crée une adresse avec ta ligne 49.
      Ca va te donner un truc du genre x/y/z, genre 0/1/1
      Une adresse physique 15.15.230 est différent du 15/15/230.
      Et je ne crois pas qu’on puisse intéroger un module par son adresse physique, puis par son numéro de ligne, à moins que je plante, il faut passer par un groupe d’adresse.
      Le 15.15.230, c’est comme une adresse IP si tu veux, c’est l’adresse du module sur le bus, et le 0/1/1 c’est le groupe d’adresse que l’on va intéroger sur le bus.

      Mais du coup, dans la ligne de réponse, même si elle est du coup fausse, tu as tout de même un GA qui ressort :
      2014/02/13 04:11:38:353 – phys addr: 15.15.255 – IND low W group addr: 15/7/230 – value: 1 | 1 | 1 | 1 (81 – eis types: 1, 2, 7, 8)
      Le 15/7/230, je ne sais pas d’où il sort.
      81°C ça serait possible ? 81°F ca fait 27°C, 27°C, c’est possible aussi ?

      Si c’est bien le cas, que tu as pris l’adresse physique pour l’adresse de bus, ton problème est déjà là, dans ce cas fait un tour sur le campus KNX http://wbt4.knx.org/ qui est plutôt bien fait pour créer correctement ce GA.

      La suite sera plus simple si déjà en ligne de commande tu as la bonne valeur.

      • Francois says:

        Bonsoir.

        Oui effectivement j’ai résolu ce bug. Je peux maintenant interroger mon bus, et je récupère mes valeurs via via ETS (via moniteur de groupe).

        Je dois maintenant corriger un script, je n’arrive pas transférer les données dans la base SQL.

        De plus la commande # knx-tail2mysql –write-initd ne me créée pas de fichier.

        Merci de la réponse, je vais poursuivre mes investigations…

        • François says:

          J’ai trouvé la solution.

          Il faut forcer l’arrêt du processus via la commande : sudo kill -9 (numéro pid)

          Tout refonctionne normalement.

          Mais à ma grande surprise je pensais que ces scripts permettaient de faire une actualisation en temps réel des valeurs des capteurs ( tous les x secondes) dans la base de données SQL.

          Merci pour ce tutoriel.

          • Lionel says:

            Content que ça ai finalement marché.

            J’allais répondre à ton premier message.

            Bon, ça m’étonne qu’il faille le killer, j’espère que tout marche tout de même.

            Oui en effet, le script n’actualise pas une table tous les X secondes, mais surveille un fichier de log de ce qu’il se passe sur le bus, ça permet d’être plus réactif que d’attendre les X secondes de rafraichissement.

  15. Mome says:

    Salut,

    Je n’arrive pas à télécharger l’image de ton RbPI..

    Lorsque je là télécharge, celle-ci est chargée en 2 secondes.

    Peux-tu créer un nouveau lien de téléchargement et ajouter l’image à un .ZIP?

    Merci d’avance et bravo pour le projet.

  16. jjay says:

    Bonjour,

    Merci pour se tuto bien détaillé qui m’a permis de me simplifier l’installation du eibnetmux. Super boulot.

    Cependant, j’ai noté quelques problèmes au long du tuto, voici des corrections que j’ai faite pour que ça marche, si ca peut aider quelqu’un :

    Installation de Zlogger, il faut mettre l’option –enable-pth-plugins sinon on a une erreur sur libpth.so.20 plus tard quand on veut utiliser eibnetmux :

    cd zlogger-1.5.0
    ./configure –with-plugins –enable-pth-plugins
    make
    make install
    ldconfig

    Pour la compilation de eibnetmux avec l’option –enable-php, il faut que php soit installé sur la machine, sinon cette option est ignorée (et si on ne fait pas attention on ne le voit pas tout de suite). Il faut donc installer php avant et non pas après comme indiqué dans le tuto.

    Encore une fois, super boulot.
    Merci
    jjay

  17. isa says:

    Bonjour,
    je suis un debutant en Knx et en raspberry pi.J’ai pas compris le role de raspberry pi dans cette installation et le role du module IP/Knx.Ne jouent tout deux le meme role ?
    Je cherche une solution pour remplacer le module IP/knx par la carte RPi est ce possible?
    Merci.

  18. khalil says:

    slt Lionel , jé klk question coté hardware , en premier lieu on fait la liaison knx avec le routeur ip/knx , en deuxième lieu est ce ke on lie les le routeur ip /knx avec le raspberry à travers le cable reseau rj45 !!

  19. issa says:

    Bonjour ,
    J’ai un routeur proKNx , une carte raspberry pi et un module TxA213 .Et j suis vraiment bloquer .Comment est ce que je peux lier tout ces composants afin d’assurer un fonctionnement en serveur web du raspberry pi en passant par le routeur ProKNx et contrôler le module Txa213.
    Merci

  20. simon jluc says:

    bonjour
    je cherche pour des besoins perso a recuperer sur le bus knx les info venant d’un interface KES de zennio (mesureur d’energie eletrique) avec un raspberryPI3 et eibd installé
    je dispose d’une passerelle ip/knx
    actuellement mes relevés de mesure sont faite par un ecran Z41 de zennio mais je ne peux les extraires
    j’aimerais connaitre par courbes x3 les conso heure/semaine/mois sur une annee et pouvoir les sortir sur fichier exel avez vous une idee
    cordialement
    Mr Simon

  21. jean says:

    Bonjour,

    J’ai un projet, pas juste de déterrer le post ^^
    L’objectif serai de tester la présence, des participants une sorte de « PING » vers les adresses physiques, mais eibnetmux et eibd propose que des solutions vers des adresses de groupes
    on peut lire l’adresse de groupe et récupérer l’adresse physique depuis la réponse de l’état, mais je cherche quelque chose de mieux car certain groupe on des flags et ne répondront donc pas, certaines fois, certains PA ne sont pas encore associer a une GA, l’objectif du système est de vérifier cela aussi
    Des idées pour « ping » les PA ?:)

    • Lionel says:

      Bonjour,

      Il me semble que c’est possible, mais je ne sais plus comment :-/
      après avoir installé eibnetmux ou eibd (je ne sais plus), il y a plein d’exécutables qui placés dans /usr/local/bin et il me semble que l’un d’entre eux permet de tester un participant.

      Oui bon, c’est très très vague comme réponse, je sais, mais bon … ca reste une piste…

      Par exemple la commeande « readmemory » parle de « device addresse » :

      readmemory [options] []
      options:
      -s server name of eibnetmux server (default: )
      -u user name of user (default: -)
      -q no verbose output (default: no)

      is knx device address either as x.y.z or 16-bit integer
      where to start reading
      how many bytes to read
      write binary data to this file

      Donc voila, voila, ca doit bien être possible je pense, mais je ne sais plus comment.

      • jean says:

        Wha merci beaucoup !

        La piste est plutôt bonne, on tient qqc la 🙂

        Je teste ça, si ça marche j’essai de faire un retour pour expliquer la démarche ça peut intéresser du monde !

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *