
Como eu descrevi no artigo anterior, atualizando a câmera do raspberry pi 3, eu comprei também um sensor de temperatura. Não que eu precisasse, não que eu tenha um uso pra ele. A janela aqui tem vedação dupla e não tem como eu colocar ele do lado de fora sem arrebentar alguma coisa ou da janela ou do sensor. Então fica aqui dentro.
Pra ativar esse camarada, eu precisei rodar o raspi-config e habiltar a interface wire-1 em "interface options". E depois rebootar.


Ele aparece habilitado no boot:
root@raspberrypi3 /h/pi [0|1]# dmesg | grep -i wire
[ 15.395743] Driver for 1-wire Dallas network protocol.
[ 15.466930] gpio-4 (onewire@0): enforced open drain please flag it properly in DT/ACPI DSDT/board file
[ 15.497220] w1_master_driver w1_bus_master1: Attaching one wire slave 28.00000025630b crc 48
[ 21.844564] Bluetooth: HCI UART protocol Three-wire (H5) registered
No caso, ele mostra que conectei no GPIO-4.
Pra ler os dados é baba: tem uma interface do kernel que te dá em formato txt. Basta ler o conteúdo de& /sys/bus/w1/devices/28-00000025630b/w1_slave. Imagino que esse caminho deva mudar se usar um GPIO diferente.
pi@raspberrypi3 ~> cat /sys/bus/w1/devices/28-00000025630b/w1_slave
31 01 7f 80 7f ff 0f 10 90 : crc=90 YES
31 01 7f 80 7f ff 0f 10 90 t=19062
O valor da temperatura é o que está na segunda linha junto com o "t=". No caso mostra 19062, que é 19.062°C.
Pra ler em Python, o jeito mais baba possível:
#! /usr/bin/env -S uv run --script
TEMPERATURE_SENSOR = "/sys/bus/w1/devices/28-00000025630b/w1_slave"
def GetLocalTemperature() -> str | None:
"""
pi@raspberrypi3 ~> cat /sys/bus/w1/devices/28-00000025630b/w1_slave
17 01 7f 80 7f ff 09 10 01 : crc=01 YES
17 01 7f 80 7f ff 09 10 01 t=17437
"""
temp_item: str = ""
with open(TEMPERATURE_SENSOR) as fh:
for line in fh.readlines():
if not re.search("t=", line):
continue
line = line.rstrip()
temp_item = line.split()[-1]
if len(temp_item) == 0:
return None
temp_int = temp_item.split("=")[-1]
temp = int(temp_int) / 1000.0
return f"{temp:0.2f}"
if __name__ == '__main__':
temp = GetLocalTemperature()
print(f"Temperature: {temp}°C")
Eu segui várias dicas de lugares aleatórios, mas o melhor foi esse aqui:

No começo do ano eu pesquisei meio que sem querer os preços de câmeras pro raspberry pi. Aqui no projeto das fotos na janela, descrito em weather snapshot em Python, eu uso um raspberry pi 3.
E achei que os preços estavas acessíveis. Então comprei uma com visão noturna e lente eyefish, pra dar aquele look maroto nas fotos.
Não sabia eu o tamanho do drama que iria iniciar aí.
A câmera chegou e já meti a mão na massa e montei a danada. Tirei o raspberry pi da janela e desmontei.

Coloquei as câmeras lado a lado pra comparar o antes e o depois.

O primeiro problema foi o encaixe da câmera. Ele não cabia nessa câmera nova, que tem 2 parafusos na parte traseira. Então fiz um "ajuste" de engenheiro: peguei o parafusador de móveis da Ikea, que tem duas brocas pequenas, e usei uma dessas pra gastar um pouco o encaixe traseiro pra caber melhor. Claro que nessas eu errei posição e precisei furar de novo. Tudo isso em cima da mesa da cozinha.

Não ficou lá aquela Brastemp, mas consegui montar.




Daí foi colocar na janela e partir pro abraço. Claro que o abraço não foi como eu esperava.


Expectativa era essa abaixo, tirada com a câmera do telefone:

Mas saiu isso aqui:

