Go で祝日判定をする github.com/soh335/shukujitsu を書きました

こんにちは北原です。

Natureのバックエンドはおおよそ Go で書かれています。3月にリリースしたNatureスマート電気も同じく Go で実装されています。

energy.nature.global

Natureスマート電気を作るにあたって、いわゆる営業日の計算をする必要があり*1、当時小さく、メンテナンスを自分でしていける Go のライブラリがなかったので github.com/soh335/shukujitsu というものを作りました。

github.com

インターフェイスとしては与えられた日付が祝日かどうかを判定するもののみを提供しており非常にシンプルな作りになっています。

if shukujitsu.IsShukujitsu(time.Now()) {
    fmt.Println("shukujitsu!")
}

こちらは内閣府から提供されている csv データをもとに作成されています。 csvのファイル名が syukujitsu.csv や、過去様々な変遷がありましたが、現在は安定して提供されています。

github.com/soh335/shukujitsu では GitHub Actions を利用し毎週こちらをチェックし*2差分があった場合は自動で pull request が作られるようになっていて、それをマージしリリースすることで新しいデータを参照できるようになります。こちらは東京オリンピックの都合で海の日、山の日、スポーツの日が移動した際の pull request になります。

github.com

また、cli も提供されており

$ shukujitsu || somecmd

のようにすると祝日の場合は実行しないということも可能です。こちらは fujiwara さんに追加していただきました。


Nature では Nature Remo, Nature Remo E, Nature スマート電気を組み合わせ新しい体験を提供していきたいと思っています。 カジュアル面談も常に募集していますので興味がある方は是非話してみませんか。

herp.careers

*1:小売電気事業者を切り替える際は標準的には切り替え元、切り替え先事業者が切り替えをることを承諾した日に加え1営業日、2暦日をあける必要があります

*2:リポジトリに60日アクティビティがないと止まってしまうという制限があります。 ワークフローの無効化と有効化 - GitHub Docs

Remo ユーザの家電操作を可視化してみた

機械学習エンジニアの原 @toohsk です。

ユーザの皆さんに使っていただくなかでNature Remo は4周年を迎えることができました、ありがとうございます。
今回は、Nature Remo シリーズが日常でどのような時間帯にどのような家電を操作しているのか?を可視化したので、紹介していきたいと思います。

何をしたの??

今回は2021年9月にNature Remo から家電にコマンドを送信した曜日 × 時間帯をヒートマップとして可視化しました。 また、Nature Remo 単位で利用した曜日 × 時間帯をヒートマップとして可視化しました。

何でこの分析をしたの??

一般的にサービスを開発していく中で、このような使われ方をされるのではないか?しているのではないか?などの想像が働くことがあります。このような想像をふくらませるときに想像者の原体験に左右されてしまい、マイノリティなケースに引っ張られすぎてしまうということがあります。

実際のNature Remo の操作ログから、どのように使われているのか?どの時間に操作されているのか?を具体的に知ることは、上記のことを防ぐだけでなく、サービス開発で広範なことに役立ちます。
例えば、

  • 新機能を開発する上で現製品がどのように使われているのかを把握する
  • どのような利用シーン(時間帯や曜日、ユーザのデモグラ)が多いのか
  • どの時間にメンテナンスをすればユーザへの影響が少なくなるか
  • 障害時にどの程度のユーザに影響が出てしまうのか

などがあります。

今回は、今後さらに使い勝手の良いサービス開発のために、Nature Remo の操作ログを可視化していきました。

ヒートマップ

私たちは、 自然との共生をテクノロジーでドライブする というミッションを掲げています。
なので、今回のヒートマップはSeaborn のocean_r カラーマップで表現してみました。 少し見にくいところがあるかもしれませんが、ご容赦ください。

ヒートマップの意味合いとしては、その表の単位で集計したときに相対的に高い、相対的に低い位置を色味で表現し、視覚的に把握できる意味合いがあります。 今回採用したカラーマップにおいて、各色が表現する意味合いは

白 < 薄い青 < 濃い青 < 緑

という並びで相対的な関係を表現しています。

f:id:toohsk:20211026113946p:plain
カラーパレットの頻度表現

また、実際の頻度の情報はあえて隠して表示してあります。

では、実際に可視化の結果を見ていきましょう。

コマンド送信数と特徴

f:id:toohsk:20211026113041p:plain
コマンド送信数のヒートマップ

コマンド送信数の特徴として以下が挙げられると思います。

  • 夜の時間帯では、どの曜日でも多く活用していただけており、メインの時間帯である
  • 一方、日中の時間では、土日は平日よりも多く活用していただけている
  • また、平日の朝の時間帯も活用していただけており、外出前の少ない時間を有効活用するために使っていただけている

コマンド送信したNature Remo 数と特徴

f:id:toohsk:20211026114110p:plain
コマンドを送信したNature Remo のヒートマップ

コマンド送信したNature Remo数の特徴として以下が挙げられると思います。

  • 活用されているNature Remo 単位で見ると、よりどの時間帯で使われているかがわかり、コマンド送信数の特徴が色濃く表現されている
  • 1つのNature Remo に対して、複数回の操作が行われている

どこから操作しているの??

Nature Remo を操作する方法はいくつかありますが、よく使われている方法としては、

の3つがあり、これらの3つについてどの時間帯で使われているのか?を可視化していきます。 それぞれコマンド送信数と操作されたNature Remo 数の2つの軸でヒートマップを6枚作ってみました。

ヒートマップ

コマンド送信数

アプリ

f:id:toohsk:20211027095738p:plain
アプリからNature Remo へのコマンド送信数

アプリからNature Remo へのコマンド送信数の特徴として以下が挙げられると思います。

  • 18時 ~ 0時の時間帯でよく使われている
  • 日中の時間帯では、平日に比べ土日は多く使われている
  • 就寝の時間はほぼ使われていない

Amazon Alexa

f:id:toohsk:20211027095857p:plain
Amazon Alexa からNature Remo へのコマンド送信数

Amazon Alexa からNature Remo へのコマンド送信数の特徴として以下が挙げられると思います。

  • 17時 ~ 0時の時間帯でよく使われている
  • 平日の朝に多く活用されており、少ない時間を効率よく使えるようにするため、スマートスピーカからシーン機能が使われている
  • 就寝の時間はほぼ使われていない

