Réseaux et télécommunications
Fermer ×

Raspberry pi et IOT

Note importante

Notez que je décline toutes responsabilités quant aux conséquences que pourraient avoir l'application des méthodes et conseils suivants ainsi que l'utilisation des programmes présentés. Ceux-ci pourraient être erronés ou obsolètes.

Serveur web

Installation

Sur la raspberry pi, on propose d'installer et d'utiliser un serveur web léger lighttpd. Il fait parti des paquetages disponibles qu'il suffit d'installer.

Configuration

L'installation par défaut correspond à une arborescence qui se trouve dans le répertoire /var/www/html. On va ajouter les scripts cgi-bin en ajoutant la configuration avec la commande exécutée en mode root :
lighty-enable-mod cgi
systemctl restart lighttpd
Après installation et redémarrage du serveur, il est possible d'utiliser des scripts cgi situés dans le répertoire /lib/cgi-bin accessible avec l'URL http://ip/cgi-bin/script.cgi. Il est bien évidement possible de changer ce répertoire dans la configuration.

On peut ajouter l'accès https avec un certificat. On pourrait faire l'acquisition d'un certificat auprès d'une autorité de certification, mais pour une utilisation sur un réseau local qui n'est pas accessible sur internet, on peut simplement utiliser un certificat auto-signé qui se crée, sous linux, avec la commande openssl comme par exemple

openssl req -sha256 -nodes -newkey rsa:2048 -keyout raspi.key -out raspi.csr
openssl x509 -req -days 365 -in raspi.csr -signkey raspi.key -out raspi.crt
cat raspi.key raspi.crt > /etc/lighttpd/server.pem

La première ligne crée les fichiers clé et certificat, la deuxième ligne crée la signature et enfin la troisième ligne crée le fichier certificat utilisé par le serveur et qui doit être dans le répertoire /etc/lighttpd/server.pem. Pendant l'étape de création, il faut répondre aux questions d'identification du propriétaire du site comme le nom, prénom, email, entreprise, ville, pays, ...

Pour comprendre exactement la commande openssl ou bien personnalisé et modifier les options, il faut se reporter à la documentation openssl.

Il faut également ajouter la configuration ssl au serveur lighttpd avec les commandes :

lighty-enable-mod ssl
systemctl restart lighttpd

Il est possible de mettre à disposition des pages html pour chaque utilisateur, ces pages sont accessibles avec l'url http://ip/~utilisateur/. Pour cela on doit créer le répertoire public_html dans le répertoire utilisateur et ajouter la configuration au serveur

lighty-enable-mod userdir
systemctl restart lighttpd

Exemples de scripts CGI

On propose de réaliser un premier script CGI qui permet de stocker les données des capteurs dans la base de donnée présentée dans le chapitre précédent. La sauvegarde concerne uniquement la table mesures. Ce script permet de stocker les valeurs de 5 capteurs : température,humidité,pression,luminosité,uv. La partie générique du script est inspirée du chapitre sur le web

Voir le contenu de la base de données utilisée

Table objets

idobjet nom idcapteur
1 température 1
2 humidité 1
3 pression 2
4 luminosité 3
5 UV 4

Table capteurs

idcapteur reference designation idconstructeur idfournisseur
1 HTS221 température et humidité 1 1
2 LPS22HB pression 1 1
3 TEMT6000X01 luminosité 2 1
4 VEML6075 uv 2 1

Table constructeurs

idconstructeur nom
1 STMicroelectronics
2 Vishay Semiconductors

Table fournisseurs

idfournisseur nom
1 Go Tronic
Voir le script CGI de sauvegarde des données des capteurs

Script CGI sauvecapteurs.cgi


#!/bin/bash

FICHIER="/var/sqlite/objetsconnectes.db"
SQLENTETE="insert into mesures (date,valeur,idobjet) values ("

if [ $REQUEST_METHOD = "GET" ]
 then
  CHAINE=$QUERY_STRING
 else
  read CHAINE
fi

temperature=""
humidite=""
pression=""
luminosite=""
uv=""

