Jeedom RTL433 et sondes hygro/temp low cost

Je parle plus ou moins réguliérement de domotique, avec des gens qui ont souvent des installations très complètes, moi au final je ne fais pas de domotique à proprement parler (je ne commande rien), mais je me contente de faire de la supervision.
Pourtant je sens toujours beaucoup de curiosité vis à vis de mon installation, cet « article » a pour but de présenter mon installation.

Des cables
Tout de même pas non!

Niveau matériel, j’ai des sondes de température/hygrométrie dans quasiment chaque pièce, de 3 provenances différentes, une oregon scientific (~15€), quelques sondes chinoises « ex modèle »(~7,5€) et quelques « nouveau modèle » Digoo (~4,5€) moins cher.
Des sondes très hétérogènes donc.
J’ai deux raspis équipés d’une clé tnt
Le serveur jeedom est une machine virtuelle sur un serveur à moi chez Online.

Je récupère les informations des sondes par les clés TNT via le logiciel rtl_433 (grâce à l’excellent spiwit vibrant sans fil  qui me l’a fait connaitre) qui sait décoder toutes ces trames différentes (et bien d’autres, la liste est sur le site et évolue très régulièrement, c’est un projet très actif) et les envoie dans un fichier de log.

« time » : « 2019-02-04 16:56:48 » « model » : « Prologue » « rid » : 66 « ch » : 3 « bat » : « OK » « temp_C » : 18.700 « hum » : 43
« time » : « 2019-02-04 16:56:51 » « model » : « Prologue » « rid » : 55 « ch » : 2 « bat » : « LOW » « temp_C » : 19.600 « hum » : 42
« time » : « 2019-02-04 16:57:01 » « model » : « Prologue » « rid » : 170 « ch » : 3 « bat » : « OK » « temp_C » : 6.800 « hum » : 72
« time » : « 2019-02-04 16:57:06 » « model » : « Prologue » « rid » : 225 « ch » : 1 « bat » : « OK » « temp_C » : 20.200 « hum » : 39
« time » : « 2019-02-04 16:57:09 » « model » : « Prologue » « rid » : 127 « ch » : 1 « bat » : « OK » « temp_C » : 6.500 « hum » : 51
« time » : « 2019-02-04 16:57:13 » « model » : « Prologue » « rid » : 19 « ch » : 2 « bat » : « OK » « temp_C » : 18.100 « hum » : 45
« time » : « 2019-02-04 16:57:17 » « model » : « Prologue » « rid » : 101 « ch » : 2 « bat » : « OK » « temp_C » : 6.300 « hum » : 52

Sur les raspis, un script maison est lancé toutes les minutes (les sondes causent en moyenne toutes les 30 secondes) et se charge de traduire les « ID » des sondes en nom de pièce et de les envoyer au serveur MQTT  qui tourne sur la même machine que le serveur Jeedom.

Il faut juste faire attention à bien construire son « arborescence MQTT », chez moi j’ai sensor/temperature/lieu et sensor/hygro/lieu, mais sensor/lieu/temperature et sensor/lieu/hygro est probablement un choix qui serait favorisé par la majorité.

Le script n’a que peu d’intérêt, il lit en entrée ce qui sort de rtl_433, le range par pièce suivant les ID (qui changent à chaque changement de pile, attention) et envoie le tout via MQTT.

script awk coloré
script d’envoi vers mqtt

Le (très bon) plugin jeedom se charge de se connecter au serveur MQTT et de ranger les infos reçues suivant l’arborescence.
La beauté du truc, c’est que pour ajouter une sonde, il n’y a qu’a ajouter une ID dans le script avec une description (qui deviendra un topic MQTT), et automagiquement, le nouveau capteur arrive dans jeedom ou il n’y a plus qu’a l’activer.

L’avantage de cette solution par rapport à quelque chose de plus classique (rfxcom plus même type de sonde); outre son prix, un rfcom étant aux alentours de 100€ il me semble, une clé tnt aux alentours de 8; l’avantage donc, c’est l’indépendance par rapport à Jeedom.
Il me semble que domoticz sait également gérer le MQTT, mais on peut aussi imaginer un script qui intègre les données dans n’importe quelle autre solution, la récupération étant simple comme bonjour.
Pour ceux qui n’arrivent pas à se décider entre Domoticz et Jeedom, MQTT permet d’utiliser les deux simultanément avec les mêmes sources en entrée.
Adieu le SPOF  🙂

Jeedom : être alerté quand y a plus de piles!

Jeedom c’est super, pour les capteurs intelligents qui remontent l’info sur leur batterie tu es alerté passé un certain seuil (enfin j’imagine, moi j’ai que des capteurs qui remontent toujours « ok » comme info batterie alors j’ai pas vraiment testé).

