#!/bin/sh # Garde du releve des cellules sur le Synology .17 (ARCHIVE3). A LANCER EN ROOT, # toutes les 5 minutes (timer systemd evcs-releve-port.timer, voir README). # # Deux defauts qu'elle corrige, tous deux vus le 25/09/2026 : # 1. Un rebranchement recree le port accessible a root seul : le conteneur # (uid 1026) meurt (« EIO: i/o error ») et ne repart pas. # 2. Le NUMERO du port change : rebranche pendant que le conteneur tenait # ttyUSB0 ouvert, le cable est revenu en ttyUSB1. Le conteneur pointait # alors vers un port qui n'existait plus. # D'ou un nom stable, /dev/pylontech-pack2, choisi d'apres le numero de SERIE # du cable (jamais d'apres l'ordre d'enumeration), que le conteneur utilise. # # Ne fait RIEN quand tout va bien ; n'ecrit dans le journal systeme (tag # evcs-releve) que lorsqu'il agit. Idempotent. # Numero de serie du cable FTDI -> nom stable. Un 2e cable (pack 1, US5000) # s'ajoutera ici, avec son propre service dans compose.yaml. CABLES="A78KC4LE:pylontech-pack2" CONTENEUR=evcs-releve-cellules DOCKER=/usr/local/bin/docker DIR=$(cd "$(dirname "$0")" && pwd) ETAT=/run/evcs-releve-port.cible dire() { logger -t evcs-releve "$*"; echo "$*"; } # Pilotes decharges (ne devrait arriver qu'apres une MAJ DSM) : on les recharge. if ! /sbin/lsmod | grep -q "^ftdi_sio "; then dire "ftdi_sio absent : rechargement des pilotes" /bin/sh "$DIR/charger-pilotes.sh" >/dev/null 2>&1 fi # Numero de serie du peripherique USB qui porte un ttyUSBn. serie_de() { cat "$(dirname "$(dirname "$(readlink -f "/sys/bus/usb-serial/devices/$1")")")/serial" 2>/dev/null; } cible="" for entree in $CABLES; do sn=${entree%%:*}; nom=${entree#*:} tty="" for t in /sys/bus/usb-serial/devices/ttyUSB*; do [ -e "$t" ] || continue n=$(basename "$t") [ "$(serie_de "$n")" = "$sn" ] && tty=$n done if [ -z "$tty" ]; then rm -f "/dev/$nom" # cable absent : pas de lien qui pointe dans le vide continue fi if [ "$(readlink "/dev/$nom")" != "/dev/$tty" ]; then ln -sf "/dev/$tty" "/dev/$nom" dire "/dev/$nom -> /dev/$tty (cable $sn)" fi if [ "$(stat -c %a "/dev/$tty")" != "666" ]; then chmod 666 "/dev/$tty" dire "droits de /dev/$tty rouverts (cable rebranche ?)" fi [ "$nom" = pylontech-pack2 ] && cible=$tty done # Cable debranche : le conteneur ne peut pas tourner sans son port. On attend. [ -n "$cible" ] || exit 0 # Le port a change de numero depuis la derniere creation du conteneur : il faut # le RECREER (Docker resout le lien a la creation). Sinon, simple relance s'il # est arrete. if [ "$(cat "$ETAT" 2>/dev/null)" != "$cible" ]; then (cd "$DIR" && "$DOCKER" compose up -d --force-recreate >/dev/null 2>&1) \ && { echo "$cible" > "$ETAT"; dire "$CONTENEUR recree sur /dev/$cible"; } \ || dire "$CONTENEUR : echec de la recreation" exit 0 fi if [ "$("$DOCKER" inspect -f '{{.State.Running}}' "$CONTENEUR" 2>/dev/null)" != "true" ]; then "$DOCKER" start "$CONTENEUR" >/dev/null 2>&1 \ && dire "$CONTENEUR relance" \ || dire "$CONTENEUR : echec de la relance" fi