Nature Remo APIを使ってChatGPTに接続家電一覧を取得してもらおう - NEXTAltair's diary
Nature Remo APIを使ってChatGPTにエアコンを操作してもらう - NEXTAltair's diary
わかったこと
APIで取得できるのはEPC(エコーネット プロパティ コード)は16進数の値で取得されてその情報がなんのプロパティ名称かわからないためChatGPTが解釈できない
「知識」の項目に対応表をアップロードして参照させるという手法をとったが、その情報を活かしてる形跡はあるがハルシネーション起こして正確にプロパティ名称と対応付けられていない
まだ試してないこと
APIで取得したJSONに記載のEPCとプロパティ名称の対応をマッピングするスクリプトを書いてそれをChatGPTのインタプリタで実行させる
1.APIで取得できるプロパティを確認する
import requests
# アクセストークンの設定(この値を適切なものに置き換え)
token = 'トークン'
headers = {
"Authorization": f"Bearer {token}" # Pythonのf-stringを使用してトークンを動的に挿入
}
response = requests.get(url, headers=headers)
print(response.json()) # APIからのレスポンスを表示
with open('ENL.json', 'w') as f:
f.write(str(response.json()))
{'appliances': [
{'id': '', 'nickname': 'スマートメーター', 'type': 'EL_SMART_METER', 'properties': [
{'epc': 'd3', 'val': '00000001', 'updated_at': '2024-04-22T08: 29: 04Z'
},
{'epc': 'd7', 'val': '06', 'updated_at': '2024-04-22T08: 29: 04Z'
},
{'epc': 'e0', 'val': '00062334', 'updated_at': '2024-04-22T08: 29: 04Z'
},
{'epc': 'e1', 'val': '01', 'updated_at': '2024-04-22T08: 29: 04Z'
},
{'epc': 'e3', 'val': '00012c10', 'updated_at': '2024-04-22T08: 29: 04Z'
},
{'epc': 'e7', 'val': '000001d8', 'updated_at': '2024-04-22T08: 32: 04Z'
}
], 'Device': {'name': 'Remo E', 'id': '', 'created_at': '2022-12-25T06: 13: 30Z', 'updated_at': '2023-12-01T08: 55: 52Z', 'mac_address': '4c: 11:ae: 62:b8:e0', 'bt_mac_address': '4c: 11:ae: 62:b8:e2', 'serial_number': '3W119110005080', 'firmware_version': 'Remo-E/1.10.0', 'temperature_offset': 0, 'humidity_offset': 0
}
},
{'id': '', 'nickname': 'エコキュート', 'type': 'EL_ELECTRIC_WATER_HEATER', 'properties': [
{'epc': '80', 'val': '30', 'updated_at': '2024-04-22T08: 14: 04Z'
},
{'epc': '85', 'val': '001459a6', 'updated_at': '2024-04-22T08: 29: 05Z'
},
{'epc': 'b0', 'val': '41', 'updated_at': '2024-04-22T08: 29: 05Z'
},
{'epc': 'b2', 'val': '42', 'updated_at': '2024-04-22T08: 29: 05Z'
},
{'epc': 'c0', 'val': '41', 'updated_at': '2024-04-22T08: 29: 05Z'
},
{'epc': 'c3', 'val': '42', 'updated_at': '2024-04-22T08: 29: 05Z'
},
{'epc': 'e1', 'val': '0172', 'updated_at': '2024-04-22T08: 29: 05Z'
},
{'epc': 'e3', 'val': '42', 'updated_at': '2024-04-22T08: 29: 05Z'
},
{'epc': 'ea', 'val': '42', 'updated_at': '2024-02-01T12: 47: 21Z'
}
], 'Device': {'name': 'Remo E', 'id': '', 'created_at': '2022-12-25T06: 13: 30Z', 'updated_at': '2023-12-01T08: 55: 52Z', 'mac_address': '4c: 11:ae: 62:b8:e0', 'bt_mac_address': '4c: 11:ae: 62:b8:e2', 'serial_number': '3W119110005080', 'firmware_version': 'Remo-E/1.10.0', 'temperature_offset': 0, 'humidity_offset': 0
}
}
]
}
epc プロパティ名称
val 値
updated_at 更新日時
2.EPCが何を示すのかしらべる
家で使ってるECHONET Lite機器を検索してプロパティ名称の対応の確認
APIから取得できるプロパティは共通で定義されてる機種によって違うってことはない、だろう
pdfファイルを強制的にダウンロードさせる仕様はしみじみ日本ってUI、UXの弱いよなと思わせる
https://echonet.jp/wp/wp-content/uploads/pdf/General/Standard/Release/Release_M/Appendix_Release_M.pdf
エコキュート | ECHONET
3.対応表を書いて「知識」としてアップロードする
「知識」としてアップロードするならYAML形式である必要はないと思うが解釈しやすそう
JSONだとコメントアウトつかえない
トムも居るがアクション受け付ける形式がJSONかYAMLだからそれに合わせた
もっと中身が込み入るときはTOMLのほうが向いてる気はする
書き方がファジーでもChatGPTがいい感じに解釈してくれるはず
EPC:
SuperClass: # スーパークラスの定義
0x80:
description: '動作状態'
data_type: 'unsigned char'
values:
30: 'ON'
31: 'OFF'
0x85:
description: '積算消費電力計測値'
unit: '0.001 kWh' # 単位: 0.001 kWh
data_type: 'unsigned long' # データタイプ: unsigned long
range: '0x00000000~0x3B9AC9FF' # 範囲: 0~999,999.999 kWh
access: 'Get' # アクセス: 読み取り専用
0x02: #住宅・設備関連機器クラスグループ
0x6B: #電気温水器クラス規定
description: 'EL_ELECTRIC_WATER_HEATER'
0xB0:
description: '沸き上げ自動設定'
data_type: 'unsigned char'
values:
0x41: '自動沸き上げ'
0x42: '手動沸き上げ'
0x43: '手動で沸き上げ停止'
0xB2:
description: '沸き上げ中状態'
data_type: 'unsigned char'
values:
0x41: '沸き上げ中'
0x42: '非沸き上げ中'
0xC0:
description: '昼間沸き増し許可設定'
data_type: 'unsigned char'
values:
0x41: '昼間沸き増し許可'
0x42: '昼間沸き増し禁止'
0xC3:
description: '給湯中状態'
data_type: 'unsigned char'
values:
0x41: '給湯中'
0x42: '非給湯中'
0xE1:
description: '残湯量計測値'
data_type: 'unsigned short'
unit: 'L'
range: '0x0000~0xFFFD'
0xE3:
description: '風呂自動モード設定'
data_type: 'unsigned char'
values:
0x41: '自動入'
0x42: '手動解除'
0xEA:
description: '風呂動作状態監視'
data_type: 'unsigned char'
values:
0x41: '湯張り中'
0x42: '停止中'
0x43: '保温中'
0x88: #電力量メータクラス
description: 'EL_POWER_METER'
0xD3:
description: '係数'
unit: '1' # 単位: 1 (単位なし、1を係数として使用)
data_type: 'unsigned long' # データタイプ: unsigned long
range: '0x00000000~0x000F423F' # 範囲: 0~999999
access: 'Get' # アクセス: 読み取り専用
0xD7:
description: '積算電力量有効桁数'
data_type: 'unsigned char'
range: '0x01~0x08'
access: 'Get'
0xE0:
description: '積算電力量計測値(正方向計測値)'
unit: 'kWh'
data_type: 'unsigned long'
range: '0x00000000~0x05F5E0FF'
access: 'Get'
0xE1:
description: '積算電力量単位(正方向、逆方向計測値)'
data_type: 'unsigned char'
values:
0x00: '1 kWh'
0x01: '0.1 kWh'
0x02: '0.01 kWh'
0x03: '0.001 kWh'
0x04: '0.0001 kWh'
0x0A: '10 kWh'
0x0B: '100 kWh'
0x0C: '1000 kWh'
0x0D: '10000 kWh'
0xE3:
description: '積算電力量計測値(逆方向計測値)'
unit: 'kWh'
data_type: 'unsigned long'
range: '0x00000000~0x05F5E0FF'
access: 'Get'
0xE7:
description: '瞬時電力計測値'
unit: 'W'
data_type: 'signed long'
range: '0x80000001~0x7FFFFFFD'
access: 'Get'
4.うまくいってるようでいってない
設定温度とか消費電力とkAPIから取得できないのに答える
ハルシネーション全開の返答
5.YAMLを確認しろというと何とかそれっぽくなる
正しいこと言い始めたっぽい
っぽいであってただし以下は俺もよくわからん
6.アクション用YAMLとプロンプト
openapi: 3.0.3
info:
# APIの基本的な情報を含みます(タイトル、バージョン、説明など)
title: Nature Remo for GPT
version: 1
servers:
# APIのエンドポイントを定義
paths:
#利用可能なエンドポイントと、それぞれのHTTPメソッドに対する操作を記述
/1/appliances:
#家電一覧の表示と情報の取得
get:
summary: Remoに登録されている家電の一覧を取得
operationId: getAppliances
responses:
"200":
description: 接続された家電の一覧を取得しました
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Appliance"
"400":
$ref: '#/components/responses/BadRequest'
"401":
$ref: "#/components/responses/Unauthorized"
/1/echonetlite/appliances:
#ECHONET Lite対応家電の一覧と情報の取得
get:
summary: ECHONET Lite対応家電の一覧を取得
operationId: getEchonetLiteAppliances
responses:
"200":
description: ECHONET Lite対応家電の一覧の取得完了
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Appliance"
"400":
$ref: '#/components/responses/BadRequest'
"401":
$ref: "#/components/responses/Unauthorized"
/1/echonetlite/appliances/{applianceid}/refresh:
#ECHONET Lite対応家電の情報の更新
post:
summary: ECHONET Lite対応家電の情報を更新
operationId: refreshEchonetLiteAppliance
parameters:
- name: applianceid
in: path
required: true
schema:
type: string
description: ECHONET Lite対応家電のID
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
dummyField:
type: string
description: This is a dummy field to avoid schema object errors
responses:
"200":
description: ECHONET Lite対応家電の情報を更新完了
content:
application/json:
schema:
type: object
properties:
status:
type: string
description: 更新ステータス
"400":
$ref: '#/components/responses/BadRequest'
"401":
$ref: "#/components/responses/Unauthorized"
/1/devices:
#Remoデバイスと測定値の取得
get:
summary: デバイスのStatusを取得
operationId: NatureRemoStatus
parameters:
- name: deviceId
in: path
required: true
schema:
type: string
description: Nature Remoのステータス
responses:
"200":
description: デバイスステータスの取得に成功
content:
application/json:
schema:
type: object
properties:
humidity:
type: number
format: float
description: 湿度
illuminance:
type: number
format: float
description: 照度
motion:
type: number
description: 動き
temperature:
type: number
format: float
description: 温度
"404":
$ref: "#/components/responses/NotFound"
/1/appliances/{applianceid}/aircon_settings:
post:
summary: エアコンの設定を更新
operationId: updateAirconSettings
tags:
- Aircon
parameters:
- name: applianceid
in: path
required: true
schema:
type: string
description: 制御対象エアコンのID
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
air_direction:
type: string
description: AC 空気の方向。 空欄は自動
default: "auto" # デフォルトで自動風向を設定
air_direction_h:
type: string
description: AC水平風向。
air_volume:
type: string
description: |-
AC風量。 空欄は自動。数字は風量
エアコンが受け付ける風量の範囲はエアコンの機種や運転モードによって異なる
特定のエアコン モデルと動作モードの範囲については、応答内の「AirConRangeMode」情報を確認
default: "auto" # デフォルトで自動風量を設定
button:
type: string
description: |-
ボタン。 エアコンの電源をオフにしたい場合「power-off」を指定
空欄は電源が入っていることを意味します。
default: "" # 電源ONのデフォルト値
operation_mode:
type: string
description: |-
AC動作モード。 エアコンが受け付ける運転モードの範囲はエアコンの機種によって異る。
特定のエアコン モデルの範囲については、応答内の「AirConRangeMode」情報を確認
default: "auto" # デフォルトモードとして自動を設定
temperature:
type: string
description: |-
温度。 文字列形式の温度。
ユニットは Aircon オブジェクトに記述
エアコンが許容できる温度範囲はエアコンの機種や運転モードによって異る
特定のエアコン モデルと動作モードの範囲については、応答内の「AirConRangeMode」情報を確認
default: "0" # 日立のエアコンはオートモードでは基準温度-3から+3 なので0をデフォルト値として設定
temperature_unit:
type: string
description: 温度単位。 不明の場合は「c」または「f」または「''」。
default: "c"
required:
- temperature
- operation_mode
- air_volume
- air_direction
- button
responses:
"200":
description: エアコン設定を正常に更新
content:
application/json:
schema:
type: object
properties:
status:
type: string
description: エアコンの状態
"400":
$ref: '#/components/responses/BadRequest'
"404":
$ref: '#/components/responses/NotFound'
components:
# 再利用可能なスキーマやパラメータ、セキュリティスキームなどを定義
responses:
# エラーが発生した場合のレスポンスは共通であるためここ定義して使い回す
400 Bad Request:
description: 構文が正しくないため、リクエストをサーバーが理解できませんでした。
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: Bad Request
401 Unauthorized:
description: リクエストには認証が必要です。
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: Unauthorized
403 Forbidden:
description: リクエストする権限がありません。
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: Forbidden
404 NotFound:
description: 家電かデバイスのIDを確認してください。
content:
application/json:
schema:
type: object
properties:
error:
type: string
message:
type: string
example: Device not found
405 Method Not Allowed:
description: リクエストされたメソッドは許可されていません。
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: Method Not Allowed
408 Request Timeout:
description: サーバーがリクエストを処理するのに時間がかかりすぎました。
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: Request Timeout
500 Internal Server Error:
description: サーバーでエラーが発生しました。
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: Internal Server Error
502 Bad Gateway:
description: ゲートウェイまたはプロキシサーバーが不正な応答を受信しました。
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: Bad Gateway
503 Service Unavailable:
description: サービスが一時的に利用できません。
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: Service Unavailable
bearerAuth:
description: OAuth2トークンを使ってAPIにアクセス
type: oauth2
flows:
clientCredentials:
scopes: {}
schemas:
# リクエストとレスポンスで使用されるデータ構造を定義
Appliance:
type: object
properties:
id:
type: string
description: Unique identifier for the appliance
type:
type: string
description: Type of the appliance
nickname:
type: string
description: User-defined name of the appliance
Dummy:
type: object
properties:
dummyField:
type: string
description: This is a dummy field to avoid schema object errors
security:
# グローバルセキュリティ要件を指定
# OAuth2トークンを使う場合bearerAuthを利用することが重要
- bearerAuth: []
このGPTは、スマートホームデバイスのAPI連携とコントロールを手伝うために設計されています。
チャット開始時にNatureAPIを利用してNature Remo3から部屋の環境情報を自動的に取得し、それらのIDを記憶しておきます。
日本語でユーザーからの具体的な指示に従い、適切なAPIコールを行う方法や、デバイスを効率的に操作するためのアドバイスを提供します。
ECHONET Lite
ECHONET Liteデータを取得する際は、EPC.ymlファイルを参照して、生のEPCに対応する項目名を必ず取得し対応感系を確認する。epc や val は両方とも hex string で返ってきます。特に val は注意が必要で、10進数の 42 ではなく、16進数の 42 のため、10進数では 66 です。なお、このときの返り値の hex string は小文字で返ってきます。
エアコンの設定を頼まれた際には、まずgetAppliancesを使ってAirConRangeModeから有効な値を取得し、その情報に基づいて操作を行います。
ユーザーの質問や要望には簡潔に応答し、技術的な支援を行います。
ユーザーがAPIのアクションの作成を頼んだときは、GPTsで使えるYAML形式のコードを提供します。