汽车回家灯光 离家自动灯光控制 你GET到了吗

微信硬件H5开发之控制灯光
原创
 14:27:00
413
这次给大家带来微信硬件H5开发之控制灯光,微信硬件H5开发控制灯光的有哪些,下面就是实战案例,一起来看一下。你可以自己扒,带参数的页面在浏览器中打开会马上跳转,不带参数的会提示参数不全,需要用mobile模式观看。呈现的界面如下: 解压开lamp.js ,目录如下,这个demo是基于sea.js+zepto实现,sea.js用来加载模块,zepto提供ajax请求和tab事件等。common中包含了一个keyConfig.js(地址参数),一个reqData.js(请求封装)还有一个zepto,ui里是一个上面图片的中的slider一样的组件。util中是一组方法集合。最重要的就是lamp.js 。define(function (require) {
var $ = require(&common/zepto&);
var keyConfig = require(&common/keyConfig&);
var reqData = require(&common/reqData&);
var util = require(&util/util&);
var ProcessBar = require(&ui/process-bar&);
var pageParam = {
device_id: util.getQuery(&device_id&),
device_type: util.getQuery(&device_type&),
appid: util.getQuery(&appid&)
var lastModTime = 0;
var powerBtn = $(&#powerBtn&), // 开关按钮
var device_status= {
services: {
lightbulb: {alpha:0},
operation_status:{status:0}
}; // 数据对象
(function () {
if(!pageParam.device_id || !pageParam.device_type){
alert(&页面缺少参数&);
log(&appid:& + pageParam.appid);
log(&device_id:& + pageParam.device_id);
log(&device_type:& + pageParam.device_type);
powerBtn.on(&tap&, togglePower); // 开关按钮事件
initBar();
initInterval();
// todo : for test, delete before submit//
renderPage({});
* 初始化进度条
function initBar() {
log(&初始化lightBar&);
lightBar = new ProcessBar({
$id: &lightBar&,
stepCount: 100,
touchEnd: function (val) {
device_status.services.lightbulb.alpha =
log(&亮度值为:&+val);
setData();
* 请求数据
function getData() {
reqData.ajaxReq({
//url: keyConfig.GET_LAMP_STATUS,
url:'https://api.weixin.qq.com/device/getlampstatus',
data: pageParam,
onSuccess: renderPage,
onError:function(msg) {
log(&获取数据失败:& + JSON.stringify(msg));
* 设置数据
function setData() {
console.log(&setUrl&, keyConfig.SET_LAMP_STATUS);
lastModTime = new Date().getTime(); // 更新最后一次操作时间
reqData.ajaxReq({
// url: keyConfig.SET_LAMP_STATUS,
url: 'https://api.weixin.qq.com/device/setlampstatus',
type: &POST&,
data: JSON.stringify(device_status)
log(&setData:& + JSON.stringify(device_status));
* 开关按钮事件
function togglePower() {
$(&#switchBtn&).toggleClass(&on&).toggleClass(&off&);
log(&灯的状态status:&+device_status.services.operation_status.status);
if(device_status.services.operation_status.status==0){
device_status.services.operation_status.status = 1;
log(&灯的状态:1&);
device_status.services.operation_status.status = 0;
log(&灯的状态:0&);
setData();
function initInterval() {
getData();
setInterval(function () {
if((new Date().getTime() - lastModTime) & 2000){ // 当有设置操作时,停止1s轮询,2秒后继续轮询
getData();
* 渲染页面
function renderPage(json) {
// todo : for test, delete before submit//
json = {//
device_status: {//
services: {//
operation_status: {//
status: 0//
lightbulb: {//
alpha: 0//
log(&renderPage:&+json);
if(!json.device_status){
console.log(&json&, json);
device_status = json.device_
log(device_status);
if(device_status.services.operation_status.status==0){
$(&#switchBtn&).addClass(&on&).removeClass(&off&);
$(&#switchBtn&).addClass(&off&).removeClass(&on&);
lightBar.setVal(device_status.services.lightbulb.alpha);
|xGv00|ade00e6d92f55 */ 首先我们看到pageParam对象是获取页面上参数的,device_id,device_type以及appid三个参数。其实有用的只有前面两个,因为appid的话,后台服务器已经配置了,而且在微信中的通过“进入面板”的时候只附带了id和type两个参数。然后device_status是一个设备状态对象对象是灯,根据微信services的定义,灯有一个亮度值。这个在上一篇提到过。然后是一个立即执行的,这个函数函数里面会先检查一下参数,然后初始化开关和亮度条。最好进入循环。initInterval中就是不断的通过getdata获取数据。注意到这儿有一个lastModTime的比较,然后延时2秒再触发,这个地方主要是因为每次设置之后再从服务器捞到数据有一个延时。原本是10,你设置了20,bar也到了20的位置,但是呢,服务器还有一个10在路上发过来,你设置的20并没有马上失效,这会有一个卡顿的效果。但这个两秒也不是那么的有效,卡顿还是会有;另外一方面就是,不能设置太快,设置太快了会报50019的错误(设备正在被操作);getdata成功后,就是renderpage,这个不用解释了。注意到在绑定开关时间的地方,其实是先调用了一次setdata powerBtn.on(&tap&, togglePower); function togglePower() {
$(&#switchBtn&).toggleClass(&on&).toggleClass(&off&);
log(&灯的状态status:&+device_status.services.operation_status.status);
if(device_status.services.operation_status.status==0){
device_status.services.operation_status.status = 1;
log(&灯的状态:1&);
device_status.services.operation_status.status = 0;
log(&灯的状态:0&);
setData();
} 这个作用有两个,一个是获取设备目前的状态,因为设备可能没有开启,或者没有联网,二个是将参数传递给后台,不然getdata无效。最后理清一下思路就是获取参数--&初始化--&setdata一次--&循环--&渲染页面
界面操作--&setdata--&延时读取。 加上后端的部分,全部的流程图如下。所以拿到前端代码只是一半,后端还需要自己实现。实现纯静态文件是无法请求微信服务器的,所以我们需要自己实现后台的部分,这也是第一节中要讲的目的。html:@{
}&!DOCTYPE html&&html&&head&
&meta http-equiv=&Content-Type& content=&text/ charset=UTF-8&&
&meta id=&viewport& name=&viewport& content=&width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0&&
&title&我的灯泡&/title&
&link href=&/css/common.css& rel=&stylesheet& /&
&link href=&/css/light_switch.css& rel=&stylesheet& /&&/head&&body&
&p class=&body&&
&p class=&inner&&
&p id=&switchBtn& class=&status_button off&&
&p class=&button_wrp&&
&p class=&button_mask&&
&p class=&alerter_button& id=&powerBtn&&
&i class=&status_pot&&&/i&
&span class=&on&&ON&/span&
&span class=&off&&OFF&/span&
&p class=&on&&
&h2&灯已开&/h2&
&p id=&reData&&&/p&
&p class=&foot&&
&p class=&slider_box J_slider_box&&
&i class=&slider_box_icon icon dark&&&/i&
&p id=&lightBar& class=&slider_box_bar&&
&p class=&slider_box_slider J_slider& style=&left:0%&&
&p class=&slider_box_slider_label J_value&&&/p&
&i class=&slider_box_slider_touch&&&/i&
&p class=&slider_box_line&&
&span class=&slider_box_line_fill J_fill& style=&width:0%&&&/span&
&i class=&slider_box_icon icon light&&&/i&
&script src=&/js/sea.js&&&/script&
seajs.config({
base: '/js/',
//map: [[/^(.*\.(?:css|js))(.*)$/i, &$1&]],
charset: 'utf-8'
seajs.use(&baby&);
&/script&&/body&&/html&View Code自己的实现就拿掉了遮罩和config部分,将sea.js的目录改到自己对应的目录即可:
seajs.config({
base: '/js/',
//map: [[/^(.*\.(?:css|js))(.*)$/i, &$1&]],
charset: 'utf-8'
seajs.use(&baby&);这个baby(命名和产品有关~)就相当于是lamp。 另外就是,修改请求地址。也就是通过后台调用api来实现getdate和setdata。第一版我修改的js和lamp.js的差别不大 就增加了一个log为了调试,修改调用路径。define(function (require) {
var $ = require(&common/zepto&);
var util = require(&util/util&);
var ProcessBar = require(&ui/process-bar&);
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: '',
var lastModTime = 0;
var powerBtn = $(&#powerBtn&), // 开关按钮
function log(msg, arg) {
console.log(msg, arg);
msg = JSON.stringify(msg);
if (arg) {
msg = msg + &,& + JSON.stringify(arg);
$.post('/device/log', { msg: msg });
(function () {
bindEvent();
if (!requestData.device_id || !requestData.device_type) {
alert(&页面缺少参数&);
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&,
stepCount: 100,
touchEnd: function (val) {
requestData.services.lightbulb.alpha =
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&);
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(&查询成功&);
alert(data.error_msg);
function initInterval() {
getData();
setInterval(function () {
if ((new Date().getTime() - lastModTime) & 2000) { // 当有设置操作时,停止1s轮询,2秒后继续轮询
getData();
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) {
console.log(&json&, json);
requestData =
if (requestData.services.operation_status.status == 0) {
$(&#switchBtn&).addClass(&off&).removeClass(&on&);
$(&#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中在绑定)之后,再进入循环。setdatapublic 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_
//args.services.air_conditioner =
args.services.power_switch =
args.services.lightbulb.value_range =
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 { }
public string device_id { }
public string user { }
public Service services { }
public object data { }
}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
var userdata = getUserWxData();
var data = wxDeviceService.GetDeviceStatus(Request);
userdata.ResponseData =
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);
}wxDeviceService如下:using Susing System.Collections.Gusing System.Dusing System.IO;using System.Lusing System.Net.Husing System.Wusing Newtonsoft.Jusing Niqiu.Core.Domain.Cusing Senparc.Wusing Senparc.Weixin.Eusing SendHelp= Senparc.Weixin.CommonAPIs.CommonJsonSnamespace Portal.MVC.WXDevice
public class WxDeviceService:IWxDeviceService
//private readonly ICacheManager _cacheM
//public WxDeviceService(ICacheManager cacheManager)
_cacheManager = cacheM
public TokenResult GetAccessToken()
var url = string.Format(WxDeviceConfig.AccessTokenUrl, WxDeviceConfig.AppId, WxDeviceConfig.APPSECRET);
var res = SendHelp.Send&TokenResult&(null, url, null, CommonJsonSendType.GET);
public WxResponseData GetDeviceStatus(HttpRequestBase request)
Stream postData = request.InputS
StreamReader sRead = new StreamReader(postData);
string postContent = sRead.ReadToEnd();
if (!string.IsNullOrEmpty(postContent))
Logger.Debug(&收到数据:& + postContent);
var data = JsonConvert.DeserializeObject&WxResponseData&(postContent);
data.rawStr = postC
Logger.Debug(&转换消息状态:& + data.asy_error_msg);
catch (Exception e)
Logger.Debug(e.Message);
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)
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);
}View Code这方法读到数据后就交给了userdata 缓存起来。在getdata方法中返回。
private UserWxData getUserWxData()
var target = _cacheManager.Get&UserWxData&(userKey) ?? new UserWxData();
private string userKey
var key = Session[&warmwood&] ?? Session.SessionID;
Session.Timeout = 240;
return key.ToString();
}View CodeUserWxData是我自定义的对象,包含了下面的几个熟悉。
public class UserWxData
private WxResponseData _responseD
public UserWxData()
CreateTime = DateTime.N
public DateTime CreateTime { }
public TokenResult AccessToken { }
public WxResponseData ResponseData
get { return _responseData??(_responseData=new WxResponseData()); }
set { _responseData = }
public string OpenId { }
}比较重要的是token和responseData。WxResponseData 也就是最终要发给页面上的对象。包含你需要的功能的参数。 public class WxResponseData
public int asy_error_code { }
public string asy_error_msg { }
public string create_time { }
public string msg_id { }
/// &summary&
/// notify 说明是设备变更
/// set_resp 说明是设置设备
/// get_resp 说明获取设备信息
/// &/summary&
public string msg_type { }
public string device_type { }
public string device_id { }
public object data { }
public Service services { }
public string user { }
public string rawStr { }
}severices看自己的设备定义,比如我现在包含了空调,开关,温度湿度。
public class Service
public lightbulb lightbulb { }
public air_conditioner air_conditioner { }
public power_switch power_switch { }
public operation_status operation_status { }
public tempe_humidity tempe_humidity { }
}到这儿,整个过程就讲完了,获取token和openid上一节讲过,就不赘述了。如果后端是node的话,就不需要这么多的了。最后可以看下效果:相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!推荐阅读:以上就是微信硬件H5开发之控制灯光的详细内容,更多请关注php中文网其它相关文章!
江湖传言:PHP是世界上最好的编程语言。真的是这样吗?这个梗究竟是从哪来的?学会本课程,你就会明白了。
PHP中文网出品的PHP入门系统教学视频,完全从初学者的角度出发,绝不玩虚的,一切以实用、有用...
点击数(113082)
ThinkPHP是国内最流行的中文PHP开发框架,也是您Web项目的最佳选择。《php.cn独孤九贱(5)-ThinkPHP5视频教程》课程以ThinkPHP5最新版本为例,从最基本的框架常识开始,将...
点击数(111410)
《php.cn原创html5视频教程》课程特色:php中文网原创幽默段子系列课程,以恶搞,段子为主题风格的php视频教程!轻松的教学风格,简短的教学模式,让同学们在不知不觉中,学会了HTML知识。
点击数(85436)
本套教程,以一个真实的学校教学管理系统为案例,手把手教会您如何在一张白纸上,从零开始,一步一步的用ThinkPHP5框架快速开发出一个商业项目。
点击数(84722)
所有计算机语言的学习都要从基础开始,《PHP入门视频教程之一周学会PHP》不仅是PHP的基础部分更主要的是PHP语言的核心技术,是学习PHP必须掌握的内容,任何PHP项目的实现都离不开这部分的内容,通...
点击数(81831)
相关视频章节智能座舱的三大关键问题,你GET到了吗?
来源:集微网
& &&提到汽车,必然离不开智能化、网联化,伴随这两大风口,智能座舱的重要性日益凸显。以全液晶仪表、 HUD、车载娱乐系统、后座娱乐为代表的智能座舱旨在带来更加智能化和安全化的交互体验,提供更加简洁高效的交互方式,有望成为汽车下一个颠覆式的创新点。呈现五大趋势智能座舱已然兴起,成为整合多车身电子部件的复杂系统,提供多屏互动以及先进的人机交互技术如语音识别、手势识别等等,并将融入云端智能和ADAS功能。同以往新技术的路径一致,智能座舱从高端车型向中低端车型的渗透正在加速,并在2018年进入大众化普及阶段。智能座舱中全液晶仪表盘、 HUD等功能的渗透率还比较低,正处于加速发展态势。比如全液晶仪表渗透率在5%左右,而2020 年渗透率能达到20%。而智能座舱在提升智能化和安全化的交互体验的同时,也成为多重软硬件技术的熔炉。重庆长安汽车股份有限公司智能化研究院院长何文分析了智能座舱未来的趋势:一是支持多种交互方式,如语音、人脸识别、手势识别等等,这是对输入多样性的支持;二是内容呈现或内容反馈的整体化,所有车内人和人交互的内容都是一个整体,可根据不同的时刻、场景,提供不同显示的方式如仪表、HUD甚至灯光反馈和内容;三是座舱的个性化,可根据不同的驾乘者呈现不同的内容,不同的驾驶场景呈现多场景的展示方式;四是简洁化,它会很了解你,主动地实时推送你所需要的信息;五是支持持续的OTA升级,进行及时的更新,让消费者的体验更好。软件必须平台化业界齐向智能座舱发力,不可避免地带来同质化考验。哈曼(中国)投资有限公司成都研发中心软件研发总监杨劲松提到:“目前来看,智能座舱的硬件设计基本上趋于同质化,今后差异化体现在软件能力上,而软件能力的核心是用户体验。”&既然差异化在软件层面,软件就必须平台化,并能实现远程更新。杨劲松认为,一方面,底层软件要适应不同的处理器,因为不同客户有不同的需求;另一方面,在硬件层面,因为智慧座舱要集成多电子系统,必须要靠虚拟机,在虚拟机的支持下在同一软件可支持不同的操作系统,并让仪表、前座或后座都可采用不同的操作系统。并且,用户体验不是简单的人机交互界面,而是一个综合性的概念。杨劲松举例说,比如在开车之前通过远程网络对车的状态进行一个诊断,进入车之后能够成为智慧助手,提供个性化的界面,实现智能设备与座舱系统自动连接,并且在行驶过程中提供一些情景化的服务,如疲劳提醒、在线支付、停车共享等等。显然,智能座舱的复杂度已远超传统的中控或仪表系统,为减轻整车厂的压力,需要提供一个全方位的从智能座舱前端到云端智能的平台。杨劲松提到,平台化的目的是为了适应不同客户的需求,比如哈曼的中高端系统可享用共同的硬件平台,低端系统则采用另一平台。目前哈曼高端的系统采用双CPU方案,最多可支持9个显示屏。为何要“一芯多屏”?&智能座舱需要仪表盘、HUD、前座及后座娱乐系统等的合力配合,到底是分而治之还是“一芯多屏”?杨劲松认为,如果采用分立式,那么每一个系统是独立的,通信的传输会是一大问题,而且会增加成本,产生延迟,造成体验不佳。而高度集成解决了高成本的通信和性能问题,尽管“一芯多屏”在前期的成本较高,因需要强大的处理器、复杂的软件操作系统等,但随着座舱系统的普及化,这一成本势必将走低,因而看好“一芯多屏”高度集成化的趋势。杨劲松还补充说,“一芯多屏”不仅解决了成本和软件问题,适应更加个性化或智能化的需求,而且因车联网需要与云端进行全面的交互,不能仅通过中控建立一个通道,而需要通过一个统一的大脑建立一个大数据网络通道,从而能更加智能化的呈现与交互。与智能驾驶的分合之争?&而在汽车全面拥抱智能化之后,引发了新的问题,在智能驾驶和智能驾舱之间的边界会越来越小,未来产业在智能驾舱的投入如何把握?智能驾驶融合智能驾舱的时间周期到底会有多长?深圳市航盛电子股份有限公司总裁杨洪认为,没有必要融合,因智慧座舱朝着安全舒适、智能化方向发展,既要有颜值还要有体验,但汽车自动驾驶对于安全可靠的需求是最重要的。以自动驾驶为主的操作平台,与智能座舱平台一定要分开,因为安全级别完全不一样,不能简单地集成。而且从产业参与角度来看,杨洪认为,智能驾舱即使不考虑智能驾驶,永远都会存在,而且要求功能越来越强大,对于产业而言未来十年都有机会。但在智能驾驶平台市场仍以几大巨头为主,对于其他业者来说鲜有机会,因而不一定非要融合。何文则认为,趋势会走向融合,毕竟一体化设计会带来设计可靠性和备份冗余的减少,但这仍取决于技术的成熟度。但智能驾驶属于高等级高安全性的要求,与智能座舱安全等级不一,可能仍需要较长一段时间才能融合。}

我要回帖

更多关于 伴你回家灯光不亮了 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信