[TUTO] AI TAsk et comment utiliser l'image de la caméra : Sujet le Poulailler!

Bonjour à tous,

Je me suis amusé avec AI Task et la caméra de mon poulailler.
Je voulais savoir où on pouvais aller avec l’IA et l’analyse d’image.

Ce que j’ai mis en place fonctionne, aussi je vous partage ce que j’ai fait, cela vous donnera surement des idées chez vous ! :wink:

EDIT :

prérequis :

  • Créé un agent de conversation dans Home Assistant, exemple Gemini :

Mes objectifs :

  • compter les oeufs et donner le nombre
  • Voir si la trappe est ouverte
  • être notifié (encore à faire)

Le résultat final :

C’est parti !

Tout d’abord il faut créer 2 input text dans les entrées :

Les nommer comme vous voulez, on les utilisera pour alimenter ces input text avec le retour de l’analyse de l’IA.

Ensuite on crée 2 automatisations :

Une automatisation pour l’analyse des oeufs :

  • Le déclenchement de 09h à 16h, toutes les heures
  • instructions: >
    Ne réponds pas par non, Dis moi si il y a des oeufs dans le poulailler et combien ? Ils sont généralement dans la cagette.
    donc :
    si il y a un oeuf : réponse : Il y a 1 oeuf
    si il y a deux oeufs : réponse : Il y a 2 oeufs
    si il y a trois oeufs : réponse Il y a 3 oeufs
    et pareil si le nombre augmente.
  • on crée la variable : ai_oeufs_response
  • action, on alimente notre inpu_text avec la variable créé auparavant.

L’automatisation complète :

alias: POULAILLER - Détection et notification d'œufs
description: >
  Prend une photo du poulailler, l'analyse avec l'intelligence artificielle pour
  détecter les œufs et envoie une notification avec le résultat.
triggers:
  - trigger: time
    at: "09:00:00"
  - trigger: time
    at: "10:00:00"
  - trigger: time
    at: "11:00:00"
  - trigger: time
    at: "12:00:00"
  - trigger: time
    at: "13:00:00"
  - trigger: time
    at: "14:00:00"
  - trigger: time
    at: "15:00:00"
  - trigger: time
    at: "16:00:00"
conditions: []
actions:
  - action: ai_task.generate_data
    metadata: {}
    data:
      task_name: Oeufs dans le poulailler ?
      instructions: >
        Ne réponds pas par non, Dis moi si il y a des oeufs dans le poulailler
        et combien ? Ils sont généralement dans la cagette.

        donc : 

        si il y a un oeuf : réponse : Il y a 1 oeuf

        si il y a deux oeufs : réponse : Il y a 2 oeufs

        si il y a trois oeufs : réponse Il y a 3 oeufs

        et pareil si le nombre augmente.
      attachments:
        media_content_id: media-source://camera/camera.camera_poulailler_fluent
        media_content_type: application/vnd.apple.mpegurl
        metadata:
          title: Camera Poulailler Fluide
          thumbnail: /api/camera_proxy/camera.camera_poulailler_fluent
          media_class: video
          children_media_class: null
          navigateIds:
            - {}
            - media_content_type: app
              media_content_id: media-source://camera
    response_variable: ai_oeufs_response
  - action: input_text.set_value
    data:
      value: "{{ ai_oeufs_response.data }}"
    target:
      entity_id: input_text.ai_des_oeufs_dans_le_poulailler
mode: single

Une automatisation pour l’analyse de la trappe :

  • Le déclenchement à 6, 7 et 8 heures et le soir.
  • instructions: >
    Je voudrai que tu me dises si la trappe du poulailler est ouverte ou fermée.
    La trappe se situe en bas à gauche de l’image.
    Si elle est ouverte, dis : La trappe est ouverte
    Si elle est fermée, dis: La trappe est fermée
  • on crée la variable : trappe_response
  • action, on alimente notre inpu_text avec la variable créé auparavant.

L’automatisation complète :

