1 poin oleh GN⁺ 17 jam lalu | 1 komentar | Bagikan ke WhatsApp
  • Karena kamar tidur yang panas dan sensitivitas terhadap suhu tubuh, penulis membeli Sleep.me Chilipad 2.0 seharga 1.700 dolar dan mengembangkan bedctl untuk mengendalikan API cloud milik produsennya
  • Chilipad menggabungkan topper tipis dengan sirkulasi air serta pompa, reservoir, dan pengatur suhu, serta mendukung konfigurasi modular dengan jadwal suhu per hari dan pemasangan mulai dari satu sisi tempat tidur
  • API menyediakan akses ke perangkat melalui /devices dan /devices/{:id}, serta mengendalikan suhu, status operasi, kecerahan layar, zona waktu, dan lainnya lewat PATCH, sambil juga memungkinkan pengecekan level air dan suhu air saat ini
  • bedctl, yang ditulis dengan Zig, terdiri dari library tanpa dependensi dan CLI tipis, dengan rencana pengembangan ke depan menjadi library dinamis libbedctl dengan antarmuka C
  • Dalam pelacakan tidur awal, durasi tidur pemulihan meningkat dan terbangun di malam hari berkurang, tetapi karena masih dalam tahap honeymoon setelah hanya dipakai beberapa hari, masih terlalu dini untuk menilai efek jangka panjang

Alasan membutuhkan pengatur suhu tempat tidur

  • Tidur membantu imunitas, fungsi kognitif, dan pemulihan setelah aktivitas fisik, tetapi nuansa ilmiah bisa hilang dalam headline soal kesehatan, sehingga penulis menilai penting apakah klaim didukung tenaga medis atau konsensus para ahli
  • Karena ADHD, pikiran terus berjalan sehingga sulit tertidur, dan kebiasaan membaca di tempat tidur digunakan untuk mengurangi stimulasi serta memberi sinyal waktu tidur ke sistem saraf
  • Karena karakteristik autisme, penulis sensitif terhadap tekstur dan sensasi tertentu serta juga sulit mengatur suhu tubuh, sehingga suhu dan berat selimut harus pas agar bisa tertidur
  • Apartemen baru di Portland hanya punya AC di ruang tamu dan tidak ada kipas langit-langit, sehingga kamar tidur di lantai atas menjadi ruang terpanas pada malam hari
    • Sensor suhu juga dipasang untuk memastikan bahwa kamar tidur memang area terpanas di apartemen
  • Karena tidur yang tidak teratur, konsumsi stimulan, kamar tidur yang pengap, dan sensitivitas suhu tubuh saling bertumpuk, penulis memutuskan mengeluarkan biaya untuk perangkat pengatur suhu tempat tidur

Alasan memilih Chilipad 2.0

  • Chilipad 2.0 mengendalikan suhu tempat tidur dengan menghubungkan mattress topper tipis berisi air ke perangkat yang mencakup pompa, reservoir, dan pengatur suhu
  • BedJet, yang meniupkan udara lewat kipas, dikesampingkan karena pada musim panas angin dinginnya langsung mengenai kaki
  • Eight Sleep, bahkan model termurahnya, berharga 3.000 dolar, memerlukan langganan, dan bahkan menyertakan fitur AI, sehingga tidak masuk pertimbangan pembelian
  • Chilipad adalah produk modular yang bisa dibeli mulai dari perangkat untuk satu sisi tempat tidur, sehingga harga awalnya lebih rendah
    • Jika memasang dua unit, kedua sisi bisa diatur ke suhu berbeda, berguna untuk pasangan yang punya preferensi suhu berbeda
  • Meski merupakan produk yang terhubung ke internet, perangkat ini mendukung mode pesawat dan menyediakan remote Bluetooth sebagai bawaan
    • Penulis belum memverifikasi apakah mode pesawat hanya mematikan Wi-Fi atau memblokir semua koneksi nirkabel
    • Awalnya penulis salah paham dan mengira ada API lokal, tetapi ternyata perangkat berkomunikasi dengan layanan cloud
  • Produsen menyediakan API pengembang, koleksi Postman, Swagger UI online, dan skema OpenAPI