retour=5
LISTE=${CHAINE//&/ }
for param in $LISTE 
 do
  champ=${param%=*}
  valeur=${param#*=}
  valeur=${valeur//+/ }
  case "$champ" in
	temperature)	
					temperature=$valeur
					retour=$(( $retour - 1))	
					;;
	humidite)
					humidite=$valeur
					retour=$(( $retour - 1))	
					;;
	pression)
					pression=$valeur
					retour=$(( $retour - 1))	
					;;
	luminosite)
					luminosite=$valeur
					retour=$(( $retour - 1))	
					;;
	uv)
					uv=$valeur
					retour=$(( $retour - 1))	
					;;
  esac
done

DATE=$(date +"%Y-%m-%d %H:%M:%S")
if [ -n "$temperature" ] 
 then
	SQL="${SQLENTETE} \"${DATE}\" , ${temperature} , 1 );"
	sqlite3 "${FICHIER}" "${SQL}"
	retour=$(($retour - $?))
fi
if [ -n "$humidite" ] 
 then
	SQL="${SQLENTETE} \"${DATE}\" , ${humidite} , 2 );"
	sqlite3 "${FICHIER}" "${SQL}"
	retour=$(($retour - $?))
fi
if [ -n "$pression" ] 
 then
	SQL="${SQLENTETE} \"${DATE}\" , ${pression} , 3 );"
	sqlite3 "${FICHIER}" "${SQL}"
	retour=$(($retour - $?))
fi
if [ -n "$luminosite" ] 
 then
	SQL="${SQLENTETE} \"${DATE}\" , ${luminosite} , 4 );"
	sqlite3 "${FICHIER}" "${SQL}"
	retour=$(($retour - $?))
fi
if [ -n "$uv" ] 
 then
	SQL="${SQLENTETE} \"${DATE}\" , ${uv} , 5 );"
	sqlite3 "${FICHIER}" "${SQL}"
	retour=$(($retour - $?))
fi

cat << EOF
Content-type: text/plain

code=$retour
EOF
					

L'URL d'envoi des données est de la forme

https://ip/cgi-bin/sauvecapteurs.cgi?temperature=23.5&humidite=50&pression=1013&luminosite=800&uv=1

Le fichier de la base de données SQLite n'est pas accessible via http, car il se trouve en dehors de la racine du site.

La valeur de retour est initialisée à 5, ce qui fait que si tous les paramètres ont été transmis, elle vaut 0 en fin de boucle.

Après la boucle de traitement des paramètres, on prend la date système afin d'horodater les données reçues. La date est commune aux 5 données enregistrées.

Ensuite on sauvegarde chaque donnée dans la base dans l'ordre suivant : température,humidité,pression,luminosité,uv. On associe à chaque valeur l'identifiant correspondant à la référence de la donnée de la table objets.

Enfin le code retour vaut 0 si tout s'est bien passé, si un problème de stockage est rencontré, on aura une valeur de retour négative.

En résumé, une valeur de retour positive indique une erreur de transmission de paramètres et une erreur de retour négative indique une erreur de stockage de données.

On propose de réaliser un script qui affiche l'ensemble des mesures dans une page html.

Voir le script CGI de lecture des données des capteurs et affichage au format HTML

Script CGI litcapteurs.cgi


#!/bin/bash

FICHIER="/var/sqlite/objetsconnectes.db"

cat << EOF
Content-type: text/html

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="/~michel/css/presentation.css">
<title>Affichage des capteurs</title>
</head>
<body>
<h1 align="center">Affichage des capteurs</h1>
EOF

LISTEBRUTEOBJETS=$(sqlite3 ${FICHIER} "select idobjet from mesures group by idobjet")
LISTEOBJETS=$(echo "$LISTEBRUTEOBJETS" | tr "\012" " ")
TOTALRANGEES=$(sqlite3 ${FICHIER} "select count(idmesure) from mesures")
TOTALOBJETS=$( echo "$LISTEBRUTEOBJETS" | grep -c "^[0-9]\+$")
TOTALMESURES=$( expr ${TOTALRANGEES} / ${TOTALOBJETS})
RESTE=$( expr ${TOTALRANGEES} % ${TOTALOBJETS})
echo "<p align=\"center\">$TOTALMESURES mesures</p>"
if [ "$RESTE" != 0 ]
 then
	echo "<p>Attention Absence de mesures ou mesures erronnées</p>"
fi 
ENTETEHTML=""
for idobjet in $LISTEOBJETS
do
	ENTETE=$(sqlite3 ${FICHIER} "select nom from objets where idobjet=${idobjet}")
	ENTETEHTML="$ENTETEHTML<th>${ENTETE}</th>"
