Publié le

Test d’impression : le Filaflex

Aujourd’hui je me suis lancé dans l’impression du Filaflex (un filament flexible).

Premier test sans modifications de la tête d’impression : le fil s’enroule autour du galet donc c’est la mort.

J’ai donc cherché un peu sur internet et je suis tombé sur un galet à venir placer entre l’entrée de la buse et le galet du moteur :

Galet

SAM_1515_preview_featured

Une fois le galet monté, aucun soucis d’entrainement du fil !

Juste pour le chargement, il faut le faire en manuel, il suffit d’appuyer sur le levier et de pousser le fil.

Voici les réglages que j’ai effectué sous cura :

Profil flex 1Profil flex 2

Voici le lien pour télécharger mon profil ImpressionFlex.ini.

Note : J’ai changé la vitesse de rétractation à 20 pour éviter de « tordre le fil ».

Les vidéos :

Publié le

Imprimante 3D – Améliorations

Comme je l’ai dit dans l’article précédent, j’ai fait quelques améliorations à mon imprimante 3D.

1. Le tapis chauffant :

Pour avoir une meilleure accroche et éviter que les pièces ce décollent, j’ai ajouté un plateau chauffant de type MK2a.

Le seul point est son alimentation, il a besoin d’un peu plus de 11A en 12V pour fonctionner, donc il faut ajouter une alimentation style pc assez puissante pour le faire fonctionner.

kit-de-cama-caliente-mk2a_800x800

Voici je kit que j’ai pris. Il vient se placer sous le plateau en verre et chauffe assez rapidement.

Suite à l’installation du plateau chauffant, il faut aller modifier le firmware de l’imprimante pour pouvoir l’utiliser :

il suffit juste de modifier dans le fichier configuration.h la valeur

#define TEMP_SENSOR_BED 0

En

#define TEMP_SENSOR_BED 1

On charge le firmware et c’est bon.

2. Octoprint (serveur d’impression réseau) :

Ah j’ai ressorti mon RaspberryPi pour l’occasion !

Pourquoi ne pas s’en faire un petit serveur d’impression qui va aussi nous permettre d’éteindre et d’allumer l’imprimante 3D ?

Chose pratique, on peut télécharger une image pour le Rasp avec octoprint préinstallé (pour éviter de devoir tout configurer à la main) c’est OctoPi.

Ca permet de surveiller l’impression (avec une caméra, voir ou on en est …) très pratique et extrêmement simple à utiliser !

Je prépare mon fichier .gcode sous Cura, et je l’upload directement via l’interface Octoprint.

La je suis en train d’implémenter un ajout pour pouvoir allumer/éteindre l’alimentation de l’imprimante 3D directement via Octoprint :

Sur les alimentations ATX, si on connecte le fil vert avec le fil noir, l’alimentation se met en marche. Il y a aussi le fil violet qui est un +5V continu (indépendant de la marche ou l’arrêt par le fil vert de l’alimentation).

Je place donc un relais qui va contacter ma masse avec le fil vert pour alimenter l’imprimante 3D.

Un petit tour en ssh sur le Rasp pour préparer tout ça :

On commence par installer WiringPi :

sudo apt-get install git-core

sudo apt-get update
sudo apt-get upgrade

git clone git://git.drogon.net/wiringPi

cd wiringPi
./build

On fait un petit test en lançant

gpio readall

et on observe quelque chose comme ça :

+-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 |     |     |    3.3v |      |   |  1 || 2  |   |      | 5v      |     |     |
 |   2 |   8 |   SDA.1 |   IN | 1 |  3 || 4  |   |      | 5V      |     |     |
 |   3 |   9 |   SCL.1 |   IN | 1 |  5 || 6  |   |      | 0v      |     |     |
 |   4 |   7 | GPIO. 7 |   IN | 1 |  7 || 8  | 0 | OUT  | TxD     | 15  | 14  |
 |     |     |      0v |      |   |  9 || 10 | 1 | ALT0 | RxD     | 16  | 15  |
 |  17 |   0 | GPIO. 0 |   IN | 0 | 11 || 12 | 0 | IN   | GPIO. 1 | 1   | 18  |
 |  27 |   2 | GPIO. 2 |   IN | 0 | 13 || 14 |   |      | 0v      |     |     |
 |  22 |   3 | GPIO. 3 |   IN | 0 | 15 || 16 | 0 | IN   | GPIO. 4 | 4   | 23  |
 |     |     |    3.3v |      |   | 17 || 18 | 0 | IN   | GPIO. 5 | 5   | 24  |
 |  10 |  12 |    MOSI |   IN | 0 | 19 || 20 |   |      | 0v      |     |     |
 |   9 |  13 |    MISO |   IN | 0 | 21 || 22 | 0 | IN   | GPIO. 6 | 6   | 25  |
 |  11 |  14 |    SCLK |   IN | 0 | 23 || 24 | 1 | IN   | CE0     | 10  | 8   |
 |     |     |      0v |      |   | 25 || 26 | 1 | IN   | CE1     | 11  | 7   |
 |   0 |  30 |   SDA.0 |   IN | 1 | 27 || 28 | 1 | IN   | SCL.0   | 31  | 1   |
 |   5 |  21 | GPIO.21 |   IN | 1 | 29 || 30 |   |      | 0v      |     |     |
 |   6 |  22 | GPIO.22 |   IN | 1 | 31 || 32 | 0 | IN   | GPIO.26 | 26  | 12  |
 |  13 |  23 | GPIO.23 |   IN | 0 | 33 || 34 |   |      | 0v      |     |     |
 |  19 |  24 | GPIO.24 |   IN | 0 | 35 || 36 | 0 | IN   | GPIO.27 | 27  | 16  |
 |  26 |  25 | GPIO.25 |   IN | 0 | 37 || 38 | 0 | IN   | GPIO.28 | 28  | 20  |
 |     |     |      0v |      |   | 39 || 40 | 0 | IN   | GPIO.29 | 29  | 21  |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+

On voit ici que mon GPIO15 est configuré en OUT (ce qui m’intéresse pour contrôler mon relais !)

un petit coup pour qu’il soit toujours actif en OUT :

sudo nano /etc/rc.local

Et on ajoute juste avant « exit 0 » la ligne :

/usr/local/bin/gpio mode 15 out

Ctrl+X et on valide par Y pour enregistrer la configuration.

Maintenant on va aller ajouter ça à l’interface d’octoprint :

sudo nano ~/.octoprint/config.yaml

iDans la partie « action » on va aller rajouter :

- action: Printer on
command: gpio write 15 1
name: Printer On
- action: Printer off
command: gpio write 15 0
name: Printer Off

Soit :

 actions:
  - action: shutdown
    async: true
    command: sudo shutdown -h now
    confirm: You are about to shutdown the system.
    ignore: true
    name: Shutdown
  - action: reboot
    async: true
    command: sudo shutdown -r now
    confirm: You are about to reboot the system
    ignore: true
    name: Reboot
  - action: restart
    async: true
    command: sudo service octoprint restart
    confirm: You are about to restart OctoPrint
    ignore: true
    name: Restart OctoPrint
  - action: Printer on
    command: gpio write 15 1
    name: Printer On
  - action: Printer off
    command: gpio write 15 0
    name: Printer Off

Et du coup on a ces deux entrées dans le menu :

5697edde807b8_OctoPrint-GoogleChrome.jpg.43028aa36a7cb5ed227261b6a7514b52

Petit rajout : Octoprint possède de nombreux plugins dont « email notifier » qui envoi un mail quand l’impression est finie.

Pour l’utiliser il faut refaire un peu de ssh :

sudo pip install keyrings.alt
sudo pip install yagmail

On lance ensuite python avec :

~/oprint/bin/python

Puis :

>> import yagmail
>> yagmail.register('mygmailusername', 'mygmailpassword')

Ajout du wifi :

Bon j’ai un CPL qui m’a lâché, donc j’ai voulu connecter le Rasp en Wifi.

Une petit manipulation à faire :

sudo nano /etc/network/interfaces

Le fichier se présente de cette façon :

auto lo
iface lo inet loopback

auto eth0
allow-hotplug eth0
iface eth0 inet manual

auto wlan0
allow-hotplug wlan0
#iface wlan0 inet manual
#wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf


auto wlan1
allow-hotplug wlan1
# iface wlan1 inet manual
# wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

on va aller rajouter ces deux lignes dans « auto wlan0 » juste après « allow-hotplug wlan0 » :

 wpa-ssid "nom du réseau"
 wpa-psk "Mot de passe"

on ferme, on reboot et voilà on est en wifi !

3. Le capteur inductif :

Bon là on complique un peu (beaucoup en fait).

J’ai pris cette sonde sur eBay et je me suis imprimé son support.

J’ai monté ma sonde et j’ai attaqué les réglages.

La sonde est une sonde 12V donc on doit réduire la sortie de la sonde pour ne pas endommager la carte ramps !

Raccordement sonde

Une fois fait on déconnecte le capteur de fin de course Zmin et on vient y brancher notre sonde.

Il est temps d’étalonner notre capteur !

Je me suis servit d’Octoprint pour commander l’imprimante pendant les manipulations, c’est très pratique !

  1. Première étape, on va aller placer l’extrudeuse au centre du plateau (icône home quand on est dans l’onglet control).
  2. Avec un marqueur on fait une petit croix juste en dessous de la buse d’impression.
  3. On coupe l’alimentation de l’imprimante (alors on coupe juste la partie sur le 12V, le cable USB doit rester branché sur le Rasp).
  4. On descend la tête manuellement (oui oui, en pesant tourner les moteurs à la main) pour ajuster notre zéro (on doit pouvoir passer une feuille sous la buse, même manipulation que quand on règle le niveau en manuel).
  5. Dans octoprint on va dans terminal et on envoie la commande : G92 X0 Y0 Z0
  6. On remet l’alimentation 12V de l’imprimante
  7. On va dans Control et on va aller déplacer la sonde de telle manière à ce qu’elle soit positionnée et centrée sur la croix (ainsi on va connaitre le décalage entre notre sonde et la buse).
  8. En jouant avec les moteur on fait varier la hauteur de l’axe Z pour trouver la position à laquelle le capteur s’enclenche (la led éclaire faiblement / fortement).
  9. Une fois cette étape faite, on lance dans l’onglet terminal la commande M114 (qui va nous donner la position de l’extruder par rapport à la position qu’on a définie comme le zéro à l’étape 5).
  10. Et on relève les valeurs obtenues en résultat (chez moi ça donne X 23 Y 28 Z 4.7) (on les notes sur un papier).
  11. Maintenant on va aller préparer le firmware pour que le niveau devienne automatique :
  • Dans configuration.h :

