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.
#!/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
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.