done
echo "<table width=\"100%\">"
echo "<tr>$ENTETEHTML</tr>"
rangee=0
LISTEMESURES=$( seq 1 $TOTALMESURES)
for mesure in $LISTEMESURES
do
	COLONNE=$(sqlite3 ${FICHIER} "select valeur from mesures limit ${rangee},${TOTALOBJETS}")
	LISTEBRUTE=$(echo "$COLONNE" | tr "\012" ",")
	LISTECOLONNE=$( expr "$LISTEBRUTE" : "\(.*\),$")
	RANGEEHTML=$(echo "$LISTECOLONNE" | sed -e 's/,/<\/td><td>/g' )
	RANGEEHTML="<tr><td align=\"center\">${RANGEEHTML}</td></tr>"
	echo "$RANGEEHTML"
	rangee=$(( $rangee + ${TOTALOBJETS}))
done
echo "</table>"
cat << EOF2
</body>
</html>
EOF2
					

Ce script construit un tableau HTML à raison d'un ensemble de mesures par ligne à partir d'une table où chaque ligne correspond à une valeur. Il faut effectuer la lecture par paquet de 5 lignes afin d'avoir les 5 valeurs à chaque lecture. Ensuite il faut afficher les 5 valeurs dans une ligne HTML.

Pour cela on a besoin du nombre de rangées (TOTALRANGEES) dans le tableau mesures. On a également besoin de la liste des objets présents dans le tableau mesures (LISTEOBJETS) ainsi que le nombre d'objets différents (TOTALOBJETS). Ce qui permet de déduire le nombre de mesures (TOTALMESURES).

Le calcul du reste permet de vérifier si le nombre de rangées est bien un multiple du nombre d'objets.

On construit l'entête du tableau à partir de la liste des objets (LISTEOBJETS) en utilisant le tableau objets qui contient les désignation des capteurs.

Maintenant pour chaque mesure, on lit l'ensemble des rangées du tableau correspondant aux valeurs des capteurs. On obtient donc une colonne de valeurs, qu'il faut transformer en ligne en remplaçant le caractère de fine de ligne (012 en octal) en une virgule. Puis on supprime la dernière virgule avant de construire la ligne HTML en remplaçant la virgule par des balises de tableau.

Le déplacement dans la base de donnée se fait tous les (TOTALOBJETS).

La page HTML utilise la feuille de style présentée dans le chapitre sur le web.

Exemple d'affichage de la page HTML

Serveur MQTT

Installation et configuration

Le serveur MQTT utilisé se nomme mosquitto, il fait parti des paquetages de la raspberry et peut donc être installé facilement.

Il faut également installer le client pour pouvoir tester le serveur : mosquitto_pub pour la publication de messages et mosquitto_sub pour l'abonnement.

Par défaut le serveur n'accepte pas les connexions anonymes, Il est possible modifier la configuration en ajoutant un fichier de configuration dans le répertoire /etc/mosquitto/conf.d :

listener 1883 0.0.0.0
alloow anonymous true
La première ligne précise que le port est 1883 et que le serveur accepte toutes les adresses IP, la deuxième ligne précise que les connexions anonymes sont acceptée, ce qui est pratique lors du développement et des tests.

Vérification du fonctionnement

On ouvre deux fenêtres shell une pour lancer l'abonnement, l'autre pour effectuer la publication.

Utilisation en C

On utilise la librairie de développement de mosquitto. Il faut inclure le fichier de définitions mosquitto.h et ajouter mosquitto à l'édition de lien.

L'essentiel des fonctions est :

  1. mosquitto_lib_init() pour initialiser la librairie
  2. mosquitto_new() pour créer un nouvel objet client mosquitto et retourne un pointeur vers un objet mosquitto
  3. mosquitto_connect(objetmosquitto,ip,port,timeout) établit la connexion avec le serveur, le timeout est un temps maximal d'attente de réponse.
  4. publication ou abonnement
    • mosquitto_publish(objetmosquitto,suivi,topic,longueurmessage,message,qos,retain) avec suivi qui est un pointeur vers un entier qui contient un indicateur suivi de message et peut être NULL, qos est la qualité de service qui peut être 0 et retain est le maintien de message qui peut être false.
    • mosquitto_subscribe(objetmosquitto,suivi,topic,qos) avec suivi qui peut être également NULL
    • mosquitto_loop_start(objetmosquitto) pour démarrer la boucle de surveillance de l'abonnement, doit être suivi par l'attente de l'appui sur une touche du clavier.
    • mosquitto_loop_stop(objetmosquitto,arret) arrête la boucle de surveillance avec arret, booléen, qui vaut vrai pour forcer l'arrêt du thread.
  5. mosquitto_disconnect(objetmosquitto) termine la connexion avec le serveur
  6. mosquitto_destroy(objetmosquitto) libère l'objet mosquitto
