[Article] Domotiser son poulailler avec ESPHome

Salut @vdelab
Je rebondis sur ce que tu disais :

je vais essayer de suivre pas à pas, étant justement en instance de réception de poules, avec le poulailler qui sera au fond du jardin, tout juste en limite de portée de wifi…

Pour ça j’ai deux solutions à te proposer.

  1. Investir dans des boitiers CPL avec WiFi : C’est ce qui me permet justement d’avoir du WiFi dans le jardin
  2. Acheter cette carte ESP avec son antenne. Le tutoriel sera à adapter concernant les pins de branchement mais tout le reste sera identique. J’ai testé cette carte sur un autre projet Jardin justement et ça fonctionne super bien. Je suis passé d’une qualité de réception WiFi de 18% à une d’environ 50%.

Non elle n’apparait pas. Je n’ai que 2 entités qui remontent :

  • màj firmware
  • statut (avec l’adresse IP en attribut)

j’ai effectivement tout copié / collé le code et j’ai remplacé l’ api key et le ota password dans le fichier secret.yaml avec ceux donné lors de la première compilation de ma cam.
J’ai en somme gardé la déclaration dans le fichier !secret que j’ai mis à jour.
Idem pour la partie wifi (ssid et password sont ceux de mon réseau), j’ai par contre gardé l’ ap (ssid et password) de l’exemple du code.

Peut-être que mon erreur vient de ma première installation de la cam. J’ai suivi le tuto mais à aucun moment j’ai dû préciser que c’était une camera. Est ce ce qu’il y a qque chose en particulier à faire ?

Il faut que je la re-installe. Je viens de voir que je n’ai pas fais « SKIP » à l’install. Donc je pense avoir installé un soft de base ESP32 (sans cam) :
Tuto :
Ensuite rendez-vous dans l’onglet Esphome et on clic sur le bouton vert New Device

  1. Nomme la caméra
  2. à l’étape de l’installation clic sur SKIP THIS STEP
  3. choisis la carte, pick specific board > Ai Thinker ESP32-CAM

Source : Esp32-cam Ai Thinker et homeassistant - Haade.fr

1 « J'aime »

Ça faisait un moment que je l’avais fait, j’ai sûrement oublié la procédure effectivement. Merci à toi du rappel je vais mettre à jour l’article avec cette subtilité, histoire que personne d’autre ne galère à installer la caméra :slight_smile:

2 « J'aime »

J’ai refait l’installation de ma camera avec le code suivant et j’ai bien les sensors et l’image qui remonte :grinning:

esphome:
  name: poulcam2
  friendly_name: Poulcam

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "xxxxxxxxxxxxxxxxxxxxxxxxxx"

ota:
  password: "yyyyyyyyyyyyyyyy"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Poulcam Fallback Hotspot"
    password: "p2YkBfT1Yl4v"

captive_portal:

esp32_camera:
  name: Poulcam
  external_clock:
    pin: GPIO0
    frequency: 20MHz
  i2c_pins:
    sda: GPIO26
    scl: GPIO27
  data_pins: [GPIO5, GPIO18, GPIO19, GPIO21, GPIO36, GPIO39, GPIO34, GPIO35]
  vsync_pin: GPIO25
  href_pin: GPIO23
  pixel_clock_pin: GPIO22
  power_down_pin: GPIO32
  
# Image/Video settings, https://esphome.io/components/esp32_camera.html

  max_framerate: 25 fps    # default: 10 fps, max 60
  idle_framerate: 0.2 fps # default: 0.1 fps - framerate for 'picture' in HA dashboard
  resolution: 1024x768
  jpeg_quality: 10
  vertical_flip: False
  contrast: 0 # default: 0, variable -2 to 2
  brightness: 1 # default: 0, variable -2 to 2
  saturation: 0 # default: 0, variable -2 to 2
  
# Server video/pictures, https://esphome.io/components/esp32_camera_web_server.html

esp32_camera_web_server:
  - port: 8080
    mode: stream
  - port: 8081
    mode: snapshot

time:
  - platform: homeassistant
    id: homeassistant_time