On commente la ligne (avec // en début de ligne) :

#define ENDSTOPPULLUP_ZMIN

On dé-commente la ligne (on vire les //) :

#define ENABLE_AUTO_BED_LEVELING

On règle ensuite le rectangle de palpage (que je vais surement modifier, mais je ne dis pas pourquoi) :

 // set the rectangle in which to probe
    #define LEFT_PROBE_BED_POSITION 15
    #define RIGHT_PROBE_BED_POSITION 160
    #define BACK_PROBE_BED_POSITION 160
    #define FRONT_PROBE_BED_POSITION 20

Le nombre de alpages, j’en veux 4 donc je met deux (mais je vais tester avec 9, donc 3, normalement à cette étape rien à faire c’est déjà à deux, mais on vérifie) :

   #define AUTO_BED_LEVELING_GRID_POINTS 2

Et ensuite on va aller définir les réglages du capteur :

#define X_PROBE_OFFSET_FROM_EXTRUDER -23
#define Y_PROBE_OFFSET_FROM_EXTRUDER -28
#define Z_PROBE_OFFSET_FROM_EXTRUDER -4.7

Et là vous retrouvez les valeurs du point 10, avec juste un signe négatif devant (le signe négatif EST INDISPENSABLE !).

On modifie encore deux trois valeurs (ça donne de la rapidité au niveau automatique).

 #define Z_RAISE_BEFORE_HOMING 10       // (in mm) Raise Z before homing (G28) for Probe Clearance.
                                        // Be sure you have this distance over your Z_MAX_POS in case

  #define Z_RAISE_BEFORE_PROBING 1    //How much the extruder will be raised before traveling to the first probing point.
  #define Z_RAISE_BETWEEN_PROBINGS 1  //How much the extruder will be raised when traveling from between next probing points
  • Dans configuration_adv.h :

On dé-commente la ligne

#define ENDSTOPS_ONLY_FOR_HOMING // If defined the endstops will only be used for homing
  • Dans ultralcd.cpp

On commente la ligne (on vire l’entrée dans le menu du lcd qui lance le niveau du plateau, vu qu’il sera fait automatiquement à chaque impression) :

MENU_ITEM(function, MSG_LEVEL_PLATE, function_config_level_bed);
  • Dans Cura :

On va aller modifier GCODE de départ :

; -- START GCODE --
;Sliced at: {day} {date} {time}
;Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {fill_density}
;Print time: {print_time}
;Filament used: {filament_amount}m {filament_weight}g
;Filament cost: {filament_cost}
;Uncomment to add your own temperature line
;M109 S{print_temperature}
;Uncomment to add your own bed temperature line
;M190 S{print_bed_temperature}
G21                     ;metric values
G90                     ;absolute positioning
M107                    ;start with the fan off
G28 X0 Y0               ;move X/Y to min endstops
G28 Z0                  ;move Z to min endstops
G1 Z15.0 F1200          ;move the platform down 15mm
G92 E0                  ;zero the extruded length
G1 F200 E20             ;extrude 20mm of feed stock
G92 E0                  ;zero the extruded length again
G1 F{travel_speed}
;Uncomment to put a printing message on LCD screen
;M117 Printing...
; -- end of START GCODE --

On modifie les lignes 14 et 15 :

; -- START GCODE --
;Sliced at: {day} {date} {time}
;Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {fill_density}
;Print time: {print_time}
;Filament used: {filament_amount}m {filament_weight}g
;Filament cost: {filament_cost}
;Uncomment to add your own temperature line
;M109 S{print_temperature}
;Uncomment to add your own bed temperature line
;M190 S{print_bed_temperature}
G21                     ;metric values
G90                     ;absolute positioning
M107                    ;start with the fan off
G28                     ;move X/Y to min endstops
G29                     ;AUTOLEVEL
G1 Z15.0 F1200          ;move the platform down 15mm
G92 E0                  ;zero the extruded length
G1 F200 E20             ;extrude 20mm of feed stock
G92 E0                  ;zero the extruded length again
G1 F{travel_speed}
;Uncomment to put a printing message on LCD screen
;M117 Printing...
; -- end of START GCODE --

 

 

Publié le

Imprimante 3D – Mon expérience de montage (Partie 1)

Ca fait 3 ou 4 ans que je m’intéresse aux imprimantes 3D, mais je n’avais jamais craqué à cause du budget élevé, mais aussi par peur de ne pas y arriver.

Pendant les soldes, j’ai reçu un mail de Darty avec un imprimante 3D soldée à 600€ (au lieu de 1200€). Petit tour sur internet pour regarder ce que ça valait, bonne imprimante pour débuter, mais le prix des filaments est exorbitant (filaments propriétaires à 55€ les 600g, j’abandonne de suite).

Mais là j’avais vraiment envie de me lancer, donc j’ai cherché des modèles à monter sois même (pour affranchir des filaments propriétaires) et je suis tombé sur la Bq Hepestos Prusa i3. Elle me parait sympa, un petit tour sur les commentaires sur internet, sur le prix des filaments (20€ le rouleau d’1kg), tour sur les forums pour le montage (montage de l’imprimante, plateau chauffant…) et je décide de craquer ! Je prends donc le kit à 510€ (livré avec 1Kg de filament couleur au choix) et j’ajoute le kit plateau chauffant à 15€ (autant le prendre de suite). Petit tour sur le panier et là une belle surprise :

IMG_1006

472€ au lieu des 525€ annoncés (il y avait une remise de 10% pour deux articles achetés).

Je la commande donc directement !

1. La réception et l’ouverture des colis (Vendredi 12 Février) :

Je reçois donc mon colis à 13h et il ne me tarde qu’une chose : ouvrir le colis et attaquer le montage.

J’avais vu sur des forums que certains avaient mit entre 20 et 25h pour la monter du coup il me tardait de m’y mettre (surtout avec un week end très chargé en cours).

IMG_1023IMG_1024IMG_1025

  1. La première étape : mettre les écrous dans les morceaux de PLA avec un fer à 100°C environ pour qu’ils restent en place.

L’étape la plus ennuyeuse du montage, et qui m’a prit dans les 1h tellement c’est *****

2.  Seconde étape : On attaque le montage de l’axe X

Alors là rien de dur, j’y ai mit 20 minutes environ, le plus chiant est de passer les tiges dans les roulements sans faire sauter de billes (on y va tout doucement, avec calme et patience).

IMG_1026

Et c’est tout joli !

3. Troisième étape : Montage de l’axe Z

On commence à rentrer dans le vif du sujet, là j’y ai passé une bonne heure, car on y assemble l’axe X à la fin.

IMG_1027

Ca commence enfin à prendre forme, mais là mon cours devait arriver donc pause le temps des cours.

4. Quatrième étape : Montage de l’axe Y

J’ai repris le montage le soir vers 20h30, pour la partie la plus épaisse du guide, le montage de l’axe Y ou vient se greffer à la fin l’assemblage axe Z et X. Deux bonnes heures pour monter tout ça (en plus avec la fatigue je commençais à avoir du mal).

 

5. Cinquième étape : montage de l’extrudeuse

J’avais vu que cette étape était très rapide, donc en 20 minutes je l’ai montée avant d’aller me coucher.

IMG_1032

2. La partie électronique (samedi 13 février) :

Alors grosse journée de cours, j’ai un peu trainé au lit et je me suis mis à la sixième étape qu’après manger (vers 12h45).

C’est la partie que j’attendais et appréhendais le plus. Là le manuel pèche un peu (surtout pour la connexion des moteurs, instinctivement je me suis repéré au fil noir et ça a roulé).

Mais le premier problème devait bien arriver ! Au premier branchement de l’imprimante, je remarque que la carte se met en court circuit ! Je titille un peu les fin de courses et je me rends compte que le capteur Z lorsqu’il n’était pas enclenché. J’échange le câblage de ce fin de course avec un X et là c’est le X qui passe problème. Là le stress est un peu monté, mais un gentil twittos m’a dit de vérifier mes câblages et une nappe de connexion avait les fils jaunes et noirs inversés !

IMG_1038

Un petit coup de tournevis et hop le problème est réglé !

J’en suis donc à la partie réglage : je met de niveau mon axe Z, facile avec une bonne règle, je met mon plateau à peut près droit (pour avoir moins à le bouger au nivellement du plateau) et je tente de mettre en place mon filament dans l’extrudeuse.

Et là second problème ! Mon filament ne veut pas rentrer !

IMG_1041IMG_1040

J’avais fait un biseau trop court, en le faisant sur 5 cm mon fil à fini par rentrer (ouf).

Il ne reste plus qu’à lancer la première impression ! Youpi !

 

 

Ah qu’elle est belle ma grenouille !

3. L’installation du plateau chauffant (Lundi 15 février) :

J’avais commandé un plateau chauffant, donc le lundi je me suis attelé à le monter.

Les tutos sur internet sont bien fait, donc je ne vais pas rentrer dans les détails (des détails il y en aura un peu plus tard !).

IMG_1067

4. Installation du capteur inductif (Jeudi 18 février – Vendredi 19 février) :

Bon refaire le niveau du plateau c’est chiant, du coup j’avais commandé un capteur inductif pour pouvoir faire un auto-level (il se fait au lancement de chaque impression, c’est un sacré gain de temps).

Pour son installation, je ferai un autre article plus tard (avec aussi la partie Raspberry Pi et serveur d’impression sur le réseau)

J’ai aussi fixé l’imprimante sur un bout de plan de travail pour éviter qu’elle vibre (ça bouge beaucoup ces bestioles !).

IMG_1108

Et voilà ja fin de l’article !

La suite dans la semaine !

image

Publié le

Collier wifi pour chien (ESP8266)

Mathieu m’a demandé si je pouvais lui faire un système pour être prévenu lorsque Stuart (son chien) n’est plus à portée du wifi. Du coup je me suis lancé dans la confection d’un prototype ainsi que d’une interface de contrôle.

1. Le prototype :

Je suis habitué à travailler avec l’ESP8266 donc naturellement je vais l’utiliser ici.

Le prototype est assez simple (mais relativement efficace !) :

IMG_0923

Je passe sur les branchements, voici le fichier :

#include <ESP8266WiFi.h>
#define led 2

const char* ssid     = "Livebox-4246-ext";
const char* password = "";

const char* host = "192.168.1.50";

void setup() {
  Serial.begin(115200);
  delay(10);
  pinMode(led,OUTPUT);
  digitalWrite(led,LOW);
  
  // We start by connecting to a WiFi network

  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

int value = 0;

void loop() {
  if (WiFi.status() == WL_CONNECTED){
    digitalWrite(led,HIGH);
  }
  else {
    digitalWrite(led,LOW);
  }
  

  Serial.print("connecting to ");
  Serial.println(host);
  
  // Use WiFiClient class to create TCP connections
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }
  
  // We now create a URI for the request
  String url = "/stuart/stuart.php";
  
  Serial.print("Requesting URL: ");
  Serial.println(url);
  
  // This will send the request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" + 
               "Connection: close\r\n\r\n");
  delay(10);
  
  // Read all the lines of the reply from server and print them to Serial
  while(client.available()){
    String line = client.readStringUntil('\r');
    Serial.print(line);
  }
  
  Serial.println();
  Serial.println("closing connection");

  delay(60000);
}

 

 

IMG_0929

Voici la version sans les leds.

La vidéo suivante vous montre le passage de l’état non connecté (led rouge) à connecté (led verte) :

 

2. La partie récupération des données et traitement :

Pour le moment j’ai tout hébergé sur mon NAS synology.

J’ai donc créé dans un premier temps deux tables :

  • Une « detection » qui va enregistrer le timestamp de la dérnière connexion de l’ESP8266
  • Une « suivit » pour activer/désactiver le tracking.

2.1 L’alimentation de la table détection :

J’ai créé un script php qui ajoute juste à ma table le temps php :

<?php
   include("connexionDB.php");

   $date = time();
   mysql_query("INSERT INTO detection (datedetection) VALUES ('$date')");
 echo $date;
?>

2.2 Le contrôle de la surveillance :

Bon Mathieu ne vas pas surveiller Stuart H24, donc il fallait trouver un système pour ne pas créer d’alerte quand on éteint le boitier.

J’ai donc ajouté la table suivit pour savoir si oui ou non on surveille le chien :

<?php 
$page = $_SERVER['PHP_SELF'];
$sec = "5";
include("connexionDB.php");
$req2 = mysql_query("SELECT * FROM suivit ORDER BY rowid DESC LIMIT 1");
   $data2 = mysql_fetch_array($req2);
   
   $etat_suivit = $data2['etat_suivit'];
?>

<style>
    html, body {
   margin: 0;
   padding: 20;
        width:100%;
   height: 100%;
}
    
    div#contenu 
    {
     
   border:none;
        width:100%;
   min-height:100%;
   
    }
    
</style>


<html>
    <head>
   <!-- <meta http-equiv="refresh" content="<?php echo $sec?>;URL='<?php echo $page?>'"> -->
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, user-scalable=no">
          <link rel="stylesheet" type="text/css" href="css/style.css" />
        <title>Gestion tracker</title>
    </head>
    <body>
        <!-- Menu d'entête : -->
        
        <?php if($etat_suivit == 1) {
         $date = time();
   $req = mysql_query("SELECT * FROM detection ORDER BY rowid DESC LIMIT 1");
   $data = mysql_fetch_array($req);
   $last = $data['datedetection'];
   $ecart = $date-$last;
         ?>
         Temps depuis la dernière détection : <?php echo $ecart; ?> sec <Br>
         <?php
        }
        ?>
        <!-- Menu Gauche : -->
        Etat du tracker : 
        
         <div style="width: 50%; height: 10%; float: left ;" class="switch demo">
         <form method='POST' action="post.php">

   
   <input type="checkbox" name="myCheckbox" value="on"
   <?php
   $req2 = mysql_query("SELECT * FROM suivit ORDER BY rowid DESC LIMIT 1");
   $data2 = mysql_fetch_array($req2);
   
   $etat_suivit = $data2['etat_suivit'];
   if ($etat_suivit == 1) {
      ?>
      CHECKED
      <?php
   }
   ?>
   > 
   
   <label><i></i></label>
   
   </div>
   <div style="width: 50%; height: 10%; float: left ;">
   <input type="submit" name="Envoyer" value="Envoyer" />
   </div>
   </form>
   
        
    </body>
</html>

Et le fichier post.php :

<?php 
include("connexionDB.php");


if(isset($_POST['myCheckbox']) && $_POST['myCheckbox']=="on")
{
    $myCheckbox='1';
}
else
{      
    $myCheckbox='0';
}

mysql_query("INSERT INTO suivit(etat_suivit) VALUES ('$myCheckbox')");
         
?>

<SCRIPT LANGUAGE="JavaScript"> 
document.location.href="gestion.php" 
</SCRIPT> 

 

C’est pas du grand art, mais c’est juste dans un premier temps faire des tests, voilà ce que ça donne :

IMG_0932 [162328]IMG_0933 [162329]

 

2.3 Le système d’alerte :

Alors petit fichier php toujours, que mon NAS va exécuter toutes les minutes :

<?php
   

   include("connexionDB.php");
   $date = time();
   $req = mysql_query("SELECT * FROM detection ORDER BY rowid DESC LIMIT 1");
   $data = mysql_fetch_array($req);
   $last = $data['datedetection'];
   $ecart = $date-$last;
   echo $ecart;

   $req2 = mysql_query("SELECT * FROM suivit ORDER BY rowid DESC LIMIT 1");
   $data2 = mysql_fetch_array($req2);
   
   $etat_suivit = $data2['etat_suivit'];
   echo $etat_suivit ;
?>

<?php
if ($ecart > 65 && $etat_suivit > 0) {
$to = "j.pgarcia@me.com";
$subject = "Alerte Stuart";
$body = "Stuart est hors de porté wifi depuis ".$ecart." secondes !";
$headers = 'From: ESP8266 Stuart';

mail($to, $subject, $body, $headers);


}


?>

Et voilà pour le moment !

 

Publié le

Tourteau Gascon

L’Epiphanie vient de passer et en Gascogne on ne mange pas de galette à la frangipane, mais du Tourteau Gascon.

A la base, ce gâteau (entre le pain et la brioche) est le gâteau de Pacques Gascon (de nos jours on en trouve sans soucis de l’Epiphanie à Pacques, ainsi qu’en dehors de cette saison).

La recette comme celle du Pastis est assez traditionnelle et contient juste un secret : le parfum. Chaque famille à sa formule pour le parfum, ou alors prend du parfum pour pâtisserie en pharmacie qui là aussi est unique.

contrairement au Pastis, cette recette on ne la fait pas dans la famille (il me semble que ma grand-mère n’en a jamais fait et donc je n’ai pas de secret particulier pour le parfum, mais je vais ajuster au fur et à mesure de mes essais).

 

La recette est très simple, facile à louper, mais moins que pour le Pastis :

Le levain :

Au choix on peut faire avec de la levure fraiche de boulanger ou avec de la levure Briochin d’Alsa.

Moi je fais avec la levure Briochin, du coup je dois préparer mon levain le matin du jour 1 :

  • 4g de levure Briochin (le sachet fait 5,5g bien sur…),
  • 70g de lait,
  • 50g de farine.

On mélange le tout dans un bol et on le laisse reposer recouvert d’un linge pendant 4h dans un endroit chaud (moi je le fait au dessus de la cheminée)

La préparation :

Pour la préparation tout se passe dans le robot :

  • Le levain préparé le matin,
  • 70g de lait (oui oui de nouveau 70g),
  • 2 cuillères à soupe de parfum (moi j’ai fait avec du pousse rapière et un poil de vanille),
  • 2 gros oeufs (oui oui des gros oeufs des vrais oeufs de ferme !),
  • 110g de sucre,
  • 3,5g de sel (en recopiant la recette je vois que j’ai fait cet oubli),
  • 500g de farine,
  • 60g de beurre ramolli.

Notre levain a reposé pendant 4h, on le mélange avec le lait (s’il y a des grumeaux c’est pas grave ils vont partir !).

image

Dans le robot on met le levain et tous les autres ingrédients SAUF LE BEURRE. La j’ai laissé pétrir environ 10 minutes à 3 (puissance max de mon robot 6).

On ajoute ensuite le beurre coupé en petit dés et on continue à pétrir pendant environ 10 minutes (les temps donnés sont peut être un peut faux hein, je ne suis pas un accro de la montre quand je cuisine). La pâte doit être encore un peu collante.

On sort le bol du robot, on le couvre d’un linge (le même que pour le levain hein, on va pas en salir plusieurs !) et on laisse reposer pendant 6h dans un endroit tempéré (chez moi c’est dans la niche à coté de la cheminée).

On en arrive donc au soir (entre le début et ce moment il c’est passé 10h30 environ). On abaisse la pâte pour la dégazer et sur une plaque de cuisson on forme une couronne (alors il faut la faire assez grande sinon plus de trou au milieu) mais pas trop grande la page va quadrupler son volume !). La couronne est faite, on replace le torchon sur la pâte et on laisse reposer toute la nuit (12h environ).

