2 Commits

8 changed files with 879 additions and 2 deletions

View File

@ -33,6 +33,7 @@
"Kofax", "Kofax",
"linc", "linc",
"Linc", "Linc",
"Modbus",
"NOPAUSE", "NOPAUSE",
"NSFX", "NSFX",
"OBJE", "OBJE",

View File

@ -20,7 +20,7 @@
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.1" /> <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging.EventLog" Version="8.0.1" /> <PackageReference Include="Microsoft.Extensions.Logging.EventLog" Version="8.0.1" />
<PackageReference Include="Oracle.ManagedDataAccess.Core" Version="23.7.0" /> <PackageReference Include="Oracle.ManagedDataAccess.Core" Version="23.7.0" />
<PackageReference Include="runtime.win-x64.Microsoft.DotNet.ILCompiler" Version="8.0.19" /> <PackageReference Include="runtime.win-x64.Microsoft.DotNet.ILCompiler" Version="8.0.20" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.6" /> <PackageReference Include="System.Data.SqlClient" Version="4.8.6" />
<PackageReference Include="System.Drawing.Common" Version="8.0.16" /> <PackageReference Include="System.Drawing.Common" Version="8.0.16" />
<PackageReference Include="System.IO.Ports" Version="8.0.0" /> <PackageReference Include="System.IO.Ports" Version="8.0.0" />

View File

@ -0,0 +1,114 @@
using File_Watcher.Models;
using System.Collections.ObjectModel;
using System.Net.Mail;
namespace File_Watcher.Helpers;
internal static partial class InfinityQSProjectHelper
{
private record Record(ReadOnlyCollection<string> FilteredLines,
DateTime LastWriteTimeUtc,
string Path);
private static long _LastReview = DateTime.UtcNow.Ticks;
private static readonly Dictionary<string, Record> _KeyValuePairs = [];
internal static bool SendEmail(AppSettings appSettings, ILogger<Worker> logger)
{
InfinityQSProjectConfiguration configuration = appSettings.InfinityQSProjectConfiguration;
Clear(logger, configuration);
ReadOnlyDictionary<string, Record> keyValuePairs = GetKeyValuePairs(logger, configuration);
SendEmail(logger, configuration, keyValuePairs);
_LastReview = DateTime.UtcNow.Ticks;
return true;
}
private static void Clear(ILogger<Worker> logger, InfinityQSProjectConfiguration configuration)
{
long check = DateTime.UtcNow.AddHours(-configuration.ClearEveryHours).Ticks;
foreach (KeyValuePair<string, Record> keyValuePair in _KeyValuePairs)
{
if (keyValuePair.Value.LastWriteTimeUtc.Ticks < check)
{
_ = _KeyValuePairs.Remove(keyValuePair.Key);
logger.LogDebug("Clear File:{file}", keyValuePair.Key);
}
}
}
private static ReadOnlyDictionary<string, Record> GetKeyValuePairs(ILogger<Worker> logger, InfinityQSProjectConfiguration configuration)
{
bool check;
Record? record;
string[] lines;
FileInfo fileInfo;
List<string> filtered = [];
Dictionary<string, Record> results = [];
string[] files = Directory.GetFiles(configuration.SourceDirectory, configuration.SearchPattern, SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
check = false;
filtered.Clear();
fileInfo = new(file);
if (fileInfo.LastWriteTimeUtc.Ticks < _LastReview)
{
logger.LogDebug("Old File:{file}", file);
continue;
}
if (_KeyValuePairs.ContainsKey(fileInfo.FullName))
{
logger.LogDebug("Verified File:{file}", file);
continue;
}
lines = File.ReadAllLines(fileInfo.FullName);
foreach (string line in lines)
{
if (!check && line.Contains(configuration.Search))
{
check = true;
continue;
}
if (check)
{
if (line.StartsWith(configuration.Search[0]))
break;
filtered.Add(line);
}
}
record = new(FilteredLines: filtered.AsReadOnly(),
LastWriteTimeUtc: fileInfo.LastWriteTimeUtc,
Path: fileInfo.FullName);
results.Add(fileInfo.FullName, record);
}
return results.AsReadOnly();
}
private static void SendEmail(ILogger<Worker> logger, InfinityQSProjectConfiguration configuration, ReadOnlyDictionary<string, Record> keyValuePairs)
{
string body;
foreach (KeyValuePair<string, Record> keyValuePair in keyValuePairs)
{
logger.LogDebug("File:{file}", keyValuePair.Key);
body = $"InfinityQS Project Change Detected{Environment.NewLine}File:{keyValuePair.Key}{Environment.NewLine}LastWriteTimeUtc:{keyValuePair.Value:O}{Environment.NewLine}{string.Join(Environment.NewLine, keyValuePair.Value.FilteredLines)}";
logger.LogWarning("SendEmail:{body}", body);
SendEmail(configuration.From, configuration.To, configuration.SimpleMailTransferProtocolServer, configuration.Subject, body);
}
}
private static void SendEmail(string from, string to, string simpleMailTransferProtocolServer, string subject, string body)
{
SmtpClient smtpClient = new(simpleMailTransferProtocolServer);
MailMessage mailMessage = new()
{
From = new MailAddress(from),
Subject = subject,
Body = body,
Priority = MailPriority.High
};
mailMessage.To.Add(new MailAddress(to));
smtpClient.Send(mailMessage);
smtpClient.Dispose();
mailMessage.Dispose();
}
}

