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; /// /// SignalR Hub cho ModbusTCP device - cung cấp real-time Modbus data /// [Authorize] public class ModbusTcpHub(IDeviceProvider deviceProvider) : Hub { /// /// Lấy thông tin device (DeviceName) theo device ID /// public async Task GetDeviceInfo(string deviceId) { var device = deviceProvider.GetDevice(deviceId); if (device is not IModbusTcpDevice) { return null; } return new DeviceInfoDto { DeviceId = device.DeviceId, DeviceName = device.DeviceName }; } /// /// Lấy tất cả dữ liệu Modbus theo device ID /// public async Task GetModbusData(string deviceId) { var device = deviceProvider.GetDevice(deviceId); if (device is not IModbusTcpDevice modbusDevice) { return null; } return MapToDto(modbusDevice); } /// /// Ghi một coil theo device ID /// /// Device ID /// Địa chỉ coil /// Giá trị cần ghi (true/false) /// True nếu thành công, false nếu thất bại public async Task 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; } } /// /// Map IModbusTcpDevice sang ModbusTcpDataDto /// 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(); // 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(); 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(); // 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(); 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(); 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(); 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(); 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(); 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; } }