- Por causa de um quarto quente e sensibilidade à temperatura corporal, comprou um Sleep.me Chilipad 2.0 por US$ 1.700 e desenvolveu o
bedctlpara controlar a API em nuvem do fabricante - O Chilipad combina um topper fino com circulação de água com uma bomba, reservatório e controlador de temperatura, e oferece configuração modular com agendamento de temperatura por dia da semana e instalação começando por um lado da cama
- A API consulta dispositivos em
/devicese/devices/{:id}e usaPATCHpara controlar temperatura, estado de funcionamento, brilho da tela, fuso horário etc., além de permitir verificar o nível da água e a temperatura atual da água - Escrito em Zig, o
bedctlé composto por uma biblioteca sem dependências e uma CLI enxuta, com plano futuro de expansão para uma biblioteca dinâmicalibbedctlcom interface C - No rastreamento inicial do sono, o tempo de sono restaurador aumentou e os despertares noturnos diminuíram, mas ainda é cedo para julgar o efeito de longo prazo por ser apenas uma fase de lua de mel de poucos dias de uso
Por que eu precisava controlar a temperatura da cama
- O sono ajuda na imunidade, na função cognitiva e na recuperação após atividade física, mas manchetes sobre saúde podem perder nuances científicas, então dou importância a saber se há respaldo de profissionais de saúde ou consenso de especialistas
- Por causa do TDAH, os pensamentos continuam vindo e é difícil pegar no sono, então reduzo estímulos lendo na cama e mando um sinal de hora de dormir para o sistema nervoso
- Por traços de autismo, sou sensível a certas texturas e sensações e também tenho dificuldade de regular a temperatura corporal, então para conseguir dormir a temperatura e o peso do cobertor precisam estar adequados
- O novo apartamento em Portland tem ar-condicionado só na sala e não tem ventilador de teto, então o quarto no andar alto vira o espaço mais quente da casa à noite
- Também confirmei com um sensor de temperatura que o quarto é o lugar mais quente do apartamento
- Combinando sono irregular, uso de estimulantes, quarto abafado e sensibilidade à temperatura corporal, decidi gastar dinheiro em um dispositivo de controle de temperatura da cama
Por que escolhi o Chilipad 2.0
- O Chilipad 2.0 controla a temperatura da cama conectando um topper fino cheio de água a uma unidade com bomba, reservatório e controlador de temperatura
- O BedJet, que sopra ar com um ventilador, foi descartado porque no verão o vento frio bateria diretamente nos pés
- O Eight Sleep foi descartado porque até o modelo mais barato custa US$ 3.000, exige assinatura e ainda inclui recursos de IA
- O Chilipad é um produto modular que pode ser comprado começando por um lado da cama, então o preço inicial é mais baixo
- Se instalar duas unidades, dá para configurar cada lado com uma temperatura diferente, o que é útil para casais com percepções térmicas diferentes
- Embora seja um produto conectado à internet, ele oferece modo avião e inclui um controle remoto Bluetooth por padrão
- Não verifiquei se o modo avião desliga só o Wi‑Fi ou bloqueia toda conexão sem fio
- No começo entendi errado e achei que fosse uma API local, mas na prática ele se comunica com um serviço em nuvem
- O fabricante fornece uma API para desenvolvedores, uma coleção do Postman, uma Swagger UI online e um esquema OpenAPI
Estrutura do dispositivo Chilipad
- O Chilipad é composto pelo dock, que é a unidade de controle, e por uma cover com circulação de água
- O dock contém o controlador de temperatura, a bomba e o reservatório
- Ele foi colocado perto dos pés da cama e da porta para reduzir a recirculação do ar quente expelido pelo trocador de calor para dentro do quarto
- A cover é formada por três camadas: uma base, a hydrolayer feita com membrana de TPU e a cover superior
- Abrindo o zíper da cover superior, o usuário instala a hydrolayer no lado onde dorme
- A parte superior usa um tecido frio ao toque e um acolchoado fino, então a hydrolayer não é sentida diretamente
API da Sleep.me
-
Autenticação e exemplos no Postman
- Para usar a API, primeiro é preciso gerar um token de usuário, e a documentação só pode ser acessada com uma conta
- Os exemplos do Postman ajudam quando faltam detalhes na documentação, mas exigem uma conta empresarial separada e também são complicados de configurar
- Prefiro alternativas como scripts
hurlde código aberto - A maioria dos exemplos tem erro de digitação nos nomes de variáveis
- É preciso usar
{{SleepMeAPI_Url}}, com distinção entre maiúsculas e minúsculas, e não{{SleepMeAPI_URL}} - O exemplo “Set Device Status” define
set_temperature_fcomo 69 ethermal_control_statuscomostandby
-
Endpoints e estrutura das respostas
- A API oferece dois tipos de endpoint: um para a lista de dispositivos e outro para dispositivos individuais
GET /devices: retorna a lista de dispositivos vinculados ao tokenGET /devices/{:id}: retorna as informações completas de um dispositivo específicoPATCH /devices/{:id}: altera propriedades do dispositivo- Cada item de
/devicesinclui o ID do dispositivo, o nome definido pelo usuário eattachments - Não está claro se
attachmentssignifica outros dispositivos conectados - A resposta detalhada é dividida nos objetos
about,controlestatusabout: informações somente leitura como versão do firmware, IP externo, IP da LAN, endereço MAC, modelo e número de sériecontrol: propriedades alteráveis como brilho da tela, unidade de temperatura exibida, temperatura configurada, estado do controle térmico e fuso horáriostatus: estado somente leitura como conexão com a API, falta de água, nível da água de 0 a 100 e temperatura atual da água
- As propriedades de
controlpodem variar por dispositivo, e às vezes são retornadas chaves não documentadas comobrightness_level thermal_control_statuspode seractiveoustandbye indica se o aparelho está regulando ativamente a temperatura
-
Valores de temperatura e controle do dispositivo
- Temperaturas em Fahrenheit são tratadas como inteiros, e em Celsius como números de ponto flutuante
- O intervalo normal é 55~115°F em Fahrenheit e 13.0~48.0°C em Celsius
MAX_COLDé representado como-1ou-1.0, eMAX_HEATcomo999ou999.0- Quando está em espera,
status.water_temperature_*igual a-1parece ser um valor sentinela, mas isso não está documentado - Ao alterar propriedades do dispositivo, basta enviar no corpo JSON apenas a chave que você quer mudar em uma requisição
PATCH - Para definir só a temperatura em Fahrenheit como 73, envie
{ "set_temperature_f": 73 } - Não é necessário incluir todas as chaves de controle nem envolver com
{ "control": ... } - Essa forma de requisição foi confirmada pela coleção do Postman, não pela documentação oficial
Estrutura e uso do bedctl
- O
bedctlfoi construído em torno de um módulo em Zig, e a CLI é um wrapper fino que chama essa biblioteca - O nome segue a convenção de colocar o sufixo
-ctlem programas de controle e também brinca com o fato de “bed cuttle” soar como “bed cuddle” - Os principais comandos são os seguintes
bedctl devices: consulta nomes e IDs dos dispositivos registrados no tokenbedctl status: consulta firmware, endereços de rede, modelo, temperatura configurada, estado de funcionamento, nível da água e temperatura observadabedctl set temp 74: define a temperatura alvo
- O token e o ID do dispositivo podem ser definidos por variáveis de ambiente ou passados pelas flags
--tokene--device
Por que escolhi Zig e as dependências
- Usei Rust no trabalho por cerca de 5 anos e como hobby desde 2018, mas queria feedback imediato e menor carga mental, então implementei isso em Zig, que venho preferindo recentemente
- Em um MacBook Pro M1 Max,
zig build check --watch -fincrementalatualiza em cerca de 75ms - A única dependência externa da CLI é um argument parser extraído e modificado do código do TigerBeetle e adaptado para o Zig 0.16.0
- A biblioteca não tem dependências além da biblioteca padrão do Zig e usa
std.http.Clientpara requisições HTTP - A CLI não faz link com
libc, e o plano é que a futura biblioteca dinâmica também funcione semlibc - Com o recurso padrão de compilação cruzada do Zig, é possível gerar builds para plataformas suportadas sem acessar diretamente o sistema de destino
Modelo de dados e sistema de tipos
- As structs principais são
Device, para a lista de dispositivos, eDeviceStatus, para a resposta detalhadaDeviceincluiid,nameeattachmentsDeviceStatusé composto porDevice.About,Device.ControleDevice.Status
- Como propriedades de
Controlpodem não existir dependendo do modelo, brilho, unidade de exibição, temperatura configurada, estado de operação e fuso horário são representados como valores opcionais - Em vez de usar strings JSON diretamente, ele aproveita enums anônimos do Zig
- As unidades de temperatura são
.ce.f - Os estados de controle térmico são
.activee.standby
- As unidades de temperatura são
- A temperatura configurada em Fahrenheit usa nomes de enum significativos para certos valores inteiros
- Em vez de memorizar
-1, é possível usar.max_cold - Temperaturas comuns podem ser passadas como literais inteiros, como
78
- Em vez de memorizar
- Não foi encontrada uma forma de restringir pelo tipo o intervalo válido de 55~115°F, e também não há validação separada antes da requisição
- Como valores em Celsius são de ponto flutuante, o intervalo permitido também não pôde ser expresso no tipo
Experiência implementando o cliente HTTP em Zig
- O cliente HTTP padrão do Zig exige um procedimento mais de baixo nível do que uma abstração simples de URI/corpo/
send- criar um objeto URI
- modificar a URI para definir o caminho
- criar um objeto de requisição com URI base, cabeçalhos e configuração de conexão
- enviar os cabeçalhos da requisição
- receber os cabeçalhos da resposta
- criar um reader para o corpo
- consumir o corpo da resposta a partir do reader
- Isso permite controle detalhado, mas, diferentemente do Rust, onde é possível descer ao baixo nível só quando necessário, no Zig a sensação é de estar fazendo trabalho de baixo nível o tempo todo
- A implementação de
/devicesenvia uma requisiçãoGETcom cabeçalho de autenticação usandosendBodiless(), lê a resposta até 64.000 bytes e faz o parse do JSON como[]const Device - Embora use
parseFromSliceLeaky, não há problema com liberação de memória graças à configuração de arena allocator não exposta externamente
Plano de expansão para biblioteca dinâmica
- O objetivo final é criar uma biblioteca dinâmica sem dependências que possa ser usada em linguagens de mais alto nível
- A estrutura planejada é a seguinte
- módulo Zig
bedctl - CLI
bedctlque usa diretamente o módulo Zig libbedctlque fornece uma interface C para o módulo Zigbedctl-dl, que usa a biblioteca dinâmica e valida por conta própria a interface C
- módulo Zig
- Se surgir um wrapper para Python, gostaria de usá-lo no Home Assistant, mas não pretende escrevê-lo pessoalmente
- O build e a interface da biblioteca dinâmica ainda não estão prontos, mas a ideia é adicioná-los em breve
Experiência de sono após alguns dias de uso
- Nos poucos dias de uso, subjetivamente dormiu muito bem, e o rastreador de atividade também mostrou mais tempo em sono restaurador e menos despertares noturnos
- Mesmo no dia em que bebeu uísque, dormiu melhor do que o normal, mas isso não deve ser interpretado como se álcool fosse bom para o sono
- O álcool continua sendo prejudicial à saúde e ao sono; no máximo, o dispositivo pode ter reduzido parcialmente a piora do sono
- Como o aparelho foi usado por apenas alguns dias e o
bedctltambém foi escrito ao longo de cerca de 3 noites, os resultados ainda estão em fase de lua de mel - Quando a temperatura foi ajustada baixa demais no início, houve uma sensação fria como se estivesse deitado em algo molhado, mas isso desapareceu depois de corrigir a temperatura
- O tempo de transição não foi medido diretamente, mas pareceu mais próximo de 1 minuto do que de 10 minutos
- Como é preciso menos de 1 galão de água para encher, a capacidade térmica a aquecer ou resfriar não é tão grande
Uso de controle remoto, ventilador e aquecimento
- O controle remoto padrão tem formato de disco grande com tela sensível ao toque, o que facilita mudar a temperatura imediatamente enquanto se ajusta a programação
- O toque do disco não é muito satisfatório, mas ele vibra a cada unidade de temperatura, permitindo ajustar sem olhar para a tela
- Mesmo usando máscara de dormir, dá para perceber o quanto mudou por meio do feedback háptico
- Também é necessário um leve fluxo de ar, então antes era preciso equilibrar ao mesmo tempo um nível que resfriasse o quarto sem bater diretamente no corpo nem ressecar as vias respiratórias
- Depois de passar a usar o Chilipad, basta deixar o ventilador na potência mínima
- De manhã, aumentar um pouco a temperatura fica aconchegante, e no inverno há expectativa de aproveitar a função de pré-aquecer a cama
- Colocar o topper reduz um pouco a ventilação vinda de baixo
- Não chega a parecer que você está deitado sobre plástico, mas em temperaturas mais altas a pele em contato com a cama pareceu ficar levemente úmida de suor
- Essa pode ser uma experiência ligada à regulação térmica pessoal e pode não se aplicar a outros usuários
- A experiência inicial é positiva no geral, e talvez seja publicado um acompanhamento depois que a biblioteca dinâmica estiver pronta
1 comentários
Comentários no Lobste.rs
Publiquei este texto logo antes de dormir, de forma bem apropriada ao tema
bedctlpara baixar bastante a temperatura em um horário específico, ele também poderia ser usado para acordar alguémO título e o texto são excelentes. Fico curioso se você também já testou cobertor ponderado e se ele realmente funcionou
Dependendo de como é fabricado, pode ter pouca respirabilidade e também ser caro. Depois de comprar o Chilipad, até fico sem graça de reclamar de preço, mas um produto que deixei anotado para olhar depois é este, com uma estrutura de trama aberta que parece bem respirável: https://bearaby.com/products/tree-napper
Estive pesquisando produtos desse tipo e penso em testar algum dia. Segundo este vídeo, a solução com melhor custo-benefício é um balde, mas nesse caso provavelmente não teria API
Texto um tanto relacionado: https://trufflesecurity.com/blog/removing-jeff-bezos-from-my-bed (discussão)
No trecho comparando Fahrenheit e Celsius, acho que a intenção não era escrever Celsius is the better temperature
O texto é divertido, e me identifiquei bastante com a forma de pensar, como na parte sobre ventiladores, mas não fica claro o que passou a ser possível controlar com esse trabalho
O parágrafo dizendo que, por causa da experiência no doutorado em física, você desconfia de reportagens sobre ciência e saúde até que sejam comprovadas pode ser lido como algo perigosamente parecido com desconfiança de vacinas. Ainda assim, entendo que a ideia é que o doutorado o fez deixar de aceitar os “fatos” da imprensa em termos preto no branco, e fico curioso sobre o que exatamente deixou essa marca
Quando o artigo de Andrew Wakefield sobre vacinas saiu, pessoas que só tinham lido uma matéria curta de um jornalista baseada no resumo passaram a afirmar categoricamente que vacinas eram absolutamente perigosas, e até um professor de biologia do ensino médio com mestrado em zoologia e três doutores em física aderiram ao movimento antivacina. Mas o consenso da comunidade médica continuou sendo que vacinas são seguras, eficazes e uma das ferramentas mais poderosas para salvar vidas, e todos os pesquisadores médicos que conheci concordavam com isso
O motivo de o doutorado ter me marcado foi perceber o tamanho do abismo entre as descobertas reais da minha área e a forma como elas apareciam nas notícias. Como não dá para entender completamente todas as áreas, devemos confiar nos médicos para medicina, nos ecólogos para meio ambiente e nos climatologistas para clima. Vi doutores em física “refutarem” especialistas com matemática de ensino fundamental II e ciência de ensino fundamental I, mas especialistas de verdade sabiam que existe uma diferença enorme entre conhecimento escolar e conhecimento sobre a realidade. Como vi esse abismo na área que estudei, nas áreas que não estudei acabei confiando ainda mais nos especialistas
Se dá para jogar campos arbitrários na estrutura desejada, quase certamente o handler está fazendo uma busca com regex do tipo
re.search('set_temperature_f\": (\\d+)',...)