700
Helpers/LabJackT7Helper.cs Normal file
View File

@ -0,0 +1,700 @@
using File_Watcher.Models;
using System.Diagnostics;
using System.Net.Sockets;
namespace File_Watcher.Helpers;
#pragma warning disable IDE0300
internal static partial class LabJackT7Helper
{
private static ModbusTransmissionControlProtocolClient? _ModbusTransmissionControlProtocolClient;
private class ModbusTransmissionControlProtocolClient : IDisposable
{
private ushort _TransactionID;
private NetworkStream? _NetworkStream;
private TcpClient? _TransmissionControlProtocolClient;
public ModbusTransmissionControlProtocolClient(string hostname, int port) =>
Connect(hostname, port);
public void Connect(string hostname, int port)
{
if (_TransmissionControlProtocolClient is not null)
Close();
_TransmissionControlProtocolClient = new TcpClient(hostname, port);
_NetworkStream = _TransmissionControlProtocolClient.GetStream();
_TransactionID = 0;
}
public void Close()
{
_NetworkStream?.Close();
_NetworkStream = null;
_TransmissionControlProtocolClient?.Close();
_TransmissionControlProtocolClient = null;
}
public bool IsConnected()
{
if (_TransmissionControlProtocolClient is not null)
return _TransmissionControlProtocolClient.Connected;
return false;
}
public void SetTimeouts(int sendTimeout, int receiveTimeout)
{
if (_TransmissionControlProtocolClient == null)
throw new Exception("Not connected.");
_TransmissionControlProtocolClient.ReceiveTimeout = receiveTimeout;
_TransmissionControlProtocolClient.SendTimeout = sendTimeout;
}
/// <summary>
/// Write a byte array of data to the Modbus device.
/// </summary>
/// <param name="address">The starting register address.</param>
/// <param name="data">The byte array of data to write.</param>
public void Write(ushort address, byte[] data)
{
if (_NetworkStream is null)
throw new Exception("Not connected.");
//Using Modbus function 16
//Create Modbus Command
if (data.Length > 254)
throw new Exception("Too many bytes. The maximum is 254.");
if (data.Length % 2 != 0)
throw new Exception("The number of bytes needs to be a multiple of 2.");
byte[] com = new byte[13 + data.Length];
com[7] = 16;
com[8] = (byte)(address >> 8);
com[9] = (byte)(address & 0xFF);
com[10] = 0;
com[11] = (byte)(data.Length / 2);
com[12] = (byte)data.Length;
Array.Copy(data, 0, com, 13, data.Length);
SetHeader(com);
_NetworkStream.Write(com, 0, com.Length);
byte[] res = new byte[12];
int expectedSize = res.Length;
int size = _NetworkStream.Read(res, 0, res.Length);
Array.Resize(ref res, size);
ResponseErrorChecks(res, expectedSize, com);
}
/// <summary>
/// Read a byte array of data from the Modbus device.
/// </summary>
/// <param name="address">The starting register address.</param>
/// <param name="data">The read byte array of data. The array length is
/// the amount of bytes to read.</param>
public void Read(ushort address, byte[] data)
{
if (_NetworkStream is null)
throw new Exception("Not connected.");
//Using Modbus function 3
//Create Modbus Command
if (data.Length > 254)
throw new Exception("Too many bytes. The maximum is 254.");
if (data.Length % 2 != 0)
throw new Exception("The number of bytes needs to be a multiple of 2.");
byte[] com = new byte[12];
com[7] = 3;
com[8] = (byte)(address >> 8);
com[9] = (byte)(address & 0xFF);
com[10] = 0;
com[11] = (byte)(data.Length / 2);
SetHeader(com);
_NetworkStream.Write(com, 0, com.Length);
byte[] res = new byte[9 + data.Length];
int expectedSize = res.Length;
int size = _NetworkStream.Read(res, 0, res.Length);
Array.Resize(ref res, size);
ResponseErrorChecks(res, expectedSize, com);
Array.Copy(res, 9, data, 0, data.Length);
}
/// <summary>
/// Write an ushort array of data to the Modbus device.
/// </summary>
/// <param name="address">The starting register address.</param>
/// <param name="data">The ushort array of data to write.</param>
public void Write(ushort address, ushort[] data)
{
if (data.Length > 127)
throw new Exception("Too many shorts. The maximum is 127.");
byte[] bytes = new byte[data.Length * 2];
for (int i = 0; i < data.Length; i++)
{
BitConverter.GetBytes(data[i]).CopyTo(bytes, i * 2);
if (BitConverter.IsLittleEndian)
Array.Reverse(bytes, i * 2, 2);
}
Write(address, bytes);
}
/// <summary>
/// Read an ushort array of data from the Modbus device.
/// </summary>
/// <param name="address">The starting register address.</param>
/// <param name="data">The read ushort array of data. The array length
/// is the amount of shorts to read.</param>
public void Read(ushort address, ushort[] data)
{
if (data.Length > 127)
throw new Exception("Too many shorts. The maximum is 127.");
byte[] bytes = new byte[data.Length * 2];
Read(address, bytes);
for (int i = 0; i < data.Length; i++)
{
if (BitConverter.IsLittleEndian)
Array.Reverse(bytes, i * 2, 2);
data[i] = BitConverter.ToUInt16(bytes, i * 2);
}
}
/// <summary>
/// Write an uint array of data to the Modbus device.
/// </summary>
/// <param name="address">The starting register address.</param>
/// <param name="data">The uint array of data to write.</param>
public void Write(ushort address, uint[] data)
{
if (data.Length > 63)
throw new Exception("Too many uint. The maximum is 63.");
byte[] bytes = new byte[data.Length * 4];
for (int i = 0; i < data.Length; i++)
{
BitConverter.GetBytes(data[i]).CopyTo(bytes, i * 4);
if (BitConverter.IsLittleEndian)
Array.Reverse(bytes, i * 4, 4);
}
Write(address, bytes);
}
/// <summary>
/// Read an uint array of data from the Modbus device.
/// </summary>
/// <param name="address">The starting register address.</param>
/// <param name="data">The read uint array of data. The array length is
/// the amount of ints to read.</param>
public void Read(ushort address, uint[] data)
{
if (data.Length > 63)
throw new Exception("Too many ints. The maximum is 63.");
byte[] bytes = new byte[data.Length * 4];
Read(address, bytes);
for (int i = 0; i < data.Length; i++)
{
if (BitConverter.IsLittleEndian)
Array.Reverse(bytes, i * 4, 4);
data[i] = BitConverter.ToUInt32(bytes, i * 4);
}
}
/// <summary>
/// Write an int array of data to the Modbus device.
/// </summary>
/// <param name="address">The starting register address.</param>
/// <param name="data">The int array of data to write.</param>
public void Write(ushort address, int[] data)
{
if (data.Length > 63)
throw new Exception("Too many ints. The maximum is 63.");
byte[] bytes = new byte[data.Length * 4];
for (int i = 0; i < data.Length; i++)
{
BitConverter.GetBytes(data[i]).CopyTo(bytes, i * 4);
if (BitConverter.IsLittleEndian)
Array.Reverse(bytes, i * 4, 4);
}
Write(address, bytes);
}
/// <summary>
/// Read an int array of data from the Modbus device.
/// </summary>
/// <param name="address">The starting register address.</param>
/// <param name="data">The read int array of data. The array length is
/// the amount of ints to read.</param>
public void Read(ushort address, int[] data)
{
if (data.Length > 63)
throw new Exception("Too many ints. The maximum is 63.");
byte[] bytes = new byte[data.Length * 4];
Read(address, bytes);
for (int i = 0; i < data.Length; i++)
{
if (BitConverter.IsLittleEndian)
Array.Reverse(bytes, i * 4, 4);
data[i] = BitConverter.ToInt32(bytes, i * 4);
}
}
/// <summary>
/// Write a float array of data to the Modbus device.
/// </summary>
/// <param name="address">The starting register address.</param>
/// <param name="data">The float array of data to write.</param>
public void Write(ushort address, float[] data)
{
if (data.Length > 63)
throw new Exception("Too many floats. The maximum is 63.");
byte[] bytes = new byte[data.Length * 4];
for (int i = 0; i < data.Length; i++)
{
BitConverter.GetBytes(data[i]).CopyTo(bytes, i * 4);
if (BitConverter.IsLittleEndian)
Array.Reverse(bytes, i * 4, 4);
}
Write(address, bytes);
}
/// <summary>
/// Reads a float array of data from the Modbus device.
/// </summary>
/// <param name="address">The starting register address.</param>
/// <param name="data">The read float array of data. The array length is
/// the amount of floats to read.</param>
public void Read(ushort address, float[] data)
{
if (data.Length > 63)
throw new Exception("Too many floats. The maximum is 63.");
byte[] bytes = new byte[data.Length * 4];
Read(address, bytes);
for (int i = 0; i < data.Length; i++)
{
if (BitConverter.IsLittleEndian)
Array.Reverse(bytes, i * 4, 4);
data[i] = BitConverter.ToSingle(bytes, i * 4);
}
}
/// <summary>
/// Write a single ushort of data to the Modbus device.
/// </summary>
/// <param name="address">The register address.</param>
/// <param name="data">The ushort data to write.</param>
public void Write(ushort address, ushort data)
{
ushort[] dataArray = new ushort[1];
dataArray[0] = data;
Write(address, dataArray);
}
/// <summary>
/// Read a single ushort of data from the Modbus device.
/// </summary>
/// <param name="address">The register address.</param>
/// <param name="data">The read ushort data.</param>
public void Read(ushort address, ref ushort data)
{
ushort[] dataArray = new ushort[1];
Read(address, dataArray);
data = dataArray[0];
}
/// <summary>
/// Write a single uint of data to the Modbus device.
/// </summary>
/// <param name="address">The starting register address.</param>
/// <param name="data">The uint data to write.</param>
public void Write(ushort address, uint data)
{
uint[] dataArray = new uint[1];
dataArray[0] = data;
Write(address, dataArray);
}
/// <summary>
/// Read a single uint of data from the Modbus device.
/// </summary>
/// <param name="address">The starting register address.</param>
/// <param name="value">The read uint data.</param>
public void Read(ushort address, ref uint data)
{
uint[] dataArray = new uint[1];
Read(address, dataArray);
data = dataArray[0];
}
/// <summary>
/// Write a single int of data to the Modbus device.
/// </summary>
/// <param name="address">The starting register address.</param>
/// <param name="data">The int data to write.</param>
public void Write(ushort address, int data)
{
int[] dataArray = new int[1];
dataArray[0] = data;
Write(address, dataArray);
}
/// <summary>
/// Read a single int of data from the Modbus device.
/// </summary>
/// <param name="address">The starting register address.</param>
/// <param name="data">The read int data.</param>
public void Read(ushort address, ref int data)
{
int[] dataArray = new int[1];
Read(address, dataArray);
data = dataArray[0];
}
/// <summary>
/// Write a single float of data to the Modbus device.
/// 1 uint = 2 registers.
/// </summary>
/// <param name="address">The starting register address.</param>
/// <param name="data">The float data to write.</param>
public void Write(ushort address, float data)
{
float[] dataArray = new float[1];
dataArray[0] = data;
Write(address, dataArray);
}
/// <summary>
/// Read a single float of data from the Modbus device.
/// </summary>
/// <param name="address">The starting register address.</param>
/// <param name="data">The read float data.</param>
public void Read(ushort address, ref float data)
{
float[] dataArray = new float[1];
Read(address, dataArray);
data = dataArray[0];
}
/// <summary>
/// Sets the MBAP header of the Modbus TCP command.
/// </summary>
/// <param name="command">The byte array for the Modbus TCP command.
/// The Modbus request bytes 7+ need to be set beforehand. The MBAP
/// header bytes 0 to 6 will be updated based on the request bytes.
/// </param>
private void SetHeader(byte[] command)
{
//Transaction ID
ushort transID = _TransactionID;
if (_TransactionID >= 65535)
{
//Rollover global transaction ID to 0.
_TransactionID = 0;
}
else
{
//Increment global transaction ID.
_TransactionID++;
}
command[0] = (byte)(transID >> 8);
command[1] = (byte)(transID & 0xFF);
//Protocol ID
command[2] = 0;
command[3] = 0;
//Length
ushort length = (ushort)(command.Length - 6);
command[4] = (byte)(length >> 8);
command[5] = (byte)(length & 0xFF);
//Unit ID
command[6] = 1;
}
/// <summary>
/// Checks the Modbus response for errors.
/// </summary>
/// <param name="response">The Modbus response byte array.</param>
/// <param name="expectedSize">The expected response byte array length.</param>
/// <param name="command">The Modbus command byte array.</param>
private void ResponseErrorChecks(byte[] response, int expectedLength, byte[] command)
{
if (response.Length < expectedLength)
{
if (response.Length < 9)
{
throw new Exception("Invalid Modbus response.");
}
if ((response[7] & 0x80) > 0)
{
//Bit 7 set, indicating Modbus error
throw new Exception("Modbus exception code " + response[8] +
", " + GetExceptionCodeString(response[8]) + ".");
}
throw new Exception("Other Modbus response error.");
}
if (response[0] != command[0] || response[1] != command[1])
{
throw new Exception("Modbus transaction ID mismatch.");
}
}
/// <summary>
/// Get the Modbus exception name.
/// </summary>
/// <param name="code">The exception code.</param>
/// <returns>The exception name.</returns>
private string GetExceptionCodeString(uint code) =>
code switch
{
1 => "Illegal Function",
2 => "Illegal Data Address",
3 => "Illegal Data Value",
4 => "Slave Device Failure",
5 => "Acknowledge",
6 => "Slave Device Busy",
7 => "Negative Acknowledge",
8 => "Memory Parity Error",
10 => "Gateway Path Unavailable",
11 => "Gateway Target Device Failed to Respond",
_ => ""
};
void IDisposable.Dispose() =>
Close();
}
internal static bool ReadAll(AppSettings appSettings, ILogger<Worker> logger)
{
LabJackT7Configuration configuration = appSettings.LabJackT7Configuration;
_ModbusTransmissionControlProtocolClient ??= new(configuration.InternetProtocolAddress, configuration.Port);
ReadAllAnalog(_ModbusTransmissionControlProtocolClient, logger);
ReadAllDigitalIO(_ModbusTransmissionControlProtocolClient, logger);
if (configuration.InternetProtocolAddress == "false")
ReadAllAnalogMux80(_ModbusTransmissionControlProtocolClient, logger);
return true;
}
/// <summary>
/// Displays "AINxx : Values" readings.
/// </summary>
/// <param name="startingAddress">Starting Modbus address of
/// readings.</param>
/// <param name="values">Float analog input (AIN) readings.</param>
private static void DisplayAnalogInputReadings(ILogger<Worker> logger, ushort startingAddress, float[] values)
{
for (int i = 0; i < values.Length; i++)
{
logger.LogInformation("AIN" + (startingAddress + i * 2) / 2 + " : " + values[i] + " V");
}
}
/// <summary>
/// Displays all digital I/O readings.
/// </summary>
/// <param name="directions">Reading from T7 Modbus address
/// 2850 (DIO_DIRECTION).</param>
/// <param name="states">Reading from T7 Modbus address
/// 2800 (DIO_STATE).</param>
private static void DisplayDigitalIOReadings(ILogger<Worker> logger, uint directions, uint states)
{
string fioDirs = "";
string fioStates = "";
string eioDirs = "";
string eioStates = "";
string cioDirs = "";
string cioStates = "";
string mioDirs = "";
string mioStates = "";
for (int i = 0; i < 8; i++)
{
fioDirs += Convert.ToString((directions >> i) & 1);
fioStates += Convert.ToString((states >> i) & 1);
}
logger.LogInformation("FIO0-FIO7 directions = " + fioDirs + ", states = " + fioStates);
for (int i = 8; i < 16; i++)
{
eioDirs += Convert.ToString((directions >> i) & 1);
eioStates += Convert.ToString((states >> i) & 1);
}
logger.LogInformation("EIO0-EIO7 directions = " + eioDirs + ", states = " + eioStates);
for (int i = 16; i < 20; i++)
{
cioDirs += Convert.ToString((directions >> i) & 1);
cioStates += Convert.ToString((states >> i) & 1);
}
logger.LogInformation("CIO0-CIO3 directions = " + cioDirs + ", states = " + cioStates);
for (int i = 20; i < 23; i++)
{
mioDirs += Convert.ToString((directions >> i) & 1);
mioStates += Convert.ToString((states >> i) & 1);
}
logger.LogInformation("MIO0-MIO2 directions = " + mioDirs + ", states = " + mioStates);
}
/// <summary>
/// Configures range, negative channel, resolution index and settling
/// time for all analog inputs.
/// AIN_ALL_RANGE, AIN_ALL_NEGATIVE_CH, AIN_ALL_RESOLUTION_INDEX, and
/// AIN_ALL_SETTLING_US registers/settings are documented here:
/// https://labjack.com/support/datasheets/t-series/ain
/// </summary>
/// <param name="mb">The ModbusTransmissionControlProtocolClient to the connected T7 </param>
/// <param name="range">AIN_ALL_RANGE setting.</param>
/// <param name="negativeChannel">AIN_ALL_NEGATIVE_CH setting.</param>
/// <param name="resolutionIndex">AIN_ALL_RESOLUTION_INDEX setting.</param>
/// <param name="settling">AIN_ALL_SETTLING_US setting.</param>
private static void ConfigureAllAnalog(ModbusTransmissionControlProtocolClient mb, float range, ushort negativeChannel, ushort resolutionIndex, float settling)
{
ushort address;
ushort uint16Value;
float float32Value;
// Configure all analog input ranges.
address = 43900; // 43900 = AIN_ALL_RANGE
float32Value = range;
mb.Write(address, float32Value);
// Configure all analog input negative channels.
address = 43902; // 43902 = AIN_ALL_NEGATIVE_CH
uint16Value = negativeChannel;
mb.Write(address, uint16Value);
// Configure all analog input resolution indexes.
address = 43903; // 43903 = AIN_ALL_RESOLUTION_INDEX
uint16Value = resolutionIndex;
mb.Write(address, uint16Value);
// Configure all analog input settling times.
address = 43904; // 43904 = AIN_ALL_SETTLING_US
float32Value = settling;
mb.Write(address, float32Value);
}
/// <summary>
/// Example that configures, reads and displays all the analog
/// inputs (AIN0-AIN13) on the T7.
/// Analog inputs (AIN) registers used are documented here:
/// https://labjack.com/support/datasheets/t-series/ain
/// </summary>
/// <param name="mb">The ModbusTransmissionControlProtocolClient to the connected T7.</param>
private static void ReadAllAnalog(ModbusTransmissionControlProtocolClient modbusTransmissionControlProtocolClient, ILogger<Worker> logger)
{
logger.LogInformation("Reading AIN0-AIN13.");
// Configure all analog inputs.
// Ranges = +/-10 to.
// Negative Channels = 199 (single-ended)
// Resolution Indexes = 8
// Settlings = 0 (auto)
ConfigureAllAnalog(modbusTransmissionControlProtocolClient, 10.0f, 199, 8, 0);
// Read all 14 analog inputs.
ushort startAddress = 0; // 0 = AIN0
float[] analogInputReadings = new float[14]; // 14 analog input readings
modbusTransmissionControlProtocolClient.Read(startAddress, analogInputReadings);
DisplayAnalogInputReadings(logger, startAddress, analogInputReadings);
logger.LogInformation("");
}
/// <summary>
/// Example that reads and displays all the digital I/O (FIOs, EIOs,
/// CIOs, MIOs) on the T7.
/// Digital I/O registers used are documented here:
/// https://labjack.com/support/datasheets/t-series/digital-io
/// </summary>
/// <param name="modbusTransmissionControlProtocolClient">The ModbusTransmissionControlProtocolClient to the connected T7.</param>
private static void ReadAllDigitalIO(ModbusTransmissionControlProtocolClient modbusTransmissionControlProtocolClient, ILogger<Worker> logger)
{
logger.LogInformation("Reading FIOs, EIOs, CIOs and MIO directions and states.");
ushort address;
uint directions = 0;
uint states = 0;
// Read all digital I/O directions and states.
address = 2850; // 2850 = DIO_DIRECTION
modbusTransmissionControlProtocolClient.Read(address, ref directions);
address = 2800; // 2800 = DIO_STATE
modbusTransmissionControlProtocolClient.Read(address, ref states);
DisplayDigitalIOReadings(logger, directions, states);
logger.LogInformation("");
}
/// <summary>
/// Example that configures, reads and displays all the analog
/// inputs on the T7 with a Mux80 (AIN0-AIN3, AIN48-AIN127).
/// Analog inputs (AIN) registers used are documented here:
/// https://labjack.com/support/datasheets/t-series/ain
/// Extended channels AIN48+ are further documented here:
/// https://labjack.com/support/datasheets/t-series/ain/extended-channels
/// Mux80 data sheet can be found here:
/// https://labjack.com/support/datasheets/accessories/mux80
/// </summary>
/// <param name="modbusTransmissionControlProtocolClient">The ModbusTransmissionControlProtocolClient to the connected T7.</param>
private static void ReadAllAnalogMux80(ModbusTransmissionControlProtocolClient modbusTransmissionControlProtocolClient, ILogger<Worker> logger)
{
// Many registers to channels are incorrect. Check with Steve.
logger.LogInformation("Reading AIN0-AIN3, AIN48-AIN127.");
// Configure all analog inputs.
// Ranges = +/-10 to.
// Negative Channels = 199 (single-ended)
// Resolution Indexes = 1
// Settlings = 0 (auto)
ConfigureAllAnalog(modbusTransmissionControlProtocolClient, 10.0f, 199, 1, 0);
//Reading from 84 analog inputs with the Mux80.
ushort startAddress;
float[] analogInputReadings;
// Read from AIN0-AIN3 on the T7 terminals.
startAddress = 0; // 0 = AIN0
analogInputReadings = new float[4]; // 4 analog input readings.
modbusTransmissionControlProtocolClient.Read(startAddress, analogInputReadings);
DisplayAnalogInputReadings(logger, startAddress, analogInputReadings);
// Read from AIN48-AIN87 on Mux80.
startAddress = 96; // 96 = AIN48
analogInputReadings = new float[40]; // 40 analog input readings
modbusTransmissionControlProtocolClient.Read(startAddress, analogInputReadings);
DisplayAnalogInputReadings(logger, startAddress, analogInputReadings);
// Read from AIN88-AIN127 on Mux80.
startAddress = 176; // 176 = AIN88
analogInputReadings = new float[40]; // 40 analog input readings
modbusTransmissionControlProtocolClient.Read(startAddress, analogInputReadings);
DisplayAnalogInputReadings(logger, startAddress, analogInputReadings);
logger.LogInformation("");
}
}