Eu achei que era alguma regulagem. Então busquei mais informações pro tipo de câmera, etc. Em algum lugar eu encontrei alguém comentando que ela vinha com 2 leds laterais pra fotos noturnas, da visão noturna, e que era só tirar. Eu acabei tirando porque de noite ficava inviável de ver qualquer coisa.

O resultado:

Não importava o que eu fizesse, tinha essa camada puxando pro vermelho em toda foto.
Acabei encontrando um programa em python pra administrar a câmera remotamente:
https://github.com/monkeymademe/CamUI

Mas mesmo usando CamUI ficava avermelhado. E isso era no fim do dia, já quase anoitecendo. Durante o dia era desastre puro.

Mas de noite, até que ia bem.


Legal pela luminosidade, mas mata toda a luz natural da noite. Não que seja muita. Mas uma das minhas esperanças é capturar as aurora boreal com essa câmera. Já são 11 anos morando aqui, uns 8 anos do raspberry pi tirando as fotos e nunca pegou nada. Mas esperança nunca morre. Geralmente o memory card morre antes. Então a câmera não funciona pro que preciso.
Depois de pesquisar em vários fóruns, achei a informação que eu já imaginava e que ia doer: não tem como desligar o modo noturno nessas câmeras. Bom pra ambientes indoor com pouca luz, porém um fracasso miserável pra colocar numa janela e tentar pegar fotos durante o dia. Eu até tentei bloquear o infrared que fica na própria câmera mas sem sucesso. Claro que tudo do melhor jeito que a engenharia moderna pode oferecer: usando silvertape.
Como eu já ia encomendar outra câmera, acabei aproveitando e comprando um sensor de temperatura também, que por acaso chegou antes. Por quê comprei? Sei lá. Pareceu legal. Como já estava comprando mais coisas mesmo, comprei um suporte que imaginei que caberia melhor a câmera nova. Claro que eu estava errado, mas eu descrevo sobre isso mais abaixo.


Enfim chegou a câmera nova nessa semana. Desmontei e coloquei em operação. Aproveitei e comprei também um cabo flat mais longo, pra não precisar grudar o raspberrypi na perna do tripé.



Essa parte que parece madeira (é acrílico) na parte de trás era do suporte novo. A câmera deveria entrar no meio do suporte mas... a lente não passa no buraco. Tentei aumentar com o esquema pseudo-furadeira com a parafusadeira da Ikea, mas não deu muito certo.
Sobrou então montar a câmera pela frente mesmo.

Como não dava pra montar o suporte como foi planejado, tive de usar novamente a engenharia moderna: dá-lhe silvertape.


Durante os testes o raspberrypi morreu. Então tive de tirar mais uma vez da janela, colocar aqui no quarto no setup de trabalho com monitor, mouse e teclado e olhar. E capturar minha cara de "ué?!" quando não achei nenhum motivo pro danado ter travado. Pelo menos não apareceu nada nos logs (e isso talvez indique que o memory card já está pedindo arrego).

Como já estava fora, aproveitei e colei o suporte pra ficar menos... engenharia moderna.



E finalmente o resultado final.

Demorou, custou o dobro do que eu queria, mas cheguei no resultado aguardado.
Próximo passo será atualizar o software. Eu vi que voltaram com um módulo em Python. E também eu uso numpy pra decidir se a foto está boa ou se precisa tirar outra com parâmetros mais pra noite como maior tempo de exposição. Achei recentemente na Wikipedia um algoritmo, já em Python, pra saber se é nascer do sol ou poente. Então é mais fácil usar o algoritmo pra bater com o horário e fazer as mudanças. Vai consumir menos CPU e deve ficar mais rápido pra tirar fotos.
E o sensor de temperatura? Tá lá na janela pegando a temperatura interna. Ele mostra abaixo do que realmente está, mas deve ser porque está na janela. E estou enviando na última linha nos dados das fotos. Claro que isso não serve pra nada, mas entre tanta coisa que já não serve pra nada, não é isso que fará grande diferença.
Pra seguir os posts da câmera:
https://mastodon.social/@helio_weather
O bom é que agora já vou poder capturar os dias ensolarados que estão voltando. Deixo pro fim do artigo a foto que tirei essa semana ao voltar pra casa pedalando. Foi o primeiro dia do ano que sai do trabalho e voltei pedalando com luz do sol.

