📝

【Flutter × Go × ESP32】ミーアにミュート機能を追加する方法

2024/06/30に公開

はじめに

方言を話すおしゃべり猫型ロボット『ミーア』を開発中。

https://mia-cat.com/

ベータ版をリリースした後、実際に使っていただいた複数のユーザから

「話す頻度に「喋らないモード」が欲しい」

との要望が来たので、今回は本機能の実装を記載。

詳細を伺ったところ、

「オンラインのmeeting中に、いきなり話し始めるとビックリするのと、勉強や仕事などで集中したい時もあるので」

とのこと。

UIUXをどうするか?→ホーム画面にトグルアイコン表示

現在、ミーアの話す頻度の設定は、「ホーム画面→設定タブ→話す頻度」の部分で設定できる。

当初は、ここのプルダウンの選択項目の一つとして「しゃべらない」を追加するか、この画面の下に「しゃべらないモードに切り替える」という文言と、スイッチのトグル表記にしようかと考えていた。


しかし、一緒に開発をしているエンジニアから

「頻度の設定は少しアクセスしにくいので、個人的にはホーム画面のわかりやすい箇所でON/OFFできると良いかな・・?と思いました。現状だと数日に一回くらい電源OFFにする機会があって、一番よく使う機能になるかもしれないです。アレクサだと、音量の横くらいにミュートボタンがありました。」

とコメントをもらったので、試しにアレクサを見てみたところ、確かにホーム画面にミュート(この場合はおやすみモード)がアイコンのトグルで表示されていた。

というわけで、アレクサを参考にして、音量スライダーの下に、ミュート機能という項目を設置して、スイッチのトグルでONOFFを切り替えられるようにしようと思う。デフォルトはOFF。

ミュート機能の改修の一連の流れ

アプリ - サーバー - デバイス間の操作で行うべきこと

アプリ→サーバー→デバイス間で、型変換が現状多数発生しているので、型変換を中心に、実装方針をまとめておく。

アプリ(Dart)

  • DartオブジェクトからProtoBufメッセージへの変換
    • アプリのUIでミュートスイッチの状態を変更し、Dartオブジェクトに反映。
    • DartオブジェクトをProtoBufメッセージに変換。
  • API通信でProtoBufメッセージをサーバーに送信
    • 変換されたProtoBufメッセージをAPI経由でサーバーに送信。

サーバー(Go)

  • ProtoBufメッセージからGo構造体への変換
    • 受け取ったProtoBufメッセージをGo構造体に変換。
  • データベースのカラム値更新
    • Go構造体を用いてデータベースのis_mutedカラムを更新。
  • Go構造体からProtoBufメッセージへの変換
    • 更新されたGo構造体をProtoBufメッセージに変換。
  • ProtoBufメッセージからJSON形式への変換
    • 変換されたProtoBufメッセージをJSON形式に変換。
  • デバイスシャドウのdesiredを更新
    • JSON形式のデータをデバイスシャドウのdesiredに反映。
  • MQTT通信でデバイスに送信
    • デバイスシャドウの更新情報をMQTT通信でデバイスに送信。

デバイス(ESP32)

  • MQTTで受信したJSONデータをC++構造体に変換
    • 受信したJSONデータを解析し、C++構造体に変換。
  • ロジック実行
    • is_mutedfalseの場合にのみ音声と表情の再生を行うロジックを追加。
  • デバイスシャドウのreportedを更新(JSON形式)
    • ロジックの実行結果をデバイスシャドウのreportedに反映。

アプリ(Flutter)

ミュートスイッチと機能の追加(UI修正)

ミュートスイッチの追加

  • アプリのホーム画面にミュート機能を有効にするためのスイッチを追加する。
  • valueプロパティには現在のミュート状態 (isMuted) を渡し、onChangedプロパティにはスイッチが切り替えられたときに呼び出されるコールバック関数 (_onMuteChanged) を設定する。
// ミュートスイッチをUIに追加
Switch(
  value: isMuted,
  onChanged: _onMuteChanged,
),

ミュート状態の更新

  • サーバーにミュート状態を送信する関数を追加する。

続きは、こちらで記載しています。
https://kazulog.fun/dev/mia-mute-function/

Discussion