サウナの温湿度情報をリアルタイムで可視化しよう！ SORACOM + Raspberry Pi + Arduino 

日本のサウナをIoT化したい城です。こんにちは！

突然ですがサウナイキタイ、使ってますか？

サウナイキタイ、それは日本のサウナ施設の情報を網羅する画期的なウェブサイト。
昨今のサウナブームも相まってもはや市民権を獲得したといっても過言ではない存在感ですが、存外知らない方がまだまだいるようです。

サウナイキタイとは何か？まずは僕のお気に入りのサウナ施設、[ドシー五反田](https://sauna-ikitai.com/saunas/4673)を調べてみましょう。

![Screenshot 2021-08-19 at 21.10.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70258/a22e237b-aaf0-8fa6-e1ce-b8c9828c5432.png)

「東京都 品川区」にある「男性専用」サウナということがわかりますね。

サウナ室の温度は100度。お水が沸騰する温度です。
水風呂の温度は10度とありあます（注）。なかなか冷たい。

......さて、ここまでサウナに関するディープな語りが続いていますが、この文章を読んでいるあなたはサウナ好きな方でしょうか？きっとそうですね！いやそうに違いない。そうだと信じてディープな語りを続けます（笑

さて、サウナ好きのあなたならきっとこう考えたはず。

「温度はなかなか。水の温度もいい。さて、このサウナは私の好きなセッティングだろうか？」と。


サウナ室と水風呂の温度だけでは自分の好みに合うかわからない。そう、サウナイキタイには一つ欠けている情報があるのです。それこそが「湿度」。サウナとは切っても切り離せない大事な要素です。

温度と湿度。ふだんから意識されている方は多くないかもしれません。

具体的に考えてみましょう。フィンランドサウナ、ロシアサウナ、そして[昭和ストロングスタイル](https://w.atwiki.jp/saunisuto/pages/23.html)を比較します。

| サウナの種類 | 温度 | 湿度 | 例 |
| :-- | :-- | :-- | :-- |
| フィンランドサウナ | 中温 | 中湿 | The Sauna, ドシー | 
| ロシアサウナ | 高温 | 中湿 | IZUBA |
| 昭和ストロングスタイル | 高温 | 低湿 | カプセル＆サウナ みづほ |

となります（独断と偏見

もっと知りたい！という方はSanalogyさんの[サウナと湿度 計測～男性サウナ室～](https://saunology.hatenablog.com/entry/sauna-humidity05)、[サウナと湿度 絶対湿度の算出～女性サウナ室～](https://saunology.hatenablog.com/entry/sauna-humidity08)などがおすすめ。

さて、大雑把に区分けしてみましたが、サウナ室の状態というのは常に固定されたものではありません。一緒に入る人、お店の方の気配り、サウナストーブの調子、季節、入る時間帯。日々刻々と表情を変える柔軟さがサウナにはあります。

そんなサウナ室のセッティング、リアルタイムで見たくありませんか？
え、見たくない？またまた〜。

とゆーことで大変前置きが長くなりましたが！

本日のメインテーマ

**「サウナ室の温湿度を計測し、リアルタイムで可視化」しよう！**

# SORACOM レシピ：IoTで、サウナ室の温湿度を計測し、可視化

レシピ難易度：★★☆☆☆

温湿度センサSHT-31とArduino、Raspberry Pi、そしてSORACOMを活用して、
サウナ室の温湿度をモニタリングしてサ活(*)に役立てるレシピです。

![E9doYsrVEAAzMMm.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70258/2b9e47ca-03ae-8bb0-13a6-9372d953b3f5.jpeg)

以下のような画面で温湿度データを可視化します。

![soracom1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70258/ba03f3c0-c2d8-0c33-a2b6-fa228fbb9a48.png)

以下のような装置構成です。

![soracom_ブレッドボード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70258/5fa76851-c5e2-232c-a534-9313fb68b89c.png)

本レシピは、ソースコードも用意しております。誰でも真似できるようにGitHub上で公開しているので、ぜひソースコードもご覧ください。

https://github.com/johiroshi/upload_temp_and_humi_to_soracom

＊サ活：サウナ活動
＊写真はイメージです

### 使用する SORACOM サービス

- 3G対応データ通信端末 AK-020（USBドングル）
- データ収集・蓄積サービス SORACOM Harvest Data
- ダッシュボード作成・共有サービス SORACOM Lagoon

### 本レシピを行うのに必要な時間、概算費用

本レシピは以下の通りです。

    必要な時間: 約60分
    概算費用: 約16,000円

※ 概算費用: ハードウェアや SORACOM を始めとした各種サービスの概ねの費用 (送料などの付帯費用や無料枠適用は考慮しないものとしています)

## 準備
### ハードウェア

| 品名 | 数量 | 価格 | 備考 |
| :-- | :-- | :-- | :-- |
| SORACOMアカウント（個人） | 1 | 無料 | |
| SORACOM USBドングル | 1 | 5,478円 | |
| Raspberry Pi 3 B+ | 1 | 4,700円 | | 
| SDカード | 1 | 1,700円 | |
| Arduino Uno | 1 | 2,700円 | |
| SHT31 | 1 | 700円 | |
| ジャンパーワイヤー | 3 | - | | 
| USBケーブル | 1 | - | | 
| カードリーダー | 1 | - | |
| 有線LANまたはWiFi | 1 | - | |
| パソコン | - | - | |

### ご購入について

ハードウェアは以下よりご購入いただけます。

- SORACOM USBドングル
> https://soracom.jp/store/s_category/usb-dongle/

- Micro SD カード
> https://www.amazon.co.jp/microSD%E3%82%AB%E3%83%BC%E3%83%89/b/ref=dp_bc_aui_C_4?ie=UTF8&node=171386011

### その他必要なもの

| 必要なもの | 費用 | 作成方法など |
| :-- | :-- | :-- |
| SORACOMアカウント | 無料※ | SORACOM アカウントの作成 (JP) |
| Arduino開発環境 |  |  |

＊アカウント作成・維持の費用の料金です。
＊筆者は「Qiitaエンジニアフェスタ_SORACOM」でレンタル

その他に、Linux, VIM などへの造詣があるとスムーズな導入ができます。わからない方はDMしてねっ！

## Arduinoにファームウェアを書き込む

Arduinoに以下のファームウェアを書き込みます。
``` Serial.begin(9600)```で設定したボーレートはRaspberry Piで動かすPythonのコードでも使うので覚えておきましょう。

```C++
#include "cactus_io_SHT31.h"

cactus_io_SHT31 sht31;

void setup() {

  if (!sht31.begin())
  {
    Serial.println("Count not find sensor. Check wiring and I2C address");
    while (1) delay(1);
  }

  Serial.begin(9600);             // シリアル通信の準備をする
  while (!Serial);                  // 準備が終わるのを待つ

  pinMode(DOUTpin, INPUT);//sets the pin as an input to the arduino

}

void loop() {

  float Humidity, Temperature, Pressure, AbsoluteHumidity;
  
  Humidity = sht31.getHumidity();
  Temperature = sht31.getTemperature_C();

  // 飽和水蒸気圧(hPa)の計算
  Pressure = 6.11 * pow(10 ,(7.5 * Temperature / (Temperature + 237.3)));
  
  // 絶対湿度(水蒸気量(g/m3))
  AbsoluteHumidity = 217 * Pressure / (Temperature + 273.15) * Humidity / 100;
  
  Serial.print(sht31.getTemperature_C());
  Serial.print(","); 
  Serial.print(AbsoluteHumidity);
  Serial.println("");
  delay(500);

}
```

これでArduinoからRaspberry Piに温湿度情報を送る用意ができました。

## Raspberry PiとArduinoの接続設定をする

1. Raspberry PiにSSHで接続し、USBドングルを使用できるようにします。手順は[こちら](https://users.soracom.io/ja-jp/guides/starter-kits/ultrasonic/setup-raspberry-pi/)
1. SSHで接続したら、```sudo apt-get update```でパッケージマネージャを更新します
1. ```sudo apt-get -y install python3-pip python3```でPython 3の実行環境を準備します
1. ```sudo pip3 install pyserial```でPythonのserialライブラリをインストールします
1. ラズパイとArduinoをUSBケーブルで接続します
1. ラズパイから```ls /dev/tty*```でArduinoとの接続に使用しているポートを調べます
1. ```vi get_value_by_serial.py```で以下の内容を書きます

```python
import serial
import time

def main():
    con=serial.Serial('/dev/tty****', 9600)
    print('connected.')
    while 1:
        str=con.readline() # byte code
        print (str.strip().decode('utf-8')) # decoded string

if __name__ == '__main__':
    main()
```

```python3 get_value_by_serial.py```で以下のような内容が出力されることを確認します

```
pi@raspberrypi:~ $ python3 get_value_by_serial.py 
connected.
24.25,18.30
24.27,18.31
24.25,18.31
```

これでSHT-31から取得した温湿度をArduinoを経由してRaspberry Piが取得できるようになりました。

## Raspberry PiからSORACOM Harvestへ温湿度データをアップロードする

```vi send_temp_and_humi_to_harvest.py```で以下の内容を書きます

```Python
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import time
import serial
import time
import requests
import json

# 第一引数を interval に設定
interval=5 if len(sys.argv)==1 else int(sys.argv[1])

def main():
    con=serial.Serial('/dev/tty****', 9600)
    print('connected.')
    while 1:
        start_time = time.time()
        print("- 温湿度を測定します")
        str=con.readline() # byte code
        if (str):
            data = str.strip().decode('utf-8')
            token = data.split(",")
            temprature = token[0]
            humidity = token[1]
            print(token[0])
            print(token[1])
            headers = {'Content-Type': 'application/json'}
            payload = {'temprature': temprature, 'humidity': humidity }
            print("- データを送信します")
            try:
                r = requests.post('http://harvest.soracom.io', data=json.dumps(payload),headers=headers, timeout=5)
                print(r)
            except requests.exceptions.ConnectTimeout:
                print('ERROR: 接続がタイムアウトしました。"connect_air.sh" は実行していますか？')
                sys.exit(1)
                if r.status_code == 400:
                    print('ERROR: データ送信に失敗しました。Harvest が有効になっていない可能性があります。')
                    sys.exit(1)
        # 指定した秒数に１回実行するためのウェイトを入れる
        wait = start_time + interval - start_time
        if wait > 0:
            time.sleep(wait)

if __name__ == '__main__':
    main()
```

```python3 send_temp_and_humi_to_harvest.py``` とするとデータを送信できます。

```
pi@raspberrypi:~ $ python3 send_temp_and_humi_to_harvest.py 
connected.
- 温湿度を測定します
26.31
16.20
- データを送信します
<Response [201]>
- 温湿度を測定します
26.36
16.17
```

これで SORACOM のサーバーへ温湿度データをアップロードできるようになりました。

![soracom2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70258/f31ca1b1-8c16-4577-3200-7a60047303c8.png)

このデータを SORACOM Lagoon で加工すると、以下のような画面が作れます。
SORACOM Lagoon の使い方は[こちら](https://users.soracom.io/ja-jp/docs/lagoon/create-dashboard/)を読んでね。

![soracom1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70258/ba03f3c0-c2d8-0c33-a2b6-fa228fbb9a48.png)

以上の手順で誰でも簡単に、サウナ室の温湿度を可視化できます。

## 次のステップ

アウトドアサウナ施設で試したいね！

## 補遺

「RaspberyPi + Arduino？それ、ラズパイだけでよくね？」と感づいたあなたはもしかして...サウナ電子工作部のメンバー？

その通りです。I2CならSHT31とラズパイで直接やりとりできます。横着な筆者はArduinoのライブラリで楽をしたかったのでUSBでデータを送っています。

PythonでI2Cしたい方は[こちら](https://ambidata.io/samples/temphumid/python/
)が参考になるんじゃないかな。

https://twitter.com/FinlandSauna/status/1431593989321330688