Nota: eu não mudei nada de código no raspberrypi por conta da câmera nova. Por isso não tem nada de código ou algo estilo bamblers nesse post.

Eu tinha esquecido de postar sobre o goosfraba, que descrevi no início aqui: Goosfraba, mas ele está atualizado. Além de chassi novo, sticker vindos diretamente do FOSDEM.
.oO(nota mental: só agora eu percebi que tenho o goosfraba desde 2011, não que seja o original já que troquei praticamente todas as peças)

Meu laptop estava tendo problemas de falta de memória com alguns playbooks em ansible.
Agora está com 64 GB de RAM e voando.
E pelo preço que está custando RAM, deve ter sido o mesmo que uma Ferrari.


Eu já tinha descrito em atualizando mapas de DNS no estilo do DynDNS como fazia o sistema de DNS dinâmico que uso pra manter o nome bolha.linux-br.org atualizado, entre alguns outros, com o link residencial que tenho em casa.
Funcionava mas não era aquela maravilha. Atualizava a cada 5 minutos e pegava a mudança de IP pelos logs do Apache.
Até aí, sem grandes problemas.
Mas daí o Guto, da instância bolha.us, disse que estava tendo problemas de conexão com a bolha.linux-br.org.
Minha suspeita foi DNS. Então dei uma olhada nos logs.
starting: 20251228T18:45:01
finished: 20251228T18:45:01
starting: 20251228T18:50:01
finished: 20251228T18:50:01
starting: 20251228T18:55:01
updating IPv4 for raspberry3: old=83.233.219.150 new=51.75.236.128
updating: filename=/etc/bind/master/db.linux-br.org old_serial=2025122854 new_serial=2025122855
restarting named.service
finished: 20251228T18:55:01
starting: 20251228T19:00:01
updating IPv4 for raspberry3: old=51.75.236.128 new=83.233.219.150
updating: filename=/etc/bind/master/db.linux-br.org old_serial=2025122855 new_serial=2025122856
restarting named.service
finished: 20251228T19:00:01
starting: 20251228T19:05:01
finished: 20251228T19:05:01
starting: 20251228T19:10:01
finished: 20251228T19:10:01
starting: 20251228T19:15:01
finished: 20251228T19:15:01
starting: 20251228T19:20:01
updating IPv4 for raspberry3: old=83.233.219.150 new=51.68.247.213
updating: filename=/etc/bind/master/db.linux-br.org old_serial=2025122856 new_serial=2025122857
restarting named.service
finished: 20251228T19:20:01
starting: 20251228T19:25:01
updating IPv4 for raspberry3: old=51.68.247.213 new=83.233.219.150
updating: filename=/etc/bind/master/db.linux-br.org old_serial=2025122857 new_serial=2025122858
restarting named.service
finished: 20251228T19:25:01
starting: 20251228T19:30:01
finished: 20251228T19:30:01
O código mostra que IPv4 mudou várias vezes no mesmo dia.
Então entrei em contato com o provedor e perguntei se não era possível deixar o lease do DHCP mais longo. A resposta foi que um desses IPs nem era deles.
Um bug na lógica.
Então resolvi escrever algo em Go pra tomar o lugar desse sistema pereba de atualização de DNS. Fiz o dns-monitor.
Agora o dns-monitor funciona ouvido numa API REST, que recebe JSON, atualiza no banco de dados, faz o update dos mapas de DNS e reinicia o serviço de DNS via systemd.
E vejo logs assim:
Feb 24 18:15:02 dns-monitor[1139847]: [2026-02-24T18:15:02] (INFO): [RESP] remote_addr=127.0.0.1:59286, real_ip=2a00:1598:23af:4900:5fe7:c566:dbbd:7b35 status_code=200 hostname=www.bolha message=unchanged
Feb 24 18:15:02 dns-monitor[1139847]: [2026-02-24T18:15:02] (INFO): [REQ] remote_addr=127.0.0.1:59312 real_ip=2a00:1598:23af:4900:5fe7:c566:dbbd:7b35 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
Feb 24 18:17:27 dns-monitor[1139847]: [2026-02-24T18:17:27] (INFO): [REQ] remote_addr=127.0.0.1:52066 real_ip=2a00:1598:23af:4900::b55 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.18.0
Feb 24 18:17:28 dns-monitor[1139847]: [2026-02-24T18:17:28] (INFO): [REQ] remote_addr=127.0.0.1:52074 real_ip=83.233.219.150 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.18.0
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): [REQ] remote_addr=127.0.0.1:47990 real_ip=83.233.219.150 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): [RESP] remote_addr=127.0.0.1:47990, real_ip=83.233.219.150 status_code=200 hostname=bolha message=unchanged
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): [REQ] remote_addr=127.0.0.1:48006 real_ip=2a00:1598:23af:4900:3e52:82ff:fe62:ff11 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): trigger update on ipv6
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): Updating DNS maps: hostname=www.bolha ip_version=6 ip_address=2a00:1598:23af:4900:3e52:82ff:fe62:ff11
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): dns maps to be udpated: [/etc/bind/master/db.truta.org /etc/bind/master/db.linux-br.org]
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): updated serial: 2026022400
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): updated serial: 2026022400
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): dns submap to also be update: /etc/bind/master/dyndns.map
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): [RESP] remote_addr=127.0.0.1:48006, real_ip=2a00:1598:23af:4900:3e52:82ff:fe62:ff11 status_code=200 hostname=www.bolha message=IPv6_updated
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): restart service named via systemd
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): [REQ] remote_addr=127.0.0.1:48010 real_ip=83.233.219.150 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): [REQ] remote_addr=127.0.0.1:48034 real_ip=83.233.219.150 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): [REQ] remote_addr=127.0.0.1:48020 real_ip=2a00:1598:23af:4900:3e52:82ff:fe62:ff11 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): [RESP] remote_addr=127.0.0.1:48034, real_ip=83.233.219.150 status_code=200 hostname=www.bolha message=unchanged
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): trigger update on ipv6
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): Updating DNS maps: hostname=bolha ip_version=6 ip_address=2a00:1598:23af:4900:3e52:82ff:fe62:ff11
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): dns maps to be udpated: [/etc/bind/master/db.truta.org /etc/bind/master/db.linux-br.org]
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): updated serial: 2026022401
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): updated serial: 2026022401
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): [REQ] remote_addr=127.0.0.1:48036 real_ip=2a00:1598:23af:4900:3e52:82ff:fe62:ff11 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): trigger update on ipv6
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): dns submap to also be update: /etc/bind/master/dyndns.map
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): dns maps to be udpated: [/etc/bind/master/db.truta.org /etc/bind/master/db.linux-br.org]
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): updated serial: 2026022402
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): updated serial: 2026022402
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): [RESP] remote_addr=127.0.0.1:48020, real_ip=2a00:1598:23af:4900:3e52:82ff:fe62:ff11 status_code=200 hostname=bolha message=IPv6_updated
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): restart service named via systemd
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): dns submap to also be update: /etc/bind/master/dyndns.map
Feb 24 18:20:01 dns-monitor[1139847]: [2026-02-24T18:20:01] (INFO): restart service named via systemd
Feb 24 18:22:28 dns-monitor[1139847]: [2026-02-24T18:22:28] (INFO): [REQ] remote_addr=127.0.0.1:48738 real_ip=2a00:1598:23af:4900::b55 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.18.0
Feb 24 18:22:28 dns-monitor[1139847]: [2026-02-24T18:22:28] (INFO): [REQ] remote_addr=127.0.0.1:48740 real_ip=83.233.219.150 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.18.0
Feb 24 18:25:02 dns-monitor[1139847]: [2026-02-24T18:25:02] (INFO): [REQ] remote_addr=127.0.0.1:52456 real_ip=83.233.219.150 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
Feb 24 18:25:02 dns-monitor[1139847]: [2026-02-24T18:25:02] (INFO): [RESP] remote_addr=127.0.0.1:52456, real_ip=83.233.219.150 status_code=200 hostname=bolha message=unchanged
Feb 24 18:25:02 dns-monitor[1139847]: [2026-02-24T18:25:02] (INFO): [REQ] remote_addr=127.0.0.1:52468 real_ip=83.233.219.150 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
Feb 24 18:25:02 dns-monitor[1139847]: [2026-02-24T18:25:02] (INFO): [REQ] remote_addr=127.0.0.1:52476 real_ip=83.233.219.150 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
Feb 24 18:25:02 dns-monitor[1139847]: [2026-02-24T18:25:02] (INFO): [RESP] remote_addr=127.0.0.1:52476, real_ip=83.233.219.150 status_code=200 hostname=www.bolha message=unchanged
Feb 24 18:25:02 dns-monitor[1139847]: [2026-02-24T18:25:02] (INFO): [REQ] remote_addr=127.0.0.1:52482 real_ip=2a00:1598:23af:4900:3e52:82ff:fe62:ff11 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
Feb 24 18:25:02 dns-monitor[1139847]: [2026-02-24T18:25:02] (INFO): [REQ] remote_addr=127.0.0.1:52484 real_ip=2a00:1598:23af:4900:3e52:82ff:fe62:ff11 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
Feb 24 18:25:02 dns-monitor[1139847]: [2026-02-24T18:25:02] (INFO): [RESP] remote_addr=127.0.0.1:52484, real_ip=2a00:1598:23af:4900:3e52:82ff:fe62:ff11 status_code=200 hostname=www.bolha message=unchanged
Feb 24 18:25:02 dns-monitor[1139847]: [2026-02-24T18:25:02] (INFO): [REQ] remote_addr=127.0.0.1:52498 real_ip=2a00:1598:23af:4900:3e52:82ff:fe62:ff11 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
Feb 24 18:25:02 dns-monitor[1139847]: [2026-02-24T18:25:02] (INFO): [RESP] remote_addr=127.0.0.1:52498, real_ip=2a00:1598:23af:4900:3e52:82ff:fe62:ff11 status_code=200 hostname=bolha message=unchanged
Feb 24 18:27:28 dns-monitor[1139847]: [2026-02-24T18:27:28] (INFO): [REQ] remote_addr=127.0.0.1:46772 real_ip=2a00:1598:23af:4900::b55 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.18.0
Feb 24 18:27:29 dns-monitor[1139847]: [2026-02-24T18:27:29] (INFO): [REQ] remote_addr=127.0.0.1:46774 real_ip=83.233.219.150 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.18.0
Feb 24 18:30:01 dns-monitor[1139847]: [2026-02-24T18:30:01] (INFO): [REQ] remote_addr=127.0.0.1:37288 real_ip=83.233.219.150 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
Feb 24 18:30:01 dns-monitor[1139847]: [2026-02-24T18:30:01] (INFO): [REQ] remote_addr=127.0.0.1:37294 real_ip=83.233.219.150 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
Feb 24 18:30:01 dns-monitor[1139847]: [2026-02-24T18:30:01] (INFO): [RESP] remote_addr=127.0.0.1:37294, real_ip=83.233.219.150 status_code=200 hostname=bolha message=unchanged
Feb 24 18:30:01 dns-monitor[1139847]: [2026-02-24T18:30:01] (INFO): [REQ] remote_addr=127.0.0.1:37302 real_ip=83.233.219.150 host=api.linux-br.org uri=/api/register method=POST user_agent=curl/8.5.0
Ficou mais fácil acompanhar as mudanças e o sistema ficou mais estável.
No servidor eu fiz um reverse proxy no Apache pra chegar no serviço dns-monitor.
Do lado do cliente, eu uso curl, como é possível ver pelos logs com user_agent. Envio algo como isso abaixo mas na crontab a cada 5 minutos:
❯ curl -6 -o /dev/null -s "https://api.linux-br.org/api/register" -d '{"hostname": "bolha", "token": "abcdefgh123456"}'
❯ curl -4 -o /dev/null -s "https://api.linux-br.org/api/register" -d '{"hostname": "bolha", "token": "abcdefgh123456"}'
O sistema está longe de estar perfeito. Roda vários updates no mapa seguidamente se o endereço mudar tanto no IPv4 quanto no IPv6, que aconteceu quando mudei o servidor fisicamente do quarto pra sala. Mas está funcionando e com menos erros que antes.
Quem quiser olhar o código, já esta no Codeberg:
https://codeberg.org/helioloureiro/dns_monitor
Não tem muita descrição, mas está lá e está funcionando em produção.
Nota: depois de tudo isso, o Guto falou que o problema era do lado da bolha.us. Ao menos serviu pra eu sair da inércia e escrever um pouco de Go, o que foi bem divertido.
Nota 2: nenhum código de AI foi usando durante o desenvolvimento desse programa.

