仙台オフィスの空調環境を IoT を使って測定してみた #tohokutech

2024.03.01

こんにちは!AWS事業本部 オペレーション部 運用イノベーショングループのキクタケです。

先日ブログにてクラスメソッド仙台オフィスのオープンをご紹介しましたが、早いものでオープンから2ヶ月が経ちました!

お陰さまで仙台オフィスの所属メンバー(グループ全体で10名前後います)や、また出張メンバーなどからも、オフィスのロケーションやファシリティなどが大変に好評で、みんなにオフィスを活用してもらっています!

そんな中で不満というほどではないのですが、この2ヶ月ほどオフィスの空調管理について少し悩んでいたりします。。。

仙台オフィスの空調設備

まず仙台オフィスの空調設備は下記の通りに2つの系統に別れています。

ビル全館空調

ビル全館空調は、入居するビルの防災センターによって一元管理されており、テナントとしては風量のみ調節が可能です(一部のみ)。なお全館空調の利用時間は平日8時〜18時となっており、18時を過ぎると送風が止まります。

テナント個別空調

テナント個別空調は、入居するテナント区画内に業務用エアコンが2基設置されており、テナント自らが On/Off や温度調整が可能です。ただし利用した分だけ電気代が別途発生します。

基本的にはビル全館空調で室温を維持し、補助的にテナント個別空調で調整する、という使い分けを行っています。

空調設備に関する悩み

そんな環境下において、具体的には以下のような点について少し悩ましいなぁと思っています。。。

  • 時間帯によって温度が一定にならない(特に平日18時の前後)
  • 系統や吹き出し口が分かれており、エリアによって温度ムラが発生している(気がする)
  • 個別空調の切り忘れに気を付ける必要がある(特に金曜の夜が危ない)
  • などなど

そんな空調設備の悩みに対して、まずはテナント区画内の温度分布やその推移を測定してみようかと考えたのですが、普通に温度計で測定してもツマラナイので、弊社らしく IoT を活用して測定してみることにしました!

採用した IoT デバイス

手元にある Raspberry Pi を使っても良かったのですが、今後の利用用途や設置場所の拡大も見据えて、以下の IoT デバイスを採用することとしました!

デバイス(参考価格)と参考リンク

Raspberry Pi ではなく ESP32 を採用した理由としては、今後オフグリッド環境(商用電源のない場所)で活用する可能性も見据えて、より省電力でかつ DeepSleep 機能(待機時間帯はほぼ停止状態となる)を有していることが魅力的だったためです。

IoT デバイスからのデータ連携

ESP32 には Arduino IDE を使って開発を行い、AWS IoT Core へ JSON 形式のメッセージを MQTT で publish し、AWS IoT Analytics へ格納します。

データ連携のイメージとしては以下のような流れとなります。

ESP32 から AWS IoT Core への publish

ESP32 の開発については DevelopersIO の以下ブログが非常に参考になりました(と言うか、ほぼそのままで開発が出来ました!)

マイコン ESP32 を使って AWS IoT Core と Pub/Sub 通信するまで - DevelopersIO

なお今回は温湿度センサとして AHT21B を採用していますので、追加で DFRobot_AHT20 ライブラリをインストールしているのと、サンプルコードを参考に Arduino スケッチも以下のように変更しています(本スケッチはあくまでも参考としてください)

