首页 > 其他分享 >硬件管理平台-硬件网关-网关配置项目

硬件管理平台-硬件网关-网关配置项目

时间:2023-08-19 18:00:37浏览次数:29  
标签:网关 string 平台 硬件 item Add 添加

硬件管理平台-硬件网关-网关配置项目

简介

在本章开始前,我们需要做一下说明,为例更好的服务于网关项目,更好的让前面章节中的xml服务于网关,需要创建一个网关配置页面来新增硬件信息,并进行保存,保存后的xml才能被网关识别,进而让网关进行后续的任务(例如:硬件管理平台-硬件网关-插件模块-集成的下半部分)。

目的

为了让配置项与网关服务分离,这样子的好处是只有在硬件添加或修改时才会使用网关配置项,而这个操作对于客户来说是比较少见的,就算前期客户无休止的添加硬件时,我们也需要通过硬件项目平台来获取这个硬件的依赖及操作类,也需要有人去给他进行配置。而分离出来的网关服务可以专一的执行他的功能,操作功能和与上位机交互即可,无需关心其他的事情。

正文

网关配置项目创建

  1. 在4.配置程序文件夹中创建一个windows窗体项目,名称设置为HardwareGatewayConfig

  2. 设置其生成路径,与HardwareGatewayService一致,或者可单独创建一个文件夹,专门存放网关配置,推荐前者。

  3. 修改App.config文件,添加dlls文件的引用

      <runtime>
        <!--xmlns是必需的特性。指定程序集绑定所需的 XML 命名空间。 使用字符串“urn: 架构-microsoft-com:asm.v1”作为值。-->
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
          <publisherPolicy apply="yes"/>
          <!--指定运行时是否使用发布者策略-->
          <!--指定加载程序集时公共语言运行时搜索的子目录, 其中privatePath是相对于*.exe.config文件的相对路径,多个文件夹以分号分隔。-->
          <probing privatePath="dlls"/>
        </assemblyBinding>
      </runtime>
    

    注意:此时网关配置项目引用的dlls与产品库的dlls文件夹相同,因此在初始化时必须判断完是否有更新后再进行后续操作,否则将无法替换dlls的相关dll,因为会被该项目占用。

Zip解压

在网关配置项目的Program.cs的Main方法中添加解压方法

/// <summary>
/// 完成更新后将压缩包进行改名,并存放在本路径下,为了方便后期查找
/// </summary>
/// <param name="zipFile">zip文件</param>
/// <param name="folder">要存放的历史压缩包路径</param>
private static void UpdateFinish(string zipFile, string folder)
{
    if (MessageBox.Show("更新完成,是否删除压缩包", "提示", MessageBoxButtons.YesNo) == DialogResult.Yes)
    {
        // 将压缩包以当前时间戳来命名
        File.Move(zipFile, string.Format("{0}\\target-{1}.zip", folder, System.DateTime.Now.ToString("yyyyMMddhhmmss")));
    }
}
/// <summary>
/// 解压zip包
/// </summary>
private static void UnZipFile()
{
    string zipFile = string.Format("{0}\\target.zip", Application.StartupPath);
    // 同一路径下存在该压缩包
    string folder = Application.StartupPath;
           
    bool isExists = false;
    if (File.Exists(zipFile))
    {
        isExists = true;
    }
    // 判断更新包存在
    if (MessageBox.Show(isExists ? "发现更新包,目前服务还未安装,是否直接解压缩zip并启动服务" : "网关未安装,是否直接进行安装", "提示", MessageBoxButtons.YesNo) == DialogResult.Yes)
    {
        if (isExists)
        {
            // 解压
            ZipUtil.UnZipFile(zipFile, folder, true);
            UpdateFinish(zipFile, folder);
        }
    }
}

在该项目中创建util文件夹,然后创建ZipUtil操作类,并将解压代码放到该处。

