操控平台后端代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

280 lines
9.7 KiB

using Bodk.Device.Storage.Attributes;
using Bodk.Device.Storage.EventArgs;
using Bodk.Device.Storage.Modules;
using Bodk.Device.Storage.Summary;
using Bodk.Extensions.Modbus;
namespace Bodk.Device.Storage;
public class M9Storage : IStorage
{
public IReadOnlyList<IModule> Modules => _modules;
private readonly List<ModuleBase> _modules = new();
private readonly ModbusWrapper _modbusWrapper;
private readonly CancellationTokenSource _cancellationTokenSource = new();
private readonly CancellationToken _cancellationToken;
public M9Storage(Action<object?, AlarmChangedEventArg> alarmEventHandler,
Action<object?, MotionTimeoutAlarmChangedEventArg> motionTimeoutAlarmEventHandler)
{
_cancellationToken = _cancellationTokenSource.Token;
_modbusWrapper = new ModbusWrapper("192.168.80.253", 502);
_modules.Add(new Turntable(alarmEventHandler, motionTimeoutAlarmEventHandler,
_modbusWrapper.WriteCoilsAsync,
_modbusWrapper.ReadCoilsAsync, _modbusWrapper.ReadHoldingRegistersAsync,
_modbusWrapper.WriteHoldingRegistersAsync));
_modules.Add(new CryogenicRackGripper1(alarmEventHandler, motionTimeoutAlarmEventHandler,
_modbusWrapper.WriteCoilsAsync,
_modbusWrapper.ReadCoilsAsync, _modbusWrapper.ReadHoldingRegistersAsync,
_modbusWrapper.WriteHoldingRegistersAsync));
_modules.Add(new CryogenicRackGripper2(alarmEventHandler, motionTimeoutAlarmEventHandler,
_modbusWrapper.WriteCoilsAsync,
_modbusWrapper.ReadCoilsAsync, _modbusWrapper.ReadHoldingRegistersAsync,
_modbusWrapper.WriteHoldingRegistersAsync));
}
public async Task Start()
{
await _modbusWrapper.ConnectAsync();
Process();
}
public void Stop()
{
_cancellationTokenSource.Cancel();
}
private ushort? _accessPositionCircle;
public ushort AccessPositionCircle
{
get
{
if (_accessPositionCircle is not null) return _accessPositionCircle.Value;
var data = _modbusWrapper.ReadHoldingRegistersAsync(AccessPositionAddress, 1).Result;
_accessPositionCircle = data[0];
return _accessPositionCircle.Value;
}
set
{
_accessPositionCircle = value;
_modbusWrapper.WriteHoldingRegistersAsync(AccessPositionAddress,
new[] { value }).Wait();
}
}
private ushort? _accessPositionColumn;
private ushort? _accessPositionFloor;
public ushort AccessPositionColumn
{
get
{
if (_accessPositionColumn is not null) return _accessPositionColumn.Value;
var data = _modbusWrapper.ReadHoldingRegistersAsync(AccessPositionAddress + 1, 1).Result;
_accessPositionColumn = data[0];
return _accessPositionColumn.Value;
}
set
{
_accessPositionColumn = value;
_modbusWrapper.WriteHoldingRegistersAsync(AccessPositionAddress + 1,
new[] { value }).Wait();
}
}
public ushort AccessPositionFloor
{
get
{
if (_accessPositionFloor is not null) return _accessPositionFloor.Value;
var data = _modbusWrapper.ReadHoldingRegistersAsync(AccessPositionAddress + 2, 1).Result;
_accessPositionFloor = data[0];
return _accessPositionFloor.Value;
}
set
{
_accessPositionFloor = value;
_modbusWrapper.WriteHoldingRegistersAsync(AccessPositionAddress + 2,
new[] { value }).Wait();
}
}
public float InCavityTemperature { get; private set; }
public float InCavityHumidity { get; private set; }
public float LiquidLevel { get; private set; }
public float FillPortTemperature { get; private set; }
public float ExhaustPortTemperature { get; private set; }
public float TankTemperature { get; private set; }
[Ignore]
public StorageSummary GetSummary()
{
StorageSummary summary = new();
summary.Summary = typeof(IStorage).GetTypeInfo();
summary.Modules = _modules.Select(m => m.GetDescription()).ToList();
return summary;
}
public TypeDescription GetModuleSummary(int moduleId)
{
var module = Modules.FirstOrDefault(m => m.Id == moduleId);
if (module is null)
throw new Exception("module not found");
return module.GetType().GetTypeInfo();
}
[Ignore]
public async Task InvokeMethod(int moduleId, string methodName, object?[]? parameters)
{
if (moduleId == 0)
{
var method = typeof(IStorage)
.GetMethod(methodName);
if (method is null)
throw new Exception("method not found");
await Task.Run(() => (Task)method.Invoke(this, parameters));
}
else
{
var module = _modules.FirstOrDefault(m => m.Id == moduleId);
if (module is null)
throw new Exception("module not found");
var method = module.GetType().GetMethod("methodName");
if (method is null)
throw new Exception("method not found");
await Task.Run(() => (Task)method.Invoke(module, parameters));
}
}
[Ignore]
public object GetPropertyValue(int moduleId, string propertyName)
{
if (moduleId == 0)
{
var property = this.GetType().GetProperty(propertyName);
if (property is null)
throw new Exception("property not found");
return property.GetValue(this);
}
else
{
var module = _modules.First(m => m.Id == moduleId);
var property = module.GetType().GetProperty(propertyName);
if (property is null)
throw new Exception("property not found");
return property.GetValue(module);
}
}
[Ignore]
public void SetPropertyValue(int moduleId, string propertyName, object value)
{
if (moduleId == 0)
{
var property = this.GetType().GetProperty(propertyName);
if (property is null)
throw new Exception("property not found");
property.SetValue(this, value);
}
else
{
var module = _modules.First(m => m.Id == moduleId);
var property = module.GetType().GetProperty(propertyName);
if (property is null)
throw new Exception("property not found");
property.SetValue(module, value);
}
}
public Task Ready()
{
throw new NotImplementedException();
}
private const ushort AccessPositionAddress = 150;
private const ushort InCavityTemperatureAddress = 162;
private const ushort MotionTimeoutAlarmAddress = 280;
private const ushort AlarmAddress = 300;
private const ushort EnabledAddress = 330;
private void Process()
{
Task.Run(async () =>
{
while (!_cancellationToken.IsCancellationRequested)
{
try
{
var data = await _modbusWrapper.ReadHoldingRegistersAsync(InCavityTemperatureAddress, 16);
var values = data.ConvertToFloat();
InCavityTemperature = values[0];
InCavityHumidity = values[1];
LiquidLevel = values[2];
FillPortTemperature = values[4];
ExhaustPortTemperature = values[5];
TankTemperature = values[6];
await Task.Delay(100, _cancellationToken);
var timeoutFlags = await _modbusWrapper.ReadCoilsAsync(MotionTimeoutAlarmAddress, 20);
for (int i = 0; i < timeoutFlags.Length; i++)
{
var i1 = i;
var module = _modules
.First(m => m.MotionTimeoutAlarmAddress == MotionTimeoutAlarmAddress + i1);
if (timeoutFlags[i] !=
module.MotionTimeoutAlarm)
{
module.OnMotionTimeoutAlarmChanged(
new MotionTimeoutAlarmChangedEventArg(module, timeoutFlags[i]));
}
}
await Task.Delay(100, _cancellationToken);
var alarmFlags = await _modbusWrapper.ReadCoilsAsync(AlarmAddress, 21);
for (int i = 0; i < alarmFlags.Length; i++)
{
var i1 = i;
var module = _modules
.First(m => m.AlarmAddress == AlarmAddress + i1);
if (alarmFlags[i] !=
module.Alarm)
{
module.OnAlarmChanged(
new AlarmChangedEventArg(module, alarmFlags[i]));
}
}
await Task.Delay(100, _cancellationToken);
var enabledFlags = await _modbusWrapper.ReadCoilsAsync(EnabledAddress, 20);
for (int i = 0; i < enabledFlags.Length; i++)
{
var i1 = i;
var module = _modules
.First(m => m.IsEnabledAddress == EnabledAddress + i1);
module.IsEnabled = enabledFlags[i];
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
await Task.Delay(1000, _cancellationToken);
}
}, _cancellationToken);
}
}