硬件管理平台-硬件产品库-硬件项目

2023-08-05 10:30:42 来源: 博客园

硬件管理平台-硬件产品库-硬件项目

本篇主要描述的是如何创建一个硬件项目,并将硬件信息进行展示。

讲了这么多至少应该能出个效果吧

在产品库文件夹中创建一个硬件集合文件夹,该文件夹存放所有硬件项目,在创建硬件项目前我们需要创建某类硬件项目的硬件接口。


(相关资料图)

我们在此以门禁和空调为例。门禁的功能有监听门禁事件,获取人员列表;空调的功能有开关机,定时获取温湿度等。

关于海康门禁的功能可以查看我的博客中的相关代码,在这里就不重复说明了。例如:门禁实时获取记录

硬件接口项目接口项目何用创建接口项目主要用于对硬件进行分类,例如空调硬件,门禁类硬件,灯控类等等,就是之前提到的所谓的硬件类型。里面再分具体型号,例如门禁类中有海康门禁,中控门禁;空调类中可能还会分出不同的大类,具体大类如何区分,主要看他们的调用参数和功能是否一致,例如海康门禁需要的是ip,port,用户和密码,而某款门禁他只用门禁地址,这时候可以强制合并,但是建议还是分开,不然会出现冗余字段。至于有部分ip,port可以当作com和波特率使用(建议勤快的人还是分开)。在类中重新定义Type属性,为了将硬件类型进行强制区分,上一篇中TreeView的顶级就是以Type进行分类的,下面才是实际的硬件型号(实现该接口的类)。接口项目

硬件集合文件夹中创建硬件接口文件夹,并创建IAccessControlLibraryIAirConditionLibrary项目

在这两个项目中分别创建IAccessControlClientIAriConditionClient类,并设置为抽象类(abstract),继承HardwareAbstract类。

IAriConditionClient为例

