Add bash-only version of cleanup script
- Works directly in SSH add-on (no Python required) - Line-by-line YAML parsing - Preserves indentation and structure - Color-coded output - Automatic backups with restore script - Removes 19 input_booleans and 10 scripts
This commit is contained in:
373
ha_chore_cleanup.sh
Normal file
373
ha_chore_cleanup.sh
Normal file
@@ -0,0 +1,373 @@
|
||||
#!/bin/bash
|
||||
################################################################################
|
||||
# Home Assistant Chore Cleanup Script (Bash Version)
|
||||
# Removes unused chore-related entities from YAML configuration files
|
||||
# Creates backups before making any changes
|
||||
################################################################################
|
||||
|
||||
set -e # Exit on error
|
||||
|
||||
# Color codes for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Configuration
|
||||
CONFIG_DIR="/config"
|
||||
BACKUP_TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
||||
BACKUP_DIR="$CONFIG_DIR/backups/cleanup_$BACKUP_TIMESTAMP"
|
||||
|
||||
# Counters
|
||||
REMOVED_BOOLEANS=0
|
||||
REMOVED_SCRIPTS=0
|
||||
|
||||
# Arrays to store removed items
|
||||
declare -a REMOVED_BOOLEAN_NAMES=()
|
||||
declare -a REMOVED_SCRIPT_NAMES=()
|
||||
|
||||
# Entities to remove
|
||||
INPUT_BOOLEANS_TO_REMOVE=(
|
||||
"task_lou_clean_desk_pending"
|
||||
"task_jess_clean_desk_pending"
|
||||
"task_william_clean_desk_pending"
|
||||
"task_xander_clean_desk_pending"
|
||||
"task_bella_clean_desk_pending"
|
||||
"task_lou_clean_room_pending"
|
||||
"task_jess_clean_room_pending"
|
||||
"task_william_clean_room_pending"
|
||||
"task_xander_clean_room_pending"
|
||||
"task_bella_clean_room_pending"
|
||||
"task_tidy_lounge_pending"
|
||||
"task_vacuum_room_pending"
|
||||
"task_get_school_ready_pending"
|
||||
"task_clean_desks_done_this_week"
|
||||
"task_clean_rooms_done_this_week"
|
||||
"task_tidy_lounge_done_this_week"
|
||||
"task_tidy_kitchen_done_today"
|
||||
"task_clean_dining_table_done_today"
|
||||
"task_vacuum_room_done_today"
|
||||
)
|
||||
|
||||
SCRIPTS_TO_REMOVE=(
|
||||
"complete_task_dishwasher_unload"
|
||||
"complete_task_washing_machine_unload"
|
||||
"complete_task_dryer_unload"
|
||||
"complete_task_bins_out"
|
||||
"complete_task_bins_in"
|
||||
"complete_task_kitty_litter_clean"
|
||||
"complete_task_kitty_litter_change"
|
||||
"complete_tidy_lounge"
|
||||
"complete_vacuum_room"
|
||||
"complete_get_school_ready"
|
||||
)
|
||||
|
||||
################################################################################
|
||||
# Helper Functions
|
||||
################################################################################
|
||||
|
||||
print_header() {
|
||||
echo ""
|
||||
echo "======================================================================"
|
||||
echo "$1"
|
||||
echo "======================================================================"
|
||||
echo ""
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}✓${NC} $1"
|
||||
}
|
||||
|
||||
print_info() {
|
||||
echo -e "${BLUE}ℹ${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}⚠${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}✗${NC} $1"
|
||||
}
|
||||
|
||||
create_backup_dir() {
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
print_success "Created backup directory: $BACKUP_DIR"
|
||||
}
|
||||
|
||||
backup_file() {
|
||||
local file="$1"
|
||||
if [ -f "$file" ]; then
|
||||
cp "$file" "$BACKUP_DIR/$(basename "$file")"
|
||||
print_info "Backed up: $(basename "$file")"
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# YAML Cleaning Functions
|
||||
################################################################################
|
||||
|
||||
clean_yaml_entity() {
|
||||
local file="$1"
|
||||
local entity_name="$2"
|
||||
local temp_file="${file}.tmp"
|
||||
local in_entity=0
|
||||
local entity_indent=""
|
||||
local removed=0
|
||||
|
||||
# Read file line by line
|
||||
while IFS= read -r line || [[ -n "$line" ]]; do
|
||||
# Check if this is the start of our target entity
|
||||
if echo "$line" | grep -q "^[[:space:]]*${entity_name}:"; then
|
||||
in_entity=1
|
||||
# Capture the indentation level
|
||||
entity_indent=$(echo "$line" | sed 's/[^[:space:]].*//')
|
||||
removed=1
|
||||
continue # Skip this line
|
||||
fi
|
||||
|
||||
# If we're in the entity block
|
||||
if [ $in_entity -eq 1 ]; then
|
||||
# Check if we've reached the next entity at same indent level
|
||||
if echo "$line" | grep -q "^${entity_indent}[^[:space:]]"; then
|
||||
in_entity=0
|
||||
else
|
||||
continue # Skip this line (part of entity definition)
|
||||
fi
|
||||
fi
|
||||
|
||||
# Write the line to temp file
|
||||
echo "$line" >> "$temp_file"
|
||||
done < "$file"
|
||||
|
||||
# Replace original with cleaned version
|
||||
if [ -f "$temp_file" ]; then
|
||||
mv "$temp_file" "$file"
|
||||
fi
|
||||
|
||||
return $removed
|
||||
}
|
||||
|
||||
clean_input_boolean_file() {
|
||||
local file="$1"
|
||||
local count=0
|
||||
|
||||
print_info "Processing $(basename "$file")..."
|
||||
|
||||
if [ ! -f "$file" ]; then
|
||||
print_warning "File not found, skipping"
|
||||
return
|
||||
fi
|
||||
|
||||
# Backup first
|
||||
backup_file "$file"
|
||||
|
||||
# Remove each input_boolean
|
||||
for entity in "${INPUT_BOOLEANS_TO_REMOVE[@]}"; do
|
||||
if grep -q "^[[:space:]]*${entity}:" "$file"; then
|
||||
clean_yaml_entity "$file" "$entity"
|
||||
if [ $? -eq 1 ]; then
|
||||
((count++))
|
||||
((REMOVED_BOOLEANS++))
|
||||
REMOVED_BOOLEAN_NAMES+=("$entity")
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $count -gt 0 ]; then
|
||||
print_success "Removed $count input_boolean entries"
|
||||
else
|
||||
print_info "No items to remove"
|
||||
fi
|
||||
}
|
||||
|
||||
clean_script_file() {
|
||||
local file="$1"
|
||||
local count=0
|
||||
|
||||
print_info "Processing $(basename "$file")..."
|
||||
|
||||
if [ ! -f "$file" ]; then
|
||||
print_warning "File not found, skipping"
|
||||
return
|
||||
fi
|
||||
|
||||
# Backup first
|
||||
backup_file "$file"
|
||||
|
||||
# Remove each script
|
||||
for entity in "${SCRIPTS_TO_REMOVE[@]}"; do
|
||||
if grep -q "^[[:space:]]*${entity}:" "$file"; then
|
||||
clean_yaml_entity "$file" "$entity"
|
||||
if [ $? -eq 1 ]; then
|
||||
((count++))
|
||||
((REMOVED_SCRIPTS++))
|
||||
REMOVED_SCRIPT_NAMES+=("$entity")
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $count -gt 0 ]; then
|
||||
print_success "Removed $count script entries"
|
||||
else
|
||||
print_info "No items to remove"
|
||||
fi
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# File Discovery
|
||||
################################################################################
|
||||
|
||||
find_config_files() {
|
||||
echo ""
|
||||
print_info "Searching for configuration files..."
|
||||
|
||||
# Find input_boolean files
|
||||
for pattern in "input_boolean.yaml" "input_booleans.yaml" "helpers.yaml"; do
|
||||
if [ -f "$CONFIG_DIR/$pattern" ]; then
|
||||
clean_input_boolean_file "$CONFIG_DIR/$pattern"
|
||||
fi
|
||||
done
|
||||
|
||||
# Check packages directory
|
||||
if [ -d "$CONFIG_DIR/packages" ]; then
|
||||
find "$CONFIG_DIR/packages" -name "*.yaml" -type f | while read -r file; do
|
||||
# Check if file contains any of our target entities
|
||||
for entity in "${INPUT_BOOLEANS_TO_REMOVE[@]}"; do
|
||||
if grep -q "$entity" "$file"; then
|
||||
clean_input_boolean_file "$file"
|
||||
break
|
||||
fi
|
||||
done
|
||||
done
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Find script files
|
||||
for pattern in "scripts.yaml" "script.yaml"; do
|
||||
if [ -f "$CONFIG_DIR/$pattern" ]; then
|
||||
clean_script_file "$CONFIG_DIR/$pattern"
|
||||
fi
|
||||
done
|
||||
|
||||
# Check packages directory for scripts
|
||||
if [ -d "$CONFIG_DIR/packages" ]; then
|
||||
find "$CONFIG_DIR/packages" -name "*.yaml" -type f | while read -r file; do
|
||||
# Check if file contains any of our target entities
|
||||
for entity in "${SCRIPTS_TO_REMOVE[@]}"; do
|
||||
if grep -q "$entity" "$file"; then
|
||||
clean_script_file "$file"
|
||||
break
|
||||
fi
|
||||
done
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Restore Script Generation
|
||||
################################################################################
|
||||
|
||||
create_restore_script() {
|
||||
local restore_script="$BACKUP_DIR/restore.sh"
|
||||
|
||||
cat > "$restore_script" << 'EOF'
|
||||
#!/bin/bash
|
||||
# Restore script - Run this if you need to undo the cleanup
|
||||
|
||||
echo "Restoring files from backup..."
|
||||
|
||||
EOF
|
||||
|
||||
# Add restore commands for each backed up file
|
||||
for backup_file in "$BACKUP_DIR"/*.yaml; do
|
||||
if [ -f "$backup_file" ]; then
|
||||
original="$CONFIG_DIR/$(basename "$backup_file")"
|
||||
echo "cp \"$backup_file\" \"$original\"" >> "$restore_script"
|
||||
fi
|
||||
done
|
||||
|
||||
cat >> "$restore_script" << 'EOF'
|
||||
|
||||
echo ""
|
||||
echo "Files restored!"
|
||||
echo "Please restart Home Assistant for changes to take effect"
|
||||
echo ""
|
||||
EOF
|
||||
|
||||
chmod +x "$restore_script"
|
||||
print_success "Created restore script: $restore_script"
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Summary Display
|
||||
################################################################################
|
||||
|
||||
print_summary() {
|
||||
print_header "CLEANUP SUMMARY"
|
||||
|
||||
print_success "Backups saved to: $BACKUP_DIR"
|
||||
|
||||
echo ""
|
||||
echo "📋 Input Booleans Removed: $REMOVED_BOOLEANS"
|
||||
if [ $REMOVED_BOOLEANS -gt 0 ]; then
|
||||
for entity in "${REMOVED_BOOLEAN_NAMES[@]}"; do
|
||||
echo " - $entity"
|
||||
done
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "📜 Scripts Removed: $REMOVED_SCRIPTS"
|
||||
if [ $REMOVED_SCRIPTS -gt 0 ]; then
|
||||
for entity in "${REMOVED_SCRIPT_NAMES[@]}"; do
|
||||
echo " - $entity"
|
||||
done
|
||||
fi
|
||||
|
||||
echo ""
|
||||
print_header "NEXT STEPS"
|
||||
echo "1. Review the changes in your YAML files"
|
||||
echo "2. Check configuration: ha core check"
|
||||
echo "3. If everything looks good, restart: ha core restart"
|
||||
echo "4. If issues occur, restore from: $BACKUP_DIR"
|
||||
echo "5. Run restore script: bash $BACKUP_DIR/restore.sh"
|
||||
echo ""
|
||||
echo "======================================================================"
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Main Execution
|
||||
################################################################################
|
||||
|
||||
main() {
|
||||
print_header "Home Assistant Chore Cleanup Script (Bash)"
|
||||
|
||||
# Check if config directory exists
|
||||
if [ ! -d "$CONFIG_DIR" ]; then
|
||||
print_error "Config directory not found: $CONFIG_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create backup directory
|
||||
create_backup_dir
|
||||
|
||||
# Process files
|
||||
find_config_files
|
||||
|
||||
# Create restore script
|
||||
create_restore_script
|
||||
|
||||
# Print summary
|
||||
print_summary
|
||||
|
||||
echo ""
|
||||
print_success "Cleanup completed successfully!"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main
|
||||
Reference in New Issue
Block a user