- Actualizar CLAUDE.md con instrucciones para usar version - Añadir soporte para Home Assistant OS (haos.sh y mensajes) - Eliminar bin/ollama/podman-compose.yml (ahora se usa ~/.ollama) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
524 lines
No EOL
14 KiB
Bash
Executable file
524 lines
No EOL
14 KiB
Bash
Executable file
#!/bin/bash
|
|
#Script : haos.sh
|
|
#Apps : MRDEVS TOOLS
|
|
#Description : Instala y administra Home Assistant OS en Podman
|
|
#Author : Cortana Rosero One <cortana@rosero.one>
|
|
#Created : 2025/04/01 12:00:00
|
|
#Modified : 2025/04/01 12:00:00
|
|
#Version : 1.3.0
|
|
#==============================================================================
|
|
# Derechos de Autor [2025] [Mauro Rosero P. <mauro@rosero.one>]
|
|
#==============================================================================
|
|
# Este programa es software libre: usted puede redistribuirlo y/o modificarlo
|
|
# bajo los términos de la Licencia Pública Affero General de GNU tal como
|
|
# lo publica la Free Software Foundation, ya sea la versión 3 de la licencia,
|
|
# o (a su elección) cualquier versión posterior.
|
|
#
|
|
# Este programa se distribuye con la esperanza de que sea útil,
|
|
# pero SIN NINGUNA GARANTÍA; sin siquiera la garantía implícita de
|
|
# COMERCIABILIDAD o IDONEIDAD PARA UN PROPÓSITO PARTICULAR. Consulte la
|
|
# Licencia Pública Affero General de GNU para obtener más detalles.
|
|
#
|
|
# Debería haber recibido una copia de la Licencia Pública Affero General
|
|
# junto con este programa. Si no la recibió, consulte <https://www.gnu.org/licenses/>.
|
|
# [Generated] Created by Claude Code (claude-3-7-sonnet-20250219)
|
|
|
|
# Configuración inicial
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
BIN_BASE="bin"
|
|
BIN_LIBS="lib"
|
|
BIN_MESG="msg"
|
|
BIN_CFGS="config"
|
|
|
|
# Leer DEVSPATH desde el archivo de configuración o usar "devs" por defecto
|
|
if [ -f "$SCRIPT_DIR/config/devspath.dat" ]; then
|
|
DEVSPATH=$(cat "$SCRIPT_DIR/$BIN_CFGS/devspath.dat")
|
|
else
|
|
DEVSPATH="devs"
|
|
fi
|
|
|
|
BIN_HOME="$HOME/$DEVSPATH"
|
|
BIN_PATH=$BIN_HOME/$BIN_BASE
|
|
VERSION=$(cat "$BIN_HOME/$BIN_BASE/$BIN_CFGS/version")
|
|
|
|
# CHECK SHELL LANGUAGE
|
|
BIN_LANG=${LANG:0:2}
|
|
|
|
# Importar bibliotecas necesarias
|
|
if [ -f "${BIN_HOME}/${BIN_BASE}/${BIN_LIBS}/base.lib" ]; then
|
|
source "${BIN_HOME}/${BIN_BASE}/${BIN_LIBS}/base.lib"
|
|
# Cargar mensajes en el idioma del sistema o español por defecto
|
|
load_messages "${BIN_HOME}/${BIN_BASE}" "${BIN_MESG}" "${BIN_LANG}" "head"
|
|
# Cargar mensajes específicos de developers
|
|
load_messages "${BIN_HOME}/${BIN_BASE}" "${BIN_MESG}" "${BIN_LANG}" "developers"
|
|
title="${head_000} ${head_002} - ${ha_000}"
|
|
fi
|
|
|
|
# Verificar que estemos en una carpeta de proyectos
|
|
if [ -f "$SCRIPT_DIR/$BIN_CFGS/projects.dat" ]; then
|
|
PROJECTS_DIR=$(cat "$SCRIPT_DIR/$BIN_CFGS/projects.dat")
|
|
else
|
|
PROJECTS_DIR="projects"
|
|
fi
|
|
|
|
# Comprobación de proyecto válido
|
|
CURRENT_PATH="$PWD"
|
|
PROJECT_BASE="$HOME/$DEVSPATH/$PROJECTS_DIR"
|
|
|
|
# Verificar que el directorio actual esté dentro de la carpeta de proyectos
|
|
if [[ "$CURRENT_PATH" != "$PROJECT_BASE"* ]]; then
|
|
echo "${head_002} ${head_warning}: ${ha_081}"
|
|
printf "${ha_082}\n" "$PROJECT_BASE"
|
|
|
|
# Crear directorio de proyectos si no existe
|
|
if [ ! -d "$PROJECT_BASE" ]; then
|
|
printf "${ha_083}" "$PROJECT_BASE" | read -p CREATE_DIR
|
|
if [[ "$CREATE_DIR" =~ ^[Ss]$ ]]; then
|
|
mkdir -p "$PROJECT_BASE"
|
|
echo "${ha_084}"
|
|
fi
|
|
else
|
|
printf "${ha_085}\n" "$PROJECT_BASE"
|
|
fi
|
|
exit 1
|
|
fi
|
|
|
|
# Configuración básica
|
|
HA_CONFIG_DIR="$PWD/ha"
|
|
HA_PORT=8123
|
|
HA_NETWORKS="--network=host" # Modo host para descubrimiento de dispositivos
|
|
|
|
# Configuración de versiones
|
|
HA_CORE_CONTAINER_NAME="homeassistant"
|
|
HA_CORE_IMAGE="ghcr.io/home-assistant/home-assistant:stable"
|
|
|
|
HA_OS_CONTAINER_NAME="haos"
|
|
HA_OS_IMAGE="docker.io/homeassistant/home-assistant:stable"
|
|
|
|
# Por defecto usamos Home Assistant Core
|
|
HA_CONTAINER_NAME=$HA_CORE_CONTAINER_NAME
|
|
HA_IMAGE=$HA_CORE_IMAGE
|
|
HA_TYPE="core" # puede ser "core" o "os"
|
|
|
|
# Verificar si podman está instalado
|
|
check_podman() {
|
|
if ! command -v podman &> /dev/null; then
|
|
echo "${ha_003}"
|
|
if [ -f "$BIN_PATH/bootstrap.sh" ]; then
|
|
$BIN_PATH/bootstrap.sh
|
|
else
|
|
echo "${ha_004}"
|
|
exit 1
|
|
fi
|
|
else
|
|
echo "${ha_005}"
|
|
fi
|
|
}
|
|
|
|
# Crear directorios necesarios
|
|
prepare_directories() {
|
|
echo "${ha_006}"
|
|
mkdir -p "$HA_CONFIG_DIR"
|
|
mkdir -p "$HA_CONFIG_DIR/config"
|
|
mkdir -p "$HA_CONFIG_DIR/media"
|
|
mkdir -p "$HA_CONFIG_DIR/ssl"
|
|
mkdir -p "$HA_CONFIG_DIR/share"
|
|
|
|
# Asegurar permisos correctos
|
|
chmod -R 755 "$HA_CONFIG_DIR"
|
|
}
|
|
|
|
# Seleccionar versión de Home Assistant
|
|
select_ha_version() {
|
|
echo "${ha_086}"
|
|
echo "${ha_087}"
|
|
echo "${ha_088}"
|
|
|
|
local choice
|
|
read -p "${ha_089}" choice
|
|
|
|
case $choice in
|
|
1)
|
|
echo "${ha_091}"
|
|
HA_CONTAINER_NAME=$HA_CORE_CONTAINER_NAME
|
|
HA_IMAGE=$HA_CORE_IMAGE
|
|
HA_TYPE="core"
|
|
;;
|
|
2)
|
|
echo "${ha_092}"
|
|
HA_CONTAINER_NAME=$HA_OS_CONTAINER_NAME
|
|
HA_IMAGE=$HA_OS_IMAGE
|
|
HA_TYPE="os"
|
|
;;
|
|
*)
|
|
echo "${ha_090}"
|
|
select_ha_version
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Instalar Home Assistant en podman
|
|
install() {
|
|
check_podman
|
|
prepare_directories
|
|
|
|
# Seleccionar qué versión de Home Assistant instalar
|
|
select_ha_version
|
|
|
|
# Descargar la imagen apropiada
|
|
if [ "$HA_TYPE" = "core" ]; then
|
|
echo "${ha_007}"
|
|
else
|
|
echo "${ha_093}"
|
|
fi
|
|
podman pull $HA_IMAGE
|
|
|
|
if podman container exists $HA_CONTAINER_NAME; then
|
|
printf "${ha_008}\n" "$HA_CONTAINER_NAME"
|
|
printf "${ha_009}\n" "$0"
|
|
exit 1
|
|
fi
|
|
|
|
echo "${ha_010}"
|
|
podman run -d \
|
|
--name=$HA_CONTAINER_NAME \
|
|
$HA_NETWORKS \
|
|
-v "$HA_CONFIG_DIR/config:/config" \
|
|
-v "$HA_CONFIG_DIR/media:/media" \
|
|
-v "$HA_CONFIG_DIR/ssl:/ssl" \
|
|
-v "$HA_CONFIG_DIR/share:/share" \
|
|
--restart=unless-stopped \
|
|
$HA_IMAGE
|
|
|
|
if [ $? -eq 0 ]; then
|
|
echo "${ha_011}"
|
|
printf "${ha_002}\n" "$HA_PORT"
|
|
echo "${ha_012}"
|
|
else
|
|
echo "${ha_013}"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Iniciar el contenedor de Home Assistant
|
|
start() {
|
|
if ! podman container exists $HA_CONTAINER_NAME; then
|
|
printf "${ha_014}\n" "$HA_CONTAINER_NAME"
|
|
printf "${ha_015}\n" "$0"
|
|
exit 1
|
|
fi
|
|
|
|
if podman container inspect $HA_CONTAINER_NAME --format '{{.State.Running}}' | grep -q "true"; then
|
|
echo "${ha_001}"
|
|
printf "${ha_002}\n" "$HA_PORT"
|
|
return 0
|
|
fi
|
|
|
|
echo "${ha_016}"
|
|
podman start $HA_CONTAINER_NAME
|
|
|
|
if [ $? -eq 0 ]; then
|
|
echo "${ha_017}"
|
|
printf "${ha_002}\n" "$HA_PORT"
|
|
else
|
|
echo "${ha_018}"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Detener el contenedor de Home Assistant
|
|
stop() {
|
|
if ! podman container exists $HA_CONTAINER_NAME; then
|
|
printf "${ha_019}\n" "$HA_CONTAINER_NAME"
|
|
return 1
|
|
fi
|
|
|
|
if ! podman container inspect $HA_CONTAINER_NAME --format '{{.State.Running}}' | grep -q "true"; then
|
|
echo "${ha_020}"
|
|
return 0
|
|
fi
|
|
|
|
echo "${ha_021}"
|
|
podman stop $HA_CONTAINER_NAME
|
|
|
|
if [ $? -eq 0 ]; then
|
|
echo "${ha_022}"
|
|
else
|
|
echo "${ha_023}"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Reiniciar el contenedor de Home Assistant
|
|
restart() {
|
|
echo "${ha_024}"
|
|
|
|
stop
|
|
sleep 3
|
|
start
|
|
}
|
|
|
|
# Mostrar el estado del contenedor de Home Assistant
|
|
status() {
|
|
if ! podman container exists $HA_CONTAINER_NAME; then
|
|
echo "${ha_026}"
|
|
return 1
|
|
fi
|
|
|
|
echo "${ha_025}"
|
|
podman container inspect $HA_CONTAINER_NAME --format '{{.State.Status}}'
|
|
|
|
if podman container inspect $HA_CONTAINER_NAME --format '{{.State.Running}}' | grep -q "true"; then
|
|
echo "${ha_027}"
|
|
printf "${ha_028}\n" "$HA_PORT"
|
|
printf "${ha_029}\n" "$HA_CONFIG_DIR"
|
|
|
|
# Mostrar tiempo de ejecución
|
|
local start_time=$(podman container inspect $HA_CONTAINER_NAME --format '{{.State.StartedAt}}')
|
|
[ -n "$start_time" ] && printf "${ha_030}\n" "$start_time"
|
|
|
|
# Verificar si el servicio está respondiendo
|
|
if command -v curl &>/dev/null; then
|
|
if curl -s "http://localhost:$HA_PORT" >/dev/null; then
|
|
echo "${ha_031}"
|
|
else
|
|
echo "${ha_032}"
|
|
fi
|
|
fi
|
|
else
|
|
echo "${ha_033}"
|
|
fi
|
|
}
|
|
|
|
# Actualizar la imagen de Home Assistant
|
|
update() {
|
|
echo "${ha_034}"
|
|
|
|
# Detener el contenedor existente
|
|
stop
|
|
|
|
# Guardar la información del contenedor actual
|
|
echo "${ha_035}"
|
|
podman commit $HA_CONTAINER_NAME homeassistant-backup
|
|
|
|
# Descargar la nueva imagen
|
|
echo "${ha_036}"
|
|
podman pull $HA_IMAGE
|
|
|
|
# Eliminar el contenedor actual pero mantener los volúmenes
|
|
echo "${ha_037}"
|
|
podman rm $HA_CONTAINER_NAME
|
|
|
|
# Recrear el contenedor con la nueva imagen
|
|
echo "${ha_038}"
|
|
podman run -d \
|
|
--name=$HA_CONTAINER_NAME \
|
|
$HA_NETWORKS \
|
|
-v "$HA_CONFIG_DIR/config:/config" \
|
|
-v "$HA_CONFIG_DIR/media:/media" \
|
|
-v "$HA_CONFIG_DIR/ssl:/ssl" \
|
|
-v "$HA_CONFIG_DIR/share:/share" \
|
|
--restart=unless-stopped \
|
|
$HA_IMAGE
|
|
|
|
if [ $? -eq 0 ]; then
|
|
echo "${ha_039}"
|
|
printf "${ha_002}\n" "$HA_PORT"
|
|
echo "${ha_040}"
|
|
echo "podman stop homeassistant && podman rm homeassistant && podman tag homeassistant-backup homeassistant && podman run -d [opciones] homeassistant"
|
|
else
|
|
echo "${ha_041}"
|
|
podman run -d \
|
|
--name=$HA_CONTAINER_NAME \
|
|
$HA_NETWORKS \
|
|
-v "$HA_CONFIG_DIR/config:/config" \
|
|
-v "$HA_CONFIG_DIR/media:/media" \
|
|
-v "$HA_CONFIG_DIR/ssl:/ssl" \
|
|
-v "$HA_CONFIG_DIR/share:/share" \
|
|
--restart=unless-stopped \
|
|
homeassistant-backup
|
|
|
|
if [ $? -eq 0 ]; then
|
|
echo "${ha_042}"
|
|
else
|
|
echo "${ha_043}"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Eliminar el contenedor de Home Assistant
|
|
remove() {
|
|
echo "${ha_044}"
|
|
|
|
# Detener el contenedor primero
|
|
stop
|
|
|
|
# Preguntar si se desea realizar una copia de seguridad
|
|
read -p "${ha_045}" BACKUP
|
|
if [[ "$BACKUP" =~ ^[Ss]$ ]]; then
|
|
echo "${ha_046}"
|
|
podman commit $HA_CONTAINER_NAME homeassistant-backup
|
|
echo "${ha_047}"
|
|
fi
|
|
|
|
# Preguntar si se desea eliminar los datos de configuración
|
|
read -p "${ha_048}" REMOVE_CONFIG
|
|
|
|
# Eliminar el contenedor
|
|
podman rm $HA_CONTAINER_NAME
|
|
|
|
if [[ "$REMOVE_CONFIG" =~ ^[Ss]$ ]]; then
|
|
echo "${ha_049}"
|
|
rm -rf "$HA_CONFIG_DIR"
|
|
fi
|
|
|
|
echo "${ha_050}"
|
|
}
|
|
|
|
# Mostrar los logs del contenedor
|
|
logs() {
|
|
if ! podman container exists $HA_CONTAINER_NAME; then
|
|
printf "${ha_019}\n" "$HA_CONTAINER_NAME"
|
|
return 1
|
|
fi
|
|
|
|
echo "${ha_051}"
|
|
podman logs -f $HA_CONTAINER_NAME
|
|
}
|
|
|
|
# Configuración de complementos adicionales
|
|
setup_addons() {
|
|
echo "${ha_052}"
|
|
|
|
# Verifica si Home Assistant está ejecutándose
|
|
if ! podman container inspect $HA_CONTAINER_NAME --format '{{.State.Running}}' | grep -q "true"; then
|
|
echo "${ha_053}"
|
|
echo "${ha_054}"
|
|
start
|
|
fi
|
|
|
|
echo "${ha_055}"
|
|
echo "1. MQTT Broker (Mosquitto)"
|
|
echo "2. Z-Wave JS"
|
|
echo "3. Zigbee2MQTT"
|
|
echo "4. AdGuard Home"
|
|
echo "5. Node-RED"
|
|
echo "0. Cancelar"
|
|
|
|
read -p "${ha_056}" ADDON_CHOICE
|
|
|
|
case $ADDON_CHOICE in
|
|
1)
|
|
echo "${ha_057}"
|
|
podman run -d \
|
|
--name=mosquitto \
|
|
--network=host \
|
|
-v "$HA_CONFIG_DIR/mosquitto:/mosquitto" \
|
|
-p 1883:1883 \
|
|
--restart=unless-stopped \
|
|
eclipse-mosquitto:latest
|
|
echo "${ha_058}"
|
|
;;
|
|
2)
|
|
echo "${ha_059}"
|
|
podman run -d \
|
|
--name=zwavejs \
|
|
--network=host \
|
|
-v "$HA_CONFIG_DIR/zwavejs:/usr/src/app/store" \
|
|
--device=/dev/ttyUSB0:/dev/ttyUSB0 \
|
|
-p 8091:8091 \
|
|
--restart=unless-stopped \
|
|
zwavejs/zwavejs2mqtt:latest
|
|
echo "${ha_060}"
|
|
;;
|
|
3)
|
|
echo "${ha_061}"
|
|
mkdir -p "$HA_CONFIG_DIR/zigbee2mqtt/data"
|
|
podman run -d \
|
|
--name=zigbee2mqtt \
|
|
--network=host \
|
|
-v "$HA_CONFIG_DIR/zigbee2mqtt/data:/app/data" \
|
|
--device=/dev/ttyUSB0:/dev/ttyUSB0 \
|
|
-p 8080:8080 \
|
|
--restart=unless-stopped \
|
|
koenkk/zigbee2mqtt:latest
|
|
echo "${ha_062}"
|
|
;;
|
|
4)
|
|
echo "${ha_063}"
|
|
podman run -d \
|
|
--name=adguardhome \
|
|
--network=host \
|
|
-v "$HA_CONFIG_DIR/adguardhome/workdir:/opt/adguardhome/work" \
|
|
-v "$HA_CONFIG_DIR/adguardhome/confdir:/opt/adguardhome/conf" \
|
|
-p 53:53/tcp -p 53:53/udp \
|
|
-p 80:80/tcp -p 443:443/tcp -p 3000:3000/tcp \
|
|
--restart=unless-stopped \
|
|
adguard/adguardhome:latest
|
|
echo "${ha_064}"
|
|
;;
|
|
5)
|
|
echo "${ha_065}"
|
|
podman run -d \
|
|
--name=nodered \
|
|
--network=host \
|
|
-v "$HA_CONFIG_DIR/nodered:/data" \
|
|
-p 1880:1880 \
|
|
--restart=unless-stopped \
|
|
nodered/node-red:latest
|
|
echo "${ha_066}"
|
|
;;
|
|
0)
|
|
echo "${ha_067}"
|
|
;;
|
|
*)
|
|
echo "${ha_068}"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Función principal y procesamiento de comandos
|
|
case "$1" in
|
|
install)
|
|
install
|
|
;;
|
|
start)
|
|
start
|
|
;;
|
|
stop)
|
|
stop
|
|
;;
|
|
restart)
|
|
restart
|
|
;;
|
|
status)
|
|
status
|
|
;;
|
|
update)
|
|
update
|
|
;;
|
|
remove)
|
|
remove
|
|
;;
|
|
logs)
|
|
logs
|
|
;;
|
|
addons)
|
|
setup_addons
|
|
;;
|
|
*)
|
|
echo "${ha_069}"
|
|
printf "${ha_070}\n" "$0"
|
|
echo ""
|
|
echo "${ha_071}"
|
|
echo "${ha_072}"
|
|
echo "${ha_073}"
|
|
echo "${ha_074}"
|
|
echo "${ha_075}"
|
|
echo "${ha_076}"
|
|
echo "${ha_077}"
|
|
echo "${ha_078}"
|
|
echo "${ha_079}"
|
|
echo "${ha_080}"
|
|
;;
|
|
esac |