日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

微信公众号硬件开发杂谈

發(fā)布時間:2023/12/14 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 微信公众号硬件开发杂谈 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

最近幫朋友研究一個單片機的項目,簡單接觸了一下微信公眾號的硬件平臺,遇到很多問題,簡單記錄一下

該怎么連接

準(zhǔn)備工作

首先不管用什么接口,做硬件和軟件的交互一般還是先想著怎么去做一個基礎(chǔ)的連接操作,最開始查到一些教程并參考微信官方的說法就是先申請設(shè)備接入的權(quán)限,以測試號來說,申請非常簡單,如圖所示

申請完成后,點擊【設(shè)置】進入設(shè)備管理頁面,按照提示一步步操作就可以添加設(shè)備,我這邊是使用的是第三方的硬件設(shè)備,通過wifi進行連接,根據(jù)相關(guān)文檔進行如下設(shè)置,具體選項內(nèi)容應(yīng)該要根據(jù)硬件設(shè)備類型來定。

經(jīng)過簡單的設(shè)置就可以生成一個設(shè)備,可以在設(shè)備列表看到,另外提一下,似乎一直都存在一個意義不明的undefined設(shè)備,應(yīng)該是平臺開發(fā)人員保留的,不影響使用

常規(guī)方法

通過這種方式新建的設(shè)備默認擁有100個配額,代表能授權(quán)100個可以控制的設(shè)備,我這里的截圖中是已經(jīng)授權(quán)了一個設(shè)備,授權(quán)需要通過接口發(fā)送請求,具體接口內(nèi)容在后面詳述。之后開始說第一次連接這個重要的問題,但是我這邊并不方便驗證結(jié)果,在這里說下最后的實踐結(jié)果。一些教程會提到通過掃描產(chǎn)品詳情里的二維碼就可以執(zhí)行連接操作,但對于普通測試情況并不符合。以下是通常情況的操作流程:

  • 在產(chǎn)品配置中連接方式選擇wifi
  • 進行設(shè)備授權(quán)(不確定是否必要)
  • 掃描產(chǎn)品詳情中的二維碼會調(diào)起Airkiss頁面(現(xiàn)在先簡單理解成一個輸入你當(dāng)前連接wifi的密碼的頁面)
  • 打開硬件設(shè)備的AirLink模式,并在手機上輸入wifi密碼進行連接
  • 連接成功后,會跳轉(zhuǎn)至一個搜索設(shè)備的頁面

問題就出在最后一步,我在這里進行了反復(fù)的測試,前置的配置操作重復(fù)了很多遍,還換過開發(fā)板,在這里都是搜索不到設(shè)備,經(jīng)過大量的查找資料發(fā)現(xiàn)如果想通過這種方式掃描到設(shè)備必須在設(shè)備芯片的固件中寫入公眾號的ID,并且我后來也在設(shè)備詳情中發(fā)現(xiàn)了相關(guān)依據(jù)

雖然找到了問題,但是固件的編寫是個很大的問題,簡單的燒錄可以做到,但修改編譯固件的代碼卻是不懂,所幸后面發(fā)現(xiàn)了另一種方法,但是由于最終使用的固件版本是第三方平臺機智云的,所以無法驗證其他的情況是否可以,這里主要是記錄一下開發(fā)的過程。

JS-SDK

上面介紹的方法在掃碼后就會自動跳出一個頁面,這個是微信官方提供的,如果不想使用這個頁面的話就可以通過JS-SDK的方式。

在進行下一步操作之前我們還要了解一下這個跳出的頁面是什么,官方的描述如下:

Airkiss是微信硬件平臺為Wi-Fi設(shè)備提供的微信配網(wǎng)、局域網(wǎng)發(fā)現(xiàn)和局域網(wǎng)通訊的技術(shù)。開發(fā)者若要實現(xiàn)通過微信客戶端對Wi-Fi設(shè)備配網(wǎng)、通過微信客戶端在局域網(wǎng)發(fā)現(xiàn)Wi-Fi設(shè)備,或者把微信客戶端內(nèi)的音樂、圖片、文件等消息通過局域網(wǎng)發(fā)送至Wi-Fi設(shè)備,需要在硬件設(shè)備中集成相應(yīng)的AirKiss靜態(tài)庫。

通過這句話我們可以知道要想在局域網(wǎng)內(nèi)發(fā)現(xiàn)設(shè)備就可以通過這一方法,更詳細的說明可以看這個頁面
AirKiss概述及應(yīng)用場景

根據(jù)Airkiss2.0的文檔我們可以知道通過JSAPI可以進行配網(wǎng),以達到我們的目的。首先在Web層引用微信JSAPI,JSAPI技術(shù)是微信JS-SDK的一部分,,主要是通過 wx.readywx.config 這兩個函數(shù)調(diào)用官方的接口,具體說明參考
JSAPI介紹

