Nest API为开发者提供了与其Nest Learning Thermostat™和Nest Protect: Smoke + Carbon Monoxide™设备的集成能力。然而,尽管API提供了Firebase、REST和REST Streaming等多种接入方式,但在.NET环境中实现实时特性时,开发者可能会遇到一些挑战。本文将介绍如何在.NET环境中使用FirebaseSharp库来实现Nest API的实时数据更新。
Nest API允许开发者接入Nest设备,但目前.NET开发者在尝试使用API的实时特性时可能会遇到困难。官方的Firebase客户端库目前仅支持Web(JavaScript客户端)、iOS和Android平台。而REST Streaming基于EventSource,这在.NET环境中并不原生支持。REST选项也不适用于实时更新,Nest对特定时间段内的调用次数有限制,因此不适合轮询更新。
在寻找解决方案的过程中,发现了FirebaseSharp,这是一个允许使用Firebase协议调用Nest API并获取实时数据的库。
首先,可以下载完整的项目。要访问Nest API,需要注册客户端。在上完成这个简单的步骤。注册新客户端时,OAuth重定向URI需要设置为http://localhost:9000/api/oauth,以便成功运行此演示(Nest会在授权后调用此URL,并附带授权码)。至少需要选择Thermostat的读取权限,以成功运行此演示。
要获取Nest设备数据的访问权限,需要按照Nest的说明进行OAuth认证。以下是.NET环境中的实现步骤:
首先,更新App.config文件,添加客户端OAuth设置:
<add key="client-id" value="<client-id>"/>
<add key="client-secret" value="<client-secret>"/>
然后,构建授权URL,使用客户端ID标识请求访问的应用程序:
var authorizationUrl = string.Format("https://home.nest.com/login/oauth2?client_id={0}&state={1}", ConfigurationManager.AppSettings["client-id"], "dummy-random-value-for-anti-csfr");
如果用户接受,Nest会重定向到配置的OAuth重定向URI。为了简化演示,在控制台应用程序中自托管ASP.NETWeb API来处理响应:
using (WebApp.Start<Startup>(url: "http://localhost:9000/"))
{
// snip
}
首先验证state参数,以确保通信的完整性。然后使用收到的授权码请求访问令牌。为了简化,将访问码响应转换为动态类型,以便可以访问token属性,而无需进行严格的反序列化:
public HttpResponseMessage Get(string state, string code)
{
if (!string.Equals("dummy-random-value-for-anti-csfr", state))
throw new HttpResponseException(HttpStatusCode.BadRequest);
var accessToken = GetAccessToken(code);
Program.SubscribeToNestDeviceDataUpdates(accessToken);
var response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent("Well done, you now have an access token which allows you to call Nest API on behalf of the user.")
};
response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html");
return response;
}
private async Task<string> GetAccessToken(string authorizationCode)
{
var url = string.Format("https://api.home.nest.com/oauth2/access_token?code={0}&client_id={1}&client_secret={2}&grant_type=authorization_code", authorizationCode, ConfigurationManager.AppSettings["client-id"], ConfigurationManager.AppSettings["client-secret"]);
using (var httpClient = new HttpClient())
{
using (var response = httpClient.PostAsync(url, content: null).Result)
{
var accessToken = JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().Result);
return (accessToken as dynamic).access_token;
}
}
}
现在有了访问令牌,可以代表用户调用Nest API了。
要模拟Nest设备,需要使用Nest Developer Chrome Extension。如果遇到任何问题,请按照上的简单步骤操作。简而言之:
现在有了可以模拟实时事件的虚拟设备,将在下一步中消费这些事件。
通过Nuget获取FirebaseSharp:
Install-Package FirebaseSharp
一旦有了访问令牌,初始化一个指向Nest API的Firebase客户端,并使用检索到的访问令牌。在这种情况下,监听设备,但请参考Nest API参考文档,了解想要如何细化选项。
var firebaseClient = new Firebase("https://developer-api.nest.com", _accessToken);
var response = firebaseClient.GetStreaming("devices", changed: (s, e) =>
{
if (e.Path.Contains("ambient_temperature_f"))
Console.WriteLine("Current temperature has been updated to: {0}.", e.Data);
});
现在有了工作解决方案!