微信公众号硬件开发杂谈(二)

时间:2022-08-31 22:45:04

设备授权与状态查询

在上一篇中我们说到要使用设备首先要进行授权操作,设备完成授权之后就可以通过接口来做一些操作,授权接口的具体参数官方说明看这个地址
设备授权

入参中的AccessToken如果不明白的要看下微信开发的基础部分,参数body中id为deviceid,调试的时候mac地址和id都要向硬件厂商索要,authkey这些参数先可以自行填写,等有了再填入正确的。“connect_protocol”这个参数填4,因为咱们进行的是wifi设备开发,close_strategy这个是断开策略,请注意。下面auth_ver选0,不加密,与上面对应,op_type这个参数注意,为0时设备授权,为1时设备更新,完成后检查问题,返回正确参数deviceid和device_type,除了返回正确的入参,在公众号的产品列表中也可以看到授权配额-1,这个过程是不可逆的,已经授权的配额就不能再取消,但是可以通过“设备状态查询”接口查询到三种状态(未授权、已授权、已绑定)。

如果没有设备想模拟在线,可以使用设备授权新接口,还会返回了qrticket,把这个字符串放到二维码生成器(随便搜索一下就有)中,会返回一个二维码,扫码即可绑定设备,然后再通过 第三方主动发送设备状态消息给微信终端 模拟状态

{
    "device_type": "公众号原始ID",
    "device_id": "XXX",
    "open_id": "XXX",
    "msg_type": " 2",
    "device_status": " 1"
}

测试公众号可以在页面右上角看到原始ID,device_id和open_id都是基础参数,状态这里填“1”就是在线状态,接口请求成功就会在公众号的名称下面看到一个“已连接”的状态。

HTTP请求帮助类

在调试过程中我们可以使用微信的接口调试工具或者Postman进行接口测试,但在产品实际应用中还是要实现HTTP请求的代码,这里贴一下帮助类的示例

/// <summary>
/// 获取html
/// </summary>
/// <param name="url">url</param>
/// <param name="encoding">encoding</param>
/// <returns>HttpResult</returns>
HttpResult _Get(string url, Encoding encoding)
{
    HttpResult result = new HttpResult();
    try
    {
        var response = HttpClient.GetAsync(url);
        result.result = true;
        result.html = response.Result.Content.ReadAsStringAsync().Result; // .Content.ReadAsStringAsync();
    }
    catch (Exception ex)
    {
        result.result = false;
        result.html = "转发接口失败," + ex.Message;
    }

    return result;
}

/// <summary>
/// 获取html
/// </summary>
/// <param name="url"></param>
/// <param name="paramss"></param>
/// <param name="encoding"></param>
/// <param name="jsonstring"></param>
/// <returns></returns>
private HttpResult _Post(string url, Dictionary<string, string> paramss, Encoding encoding, string jsonstring = "")
{
    HttpResult r = new HttpResult();
    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
    req.Proxy = null;
    try
    {
        string param = string.Empty;
        if (string.IsNullOrWhiteSpace(jsonstring))
        {
            foreach (string p in paramss.Keys)
            {
                param += p + "=" + paramss[p] + "&";
            }

            req.ContentType = "application/x-www-form-urlencoded";
        }
        else
        {
            param = jsonstring;
            req.ContentType = "application/json";
        }

        foreach (var headerParam in paramss)
        {
            req.Headers.Add(headerParam.Key, headerParam.Value);
        }

        byte[] bs = Encoding.UTF8.GetBytes(param);
        string responseData = string.Empty;
        req.Method = "POST";
        req.ContentLength = bs.Length;
        using (Stream reqStream = req.GetRequestStream())
        {
            reqStream.Write(bs, 0, bs.Length);
            reqStream.Close();
        }

        using (HttpWebResponse response = (HttpWebResponse)req.GetResponse())
        {
            using (StreamReader reader = new StreamReader(response.GetResponseStream(), encoding))
            {
                responseData = reader.ReadToEnd().ToString();
            }

            r.result = true;
            r.html = responseData;
        }
    }
    catch (Exception e)
    {
        r.html = e.ToString();
        if (req != null)
        {
            req.Abort();
        }

        return r;
    }

    return r;
}

public class HttpResult
{
    public bool result;
    public Task<string> htmlasync;
    public string html;
    public int stateCode;
}

Get请求结构较为简单,需要注意的是Post请求中,根据接口的不同,参数会出现不同的位置,在url、header和body中均有可能需要传参。

WebSocket

以前知道有这么个东西,但是具体有什么作用,特别在哪是不太清楚,或者为什么要用这个东西,但通过这次接触微信硬件的开发大概理解了一点,首先要明确WebSocket是一种与HTTP不同的协议,引用*的说明如下:

服务器可以通过标准化的方式来实现,而无需客户端首先请求内容,并允许消息在保持连接打开的同时来回传递。通过这种方式,可以在客户端和服务器之间进行双向持续对话。

简单来说他可以让客户端和服务器之间保持一个低耗的长连接,那么这个和硬件开发有什么关系呢?

最初我只是知道智能家居通过wifi远程控制,所以想单片机应该也可以通过同样的原理实现,利用一个业务服务器接受用户的操作,然后服务器发送请求给家里的路由器,再由路由器转发给家里的设备,既然是这样,就转化成了我说属性的HTTP请求,中间的传输无非就是POST请求发送json格式的数据。

想来是挺简单的,但是虽然开发的深入,发现硬件设备是一个发信器,它只向外请求并接收返回的结果,但是当路由器想发送接收自客户端的设备状态数据时却不知道发送给谁,这样引起的一个情况是如果要想实现实时的设备控制,需要设备不停地向服务器发送GET请求来获取当前的状态,这样就形成的极大的浪费,这样的轮询过程中大部分的数据可能都是无效的,比如请求头中的一些必要条件,但实际要传输的状态数据往往就只是一个字符串。

在WebSocket出现之前,也确实都是这样做的,但自从有了WebSocket,硬件设备就可以和服务器之间建立一个长连接,这也就是我们在前面所实现“上线”操作,实际上就是打开这一长连接。

这次做硬件的研究断断续续持续了很久,其中真的是遇到了相当多的问题,尤其是在不了解的领域中,但是随着问题一个个被克服,有让我感受到了最初的那种解决问题的快乐,因为问题比较零碎,而且自己的理解还不到位,所以其中很多问题不能形成段落记录下来比较可惜,但是整个开发的过程和结果都是相当令人难忘的。