Google Assistant

f:id:toohsk:20211027095806p:plain
GoogleアシスタントからNature Remoへのコマンド送信数

Google Assistant からNature Remo へのコマンド送信数の特徴として以下が挙げられると思います。

  • 多少の違いはあれど、Amazon Alexa とほぼ同じ配色パターンが示されているので、Amazon Alexa ユーザと同じ活用のされ方をしている

操作されたNature Remo 数

アプリ

f:id:toohsk:20211027101814p:plain
アプリから操作されたNature Remo 数

アプリから操作されたNature Remo 数の特徴として以下が挙げられると思います。

  • 18時 ~ 0時の時間帯でよく使われている
    • 特に土日の0時 ~ 1時にコマンド送信されたNature Remo 数が多く、生活の時間帯が平日と比較すると遅くずれていることがわかります
  • 平日の日中において、コマンド送信数は多くなかったものの、操作されたNature Remo 数は多い傾向にある
    • 外出時でもアプリから家電が操作されていると考えられます

Amazon Alexa

f:id:toohsk:20211027101855p:plain
Amazon Alexa からコマンド送信されたNature Remo 数

Amazon Alexaから操作されたNature Remo 数の特徴として以下が挙げられると思います。

  • 17時 ~ 0時の時間帯でよく使われている
    • アプリと異なり土日の0時に操作された台数は平日と大きな差はみられない
  • 土日の日中においても、操作されたNature Remo 数は多く、活動しやすい時間帯では定常的に使っていただけている

Google Assistant

f:id:toohsk:20211027101938p:plain
Google アシスタントからコマンド送信されたNature Remo 数

Google Assistantから操作されたNature Remo 数の特徴として以下が挙げられると思います。

  • 操作数と同様に多少の違いはあれど、Amazon Alexa ユーザと同じ活用のされ方をしている

どのような家電が動いているの??

続いて、Nature Remo から操作した家電を曜日 × 時間帯で見ていこうと思います。 Nature Remo に登録されている代表的な家電は

  • テレビ
  • 照明器具
  • エアコン

の3つがあり、この3つの家電に対して、どの時間帯で使われているのか?を可視化していきます。それぞれコマンド送信数とコマンド送信したNature Remo 数の2つの軸でヒートマップを6枚作ってみました。

ヒートマップ

コマンド送信数

テレビ

f:id:toohsk:20211026134057p:plain
テレビへのコマンド送信数

テレビ操作の特徴として以下が挙げられると思います。

  • 夜の時間帯では、どの曜日も活用していただけている
  • 朝の時間帯では、平日は6時 ~ 8時の時間で活用していただけている
  • 平日の日中と比較すると、土日の日中のほうが活用していただけている

照明器具

f:id:toohsk:20211026134720p:plain
照明器具へのコマンド送信数

照明器具操作の特徴として以下が挙げられると思います。

  • 夜の時間帯では、どの曜日も活用していただけている
    • テレビよりも遅い時間で多くコマンドが送信されている
  • 朝の時間帯では、平日は6時 ~ 7時の時間で活用していただけている
  • 平日の日中と比較すると、土日の日中のほうがわずかに多く活用していただけている

エアコン

f:id:toohsk:20211026134907p:plain
エアコンへのコマンド送信数

エアコン操作の特徴として以下が挙げられると思います。

  • 夜の時間帯では、どの曜日も活用していただけている
    • テレビと照明器具よりも広い時間帯で多く活用していただけている
  • 朝の時間帯では、平日は6時 ~ 8時の時間で活用していただけている
  • 他の家電と比較すると
    • 平日の日中であっても活用していただけている
    • 土日の日中も多く活用していただけている

コマンド送信したNature Remo 数

テレビ

f:id:toohsk:20211026140243p:plain
テレビへコマンド送信したNature Remo数

テレビ操作を行っているNature Remo数の特徴として以下が挙げられると思います。

  • 夜の時間帯では、どの曜日も多くのNature Remo が活用していただけている
  • 朝の時間帯では、平日は6時 ~ 8時の時間で多くのNature Remo が活用していただけている
  • 平日の日中と比較すると、土日の日中のほうが多くのNature Remo を活用していただけている
  • 0時 ~ 1時の時間帯において、平日と土日を比較すると、土日のほうがNature Remo を活用していただけており、土日のほうが多少夜ふかし気味であることがわかります

照明器具

f:id:toohsk:20211026140828p:plain
照明器具へコマンド送信したNature Remo 数

照明器具操作の特徴として以下が挙げられると思います。

  • 23時 ~ 0時では、どの曜日も活用していただけている
    • Nature Remo 単位で見ると、より就寝時間に活用されている
  • 朝の時間帯では、平日は6時 ~ 7時の時間で活用していただけている
  • 平日の日中と比較すると、土日の日中のほうがわずかに多く活用していただけている

エアコン

f:id:toohsk:20211026141452p:plain
エアコンへコマンド送信したNature Remo数
エアコン操作の特徴として以下が挙げられると思います。

  • コマンド送信と同様に、夜の時間帯では、どの曜日も活用していただけている
    • テレビと照明器具よりも広い時間帯で多くのNature Remo が活用していただけている
  • 他の家電と比較すると就寝時間にNature Remo を活用していただけている
  • 室温などをトリガーにした方法でNature Remo を活用して、エアコンを操作できている
  • 土日では、12時以降に活用していただけるNature Remo 数が徐々に増えている

最後に

2021年9月の一月分だけでしたが、Nature Remo の活用状況を可視化してみました。 日常生活に深く紐付いてNature Remo が活用されていることが確認できたと思います。

Nature ではNature Remo とNature スマート電気を組み合わせて、生活の心地よさを向上しながら自然への負荷を低減するサービスを開発していくエンジニアを募集しています。
カジュアル面談から雑多に話すこともできますので、ご気軽に応募してください!

nature.global

特に、生活の心地よさの向上と自然への負荷低減を両立は、データの活用と価値をユーザに還元することが重要だと思います。
そのようなデータの活用をしていくエンジニアも募集しています!