output:
#flashlight
  - platform: gpio
    pin: GPIO4
    id: gpio_4
#statuslight led 33 for wifi connect
  - platform: gpio
    pin:
      number: GPIO33
      inverted: True
    id: gpio_33

light:
#flashlight
  - platform: binary
    output: gpio_4
    name: Light

sensor:
  - platform: wifi_signal
    name: Wifi signal
    id: wifi_signal_db
    update_interval: 60s

#Reports the WiFi signal strength in %
  - platform: copy 
    source_id: wifi_signal_db
    name: "Wifi signal percent"
    filters:
      - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
    unit_of_measurement: "%"
    entity_category: "diagnostic"
    device_class: ""

  - platform: uptime
    name: Uptime

#Capteur DHT temperature & humidité
  - platform: dht
    model: dht22
    pin: GPIO15
    temperature:
      name: Température
    humidity:
      name: Humidité
    update_interval: 60s


text_sensor:
  - platform: version
    name: ESPHome Version
  - platform: wifi_info
    ssid:
      name: Wifi

switch:      
  - platform: restart
    name: Restart

binary_sensor:
  - platform: template
    name: "Camera is streaming"
    id: cam_streaming

Il me reste un problème à résoudre, ma camera est connecté en usb au PC et fonctionne mais lorsque je l’alimente seulement (via un chargeur usb par ex.) elle est « OFFLINE », mais ce problème n’est pas en lien avec l’objet de cet article donc je vais mener mes recherches pour sa résolution.

Maintenant quand je modifie mon code initial pour implémenter ce qui nous concerne pour activer/désactiver l’IR flash j’ai une erreur de compilation du code (via la fonction « Validate » dans ESPHome), ce qui m’empêche de charger le yaml.
Failed config
ID relay_ir_light redefined! Check light->0->id.

Code :

esphome:
  name: poulcam2
  friendly_name: Poulcam

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "xxxxxxxxxxxxxxxxxxxxxxxxxx"

ota:
  password: "yyyyyyyyyyyyyyyy"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Poulcam Fallback Hotspot"
    password: "p2YkBfT1Yl4v"

captive_portal:

esp32_camera:
  name: Poulcam
  external_clock:
    pin: GPIO0
    frequency: 20MHz
  i2c_pins:
    sda: GPIO26
    scl: GPIO27
  data_pins: [GPIO5, GPIO18, GPIO19, GPIO21, GPIO36, GPIO39, GPIO34, GPIO35]
  vsync_pin: GPIO25
  href_pin: GPIO23
  pixel_clock_pin: GPIO22
  power_down_pin: GPIO32
  
# Image/Video settings, https://esphome.io/components/esp32_camera.html

  max_framerate: 25 fps    # default: 10 fps, max 60
  idle_framerate: 0.2 fps # default: 0.1 fps - framerate for 'picture' in HA dashboard
  resolution: 1024x768
  jpeg_quality: 10
  vertical_flip: False
  contrast: 0 # default: 0, variable -2 to 2
  brightness: 1 # default: 0, variable -2 to 2
  saturation: 0 # default: 0, variable -2 to 2
  
# Server video/pictures, https://esphome.io/components/esp32_camera_web_server.html

esp32_camera_web_server:
  - port: 8080
    mode: stream
  - port: 8081
    mode: snapshot

time:
  - platform: homeassistant
    id: homeassistant_time

output:
#flashlight
  - platform: gpio
    pin: GPIO4
    id: gpio_4

light:
#Test IR light    
  - platform: binary
    id: relay_ir_light
    output: gpio_4
    name: ${friendly_name} flash


sensor:
  - platform: wifi_signal
    name: Wifi signal
    id: wifi_signal_db
    update_interval: 60s

#Reports the WiFi signal strength in %
  - platform: copy 
    source_id: wifi_signal_db
    name: "Wifi signal percent"
    filters:
      - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
    unit_of_measurement: "%"
    entity_category: "diagnostic"
    device_class: ""

  - platform: uptime
    name: Uptime

#Capteur DHT temperature & humidité
  - platform: dht
    model: dht22
    pin: GPIO15
    temperature:
      name: Température
    humidity:
      name: Humidité
    update_interval: 60s


