Superviser un capteur Shelly BLU Door Window avec Centreon

Superviser un capteur Shelly BLU Door Window avec Centreon

La domotique connectée prend de plus en plus d’importance, et les capteurs sans fil comme le Shelly BLU Door Window offrent une solution simple pour surveiller l’ouverture de portes et fenêtres. Mais qu’en est-il de leur intégration dans une solution de supervision comme Centreon ? Dans cet article, nous allons découvrir un script Bash conçu pour interroger l’API Cloud de Shelly et récupérer en temps réel les informations clés d’un capteur.

Étape 1 : Paramètres et options du script

Le script accepte plusieurs options :

./check_shelly_blu.sh --device-id <ID> --auth-key <AUTH_KEY> --metric <METRIC> [-w <warning>] [-c <critical>]
  • --device-id : identifiant unique du capteur (ex. XB1371929066...)

  • --auth-key : clé d’authentification fournie par Shelly Cloud

  • --metric : métrique à superviser (status, battery, tilt, illuminance, online, fwversion, last_update, ou all).

Étape 2 : Connexion à l’API Cloud Shelly

Le script interroge l’API via curl pour récupérer les données du capteur au format JSON. L’utilisation de jq permet d’extraire les valeurs recherchées (niveau de batterie, état de la fenêtre, luminosité, etc.). En cas de problème de connexion ou de réponse vide, un état CRITICAL est immédiatement renvoyé. Il vous faurdra créer une clé API depuis l'interface Shelly Cloud si ce n'est pas déjà fait.

Étape 3 : Gestion des seuils et alertes

Certaines métriques utilisées pour la supervision Centreon, comme la batterie ou la température, peuvent être surveillées avec des seuils personnalisés (-w pour warning, -c pour critical).

  • Exemple : --metric battery -w 30 -c 15 alerte si la batterie passe sous 30 % (warning) et critique sous 15 %.

  • Pour la luminosité, l’inclinaison ou l’état d’ouverture, le script retourne des messages clairs au format attendu par Centreon/Nagios.

Étape 4 : Supervision complète avec all

L’option --metric all permet d’afficher en une seule exécution :

  • l’état de la porte/fenêtre (ouverte/fermée),

  • le niveau de batterie,

  • l’angle d’inclinaison,

  • la luminosité,

  • l’état de connexion (en ligne/hors ligne),

  • la version firmware,

  • et l’heure du dernier réveil.

Exemple d’utilisation

 
./check_shelly_blu.sh --device-id "XXXXX" --auth-key "YYYYY" --metric all 

Contenu du script :

Voici le script en question :

#!/bin/bash

# Script Centreon pour Shelly BLU Door Window
# Récupération des infos de puis l'API cloud de Shelly
# Mesures : status (ouvert/fermé), batterie, inclinaison, luminosité, en ligne

usage() {
  echo "Usage: $0 --device-id <ID> --auth-key <AUTH_KEY> --metric <METRIC> [-w <warning>] [-c <critical>]"
  echo "  METRIC: status | battery | tilt | illuminance | online | fwversion | last_update | all"
  exit 3
}

debug_log() {
  echo "$@" >> /tmp/check_bluedoor_debug.log
}

compare_float() {
  local val1=$1
  local op=$2
  local val2=$3
  if [[ "$op" == ">" ]]; then
    if (( $(echo "$val1 > $val2" | bc -l) )); then
      return 0
    fi
  elif [[ "$op" == "<" ]]; then
    if (( $(echo "$val1 < $val2" | bc -l) )); then
      return 0
    fi
  elif [[ "$op" == "==" ]]; then
    if (( $(echo "$val1 == $val2" | bc -l) )); then
      return 0
    fi
  fi
  return 1
}

check_thresholds() {
  local value=$1
  local warning=$2
  local critical=$3
  local metric=$4
  debug_log "===== DEBUG CHECK_THRESHOLDS ====="
  debug_log "Métrique: $metric"
  debug_log "Valeur: $value"
  debug_log "Seuil Warning: $warning"
  debug_log "Seuil Critical: $critical"
  # Pour la batterie, on alerte si valeur INFERIEURE au seuil
  if [[ "$metric" == "battery" ]]; then
    debug_log "Mode batterie: alerte si < seuil"
    if [[ -n "$critical" ]]; then
      compare_float "$value" "<" "$critical"
      if [[ $? -eq 0 ]]; then
        debug_log "CRITICAL - Batterie $value < seuil critique $critical"
        return 2
      fi
    fi
    if [[ -n "$warning" ]]; then
      compare_float "$value" "<" "$warning"
      if [[ $? -eq 0 ]]; then
        debug_log "WARNING - Batterie $value < seuil warning $warning"
        return 1
      fi
    fi
  # Pour la température, on alerte si valeur > seuil
  elif [[ "$metric" == "temperature" ]]; then
    debug_log "Mode température: alerte si > seuil"
    if [[ -n "$critical" ]]; then
      compare_float "$value" ">" "$critical"
      if [[ $? -eq 0 ]]; then
        debug_log "CRITICAL - Température $value > seuil critique $critical"
        return 2
      fi
    fi
    if [[ -n "$warning" ]]; then
      compare_float "$value" ">" "$warning"
      if [[ $? -eq 0 ]]; then
        debug_log "WARNING - Température $value > seuil warning $warning"
        return 1
      fi
    fi
  fi
  debug_log "Status final: OK"
  return 0
}

