智能家居通用管理平台 - 即插即用机制的设计
Posted ionfox
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了智能家居通用管理平台 - 即插即用机制的设计相关的知识,希望对你有一定的参考价值。
即插即用机制,对智能家居的推广,非常重要。没有她,老百姓估计不会使用。
好了,现在有了“智能冰箱”和它的驱动程序,SHM就可以使用它的SHDD来与冰箱交互了,并且是使用TCPIP协议通信。但还有一个环节没有解决,TCP通信需要知道通信端口。每个SHM都是使用不同的端口与设备通信,怎样约定通信端口?其次,为了安全起见,冰箱连接SHM,需要账号和密码,冰箱也可以自己决定,SHM是否是受信任的平台程序?如果不在我的授信列表中,可以拒绝连接到SHM。
这实际是一个设备即插即用的问题。冰箱买回来,第一次上电,它应该很快就能接入SHP平台,一般是几秒钟的时间,否则老百姓肯定骂娘。
现在流行的UPnP,是目前很多智能设备相互发现的机制。相关的文章很多,这里不做介绍。但它主要适用于点对点的通信方式(P2P)。SHP平台设计的PNP机制,不需要对现有网络做任何的改变,仅仅通过程序使用特定协议来完成设备交互。下图是SHP平台的设备发现和接入机制(转载请注明来源):
所以SHP 的PNP机制,实际上分两个阶段执行,分别在不同的程序中完成。目前的“冰箱”程序中,我们设
定3秒广播一次信息、15秒尝试连接SHM,所以第一次接入系统,在18秒内完成(如果设定连接时间间隔更
短,则接入更快)。下次冰箱重新上电再连接SHM 时,直接使用连接信息连接SHM,无需再次广播。只要
SHP在工作,一般瞬间就连接成功。
广播的协议,在考虑多种情况后,再严格规范。下面是目前“冰箱”程序PNP机制的部分代码:
#region PNP机制
private void btnBroadcast_Click(object sender, EventArgs e) //启动消息广播
//if (sockBroadcast == null) InitSockBroadcast();
if (btnBroadcast.Text == "启动消息广播")
InitSockBroadcast();
tmBroadcast.Start();
lbBCState.Text = "正在广播消息...";
btnBroadcast.Text = "停止消息广播";
BroadcastMessage();
else
if (tReceiveBroadcast != null) tReceiveBroadcast.Abort();
tmBroadcast.Stop();
btnBroadcast.Text = "启动消息广播";
lbBCState.Text = "停止广播消息";
private void tmBroadcast_Tick(object sender, EventArgs e) //定时广播
BroadcastMessage();
void BroadcastMessage() //广播设备系统本身的信息
stringJson json = new stringJson(SmartHomeChannel.SHFLAG);
//string hostname = Dns.GetHostName();
json.AddNameValume("product", "金鹰智能冰箱ESR2014"); //设备系统名称
json.AddNameValume("driver", "eaglesmartrefrigerator.dll"); //系统驱动程序
json.AddNameValume("downnet", "http://ionfox.com.cn/eaglesmartrefrigerator.dll"); //下载链接
json.AddNameValume("localip", LocalIP); //本机IP地址
json.AddNameValume("devid", "996"); //本设备系统的设备号
json.AddNameValume("time", DateTime.Now.ToLongTimeString()); //广播时间
byte[] data = json.GetBytes();
sockBroadcast.SendTo(data, iep);
nBCCount++;
lbBCCount.Text = nBCCount.ToString();
void InitSockBroadcast() //初始化广播
if (sockBroadcast != null)
sockBroadcast.Close();
sockBroadcast.Dispose();
sockBroadcast = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,
ProtocolType.Udp);
iep = new IPEndPoint(IPAddress.Broadcast, (int)nBroadcastPort.Value);//255.255.255.255:50005
sockBroadcast.Bind(new IPEndPoint(IPAddress.Any, (int)nListenPort.Value)); //50006
ep = new IPEndPoint(IPAddress.Broadcast, (int)nListenPort.Value);
sockBroadcast.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
StartReceiveBroadcast();
Thread tReceiveBroadcast; //接收返回数据的线程
private void StartReceiveBroadcast() //启动接收广告消息
if (tReceiveBroadcast != null)
tReceiveBroadcast.Abort();
Thread.Sleep(50);
try
tReceiveBroadcast = new Thread(new ThreadStart(ListenBroadcast));
tReceiveBroadcast.Start();
//lbInfo.Text = "正在接收广播...";
//tmListen.Start();
catch
tReceiveBroadcast = null;
void ListenBroadcast() //监听广播信息,用于发现智能设备
while (true)
byte[] data = new byte[10240];
int recv = sockBroadcast.ReceiveFrom(data, ref ep);
if (recv == 0) continue;
stringJson json = stringJson.ConvertBytesTostringJson(data, SmartHomeChannel.SHFLAG);
this.Invoke(new OnProcessBroadcast(ProcessBroadcast), json); //处理接收到服务器回传的数据
public delegate void OnProcessBroadcast(stringJson json);
string[] AcceptedServer = new string[] "金鹰智能家居平台","海尔U+智能家居系统","格力智能家居系统" ;
void ProcessBroadcast(stringJson json) //处理接收到服务器回传的数据
txtInfo.Text = json.ToString();
string recieved = json.GetValume("recieved");
if (recieved == null) return; //1、没被服务器接受,继续广播
//2、判断是否可以接收连接邀请
string server = json.GetValume("server");
if (server == null) return; //意外
if (!AcceptedServer.Contains(server)) return; //服务器不在被信任的服务器列表中
//3、发送连接接收信息
SendInvitedMessage(json); //发送邀请函
//4、开始连接服务器平台(服务器启动SHM可能需要好几秒的时间)
StartConnettion(); //开始连接服务器
void SendInvitedMessage(stringJson json) //发送接收邀请信息
json.AddNameValume("time", DateTime.Now.ToLongTimeString()); //广播时间
json.AddNameValume("agreen", "ok"); //同意接收邀请
json.AddNameValume("stopbroadcast", "yes"); //停止广播
byte[] data = json.GetBytes();
sockBroadcast.SendTo(data, iep);
nBCCount++;
lbBCCount.Text = nBCCount.ToString();
Thread.Sleep(50);
setting.AppId =int.Parse(json.GetValume("appid")); //保存AppId等信息!
txtIP.Text = json.GetValume("serverip");
lbPort.Text = json.GetValume("port");
lbUser.Text = json.GetValume("user");
lbPassword.Text = json.GetValume("pass");
refrigerator.ServerIP = txtIP.Text;
refrigerator.User = lbUser.Text;
refrigerator.Passsword = lbPassword.Text;
refrigerator.nConnectPort = int.Parse(lbPort.Text);
refrigerator.SaveToFile();
this.Text = string.Format("模拟智能冰箱(0 - 1)", AppId, smarthomechannel.DevicePID);
setting.Save();
void StartConnettion() //开始连接服务器
if (tReceiveBroadcast != null)
tReceiveBroadcast.Abort();
tmBroadcast.Stop();
sockBroadcast.Close();
lbBCState.Text = "正在连接SHM:" + refrigerator.ServerIP;
if (!MakeConnection(refrigerator.ServerIP, refrigerator.nConnectPort.ToString())) return; //连接失败
lbBCState.Text = "连接SHM成功:" + refrigerator.ServerIP;
#endregion
突然觉得好累,写文章暂告一段落。着急写客户端程应用系统,也许在开发客户端程序的时候,有更多的体验,再与各位同行交流。
以上是关于智能家居通用管理平台 - 即插即用机制的设计的主要内容,如果未能解决你的问题,请参考以下文章
Linux To Go:制作随身携带、即插即用的Linux系统
如何让即插即用的 WPF 应用程序创建 SQL 数据库? [关闭]