View File

@ -13,7 +13,9 @@ public record AppSettings(CamstarOracleConfiguration CamstarOracleConfiguration,
EDADatabaseConfiguration EDADatabaseConfiguration, EDADatabaseConfiguration EDADatabaseConfiguration,
FileWatcherConfiguration FileWatcherConfiguration, FileWatcherConfiguration FileWatcherConfiguration,
InfinityQSConfiguration InfinityQSConfiguration, InfinityQSConfiguration InfinityQSConfiguration,
InfinityQSProjectConfiguration InfinityQSProjectConfiguration,
IsoConfiguration IsoConfiguration, IsoConfiguration IsoConfiguration,
LabJackT7Configuration LabJackT7Configuration,
MetadataSettings MetadataSettings, MetadataSettings MetadataSettings,
MetrologyConfiguration MetrologyConfiguration, MetrologyConfiguration MetrologyConfiguration,
NationalInstrumentsConfiguration NationalInstrumentsConfiguration, NationalInstrumentsConfiguration NationalInstrumentsConfiguration,
@ -33,14 +35,16 @@ public record AppSettings(CamstarOracleConfiguration CamstarOracleConfiguration,
#pragma warning disable IL3050, IL2026 #pragma warning disable IL3050, IL2026
CamstarOracleConfiguration? camstarOracleConfiguration = configurationRoot.GetSection(nameof(CamstarOracleConfiguration)).Get<CamstarOracleConfiguration>(); CamstarOracleConfiguration? camstarOracleConfiguration = configurationRoot.GetSection(nameof(CamstarOracleConfiguration)).Get<CamstarOracleConfiguration>();
CompassConfiguration? compassConfiguration = configurationRoot.GetSection(nameof(CompassConfiguration)).Get<CompassConfiguration>(); CompassConfiguration? compassConfiguration = configurationRoot.GetSection(nameof(CompassConfiguration)).Get<CompassConfiguration>();
DiskInfoConfiguration? diskInfoConfiguration = configurationRoot.GetSection(nameof(DiskInfoConfiguration)).Get<DiskInfoConfiguration>();
DeterministicHashCodeConfiguration? deterministicHashCodeConfiguration = configurationRoot.GetSection(nameof(DeterministicHashCodeConfiguration)).Get<DeterministicHashCodeConfiguration>(); DeterministicHashCodeConfiguration? deterministicHashCodeConfiguration = configurationRoot.GetSection(nameof(DeterministicHashCodeConfiguration)).Get<DeterministicHashCodeConfiguration>();
DiskInfoConfiguration? diskInfoConfiguration = configurationRoot.GetSection(nameof(DiskInfoConfiguration)).Get<DiskInfoConfiguration>();
DriveConfiguration? driveConfiguration = configurationRoot.GetSection(nameof(DriveConfiguration)).Get<DriveConfiguration>(); DriveConfiguration? driveConfiguration = configurationRoot.GetSection(nameof(DriveConfiguration)).Get<DriveConfiguration>();
EAFLogConfiguration? eafLogConfiguration = configurationRoot.GetSection(nameof(EAFLogConfiguration)).Get<EAFLogConfiguration>(); EAFLogConfiguration? eafLogConfiguration = configurationRoot.GetSection(nameof(EAFLogConfiguration)).Get<EAFLogConfiguration>();
EDADatabaseConfiguration? edaDatabaseConfiguration = configurationRoot.GetSection(nameof(EDADatabaseConfiguration)).Get<EDADatabaseConfiguration>(); EDADatabaseConfiguration? edaDatabaseConfiguration = configurationRoot.GetSection(nameof(EDADatabaseConfiguration)).Get<EDADatabaseConfiguration>();
FileWatcherConfiguration? fileWatcherConfiguration = configurationRoot.GetSection(nameof(FileWatcherConfiguration)).Get<FileWatcherConfiguration>(); FileWatcherConfiguration? fileWatcherConfiguration = configurationRoot.GetSection(nameof(FileWatcherConfiguration)).Get<FileWatcherConfiguration>();
InfinityQSConfiguration? infinityQSConfiguration = configurationRoot.GetSection(nameof(InfinityQSConfiguration)).Get<InfinityQSConfiguration>(); InfinityQSConfiguration? infinityQSConfiguration = configurationRoot.GetSection(nameof(InfinityQSConfiguration)).Get<InfinityQSConfiguration>();
InfinityQSProjectConfiguration? infinityQSProjectConfiguration = configurationRoot.GetSection(nameof(InfinityQSProjectConfiguration)).Get<InfinityQSProjectConfiguration>();
IsoConfiguration? isoConfiguration = configurationRoot.GetSection(nameof(IsoConfiguration)).Get<IsoConfiguration>(); IsoConfiguration? isoConfiguration = configurationRoot.GetSection(nameof(IsoConfiguration)).Get<IsoConfiguration>();
LabJackT7Configuration? labJackT7Configuration = configurationRoot.GetSection(nameof(LabJackT7Configuration)).Get<LabJackT7Configuration>();
MetadataSettings? metadataSettings = configurationRoot.GetSection(nameof(MetadataSettings)).Get<MetadataSettings>(); MetadataSettings? metadataSettings = configurationRoot.GetSection(nameof(MetadataSettings)).Get<MetadataSettings>();
MetrologyConfiguration? metrologyConfiguration = configurationRoot.GetSection(nameof(MetrologyConfiguration)).Get<MetrologyConfiguration>(); MetrologyConfiguration? metrologyConfiguration = configurationRoot.GetSection(nameof(MetrologyConfiguration)).Get<MetrologyConfiguration>();
NationalInstrumentsConfiguration? nationalInstrumentsConfiguration = configurationRoot.GetSection(nameof(NationalInstrumentsConfiguration)).Get<NationalInstrumentsConfiguration>(); NationalInstrumentsConfiguration? nationalInstrumentsConfiguration = configurationRoot.GetSection(nameof(NationalInstrumentsConfiguration)).Get<NationalInstrumentsConfiguration>();
@ -62,7 +66,9 @@ public record AppSettings(CamstarOracleConfiguration CamstarOracleConfiguration,
|| edaDatabaseConfiguration is null || edaDatabaseConfiguration is null
|| fileWatcherConfiguration is null || fileWatcherConfiguration is null
|| infinityQSConfiguration is null || infinityQSConfiguration is null
|| infinityQSProjectConfiguration is null
|| isoConfiguration is null || isoConfiguration is null
|| labJackT7Configuration is null
|| metadataSettings is null || metadataSettings is null
|| metrologyConfiguration is null || metrologyConfiguration is null
|| nationalInstrumentsConfiguration is null || nationalInstrumentsConfiguration is null
@ -96,7 +102,9 @@ public record AppSettings(CamstarOracleConfiguration CamstarOracleConfiguration,
edaDatabaseConfiguration, edaDatabaseConfiguration,
fileWatcherConfiguration, fileWatcherConfiguration,
infinityQSConfiguration, infinityQSConfiguration,
infinityQSProjectConfiguration,
isoConfiguration, isoConfiguration,
labJackT7Configuration,
metadataSettings, metadataSettings,
metrologyConfiguration, metrologyConfiguration,
nationalInstrumentsConfiguration, nationalInstrumentsConfiguration,

View File

@ -0,0 +1,28 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace File_Watcher.Models;
public record InfinityQSProjectConfiguration(string From,
int ClearEveryHours,
string Search,
string SearchPattern,
string SimpleMailTransferProtocolServer,
string SourceDirectory,
string Subject,
string To)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, InfinityQSProjectConfigurationSourceGenerationContext.Default.InfinityQSProjectConfiguration);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(InfinityQSProjectConfiguration))]
internal partial class InfinityQSProjectConfigurationSourceGenerationContext : JsonSerializerContext
{
}

View File

@ -0,0 +1,23 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace File_Watcher.Models;
public record LabJackT7Configuration(string InternetProtocolAddress,
int Port,
string To)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, LabJackT7ConfigurationSourceGenerationContext.Default.LabJackT7Configuration);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(LabJackT7Configuration))]
internal partial class LabJackT7ConfigurationSourceGenerationContext : JsonSerializerContext
{
}

