|
|
|
|
@@ -33,53 +33,96 @@ log() {
|
|
|
|
|
echo "[$timestamp] $message" | tee -a "$LOG_FILE"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
test_ha_connection() {
|
|
|
|
|
# Test Home Assistant connectivity at startup
|
|
|
|
|
log "Testing Home Assistant connection..."
|
|
|
|
|
local http_code=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $HA_TOKEN" "$HA_URL/api/" 2>/dev/null)
|
|
|
|
|
|
|
|
|
|
if [[ "$http_code" == "200" ]]; then
|
|
|
|
|
log "Home Assistant API connection successful"
|
|
|
|
|
return 0
|
|
|
|
|
else
|
|
|
|
|
log "ERROR: Home Assistant API returned HTTP $http_code"
|
|
|
|
|
return 1
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
check_target() {
|
|
|
|
|
# Use curl to get HTTP response code without following redirects
|
|
|
|
|
local response_code=$(curl -s -o /dev/null -w "%{http_code}" -m 5 "$TARGET_URL" 2>/dev/null)
|
|
|
|
|
echo "$response_code"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
trigger_power_cycle() {
|
|
|
|
|
get_entity_domain() {
|
|
|
|
|
# Extract domain from entity_id (e.g., "switch" from "switch.device_name")
|
|
|
|
|
local entity="$1"
|
|
|
|
|
|
|
|
|
|
log "ALERT: Triggering power cycle for entity: $entity"
|
|
|
|
|
|
|
|
|
|
# Turn off
|
|
|
|
|
log "Sending turn_off request to Home Assistant..."
|
|
|
|
|
curl -s -X POST \
|
|
|
|
|
-H "Authorization: Bearer $HA_TOKEN" \
|
|
|
|
|
-H "Content-Type: application/json" \
|
|
|
|
|
-d "{\"entity_id\": \"$entity\"}" \
|
|
|
|
|
"$HA_URL/api/services/switch/turn_off" > /dev/null 2>&1
|
|
|
|
|
|
|
|
|
|
if [[ $? -eq 0 ]]; then
|
|
|
|
|
log "Turn off request sent successfully"
|
|
|
|
|
else
|
|
|
|
|
log "ERROR: Failed to send turn_off request"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Wait 10 seconds
|
|
|
|
|
log "Waiting 10 seconds before power-on..."
|
|
|
|
|
sleep 10
|
|
|
|
|
|
|
|
|
|
# Turn on
|
|
|
|
|
log "Sending turn_on request to Home Assistant..."
|
|
|
|
|
curl -s -X POST \
|
|
|
|
|
-H "Authorization: Bearer $HA_TOKEN" \
|
|
|
|
|
-H "Content-Type: application/json" \
|
|
|
|
|
-d "{\"entity_id\": \"$entity\"}" \
|
|
|
|
|
"$HA_URL/api/services/switch/turn_on" > /dev/null 2>&1
|
|
|
|
|
|
|
|
|
|
if [[ $? -eq 0 ]]; then
|
|
|
|
|
log "Turn on request sent successfully"
|
|
|
|
|
log "Power cycle completed for $entity"
|
|
|
|
|
else
|
|
|
|
|
log "ERROR: Failed to send turn_on request"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Reset state
|
|
|
|
|
ERROR_START_TIME=""
|
|
|
|
|
IN_GRACE_PERIOD=false
|
|
|
|
|
echo "${entity%%.*}"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get_toggle_service() {
|
|
|
|
|
# Determine correct service based on entity domain
|
|
|
|
|
local domain="$1"
|
|
|
|
|
case "$domain" in
|
|
|
|
|
switch) echo "switch/turn_off" ;;
|
|
|
|
|
light) echo "light/turn_off" ;;
|
|
|
|
|
*) echo "switch/turn_off" ;; # Default fallback
|
|
|
|
|
esac
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
trigger_power_cycle() {
|
|
|
|
|
local entity="$1"
|
|
|
|
|
local domain=$(get_entity_domain "$entity")
|
|
|
|
|
local turn_off_service=$(get_toggle_service "$domain")
|
|
|
|
|
local turn_on_service="${turn_off_service%/*}/turn_on"
|
|
|
|
|
|
|
|
|
|
log "ALERT: Triggering power cycle for entity: $entity (domain: $domain)"
|
|
|
|
|
|
|
|
|
|
# Turn off
|
|
|
|
|
log "Sending turn_off request to Home Assistant ($turn_off_service)..."
|
|
|
|
|
log "DEBUG: POST to $HA_URL/api/services/$turn_off_service with entity_id=$entity"
|
|
|
|
|
local response=$(curl -s -w "\n%{http_code}" -X POST \
|
|
|
|
|
-H "Authorization: Bearer $HA_TOKEN" \
|
|
|
|
|
-H "Content-Type: application/json" \
|
|
|
|
|
-d "{\"entity_id\": \"$entity\"}" \
|
|
|
|
|
"$HA_URL/api/services/$turn_off_service" 2>&1)
|
|
|
|
|
|
|
|
|
|
local http_code=$(echo "$response" | tail -n 1)
|
|
|
|
|
local body=$(echo "$response" | head -n -1)
|
|
|
|
|
|
|
|
|
|
if [[ "$http_code" =~ ^[2][0-9]{2}$ ]]; then
|
|
|
|
|
log "Turn off request sent successfully (HTTP $http_code)"
|
|
|
|
|
else
|
|
|
|
|
log "ERROR: Failed to send turn_off request (HTTP $http_code)"
|
|
|
|
|
log "ERROR: Response body: $body"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Wait 10 seconds
|
|
|
|
|
log "Waiting 10 seconds before power-on..."
|
|
|
|
|
sleep 10
|
|
|
|
|
|
|
|
|
|
# Turn on
|
|
|
|
|
log "Sending turn_on request to Home Assistant ($turn_on_service)..."
|
|
|
|
|
log "DEBUG: POST to $HA_URL/api/services/$turn_on_service with entity_id=$entity"
|
|
|
|
|
local response=$(curl -s -w "\n%{http_code}" -X POST \
|
|
|
|
|
-H "Authorization: Bearer $HA_TOKEN" \
|
|
|
|
|
-H "Content-Type: application/json" \
|
|
|
|
|
-d "{\"entity_id\": \"$entity\"}" \
|
|
|
|
|
"$HA_URL/api/services/$turn_on_service" 2>&1)
|
|
|
|
|
|
|
|
|
|
local http_code=$(echo "$response" | tail -n 1)
|
|
|
|
|
local body=$(echo "$response" | head -n -1)
|
|
|
|
|
|
|
|
|
|
if [[ "$http_code" =~ ^[2][0-9]{2}$ ]]; then
|
|
|
|
|
log "Turn on request sent successfully (HTTP $http_code)"
|
|
|
|
|
log "Power cycle completed for $entity"
|
|
|
|
|
else
|
|
|
|
|
log "ERROR: Failed to send turn_on request (HTTP $http_code)"
|
|
|
|
|
log "ERROR: Response body: $body"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Reset state
|
|
|
|
|
ERROR_START_TIME=""
|
|
|
|
|
IN_GRACE_PERIOD=false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
log "=== Thinkcentre Monitor Started ==="
|
|
|
|
|
@@ -90,6 +133,12 @@ log " HA_ENTITY: $HA_ENTITY"
|
|
|
|
|
log " GRACE_PERIOD: ${GRACE_PERIOD}s ($(( GRACE_PERIOD / 60 )) minutes)"
|
|
|
|
|
log " CHECK_INTERVAL: ${CHECK_INTERVAL}s"
|
|
|
|
|
|
|
|
|
|
# Test HA connection before entering main loop
|
|
|
|
|
if ! test_ha_connection; then
|
|
|
|
|
log "FATAL: Cannot connect to Home Assistant. Exiting."
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Main monitoring loop
|
|
|
|
|
while true; do
|
|
|
|
|
RESPONSE_CODE=$(check_target)
|
|
|
|
|
@@ -104,7 +153,7 @@ while true; do
|
|
|
|
|
# First 502 error - start grace period
|
|
|
|
|
ERROR_START_TIME=$(date +%s)
|
|
|
|
|
IN_GRACE_PERIOD=true
|
|
|
|
|
log "502 error detected - starting 5-minute grace period (recovery window for deployment scenarios)"
|
|
|
|
|
log "502 error detected - starting $(( GRACE_PERIOD / 60 ))- minute grace period (recovery window for deployment scenarios)"
|
|
|
|
|
else
|
|
|
|
|
# Already in grace period - check if it has expired
|
|
|
|
|
CURRENT_TIME=$(date +%s)
|
|
|
|
|
|