alias: POULAILLER - détection de trappe ouverte ou fermée
description: >
  Prend une photo du poulailler, l'analyse avec l'intelligence artificielle pour
  détecter si la trappe est ouverte et envoie une notification avec le résultat.
triggers:
  - trigger: time
    at: "07:00:00"
    weekday:
      - sat
      - sun
      - fri
      - thu
      - wed
      - tue
      - mon
  - trigger: time
    at: "08:00:00"
    weekday:
      - sat
      - fri
      - thu
      - wed
      - tue
      - mon
      - sun
  - trigger: time
    at: "06:00:00"
    weekday:
      - mon
      - tue
      - wed
      - thu
      - fri
      - sat
      - sun
  - trigger: time
    at: "21:30:00"
    weekday:
      - mon
      - tue
      - wed
      - fri
      - sat
      - thu
      - sun
  - trigger: time
    at: "22:30:00"
    weekday:
      - mon
      - tue
      - wed
      - thu
      - fri
      - sat
      - sun
  - trigger: time
    at: "23:00:00"
    weekday:
      - mon
      - tue
      - wed
      - thu
      - fri
      - sat
      - sun
  - trigger: time
    at: "22:00:00"
    weekday:
      - mon
      - tue
      - wed
      - fri
      - sat
      - thu
      - sun
conditions: []
actions:
  - action: ai_task.generate_data
    metadata: {}
    data:
      instructions: >-
        Je voudrai que tu me dises si la trappe du poulailler est ouverte ou
        fermée.

        La trappe se situe en bas à gauche de l'image.

        Si elle est ouverte, dis : La trappe est ouverte

        Si elle est fermée, dis: La trappe est fermée
      attachments:
        media_content_id: media-source://camera/camera.camera_poulailler_fluent
        media_content_type: application/vnd.apple.mpegurl
        metadata:
          title: Camera Poulailler Fluide
          thumbnail: /api/camera_proxy/camera.camera_poulailler_fluent
          media_class: video
          children_media_class: null
          navigateIds:
            - {}
            - media_content_type: app
              media_content_id: media-source://camera
      task_name: Trappe dans le poulailler ?
    response_variable: trappe_response
  - action: input_text.set_value
    data:
      value: "{{ trappe_response.data}}"
    target:
      entity_id:
        - input_text.ai_la_trappe_du_poulailler_ouverte
mode: single

Création de la carte :

Le code de la carte :

