Communication entre le bus KNX et un serveur Linux

Jusqu’à présent, j’ai découvert comment envoyer des ordres ou obtenir une valeur avec mon bus KNX.
Que ce soit en PHP ou par ligne de commande.

Mon souhait est de pouvoir faire l’inverse : depuis le bus KNX, de donner un autre à mon serveur.
Plusieurs applications possibles, en voici deux concrètes :

  • Allumer/couper les lumières d’ambiance DMX, changer les couleurs.
  • Allumer/couper le wifi.

C’est sans limite en fait.
Du moment où j’envois une commande (boutton poussoir) au serveur celui-ci peut être interprété comme bon me semble.
Je passe de l’électrique de puissance à l’informatique classique.

Comment ça marche ?

J’ai essayé de faire un schéma :

Schéma de principe de l'écoute du bus  KNX

Schéma de principe de l'écoute du bus KNX

Coté programmation, j’ai crée un groupe d’adresses 0/0/10 qui ne contient aucune action, le groupe est lié à l’interrupteur bouton poussoir.

Configuration ETS4 avec un groupe vite pour le DMX

Configuration ETS4 avec un groupe vite pour le DMX

Notre serveur, équipé d’eibnetmux (lien vers son installation) utilise grouplisten pour écouter ce qu’il se passe sur le bus KNX pour un Groupe d’Adresse spécifié, ici le GA 0/0/10.

La fonction grouplisten est exécutée en même temps que le démarrage d’eibnetmux, j’ai rajouté quelques lignes à partir de mon script initial.
La sortie de cette commande est redirigée vers un fichier.

#
# Function that starts the daemon/service
#
do_start()
{
echo -n "Starting eibdnetmux"
/usr/local/bin/eibnetmux $DAEMON_ARGS
echo " done"
sleep 2
echo -n "Starting group listen"
/usr/local/bin/grouplisten ip:127.0.0.1 0/0/10 > /tmp/knx_0-0-10 &
echo " done"
}

Je vais me servir de ce fichier pour surveiller les changements d’état.
J’utilise l’outil logtail pour vérifier les nouveaux évènements.

Pour cet exemple, je souhaite que l’utilisation du bouton poussoir allume mon bandeau RGB, dont j’ai récemment effectué l’installation.

# touch /usr/local/bin/knx2dmx
# chmod +x /usr/local/bin/knx2dmx
# vi /usr/local/bin/knx2dmx
#!/bin/bash

lockfile=/tmp/knx2dmx.run
if [[ -f $lockfile ]] ; then
    echo "knx2dmx déjà en cours d'exécution ou supprimer le fichier $lockfile"
    exit
fi
touch $lockfile

groupaddress=$1
file=/tmp/knx_$groupaddress

bouclette="yes"
# Boucle sans fin
while [ $bouclette = "yes" ]
 do
 {
  # Mais on est pas à 1 seconde près
  sleep 1
   value=`/usr/sbin/logtail -f -o $file | grep "Write" | cut -d" " -f4`
  if [ "$value" == 01 ]
  then
        # Ici j'allume mon bandeau RGB, mais toute autre action est envisageable
        /usr/local/bin/dmxchangecolorfader.py 255 25 100
  elif [ "$value" == 00 ]
  then
        # Je l'éteinds
        /usr/local/bin/dmxchangecolor.py 0 0 0
 fi
 }
done

Et celui là, je le lance dans le cron.

*/10 *          * * *   root    /usr/local/bin/knx2dmx 0-0-10

Donc si mon script, via logtail, détecte que l’adresse de groupe 0/0/10 KNX passe à 1, il allume le strip RGB DMX.
A l’inverse, s’il détecte un 0, il l’éteint.

A titre de supplément, le script dmxchangecolor.py est celui abordé dans l’installation d’OLA.

#!/usr/bin/python
import sys, array
from ola.ClientWrapper import ClientWrapper

def DmxSent(state):
  wrapper.Stop()

universe = 1
data = array.array('B')
data.append(int(sys.argv[1]))
data.append(int(sys.argv[2]))
data.append(int(sys.argv[3]))
wrapper = ClientWrapper()
client = wrapper.Client()
client.SendDmx(universe, data, DmxSent)
wrapper.Run()