View File

@ -46,6 +46,7 @@ public partial class Worker : BackgroundService
if (!_IsWindowsService) if (!_IsWindowsService)
{ {
_Logger.LogInformation("Set break point and skip to run {_AppSettings.FileWatcherConfiguration.Helper}!", _AppSettings.FileWatcherConfiguration.Helper); _Logger.LogInformation("Set break point and skip to run {_AppSettings.FileWatcherConfiguration.Helper}!", _AppSettings.FileWatcherConfiguration.Helper);
BodyInner(cancellationToken);
throw new EvaluateException($"Set break point and skip to run {_AppSettings.FileWatcherConfiguration.Helper}!"); throw new EvaluateException($"Set break point and skip to run {_AppSettings.FileWatcherConfiguration.Helper}!");
} }
if (!_IsWindowsService) if (!_IsWindowsService)
@ -83,12 +84,14 @@ public partial class Worker : BackgroundService
nameof(Helpers.HelperCompass) => Helpers.HelperCompass.CopyFile(_AppSettings, _Logger), nameof(Helpers.HelperCompass) => Helpers.HelperCompass.CopyFile(_AppSettings, _Logger),
nameof(Helpers.HelperStratus) => Helpers.HelperStratus.MoveFile(_AppSettings, _Logger), nameof(Helpers.HelperStratus) => Helpers.HelperStratus.MoveFile(_AppSettings, _Logger),
nameof(Helpers.HelperEAFLog) => Helpers.HelperEAFLog.DeleteFiles(_AppSettings, _Logger), nameof(Helpers.HelperEAFLog) => Helpers.HelperEAFLog.DeleteFiles(_AppSettings, _Logger),
nameof(Helpers.LabJackT7Helper) => Helpers.LabJackT7Helper.ReadAll(_AppSettings, _Logger),
nameof(Helpers.DiskInfoHelper) => Helpers.DiskInfoHelper.WriteDiskInfo(_AppSettings, _Logger), nameof(Helpers.DiskInfoHelper) => Helpers.DiskInfoHelper.WriteDiskInfo(_AppSettings, _Logger),
nameof(Helpers.HelperEventLog) => Helpers.HelperEventLog.ClearEventLogs(_AppSettings, _Logger), nameof(Helpers.HelperEventLog) => Helpers.HelperEventLog.ClearEventLogs(_AppSettings, _Logger),
nameof(Helpers.HelperInfinityQS) => Helpers.HelperInfinityQS.ProcessStart(_AppSettings, _Logger), nameof(Helpers.HelperInfinityQS) => Helpers.HelperInfinityQS.ProcessStart(_AppSettings, _Logger),
nameof(Helpers.HelperWaferCounter) => Helpers.HelperWaferCounter.MoveFile(_AppSettings, _Logger), nameof(Helpers.HelperWaferCounter) => Helpers.HelperWaferCounter.MoveFile(_AppSettings, _Logger),
nameof(Helpers.HelperSerial) => Helpers.HelperSerial.ReadWrite(_AppSettings, _Logger, cancellationToken), nameof(Helpers.HelperSerial) => Helpers.HelperSerial.ReadWrite(_AppSettings, _Logger, cancellationToken),
nameof(Helpers.HelperMetrologyFiles) => Helpers.HelperMetrologyFiles.SortAndDelete(_AppSettings, _Logger), nameof(Helpers.HelperMetrologyFiles) => Helpers.HelperMetrologyFiles.SortAndDelete(_AppSettings, _Logger),
nameof(Helpers.InfinityQSProjectHelper) => Helpers.InfinityQSProjectHelper.SendEmail(_AppSettings, _Logger),
nameof(Helpers.NationalInstrumentsHelper) => Helpers.NationalInstrumentsHelper.WriteData(_AppSettings, _Logger), nameof(Helpers.NationalInstrumentsHelper) => Helpers.NationalInstrumentsHelper.WriteData(_AppSettings, _Logger),
nameof(Helpers.DeterministicHashCodeHelper) => Helpers.DeterministicHashCodeHelper.WindowsWork(_AppSettings, _Logger), nameof(Helpers.DeterministicHashCodeHelper) => Helpers.DeterministicHashCodeHelper.WindowsWork(_AppSettings, _Logger),
nameof(Helpers.TransmissionControlProtocolHelper) => Helpers.TransmissionControlProtocolHelper.ReadWrite(_AppSettings, _Logger), nameof(Helpers.TransmissionControlProtocolHelper) => Helpers.TransmissionControlProtocolHelper.ReadWrite(_AppSettings, _Logger),