首页 > 其他分享 >硬件管理平台-硬件产品库-底层实现

硬件管理平台-硬件产品库-底层实现

时间:2023-08-03 17:48:19浏览次数:26  
标签:set string get 产品库 List 硬件 public 底层

HardwareAbstract

在编写LoadLibrary前,我们需要完善HardwareAbstract类,否则TreeView显示什么?后续的内容应该如何操作?都将是一个坑。

由于本项目已完成,所以就不再一点一点的回顾HardwareAbstract类中添加的一堆一堆的代码了,先大体阐述一下类中的内容,具体代码展示

abstract or interface

由于要进行反射,所以必然要将所有硬件的公共部分提取出来,而抽象和接口都可以实现这个工作,使用接口更规范,如果不实现接口类,是会报错的;而使用抽象可以编写一些内部类,只要继承了该抽象类就可以调用内部类,虽然使用静态类也能实现,不过还是抽象类的封装更好一些,随着项目内容增多,公共方法不好找。不过最后还是使用了abstract抽象类,因为如果使用interface的话还是要在上面加一层,这样子就无法体现接口的好处了。

之前的项目使用的是abstract,导致了该类过于臃肿

该抽象类一共550多行代码,这还是注释不全的情况下,看到以后说实话都不太想动他了。

HardwareAbstract 应该有什么

何为HardwareAbstract,肯定是与硬件相关的抽象方法和抽象类(再加上interface部分),那对于硬件的交互信息和展示信息都应该在该类中,因此该类应该设计成一个硬件的集合抽象,其中包含了必须的接口和公共实现类。接口中必须要能返回硬件的所有信息,例如该硬件的功能,调用该功能必须要输入的信息以及该功能内部的执行接口。分别为GetHardwareInfoExecute

GetHardwareInfo

该方法主要是为了获取硬件的所有信息,包含硬件类型,名称,描述等基础信息,又包含了该硬件的功能信息,其中功能可分为初始化,定时和可调用三个维度。

  • 初始化指的是系统利用反射加载完现有的硬件模块后,通过硬件模块获得现场的真实数据后需要对该硬件进行初始化,例如我们反射加载了一个海康门禁的模块,门禁模块提出,我需要ip地址,端口号,用户名和密码才能工作。而现场肯定要将一个真实存在的海康门禁进行添加,加上这些门禁所需的信息。通过对这个门禁实例化后,会调用初始化方法,初始化方法的内容可能是模拟登录,拿到Handle的句柄,则初始化维度中将有一个模拟登录的功能。
  • 定时指的是定时触发的功能,例如获取温湿度如果需要定时触发,则定时这个维度中应该有一个功能叫获取温湿度。
  • 可调用值得是该硬件中有哪些功能是上位机可以调用的。

Execute

真正执行调用维度的接口实现方法,通过GetHardwareInfo方法获得的信息中,只有可调用的维度是需要上位机主动调用的,其他的都是系统内部调用。Execute方法应该为async/wait还是同步的,之前的实现是同步的,在网关服务中统一调用。这样的不便之处就是对于某个功能或者某类功能要异步或者同步需要动态设定或者写死,而在Execute中可通过编写人员的判断来约定好这个功能,好处是服务不需要去管理这个。

公用方法

目前公用的方法很全,包括了log4j,配置文件(ini),异步execute方法的事件,心跳公用方法,测试类,http相关类等。

实现

HardwareAbstract

在公共包中创建一个HardwareLibrary项目,该项目的位置位于Public文件下。将AssemblyLibrary项目的HardwareAbstract类放到新建的项目中。此时HardwareGateWebApiAssemblyLibraryHardwareGatewayProductization**项目会报错,因此需要添加对新项目的引用。

HardwareLibrary中创建HardwareAbstract类,用于存放抽象方法;在创建一个abstract文件夹,用于存放HardwareAbstract继承的抽象类,该类主要用于存放一些公共的方法,如果写在一起对于维护不好维护。

注意:这样子的namespace会报错,所以我直接将namespace改为了HardwareLibrary,没有加文件夹名称。

HardwareAbstract.cs中添加代码