imageimage

On en est donc au jour 2 le matin (moi j’ai un peu mal dormi, j’ai façonné ma couronne à 1h du mat, et à 5h je suis venu voir si elle avait poussée). on met le four à préchauffer à 150-160°C. On badigeonne toute notre couronne avec du jaune d’oeuf et on saupoudre généreusement de sucre (du classique hein, pas de chichis).

IMG_0816

On enfourne ensuite 20-30 minutes. Une fois le Tourteau bien doré, on le sort du four et on le saupoudre de nouveau de sucre.

IMG_0817IMG_0818

 

Publié le

Pastis Gascon (ou Croustade)

Allez un peu de cuisine aujourd’hui avec un monument des desserts gascons : le Pastis.

On en trouve dans les pâtisseries du coin, mais ils sont fait avec de la pâte filo.

Petit, j’en faisais avec ma grand-mère, j’ai beaucoup de bons souvenirs en cuisine avec elle et ça reste de loin mon gâteau préféré. Mais il faut le coup de main ! Un coup de main non pas de pâtissier, mais le coup de main pour étirer la pâte (qui doit être aussi fine que du papier à cigarette !).

Du coup aujourd’hui, je vais vous donner ma recette !

Ingrédients :

  • 500g de farine
  • 20 cl d’eau
  • 1 cs d’huile de tournesol
  • 1 oeuf
  • 1 pincée de sel
  • 2 belles pommes
  • du sucre
  • 2 cs d’Armagnac

Etape 1 : La pâte (à faire la veille au soir)

On commence par battre l’œuf, l’eau et l’huile ensemble avec une pincée de sel. Une fois bien mélangé, on ajoute petit à petit la farine en mélangeant avec le fouet.

Au fur et à mesure de l’ajout de la farine, on remplace le fouet par une cuillère en bois, puis vers la fin on y va avec les mains. La pâte ne doit plus coller (consistance de pâte à pain en gros).

On forme une boule avec la pâte et on donne des coups dessus pour la détendre avec le rouleau à patisserie (environ pendant 3-4 min).

Voilà la video fragmentée :

On place ensuite le pâton dans une poche congélateur avec de l’huile (on hésite pas avec la quantité d’huile !).

Et on laisse reposer toute une nuit (ou au minimum 5h).

IMG_0658

D’un autre coté, on coupe les pommes et on les met à macérer avec l’Armagnac toute la nuit aussi.

Etape 2 : étirer la pâte

C’est l’étape que vous allez louper 7 ou 8 fois avant d’y arriver ! pour ça je vous conseille cette vidéo d’une amie qui maîtrise à la perfection :

(en prime vous avez la recette en entier pour voir la consistance de la pâte).

Sur une table (assez grande la table), on met un linge (moi je fais avec un vieux drap), on le saupoudre de farine, on met notre pâton au centre et on l’étire délicatement pour qu’il recouvre toute la table :

IMG_0661IMG_0662

Une fois la pâte bien étirée, on a deux possibilité : soit la laisser sécher (entre 30 min et 1h) soit accélérer et la sécher au sèche cheveux (très pratique et rapide).

Une fois la pâte sèche, on arrose d’huile (ou de beurre comme Isabelle) et de sucre.

On découpe 4 cercles légèrement plus grand que le poule pour les disposer au fond du moule, on ajoute les pommes, un nouveau cercle sur les pommes.

Avec le reste de pâte étalée (et la plus fine possible) on la froisse pour la déposer au dessus :

IMG_0663

Il ne reste plus qu’à le mettre 30 min au four à 200°C.

IMG_0665

Publié le

Serre connectée !

L’hiver arrive et qui dit hiver, dit préparation des semis pour le jardin (et des plantes aussi).

L’an dernier nous avons fait une étagère sur roulette pour pouvoir entreposer les bacs à semis sous la véranda. Je n’en était pas très satisfait car les chiens dormant dans la véranda, on laisse la porte ouverte et donc la nuit descend pas mal (c’est suffisant pour les agrumes qui sont en hors-gel, mais pour faire lever des pieds de tomate il faut au minimum un mois).