Voir le code C d'un client qui publie un message

code pqtt_pub.c


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <mosquitto.h>

#define HOSTNAME "courtier"
#define PORT 1883
#define TOPIC "/maison/piece/lumiere"

int main(int argc, char **argv) {
	struct mosquitto *mqtt_client = NULL; 
	char message[64];
	int err;
	if (argc == 2) {
		strcpy(message,argv[1]);
	}
	else {
		strcpy(message,"allume");
	}
	int lgmessage = strlen(message);
	err =  mosquitto_lib_init();
	if (err != MOSQ_ERR_SUCCESS) {
		fprintf(stderr,"ERREUR init mosquitto\n");
		return EXIT_FAILURE;
	}
	mqtt_client = mosquitto_new("mqttclient", true, NULL);
	err = mosquitto_connect(mqtt_client, HOSTNAME,PORT, 60);
	if(err != 0){
		fprintf(stderr,"erreur connexion : %s\n", strerror(err));
		mosquitto_destroy(mqtt_client);
		mosquitto_lib_cleanup();
		return EXIT_FAILURE;
	}
	mosquitto_publish(mqtt_client, NULL, TOPIC,lgmessage , message , 0, false);
	mosquitto_disconnect(mqtt_client);
	mosquitto_destroy(mqtt_client);
	mosquitto_lib_cleanup();
	return EXIT_SUCCESS;
}
					

Le programme publie le message transmis en paramètre au topic /maison/piece/lumiere, la valeur par défaut est allume. Ce programme respecte les étapes d'initialisation, connexion, publication, déconnexion et suppression de l'objet client et libération de la mémoire.

En cas d'erreur de connexion, l'objet client est supprimé, la mémoire allouée est libérée avant de terminer le programme sur un code d'erreur.

La publication se fait avec une qos de 0 et sans maintien du message.

Voir le code C d'un client qui s'abonne au serveur

code mqtt_sub.c


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <mosquitto.h>

#define HOSTNAME "courtier"
#define PORT 1883
#define TOPIC "/maison/piece/lumiere"
#define CONNECT_KEEP_ALIVE	30


void on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg) {
	printf("message %s : %s\n", msg->topic, (char *) msg->payload);
}

int main(int argc, char **argv) {
	
	struct mosquitto *mqtt_sub = NULL; 
	int err =  mosquitto_lib_init();
	if (err != MOSQ_ERR_SUCCESS) {
		fprintf(stderr,"ERREUR init mosquitto\n");
		return EXIT_FAILURE;
	}
	mqtt_sub = mosquitto_new(NULL, true, NULL);
	if (mqtt_sub == NULL) {
		fprintf(stderr,"ERREUR new mosquitto\n");
		return EXIT_FAILURE;
	}
	mosquitto_message_callback_set(mqtt_sub, on_message);
	err = mosquitto_connect(mqtt_sub, HOSTNAME,PORT, CONNECT_KEEP_ALIVE);
	if(err != 0){
		fprintf(stderr,"erreur connexion : %s\n", strerror(err));
		mosquitto_destroy(mqtt_sub);
		mosquitto_lib_cleanup();
		return EXIT_FAILURE;
	}
	mosquitto_subscribe(mqtt_sub, NULL, TOPIC, 0);
	mosquitto_loop_start(mqtt_sub);
	printf("Appuyer sur une touche pour terminer ...\n");
	getchar();
	mosquitto_loop_stop(mqtt_sub, true);	
	mosquitto_disconnect(mqtt_sub);
	mosquitto_destroy(mqtt_sub);
	mosquitto_lib_cleanup();
	return EXIT_SUCCESS;
}
					

Le programme s'abonne au topic /maison/piece/lumiere. Ce programme respecte les étapes d'initialisation, connexion, souscription, boucle de surveillance, arrêt de la boucle de surveillance, déconnexion et suppression de l'objet client et libération de la mémoire.

