Skip to content

Commit

Permalink
Merge pull request #14 from feydelight/feature/5-request-move-serial-…
Browse files Browse the repository at this point in the history
…message-management-to-serialportmanager-instead-of-allowing-each-button-to-connect-to-the-serial-output

Feature/5 request move serial message management to serialportmanager instead of allowing each button to connect to the serial output
  • Loading branch information
asaravi committed May 2, 2023
2 parents 47afa8d + 86734e4 commit 4c85ab5
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 61 deletions.
51 changes: 12 additions & 39 deletions FeyDelight.SerialIRBlaster/Actions/DecodeCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,52 +40,39 @@ public DecodeCommand(SDConnection connection, InitialPayload payload)
base.TryToGetPort();
}

DateTimeOffset endOfChecking { get; set; }
bool removeTrigger = false;
DateTimeOffset EndOfChecking { get; set; }

public async override void KeyPressed(KeyPayload payload)
{
Logger.Instance.LogMessage(TracingLevel.INFO, $"{this.GetType()} {nameof(KeyPressed)}");
var serialPort = Program.SerialPortManager.GetSerialPort(Settings);
var serialPort = Program.SerialPortManager.GetSerialPort(Settings, SerialPort_DataReceived);
if (serialPort == null)
{
Logger.Instance.LogMessage(TracingLevel.INFO, $"Failed to get the serial port");
await Connection.ShowAlert();
return;
}


SettingsSerialMessage message = new SettingsSerialMessage(true, false, true);
Logger.Instance.LogMessage(TracingLevel.INFO, $"Sending: {message}");
serialPort.DataReceived += SerialPort_DataReceived;
serialPort.Write(message.GetPayload());
endOfChecking = DateTimeOffset.Now.AddSeconds(decodeTime);
removeTrigger = true;
Logger.Instance.LogMessage(TracingLevel.INFO, $"Checking for decoded messages till {endOfChecking}. Currently {DateTimeOffset.Now}");
EndOfChecking = DateTimeOffset.Now.AddSeconds(decodeTime);
Logger.Instance.LogMessage(TracingLevel.INFO, $"Checking for decoded messages till {EndOfChecking}. Currently {DateTimeOffset.Now}");
await Connection.ShowOk();
}

public override void KeyReleased(KeyPayload payload)
{
}

private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
protected override void SerialPort_DataReceived(SerialPort sender, string line)
{
SerialPort sp = (SerialPort)sender;
try
{
string indata = sp.ReadLine().Trim();
Logger.Instance.LogMessage(TracingLevel.INFO, $"[Decoder] Serial replied: {indata}");
if (DateTimeOffset.Now < endOfChecking)
{
TryParseReturnData(indata);
}
}
catch (Exception)
base.SerialPort_DataReceived(sender, line);
if (DateTimeOffset.Now < EndOfChecking)
{
// either timed out, or the port got closed. either way, no biggy.
return;
TryParseReturnData(line);
}
}

