GPTsにSwitchBotを操作してもらう

:::note warn
著者はGPTs作成のため、ChatGPT Plusに加入しました。
:::
# ChatGPTでSwitchBotを操作する。
SwitchBotに登録したデバイスを操作できるGPTsを作りたいと思いました。そしてChatGPTが他の音声アシスタントよりも**ユーザーの意図を高度に解釈できるのか**試すために作りました。

# 手順
以下のような手順になりました。

1\.「OpenAPIスキーマ」を作成する。
2\.「認証」にトークンを入力する。
3\.「知識」にマニュアルをアップロードする。

:::note warn
『3.「知識」にマニュアルをアップロードする。』が難しいかもしれません。申し訳ありませんが、**SwitchBot APIの仕組みをある程度理解しておく必要**があります。
:::

### 1\. 「OpenAPIスキーマ」を作成する
[ChatGPT](https://chatgpt.com)にアクセスします。ブラウザからのみGPTsを作れるようです。(2024/08/20時点)
設定の「マイGPT」からGPTを作成し、「構成」の下にある「新しいアクションを作成する」を選択した先に、OpenAPIスキーマ入力ボックスがあります。
![ChatGPT-UI_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2464900/d48001d5-2c9c-6667-68e7-67c34a8e8c07.png)

ActionsGPTに[SwitchBotAPIのGitHub](https://github.com/OpenWonderLabs/SwitchBotAPI/blob/main/README-v1.0.md)を読んで生成してもらったのを参考に作成しました。
[SwitchBotAPIのv1.1](https://github.com/OpenWonderLabs/SwitchBotAPI/tree/main)は、認証が複雑な(ハッシュやタイムスタンプを使う)ため、v1.0で作成しています。つまり、v1.1(最新のSwitchBotデバイス)は利用不可です。

以下はChatGPT用のOpenAPIです。**コピペできます。**(2024/12/01 作り直して更新しました。)
```json
{
    "openapi": "3.1.0",
    "info": {
        "title": "SwitchBot API",
        "description": "Controlling SwitchBot devices and getting status such as bots, curtains, humidifiers, and more. you can use only v1.0 (not v1.1). you must search knowledge files(SwitchBot manual) before API requests. ",
        "version": "1.0.0"
    },
    "servers": [
        {
            "url": "https://api.switch-bot.com/v1.0"
        }
    ],
    "paths": {
        "/devices/{deviceId}/status": {
            "get": {
                "description": "Get the status of a specific device.",
                "operationId": "getDeviceStatus",
                "parameters": [
                    {
                        "name": "deviceId",
                        "in": "path",
                        "description": "The ID of the device to retrieve status for",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "deprecated": false
            }
        },
        "/devices/{deviceId}/commands": {
            "post": {
                "description": "Send a command to a specific device.",
                "operationId": "sendCommand",
                "parameters": [
                    {
                        "name": "deviceId",
                        "in": "path",
                        "description": "The ID of the device to send the command to",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "command": {
                                        "type": "string",
                                        "example": "turnOn"
                                    },
                                    "parameter": {
                                        "type": "string",
                                        "example": "default"
                                    },
                                    "commandType": {
                                        "type": "string",
                                        "example": "command"
                                    }
                                }
                            }
                        }
                    }
                },
                "deprecated": false
            }
        }
    },
    "components": {
        "schemas": {}
    }
}
```

### 2\. 「認証」にトークンを入力する
認証に認証タイプをAPIキーにしてBearerにします。
SwitchBotアプリの開発者向けオプションで入手したトークンをAPIキーに入力して保存します。入手方法は他で調べていただけると助かります。
![ChatGPT-UI_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2464900/9e5e57bd-b077-f139-014c-44f9006d8782.png)

:::note warn
トークンがわかれば誰でもデバイスを自由に操作できてしまうので、注意してここだけに入力します。
:::
トークンを入力して保存したあと、再度開くとまるで何も入力されていないように見えますが(2024/08/20時点)、どうやら保存されているらしく問題ありませんでした。(ここで戸惑った...)

### 3\. 「知識」に マニュアル をアップロードする。
:::note info
ここはコピペではできないので注意してください
:::
**ここが少々めんどくさいです。**

「知識」は一つ戻った「構成」の項目にあります。今回はマニュアルを使ってもらうような仕組みにしました。
ChatGPTがユーザのSwitchBotデバイスを操作できるようにマニュアルを知識としてアップロードします。現時点ではまだ、ChatGPTが、登録されているデバイスを知らない状態です。
getDeviceStatusに必要なのはdeviceIdの1つで、sendCommandに必要なのは、deviceId、commandType、command、command parameterの4つです。

マニュアルを作るのに、**SwitchBot APIの仕組みをある程度理解しておく必要があります。**
以下のコードで登録したデバイスの一覧を取得できます。
```python
headers = {"Authorization":"(SwitchBotのトークン)","Content-Type":"application/json"}
response = requests.get("https://api.switch-bot.com/v1.0/devices",headers=headers)
print(response.text)
```
マニュアルを[SwitchBotAPIのGitHub](https://github.com/OpenWonderLabs/SwitchBotAPI/blob/main/README-v1.0.md)からdescriptionや各パラメータ、上記のコードで得たデバイスの一覧を参考に、手動で作成します。
以下はマニュアルの例です。jsonで構成しています。マニュアルですので、ChatGPTはもちろん人間が読んでわかれば形式はなんでも良いです。

**例ですので、コピペではできないため注意してください。**
```json
 [
     {
        "deviceId": "(実際のデバイスID)",
        "deviceName": "洋室の加湿器",
        "parameter": [
            {
                "description": "set to OFF state",
                "commandType": "command",
                "command": "turnOff",
                "command parameter": "default"
            },
            {
                "description": "set to ON state",
                "commandType": "command",
                "command": "turnOn",
                "command parameter": "default"
            },
            {
                "description": "auto, set to Auto Mode,101, set atomization efficiency to 34%,102, set atomization efficiency to 67%,103, set atomization efficiency to 100%",
                "commandType": "command",
                "command": "setMode",
                "command parameter": "auto or 101 or 102 or 103 or {0~100}"
            }
        ]
    },
...
```
※ デバイス名は、GPTが理解できるように「リビングの照明」といったように全て「部屋+デバイス」にしています。また、人感センサーが「明るさ」を検出できることがわかるように「トイレの人感センサー(明るさセンサーつき)」のように()でわかりやすくしています。
※ マニュアルを使ってもらうような仕組みの方が、GPTが都度APIでデバイスリストを取得し、GitHubをweb検索してもらう方法よりも、負荷が減ると考えています。
※ SwitchBotデバイスや赤外線リモコンを新たに登録したりして更新したのであれば、マニュアルも更新する必要はありますが、頻繁にやらないので良いかと思います。

補足が多くてすみません。ここで挫折させてしまっていたら申し訳ないです...

# 動かしてみる
![ChatGPT-UI_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2464900/e033c120-4526-3537-c7ac-dccafcf8d7ec.png)
「リビングの窓」は実際に設置している開閉センサーから取得しており想定通りでした。気温と湿度はホームに3つ温湿度計があるので、きちんと3回リクエストしてから提示してくれました。数値も合ってました。

プライバシー設定で「常に許可」にするとGETリクエスト(窓の開閉状態、室内気温と湿度の取得)は確認を求められずに実行できますが、POSTリクエスト(リビングの電気をつけて)は「常に許可」にしていても、確認を求められる(2024/12/01)ようですが、思った通りに機能しました。
![ChatGPT-UI_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2464900/d75ecce1-63f5-043c-846c-6dd180a8289a.png)

画像にはないですが「リビングの電気をつけて」の後に「やっぱ戻して」と指示をすると電気を消してくれました。

やってみたことは以下のNoteで書きました。ChatGPTの優秀さを確認できるので、ぜひご覧ください。
[ChatGPTにSwitchBotを操作してもらう - Note](https://note.com/potemayorca/n/n84bc5a0ff49f)

# まとめ
やりたいことができて満足しました！
せっかくGPTがSwitchBotを操作したり、センサーからデータを取得できるようになったので、「室内温度と室外温度を比較してエアコンのオンオフを推測する」ようなロジックをGPTが考えて、実際にできるのか試してみたいと思います。

### 使用したサービス、参考
[SwitchBot](https://www.switchbot.jp/)
[SwitchBotAPI-v1.0-Github](https://github.com/OpenWonderLabs/SwitchBotAPI/blob/main/README-v1.0.md)
[ChatGPT-OpenAI](https://chatgpt.com)

ありがとうございます。

記事に不備があれば、お手数ですがお知らせください。