Avalonia+ASP.NET Core Web API实现设备集中控制平台简单方案

综合设计方案

下面的设计方案结合了设备通信协议的扩展、ASP.NET Core Web API、以及使用 Avalonia 实现跨平台桌面前端。

 1. 协议层

定义 ICommunicationProtocol 接口,并为不同的协议创建具体实现。

 1 public interface ICommunicationProtocol
 2 {
 3     void Connect();
 4     void Disconnect();
 5     byte[] ReadData(ushort startAddress, int quantity);
 6     void WriteData(ushort startAddress, byte[] data);
 7     bool IsConnected { get; }
 8 }
 9 
10 public class ModbusRtuProtocol : ICommunicationProtocol
11 {
12     // 实现接口中的方法
13     public void Connect() { /* ... */ }
14     public void Disconnect() { /* ... */ }
15     public byte[] ReadData(ushort startAddress, int quantity) { /* ... */ return new byte[0]; }
16     public void WriteData(ushort startAddress, byte[] data) { /* ... */ }
17     public bool IsConnected { get; private set; }
18 }

2. 服务层

管理设备和协议实例的服务层。

 1 public class DeviceService
 2 {
 3     private Dictionary<string, ICommunicationProtocol> deviceProtocols = new Dictionary<string, ICommunicationProtocol>();
 4 
 5     public void AddDevice(string name, ICommunicationProtocol protocol)
 6     {
 7         deviceProtocols[name] = protocol;
 8     }
 9 
10     public void RemoveDevice(string name)
11     {
12         deviceProtocols.Remove(name);
13     }
14 
15     public byte[] ReadData(string deviceName, ushort startAddress, int quantity)
16     {
17         if (deviceProtocols.TryGetValue(deviceName, out var protocol))
18         {
19             return protocol.ReadData(startAddress, quantity);
20         }
21         throw new Exception("Device not found");
22     }
23 
24     public void WriteData(string deviceName, ushort startAddress, byte[] data)
25     {
26         if (deviceProtocols.TryGetValue(deviceName, out var protocol))
27         {
28             protocol.WriteData(startAddress, data);
29         }
30         else
31         {
32             throw new Exception("Device not found");
33         }
34     }
35 
36     public void ConnectDevice(string deviceName)
37     {
38         if (deviceProtocols.TryGetValue(deviceName, out var protocol))
39         {
40             protocol.Connect();
41         }
42     }
43 
44     public void DisconnectDevice(string deviceName)
45     {
46         if (deviceProtocols.TryGetValue(deviceName, out var protocol))
47         {
48             protocol.Disconnect();
49         }
50     }
51 }

 3. ASP.NET Core Web API

  暴露服务层功能的 Web API。

 1 [ApiController]
 2 [Route("api/[controller]")]
 3 public class DeviceController : ControllerBase
 4 {
 5     private readonly DeviceService _deviceService;
 6 
 7     public DeviceController(DeviceService deviceService)
 8     {
 9         _deviceService = deviceService;
10     }
11 
12     [HttpPost("add-device")]
13     public IActionResult AddDevice(string name, string protocolType)
14     {
15         ICommunicationProtocol protocol = ProtocolFactory.Create(protocolType); // 假设有个工厂类创建协议实例
16         _deviceService.AddDevice(name, protocol);
17         return Ok();
18     }
19 
20     [HttpPost("remove-device")]
21     public IActionResult RemoveDevice(string name)
22     {
23         _deviceService.RemoveDevice(name);
24         return Ok();
25     }
26 
27     [HttpGet("read-data")]
28     public IActionResult ReadData(string deviceName, ushort startAddress, int quantity)
29     {
30         var data = _deviceService.ReadData(deviceName, startAddress, quantity);
31         return Ok(data);
32     }
33 
34     [HttpPost("write-data")]
35     public IActionResult WriteData(string deviceName, ushort startAddress, byte[] data)
36     {
37         _deviceService.WriteData(deviceName, startAddress, data);
38         return Ok();
39     }
40 
41     [HttpPost("connect-device")]
42     public IActionResult ConnectDevice(string deviceName)
43     {
44         _deviceService.ConnectDevice(deviceName);
45         return Ok();
46     }
47 
48     [HttpPost("disconnect-device")]
49     public IActionResult DisconnectDevice(string deviceName)
50     {
51         _deviceService.DisconnectDevice(deviceName);
52         return Ok();
53     }
54 }

 4. 前端层(使用 Avalonia)