En cas d'erreur de connexion, l'objet client est supprimé, la mémoire allouée est libérée avant de terminer le programme sur un code d'erreur.

Utilisation en python

On utilise la librairie python paho. Ici on utilise les connexions simples pour la publication avec le paquetage paho.mqtt.publish et l'abonnement avec le paquetage paho.mqtt.suscribe, ou encore un abonnement permanent avec fonction callback

Voir le code python d'un client qui publie un message

code mqtt_pub.py


import paho.mqtt.publish as publish

hostname = "courtier"
topic = "/maison/piece/lumiere"

def main(args):
	nbargs=len(args)
	if nbargs==2 :
		message = args[1]
	else :
		message = "allume"
	publish.single(topic, message, hostname=hostname)
	return 0

if __name__ == '__main__':
    import sys
    sys.exit(main(sys.argv))
					

Le message est transmis en argument. En l'absence d'argument, c'est le message par défaut allume qui est publié.

Voir le code python d'un client qui s'abonne au serveur

code mqtt_sub.py


import paho.mqtt.subscribe as subscribe

hostname = "courtier"
topic = "/maison/piece/lumiere"


def main(args):
	message = subscribe.simple(topic, hostname=hostname)
	print(f"topic {message.topic} : {message.payload}")
	return 0

if __name__ == '__main__':
    import sys
    sys.exit(main(sys.argv))
					

La fonction effectue la souscription, et bloque jusqu'à l'arrivée d'un message.

Voir le code python d'un client qui s'abonne au serveur en version callback

code mqtt_sub.py


import paho.mqtt.subscribe as subscribe

hostname = "courtier"
topic = "/maison/piece/lumiere"

def messagerecu(client, userdata, message):
    print(f"topic {message.topic} : {message.payload}")

def main(args):
	subscribe.callback(messagerecu, topic, hostname=hostname)
	return 0

if __name__ == '__main__':
    import sys
    sys.exit(main(sys.argv))
					

La fonction effectue la souscription puis lance une boucle de surveillance. A chaque message la fonction messagerecu est appelée pour traiter le message reçu.

Serveur Domoticz

Installation

L'installation de domoticz est expliquée sur le site de l'application domoticz pour raspberry pi ou encore l'installation sous linux.

Attention : l'installation présentée sur ce site configure le mode https avec le port 443, utilisé par les serveurs web comme lighttpd.

Pour une utilisation occasionnelle ou des tests avant installation définitive, on peut également l'installer dans le répertoire utilisateur pi (/home/pi) en mode utilisateur. Dans ce cas il faut configurer le numéro de port https dans l'espace utilisateur, comme cela est expliqué dans le chapitre précédent. On peut utiliser le script de démarrage suivant :

#!/bin/sh
${HOME}/domoticz/domoticz -sslwww 6443 -sslcert ${HOME}/domoticz/server_cert.pem

Après avoir rendu ce script exécutable, il suffit de l'exécuter pour lancer le serveur domoticz, puis ctlr-c pour stopper le serveur.

Voir l'installation personnalisée pour un démarrage automatique, réservé uniquement aux experts linux

Télécharger l'archive pour raspberry pi

Toutes les commandes se font avec sudo ou en root

  1. Décompresser l'archive domoticz dans /opt/domoticz :
    tar zxvf domoticz_linux_armv7l.tgz
  2. Ajouter un groupe domoticz :
    groupadd -r domoticz
  3. Ajouter un utilisateur domoticz :
    useradd -r -g domoticz -b /opt -s /usr/sbin/nologin domoticz
  4. Dans /opt, changer les noms de groupe et utilisateur :
    chown -R domoticz:domoticz domoticz
    
  5. dans /opt/domoticz, Modifier manuellement le fichier domoticz.sh :
    USERNAME=domoticz
    DAEMON=/opt/domoticz/$NAME
    DAEMON_ARGS="-daemon"
    DAEMON_ARGS="$DAEMON_ARGS -daemonname $NAME -pidfile $PIDFILE"
    DAEMON_ARGS="$DAEMON_ARGS -www 8080"
    DAEMON_ARGS="$DAEMON_ARGS -sslwww 6443 -sslcert /opt/domoticz/server_cert.pem"
    ou appliquer le patch domoticz.patch :
    patch < domoticz.patch
  6. Avant de passer à la configuration du démarrage automatique, il est possible de tester le serveur en utilisateur domoticz :
    sudo -u domoticz -g domoticz /opt/domoticz/domoticz -sslwww 6443 -sslcert /opt/domoticz/server_cert.pem
    Si le démarrage est OK, se connecter avec un navigateur pour vérifier que tout fonctionne :
    https://ip:6443/
  7. Copier ce fichier dans /et/init.d
    cp domoticz.sh /etc/init.d/domoticz
  8. Toujours dans /etc/init.d, rendre exécutable le script :
    chmod a+x domoticz
  9. Tester manuellement le script dans /etc/init.d :
    ./domoticz start
    Si le démarrage est OK, se connecter avec un navigateur pour vérifier que tout fonctionne :
    https://ip:6443/
  10. Si c'est OK, ajouter le script aux niveaux de démarrages :
    update-rc.d domoticz.sh defaults
  11. Redémarrer
    reboot

