Doc de Laumio : une lampe connectée programmable¶
Un Laumio est une lampe Ikea bidouillée par le HAUM et incluant 13 LEDs RGB. Celui-ci peut être programmé directement en Wifi via socat
, l’interprêteur Python or en… regardant l’API.
Tout le code est disponible sur le dépôt Github dédié. Vous êtes libres de l’utilier, de le cloner, de le modifier, et de le publier.
Une version anglaise de la documentation est aussi disponible ici.
Conception du Laumio¶
Le Laumio est constitué d’une lampe Ikea FADO et d’une structure « maison » contrôlant 13 LEDs RGB.
Cette structure physique est elle-même constituée d’une partie mécanique supportant les lampes et du système électronique associé.
Partie mécanique¶
Astuce
Tous les fichiers de conception peuvent être récupérés sur le dépôt Git.
La structure mécanique est composée d’un tronc central conçu pour se tenir sur la douille de l’ampoule. Celui-ci a été usiné grâce à une minifraiseuse et assemblé sans colle.

Deux propositions ont ensuite été portées pour accueillir les LEDs en elles-mêmes.
La première proposition est basée sur des bras pliables, les LEDs étant collées à leurs extrémités. Les problèmes qui en découlent sont principalement la fragilité de la conception (notamment au niveau des soudures) et l’importante manipulation nécessaire pour insérer cet arbre dans le verre.
La seconde proposition est toujours à l’étude. Celle-ci utiliserait des bandes de plastique souple reliées en haut et en bas de la structure.
Système électronique¶
Le système électronique est construit autour d’un ESP Wemos d1 Mini de de 13 LED WS2812. Afin de réutiliser le Wemos dans d’autres projets, il a été décidé de créer un shield adapter pour y connecter le microcontrôleur. Les fichiers de conception KiCAD design de ce shield peuvent être téléchargés ici.
Le code utilisé dans l’ESP est aussi présent sur le dépôt, merci de lire le fichier README pour être en mesure de compiler et de flasher le programme.
Une fois flashé et démarré, le Laumio va chercher à se connecter au réseau WiFi spécifié (voir
wifi-config.h
) et attendre des instructions UDP ou HTTP.
Démarrage¶
Au lancement, le Laumio clignote en violet puis démarre une animation de couleur rouge : il est en train de chercher le réseau WiFi spécifié et va tenter de s’y connecter.
Si la connexion est réussie, le Laumio lancera une animation Arc-en-ciel. Sinon, il s’illuminera en orage, signalant par-là que le mode Access Point est activé. Ce mode permettra à l’utilisateur de donner les informations nécessaires pour connecter l’appareil à un réseau WiFi valide.
Anatomie du Laumio’s et and commandes en valeurs hexadécimales¶
Le laumio peut être commandé via une API UDP minimale utilisant des commandes simples en hexadécimal envoyées sur le port 6969, via une interface REST ou à travers MQTT.
Quatre types de sous-ensembles sont utilisables pour commander les LEDs du Laumio : le pixel (une seule led), l’anneau, la colonne et le Laumio dans son intégralité. Il est aussi possible de lancer quelques animations plus spécifiques.
Les LEDs sont disposées en 4 branches de trois LEDs, en plus d’une à son sommet. Celles-ci sont toutes numérotées de 0 à 12 depuis le bas d’une des branches vers sa cîme, évitant l’unique led du sommet, descendant ensuite de l’autre côté de la structure, et enfin remontant du bas d’une des deux branches restantes pour atteindre le bas de la dernière (la LED de sommet étant cette fois-ci reliée entre les deux branches).
Les anneaux correspondant quant à eux à une ligne horizontale de LEDs. Il y en a trois numérotées de 0 à 2, de bas en haut.
Enfin, dans le cas des colonnes, celles-ci se rapportent aux quatre branches de LEDs, bien entendu sans la LED du sommet.
API UDP minimale¶
Commande pixel par pixel¶
La commande est 0x00
. Les données à envoyer sont d’abord l’ID du pixel considéré et les trois octets de la couleur (RGB) choisie:
0x00 PixelID R G B
Commande anneau par anneau¶
La commande est 0x01
. Il faut d’abord spécifier l’ID de l’anneau (0x00
, 0x01
or 0x02
) puis préciser les trois octets de couleur:
0x01 RingID R G B
Commande colonne par colonne¶
La commande est 0x02
. Ici, il faut indiquer l’ID de la colonne (0x00
, 0x01
, 0x02
or 0x03
) puis les trois octets de couleur:
0x02 ColumnID R G B
Remplissage intégral¶
La commande est 0xff
, il suffit ensuite de specifier la couleur RGB:
0xff R G B
Animations¶
Les animations prédéfinies sont encore en développement mais deux d’entre elles ont déjà implémentées dans le Laumio.
Remplissage progressif¶
L’animation de Remplissage progressif (« color wipe ») change passe le Laumio intégralement dans une seule couleur, mais LED après LED. Elle prend deux paramètres, que sont les trois octets de la nouvelle couleur et l’intervalle de temps entre de deux LEDs en millisecondes:
0x0b R G B Delay
Arc-en-ciel¶
L’animation Arc-en-ciel (« rainbow ») ne prend pas de paramètres. En l’occurence, c’est celle utilisée par le Laumio quand celui-ci réussit à se connecter à un réseau WiFi:
0x0a
API REST¶
L’API REST peut être appelée en envoyant des données sur le chemin /api/
.
Statut¶
Le statut du Laumio peut être obtenu en utilisant un endpoint de l”/api/
:
GET http://<laumio_ip>/api/
La réponse reçue et de la forme suivante :
{"hostname":"laumio","version":"devel"}
Commandes¶
Le Laumio peut être controllé à travers un simple requête POST avec une donnée JSON jointe. Voir l’API JSON pour les détails du contenu de ces JSON.
En cas de succès :
{"hostname":"laumio","status":"Success"}
En cas d’erreur :
{"hostname":"laumio","status":"Invalid Request","massage":"Unable to parse JSON"}
API MQTT¶
Si le Laumio a pu se connecter au broker, il peut être contrôlé à travers MQTT.
Status de connexion¶
A la connexion le laumio publie sur le topic laumio/<name>/status
son status de connexion,
Si le laumio se trouve hors ligne ce topic publiera un status offline
Annonce¶
À la connexion, il publie son nom sur le topic laumio/status/advertise
.
Ce même message est envoyé quand il reçoit une commande discover
.
Commandes¶
La commande est choisie en fonction du topic : laumio/all/<cmd>
ou laumio/<name>/<cmd>
selon que vous voulez l’envoyer à tous les clients connectés ou à un en particulier.
set_pixel¶
Change la couleur d’une led.
Les 4 octets du message sont le numéro de la led suivi des composantes rouge, vert, bleu de la couleur (0 à 255)
set_ring¶
Change la couleur d’un anneau.
Les 4 octets du message sont le numéro de l’anneau suivi des composantes rouge, vert, bleu de la couleur (0 à 255)
set_column¶
Change la couleur d’une colonne.
Les 4 octets du message sont le numéro de la colonne suivi des composantes rouge, vert, bleu de la couleur (0 à 255)
color_wipe¶
Démarre l’animation de remplissage progressif avec une couleur et une durée.
Les 4 octets du message sont les composantes rouge, vert, bleu de la couleur (0 à 255) suivies de la durée.
fill¶
Change la couleur de toutes les leds.
Les 3 octets du message sont les composantes rouge, vert, bleu de la couleur (0 à 255)
json¶
Envoie des commandes JSON via l’API JSON.
discover¶
Renvoie un message sur le topic laumio/status/advertise
contenant son nom.
API JSON¶
Cette API ne peut pas être utilisée seule. Elle est accédée soit par la commande
json
de l’interface MQTT ou par l’API REST.
Commandes¶
set_pixel¶
Change la couleur d’une led.
{
'command': 'set_pixel',
'led': PixelID,
'rgb': [R, G, B]
}
set_ring¶
Change la couleur d’un anneau.
{
'command': 'set_ring',
'ring': RingID,
'rgb': [R, G, B]
}
set_column¶
Change la couleur d’une colonne.
{
'command': 'set_column',
'column': ColumnID,
'rgb': [R, G, B]
}
color_wipe¶
Démarre l’animation de remplissage progressif avec une couleur et une durée.
{
'command': 'color_wipe',
'duration': Duration,
'rgb': [R, G, B]
}
Commandes multiples¶
Quelques commandes peuvent être chaînées dans un même appel lorsqu’elles
sont regroupées dans un tableau nommé commands
, mais notez que la
taille du JSON est quelque peu limitée.
{
'commands': [
{
'command': 'set_column',
'column': 0,
'rgb': [255, 0, 0]
},
{
'command': 'set_column',
'column': 2,
'rgb': [0, 0, 255]
}
]
}
Commande pixel par pixel (ancienne API)¶
{
'led': PixelID,
'rgb': [R, G, B]
}
Remplissage intégral (ancienne API)¶
{
'led': 255,
'rgb': [R, G, B]
}
Interface bash minimale¶
Le Laumio peut être commandé très simplement en utilisant socat ou n’importe quel autre outil réseau bien conçu.
Nous vous proposons le code suivant en guise d’exemple et de base de travail :
#!/bin/bash
# Consts
IP= # Laumio's IP
ANIM_TIME=0.05
PAUSE_TIME=0.3
# Utils
fill() {
echo -en "\xff\x$1\x$2\x$3"
}
led() {
echo -en "\x00\x$1\x$2\x$3\x$4"
}
ring() {
echo -en "\x01\x$1\x$2\x$3\x$4"
}
column() {
echo -en "\x02\x$1\x$2\x$3\x$4"
}
# Program
(
fill 00 00 00
sleep $ANIM_TIME
while true; do
# write your animation here...
done
) | socat - udp-sendto:$IP:6969
En outre, il est également possible d’envoyer plusieurs commandes en une seule requête, comme dans l’exemple suivant:
Ici, le Laumio est d’abord intégralement passé en rouge, puis la LED du sommet est passée en blanc.
Librairie Python¶
La classe Laumio
est construite comme une encapsulation des commandes minimales présentées dans la page de l’API.
-
class
Laumio
¶ -
__init__
(ip)¶ Constructeur pour contrôler un Laumio répondant à l’adresse IP ip.
-
wipeOut
()¶ Eteint toutes les LEDs.
En réalité juste un alias pour :py:method:`fillColor`.
-
fillColor
(r, g, b)¶ Remplit toutes les LEDs du Laumio avec la couleur (r, g, b).
-
fillRing
(ringid, r, g, b)¶ Remplit un anneau d’une seule couleur. ringid est dans l’intervalle 0~3 et r, g, b précisent la couleur. La LED du sommet n’est pas commandable ici.
-
fillColumn
(colmunid, r, g, b)¶ Remplit une colonne d’une seule couleur. columnid est dans l’intervalle 0~4 et r, g, b précisentla couleur. La LED du sommet n’est pas incluse dans les colonnes.
-
setPixelColor
(pixel, r, g, b)¶ Passe un pixel pixel (0~12) à la couleur (r, g, b) demandée.
-
colorWipe
(r, g, b, delay)¶ Lance une animation de remplissage progressif avec la color (r, g, b) et un intervalle de temps delay entre deux LEDs.
-
rainbow
()¶ Lance une animation arc-en-ciel.
-
status
()¶ Return the JSON string for the Laumio’s status
-
_send
(payload)¶ Conventionnaly private, this method is used to transmit a raw
bytearray
payload to a Laumio. It can be used to trigger custom animations.
-