From 3ab2a15691efcd8a1d9ba66ae3142448483356d8 Mon Sep 17 00:00:00 2001 From: tungntEmotiv Date: Thu, 14 Nov 2024 08:41:10 +0700 Subject: [PATCH] =?UTF-8?q?COR-5444:=20update=20csharp=20examples=20to=20h?= =?UTF-8?q?andle=20headset=20warnings=20and=20impro=E2=80=A6=20(#220)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * COR-5444: update csharp examples to handle headset warnings and improve examples * update rework --- csharp/BandPowerLogger/Program.cs | 5 +- csharp/CortexAccess/Config.cs | 4 + csharp/CortexAccess/CortexAccess.csproj | 1 + csharp/CortexAccess/CtxClient.cs | 77 ++++--- csharp/CortexAccess/DataStreamExample.cs | 20 +- csharp/CortexAccess/HeadsetFinder.cs | 127 ++++++----- csharp/CortexAccess/RecordManager.cs | 249 +++++++++++++++++++++ csharp/CortexAccess/SessionCreator.cs | 49 ++++ csharp/CortexAccess/Training.cs | 15 +- csharp/EEGLogger/Program.cs | 8 +- csharp/FacialExpressionTraining/Program.cs | 4 +- csharp/InjectMarker/Program.cs | 124 +++------- csharp/MentalCommandTraining/Program.cs | 5 +- csharp/MotionLogger/Program.cs | 8 +- csharp/PMLogger/Program.cs | 9 +- csharp/README.md | 13 +- csharp/RecordData/Program.cs | 142 +++--------- 17 files changed, 540 insertions(+), 320 deletions(-) create mode 100644 csharp/CortexAccess/RecordManager.cs diff --git a/csharp/BandPowerLogger/Program.cs b/csharp/BandPowerLogger/Program.cs index f10e3dc..d8a9000 100644 --- a/csharp/BandPowerLogger/Program.cs +++ b/csharp/BandPowerLogger/Program.cs @@ -11,7 +11,10 @@ namespace BandPowerLogger { class Program { + // init constants before running const string OutFilePath = @"BandPowerLogger.csv"; + const string WantedHeadsetId = ""; // if you want to connect to specific headset, put headset id here. For example: "EPOCX-71D833AC" + private static FileStream OutFileStream; static void Main(string[] args) @@ -31,7 +34,7 @@ static void Main(string[] args) dse.AddStreams("pow"); dse.OnSubscribed += SubscribedOK; dse.OnBandPowerDataReceived += OnBandPowerOK; - dse.Start(); + dse.Start("", false, WantedHeadsetId); Console.WriteLine("Press Esc to flush data to file and exit"); while (Console.ReadKey().Key != ConsoleKey.Escape) { } diff --git a/csharp/CortexAccess/Config.cs b/csharp/CortexAccess/Config.cs index a04fe17..9c54dcd 100644 --- a/csharp/CortexAccess/Config.cs +++ b/csharp/CortexAccess/Config.cs @@ -38,6 +38,10 @@ public static class WarningCode public const int UserLoginOnAnotherOsUser = 16; public const int EULAAccepted = 17; public const int StreamWritingClosed = 18; + public const int HeadsetWrongInformation = 100; + public const int HeadsetCannotConnected = 101; + public const int HeadsetConnectingTimeout = 102; + public const int HeadsetDataTimeOut = 103; public const int HeadsetConnected = 104; public const int HeadsetScanFinished = 142; } diff --git a/csharp/CortexAccess/CortexAccess.csproj b/csharp/CortexAccess/CortexAccess.csproj index e391773..a27404c 100644 --- a/csharp/CortexAccess/CortexAccess.csproj +++ b/csharp/CortexAccess/CortexAccess.csproj @@ -82,6 +82,7 @@ + diff --git a/csharp/CortexAccess/CtxClient.cs b/csharp/CortexAccess/CtxClient.cs index 7efed1f..b7df86d 100644 --- a/csharp/CortexAccess/CtxClient.cs +++ b/csharp/CortexAccess/CtxClient.cs @@ -68,6 +68,20 @@ public ErrorMsgEventArgs(int code, string messageError) public string MessageError { get; set; } } + // event to inform about headset connect + public class HeadsetConnectEventArgs + { + public HeadsetConnectEventArgs(bool isSuccess, string message, string headsetId) + { + IsSuccess = isSuccess; + Message = message; + HeadsetId = headsetId; + } + public bool IsSuccess { get; set; } + public string Message { get; set; } + public string HeadsetId { get; set; } + } + public sealed class CortexClient { const string Url = "wss://localhost:6868"; @@ -86,8 +100,6 @@ public sealed class CortexClient public event EventHandler OnErrorMsgReceived; public event EventHandler OnStreamDataReceived; public event EventHandler> OnQueryHeadset; - public event EventHandler OnHeadsetConnected; - public event EventHandler OnHeadsetDisConnected; public event EventHandler OnHasAccessRight; public event EventHandler OnRequestAccessDone; public event EventHandler OnAccessRightGranted; @@ -118,6 +130,8 @@ public sealed class CortexClient public event EventHandler OnQueryProfile; public event EventHandler OnGetTrainingTime; public event EventHandler OnTraining; + public event EventHandler SessionClosedNotify; + public event EventHandler HeadsetConnectNotify; public event EventHandler HeadsetScanFinished; // Constructor @@ -250,29 +264,7 @@ private void HandleResponse(string method, JToken data) else if (method == "controlDevice") { string command = (string)data["command"]; - if (command == "connect") - { - string message = (string)data["message"]; - string headsetId = ""; - - Console.WriteLine("ConnectHeadset " + message); - if (message.Contains("Start connecting to device")) - { - //"Start connecting to device " + headsetId - headsetId = message.Substring(27); - } - else if (message.Contains("The device")) - { - //"The device " + headsetId + " has been connected or is connecting"; - string tmp = message.Replace(" has been connected or is connecting", ""); - headsetId = tmp.Substring(11); - } - OnHeadsetConnected(this, headsetId); - } - else if (command == "disconnect") - { - OnHeadsetDisConnected(this, true); - } + Console.WriteLine("controlDevice response for command " + command); } else if (method == "getUserLogin") { @@ -468,6 +460,36 @@ private void HandleWarning(int code, JToken messageData) string message = messageData["behavior"].ToString(); HeadsetScanFinished(this, message); } + else if (code == WarningCode.StreamStop) + { + string sessionId = messageData["sessionId"].ToString(); + SessionClosedNotify(this, sessionId); + } + else if (code == WarningCode.SessionAutoClosed) + { + string sessionId = messageData["sessionId"].ToString(); + SessionClosedNotify(this, sessionId); + } + else if (code == WarningCode.HeadsetConnected) + { + string headsetId = messageData["headsetId"].ToString(); + string message = messageData["behavior"].ToString(); + Console.WriteLine("handleWarning:" + message); + HeadsetConnectNotify(this, new HeadsetConnectEventArgs(true, message, headsetId)); + } + else if (code == WarningCode.HeadsetWrongInformation || + code == WarningCode.HeadsetCannotConnected || + code == WarningCode.HeadsetConnectingTimeout) + { + string headsetId = messageData["headsetId"].ToString(); + string message = messageData["behavior"].ToString(); + HeadsetConnectNotify(this, new HeadsetConnectEventArgs(false, message, headsetId)); + } + else if (code == WarningCode.CortexAutoUnloadProfile) + { + // the current profile is unloaded automatically + OnUnloadProfile(this, true); + } } private void WebSocketClient_Closed(object sender, EventArgs e) @@ -580,6 +602,7 @@ public void QueryHeadsets(string headsetId) // mappings is required if connect to epoc flex public void ControlDevice(string command, string headsetId, JObject mappings) { + Console.WriteLine("ControlDevice " + command + " headsetId:" + headsetId); JObject param = new JObject(); param.Add("command", command); if (!String.IsNullOrEmpty(headsetId)) @@ -622,7 +645,7 @@ public void UpdateSession(string cortexToken, string sessionId, string status) // CreateRecord // Required params: session, title, cortexToken public void CreateRecord(string cortexToken, string sessionId, string title, - JToken description = null, JToken subjectName = null, JToken tags= null) + JToken description = null, JToken subjectName = null, List tags = null) { JObject param = new JObject(); param.Add("session", sessionId); @@ -638,7 +661,7 @@ public void CreateRecord(string cortexToken, string sessionId, string title, } if (tags != null) { - param.Add("tags", tags); + param.Add("tags", JArray.FromObject(tags)); } SendTextMessage(param, "createRecord", true); } diff --git a/csharp/CortexAccess/DataStreamExample.cs b/csharp/CortexAccess/DataStreamExample.cs index d3feca0..40c77e6 100644 --- a/csharp/CortexAccess/DataStreamExample.cs +++ b/csharp/CortexAccess/DataStreamExample.cs @@ -16,6 +16,7 @@ public class DataStreamExample private HeadsetFinder _headsetFinder; private Authorizer _authorizer; private SessionCreator _sessionCreator; + private string _wantedHeadsetId; public List Streams { @@ -63,6 +64,7 @@ public DataStreamExample() { _ctxClient.OnStreamDataReceived += StreamDataReceived; _ctxClient.OnSubscribeData += SubscribeDataOK; _ctxClient.OnUnSubscribeData += UnSubscribeDataOK; + _ctxClient.SessionClosedNotify += SessionClosedOK; _authorizer.OnAuthorized += AuthorizedOK; _headsetFinder.OnHeadsetConnected += HeadsetConnectedOK; @@ -72,7 +74,12 @@ public DataStreamExample() { private void SessionClosedOK(object sender, string sessionId) { - Console.WriteLine("The Session " + sessionId + " has closed successfully."); + if (sessionId == _sessionId) + { + Console.WriteLine("The Session " + sessionId + " has closed successfully."); + _sessionId = ""; + _headsetFinder.HasHeadsetConnected = false; + } } private void UnSubscribeDataOK(object sender, MultipleResultEventArgs e) @@ -126,14 +133,16 @@ private void SubscribeDataOK(object sender, MultipleResultEventArgs e) private void SessionCreatedOk(object sender, string sessionId) { - // subscribe _sessionId = sessionId; + // subscribe + string streamsString = string.Join(", ", Streams); + Console.WriteLine("Session is created successfully. Subscribe for Streams: " + streamsString); _ctxClient.Subscribe(_cortexToken, _sessionId, Streams); } private void HeadsetConnectedOK(object sender, string headsetId) { - //Console.WriteLine("HeadsetConnectedOK " + headsetId); + Console.WriteLine("HeadsetConnectedOK " + headsetId); // Wait a moment before creating session System.Threading.Thread.Sleep(1500); // CreateSession @@ -152,7 +161,7 @@ private void AuthorizedOK(object sender, string cortexToken) _headsetFinder.ScanHeadsets(); } // find headset - _headsetFinder.FindHeadset(); + _headsetFinder.FindHeadset(_wantedHeadsetId); } } @@ -194,8 +203,9 @@ public void AddStreams(string stream) } } // start - public void Start(string licenseID="", bool activeSession = false) + public void Start(string licenseID="", bool activeSession = false, string wantedHeadsetId = "") { + _wantedHeadsetId = wantedHeadsetId; _isActiveSession = activeSession; _authorizer.Start(licenseID); } diff --git a/csharp/CortexAccess/HeadsetFinder.cs b/csharp/CortexAccess/HeadsetFinder.cs index 59f231e..3c3b90c 100644 --- a/csharp/CortexAccess/HeadsetFinder.cs +++ b/csharp/CortexAccess/HeadsetFinder.cs @@ -9,116 +9,120 @@ namespace CortexAccess public class HeadsetFinder { private CortexClient _ctxClient; - private string _headsetId; // headset id of connected device + private string _wantedHeadsetId; // headset id of wanted headset device private Timer _aTimer; - private bool _isFoundHeadset; + private bool _hasHeadsetConnected; private bool _isHeadsetScanning = false; + private bool _isAutoConnect = true; // set to false if you don't want to connect automatically to a headset // Event public event EventHandler OnHeadsetConnected; public event EventHandler OnHeadsetDisConnected; - public bool IsHeadsetScanning { get => _isHeadsetScanning; } + public bool HasHeadsetConnected { get => _hasHeadsetConnected; set => _hasHeadsetConnected = value; } + public bool IsAutoConnect { get => _isAutoConnect; set => _isAutoConnect = value; } public HeadsetFinder() { _ctxClient = CortexClient.Instance; - _headsetId = ""; - _isFoundHeadset = false; + _wantedHeadsetId = ""; + _hasHeadsetConnected = false; _ctxClient.OnQueryHeadset += QueryHeadsetOK; - _ctxClient.OnHeadsetConnected += HeadsetConnectedOK; - _ctxClient.OnHeadsetDisConnected += HeadsetDisconnectedOK; + _ctxClient.HeadsetConnectNotify += OnHeadsetConnectNotify; _ctxClient.HeadsetScanFinished += OnHeadsetScanFinished; } - private void HeadsetDisconnectedOK(object sender, bool e) + public void FindHeadset(string wantedHeadsetId = "") { - _headsetId = ""; - OnHeadsetDisConnected(this, true); + Console.WriteLine("FindHeadset: hasHeadsetConnected " + _hasHeadsetConnected + " wantedHeadsetId: " + wantedHeadsetId); + if (!_hasHeadsetConnected) + { + _wantedHeadsetId = wantedHeadsetId; + SetTimer(); // set timer for query headset + _ctxClient.QueryHeadsets(wantedHeadsetId); + } } + + /// + /// ScanHeadsets to trigger scan headsets from Cortex + /// + public void ScanHeadsets() + { + Console.WriteLine("Start scanning headset."); + _isHeadsetScanning = true; + _ctxClient.ControlDevice("refresh", "", new JObject()); + } + private void OnHeadsetScanFinished(object sender, string message) { _isHeadsetScanning = false; Console.WriteLine(message); } - private void HeadsetConnectedOK(object sender, string headsetId) + private void OnHeadsetConnectNotify(object sender, HeadsetConnectEventArgs e) { - if (!String.IsNullOrEmpty(headsetId)) + string headsetId = e.HeadsetId; + Console.WriteLine("OnHeadsetConnectNotify headsetId:" + headsetId + " _wantedHeadsetId:" + _wantedHeadsetId + " isSuccess " + e.IsSuccess); + if (headsetId == _wantedHeadsetId) { - _headsetId = headsetId; - OnHeadsetConnected(this, _headsetId); + if (e.IsSuccess) + { + OnHeadsetConnected(this, _wantedHeadsetId); + _hasHeadsetConnected = true; + } + else + { + _hasHeadsetConnected = false; + Console.WriteLine("Connect the headset " + headsetId + " unsuccessfully. Message : " + e.Message); + } } } private void QueryHeadsetOK(object sender, List headsets) { - if ( headsets.Count > 0) + if (headsets.Count > 0 && !_hasHeadsetConnected) { - _isFoundHeadset = true; - //Turn off timer - _aTimer.Stop(); - _aTimer.Dispose(); + Headset _wantedHeadset = new Headset(); + foreach (var headsetItem in headsets) + { + if (!String.IsNullOrEmpty(_wantedHeadsetId) && _wantedHeadsetId == headsetItem.HeadsetID) + { + _wantedHeadset = headsetItem; + } + } - Headset headset = headsets.First(); - if (headset.Status == "discovered") + if (String.IsNullOrEmpty(_wantedHeadsetId)) { + // set wanted headset is first headset + _wantedHeadset = headsets.First(); + _wantedHeadsetId = _wantedHeadset.HeadsetID; + } + + if (_wantedHeadset.Status == "discovered") + { + // prepare flex mapping if the headset is EPOC Flex JObject flexMappings = new JObject(); - if (headset.HeadsetID.IndexOf("FLEX", StringComparison.OrdinalIgnoreCase) > 0) + if (_wantedHeadset.HeadsetID.IndexOf("FLEX", StringComparison.OrdinalIgnoreCase) > 0) { // For an Epoc Flex headset, we need a mapping flexMappings = JObject.Parse(Config.FlexMapping); } - _ctxClient.ControlDevice("connect", headset.HeadsetID, flexMappings); - } - else if (headset.Status == "connected") - { - _headsetId = headset.HeadsetID; - OnHeadsetConnected(this, _headsetId); + _ctxClient.ControlDevice("connect", _wantedHeadset.HeadsetID, flexMappings); } - else if (headset.Status == "connecting") + else if (_wantedHeadset.Status == "connected") { - Console.WriteLine(" Waiting for headset connection " + headset.HeadsetID); + OnHeadsetConnected(this, _wantedHeadsetId); + _hasHeadsetConnected = true; } } else { - _isFoundHeadset = false; Console.WriteLine(" No headset available. Please connect headset to the machine"); } } - // Property - public string HeadsetId - { - get - { - return _headsetId; - } - } - - public void FindHeadset() - { - Console.WriteLine("FindHeadset"); - if (!_isFoundHeadset) - { - SetTimer(); // set timer for query headset - _ctxClient.QueryHeadsets(""); - } - } - - /// - /// ScanHeadsets to trigger scan headsets from Cortex - /// - public void ScanHeadsets() - { - Console.WriteLine("Start scanning headset."); - _isHeadsetScanning = true; - _ctxClient.ControlDevice("refresh", "", new JObject()); - } - // Create Timer for headset finding private void SetTimer() { @@ -133,9 +137,8 @@ private void SetTimer() private void OnTimedEvent(object sender, ElapsedEventArgs e) { - if (!_isFoundHeadset) + if (!_hasHeadsetConnected && _isAutoConnect) { - // Still not found headset // Query headset again _ctxClient.QueryHeadsets(""); } diff --git a/csharp/CortexAccess/RecordManager.cs b/csharp/CortexAccess/RecordManager.cs new file mode 100644 index 0000000..5ed8f16 --- /dev/null +++ b/csharp/CortexAccess/RecordManager.cs @@ -0,0 +1,249 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace CortexAccess +{ + /// + /// Reponsible for managing and handling records and markers. + /// + public class RecordManager + { + private static Authorizer _authorizer; + private static HeadsetFinder _headsetFinder; + private static SessionCreator _sessionCreator; + private static CortexClient _ctxClient; + private string _wantedHeadsetId; + private static List _recordLists = new List(); + private static List _markersList = new List(); + + + private string _currRecordId; + private string _currMarkerId; + private string _cortexToken; + private string _sessionId; + + public static List RecordLists { get => _recordLists; set => _recordLists = value; } + public static List MarkersList { get => _markersList; set => _markersList = value; } + + public event EventHandler informMarkerResult; + public event EventHandler sessionCreateOk; + + // Constructor + public RecordManager () + { + _authorizer = new Authorizer(); + _headsetFinder = new HeadsetFinder(); + _sessionCreator = new SessionCreator(); + _ctxClient = CortexClient.Instance; + + _cortexToken = ""; + _sessionId = ""; + + _ctxClient.OnErrorMsgReceived += MessageErrorRecieved; + _ctxClient.SessionClosedNotify += SessionClosedOK; + _ctxClient.OnCreateRecord += OnCreateRecordOK; + _ctxClient.OnStopRecord += OnStopRecordOK; + _ctxClient.OnQueryRecords += QueryRecordsOK; + _ctxClient.OnDeleteRecords += DeleteRecordOK; + _ctxClient.OnUpdateRecord += RecordUpdatedOK; + _ctxClient.OnInjectMarker += OnInjectMarkerOK; + _ctxClient.OnUpdateMarker += OnUpdateMarkerOK; + _ctxClient.OnErrorMsgReceived += MessageErrorRecieved; + + _authorizer.OnAuthorized += AuthorizedOK; + _headsetFinder.OnHeadsetConnected += HeadsetConnectedOK; + _sessionCreator.OnSessionCreated += SessionCreatedOk; + _sessionCreator.OnSessionClosed += SessionClosedOK; + } + + private void RecordUpdatedOK(object sender, Record record) + { + Console.WriteLine("RecordUpdatedOK"); + record.PrintOut(); + } + + private void DeleteRecordOK(object sender, MultipleResultEventArgs e) + { + Console.WriteLine("DeleteRecordOK"); + Console.WriteLine("Successes: " + e.SuccessList); + Console.WriteLine("Failures: " + e.FailList); + } + + private void AuthorizedOK(object sender, string cortexToken) + { + if (!String.IsNullOrEmpty(cortexToken)) + { + _cortexToken = cortexToken; + if (!_headsetFinder.IsHeadsetScanning) + { + // Start scanning headset. It will call one time whole program. + // If you want re-scan, please check IsHeadsetScanning and call ScanHeadsets() again + _headsetFinder.ScanHeadsets(); + } + // find headset + _headsetFinder.FindHeadset(_wantedHeadsetId); + } + } + + private void HeadsetConnectedOK(object sender, string headsetId) + { + Console.WriteLine("HeadsetConnectedOK " + headsetId); + // Wait a moment before creating session + System.Threading.Thread.Sleep(1500); + // CreateSession + _sessionCreator.Create(_cortexToken, headsetId, true); + } + + private void OnStopRecordOK(object sender, Record record) + { + Console.WriteLine("RecordManager: OnStopRecordOK recordId: " + record.Uuid + + " at: " + record.EndDateTime); + _currRecordId = ""; + } + + private static void QueryRecordsOK(object sender, List records) + { + _recordLists = records; + Console.WriteLine("QueryRecordsOK"); + foreach (Record ele in records) + { + ele.PrintOut(); + } + } + + private void SessionClosedOK(object sender, string sessionId) + { + if (sessionId == _sessionId) + { + Console.WriteLine("The Session " + sessionId + " has closed successfully."); + _sessionId = ""; + _headsetFinder.HasHeadsetConnected = false; + } + } + + private void SessionCreatedOk(object sender, string sessionId) + { + _sessionId = sessionId; + sessionCreateOk(this, true); + } + + private void OnCreateRecordOK(object sender, Record record) + { + _currRecordId = record.Uuid; + Console.WriteLine("Record " + record.Uuid + " is created successfully."); + } + private void OnInjectMarkerOK(object sender, JObject markerObj) + { + Console.WriteLine("Marker is injected successfully. Marker " + markerObj); + _currMarkerId = markerObj["uuid"].ToString(); + _markersList.Add(_currMarkerId); + } + private void OnUpdateMarkerOK(object sender, JObject markerObj) + { + Console.WriteLine("Marker is updated successfully. Marker " + markerObj); + } + + private void MessageErrorRecieved(object sender, ErrorMsgEventArgs errorInfo) + { + + string message = errorInfo.MessageError; + int errorCode = errorInfo.Code; + Console.WriteLine("MessageErrorRecieved :code " + errorCode + + " message " + message); + //string errorMsg = method +" gets error: "+ message; + //if (method == "injectMarker" || method == "updateMarker") { + // informMarkerResult(this, errorMsg); + //} + //else if (method == "createRecord" || method == "stopRecord") { + // informRecordResult(this, errorMsg); + //} + } + + + /// + /// start a record manager with a license ID and a wanted headset ID. + /// + public void Start( string wantedHeadsetId = "", string licenseID = "") + { + _wantedHeadsetId = wantedHeadsetId; + _authorizer.Start(licenseID); + } + + /// + /// stop a record manager + /// + public void Stop() + { + _sessionCreator.CloseSession(); + _recordLists.Clear(); + _currRecordId = ""; + } + + /// + /// Create a new record. + /// + public void StartRecord(string title, JToken description = null, + JToken subjectName = null, List tags= null) + { + // start record + _sessionCreator.StartRecord(_authorizer.CortexToken, title, description, subjectName, tags); + } + + /// + /// Stop a record that was previously started by StartRecord + /// + public void StopRecord() + { + _sessionCreator.StopRecord(_authorizer.CortexToken); + } + /// + /// Update for record has uuid is recordId + /// + public void UpdateRecord(string recordId , string description = null, List tags = null) + { + _sessionCreator.UpdateRecord(_authorizer.CortexToken, recordId, description, tags); + } + /// + /// Query records + /// + public void QueryRecords(JObject queryObj, JArray orderBy, int limit, int offset) + { + queryObj.Add("applicationId", _sessionCreator.ApplicationId); + + _ctxClient.QueryRecord(_authorizer.CortexToken, queryObj, orderBy, offset, limit); + } + + public void DeleteRecords(List records) + { + _ctxClient.DeleteRecord(_authorizer.CortexToken, records); + } + + /// + /// inject marker + /// + public void InjectMarker(string markerLabel, string markerValue) + { + string cortexToken = _authorizer.CortexToken; + string sessionId = _sessionCreator.SessionId; + + // inject marker + _ctxClient.InjectMarker(cortexToken, sessionId, markerLabel, markerValue, Utils.GetEpochTimeNow()); + } + + /// + /// update marker to set the end date time of a marker, turning an "instance" marker into an "interval" marker + /// + public void UpdateMarker() + { + string cortexToken = _authorizer.CortexToken; + string sessionId = _sessionCreator.SessionId; + + // update marker + _ctxClient.UpdateMarker(cortexToken, sessionId, _currMarkerId, Utils.GetEpochTimeNow()); + } + + } +} diff --git a/csharp/CortexAccess/SessionCreator.cs b/csharp/CortexAccess/SessionCreator.cs index d0965f7..3e0cf72 100644 --- a/csharp/CortexAccess/SessionCreator.cs +++ b/csharp/CortexAccess/SessionCreator.cs @@ -1,4 +1,6 @@ using System; +using Newtonsoft.Json.Linq; +using System.Collections.Generic; namespace CortexAccess { @@ -92,6 +94,7 @@ public void Create(string cortexToken, string headsetId, bool activeSession = fa { _cortexToken = cortexToken; string status = activeSession ? "active" : "open"; + Console.WriteLine("Create session with headsetId " + headsetId); _ctxClient.CreateSession(CortexToken, headsetId, status); } else @@ -109,5 +112,51 @@ public void CloseSession() _ctxClient.UpdateSession(_cortexToken, _sessionId, "close"); } } + + // ... other code ... + + public void StartRecord(string cortexToken, string title, + JToken description = null, JToken subjectName = null, List tags = null) + { + if (!String.IsNullOrEmpty(_sessionId)) + { + _ctxClient.CreateRecord(cortexToken, _sessionId, title, description, subjectName, tags); + } + else + { + Console.WriteLine("StartRecord: invalid sessionId."); + } + } + + /// + /// Stop a record that was previously started by createRecord + /// + public void StopRecord(string cortexToken) + { + if (!String.IsNullOrEmpty(_sessionId)) + { + _ctxClient.StopRecord(cortexToken, _sessionId); + } + else + { + Console.WriteLine("StopRecord: invalid sessionId."); + } + } + + /// + /// Update a record. + /// + public void UpdateRecord(string cortexToken, string recordId, + string description = null, List tags = null) + { + if (!String.IsNullOrEmpty(_sessionId)) + { + _ctxClient.UpdateRecord(cortexToken, recordId, description, tags); + } + else + { + Console.WriteLine("UpdateRecord: invalid sessionId."); + } + } } } diff --git a/csharp/CortexAccess/Training.cs b/csharp/CortexAccess/Training.cs index c6ed897..b0d6cee 100644 --- a/csharp/CortexAccess/Training.cs +++ b/csharp/CortexAccess/Training.cs @@ -20,6 +20,7 @@ public class Training private Authorizer _authorizer; private SessionCreator _sessionCreator; private List _profileLists; + private string _wantedHeadsetId; // event public event EventHandler OnProfileLoaded; @@ -51,6 +52,7 @@ public Training() _ctxClient.OnUnloadProfile += ProfileUnloadedOK; _ctxClient.OnTraining += TrainingOK; _ctxClient.OnQueryProfile += QueryProfileOK; + _ctxClient.SessionClosedNotify += SessionClosedOK; _authorizer.OnAuthorized += AuthorizedOK; _headsetFinder.OnHeadsetConnected += HeadsetConnectedOK; @@ -61,6 +63,12 @@ public Training() private void SessionClosedOK(object sender, string sessionId) { Console.WriteLine("Session " + sessionId + " has closed"); + if (sessionId == _sessionId) + { + Console.WriteLine("The Session " + sessionId + " has closed successfully."); + _sessionId = ""; + _headsetFinder.HasHeadsetConnected = false; + } } private void ProfileUnloadedOK(object sender, bool e) @@ -83,7 +91,7 @@ private void QueryProfileOK(object sender, JArray profiles) _headsetFinder.ScanHeadsets(); } // find headset - _headsetFinder.FindHeadset(); + _headsetFinder.FindHeadset(_wantedHeadsetId); } private void ProfileSavedOK(object sender, string profileName) @@ -176,7 +184,7 @@ private void SubscribeDataOK(object sender, MultipleResultEventArgs e) if (found) { // Ready for training - OnReadyForTraning(this, true); + OnReadyForTraning(this, true); } else { @@ -227,11 +235,12 @@ private void MessageErrorRecieved(object sender, ErrorMsgEventArgs e) Console.WriteLine("MessageErrorRecieved :code " + e.Code + " message " + e.MessageError); } - public void Start(string detection) + public void Start(string detection, string wantedHeadsetId = "") { if (detection == "mentalCommand" || detection == "facialExpression") { + _wantedHeadsetId = wantedHeadsetId; _detection = detection; _authorizer.Start(); } diff --git a/csharp/EEGLogger/Program.cs b/csharp/EEGLogger/Program.cs index 323effd..0db4c8a 100644 --- a/csharp/EEGLogger/Program.cs +++ b/csharp/EEGLogger/Program.cs @@ -11,8 +11,11 @@ namespace EEGLogger { class Program { + // init constants before running const string OutFilePath = @"EEGLogger.csv"; - const string licenseID = "put_your_license_here"; + const string LicenseID = ""; // Should be put empty string. Emotiv Cloud will choose the license automatically + const string WantedHeadsetId = ""; // if you want to connect to specific headset, put headset id here. For example: "EPOCX-71D833AC" + private static FileStream OutFileStream; static void Main(string[] args) @@ -33,8 +36,7 @@ static void Main(string[] args) dse.OnSubscribed += SubscribedOK; dse.OnEEGDataReceived += OnEEGDataReceived; - // Need a valid license key and activeSession when subscribe eeg data - dse.Start(licenseID, true); + dse.Start(LicenseID, true, WantedHeadsetId); Console.WriteLine("Press Esc to flush data to file and exit"); while (Console.ReadKey().Key != ConsoleKey.Escape) { } diff --git a/csharp/FacialExpressionTraining/Program.cs b/csharp/FacialExpressionTraining/Program.cs index a719dee..0da80ec 100644 --- a/csharp/FacialExpressionTraining/Program.cs +++ b/csharp/FacialExpressionTraining/Program.cs @@ -8,7 +8,9 @@ namespace FacialExpressionTraining { class Program { + // init before running private static string _profileName = "put_your_profile_here"; // new profile name for creating or existed profile name for loading + private static string _wantedHeadsetId = ""; // if you want to connect to specific headset, put headset id here. For example: "EPOCX-71D833AC" private static Training _trainer = new Training(); private static bool _isSucceeded = false; @@ -32,7 +34,7 @@ static void Main(string[] args) Console.WriteLine("Prepare to training"); // Start - _trainer.Start("facialExpression"); + _trainer.Start("facialExpression", _wantedHeadsetId); if (_readyForTrainingEvent.WaitOne(50000)) { diff --git a/csharp/InjectMarker/Program.cs b/csharp/InjectMarker/Program.cs index d18c258..eb1bdfe 100644 --- a/csharp/InjectMarker/Program.cs +++ b/csharp/InjectMarker/Program.cs @@ -8,41 +8,26 @@ namespace InjectMarker { class Program { - private static string _cortexToken; - private static string _sessionId; - private static bool _isRecording; - private static List _markersList = new List(); + const string WantedHeadsetId = ""; // if you want to connect to specific headset, put headset id here. For example: "EPOCX-71D833AC" + private static RecordManager _recordManager; private static int _recordNo = 1; - private static Authorizer _authorizer = new Authorizer(); - private static HeadsetFinder _headsetFinder = new HeadsetFinder(); - private static SessionCreator _sessionCreator = new SessionCreator(); - private static CortexClient _ctxClient; - private static AutoResetEvent _readyForInjectMarkerEvent = new AutoResetEvent(false); + private static AutoResetEvent _readyForRecordDataEvent = new AutoResetEvent(false); static void Main(string[] args) { Console.WriteLine("INJECT MARKER DEMO"); Console.WriteLine("Please wear Headset with good signal!!!"); + _recordManager = new RecordManager(); + _recordManager.sessionCreateOk += OnSessionCreatedOk; - _ctxClient = CortexClient.Instance; - _ctxClient.OnCreateRecord += RecordCreatedOK; - _ctxClient.OnStopRecord += RecordStoppedOK; - _ctxClient.OnInjectMarker += MarkerInjectedOk; - _ctxClient.OnErrorMsgReceived += MessageErrorRecieved; - - _authorizer.OnAuthorized += AuthorizedOK; - _headsetFinder.OnHeadsetConnected += HeadsetConnectedOK; - _sessionCreator.OnSessionCreated += SessionCreatedOk; - _sessionCreator.OnSessionClosed += SessionClosedOK; - - Console.WriteLine("Prepare to inject marker"); // Start - _authorizer.Start(); + _recordManager.Start(WantedHeadsetId); - if (_readyForInjectMarkerEvent.WaitOne(50000)) + if (_readyForRecordDataEvent.WaitOne(50000)) { Console.WriteLine("Press certain key except below keys to inject marker"); + Console.WriteLine("Press C to create record"); Console.WriteLine("Press S to stop record and quit"); Console.WriteLine("Press Esc to quit"); Console.WriteLine("Press H to show all commands"); @@ -56,12 +41,19 @@ static void Main(string[] args) Console.WriteLine(keyInfo.KeyChar.ToString() + " has pressed"); if (keyInfo.Key == ConsoleKey.S) { - // Querry Sessions before quit - _ctxClient.StopRecord(_cortexToken, _sessionId); - Thread.Sleep(10000); - break; + // Stop Record + Console.WriteLine("Stop Record"); + _recordManager.StopRecord(); + } + else if (keyInfo.Key == ConsoleKey.C) + { + // Create Record + string title = "RecDemo-" + _recordNo; + Console.WriteLine("Create Record" + title); + _recordManager.StartRecord(title); + _recordNo++; } - if (keyInfo.Key == ConsoleKey.H) + else if (keyInfo.Key == ConsoleKey.H) { Console.WriteLine("Press certain key except below keys to inject marker"); Console.WriteLine("Press S to stop record and quit"); @@ -79,15 +71,11 @@ static void Main(string[] args) } else { - // Inject marker - if (_isRecording) - { - _ctxClient.InjectMarker(_cortexToken, _sessionId, keyInfo.Key.ToString(), valueMaker, Utils.GetEpochTimeNow()); - Thread.Sleep(2000); - valueMaker++; - } + _recordManager.InjectMarker(keyInfo.Key.ToString(), valueMaker.ToString()); + valueMaker++; } } + _recordManager.Stop(); Thread.Sleep(10000); } @@ -96,70 +84,12 @@ static void Main(string[] args) Console.WriteLine("The preparation for injecting marker is unsuccessful. Please try again"); } } - - private static void SessionClosedOK(object sender, string sessionId) - { - Console.WriteLine("The Session " + sessionId + " has closed successfully."); - } - - private static void MessageErrorRecieved(object sender, ErrorMsgEventArgs e) - { - Console.WriteLine("MessageErrorRecieved :code " + e.Code + " message " + e.MessageError); - } - - private static void MarkerInjectedOk(object sender, JObject marker) - { - Console.WriteLine("Marker is injected successfully. Marker " + marker); - string markerId = (string)marker["uuid"]; - _markersList.Add(markerId); - } - - private static void RecordStoppedOK(object sender, Record record) - { - Console.WriteLine("Record " + record.Uuid + " is stopped successfully."); - _isRecording = false; - _sessionCreator.CloseSession(); - } - - private static void RecordCreatedOK(object sender, Record record) - { - Console.WriteLine("Record " + record.Uuid + " is created successfully."); - _readyForInjectMarkerEvent.Set(); - _isRecording = true; - } - - private static void SessionCreatedOk(object sender, string sessionId) + private static void OnSessionCreatedOk(object sender, bool isOk) { - _sessionId = sessionId; - // create Record - string title = "test-" + _recordNo; - _ctxClient.CreateRecord(_cortexToken, sessionId, title); - _recordNo++; - } - - private static void HeadsetConnectedOK(object sender, string headsetId) - { - Console.WriteLine("HeadsetConnectedOK " + headsetId); - - // Wait a moment before creating session - System.Threading.Thread.Sleep(1500); - // CreateSession - _sessionCreator.Create(_cortexToken, headsetId, true); - } - - private static void AuthorizedOK(object sender, string cortexToken) - { - if (!String.IsNullOrEmpty(cortexToken)) + if (isOk) { - _cortexToken = cortexToken; - if (!_headsetFinder.IsHeadsetScanning) - { - // Start scanning headset. It will call one time whole program. - // If you want re-scan, please check IsHeadsetScanning and call ScanHeadsets() again - _headsetFinder.ScanHeadsets(); - } - // find headset - _headsetFinder.FindHeadset(); + Console.WriteLine("SessionCreatedOK"); + _readyForRecordDataEvent.Set(); } } } diff --git a/csharp/MentalCommandTraining/Program.cs b/csharp/MentalCommandTraining/Program.cs index c99a6f0..e8bcc19 100644 --- a/csharp/MentalCommandTraining/Program.cs +++ b/csharp/MentalCommandTraining/Program.cs @@ -8,7 +8,10 @@ namespace MentalCommandTraining { class Program { + const string WantedHeadsetId = ""; // if you want to connect to specific headset, put headset id here. For example: "EPOCX-71D833AC" + private static string _profileName = "put_your_profile_here"; // new profile name for creating or existed profile name for loading + private static Training _trainer = new Training(); private static bool _isSucceeded = false; @@ -30,7 +33,7 @@ static void Main(string[] args) Console.WriteLine("Prepare to training"); // Start - _trainer.Start("mentalCommand"); + _trainer.Start("mentalCommand", WantedHeadsetId); if (_readyForTrainingEvent.WaitOne(50000)) { diff --git a/csharp/MotionLogger/Program.cs b/csharp/MotionLogger/Program.cs index be6772e..07200b8 100644 --- a/csharp/MotionLogger/Program.cs +++ b/csharp/MotionLogger/Program.cs @@ -6,13 +6,16 @@ using CortexAccess; using Newtonsoft.Json.Linq; using System.Collections.Generic; +using System.ComponentModel; namespace MotionLogger { class Program { + // init constants before running const string OutFilePath = @"MotionLogger.csv"; - const string licenseID = ""; // Do not need license id when subscribe motion + const string LicenseID = ""; // Should be put empty string. Emotiv Cloud will choose the license automatically + const string WantedHeadsetId = ""; // if you want to connect to specific headset, put headset id here. For example: "EPOCX-71D833AC" private static FileStream OutFileStream; @@ -33,7 +36,8 @@ static void Main(string[] args) dse.AddStreams("mot"); dse.OnSubscribed += SubscribedOK; dse.OnMotionDataReceived += OnMotionDataReceived; - dse.Start(licenseID); + + dse.Start(LicenseID, false, WantedHeadsetId); Console.WriteLine("Press Esc to flush data to file and exit"); while (Console.ReadKey().Key != ConsoleKey.Escape) { } diff --git a/csharp/PMLogger/Program.cs b/csharp/PMLogger/Program.cs index 1b94a52..c6166b3 100644 --- a/csharp/PMLogger/Program.cs +++ b/csharp/PMLogger/Program.cs @@ -11,8 +11,12 @@ namespace PMLogger { class Program { + // init constants before running const string OutFilePath = @"PMLogger.csv"; - const string licenseID = "put_your_license_here"; + const string LicenseID = ""; // Should be put empty string. Emotiv Cloud will choose the license automatically + const string WantedHeadsetId = ""; // if you want to connect to specific headset, put headset id here. For example: "EPOCX-71D833AC" + const bool ActiveSession = false; // set true if you want to uses the license of the user. Depending on the license scope of the license, you can subscribe high resolution performance metrics + private static FileStream OutFileStream; static void Main(string[] args) @@ -33,8 +37,7 @@ static void Main(string[] args) dse.OnSubscribed += SubscribedOK; dse.OnPerfDataReceived += OnPMDataReceived; - // Need a valid license key and activeSession when subscribe performance metric data - dse.Start(licenseID, true); + dse.Start(LicenseID, ActiveSession, WantedHeadsetId); Console.WriteLine("Press Esc to flush data to file and exit"); while (Console.ReadKey().Key != ConsoleKey.Escape) { } diff --git a/csharp/README.md b/csharp/README.md index c075d4c..9203410 100644 --- a/csharp/README.md +++ b/csharp/README.md @@ -24,8 +24,9 @@ This section describe structure overview, core classes and examples. The C# Cort * CortexClient: Responsible for sending requests to Cortex and handle responses, warning, data from Cortex. * Config: Contain configurations. User must fill clientId, client Secret of App. To get EEG and Performance metric data, an appropriate license is required. * Authorizer: Responsible for getUserLogin, requestAccess, authorize for App. -* HeadsetFinder: Reponsible for finding headsets, connect headset. -* SessionCreator: Responsible for createSession, updateSession for work-flow. +* HeadsetFinder: Reponsible for finding headsets, connect headset. If you don't want to connect automatically to a headset (after first time), you should set IsAutoConnect = false +* SessionCreator: Responsible for createSession, updateSession, start/stop/update record for work-flow. +* RecordManager: To handle records and markers * Training: Responsible for create/load/unload/ query Profiles and training. * Examples: We have examples to demo subscribe data, record, inject marker, training. @@ -34,8 +35,7 @@ This section describe structure overview, core classes and examples. The C# Cort * This example opens a session with the first Emotiv headset. Then subscribe and save eeg data to EEGLogger.csv file until Esc key pressed. * The basic work-flow: Login via EMOTIV Launcher -> requestAccess-> Authorize (an appropriate license is required) -> find and connect headset -> Create Session -> Subscribe EEG data. * Notes: - - 1) Need put an appropriate license in Program.cs - - 2) Press Esc to flush data to output file and exit. + - 1) Press Esc to flush data to output file and exit. **2. MotionLogger** * This example opens a session with the first Emotiv headset. Then subscribe and save motion data to MotionLogger.csv file until Esc key pressed. @@ -73,9 +73,8 @@ This section describe structure overview, core classes and examples. The C# Cort * The basic work-flow: Login via EMOTIV Launcher -> requestAccess-> Authorize (an appropriate license is required) -> find and connect headset -> Create Session -> Subscribe PM data. * The performance metric data frequency depend on scope of license. For low performance metric : 1 sample/ 10 seconds ; for high performance metric 2 samples/ seconds. * Notes: - - 1) Need put an appropriate license in Program.cs - - 2) Press Esc to flush data to output file and exit. - - 3) Each performance metric is a decimal number between 0 and 1. Zero means "low power", 1 means "high power". If the detection cannot run because of a bad contact quality then the value can also be **null** + - 1) Press Esc to flush data to output file and exit. + - 2) Each performance metric is a decimal number between 0 and 1. Zero means "low power", 1 means "high power". If the detection cannot run because of a bad contact quality then the value can also be **null** ### Notes * You must login and logout via EMOTIV Launcher. * You must use EMOTIV Launcher to grant AccessRight for the App one time for one emotiv user. diff --git a/csharp/RecordData/Program.cs b/csharp/RecordData/Program.cs index 86860a2..4a0d669 100644 --- a/csharp/RecordData/Program.cs +++ b/csharp/RecordData/Program.cs @@ -8,15 +8,10 @@ namespace RecordData { class Program { - private static string _cortexToken; - private static string _sessionId; - private static string _currRecordId;// current recordID - private static List _recordLists = new List(); + const string WantedHeadsetId = ""; // if you want to connect to specific headset, put headset id here. For example: "EPOCX-71D833AC" + private static int _recordNo = 1; - private static Authorizer _authorizer = new Authorizer(); - private static HeadsetFinder _headsetFinder = new HeadsetFinder(); - private static SessionCreator _sessionCreator = new SessionCreator(); - private static CortexClient _ctxClient; + private static RecordManager _recordManager; private static AutoResetEvent _readyForRecordDataEvent = new AutoResetEvent(false); static void Main(string[] args) @@ -25,31 +20,19 @@ static void Main(string[] args) Console.WriteLine("Please wear Headset with good signal!!!"); - _ctxClient = CortexClient.Instance; - _ctxClient.OnCreateRecord += RecordCreatedOK; - _ctxClient.OnStopRecord += RecordStoppedOK; - _ctxClient.OnErrorMsgReceived += MessageErrorRecieved; - _ctxClient.OnQueryRecords += QueryRecordsOK; - _ctxClient.OnDeleteRecords += DeleteRecordOK; - _ctxClient.OnUpdateRecord += RecordUpdatedOK; - - _authorizer.OnAuthorized += AuthorizedOK; - _headsetFinder.OnHeadsetConnected += HeadsetConnectedOK; - _sessionCreator.OnSessionCreated += SessionCreatedOk; - _sessionCreator.OnSessionClosed += SessionClosedOK; - + _recordManager = new RecordManager(); + _recordManager.sessionCreateOk += OnSessionCreatedOk; Console.WriteLine("Prepare to record Data"); // Start - _authorizer.Start(); - + _recordManager.Start(WantedHeadsetId); + if (_readyForRecordDataEvent.WaitOne(50000)) { - Console.WriteLine("Press certain key to inject marker"); Console.WriteLine("Press C to create record"); Console.WriteLine("Press S to stop record"); Console.WriteLine("Press Q to query record"); - Console.WriteLine("Press D to delete record"); + Console.WriteLine("Press D to delete first record Id from recording list"); Console.WriteLine("Press U to update record"); Console.WriteLine("Press H to show all commands"); Console.WriteLine("Press Esc to quit"); @@ -64,30 +47,36 @@ static void Main(string[] args) { // Stop Record Console.WriteLine("Stop Record"); - _ctxClient.StopRecord(_cortexToken, _sessionId); + _recordManager.StopRecord(); } else if (keyInfo.Key == ConsoleKey.C) { // Create Record string title = "RecDemo-" + _recordNo; Console.WriteLine("Create Record" + title); - _ctxClient.CreateRecord(_cortexToken, _sessionId, title); + _recordManager.StartRecord(title); _recordNo++; } else if (keyInfo.Key == ConsoleKey.U) { - // Update Record - string description = "description for RecDemo"; - List tags = new List() { "demo1", "demo2" }; - Console.WriteLine("Update Record: " + _currRecordId); - _ctxClient.UpdateRecord(_cortexToken, _currRecordId, description, tags); + // Update for first record in the list. Or you can update for any record has recordId + if (RecordManager.RecordLists.Count > 0) + { + Record lastRecord = RecordManager.RecordLists[0]; + string recordId = lastRecord.Uuid; + string description = "description for RecDemo"; + List tags = new List() { "demo1", "demo2" }; + _recordManager.UpdateRecord(recordId, description, tags); + } + else + { + Console.WriteLine("No recording list. Please create records and queryRecords first"); + } } else if (keyInfo.Key == ConsoleKey.Q) { - // Query Record // query param JObject query = new JObject(); - query.Add("applicationId", _sessionCreator.ApplicationId); //order JArray orderBy = new JArray(); @@ -97,17 +86,19 @@ static void Main(string[] args) // limit int limit = 5; // number of maximum record return int offset = 0; - _ctxClient.QueryRecord(_cortexToken, query, orderBy, offset, limit); + _recordManager.QueryRecords(query, orderBy, limit, offset); } else if (keyInfo.Key == ConsoleKey.D) { // Delete first Record - if (_recordLists.Count > 0) + if (RecordManager.RecordLists.Count > 0) { - Record lastRecord = _recordLists[0]; + Record lastRecord = RecordManager.RecordLists[0]; string recordId = lastRecord.Uuid; Console.WriteLine("Delete Record" + recordId); - _ctxClient.DeleteRecord(_cortexToken, new List() { recordId }); + List wantedDeleteRecord = new List(); + wantedDeleteRecord.Add(recordId); + _recordManager.DeleteRecords(wantedDeleteRecord); } else { @@ -131,7 +122,7 @@ static void Main(string[] args) else if (keyInfo.Key == ConsoleKey.Spacebar) continue; else if (keyInfo.Key == ConsoleKey.Escape) { - _sessionCreator.CloseSession(); + _recordManager.Stop(); break; } else @@ -148,77 +139,12 @@ static void Main(string[] args) } } - private static void RecordUpdatedOK(object sender, Record record) - { - Console.WriteLine("RecordUpdatedOK"); - record.PrintOut(); - } - - private static void DeleteRecordOK(object sender, MultipleResultEventArgs e) - { - Console.WriteLine("DeleteRecordOK"); - Console.WriteLine("Successes: " + e.SuccessList); - Console.WriteLine("Failures: " + e.FailList); - } - - private static void QueryRecordsOK(object sender, List records) - { - _recordLists = records; - Console.WriteLine("QueryRecordsOK"); - foreach(Record ele in records) - { - ele.PrintOut(); - } - } - - private static void SessionClosedOK(object sender, string sessionId) - { - Console.WriteLine("The Session " + sessionId + " has closed successfully."); - } - - private static void MessageErrorRecieved(object sender, ErrorMsgEventArgs e) - { - Console.WriteLine("MessageErrorRecieved :code " + e.Code + " message " + e.MessageError); - } - private static void RecordStoppedOK(object sender, Record record) - { - Console.WriteLine("Record " + record.Uuid + " is stopped successfully."); - } - - private static void RecordCreatedOK(object sender, Record record) - { - Console.WriteLine("Record " + record.Uuid + " is created successfully."); - _currRecordId = record.Uuid; - } - - private static void SessionCreatedOk(object sender, string sessionId) - { - _sessionId = sessionId; - _readyForRecordDataEvent.Set(); - } - - private static void HeadsetConnectedOK(object sender, string headsetId) + private static void OnSessionCreatedOk(object sender, bool isOK) { - Console.WriteLine("HeadsetConnectedOK " + headsetId); - // Wait a moment before creating session - System.Threading.Thread.Sleep(1500); - // CreateSession - _sessionCreator.Create(_cortexToken, headsetId, true); - } - - private static void AuthorizedOK(object sender, string cortexToken) - { - if (!String.IsNullOrEmpty(cortexToken)) + if (isOK) { - _cortexToken = cortexToken; - if (!_headsetFinder.IsHeadsetScanning) - { - // Start scanning headset. It will call one time whole program. - // If you want re-scan, please check IsHeadsetScanning and call ScanHeadsets() again - _headsetFinder.ScanHeadsets(); - } - // find headset - _headsetFinder.FindHeadset(); + Console.WriteLine("SessionCreatedOK"); + _readyForRecordDataEvent.Set(); } } }