Files
tbf/TBF/BenchControl/Modbus/QuidoRS/QuidoRS.cs
T

198 lines
6.5 KiB
C#

///
/// Copyright (c) 2015-2019 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using log4net;
using Config.Entities;
using TBF.BenchControl.Generic;
using TBF.Boxes;
namespace TBF.BenchControl.Modbus.QuidoRS
{
public class QuidoRS : ComponentBase, IDevice, GenericDevices.IParallelOutput
{
private static readonly ILog log = LogManager.GetLogger(typeof(QuidoRS));
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
readonly QuidoRSCfg quidoRSCfg;
public QuidoVariant Variant { get { return quidoRSCfg.Variant; } }
readonly GenericDevices.IModbus modbus;
ushort watchdogBitMask;
private ushort currentOutputs;
private DateTime lastOutputsChange;
public QuidoRS() { }
public QuidoRS(Generic.IComponentCfg cfg, IList<Generic.IComponent> components)
: base(cfg)
{
quidoRSCfg = cfg as QuidoRSCfg;
modbus = (GenericDevices.IModbus)TbfComponents.FindComponent(cfg.ParentName, components);
if (modbus == null) throw new Exception("Cannot find " + Name + " parent");
}
/// <summary>Initialize this device</summary>
public override void Initialize()
{
watchdogBitMask = (ushort)(quidoRSCfg.WatchdogEnabled ? (1 << quidoRSCfg.WatchdogBitNr) : 0);
if (quidoRSCfg.DebugLevel == DebugMode.Simulate)
log.FatalFormat("{0} simulated: {1}", Name, this);
else
log.FatalFormat("{0} initialized: {1}", Name, this);
}
/// <summary>Run this device</summary>
public void RunDeviceBefore()
{
if (quidoRSCfg.DebugLevel == Config.Entities.DebugMode.Simulate) return;
lock (this)
{
if (watchdogBitMask != 0 && (DateTime.Now - lastOutputsChange) > new TimeSpan(0, 0, 0, 0, 3000)) /// Toggle after 1.5 sec (resulting in toggle period 2 sec)
{
currentOutputs = (UInt16)((Int32)currentOutputs ^ (Int32)watchdogBitMask);
SendOutputs(currentOutputs);
}
}
if (modbus.ReceivedTelegrams[quidoRSCfg.ModbusAddress].Count > 0)
{
byte[] telegram = modbus.ReceivedTelegrams[quidoRSCfg.ModbusAddress].Dequeue();
if ((telegram.Length >= 8) && (telegram[1] == 0x11) && (telegram[2] == telegram.Length - 5))
{
int msgLen = telegram.Length - 7;
byte modbusAddress = telegram[3];
string msg = Encoding.ASCII.GetString(telegram, 5, msgLen);
string s = string.Format("QuidoRS detected: Address={0}, Message={1}", modbusAddress, msg);
Debug.WriteLine(s);
log.Warn(s);
}
}
}
public void RunDeviceAfter() { }
public void StopDevice()
{
SendOutputs(0);
}
public void StopDevice2() { }
/// <summary>
/// Set outputs of QuidoRS board
/// </summary>
/// <param name="outputs">output value</param>
public void SetOutputs(ushort outputs)
{
lock (this)
{
currentOutputs = (UInt16)((Int32)outputs | ((Int32)currentOutputs & (Int32)watchdogBitMask));
if (watchdogBitMask != 0)
{
currentOutputs = (UInt16)((Int32)currentOutputs ^ (Int32)watchdogBitMask);
}
SendOutputs(currentOutputs);
}
}
/// <summary>
/// Set bit(s) specified by a bitMask. Leave other bits unaffeced.
/// </summary>
/// <param name="bitMask">Specifies bit(s) to set</param>
/// <param name="outputs">output value</param>
public void SetBit(ushort bitMask)
{
lock (this)
{
currentOutputs = (UInt16)((Int32)currentOutputs | (Int32)bitMask);
if (watchdogBitMask != 0)
{
currentOutputs = (UInt16)((Int32)currentOutputs ^ (Int32)watchdogBitMask);
}
SendOutputs(currentOutputs);
}
}
/// <summary>
/// Reset bit(s) specified by a bitMask. Leave other bits unaffeced.
/// </summary>
/// <param name="bitMask">Specifies bit(s) to reset</param>
/// <param name="outputs">output value</param>
public void ResetBit(ushort bitMask)
{
lock (this)
{
currentOutputs = (UInt16)((Int32)currentOutputs & (~(Int32)bitMask));
if (watchdogBitMask != 0)
{
currentOutputs = (UInt16)((Int32)currentOutputs ^ (Int32)watchdogBitMask);
}
SendOutputs(currentOutputs);
}
}
private void SendOutputs(ushort outputs)
{
byte addr = quidoRSCfg.ModbusAddress;
byte cmd = (byte)Function.ForceMultipleCoils;
byte dataLo = (byte)(outputs & 0xFF);
byte dataHi = (byte)(outputs >> 8);
if (quidoRSCfg.Variant == QuidoVariant.QuidoRS_2_16)
{
modbus.SendMessage(new byte[] { addr, cmd, 0, 0, 0, 16, 2, dataLo, dataHi, 0, 0 });
}
else if (quidoRSCfg.Variant == QuidoVariant.QuidoRS_4_4)
{
modbus.SendMessage(new byte[] { addr, cmd, 0, 0, 0, 4, 1, dataLo, 0, 0 });
}
else if (quidoRSCfg.Variant == QuidoVariant.QuidoRS_8_8)
{
modbus.SendMessage(new byte[] { addr, cmd, 0, 0, 0, 8, 1, dataLo, 0, 0 });
}
lastOutputsChange = DateTime.Now;
}
/// <summary>
/// Events: SetOpututsDone, Error
/// </summary>
/// <param name="outValue">Parallel output data</param>
/// <returns>SetOutputsOp operation casted to IOperaton</returns>
public IOperation SetOutputsOp(ushort outValue)
{
return new SetOutputsOp(this, outValue);
}
/// <summary>
/// Events: Event.None
/// </summary>
/// <returns>ShowBenchWaitingOp operation casted to generic IOperaton</returns>
public IOperation ShowBenchWaitingOp()
{
return new ShowBenchWaitingOp(this);
}
/// <summary>
/// Events: Event.None
/// </summary>
/// <returns>ShowBenchErrorOp operation casted to generic IOperaton</returns>
public IOperation ShowBenchErrorOp()
{
return new ShowBenchErrorOp(this);
}
}
}