Depois do erro do upgrade pro Joomla 6.0.3 descrito em deu ruim com o Joomla 6.0.2, eu meio que deixei pra lá esperando algo como sair o 6.0.4 que talvez resolvesse isso. Mas hoje eu decidi abrir um bug report.
Botei o site em mode debug e rodei o upgrade. Peguei o erro e fui pro site registrar o bug.
A primeira tarefa foi ver se já existia bug aberto. E encontrei um:
https://issues.joomla.org/tracker/joomla-cms/31330
No bug é comentado que falta suporte ao curl.
Então conectei no servidor e instaleio php8.4-curl. Rodei o upgrade e... falhou.
Claro! PHP exige reiniciar o servidor web, que é Apache.
Reiniciei e... pimba! Estamos na versão 6.0.3.
Quebrou algum treco. E não faz mais upgrade.

Aparece certo na tela de apresentação de administração. Mas na hora de fazer o upgrade em si...

Não tenho muito o que fazer e vou aguardar a próxima versão.
Faz tempo que eu queria dar um tapa no servidor do bolha.linux-br.org, que fica na máquina mimir. A descrição pode ser lida aqui: uma bolha pra chamar de minha.
O servidor ficou temporariamente no meu quarto, ao lado da impressora. E perto da Alexa, que é uma baita duma má influência. Apesar de não fazer muito barulho, fazia um ruído baixo. E eu prefiro não ter som nenhum enquanto durmo.
Eu estava de olho em alguns móveis na Ikea pra mover o servidor pra sala, onde ficam outros dispositivos como o PlayStation 5. Esse aliás habitando uma cadeira desde que soltou um alerta de aquecimento durante o verão. Que nem é tão quente assim por aqui.
![]() |
![]() |
Então aproveitei o fim de semana pra ir almoçar no Ikea, uma grande tradição sueca, e dar uma olhada nos móveis. E acabei comprando esse Trotten mesmo. Eu já tinha comprado um cabo de energia mais comprido, então bastou passar tudo por dentro do móvel da TV e ligar.
E agora tem um visual mais... digamos menos bagunçado.

