世界を動かす技術を、日本語で。

古いKindleをハッキングしてバスの到着時刻を表示する

概要

  • 古いKindle をバス到着時刻表示デバイスに改造する手順の解説
  • Jailbreak、KUAL/MRPI導入、SSH設定 などのハック方法を詳述
  • サーバー構築・画像生成・KUALアプリ作成 までの全工程を網羅
  • トラブルシューティングや工夫点 も実体験をもとに紹介
  • 運用後の課題や応用例 についても言及

古いKindleをバス到着時刻表示デバイスに改造する方法

  • Kindle Touch 4th Generation/K5/KT などの古いKindleを活用したIoTデバイス化
  • リアルタイムでバス到着時刻 を1分ごとに更新表示
  • ダッシュボードモード からはメニューボタンで簡単に退出可能
  • TRMNLのような高価な専用端末 を自作で再現

準備と主要ステップ

  • Jailbreakの実施
    • Kindleの機種・ファームウェアバージョンを特定
    • 適切なtarファイル ダウンロードとJailbreak手順の実行
  • KUAL & MRPIのインストール
    • KUAL:Kindle用カスタムアプリランチャー
    • MRPI:カスタムアプリのインストール支援ツール
    • Hotfixの適用 が必要な場合あり
    • OTAアップデートの無効化 も推奨
  • SSH環境の構築
    • KUAL拡張のUSBNetwork を利用しSSH接続を実現
    • MRPI経由でKUAL拡張をインストール する手順に注意
    • SSH接続成功後、Kindleがネットワークデバイスとして認識される

サーバーと画像生成

  • Kindle用画像サーバーの構築
    • NJTransitのGraphQL API からバス到着時刻データ取得
    • curlコマンド でデータ取得例を紹介
    • HTML→PNG画像生成 にはpuppeteerではなく wkhtmltoimage を採用
      • 低コストサーバー (例:Digital Ocean $6プラン)でも安定運用
      • cronで3分ごとにPNG生成 し、Kindleが取得できるようにエンドポイントを用意
  • 画像の解像度・回転処理
    • eipsコマンド でKindle画面に画像表示
    • Kindleの画面解像度(例:600x800) に合わせて画像生成
    • 画像の回転・位置調整 にはCSSのtransform(rotate, translate)を利用

KUALアプリの作成

  • ダッシュボード起動・終了を柔軟に制御
    • KUAL用のカスタム拡張 を/mnt/us/extensions/配下に配置
    • menu.jsonでメニュー項目を定義 し、bin/start.shでダッシュボード起動
    • trapコマンド でシグナル(HUP, TERM)を無視し、スクリプトの早期終了を防止
    • rtcwakeコマンド でスリープ・復帰制御(デバイス選択に注意)
    • refresh_screen関数 で画像取得・画面クリア・日時/バッテリー表示を実装
    • evtestコマンド でメニューボタン押下を監視し、stop.shでダッシュボード終了

運用・課題・応用

  • 色残り(color bleeding)対策
    • 画面を完全黒→白でフラッシュしてリセットする案を検討中
  • バッテリー寿命
    • 約5日間稼働可能、夜間10時間オフで2日延長
    • 2週間稼働を目指しつつ、1分更新のリアルタイム性は維持したい
  • 応用可能性
    • バス時刻以外にもカレンダー・天気・タスク表示 など、e-ink画面の情報端末化が可能
    • 毎日の実用性とカスタマイズ性の高さ を実感

まとめ

  • 古いKindleの再利用・IoT化の実践例 として高い応用力
  • Jailbreakからカスタムアプリ開発まで一気通貫のノウハウ を公開
  • 低コスト・高カスタマイズ性 で日常生活の利便性向上を実現

Hackerたちの意見

Kindleを単機能のタブレットやインターフェース、ディスプレイとして使うのが大好きなんだ。実は、eInkよりもLCDディスプレイの方が好きな変わり者なんだけど、Kindle Fireを開発モードにするのがめちゃくちゃ簡単で、ウェブページを表示させたり、電源に繋いでる間はずっとオフにならなかったり、広告も出ないようにできるんだよね。Kindle Fire HD10はだいたい40ドルくらいで手に入るよ。