/*
  Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  Permission is hereby granted, free of charge, to any person obtaining a copy of this
  software and associated documentation files (the "Software"), to deal in the Software
  without restriction, including without limitation the rights to use, copy, modify,
  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
  permit persons to whom the Software is furnished to do so.
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/


#include "secrets.h"
#include <WiFiClientSecure.h>
#include <MQTTClient.h>
#include <ArduinoJson.h>
#include "WiFi.h"
#include "DFRobot_AHT20.h"

DFRobot_AHT20 aht20;

// The MQTT topics that this device should publish/subscribe
#define AWS_IOT_PUBLISH_TOPIC   "esp32/pub"
#define AWS_IOT_SUBSCRIBE_TOPIC "esp32/sub"

WiFiClientSecure net = WiFiClientSecure();
MQTTClient client = MQTTClient(256);

void connectAWS()
{
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

  Serial.println("Connecting to Wi-Fi");

  while (WiFi.status() != WL_CONNECTED){
    delay(500);
    Serial.print(".");
  }

  // Configure WiFiClientSecure to use the AWS IoT device credentials
  net.setCACert(AWS_CERT_CA);
  net.setCertificate(AWS_CERT_CRT);
  net.setPrivateKey(AWS_CERT_PRIVATE);

  // Connect to the MQTT broker on the AWS endpoint we defined earlier
  client.begin(AWS_IOT_ENDPOINT, 8883, net);

  // Create a message handler
  client.onMessage(messageHandler);

  Serial.print("Connecting to AWS IOT");

  while (!client.connect(THINGNAME)) {
    Serial.print(".");
    delay(100);
  }

  if(!client.connected()){
    Serial.println("AWS IoT Timeout!");
    return;
  }

  // Subscribe to a topic
  client.subscribe(AWS_IOT_SUBSCRIBE_TOPIC);

  Serial.println("AWS IoT Connected!");
}

void messageHandler(String &topic, String &payload) {
  Serial.println("incoming: " + topic + " - " + payload);

//  StaticJsonDocument<200> doc;
//  deserializeJson(doc, payload);
//  const char* message = doc["message"];
}

void setup() {
  Serial.begin(9600);
  connectAWS();

  while(!Serial){
    //Wait for USB serial port to connect. Needed for native USB port only
  }
  
  /**
   * @fn begin
   * @brief Initialize AHT20 sensor
   * @return Init status value
   * @n      0    Init succeeded
   * @n      1    _pWire is NULL, please check if the constructor DFRobot_AHT20 has correctly uploaded a TwoWire class object reference
   * @n      2    Device not found, please check if the connection is correct
   * @n      3    If the sensor init fails, please check if there is any problem with the sensor, you can call the reset function and re-initialize after restoring the sensor
   */
  uint8_t status;
  while((status = aht20.begin()) != 0){
    Serial.print("AHT20 sensor initialization failed. error status : ");
    Serial.println(status);
    delay(1000);
  }
}

void loop() {
  /**
   * @fn startMeasurementReady
   * @brief Start measurement and determine if it's completed.
   * @param crcEn Whether to enable check during measurement
   * @n     false  Measure without check (by default)
   * @n     true   Measure with check
   * @return Whether the measurement is done
   * @n     true  If the measurement is completed, call a related function such as get* to obtain the measured data.
   * @n     false If the measurement failed, the obtained data is the data of last measurement or the initial value 0 if the related function such as get* is called at this time.
   */
  if(aht20.startMeasurementReady(/* crcEn = */true)){
    StaticJsonDocument<200> doc;
    doc["time"] = millis();
    doc["temperature"] = aht20.getTemperature_C();
    doc["humidity"] = aht20.getHumidity_RH();
    char jsonBuffer[512];
    serializeJson(doc, jsonBuffer); // print to client
    client.publish(AWS_IOT_PUBLISH_TOPIC, jsonBuffer);
    client.loop();
    delay(1000);
  }
}

AWS IoT Analytics の設定

上記のブログを参考に AWS IoT Core 上で MQTT テストクライアントを用いて publish されていることが確認出来たら、AWS IoT Analytics の設定を進めていきます。

AWS IoT Analytics の設定は、ワンクリッククイックスタートを使うと非常に簡単で、以下の2項目を入力して「リソースを作成」をクリックするだけです。

  • リソースプレフィックス
  • MQTT トピック

「リソースを作成」をクリックすると、AWS IoT Analytics を構成する以下のリソースが順次作成されていきます。

  • チャンネル
  • データストア
  • パイプライン
  • データセット
  • ロール
  • ルール