public abstract class IAriConditionClient : HardwareAbstract{    public static readonly string Type = "空调";}public class AirConditionInfo : HardwareInfo{    string _设备地址;    ///     /// 设备号    ///     public string 设备地址 { get => _设备地址; set => _设备地址 = value; }}

IAriConditionClient

IAriConditionClient中Type为该类型的名称,用于进行分类

HardwareInfo

该类是硬件信息,与HardwareProperties的区别如下:

HardwareProperties类中存放的是该硬件类的属性信息,例如硬件类型,型号,版本,依赖包和功能等针对于该硬件的信息。HardwareInfo类中存放了同一个硬件中不相同的属性,例如设备主键,IP地址,设备地址等,虽然也有相同部分,可以认为是冗余数据。用处不同,HardwareProperties主要用于产品库的展示和更新硬件时依赖项的赋值及版本的判断,因此该类主要存储的是总体信息;而HardwareInfo用于硬件网关中调用数据时传入的信息,例如向上位机发送温湿度时,不添加设备主键如何知道哪个设备传入的信息。是否能合并?答案肯定是可以的,不过一旦合并感觉冗余的数据有多了很多,而且两个类之间的使用可以部分解耦,因此暂时先不进行合并。

该类的属性信息如下:

/// /// 设备类型/// private string _设备类型;/// /// 设备主键/// private string _设备主键;/// /// 设备型号/// private string _设备型号;/// /// 设备ip地址/// private string _Ip地址;/// /// 设备端口号/// private string _端口号;/// /// 备注/// private string _备注;/// /// 定时功能设定/// private List _定时功能;/// /// 功能列表/// private List _操作功能;/// /// 初始化/// private List _初始化;

其中FunctionSetting类为调度任务所需要的类,为防止后续忘记,在此也将属性进行罗列

/// /// 功能码/// private Function _runFunction;/// /// 功能码说明/// private string _functionStr;/// /// Cron/// private string _cronTime;

本来还有_nextFunction,意为执行该功能码后是否有关联功能码直接调用,之后由于并没有因此将该属性去掉。

_cronTime 原来为执行时间(_dateTime),之后改为了cron,因此在此将属性进行修改。

门禁项目接口同空调接口,本文就不再重复,门禁接口代码如下:

硬件项目硬件项目说明

在硬件集合文件夹中添加门禁和空调的文件夹,并分别创建两个硬件类,实现各自的抽象类。

项目创建如图:

这里将之前的硬件接口文件夹改为了00硬件接口,每个硬件类都创建了单独的文件夹,硬件类前面的标号为约定好的硬件类型编号,而例如01HkAccessControlLibrary表示为门禁类中,海康门禁的型号是0501,这样就有了唯一的硬件类别和唯一标识与该dll对应。该唯一标识在硬件实现类中也有使用。

实现抽象类

01TestAirConditionLibrary中创建TestAirConditionClient.cs类,并继承抽象类IAriConditionClient

public class TestAirConditionClient : IAriConditionClient{    public override AjaxResult Execute(Function function, string hardware, string param)    {        throw new NotImplementedException();    }    public override HardwareProperties GetHardwareInfo()    {        throw new NotImplementedException();    }}

注:这里改正之前描述的错误,就是abstract抽象接口与interface的接口方法一致,class继承后必须实现该类,否则会报错。之前编写的时候有误。

TestAirConditionClient进行修改,添加GetHardwareInfo方法的返回值

#region 约定的相关信息private const String Model = "实际硬件型号";private const int Version = 1;private const String Describe = "对于该硬件的信息描述";#endregion#region 功能部分private readonly List OperationFun = new List() { Function.SettingTemputre, Function.HumAndTem, Function.OpenMachine, Function.CloseMachine};private readonly List TimeingFun = new List() { Function.HumAndTem, Function.Beat };#endregionpublic override HardwareProperties GetHardwareInfo(){    return new HardwareProperties("04", "0401", IAriConditionClient.Type, Model, null, null, Version, Describe, typeof(AirConditionInfo), OperationFun, null, TimeingFun, null);}

HardwareProperties构造函数传入的属性请参见上文的构造类。其中OperationFun和TimeingFun分别表示的可操作功能和定时功能。

Function.HumAndTem和Function.Beat为新增功能,需要在Function中添加

/// /// 获取温湿度/// [Description("获取温湿度")]HumAndTem = 08,/// /// 心跳/// [Description("心跳")]Beat = 09,

门禁项目接口类似,就不一一描述了,最后实现类如下:

private const string Model = "海康门禁";private const int Version = 1;private const string Describe = "海康门禁";private const string RelyOnFolder = "hk";private readonly List OperationFun = new List() { Function.GetPersonList, Function.Beat };private readonly List TimeingFun = new List() { Function.Beat };private readonly List InitializationFun = new List() { Function.Initialization };public override AjaxResult Execute(Function function, string hardware, string param){    throw new NotImplementedException();}public override HardwareProperties GetHardwareInfo(){    return new HardwareProperties("05", "0501", IAccessControlClient.Type, Model, RelyOnFolder, null, Version, Describe, typeof(AccessInfo), OperationFun, InitializationFun, TimeingFun, null);}
新添加的Function请按照上面的写法自行添加RelyOnFolder为依赖的文件夹,因为海康有一整个文件夹的运行库作为依赖,将该依赖放置在第五个参数中;如果只依赖一个文件,我们可以将它放在第六个参数中,注意relyOnFiles为文件夹列表,文件名称也要写全。第11个参数为当实例加载完成后调用的初始化方法第13个参数independentFun为模块功能,例如在硬件类中做一个端口映射,该功能不需要指定设备,是独立与设备之外的,类似于设备类的功能。

编译一下,如果有问题,可能是引用问题,需使用Alt+Enter进行库的引用。

项目生成路径修改

HardwareGatewayProductization项目的生成路径改为:..\bin\Debug\产品库\

将硬件项目的生成路径改为:..\..\..\bin\Debug\产品库\plugins\硬件类型名称,例如01HkAccessControlLibrary可修改为:..\..\..\bin\Debug\产品库\plugins\空调

重新生成后,生成路径会修改为

同级依然还存在很多dll,而且每个硬件中也有大量dll,让我们来精简一下。

优化依赖项在bin->Debug->产品库文件夹创建dlls文件夹(系统中的文件夹,非vs中的),将公共库中的项目生成路径都设置为该文件夹。路径设置为:..\..\bin\Debug\产品库\dlls\。同理,将硬件接口中的项目生成路径也修改为dlls文件夹中。路径设置为:..\..\..\bin\Debug\产品库\dlls\。将HardwareGatewayProductization和硬件项目引用依赖的属性复制本地都改为false。在bin->Debug->产品库文件夹中创建runtime文件夹,如果不创建运行HardwareGatewayProductization会失败。

重新生成,查看效果。

此时exe同级下 就没有多余的dll依赖文件了(如果有,可以删除然后重新生成产品库的项目)。

硬件项目也只有本项目自己的dll,而其他依赖都没有进行复制,如果生成时还有,可将所有dll删除然后重新尝试。

此时,所有的依赖都来到了dlls文件夹中,这样在后期复制时可以直接复制dlls文件夹到硬件网关项目即可。

目前会发现这个报错(提示是未找到引用),不过我这边并不影响运行使用,因此就直接忽略了红线的报错。

运行后效果如图:

标签:

[责任编辑:]

最近更新