herp.careers

React Native Matsuri 2021 で発表を行いました

北原です。10月2日に React Native Matsuri 2021 にて React Native in Nature というタイトルで発表を行いました。

reactnative-matsuri.com

Nature では2018年当時に iOS, Android それぞれ開発を行なっていましたが React Native を用いた開発に移行しました。 当時の話や、最近行った hermes への移行の結果などについても話しました。

speakerdeck.com

こちらは hermes 移行時の内容です。Android 64bit 対応を行った後から Android JSC の中で起動時にランダムにクラッシュしてしまうという問題に悩まされていました。 移行後はこの問題が解決されクラッシュ数が激減しました。他の登壇者の方も hermes への移行による起動速度の改善などにも言及されており印象的でした。

f:id:soh335:20211007125448p:plain

個人的にはオンラインで Keynote を用いて発表する際に全画面で行うと、発表サイトなどでの見てもらっている方からのコメントの反応が掴めない等に困っていました。リハーサルの際にウィンドウで再生することができることを教えてもらい、非常に助かりました。 準備期間、当日含めて運営チームの方々には色々サポートしていただきスムーズに行えました。改めてありがとうございました。

最後に、Nature ではエンジニアの採用を行なっています。 会社のミッションとして、"自然との共生をテクノロジーでドライブする"を掲げて Nature Remo, Nature Remo E や Nature スマート電気の開発をしています。まずはカジュアルに Nature の事を知ってみたい、という方はぜひこちらからご応募ください。

herp.careers

スマートホームの新標準「Matter」のサンプルを動かしてみる

Nature株式会社ファームウェアエンジニアの中林 (id:tomo-wait-for-it-yuki) です。スマートリモコンNature Remoシリーズを手がけるNatureでは、スマートホーム新標準のMatter1に注目しています。

GitHubでMatterのプロトコルスタックやいくつかのサンプルが公開されて2います。今回は比較的簡単に動かせるM5Stack3のBLE/無線LANを使ったサンプルを試しながらMatterについて学んでみたいと思います。

Matter

MatterはCSA (Connectivity Standards Alliance) が策定している新しいスマートホームの標準規格です。これまでのスマートホームバイスは各デバイスメーカーがそれぞれの規格に沿って開発していましたが、各社のデバイスが共通して使う規格を決めることで、デバイス間の相互接続性を高めよう、という狙いです。Google, Apple, Amazonなどが参画しており、今後スマートホームバイスの標準になっていくことが期待できます。

無線LAN, BLE, Threadといった通信規格の上位にIPv6をベースとする共通プロトコルを定義しています。このことにより、下位の通信規格に依存せず、相互接続を可能とします。元々CHIP (Connected Home over IP) という名称で、まだところどころにその名残が残っています。技術者視点だとConnected Home over IPはずばり何したいのかそのまんまの名称だったわけですね。

サンプル動かしてみる

注意!

  • 2021/09/29時点の手順です
  • 著者の環境はUbuntu20.04です

用意するものはこれだけです。

  • ホストPC
  • M5Stack BASICを1つ

M5Stack Core2はディスプレイ非対応とのことなので、動かせるものを全て動かしたい場合、M5Stack BASICが安定択です。

M5Stackでall-clusters-appサンプルを動かし、ホストPCのデバイス制御用CLIツールからコミッショニングおよび制御を行います。

all-clusters-app

これまでいくつかサンプル動かしてみましたが、お手軽に雰囲気掴みたい場合、examples/all-clusters-app/esp324を使うのがおすすめです。all-clusters-appではデバイスのコミッショニング (機器の初期設定) とデバイスの制御を試すことが可能です。

今回はM5Stackを使用しますが、DevKitCなどもっと安価なデバイスでも動きます。RISC-Vコアが搭載されたESP32C3-DevKitMで動かすこともできます。デバイスを用意したら、all-clusters-appのREADME.md5に記載の手順通り進めていきます。

all-clusters-appでは、次のようなデバイスがあるかのようにM5Stackが振る舞います。

  • 時計 (バッテリ、心拍計歩数計)
  • ライト2つ
  • 温度計
  • ドアロック
  • ガレージ2つ (ドア)

時計のバッテリ残量やドアロックの状態などは、M5Stackの画面とボタンから変更することができます。ライトのようなコントローラから制御するデバイスは制御に合わせて画面の表示内容が変わります。

サンプルのビルド

次の手順でサンプルをビルドします。

  1. ESP-IDF v4.3のセットアップ
  2. Matter開発環境のセットアップ
  3. サンプルアプリケーションのビルド

ESP-IDF v4.3のセットアップ

ESP-IDF (Espressif ESP32 IoT Development Framework) とxtensa用のビルドツールチェインをセットアップします。セットアップ手順は下記を参照ください。

https://docs.espressif.com/projects/esp-idf/en/v4.3/esp32/get-started/index.html

環境変数IDF_PATHが設定されていることを確認した上で、ESP-IDFの環境をセットアップし、Matter開発環境をセットアップします。

source $IDF_PATH/export.sh
# このコンソールで次の手順へ

Matter開発環境のセットアップ

submoduleのcloneなどあるので、サンプルをビルドする前に実行します。

git clone https://github.com/project-chip/connectedhomeip.git
cd connectedhomeip
source ./scripts/bootstrap.sh
source ./scripts/activate.sh

2回目以降はsource ./scripts/activate.shだけでOKです。

サンプルアプリケーションのビルド

# connectedhomeipのルートディレクトリから
cd examples/all-clusters-app/esp32

デフォルトではESP32-DevKitCがターゲットになっているので、M5Stackに切り替えます。

idf.py menuconfig

Demo -> Device TypeからM5Stackを選択して、保存します。

サンブルアプリケーションをビルドします。

idf.py build

サンプルの実行

M5StackをホストPCにUSBケーブルで接続して、ファームウェアを書き込みます。

idf.py flash monitor

次のような画面が表示されればOKです。CHIPと表示されているのはご愛嬌ですね。

f:id:tomo-wait-for-it-yuki:20210927164500p:plain
all-clusters-app起動画面

コミッショニングと制御