/// <summary>
/// 获得设备相关配置项
/// </summary>
/// <returns></returns>
public abstract HardwareProperties GetHardwareInfo();
/// <summary>
/// 执行方法
/// </summary>
/// <param name="function">功能码</param>
/// <param name="hardware">设备基础信息</param>
/// <param name="param">调用参数</param>
/// <returns>如果返回值是非空,则出现错误信息,记录或将日志放到服务器上</returns>
public abstract AjaxResult Execute(Function function, string hardware, string param);
AjaxResult

该类在之前提到过,此时我们需要将该类放到公共包中使用,重新创建一个类项目,命名为UtilsLibaray,将该类放到此项目中

之前添加后,忘记说使用Nuget下载Newtonsoft.Json了,在此补上,添加的依赖如下

HardwareProperties

该类为硬件信息参数,大体展现内容已在前文描述,代码如下

public class HardwareProperties
{
    private string _type;
    private string _model;
    private string _folder;
    private string _relyOnFolder;
    private List<string> _relyOnFiles;
    private string _version;
    private string _describe;
    private List<Function> _operationFun;
    private List<Function> _initializationFun;
    private List<Function> _timeingFun;
    private List<String> _params;

    /// <summary>
    /// 类型
    /// </summary>
    public string Type { get => _type; set => _type = value; }
    /// <summary>
    /// 类型主键
    /// </summary>
    public string TypeId { get; set; }
    /// <summary>
    /// 型号
    /// </summary>
    public string Model { get => _model; set => _model = value; }
    /// <summary>
    /// 型号主键
    /// </summary>
    public string ModelId { get; set; }
    /// <summary>
    /// 依赖文件夹
    /// 单一文件夹
    /// </summary>
    public string RelyOnFolder { get => _relyOnFolder; set => _relyOnFolder = value; }
    /// <summary>
    /// 版本号
    /// </summary>
    public string Version { get => _version; set => _version = value; }
    /// <summary>
    /// 模块描述
    /// </summary>
    public string Describe { get => _describe; set => _describe = value; }
    /// <summary>
    /// 所在文件夹
    /// dll所在文件夹的路径
    /// </summary>
    public string Folder { get => _folder; set => _folder = value; }
    /// <summary>
    /// 依赖文件列表
    /// runtime文件夹中个别dll
    /// </summary>
    public List<string> RelyOnFiles { get => _relyOnFiles; set => _relyOnFiles = value; }
    /// <summary>
    /// 可操作功能
    /// </summary>
    public List<Function> OperationFun { get => _operationFun; set => _operationFun = value; }
    /// <summary>
    /// 初始化时触发功能
    /// </summary>
    public List<Function> InitializationFun { get => _initializationFun; set => _initializationFun = value; }
    /// <summary>
    /// 定时功能
    /// </summary>
    public List<Function> TimeingFun { get => _timeingFun; set => _timeingFun = value; }
    public List<Function> IndependentFun { get; set; }
    public List<String> Params { get => _params; set => _params = value; }
    /// <summary>
    /// 构造函数
    /// </summary> 
    /// <param name="typeId">类型ID</param>
    ///  <param name="modelId">型号ID</param>
    /// <param name="type">类型</param>
    /// <param name="model">型号</param>
    /// <param name="relyOnFolder">依赖的文件夹</param>
    /// <param name="relyOnFiles">依赖的文件列表</param>
    /// <param name="version">版本号</param>
    /// <param name="describe">描述</param>
    /// <param name="typeClass">类型描述</param>
    /// <param name="operationFun">操作功能</param>
    /// <param name="initializationFun">初始功能</param>
    /// <param name="timeingFun">定时功能</param>
    /// <param name="independentFun">模块功能</param>
    public HardwareProperties(string typeId, string modelId, string type, string model, string relyOnFolder, List<string> relyOnFiles, string version, string describe, Type typeClass, List<Function> operationFun, List<Function> initializationFun, List<Function> timeingFun, List<Function> independentFun)
    {
        TypeId = typeId;
        ModelId = modelId;
        _type = type;
        _model = model;
        _relyOnFolder = relyOnFolder;
        _relyOnFiles = relyOnFiles;
        _version = version;
        _describe = describe;
        _operationFun = operationFun;
        _initializationFun = initializationFun;
        _timeingFun = timeingFun;
        if (typeClass == null)
        {
            _params = new List<string>();
        }
        else
        {
            _params = AssemblyControl.GetParams(typeClass, new List<string>() { "定时功能", "操作功能", "初始化", "模块功能" });
        }
        IndependentFun = independentFun;
    }


}