Kindle Fireについて知れてよかった!それに、LCDの方がe-inkより好きな理由もわかるよ。ゴーストイングがないし、真っ暗な中でも読めるのはダッシュボードにとって最高のアップグレードだね。

なんか、このプロジェクトがこれを思い出させるな: https://engineersneedart.com/systemsix/systemsix.html

わお、これめっちゃクール!カスタムマウント作りたくなっちゃう。

Kindleはハックしたり遊んだりするのが楽しいデバイスだよね。古いKindleをeBayで15〜20ユーロで手に入れられるし、去年も同じことやってすごく楽しんだよ。 https://samkhawase.com/blog/hacking-kindle/

大好き!他の人が同じ製品にたどり着くまでの道のりを見るのはいつも楽しい。君の投稿を見て、Cloudflare Developer PlatformのCloudflare Workersみたいなことをもっと試してみたくなったよ。

リバースエンジニアリングが得意じゃない人向けに、Raspberry PiのDSIポートに接続できる同じくらいのサイズのe-inkディスプレイが、AliExpressで5ドルくらい高く売ってるよ。もしかしたら、古いKindleのスクリーンを再利用したものかもしれないね。

すぐに脱獄を始められるの?それとも、最初の設定でインターネット接続とAmazonアカウントが必要なのかな?

何年も前にKindleの電力消費について作業していた者として言わせてもらうと、最大の電力消費源の一つはWiFi接続なんだよね。WiFiが切れないように、APに応答するために起き上がる必要があるから、数秒ごとに切断されないようにしないといけない。ざっくり言うと、WiFiなしの平均消費電力は約700μAで、WiFiありだと約1.5mA±だったと思う。もう10年以上前のことだから、記憶が曖昧だけど…。ページの切り替えも結構な電力を使ってたのは確か。正確な数値は覚えてないけど、数秒で100mA以上は使ってたと思う。記事の著者が見たゴーストイングの問題を解決するために、「xページごとに全画面リフレッシュ(黒から白)」もあったよ。

すごいヒントだね!リフレッシュ間隔を2分に増やして、リフレッシュの間はWiFiを切ってみることにするよ。これでバッテリー寿命が良くなるか試してみる。ちなみに、これでKindleの飛行機モードでのバッテリー寿命がすごく良い理由もやっと分かった!

自分のKindleからバッテリーを外して、バッテリーチップはそのままにして、バッテリー端子に5Vを供給したんだ。KindleのUSBコネクタから、ダイオードを通して(だいたい4.4Vくらい)。バッテリーなしだと、短いバーストで少なくとも1.5Aを供給できるものが必要なんだ。古いUSBハブがうまく機能して、ハブはRaspberry Piに接続されてる。USBネットワーキングを通じてSSHを使ってるから、WiFiもバッテリーもなしで、数ヶ月間問題なく動いてるよ。

Kindleの周りに小さなアモルファスシリコンの太陽電池を貼り付けたら、5日ごとに充電しなくても足りるかな?

これ最高!電子インクやKindle関連のディスプレイを見るのが大好きなんだ。ちょっと前にHNの記事を見た気がするけど、時間が経つのは早いもので、それが2024年のことだった!これがそのリンクだよ: https://lilymara.xyz/posts/2024/01/transit-kindle/ これは https://news.ycombinator.com/item?id=41923753 からのもので、著者はKindleでピクセルパーフェクトな画像をレンダリングするところから、Rustで別のHTTPサーバーを構築するところまで進化したんだ!関連リンク: https://news.ycombinator.com/item?id=37661387

しばらく前に、TRMNLのKindleクライアントをBashからLuaに書き直して、ちょっと最適化したんだ。5分ごとにリフレッシュするようにしたら、Kindle Paperwhite第10世代が充電1回で約5〜6日持つようになったよ。https://github.com/mbirth/trmnl-kindle/tree/lua-rewrite