ホストPCからM5Stackのコミッショニング (初期設定) を実施して、Matterデバイスとして制御します。具体的にはBLE経由でコミッショニングして、M5StackをホストPCと同じ無線LANアクセスポイントに接続し、無線LAN経由で制御します。

CLIツールのセットアップ

ホストPCからM5Stackのコミッショニングと制御を行うためのCLIツールをセットアップします。

# connecteddhomeipのルートディレクトリ
./scripts/build_python.sh -m platform
source ./out/python_env/bin/activate

python contollerを起動します。

$ chip-device-ctrl
[1632729563.198847][112356:112356] CHIP:DL: Avahi client registered
[1632729563.199274][112356:112356] CHIP:ZCL: Using ZAP configuration...
# ...
[1632729563.200628][112356:112356] CHIP:CTL: Loaded credentials successfully
[1632729563.203879][112356:112364] CHIP:DL: Platform main loop started.
Chip Device Controller Shell

chip-device-ctrl >

BLE経由のコミッショニング

まずBLEをスキャンします。無事見つかりました。

chip-device-ctrl > ble-scan

2021-09-29 09:52:43,642 ChipBLEMgr   INFO     scanning started
2021-09-29 09:52:45,344 ChipBLEMgr   INFO     Name            = None
2021-09-29 09:52:45,344 ChipBLEMgr   INFO     ID              = 5f294ca3-b123-465a-aa2f-e48633e07dbe
2021-09-29 09:52:45,345 ChipBLEMgr   INFO     RSSI            = -56
2021-09-29 09:52:45,345 ChipBLEMgr   INFO     Address         = 08:3A:F2:68:37:1E
2021-09-29 09:52:45,347 ChipBLEMgr   INFO     Pairing State   = 0
2021-09-29 09:52:45,347 ChipBLEMgr   INFO     Discriminator   = 3840
2021-09-29 09:52:45,347 ChipBLEMgr   INFO     Vendor Id       = 9050
2021-09-29 09:52:45,347 ChipBLEMgr   INFO     Product Id      = 17729
2021-09-29 09:52:45,348 ChipBLEMgr   INFO     Adv UUID        = 0000fff6-0000-1000-8000-00805f9b34fb
2021-09-29 09:52:45,348 ChipBLEMgr   INFO     Adv Data        = 00000f5a234145
2021-09-29 09:52:45,348 ChipBLEMgr   INFO

M5StackにBLEで接続します。

chip-device-ctrl > connect -ble 3840 20202021 135246

Device is assigned with nodeid = 135246
[1632877083.478955][19975:19979] CHIP:BLE: BLE removing known devices.
[1632877083.487762][19975:19979] CHIP:BLE: BLE initiating scan.
[1632877084.025243][19975:19979] CHIP:BLE: New device scanned: 08:3A:F2:68:37:1E
[1632877084.025283][19975:19979] CHIP:BLE: Device discriminator match. Attempting to connect.

# たくさんログが出る

[1632877096.354977][19975:19983] CHIP:ZCL: NOCResponse:
[1632877096.354993][19975:19983] CHIP:ZCL:   StatusCode: 0
[1632877096.355000][19975:19983] CHIP:ZCL:   FabricIndex: 0
[1632877096.355007][19975:19983] CHIP:ZCL:   DebugText: 0
[1632877096.355018][19975:19983] CHIP:CTL: Device returned status 0 on receiving the NOC
[1632877096.355028][19975:19983] CHIP:CTL: Operational credentials provisioned on device 0x23baba8
Secure Session to Device Established
Device temporary node id (**this does not match spec**): 135246

これでデバイスとのセキュアセッションが確立できたようです。おおよそ10秒くらいでしょうか?ちょっとわかりにくいですが、BLE接続ができるとM5Stack画面の左側にある青色の四角が明るくなります。

f:id:tomo-wait-for-it-yuki:20210929133413p:plain
BLE接続後

少しコマンド connect -ble 3840 20202021 135246 のパラメータを説明しておきます。384020202021は、それぞれ識別用のIDとPINコードで、ビルド時のパラメータとして設定可能です。135246はノードIDでこの後のコマンドでは一貫してこのIDを使用しなければなりません。接続時の最後のログにDevice temporary node id (**this does not match spec**): 135246と出ていて、一時的なデバイスノードIDであろうことがわかります。ちなみにconnect-ble実行時にこのパラメータを指定しなければ、chip-device-ctrlがIDを生成して表示してくれます。

無線LANアクセスポイントに接続するために、SSID/passwordを設定し、無線LANネットワークを有効化します。

chip-device-ctrl > zcl NetworkCommissioning AddWiFiNetwork 135246 0 0 ssid=str:TESTSSID credentials=str:TESTPASSWD breadcrumb=0 timeoutMs=1000
chip-device-ctrl > zcl NetworkCommissioning EnableNetwork 135246 0 0 networkID=str:TESTSSID breadcrumb=0 timeoutMs=1000

1つ目のコマンドでSSID/passwordをM5Stackに送信します。TESTSSIDTESTPASSWDの部分は使用するアクセスポイントのものに置き換えて実行します。2つ目のコマンドでnetworkIDで指定したアクセスポイントに接続します。

M5Stack側のログでもアクセスポイントに接続したことがわかります。

I (390625) wifi:new:<3,1>, old:<1,1>, ap:<255,255>, sta:<3,1>, prof:1
I (391125) wifi:state: init -> auth (b0)
I (391135) wifi:state: auth -> assoc (0)
I (391155) wifi:state: assoc -> run (10)
I (391165) wifi:connected with TESTSSID, aid = 3, channel 3, 40U, bssid = xx:xx:xx:xx:xx:xx
I (391175) wifi:security: WPA2-PSK, phy: bgn, rssi: -50
I (391185) wifi:pm start, type: 1

I (391185) wifi:AP's beacon interval = 102400 us, DTIM period = 3

アクセスポイントに接続すると黄色い四角が明るくなります。

f:id:tomo-wait-for-it-yuki:20210929133526p:plain
アクセスポイント接続後

もうBLEは使わないのでBLEを切断します。これ以降はBLEのadvertiseをしなくなるようで、scanに引っかからなくなります。BLE切断しても青色の四角は明るいままのようです。