使用 Avalonia 创建跨平台桌面应用,提供用户界面以与设备交互。

首先,创建一个 Avalonia 项目,然后定义主窗口和视图模型:

MainWindow.axaml:

 1 <Window xmlns="https://github.com/avaloniaui"
 2         xmlns:d="https://github.com/avaloniaui/designtime"
 3         xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
 4         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 5         mc:Ignorable="d"
 6         x:Class="YourNamespace.MainWindow"
 7         Title="Device Control">
 8     <StackPanel>
 9         <TextBox Name="DeviceNameTextBox" PlaceholderText="Device Name" />
10         <ComboBox Name="ProtocolTypeComboBox">
11             <ComboBoxItem Content="Modbus RTU" />
12             <ComboBoxItem Content="Another Protocol" />
13         </ComboBox>
14         <Button Name="AddDeviceButton" Content="Add Device" Click="OnAddDeviceButtonClick" />
15         <!-- 其他UI元素和绑定 -->
16     </StackPanel>
17 </Window>

MainWindow.axaml.cs:

 1 public partial class MainWindow : Window
 2 {
 3     public MainWindow()
 4     {
 5         InitializeComponent();
 6     }
 7 
 8     private async void OnAddDeviceButtonClick(object sender, Avalonia.Interactivity.RoutedEventArgs e)
 9     {
10         var deviceName = DeviceNameTextBox.Text;
11         var protocolType = (ProtocolTypeComboBox.SelectedItem as ComboBoxItem)?.Content.ToString();
12 
13         using (var client = new HttpClient())
14         {
15             var response = await client.PostAsync($"http://localhost:5000/api/device/add-device?name={deviceName}&protocolType={protocolType}", null);
16             if (response.IsSuccessStatusCode)
17             {
18                 MessageBox.Avalonia.MessageBoxManager.GetMessageBoxStandardWindow("Success", "Device added successfully.").Show();
19             }
20         }
21     }
22 }

 5. 数据展示和图表绘制

在前端,通过HTTP请求获取设备数据,并使用图表库进行绘制(例如使用LiveCharts库)。

DeviceDataChart.axaml:

1 <UserControl xmlns="https://github.com/avaloniaui"
2              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
3              xmlns:lvc="clr-namespace:LiveChartsCore.SkiaSharpView.Avalonia;assembly=LiveChartsCore.SkiaSharpView.Avalonia"
4              x:Class="YourNamespace.DeviceDataChart">
5     <lvc:CartesianChart Series="{Binding Series}" />
6 </UserControl>

DeviceDataChartViewModel.cs:

 

 1 public class DeviceDataChartViewModel : ReactiveObject
 2 {
 3     public ObservableCollection<ISeries> Series { get; set; }
 4 
 5     public DeviceDataChartViewModel()
 6     {
 7         Series = new ObservableCollection<ISeries>
 8         {
 9             new LineSeries<double>
10             {
11                 Values = new ObservableCollection<double> { 3, 5, 7, 4, 2, 6, 3 }
12             }
13         };
14     }
15 
16     public async Task LoadData(string deviceName)
17     {
18         using (var client = new HttpClient())
19         {
20             var response = await client.GetAsync($"http://localhost:5000/api/device/read-data?deviceName={deviceName}&startAddress=0&quantity=10");
21             if (response.IsSuccessStatusCode)
22             {
23                 var data = await response.Content.ReadAsAsync<byte[]>();
24                 Series[0].Values = data.Select(b => (double)b).ToArray();
25             }
26         }
27     }
28 }

 

 

 

总结

协议层:使用接口和具体实现,支持多种设备协议。
服务层:管理设备和协议实例。
Web API:提供统一的接口供前端调用。
前端层:使用 Avalonia 创建跨平台桌面应用,展示设备数据并提供用户交互功能。

这种设计模式结合了可扩展性、跨平台支持和易用性,满足了集中控制和大规模设备管理的需求。

posted @ 2024-06-19 11:06  .net小峰  阅读(161)  评论(0编辑  收藏  举报