/// <summary>
/// 解压文件
/// </summary>
/// <param name="zipFile">被解压的压缩文件</param>
/// <param name="dirAim">解压到目标路径</param>
/// <param name="emptyFolder">是否解压空文件夹</param>
public static void UnZipFile(string zipFile, string dirAim, bool emptyFolder)
{
    FastZip fastzip = new FastZip();
    //// Create Empty Directory
    fastzip.CreateEmptyDirectories = emptyFolder;
    fastzip.ExtractZip(zipFile, dirAim, string.Empty);
}

为什么要单独创建一个类,而不是把他放到公共包中使用?由于公共包中的dll可能会被更新,如果使用的话会导致相关依赖包无法被替换,因此该类需要独立存在于util文件夹中。

其中FastZip是引用了ICSharpCode.SharpZipLib控件,该控件也需要独立存放,防止被更新。

注意:该处未添加服务的相关代码,例如当网关服务在运行时需将网关关闭然后再进行替换,否则也是无法更新的(又给自己挖一坑)。

网关配置项目xml配置

  1. 页面布局

    在编写前我们将页面进行布局,左侧为硬件树,展示内容与产品库项目的左侧树一致,唯一的不同是不需要添加checkbox框;右侧的上方为动态显示的属性值与对应的输入框;中部是”添加“、”删除“按钮。

    右上侧输入框的作用,目前动态输入框的逻辑是在少于8个属性的时候,将多余的label和TextBox都进行隐藏,而保存到xml时,判断是否被隐藏,如果显示且label的值不是以label开头的,则被存入xml中的HardwareInfo属性中。

    其他功能或非xml逻辑后期再添加

  2. 在窗体中添加两类方法,一类是获取硬件项目的类;一类是读取xml的相关展示类

    1. 获取硬件类

              /// <summary>
              /// 初始化网关
              /// 1. 尝试获取网关服务的返回值
              /// 2. 获取到成功信息后获取目前网关服务中的硬件类,并将该硬件类初始化到左侧的硬件树中
              /// </summary>
              private void InitGateway()
              {
                  // 判断硬件网关是否连通;之前是重置硬件
                  AjaxResult result = _hardwareControl.RefreshHardware();
                  if (result == null)
                  {
                      MessageBox.Show("返回数据失败");
                  }
                  else
                  {
                      if (result.code == AjaxResult.OK)
                      {
                          // 获取所有的硬件类
                          List<HardwareProperties> properties = _hardwareControl.GetHardwares();
                          // 获取自定义的硬件类,该类的特点是不需要控制
                          DeviceTypeList.Clear();
                          _funClient.GetDeviceTypes().ForEach(dic => {
                              DeviceTypeList.Add(dic["deviceTypeName"], dic["deviceTypeId"]);
                          });
                          // 初始化所有的硬件类,包括非自定义和自定义的
                          LoadLibrary(properties);
                      }
                  }
              }
      
              /// <summary>
              /// 获得属性进行设备展示
              /// </summary>
              /// <param name="properties">可控制的硬件</param>
              private void LoadLibrary(List<HardwareProperties> properties)
              {
                  DeviceTypeDic.Clear();
                  independentDic.Clear();
                  Dictionary<string, List<HardwareProperties>> valuePairs = new Dictionary<string, List<HardwareProperties>>();
                  if (properties != null)
                  {
                      properties.ForEach(item => {
                          // 按照类型进行分组,形成先是类型树,对应硬件类中的详细硬件型号
                          if (!valuePairs.ContainsKey(item.Type))
                          {
                              valuePairs.Add(item.Type, new List<HardwareProperties>());
                          }
                          // 模块自有功能
                          if (item.IndependentFun != null)
                          {
                              String funs = AssemblyUtil.GetDescriptionByEnumLis(item.IndependentFun);
                              if (!String.IsNullOrEmpty(funs))
                              {
                                  independentDic.Add(item.Model, funs.Split(','));
                              }
                          }
                          // 硬件类型对应的类型主键
                          if (!DeviceTypeDic.ContainsKey(item.Type))
                          {
                              DeviceTypeDic.Add(item.Type, item.TypeId);
                          }
                          valuePairs[item.Type].Add(item);
                      });
                  }
                  // 添加类型树
                  hardwareTV.Nodes.Clear();
                  foreach (string item in valuePairs.Keys)
                  {
                      TreeNode typeNode = new TreeNode(item);
                      List<HardwareProperties> hardwares = valuePairs[item];
                      hardwares.ForEach(propertie => {
                          TreeNode modelNode = typeNode.Nodes.Add(propertie.Model);
                          modelNode.Tag = propertie;
                      });
                      hardwareTV.Nodes.Add(typeNode);
                  }
                  // 在类型中添加非控制类硬件
                  foreach (String key in DeviceTypeList.Keys)
                  {
                      TreeNode typeNode = new TreeNode(key)
                      {
                          Tag = DeviceTypeList[key]
                      };
                      hardwareTV.Nodes.Add(typeNode);
                  }
              }
      
    2. 读取xml信息

              /// <summary>
              /// 读取xml中的列表
              /// </summary>
              /// <param name="model"></param>
              private void LoadXml(string model)
              {
                  _hardwareXmlEntitys = xmlClient.GetHardwareInfos();
                  List<HardwareXmlEntity> hardwares = new List<HardwareXmlEntity>();
                  if (string.IsNullOrEmpty(model))
                  {
                      hardwares.AddRange(_hardwareXmlEntitys);
                  }
                  else
                  {
                      hardwares = _hardwareXmlEntitys.Where(dic => dic.Param["设备型号"].Equals(model)).ToList<HardwareXmlEntity>();
                  }
                  hardwareLV.Items.Clear();
                  hardwares.ForEach(hardware => {
                      hardwareLV.Items.Add(AddListViewItem(hardware));
                  });
              }
      
              /// <summary>
              /// 添加节点
              /// </summary>
              /// <param name="hardware"></param>
              /// <returns></returns>
              private ListViewItem AddListViewItem(HardwareXmlEntity hardware)
              {
                  ListViewItem item = new ListViewItem
                  {
                      Text = string.Format("{0}", (hardwareLV.Items.Count + 1)),
                      Tag = hardware
                  };
                  item.SubItems.Add(hardware.Param["设备主键"]);
                  item.SubItems.Add(hardware.Param["设备型号"]);
                  item.SubItems.Add(hardware.Param["Ip地址"]);
                  item.SubItems.Add(hardware.Param["端口号"]);
                  item.SubItems.Add(hardware.OperationTxt);
                  item.SubItems.Add(hardware.SettingsTxt);
                  return item;
              }
          }
      
  3. 增加选择左侧树的点击事件

    业务场景是当选择了硬件树后,右侧上半部分显示该硬件需要输入的属性信息,右侧下半部分显示目前已经添加的硬件信息。

    1. 左侧硬件树添加AfterSelect事件

      // 判断是选择的硬件还是硬件的型号
      if (e.Node.Tag != null)
      {
          // 当选择的为硬件型号
          if (e.Node.Tag is HardwareProperties properties)
          {
              // 将该硬件型号的内容进行赋值
              modifyField.DeviceType = properties.Type;
              modifyField.DeviceTypeId = properties.TypeId;
              modifyField.ModelType = properties.Model;
              modifyField.ModelTypeId = properties.ModelId;
              SettingFunction(properties.Model, properties.InitializationFun, properties.OperationFun);
              // 读取该型号的硬件信息
              LoadXml(properties.Model);
              // 动态显示硬件属性
              SelectTreeView(properties.Params);
              //修改按钮属性
              SettingAttribute(this.modifyBtn, "新增", true);
              SettingAttribute(this.delBtn, "删除", false);
              // 将该次操作定义为新增
              _operation = Operation.Add;
      
          }
          // 选择的为硬件
          else if (e.Node.Tag is String)
          {
              // 读取该类型种的硬件列表
              LoadXmlByType(e.Node.Tag as String);
              //修改按钮属性
              SettingAttribute(this.modifyBtn, "新增", false);
              SettingAttribute(this.delBtn, "删除", false);
              _operation = Operation.Showing;
          }
      }
      

      此方法为点击了硬件树后触发的方法,主要目的是动态显示硬件属性;展示硬件信息;将选择的数据记录下来;动态修改按钮属性。

    2. 右上侧的动态框SelectTreeView方法

      /// <summary>
      /// 动态加载硬件属性
      /// </summary>
      /// <param name="items">当前选中的硬件型号所拥有的属性</param>
      private void SelectTreeView(List<string> items)
      {
          // 先判断属性个数是否大于了控件区的个数(现在是8个)
          if (items.Count > this.bodyPal.Controls.Count)
          {
              // 大于了,则提示
              MessageBox.Show(String.Format("目前仅支持{0}个参数", items.Count));
          }
          // 去掉无需人工添加的硬件属性
          int nCount = items.Count - autoValue.Count;
          int nSeek = 1;
          for (int i = 0; i < bodyPal.Controls.Count; i++)
          {
              // 判断是否超过了硬件设置属性
              if (nSeek <= nCount)
              {
                  // 如果是无需人工添加的硬件属性则跳过
                  if (autoValue.Contains(items[i]))
                  {
                      continue;
                  }
                  // 改为硬件属性名称,将label或textBox进行修改,修改显示情况和显示内容
                  // label修改
                  SettingAttribute(bodyPal.Controls[String.Format("label{0}", nSeek)], items[i], true);
                  // textBox修改
                  SettingAttribute(bodyPal.Controls[String.Format("textBox{0}", nSeek)], "", true);
                  // textBox设置为可编辑
                  bodyPal.Controls[String.Format("textBox{0}", nSeek)].Enabled = true;
                  nSeek += 1;
              }
              else
              {
                  // 如果没有该控件则跳过
                  if (bodyPal.Controls[String.Format("label{0}", nSeek)] == null)
                  {
                      break;
                  }
                  // 设置回原来样式
                  SettingAttribute(bodyPal.Controls[String.Format("label{0}", nSeek)], bodyPal.Controls[String.Format("label{0}", nSeek)].Name, false);
                  SettingAttribute(bodyPal.Controls[String.Format("textBox{0}", nSeek)], bodyPal.Controls[String.Format("textBox{0}", nSeek)].Name, false);
                  bodyPal.Controls[String.Format("textBox{0}", nSeek)].Enabled = true;
                  nSeek += 1;
              }
          }
      }
      

      SettingAttribute方法为通用设置属性参数值

      /// <summary>
      /// 设置控件属性信息
      /// </summary>
      /// <param name="control">控件</param>
      /// <param name="text">显示信息</param>
      /// <param name="isVisible">是否显示属性</param>
      private void SettingAttribute(Control control, string text, bool isVisible)
      {
          control.Text = text;
          control.Visible = isVisible;
      }
      
    3. 显示硬件信息列表,通过读取xml即可获得

      // 读取该类型种的硬件列表
      LoadXmlByType(e.Node.Tag as String);
      // 读取该型号的硬件信息
      LoadXml(properties.Model);
      
  4. 双击添加按钮,增加添加事件

    该事件的作用是添加/修改硬件属性信息

    private void modifyBtn_Click(object sender, EventArgs e)
    {
        // 获得硬件属性信息
        HardwareXmlEntity hardwareDic = GetNewHardwareDic();
        // 判断如果是修改,则将原来的设备主键赋值给该硬件属性实例
        if (_operation == Operation.Edit)
        {
            xmlClient.RemoveHardwareInfo(hardwareDic.Param["设备主键"]);
        }
        // 向xml中添加硬件属性实例
        xmlClient.AddHardwareInfo(hardwareDic);
        // 因变更,因此设置一个标识,该标识主要作用是判断是否有过修改
        SetDeviceSetting(true);
        // 重新读取该设备信息,类似于刷新设备信息列表
        LoadXml(_selectHardwareInfo.设备型号);
    }
    

    我们着重说明获取硬件信息,获取硬件信息主要是将非人工添加的硬件信息和人工添加的硬件信息整合的过程,非人工添加的部分属性我们已经将其存储起来了,只需要对应赋值即可;人工添加的部分只需要遍历bodyPal中的控件,通过label控件的value和textBox对应的value即可获得硬件信息的数值

    /// <summary>
    /// 点击新增/修改按钮后,获得一个新的设备信息,根据_operation来判断是新增还是修改
    /// 新增:创建新的主键,添加到xml中,刷新ListView
    /// 修改:将原有主键赋值给新的设备信息,然后从xml中删除并新增
    /// 新的设备中InitializationFun和OperationFun的获得方式
    /// 1.点击了treeView后获得的
    /// 2.点击了ListView(双击/单击)后获得
    /// Param 调用GetNewHardwareByDic获得
    /// SettingFun可支持多种方式
    /// 1.按照定时功能分类,不涉及设备类型和型号
    /// 2.按照同类型号的功能分类,不细化每个设备信息
    /// 3.细化到设备信息,每一条都进行设置
    /// </summary>
    /// <returns></returns>
    private HardwareXmlEntity GetNewHardwareDic()
    {
        HardwareXmlEntity hardwareDic = new HardwareXmlEntity
        {
            InitializationFun = _selectHardwareInfo.初始化,
            OperationFun = _selectHardwareInfo.操作功能,
            Param = GetNewHardwareByDic()
        };
        if (_operation != Operation.Edit)
        {
            hardwareDic.Param.Add("设备主键", System.Guid.NewGuid().ToString("N"));
        }
        else
        {
            hardwareDic.Param.Add("设备主键", _selectHardwareInfo.设备主键);
        }
        return hardwareDic;
    }
    

    GetNewHardwareByDic方法中为添加硬件属性

    /// <summary>
    /// 根据BodyPal获得所有的组件
    /// </summary>
    /// <returns></returns>
    private Dictionary<string, string> GetNewHardwareByDic()
    {
        Dictionary<string, string> valuePairs = new Dictionary<string, string>();
        foreach (Control control in this.bodyPal.Controls)
        {
            if (control.Visible && control is Label)
            {
                valuePairs.Add(control.Text, this.bodyPal.Controls["textBox" + control.Name.Replace("label", "")].Text);
            }
        }
        if (!string.IsNullOrEmpty(modifyField.DeviceType))
        {
            valuePairs.Add("设备类型", modifyField.DeviceType);
        }
        if (!string.IsNullOrEmpty(modifyField.DeviceTypeId))
        {
            valuePairs.Add("类型主键", modifyField.DeviceTypeId);
        }
        if (!string.IsNullOrEmpty(modifyField.ModelType))
        {
            valuePairs.Add("设备型号", modifyField.ModelType);
        }
        if (!string.IsNullOrEmpty(modifyField.ModelTypeId))
        {
            valuePairs.Add("型号主键", modifyField.ModelTypeId);
        }
        return valuePairs;
    }
    