type: custom:vertical-stack-in-card
cards:
  - type: custom:stack-in-card
    mode: horizontal
    cards:
      - type: markdown
        content: >
          **Analyse des oeufs :**

          {{ states('input_text.ai_des_oeufs_dans_le_poulailler') }}


          **Dernière mise à jour :**

          {{ states.input_text.ai_des_oeufs_dans_le_poulailler.last_updated |
          as_timestamp | timestamp_custom("%d-%m-%Y à %H:%M") }}
      - type: custom:button-card
        entity: input_text.ai_des_oeufs_dans_le_poulailler
        show_name: false
        show_state: false
        show_icon: false
        layout: vertical
        styles:
          card:
            - padding: 0
            - background: none
            - box-shadow: none
            - border-radius: 0
          grid:
            - grid-template-areas: "\"image\""
            - grid-template-columns: 1fr
            - grid-template-rows: 1fr
          custom_fields:
            image:
              - display: flex
              - justify-content: center
              - align-items: center
              - width: 100%
              - height: 100%
        custom_fields:
          image: |
            [[[
              const s = (entity && entity.state) ? String(entity.state).toLowerCase().trim() : "";
              if (/\b(un|deux|trois|1|2|3)\b/.test(s)) {
                return `
                  <style>
                    @keyframes pulse {
                      0% { transform: scale(1); }
                      50% { transform: scale(1.08); }
                      100% { transform: scale(1); }
                    }
                  </style>
                  <img src="/local/images/buttons/oeuf2.png"
                       style="width: 50%; height: auto; object-fit: contain; animation: pulse 2s infinite;"/>
                `;
              }
              return `<img src="/local/images/buttons/oeuf_ko2.png"
                           style="width: 50%; height: auto; object-fit: contain;"/>`;
            ]]]
  - type: custom:stack-in-card
    mode: horizontal
    cards:
      - type: markdown
        content: >
          **Analyse de la trappe :**

          {{ states('input_text.ai_la_trappe_du_poulailler_ouverte') }}


          **Dernière mise à jour :**

          {{ states.input_text.ai_la_trappe_du_poulailler_ouverte.last_updated |
          as_timestamp | timestamp_custom("%d-%m-%Y à %H:%M") }}
      - type: custom:button-card
        entity: input_text.ai_la_trappe_du_poulailler_ouverte
        show_name: false
        show_state: false
        show_icon: false
        layout: vertical
        styles:
          card:
            - padding: 0
            - background: none
            - box-shadow: none
            - border-radius: 0
          grid:
            - grid-template-areas: "\"image\""
            - grid-template-columns: 1fr
            - grid-template-rows: 1fr
          custom_fields:
            image:
              - display: flex
              - justify-content: center
              - align-items: center
              - width: 100%
              - height: 100%
        custom_fields:
          image: |
            [[[
              const s = (entity && entity.state) ? String(entity.state).toLowerCase().trim() : "";
              if (/\b(ouverte)\b/.test(s)) {
                return `

                  <img src="/local/images/buttons/trappe_on.png"
                       style="width: 50%; height: auto; object-fit: contain; animation: pulse 2s infinite;"/>
                `;
              }
              return `<img src="/local/images/buttons/trappe_off.png"
                           style="width: 50%; height: auto; object-fit: contain;"/>`;
            ]]]

Les images des oeufs et de la trappe :

Prochaines étapes :

  • être notifié si la trappe n’est pas ouverte le matin
  • être notifié si la trappe est restée ouverte le soir
  • être notifié une fois dans la journée si il y a des oeufs

J’ai trouvé la manipulation cool et ludique :wink:
A bientôt !

1 « J'aime »

Bonjour @olivier_verstraet
Sympa, merci pour le partage.
Je n’ai pas dans mes automatisations de ai_task.xxx, il semblerait qu’il faille ajouter une intégration mais je ne la vois pas, j’ai la dernière version de HA.
Il faut sans doute d’abord ajouter une intégration comme OpenAI ?

Bob

1 « J'aime »

Hello, bonne idée !

J’ai aussi une caméra dans mon poulailler, avec un script qui m’envoie une photo 2 x par jour de ce type :

ça pourrait etre un bon exercice !

Merci pour le partage…

1 « J'aime »

Merci :wink:

Oui normalement tu dois voir “AI Task” dans les actions. :

Si tu ne l’as pas regarde :

  • si tu as la dernière version de Home Assistant.
  • Créé un agent de conversation dans Home Assistant (Je vais l’ajouter en tant que pré-requis)

Pour créer cet agent tu dois utiliser cette page d’explication :

Personnellement j’ai utilisé Gemini de Google.

Bonjour,
je viens de tester suite à l’ajout d’une caméra OV3660 sur un ESP32-S3 CAM, c’est assez incroyable.

Mon script:

