179 lines
5.6 KiB
C#
179 lines
5.6 KiB
C#
|
namespace InnovEnergy.Lib.Devices.BatteryDeligreen;
|
||
|
|
||
|
using System;
|
||
|
using System.IO.Ports;
|
||
|
|
||
|
|
||
|
public class BatteryDeligreenDevice
|
||
|
{
|
||
|
private const Parity Parity = System.IO.Ports.Parity.None;
|
||
|
private const StopBits StopBits = System.IO.Ports.StopBits.One;
|
||
|
private const Int32 BaudRate = 19200;
|
||
|
private const Int32 DataBits = 8;
|
||
|
|
||
|
private readonly SerialPort _serialPort;
|
||
|
|
||
|
// Constructor for local serial port connection
|
||
|
public BatteryDeligreenDevice(String tty)
|
||
|
{
|
||
|
_serialPort = new SerialPort(tty, BaudRate, Parity, DataBits, StopBits)
|
||
|
{
|
||
|
ReadTimeout = 1000, // 1 second timeout for reads
|
||
|
WriteTimeout = 1000 // 1 second timeout for writes
|
||
|
};
|
||
|
|
||
|
try
|
||
|
{
|
||
|
// Open the serial port
|
||
|
_serialPort.Open();
|
||
|
Console.WriteLine("Serial port opened successfully.");
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
Console.WriteLine(e);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
// Method to send data to the device
|
||
|
private void Write(String hexCommand)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
// Convert hex string to byte array
|
||
|
byte[] commandBytes = HexStringToByteArray(hexCommand);
|
||
|
|
||
|
// Send the command
|
||
|
_serialPort.Write(commandBytes, 0, commandBytes.Length);
|
||
|
Console.WriteLine("Command sent successfully.");
|
||
|
}
|
||
|
catch (TimeoutException)
|
||
|
{
|
||
|
Console.WriteLine("Write operation timed out.");
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
Console.WriteLine($"Error during write operation: {e.Message}");
|
||
|
throw;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Method to read data from the device
|
||
|
private Byte[] Read(Int32 bufferSize)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
// Read data from the serial port
|
||
|
var buffer = new Byte[bufferSize];
|
||
|
var bytesRead = _serialPort.Read(buffer, 0, bufferSize);
|
||
|
|
||
|
Console.WriteLine($"Read {bytesRead} bytes from the device.");
|
||
|
|
||
|
// Return only the received bytes
|
||
|
var responseData = new Byte[bytesRead];
|
||
|
Array.Copy(buffer, responseData, bytesRead);
|
||
|
return responseData;
|
||
|
}
|
||
|
catch (TimeoutException)
|
||
|
{
|
||
|
Console.WriteLine("Read operation timed out.");
|
||
|
return Array.Empty<Byte>(); // Return empty array on timeout
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
Console.WriteLine($"Error during read operation: {e.Message}");
|
||
|
throw;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static String BytesToHexString(byte[] byteArray)
|
||
|
{
|
||
|
return BitConverter.ToString(byteArray).Replace("-", "").ToUpper();
|
||
|
}
|
||
|
|
||
|
// Helper method to convert a hex string to a byte array
|
||
|
private static Byte[] HexStringToByteArray(string hex)
|
||
|
{
|
||
|
if (string.IsNullOrWhiteSpace(hex) || hex.Length % 2 != 0)
|
||
|
throw new ArgumentException("Invalid hex string.");
|
||
|
|
||
|
byte[] bytes = new byte[hex.Length / 2];
|
||
|
for (var i = 0; i < hex.Length; i += 2)
|
||
|
{
|
||
|
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
|
||
|
}
|
||
|
return bytes;
|
||
|
}
|
||
|
|
||
|
// Dispose method to release the serial port
|
||
|
public void Dispose()
|
||
|
{
|
||
|
if (_serialPort.IsOpen)
|
||
|
{
|
||
|
_serialPort.Close();
|
||
|
Console.WriteLine("Serial port closed.");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Read telemetry data from the connected device
|
||
|
public async Task<Byte[]> ReadTelemetryData()
|
||
|
{
|
||
|
const String frameToSend = "7E3230303034363432453030323030464433370D"; // Example custom frame
|
||
|
|
||
|
try
|
||
|
{
|
||
|
// Write the frame to the channel (send it to the device)
|
||
|
await Task.Run(() => Write(frameToSend));
|
||
|
|
||
|
// Read the response from the channel (assuming max response size)
|
||
|
var responseBytes = await Task.Run(() => Read(1024)); // Assuming Read can be executed asynchronously
|
||
|
|
||
|
// Convert the byte array to a hexadecimal string
|
||
|
var responseHex = BytesToHexString(responseBytes);
|
||
|
|
||
|
new TelemetryFrameParser().ParsingTelemetryFrame(responseHex);
|
||
|
|
||
|
// Parse the ASCII response (you can implement any custom parsing logic)
|
||
|
var responseData = ParseAsciiResponse(responseBytes.ToArray());
|
||
|
|
||
|
return responseData;
|
||
|
}
|
||
|
catch (Exception ex)
|
||
|
{
|
||
|
Console.WriteLine($"Error during telemetry data retrieval: {ex.Message}");
|
||
|
throw;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public Byte[] ReadTelecomandData()
|
||
|
{
|
||
|
const String frameToSend = "7E3230303034363434453030323030464433350D"; // Example custom frame
|
||
|
|
||
|
// Write the frame to the channel (send it to the device)
|
||
|
Write(frameToSend);
|
||
|
|
||
|
// Read the response from the channel (assuming max response size)
|
||
|
var responseBytes = Read(1024); // Adjust this size if needed
|
||
|
|
||
|
// Parse the ASCII response (you can implement any custom parsing logic)
|
||
|
var responseData = ParseAsciiResponse(responseBytes.ToArray());
|
||
|
|
||
|
return responseData;
|
||
|
}
|
||
|
|
||
|
// Helper method to parse the ASCII response (you can add any parsing logic here)
|
||
|
private static byte[] ParseAsciiResponse(byte[] responseBytes)
|
||
|
{
|
||
|
Console.WriteLine($"Last Timestamp: {DateTime.Now:HH:mm:ss.fff}");
|
||
|
// Convert the byte array to a hex string for display
|
||
|
var hexResponse = BitConverter.ToString(responseBytes).Replace("-", " ");
|
||
|
//Console.WriteLine($"Response (Hex): {hexResponse}");
|
||
|
// Implement custom parsing logic if necessary based on the protocol's frame
|
||
|
// For now, we return the raw response bytes
|
||
|
return responseBytes;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|