Files
carinha-control-panel/deploy.ps1
julioandClaude Opus 5.5 972dd8dd66 feat(rosto): motor de palpebras, 4 rostos novos, formato do olho e tela Rosto
- rosto-motor.js: emocoes como posicao de palpebra (cima, inclinacao, baixo)
  com transicao suave; respiracao, sacadas e piscada que achata o olho
- rostos novos Carinha Viva, Bloco, Matriz (LEDs) e Lente (iris/pupila);
  os classicos continuam; emoji/figurinha nos olhos seguem no SVG
- formato do olho (padrao, redondo, pilula, quadrado, largo) para Viva,
  Bloco e Matriz; salvo na aparencia e enviado como ordem "formato X"
- toque na tela do S10: cutucar = susto e risada, deslizar = carinho,
  tocar dormindo acorda
- painel: tela Rosto (celular em destaque, cartoes de rosto, formatos,
  cores, testar emocoes so na previa ou no celular, lista do que ja esta
  pronto); Ao vivo leva a ela; paleta ganha rostos e formatos
- corrige /comando rosto que nao salvava a aparencia

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 01:33:56 -03:00

108 lines
4.8 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',
'carinha.html', 'camera.html', 'reacoes-render.js', 'rastreador-worker.js', 'rosto-motor.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'
$script -replace "`r", '' | & ssh $alvo '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"