使用Airkiss文檔里的configWXDeviceWiFi這個方法就可以進行自定義的AirKiss連接,這里我使用的框架是ASP.NET MVC,所以可以看到AppID、timestamp、nonceStr、signature這幾個參數(shù)是從后臺傳入的,具體的后臺生成代碼放在下面參考,有些參數(shù)需要自行傳入,注意修改。

<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> <script type="text/javascript">$(function () {});$('#btnLink').click(function () {wx.config({beta: true,debug: true, // 開啟調(diào)試模式,調(diào)用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數(shù),可以在pc端打開,參數(shù)信息會通過log打出,僅在pc端時才會打印。appId: '@ViewBag.appId', // 必填,公眾號的唯一標(biāo)識timestamp: '@ViewBag.timeStamp', // 必填,生成簽名的時間戳nonceStr: '@ViewBag.randomStr', // 必填,生成簽名的隨機串signature: '@ViewBag.signatur',// 必填,簽名jsApiList: ["configWXDeviceWiFi"] // 必填,需要使用的JS接口列表});wx.invoke('configWXDeviceWiFi');}); </script>

C#后臺代碼參考

public class AirkissHelper {public static string appID = BaseConfig.appID;public static string appsecret = BaseConfig.appsecret;class TokenResultMessage // 封裝調(diào)用access_token接口返回的數(shù)據(jù){public string access_token;public string expires_in;}class JsapiResultMessage // 封裝調(diào)用jsapi_ticket接口返回的數(shù)據(jù){public string errcode;public string errmsg;public string ticket;public string expires_in;}/// <summary>/// Get請求封裝/// </summary>/// <param name="url"></param>/// <returns></returns>private static string GetWebUrl(string url){WebClient client = new WebClient(); // 創(chuàng)建瀏覽器Stream stream = client.OpenRead(url); // 傳入url地址return new StreamReader(stream).ReadToEnd(); // 得到響應(yīng)字符串}/// <summary>/// sha1簽名算法/// </summary>/// <param name="str"></param>/// <returns></returns>private static string Sha1(string str){var sha1 = System.Security.Cryptography.SHA1.Create();byte[] bytes = Encoding.UTF8.GetBytes(str);byte[] bytesArr = sha1.ComputeHash(bytes);StringBuilder sb = new StringBuilder();foreach (var item in bytesArr){sb.AppendFormat("{0:x2}", item);}return sb.ToString();}/// <summary>/// 生成時間戳/// </summary>public static string GetTimeStamp(){TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1);return Convert.ToInt64(ts.TotalSeconds).ToString();}/// <summary>/// 生成32位隨機字符串/// </summary>public static string GetRandomStr(){string strArr = "0123456789QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm";Random rand = new Random();string randStr = "";for (int i = 0; i < 32; i++){int index = rand.Next(strArr.Length);randStr += strArr.Substring(index, 1);}return randStr;}/// <summary>/// 生成簽名/// </summary>public static string GetSignatur(string timestamp,string nonceStr){// 通過API獲取access_tokenstring tokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appID + "&secret=" + appsecret;var tokenInfo = new JavaScriptSerializer().Deserialize<TokenResultMessage>(GetWebUrl(tokenUrl));// 通過API獲取jsapi_ticketstring jsapiUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + tokenInfo.access_token + "&type=jsapi";var jsapiInfo = new JavaScriptSerializer().Deserialize<JsapiResultMessage>(GetWebUrl(jsapiUrl));// 當(dāng)前網(wǎng)頁的URL,不包含#及其后面部分string nowUrl = BaseConfig.nowUrl;//string nowUrl = Request.Url.AbsoluteUri; // 部署服務(wù)器后應(yīng)動態(tài)獲取頁面url// 用Dictionary集合存儲各變量Dictionary<string, string> dic = new Dictionary<string, string>{["timestamp"] = timestamp,["noncestr"] = nonceStr,["url"] = nowUrl,["jsapi_ticket"] = jsapiInfo.ticket};// 對變量名字典排序string[] arrKey = new string[] { "timestamp", "noncestr", "url", "jsapi_ticket" };arrKey = arrKey.OrderBy(n => n).ToArray();// 拼接字符串string signatureStr = "";foreach (var item in arrKey){signatureStr += item + "=" + dic[item] + "&";}signatureStr = signatureStr.Substring(0, signatureStr.Length - 1);// 對拼接串sh1簽名,得到最終簽名return Sha1(signatureStr);} }

做好配置部分的代碼后,在頁面上使用 wx.invoke(‘configWXDeviceWiFi’); 就可以手動調(diào)起Airkiss頁面,輸入wifi密碼后手動連接,根據(jù)wx.config里面的debug配置會返回提示消息。

設(shè)備授權(quán)與狀態(tài)查詢

在上一篇中我們說到要使用設(shè)備首先要進行授權(quán)操作,設(shè)備完成授權(quán)之后就可以通過接口來做一些操作,授權(quán)接口的具體參數(shù)官方說明看這個地址
設(shè)備授權(quán)

入?yún)⒅械腁ccessToken如果不明白的要看下微信開發(fā)的基礎(chǔ)部分,參數(shù)body中id為deviceid,調(diào)試的時候mac地址和id都要向硬件廠商索要,authkey這些參數(shù)先可以自行填寫,等有了再填入正確的。“connect_protocol”這個參數(shù)填4,因為咱們進行的是wifi設(shè)備開發(fā),close_strategy這個是斷開策略,請注意。下面auth_ver選0,不加密,與上面對應(yīng),op_type這個參數(shù)注意,為0時設(shè)備授權(quán),為1時設(shè)備更新,完成后檢查問題,返回正確參數(shù)deviceid和device_type,除了返回正確的入?yún)?#xff0c;在公眾號的產(chǎn)品列表中也可以看到授權(quán)配額-1,這個過程是不可逆的,已經(jīng)授權(quán)的配額就不能再取消,但是可以通過“設(shè)備狀態(tài)查詢”接口查詢到三種狀態(tài)(未授權(quán)、已授權(quán)、已綁定)。

如果沒有設(shè)備想模擬在線,可以使用設(shè)備授權(quán)新接口,還會返回了qrticket,把這個字符串放到二維碼生成器(隨便搜索一下就有)中,會返回一個二維碼,掃碼即可綁定設(shè)備,然后再通過 第三方主動發(fā)送設(shè)備狀態(tài)消息給微信終端 模擬狀態(tài)

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

測試公眾號可以在頁面右上角看到原始ID,device_id和open_id都是基礎(chǔ)參數(shù),狀態(tài)這里填“1”就是在線狀態(tài),接口請求成功就會在公眾號的名稱下面看到一個“已連接”的狀態(tài)。

HTTP請求幫助類

在調(diào)試過程中我們可以使用微信的接口調(diào)試工具或者Postman進行接口測試,但在產(chǎn)品實際應(yīng)用中還是要實現(xiàn)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 = "轉(zhuǎn)發(fā)接口失敗," + 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請求結(jié)構(gòu)較為簡單,需要注意的是Post請求中,根據(jù)接口的不同,參數(shù)會出現(xiàn)不同的位置,在url、header和body中均有可能需要傳參。

WebSocket

以前知道有這么個東西,但是具體有什么作用,特別在哪是不太清楚,或者為什么要用這個東西,但通過這次接觸微信硬件的開發(fā)大概理解了一點,首先要明確WebSocket是一種與HTTP不同的協(xié)議,引用維基百科的說明如下:

服務(wù)器可以通過標(biāo)準(zhǔn)化的方式來實現(xiàn),而無需客戶端首先請求內(nèi)容,并允許消息在保持連接打開的同時來回傳遞。通過這種方式,可以在客戶端和服務(wù)器之間進行雙向持續(xù)對話。

簡單來說他可以讓客戶端和服務(wù)器之間保持一個低耗的長連接,那么這個和硬件開發(fā)有什么關(guān)系呢?

最初我只是知道智能家居通過wifi遠程控制,所以想單片機應(yīng)該也可以通過同樣的原理實現(xiàn),利用一個業(yè)務(wù)服務(wù)器接受用戶的操作,然后服務(wù)器發(fā)送請求給家里的路由器,再由路由器轉(zhuǎn)發(fā)給家里的設(shè)備,既然是這樣,就轉(zhuǎn)化成了我說屬性的HTTP請求,中間的傳輸無非就是POST請求發(fā)送json格式的數(shù)據(jù)。

想來是挺簡單的,但是雖然開發(fā)的深入,發(fā)現(xiàn)硬件設(shè)備是一個發(fā)信器,它只向外請求并接收返回的結(jié)果,但是當(dāng)路由器想發(fā)送接收自客戶端的設(shè)備狀態(tài)數(shù)據(jù)時卻不知道發(fā)送給誰,這樣引起的一個情況是如果要想實現(xiàn)實時的設(shè)備控制,需要設(shè)備不停地向服務(wù)器發(fā)送GET請求來獲取當(dāng)前的狀態(tài),這樣就形成的極大的浪費,這樣的輪詢過程中大部分的數(shù)據(jù)可能都是無效的,比如請求頭中的一些必要條件,但實際要傳輸?shù)臓顟B(tài)數(shù)據(jù)往往就只是一個字符串。

在WebSocket出現(xiàn)之前,也確實都是這樣做的,但自從有了WebSocket,硬件設(shè)備就可以和服務(wù)器之間建立一個長連接,這也就是我們在前面所實現(xiàn)“上線”操作,實際上就是打開這一長連接。

后記

這次做硬件的研究斷斷續(xù)續(xù)持續(xù)了很久,其中真的是遇到了相當(dāng)多的問題,尤其是在不了解的領(lǐng)域中,但是隨著問題一個個被克服,有讓我感受到了最初的那種解決問題的快樂,因為問題比較零碎,而且自己的理解還不到位,所以其中很多問題不能形成段落記錄下來比較可惜,但是整個開發(fā)的過程和結(jié)果都是相當(dāng)令人難忘的。

總結(jié)

以上是生活随笔為你收集整理的微信公众号硬件开发杂谈的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。