diff --git a/Palmtree/Palmtree.csproj b/Palmtree/Palmtree.csproj index 96f4eb9..22dd961 100644 --- a/Palmtree/Palmtree.csproj +++ b/Palmtree/Palmtree.csproj @@ -99,6 +99,15 @@ + + ..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + ..\packages\WebSocketSharp-netstandard.1.0.1\lib\net45\websocket-sharp.dll + + + ..\packages\System.Text.Json.5.0.2\lib\net461\System.Text.Json.dll + False dependencies\Windows.winmd @@ -131,6 +140,7 @@ + Form diff --git a/Palmtree/packages.config b/Palmtree/packages.config index 7bf3d1b..a424e5f 100644 --- a/Palmtree/packages.config +++ b/Palmtree/packages.config @@ -9,4 +9,7 @@ + + + \ No newline at end of file diff --git a/Palmtree/src/Core/DataIO/Data.cs b/Palmtree/src/Core/DataIO/Data.cs index 217d87f..a94f8aa 100644 --- a/Palmtree/src/Core/DataIO/Data.cs +++ b/Palmtree/src/Core/DataIO/Data.cs @@ -34,6 +34,8 @@ namespace Palmtree.Core.DataIO { /// providing slightly better performance (important since the Data class is called upon very frequently) /// public static class Data { + public delegate void OnEventLogged(string eventMessage); + public static event OnEventLogged eventLogged; private const string CLASS_NAME = "Data"; private const int CLASS_VERSION = 3; @@ -1442,7 +1444,9 @@ public static void logEvent(int level, string text, string value) { // construct event String string eventOut = eventTime.ToString("yyyyMMdd_HHmmss_fff") + " " + eventRunElapsedTime + " " + strsourceSamplePackageCounter + " " + strDataSampleCounter + " " + text + " " + value; - + if(eventLogged != null) { + eventLogged(eventOut); + } // write event to event file if (eventStreamWriters.Count > levelIndex && eventStreamWriters[levelIndex] != null) { diff --git a/Palmtree/src/Filters/WSIO.cs b/Palmtree/src/Filters/WSIO.cs new file mode 100644 index 0000000..ef71698 --- /dev/null +++ b/Palmtree/src/Filters/WSIO.cs @@ -0,0 +1,31 @@ +using NLog; +using Palmtree.Core; +using Palmtree.Core.DataIO; +using Palmtree.Core.Params; +using Palmtree.Filters; +using System; +using System.Linq; +using WebSocketSharp; +using WebSocketSharp.Server; +using System.Text.Json; + +namespace Palmtree.Filters +{ + + public class WSIO : WebSocketBehavior + { + private static NLog.Logger logger = LogManager.GetLogger("Data"); + + public class DataStruct + { + public string eventState { get; set; } + public string eventCode { get; set; } + } + + protected override void OnMessage(MessageEventArgs e) + { + DataStruct dataStruct = JsonSerializer.Deserialize(e.Data); + Data.logEvent(1, dataStruct.eventState, dataStruct.eventCode); + } + } +} \ No newline at end of file diff --git a/Palmtree/src/Filters/WSIOFilter.cs b/Palmtree/src/Filters/WSIOFilter.cs index a657913..d05721b 100644 --- a/Palmtree/src/Filters/WSIOFilter.cs +++ b/Palmtree/src/Filters/WSIOFilter.cs @@ -15,7 +15,10 @@ using NLog; using Palmtree.Core; using Palmtree.Core.Params; +using Palmtree.Core.DataIO; +using WebSocketSharp.Server; using System; +using System.Linq; namespace Palmtree.Filters { @@ -25,6 +28,8 @@ namespace Palmtree.Filters { /// ... /// public class WSIOFilter : FilterBase, IFilter { + public static WebSocketServer wssv_data; + public static WebSocketServer wssv_event; private new const int CLASS_VERSION = 1; @@ -41,9 +46,9 @@ public WSIOFilter(string filterName) { parameters = ParameterManager.GetParameters(filterName, Parameters.ParamSetTypes.Filter); // define the parameters - parameters.addParameter ( + parameters.addParameter( "EnableFilter", - "Enable TimeSmoothing Filter", + "Enable WSIO Filter", "1"); parameters.addParameter( @@ -51,11 +56,19 @@ public WSIOFilter(string filterName) { "Log the filter's intermediate and output data streams. See 'Data' tab for more settings on sample stream logging.", "0"); - // message - logger.Info("Filter created (version " + CLASS_VERSION + ")"); + parameters.addParameter( + "Data_WebsocketPort", + "Port to send data out onto", + "21111"); + parameters.addParameter( + "Event_WebsocketPort", + "Port to send data out onto", + "21112"); + + Data.eventLogged += Data_onEventLogged; } - + /** * Configure the filter. Checks the values and application logic of the * parameters and, if valid, transfers the configuration parameters to local variables @@ -83,7 +96,7 @@ public bool configure(ref SamplePackageFormat input, out SamplePackageFormat out // store a references to the input and output format inputFormat = input; outputFormat = output; - + // check the values and application logic of the parameters if (!checkParameters(parameters)) return false; @@ -106,7 +119,7 @@ public bool configure(ref SamplePackageFormat input, out SamplePackageFormat out /// Filter reset options. 0 will reset the minimum; 1 will perform a complete reset of filter information. > 1 for custom resets. /// A boolean, either true for a succesfull re-configuration, or false upon failure public bool configureRunningFilter(Parameters newParameters, int resetOption) { - + // check if new parameters are given (only a reset is also an option) if (newParameters != null) { @@ -163,7 +176,7 @@ public bool configureRunningFilter(Parameters newParameters, int resetOption) { // TODO: take resetFilter into account (currently always resets the buffers on initialize // but when set not to reset, the buffers should be resized while retaining their values!) - + // initialize the variables initialize(); @@ -187,7 +200,7 @@ private bool checkParameters(Parameters newParameters) { // check if the filter is enabled if (newEnableFilter) { - + } @@ -206,7 +219,7 @@ private void transferParameters(Parameters newParameters) { // check if the filter is enabled if (mEnableFilter) { - + } } @@ -228,20 +241,27 @@ public bool initialize() { // check if the filter is enabled if (mEnableFilter) { + double wsPort_data = parameters.getValue("Data_WebsocketPort"); + double wsPort_event = parameters.getValue("Event_WebsocketPort"); - + wssv_data = new WebSocketServer("ws://localhost:" + wsPort_data); + wssv_event = new WebSocketServer("ws://localhost:" + wsPort_event); + + wssv_data.AddWebSocketService("/"); + wssv_event.AddWebSocketService("/"); } - - // return success return true; } public void start() { - + wssv_data.Start(); + wssv_event.Start(); } public void stop() { + wssv_data.Stop(); + wssv_event.Stop(); } @@ -250,28 +270,55 @@ public bool isStarted() { } public void process(double[] input, out double[] output) { - + // create the output package output = new double[input.Length]; - + // check if the filter is enabled + output = input; if (mEnableFilter) { - // filter enabled - - // TODO: send input-package to anywhere... - - + byte[] result = new byte[0]; + output.Select(n => + { + BitConverter.GetBytes(n).ToArray().Select(m => + { + result = result.Append(m).ToArray(); + + return m; + }).ToArray(); + + return n; + }).ToArray(); + + result = result.Prepend(Convert.ToByte(outputFormat.packageRate)).ToArray(); + result = result.Prepend(Convert.ToByte(outputFormat.numSamples)).ToArray(); + result = result.Prepend(Convert.ToByte(outputFormat.numChannels)).ToArray(); + + if (wssv_data.IsListening) + { + wssv_data.WebSocketServices["/"].Sessions.Broadcast(result); + } } // pass reference - output = input; // handle the data logging of the output (both to file and for visualization) processOutputLogging(output); - + } - + + private void Data_onEventLogged(string message) + { + if (wssv_event.IsListening) + { + wssv_event.WebSocketServices["/"].Sessions.Broadcast(message); + } + } + public void destroy() { + wssv_data.Stop(); + wssv_event.Stop(); + // stop the filter // Note: At this point stop will probably have been called from the mainthread before destroy, however there is a slight