智能家居通用管理平台 - 即插即用机制的设计

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
突然觉得好累,写文章暂告一段落。着急写客户端程应用系统,也许在开发客户端程序的时候,有更多的体验,再与各位同行交流。



以上是关于智能家居通用管理平台 - 即插即用机制的设计的主要内容,如果未能解决你的问题,请参考以下文章

如何为高度解耦、即插即用的复杂组件构建 Redux?

即插即用开源在线客服系统——PPMessage

Linux To Go:制作随身携带、即插即用的Linux系统

如何让即插即用的 WPF 应用程序创建 SQL 数据库? [关闭]

CVPR‘2023 即插即用系列! | BiFormer: 通过双向路由注意力构建高效金字塔网络架构

打包基于 JavaScript 的即插即用应用程序