Konfigurasi perangkat Chilipad

  • Chilipad terdiri dari dock sebagai unit kontrol dan cover tempat air bersirkulasi
    • Dock berisi pengatur suhu, pompa, dan reservoir
    • Perangkat ditempatkan di dekat kaki tempat tidur dan dekat pintu kamar untuk mengurangi udara panas dari heat exchanger agar tidak kembali menyebar ke dalam kamar
  • Cover terdiri dari tiga lapisan: lapisan dasar, hydrolayer dari membran TPU, dan cover atas
    • Dengan membuka ritsleting cover atas, pengguna dapat memasang hydrolayer di sisi tempat mereka tidur
    • Bagian atas menggunakan kain yang terasa sejuk saat disentuh dan bantalan tipis, sehingga hydrolayer tidak terasa langsung

Sleep.me API

  • Autentikasi dan contoh Postman

    • Untuk memakai API, pengguna harus lebih dulu membuat token, dan dokumentasinya hanya bisa diakses jika memiliki akun
    • Contoh Postman membantu saat detail dokumentasi kurang memadai, tetapi memerlukan akun perusahaan terpisah dan konfigurasinya juga rumit
    • Penulis lebih menyukai alternatif seperti skrip hurl open source
    • Sebagian besar contoh memiliki typo pada nama variabel
    • Harus memakai {{SleepMeAPI_Url}} yang peka huruf besar-kecil, bukan {{SleepMeAPI_URL}}
    • Contoh “Set Device Status” menetapkan set_temperature_f ke 69 dan thermal_control_status ke standby
  • Endpoint dan struktur respons

    • API menyediakan dua jenis endpoint: untuk daftar perangkat dan untuk perangkat individual
    • GET /devices: mengembalikan daftar perangkat yang terhubung ke token
    • GET /devices/{:id}: mengembalikan informasi lengkap perangkat tertentu
    • PATCH /devices/{:id}: mengubah properti perangkat
    • Tiap item di /devices mencakup ID perangkat, nama yang ditentukan pengguna, dan attachments
    • Belum jelas apakah attachments berarti perangkat lain yang terhubung
    • Respons detail dibagi menjadi objek about, control, dan status
      • about: informasi read-only seperti versi firmware, IP eksternal, IP LAN, alamat MAC, model, dan nomor seri
      • control: properti yang bisa diubah seperti kecerahan layar, unit suhu tampilan, suhu target, status kontrol suhu, dan zona waktu
      • status: status read-only seperti apakah API terhubung, apakah air kurang, level air 0~100, dan suhu air saat ini
    • Properti control dapat berbeda antar perangkat, dan kadang mengembalikan key yang tidak ada di dokumentasi seperti brightness_level
    • thermal_control_status bernilai active atau standby, dan menunjukkan apakah perangkat sedang aktif mengatur suhu
  • Nilai suhu dan kontrol perangkat

    • Suhu Fahrenheit diperlakukan sebagai bilangan bulat, sedangkan Celsius sebagai bilangan pecahan
    • Rentang normal adalah 55~115°F atau 13.0~48.0°C
    • MAX_COLD direpresentasikan sebagai -1 atau -1.0, dan MAX_HEAT sebagai 999 atau 999.0
    • Saat dalam mode siaga, status.water_temperature_* bernilai -1, tampaknya sebagai nilai sentinel, tetapi tidak didokumentasikan
    • Saat mengubah properti perangkat, cukup kirim permintaan PATCH dengan key yang ingin diubah saja di body JSON
    • Untuk menetapkan suhu Fahrenheit ke 73 saja, kirim { "set_temperature_f": 73 }
    • Tidak perlu menyertakan semua key kontrol atau membungkusnya dengan { "control": ... }
    • Cara permintaan ini dipastikan lewat koleksi Postman, bukan dokumentasi resmi

