mdf73 1 112 Posté(e) mai 30 Auteur Partager Posté(e) mai 30 (modifié) Bonjour a tous Allez reprenons la suite de la présentation avec la page suivante : 6 - Les Extractions - Rosin & Hash Ce que c'est GrowManager intègre deux pages dédiées aux extractions : une pour la Rosin et une pour le Hash. L'idée est la même dans les deux cas - enregistrer chaque session, suivre vos rendements, et accumuler des stats pour progresser d'une session à l'autre. Extractions Rosin La liste des sessions Toutes vos sessions de presse sont listées dans un tableau triable : variété, maillage, nombre de passes, poids d'entrée, poids de sortie, rendement en %, date. Triable sur toutes ces colonnes, avec tri par défaut sur la date (les plus récentes en premier). Une barre de recherche vous permet de filtrer par variété - et quand vous filtrez, les statistiques en haut de page se recalculent automatiquement pour ne refléter que les sessions de la variété sélectionnée. Pratique pour comparer les rendements d'un même strain sur plusieurs sessions. Les stats Quatre cartes en haut de page : Rendement moyen Total pressé (poids d'entrée cumulé) Rosin extrait (poids de sortie cumulé) Nombre de sessions Ces chiffres s'adaptent au filtre variété si vous en avez un d'actif. Enregistrer une session Quand vous lancez une nouvelle session, vous renseignez : La variété pressée Le maillage du rosin bag Le nombre de passes Le poids de chaque sac individuellement (en grammes avec deux décimales) - le total d'entrée se calcule automatiquement Le poids de sortie (rosin récupéré) La température de presse Des notes libres Le rendement est calculé automatiquement. Le détail d'une session Chaque session est cliquable pour accéder à sa fiche complète - tous les paramètres enregistrés, les poids par sac, le rendement calculé, les notes. Extractions Hash La page Hash fonctionne sur le même principe mais adaptée aux techniques de tamisage à sec (Polinator) et à l'eau (Ice-o-lator). Vous enregistrez vos sessions avec : la variété, la technique utilisée, le nombre de passages, les sacs et leurs rendements, les notes. Même système de filtre par variété, même logique de stats cumulées. Ice-O-Lator : Polinator (mais marche aussi pour les tamis) N'ayant pas eu l'occasion de faire du hash dernièrement je n'ai pas eu l'occasion de tester les fonctionnalités de cette page en conditions réelles donc il manque surement plein de choses Les deux pages extractions sont aussi alimentées par l'onglet "Pour extraction" de la page Stock - vous savez toujours exactement ce que vous avez en attente de traitement et depuis combien de temps. D'autres options d'extractions seront ajoutées dans le futur (BHO, etc...) A+ Hey bonjour a tous, @Lamic-Tal : Désolé j'avais zappé de te répondre. L'intégration des outils bluetooth est pas prete d'arrivée. Je sais meme pas si c'est possible. Je vais ajouter des options pour d'autres outils mais uniquement via wifi pour le moment. @Maledikchaouch encore merci pour tous tes retours. - Pour le Dashboard c'est pas normal il doit s'afficher meme si tu n'a rien. Il s'affiche juste avec des valeurs a 0 partout mais il doit t'afficher les modules. - Tres bonne idée pour les clones je vais bosser dessus et je te tiens au jus - Tres bonne idée aussi pour les croisements je vais bosser dessus aussi A+ Modifié mai 30 par mdf73 1 6 Lien à poster Partager sur d’autres sites
Maledikchaouch 1 251 Posté(e) mai 31 Partager Posté(e) mai 31 Hello dominical ! Il y a 21 heures, mdf73 a dit: - Pour le Dashboard c'est pas normal il doit s'afficher meme si tu n'a rien. Il s'affiche juste avec des valeurs a 0 partout mais il doit t'afficher les modules. J'ai suivi tes instructions (pas le choix vu mon expertise dans le domaine), c'est donc ta faute 🤣. Plus sérieusement, c'est comme ça depuis la première installation et ça m'énerve d'être trop une buse pour essayer de comprendre pourquoi (plus que le non-affichage). Tentative de suivre le guide que tu m'as envoyé pour Github dans la matinée, je viendrai éditer le post après avoir tenté une réinstallation via la plateforme. ++ 1 1 Lien à poster Partager sur d’autres sites
Dominiquesuppo 26 Posté(e) mai 31 Partager Posté(e) mai 31 (modifié) Bravo, super application. C'est la plus complète et relativement simple à metttre en place. Je l'ai fait tourner via portainer sur mon serveur. J'ai mouliné un peu avec l'AI pour ajouter les capteurs que j'ai déjà. Les capteurs tournent sur esphome, une solution portée par la communauté Home Assistant. Pour se faire, il suffit : Créer backend/app/schemas/esphome.py """ Schémas Pydantic pour l'intégration ESPHome. NOUVEAU FICHIER — backend/app/schemas/esphome.py """ from datetime import datetime from typing import Optional from pydantic import BaseModel class ESPHomePushPayload(BaseModel): """Corps JSON envoyé par le capteur ESPHome via http_request.""" device_id: str temperature: Optional[float] = None humidite: Optional[float] = None co2: Optional[float] = None timestamp: Optional[int] = None # Unix timestamp UTC (optionnel) class ESPHomePushResult(BaseModel): status: str id_log: Optional[int] = None vpd: Optional[float] = None message: Optional[str] = None class ESPHomeDeviceCreate(BaseModel): """Enregistrement d'un nouveau capteur ESPHome.""" nom: str device_id: str ip_lan: Optional[str] = None id_espace: Optional[int] = None notes: Optional[str] = None Étape 2 — Créer backend/app/routers/esphome.py """ Router ESPHome — intégration capteurs ESPHome dans GrowManager. NOUVEAU FICHIER — backend/app/routers/esphome.py Architecture : - ESPHome pousse ses données via POST /api/capteurs/esphome/push - Les capteurs ESPHome sont stockés dans GoveeDevice avec modele="esphome" - Les relevés sont dans TemperatureLog avec source="esphome" => graphiques et filtres existants déjà compatibles sans toucher au frontend """ from datetime import datetime, timezone from typing import List, Optional from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session from app.database import get_db from app.models.all_models import GoveeDevice, TemperatureLog from app.schemas.esphome import ESPHomePushPayload, ESPHomePushResult, ESPHomeDeviceCreate from app.services.govee_poller import compute_vpd, _get_active_culture_id router = APIRouter(tags=["esphome"]) ESPHOME_MODELE = "esphome" # ───────────────────────────────────────────────────────────────────────────── # Helper interne # ───────────────────────────────────────────────────────────────────────────── def _get_device_by_esphome_id(device_id: str, db: Session) -> Optional[GoveeDevice]: return ( db.query(GoveeDevice) .filter( GoveeDevice.device_id == device_id, GoveeDevice.modele == ESPHOME_MODELE, ) .first() ) # ───────────────────────────────────────────────────────────────────────────── # Endpoint principal : réception des données ESPHome # ───────────────────────────────────────────────────────────────────────────── @router.post("/api/capteurs/esphome/push", response_model=ESPHomePushResult) def esphome_push(payload: ESPHomePushPayload, db: Session = Depends(get_db)): """ Reçoit un relevé depuis un capteur ESPHome via HTTP POST. Le capteur doit être enregistré au préalable via POST /api/capteurs/esphome/devices. """ device = _get_device_by_esphome_id(payload.device_id, db) if not device: raise HTTPException( status_code=404, detail=f"Capteur ESPHome '{payload.device_id}' non enregistré. " f"Créez-le d'abord via POST /api/capteurs/esphome/devices" ) if not device.actif: return ESPHomePushResult(status="ignored", message="Capteur inactif — donnée ignorée") # Calcul VPD si temp + humidité disponibles vpd = None if payload.temperature is not None and payload.humidite is not None: vpd = compute_vpd(payload.temperature, payload.humidite) # Culture active liée à l'espace du capteur id_culture = None if device.id_espace: id_culture = _get_active_culture_id(db, device.id_espace) # Horodatage : timestamp ESPHome si fourni, sinon maintenant if payload.timestamp: date_heure = datetime.fromtimestamp(payload.timestamp, tz=timezone.utc) else: date_heure = datetime.now(timezone.utc) # Insertion dans TemperatureLog avec source="esphome" log = TemperatureLog( id_device= device.id_device, id_culture= id_culture, id_espace= device.id_espace, date_heure= date_heure, temperature= payload.temperature, humidite= payload.humidite, vpd= vpd, source= "esphome", ) db.add(log) db.commit() db.refresh(log) return ESPHomePushResult(status="ok", id_log=log.id_log, vpd=vpd) # ───────────────────────────────────────────────────────────────────────────── # CRUD capteurs ESPHome # ───────────────────────────────────────────────────────────────────────────── @router.get("/api/capteurs/esphome/devices") def list_esphome_devices(db: Session = Depends(get_db)): """Liste tous les capteurs ESPHome enregistrés.""" return ( db.query(GoveeDevice) .filter(GoveeDevice.modele == ESPHOME_MODELE) .order_by(GoveeDevice.nom) .all() ) @router.post("/api/capteurs/esphome/devices", status_code=201) def create_esphome_device(payload: ESPHomeDeviceCreate, db: Session = Depends(get_db)): """ Enregistre un nouveau capteur ESPHome. Le device_id doit correspondre exactement à celui configuré dans le YAML ESPHome. """ existing = _get_device_by_esphome_id(payload.device_id, db) if existing: raise HTTPException( status_code=409, detail=f"Un capteur ESPHome avec device_id='{payload.device_id}' existe déjà" ) device = GoveeDevice( nom= payload.nom, device_id= payload.device_id, modele= ESPHOME_MODELE, ip_lan= payload.ip_lan, id_espace= payload.id_espace, actif= True, notes= payload.notes, ) db.add(device) db.commit() db.refresh(device) return device @router.delete("/api/capteurs/esphome/devices/{device_id}", status_code=204) def delete_esphome_device(device_id: int, db: Session = Depends(get_db)): """Supprime un capteur ESPHome (les logs associés sont conservés).""" device = db.query(GoveeDevice).filter(GoveeDevice.id_device == device_id).first() if not device or device.modele != ESPHOME_MODELE: raise HTTPException(status_code=404, detail="Capteur ESPHome introuvable") db.delete(device) db.commit() Étape 3 — Modifier backend/app/main.py Ajouter : from app.routers import esphome Et app.include_router(esphome.router) A la suite des autres from.... et app.inclu.... Ouvrir http://votregrowmanager:port/docs Aller à POST /api/capteurs/esphome/devices Ajouter : { "nom": "LeNom", "device_id": "LeNom", "id_espace": 1, "notes": "Capteur température/humidité ESPHome" } Ensuite dans esphome, ajouter à votre yaml : interval: - interval: 60s then: - if: condition: lambda: |- return !isnan(id(LeNom_temperature).state) && !isnan(id(LeNom_humidite).state); then: - http_request.post: url: "http://localhost:port/api/capteurs/esphome/push" request_headers: Content-Type: application/json json: |- root["device_id"] = "LeNom"; root["temperature"] = id(LeNom_temperature).state; root["humidite"] = id(LeNom_humidite).state; root["co2"] = 0; Petite modification de niche, mais ça pourra peut être guider ceux qui veulent modifier un peu... J'ai aussi fait une petite modification perso du docker-compose.yaml version: "3.8" services: db: image: mysql:8.2 container_name: growmanager-db restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-growroot} MYSQL_DATABASE: ${MYSQL_DATABASE:-growmanager} MYSQL_USER: ${MYSQL_USER:-grow} MYSQL_PASSWORD: ${MYSQL_PASSWORD:-grow2024} TZ: ${TZ:-Europe/Paris} volumes: - ${GM_DATA_ROOT}/mysql:/var/lib/mysql - ./backend/init.sql:/docker-entrypoint-initdb.d/01_init.sql:ro ports: - "${MYSQL_PORT:-3306}:3306" healthcheck: test: ["CMD-SHELL", "mysqladmin ping -h localhost -u${MYSQL_USER:-grow} -p${MYSQL_PASSWORD:-grow2024} --silent"] interval: 10s timeout: 5s retries: 10 backend: build: context: ./backend container_name: growmanager-backend restart: unless-stopped environment: DATABASE_URL: mysql+pymysql://${MYSQL_USER:-grow}:${MYSQL_PASSWORD:-grow2024}@db:3306/${MYSQL_DATABASE:-growmanager} SECRET_KEY: ${SECRET_KEY:-changeme-in-production} GROWMANAGER_URL: ${GROWMANAGER_URL:-http://growmanager} TZ: ${TZ:-Europe/Paris} depends_on: db: condition: service_healthy ports: - "${BACKEND_PORT:-8000}:8000" volumes: - ${GM_DATA_ROOT}/uploads:/app/uploads frontend: build: context: ./frontend container_name: growmanager-frontend restart: unless-stopped depends_on: - backend ports: - "${FRONTEND_PORT:-5173}:5173" nginx: image: nginx:alpine container_name: growmanager-nginx restart: unless-stopped ports: - "${APP_PORT:-80}:80" volumes: - ${GM_DATA_ROOT}/nginx.conf:/etc/nginx/conf.d/default.conf:ro depends_on: - frontend - backend Avec en environnement : GM_DATA_ROOT=/mnt/user/appdata/growmanager MYSQL_ROOT_PASSWORD=ChangeMoiRoot MYSQL_DATABASE=growmanager MYSQL_USER=grow MYSQL_PASSWORD=ChangeMoiApp SECRET_KEY=UneCleLongueAleatoire GROWMANAGER_URL=http://xxx.xxx.xxx.:420 TZ=Europe/Paris MYSQL_PORT=3306 BACKEND_PORT=8000 FRONTEND_PORT=5173 APP_PORT=420 En changeant les ports dans l'environnement, ça ignore les ports du compose, ça m'arrange. Plus simple de les gérer ici directement. Petite question au passage, comment modifier les offsets pour la température des feuilles dans le calcul du vpd ? Serait il plus simple de tourner directement avec une image ? Comme ça on a un versioning plus logique avec des tags etc... Encore une fois, je ne suis qu'un amateur, je dis peut être des conneries... A bientôt ! Edit : Je dois être nul mais si l'on crée une culture (alors déjà en cours) comment éditer les différentes dates germination, passage 12/12 etc ? Edit2 : On ne peut pas cliquer sur les cases du calendrier passées, mais on peut cliquer sur une à venir et dans le menu déroulant choisir une date passée. Je pense que c'est un bon moyen d'assurer une erreur éventuelle de sélection de date, pas la peine de modifier pour pouvoir cliquer sur les cases passées bien que ça puisse être rébarbatif Modifié mai 31 par Dominiquesuppo Ajoute question culture. 1 2 Lien à poster Partager sur d’autres sites
mdf73 1 112 Posté(e) Mercredi à 19:14 Auteur Partager Posté(e) Mercredi à 19:14 (modifié) Bonsoir les jardigeek Deja un grand merci à tous pour vos retours c'est top !! @Maledikchaouch : La partie Croisements a été revue en profondeur. On a ajouté un troisième onglet dédié "Open Field" qui gère exactement ce que tu décrivais : tu peux créer un projet avec N plantes mères, ajouter autant de pères que tu veux (depuis le stock de pollen ou en phénotype libre), et cocher les pères probables par mère. Pour chaque mère tu indiques si la pollinisation est simple (1 mâle identifié) ou ouverte (plusieurs pères, voire inconnus). À la récolte, ça crée automatiquement une nouvelle variété (♀ × ♂) et un pack de graines dans le catalogue. Et oui, tu peux lier tout ça à une culture active existante pour choisir les parents directement depuis tes plantes en cours. @Dominiquesuppo : On a traité tous tes points : ESPHome est maintenant intégré nativement. Les capteurs ESPHome s'ajoutent dans Paramétrage → onglet Capteurs, côte à côte avec les Govee. Les logs rentrent dans la même table que les autres capteurs, donc les graphiques et le VPD fonctionnent sans rien changer. Offset température foliaire (VPD) : c'est maintenant un paramètre configurable dans Paramétrage → onglet Capteurs. La valeur par défaut est 2°C (différentiel feuille/air classique) mais tu peux l'ajuster. Édition des dates d'une culture déjà en cours : un bouton "Dates" a été ajouté dans le header du détail de culture. Tu peux modifier germination, passage 12/12, début floraison, récolte estimée, date de fin — sans contrainte sur les dates passées. Images Docker avec versioning : c'est fait. Les images sont buildées et publiées automatiquement sur ghcr.io/mdf73/ à chaque tag vX.Y.Z. Pour Portainer, tu utilises docker-compose.prod.yml et un simple ./update.sh v1.2.0 pour passer à une nouvelle version. Plus besoin de builder en local. Merci encore pour les retours constructifs, c'est exactement ce qui fait avancer le projet ! 🙏 Modifié Jeudi à 10:54 par mdf73 4 1 Lien à poster Partager sur d’autres sites
Maledikchaouch 1 251 Posté(e) Jeudi à 05:33 Partager Posté(e) Jeudi à 05:33 Hello ! Une nouvelle fois merci ! Derniere version installée et tout y est, excepté le Dashboard qui n’a apparemment pas envie que je sache à quoi il ressemble 😅 Je ferai un petit tour dans les nouvelles fonctionnalités après ma journée. ++ Lien à poster Partager sur d’autres sites
Dominiquesuppo 26 Posté(e) Jeudi à 13:05 Partager Posté(e) Jeudi à 13:05 Il y a 7 heures, Maledikchaouch a dit: Hello ! Une nouvelle fois merci ! Derniere version installée et tout y est, excepté le Dashboard qui n’a apparemment pas envie que je sache à quoi il ressemble 😅 Je ferai un petit tour dans les nouvelles fonctionnalités après ma journée. ++ Salut, C'est curieux, les autres pages fonctionnent je suppose ? Tu peux depuis ton navigateur faire : F12 → onglet "Console" ou "Réseau/Network" puis recharger la page dashboard. Tu verras surement une erreur en rouge, l'endpoint qui plante (ex: GET /api/cultures 500 ou GET /api/stats 404). Un petit screen ou copier coller de tout ça, on en saura plus. Sinon, un petit terminal dans l'appli docker depuis le dossier du projet docker compose logs backend --tail=50 Je présume qu'il y a un terminal, j'ai jamais utilisé docker desktop... A bientôt ! 2 Lien à poster Partager sur d’autres sites
Maledikchaouch 1 251 Posté(e) Jeudi à 16:59 Partager Posté(e) Jeudi à 16:59 Yop, Il y a 3 heures, Dominiquesuppo a dit: C'est curieux, les autres pages fonctionnent je suppose ? Yep, et sans soucis. Depuis la première install, je n'ai pas le Dashboard. Tout viré en début de semaine, y compris Docker pour repartir de zéro, mais topujours la même chose. Je suis plus doué avec un marteau qu'un clavier 😂 Il y a 3 heures, Dominiquesuppo a dit: Sinon, un petit terminal dans l'appli docker depuis le dossier du projet Révélation PS C:\Users\pc\OneDrive\Documents\growmanager-main> docker compose logs backend --tail=50 time="2026-06-04T18:48:00+02:00" level=warning msg="C:\\Users\\pc\\OneDrive\\Documents\\growmanager-main\\docker-compose.yml : the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion" backend-1 | ^^^^^^^^^^^^^^^^^^^^^^^ backend-1 | File "/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/session.py", line 2236, in _execute_internal backend-1 | result: Result[Any] = compile_state_cls.orm_execute_statement( backend-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ backend-1 | File "/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/context.py", line 293, in orm_execute_statement backend-1 | result = conn.execute( backend-1 | ^^^^^^^^^^^^^ backend-1 | File "/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/base.py", line 1418, in execute backend-1 | return meth( backend-1 | ^^^^^ backend-1 | File "/usr/local/lib/python3.11/site-packages/sqlalchemy/sql/elements.py", line 515, in _execute_on_connectio n backend-1 | return connection._execute_clauseelement( backend-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ backend-1 | File "/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/base.py", line 1640, in _execute_clauseelemen t backend-1 | ret = self._execute_context( backend-1 | ^^^^^^^^^^^^^^^^^^^^^^ backend-1 | File "/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/base.py", line 1846, in _execute_context backend-1 | return self._exec_single_context( backend-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ backend-1 | File "/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/base.py", line 1986, in _exec_single_context backend-1 | self._handle_dbapi_exception( backend-1 | File "/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/base.py", line 2353, in _handle_dbapi_excepti on backend-1 | raise sqlalchemy_exception.with_traceback(exc_info[2]) from e backend-1 | File "/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/base.py", line 1967, in _exec_single_context backend-1 | self.dialect.do_execute( backend-1 | File "/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/default.py", line 924, in do_execute backend-1 | cursor.execute(statement, parameters) backend-1 | File "/usr/local/lib/python3.11/site-packages/pymysql/cursors.py", line 153, in execute backend-1 | result = self._query(query) backend-1 | ^^^^^^^^^^^^^^^^^^ backend-1 | File "/usr/local/lib/python3.11/site-packages/pymysql/cursors.py", line 322, in _query backend-1 | conn.query(q) backend-1 | File "/usr/local/lib/python3.11/site-packages/pymysql/connections.py", line 563, in query backend-1 | self._affected_rows = self._read_query_result(unbuffered=unbuffered) backend-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ backend-1 | File "/usr/local/lib/python3.11/site-packages/pymysql/connections.py", line 825, in _read_query_result backend-1 | result.read() backend-1 | File "/usr/local/lib/python3.11/site-packages/pymysql/connections.py", line 1199, in read backend-1 | first_packet = self.connection._read_packet() backend-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ backend-1 | File "/usr/local/lib/python3.11/site-packages/pymysql/connections.py", line 775, in _read_packet backend-1 | packet.raise_for_error() backend-1 | File "/usr/local/lib/python3.11/site-packages/pymysql/protocol.py", line 219, in raise_for_error backend-1 | err.raise_mysql_exception(self._data) backend-1 | File "/usr/local/lib/python3.11/site-packages/pymysql/err.py", line 150, in raise_mysql_exception backend-1 | raise errorclass(errno, errval) backend-1 | sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (1054, "Unknown column 'Stock.substrat_type' in 'field list'") backend-1 | [SQL: SELECT `Stock`.id_stock AS `Stock_id_stock`, `Stock`.id_variete AS `Stock_id_variete`, `Stock`.id_bocal A S `Stock_id_bocal`, `Stock`.id_materiel_bocal AS `Stock_id_materiel_bocal`, `Stock`.id_plant AS `Stock_id_plant`, `Stock`.ty pe_stock AS `Stock_type_stock`, `Stock`.sous_type_stock AS `Stock_sous_type_stock`, `Stock`.lampe_type AS `Stock_lampe_type` , `Stock`.engrais_type AS `Stock_engrais_type`, `Stock`.substrat_type AS `Stock_substrat_type`, `Stock`.maillage AS `Stock_m aillage`, `Stock`.type_hash AS `Stock_type_hash`, `Stock`.type_rosin AS `Stock_type_rosin`, `Stock`.date_stock AS `Stock_dat e_stock`, `Stock`.date_fin_stock AS `Stock_date_fin_stock`, `Stock`.quantite_stock AS `Stock_quantite_stock`, `Stock`.quanti te_initiale AS `Stock_quantite_initiale` backend-1 | FROM `Stock`] backend-1 | (Background on this error at: https://sqlalche.me/e/20/e3q8) What's next: Filter, search, and stream logs from all your Compose services in one place with Docker Desktop's Logs view. docker-desktop://dashboard/logs Je comprends plus de trucs sur un texte en japonais... Merci à mdf et toi pour la tentative de coup de main ! ++ Lien à poster Partager sur d’autres sites
Dominiquesuppo 26 Posté(e) Jeudi à 17:57 Partager Posté(e) Jeudi à 17:57 re il y a 48 minutes, Maledikchaouch a dit: Yop, Yep, et sans soucis. Depuis la première install, je n'ai pas le Dashboard. Tout viré en début de semaine, y compris Docker pour repartir de zéro, mais topujours la même chose. Je suis plus doué avec un marteau qu'un clavier 😂 Masquer le contenu PS C:\Users\pc\OneDrive\Documents\growmanager-main> docker compose logs backend --tail=50 time="2026-06-04T18:48:00+02:00" level=warning msg="C:\\Users\\pc\\OneDrive\\Documents\\growmanager-main\\docker-compose.yml : the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion" backend-1 | ^^^^^^^^^^^^^^^^^^^^^^^ backend-1 | File "/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/session.py", line 2236, in _execute_internal backend-1 | result: Result[Any] = compile_state_cls.orm_execute_statement( backend-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ backend-1 | File "/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/context.py", line 293, in orm_execute_statement backend-1 | result = conn.execute( backend-1 | ^^^^^^^^^^^^^ backend-1 | File "/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/base.py", line 1418, in execute backend-1 | return meth( backend-1 | ^^^^^ backend-1 | File "/usr/local/lib/python3.11/site-packages/sqlalchemy/sql/elements.py", line 515, in _execute_on_connectio n backend-1 | return connection._execute_clauseelement( backend-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ backend-1 | File "/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/base.py", line 1640, in _execute_clauseelemen t backend-1 | ret = self._execute_context( backend-1 | ^^^^^^^^^^^^^^^^^^^^^^ backend-1 | File "/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/base.py", line 1846, in _execute_context backend-1 | return self._exec_single_context( backend-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ backend-1 | File "/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/base.py", line 1986, in _exec_single_context backend-1 | self._handle_dbapi_exception( backend-1 | File "/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/base.py", line 2353, in _handle_dbapi_excepti on backend-1 | raise sqlalchemy_exception.with_traceback(exc_info[2]) from e backend-1 | File "/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/base.py", line 1967, in _exec_single_context backend-1 | self.dialect.do_execute( backend-1 | File "/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/default.py", line 924, in do_execute backend-1 | cursor.execute(statement, parameters) backend-1 | File "/usr/local/lib/python3.11/site-packages/pymysql/cursors.py", line 153, in execute backend-1 | result = self._query(query) backend-1 | ^^^^^^^^^^^^^^^^^^ backend-1 | File "/usr/local/lib/python3.11/site-packages/pymysql/cursors.py", line 322, in _query backend-1 | conn.query(q) backend-1 | File "/usr/local/lib/python3.11/site-packages/pymysql/connections.py", line 563, in query backend-1 | self._affected_rows = self._read_query_result(unbuffered=unbuffered) backend-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ backend-1 | File "/usr/local/lib/python3.11/site-packages/pymysql/connections.py", line 825, in _read_query_result backend-1 | result.read() backend-1 | File "/usr/local/lib/python3.11/site-packages/pymysql/connections.py", line 1199, in read backend-1 | first_packet = self.connection._read_packet() backend-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ backend-1 | File "/usr/local/lib/python3.11/site-packages/pymysql/connections.py", line 775, in _read_packet backend-1 | packet.raise_for_error() backend-1 | File "/usr/local/lib/python3.11/site-packages/pymysql/protocol.py", line 219, in raise_for_error backend-1 | err.raise_mysql_exception(self._data) backend-1 | File "/usr/local/lib/python3.11/site-packages/pymysql/err.py", line 150, in raise_mysql_exception backend-1 | raise errorclass(errno, errval) backend-1 | sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (1054, "Unknown column 'Stock.substrat_type' in 'field list'") backend-1 | [SQL: SELECT `Stock`.id_stock AS `Stock_id_stock`, `Stock`.id_variete AS `Stock_id_variete`, `Stock`.id_bocal A S `Stock_id_bocal`, `Stock`.id_materiel_bocal AS `Stock_id_materiel_bocal`, `Stock`.id_plant AS `Stock_id_plant`, `Stock`.ty pe_stock AS `Stock_type_stock`, `Stock`.sous_type_stock AS `Stock_sous_type_stock`, `Stock`.lampe_type AS `Stock_lampe_type` , `Stock`.engrais_type AS `Stock_engrais_type`, `Stock`.substrat_type AS `Stock_substrat_type`, `Stock`.maillage AS `Stock_m aillage`, `Stock`.type_hash AS `Stock_type_hash`, `Stock`.type_rosin AS `Stock_type_rosin`, `Stock`.date_stock AS `Stock_dat e_stock`, `Stock`.date_fin_stock AS `Stock_date_fin_stock`, `Stock`.quantite_stock AS `Stock_quantite_stock`, `Stock`.quanti te_initiale AS `Stock_quantite_initiale` backend-1 | FROM `Stock`] backend-1 | (Background on this error at: https://sqlalche.me/e/20/e3q8) What's next: Filter, search, and stream logs from all your Compose services in one place with Docker Desktop's Logs view. docker-desktop://dashboard/logs Je comprends plus de trucs sur un texte en japonais... Merci à mdf et toi pour la tentative de coup de main ! ++ Alors, en fait sur le dashboard, il y a une tuile qui affiche les stocks. Il semble qu'il y ait une erreur liée à cette requête. T'as déjà rempli des infos je suppose ? Notamment ce qui est dans ton stock (fleur/rosin/...) ? Ce qui est bizarre c'est qu'il dit que la colonne n'existe pas dans la base de donnée... J'arrive pas à reproduire l'erreur de mon côté. Je pense que ça vient de quelque part par là. Mdf73 pourra surement t'en dire un peu plus. A bientôt. 2 Lien à poster Partager sur d’autres sites
mdf73 1 112 Posté(e) Jeudi à 18:36 Auteur Partager Posté(e) Jeudi à 18:36 Salut les ordinagrowers Un grand merci a toi @Dominiquesuppo pour le support. @Maledikchaouch j'ai creusé un peu plus loin ton soucis et ca m'a permis de decouvrir un petit soucis de syhchro . Du coup pour la faire simple j'ai fait une mise a jour qui corrigera ce soucis pour les prochains utilisateurs donc ca c'est bien. En revanche toi tu as deja créé les bases de données donc il faut que tu tape 2 commandes : docker-compose exec db mysql -u growuser -pgrowpassword growmanager -e "ALTER TABLE Stock ADD COLUMN substrat_type VARCHAR(200) NULL;" Et une fois que ca c'est passé il faut lancer la commande : docker-compose restart backend Si ca marche toujours pas tu lance la commande : docker-compose up --build pour tout reconstruire Au plaisir de te lire (on continue le debugg sur didi si ca te va pour pas trop polluer le fil avec ca! ++ 2 Lien à poster Partager sur d’autres sites
Maledikchaouch 1 251 Posté(e) Jeudi à 21:12 Partager Posté(e) Jeudi à 21:12 Merci à vous deux ! Je teste ça pour le petit déjeuner 👌 @Dominiquesuppo, sur la bases de données, je ne me suis occupé que des génétiques et la création de deux espaces de cultures pour faites des essais sur le fonctionnement. Et deux trois trucs pour les amendements je crois. @mdf73, c’est du chinois mais je tente d’appliquer et reviendrai t’embêter en dm si je n’y arrive pas. Encore merci les gars🫶🫶 ++ Lien à poster Partager sur d’autres sites
Maledikchaouch 1 251 Posté(e) Vendredi à 05:38 Partager Posté(e) Vendredi à 05:38 Re, J'ai le dashboard !!! Merci merci ! ++ 2 Lien à poster Partager sur d’autres sites
mdf73 1 112 Posté(e) hier à 04:27 Auteur Partager Posté(e) hier à 04:27 Hello. Bon c'est pas tout ca mais on a une app a présenter. On enchaine donc avec la partie suivante : 8 - Espaces de culture - Gérez vos boxes et tentes Ce que c'est La page Espaces de culture c'est le registre de tous vos espaces de pousse - tentes, box, armoires, salles dédiées. Chaque espace est configuré une fois et devient ensuite disponible partout dans l'application : pour déclarer une culture, pour le suivi des capteurs, pour le calcul du nombre de pots... Ce qu'on renseigne pour chaque espace Pour chaque espace vous avez : Le nom (Box 1, Tente veg, Salle de fleur...) Les dimensions en cm (largeur, profondeur, hauteur) - la surface en m² se calcule automatiquement Le statut : Actif, Inactif ou Maintenance Le matériel assigné - lampes, ventilation, irrigation - pioché depuis votre inventaire matériel Des notes libres Import / Export Les espaces sont exportables et importables - pratique si vous changez de machine ou si vous voulez partager votre configuration. ++ Lien à poster Partager sur d’autres sites
mdf73 1 112 Posté(e) hier à 04:33 Auteur Partager Posté(e) hier à 04:33 9 - Le Matériel - Votre inventaire d'équipements Ce que c'est La page Matériel c'est le registre de tout ce que vous avez acheté pour cultiver - lampes, ventilation, irrigation, pots, presses, sacs de filtration... Chaque pièce de matériel est référencée avec sa date d'achat, son prix et ses caractéristiques. Utile pour suivre l'âge de vos équipements et avoir une idée du capital investi. Deux vues disponibles Vue groupée par catégorie La vue par défaut - le matériel est regroupé par type : Lampes, Ventilation, Irrigation, Pots, etc. Pratique pour avoir une vue d'ensemble rapide de ce que vous avez dans chaque catégorie. Vue liste Toutes les pièces de matériel dans un seul tableau trié et filtrable. Les colonnes sont cliquables pour trier : numéro, nom, marque, code ou numéro de série, date d'achat, prix, âge, état. Pratique quand vous cherchez une pièce précise ou que vous voulez voir tout trié par date d'achat ou par prix. Ajouter un équipement Pour chaque pièce de matériel vous renseignez : Le nom et la marque La catégorie (depuis la liste configurée dans le Paramétrage) Le code ou numéro de série si vous l'avez La date d'achat et le prix L'état : Neuf, Bon état, Usé, Hors service Les caractéristiques libres - puissance pour une lampe, débit pour une pompe, volume pour un pot... L'âge se calcule automatiquement à partir de la date d'achat. Le lien avec les Espaces de culture Le matériel référencé ici est ensuite assignable à vos espaces de culture - vous pouvez indiquer quelle lampe tourne dans quelle box, quel système d'irrigation est branché où. Ça permet aussi de calculer les grammes par watt sur vos récoltes. Gestion des vaporisateurs Un page de gestion des vaporisateurs est également présente et sera utile lorsque le module de gestion de la consommation sera finalisé. ++ Lien à poster Partager sur d’autres sites
mdf73 1 112 Posté(e) hier à 04:42 Auteur Partager Posté(e) hier à 04:42 11 - Les Statistiques - Vue globale sur votre activité Ce que c'est La page Statistiques c'est la vue macro sur tout ce que vous avez fait depuis que vous utilisez GrowManager. Valeur de votre stock de graines, coûts de culture, production par variété, rendements... Plus vous cultivez et enregistrez, plus cette page devient intéressante. Valeur du stock de graines Un aperçu de la valeur totale de vos graines en stock, calculée à partir des prix d'achat renseignés dans vos packs. Utile pour avoir une idée de ce que représente votre génothèque en termes d'investissement. Coûts de culture La section que j'utilise le plus pour progresser. Elle affiche six indicateurs calculés sur l'ensemble de vos cultures clôturées : Coût total moyen, maximum et minimum par culture Coût par gramme moyen, maximum et minimum Ces chiffres sont calculés à la clôture de chaque culture et permettent de voir concrètement si vous optimisez vos coûts d'une culture à l'autre - engrais, substrat, électricité... Cette section n'apparaît que si vous avez des cultures clôturées avec des données de coût renseignées. Tendances d'extractions L'évolution de votre production dans le temps - quantités récoltées par extractions, ratio moyen, .... La page Statistiques se nourrit de toutes les autres pages de l'application - plus vous renseignez vos actions, vos coûts et vos récoltes, plus les stats sont précises et utiles. ++ 1 Lien à poster Partager sur d’autres sites
mdf73 1 112 Posté(e) hier à 04:51 Auteur Partager Posté(e) hier à 04:51 (modifié) 12 - Le Paramétrage - Configurez l'application à votre façon Ce que c'est La page Paramétrage c'est le panneau de configuration de GrowManager. C'est ici que vous personnalisez toutes les listes déroulantes de l'application - les types de pots, les matières, les catégories de matériel, les types de bocaux... Et c'est aussi ici que vous configurez vos capteurs Govee. C'est une page qu'on visite surtout au début, pour tout mettre à son goût, et de temps en temps quand on veut ajouter une nouvelle option quelque part. Les listes configurables Toutes les listes déroulantes de l'application sont gérées ici. Parmi les listes disponibles : Types et matières de pots Catégories de matériel Types de bocaux Types de substrats Types d'extractions Et d'autres encore... Pour chaque liste vous pouvez ajouter, modifier ou supprimer des valeurs. Si vous utilisez un type de pot ou un bocal qui n'est pas dans la liste par défaut, c'est ici que vous l'ajoutez - il sera ensuite disponible partout dans l'application. L'application est livrée avec des valeurs par défaut pour toutes ces listes, donc ça tourne directement à l'installation sans avoir à tout configurer. Configuration des capteurs Govee (et ESPHome) C'est aussi dans le Paramétrage que vous ajoutez vos capteurs Govee. Vous renseignez l'adresse MAC du capteur et son nom - l'application commence ensuite à le poller automatiquement en arrière-plan pour récupérer les relevés de température et d'humidité. Une fois configuré, le capteur apparaît dans le Dashboard et dans la page Suivi des constantes. Il est également possible de configurer ici l'offset foliaire. C'est la température qui sera prise en compte pour le calcul du VPD. Pour etre au plus proche de la vérité, le VPD doit etre calculé depuis la température des feuilles et non celle de l'air ambiant. Pour ce faire il suffit de définir cet offset qui est en moyenne de 2°c (ecart entre temp de l'air et des feuilles) Sauvegarde et restauration Depuis cette page il est possible de sauvegarder la base de donnée SQL complete ou de l'importer depuis une sauvegarde deja réalisée L'alerte Stock Paramétrez ici les seuils d'alertes de stocks bas en fonction du type de stock Je reviens vite pour terminer les 2 dernieres grosse parties : La gestion de la culture et le paramétrage des substrats. A tout vite Modifié hier à 04:53 par mdf73 1 Lien à poster Partager sur d’autres sites
Messages recommandés