Du coup on est parti pour fermer l’étagère-serre avec des plaques de polycarbonate alvéolé de 16mm (les même que nous avions utilisé en 2011 pour faire la véranda.

Bien sur, je n’ai pas voulu m’arrêter là. J’ai une mini-serre depuis 2 ans qui me sert à faire les semis les plus délicats (surtout niveau température) et j’avais un thermomètre digital, mais bon j’avais la température sur le moment, mais pas d’historique.

1. Partie bricolage, conception de la serre :

Bon là pas trop de bla bla, je ne veux pas rentrer dans les détails, une étagère, des plaques de polycarbonate et on ferme le tout ! (Sauf le haut ou j’ai mit de l’aggloméré).

IMG_0563

2. Partie montage de l’électronique :

J’ai percé mes plaque avec une scie cloche pour poser des ventilateurs de PC sur les deuxième et troisième étagère au centre pour faire une circulation d’air, ainsi que sur les cotés pour faire passer mes câbles.

IMG_0560

Pour le haut de la serre j’ai fait une aération avec une plaque de polycarbonate qui glisse en récupérant le chariot d’un vieux lecteur CD de PC. Le voici en action :

Voici la liste des composants que j’ai utilisé :

  • Un Arduino méga,
  • Un shield Ethernet,
  • Quatre DS18B20 (capteur température),
  • Un DHT22 (capteur température et humidité),
  • Un pont en H (SainSmart L298N),
  • Un écran LCD 1602 en I2C,
  • Un transfo 12V,
  • Un régulateur de tension 5V,
  • Un relais,
  • Une boite de dérivation,
  • Une boite de jonction avec façade transparente,
  • Un vieux lecteur CD,
  • Des câbles, des résistances de 4.7kΩ.

Petit avantage du L298N, il permet d’alimenter l’Arduino (et oui j’ai besoin de 12V pour alimenter les ventilos et le chariot du lecteur CD).

Voici le montage :

Serre_bb3

 

3. Programmation de la carte :

Gros programme :

  • Relevé des températures
  • Si la moyenne est supérieure à 30°C => ouverture de la serre
  • Si la température est inférieure à 22°C => On allume le chauffage
  • Envoie des données sur mon site.

Voici le programme (qui est à mon sens encore améliorable :

#include <LiquidCrystal_I2C.h>
#include <SPI.h>
#include <Ethernet.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include "DHT.h"
#include <Wire.h>

//Déclarations de l'écran
LiquidCrystal_I2C lcd(0x27, 16, 2);

// Déclaration des sondes DS18B20
#define ONE_WIRE_MINI_SERRE 22 
#define ONE_WIRE_ETAGE_1 23
#define ONE_WIRE_ETAGE_3 25 
#define ONE_WIRE_VERRANDA 26 

OneWire oneWire1(ONE_WIRE_MINI_SERRE);
OneWire oneWire2(ONE_WIRE_ETAGE_1);
OneWire oneWire3(ONE_WIRE_ETAGE_3);
OneWire oneWire4(ONE_WIRE_VERRANDA);

DallasTemperature mini_serre(&oneWire1);
DallasTemperature etage_1(&oneWire2);
DallasTemperature etage_3(&oneWire3);
DallasTemperature verranda(&oneWire4);

// Déclaration DHT :
#define DHTTYPE DHT22
#define DHTPIN 24

DHT dht(DHTPIN, DHTTYPE);

// Déclaration interrupteur ouverture porte
#define Etat_Ouverture 27

// Déclaration RELAIS chauffage
#define Relais_Chauffage 28
int Etat_chauffage = 0 ;

//Déclaration pins OUVERTURE HAUT :
#define Pin1 29
#define Pin2 30

// Réseau :
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
char server[] = "www.jpg32190.fr";
IPAddress ip(192, 168, 1, 177);
EthernetClient client;


void setup() {
  Serial.begin(9600);
  lcd.begin();
  lcd.backlight();
  mini_serre.begin();
  etage_1.begin();
  etage_3.begin();
  verranda.begin();
  dht.begin();
  pinMode(Etat_Ouverture,INPUT);
  pinMode(Relais_Chauffage,OUTPUT);
  pinMode(Pin1,OUTPUT);
  pinMode(Pin2,OUTPUT);

  // On met le chauffage à zéro :
  digitalWrite(Relais_Chauffage,LOW);

 // LANCEMENT RESEAU
 lcd.print("demarrage");
  if (Ethernet.begin(mac) == 0) {
     Serial.println("Failed to configure Ethernet using DHCP");
     Ethernet.begin(mac, ip);
   }
    delay(1000);
    Serial.println("connecting...");
    Serial.print("My IP address: ");
    String showIP = "";
    lcd.clear();
    for (byte thisByte = 0; thisByte < 4; thisByte++) {
    // print the value of each byte of the IP address:
      Serial.print(Ethernet.localIP()[thisByte], DEC);
    
      lcd.print(Ethernet.localIP()[thisByte], DEC);
      lcd.print(".");
      Serial.print(".");
    }
    Serial.println();
  delay(3000);

  
}

void loop() {
  // Requêtes des DS18B20 :
  mini_serre.requestTemperatures();
  float temp_mini_serre = mini_serre.getTempCByIndex(0);
  while (temp_mini_serre >80 || temp_mini_serre < -50) {
    mini_serre.requestTemperatures();
  float temp_mini_serre = mini_serre.getTempCByIndex(0);
  }
  etage_1.requestTemperatures();
  float temp_etage_1 = etage_1.getTempCByIndex(0);
  while (temp_etage_1 >80 || temp_etage_1 < -50) {
    etage_1.requestTemperatures();
  float temp_etage_1 = etage_1.getTempCByIndex(0);
  }
  etage_3.requestTemperatures();
  float temp_etage_3 = etage_3.getTempCByIndex(0);
  while (temp_etage_3 >80 || temp_etage_3 < -50) {
    etage_3.requestTemperatures();
  float temp_etage_3 = etage_3.getTempCByIndex(0);
  }
  verranda.requestTemperatures();
  float temp_verranda = verranda.getTempCByIndex(0);
  while (temp_verranda >80 || temp_verranda < -50) {
    verranda.requestTemperatures();
  float temp_verranda = verranda.getTempCByIndex(0);
  }
  
  // Requete du DHT22 :
  float temp_etage_2 = dht.readTemperature();
  float humidite = dht.readHumidity();
  

  // AFFICHAGE SUR LE LCD :
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(temp_etage_1);
  lcd.print("  ");
  lcd.print(temp_etage_2);
  lcd.setCursor(0,1);
  lcd.print(temp_etage_3);
  lcd.print("  ");
  lcd.print(temp_mini_serre);
  

  
  // Commande ouverture / fermeture haut :
  float moyenne_temperature = (temp_etage_1 + temp_etage_2 + temp_etage_3 ) / 3;
  int Etat_Couvercle = digitalRead(Etat_Ouverture);

  if (moyenne_temperature > 30) {
    if (Etat_Couvercle != 1) {
      ouverture();
      }
  }
  else {
    if (Etat_Couvercle != 0) {
      fermeture();
      }
  }

  // Controle du chauffage 

  if (moyenne_temperature < 22) {
    digitalWrite(Relais_Chauffage,HIGH);
    Etat_chauffage = 1;
  }
  else {
    digitalWrite(Relais_Chauffage,LOW);
    Etat_chauffage = 0;
  }
   Serial.println(temp_mini_serre);
// PREPARATION DU PULL SUR LE SITE :
  String url = "GET /meteo/serre_data.php?t_mini_serre=";
  url+=String(temp_mini_serre,2);
  url+="&t_serre_1=";
  url+=String(temp_etage_1,2);
  url+="&t_serre_2=";
  url+=String(temp_etage_2,2);
  url+="&t_serre_3=";
  url+=String(temp_etage_3,2);
  url+="&t_verranda=";
  url+=String(temp_verranda,2);
  url+="&h_serre_2=";
  url+=String(humidite,2);
  url+="&etat_ouverture=";
  url+= Etat_Couvercle;
  url+="&etat_chauffage=";
  url+= Etat_chauffage;
  url+= " HTTP/1.1";

  Serial.println(url);
// Envoi des données : 

  if (client.connect(server, 80)) {
    Serial.println("connected");
    client.println(url);
    client.println("Host: www.jpg32190.fr");
    client.println("Connection: close");
    client.println();
    client.stop();
  }
  else {
    Serial.println("connection failed");
  }

  


  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
   // client.stop();
    //while (true);
  }

  delay(60000);
  
  
}


// Fonctions ouverture et fermeture porte :

void ouverture() {
  Serial.println("OUVERTURE");
      digitalWrite(Pin1,LOW);
      digitalWrite(Pin2,HIGH);
      delay(3000);
      Serial.println("pause");
      digitalWrite(Pin1,LOW);
      digitalWrite(Pin2,LOW);
      delay(7000);
}

void fermeture() {
  digitalWrite(Pin1,HIGH);
      digitalWrite(Pin2,LOW);
      delay(3000);
      Serial.println("pause");
      digitalWrite(Pin1,LOW);
      digitalWrite(Pin2,LOW);
      delay(7000);
}

4. Partie web :

Partie ou je suis le plus novice (je faisais déjà du HTML en 2000, mais c’était pas très esthétique).

Ici j’ai choisit d’utiliser encore une fois Highstock pour faire des graphes liée.

Avant ça, première partie la table de données contenant mes températures. Le fichier serre_data.php me permet d’insérer mes données dans ma table sql :

<?php
  include("connexionDB.php");
   $t_mini_serre = $_GET['t_mini_serre'];
   $t_serre_1 = $_GET['t_serre_1'];
   $t_serre_2 = $_GET['t_serre_2'];
   $t_serre_3 = $_GET['t_serre_3'];
   $t_verranda = $_GET['t_verranda'];
   $h_serre_2 = $_GET['h_serre_2'];
   $etat_ouverture = $_GET['etat_ouverture'];
   $etat_chauffage = $_GET['etat_chauffage'];
   
  
   mysql_query("INSERT INTO serre (t_mini_serre, t_serre_1, t_serre_2, t_serre_3, t_verranda, h_serre_2, etat_ouverture, etat_chauffage ) VALUES ('$t_mini_serre','$t_serre_1','$t_serre_2','$t_serre_3','$t_verranda','$h_serre_2','$etat_ouverture','$etat_chauffage' )");
  
?>

La rien de bien compliqué.

Ensuite je dois formater mes données pour pouvoir faire mes graphes. J’ai repris le modèle que j’avais fait pour récupérer mes données Netatmo en faisant un formatage spécial pour l’heure d’été/hiver. C’est mon fichier temperatureserre.php :

<?php
include('connexionDB.php');

$date = 1445538928*1000;
echo "[";
$i=0;
$sth = mysql_query("SELECT datemesure, t_mini_serre, t_serre_1, t_serre_2, t_serre_3 , t_verranda, h_serre_2, etat_chauffage, etat_ouverture FROM serre ORDER BY datemesure ASC");
$rows = array();

while($r = mysql_fetch_array($sth)) {
    if (date("I",time())==0){
    	
    	$date = (strtotime($r["datemesure"])+3600)*1000 ;
    	if (strtotime($r["datemesure"])<1449595350) {
    		$rows[] = "[".$date.",".$r["t_mini_serre"].",".$r["t_serre_1"].",".$r["t_serre_2"].",".$r["t_serre_3"].",".$r["t_verranda"].",".$r["h_serre_2"].",null,".$r["etat_chauffage"].",".$r["etat_ouverture"]."]";
    		$i = $i +1;
    	}
    	else {
    		$rows[] = "[".$date.",".$r["t_mini_serre"].",".$r["t_serre_1"].",".$r["t_serre_2"].",".$r["t_serre_3"].",".$r["t_verranda"].",".$r["h_serre_2"].",".$r["t_verranda"].",".$r["etat_chauffage"].",".$r["etat_ouverture"]."]";
    		$i = $i +1;
    	}
	}
	else {
		
		$date = (strtotime($r["datemesure"])+3600)*1000 ;	
		$rows[] = "[".$date.",".$r["t_mini_serre"].",".$r["t_serre_1"].",".$r["t_serre_2"].",".$r["t_serre_3"].",".$r["t_verranda"].",".$r["h_serre_2"].",".$r["t_verranda"].",".$r["etat_chauffage"].",".$r["etat_ouverture"]."]";
        $i = $i+1;
	}
}
for ($j = 0 ; $j<$i-1; $j ++){
	echo $rows[$j];
	echo ",";
}
echo $rows[$i-1];
echo "]";

?>

Là aussi, je passe les détails, quelques compétences en php permettent de comprendre le code. Vous pouvez regarder le résultat sur ce lien.

Une fois toutes les données récupérées, il reste juste à faire un jolie page pour afficher nos graphes.

C’est la partie qui m’a pris le plus de temps, voici le code :

<?php 
$page = $_SERVER['PHP_SELF'];
$sec = "30";
include('connexionDB.php');

$req = mysql_query("SELECT * FROM serre ORDER BY datemesure DESC LIMIT 1");
while($row = mysql_fetch_assoc($req)) {
   $t_mini_serre =  $row["t_mini_serre"];
   $t_serre_1 =  $row["t_serre_1"];
   $t_serre_2 =  $row["t_serre_2"];
   $t_serre_3 =  $row["t_serre_3"];
   $t_verranda =  $row["t_verranda"];
   $h_serre =  $row["h_serre_2"];
   $etat_ouverture = $row['etat_ouverture'];
   $etat_chauffage = $row['etat_chauffage'];
   
};



        /* On récupère la date du jour et on crée la plage horaire de la journée */
        $day = date("d");
        $month = date("m");
        $year = date("Y");
        $date_inf = $year."-".$month."-".$day." 00:00:00";
        $date_sup = $year."-".$month."-".$day." 23:59:59";

       
        /* On récupère la Température minimum mini serre*/

        $req2 = mysql_query("SELECT * FROM serre WHERE datemesure BETWEEN '$date_inf' AND '$date_sup' ORDER BY t_mini_serre ASC LIMIT 1");
        $data2 = mysql_fetch_array($req2);
        $temperature_minimale_mini = $data2['t_mini_serre'];

        /* On récupère la Température maximum mini serre*/

        $req3 = mysql_query("SELECT * FROM serre WHERE datemesure BETWEEN '$date_inf' AND '$date_sup' ORDER BY t_mini_serre DESC LIMIT 1");
        $data3 = mysql_fetch_array($req3);
        $temperature_maximale_mini = $data3['t_mini_serre'];
    
        

        /* On récupère le temperature minimum serre 1 */

        $req4 = mysql_query("SELECT * FROM serre WHERE datemesure BETWEEN '$date_inf' AND '$date_sup' ORDER BY t_serre_1 ASC LIMIT 1");
        $data4 = mysql_fetch_array($req4);
        $temperature_minimale_serre_1 =  $data4['t_serre_1']   ;
        

        $req5 = mysql_query("SELECT * FROM serre WHERE datemesure BETWEEN '$date_inf' AND '$date_sup' ORDER BY t_serre_1 DESC LIMIT 1");
        $data5 = mysql_fetch_array($req5);
        $temperature_maximale_serre_1 = $data5['t_serre_1'];
        
        /* On récupère le temperature minimum serre 2 */

        $req4 = mysql_query("SELECT * FROM serre WHERE datemesure BETWEEN '$date_inf' AND '$date_sup' ORDER BY t_serre_2 ASC LIMIT 1");
        $data4 = mysql_fetch_array($req4);
        $temperature_minimale_serre_2 =  $data4['t_serre_2']   ;
        

        $req5 = mysql_query("SELECT * FROM serre WHERE datemesure BETWEEN '$date_inf' AND '$date_sup' ORDER BY t_serre_2 DESC LIMIT 1");
        $data5 = mysql_fetch_array($req5);
        $temperature_maximale_serre_2 = $data5['t_serre_2'];
        
        /* On récupère le temperature minimum serre 3 */

        $req4 = mysql_query("SELECT * FROM serre WHERE datemesure BETWEEN '$date_inf' AND '$date_sup' ORDER BY t_serre_3 ASC LIMIT 1");
        $data4 = mysql_fetch_array($req4);
        $temperature_minimale_serre_3 =  $data4['t_serre_3']   ;
        

        $req5 = mysql_query("SELECT * FROM serre WHERE datemesure BETWEEN '$date_inf' AND '$date_sup' ORDER BY t_serre_3 DESC LIMIT 1");
        $data5 = mysql_fetch_array($req5);
        $temperature_maximale_serre_3 = $data5['t_serre_3'];
        
        
        // Moyenne de la temperature de la serre :
        $temperature_minimale_serre = ( $temperature_minimale_serre_1 + $temperature_minimale_serre_2 + $temperature_minimale_serre_3 ) / 3 ;
        $temperature_maximale_serre = ( $temperature_maximale_serre_1 + $temperature_maximale_serre_2 + $temperature_maximale_serre_3 ) / 3 ;
        
        // Humidité serre MINI
        $req8 = mysql_query("SELECT * FROM serre WHERE datemesure BETWEEN '$date_inf' AND '$date_sup' ORDER BY h_serre_2 ASC LIMIT 1");
        $data8 = mysql_fetch_array($req8);
        $humidite_minimale = $data8["h_serre_2"];
        
        // Humidité serre MAXI
        $req9 = mysql_query("SELECT * FROM serre WHERE datemesure BETWEEN '$date_inf' AND '$date_sup' ORDER BY h_serre_2 DESC LIMIT 1");
        $data9 = mysql_fetch_array($req9);
        $humidite_maximale = $data9["h_serre_2"];
        
        // temperature verranda mini
        $req8 = mysql_query("SELECT * FROM serre WHERE datemesure BETWEEN '$date_inf' AND '$date_sup' ORDER BY t_verranda ASC LIMIT 1");
        $data8 = mysql_fetch_array($req8);
        $temperature_verranda_minimale = $data8["t_verranda"];
        
        // temperature verranda maxi
        $req9 = mysql_query("SELECT * FROM serre WHERE datemesure BETWEEN '$date_inf' AND '$date_sup' ORDER BY t_verranda DESC LIMIT 1");
        $data9 = mysql_fetch_array($req9);
        $temperature_verranda_maximale = $data9["t_verranda"];
        
        // VARIATIONS T  / T-1
        $req = mysql_query("SELECT * FROM serre ORDER BY datemesure DESC LIMIT 2");
            while($row = mysql_fetch_assoc($req)) {
                $t_mini_serre_delta[] =  $row["t_mini_serre"];
                $t_serre_1_delta[] =  $row["t_serre_1"];
                $t_serre_2_delta[] =  $row["t_serre_2"];
                $t_serre_3_delta[] =  $row["t_serre_3"];
                $t_verranda_delta[] =  $row["t_verranda"];
                $h_serre_delta[] =  $row["h_serre_2"];
                $etat_ouverture_delta[] = $row['etat_ouverture'];
                $etat_chauffage_delta[] = $row['etat_chauffage'];
   
            };
            $delta_mini_serre = $t_mini_serre_delta[0] - $t_mini_serre_delta[1];
            $delta_serre_1 = $t_serre_1_delta[0] - $t_serre_1_delta[1];
            $delta_serre_2 = $t_serre_2_delta[0] - $t_serre_2_delta[1];
            $delta_serre_3 = $t_serre_3_delta[0] - $t_serre_3_delta[1];
            $delta_verranda = $t_verranda_delta[0] - $t_verranda_delta[1];
            $delta_humidite = $h_serre_delta[0] - $h_serre_delta[1];

    ?>

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <meta http-equiv="refresh" content="<?php echo $sec?>;URL='<?php echo $page?>'">
        <title>Surveillance Serre</title>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
        <link rel="stylesheet" type="text/css" href="css/tableaux.css" media="screen" />
        <link rel="stylesheet" type="text/css" href="css/style.css" />


<script type="text/javascript">





$(function () {
    var highchartsOptions = Highcharts.setOptions(Highcharts.theme);    
Highcharts.setOptions({
lang: {

months: ["Janvier "," Février ","Mars "," Avril "," Mai "," Juin "," Juillet "," Août "," Septembre ",
" Octobre "," Novembre "," Décembre"],
weekdays: ["Dim "," Lun "," Mar "," Mer "," Jeu "," Ven "," Sam"],
shortMonths: ['Jan', 'Fev', 'Mar', 'Avr', 'Mai', 'Juin', 'Juil','Août', 'Sept', 'Oct', 'Nov', 'Déc'],
decimalPoint: ',',
resetZoom: 'Reset zoom',
resetZoomTitle: 'Reset zoom à 1:1',
downloadPNG: "Télécharger au format PNG image",
downloadJPEG: "Télécharger au format JPEG image",
downloadPDF: "Télécharger au format PDF document",
downloadSVG: "Télécharger au format SVG vector image",
exportButtonTitle: "Exporter image ou document",
printChart: "Imprimer le graphique",
loading: "Chargement...",
rangeSelectorFrom: "Du",
rangeSelectorTo: "au"
 }

});
    $.getJSON('temperatureserre.php', function (data) {

        // split the data set into temp_int and temp_ext
        var graph_temp_mini_serre = [],
            graph_t_serre_1 = [],
            graph_t_serre_2 = [],
            graph_t_serre_3 = [],
            graph_h_serre_2 = [],
            graph_t_verranda = [],
            graph_chauffage = [],
            graph_ouverture = [],
            dataLength = data.length,
            // set the allowed units for data grouping
            

            i = 0;

        for (i; i < dataLength; i += 1) {
            graph_temp_mini_serre.push([
                data[i][0], // the date
                data[i][1], // température mini serre
                
            ]);

            graph_t_serre_1.push([
                data[i][0], // the date
                data[i][2] // température serre 1 
            ]);
            
            graph_t_serre_2.push([
                data[i][0], // the date
                data[i][3] // température serre 2 
            ]);
            
            graph_t_serre_3.push([
                data[i][0], // the date
                data[i][4] // température serre 3 
            ]);
            
            
            graph_h_serre_2.push([
                data[i][0], // the date
                data[i][6] // hum 
            ]);

            graph_t_verranda.push([
                data[i][0], // the date
                data[i][7] // hum 
            ]);
            
            graph_chauffage.push([
                data[i][0], // the date
                data[i][8] // état chauffage 
            ]);
            
            graph_ouverture.push([
                data[i][0], // the date
                data[i][9] // état ouverture 
            ]);
            
           
            }


        // create the chart
        $('#container2').highcharts('StockChart', {
            credits: {
            enabled: false
        },
             rangeSelector : {
                buttons : [ {
                    type : 'hour',
                    count : 3,
                    text : '3h'
                },{
                    type : 'hour',
                    count : 12,
                    text : '12h'
                },{
                    type : 'day',
                    count : 1,
                    text : '1j'
                },{
                    type : 'day',
                    count : 7,
                    text : '1s'
                },{
                    type : 'month',
                    count : 1,
                    text : '1m'
                }, {
                    type : 'all',
                    count : 1,
                    text : 'Tout'
                }],
                selected : 1
            },
           
            title: {
                text: 'Surveillance Serre'
            },
            
            yAxis: [{
                
                labels: {
                    align: 'right',
                    x: -3
                },
                title: {
                    text: 'Température'
                },
                height: '50%',
                lineWidth: 2
            }, {
                labels: {
                    align: 'right',
                    x: -3
                },
                title: {
                    text: 'Humidité'
                },
                top: '55%',
                height: '30%',
                offset: 0,
                lineWidth: 2
            },{
                labels: {
                    align: 'right',
                    x: -3
                },
                title: {
                    text: 'État'
                },
                min:-0.25,
                max:1,
                top: '90%',
                height: '10%',
                offset: 0,
                lineWidth: 2
            }],
            xAxis: {
                ordinal: false,
                alternateGridColor: '#F0FFFF'
            },
            tooltip: {
                    xDateFormat: '%a %d %b %H:%M'
                    
                },
            plotOptions: {
                line: {
                    connectNulls: false,
                        }
            },
            series: [{
                name: 'T° mini Serre',
                color:'#58ACFA',
                data: graph_temp_mini_serre,
                tooltip: {
                    valueDecimals: 1,
                    valueSuffix:' °C'
                }
            }, {
                name: 'T° Serre étage 1',
                color:'#CC2EFA',
                data: graph_t_serre_1,
                yAxis:0,
                tooltip: {
                    valueDecimals: 1,
                    valueSuffix:' °C'
                }
            },
            {
                name: 'T° Serre étage 2',
                color: '#FE2E64',
                data: graph_t_serre_2,
                yAxis:0,
                tooltip: {
                    valueDecimals: 1,
                    valueSuffix:' °C'
                }
            },
            {
                name: 'T° Serre étage 3',
                color: '#04B431',
                data: graph_t_serre_3,
                yAxis:0,
                tooltip: {
                    valueDecimals: 1,
                    valueSuffix:' °C'
                }
            },
            {
                name: 'T° Verranda',
                color: '#FE642E',
                data: graph_t_verranda,
                yAxis:0,
                tooltip: {
                    valueDecimals: 1,
                    valueSuffix:' °C'
                }
            },
            
            {
                name: 'Humidité intérieur',
                color: '#5882FA',
                data: graph_h_serre_2,
                yAxis: 1,
                tooltip: {
                    valueDecimals: 1,
                    valueSuffix:' %'
                }
            },
            {
                name: 'Chauffage',
                data: graph_chauffage,
                yAxis:2,
                tooltip: {
                    valueDecimals: 1,
                    valueSuffix:' °C'
                }
            },
            {
                name: 'Ouverture',
                data: graph_ouverture,
                yAxis:2,
                tooltip: {
                    valueDecimals: 1,
                    valueSuffix:' °C'
                }
            }]
        });
    });
});




// Temp mini serre
$(function () {

    $('#temp_mini_serre').highcharts({

        chart: {
            type: 'gauge',
            plotBackgroundColor: null,
            plotBackgroundImage: null,
            plotBorderWidth: 0,
            plotShadow: false
        },

        title: {
            text: '<span style="font-size:14px; color:#58ACFA">Mini Serre :  <?php echo number_format($t_mini_serre,1,',','.'); ?>°C'
        },
        credits: {
            enabled: false
        },

        pane: {
            startAngle: -150,
            endAngle: 150,
            background: [{
                backgroundColor: {
                    linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
                    stops: [
                        [0, '#FFF'],
                        [1, '#333']
                    ]
                },
                borderWidth: 0,
                outerRadius: '109%'
            }, {
                backgroundColor: {
                    linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
                    stops: [
                        [0, '#333'],
                        [1, '#FFF']
                    ]
                },
                borderWidth: 1,
                outerRadius: '107%'
            }, {
                // default background
            }, {
                backgroundColor: '#DDD',
                borderWidth: 0,
                outerRadius: '105%',
                innerRadius: '103%'
            }]
        },

        // the value axis
        yAxis: {
            min: 10,
            max: 40,

            minorTickInterval: 'auto',
            minorTickWidth: 1,
            minorTickLength: 10,
            minorTickPosition: 'inside',
            minorTickColor: '#666',

            tickPixelInterval: 30,
            tickWidth: 2,
            tickPosition: 'inside',
            tickLength: 10,
            tickColor: '#666',
            labels: {
                step: 1,
                rotation: 'auto'
            },
            title: {
                text: '°C'
            },
            plotBands: [{
                from: 10,
                to: 20,
                color: '#55BF3B' // green
            }, {
                from: 20,
                to: 30,
                color: '#DDDF0D' // yellow
            }, {
                from: 30,
                to: 40,
                color: '#DF5353' // red
            }]
        },
        plotOptions: {
            gauge: {
                dataLabels: {
                    enabled: false
                },
                dial: {
                    radius: '100%'
                }
            }
        },
        series: [{
            color:'#58ACFA',
            name: 'Température mini Serre',
            data: [<?php echo $t_mini_serre; ?>],
            tooltip: {
                valueSuffix: ' °C'
            }
        }]

    });
});

// temp etage 1
$(function () {

    $('#temp_serre_etage_1').highcharts({

        chart: {
            type: 'gauge',
            plotBackgroundColor: null,
            plotBackgroundImage: null,
            plotBorderWidth: 0,
            plotShadow: false
        },
        credits: {
            enabled: false
        },

        title: {
            text: '<span style="font-size:14px; color:#CC2EFA">Serre étage 1 :  <?php echo number_format($t_serre_1,1,',','.'); ?> °C'
        },

        pane: {
            startAngle: -150,
            endAngle: 150,
            background: [{
                backgroundColor: {
                    linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
                    stops: [
                        [0, '#FFF'],
                        [1, '#333']
                    ]
                },
                borderWidth: 0,
                outerRadius: '109%'
            }, {
                backgroundColor: {
                    linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
                    stops: [
                        [0, '#333'],
                        [1, '#FFF']
                    ]
                },
                borderWidth: 1,
                outerRadius: '107%'
            }, {
                // default background
            }, {
                backgroundColor: '#DDD',
                borderWidth: 0,
                outerRadius: '105%',
                innerRadius: '103%'
            }]
        },

        // the value axis
        yAxis: {
            min: -10,
            max: 40,

            minorTickInterval: 'auto',
            minorTickWidth: 1,
            minorTickLength: 10,
            minorTickPosition: 'inside',
            minorTickColor: '#666',

            tickPixelInterval: 30,
            tickWidth: 2,
            tickPosition: 'inside',
            tickLength: 10,
            tickColor: '#666',
            labels: {
                step: 2,
                rotation: 'auto'
            },
            title: {
                text: '°C'
            },
            plotBands: [{
                from: -10,
                to: 0,
                color: '#6BDBF7' // blue
            },{
                from: 0,
                to: 20,
                color: '#55BF3B' // green
            }, {
                from: 20,
                to: 30,
                color: '#DDDF0D' // yellow
            }, {
                from: 30,
                to: 40,
                color: '#DF5353' // red
            }]
        },
        plotOptions: {
            gauge: {
                dataLabels: {
                    enabled: false
                },
                dial: {
                    radius: '100%'
                }
            }
        },
        series: [{
            color:'#CC2EFA',
            name: 'Température Serre',
            data: [<?php echo $t_serre_1; ?>],
            tooltip: {
                valueSuffix: ' °C'
            }
        }]

    });
});


// temp etage 2
$(function () {

    $('#temp_serre_etage_2').highcharts({

        chart: {
            type: 'gauge',
            plotBackgroundColor: null,
            plotBackgroundImage: null,
            plotBorderWidth: 0,
            plotShadow: false
        },
        credits: {
            enabled: false
        },
        title: {
            text: '<span style="font-size:14px; color:#FE2E64">Serre étage 2 : <?php echo number_format($t_serre_2,1,',','.'); ?> °C'
        },

        pane: {
            startAngle: -150,
            endAngle: 150,
            background: [{
                backgroundColor: {
                    linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
                    stops: [
                        [0, '#FFF'],
                        [1, '#333']
                    ]
                },
                borderWidth: 0,
                outerRadius: '109%'
            }, {
                backgroundColor: {
                    linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
                    stops: [
                        [0, '#333'],
                        [1, '#FFF']
                    ]
                },
                borderWidth: 1,
                outerRadius: '107%'
            }, {
                // default background
            }, {
                backgroundColor: '#DDD',
                borderWidth: 0,
                outerRadius: '105%',
                innerRadius: '103%'
            }]
        },

        // the value axis
        yAxis: {
            min: -10,
            max: 40,

            minorTickInterval: 'auto',
            minorTickWidth: 1,
            minorTickLength: 10,
            minorTickPosition: 'inside',
            minorTickColor: '#666',

            tickPixelInterval: 30,
            tickWidth: 2,
            tickPosition: 'inside',
            tickLength: 10,
            tickColor: '#666',
            labels: {
                step: 2,
                rotation: 'auto'
            },
            title: {
                text: '°C'
            },
            plotBands: [{
                from: -10,
                to: 0,
                color: '#6BDBF7' // blue
            },{
                from: 0,
                to: 20,
                color: '#55BF3B' // green
            }, {
                from: 20,
                to: 30,
                color: '#DDDF0D' // yellow
            }, {
                from: 30,
                to: 40,
                color: '#DF5353' // red
            }]
        },
        plotOptions: {
            gauge: {
                dataLabels: {
                    enabled: false
                },
                dial: {
                    radius: '100%'
                }
            }
        },
        series: [{
            color:'#FE2E64',
            name: 'Température Serre',
            data: [<?php echo $t_serre_2; ?>],
            tooltip: {
                valueSuffix: ' °C'
            }
        }]

    });
});


// temp etage 3
$(function () {

    $('#temp_serre_etage_3').highcharts({

        chart: {
            type: 'gauge',
            plotBackgroundColor: null,
            plotBackgroundImage: null,
            plotBorderWidth: 0,
            plotShadow: false
        },
        credits: {
            enabled: false
        },
        title: {
            text: '<span style="font-size:14px; color:#04B431">Serre étage 3   : <?php  echo number_format($t_serre_3,1,',','.'); ?> °C'
        },

        pane: {
            startAngle: -150,
            endAngle: 150,
            background: [{
                backgroundColor: {
                    linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
                    stops: [
                        [0, '#FFF'],
                        [1, '#333']
                    ]
                },
                borderWidth: 0,
                outerRadius: '109%'
            }, {
                backgroundColor: {
                    linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
                    stops: [
                        [0, '#333'],
                        [1, '#FFF']
                    ]
                },
                borderWidth: 1,
                outerRadius: '107%'
            }, {
                // default background
            }, {
                backgroundColor: '#DDD',
                borderWidth: 0,
                outerRadius: '105%',
                innerRadius: '103%'
            }]
        },

        // the value axis
        yAxis: {
            min: -10,
            max: 40,

            minorTickInterval: 'auto',
            minorTickWidth: 1,
            minorTickLength: 10,
            minorTickPosition: 'inside',
            minorTickColor: '#666',

            tickPixelInterval: 30,
            tickWidth: 2,
            tickPosition: 'inside',
            tickLength: 10,
            tickColor: '#666',
            labels: {
                step: 2,
                rotation: 'auto'
            },
            title: {
                text: '°C'
            },
            plotBands: [{
                from: -10,
                to: 0,
                color: '#6BDBF7' // blue
            },{
                from: 0,
                to: 20,
                color: '#55BF3B' // green
            }, {
                from: 20,
                to: 30,
                color: '#DDDF0D' // yellow
            }, {
                from: 30,
                to: 40,
                color: '#DF5353' // red
            }]
        },
        plotOptions: {
            gauge: {
                dataLabels: {
                    enabled: false
                },
                dial: {
                    radius: '100%'
                }
            }
        },
        series: [{
            color:'#04B431',
            name: 'Température Serre',
            data: [<?php echo $t_serre_3; ?>],
            tooltip: {
                valueSuffix: ' °C'
            }
        }]

    });
});


// temp verranda
$(function () {

    $('#temp_verranda').highcharts({

        chart: {
            type: 'gauge',
            plotBackgroundColor: null,
            plotBackgroundImage: null,
            plotBorderWidth: 0,
            plotShadow: false
        },
        credits: {
            enabled: false
        },
        title: {
            text: ' <span style="font-size:14px; color:#FE642E"> Verranda :  <?php echo number_format($t_verranda,1,',','.'); ?> °C </span>'
        },

        pane: {
            startAngle: -150,
            endAngle: 150,
            background: [{
                backgroundColor: {
                    linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
                    stops: [
                        [0, '#FFF'],
                        [1, '#333']
                    ]
                },
                borderWidth: 0,
                outerRadius: '109%'
            }, {
                backgroundColor: {
                    linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
                    stops: [
                        [0, '#333'],
                        [1, '#FFF']
                    ]
                },
                borderWidth: 1,
                outerRadius: '107%'
            }, {
                // default background
            }, {
                backgroundColor: '#DDD',
                borderWidth: 0,
                outerRadius: '105%',
                innerRadius: '103%'
            }]
        },

        // the value axis
        yAxis: {
            min: -10,
            max: 40,

            minorTickInterval: 'auto',
            minorTickWidth: 1,
            minorTickLength: 10,
            minorTickPosition: 'inside',
            minorTickColor: '#666',

            tickPixelInterval: 30,
            tickWidth: 2,
            tickPosition: 'inside',
            tickLength: 10,
            tickColor: '#666',
            labels: {
                step: 2,
                rotation: 'auto'
            },
            title: {
                text: '°C'
            },
            plotBands: [{
                from: -10,
                to: 0,
                color: '#6BDBF7' // blue
            },{
                from: 0,
                to: 20,
                color: '#55BF3B' // green
            }, {
                from: 20,
                to: 30,
                color: '#DDDF0D' // yellow
            }, {
                from: 30,
                to: 40,
                color: '#DF5353' // red
            }]
        },
        plotOptions: {
            gauge: {
                dataLabels: {
                    enabled: false
                },
                dial: {
                    radius: '100%'
                }
            }
        },
        series: [{

            color:'#FE642E',
            name: 'Température Verranda',
            data: [<?php echo $t_verranda; ?>],
            tooltip: {
                valueSuffix: ' °C'
            }
        }]

    });
});



//Humidité
$(function () {

    $('#hum_serre').highcharts({

        chart: {
            type: 'gauge',
            plotBackgroundColor: null,
            plotBackgroundImage: null,
            plotBorderWidth: 0,
            plotShadow: false
        },
        credits: {
            enabled: false
        },

        title: {
            text: '<span style="font-size:14px; color:#5882FA"> Humidité Serre : <?php echo number_format($h_serre,0,',','.'); ?> %</span> '
        },

        pane: {
            startAngle: -150,
            endAngle: 150,
            background: [{
                backgroundColor: {
                    linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
                    stops: [
                        [0, '#FFF'],
                        [1, '#333']
                    ]
                },
                borderWidth: 0,
                outerRadius: '109%'
            }, {
                backgroundColor: {
                    linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
                    stops: [
                        [0, '#333'],
                        [1, '#FFF']
                    ]
                },
                borderWidth: 1,
                outerRadius: '107%'
            }, {
                // default background
            }, {
                backgroundColor: '#DDD',
                borderWidth: 0,
                outerRadius: '105%',
                innerRadius: '103%'
            }]
        },

        // the value axis
        yAxis: {
            min: 0,
            max: 100,

            minorTickInterval: 'auto',
            minorTickWidth: 1,
            minorTickLength: 10,
            minorTickPosition: 'inside',
            minorTickColor: '#666',

            tickPixelInterval: 30,
            tickWidth: 2,
            tickPosition: 'inside',
            tickLength: 10,
            tickColor: '#666',
            labels: {
                step: 2,
                rotation: 'auto'
            },
            title: {
                text: '%'
            },
            
        },
        plotOptions: {
            gauge: {
                dataLabels: {
                    enabled: false
                },
                dial: {
                    radius: '100%'
                }
            }
        },
        series: [{
            color:'#5882FA',
            name: 'Humidité Serre',
            data: [<?php echo $h_serre; ?>],
            tooltip: {
                valueSuffix: ' %'
            }
        }]

    });
});

$(function () {

    var gaugeOptions = {

        chart: {
            type: 'solidgauge'
        },

        title: null,

        pane: {
            center: ['50%', '85%'],
            size: '140%',
            startAngle: -90,
            endAngle: 90,
            background: {
                backgroundColor: (Highcharts.theme && Highcharts.theme.background2) || '#DF5353',
                innerRadius: '60%',
                outerRadius: '100%',
                shape: 'arc'
            }
        },

        tooltip: {
            enabled: false
        },

        // the value axis
        yAxis: {
            stops: [
                [0.1, '#DF5353'], // red
                [0.9, '#55BF3B'] // green
            ],
            lineWidth: 0,
            minorTickInterval: null,
            tickPixelInterval: 400,
            tickWidth: 0,
            title: {
                y: -70
            },
            labels: {
                y: 16
            }
        },

        plotOptions: {
            solidgauge: {
                dataLabels: {
                    y: 5,
                    borderWidth: 0,
                    useHTML: true
                }
            }
        }
    };

    // The speed gauge
    $('#aeration').highcharts(Highcharts.merge(gaugeOptions, {
        yAxis: {
            min: 0,
            max: 1,
           
        },

        credits: {
            enabled: false
        },

        series: [{
            name: 'Speed',
            data: [<?php echo $etat_ouverture; ?>],
            dataLabels: {
                format: '<span style="font-size:20px">Aération</span></div>'
            },
            tooltip: {
                valueSuffix: ' km/h'
            }
        }]

    }));

    // The RPM gauge
    $('#chauffage').highcharts(Highcharts.merge(gaugeOptions, {
        yAxis: {
            min: 0,
            max: 1,
            
        },
        credits: {
            enabled: false
        },
        series: [{
            name: 'RPM',
            data: [<?php echo $etat_chauffage; ?>],
            dataLabels: {
                format: '<span style="font-size:20px">Chauffage</span></div>'
            },
            tooltip: {
                valueSuffix: ' revolutions/min'
            }
        }]

    }));

    


});




</script>





     
<script src="http://code.highcharts.com/stock/highstock.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/highcharts-more.js"></script>
<script src="https://code.highcharts.com/modules/solid-gauge.js"></script>
<script src="https://code.highcharts.com/modules/data.js"></script>
<!-- <script src="http://code.highcharts.com/modules/exporting.js"></script> -->
    </head>
    <body>
       
       <div id="container2" style="width: 55%; height: 100%; float: left; "></div>
       <div id="temp_mini_serre" style="width: 15%; height: 30%; float: left ; "></div>
       <div id="temp_serre_etage_1" style="width: 15%; height: 30%; float: left ; "></div>
       <div id="temp_serre_etage_2" style="width: 15%; height: 30%; float: left ; "></div>
       <div id="temp_serre_etage_3" style="width: 15%; height: 30%; float: left ; "></div>
       <div id="temp_verranda" style="width: 15%; height: 30%; float: left ; "></div>
       <div id="hum_serre" style="width: 15%; height: 30%; float: left ; "></div>
       
       <div style="width: 1%; height: 4%; float: left ;"></div> 
      <div style="width: 10%; height: 4%; float: left; font-size:26px;  top: 50%; margin-top: 50px; right: -50%; "> Aération</div>
      <div style="width: 8%; height: 4%; float: left ;" class="switch demo">
    <input type="checkbox" disabled="disabled"
    <?php 
    if($etat_ouverture == 1) {
        ?>
        checked
        <?php
    }
    ?>
    ><label><i></i></label>
    </div>

      
      <div style="width: 5%; height: 4%; float: left ;"></div>
      <div style="width: 10%; height: 4%; float: left; font-size:26px;  top: 50%; margin-top: 50px; right: -50%; "> Chauffage</div>
      <div style="width: 8%; height: 4%; float: left ;" class="switch demo">
    <input type="checkbox" disabled="disabled"
    <?php 
    if($etat_chauffage == 1) {
        ?>
        checked
        <?php
    }
    ?>
    ><label><i></i></label>
    </div>
      

<div style="width: 44%; height: 20%; float: left ;" class="CSSTableGenerator" >
                <table >
                    <tr>
                        <td width="8%">
                        </td>
                        <td colspan="2" width="15%">
                           Mini Serre
                        </td>
                        <td colspan="2" width="15%">
                           Serre 1
                        </td>
                        <td colspan="2" width="15%">
                           Serre 2
                        </td>
                        <td colspan="2" width="15%">
                           Serre 3
                        </td>
                        <td colspan="2" width="15%">
                           Humidité
                        </td>
                        <td colspan="2" width="15%">
                           Verranda
                        </td>

                    </tr>
                    <tr style="color:#0000FF">
                        <td>
                        Mini
                        </td>
                        <td colspan="2">
                           <?php echo number_format($temperature_minimale_mini,1);?>°C
                        </td>
                        <td colspan="2">
                           <?php echo number_format($temperature_minimale_serre_1,1);?>°C
                        </td>
                        <td colspan="2">
                           <?php echo number_format($temperature_minimale_serre_2,1);?>°C
                        </td>
                        <td colspan="2">
                           <?php echo number_format($temperature_minimale_serre_3,1);?>°C
                        </td>
                        <td colspan="2">
                           <?php echo $humidite_minimale;?>%
                        </td>
                        <td colspan="2">
                           <?php echo $temperature_verranda_minimale;?>°C
                        </td>

                    </tr>
                    
                    <tr style="color:#FF0000">
                        <td>
                        Maxi
                        </td>
                        <td colspan="2">
                           <?php echo number_format($temperature_maximale_mini,1);?>°C
                        </td>
                        <td colspan="2">
                           <?php echo number_format($temperature_maximale_serre_1,1);?>°C
                        </td>
                        <td colspan="2">
                           <?php echo number_format($temperature_maximale_serre_2,1);?>°C
                        </td>
                        <td colspan="2">
                           <?php echo number_format($temperature_maximale_serre_3,1);?>°C
                        </td>
                        <td colspan="2">
                           <?php echo $humidite_maximale;?>%
                        </td>
                        <td colspan="2">
                           <?php echo $temperature_verranda_maximale;?>°C
                        </td>

                    </tr>
                    
                    <tr >
                        <td>
                        Ecart
                        </td>
                        <td 
                        <?php if ($delta_mini_serre<0) {
                            ?>
                            style="color:#FF0000"
                            <?php
                        }
                        ?>
                        colspan="2">
                           <?php echo number_format($delta_mini_serre,2);?>°C
                        </td>
                        <td <?php if ($delta_serre_1<0) {
                            ?>
                            style="color:#FF0000"
                            <?php
                        }
                        ?>
                        colspan="2">
                           <?php echo number_format($delta_serre_1,2);?>°C
                        </td>
                        <td <?php if ($delta_serre_2<0) {
                            ?>
                            style="color:#FF0000"
                            <?php
                        }
                        ?>
                        colspan="2">
                           <?php echo number_format($delta_serre_2,2);?>°C
                        </td>
                        <td <?php if ($delta_serre_3<0) {
                            ?>
                            style="color:#FF0000"
                            <?php
                        }
                        ?>
                        colspan="2">
                           <?php echo number_format($delta_serre_3,2);?>°C
                        </td>
                        <td <?php if ($delta_humidite<0) {
                            ?>
                            style="color:#FF0000"
                            <?php
                        }
                        ?>
                        colspan="2">
                           <?php echo number_format($delta_humidite,2);?>%
                        </td>
                        <td <?php if ($delta_verranda<0) {
                            ?>
                            style="color:#FF0000"
                            <?php
                        }
                        ?>
                        colspan="2">
                           <?php echo number_format($delta_verranda,2);?>°C
                        </td>

                    </tr>
                    
                </table>
                
            </div>
       

    </body>
</html>

Le résultat est visible sur ce lien.

Quelques images en vrac :

IMG_0558 IMG_0536 IMG_0528 IMG_0560 IMG_0561 IMG_0568 IMG_0565IMG_0566

 

Publié le

Formater les Strings en float et int

Dans le petit tuto précédent,  j’ai manipulé des Strings pour les avoir en Float et en Int.

Voici mon pense-bête :

1. Convertir un String en Float :

Commençons par le plus simple.

Les données que je récupère dans mon tab2[] sont sous format String, mais si pour la pluviométrie je veux quelque chose de propre, il faut que je le passe en Float (j’aurai 2 décimales au lieu de 3, plus pratique).

String preci_hString = tab2[7];
float preci_h = preci_hString.toFloat()

Alors c’est très simple, je définis mon String « preci_hString avec la valeur de ma table, je définis mon float preci_h et je lui donne la valeur preci_hString en ajoutant .toFloat().

2. Convertir un String en Int :

Alors là déjà ça se complique, on est OBLIGE de passer par une variable de type Char :

String pressionStr = tab2[3];
int pressionStrLength = pressionStr.length()+1;
char pressionStrChar[pressionStrLength];
pressionStr.toCharArray(pressionStrChar,pressionStrLength);
int pression = atoi(pressionStrChar);

Donc on récupère la valeur en String, on calcule le nombre de carractères, on définit notre Char à partir avec la longueur du String, et on converti ensuite le String en Char.

Ensuite il reste à convertir le Char en Int avec la fonction atoi().

Publié le

Netatmo et ESP partie 2

Une seconde partie n’était pas prévue, mais Mathieu (ouais c’est un blog de cuisine) c’est lancé dans l’aventure et du coup m’a fait pas mal retravailler mon code !

Du coup, j’ai repris mon code php pour l’importation des données Netatmo et ajouter la pluviométrie (Que je vais devoir aller ajouter dans Station météo maison couplée à une station Netatmo Part. 1 ça sera donc la partie 2).

Donc pour commencer, il faut récupérer les infos sur la pluviométrie. J’avais déjà identifié mon module, donc petit tour sur dev.netatmo.com ;

For Weather Station :

  • max -> Temperature, CO2, Humidity, Pressure, Noise, Rain (if module_id is a rain sensor), WindStrength, WindAngle, GustStrength, GustAngle, date_max_gust (if module_id is a Wind Gauge)
  • 30min, 1hour, 3hours -> Temperature, CO2, Humidity, Pressure, Noise, min_temp, max_temp, min_hum, max_hum, min_pressure, max_pressure, min_noise, max_noise, sum_rain (if module_id is a rain sensor), WindStrength, WindAngle, GustStrength, GustAngle, date_max_gust (if module_id is a Wind Gauge)
  • 1day, 1week, 1month -> Temperature, Co2, Humidity, Pressure, Noise, min_temp, date_min_temp, max_temp, date_max_temp, min_hum, date_min_hum, max_hum, date_max_hum, min_pressure, date_min_pressure, max_pressure, date_max_pressure, min_noise, date_min_noise, max_noise, date_max_noise, date_min_co2, date_max_co2, sum_rain (if module_id is a rain sensor), WindStrength, WindAngle, GustStrength, GustAngle, date_max_gust (if module_id is a Wind Gauge)

Donc, on peut en mettant des timers  récupérer le « sum_rain » !

Allez hop on intègre du code : (je ne rebalance pas tout hein)

$pluvio=$json_devices["body"]["modules"][1]["_id"];

$h_moins_1 = time() - 3600;
$hier = time() - 24* 3600;

$url_pluvio_h = "https://api.netatmo.net/api/getmeasure?access_token=" .  $params['access_token'] . "&device_id=" . $module_interne . "&module_id=" . $pluvio . "&scale=5min&type=sum_rain&date_begin=". $h_moins_1;
$pluvio_h = file_get_contents($url_pluvio_h);   

$url_pluvio_j = "https://api.netatmo.net/api/getmeasure?access_token=" .  $params['access_token'] . "&device_id=" . $module_interne . "&module_id=" . $pluvio . "&scale=30min&type=sum_rain&date_begin=". $hier;
$pluvio_j = file_get_contents($url_pluvio_j);

Donc là, je définit mon module pluvio (le mien est 1, celui de Mathieu est 3 ou 4).

Je définit $h_moins-1 et $hier en timestamp pour ma requête (Je veux le cumul sur la dernière heure et sur les dernières 24h).

Comme pour les autres mesures, il faut attaquer le découpage (et c’est la fête !) la sortie donne un truc du style :

{"body":[{"beg_time":1446581259,"step_time":300,"value":[[0],[0],[0],[0],[0],[0],[0],[0],[0],[0],[0],[0]]}],"status":"ok","time_exec":0.012279987335205,"time_server":1446584710}

Ce qui nous intéresse c’est le cumul de

[[0],[0],[0],[0],[0],[0],[0],[0],[0],[0],[0],[0]]

Allez hop on découpe et on somme les valeurs !

$pluvio_h_decoupe = substr($pluvio_h,57,1000);
$recup1_pluvio_h = explode("}", $pluvio_h_decoupe);
$recup2_pluvio_h = explode("[",$recup1_pluvio_h[0]);
$sum_pluvio_h = 0;
for ($i=0; $i<count($recup2_pluvio_h); $i++) {
$mesure = explode("]",$recup2_pluvio_h["$i"]);
$sum_pluvio_h += $mesure[0];
}

Et on fait pareil pour la pluvio des dernières 24h.

On ajoute ensuite les sommes dans la chaîne à afficher pour obtenir en sortie notre fichier out.txt qui ressemble à ça :

[21.1n635n74n1017.4n45n14.8n91n0n0[

Comme je suis joueur, avant de donner mon code Arduino, je vais vous montrer le résultat qu’on souhaitait :

Donc en gros, toutes les 10 secondes on alterne l’affichage intérieur/extérieur dans un boucle de 3 rotations avant mise à jour des données.

J’ai du formater un peu l’affichage pour la pression et la pluviométrie :

#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <ESP8266WiFi.h>

LiquidCrystal_I2C lcd(0x3F, 20, 4);

const char* ssid     = "Votre SSID";
const char* password = "MDP Wifi";

const char* host = "192.168.1.50";

void setup() {
  Serial.begin(115200);
  delay(10);
  Wire.begin(0,2);
  lcd.begin();
  lcd.backlight();
  // We start by connecting to a WiFi network

  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

int value = 0;

void loop() {
 
  ++value;

  Serial.print("connecting to ");
  Serial.println(host);
  
  // Use WiFiClient class to create TCP connections
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }
  
  // We now create a URI for the request
  String url = "/Netatmo/out.txt";
  
  
  Serial.print("Requesting URL: ");
  Serial.println(url);
  
  // This will send the request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" + 
               "Connection: close\r\n\r\n");
  delay(10);
  String line = "";
  // Read all the lines of the reply from server and print them to Serial
  while(client.available()){
    line = client.readStringUntil('\r');
   }

char messageChar[500]; 
  line.toCharArray(messageChar,500);
  
  char dlm[] = "[";
            int cnt = 0;
            char* tab[255] = { 0 };
            char *pch = strtok(messageChar, dlm);
            while ( pch != NULL ) {
              if (cnt < 60) {
              tab[cnt++] = pch;
              } else {
              break;
              }
            pch = strtok (NULL, dlm);
            }
 
  
  char *chaine = tab[1];

  char dlm2[] = "n";
            int cnt2 = 0;
            char* tab2[255] = { 0 };
            char *pch2 = strtok(chaine, dlm2);
            while ( pch2 != NULL ) {
              if (cnt2 < 60) {
              tab2[cnt2++] = pch2;
              } else {
              break;
              }
            pch2 = strtok (NULL, dlm2);
            }
String pressionStr = tab2[3];
int pressionStrLength = pressionStr.length()+1;
char pressionStrChar[pressionStrLength];
pressionStr.toCharArray(pressionStrChar,pressionStrLength);
int pression = atoi(pressionStrChar);

String preci_hString = tab2[7];
float preci_h = preci_hString.toFloat(); 

String preci_jString = tab2[8];
float preci_j = preci_jString.toFloat(); 

if (tab2[1] > 0) {
for (int i = 0; i<3; i++)
{
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Interieur");
  lcd.setCursor(0,1);
  lcd.print("T: ");
  lcd.print(tab2[0]);
  lcd.print(char(223));
  lcd.print("C");
  lcd.setCursor(0,2);
  lcd.print("CO2: ");
  lcd.print(tab2[1]);
  lcd.print("ppm");
  lcd.setCursor(0,3);
  lcd.print("Hum: ");
  lcd.print(tab2[2]);
  lcd.print("% P: ");
  lcd.print(pression);
  lcd.print(" hPa");
  delay(10000);
  
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Exterieur");
  lcd.setCursor(0,1);
  lcd.print("T: ");
  lcd.print(tab2[5]);
  lcd.print(char(223));
  lcd.print("C  Hum: ");
  lcd.print(tab2[6]);
  lcd.print("%");
  lcd.setCursor(0,2);
  lcd.print("Pluie : ");
  lcd.print(preci_h);
  lcd.print(" mm/h");
  lcd.setCursor(8,3);
  lcd.print(preci_j);
  lcd.print(" mm/j");
  delay(10000);
}
}

  Serial.println();
  Serial.println("closing connection");
}

 

 

 

Publié le

Gâteau Basque à la cerise / Faisan au pommes- Test1

J’ai un oncle qui habite au Pays Basque et quand on y allait gamin, ma tante faisait toujours un gâteau basque à la cerise.

Du coup ce matin je me suis lancé pour en faire un.

1. Ingrédients :

  • 300g de farine,
  • 3 pincées de sel,
  • 120g de beurre,
  • 200g de sucre en poudre,
  • 2 œufs + 1 jaune,
  • 1 sachet de levure chimique,
  • 1 gousse de vanille / vanille en poudre,
  • 1 faisan
  • 1 1/2 pommes,
  • sel, poivre huile.

2. La préparation :

Allez je commence à attraper mes ingrédients !

Et là premier drame : je n’ai pas d’œufs ! Bon pas de soucis, je vais en chercher chez la voisine, il lui en reste que deux, donc exit le jaune d’œuf pour dorer le gâteau ! On papotte on papotte, et je reviens chez moi.

Second drame : je n’ai plus de farine et je n’ai pas de levure ! Allez hop direction l’épicerie du village, 2€50 pour les deux (en prenant de la farine premier prix hein).

Allez go ! On sort le robot, la feuille (l’accessoire feuille hein) :

  • On mélange dans un premier temps le beurre un peu ramolli avec le sucre,
  • On y ajoute la farine, la levure, les œufs, le sel, la vanille et on mélange pour avoir une pâte bien lisse.
  • On fait une boule, dans du film plastique et au frigo pour la faire reposer environ 1h.

IMG_0118

  • Pendant ce temps, éplucher les pommes, les couper en morceau et farcir le faisan,
  • Ficeler le faisan pour ne pas que les pommes sortent pendant la cuisson. Assaisonner.
  • Mettre au four le faisan à 200°C pendant 1 heure (en le retournant à mi-cuisson).

IMG_0119IMG_0120

  • Une heure après, on sépare la boule en deux en en faisant une plus petite que l’autre.
  • On étale la grosse boule, on dispose la confiture de cerises,
  • On étale la seconde, on recouvre la confiture avec pour obtenir :

IMG_0123

  • On fait cuire 40 minutes à 160°C
  • Et on obtient ce truc tout moche (mais très bon) car il s’est dilaté à la cuisson (avec un cerclage ça doit être mieux, je testerai) :

IMG_0124IMG_0126

 

Oubli : le faisan en sortie de cuisson