A Miko supervisionou todo o trabalho do humano dela e aprovou o resultado. E não sei quanto tempo o PlayStation vai aguentar de pé. Hoje pelo menos ele passou no teste de fogo do Bender, o roomba que uso pra tirar o pó e pelos de gata do chão.

Durante o FOSDEM2026 a palavra de ordem da conferência foi "soberania de dados", sobre como não deixar nossos dados na Big Techs ou mesmo serviços, mesmos que livres, nos EUA. E dentro do mais citados estava o site que está no título do artigo: GitHub.
Não só pelo fato de ser agora parte da Microsoft, mas porque está enfiando AI em tudo, mesmo ninguém pedindo por isso. Como faz atualmente a Mozilla.
A alternativa, Codeberg, eu já tinha conta. Mas nunca de fato mexi. Só que o poder do git é justamente não depender de servidor centralizado. Basta alterar o destino e mandar o push.
Então comecei a fazer isso pros repos que estou mexendo atualmente. Manualmente.
❯ git clone This email address is being protected from spambots. You need JavaScript enabled to view it. :helioloureiro/obamawatcher.git
❯ cd obamawatcher
❯ git remote add codeberg ssh://This email address is being protected from spambots. You need JavaScript enabled to view it. /helioloureiro/obamawatcher.git
❯ git fetch -a
❯ it push codeberg
Claro que isso não ia escalar. Então resolvi buscar um script pra fazer o trabalho sujo por mim. E achei. E no GitHub aind por cima (sinta o gosto doce do sarcasmo aqui).
https://github.com/LionyxML/migrate-github-to-codeberg

