我处理设备网络访问的正确方法是什么

发布于 2025-01-13 09:22:40 字数 2318 浏览 0 评论 0原文

我目前正在开发 blazor 服务器项目,该项目将显示来自 modbus tcp/ip 设备的信息。我有一个名为“DeviceModel”的类,它对 Modbus 设备进行建模。下面显示了一个简化的示例。

public string DeviceName {get;set;}
public string IpAddress {get;set;}
public string Port {get;set;}
public int[] Registers {get;set;}
public string Alarm1 {get;set;}

设备模型类还包含解析寄存器信息的方法。例如,下面的代码片段将检查寄存器数组中某个索引处的值。根据该值,它将 Alarm1 属性设置为 ON 或 OFF。

public void CheckAlarm1(){
int status = Registers[4];
Alarm1 = status == 1 ? "ON" : "OFF";

}

我有另一个名为“NetworkAccess”的类,它处理与设备的 TCP/IP 连接。下面显示了一个简化的示例

// ModbusClient is a package which handles the reading/writing to TCP/IP Modbus 
private ModbusClient _client;
public string IPAddress {get;set;}
public string Port {get;set;}
public DeviceModel Device {get;set;}

public NetworkAccess(DeviceModel dev){
      IPAddress = dev.IPAddress;
      Port = dev.Port;
      _client = new ModbusClient(IPAddress,Port);
      _client.Connect();
}

NetworkAccess 类处理从网络上的设备读取和写入数据。下面是将数据写入 Modbus 设备上的单个寄存器的示例方法。

public void WriteSingleRegister(int address,int dataToAdd){
     _client.WriteSingleRegister(address,dataToAdd);
}

在网页的 Razor 组件中,在 OnInitialized() 方法中,我从数据库中获取包含 DeviceModels 的列表,其中填充了每个设备的 IP 地址、端口和名称等信息。为了将信息读取到设备,我有另一种方法“GetData()”,如下所示。

public async void GetData(){
     foreach(var device in Devices){
          NetworkAccess network = new NetworkAccess(dev);
          var dataUpdate = await network.ReadRegistersAsync(0,20);
          dev.Registers= dataUpdate;
     }
}

我目前的设置工作正常。为了写入设备,我会在 Razor 组件中执行类似的操作,

NetworkAccess network = new NetworkAccess(dev);
network.WriteRegistersAsync(0,new int[] {0,0,0,...}};

但我遇到的问题是我不确定处理我的情况的正确(或最佳)方法。在我看来,如果我的 DeviceModel 类中有用于特定操作(例如“ResetAlarm1”或“ClearRegisters”)的方法,那么对我来说更有意义。这样我就可以这样做,

dev.ResetAlarm1();

而不是在下面的剃刀组件中这样做

NetworkAccess net = new NetworkAccess(dev)
dev.WriteRegister(6,0); // where 6 is the register to write to and 0 is value to write

,我想我的问题是我应该将“NetworkAccess”添加到设备模型中并处理在其中创建连接和读/写设备的操作吗?或者将 NetworkAccess 和 DeviceModel 分开更有意义吗?

我希望这篇文章有意义。这更多的是一个关于设计的问题,而不是一个关于解决问题的问题。虽然我当前的解决方案运行良好,但我想更好地了解这是否是正确的方法,或者我是否偏离了。

感谢您的帮助!

I am currently working on a blazor server project which will display information from modbus tcp/ip devices. I have a class called "DeviceModel" which models a Modbus device. A simplified example is shown below.

public string DeviceName {get;set;}
public string IpAddress {get;set;}
public string Port {get;set;}
public int[] Registers {get;set;}
public string Alarm1 {get;set;}

The device model class also contains methods to parse information from the Registers. For example the snippet below will check the value at a certain index in the Registers array. Based on that value it will set the Alarm1 property to ON or OFF.

public void CheckAlarm1(){
int status = Registers[4];
Alarm1 = status == 1 ? "ON" : "OFF";

}

I have another class called "NetworkAccess" which handles the TCP/IP connection to a device. A simplified example is shown below