Et le script dmxchangecolorfader.py provient aussi de la page wiki d’OLA.
Que j’ai beaucoup bidouillé car je ne sais pas codé en python :
Je n’en suis pas fier, surtout qu’il ne faut pas mettre de valeur à 0.

#!/usr/bin/python
import sys, array
from ola.ClientWrapper import ClientWrapper

red_arg = int(sys.argv[1])
green_arg = int(sys.argv[2])
blue_arg = int(sys.argv[3])

red = 0
green = 0
blue = 0

wrapper = None
loop_count = 0
TICK_INTERVAL = 10  # in ms

def DmxSent(state):
  if not state.Succeeded():
    wrapper.Stop()

def SendDMXFrame():
  # schdule a function call in 100ms
  # we do this first in case the frame computation takes a long time.
  wrapper.AddEvent(TICK_INTERVAL, SendDMXFrame)

  # compute frame here
  data = array.array('B')
  global loop_count
  global red
  global green
  global blue

  if red == (red_arg-1):
    data.append(red_arg)
  else:
    red = loop_count % red_arg
    data.append(red)

  if green == (green_arg-1):
    data.append(green_arg)
  else:
    green = loop_count % green_arg
    data.append(green)

  if blue == (blue_arg-1):
    data.append(blue_arg)
  else:
    blue = loop_count % blue_arg
    data.append(blue)

  loop_count += 1

  if (red == (red_arg-1)) and (green == (green_arg-1)) and (blue == (blue_arg-1)):
    exit()

  # send
  wrapper.Client().SendDmx(1, data, DmxSent)

wrapper = ClientWrapper()
wrapper.AddEvent(TICK_INTERVAL, SendDMXFrame)
wrapper.Run()

Résultat

Pour aller plus loin avec un frontend php

Et voila ! Une bonne base pour faire interagir le serveur depuis le bus KNX.
Je pourrai rajouter autant de grouplisten que necessaire, mais dans une certaine mesure, il sera certainement préférable d’écouter tout ce qu’il se passe sur le bus via groupsocketlisten.

Avec un principe un petit peu différent :

Utilisation de groupsocketlisten pour une interface web

Utilisation de groupsocketlisten pour une interface web

Dans ce cas, groupsocketlisten écoute tout ce qu’il se passe sur le bus.
Un script PHP est à l’écoute des informations, certainement sur le même principe du logtail.
Il filtre et remplit des informations dans la base de données MySQL.

Cette partie là est intéressante, si par exemple, j’allume une lumière derrière un variateur TXA213, groupsocketlisten y voit défiler deux informations :

Write from 0.2.189 to 0/0/1: 01
Write from 1.1.2 to 0/0/7: 01
Write from 1.1.2 to 0/0/8: AF

Ici, j’ai allumé ma lumière grâce à un « groupswrite ip:127.0.0.1 0/0/1 1 », je le vois sur mon bus (0.2.189).
Et deux autres informations utiles y circulent :
– 0/0/7 correspond à l’indicateur d’état, à 01 donc ma lampe est allumée.
– 0/0/8 correspond à l’indicateur de la valeure d’éclairement en hexadécimale sur FF (255).
Ici la valeur hexa AF (FF étant le max) correspond à 175 en décimale (255 étant le max).
Ainsi, avec un base de données bien pensée, il est possible de faire un filtre intelligent : un type d’objet c’est tant et tant d’information à récolter avec tels et tels groupes d’adresses.
On peut pousser le bouchon plus loin, c’est ce « frontend » PHP qui pourrait exécuter des actions sur le système tel que l’allumage DMX.

Une fois la BDD avec des informations actualisées, il ne reste plus qu’à les exploiter à travers une page web.

Une solution qui me semble bonne pour les fondations d’une bonne usine à gaz.
Je vais commencer quelque chose dans ce principe pour un prochain article.

Ce billet est posté dans Debian, dmx, KNX, led, Sysadmin. Mettre en favoris le permalien.

Une réponse à Communication entre le bus KNX et un serveur Linux

  1. Pingback: Une interface web pour contrôler le bus KNX sur Raspberry Pi | Domolio, la domotique et pas que…

Laisser un commentaire

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