Version CorrigĂ©e â 25/11/2025
Surveillance Imprimante 3D par IA Google Gemini + Serveur de marquage (FastAPI)
Description
SystĂšme de surveillance automatique dâimprimante 3D utilisant lâIA Google Gemini pour analyser des captures de la camĂ©ra toutes les 5 minutes pendant lâimpression.
LâIA dĂ©tecte les problĂšmes classiques (spaghetti, warping, piĂšce dĂ©collĂ©e, couches manquantes, amas de filament, etc.) et, en cas dâalerte, dessine un cadre rouge autour de la zone suspecte via un petit serveur FastAPI, puis envoie une notification sur votre tĂ©lĂ©phone avec lâimage annotĂ©e.
Fonctionnalités principales
Analyse IA automatique toutes les X minutes pendant lâimpression (par dĂ©faut 5 min)
Détection des problÚmes courants (spaghetti, warping, détachement, débris de filament, sous/sur-extrusion visible, etc.)
Image annotée avec un rectangle rouge sur la zone problématique (via serveur Gemini Marker)
Notifications mobiles avec image cliquable + actions rapides (Pause / ArrĂȘt)
Statistiques par impression (nombre dâanalyses, nombre de problĂšmes, sĂ©ries de problĂšmes consĂ©cutifs)
Notifications de dĂ©but, fin et pause dâimpression avec photos
Prérequis
-
Home Assistant fonctionnel
-
Intégration Bambu Lab (ou équivalent) exposant au minimum :
-
un capteur dâĂ©tat de lâimprimante (
printing,idle,paused, âŠ) -
le nom de la tĂąche en cours
-
la camĂ©ra de lâimprimante
-
des boutons Pause / Stop
-
-
Intégration Google Generative AI Conversation configurée avec votre clé Gemini
(modÚle recommandé :gemini-2.5-flash-lite) -
Application mobile Home Assistant (Android / iOS)
-
Dossier
/config/www/accessible (pour stocker les images) -
Un petit conteneur / VM (ex.
192.168.1.7) pour faire tourner le serveur FastAPI Gemini Marker
Mode dâemploi et personnalisation
Entités à personnaliser
Dans le YAML, remplacez les entités suivantes par celles de VOTRE imprimante :
| Entité à remplacer | Votre entité | Description |
|---|---|---|
sensor.3d_imprimante_bambu_p1s_etape_actuelle |
sensor.VOTRE_IMPRIMANTE_etape_actuelle |
Statut de lâimprimante (printing, âŠ) |
camera.3d_imprimante_bambu_p1s_camera |
camera.VOTRE_IMPRIMANTE_camera |
CamĂ©ra de lâimprimante |
sensor.3d_imprimante_bambu_p1s_nom_de_la_tache |
sensor.VOTRE_IMPRIMANTE_nom_de_la_tache |
Nom du fichier en impression |
button.3d_imprimante_bambu_p1s_arreter_l_impression |
button.VOTRE_IMPRIMANTE_arreter |
Bouton ArrĂȘt |
button.3d_imprimante_bambu_p1s_mettre_en_pause_l_impression |
button.VOTRE_IMPRIMANTE_pause |
Bouton Pause |
Adapter aussi si besoin lâIP du serveur FastAPI : http://192.168.1.7:5000/mark.
Service de notification
Dans toutes les notifications, remplacez :
notify.mobile_app_tel_mm
par votre service :
-
notify.mobile_app_VOTRE_TELEPHONE -
ou tout autre service
notify.*que vous utilisez.
Pour le trouver :
-
Outils de dĂ©veloppement â onglet Services
-
Cherchez
notify.mobile_app_ -
Notez le nom complet (ex.
notify.mobile_app_s25)
Configuration de lâIA Gemini (Google Generative AI Conversation)
-
Dans Home Assistant :
ParamĂštres â Appareils et services â Ajouter une intĂ©gration â Google Generative AI Conversation -
Saisir votre API Key Gemini.
-
Dans les options de lâintĂ©gration, choisir le modĂšle (ex.
gemini-2.5-flash-lite).
Le package utilise ensuite simplement le service :
action: google_generative_ai_conversation.generate_content
Aucun ai_task ni agent_id à gérer dans ce setup.
FrĂ©quence dâanalyse
Par défaut, HA lance une analyse toutes les 5 minutes :
trigger:
- trigger: time_pattern
minutes: "/5"
Vous pouvez changer "/5" par :
-
"/3"â toutes les 3 minutes -
"/10"â toutes les 10 minutes, etc.
Personnalisation du prompt IA
Dans lâautomatisation principale, vous avez un prompt dĂ©taillĂ© du type :
prompt: >
Tu agis comme un contrĂŽleur automatique d'impression 3D.
...
Ne considĂšre comme PROBLĂME que les cas suivants :
- spaghetti / gros amas de filament
- piÚces décollées du plateau ou qui penchent
- warping important, coins qui se relĂšvent
- gros défauts d'adhérence de la premiÚre couche
- accumulation de débris de filament sur le plateau
- sous-extrusion ou couches manquantes trĂšs visibles
- couche supĂ©rieure totalement dĂ©truite ou extrĂȘmement irrĂ©guliĂšre
Vous pouvez :
-
Durcir la dĂ©tection : ajouter dâautres cas dans la liste.
-
Lâassouplir : insister sur le fait que des modĂšles trĂšs rugueux (rochers, terrains, dĂ©cors) ne sont pas des dĂ©fauts tant quâils sont nets et bien attachĂ©s.
Serveur Gemini Marker (FastAPI)
Ce serveur sert uniquement Ă dessiner un rectangle rouge sur lâimage lorsquâun problĂšme est dĂ©tectĂ©.
a) Installation rapide (sur 192.168.1.7 par exemple)
apt update
apt install python3 python3-pip -y
pip3 install fastapi uvicorn pillow
b) Script FastAPI
Fichier : /opt/gemini_marker/server.py
from fastapi import FastAPI
from PIL import Image, ImageDraw
app = FastAPI()
@app.post("/mark")
async def mark(data: dict):
image_path = data["image_path"]
output_path = data["output_path"]
bbox = data["bbox"]
stroke_width = int(data.get("stroke_width", 4))
img = Image.open(image_path)
draw = ImageDraw.Draw(img)
w, h = img.size
x1 = int(bbox["x_min"] * w)
y1 = int(bbox["y_min"] * h)
x2 = int(bbox["x_max"] * w)
y2 = int(bbox["y_max"] * h)
draw.rectangle([x1, y1, x2, y2], outline="red", width=stroke_width)
img.save(output_path)
return {"status": "ok", "bbox": bbox}
c) Lancement simple
cd /opt/gemini_marker
uvicorn server:app --host 0.0.0.0 --port 5000 &
Dans le YAML HA, on envoie :
-
image_path:/mnt/ha_config/www/imp3d_ai_check.jpg -
output_path:/mnt/ha_config/www/imp3d_ai_check_marked.jpg
Lâimage annotĂ©e est ensuite servie par Home Assistant via :
https://VOTRE_HA/local/imp3d_ai_check_marked.jpg
Installation
-
Créez (ou vérifiez) le dossier :
/config/www/ -
Créez le fichier :
/config/packages/pkg_google_gemini_imp_3d.yaml -
Collez le code complet ci-dessous.
-
Personnalisez les entités (capteurs, boutons, service notify, IP du serveur FastAPI).
-
Redémarrez Home Assistant.
-
Lancez une impression test.
Entités créées
-
input_number.gemini_analyses_current_printâ Compteur dâanalyses pour lâimpression en cours -
input_number.gemini_problemes_current_printâ Compteur de problĂšmes pour lâimpression en cours -
input_number.gemini_problemes_streakâ SĂ©rie de problĂšmes consĂ©cutifs -
input_text.gemini_last_rawâ DerniĂšre rĂ©ponse brute (DEBUG) -
input_text.gemini_last_responseâ Dernier rĂ©sumĂ© lisible -
input_text.gemini_current_print_nameâ Nom de lâimpression en cours -
input_datetime.gemini_last_checkâ Horodatage de la derniĂšre vĂ©rification -
sensor.gemini_total_analyses_count/sensor.gemini_total_problems_countâ Stats globales sur le log -
sensor.gemini_total_analyses_history/sensor.gemini_total_problemes_historyâ Stats historisĂ©es -
binary_sensor.gemini_probleme_en_coursâ Indicateur binaire de problĂšme IA -
sensor.imprimante_3d_-_statut_lisibleâ Statut lisible de lâimprimante (En impression / Inactive / En pause)
Code complet â PACKAGE HA + IA + Marquage
# =============================================================================
# PACKAGE : Surveillance Imprimante 3D + Gemini (Bambu P1S)
# FICHIER : /config/packages/pkg_google_gemini_imp_3d.yaml
# VERSION : 2.0
# =============================================================================
# -----------------------------------------------------------------------------
# SHELL COMMANDS : log texte + purge
# -----------------------------------------------------------------------------
shell_command:
gemini_log_append: >
sh -c 'printf "%s\n" "$1" >> /config/www/imp3d_gemini_history.log' --
"{{ message }}"
purge_gemini_current_log: ">: /config/www/imp3d_gemini_history.log"
# -----------------------------------------------------------------------------
# REST COMMAND : FastAPI marquage dâimage (bbox dynamique)
# -----------------------------------------------------------------------------
rest_command:
gemini_mark_image:
url: "http://192.168.1.7:5000/mark" # â adapter l'IP si besoin
method: POST
headers:
Content-Type: application/json
payload: >
{
"image_path": "/mnt/ha_config/www/imp3d_ai_check.jpg",
"output_path": "/mnt/ha_config/www/imp3d_ai_check_marked.jpg",
"bbox": {
"x_min": {{ x_min | default(0.45) }},
"y_min": {{ y_min | default(0.45) }},
"x_max": {{ x_max | default(0.55) }},
"y_max": {{ y_max | default(0.55) }}
},
"stroke_width": 4,
"margin": 0.0
}
# -----------------------------------------------------------------------------
# INPUTS (compteurs + derniers résultats)
# -----------------------------------------------------------------------------
input_number:
gemini_analyses_current_print:
name: "Gemini - Analyses (impression actuelle)"
min: 0
max: 1000
step: 1
icon: mdi:counter
gemini_problemes_current_print:
name: "Gemini - ProblÚmes détectés (impression actuelle)"
min: 0
max: 100
step: 1
icon: mdi:alert-circle
gemini_problemes_streak:
name: "Gemini - Série de problÚmes consécutifs"
min: 0
max: 50
step: 1
icon: mdi:alert-decagram
input_text:
gemini_last_raw:
name: "Gemini - DerniÚre réponse brute (DEBUG)"
max: 255
icon: mdi:code-json
gemini_last_response:
name: "Gemini - Dernier résumé lisible"
max: 255
icon: mdi:message-text
gemini_current_print_name:
name: "Gemini - Nom impression"
max: 100
icon: mdi:printer-3d
input_datetime:
gemini_last_check:
name: "Gemini - DerniÚre vérification"
has_date: true
has_time: true
input_boolean:
gemini_package_loaded:
name: "DEBUG - Gemini package chargé"
icon: mdi:bug
# -----------------------------------------------------------------------------
# SCRIPT : consultation de lâhistorique (log)
# -----------------------------------------------------------------------------
script:
voir_historique_gemini:
alias: "đ Voir Historique Gemini"
mode: single
sequence:
- action: homeassistant.update_entity
target:
entity_id:
- sensor.gemini_total_analyses_count
- sensor.gemini_total_problems_count
- delay:
seconds: 1
- variables:
total_lines: "{{ states('sensor.gemini_total_analyses_count') | int(0) }}"
total_problems: "{{ states('sensor.gemini_total_problems_count') | int(0) }}"
- action: persistent_notification.create
data:
title: "đ Historique Gemini"
message: |
đ Total analyses (lignes log): {{ total_lines }}
â ïž Total problĂšmes (lignes log): {{ total_problems }}
Fichier actuel: /config/www/imp3d_gemini_history.log
Accessible via: /local/imp3d_gemini_history.log
# -----------------------------------------------------------------------------
# SENSORS COMMAND_LINE : stats depuis le fichier log
# -----------------------------------------------------------------------------
command_line:
- sensor:
name: "Gemini Total Analyses Count"
unique_id: gemini_total_analyses_count
command: "wc -l < /config/www/imp3d_gemini_history.log 2>/dev/null || echo 0"
scan_interval: 300
- sensor:
name: "Gemini Total Problems Count"
unique_id: gemini_total_problems_count
command: "grep -c 'PROBLĂME' /config/www/imp3d_gemini_history.log 2>/dev/null || echo 0"
scan_interval: 300
# -----------------------------------------------------------------------------
# TEMPLATE SENSORS + BINARY_SENSOR
# -----------------------------------------------------------------------------
template:
- sensor:
- name: "Imprimante 3D - Statut Lisible"
unique_id: p1s_status_readable
state: >
{% set s = states('sensor.3d_imprimante_bambu_p1s_etape_actuelle') %}
{% if s == 'printing' %}En impression
{% elif s == 'idle' %}Inactive
{% elif 'paused' in s %}En pause
{% else %}{{ s | replace('_', ' ') | title }}{% endif %}
icon: mdi:printer-3d
- name: "Gemini - Total Analyses Historique"
unique_id: gemini_total_analyses_history
state: "{{ states('sensor.gemini_total_analyses_count') | int(0) }}"
icon: mdi:counter
unit_of_measurement: "analyses"
- name: "Gemini - Total ProblĂšmes Historique"
unique_id: gemini_total_problemes_history
state: "{{ states('sensor.gemini_total_problems_count') | int(0) }}"
icon: mdi:alert-circle
unit_of_measurement: "problĂšmes"
binary_sensor:
- name: "Gemini - ProblĂšme en cours"
unique_id: gemini_probleme_en_cours
state: >
{{ 'PROBLEME' in states('input_text.gemini_last_response') }}
icon: mdi:alert-octagram
# -----------------------------------------------------------------------------
# AUTOMATISATIONS
# -----------------------------------------------------------------------------
automation:
- alias: "đ§Ș TEST - Analyse Gemini Manuelle"
id: test_gemini_manual_trigger
trigger:
- trigger: event
event_type: test_gemini_analysis
action:
- action: shell_command.gemini_log_append
data:
message: "TEST MANUEL OK"
- alias: "đ Surveillance Impression 3D - IA Gemini"
id: p1s_ai_monitoring_gemini
mode: queued
trigger:
- trigger: time_pattern
minutes: "/5"
condition:
- condition: template
value_template: >
{{ states('sensor.3d_imprimante_bambu_p1s_etape_actuelle')
not in ['idle','offline','unknown'] }}
action:
- action: camera.snapshot
target:
entity_id: camera.3d_imprimante_bambu_p1s_camera
data:
filename: /config/www/imp3d_ai_check.jpg
- delay:
seconds: 2
- action: google_generative_ai_conversation.generate_content
continue_on_error: true
data:
prompt: >
Tu agis comme un contrĂŽleur automatique d'impression 3D.
Tu reçois UNE SEULE photo d'une imprimante 3D en cours d'impression.
Le modĂšle peut ĂȘtre volontairement trĂšs rugueux ou irrĂ©gulier
(rocher, pierre, terrain, décor, sculpture organique, etc.).
Une surface globalement rugueuse mais cohérente, bien attachée
et sans filaments parasites n'est PAS un défaut.
Ne considĂšre comme PROBLĂME que les cas suivants :
- spaghetti / gros amas de filament
- piÚces décollées du plateau ou qui penchent
- warping important, coins qui se relĂšvent
- gros défauts d'adhérence de la premiÚre couche
- accumulation de débris de filament sur le plateau
- sous-extrusion ou couches manquantes trĂšs visibles
- couche supĂ©rieure totalement dĂ©truite ou extrĂȘmement irrĂ©guliĂšre
Réponds STRICTEMENT avec l'un de ces deux JSON, sans texte autour :
1) Si tout va bien :
{"status":"OK"}
2) S'il y a un problĂšme visible :
{
"status": "PROBLEME",
"description": "texte court en français décrivant le problÚme",
"bbox": {
"x_min": 0.0,
"y_min": 0.0,
"x_max": 1.0,
"y_max": 1.0
}
}
Ne rajoute pas de ```json``` ni de commentaires.
filenames:
- /config/www/imp3d_ai_check.jpg
response_variable: gemini_response
- variables:
gemini_raw: >
{{ gemini_response.text if gemini_response is defined
else 'ERREUR_APPEL_GEMINI' }}
gemini_clean: >
{% set raw = gemini_raw | string %}
{% set raw = raw | replace('```json','') | replace('```','') %}
{% set raw = raw | regex_replace('\\s+', ' ') %}
{{ raw | trim }}
gemini_json: >
{% if gemini_clean.startswith('{') and gemini_clean.endswith('}') %}
{{ gemini_clean | from_json(default={}) }}
{% else %}
{}
{% endif %}
gemini_status: >
{% if gemini_json is mapping and gemini_json.status is defined %}
{% set s = gemini_json.status | string | upper %}
{% if s in ['OK', 'PROBLEME'] %}
{{ s }}
{% else %}
ERREUR
{% endif %}
{% elif gemini_raw == 'ERREUR_APPEL_GEMINI' %}
ERREUR
{% elif '"status"' in gemini_raw %}
{% if 'PROBLEME' in gemini_raw %}PROBLEME
{% elif 'OK' in gemini_raw %}OK
{% else %}ERREUR{% endif %}
{% else %}
ERREUR
{% endif %}
gemini_description: >
{% if gemini_status == 'PROBLEME' %}
{% if gemini_json is mapping and gemini_json.description is defined %}
{{ gemini_json.description }}
{% else %}
ProblÚme détecté sur l'impression.
{% endif %}
{% elif gemini_status == 'OK' %}
OK
{% else %}
Erreur dâanalyse IA
{% endif %}
gemini_bbox_x_min: >
{% if gemini_status == 'PROBLEME'
and gemini_json is mapping
and gemini_json.bbox is defined
and gemini_json.bbox.x_min is defined %}
{{ gemini_json.bbox.x_min }}
{% else %}
0.45
{% endif %}
gemini_bbox_y_min: >
{% if gemini_status == 'PROBLEME'
and gemini_json is mapping
and gemini_json.bbox is defined
and gemini_json.bbox.y_min is defined %}
{{ gemini_json.bbox.y_min }}
{% else %}
0.45
{% endif %}
gemini_bbox_x_max: >
{% if gemini_status == 'PROBLEME'
and gemini_json is mapping
and gemini_json.bbox is defined
and gemini_json.bbox.x_max is defined %}
{{ gemini_json.bbox.x_max }}
{% else %}
0.55
{% endif %}
gemini_bbox_y_max: >
{% if gemini_status == 'PROBLEME'
and gemini_json is mapping
and gemini_json.bbox is defined
and gemini_json.bbox.y_max is defined %}
{{ gemini_json.bbox.y_max }}
{% else %}
0.55
{% endif %}
gemini_ts: "{{ now().strftime('%Y-%m-%d %H:%M:%S') }}"
gemini_resume: >
{% if gemini_status == 'PROBLEME' %}
{{ gemini_ts }} - PROBLEME - {{ gemini_description }}
{% elif gemini_status == 'OK' %}
{{ gemini_ts }} - OK
{% else %}
{{ gemini_ts }} - ERREUR - {{ gemini_description }}
{% endif %}
- action: input_number.set_value
target:
entity_id: input_number.gemini_analyses_current_print
data:
value: "{{ states('input_number.gemini_analyses_current_print') | float + 1 }}"
- choose:
- conditions:
- condition: template
value_template: "{{ gemini_status == 'PROBLEME' }}"
sequence:
- action: input_number.set_value
target:
entity_id: input_number.gemini_problemes_streak
data:
value: "{{ states('input_number.gemini_problemes_streak') | float + 1 }}"
- conditions:
- condition: template
value_template: "{{ gemini_status != 'PROBLEME' }}"
sequence:
- action: input_number.set_value
target:
entity_id: input_number.gemini_problemes_streak
data:
value: 0
- action: input_text.set_value
target:
entity_id: input_text.gemini_last_raw
data:
value: "{{ gemini_raw }}"
- action: input_text.set_value
target:
entity_id: input_text.gemini_last_response
data:
value: "{{ gemini_resume }}"
- action: input_datetime.set_datetime
target:
entity_id: input_datetime.gemini_last_check
data:
datetime: "{{ now().isoformat() }}"
- action: shell_command.gemini_log_append
data:
message: >
{% if gemini_status == "OK" %}â
OK
{% elif gemini_status == "PROBLEME" %}â ïž PROBLĂME
{% else %}â ERREUR GEMINI{% endif %}
| {{ now().strftime('%Y-%m-%d %H:%M:%S') }}
| {{ states('input_text.gemini_current_print_name') }}
| Analyse #{{ states('input_number.gemini_analyses_current_print') | int }}
| {{ gemini_description }}
- condition: template
value_template: "{{ gemini_status == 'PROBLEME' }}"
- action: rest_command.gemini_mark_image
data:
x_min: "{{ gemini_bbox_x_min }}"
y_min: "{{ gemini_bbox_y_min }}"
x_max: "{{ gemini_bbox_x_max }}"
y_max: "{{ gemini_bbox_y_max }}"
- action: input_number.set_value
target:
entity_id: input_number.gemini_problemes_current_print
data:
value: "{{ states('input_number.gemini_problemes_current_print') | float + 1 }}"
- action: notify.mobile_app_tel_mm
data:
title: "â ïž ProblĂšme Impression 3D !"
message: "{{ gemini_description }}"
data:
image: "https://xxxxxxxxx.org/local/imp3d_ai_check_marked.jpg?t={{ now().timestamp() | int }}"
clickAction: "/local/imp3d_ai_check_marked.jpg?t={{ now().timestamp() | int }}"
priority: high
ttl: 0
color: "#FF0000"
tag: "print_issue"
actions:
- action: "PAUSE_PRINT"
title: "âžïž Pause"
- action: "STOP_PRINT"
title: "đ ArrĂȘter"
- alias: "âžïž Auto-pause impression 3D si problĂšmes rĂ©pĂ©tĂ©s"
id: p1s_auto_pause_gemini
trigger:
- trigger: numeric_state
entity_id: input_number.gemini_problemes_streak
above: 2
condition:
- condition: state
entity_id: sensor.3d_imprimante_bambu_p1s_etape_actuelle
state: "printing"
action:
- action: button.press
target:
entity_id: button.3d_imprimante_bambu_p1s_mettre_en_pause_l_impression
- action: notify.mobile_app_tel_mm
data:
title: "âžïž Pause automatique par IA"
message: >
Impression "{{ states('input_text.gemini_current_print_name') }}"
mise en PAUSE aprĂšs {{ states('input_number.gemini_problemes_streak') | int }}
analyses problématiques consécutives.
data:
priority: high
color: "#FFA500"
tag: "print_issue_auto_pause"
- alias: "đ Auto-stop impression 3D si problĂšmes persistants"
id: p1s_auto_stop_gemini
trigger:
- trigger: numeric_state
entity_id: input_number.gemini_problemes_streak
above: 5
condition:
- condition: state
entity_id: sensor.3d_imprimante_bambu_p1s_etape_actuelle
state: "printing"
action:
- action: button.press
target:
entity_id: button.3d_imprimante_bambu_p1s_arreter_l_impression
- action: notify.mobile_app_tel_mm
data:
title: "đ ArrĂȘt automatique par IA"
message: >
Impression "{{ states('input_text.gemini_current_print_name') }}"
arrĂȘtĂ©e automatiquement aprĂšs
{{ states('input_number.gemini_problemes_streak') | int }}
analyses problématiques consécutives.
data:
priority: high
color: "#FF0000"
tag: "print_issue_auto_stop"
- alias: "đšïž DĂ©but Surveillance Impression 3D"
id: print_start_gemini_notification
trigger:
- trigger: state
entity_id: sensor.3d_imprimante_bambu_p1s_etape_actuelle
to: "printing"
action:
- action: shell_command.purge_gemini_current_log
- action: input_number.set_value
target:
entity_id:
- input_number.gemini_analyses_current_print
- input_number.gemini_problemes_current_print
- input_number.gemini_problemes_streak
data:
value: 0
- action: input_text.set_value
target:
entity_id:
- input_text.gemini_last_raw
- input_text.gemini_last_response
data:
value: ""
- action: input_text.set_value
target:
entity_id: input_text.gemini_current_print_name
data:
value: "{{ states('sensor.3d_imprimante_bambu_p1s_nom_de_la_tache') }}"
- action: shell_command.gemini_log_append
data:
message: >
đšïž DĂBUT
| {{ now().strftime('%Y-%m-%d %H:%M:%S') }}
| {{ states('sensor.3d_imprimante_bambu_p1s_nom_de_la_tache') }}
| Analyse #0
| Impression démarrée - Surveillance IA activée
- action: camera.snapshot
target:
entity_id: camera.3d_imprimante_bambu_p1s_camera
data:
filename: /config/www/imp3d_start.jpg
- delay:
seconds: 2
- action: notify.mobile_app_tel_mm
data:
title: "đšïž Impression DĂ©marrĂ©e"
message: "{{ states('sensor.3d_imprimante_bambu_p1s_nom_de_la_tache') }} - Surveillance IA activée"
data:
image: "/api/camera_proxy/camera.3d_imprimante_bambu_p1s_camera?{{ now().timestamp() | int }}"
clickAction: "/api/camera_proxy/camera.3d_imprimante_bambu_p1s_camera?{{ now().timestamp() | int }}"
priority: normal
color: "#0000FF"
tag: "print_status"
- alias: "â
Fin Impression 3D Réussie"
id: print_completed_gemini_notification
trigger:
- trigger: state
entity_id: sensor.3d_imprimante_bambu_p1s_etape_actuelle
to: "idle"
from: "printing"
action:
- action: shell_command.gemini_log_append
data:
message: >
â
FIN
| {{ now().strftime('%Y-%m-%d %H:%M:%S') }}
| {{ states('input_text.gemini_current_print_name') }}
| Analyse #{{ states('input_number.gemini_analyses_current_print') | int }}
| Impression terminée - {{ states('input_number.gemini_analyses_current_print') | int }} analyses - {{ states('input_number.gemini_problemes_current_print') | int }} problÚmes détectés
- action: camera.snapshot
target:
entity_id: camera.3d_imprimante_bambu_p1s_camera
data:
filename: /config/www/imp3d_final.jpg
- delay:
seconds: 2
- action: notify.mobile_app_tel_mm
data:
title: "â
Impression Terminée"
message: >
{{ states('input_text.gemini_current_print_name') }}
đ Analyses IA: {{ states('input_number.gemini_analyses_current_print') | int }}
â ïž ProblĂšmes: {{ states('input_number.gemini_problemes_current_print') | int }}
data:
image: "/local/imp3d_final.jpg?t={{ now().timestamp() | int }}"
clickAction: "/local/imp3d_final.jpg?t={{ now().timestamp() | int }}"
priority: high
ttl: 0
color: "#00FF00"
tag: "print_status"
Checklist avant test
-
Toutes les entités
sensor.3d_imprimante_bambu_p1s_*remplacées -
Toutes les entités
camera.3d_imprimante_bambu_p1s_cameraremplacées -
Boutons Pause / Stop adaptés
-
Service
notify.mobile_app_tel_mmremplacé -
IP du serveur FastAPI corrigée si besoin
-
Fichier sauvegardé dans
/config/packages/ -
Home Assistant redémarré
-
Une impression test lancée (attendre au moins 5 min pour la premiÚre analyse)
Dépannage rapide
-
Pas de notification
â VĂ©rifier le servicenotify.*dans Outils de dĂ©veloppement. -
Aucune analyse ne se lance
â VĂ©rifier que lâĂ©tat de lâimprimante passe bien Ăprinting.
â VĂ©rifier le dĂ©clencheurtime_pattern(minutes/5). -
Message
ERREUR_APPEL_GEMINI
â VĂ©rifier lâintĂ©gration Google Generative AI Conversation (clĂ© API, quotas, modĂšle). -
Pas de cadre rouge sur lâimage
â Tester le FastAPI Ă part, vĂ©rifier le chemin des fichiers (/mnt/ha_config/www/...) et les droits.
Une fois tout ça en place, tu es tranquille : lâIA surveille tes impressions, tâenvoie les captures comme celles que tu as dĂ©jĂ vu (plateau avec cadre rouge bien centrĂ©) et te spamme uniquement quand il y a un vrai souci.