using Common.Attributes; using DeviceCommand.Base; using System; using System.Threading; using System.Threading.Tasks; namespace DeviceCommand.Device { [BOBCommand] public class PSB11000 : ModbusTcp { public PSB11000(string IpAddress, int port, int SendTimeout, int ReceiveTimeout) { ConfigureDevice(IpAddress, port, SendTimeout, ReceiveTimeout); } public PSB11000() { } #region 一、基础控制寄存器 public async Task SetRemoteControlAsync(bool activate, byte slaveAddress = 1, CancellationToken ct = default) { ushort value = (ushort)(activate ? 0xFF00 : 0x0000); await WriteSingleRegisterAsync(slaveAddress, 402, value, ct); } public async Task SetOutputAsync(bool on, byte slaveAddress = 1, CancellationToken ct = default) { ushort value = (ushort)(on ? 0xFF00 : 0x0000); await WriteSingleRegisterAsync(slaveAddress, 405, value, ct); } public async Task SetWorkModeAsync(bool useResistanceMode, byte slaveAddress = 1, CancellationToken ct = default) { ushort value = (ushort)(useResistanceMode ? 0xFF00 : 0x0000); await WriteSingleRegisterAsync(slaveAddress, 409, value, ct); } public async Task ResetAlarmAsync(byte slaveAddress = 1, CancellationToken ct = default) { await WriteSingleRegisterAsync(slaveAddress, 411, 0xFF00, ct); } public async Task QueryRemoteControlAsync(byte slaveAddress = 1, CancellationToken ct = default) { ushort[] result = await ReadHoldingRegistersAsync(slaveAddress, 402, 1, ct); return result[0] == 0xFF00; } public async Task QueryOutputAsync(byte slaveAddress = 1, CancellationToken ct = default) { ushort[] result = await ReadHoldingRegistersAsync(slaveAddress, 405, 1, ct); return result[0] == 0xFF00; } public async Task QueryWorkModeAsync(byte slaveAddress = 1, CancellationToken ct = default) { ushort[] result = await ReadHoldingRegistersAsync(slaveAddress, 409, 1, ct); return result[0] == 0xFF00; // true 表示阻抗模式 } #endregion #region 二、电压/电流/功率/电阻设定值 public async Task SetVoltageAsync(double voltage, double ratedVoltage, byte slaveAddress = 1, CancellationToken ct = default) { ushort value = (ushort)(voltage / ratedVoltage * 0xCCCC); await WriteSingleRegisterAsync(slaveAddress, 500, value, ct); } public async Task GetVoltageAsync(double ratedVoltage, byte slaveAddress = 1, CancellationToken ct = default) { ushort[] reg = await ReadHoldingRegistersAsync(slaveAddress, 500, 1, ct); return reg[0] / (double)0xCCCC * ratedVoltage; } public async Task SetCurrentAsync(double current, double ratedCurrent, byte slaveAddress = 1, CancellationToken ct = default) { ushort value = (ushort)(current / ratedCurrent * 0xCCCC); await WriteSingleRegisterAsync(slaveAddress, 501, value, ct); } public async Task GetCurrentAsync(double ratedCurrent, byte slaveAddress = 1, CancellationToken ct = default) { ushort[] reg = await ReadHoldingRegistersAsync(slaveAddress, 501, 1, ct); return reg[0] / (double)0xCCCC * ratedCurrent; } public async Task SetPowerAsync(double power, double ratedPower, byte slaveAddress = 1, CancellationToken ct = default) { ushort value = (ushort)(power / ratedPower * 0xCCCC); await WriteSingleRegisterAsync(slaveAddress, 502, value, ct); } public async Task GetPowerAsync(double ratedPower, byte slaveAddress = 1, CancellationToken ct = default) { ushort[] reg = await ReadHoldingRegistersAsync(slaveAddress, 502, 1, ct); return reg[0] / (double)0xCCCC * ratedPower; } public async Task SetResistanceAsync(double resistance, double maxResistance, byte slaveAddress = 1, CancellationToken ct = default) { ushort value = (ushort)(resistance / maxResistance * 0xCCCC); await WriteSingleRegisterAsync(slaveAddress, 503, value, ct); } public async Task GetResistanceAsync(double maxResistance, byte slaveAddress = 1, CancellationToken ct = default) { ushort[] reg = await ReadHoldingRegistersAsync(slaveAddress, 503, 1, ct); return reg[0] / (double)0xCCCC * maxResistance; } #endregion #region 三、Sink 双向模式设定值 public async Task SetSinkPowerAsync(double power, double sinkRatedPower, byte slaveAddress = 1, CancellationToken ct = default) { ushort value = (ushort)(power / sinkRatedPower * 0xCCCC); await WriteSingleRegisterAsync(slaveAddress, 498, value, ct); } public async Task GetSinkPowerAsync(double sinkRatedPower, byte slaveAddress = 1, CancellationToken ct = default) { ushort[] reg = await ReadHoldingRegistersAsync(slaveAddress, 498, 1, ct); return reg[0] / (double)0xCCCC * sinkRatedPower; } public async Task SetSinkCurrentAsync(double current, double sinkRatedCurrent, byte slaveAddress = 1, CancellationToken ct = default) { ushort value = (ushort)(current / sinkRatedCurrent * 0xCCCC); await WriteSingleRegisterAsync(slaveAddress, 499, value, ct); } public async Task GetSinkCurrentAsync(double sinkRatedCurrent, byte slaveAddress = 1, CancellationToken ct = default) { ushort[] reg = await ReadHoldingRegistersAsync(slaveAddress, 499, 1, ct); return reg[0] / (double)0xCCCC * sinkRatedCurrent; } public async Task SetSinkResistanceAsync(double resistance, double sinkMaxResistance, byte slaveAddress = 1, CancellationToken ct = default) { ushort value = (ushort)(resistance / sinkMaxResistance * 0xCCCC); await WriteSingleRegisterAsync(slaveAddress, 504, value, ct); } public async Task GetSinkResistanceAsync(double sinkMaxResistance, byte slaveAddress = 1, CancellationToken ct = default) { ushort[] reg = await ReadHoldingRegistersAsync(slaveAddress, 504, 1, ct); return reg[0] / (double)0xCCCC * sinkMaxResistance; } #endregion #region 四、实时测量与设备状态 public async Task ReadDeviceStatusAsync(byte slaveAddress = 1, CancellationToken ct = default) { ushort[] reg = await ReadHoldingRegistersAsync(slaveAddress, 505, 2, ct); return (uint)(reg[0] << 16 | reg[1]); } public async Task IsDcOnAsync(byte slaveAddress = 1, CancellationToken ct = default) { uint status = await ReadDeviceStatusAsync(slaveAddress, ct); return (status & (1 << 7)) != 0; } public async Task IsRemoteActiveAsync(byte slaveAddress = 1, CancellationToken ct = default) { uint status = await ReadDeviceStatusAsync(slaveAddress, ct); return (status & (1 << 10)) != 0; } public async Task IsSinkModeActiveAsync(byte slaveAddress = 1, CancellationToken ct = default) { uint status = await ReadDeviceStatusAsync(slaveAddress, ct); return (status & (1 << 12)) != 0; } public async Task ReadActualVoltageAsync(double ratedVoltage, byte slaveAddress = 1, CancellationToken ct = default) { ushort[] reg = await ReadHoldingRegistersAsync(slaveAddress, 507, 1, ct); return reg[0] / (double)0xCCCC * ratedVoltage; } public async Task ReadActualCurrentAsync(double ratedCurrent, byte slaveAddress = 1, CancellationToken ct = default) { ushort[] reg = await ReadHoldingRegistersAsync(slaveAddress, 508, 1, ct); double current = reg[0] / (double)0xCCCC * ratedCurrent; if (await IsSinkModeActiveAsync(slaveAddress, ct)) current = -current; return current; } public async Task ReadActualPowerAsync(double ratedPower, byte slaveAddress = 1, CancellationToken ct = default) { ushort[] reg = await ReadHoldingRegistersAsync(slaveAddress, 509, 1, ct); double power = reg[0] / (double)0xCCCC * ratedPower; if (await IsSinkModeActiveAsync(slaveAddress, ct)) power = -power; return power; } #endregion #region 五、保护阈值 public async Task SetOverVoltageLimitAsync(double voltage, double ratedVoltage, byte slaveAddress = 1, CancellationToken ct = default) { ushort value = (ushort)(voltage / ratedVoltage * 0xCCCC); await WriteSingleRegisterAsync(slaveAddress, 510, value, ct); } public async Task ReadOverVoltageLimitAsync(double ratedVoltage, byte slaveAddress = 1, CancellationToken ct = default) { ushort[] reg = await ReadHoldingRegistersAsync(slaveAddress, 510, 1, ct); return reg[0] / (double)0xCCCC * ratedVoltage; } public async Task SetOverCurrentLimitAsync(double current, double ratedCurrent, byte slaveAddress = 1, CancellationToken ct = default) { ushort value = (ushort)(current / ratedCurrent * 0xCCCC); await WriteSingleRegisterAsync(slaveAddress, 511, value, ct); } public async Task ReadOverCurrentLimitAsync(double ratedCurrent, byte slaveAddress = 1, CancellationToken ct = default) { ushort[] reg = await ReadHoldingRegistersAsync(slaveAddress, 511, 1, ct); return reg[0] / (double)0xCCCC * ratedCurrent; } public async Task SetOverPowerLimitAsync(double power, double ratedPower, byte slaveAddress = 1, CancellationToken ct = default) { ushort value = (ushort)(power / ratedPower * 0xCCCC); await WriteSingleRegisterAsync(slaveAddress, 512, value, ct); } public async Task ReadOverPowerLimitAsync(double ratedPower, byte slaveAddress = 1, CancellationToken ct = default) { ushort[] reg = await ReadHoldingRegistersAsync(slaveAddress, 512, 1, ct); return reg[0] / (double)0xCCCC * ratedPower; } #endregion } }