# Valeurs par défaut (à adapter)
DEFAULT_DEVICE_ID="ID_DE_LA_DEVICE" 
DEFAULT_AUTH_KEY="CLE_API_CLOUD_SHELLY"

DEVICE_ID=""
AUTH_KEY=""
METRIC=""
WARNING=""
CRITICAL=""
MODE_TEST=0

while [[ $# -gt 0 ]]; do
  case $1 in
    --device-id) DEVICE_ID="$2"; shift 2 ;;
    --auth-key) AUTH_KEY="$2"; shift 2 ;;
    --metric) METRIC="$2"; shift 2 ;;
    -w|--warning) WARNING="$2"; shift 2 ;;
    -c|--critical) CRITICAL="$2"; shift 2 ;;
    --test) MODE_TEST=1; shift ;;
    *) usage ;;
  esac
done

if [[ $MODE_TEST -eq 1 ]]; then
  cat <<EOF
{
  "status": {
    "window:0": {
      "open": true
    },
    "devicepower:0": {
      "battery": { "percent": 87 }
    },
    "tilt:0": {
      "angle": 30
    },
    "illuminance:0": {
      "lux": 150
    }
  },
  "settings": {}
}
EOF
  exit 0
fi

# Appliquer les valeurs par défaut si non définies
: "${DEVICE_ID:=$DEFAULT_DEVICE_ID}"
: "${AUTH_KEY:=$DEFAULT_AUTH_KEY}"

[[ -z "$DEVICE_ID" || -z "$AUTH_KEY" || -z "$METRIC" ]] && usage

RESPONSE=$(curl -s -X POST \
  "https://shelly-180-eu.shelly.cloud/v2/devices/api/get?auth_key=${AUTH_KEY}" \
  -H "Content-Type: application/json" \
  -d "{\"ids\": [\"${DEVICE_ID}\"], \"select\": [\"status\",\"settings\"]}")

if [[ $? -ne 0 || -z "$RESPONSE" ]]; then
  echo "CRITICAL - Erreur API REST"
  exit 2
fi

DATA=$(echo "$RESPONSE" | jq '.[0]')