text_sensor:
  - platform: version
    name: ESPHome Version
  - platform: wifi_info
    ssid:
      name: Wifi

switch:      
  - platform: restart
    name: Restart

 # Test IR light   
  - platform: gpio
    name: "IR Light Switch"
    id: relay_ir_light
    pin:
      number: GPIO2
      inverted: False

binary_sensor:
  - platform: template
    name: "Camera is streaming"
    id: cam_streaming

Logs de l’erreur :

INFO ESPHome 2024.4.1
INFO Reading configuration /config/esphome/poulcam2.yaml...
WARNING GPIO0 is a strapping PIN and should only be used for I/O with care.
Attaching external pullup/down resistors to strapping pins can cause unexpected failures.
See https://esphome.io/guides/faq.html#why-am-i-getting-a-warning-about-strapping-pins
WARNING GPIO5 is a strapping PIN and should only be used for I/O with care.
Attaching external pullup/down resistors to strapping pins can cause unexpected failures.
See https://esphome.io/guides/faq.html#why-am-i-getting-a-warning-about-strapping-pins
INFO Detected timezone 'Europe/Paris'
WARNING GPIO15 is a strapping PIN and should only be used for I/O with care.
Attaching external pullup/down resistors to strapping pins can cause unexpected failures.
See https://esphome.io/guides/faq.html#why-am-i-getting-a-warning-about-strapping-pins
WARNING GPIO2 is a strapping PIN and should only be used for I/O with care.
Attaching external pullup/down resistors to strapping pins can cause unexpected failures.
See https://esphome.io/guides/faq.html#why-am-i-getting-a-warning-about-strapping-pins
Failed config

switch.gpio: [source /config/esphome/poulcam2.yaml:125]
  platform: gpio
  name: IR Light Switch
  
  ID relay_ir_light redefined! Check light->0->id.
  id: relay_ir_light
  pin: 
    number: 2
    inverted: False
    mode: 
      output: True
      input: False
      open_drain: False
      pullup: False
      pulldown: False
    ignore_strapping_warning: False
    drive_strength: 20.0
  disabled_by_default: False
  restore_mode: ALWAYS_OFF
  interlock_wait_time: 0ms

Avez vous une idée de l’origine du problème ?

Salut,

Je viens de comparer avec ma version et j’ai commenté les lignes 84 à 93

output:
#flashlight
  - platform: gpio
    pin: GPIO4
    id: gpio_4

light:
#Test IR light    
  - platform: binary
    id: relay_ir_light
    output: gpio_4
    name: ${friendly_name} flash

Je pense que ça peut venir de là. Essaie de supprimer ces lignes.

1 « J'aime »

Le code ne génère plus d’erreur ainsi. Merci !!
Code à mettre à jour donc dans l’article :wink:

2 « J'aime »

Bonjour à tous,

mon poulailler avance bien.
La version low tech est entrée en service il y a 10 jours, et les pensionnaires apprécient bien.
La phase bricolage est quasi terminée. Le weekend dernier, j’ai raccordé l’eau et l’électricité au poulailler. On est donc prêt pour la seconde phase, la domotisation ! :smile:



Pour cela, d’une part j’ai commandé le matériel indiqué (ou équivalent) dans cet article, mais il me manque encore des pièces (en particulier les moteurs :weary: ).
A noter qu’il y a deux portes à controler: celle de l’habitat, et celle de l’enclos qui donne sur une partie du jardin, et que comme le tutos, il y aura aussi la caméra, des capteurs de temp, etc.

J’ai aussi récupéré le matos d’un collègue qui avait fait une porte automatique à base d’arduino Uno. Par contre, c’est du pur autonome, pas de controle à distance et juste avec la luminosité et deux microswitch pour la position de la porte.
Dans un premier temps, je vais poser tel quel son montage sur ma porte.

