智能家居通用管理平台 – 监控程序的设计
Posted ionfox
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了智能家居通用管理平台 – 监控程序的设计相关的知识,希望对你有一定的参考价值。
智能家居监控程序SHM(SmartHomeMonitor),是真正与设备系统打交道的程序。它由服务程序SHS启动,以独立的进程运行。这也是PNP机制要求的。SHM需要动态加载设备系统的驱动程序(SHDD)来监控设备,SHDD再与“硬件设备”交互。也就是说SHM实际上由两个部分组成(监控管理线程SHMM,驱动程序SHDD);所以通信比较复杂。先理清楚通信的流程,根据不同的通信方式,有两种不同的通信结构。下图是用用串口、USB、PCI等方式直接与服务器电脑通信时的情况,所有信息都是在进程间交换数据。
如果设备系统是通过TCP/IP方式如服务器交互,则使用下图所示的有些诡异的通信方式:
为什么这样?因为设备系统运行在其他硬件系统上,无法与服务器进行直接的IPC通信。为减轻驱动程序的编写难度,我们把接收设备发来的数据,直接在SHMM中处理:首先把收到的信息转发给SHS(IPC方式),再把信息直接交给ISmartHome接口的ProcessDeviceStateData方法处理,由于ISmartHomes实现了事件响应机制,当数据有变化时,再通知SHM,否则不通知。而SHDD收到SHMM传来的通知时( json =smarthomeshareMemory.GetNotify();,ProcessNotifyData(json); ),用TCP/IP通信对象转发给设备系统:
public void ProcessNotifyData(stringJson json) //★★驱动程序处理服务器发来的指令
if (json == null) return;
string cmd = json.GetValume("cmd");
if (cmd == null) return;
else if (cmd == SHProtocol.DEVSTATE)
this.TCPNotifyDevice(json); //直接转发给设备系统
else if (cmd == SHProtocol.SHACTRL)
this.TCPNotifyDevice(json); //直接转发给设备系统
……
SHM业务类图相对简单,见下图:
只增加了一个窗口通信对象CommParameter。IPC、TCP/IP 通信对象在接口说明的类库中定义了。编写SHM程序的困难之处有两个:处理三种不同的通信方式,动态使用驱动程序。大部分时间花在通信调试上,以及编写设备驱动程序。大约花了2个月时间,开始由于自己编写驱动不熟练,来回修改接口,耽误较多时间。
这里介绍如何电台使用驱动程序。SHS启动SHM时,传递了驱动程序的文件名给SHM,所以SHM启动后,要负责加载驱动程序,获取设备系统的详细信息:设备状态信息和控制信息。
//★★动态加载智能家居程序集,事件响应机制!★★
Assembly asm = null;
ISmartHome SmartHome; //智能家居程序集接口
string classType = "";
private bool LoadAssembly(string dll) //动态加载厂家的智能家居程序集
string fn = Application.StartupPath + "\\\\" + dll + ".dll";
if (!File.Exists(fn)) return false;
try
if (asm == null)
asm = Assembly.LoadFrom(dll + ".dll"); //动态加载程序集
catch return false;
if (asm == null) return false;
classType = System.IO.Path.GetFileNameWithoutExtension(dll) + ".SmartHome"; //类名:EagleSmartHome.SmartHome
Type smarthome = asm.GetType(classType); //获取指定对象类型
if (smarthome == null) Application.Exit(); //连接库不是合法驱动
object obj = Activator.CreateInstance(smarthome, new object[] AppDataDir + "\\\\SmartHome.smh" ); //创建SH对象,构造函数有两个参数
SmartHome = (ISmartHome)obj;
SetDeviceEvent(); //★★设置设备开始工作,并且设置每个设备的数据变化响应事件
ShowDevices(); //显示所有设备
return true;
可以看到,关键之处在Activator.CreateInstance方法,创建了一个对象,正是该对象实现了ISmartHome接口,拿到了该接口,什么都知道了。事件响应机制,在该对象中实现了,但没有编写具体处理代码,这里编写一个通用的处理方法SetDeviceEvent:
private void SetDeviceEvent() //★★★设置每个设备的数据变化响应事件
if (SmartHome != null)
//★★★初始化通信,不调用IninComm接口方法,驱动程序不开始工作工作,只有内存数据
SmartHome.InitComm(new object[] comm, Clients, smarthomeshareMemory2dev, smarthomechannel2dev );
tbInfo.Text = SmartHome.HomeName;
for (int n = 0; n < SmartHome.HomeDevices.Count; n++) //设置每个设备的数据变化响应事件
#region 设置每个设备的数据变化响应事件
for (int i = 0; i < SmartHome.HomeDevices[n].DODevices.Count; i++) //每个DO子设备
IDeviceDO dv = (IDeviceDO)(SmartHome.HomeDevices[n].DODevices[i]);
dv.OnDigitalDataChanged += DigitalDataChanged;
for (int i = 0; i < SmartHome.HomeDevices[n].DIDevices.Count; i++) //每个DI子设备
IDeviceDI dv = (IDeviceDI)(SmartHome.HomeDevices[n].DIDevices[i]);
dv.OnDigitalDataChanged += DigitalDataChanged;
for (int i = 0; i < SmartHome.HomeDevices[n].AODevices.Count; i++) //每个AO子设备
IDeviceAO dv = (IDeviceAO)(SmartHome.HomeDevices[n].AODevices[i]);
dv.OnAnalogDataChanged += AnalogDataChanged;
for (int i = 0; i < SmartHome.HomeDevices[n].AIDevices.Count; i++) //每个AI子设备
IDeviceAI dv = (IDeviceAI)(SmartHome.HomeDevices[n].AIDevices[i]);
dv.OnAnalogDataChanged += AnalogDataChanged;
for (int i = 0; i < SmartHome.HomeDevices[n].SODevices.Count; i++) //每个SO子设备
IDeviceSO dv = (SmartHome.HomeDevices[n].SODevices[i]);
dv.OnStreamDataChanged += StreamDataChanged;
for (int i = 0; i < SmartHome.HomeDevices[n].SIDevices.Count; i++) //每个SI子设备
IDeviceSI dv = (SmartHome.HomeDevices[n].SIDevices[i]);
dv.OnStreamDataChanged += StreamDataChanged;
#endregion
就这么简单?确是就是这样。重担都落在驱动程序的编写上了。 SHM大部分时间在处理通信事件。只是想在SHM的UI界面显示和控制设备,所以程序才稍微变得复杂了。如果没有UI界面,那确实是一个很小的程序。
下篇介绍WindowsPhone客户端程序的设计。
以上是关于智能家居通用管理平台 – 监控程序的设计的主要内容,如果未能解决你的问题,请参考以下文章