131 lines
4.6 KiB
Bash
Executable File
131 lines
4.6 KiB
Bash
Executable File
#!/bin/bash
|
||
# Экспорт данных по теплице из Home Assistant за указанный период (через curl + jq)
|
||
|
||
set -euo pipefail
|
||
|
||
# ============ НАСТРОЙКИ ============
|
||
HA_URL="https://ha.homenet542.keenetic.pro"
|
||
TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmOTkyNzMxNmNlZTI0MjYzOWU4NjRhMGZlOGI2OTExZSIsImlhdCI6MTc3NTIzOTM1OCwiZXhwIjoyMDkwNTk5MzU4fQ.eumM2Vhk68uZZTvA4uIjKDqzlwBPKhBV6JeVRmSAJos"
|
||
DAYS=7
|
||
ENTITIES=(
|
||
"sensor.ulitsa_teplitsa_klimat_temperature"
|
||
"sensor.ulitsa_teplitsa_klimat_humidity"
|
||
"switch.ulitsa_teplitsa_vytiazhka"
|
||
"switch.ulitsa_teplitsa_obogrev"
|
||
"sun.sun"
|
||
)
|
||
OUTPUT_FILE="/home/node/.openclaw/workspace/teplitsa_export.json"
|
||
# ====================================
|
||
|
||
if ! command -v jq >/dev/null 2>&1; then
|
||
echo "❌ jq не найден. Установи: apt-get install -y jq"
|
||
exit 1
|
||
fi
|
||
if ! command -v curl >/dev/null 2>&1; then
|
||
echo "❌ curl не найден"
|
||
exit 1
|
||
fi
|
||
|
||
START_ISO=$(date -u -d "$DAYS days ago" +"%Y-%m-%dT%H:%M:%S+00:00" 2>/dev/null || date -u -v-${DAYS}d +"%Y-%m-%dT%H:%M:%S+00:00" 2>/dev/null || echo "")
|
||
if [ -z "$START_ISO" ]; then
|
||
# Fallback: python для даты
|
||
START_ISO=$(python3 -c "
|
||
from datetime import datetime, timedelta, timezone
|
||
print((datetime.now(timezone.utc) - timedelta(days=$DAYS)).isoformat())
|
||
" )
|
||
fi
|
||
|
||
echo "📊 Сбор данных за $DAYS дней с ${START_ISO:0:10}..."
|
||
|
||
# История
|
||
ENTITIES_CSV=$(IFS=,; echo "${ENTITIES[*]}")
|
||
HISTORY=$(curl -sS -H "Authorization: Bearer $TOKEN" \
|
||
"$HA_URL/api/history/period/$START_ISO?filter_entity_id=$ENTITIES_CSV&minimal_response=true" \
|
||
| jq 'map(map(select(.state != "unavailable" and .state != "unknown" and .state != null)))')
|
||
|
||
TOTAL=$(echo "$HISTORY" | jq '[.[] | length] | add')
|
||
COUNT=$(echo "$HISTORY" | jq 'length')
|
||
echo "✅ История: $TOTAL записей по $COUNT сущностям"
|
||
|
||
# Логбук
|
||
LOGBOOK=$(curl -sS -H "Authorization: Bearer $TOKEN" \
|
||
"$HA_URL/api/logbook/$START_ISO" \
|
||
| jq --argjson ents "$(printf '%s\n' "${ENTITIES[@]}" | jq -R . | jq -s .)" '
|
||
map(select(
|
||
(.entity_id as $eid | $ents | index($eid)) != null
|
||
or (.name // "" | ascii_downcase | contains("теплиц"))
|
||
))
|
||
')
|
||
|
||
LOGBOOK_COUNT=$(echo "$LOGBOOK" | jq 'length')
|
||
echo "✅ Логбук: $LOGBOOK_COUNT релевантных событий"
|
||
|
||
# Текущие состояния
|
||
STATES_JSON="[]"
|
||
for eid in "${ENTITIES[@]}"; do
|
||
STATE=$(curl -sS -H "Authorization: Bearer $TOKEN" "$HA_URL/api/states/$eid" || true)
|
||
if echo "$STATE" | jq -e '.entity_id' >/dev/null 2>&1; then
|
||
STATES_JSON=$(echo "$STATES_JSON" | jq --argjson s "$STATE" '. + [$s]')
|
||
else
|
||
echo "⚠️ Не удалось получить $eid"
|
||
fi
|
||
done
|
||
|
||
# Собираем результат
|
||
jq -n \
|
||
--arg exported_at "$(date -Iseconds)" \
|
||
--argjson days "$DAYS" \
|
||
--argjson entities "$(printf '%s\n' "${ENTITIES[@]}" | jq -R . | jq -s .)" \
|
||
--argjson states "$STATES_JSON" \
|
||
--argjson history "$HISTORY" \
|
||
--argjson logbook "$LOGBOOK" '
|
||
{
|
||
exported_at: $exported_at,
|
||
period_days: $days,
|
||
entities: $entities,
|
||
current_states: $states,
|
||
history: $history,
|
||
logbook: $logbook
|
||
}' > "$OUTPUT_FILE"
|
||
|
||
echo ""
|
||
echo "💾 Сохранено: $OUTPUT_FILE"
|
||
echo ""
|
||
echo "=================================================="
|
||
echo "📈 КРАТКАЯ СВОДКА"
|
||
echo "=================================================="
|
||
|
||
for eid in "${ENTITIES[@]}"; do
|
||
if [[ $eid == sensor.* ]]; then
|
||
VALUES=$(echo "$HISTORY" | jq -r --arg eid "$eid" '
|
||
.[] | select(.[0].entity_id == $eid) | .[].state | tonumber
|
||
' 2>/dev/null || true)
|
||
if [ -n "$VALUES" ]; then
|
||
MIN=$(echo "$VALUES" | sort -n | head -1)
|
||
MAX=$(echo "$VALUES" | sort -n | tail -1)
|
||
AVG=$(echo "$VALUES" | awk '{s+=$1; c++} END {printf "%.1f", s/c}')
|
||
echo ""
|
||
echo "$eid"
|
||
echo " Мин/Макс/Среднее: $MIN / $MAX / $AVG"
|
||
fi
|
||
elif [[ $eid == switch.* ]]; then
|
||
ON=$(echo "$HISTORY" | jq -r --arg eid "$eid" '
|
||
.[] | select(.[0].entity_id == $eid) | .[] | select(.state == "on") | .state
|
||
' | wc -l)
|
||
OFF=$(echo "$HISTORY" | jq -r --arg eid "$eid" '
|
||
.[] | select(.[0].entity_id == $eid) | .[] | select(.state == "off") | .state
|
||
' | wc -l)
|
||
TRANS=$(echo "$HISTORY" | jq -r --arg eid "$eid" '
|
||
.[] | select(.[0].entity_id == $eid) as $h |
|
||
range(1; ($h | length)) |
|
||
select( ($h[.].state) != ($h[.-1].state) )
|
||
' | wc -l)
|
||
echo ""
|
||
echo "$eid"
|
||
echo " Состояний 'on': $ON, 'off': $OFF"
|
||
echo " Переключений: $TRANS"
|
||
fi
|
||
done
|
||
|
||
echo ""
|
||
echo "📤 Загрузи файл teplitsa_export.json в чат для анализа." |