Jellyfin Hue

actif · depuis 2026

Un plugin Jellyfin qui pilote les lumières Philips Hue en fonction de la lecture : la pièce s'éteint quand le film démarre, se rallume en douceur sur pause, et revient comme avant à l'arrêt.

stack
  • ▸C# / .NET 10
  • ▸Plugin Jellyfin 10.11+ / 12+
  • ▸API Hue CLIP v2, en HTTPS local
  • ▸Page de config HTML/JS dans le dashboard
  • ▸xUnit, Moq
  • ▸GitHub Actions (tests, CodeQL, releases)
links

Ce que ça fait

Le film démarre, la pièce descend en fondu jusqu'au niveau choisi, ou jusqu'au noir complet. On met en pause, une lumière chaude remonte doucement, assez pour se lever sans se cogner. On reprend, elle redescend. On arrête, et tout revient dans l'état d'avant, ou bascule sur un éclairage d'ambiance, au choix.

Le reste, c'est du filtrage, parce qu'une seule règle pour toute la maison, ça ne suffit pas. Un profil vise des utilisateurs Jellyfin, des appareils ou des applications clientes (la télé du salon, l'Apple TV de la chambre), un type de média (films, séries, et rien d'autre) et une plage horaire, pour que rien ne se déclenche en plein après-midi. On en crée autant qu'on a de pièces ou de personnes.

Côté Hue, ça pilote une pièce, une zone ou une lampe seule, et ça gère les ampoules couleur, les blancs réglables et les blancs fixes, en envoyant à chacune seulement les champs qu'elle accepte. Un bouton de test envoie la transition pour de vrai sur les lampes visées, sans avoir à lancer un film.

L'appairage se fait depuis le dashboard : découverte automatique du pont, une pression sur son bouton physique, et la clé est enregistrée.

Comment c'est fait

Une DLL .NET 10 accrochée aux événements de lecture du serveur, une page de configuration servie dans le dashboard, et un petit contrôleur d'API pour ce que cette page a besoin de demander (la liste des pièces du pont, l'appairage, les tests). Tout passe par CLIP v2, en HTTPS sur le réseau local, sans passer par le cloud Hue.

La partie qui a demandé le plus d'attention, c'est la couleur et la restauration d'état. Hue ne raisonne pas en RGB mais en coordonnées xy et en température de couleur, et toutes les ampoules n'acceptent pas les mêmes champs : envoyer une couleur à une ampoule blanche, c'est une erreur, pas une approximation. Et "remettre comme avant" suppose de lire et de stocker l'état de chaque lampe avant d'y toucher, sinon on ne peut que tout rallumer à 100 %.

Une suite xUnit couvre l'orchestration, la conversion des couleurs et le client du pont, avec les appels HTTP remplacés par de fausses réponses, donc les tests tournent sans pont sous la main.

Pourquoi

Je voulais que le salon se comporte comme une salle de cinéma. Ça existe déjà, mais sous forme d'automatisation externe qui doit deviner ce que fait le lecteur. Un plugin installé dans le serveur n'a rien à deviner : il reçoit l'événement quand la lecture démarre, s'arrête ou reprend.

Et comme pour Jellyfin BetaSeries , je n'ai jamais écrit une ligne de .NET : j'ai écrit les specs, un LLM a écrit le code, et j'ai lu, corrigé et redemandé jusqu'à ce que ça marche. C'était le deuxième, donc les specs étaient plus complètes dès le départ, surtout sur les cas où le plugin doit refuser d'agir plutôt que choisir à ma place.

← retour aux projets