Struktur dan penggunaan bedctl

  • bedctl dibuat berpusat pada modul Zig, dan CLI-nya adalah wrapper tipis yang memanggil library tersebut
  • Namanya mengikuti konvensi memberi akhiran -ctl pada program kontrol, sekaligus mengacu pada bunyi “bed cuttle” yang terdengar seperti “bed cuddle”
  • Perintah utamanya adalah sebagai berikut
    • bedctl devices: melihat nama dan ID perangkat yang terdaftar pada token
    • bedctl status: melihat firmware, alamat jaringan, model, suhu yang diatur, status operasi, level air, dan suhu teramati
    • bedctl set temp 74: mengatur suhu target
  • Token dan ID perangkat dapat ditentukan lewat variabel lingkungan atau dikirim lewat flag --token dan --device

Alasan memilih Zig dan dependensi

  • Meski sudah memakai Rust sekitar 5 tahun untuk pekerjaan dan sejak 2018 sebagai hobi, penulis ingin umpan balik instan dan beban mental yang lebih ringan, sehingga mengimplementasikannya dengan Zig yang belakangan lebih disukai
  • Pada M1 Max MacBook Pro, zig build check --watch -fincremental diperbarui dalam sekitar 75ms
  • Satu-satunya dependensi eksternal CLI adalah argument parser yang diekstrak dan dimodifikasi dari kode TigerBeetle, lalu disesuaikan untuk Zig 0.16.0
  • Library tidak punya dependensi selain pustaka standar Zig, dan memakai std.http.Client untuk permintaan HTTP
  • CLI tidak ditautkan dengan libc, dan library dinamis di masa depan juga direncanakan tanpa libc
  • Fitur cross-compilation bawaan Zig memungkinkan pembuatan build untuk platform yang didukung tanpa perlu akses langsung ke sistem target

Model data dan sistem tipe

  • Struct inti adalah Device untuk daftar perangkat dan DeviceStatus untuk respons detail
    • Device mencakup id, name, dan attachments
    • DeviceStatus terdiri dari Device.About, Device.Control, dan Device.Status
  • Properti Control bisa saja tidak ada tergantung model, sehingga kecerahan, unit tampilan, suhu yang diatur, status operasi, dan zona waktu direpresentasikan sebagai nilai opsional
  • Alih-alih memakai string JSON mentah, penulis memanfaatkan enum anonim di Zig
    • Unit suhu adalah .c dan .f
    • Status kontrol suhu adalah .active dan .standby
  • Suhu target Fahrenheit diberi nama enum yang bermakna untuk nilai bilangan bulat tertentu
    • Daripada harus mengingat -1, bisa menggunakan .max_cold
    • Suhu biasa bisa diberikan sebagai literal bilangan bulat seperti 78
  • Penulis tidak menemukan cara untuk membatasi rentang normal 55~115°F hanya lewat tipe, dan juga tidak melakukan validasi terpisah sebelum mengirim permintaan
  • Nilai Celsius berupa pecahan sehingga rentang yang diizinkan juga tidak bisa diekspresikan lewat tipe

Pengalaman mengimplementasikan klien HTTP Zig

  • Klien HTTP standar Zig memerlukan prosedur tingkat rendah dibanding abstraksi sederhana URI, body, dan send
    • Membuat objek URI
    • Mengubah URI agar menunjuk path
    • Membuat objek request dengan URI dasar, header, dan konfigurasi koneksi
    • Mengirim header request
    • Menerima header respons
    • Membuat reader untuk body
    • Mengonsumsi body respons dari reader
  • Kontrol yang detail memang memungkinkan, tetapi tidak seperti Rust yang memungkinkan turun ke level rendah hanya saat dibutuhkan, di Zig rasanya terus-menerus melakukan pekerjaan tingkat rendah
  • Implementasi /devices mengirim request GET dengan header autentikasi lewat sendBodiless(), lalu membaca respons hingga maksimum 64.000 byte dan mem-parsing JSON menjadi []const Device
  • Meski memakai parseFromSliceLeaky, tidak ada masalah pembebasan memori berkat konfigurasi arena allocator yang tidak diekspos ke luar