chip-device-ctrl > close-ble

M5StackのIPアドレスを取得します。M5Stack上でmDNSが動いており、これで通信するIPアドレスが取得できます。

chip-device-ctrl > resolve 0 135246

[1632878616.341733][38115:38123] CHIP:DL: Avahi resolve found
[1632878616.341806][38115:38123] CHIP:DIS: Node ID resolved for 0x000000000002104E to [192.168.1.16]:5540
Node address has been updated
[1632878616.342207][38115:38123] CHIP:CTL: OperationalDiscoveryComplete for device ID 135246
[1632878618.350885][38115:38123] CHIP:EM: Received message of type 0x31 with vendorId 0x0000 and protocolId 0x0000 on exchange 39023
Commissioning complete
Current address: 192.168.1.16:5540

ログを見ると0x000000000002104E (135246)[192.168.1.16]:5540に解決された、とあります。これでコミッショニングは完了です。次はデバイスの制御を試します。

バイスの制御

まずはライトのOn/Offを制御してみます。上から1番目の緑の四角が明るくなります。

chip-device-ctrl > zcl OnOff On 135246 1 1

f:id:tomo-wait-for-it-yuki:20210929133625p:plain
ライトON

ライトは2つあるので、もう1つの方を制御してみます。上から3番目の水色の四角が明るくなります。

chip-device-ctrl > zcl OnOff On 135246 2 1

f:id:tomo-wait-for-it-yuki:20210929133647p:plain
別のライトON

コマンドのフォーマットはこのような感じです。先程はendpointを変えることで、異なるライトを制御しました。

zcl <cluster> <command> <nodeid> <endpoint> <groupid> [key=value]

次は温度計から温度を読み取ってみます。

chip-device-ctrl > zclread TemperatureMeasurement MeasuredValue 135246 1 0

#...

[1632883644.088914][38115:38123] CHIP:ZCL: ReadAttributesResponse:
[1632883644.088919][38115:38123] CHIP:ZCL:   ClusterId: 0x0000_0402
[1632883644.088922][38115:38123] CHIP:ZCL:   attributeId: 0x0000_0000
[1632883644.088924][38115:38123] CHIP:ZCL:   status: Success                (0x0000)
[1632883644.088925][38115:38123] CHIP:ZCL:   attribute TLV Type: 0x00
[1632883644.088930][38115:38123] CHIP:ZCL:   attributeValue: 2100

#...

2100が返ってきています。これはZigBee Cluster Library Specificationによると21.0℃を表しています。

MeasuredValue = 100 x temperature in degrees Celsius.

値はプログラムの初期化時に設定されたものがそのまま返ってきています。M5Stackの画面とボタンから温度の値を変更すると、取得できる値も変わります。

大体雰囲気はつかめてきましたね。

サンプルを動かしてわかったこと

けっこうZigBee

Matterを策定しているCSA (Connectivity Standard Alliance)6は元々ZigBee Allianceだったこともあり、随所にZigBeeの資産を活用している様子が伺えます。プロトコルスタックの少し下の方をみると、ZigBee Cluster Library (zcl) を利用しているのも見て取れます。clusterの仕様などはZigBee Cluster Library Specification7を見ると読み解くことができます。

バイス初期設定も標準化

バイスの初期設定 (コミッショニング) が標準の中に含まれていて、その実装も与えられているのは嬉しいですね。今は各デバイスで独自の初期設定を持っていると思いますが (Nature Remoも)、これも統一化されることでユーザーが戸惑うことも少なくなるのではないか、と期待できます。BLE/IP/QRコードあたりが初期設定で使えるようになりそうです。

C++実装

ぱっと見、スタックもAPIC++です。スマートホーム用の標準でその実装なので当然マイコンをターゲットとしていますし、サンプルも複数のマイコン上で動くものが提供されています。こういうところもCではなくC++で作っていく感じなのでしょうね。Matterに関しては少なくとも暗号化処理やIPスタックが必要になってくるため、それなりの性能があるマイコン使うのが前提というのも言語選定の根底にありそうです。

今後C言語のbinding作られるのかどうかは少し注目です。

他のサンプル

今回はall-clusters-appサンプルをM5Stackで動かしましたが、複数のサンプルがいくつかのターゲットデバイスに対して提供されています。

nRF52840を使ったサンプルでは、モバイルアプリも含めてサンプルが提供されているので、けっこうそれっぽい雰囲気を味わうことができます。が、nRF52840を2台用意して、1台をThread Border Routerにして…、みたいな感じで動かすのが大変です。興味がある場合は、lock-app8を見てください。

Matterでこまったーこと

CLIツールを起動するとBluetoothペアリングが解除される

ホストPCからBLE接続するときにCLIツールを起動するとBluetoothのペアリングが解除されてしまいます。初回Bluetoothイヤホンで音楽聞きながら作業していたわけですが、急に音が止まりました。BLE使うししゃーないか、と思って改めてMatterのサンプル動かし終わった後にWeb会議のためBluetoothイヤホン接続しようとしたら、接続できなくて焦りました。

あとからペアリング自体が解除されていることに気づいてことなきを得ました。

2回目以降のコミッショニング方法が謎

M5Stackにファームウェアを書き込んで、CLIツールでBLE接続するところからコミッショニングすれば制御できるのですが、M5Stackを再起動したあとにコミッショニングする方法がわからず、事故ったら最初からやり直していて不便です!助けてください!

ツールをしらばく起動しているとCPU使用率が100%になる

Matterのサンプルで遊んでいると、特にPCに負荷かけていないはずなのに急にファンが唸りだしました。なんだろう?と思ってシステム負荷確認してみると…

f:id:tomo-wait-for-it-yuki:20210929135244p:plain
chip-device-ctrlがCPUを1個持っていく…

うーん、なんかイベントループの実装ミスってたりするのでしょうか…。

最後に

簡単にではありますが、Matterのサンプルを動かしてみました。ホストPCとM5Stack間のやり取りしかしていないのであまりスマートホーム感は出ませんでしたが。…スマートホームのデモとしてはやはりスマートスピーカーから制御できるようなものがあると見栄えが良いですね。