case $METRIC in
  status)
    OPEN=$(echo "$DATA" | jq -r '.status["window:0"].open // empty')
    if [[ "$OPEN" == "true" ]]; then
      echo "WARNING - Porte/Fenêtre OUVERTE | status=1"
      exit 1
    else
      echo "OK - Porte/Fenêtre FERMÉE | status=0"
      exit 0
    fi
    ;;
  battery)
    VALUE=$(echo "$DATA" | jq -r '.status["devicepower:0"].battery.percent // empty')
    [[ -z "$VALUE" ]] && echo "CRITICAL - Batterie non disponible" && exit 2
    debug_log "===== AVANT CHECK BATTERIE ====="
    debug_log "Valeur batterie: $VALUE"
    debug_log "Warning: $WARNING"
    debug_log "Critical: $CRITICAL"
    check_thresholds "$VALUE" "$WARNING" "$CRITICAL" "battery"; STATUS=$?
    debug_log "Status après check: $STATUS"
    if [[ $STATUS -eq 0 ]]; then
      echo "OK - Batterie = ${VALUE}% | battery=${VALUE}%"
    elif [[ $STATUS -eq 1 ]]; then
      echo "WARNING - Batterie = ${VALUE}% | battery=${VALUE}%"
    else
      echo "CRITICAL - Batterie = ${VALUE}% | battery=${VALUE}%"
    fi
    exit $STATUS
    ;;
  tilt)
    ANGLE=$(echo "$DATA" | jq -r '.status["tilt:0"].angle // empty')
    [[ -z "$ANGLE" ]] && echo "CRITICAL - Inclinaison non disponible" && exit 2
    echo "OK - Angle d'inclinaison = ${ANGLE}° | tilt=${ANGLE}"
    exit 0
    ;;
  illuminance)
    LUX=$(echo "$DATA" | jq -r '.status["illuminance:0"].lux // empty')
    [[ -z "$LUX" ]] && echo "CRITICAL - Luminosité non disponible" && exit 2
    echo "OK - Luminosité = ${LUX} lux | illuminance=${LUX}"
    exit 0
    ;;
  online)
    ONLINE=$(echo "$DATA" | jq -r '.online // empty')
    if [[ "$ONLINE" == "1" ]]; then
      echo "OK - Capteur en ligne | online=1"
      exit 0
    else
      echo "CRITICAL - Capteur hors ligne | online=0"
      exit 2
    fi
    ;;
  fwversion)
    FW=$(echo "$DATA" | jq -r '.status["fwversion:0"].version // empty')
    [[ -z "$FW" ]] && echo "CRITICAL - Version firmware non disponible" && exit 2
    echo "OK - Firmware version = $FW | fwversion=$FW"
    exit 0
    ;;
  last_update)
    UPDATED=$(echo "$DATA" | jq -r '.status._updated // empty')
    [[ -z "$UPDATED" ]] && echo "CRITICAL - Date/heure de réveil non disponible" && exit 2
    # Conversion UTC -> Europe/Paris
    LOCAL_DATE=$(TZ='Europe/Paris' date -d "$UPDATED UTC" '+%d/%m/%Y %H:%M:%S' 2>/dev/null)
    if [[ -z "$LOCAL_DATE" ]]; then
      LOCAL_DATE="$UPDATED"
    fi
    echo "OK - Dernier réveil : $LOCAL_DATE"
    exit 0
    ;;
  all)
    # Affichage groupé de tous les métriques principaux
    OPEN=$(echo "$DATA" | jq -r '.status["window:0"].open // empty')
    BATTERY=$(echo "$DATA" | jq -r '.status["devicepower:0"].battery.percent // empty')
    ANGLE=$(echo "$DATA" | jq -r '.status["tilt:0"].angle // empty')
    LUX=$(echo "$DATA" | jq -r '.status["illuminance:0"].lux // empty')
    ONLINE=$(echo "$DATA" | jq -r '.online // empty')
    FW=$(echo "$DATA" | jq -r '.status["fwversion:0"].version // empty')
    UPDATED=$(echo "$DATA" | jq -r '.status._updated // empty')
    LOCAL_DATE=$(TZ='Europe/Paris' date -d "$UPDATED UTC" '+%d/%m/%Y %H:%M:%S' 2>/dev/null)
    if [[ -z "$LOCAL_DATE" ]]; then
      LOCAL_DATE="$UPDATED"
    fi
    STATUS_MSG=""
    [[ "$OPEN" == "true" ]] && STATUS_MSG="OUVERTE" || STATUS_MSG="FERMÉE"
    echo "Etat : $STATUS_MSG - Batterie : ${BATTERY}% - Inclinaison : ${ANGLE}° - Luminosité : ${LUX} lux - Online: $ONLINE - Firmware : $FW - Dernier réveil : $LOCAL_DATE | status=$OPEN battery=${BATTERY}% tilt=${ANGLE} illuminance=${LUX} online=${ONLINE} fwversion=$FW"
    exit 0
    ;;
  *)
    echo "UNKNOWN - Métrique inconnue"
    exit 3
    ;;
esac

Conclusion

Ce script fournit un moyen efficace d’intégrer un capteur Shelly BLU Door Window dans une supervision professionnelle. Grâce à lui, il devient possible de suivre l’état des ouvertures, la santé de la batterie et la connectivité, directement depuis Centreon, et d’être alerté en cas d’anomalie.

Partager cet article :

Articles récents

Configurer un serveur OpenVPN sur un EdgeRouterX Ubiquiti
Configurer un serveur OpenVPN sur un EdgeRouterX Ubiquiti

18 June 2026

Vous avez un EdgeRouter Ubiquiti (EdgeOS) et vous voulez pouvoir accéder à votre réseau local depuis l'extrérieur, en toute sécurité; ? Dans ce tuto, on monte p...

Lire la suite
Pourquoi depuis fin 2025 vos mails Free ne fonctionnent plus dans Outlook ?
Pourquoi depuis fin 2025 vos mails Free ne fonctionnent plus dans Outlook ?

16 June 2026

&nbsp; Depuis fin 2025, de nombreux utilisateurs Free constatent un probl&egrave;me identique : leurs mails fonctionnent parfaitement sur le webmail Free ou depuis un smartphone, mais le client Outlo...

Lire la suite
Exposer un VirtualHost local en permanence avec ngrok
Exposer un VirtualHost local en permanence avec ngrok

12 June 2026

Configurer un service autonome pour ngrok sur un serveur Linux

Lire la suite