Mais comme ensuite je compte avoir dans le poulailler aussi le montage à base d’ESP-home de ce tuto et un HA « local » sur un vieux raspberry (et son propre réseau Zigbee - je re-utilise des senseurs etc que j’ai en rab), je me demande s’il y a un moyen de récuperer sur le Raspberry+HA local les infos de l’Arduino existant qui controlerai déjà une des portes.
D’où ma question, y a t-il un moyen « simple » de connecter l’Arduino existant au Pi+HA (via USB?) et que HA ai accès aux états des paramètres de l’arduino et puisse envoyer des commandes?

Voici le montage et le code Arduino existant… ça vous inspire des idées? Je suis débutant en ESP et Arduino…

const int MotorPinA = 12; // for motor A
const int MotorSpeedPinA = 3; // for motor A
const int MotorBrakePinA = 9; // for motor A
const int MotorSpeed = 255; //Motor Speed (0 to 255)
const int SwitchPin = 2;    // V3: Digital for Cmde Switch
const int EndClosedPin = 4; // V3: Digital for End Stop microswitch Closed
const int EndOpenPin = 5; // Digital for End Stop microswitch Open
const int PhotoResistorPin = 2; // for PhotoResistor (Analog)
const int delayswitch = 20; //in ms for antirebounds
const int DureeUp = 25000; //Durée pour ouvrir la porte
const int DureeDn = 20000; //Durée pour ouvrir la porte
long instant = 0; //Pour compter combien de temps on active le moteur
long InstantLight = 0; //Pour compter depuis combien de temps on capte que la limière a franchi un seuil de luminosité
float Light = 0; //Tension de luminosité (0V= forte lumière, 5V=obscurité complète, 3.8V = seuil de lever ou coucher du soleil
const float LightThr = 4.4; //seuil en Volt de lever/coucher du soleil) // modifié en V4, Ancien seuil = 4.1
const long DelayLight = 600000; //Tps de conf lever/coucher du soleil 600000ms=10min
bool SwitchCmd = 0;
bool CoucherStart = 0;
bool LeverStart = 0;
bool CoucherStop = 0;
bool LeverStop = 0;
bool Cmde = 0;
bool PrevCmde = 0;
bool SwitchReleased = 1;
bool Run = 0;
bool EndStopClosed = 0;   // V3: Status ==> 1 = Closed ; 0 = Not Closed
bool EndStopOpen = 0;     // V3: Status ==> 1 = Open ; 0 = Not Open
bool EndStopFault = 0;  // V3: Fault si les 2 microswitchs sont à 1 en même temps
const int CW  = HIGH;
const int CCW = LOW;

void setup() {
  // motor A pin assignment
  pinMode (SwitchPin, INPUT);
  pinMode (EndClosedPin, INPUT);  //V3
  pinMode (EndOpenPin, INPUT);    //V3
  pinMode(MotorPinA, OUTPUT);
  pinMode(MotorSpeedPinA, OUTPUT);
  Serial.begin(9600);//  serial monitor initialized 

}