image_jeedom_batterie
Paramétrage des seuils d’alerte

 

 

 

Mais pour les capteurs idiots, ou les infos étranges venues d’ailleurs (par exemple, je chope la pollution via un grep bien crado sur https://www.atmo-auvergnerhonealpes.fr/monair/commune/69123 et j’ai pu du coup voir que ça passait plus au changement de nom de domaine puis au passage en https (sans redirection (oui, c’est une parenthèse dans une parenthèse dans une parenthèse, pour remarquer la parenthèse  dans la parenthèse du niveau du dessous.) parce que les 301 à la région, c’est pas leur truc)).

C’est pas très compliqué, il suffit de faire un scenario qui se déclenche quand un délai donné est dépassé.

Scenario d'envoi sms sur perte de la sonde de température du salon
Scenario d’envoi sms sur perte de la sonde de température du salon

Petite explication de texte, on prend l’heure courante au format Unix avec  #timestamp# puis on soustrait l’heure du dernier contact, stockée dans jeedom via CollectDate.

On transforme cette heure au format Unix aussin via le « ,U » (cf http://php.net/manual/fr/function.date.php ) puis on vérifie si c’est supérieur à 3600 (soit 1h).

Pour une raison que j’ignore, je n’ai pas réussi à afficher la valeur de CollectDate(#[Maison][Températures][Salon]#) directement dans mes messages d’avertissement d’ou mes deux actions, d’abord j’initialise la variable délai salon, puis je l’envoi dans mon message.

Forcer le https avec haproxy devant varnish (devant apache et/ou nginx)

Bon, étant assez bordélique de nature, je vais parler de comment tripatouiller varnish que j’ai un peu présenté dans le Billet de présentation de mon infra  et haproxy (dont j’ai pas encore beaucoup causé), pour forcer le https.

Donc en fait, devant Varnish j’ai un service haproxy qui tourne pour servir de terminaison TLS mais un (fort joli) dessin valant mieux qu’un long discours, voici à quoi ressemble une requête arrivant chez moi.

Schéma d'une requêtte http(s)
Paint 4 ever

Ce que j’ai essayé de (mal) représenter c’est le parcours d’une requête http(s) arrivant chez moi.
Si c’est du http, le client cause directement à Varnish qui cause au serveur « backend ».
Si c’est du https, le client cause à haproxy qui cause à Varnish qui cause au serveur « backend », c’est donc pas du TLS de bout en bout ce qui est sans doute un péché mortel chez les pastafariens.

Ceci étant dit, si je veux maintenant forcer le https, j’ai quand même un petit soucis (en fait plusieurs).
1. Le serveur de backend ne voit pas qu’il sait causer en https (en tout cas joomla et wordpress ont tendance à être comme saint thomas, si leur serveur web ne cause pas sur le port 443, ils pensent être inaccessibles en https.)
2. Varnish ne peut pas systématiquement rediriger sur haproxy, puisque haproxy lui renvoie tout, ça ferait donc une boucle de redirection, ça devient lassant et pas très efficace pour servir une page web.

La solution c’est d’ajouter un header spécifique aux requêtes passant par haproxy, et de ne rediriger dans varnish que celles n’ayant pas ce header.

Alors la config dans haproxy est hyper basique, on ajoute juste une ligne dans la partie frontend : http-request set-header X-I-CAN-HAS-TLS ON

Dans varnish c’est un tout petit peu plus compliqué, il faut d’abord détecter si ce header est présent dans la partie vcl_recv :
if (req.http.X-I-CAN-HAS-TLS != « ON ») {
set req.http.x-redir = « https:// » + req.http.host + req.url;
return(synth(007, « Moved permanently »));
}

Puis dans vcl_synth on redirige à coup de http 301 :
if (resp.status == 007) {
   set resp.http.Location = req.http.x-redir;
   set resp.status = 301;
   return (deliver);
}

Ainsi, on a une redirection permanente et les moteurs de recherche se mettent à jour pour remplacer les liens de http vers https, et bien, sur on peut filtrer pour exclure certains hôtes (genre wordpress ^^) temporairement ou pas (procrastination rulez).

 

 

 

 

 

 

 

Une seule IP publique avec plusieurs machines ou services.

Il y a (déjà) un mois, je présentais mon infra perso aujourd’hui suite à des papotages sur irc, je vois qu’il peut être nécessaire de rentrer un peu plus dans les détails concernant Varnish, qui semble pouvoir aider plus de gens que prévu.

Bon dans la vraie vie, on utilise plutôt nginx ou le mod_proxy d’apache pour faire ça mais Varnish est moins gourmand qu’apache et permet plein de choses en plus.

Et puis quand on y a gouté on a du mal à s’en passer…

Pour cette présentation, on va dire que mon adresse IP publique est 127.0.0.1 parce que c’est facile à retenir.
Et coté dns va dire que tous mes trucs sont en *.bazar.4ze.win

Je ne sais pas si c’est le cas partout mais chez Gandi en tout cas, on peut faire des enregistrements DNS « wildcard » (génériques en français).
J’ai donc pour le nom de domaine 4ze.win une ligne de config dns :
*.bazar 1080 IN A 127.0.0.1
En français ça veut dire quelque chose comme « quelque soit le machin qu’on met avant .bazar.4ze.win, faut répondre 127.0.0.1 ».

L’intérêt est double : permettre de rendre accessible en quelques secondes un service via un nouveau nom (juste une modif de varnish) et aussi de pouvoir afficher un site par défaut en cas de faute de frappe par exemple.

Voici un petit schéma, avec Varnish qui reçoit tout le trafic du port 80 (http donc) et redirige ensuite vers d’autres machines suivant le nom demandé.

Un superbe?! schéma du fonctionnement de varnish
Paint rulez! ^^

Maintenant que j’ai présenté le principe, on va rentrer dans le vif du sujet avec la config de Varnish (la version 4 en l’occurrence)…
Le fichier de config par défaut (chez debian en tout cas) est /etc/varnish/default.vcl et il est commenté ce qui est plutôt gentil.

Tout d’abord on définit un « backend », c’est à dire le serveur final auquel on veut causer :
backend jeedom {
    .host = « 172.16.32.9 »;
    .port = « 80 »;
}

Ensuite, dans la partie sub vcl_recv on définit quand est-ce que les requêtes sont envoyées à ce serveur :

if ( req.http.host == « jeedom.bazar.4ze.win » ) {
set req.backend_hint = jeedom;
}

Et puis c’est tout!
Quand on ajoute un service ou une machine on a juste à créer un nouveau backend et à dire quand il doit être sollicité.

En bonus, on peut aussi ajouter des headers du genre :

sub vcl_deliver {
#on empêche iframe et XSS
set resp.http.X-Frame-Options =  « SAMEORIGIN »;
set resp.http.X-Xss-Protection =  « 1; mode=block »;
set resp.http.X-Content-Security-Policy = « sript-src ‘self' »;
set resp.http.Content-Security-Policy = « sript-src ‘self' »;
set resp.http.X-Content-Type-Options = « nosniff »;
}

On peut aussi nettoyer les « user-agent » (il y a des failles au moins pour joomla qui tourne avec ça) :

sub normalize_user_agent {
if (req.http.user-agent ~ « Android ») {
set req.http.user-agent = « Android »;
}  else if (req.http.user-agent ~ « Opera ») {
set req.http.user-agent = « Opera Mini »;
} else if (req.http.user-agent ~ « MSIE ») {
set req.http.user-agent = « MSIE »;
} else if (req.http.user-agent ~ « iPhone ») {
set req.http.user-agent = « iPhone »;
} else if (req.http.user-agent ~ « Firefox ») {
set req.http.user-agent = « firefox »;
} else if (req.http.user-agent ~ « Chrome ») {
set req.http.user-agent = « Chrome »;
} else if (req.http.user-agent ~ « Safari ») {
set req.http.user-agent = « Safari »;
} else {
set req.http.user-agent = « truc louche »;
}
}

Bref, varnish c’est le bien et la doc est bien faite Doc Varnish (en)

 

Petite présentation de mon infra

Puisqu’il y a quand même de grandes chances que pas mal des articles ici concernent plus ou moins un bout de mon « infrastructure perso », je vais commencer par la présenter un peu.

Cables en bazar
Hum non, j’espère pas

Donc j’ai une machine physique chez Online (à l’époque, ils avaient des stocks ^^) avec une vm Pfsense en frontal.

Tout le trafic HTTP est envoyé vers une VM sur laquelle tourne Varnish qui redirige ensuite vers différences machines virtuelles suivant la demande.

Le HTTPS (quand il existe) passe par haproxy qui redirige ensuite vers Varnish.

Bon tout ça n’est sans doute pas super optimisé mais le but c’est plus de jouer avec des machins différents et de me faire la main que les perfs (on est de toute façon sur une machine à ~20€/mois hein).

Dans les machines virtuelles que j’ai ici, j’ai un Cozy Cloud bien sur pour les fichiers, sauvegarde de tel…
J’ai aussi une machine virtuelle pour la domotique avec l’excellent Jeedom dont je risque de reparler.

Ça c’était pour la partie pas à la maison mais le reste suivra bientôt.