【設計編】M5StickCで作るスマートバンド的なモノ

## 目的
寝落ちや在宅ワークによる運動不足など不健康な生活を改善できるスマートバンド的なモノを作りたい！
今回は概要レベルの設計を行う。[^1]
[^1]: Qiitaなどの投稿でソースコードは書かれているが仕様は書かれていない記事も多く、なぜこのコードになったのか分からないと感じるケースがあったので、残してみようと思った。

## 環境
+ Raspberry Pi 3 ModelB
+ M5StickC
  + 心拍数取得用：心拍センサユニット(https://www.switch-science.com/catalog/5695/)
  + 警告用：Vibrator Hat(https://www.switch-science.com/catalog/6127/)
  + 腕時計アクセサリ(https://www.marutsu.co.jp/pc/i/33227880/)

### 構成イメージ
![構成イメージ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248487/4d9720c7-5d67-f9db-99f2-d76c35510578.png)


## 作業メモ

### どんな機能を作るのか？
加速度/ジャイロ/心拍数をM5StickCで取得して、そこから寝落ちや運動不足を検知→ユーザーに警告、といった動きをさせる予定

### 設計
<b>参考サイト</b>
https://plantuml.com/ja/

+ ユースケース図(ユースケース記述)/アクティビティ図にて概要レベルの設計を行う
+ ユースケース図/アクティビティ図は [参考サイト](https://plantuml.com/ja/) のPlantUMLにて作成

#### ユースケース図
![ユースケース図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248487/ac210039-7ba7-b60f-9447-1cad785fc3fd.png)

+ PlantUMLのコード
```
@startuml
left to right direction

actor "User" as Men1
actor "raspberry pi" as Men2

rectangle M5StickC {
  usecase "データを取得する" as Func1
  usecase "寝落ちを検知する" as Func2
  usecase "運動不足を検知する" as Func3
  usecase "警告音を出力する" as Func4
}

Men1 -- Func1
Func1 -- Men2
Men1 -- Func2
Men1 -- Func3
Func2 --> Func4:include
Func3 --> Func4:include
@enduml
```

#### ユースケース記述

<table>
<tr><th>ユースケース名</th><th>データを取得する</th></tr>
<tr><td>目的</td><td>加速度/ジャイロ/心拍数の値を定期的に取得し、取得したデータを外部機器へ送信する</td></tr>
<tr><td>アクター</td><td>User/raspberry pi</td></tr>
<tr><td>事前条件</td><td>外部機器とネットワーク接続済み</td></tr>
<tr><td>事後条件</td><td>-</td></tr>
<tr><td rowspan="4">基本系列</td><td>1．User(アクター)がこのユースケースを起動する</td>
<tr><td>2．加速度/ジャイロ/心拍数の値を定期的(数秒程度の周期)に取得し、取得したデータをRAMへ保持</td></tr>
<tr><td>3．データが一定容量になるまで2を繰り返す</td></tr>
<tr><td>4．一定容量保持したデータを事前に定めたフォーマットに則り、raspberry pi(アクター)へ送信する</td></tr>
<tr><td>代替系列</td><td>・基本系列4でraspberry pi(アクター)への送信に失敗する場合、ネットワーク再接続を行う</td></tr>
<tr><td>拡張</td><td>-</td></tr>
<tr><td>備考</td><td>・基本系列4の"フォーマット"は {日時} `{加速度},{ジャイロ},{心拍数}/{加速度},{ジャイロ},{心拍数}/・・・</td></tr>
<tr><td rowspan="4">シナリオ</td><td>1．UserはM5StickC(システム)をデータ取得モードに設定する</td></tr>
<tr><td>2-1．M5StickCを身に着けた状態で1.5時間程度日常生活を行った</td></tr>
<tr><td>2-2．M5StickCを身に着けた状態で1.5時間程度睡眠した</td></tr>
<tr><td>3．raspberry piにてデータがフォーマット通りに送信されている事を確認できた</td></tr>
</table>

<table>
<tr><th>ユースケース名</th><th>寝落ちを検知する</th></tr>
<tr><td>目的</td><td>加速度/ジャイロ/心拍数の値を定期的に取得し、取得値が定めた閾値を超える場合、寝落ちと判断し警告をする</td></tr>
<tr><td>アクター</td><td>User</td></tr>
<tr><td>事前条件</td><td>閾値が設定されている</td></tr>
<tr><td>事後条件</td><td>寝落ちを通知する警告音が出力されている</td></tr>
<tr><td rowspan="4">基本系列</td><td>1．User(アクター)がこのユースケースを起動する</td></tr>
<tr><td>2．加速度/ジャイロ/心拍数の値を定期的(数秒程度の周期)に取得し、閾値と比較する</td></tr>
<tr><td>3-1．一定時間連続で閾値を超えた場合、ユースケース「警告音を出力する」を呼び出し、Userへ寝落ちを通知する</td></tr>
<tr><td>3-2．上記以外の場合、2を繰り返す</td></tr>
<tr><td>代替系列</td><td>-</td></tr>
<tr><td>拡張</td><td>-</td></tr>
<tr><td>備考</td><td>-</td></tr>
<tr><td rowspan="5">シナリオ</td><td>1．UserはM5StickC(システム)を寝落ち検知モードに設定する</td></tr>
<tr><td>2．M5StickCを身に着けた状態で日常生活を行った</td></tr>
<tr><td>3-1．10分連続でソファーで横になって眠ってしまった。M5StickC(システム)が寝落ちを判断し警告音が鳴ることで目が覚めた</td></tr>
<tr><td>3-2．5分×2回でソファーで横になって眠ってしまったが、10分連続ではないため、M5StickC(システム)が寝落ちと判断しなかった</td></tr>
<tr><td>3-3．ソファーで横になりながら長時間ネットサーフィンをしていたが、眠っているわけではないため、M5StickC(システム)が寝落ちと判断しなかった。</td></tr>
</table>

<table>
<tr><th>ユースケース名</th><th>運動不足を検知する</th></tr>
<tr><td>目的</td><td>加速度/ジャイロ/心拍数の値を定期的に取得し、取得値が定めた閾値を超える場合、運動不足と判断し警告する(運動を促す)</td></tr>
<tr><td>アクター</td><td>User</td></tr>
<tr><td>事前条件</td><td>閾値が設定されている</td></tr>
<tr><td>事後条件</td><td>運動不足を通知する警告音が出力されている</td></tr>
<tr><td rowspan="5">基本系列</td><td>1．User(アクター)がこのユースケースを起動する</td></tr>
<tr><td>2．User(アクター)が運動不足を検知する時間を設定する</td></tr>
<tr><td>3．加速度/ジャイロ/心拍数の値を定期的(数秒程度の周期)に取得し、閾値と比較する</td></tr>
<tr><td>4-1．一定時間連続で閾値を超えた場合、ユースケース「警告音を出力する」を呼び出し、Userへ寝落ちを通知する</td></tr>
<tr><td>4-2．上記以外の場合、3を繰り返す</td></tr>
<tr><td>代替系列</td><td>-</td></tr>
<tr><td>拡張</td><td>-</td></tr>
<tr><td>備考</td><td>テレワークなどで運動不足になることを抑制するために検討した機能</td></tr>
<tr><td rowspan="5">シナリオ</td><td>1．UserはM5StickC(システム)を運動不足検知モードに設定する</td></tr>
<tr><td>2．運動不足を検知する時間を設定した</td></tr>
<tr><td>3．M5StickCを身に着けた状態で日常生活を行った</td></tr>
<tr><td>4-1．設定時間以上にほとんど体を動かさず生活を送った。M5StickC(システム)は運動不足と判断し警告音が鳴ることで運動を促された</td></tr>
<tr><td>4-2．設定時間以内に適度に体を動かしつつ生活を送った。M5StickC(システム)は運動不足と判断せず警告音が鳴ることはなかった</td></tr>
</table>

<table>
<tr><th>ユースケース名</th><th>警告音を出力する</th></tr>
<tr><td>目的</td><td>アクターへ警告を出すため、気づくことができるような警告音を出力する</td></tr>
<tr><td>アクター</td><td>User</td></tr>
<tr><td>事前条件</td><td>警告音は出力されていない(すでに警告音が出力されている場合は出力しないようにする)</td></tr>
<tr><td>事後条件</td><td>警告音が出力されている</td></tr>
<tr><td>基本系列</td><td>ユースケース「寝落ちを通知する」、ユースケース「運動不足を通知する」を参照</td></tr>
<tr><td>代替系列</td><td>ユースケースが起動されたとき、警告音が出力されている場合は追加で警告音を出力しない</td></tr>
<tr><td>拡張</td><td>-</td></tr>
<tr><td>備考</td><td>-</td></tr>
<tr><td>シナリオ</td><td>ユースケース「寝落ちを通知する」、ユースケース「運動不足を通知する」を参照</td></tr>
</table>

#### アクティビティ図
![アクティビティ図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248487/a15b4409-ed98-af71-b10d-f2ac3b9b229c.png)

+ PlantUMLのコード
```
@startuml
|User|
start
:モードを選択する;

|M5StickC|
switch (モード)
case (それ以外のモード(例外))
  stop

case (寝落ち検知モード)
  repeat
    :データを取得する;
    floating note left: モード変化があるまで\n繰り返し
  repeat while(寝落ち検知の閾値) is (超えない) not (超える)
  :警告音を出力する;

case (運動不足検知モード)
  repeat
    :データを取得する;
  repeat while(運動不足検知の閾値) is (超えない) not (超える)
  :警告音を出力する;

case (データ取得モード)
  while ()
    :データを取得する;
    :データを送信する;
    |raspberry pi|
    :データを受信する;
  endwhile
|M5StickC|
endswitch

stop
@enduml
```

## まとめ
>寝落ちや在宅ワークによる運動不足など不健康な生活を改善できるスマートバンド的なモノを作りたい！
今回は概要レベルだが設計を行う。

目標達成！
概要レベルでも設計することで、検討漏れを洗い出すことができたかなと思う。
次回から実装を行っていく。