ソースコードもそれなりに読んでいるので、別の機会で紹介していければ良いな、と考えています。今後、Matterがもっと盛り上がるとおもしろいな、と思っているのでぜひ皆様もお試しください。

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

We are hiringです。ファームウェアのポジションもオープンしていますので、一緒にMatterでこまったー、となってくれる方からのご応募をお待ちしております。カジュアル面談等も歓迎なので、その場合はTwitterなどでお声がけくださると嬉しいです。

nature.global

ファームウェアエンジニアのお仕事

Nature株式会社ファームウェアエンジニアの中林 (id:tomo-wait-for-it-yuki) です。今回は、Natureのファームウェアエンジニアの業務内容を紹介し、その魅力をお伝えします!

NatureはスマートリモコンNature Remo1/スマートエナジーハブNature Remo E2を製品として展開しています。ファームウェアエンジニアはこれら製品のファームウェア開発を主に担当しますが、それだけに留まらず多岐にわたる業務を遂行しています。 現在ファームウェアエンジニアとして携わっている業務としては、次のものがあります。

Nature Remoの企画/開発

スマートリモコンというジャンルも認知度が上がり、競合製品が次々登場しています。 Nature RemoはNatureが電力需給にコミットするための入り口であり、競合他社より魅力的なスマートリモコンとして、ユーザーに選んでもらえるものを作らなければなりません。

これまでNatureでは、
2018年にNature Remo mini
2019年にNature Remo E
2020年にNature Remo E lite / Nature Remo3 / Nature Remo mini2
2021年にNature Remo mini 2 Premium
をローンチしており、私たちは常に新しいRemoについて考えています。Remoに採用したいアイデアを発想したり、技術を調査したり、といった具合です。

ファームウェアエンジニアはその製品企画にコアメンバーとして参画できるポジションでもあります。マイコン選定から、搭載する通信規格、サーバー通信のデータフォーマット策定など、ファームウェアに関係する要素は製品企画の初期段階からハードウェアエンジニアと協力しながら進めていきます。そのため、新しい通信モジュールやセンサー、通信規格には特に目を光らせています。最近だとMatter3 (元CHIP: Connected Home over IP) というスマートホーム規格に注目しており、社内で調査したり議論したりしています。

また、同時にNatureのミッションを実現するための別のハードウェア製品の可能性も検討しています。Natureが得意とするWebの技術をうまく活かしながら、Natureらしいハードウェア製品って何だろうか?ということに知恵を振り絞っています。

toB向け新規事業の立ち上げ

次なるNatureの柱であるBehind The Meter (BTM) 事業では、Nature Remo E を中核としたサービス事業を展開していきます。BTM事業とは、家庭用太陽光の導入とエコキュート(給湯器)・蓄電池・EV等のエネルギーマネージメントをセットで行うことで戸建て住宅で再エネでのエネルギー自給自足を実現する事業です。

これまでtoC向けの製品として作っていたRemo Eですが、スマートエナジーハブとしてその存在感が増しており、業界での認知も進んでいます。そこでtoC向けの開発は継続しつつ、Remo EのtoB向け活用を視野に入れて、toB向けにはRemo Eを作り直すべきか?Remo Eを中心としたどのようなサービスを提供すべきか?ということをビジネス開発の担当者と日夜意見を交換しています。

この新規事業立ち上げは、Remo Eが中心となるため、Remo E自体を熟知している必要がありますが、提供するのはサービスであるため、アプリやサーバーがどうあるべきか、といったことも検討します。ハードウェア製品開発やファームウェア実装だけでなくサービスの立ち上げに深く関われるのも、Natureのファームウェアエンジニアの魅力だと思っています。

Remoの改善

Nature Remoにはファームウェアアップデートの機能を搭載しています。一度ファームウェアをリリースしたら終了、ではなく、常にユーザーフィードバックを受けて、ファームウェアの改善を続けています。Nature Remo3も発売後Qrio Lock4との連携機能をファームウェアアップデートで提供しています。

Nature Remoの動作状態のオブザーバビリティを向上し、サービスの質を高めるプロジェクトも目下進行中です。このプロジェクトは、Remoの動作状態として何が見えれば良いか?取得可能な情報はなにか?それはユーザーの利便性向上にインパクトがあるか?ということを意識しながら進めています。やはり問題になりがちなのは通信に関連するところなので、無線通信規格やレイヤー3以上の通信プロトコルについても理解を深めながら、安定的に動作する製品の開発を目指しています。

小さな新機能であれば、サーバー側の実装もファームウェアエンジニアで行います (サーバーエンジニアの助力を受けながらGo言語書いてます) 。例えば、毎日の統計情報を google spread sheets に反映させて更新するバッチがサーバーで動いていますが、ファームウェアに関するシートの更新はファームウェアチームで実装しています。

カスタマーサポートの技術調査

Remoの改善活動と重複する部分もありますが、カスタマーサポートで問題となっている技術課題の調査も重要な役割です。Nature Remoシリーズは累計販売台数が30万台を超えており、様々な環境で利用されています。そのため、販売開始当初には予想もしなかった問題も発生します。

Amazon Athena5でサーバーログに対してSQLでクエリを書いて、問題を分析します。私は情報処理技術者試験を除くと始めてSQLを使う機会となりました。個人で入門書を読んで普段遣いの簡単なクエリは自力で書けるようになりましたが、複雑なクエリはサーバーエンジニアやデータエンジニアに助力を請います。スーパーcoolなクエリを教えてもらえるので、「スーパーcool...」とお礼を言って後でじっくり何やっているのか理解しています。

ファームウェア開発プロセスの改善活動

Nature Remoというハードウェア製品を主力としていますが、私たちの強みはソフトウェア的な継続的な改善だと考えています。ユーザーにより短いリードタイムで、より多くの機能を届けるために、ファームウェア開発のプロセス改善活動を行っています。具体的には、自動テストの整備、CI環境の構築や、社内ユーザーが使用するRemoで問題を早期発見するためのログシステム、をファームウェアチームでてがけています。