// ModbusClient is a package which handles the reading/writing to TCP/IP Modbus 
private ModbusClient _client;
public string IPAddress {get;set;}
public string Port {get;set;}
public DeviceModel Device {get;set;}

public NetworkAccess(DeviceModel dev){
      IPAddress = dev.IPAddress;
      Port = dev.Port;
      _client = new ModbusClient(IPAddress,Port);
      _client.Connect();
}

The NetworkAccess class handles reading and writing data to/from the device on the network. An example method which would write data to a single register on the Modbus device is below.

public void WriteSingleRegister(int address,int dataToAdd){
     _client.WriteSingleRegister(address,dataToAdd);
}

Within my Razor Component for the webpage, within the OnInitialized() method I get a List containing DeviceModels from a database which fills in information such as IPAddress,Port, and Name for each device. To read information to the device, I have another method "GetData()" shown below

public async void GetData(){
     foreach(var device in Devices){
          NetworkAccess network = new NetworkAccess(dev);
          var dataUpdate = await network.ReadRegistersAsync(0,20);
          dev.Registers= dataUpdate;
     }
}

The way I currently have this setup works fine. In order to write to a device I would do something like this in my Razor Component

NetworkAccess network = new NetworkAccess(dev);
network.WriteRegistersAsync(0,new int[] {0,0,0,...}};

Where I am having trouble is I am not sure the of the correct (or best) way to handle my situation. In my head it makes more sense to me if I had methods within my DeviceModel class for specific operations such as "ResetAlarm1" or "ClearRegisters". That way I could do

dev.ResetAlarm1();

rather than doing this in my razor component below

NetworkAccess net = new NetworkAccess(dev)
dev.WriteRegister(6,0); // where 6 is the register to write to and 0 is value to write

I guess my question is should I add "NetworkAccess" to the device model and handle creating the connection and reading/writing to the device within that? Or does it make more sense to keep NetworkAccess and DeviceModel seperate?

I hope this post makes sense. This is more a question about design than it is about fixing a problem. While my current solution is working fine, I want to better understand if this is the correct approach or if I am way off.

Thanks for any help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

过期情话 2025-01-20 09:22:40

或者将 NetworkAccess 和 DeviceModel 分开更有意义吗?

正如 SOLID 的单一责任原则所说:

单一职责原则(SRP)是一种计算机编程
该原则指出,一个中的每个模块、类或函数
计算机程序应该对其中的一个部分负责
程序的功能,并且它应该封装该部分。所有的
该模块、类或功能的服务应该紧密结合
承担这个责任。

在此处详细了解 SOLID 单一责任原则

因此,在 Device 类中创建单独的方法 dev.ResetAlarm1() 对我来说更可取。

很难说我的重构代码是否适合你,但我尽力了:

public class Device
{
    public string Name { get; set; }

    public string IpAddress { get; set; }

    public string Port { get; set; }

    public int[] Registers { get; set; }

    public string[] Alarms { get; set; }


    public void CheckAlarm(int registerIndex)
    {
        int status = Registers[registerIndex];
        Alarms[registerIndex] = status == 1 ? "ON" : "OFF";
    }
}

Or does it make more sense to keep NetworkAccess and DeviceModel separate?

As single responsibility principle of SOLID says:

The single-responsibility principle (SRP) is a computer-programming
principle that states that every module, class or function in a
computer program should have responsibility over a single part of that
program's functionality, and it should encapsulate that part. All of
that module, class or function's services should be narrowly aligned
with that responsibility.

Read more about single responsibility principle of SOLID here.

So making separate method dev.ResetAlarm1() in Device class is more preferable for me.

It is hard to say whether my refactoring code is appropriate to you, but I tried to do my best:

public class Device
{
    public string Name { get; set; }

    public string IpAddress { get; set; }

    public string Port { get; set; }

    public int[] Registers { get; set; }

    public string[] Alarms { get; set; }


    public void CheckAlarm(int registerIndex)
    {
        int status = Registers[registerIndex];
        Alarms[registerIndex] = status == 1 ? "ON" : "OFF";
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文