小结

此时,在硬件网关服务启动的情况下,运行网关配置程序可进行硬件信息的增删改,为硬件网关添加硬件数据并进行操作做准备。

标签:网关,string,平台,硬件,item,Add,添加
From: https://www.cnblogs.com/wanghun315/p/17642815.html

相关文章

  • 智慧建筑工地平台源码,数字化项目管理云平台源码
    智慧工地管理平台源码智慧工地管理平台是以物联网、移动互联网技术为基础,充分应用大数据、人工智能、移动通讯、云计算等信息技术,利用前端信息采通过人机交互、感知、决策、执行和反馈等,实现对工程项目內人员、车辆、安全、设备、材料等的智能化管理,是信息技术、人工技术与工程施工......
  • 大华智慧园区综合管理平台SQL注入漏洞复现
    一、产品简介大华智慧园区综合管理平台是一款综合管理平台,具备园区运营、资源调配和智能服务等功能。平台意在协助优化园区资源分配,满足多元化的管理需求,同时通过提供智能服务,增强使用体验。二、漏洞概述大华智慧园区综合管理平台未对用户的输入进行有效的过滤,直接将其拼接进了S......
  • 物联网管理平台助力清洁设备实现智能运维
    清洁设备是用来替代人工清洁工作的机械设备,可以有效降低清洁工作的人力成本并提高工作效率,在商场、机场、图书馆、博物馆、酒店等场景广泛使用。随着清洁设备的市场竞争不断加剧,设备运维成本的不断上升,同时还要面对闲置产能带来的损失,迫使清洁设备厂商寻求高效低成本的设备管理系统......
  • Debezium+KafkaConnect+Confluent实现企业级实时数据复制平台
    【I】集群规划5台节点IP地址  10.101.1.45 ZK、Kafka、DebeziumConnector、JDK、DebeziumUI、MySQL、Kafka-Eagle10.101.1.46 ZK、Kafka、DebeziumConnector、JDK10.101.1.47 ZK、Kafka、DebeziumConnector、JDK10.101.1.48 ZK、Kafka、DebeziumConnector、JDK10.......
  • 微信小程序项目:粤语教学平台-粤言粤语
    视频介绍1项目简介1.1创意来源根据中共中央办公厅、国务院办公厅印发的《关于实施中华优秀传统文化传承发展工程的意见》,我小组计划开发一款推广中国部分地区传统文化的可广泛推广的软件。为紧贴国家计划在2025年前全面复兴传统文化的重大国策,我小组计划从语言出发,以语言为......
  • 三大线上知识付费平台有哪些,体验如何
    离开学校以后,投资自己的不懈学习成为了我认为最明智的选择之一。虽然我从事教培咨询行业,但我也是知识付费领域的资深探索者。在这里,我将以用户的身份,分享我在三大线上知识付费平台的体验,希望能为大家提供一些参考。同时,我想向您介绍一款备受欢迎的私域场景下的知识付费解决方案—......
  • 找到最适合您的课程销售平台,了解知识付费三大类别
    在如今的知识付费时代,选择一个合适的平台来销售您的课程至关重要。我将为您介绍不同类型的知识付费平台,以及其中的特点。如果您想了解更多关于适合私域场景的知识付费解决方案,请访问兔知云课堂的网址:https://knowledge.mutouweb.com/。 了解平台分类 在选择知识付费平台时,......
  • 学浪、荔枝微课平台的平替,兔知云课堂知识付费源码
    经历了雪浪下架风波后,我们深刻认识到“鸡蛋不能放在一个篮子里”的道理。尽管现在已经恢复正常,但这段经历仍然促使我们在寻找其他课程上架平台的同时,审慎对待不同的推销信息。作为知识付费领域的一份子,我希望分享一款备受认可的私域场景下的知识付费解决方案——兔知云课堂。如果......
  • 知识付费系统开源,兔知云课堂与其他平台对比
    在当今数字时代,知识付费已经成为许多人探索创业机会和共享专业知识的热门方式。然而,当您考虑出售课程时,选择适合的小程序变得尤为关键。如今市场上有许多选择,但不仅要考虑管理费用,更要考虑工具的可靠性和易用性。兔知云课堂,作为一款低成本的音视频课程点播系统,为您提供了私域场......
  • 2023年度知识付费平台排名揭晓:兔知云课堂领跑私域场景解决方案
     随着数字化时代的来临,知识付费平台成为了知识传播和变现的重要途径。2023年度,知识付费领域呈现出热火朝天的态势,许多平台在竞争中脱颖而出。以下是2023年度排名前十的知识付费平台: 第10名:混沌混沌作为知识付费领域的一员,不仅提供了丰富的知识内容,还致力于满足用户多元化的......