LoginSignup
1
1

OpenAPIを用いてSwitchbot Hubのデータを取得するAPIを実装する

Last updated at Posted at 2023-10-06

はじめに

OpenAPIはAPI実装における標準化された手法の一つです。OpenAPIには以下のメリットがあります。

  • API仕様書のフォーマットの統一
  • サーバーへのリクエストテスト機能
  • ツールを用いたコードの雛形の生成

本記事では、Switchbotのスマート家電からデータを取得するAPIをOpenAPIを用いて実装し、取得したデータを表示する方法を紹介いたします。

最終的な構成図は以下のようになります。
image.png

使用した環境:

また、データ取得をするスマート家電として、自宅においてある Switchbot Hub 2 を用いました。

0. 事前準備

SwitchbotのAPIを利用するためには、アプリの開発者向けオプションをオンにし、トークンを取得する必要があります。手順は以下のページを御覧ください。

本記事では、実装の簡易化のためにAPIのv1.0を利用します。API v1.1で導入された新しい認証方法には対応していません。

以下の本文で YOUR_TOKEN と記載してある部分は、上記の手順で入手した実際のトークンに置き換えてください。

1. APIの実装

Switchbot APIの仕様を参考に、以下の2つのAPIを定義します。

  • GET /devices:デバイスの一覧を取得する
  • GET /devices/{deviceId}/status:指定したdeviceIdのデバイスの情報を取得する

また、リクエストヘッダーで、Authorizationパラメータを定義する必要があります。
以下が実装例です。

api.yaml
openapi: '3.0.3'
info:
  title: SwitchBot
  version: "0.0.1"
servers:
  - url: https://api.switch-bot.com/v1.0
security:
  - Authorization: []
paths:
  /devices:
    get:
      operationId: devicesget
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Devices"
  /devices/{deviceId}/status:
    get:
      operationId: devicesidstatusget
      parameters:
        - name: deviceId
          in: path
          required: true
          schema:
            type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/StatusOfDevice"
components:
  schemas:
    Devices:
      type: object
      properties:
        statusCode: 
          type: integer
        message:
          type: string
        body:
          type: object
          properties:
            deviceList:
              type: array
              items: 
                properties:
                  deviceId:
                    type: string
                  deviceName:
                    type: string
                  deviceType:
                    type: string
                  enableCloudService:
                    type: boolean
                  hubDeviceId:
                    type: string
            infraredRemoteList:
              type: array
              items:
                type: object
                properties:
                  deviceId:
                    type: string
                  deviceName:
                    type: string
                  remoteType:
                    type: string
                  hubDeviceId:
                    type: string
    StatusOfDevice:
      type: object
      properties:
        statusCode: 
          type: integer
        message:
          type: string
        body:
          type: object
          properties: 
            deviceId: 
              type: string
            deviceType:
              type: string
            hubDeviceId:
              type: string
            humidity: 
              type: integer
            temperature:
              type: number
  securitySchemes:
    Authorization:
      type: apiKey
      in: header
      name: Authorization

上記のコードの確認方法として、Switchbot Editorにコードを貼り付けると、レンダリングされた状態で確認できます。

以下のように、画面右側の部分で入力したAPIを確認できます。

image.png

2. コード生成

openapi-generator-cliを使うことで、定義したOpenAPIのyamlファイルから、クライアントのコードを生成します。openapi-generator-cliを使う方法はいくつかありますが、ここではdockerを利用します。作業ディレクトリにapi.yamlを作成してから、以下を実行します。

$  docker run --rm -v ${PWD}:/local openapitools/openapi-generator-cli generate -g python -o /local/client -i /local/api.yaml 

実行後に、clientディレクトリにpythonのコードが生成されます。この生成されたアプリケーションを以下の手順でインストールします。

$ cd client
$ python3 setup.py install --user

3. Webアプリケーションの実装

上記で生成したAPIを通じてSwitchbot Hub 2の温度を取得してグラフとして表示するWebアプリケーションを、streamlitというフレームワークを用いて実装してみます。

まずSwitchbot Hub 2のデバイスID(以下、YOUR_DEVICE_IDと表記します)を取得するために、以下のリクエストを実行します。

$ curl -X 'GET' \
  'https://api.switch-bot.com/v1.0/devices' \
  -H 'accept: application/json' \
  -H 'Authorization: ${YOUR_TOKEN}'

正常なレスポンスが取得できた場合、JSON形式でデバイス一覧情報が表示されます。このとき、body->deviceListのリストの中で、deviceName(ハブの名前)が一致する項目のdeviceIdがデバイスID(YOUR_DEVICE_ID)です。

実行結果例
{
    "statusCode": 100,
    "body": {
        "deviceList": [
            {
                "deviceId": "YOUR_DEVICE_ID",
                "deviceName": "hub",
                "enableCloudService": true,
                "hubDeviceId": ""
            }
        ],
        "infraredRemoteList": [
        ]
    },
    "message": "success"
}

以下のコードでは、取得したデバイスIDを用いてハブの温度情報を取得し、グラフ表示します。温度情報の取得間隔は0.1秒とし、最新1000回分をグラフで表示します。

app.py
import streamlit as st

import openapi_client
import numpy as np
import collections
import time
import datetime
from matplotlib import pyplot as plt

configuration = openapi_client.Configuration()
configuration.api_key['Authorization'] = "YOUR_TOKEN"
placeholder = st.empty()
fig = plt.figure()
ax = fig.add_subplot()

queue1 = collections.deque(maxlen=1000)
queue2 = collections.deque(maxlen=1000)
with openapi_client.ApiClient(configuration) as api_client:
    api_instance = openapi_client.DefaultApi(api_client)
    try:
        with placeholder:
            while True:
                ax.clear()
                response = api_instance.devicesidstatusget("YOUR_DEVICE_ID")
                queue1.append(response.body.temperature)
                queue2.append(datetime.datetime.now())
                
                ax.plot(np.array(queue2, dtype=np.datetime64), np.array(queue1, dtype=np.float32))
                ax.set_title(datetime.datetime.now())
                placeholder.pyplot(fig)
                time.sleep(0.1)

    except Exception as e:
        print("Exception when calling DefaultApi->devicesget: %s\n" % e)

作業ディレクトリ上にapp.pyを作成してから、アプリケーションを実行します。

$ streamlit run app.py

正常に実行できた場合、アプリケーションのURLが表示されます(例:http://localhost:8555)。このURLにローカル環境のブラウザからアクセスすると、画面中にグラフが表示されます。
以下はその実行例です。横軸は日時、縦軸は温度/℃を表しています。

b9e7860a225f4e9a1b3d8e01b51062cdad6ba532c228f19d7df775bc.png

4. まとめ

本記事では、以下の機能について紹介しました。

  • OpenAPIを用いたAPI定義
  • openapi-generator-cliを用いたコード生成
  • streamlit/matplotlibを用いたリアルタイムな情報の可視化

記事の前半部分では、OpenAPIを用いることで、実装するプログラミング言語に依存しない形でAPI定義を作成することができることが確認しました。また後半部分では、生成したクライアント側のコードを通じて、簡単にAPIを呼び出す事ができることを確認しました。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1