自動テストの整備では、Catch26というユニットテストフレームワークを使って、C++でテストを書いています。テストは可能な限りデュアルターゲット化 (開発しているホストPCでもターゲットデバイスでも動く) するようにしています。モックを作るコストが高い (=ハードウェアを直接制御する) 部分は、ターゲットデバイスだけで動作するテストも書きますが、テストを回すサイクルが遅くなるのでできるだけホストPCだけで開発を進められるようにしたいところです。ホストPCでテストすることで、AddressSanitizer7のような動的解析ツールでバグを検出できる、という利点もあります。

CIはGitHub Actionsを使っています。ユニットテストのうち、ホストPCで実行できるものをプルリクエストごとにテストしています。また、ターゲットデバイス向けのクロスコンパイルが通ることの確認として、ファームウェアのクロスビルドまでは自動で行うようになっています。リリース作業も一部自動化が済んでおり、社内ユーザーへの内部リリースは以前よりずっと楽になっています。今は、CIでターゲットデバイス上のテストまで自動実行できる環境の構築やさらなるリリースの自動化を目指しています。

ファームウェアはユーザーにリリースする前に、社内ユーザーに内部リリースし、実環境での利用で問題が発生しないか確認しています。社内ユーザーにはRemoと一緒にログ収集用のRaspberry Piをセットアップしてもらい、何か問題が発生したときに、その時のログが確認できるようになっています。ただ、現状は問題発生に気づくのが遅れてしまうことがある、という課題が存在しています。そこで、このRaspberry Piログシステムをサーバーのモニタリングで活用しているDatadog8に集約して、良い感じにする大改造作戦を練っています。こちらはSREとの共同作戦になっており、ファームウェアエンジニアも様々な領域のエンジニアと関わりながら刺激を受けられる例の1つと言えます。

開発補助ツールの開発

日々の開発を楽にするための補助ツールの開発も行っています。この補助ツールについては特に開発言語の縛りもないため、大々的にRustを採用することができます (鉄分補給) 。直近で言うと、Remo Eが搭載しているスマートホーム標準であるECHONET Lite9用の開発補助ツールをRustで書いています。Rustでは一度 serde10 でシリアライザ/デシリアライザを書いてしまえば、自在にフォーマット変換できるため、非常に重宝しています。

こちらのECHONET Lite用ツールについては、昨夜のNature Bath vol.1311で発表しましたので、当日発表見れなかった方はレポートの公開をお待ちください。

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

本記事ではNatureのファームウェアエンジニアの仕事内容を紹介しました。まとめると、Natureにおけるファームウェアエンジニアは次のような魅力のあるポジションであると言えます。

  • いわゆるIoT製品として30万台を超える販売台数を誇るハードウェア製品の企画に参画できる
  • ハードウェア製品を中核においた新しいサービス事業に携われる
  • ファームウェアの継続的改善を試みることができる
  • 『リアル』なIoT製品の問題解決のノウハウが身につく
  • ファームウェア開発をモダンな開発プロセスに近づけるための試行錯誤ができる
  • 直接的なファームウェア開発以外にも様々な技術に触れたり領域の異なるエンジニアと協力したりできる
  • ファームウェア開発へのRust導入に好意的である (めっちゃ大事!)

もちろんC言語でハードウェアを相手にしている以上、泥臭いエンジニアリングをしなければいけないことも少なからずありますが、そこはご愛嬌です。

Natureではエンジニアを積極採用しています。

という方は、カジュアル面談等も行っていますので、Twitterなどで連絡いただければ嬉しく思います。

https://nature.global/careers/job/

Natureの電気事業の技術的な面白さや、IoT事業との関わりについてお話する会をやります

タイトルのとおり、「Nature Bath【エンジニア向け】開発メンバーが語る!Natureスマート電気事業の開発秘話」と題して、オンライン勉強会を明日5/26(水)に実施します。以下のようなことについて、私を含めたNatureスマート電気開発の主要エンジニア陣がお話します。

  • Natureスマート電気とNature Remoとの関わりや今後の展開
  • 電気事業の技術的な面白さやチャレンジングな点
  • Nature初のSPAアプリをReactで開発した話

まだまだ申し込みは受け付けていますので、ぜひご参加ください。

さて、Nature社は、スマートリモコンのNature Remoを作っていたはずなのに、突然Natureスマート電気という電気小売サービスを始めてどうしたんだ、Nature Remo事業は大丈夫なのか、と感じている人もいるかも知れません。

また、IoTは技術的に面白そうだったのに、電気事業の技術的な面白さってどういったところにあるのだろう、と感じてくださっているエンジニアの方もいらっしゃるのではないでしょうか。

今回は、そういった懸念を払拭し、Natureでの開発の面白さに魅力を感じてもらうと共に、有益な情報を持ち帰ってもらえる会にしたいと考えています。

前提として、Nature Remo事業を疎かにするつもりはありませんし注力の度合いも変わりません。実際、販売計画もこれまで以上のチャレンジングな目標を掲げています。

また、Natureはそもそもエネルギー問題に取り組むべく事業を立ち上げましたが、実は、Nature Remoもその課題意識の中から生まれたプロダクトです。ですので、今回の小売電力事業の立ち上げは僕たちが元々想定していたシナリオでもあるのです。

今年のNature社内のテーマに「融合」というものがあります、この意味の一つは、既存のNature Remo、Nature Remo E、Natureスマート電気それぞれのサービスを融合させてシナジーを生み出すことにより、より大きい独自の顧客価値を提供していくというものです。

それぞれのサービスが今後どのように絡み合い、最終的にどんなプロダクトに進化させていくのか、そこにどういった技術的課題と面白さがあるのか等、当日お話できればと思っています。

また、Nature社はこれまでアプリ開発がメインだったため、Natureスマート電気でのSPAアプリケーション開発は実は初めての試みでした。その開発中の苦労話などもお伝えできればと思います。

それでは改めてご参加をお待ちしています!

『基礎から学ぶ 組込みRust』執筆に寄せて〜Nature RemoへのRust導入の展望〜

