Novo módulo vida.py: energia, alegria, companhia e diversão caem com o tempo e sobem com presença (PIR), movimento, conversa e carinho. Delas sai o humor e, do humor, os atos: gestos, cochilo quando cansado, dormir à noite sem ninguém por perto, acenar pedindo atenção quando carente com gente perto, tocar reações da biblioteca e inventar figurinhas novas com o Gemini (no máximo 3 por dia, 90 min entre elas). - O celular recebe "humor x" e escolhe os gestos soltos por ele. - Toque na tela do celular conta como carinho/cutucada (/vida/cuidar). - Respeita E-Stop e o modo presença (ninguém em casa = quieto). - Painel: cartão Vida no Ao vivo com humor, barras, cuidados, ritmo e diário; liga por padrão. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
109 lines
5.0 KiB
PowerShell
109 lines
5.0 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
Publica o Carinha no Orange Pi: compila o painel, empacota o código, faz backup na placa,
|
|
instala e reinicia o serviço. Configurações e bancos da placa nunca são sobrescritos.
|
|
|
|
.EXAMPLE
|
|
.\deploy.ps1 # compila, publica em root@192.168.1.35:/opt/carinha-pc e reinicia
|
|
.\deploy.ps1 -SoPacote # só gera o pacote local (nada vai para a placa)
|
|
.\deploy.ps1 -Placa 192.168.1.40 -Usuario carinha
|
|
.\deploy.ps1 -Ssh orangepi # usa um Host do ~/.ssh/config (chave própria)
|
|
#>
|
|
param(
|
|
[string]$Placa = '192.168.1.35',
|
|
[string]$Usuario = 'root',
|
|
[string]$Destino = '/opt/carinha-pc',
|
|
[int]$Porta = 8100,
|
|
[string]$Ssh = '',
|
|
[switch]$SemCompilar,
|
|
[switch]$SoPacote
|
|
)
|
|
# Comandos nativos (npm, tar, scp, ssh) escrevem avisos no stderr; o PowerShell 5.1 trataria isso
|
|
# como erro fatal. Por isso o sucesso de cada um é decidido pelo $LASTEXITCODE.
|
|
$ErrorActionPreference = 'Continue'
|
|
Set-Location $PSScriptRoot -ErrorAction Stop
|
|
|
|
# Código que vai para a placa. Ficam de fora: configurações (*.json da placa), bancos (*.db),
|
|
# chaves, vendor/ (modelos já instalados na placa) e o fonte do painel (só web/dist vai).
|
|
$arquivos = @(
|
|
'kiosk-server.py', 'comum.py', 'eventos.py', 'controle_pc.py', 'sinalizacao.py', 'servos.py', 'braco.py',
|
|
'cerebro.py', 'conversa.py', 'gemini.py', 'treinamento.py', 'figurinhas.py', 'api_config.py', 'historico.py', 'vida.py',
|
|
'carinha.html', 'camera.html', 'reacoes-render.js', 'rastreador-worker.js', 'rosto-motor.js', 'voz-robo.js', 'version.json',
|
|
'obter-rastreamento.py', 'android/app/assets/qualidade-auto.js'
|
|
)
|
|
if (Test-Path 'android/carinha-rosto.apk') { $arquivos += 'android/carinha-rosto.apk' }
|
|
|
|
# Telas antigas (até 0.7) que ainda podem estar na placa; vão para o backup e saem da pasta.
|
|
$legado = 'dashboard.html dashboard.css dashboard.js overview.js painel.html painel.css painel-controle.js ' +
|
|
'painel-video.js painel-rastreamento.js painel-conversa.js conversa.html conversa.css emojis.html biblioteca.js ' +
|
|
'treinamento.html treinamento.js treinamento.css braco.html braco.css braco.js braco-calibracao.js ' +
|
|
'braco-movimentos.js movimentos-core.js servos.html servos.css servos.js api.html api-painel.js ' +
|
|
'rastreamento-core.js audio-robot.js'
|
|
|
|
if (-not $SemCompilar) {
|
|
Write-Host '== Compilando o painel (web/)'
|
|
Push-Location web
|
|
try {
|
|
if (-not (Test-Path node_modules)) { npm ci; if ($LASTEXITCODE) { throw 'npm ci falhou' } }
|
|
npm run check; if ($LASTEXITCODE) { throw 'svelte-check encontrou erros' }
|
|
npm test; if ($LASTEXITCODE) { throw 'testes do painel falharam' }
|
|
npm run build; if ($LASTEXITCODE) { throw 'build do painel falhou' }
|
|
} finally { Pop-Location }
|
|
}
|
|
if (-not (Test-Path 'web/dist/index.html')) { throw 'web/dist não existe: rode sem -SemCompilar' }
|
|
|
|
$versao = (Get-Content version.json -Raw -ErrorAction Stop | ConvertFrom-Json).versao
|
|
$carimbo = Get-Date -Format 'yyyyMMdd-HHmmss'
|
|
$pacote = Join-Path $env:TEMP "carinha-$versao-$carimbo.tar.gz"
|
|
Write-Host "== Empacotando $versao em $pacote"
|
|
$faltando = $arquivos | Where-Object { -not (Test-Path $_) }
|
|
if ($faltando) { throw "Arquivos ausentes: $($faltando -join ', ')" }
|
|
& tar -czf $pacote @arquivos web/dist
|
|
if ($LASTEXITCODE) { throw 'tar falhou' }
|
|
$hash = (Get-FileHash $pacote -Algorithm SHA256 -ErrorAction Stop).Hash.ToLower()
|
|
Write-Host " SHA256 $hash"
|
|
|
|
if ($SoPacote) {
|
|
& tar -tzf $pacote | Measure-Object | ForEach-Object { Write-Host " $($_.Count) arquivos no pacote" }
|
|
Write-Host 'Pacote pronto (nada enviado à placa).'
|
|
return
|
|
}
|
|
|
|
$alvo = if ($Ssh) { $Ssh } else { "$Usuario@$Placa" }
|
|
$remoto = "/tmp/carinha-$versao-$carimbo.tar.gz"
|
|
Write-Host "== Enviando para $alvo"
|
|
& scp -q $pacote "${alvo}:$remoto"
|
|
if ($LASTEXITCODE) { throw 'scp falhou' }
|
|
|
|
# Na placa: backup do código atual, remove telas antigas, extrai o novo e reinicia.
|
|
$script = @"
|
|
set -e
|
|
cd '$Destino'
|
|
backup='$Destino/backup-$carimbo'
|
|
mkdir -p "`$backup"
|
|
for f in $($arquivos -join ' ') $legado; do [ -e "`$f" ] && cp -a --parents "`$f" "`$backup/" || true; done
|
|
[ -d web/dist ] && mkdir -p "`$backup/web" && cp -a web/dist "`$backup/web/" || true
|
|
echo "$hash $remoto" | sha256sum -c --quiet
|
|
rm -f $legado
|
|
rm -rf web/dist
|
|
tar -xzf '$remoto' -C '$Destino'
|
|
rm -f '$remoto'
|
|
systemctl restart carinha-pc
|
|
echo "backup em `$backup"
|
|
"@
|
|
Write-Host '== Instalando na placa'
|
|
# O PowerShell 5.1 põe BOM no stdin do ssh; sem tirar, o bash lê "<BOM>set -e" e não para no primeiro erro.
|
|
$script -replace "`r", '' | & ssh $alvo "sed '1s/^\xEF\xBB\xBF//' | bash -s"
|
|
if ($LASTEXITCODE) { throw 'instalação na placa falhou (o backup foi feito antes de qualquer remoção)' }
|
|
|
|
Write-Host '== Conferindo'
|
|
$url = "http://${Placa}:$Porta"
|
|
for ($i = 0; $i -lt 10; $i++) {
|
|
try {
|
|
$saude = Invoke-RestMethod "$url/app/health" -TimeoutSec 3
|
|
if ($saude.versao -eq $versao) { Write-Host "OK: $url/ responde versão $versao"; return }
|
|
} catch { }
|
|
Start-Sleep -Seconds 1
|
|
}
|
|
throw "O serviço não respondeu a versão $versao em $url. Veja: ssh $alvo journalctl -u carinha-pc -n 50"
|