private void TryParseReturnData(string line)
{
/*
Expand Down Expand Up @@ -114,8 +101,8 @@ private async void DrawText(string protocol, string address, string command)
{
const int STARTING_TEXT_Y = 3;
const int BUFFER_Y = 16;
address = $"Addr: {address}";
command = $"Cmd: {command}";
address = $"Addr: {address} ";
command = $"Cmd: {command} ";
try
{
using (Bitmap bmp = Tools.GenerateGenericKeyImage(out Graphics graphics))
Expand Down Expand Up @@ -156,26 +143,12 @@ private async void DrawText(string protocol, string address, string command)

public override void OnTick()
{
if (removeTrigger && DateTimeOffset.Now > endOfChecking)
{
removeTrigger = false;
var serialPort = Program.SerialPortManager.GetSerialPort(Settings);
if (serialPort != null)
{
serialPort.DataReceived -= SerialPort_DataReceived;
}
}
}

public override void Dispose()
{
base.Dispose();
Logger.Instance.LogMessage(TracingLevel.INFO, "Destructor called");
var serialPort = Program.SerialPortManager.GetSerialPort(Settings);
if (serialPort != null)
{
serialPort.DataReceived -= SerialPort_DataReceived;
}
Program.SerialPortManager.CloseSerialPort(Settings);
}

Expand Down
3 changes: 1 addition & 2 deletions FeyDelight.SerialIRBlaster/Actions/MultiIRCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public MultiIRCommand(SDConnection connection, InitialPayload payload)
public override async void KeyPressed(KeyPayload payload)
{
Logger.Instance.LogMessage(TracingLevel.INFO, $"{this.GetType()} {nameof(KeyPressed)}");
var serialPort = Program.SerialPortManager.GetSerialPort(Settings);
var serialPort = Program.SerialPortManager.GetSerialPort(Settings, SerialPort_DataReceived);
if (serialPort == null)
{
await Connection.ShowAlert();
Expand Down Expand Up @@ -82,7 +82,6 @@ public override void KeyReleased(KeyPayload payload)
}



public override void OnTick()
{

Expand Down
23 changes: 12 additions & 11 deletions FeyDelight.SerialIRBlaster/Actions/SerialIRBlasterBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,31 +68,24 @@ public override void ReceivedSettings(ReceivedSettingsPayload payload)

public async override void ReceivedGlobalSettings(ReceivedGlobalSettingsPayload payload)
{
Logger.Instance.LogMessage(TracingLevel.INFO, $"{this.GetType()}.{nameof(ReceivedGlobalSettings)}");
// existing settings
if (payload?.Settings != null && payload.Settings.Count > 0)
{
Logger.Instance.LogMessage(TracingLevel.INFO, $"previous setting available, retrieving...");
globalSettings = payload.Settings.ToObject<GlobalSettings>();
if (globalSettings.SerialPortSettings == null)
{
globalSettings.SerialPortSettings = new Dictionary<string, SerialPortSettings>();
}
Logger.Instance.LogMessage(TracingLevel.INFO, $"retrieved.");
}
else
{
Logger.Instance.LogMessage(TracingLevel.INFO, $"no settings available, creating one...");
globalSettings = new GlobalSettings()
{
SerialPortSettings = new Dictionary<string, SerialPortSettings>(),
};
await SetGlobalSettings();
Logger.Instance.LogMessage(TracingLevel.INFO, $"done.");
}


Logger.Instance.LogMessage(TracingLevel.INFO, $"creating all sockets");
if (globalSettings.SerialPortSettings.Count > 0)
{
foreach (var setting in globalSettings.SerialPortSettings)
Expand All @@ -101,8 +94,6 @@ public async override void ReceivedGlobalSettings(ReceivedGlobalSettingsPayload
}
}

Logger.Instance.LogMessage(TracingLevel.INFO, $"done.");

Settings.Serials = this.GetSerialPortSettingsList();
await SaveSettings();
}
Expand Down Expand Up @@ -175,6 +166,16 @@ public override void Dispose()
Connection.OnSendToPlugin -= Connection_OnSendToPlugin;
}


protected virtual void SerialPort_DataReceived(SerialPort sender, string line)
{
if (string.IsNullOrEmpty(line))
{
return;
}
// do a sanity check to see if its finished
}

private Task SetGlobalSettings()
{

Expand All @@ -188,8 +189,8 @@ private Task SetGlobalSettings()
int triedToGetPort = 0;
protected async void TryToGetPort()
{
await Task.Delay(500);
var port = Program.SerialPortManager.GetSerialPort(Settings);
await Task.Delay(1000);
var port = Program.SerialPortManager.GetSerialPort(Settings, SerialPort_DataReceived);
if (port == null && triedToGetPort < 10)
{
++triedToGetPort;
Expand Down
3 changes: 1 addition & 2 deletions FeyDelight.SerialIRBlaster/Actions/SingleIRCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public SingleIRCommand(SDConnection connection, InitialPayload payload)
public async override void KeyPressed(KeyPayload payload)
{
Logger.Instance.LogMessage(TracingLevel.INFO, $"{this.GetType()} {nameof(KeyPressed)}");
var serialPort = Program.SerialPortManager.GetSerialPort(Settings);
var serialPort = Program.SerialPortManager.GetSerialPort(Settings, SerialPort_DataReceived);
if (serialPort == null)
{
await Connection.ShowAlert();
Expand Down Expand Up @@ -68,7 +68,6 @@ public override void KeyReleased(KeyPayload payload)
{
}


public override void OnTick()
{

Expand Down
7 changes: 5 additions & 2 deletions FeyDelight.SerialIRBlaster/Common/ISerialPortManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@

namespace FeyDelight.SerialIRBlaster.Common
{
public delegate void ReplyDelegate(SerialPort Sender, string Line);
internal interface ISerialPortManager
{

/// <summary>
/// Closes all serial ports. Continues to keep record of the settings for future use
/// </summary>
Expand All @@ -14,9 +16,10 @@ internal interface ISerialPortManager
/// Retrieves a serial port. If the port is not yet opened, it will attempt to open it.
/// </summary>
/// <param name="Requester"></param>
/// <param name="replyDelegate">Event that you can subscribe to </param>
/// <returns>Returns null if the port failed to open</returns>
SerialPort GetSerialPort(ISerialPortRequester Requester);
SerialPort GetSerialPort(ISerialPortRequester requester, ReplyDelegate replyDelegate);

/// <summary>
/// Closes a serial port. Continues to keep record of the settings for future use
/// </summary>
Expand Down
50 changes: 45 additions & 5 deletions FeyDelight.SerialIRBlaster/Common/SerialPortManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ internal class SerialPortManager : ISerialPortManager
private class SerialPortCache
{
public SerialPort SerialPort { get; set; }
public HashSet<Guid> ConnectedActions { get; set; }
public Dictionary<Guid, ReplyDelegate> ConnectedActions { get; set; }
public ISerialPortSettings SerialPortSettings { get; set; }
}

Expand Down Expand Up @@ -53,7 +53,7 @@ public bool AddSerialPort(ISerialPortSettings settings)
{
PortCaches.Add(key, new SerialPortCache
{
ConnectedActions = new HashSet<Guid>(),
ConnectedActions = new Dictionary<Guid, ReplyDelegate>(),
SerialPort = null,
SerialPortSettings = settings
});
Expand Down Expand Up @@ -82,7 +82,7 @@ public void RemoveSerialPort(string key)
}
}

public SerialPort GetSerialPort(ISerialPortRequester requester)
public SerialPort GetSerialPort(ISerialPortRequester requester, ReplyDelegate replyDelegate)
{
var key = requester.Key;
if (string.IsNullOrEmpty(key))
Expand All @@ -96,6 +96,7 @@ public SerialPort GetSerialPort(ISerialPortRequester requester)
}
lock (dictLock)
{
Logger.Instance.LogMessage(TracingLevel.INFO, $"ID {requester.ID} requesting port: {key}");
if (PortCaches.TryGetValue(key, out var portCache) == false)
{
Logger.Instance.LogMessage(TracingLevel.INFO, $"Requesting port that doesn't exist or has been deleted {requester.ID}");
Expand All @@ -116,15 +117,18 @@ public SerialPort GetSerialPort(ISerialPortRequester requester)
return null;
}
}
portCache.ConnectedActions.Add(requester.ID);
portCache.ConnectedActions[requester.ID] = replyDelegate;

if (portCache.SerialPort.IsOpen == false)
{
try
{
Logger.Instance.LogMessage(TracingLevel.INFO, $"Adding DataReceived hook to {portCache.SerialPort.PortName}...");
portCache.SerialPort.DataReceived += SerialPort_DataReceived;
Logger.Instance.LogMessage(TracingLevel.INFO, $"Successfully added hook to {portCache.SerialPort.PortName}.");
Logger.Instance.LogMessage(TracingLevel.INFO, $"Opening port {portCache.SerialPort.PortName}...");
portCache.SerialPort.Open();
Logger.Instance.LogMessage(TracingLevel.INFO, $"Port {portCache.SerialPort.PortName} opened.");
Logger.Instance.LogMessage(TracingLevel.INFO, $"Port {portCache.SerialPort.PortName} opened.");
}
catch (Exception e)
{
Expand All @@ -135,6 +139,42 @@ public SerialPort GetSerialPort(ISerialPortRequester requester)
return portCache.SerialPort;
}
}
private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
try
{
string indata = sp.ReadLine().Trim();
if (string.IsNullOrEmpty(indata))
{
return;
}
lock(dictLock)
{
string key = sp.PortName;
if (PortCaches.TryGetValue(key, out var portCache) == false)
{
Logger.Instance.LogMessage(TracingLevel.INFO, $"Port {key} sent messages after it was asked to be closed.");
return;
}
//Logger.Instance.LogMessage(TracingLevel.INFO, $"Serial replied: '{indata}'");
foreach(var action in portCache.ConnectedActions)
{
if (action.Value == null)
{
continue;
}
//Logger.Instance.LogMessage(TracingLevel.INFO, $"Sending it to: {action.Key}");
action.Value.Invoke(sp, indata);
}
}
}
catch (Exception)
{
// either timed out, or the port got closed. either way, no biggy.
return;
}
}


public void CloseSerialPort(ISerialPortRequester requester)
Expand Down

0 comments on commit 4c85ab5

Please sign in to comment.