すごい仕事だね!元々のKindleプロジェクトには確かにクセがあるから、今はKOReaderオプションも提供してるよ。https://github.com/usetrmnl/trmnl-koreader/

もっとシンプルな方法を選んだよ。脱獄してSSHを使った後、Kindleに2つのスクリプトを作ったんだ。1つは毎分トリガーされ、もう1つは30分ごとにトリガーされる。どちらも同じ場所から同じ画像を描画するけど、30分の方はフルリフレッシュも加わる。これで、毎分フルリフレッシュするわけじゃないけど、時間が経つにつれて画像が劣化するから、30分ごとにフルリフレッシュするのがちょうどいい感じ。Kindleはとてもシンプルな仕事をしていて、アプリもインストールされてないし、ただ2つの追加のcronジョブで画像を描画するワンライナーのBashスクリプトを実行してるだけ。新しい画像はRaspberry Piからrsyncを使って毎分プッシュしてるよ。その画像は、Raspberry Pi側で空気質データを使ってPythonスクリプトで組み立ててる。ローカルのMySQLサーバーに接続して、値を引っ張ってきてから組み立てるんだ。

もっとシンプルな方法 ... Raspberry Piからrsync ... Pythonスクリプト ... 空気質データ ... ローカルMySQLサーバー なんか微笑んじゃった。

かなりシンプルなeInkディスプレイで、できることは一つ、指定した場所にビットマップを受信して表示するだけで、いろんな用途に十分だよね。Wi-FiかZigbeeに安全に接続する方法があればいいんだ。例えば、TLSを使うとか。

こういうプロジェクトを見ると、古い電子機器の引き出しを漁りたくなるよね。hex4def6の電力消費の内訳もすごく参考になるし、Wi-Fiが主な電力消費源ってのが分かると、こういうe-inkダッシュボードプロジェクトがUSB経由でPiに頼る理由も納得できる。キッチンのレシピ表示用の似たようなセットアップを考えてたんだ。e-inkはチラ見するのにぴったりで、朝6時に目を焼くバックライトもないし、常に表示されてるから画面を起こす必要もない。データが数分ごとにしか変わらないなら、遅いリフレッシュレートも逆にメリットになるよね。

すごくクールだね!

もっとシンプルな方法を選んだよ:OneBusAwayのiOSアプリをゼロからSwiftフレームワークのペアとして作り直したんだ。これならどこでも動くし、tvOSでも使えるよ[1]。それから、OneBusAwayサーバーをGolangでゼロから作り直す新しいプロジェクトを始めたんだ[2]。さらに、インターンを雇ってStainlessの上に素晴らしいSDKのセットを作ってもらった[3]。最後に、昨夏にGoogleにインターンの費用を出してもらって、どのブラウザでも動くSvelteKitでサインモードのUIを作ってもらったんだ[4]。簡単だよね!でも本気で言うと、もしあなたの交通機関がGraphQLエンドポイントを提供してないなら、OneBusAway Maglevサーバーが交通機関のスケジュールやリアルタイムデータを取得するのにすごく簡単な方法だと思うよ。私たちのSDKやアプリは、その情報を視覚化するのに素晴らしい方法だし、常にプロジェクトを手伝ってくれるソフトウェア開発者を探してるんだ。ユーザーエクスペリエンスやプロダクトマネジメント、ビジネス開発やマーケティングなどの分野でボランティアしてくれる人も大歓迎だよ。興味があったら、aaron@onebusaway.orgまで気軽に連絡してね。私たちのソフトウェアは、シアトルやニューヨーク市を含む世界中の都市で毎日何百万人にも使われてるんだ。 ---- [1] https://github.com/oneBusAway/onebusaway-ios/ [2] https://github.com/OneBusAway/maglev [3] https://developer.onebusaway.org/api/sdk そしてStainless(これは本当に素晴らしい製品だよ)は https://www.stainless.com にあるよ。[4] https://github.com/oneBusAway/waystation