ファームウェア段階リリースのcliを作った話

FOTAはフォタと読んでいますよね? エンジニアの@maaashです。
この記事は Nature Remo Advent Calendar 2022 - Adventar の8日目の記事です。

adventar.org

今日は、先日のBitkey x Nature / IoTぶっちゃけNight Vol.2 でお話ししたNature社のFOTAcliについて書きます。

背景

Nature RemoやRemo EなどNature社のハードウェアプロダクトは、セットアップ後、家のWi-Fiアクセスポイント、インターネットを通してNature社のクラウドに接続します。 Websocketでクラウドと双方向通信することで、エアコンなど家電の遠隔操作やセンサ情報をアプリで表示する、といった機能を実現しています。

この同じルートで、デバイスクラウドからファームウェアをダウンロードし、自身のファームウェアを上書きすることを、 FOTA (Firmware Over The Air) update と言います。

FOTA

FOTAは、以下の点から大事です。

上記のリンク先のように過去Natureのエンジニアが発表してきた成果も、開発後に買っていただいた方に限らず、すでに購入いただいた方にもFOTAを通して使われています。

NatureのFOTAの仕組み

Natureには大きく分けると2種類のFOTAの仕組みを持っています。

  • 自動アップデート

    優先度が非常に高く全台に対してアップデートを行いたい場合のみ使う

  • 手動アップデート

    • ユーザーが新しいバージョンに気づいてアップデート
    • セットアップ直後に新しいファームウェアがあればアップデート

新しいバージョンがあると、Nature Remoアプリ内で、以下のようにアップデートがあることを案内します(手動アップデート)。

手動アップデート - FOTA

課題

このようにFOTA機能はありましたが、 FOTA対象は以下のように荒い区分しかない、と言うのが現状でした。

  1. ある個体に新しいバージョンをリリースする
  2. 社内ユーザーのみに新しいバージョンをリリースする
  3. 全ユーザーに新しいバージョンをリリースする(ドン)

これにより、

  • ファームウェアリリースで事故が発生したときの被害が大きい

    • オペレーションミスで間違ったバージョンをリリースしてしまった
    • リリースしたファームウェアに重大な問題があった
  • 大きな変更を加えたときに CS チームの負担が大きい

といった理由から、気軽に使えない問題がありました。 そこで次のような機能が求められていました。

  • 公開範囲 (割合) を指定してファームウェアをリリースできる

    全ユーザーの10%, 20%, .. 100%のように少しずつ広げたい 社内ユーザー、ファームウェアエンジニア、その中のサブグループ

  • 現在の公開範囲を見たい

  • 段階リリースで事故ったときに、段階リリースの対象になっているユーザーにだけ新しいファームウェアを配りたい

nature-cli

ところで、Nature社のバックエンドはGo言語を採用していまして、 レポジトリルートで make build すると natureというシングルバイナリができます。

natureバイナリは以下のように、本番のAPIサーバを実行する際にも、手元の開発環境を整えたり、FOTAを実行する際にも使っています。

  • bin/nature serve   APIサーバが動く
  • bin/nature deploy db データベースを最新バージョンにマイグレーションする
  • bin/nature fotav2    FOTA関連のコマンド

良いcliコマンドを作りたい

良いインターフェースに囲まれていたい、と言う気持ちは思い出せばNature Remoの前身のIRKitを作ることになった一つの欲求でありました。

そこで、ファームウェア段階リリースのcliを作るにあたり、ファームウェアエンジニアがcliを使う際にどのようなUIが良いのか、考えていました。

自分にとって、複雑なのに使っていて気持ち良いcliコマンドを思い出すと...

  • git add, git pull, git push

    stage, commitの概念

  • docker run, docker images

    Dockerイメージ, レジストリの概念

やろうとしている操作の概念がある程度理解できて、操作とコマンド名の英語がマッチすることは大事だなと思います。

ファームウェア段階リリースのイメージとcliコマンド

ファームウェア段階リリースのイメージはこんな感じです。

ファームウェア段階リリースのイメージ

staff, devなどの名前付きのグループがあり、また10%, 30%など全ユーザーに対する割合があるのでしょう。

それぞれのグループは異なるバージョンのファームウェアを持つことができ、あるユーザーが複数のグループに属する場合にどちらのグループが勝つかを表す優先度を持ちます。 このようなグループを、(gitやdockerに倣って良い名前をつけようとして)release-group としました。

ファームウェアをあるrelease-groupにリリースする、という操作をcliから行います。

ファームウェア段階リリースのリリース

このコマンドを

fotav2 release 30% remo3 1.1.1

のようにしてcliを使います。 また、release-groupをコピペするようにして作る時には..

fotav2 release-group clone staff dev 30

です。同様に削除する際には

fotav2 release-group remove dev

まとめると以下のようになりました。

fotav2 release {release-group:staff|beta|10%|etc} {product model} {firmware version}
fotav2 release-group clone {from name: staff|10%} {to name: dev|30%} {priority}
fotav2 release-group remove {name}

困ったら
fotav2 release -h
fotav2 release-group -h

Slack通知もあるよ

まとめ

ファームウェアを段階的にリリースできる機能を作りました。

  • backendではcliコマンドから叩くAPIを作っています

    よく使うcliコマンドに倣ってデザインしました

  • fotav2コマンドは毎日のように使われています

    CIでも使ったりするといいね

同業の方がどうしているか、聞いてみたいです! よろしければTwitter@maaashに教えてください。


このプレゼンをした際の発表資料はこちらです。

www.slideshare.net


エンジニア積極採用中です

Natureでは一緒に開発してくれる仲間を募集しています。

採用情報 | Nature株式会社

カジュアル面談も歓迎なので、ぜひお申し込みください。

Natureのミッション、サービス、組織や文化、福利厚生についてご興味のある方は、ぜひCulture Deckをご覧ください。

speakerdeck.com