Bastou configurar com os tokens de ambos os lados, GitHub e Codeberg, rodar, esperar alguns minutos e lá estava meu Codeberg todo populado com tudo o que eu tenho no GitHub.
Vou apagar o GitHub? Com certeza não. Mas vou passar a atualizar somente no Codeberg que aliás fica na Alemanha. Então dentro da soberania de dados, eu não estou tão soberano assim, mas pelo menos estou dentro da EU.
Quer acompanhar? Esse é meu perfil por lá:
Aproveitei a oportunidade do FOSDEM pra tirar uma foto com o Maddog. Da última vez foi no FISL. Acho que o de 2001, mas pode ter sido no de 2002.


Jamais imaginei em que algum dia minha barba estaria maior que a do Maddog.

Se saiu, então temos de atualizar.
Claro que não mandei o full package. Fiz com o de upgrade.
Em tempo: descobri alguns arquivos que não foram bem sucedidos durante o upgrade. Fui olhar e o dono estava para... root. Foram corrigidos.

Como faço em todo começo de ano, ou quase todo uma vez que não fiz isso no ano passado, voltei a jogar Skyrim. E dessa vez como nórdico. Beowulf, pra ficar bem à carácter. Como já descrevi em skyrim, um dos melhores jogos que existem eu gosto de começar pela Thieves Guild pra pegar a skeleton key. Depois vou pra Assassins Brotherhood. E aqui estou eu com meu traje de assassino vindo atrás da informação do "Gourmet".

