Sic.Framework-Nanjing-Baishi/MECF.Framework.Common/MECF/Framework/RT/Core/IoProviders/IoProvider.cs

245 lines
5.6 KiB
C#
Raw Normal View History

2023-04-13 11:51:03 +08:00
#define TRACE
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Xml;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.IOCore;
using Aitex.Core.RT.Log;
using Aitex.Core.Util;
namespace MECF.Framework.RT.Core.IoProviders
{
public abstract class IoProvider : IIoProvider
{
protected PeriodicJob _thread;
protected IIoBuffer _buffer;
protected R_TRIG _trigError = new R_TRIG();
protected RD_TRIG _trigNotConnected = new RD_TRIG();
protected string _source;
protected XmlElement _nodeParameter;
protected List<IoBlockItem> _blockSections;
public string Module { get; set; }
public string Name { get; set; }
public bool IsOpened => State == IoProviderStateEnum.Opened;
/// <summary>
/// 根据DI的值判断是否已经和PLC同步数据。
/// </summary>
public bool IsSynced
{
get
{
try
{
var dict = _buffer.GetDiBuffer(_source);
if (dict == null)
return false;
if (dict.TryGetValue(0, out var diBuff) == false)
return false;
if(diBuff == null)
return false;
if (Array.TrueForAll(diBuff, x => x == true) ||
Array.TrueForAll(diBuff, x => x == false))
return false;
return true;
return true;
}
catch (Exception e)
{
return false;
}
}
}
2023-04-13 11:51:03 +08:00
public IoProviderStateEnum State { get; set; }
protected abstract void SetParameter(XmlElement nodeParameter);
protected abstract void Open();
protected abstract void Close();
protected abstract bool[] ReadDi(int offset, int size);
protected abstract short[] ReadAi(int offset, int size);
protected abstract void WriteDo(int offset, bool[] buffer);
protected abstract void WriteAo(int offset, short[] buffer);
protected abstract void ReadDo(int offset, bool[] buffer);
protected abstract short[] ReadAo(int offset, int size);
protected virtual float[] ReadAiFloat(int offset, int size)
{
return null;
}
protected virtual void WriteAoFloat(int offset, float[] buffer)
{
}
public virtual void Initialize(string module, string name, List<IoBlockItem> lstBuffers, IIoBuffer buffer, XmlElement nodeParameter, Dictionary<int, string> ioMappingPathFile)
{
Module = module;
Name = name;
_source = module + "." + name;
_buffer = buffer;
_nodeParameter = nodeParameter;
_blockSections = lstBuffers;
buffer.SetBufferBlock(_source, lstBuffers);
buffer.SetIoMap(_source, ioMappingPathFile);
SetParameter(nodeParameter);
State = IoProviderStateEnum.Uninitialized;
_thread = new PeriodicJob(50, OnTimer, name);
2023-04-13 11:51:03 +08:00
}
public virtual void Initialize(string module, string name, List<IoBlockItem> lstBuffers, IIoBuffer buffer, XmlElement nodeParameter, string ioMappingPathFile, string ioModule)
{
Module = module;
Name = name;
_source = module + "." + name;
_buffer = buffer;
_nodeParameter = nodeParameter;
_blockSections = lstBuffers;
buffer.SetBufferBlock(_source, lstBuffers);
buffer.SetIoMapByModule(_source, 0, ioMappingPathFile, ioModule);
SetParameter(nodeParameter);
State = IoProviderStateEnum.Uninitialized;
_thread = new PeriodicJob(50, OnTimer, name);
2023-04-13 11:51:03 +08:00
}
protected void SetState(IoProviderStateEnum newState)
{
State = newState;
}
public void TraceArray(bool[] data)
{
string[] array = new string[data.Length];
for (int i = 0; i < data.Length; i++)
{
array[i++] = (data[i] ? "1" : "0");
}
Trace.WriteLine(string.Join(",", array));
}
protected virtual bool OnTimer()
{
if (State == IoProviderStateEnum.Uninitialized)
{
SetState(IoProviderStateEnum.Opening);
Open();
}
if (State == IoProviderStateEnum.Opened)
{
try
{
foreach (IoBlockItem blockSection in _blockSections)
{
if (blockSection.Type == IoType.DI)
{
var diBuffer = ReadDi(blockSection.Offset, blockSection.Size);
if (diBuffer != null)
_buffer.SetDiBuffer(_source, blockSection.Offset, diBuffer);
2023-04-13 11:51:03 +08:00
}
else
{
if (blockSection.Type == IoType.AI)
2023-04-13 11:51:03 +08:00
{
var aiBuffer = ReadAi(blockSection.Offset, blockSection.Size);
if (aiBuffer != null)
_buffer.SetAiBuffer(_source, blockSection.Offset,
aiBuffer.Select(s => (float)s).ToArray());
2023-04-13 11:51:03 +08:00
}
}
}
var aoBuffer = _buffer.GetAoBuffer(_source);
2023-04-13 11:51:03 +08:00
if (aoBuffer != null)
{
foreach (var item in aoBuffer)
WriteAo(item.Key, item.Value.Select(x => (short)x).ToArray());
2023-04-13 11:51:03 +08:00
}
var doBuffer = _buffer.GetDoBuffer(_source);
2023-04-13 11:51:03 +08:00
if (doBuffer != null)
{
foreach (KeyValuePair<int, bool[]> item2 in doBuffer)
WriteDo(item2.Key, item2.Value);
}
}
catch (Exception ex)
{
LOG.Write(ex);
SetState(IoProviderStateEnum.Error);
Close();
}
}
_trigError.CLK = State == IoProviderStateEnum.Error;
if (_trigError.Q)
{
EV.PostAlarmLog(Module, _source + " error");
}
_trigNotConnected.CLK = State != IoProviderStateEnum.Opened;
if (_trigNotConnected.T)
{
EV.PostInfoLog(Module, _source + " connected");
}
if (_trigNotConnected.R)
{
EV.PostWarningLog(Module, _source + " not connected");
}
return true;
}
public virtual void Reset()
{
_trigError.RST = true;
_trigNotConnected.RST = true;
}
public void Start()
{
if (_thread != null)
{
_thread.Start();
}
}
public void Stop()
{
SetState(IoProviderStateEnum.Closing);
Close();
_thread.Stop();
}
public virtual bool SetValue(AOAccessor aoItem, float value)
2023-04-13 11:51:03 +08:00
{
return true;
}
2023-04-13 11:51:03 +08:00
public virtual bool SetValue(DOAccessor doItem, bool value)
{
return true;
}
}
}