ただし残念ながらルールだけは上手く作成されないようでしたので、下記の通りに手動で作成して対応しました。

AWS IoT Core ルールの作成

  1. マネジメントコンソールより AWS IoT Core を開く
  2. 管理「メッセージのルーティング」→「ルール」をクリック
  3. 「ルールを作成」をクリック
  4. 「ルールのプロパティを指定」で「ルール名」を入力して「次へ」をクリック
  5. 「 SQL ステートメントを設定」で「 SQL ステートメント」を入力して「次へ」をクリック
    1. SQL ステートメント: SELECT * FROM 'esp32/pub'
  6. 「ルールアクションをアタッチ」で「アクション1」に下記内容を入力して「次へ」をクリック
    1. アクション: IoT Analytics
    2. チャネル名: AWS IoT Analytics で作成したチャンネル(プレフィックス+_channel
    3. IAM ロール: AWS IoT Analytics で作成したロール(プレフィックス+_role
  7. 「確認と作成」で内容を確認して「作成」をクリック

以上でルールが作成されました。ルールの作成によって AWS IoT Core 経由で publish されたデータを AWS IoT Analytics 上で確認することが出来ます。

AWS IoT Analytics でのデータ確認方法

  1. マネジメントコンソールより AWS IoT Analytics を開く
  2. 「データセット」をクリックし、作成されたデータセット名をクリック
  3. 「今すぐ実行」をクリック

実行後に「コンテンツ」タブをクリックし、作成されたコンテンツ名をクリックすると、下記のようにデータを確認することが出来ます。

まとめ

以上のように非常に簡単なステップで IoT デバイスを開発し、AWS IoT Core 経由で publish したデータを AWS IoT Analytics へ格納することが出来ました。

今後は格納されたデータの分析を進めたり(例えば QuickSight を使うなど)、一定の条件に達した場合には何かしらのアクションを呼び出すなど、より働きやすい仙台オフィスの環境整備を目指していきたいと思います。

さらにこの IoT の技術を発展させて、仙台や東北ならではの分野や用途で何か面白い取り組みが出来ないか、模索をしていきたいと考えています。その際にはブログでご紹介する予定ですので、乞うご期待ください!

【告知】技術を語り合う勉強会「Tohoku.Tech」を立ち上げます!

弊社では、株式会社テンダ(本社/東京都渋谷区、代表取締役会長CEO/小林 謙、以下「テンダ」)東北支店と共同で、仙台・東北において技術を語り合う勉強会「Tohoku.Tech」を立ち上げます。

初回の勉強会は、テンダ東北支店が入居する WeWork JR 仙台イーストゲートビルにおいて、2024年3月14日(木)に開催します。

開催要項

  • 日時: 2024年3月14日(木) 18:30~20:10(受付18:00~)
  • 会場: WeWork JR仙台イーストゲートビル(株式会社テンダ東北支店)
  • 参加費: 無料
  • 対象: AWSをはじめ技術が好きな方、技術について語り合いたい方

タイムテーブル

時間 スピーカー セッション
18:00-18:30 会場受付
18:30-18:35 オープニング
18:35-18:55 クラスメソッド株式会社 今野 壮輝 EC 基盤「ヘッドレスコマース」やってみた
18:55-19:15 株式会社テンダ 島田 裕基 EC-CUBE/AWSの構築をChatGPTに相談してみました
19:15-19:35 株式会社ねこまた 齋藤 昌秀 Cursorを使ったRasberryPiの開発
19:35-19:40 クロージング
19:40~20:10 懇親会

参加受付ページ

参加をご希望の方はこちらからお申し込みください。

Tohoku.Tech #1 「仙台でIT勉強会! クラスメソッド & テンダ共催」- connpass

みなさまのご参加を心よりお待ちしております!

一緒に仙台そして東北を、技術を使って盛り上げて行きましょう!