该代码我放到了entity文件夹中,此时interface和abstract有些怪怪的,就新建了一个util将这两个文件夹放入其中。

AssemblyControl.GetParams

该方法为通过硬件的功能类型获得各自的功能值,主要用于展示。

我们将它作为HardwareProperties的扩展类,新建一个extends文件夹,创建HardwarePropertiesExt扩展类,将代码放入

/// <summary>
/// 根据类型获取展示信息
/// </summary>
/// <param name="typeClass"></param>
/// <returns></returns>
public static List<string> GetParams(this HardwareProperties properties, Type typeClass, List<string> ignoreFun)
{
    List<string> retList = new List<string>();
    foreach (PropertyInfo info in typeClass.GetProperties())
    {
        if (ignoreFun == null || !ignoreFun.Contains(info.Name))
        {
            retList.Add(info.Name);
        }
    }
    return retList;
}

布局如图:

Function

此时生成解决方案时还会报错,报错为未识别Function类,该类为枚举类,主要是列出了所有的硬件功能。

一开始打算细分,例如空调的功能为一个枚举,灯控的为一个枚举,这样子更清晰,后来放弃了。虽然清晰了,但是会形成同一个功能重复,例如空调的关机和一体机的关机是一个功能,而空调的设置温度可能是一个特定的值,也有可能是设置温度范围。所以这里就没有分的那么清晰。而且有些值的确有歧义,例如空调的开机可能是风机工作(直接485控制),也有可能是接通电源(红外控制)。

public enum Function
{
    /// <summary>
    /// 文件下载
    /// </summary>
    [Description("文件下载")]
    DownLoadFile = 03,
    /// <summary>
    /// 开机
    /// </summary>
    [Description("开机")]
    OpenMachine = 05,
    /// <summary>
    /// 关机
    /// </summary>
    [Description("关机")]
    CloseMachine = 06,
    /// <summary>
    /// 设置温度
    /// </summary>
    [Description("设置温度")]
    SettingTemputre = 07,
    /// <summary>
    /// 自动
    /// </summary>
    [Description("自动")]
    SettingAuto = 08,
}

AHardware

该方法用于存放抽象类的公共方法,例如模拟数据方法,心跳返回等,该部分在后续进行说明。

LoadLibrary方法

此时就可以在MainForm中添加LoadLibrary方法了,该方法主要就是利用放射类获得硬件属性来进行展示。

Dictionary<string, List<HardwareProperties>> valuePairs = new Dictionary<string, List<HardwareProperties>>();
_properties.Clear();
// 解析硬件反射类
_hardwares.ForEach(hardwareAbstract =>
{
    // 获得硬件信息
    HardwareProperties hardware = hardwareAbstract.GetHardwareInfo();
    // 将引用的路径赋值给硬件信息
    hardware.Folder = hardwareAbstract.IncludeDll;
    _properties.Add(hardware);

    // 形成 类型为key的字典,便于后面初始化TreeView控件
    if (!valuePairs.ContainsKey(hardware.Type))
    {
        valuePairs.Add(hardware.Type, new List<HardwareProperties>());
    }
    valuePairs[hardware.Type].Add(hardware);
});
hardwareTV.Nodes.Clear();
foreach (string item in valuePairs.Keys)
{
    // 创建一个硬件类型的Node
    TreeNode typeNode = new TreeNode(item);
    // 遍历硬件,获取硬件的型号(该型号必须唯一)
    valuePairs[item].ForEach(propertie => {
        TreeNode modelNode = typeNode.Nodes.Add(propertie.Model);
        modelNode.Tag = propertie;
    });
    // 展示时树的顶级为硬件类型分类,下面为各型号分类
    hardwareTV.Nodes.Add(typeNode);
}

编译成功,但是还无法查看效果,需要创建硬件项目。