Eu até comecei a jogar The Outer Worlds, mas achei enfadonho que leva muito tempo carregando a tela e jogar o tempo todo em primeira pessoa é cansativo (não é mesmo sr. CyberPunk 2077?).
Mas não só de Skyrim eu vivo. E como retrospectiva de 2025 eu gostaria de deixar a menção de honra pras pedaladas. Em 2025 eu fiz uma retrospectiva sobre a isso em totais de transporte durante 2024. Lá eu descrevi como fiquei decepcionado por ter chegado mais ou menos em 2000 Km pedalados. Esse ano não foi muito diferente em relação ao Google: não achei o resumo do ano. Teria de entrar mensalmente e pegar manualmente os totais.
Mas em 2025 eu tinha à mão o computador da Garmin. E com ele eu pude realmente acompanhar o quanto pedalei.

Foram 3.339,06 Km na Gravel e 138,65 na MTB. 3.477,71 Km total. Pra minha felicidade, passei dos almejados 3.000 Km.
2025 foi o ano em que pedalamos muito mais. Passamos de ir pro local de destino e voltar de trem a pedalar todo o caminho de volta.

E não só isso: fizemos os trechos várias vezes. Se nos anos anteriores fomos pra Nynäshamn uma vez, em 2025 fomos 4. Uppsala? 3.

Uppsala inclusive foi o recorde de distância no ano passado: 161,14 Km pedalados.

E claro que não foi um ano isento de acidentes. 2 batidas com a bike, sendo uma que eu voei por cima dela ao bater numa grade (que não vi), e a outra uma virada pra esquerda sem avisar com antecedência. Arranhões, torções, roupas rasgadas e uns pontos roxos mas no fim sobrevivemos. E tive ainda uma corrente quebrada no meio do caminho.

Depois dessa eu passei a usar quick-links e levo uns extras de backup. E passei a medir a distância de uso da corrente em outro indicador da Garmin.

Já com 1.520,64 Km rodados. Assumindo que vá durar uns 3.000 Km, já está em meia vida.
E também foi em 2025 que comecei a acompanhar meu peso mais de perto. Não com uma balança lá muito das boas, mas o suficiente pra fazer um acompanhamento básico e ver que baixei de quase 100 Kg pra 95 Kg (agora no inverno, com poucas pedaladas, não tenho muito o que fazer).

Aproveitei que comprei o smartwatch da Garmin e passei também a acompanhar meu ritmo cardíaco.

E sono.

Menção de honra ao Komoot, o app que usamos pra navegação quando saímos pra pedalar. Ele achou por algum motivo que pedalei 4.500 Km. Só 1000 Km a mais. Como ele integra com o app e computador da Garmin, imagino que tenha contado dobrado algumas pedaladas.

