Suite à un incident avec le congélateur (porte mal refermée), ça fait un moment que je voulais mettre une sonde de température avec une alarme. Le Frigo est lui-même dôté d’une alarme, mais celle-ci n’indique pas correctement s’il y a eu un incident sur le maintient de la chaîne du froid.
J’ai un peu cherché des sondes « toutes faites » mais elles ne me semblaient pas très fiables notamment avec les piles qui doivent supporter des températures de l’ordre de -18°C.
Pourquoi ne pas créer son propre système ? J’ai un ESP8266 (WeMos) de disponible et quelques sondes DS18B20 étanches.
Je passe les sondes dans le compartiment congélation en passant par le passe câble en mousse de la sonde d’origine.
Idem pour la partie réfrigérateur. Là, il faut démonter un cache en plastique pour passer le capteur.
Le branchement des capteurs 1-Wire est extrêmement simple, il suffit des les connecter à la Masse (fil noir), au +3/3v (fil rouge) et le fil de données en D4 sur l’ESP8266. Il faut aussi placer une résistance de 4.7 kOhms entre le +3.3v et D4. Une petite recherche sur internet permet de trouver rapidement les schémas de branchement. Je me suis largement inspiré de cet article.
L’ESP est placé sur une carte perforée pour que ce soit plus « propre ».
Le tout est attaché dans un petit boitier plastique sur les grilles derrière le frigo. Ces grilles sont chaudes mais pas suffisamment pour perturber le fonctionnement de l’ESP, même en plein été.
Voilà pour la partie matériel. Maintenant, il s’agit de programmer l’ESP pour qu’il récupère les informations de température toutes les 30s et qu’il les transmette à mon serveur Domoticz.
Sur le raspberry qui héberge Domoticz, j’installe le serveur MQTT mosquitto. C’est lui qui recevra les messages de l’ESP et qui les transmettra à Domoticz.
sudo apt install mosquitto mosquitto-clients
Sur domoticz, il faut rajouter un matériel MQTT
Puis un périphérique virtuel correspondant au capteur de température (2 dans mon cas)
Quand le capteur est créé, on peut voir son ID dans la barre d’adresse du navigateur. Cet ID (2762 ici) est à noter, il sera utilisé dans le code de l’ESP.
Voici le code à compiler dans l’ESP. Vous aurez besoin de l’IDE arduino configuré pour accepter des cartes ESP8266, ainsi que des différentes librairies utilisées dans le code: PubSubClient, WifiManager, OneWire, DallasTemperature.
Il vous faudra adapter dans le code l’ip de domoticz, le port MQTT, les deux ID des capteurs dans domoticz et les adresses 1-Wire de vos 2 capteurs. Les adresses découvertes sur le BUS 1-wire sont affichée sur la console série au démarrage du module.
Pour la connexion réseau, j’utilise la librairie Wifi manager qui créé un réseau Wifi (AutoConnectAP) avec une interface web pour réaliser le paramétrage depuis votre téléphone. C’est simplissime !
#include <PubSubClient.h>
#include <ESP8266WiFi.h> //https://github.com/esp8266/Arduino
//needed for library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS D4
#define TEMPERATURE_PRECISION 10
byte i;
byte type_s;
byte data[12];
byte addr[8];
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
WiFiClient espClient;
PubSubClient client(espClient);
// Valeurs à adapter à votre configuration
const char* host = « 192.168.0.19 »;
const int port = 1883;
#define IDX_sensor1 2762
#define IDX_sensor2 2763
// Tableaux contenant l’adresse de chaque sonde OneWire | arrays to hold device addresses
DeviceAddress sensor1 = { 0x28, 0x4E, 0xCF, 0x80, 0x3A, 0x19, 0x1, 0x58 };
DeviceAddress sensor2 = { 0x28, 0xD7, 0x9A, 0x7B, 0x3A, 0x19, 0x1, 0xDD };
// Reconnexion au serveur MQTT
void reconnect() {
// Loop until we’re reconnected
while (!client.connected()) {
Serial.print(« Attempting MQTT connection… »);
// Create a random client ID
String clientId = « ESP8266Client-« ;
clientId += String(random(0xffff), HEX);
// Attempt to connect
if (client.connect(clientId.c_str())) {
Serial.println(« connected »);
// … and resubscribe
client.subscribe(« domoticz/in »);
} else {
Serial.print(« failed, rc= »);
Serial.print(client.state());
Serial.println( » try again in 5 seconds »);
// Wait 5 seconds before retrying
delay(5000);
}
}
}
// Liste les périphériques 1-Wire
void OneWireScanner() {
if ( !oneWire.search(addr)) {
Serial.println(« No more addresses. »);
Serial.println();
oneWire.reset_search();
return;
}
Serial.print(« ROM = « );
for ( i = 0; i < 8; i++) {
Serial.write(‘ ‘);
Serial.print(« 0x »);
Serial.print(addr[i], HEX);
if ( i != 7 ) {
Serial.print(« , « );
}
}
if (OneWire::crc8(addr, 7) != addr[7]) {
Serial.println(« CRC is not valid! »);
return;
}
Serial.println();
// the first ROM byte indicates which chip
switch (addr[0]) {
case 0x10:
Serial.println( » Chip = DS18S20″); // or old DS1820
type_s = 1;
break;
case 0x28:
Serial.println( » Chip = DS18B20″);
type_s = 0;
break;
case 0x22:
Serial.println( » Chip = DS1822″);
type_s = 0;
break;
default:
Serial.println(« Device is not a DS18x20 family device. »);
return;
}
}
// Envoie les températures via MQTT
void sendTemp(int IDX, DeviceAddress addr)
{
sensors.requestTemperatures();
float temp = sensors.getTempC(addr);
if (temp == -127.00) {
Serial.println(« Error getting temperature on id » + String(IDX));
}
else
{
String msg = « { \ »idx\ » : » + String(IDX) + « , \ »nvalue\ » : 0, \ »svalue\ » : \ » » + String(temp) + « \ »} »;
char buf[msg.length() + 1];
msg.toCharArray(buf, msg.length() + 1);
Serial.println(temp);
Serial.println(msg);
Serial.println(buf);
client.publish(« domoticz/in », buf);
}
}
void setup() {
Serial.begin(115200);
// Connexion au Wifi
WiFiManager wifiManager;
wifiManager.autoConnect(« AutoConnectAP »);
Serial.println(« connected… 🙂 »);
client.setServer(host, 1883);
OneWireScanner();
sensors.begin();
// locate devices on the bus
Serial.print(« Locating devices… »);
Serial.print(« Found « );
Serial.print(sensors.getDeviceCount(), DEC);
Serial.println( » devices. »);
// report parasite power requirements
Serial.print(« Parasite power is: « );
if (sensors.isParasitePowerMode()) Serial.println(« ON »);
else Serial.println(« OFF »);
// Vérifie sir les capteurs sont connectés | check and report if sensors are conneted
if (!sensors.getAddress(sensor1, 0)) Serial.println(« Unable to find address for Device 0 »);
if (!sensors.getAddress(sensor2, 1)) Serial.println(« Unable to find address for Device 1 »);
// set the resolution to 9 bit per device
sensors.setResolution(sensor1, TEMPERATURE_PRECISION);
sensors.setResolution(sensor2, TEMPERATURE_PRECISION);
// On vérifie que le capteur st correctement configuré | Check that ensor is correctly configured
Serial.print(« Device 0 Resolution: « );
Serial.print(sensors.getResolution(sensor1), DEC);
Serial.println();
Serial.print(« Device 1 Resolution: « );
Serial.print(sensors.getResolution(sensor2), DEC);
Serial.println();
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
sendTemp(IDX_sensor1, sensor1);
sendTemp(IDX_sensor2, sensor2);
delay(30000);
}
Si tout fonctionne comme prévu, vous verrez vos capteurs se mettre à jour dans domoticz.
Un petit Blocky permet de gérer l’alarme:
Si la température dépasse -10°C je suis notifié sur mon téléphone. Et en plus de l’alarme, on dispose d’un suivi de la chaîne du froid.