「AIしげちゃん」でNature Remoの環境センサーの値を取得
前回に引き続き、破損前の「AIしげちゃん」にあった、Nature Remoの環境センサーの値を取得して、温湿度の値を答えるスキルを復活中。
ただ、センサーの値を答えるだけでは芸がないので、温湿度の値から不快指数を計算して、少し盛った会話ができるようにしているw
[SensorSkill.cs]
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
using Cysharp.Threading.Tasks;
using Newtonsoft.Json;
using ChatdollKit.Dialog;
using ChatdollKit.Dialog.Processor;
using System.Net.Http;
namespace ChatdollKit.Kazz
{
public class SensorSkill : ChatGPTFunctionSkillBase
{
public string FunctionName = @"get_sensor";
public string FunctionDescription = @"仕事部屋の環境センサーの値を取得します。環境センサーの種類は「Temperature」「Humidity」「Illuminance」です。";
public string InstructionPrompt = @"以下は仕事部屋の環境センサーから取得した値です。あなた自身の言葉でユーザーに伝えてください。";
private const string TOKEN_REMO
= @"Nature Remo Cloud APIのアクセストークン";
public override ChatGPTFunction GetFunctionSpec()
{
// Make function spec for ChatGPT Function Calling
var func = new ChatGPTFunction(FunctionName, FunctionDescription);
func.AddProperty("sensor_name", new Dictionary<string, object>() { { "type", "string" } });
return func;
}
protected override async UniTask<FunctionResponse> ExecuteFunction(
string argumentsJsonString, Request request, State state, User user, CancellationToken token)
{
// Parse arguments
// var arguments = JsonConvert.DeserializeObject<Dictionary<string, string>>(argumentsJsonString);
// var sensorName = arguments["sensor_name"];
string message = string.Empty; ;
try
{
string url = "https://api.nature.global/1/devices";
var httpClient = new HttpClient();
var httpRequest = new HttpRequestMessage(HttpMethod.Get, url);
httpRequest.Headers.Add("accept", "application/json");
httpRequest.Headers.Add("Authorization", "Bearer " + TOKEN_REMO);
var devicesResponse = await httpClient.SendAsync(httpRequest);
var devicesjson = devicesResponse.Content.ReadAsStringAsync().Result;
List<Device> devices = JsonConvert.DeserializeObject<List<Device>>(devicesjson);
double te = devices[0].newest_events.te.val;
double hu = devices[0].newest_events.hu.val;
double il = devices[0].newest_events.il.val;
double di = 0.81 * te + 0.01 * hu * (0.99 * te - 14.3) + 46.3;
message = @"現在の温度は" + te.ToString() + @"度、湿度は" + hu + @"パーセント、照度は"
+ il.ToString() + @"ルクス、不快指数は" + di.ToString("0.0") + @"で、";
// 不快指数の算定
if (di < 50)
{
message += @"寒くてたまりません。";
}
else if (50 <= di && di < 55)
{
message += @"寒いです。";
}
else if (55 <= di && di < 60)
{
message += @"肌寒いです。";
}
else if (60 <= di && di < 65)
{
message += @"特に何も感じません";
}
else if (65 <= di && di < 70)
{
message += @"快適です。";
}
else if (70 <= di && di < 75)
{
message += "暑くはありません。";
}
else if (75 <= di && di < 80)
{
message += @"少し暑いです。";
}
else if (80 <= di && di < 85)
{
message += @"暑くて汗が出ます。";
}
else if (85 <= di)
{
message += @"暑くてたまりませんね。";
}
}
catch
{
message = @"環境センサーの値を取得できませんでした。";
}
return new FunctionResponse(
InstructionPrompt + $"\n\n{message}");
}
private class Device
{
//public string name { get; set; }
//public string id { get; set; }
//public DateTime created_at { get; set; }
//public DateTime updated_at { get; set; }
//public string mac_address { get; set; }
//public string serial_number { get; set; }
//public string firmware_version { get; set; }
//public int temperature_offset { get; set; }
//public int humidity_offset { get; set; }
//public List<User> users { get; set; }
public NewestEvents newest_events { get; set; }
}
//private class User
//{
// public string id { get; set; }
// public string nickname { get; set; }
// public bool superuser { get; set; }
//}
private class NewestEvents
{
public Te te { get; set; }
public Hu hu { get; set; }
public Il il { get; set; }
}
private class Te
{
public double val { get; set; }
//public DateTime created_at { get; set; }
}
private class Hu
{
public double val { get; set; }
//public DateTime created_at { get; set; }
}
private class Il
{
public double val { get; set; }
//public DateTime created_at { get; set; }
}
}
}
GPTのFunction Callingでセンサーの種類を返すようにしているけど、温度、湿度、照度の値をすべて答えるようにしているので、実際には使ってない。
作成したスキルを ChatdollKitVRMにアタッチしておけば、ChatGPTRouterが起動時にFunction Callingの関数として登録してくれる。ありがたいね。