Files
I150/srcs/RobotNet10/RobotApp/RobotNet10.RobotApp/Hubs/ModbusTcpHub.cs
2026-07-03 16:37:12 +07:00

242 lines
8.4 KiB
C#

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR;
using RobotNet10.RobotApp.Client.Shared.Devices;
using RobotNet10.RobotApp.Devices;
using RobotNet10.Shared;
namespace RobotNet10.RobotApp.Hubs;
/// <summary>
/// SignalR Hub cho ModbusTCP device - cung cấp real-time Modbus data
/// </summary>
[Authorize]
public class ModbusTcpHub(IDeviceProvider deviceProvider) : Hub
{
/// <summary>
/// Lấy thông tin device (DeviceName) theo device ID
/// </summary>
public async Task<DeviceInfoDto?> GetDeviceInfo(string deviceId)
{
var device = deviceProvider.GetDevice(deviceId);
if (device is not IModbusTcpDevice)
{
return null;
}
return new DeviceInfoDto
{
DeviceId = device.DeviceId,
DeviceName = device.DeviceName
};
}
/// <summary>
/// Lấy tất cả dữ liệu Modbus theo device ID
/// </summary>
public async Task<ModbusTcpData?> GetModbusData(string deviceId)
{
var device = deviceProvider.GetDevice(deviceId);
if (device is not IModbusTcpDevice modbusDevice)
{
return null;
}
return MapToDto(modbusDevice);
}
/// <summary>
/// Ghi một coil theo device ID
/// </summary>
/// <param name="deviceId">Device ID</param>
/// <param name="address">Địa chỉ coil</param>
/// <param name="value">Giá trị cần ghi (true/false)</param>
/// <returns>True nếu thành công, false nếu thất bại</returns>
public async Task<bool> WriteCoil(string deviceId, ushort address, bool value)
{
var device = deviceProvider.GetDevice(deviceId);
if (device is not IModbusTcpDevice modbusDevice)
{
return false;
}
try
{
await modbusDevice.WriteCoilAsync(address, value);
return true;
}
catch
{
return false;
}
}
/// <summary>
/// Map IModbusTcpDevice sang ModbusTcpDataDto
/// </summary>
private static ModbusTcpData MapToDto(IModbusTcpDevice modbusDevice)
{
var dto = new ModbusTcpData
{
IpAddress = modbusDevice.IpAddress,
Port = modbusDevice.Port,
SlaveId = modbusDevice.SlaveId,
IsConnected = modbusDevice.IsConnected
};
var holdingRegisters = new List<ModbusRangeData>();
// Lấy Holding Registers
foreach (var range in modbusDevice.HoldingRegisterRanges)
{
try
{
var values = modbusDevice.ReadHoldingRegisters(range.StartAddress, range.Quantity);
var rangeData = new ModbusRangeData
{
StartAddress = range.StartAddress,
Quantity = range.Quantity,
Name = range.Name,
ChildrenNames = range.ChildrenNames == null ? [] : [.. range.ChildrenNames]
};
var modbusValues = new List<ModbusValue>();
for (ushort i = 0; i < values.Length; i++)
{
var address = (ushort)(range.StartAddress + i);
var childName = (range.ChildrenNames != null && i < range.ChildrenNames.Length) ? range.ChildrenNames[i] : "";
modbusValues.Add(new ModbusValue
{
Address = address,
Index = i,
Value = values[i],
Name = childName
});
}
rangeData.Values = [.. modbusValues];
holdingRegisters.Add(rangeData);
}
catch
{
// Skip range nếu không đọc được
}
}
dto.HoldingRegisters = [.. holdingRegisters];
var inputRegisters = new List<ModbusRangeData>();
// Lấy Input Registers
foreach (var range in modbusDevice.InputRegisterRanges)
{
try
{
var values = modbusDevice.ReadInputRegisters(range.StartAddress, range.Quantity);
var rangeData = new ModbusRangeData
{
StartAddress = range.StartAddress,
Quantity = range.Quantity,
Name = range.Name,
ChildrenNames = range.ChildrenNames == null ? [] : [.. range.ChildrenNames]
};
var modbusValues = new List<ModbusValue>();
for (ushort i = 0; i < values.Length; i++)
{
var address = (ushort)(range.StartAddress + i);
var childName = (range.ChildrenNames != null && i < range.ChildrenNames.Length) ? range.ChildrenNames[i] : "";
modbusValues.Add(new ModbusValue
{
Address = address,
Index = i,
Value = values[i],
Name = childName
});
}
rangeData.Values = [.. modbusValues];
inputRegisters.Add(rangeData);
}
catch
{
// Skip range nếu không đọc được
}
}
dto.InputRegisters = [.. inputRegisters];
// Lấy Coils
var coils = new List<ModbusRangeData>();
foreach (var range in modbusDevice.CoilRanges)
{
try
{
var values = modbusDevice.ReadCoils(range.StartAddress, range.Quantity);
var rangeData = new ModbusRangeData
{
StartAddress = range.StartAddress,
Quantity = range.Quantity,
Name = range.Name,
ChildrenNames = range.ChildrenNames ?? []
};
var modbusValues = new List<ModbusBoolValue>();
for (ushort i = 0; i < values.Length; i++)
{
var address = (ushort)(range.StartAddress + i);
var childName = (range.ChildrenNames != null && i < range.ChildrenNames.Length) ? range.ChildrenNames[i] : "";
modbusValues.Add(new ModbusBoolValue
{
Address = address,
Index = i,
Value = values[i],
Name = childName
});
}
rangeData.BoolValues = [.. modbusValues];
coils.Add(rangeData);
}
catch
{
// Skip range nếu không đọc được
}
}
dto.Coils = [.. coils];
// Lấy Discrete Inputs
var inputs = new List<ModbusRangeData>();
foreach (var range in modbusDevice.DiscreteInputRanges)
{
try
{
var values = modbusDevice.ReadDiscreteInputs(range.StartAddress, range.Quantity);
var rangeData = new ModbusRangeData
{
StartAddress = range.StartAddress,
Quantity = range.Quantity,
Name = range.Name,
ChildrenNames = range.ChildrenNames ?? []
};
var modbusValues = new List<ModbusBoolValue>();
for (ushort i = 0; i < values.Length; i++)
{
var address = (ushort)(range.StartAddress + i);
var childName = (range.ChildrenNames != null && i < range.ChildrenNames.Length) ? range.ChildrenNames[i] : "";
modbusValues.Add(new ModbusBoolValue
{
Address = address,
Index = i,
Value = values[i],
Name = childName
});
}
rangeData.BoolValues = [.. modbusValues];
inputs.Add(rangeData);
}
catch
{
// Skip range nếu không đọc được
}
}
dto.DiscreteInputs = [.. inputs];
return dto;
}
}