Nature株式会社ファームウェアエンジニアの中林 (id:tomo-wait-for-it-yuki) です。 本記事では、拙著『基礎から学ぶ 組込みRust』1がC&R研究所様より出版されたので、書籍の紹介やNatureのファームウェア開発にRustを使っていきたい、ということを書きます。 本を書きましたエントリは個人ブログで書いている2ので、それとは少し違った観点から話をしたいと思います。

『基礎から学ぶ 組込みRust』の紹介

2021年5月現在、Rustはすでにマイナーの域を超えたと言って差し支えない状況でしょう。一方、組込みRustはまだまだマイナーな分野です。『基礎から学ぶ 組込みRust』出版をtwitterやブログで告知した際も、「Rustって組込みできたんだ?」という反応が少なくありませんでした。

マイナー扱いから脱するための施策として、認知度を上げ、入門を手厚くする、というのが王道だと思っています。Rustの入門ドキュメントは素晴らしい書籍がたくさん出ています。組込みRustのドキュメントもRust Embedded devices Working Groupが良いドキュメントを用意してくれています。しかし、Rustと組込みRustとの両方を1冊でカバーしている書籍は、これまでありませんでした。ここでなら私も貢献できそうだと感じ、ちょうどよいタイミングで執筆のお声がけをいただいたこともあり、Rustの文法もカバーした組込みRustの入門書を執筆することにしました (このあたりは先日のShinjuku.rs #153のLT4もご参照ください) 。

『基礎から学ぶ 組込みRust』はRustの文法や組込みの基礎から、マイコンモジュール『Wio Terminal』搭載のデバイスを制御するプログラムを作成する内容です (Rustも組込みも未経験だと、少ししんどいかもしれません) 。ボタンとLED/GPIO 、シリアル通信/UART 、タイマ/割り込み、ブザー/PWM 、光センサ/ADC 、加速度センサ/I2C 、LCD/SPI と組込み開発で頻繁に利用する要素のカバー率は高くなっています。 回路図やデータシートの参照方法から始まり、Rustの抽象化されたAPIをどう扱うかまで解説を書いています。書籍内のサンプルをWio Terminalで動かすだけでなく、その先、自身でWio Terminalにデバイスを追加したり、Wio Terminal以外のデバイスで組込みRustをお試しいただける内容になっていると自負しています。

組込みRustにかける思い

少し話が前後しますが、そもそも私が組込みRustに入れ込んで活動している理由について、少し説明します。 現在、組込み開発ではC/C++が圧倒的なシェアを占めています。C/C++を使うことの是非もあると思いますが、私にとってはそれほど重要ではありません。Cで全てを明示的にハンドリングするのが良いと思う人も居れば、C++の強力なテンプレートメタプログラミングを好む人も居るでしょう。組織としてはC/C++に熟練したプログラマに存分に力を発揮してもらって良いプロダクトを作ることを望むと思います。

その一方で、イケてるRustで組込み開発したい人が増えています。私もその1人です。ではRustの何が組込み開発でイケているのでしょう?書籍では、性能、信頼性、生産性を兼ね備える数少ないプログラミング言語であることを理由として挙げています (詳しくは書籍を読んでみてください!) 。せっかくなので、書かなかったことを書きましょう。

それは「Rustでプログラミングするのが楽しいから」です。確かにコンパイル通すのが難しい時があったり、適当に書いて動かすのが難しい時があったりします。ただ、それは本当はプログラム書くってことは、そういう設計について考えることだよね、って気がします。

オライリーから出版されている『プログラミングRust』5 (通称カニ本) の参照について書いてある章に、私の好きな1文があります。

Rustの本質は、プログラムを理解する苦労を、未来から現在に移すことにある。
プログラミングRust p.120 より

つまり、Rustでプログラムを作る、ということは、コンパイルを通す前に良い設計を考えなければならないのだ、ということを言っています (実際はRust的にはイケてないコードや安全なちょっとダメなコード書いてしまったりするのですが、まあ安全性が担保される設計にはしないといけないので許して欲しい) 。

Nature Remoがそうであるように、今や組込み機器のファームウェアもインターネット経由でアップデートできる時代ではありますが、それでも他のソフトウェアよりはアップデートするのが難しいことに変わりはありません。そのような組込み機器の開発に使うプログラミング言語だからこそ、コンパイル前に良い設計を考えなければいけないRustが適している、と思いませんか?思いますね。思いましょう。

Rustが組込み開発におけるC/C++に次ぐ第3の選択肢になる世界を作っていくのは、人生を費やすに値する挑戦だと確信しています。

Nature RemoへのRust導入の展望

Nature Remoのファームウェアは現在C言語で書かれています。しかし、チャンスがあればRust導入へのチャレンジを積極的に行いたいと考えています。プロダクトでの採用事例は、有無を言わさぬ説得力があります。その際、スクラッチからRustで書き直しました!みたいなことができるとセンセーショナルなのですが、もう少し地味なチャレンジを狙っています (結果が地味という意味で、必ずしも技術的にそちらの方が簡単、という意味ではないです)

まず第一に、Nature Remoのファームウェアは良い感じに書かれており、あえて全てをスクラッチから書き直す必要性はあまり感じていません。元々がC言語なので性能上の問題は存在しませんし、メモリリークバッファオーバーランもおおよそ潰してあるので安全性の面でも全面的に書き直すほどのモチベーションはありません。 そのため、全面的に書き直すよりは、使えるものはそのまま使いつつ、新規開発する部分や現時点でどうしても書き換えたいところだけをRustで書くのが理にかなっています。

また、プロダクトのファームウェアをスクラッチからRustで書くことができるのは極々一部で、C/C++の資産を使いたい、というのが大半だと考えています。そのため、C/C++の資産がある中で、小さくRustを導入するケースを作る、というのが、わたしよし、Natureよし、世間よしの三方よしな気がしています。

Rustが組込み開発で当たり前に選択肢になる世界、を目指して、今後もコツコツできることを積み重ねて行きます。 開設したエンジニアリングブログの第2弾で会社で採用していない技術を紹介させてもらえているように、Natureはそのようなチャレンジを応援してくれる会社です。

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

Natureでは一緒に開発してくれる仲間を募集しています。カジュアル面談等も歓迎なのでその場合はTwitterなどでお声がけくださると嬉しいです。

https://nature.global/careers/job/