sequence:
  - action: ai_task.generate_data
    data:
      entity_id: ai_task.openai_ai_task
      task_name: Analyse plantes
      instructions: >-
        Regarde cette image de mon séjour.  Dis-moi combien il y a de pots de
        fleurs et décris brièvement où ils se trouvent  ou un détail marquant
        (ex: sous la fenêtre, sur la table).  Fais une phrase courte, naturelle
        et chaleureuse. Dis moi si tu trouve un autre élément important à cet
        endroit.
      structure:
        message_libre:
          selector:
            text: null
      attachments:
        - media_content_id: media-source://camera/camera.espcam32h_sejour_esp32_camera
          media_content_type: image/jpeg
    response_variable: result
  - action: input_text.set_value
    metadata: {}
    data:
      value: monImageIA_{{now().strftime("%Y%m%d-%H%M%S")}}.jpg
    target:
      entity_id: input_text.namephotoanalyseia
  - action: camera.snapshot
    metadata: {}
    data:
      filename: /media/photos/{{states('input_text.namephotoanalyseia')}}
    enabled: true
    target:
      entity_id: camera.espcam32h_sejour_esp32_camera
  - action: notify.mobile_app_iphone_x2
    data:
      title: Résultat IA
      message: "{{ result.data.message_libre }}"
  - delay:
      hours: 0
      minutes: 0
      seconds: 2
      milliseconds: 0
  - action: telegram_bot.send_message
    metadata: {}
    data:
      config_entry_id: 01JZJXXXXXXXXXZ0A7YVHWGSJ7
      message: "{{ result.data.message_libre }}"
      title: Nombre de pot
  - data:
      file: /media/photos/{{states('input_text.namephotoanalyseia')}}
      config_entry_id: 01JZJXXXXXXXXXZ0A7YVHWGSJ7
    action: telegram_bot.send_photo
    enabled: true
  - action: tts.speak
    metadata: {}
    data:
      cache: true
      media_player_entity_id: media_player.respeaker_satellite
      message: "{{ result.data.message_libre }}"
    target:
      entity_id: tts.piper
alias: AI Task pot de fleurtexte libre
description: ""

Ici avec une réponse prédéterminée avec le nombre de pot de fleur trouvé :

alias: AI Task pot de fleur
sequence:
  - action: ai_task.generate_data
    data:
      entity_id: ai_task.openai_ai_task
      task_name: Analyse plantes
      instructions: >-
        Combien de pots de fleurs y a-t-il sur cette image ? Réponds par un
        nombre entier uniquement.
      structure:
        nombre:
          selector:
            number: null
      attachments:
        - media_content_id: media-source://camera/camera.espcam32h_sejour_esp32_camera
          media_content_type: image/jpeg
    response_variable: result
  - action: input_text.set_value
    metadata: {}
    data:
      value: monImageIA_{{now().strftime("%Y%m%d-%H%M%S")}}.jpg
    target:
      entity_id: input_text.namephotoanalyseia
  - action: camera.snapshot
    metadata: {}
    data:
      filename: /media/photos/{{states('input_text.namephotoanalyseia')}}
    enabled: true
    target:
      entity_id: camera.espcam32h_sejour_esp32_camera
  - action: notify.mobile_app_iphone_x2
    data:
      title: Résultat IA
      message: >-
        L'IA a détecté {{ result.data.nombre }} pots de fleurs à {{
        now().strftime('%H:%M') }}.
  - delay:
      hours: 0
      minutes: 0
      seconds: 2
      milliseconds: 0
  - action: telegram_bot.send_message
    metadata: {}
    data:
      config_entry_id: 01JZJ1XXXXXXXXX0A7YVHWGSJ7
      message: >-
        L'IA a détecté *{{ result.data.nombre }}* pots de fleurs à
        {{now().strftime('%H:%M') }}.
      title: Nombre de pot
  - data:
      file: /media/photos/{{states('input_text.namephotoanalyseia')}}
      config_entry_id: 01JZJ1XXXXXXXXX0A7YVHWGSJ7
    action: telegram_bot.send_photo
    enabled: true
  - action: tts.speak
    metadata: {}
    data:
      cache: true
      media_player_entity_id: media_player.respeaker_satellite
      message: L'IA a détecté {{ result.data.nombre }} pots de fleurs.
    target:
      entity_id: tts.piper
description: ""

Bob

Bonjour,

Je voulais savoir on est limité à 20 demandes par jour ?

Oui depuis debut decembre la formule gratuite est limitée a 20.

merci pour ta réponse, on peut utiliser que Gemini ?

Avec google generative ia oui

On peut pas utiliser d’autre IA pour faire de la surveillance via image ?

Si tu peux utilisé d’autre llm. Faut chercher dans la doc ha tu dois avoir les infos.