标签:set,string,get,产品库,List,硬件,public,底层
From: https://www.cnblogs.com/wanghun315/p/17603986.html

相关文章

  • memcpy赋值/复制速度快的底层
    memcpy赋值速度一般来说比多重for循环更快,对于其底层原理十分感兴趣,面向百度,总结了一些答案,不是很专业,就是理解个大概总的来说有这么两个主要原因:1.SIMD:就是使用多个微处理器对同一个数据进行操作,其实就是并行操作参考:https://zhuanlan.zhihu.com/p/553270372.......
  • jvm attach过程与底层实现
    rasp的技术重点之一是java-agent技术,通过agent可以获取到Instrumentation接口的实现,通过这个inst变量对字节码进行修改。javaagent可以在jvm启动时使用-agentjar参数启动,也可以在运行时通过attach相应进程,并且指明需要加载的jar包,就可以进入到jar包中定义好的agentmain方法处,执......
  • stm32串口USART 硬件流控(转载)
    尊重原创,分享学习,内容来源:stm32串口USART硬件流控--学习笔记-国产零零柒-博客园(cnblogs.com)    流控的概念源于RS232这个标准,在RS232标准里面包含了串口、流控的定义。大家一定了解,RS232中的“RS”是RecommendStandard的缩写,即”推荐标准“之意,它并不像......
  • 硬件开发趋势与技术探索
    LiveVideoStackCon2022音视频技术大会北京站将于11月25日至26日在北京丽亭华苑酒店召开,本次大会将延续【音视频+无限可能】的主题,邀请业内众多企业及专家学者,将他们在过去一年乃至更长时间里对音视频在更多领域和场景下应用的探索、在实践中打磨优化技术的经验心得、对技术与商......
  • 硬件管理平台-硬件产品库-反射模块
    硬件产品库-反射模块公共项目改进在公共项目中对当前目录进行分组,主要按照使用场景进行划分按照上一章所描述的顺序进行1-4的划分,其中公共包为所有项目共用的代码,虽然该部分是编写期间随时进行编写的,但是按照个人习惯,喜欢将公共部分放到最上面。界面布局该项目暂不涉及酷炫......
  • 硬件管理平台-搭建
    硬件管理平台-搭建简述之前描述了硬件网关的公共部分的搭建方式,本次回归到硬件管理平台,进行下一步的开发工作。在开始之前,想先描述下文章后续的思路,该平台涉及了多个项目,来回跳跃式的叙述估计到最后谁也无法看懂了,如果不跳跃,当作伏笔去写,最后伏笔就变成了坑,怕填不完。因此在这......
  • RTSP流媒体服务器LntonNVR(源码版)平台硬件设备拔电关闭后不能自动重启的问题解决方案
    LntonNVR视频边缘计算网关可以放置在项目现场,7x24小时不间断使用,通电联网即可成功运行,部署操作十分简单。我们在测试时,将LntonNVR注册到服务启动,拔掉硬件设备的电源后,再次恢复供电,发现LntonNVR服务并没有再次启动。对此我们也进行了分析与排查。排查步骤如下:1、首先检查是否已经......
  • Java面试题 P28:数据库篇:MySql篇-MySql优化-索引-什么是索引?索引的底层数据结构是什么?
    什么是索引:索引(index)是帮助MySql高效获取数据的数据结构(有序)。在数据之外,数据库还维护着满足特定查找算法的数据结构(B+树),这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。 ......
  • 探究eFuse:硬件保障与系统安全的核心
    探究eFuse:硬件保障与系统安全的核心图1:编程熔断的eFuseeFUSE的全名是"ElectricallyProgrammableRead-OnlyMemoryFuse",它是一种电可编程只读存储器。eFUSE是一种用于存储固定信息的存储器,它的主要特点是一旦编程后就无法再进行擦除或修改,类似于传统的只读存储器(ROM)的功......
  • 硬件
    raid级别就是磁盘的组合方式RAID功能提高IO能力,读写性能远远重要于容量磁盘冗余备份RAID实现的方式外接式磁盘阵列内接式RAID软件RAID直通模式:不使用raid技术,直连主板raid模式:使用raid卡将多块硬盘组成硬盘组使用 RAID0:需要几块盘:提升性能至少2块(实际......