Files
laatzen/Common/Hardware/Common.Hardware.SIRT/SIRTTask.Public.cs
T

151 lines
4.2 KiB
C#

namespace Common.Hardware.SIRT
{
using System;
using System.Collections.Concurrent;
using System.Timers;
public partial class SIRTTask
{
public readonly ConcurrentStack<SIRTMessage> responses;
public readonly SIRTMessage request;
protected readonly Timer timeoutTimer;
public SIRTTask(int frequency, int timeout = 5_000)
{
this.Timeout = timeout;
this.Frequency = frequency;
this.responses = new ConcurrentStack<SIRTMessage>();
this.request = new SIRTMessage();
this.timeoutTimer = new Timer
{
AutoReset = false,
Enabled = false,
Interval = this.Timeout
};
this.timeoutTimer.Elapsed += this.OnTimeout;
}
public event Action<SIRTTask> Completed;
public event Action<SIRTTask> Cancelled;
public event Action<SIRTTask> Timeouted;
public event Action<SIRTTask> Updated;
public byte Cmd
{
get => this.request.Cmd;
set => this.request.Cmd = value;
}
public byte P1
{
get => this.request.P1;
set => this.request.P1 = value;
}
public byte P2
{
get => this.request.P2;
set => this.request.P2 = value;
}
public uint RequestAddress
{
get => this.request.Address;
set
{
this.request.Address = value;
this.ResponseAddress = value;
}
}
public uint ResponseAddress { get; set; }
public byte[] Data
{
get => this.request.Data;
set => this.request.Data = value;
}
public int Timeout { get; }
public int Frequency { get; }
public SIRTTaskState State { get; protected set; }
public void PushResponse(SIRTMessage response)
{
if (this.State == SIRTTaskState.Cancelled)
{
return;
}
this.responses.Push(response);
if (response.Length >= 13)
{
var responseAddress = response.Address;
if (responseAddress != this.RequestAddress)
{
var requestAddress = this.RequestAddress;
this.RequestAddress = this.ResponseAddress;
this.ResponseAddress = requestAddress;
this.NotifyUpdated();
}
}
this.ProcessResponse(response);
}
public virtual byte[] ToByteArray() => this.request.ToByteArray();
public override string ToString() => BitConverter.ToString(this.ToByteArray());
public virtual void UpdateFrom(SIRTTask task)
{
this.P1 = task.P1;
this.P2 = task.P2;
this.RequestAddress = task.RequestAddress;
this.ResponseAddress = task.ResponseAddress;
}
protected void NotifyCancelled() => this.Cancelled?.Invoke(this);
protected void NotifyCompleted() => this.Completed?.Invoke(this);
protected void NotifyTimeouted() => this.Timeouted?.Invoke(this);
protected void NotifyUpdated() => this.Updated?.Invoke(this);
protected virtual void OnTimeout(object sender, ElapsedEventArgs e)
{
this.State = SIRTTaskState.Cancelled;
this.NotifyCancelled();
}
protected virtual void ProcessResponse(SIRTMessage response)
{
if (this.State == SIRTTaskState.Running)
{
if (response.Cmd == SIRTMessage.ACKNANSW || (response.Data.Length > 0 && response.Data[0] == SIRTMessage.SEMI))
{
this.State = SIRTTaskState.Completed;
}
}
if (this.State == SIRTTaskState.Completed)
{
this.timeoutTimer.Stop();
this.NotifyCompleted();
}
else if (this.State == SIRTTaskState.Cancelled)
{
this.timeoutTimer.Stop();
this.NotifyCancelled();
}
}
}
}