Rencana ekspansi ke library dinamis

  • Tujuan akhirnya adalah membuat library dinamis tanpa dependensi yang bisa digunakan dari bahasa tingkat tinggi
  • Struktur yang direncanakan adalah sebagai berikut
    • Modul Zig bedctl
    • CLI bedctl yang langsung memakai modul Zig
    • libbedctl yang menyediakan antarmuka C untuk modul Zig
    • bedctl-dl yang memakai library dinamis dan sekaligus memverifikasi sendiri antarmuka C tersebut
  • Jika nanti ada wrapper Python, penulis ingin memakainya di Home Assistant, tetapi tidak berencana menulisnya sendiri
  • Build dan antarmuka library dinamisnya belum siap dan direncanakan akan ditambahkan dalam waktu dekat

Pengalaman tidur setelah dipakai beberapa hari

  • Selama beberapa hari pemakaian, penulis secara subjektif merasa tidur lebih nyenyak, dan fitness tracker juga menunjukkan fase tidur pemulihan yang lebih panjang serta lebih sedikit terbangun di malam hari
  • Bahkan pada hari minum whiskey, tidur terasa lebih baik dari biasanya, tetapi ini tidak boleh ditafsirkan sebagai alkohol baik untuk tidur
    • Alkohol tetap buruk bagi kesehatan dan tidur; kemungkinan perangkat ini hanya sedikit mengurangi penurunan kualitas tidur
  • Karena perangkat baru dipakai beberapa hari dan bedctl juga ditulis hanya dalam sekitar 3 malam, hasilnya masih berada pada tahap honeymoon
  • Saat awalnya suhu diatur terlalu rendah, ada sensasi dingin seperti berbaring di tempat basah, tetapi hilang setelah suhunya disesuaikan
  • Waktu transisi tidak diukur secara langsung, tetapi terasa cepat, lebih mendekati 1 menit daripada 10 menit
    • Air yang dibutuhkan untuk mengisi kurang dari 1 galon, jadi kapasitas panas yang harus dipanaskan atau didinginkan tidak besar

Penggunaan remote, kipas, dan pemanas

  • Remote bawaan berbentuk dial besar dengan layar sentuh, sehingga mudah langsung mengubah suhu saat sedang menyesuaikan jadwal suhu
  • Tekstur dial-nya tidak terlalu memuaskan, tetapi ada getaran pada tiap unit suhu sehingga bisa disesuaikan tanpa melihat layar
    • Bahkan saat memakai masker tidur, perubahan tetap bisa diketahui lewat umpan balik haptik
  • Penulis juga tetap membutuhkan aliran udara lemah, dan sebelumnya harus menyeimbangkan antara mendinginkan ruangan serta menghindari hembusan langsung ke tubuh atau membuat saluran napas kering
  • Setelah memakai Chilipad, kipas cukup dinyalakan di tingkat paling rendah saja
  • Menaikkan suhu sedikit di pagi hari terasa nyaman, dan pada musim dingin penulis menantikan fitur pemanasan awal tempat tidur
  • Memasang topper ini sedikit mengurangi sirkulasi udara dari bawah
    • Rasanya bukan seperti berbaring di atas plastik, tetapi pada suhu yang lebih tinggi kulit yang menyentuh tempat tidur terasa sedikit lembap oleh keringat
    • Ini adalah pengalaman pribadi terkait cara tubuh penulis mengatur suhu, jadi belum tentu sama bagi pengguna lain
  • Kesan awalnya secara keseluruhan positif, dan ada kemungkinan penulis akan memposting tindak lanjut setelah library dinamis selesai dibuat