Configuration

Lors de la première connexion avec le login admin et le mot de passe domoticz, dans le menu Settings->Parameters ,il faut choisir la langue et fournir obligatoirement des coordonnées GPS comme par exemple une latitude de 48.862725 et une longitude : 2.287592 (place du Trocadéro à Paris).

Ensuite il faut créer un utilisateur, qui sera utilisé pour les connexions des objets connectés, mais également pour visualiser et gérer les données des capteurs, le mode administrateur étant réservé à la l'administration. Dans le menu Configuration->Users, il faut saisir un nom (ex user) et un mot de passe (ex access) ainsi que les droits utilisateur, activer les menus qui seront utilisés (Interrupteurs, Température, Météo, Mesures ) puis cliquer sur Ajouter.

Eventuellement, dans le menu Configuration->Paramètres->sécurité activer la protection API et ajouter les réseaux de confiance.

Ajout des composants

On propose d'ajouter les composants température, Humidité, Pression, luminosité, et indice UV.

  1. En premier lieu, il faut ajouter le composant matériel Dummy en utilisant le menu Configuration->Matériel, ajouter un nom (ex objets) et sélectionner le type Dummy (Does nothing, use for virtual switches only) puis cliquer sur Ajouter.
  2. On reste dans cette page pour installer les composants, on clique sur le lien Créer un capteur virtuel pour ajouter chaque composant.
    1. Choisir le type de capteur Température et saisir le nom, par exemple, Température
    2. Choisir le type de capteur Humidité et saisir le nom, par exemple, Humidité
    3. Choisir le type de capteur Baromètre et saisir le nom, par exemple, Pression
    4. Choisir le type de capteur Lux et saisir le nom, par exemple, Luminosité
    5. Choisir le type de capteur UV et saisir le nom, par exemple, UV

La syntaxe des commandes à utiliser par les objets connectés pour mettre à jour les valeurs des capteurs est disponible dans la documentation du site domoticz

Ajouter un sélecteur de niveau en allant dans le menu Interrupteurs, cliquer sur Ajout manuel. Choisir un nom (ex led RGB) et le type selector, on créer un interrupteur qui permet de choisir un niveau de commande, qui pourra, par exemple, piloter une led RGB sur un objet connecté. A cet effet, on pourra renommer les niveaux 1 à 3 en rouge,vert,bleu et ajouter le niveau blanc.

Ajout de l'abonnement MQTT

Cela consiste à ajouter un composant matériel qui est MQTT Client Gateway with LAN interface, qu'il faut configurer avec :

Avec cette configuration un clic sur un des niveaux (off,rouge,vert,bleu,blanc) publie le message json suivant :

{
	"Battery" : 255,
	"LastUpdate" : "2024-07-15 13:26:47",
	"LevelActions" : "||||",
	"LevelNames" : "Off|rouge|vert|bleu|blanc",
	"LevelOffHidden" : "false",
	"RSSI" : 12,
	"SelectorStyle" : "0",
	"description" : "",
	"dtype" : "Light/Switch",
	"hwid" : "2",
	"id" : "00000000",
	"idx" : 6,
	"name" : "led RGB",
	"nvalue" : 2,
	"org_hwid" : "2",
	"stype" : "Selector Switch",
	"svalue1" : "20",
	"switchType" : "Selector",
	"unit" : 1
}
voir les informations à propos de RSSI.

La valeur du champ svalue1 contient la valeur du niveau correspondant au bouton (ici 20 pour rouge).