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/

Nature Remoやその関連サービスで使われている技術と今後の展望

Nature株式会社VPoEのid:Songmuです。当社でもエンジニアリングブログを始めることにしました。

NatureはIoTスマートリモコン製品のNature Remo1を主力製品としていますが、家庭の電力マネジメントのためのIoT製品スマートエネルギーハブNature Remo E2や、電気小売事業のNatureスマート電気3も提供しています。目指すところはクリーンエネルギー100%の世界の実現で、お客様に利便性と同時にエコであるという、気持ちの良いライフスタイルを提供したいと考えています。

先日、Nature Remoは累積販売台数30万台を越えました4が、エンジニアはハードウェアエンジニアが2名、ソフトウェアエンジニアが8名の体制です。ハードウェアも含め、技術領域が多岐にわたっているため、まだまだエンジニアを募集中です。

さて、今回は最初のエントリということで、Natureで使っているソフトウェアの技術スタックや今後の展望を軽く紹介したいと思います。これは現状の状況を踏まえて選定しているものであり、当然今後は必要に応じて変化させていくことが前提です。

クラウド

AWSをメインで使っています。Google Nestとの連携部分でCloud Functionsを使ったり、FirebaseなどGoogle系のサービスも一部利用しています。インフラの管理にはTerraform、監視にはDatadogを利用しています。

お客様も継続的に増加しており求められる信頼性も上がっています。今後サービスが拡大してく中でも安定性を維持して、より安心してお客様にサービスを利用してもらえるように継続的な改善に取り組んでいきます。数年で100万台規模を目指しているので、それにも耐えられるように、アーキテクチャ変更が必要になるかも知れません。

バックエンド

ほぼ全てGoで書いています。一部、LambdaやCloud FunctionsでNode.jsを使っています。Goは開発速度と実行速度のバランスを取りやすい優れた言語だと感じています。

アプリケーション実行環境にはAmazon ECSを使っています。フロントエンドではAWS Amplifyを利用しています。

一部、Amazon EchoGoogle Nestとの連携のためにLambdaやCloud Functionsを使っていますが、他の部分でFaaSはあまり積極的に活用しているわけではありません。

Nature Remoのシステムは、IoTデバイス側には、リソースの制約もあるため、あまり複雑なことをさせず、代わりにバックエンド側にコアなロジックを持たせています。なので、何気にバックエンドが担う部分は大きいです。安定させながら機能追加をしていくことがチャレンジングな部分です。

データストア

Amazon Aurora MySQL, Amazon ElastiCache Redis, Amazon DynamoDBを使っています。メインのデータはMySQLに保存する方針ですが、RedisはキャッシュやPub/Sub用途、DynamoDBは時系列データのようなデータを保持するのに活用しています。

以外にも割とオーソドックスなバックエンドのスタックを活用していると思われるのではないでしょうか。

特殊な点としては、20万台を超えるNature Remoが僕たちのシステムに常時接続しているので、そこのハンドリングが難しかったり、内部的なメッセージングにRedisのPub/Subを使っている点などがあります。

モバイルアプリケーション

React Nativeを採用してTypeScriptで開発し、iOSAndroid向けにアプリを提供しています。

React Nativeは使い物になるマルチプラットフォーム向けのフレームワークとして認知されるようになったと思うのでそれ自体の評価はしませんが、少人数チームで機能やデザインの整合を取りながら高速に開発できる点でも今のNatureにマッチしていると考えています。

実際、月に2,3回は新しいバージョンのアプリのリリースをおこなっています。

モバイルに関しては、お客様が実際に多く手に触れる部分なので、継続的に改善し続けたいと思っています。Nature Remoはデザインを評価いただくことが多いですが、継続的に変更できていることが、それの一翼を担っているとも考えています。

ただ、お客様の数も増えてきてお客様の層も変わってきているため、テクノロジーにそれほど明るくない人でも使いやすいようにUI/UXを変化・洗練させていく必要があります。そのため、今年は、大きめの変更を目論んでいます。

フロントエンド

Natureスマート電気の開発は、僕らにとって初めてのブラウザアプリケーション開発でしたが、SPAの開発には当然ReactとTypeScriptを使いました。状態管理にはRecoilを採用しました。

ここは3月にサービスを立ち上げたばかりなので、お客様の要望を聞きながら改善にとりくんでいきます。Nature Remoとインテグレートした機能にもつなげたいとも考えています。

組み込みFirmware

組み込みのFirmware開発があるところがIoTを扱っているスタートアップならではです。

現状はマイコンボード上でのC言語開発となりますが、Rustが好きで得意なエンジニアもいるため、チャンスが有ればRustを導入したいと妄想しています。

組み込みに関しては、トラブルを少なくするため、デバイス側のFirmwareは現状シンプルな作りにしています。ただし、最近は赤外線だけではなく、Mornin' PlusやQrio LockといったBLEデバイスとの連携機能を作る局面もでてきており、Firmwareに求められる複雑性も増しています。また、今後は体験の向上のため、よりエッジ側で素早く処理するために、デバイス単体でできることも増やしていく必要があるとも考えています。

機械学習

機械学習関連の機能も強めていきたいと考えています。今は、AWS GlueでParquetデータを作って内部的な分析に使ったり、バッチで定期的にスコア計算したりしているくらいですが、僕たちは多くのセンサーデータや電力データを保持しているためそれらを活用して以下のような機能につなげていきたいと考えています。

  • 家電の自動制御をより賢く
    • 閾値ベースの設定だけではなく、機械学習を用いたより賢い制御や提案
    • 部屋を快適するためや電力消費を抑えるため
  • お客様の利用電力の需要予測
    • 小売事業における電気の買付の最適化
    • DR(Demand Response)の自動化
  • 将来的な電力P2P売買サービス時のマッチング

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

ということで、駆け足でNatureのソフトウェアスタックを軽く紹介しました。ここにも書いたとおり、まだまだやりたいことがたくさんあるので、一緒に開発してくれる仲間を募集しています。カジュアル面談等も歓迎なのでその場合はTwitterなどで僕にお声がけくださると嬉しいです。

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

Appendix

eh-career.com