1 komentar

 
GN⁺ 17 jam lalu
Komentar di Lobste.rs
  • Sesuai topiknya, tulisan ini diposting tepat sebelum tidur

    • Penasaran apakah kalau bedctl diatur untuk menurunkan suhu sangat rendah pada waktu tertentu, bisa juga dipakai untuk membangunkan tidur
  • Judul dan tulisannya sama-sama bagus. Penasaran apakah pernah mencoba selimut berbobot, dan apakah benar-benar efektif

    • Dulu pernah memakai selimut berbobot dan secara umum suka, tetapi dibuang saat pindahan. Namun, itu tidak membantu pengaturan suhu tubuh, jadi bukan solusi yang diinginkan di sini
      Tergantung cara pembuatannya, sirkulasi udaranya bisa buruk dan harganya juga bisa mahal. Setelah membeli Chilipad, agak canggung juga menyebutnya mahal, tetapi produk yang saya ingat untuk dilihat lagi nanti adalah https://bearaby.com/products/tree-napper, yang strukturnya berupa tenunan terbuka dan tampak punya sirkulasi udara yang baik
  • Sempat mencari-cari produk seperti ini dan suatu saat berniat mencobanya sendiri. Menurut video ini, solusi dengan nilai terbaik adalah ember, tetapi dalam kasus itu sepertinya tidak ada API

    • Saya juga menonton video itu, tetapi ember Home Depot sepertinya tidak akan lolos uji persetujuan pasangan yang bahkan sebenarnya tidak ada 😅
  • Tulisan yang agak terkait: https://trufflesecurity.com/blog/removing-jeff-bezos-from-my-bed (diskusi)

  • Sepertinya pada bagian yang membandingkan Fahrenheit dan Celsius, maksudnya bukan menulis Celsius is the better temperature

  • Tulisannya menarik dan saya cukup sepakat dengan cara berpikirnya, termasuk bagian tentang kipas, tetapi tidak jelas apa yang akhirnya bisa dikendalikan lewat pekerjaan ini
    Paragraf yang mengatakan bahwa pengalaman PhD fisika membuatnya meragukan liputan terkait sains dan kesehatan sampai terbukti bisa terbaca ke arah yang berbahaya, mirip ketidakpercayaan terhadap vaksin. Namun, saya memahaminya sebagai maksud bahwa masa PhD membuatnya tidak menerima “fakta” dari media secara hitam-putih, dan saya penasaran secara spesifik apa yang meninggalkan luka

    • Intinya justru kebalikannya. Karena menjadi fisikawan tidak membuat intuisi saya tentang kedokteran menjadi istimewa, pilihan terbaik adalah mengikuti pakar yang meneliti bidang tersebut, bukan membaca beberapa artikel lalu berpura-pura menjadi dokter. Itu bukan patuh buta pada otoritas, melainkan mengakui kemungkinan diri sendiri salah, dan berharap orang lain juga menghormati keahlian saya pada sedikit bidang yang saya teliti
      Ketika makalah vaksin Andrew Wakefield keluar, orang-orang yang hanya membaca artikel singkat dari jurnalis yang membaca abstraknya menyatakan dengan tegas bahwa vaksin mutlak berbahaya, dan bahkan guru biologi SMA bergelar magister zoologi serta tiga PhD fisika ikut menentang vaksin. Namun, konsensus komunitas medis tetap bahwa vaksin aman, efektif, dan merupakan salah satu sarana paling ampuh untuk menyelamatkan nyawa, dan semua peneliti medis yang saya temui juga sepakat
      Alasan masa PhD melukai saya adalah karena saya melihat betapa besarnya jurang antara temuan nyata di bidang saya dan pemberitaan media. Kita tidak bisa sepenuhnya memahami semua bidang, jadi untuk kedokteran kita perlu memercayai dokter, untuk lingkungan memercayai ekolog, dan untuk iklim memercayai klimatolog. Saya pernah melihat para PhD fisika “membantah” para ahli dengan matematika setingkat SMP dan sains setingkat SD, tetapi pakar sebenarnya tahu ada jurang besar antara pengetahuan tingkat sekolah dan pengetahuan tentang realitas. Karena saya menyaksikan jurang itu di bidang yang saya pelajari, saya justru menjadi lebih memercayai para ahli di bidang yang tidak saya pelajari
  • Kalau field bisa dilempar sembarangan dalam struktur yang diinginkan, hampir pasti handler-nya melakukan pencarian regex seperti re.search('set_temperature_f\": (\\d+)',...)