Mas vamos de mês em mês pra ver o que aconteceu comigo em 2025. Pegue seu café que a viagem é longa.


Depois de 8 anos só na Europa, eu finalmente fui ao Brasil. Passei o natal com a família e ano novo com os amigos. Foi bom, mas no fim eu já estava com saudades de casa.

Todo feveiro tem FOSDEM. E lá estarei eu novamente esse ano. Melhor evento de software livre da Europa.

Foi também em fevereiro que dei manutenção nas bike. Troquei as catracas e correntes de ambas. Da gravel e da MTB (mountainbike).

Março foi o primeiro pedal mais longo. Somente uns 50 Km, mas o suficiente pra estreiar o ano.

Em abril que realmente começamos a pedalar distâncias maiores. Essa é a foto de Gustavsberg, 70 Km de pedal.

E foi em Abril que meu Fitbit morreu. Não carregou mais. E comprei um Garmin pra fazer companhia pro computador da bike.
E posso dizer que foi 6 por meia dúzia. Os dados não ficaram mais precisos ou melhores. Basicamente foi a mesma coisa. Mesma quantidade de passos, mesma ritmo cardíaco, etc. Mas no Garmin ao menos eu pude carregar esse skin do pip-boy.
Maio é o mês da flores.

Sério.

E foi também o mês que finalmente eu levei a felina pra castrar. Ela estava fazendo xixi em tudo quanto era lugar e não estava dando certo.

E teve a festa de primavera-verão da firma. Tem de ser na primavera porque no verão todo mundo some de férias. Eu generosamente levei um keg de 23 litros de IPA.

Em junho não tem nem o que discutir: é Sweden Rock!

Com fechamento do Sabaton.

E foi nesse mês que meu bebê foi ao seu primeiro concerto de rock/metal. E foi Iron Maiden ainda por cima.

Já em julho é férias. É ir dar um pulo no laguinho no fim do dia pra dar uma refrescada.

Foi em julho que também comecei a usar o que seria o uniforme do time de pedal.

E foi também em julho que quebrou minha corrente.

Em agosto fomos até Gotemburgo pra assistir AC⚡DC. For those about to rock, we sallute you!

Também fizemos um pedal bacana, que pegava duas balsas na região de Waxholm.

Nem tudo foi bom em 2025. Em setembro foi quando saiu a notícia do querido José Naves ter sido forçado a voltar ao Brasil por conta da nova lei anti-imigração da Suécia.

Outro problema de bike. Dessa vez um raio quebrado. O equipamento já está mostrando fadiga do tempo (e distância) de uso.

Foi em outubro que comprei o hardware usado, esse do lado esquerdo da impressora, e fiz minha própria instância no fediverso.


E tivemos PyCon Suécia. No fim de outubro, mas teve.


Tudo organizado via web com uma equipe maravilhosa.

Em novembro é época de levar aquele soco na barriga do inverno e te lembrar que aqui é Suécia. Fica escuro logo às 16:00 e temos de trocar os pneus pros de inverno.

E temos sempre uma nevadinha. De leve. Mas tem.

E chega o último mês do ano. Aquele que a gente só quer descansar. Eu aproveitei pra fazer uma Winter Ale, de sabor caramelado.

Dezembro foi também quando terminei de montar a nova máquina de AI da firma. Lego de gente grande. Foi bem divertido.

E claro, é o mês em que a felina da casa entra em polvorosa.

E com isso chegamos ao final do grande pequeno resumo do meu ano.
Deixo vocês com a imagem do pão de banana que estou ficando craque em fazer. E bom 2026!

E vamos de volta pra Skyrim. Mother, mother, sweety mother. Temos um contrato pra matar o imperador de Tanriel pra completar.

Como parte das atividades de fim de ano, atualizei o Joomla do site pro 6.0.1. Se algo estiver quebrado, já sabem o motivo.
Aproveitei o embalo e também fiz upgrade do sistema operacional pro Debian Trixie.
Tudo pronto pra iniciar 2026.
Page 1 of 38
script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js">