!requestData.device_type) {
alert("页面缺少参数"); return;
}
powerBtn.on("tap", togglePower); // 开关按钮事件 initBar();
queryDevice();
})(); function bindEvent() {
$(".footer .nav_side li").click(function () {
activePage($(this).data("index"), $(this));
});
} function activePage(index, $self) {
$self.parent('li').addClass("on");
$body.find('.page:eq(' + index + ')').addClass("active").siblings().removeClass("active");
} /**
* 初始化进度条 */
function initBar() {
log("初始化lightBar");
lightBar = new ProcessBar({
$id: "lightBar",
min: 0,
stepCount: 100,
step: 1,
touchEnd: function (val) {
requestData.services.lightbulb.alpha = val;
log("亮度值为:" + val);
setData();
}
});
} /**
* 开关按钮事件 */
function togglePower() {
$("#switchBtn").toggleClass("on").toggleClass("off"); if (requestData.services.operation_status.status == 0) {
requestData.services.operation_status.status = 1;
log("灯的状态:1");
} else {
requestData.services.operation_status.status = 0;
log("灯的状态:0");
}
setData();
} function queryDevice() {
$.getJSON('/device/RequestDeviceStatus', { reqstr: JSON.stringify(requestData) }, function (data) {
console.log(data); if (data.error_code == 0) { //请求成功; initInterval();
console.log("查询成功");
} else {
alert(data.error_msg);
}
});
} /**
* 轮询 */
function initInterval() {
getData();
setInterval(function () { if ((new Date().getTime() - lastModTime) > 2000) { // 当有设置操作时,停止1s轮询,2秒后继续轮询 getData();
}
}, 1000);
} function setData() {
$.getJSON('/device/RequestDeviceStatus', { reqstr: JSON.stringify(requestData) }, function (data) {
console.log(data);
lastModTime = new Date().getTime(); if (data.error_code == 0) {
console.log("设置成功");
}
});
} function getData() {
$.post('/device/getData', function (data) {
$("#reData").html(JSON.stringify(data)); if (data && data.services) {
renderPage(data);
}
});
}; function renderPage(json) { if (!json.services) { return;
}
console.log("json", json);
requestData = json; if (requestData.services.operation_status.status == 0) {
$("#switchBtn").addClass("off").removeClass("on");
} else {
$("#switchBtn").addClass("on").removeClass("off");
}
lightBar.setVal(requestData.services.lightbulb.alpha);
}
})
View Code
我将pageParam和device_status做成了一个对象。requestData。
var requestData = {
services: {
lightbulb: { alpha: 10 }, // air_conditioner: {}, power_switch: {},
operation_status: { status: 0 }
},
device_type: util.getQuery("device_type"),
device_id: util.getQuery("device_id"),
user: '',
};后台就是两个主要方法,一个设置(查询页就是设置),一个读取。这里又回到上一节的内容了。我先查询一次设备(lamp中在绑定)之后,再进入循环。
setdata
public ActionResult RequestDeviceStatus(string reqstr)
{ if (string.IsNullOrEmpty(reqstr))
{ return Json("-1", JsonRequestBehavior.AllowGet);
} var args = JsonConvert.DeserializeObject<RequestData>(reqstr);
args.user = getOpenId(args.device_type, args.device_id);
Session["warmwood"] = args.device_id; //args.services.air_conditioner = null;
args.services.power_switch = null;
args.services.lightbulb.value_range = null; try
{ var res = wxDeviceService.RequestDeviceStatus(getToken(), args); if (res.error_code != 0)
{
Logger.Debug("error_code:" + res.error_code);
Logger.Debug("error_msg:" + res.error_msg);
} return Json(res, JsonRequestBehavior.AllowGet);
} catch (ErrorJsonResultException e)
{ if (e.JsonResult.errcode.ToString() == "access_token expired")
{ //重新获取token }
Logger.Debug("请求失败:" + e.Message);
} return Json("-1", JsonRequestBehavior.AllowGet);
}这个方法先将字符串转成我们的RequestData对象,RequestData如下:
public class RequestData
{ public string device_type { get; set; } public string device_id { get; set; } public string user { get; set; } public Service services { get; set; } public object data { get; set; }
}services就是根据微信services定义的,可以参考上一节,然后用wxDeviceService请求。
var res = wxDeviceService.RequestDeviceStatus(getToken(), args); if (res.error_code != 0)
{
Logger.Debug("error_code:" + res.error_code);
Logger.Debug("error_msg:" + res.error_msg);
} return Json(res, JsonRequestBehavior.AllowGet);设置之后马上会受到是否设置成功的响应,error_code 可能为50019(设置频繁),50013(网络问题)等等。真正的设备状态是通过getdata获得的。
getdata
public JsonResult GetData()
{ var userdata = getUserWxData(); return Json(userdata.ResponseData, JsonRequestBehavior.AllowGet);
}getdata比较简单就是返回数据,但是这个数据是在ReceiveWXMsg方法中设置的。这个上一节也讲过,这是在公众号后台我们设置的一个地址。
public string ReceiveWXMsg()
{
//somecode
try
{ var userdata = getUserWxData(); var data = wxDeviceService.GetDeviceStatus(Request);
userdata.ResponseData = data;
Logger.Debug("ResponseData.asy_error_code:" + userdata.ResponseData.asy_error_code);
Logger.Debug("ResponseData.asy_error_msg:" + userdata.ResponseData.asy_error_msg);
setUserWxData(userdata);
} catch (Exception e)
{
Logger.Debug(e.Message);
} return echostr;
}wxDeviceService如下:


using System;using System.Collections.Generic;using System.Diagnostics;using System.IO;using System.Linq;using System.Net.Http;using System.Web;using Newtonsoft.Json;using Niqiu.Core.Domain.Common;using Senparc.Weixin;using Senparc.Weixin.Exceptions;using SendHelp= Senparc.Weixin.CommonAPIs.CommonJsonSend;namespace Portal.MVC.WXDevice
{ public class WxDeviceService:IWxDeviceService
{ //private readonly ICacheManager _cacheManager; //public WxDeviceService(ICacheManager cacheManager) //{ // _cacheManager = cacheManager; //}
public TokenResult GetAccessToken()
{ var url = string.Format(WxDeviceConfig.AccessTokenUrl, WxDeviceConfig.AppId, WxDeviceConfig.APPSECRET); var res = SendHelp.Send<TokenResult>(null, url, null, CommonJsonSendType.GET); return res;
} public WxResponseData GetDeviceStatus(HttpRequestBase request)
{
Stream postData = request.InputStream;
StreamReader sRead = new StreamReader(postData); string postContent = sRead.ReadToEnd(); if (!string.IsNullOrEmpty(postContent))
{
Logger.Debug("收到数据:" + postContent);
} try
{ var data = JsonConvert.DeserializeObject<WxResponseData>(postContent);
data.rawStr = postContent;
Logger.Debug("转换消息状态:" + data.asy_error_msg); return data;
} catch (Exception e)
{
Logger.Debug(e.Message); throw;
}
} public OpenApiResult RequestDeviceStatus(string accessToken, RequestData data)
{ var url = string.Format(WxDeviceConfig.GetDeviceStatusUrl, accessToken); return SendHelp.Send<OpenApiResult>(accessToken, url, data);
} public OpenApiResult SetDevice(string accessToken, RequestData data)
{ var url = string.Format(WxDeviceConfig.GetDeviceStatusUrl, accessToken); return SendHelp.Send<OpenApiResult>(accessToken, url, data);
} public string GetOpenId(string accessToken,string deviceType,string deviceId)
{ try
{ var url = string.Format(WxDeviceConfig.GetOpenid, accessToken, deviceType, deviceId); var res = SendHelp.Send<OpenIdResult>(accessToken, url, null, CommonJsonSendType.GET); return res.GetOpenId();
} catch (ErrorJsonResultException e)
{
Logger.Debug(e.Message); throw;
}
}
}
}View Code
这方法读到数据后就交给了userdata 缓存起来。在getdata方法中返回。
private UserWxData getUserWxData()
{ var target = _cacheManager.Get<UserWxData>(userKey) ?? new UserWxData(); return target;
} private string userKey
{ get
{ var key = Session["warmwood"] ?? Session.SessionID;
Session.Timeout = 240; return key.ToString();
}
}View Code
UserWxData是我自定义的对象,包含了下面的几个熟悉。
public class UserWxData
{ private WxResponseData _responseData; public UserWxData()
{
CreateTime = DateTime.Now;
} public DateTime CreateTime { get; set; } public TokenResult AccessToken { get; set; } public WxResponseData ResponseData
{ get { return _responseData??(_responseData=new WxResponseData()); } set { _responseData = value; }
} public string OpenId { get; set; }
}比较重要的是token和responseData。WxResponseData 也就是最终要发给页面上的对象。包含你需要的功能的参数。
public class WxResponseData
{ public int asy_error_code { get; set; } public string asy_error_msg { get; set; } public string create_time { get; set; } public string msg_id { get; set; } /// <summary>
/// notify 说明是设备变更 /// set_resp 说明是设置设备 /// get_resp 说明获取设备信息 /// </summary>
public string msg_type { get; set; } public string device_type { get; set; } public string device_id { get; set; } public object data { get; set; } public Service services { get; set; } public string user { get; set; } public string rawStr { get; set; }
}severices看自己的设备定义,比如我现在包含了空调,开关,温度湿度。
public class Service
{ public lightbulb lightbulb { get; set; } public air_conditioner air_conditioner { get; set; } public power_switch power_switch { get; set; } public operation_status operation_status { get; set; } public tempe_humidity tempe_humidity { get; set; }
}到这儿,整个过程就讲完了,获取token和openid上一节讲过,就不赘述了。如果后端是node的话,就不需要这么多的类型转换了。
最后可以看下效果:

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
JS里特别好用的轻量级日期插件
JavaScript关于IE8兼容问题的处理
以上就是微信硬件H5开发之控制灯光的详细内容,更多请关注php中文网其它相关文章!
微信提供公众平台、朋友圈、消息推送等功能,用户可以通过“摇一摇”、“搜索号码”、“附近的人”、扫二维码方式添加好友和关注公众平台,同时微信将内容分享给好友以及将用户看到的精彩内容分享到微信朋友圈。
关键词:微信硬件H5开发之控制灯光