void loop() {

//--------------LUMINOSITE------------------------
//Lecture de la luminosité
Light = analogRead(PhotoResistorPin);
Light = Light * 5 / 1023;
//Serial.println(Light);

if(Light > LightThr && CoucherStart == 0){ //Détection d'obscurité
  InstantLight = millis(); //on mémorise l'instant où on a franchi le seuil
  CoucherStart = 1;
  LeverStart = 0;
  LeverStop = 0;
  CoucherStop == 0; // ajouté en V4
}
if(CoucherStart == 1 && CoucherStop == 0 && (millis() - InstantLight > DelayLight)){
  Cmde = 0;
  CoucherStop = 1;
}
if(Light < (LightThr - 0.1) && LeverStart == 0){ //Détection d'aube
  InstantLight = millis(); //on mémorise l'instant où on a franchi le seuil
  LeverStart = 1;
  CoucherStart = 0;
  CoucherStop =0;
  LeverStop = 0; //ajouté en V4
}
if(LeverStart == 1 && LeverStop == 0 && (millis() - InstantLight > DelayLight)){
  Cmde = 1;
  LeverStop = 1;
}
//--------------FIN DE LUMINOSITE------------------------

//-V3-----------SWITCH DE FIN DE COURSE-----------------------
EndStopClosed = digitalRead(EndClosedPin);  // read input EndStopClosed
EndStopOpen = digitalRead(EndOpenPin);  // read input EndStopOpen

if(EndStopClosed == 1 && EndStopOpen == 1){
  EndStopFault = 1;
} else
  {
    EndStopFault = 0;
  }



//-V3-----------FIN DE SWITCH DE FIN DE COURSE------------------------


//--------------SWITCH DE COMMANDE------------------------
//Lecture des switch de commande
SwitchCmd = digitalRead(SwitchPin);  // read input SwitchCmde

  if(SwitchCmd == 0) 
  {
    SwitchReleased = 1;
  }

  if (Run == 1 && SwitchReleased == 1 && SwitchCmd == 1) 
  {
    Run = 0;
    SwitchReleased = 0;
    Serial.println("Switch OFF"); 
    //Cmde = !Cmde;
  } else
    {  
      if (SwitchCmd == 1 && Cmde == 0 && SwitchReleased == 1) 
      {         // check if the input is HIGH (button released)
        delay(delayswitch);                       // 200ms anti rebond
        if (SwitchCmd == 1 && Cmde == 0) 
        {
          SwitchReleased = 0;
          Cmde = 1;
          Serial.println("Commande UP"); 
          delay(delayswitch);
        }
      }
      else 
      {
        if (SwitchCmd == 1 && Cmde == 1 && SwitchReleased == 1)
        {
          delay(delayswitch);                       // 200ms anti rebond
          if (SwitchCmd == 1 && Cmde == 1)
          {
            SwitchReleased = 0;
            Cmde = 0;
            Serial.println("Commande DN"); 
            delay(delayswitch);
          }
        }
      }
    }
//--------------FIN DE SWITCH DE COMMANDE------------------------


//--------------COMMANDE MOTEUR----------------------------------

  if (Cmde != PrevCmde) 
  {
    Run = 1;
    PrevCmde = Cmde;
    instant = millis();  
    Serial.println("Changement de Sens"); 
  }

 //COMMANDE OUVERTURE
  if (Cmde == 1){   
    if (Run == 1 && ((millis()-instant)<DureeUp) && EndStopFault == 0 && EndStopOpen == 0)     //Commande UP pendant DureeUp sauf si intérompu par un appui - V3 ajout microswitch
    {
      Serial.println("Direction CW"); 
      digitalWrite(MotorPinA, CW);// set direction
      analogWrite(MotorSpeedPinA, MotorSpeed);// set speed at maximum
    } else 
      { 
          analogWrite(MotorSpeedPinA, 0);// set speed at zero
          Run = 0;
      }      
  }
 //COMMANDE FERMETURE
  if (Cmde == 0){   
    if (Run == 1 && ((millis()-instant)<DureeDn) && EndStopFault == 0 && EndStopClosed == 0)     //Commande Dn pendant DureeDn sauf si intérompu par un appui - V3 ajout microswitch
    {
      Serial.println("Direction CCW"); 
      digitalWrite(MotorPinA, CCW);// set direction
      analogWrite(MotorSpeedPinA, MotorSpeed);// set speed at maximum
    } else 
      { 
          analogWrite(MotorSpeedPinA, 0);// set speed at zero
          Run = 0;
          Serial.println("Fin de DN");
      }   
}
/*  if (Run == 1 && ((millis()-instant)<DureeUp) && EndStopFault == 0)     //Commande UP pendant DureeUp sauf si intérompu par un appui - V3 ajout microswitch
  {
    if (Cmde == 1)
    {
      Serial.println("Direction CW"); 
      digitalWrite(MotorPinA, CW);// set direction
      analogWrite(MotorSpeedPinA, MotorSpeed);// set speed at maximum
    } else
      {
        digitalWrite(MotorPinA, CCW);// set direction
        Serial.println("Direction CCW"); 
        analogWrite(MotorSpeedPinA, MotorSpeed);// set speed at maximum
      }
    
  } else 
    { 
        analogWrite(MotorSpeedPinA, 0);// set speed at zero
        Run = 0;
    }      */

//--------------FIN DE COMMANDE MOTEUR----------------------------------
}// loop end


Merci de vos idées...
2 « J'aime »