diff --git a/python/cortex.py b/python/cortex.py index 98c879f..447216a 100644 --- a/python/cortex.py +++ b/python/cortex.py @@ -56,6 +56,7 @@ REFRESH_HEADSET_LIST_ID = 25 QUERY_RECORDS_ID = 26 REQUEST_DOWNLOAD_RECORDS_ID = 27 +SYNC_WITH_HEADSET_CLOCK_ID = 28 #define error_code ERR_PROFILE_ACCESS_DENIED = -32046 @@ -89,7 +90,7 @@ class Cortex(Dispatcher): 'warn_record_post_processing_done', 'query_records_done', 'request_download_records_done', 'inject_marker_done', 'update_marker_done', 'export_record_done', 'new_data_labels', 'new_com_data', 'new_fe_data', 'new_eeg_data', 'new_mot_data', 'new_dev_data', - 'new_met_data', 'new_pow_data', 'new_sys_data'] + 'new_met_data', 'new_pow_data', 'new_sys_data', 'sync_with_headset_clock_done'] def __init__(self, client_id, client_secret, debug_mode=False, **kwargs): """ Initialize a Cortex instance with authentication and configuration options. @@ -220,6 +221,7 @@ def _get_result_handler(self, req_id): EXPORT_RECORD_ID: self._handle_export_record, INJECT_MARKER_REQUEST_ID: self._handle_inject_marker_request, UPDATE_MARKER_REQUEST_ID: self._handle_update_marker_request, + SYNC_WITH_HEADSET_CLOCK_ID: self._handle_sync_with_headset_clock } return handlers.get(req_id) @@ -420,6 +422,9 @@ def _handle_inject_marker_request(self, result_dic): def _handle_update_marker_request(self, result_dic): self.emit('update_marker_done', data=result_dic['marker']) + def _handle_sync_with_headset_clock(self, result_dic): + self.emit('sync_with_headset_clock_done', data=result_dic) + def handle_error(self, recv_dic): req_id = recv_dic['id'] print('handle_error: request Id ' + str(req_id)) @@ -1091,6 +1096,29 @@ def refresh_headset_list(self): self.ws.send(json.dumps(refresh_request, indent=4)) + def sync_with_headset_clock(self, headset_id=None): + print('sync with headset clock --------------------------------') + + # Use instance headset_id if not provided + if headset_id is None: + headset_id = self.headset_id + + sync_request = { + "jsonrpc": "2.0", + "id": SYNC_WITH_HEADSET_CLOCK_ID, # Using next available ID + "method": "syncWithHeadsetClock", + "params": { + "headset": headset_id, + "systemTime": time.time(), + "monotonicTime": time.monotonic() + } + } + + if self.debug: + print('sync with headset clock request \n', json.dumps(sync_request, indent=4)) + + self.ws.send(json.dumps(sync_request)) + # ------------------------------------------------------------------- # ------------------------------------------------------------------- # ------------------------------------------------------------------- diff --git a/python/marker.py b/python/marker.py index 1c75355..c1f66de 100644 --- a/python/marker.py +++ b/python/marker.py @@ -12,6 +12,8 @@ def __init__(self, app_client_id, app_client_secret, **kwargs): self.c.bind(export_record_done=self.on_export_record_done) self.c.bind(inform_error=self.on_inform_error) self.c.bind(warn_record_post_processing_done=self.on_warn_record_post_processing_done) + self.c.bind(sync_with_headset_clock_done=self.on_sync_with_headset_clock_done) + self.headset_clock_adjustment = 0 def start(self, number_markers=10, headset_id=''): """ @@ -73,7 +75,7 @@ def export_record(self, folder, stream_types, export_format, record_ids, def add_markers(self): print('add_markers: ' + str(self.number_markers) + ' markers will be injected each second automatically.') for m in range(self.number_markers): - marker_time = time.time()*1000 + marker_time = (time.monotonic() + self.headset_clock_adjustment) * 1000 print('add marker at : ', marker_time) # marker_value = "test marker value" @@ -112,6 +114,14 @@ def update_marker(self, marker_id, time, **kwargs): def on_create_session_done(self, *args, **kwargs): print('on_create_session_done') + # sync with headset clock before creating record + self.c.sync_with_headset_clock() + + def on_sync_with_headset_clock_done(self, *args, **kwargs): + print('on_sync_with_headset_clock_done') + data = kwargs.get('data') or {} + self.headset_clock_adjustment = data.get('adjustment', 0) + print(f'Headset clock adjustment: {self.headset_clock_adjustment} s') # create a record self.create_record(self.record_title, description=self.record_description)