class APIClient(EventDispatcher): def __init__(self): self.register_event_type('on_error') App.get_running_app().bind( on_settings_changed=self.on_settings_changed) self._socket = None def on_error(self, message): pass def on_settings_changed(self, instance): log.info('Settings changed, restarting conenction') if self._socket and self._socket.connected: self._socket.disconnect() self._socket = None def _connect(self): try: if not self._socket: self._socket = SocketIO( read_configs()['server_host'], read_configs()['server_port'], LoggingNamespace, wait_for_connection=False, ) self._socket.connect() return True except ConnectionError: log.error('Failed to connect') self.dispatch('on_error', 'Failed to connect to server') return False def _emit(self, event, data): if not self._connect(): return try: self._socket.emit(event, data) except ConnectionError: log.error('Failed to emit event %s', event) self.dispatch('on_error', 'Failed to send command') def set_baby_magnet_mode(self, mode, brightness): self._emit( 'set_led_panel_mode', { 'new_mode': mode, 'brightness': int(brightness) }, ) def set_lullaby_mode(self, mode): self._emit('set_lullaby_mode', {'new_mode': mode}) def connect_bluetooth(self): self._emit('connect_bluetooth', {}) def power_off_device(self): self._emit('power_off_device', {})
class WxSocket(threading.Thread): def __init__(self, callbacks, host, port): super(WxSocket, self).__init__() self.callbacks = callbacks self.host = host self.port = port self.daemon = True #this will kill the thread when the main thread exits self.start() #this is the worker function that will be held in the other thread def run(self): self.io = SocketIO(self.host, self.port, LoggingNamespace) for event, callback in self.callbacks.iteritems(): self.io.on(event, callback) self.io.wait() def connect(self): self.io.connect() def disconnect(self): self.io.disconnect() def __enter__(self): return self def __exit__(self, exc_type, exc_value, exc_tb): self.disconnect()
def connect(self): if self.io is None: socket_io = SocketIO(host=self.host, port=self.port, namespace=LoggingNamespace, path='/chat') socket_io.on('connect', self.on_connect, path='/chat') socket_io.on('disconnect', self.on_disconnect, path='/chat') socket_io.on('reconnect', self.on_reconnect, path='/chat') socket_io.on('status', self.on_status, path='/chat') socket_io.on('message', self.on_message, path='/chat') socket_io.connect(path='/chat') self.io = socket_io
class SocketIOHandler(object): def __init__(self, cfg): """ save the server config.. """ self.server_address = cfg['graphite_ip'] self.server_port = cfg['graphite_port'] self.namespace = cfg['graphite_namespace'] self.socketIO = None self.channel = None def handle(self, non_metrics): if len(non_metrics) == 0: logging.debug('No metrics be handled!') return nm_list = [] for nm in non_metrics: nm_list.append(dumps(nm.to_dict())) # serialized to json msg_type = non_metrics[0].type self.socketIO = SocketIO(self.server_address, self.server_port, BaseNamespace) self.channel = self.socketIO.connect(self.namespace, BaseNamespace) self.channel.emit(msg_type, nm_list, self.on_response) # send to server self.socketIO.wait(forCallbacks=True) logging.debug('SokcetIOHandler emitting %s to sever:\n %s' % (msg_type, dumps(nm_list))) def on_response(self, *args): # is it necessary? self.socketIO.disconnect() logging.debug('emit non metrics success!')
def test_channels(self): mainSocket = SocketIO('localhost', 8000, Namespace) chatSocket = mainSocket.connect('/chat', Namespace) newsSocket = mainSocket.connect('/news', Namespace) newsSocket.emit('aaa', PAYLOAD) sleep(0.5) self.assertNotEqual(mainSocket.namespace.payload, PAYLOAD) self.assertNotEqual(chatSocket.namespace.payload, PAYLOAD) self.assertEqual(newsSocket.namespace.payload, PAYLOAD)
class VolumioController: PLAYER_PLAY = 'play' PLAYER_STOP = 'stop' def __init__(self, hdmi_controller: CecController): self.controller = hdmi_controller self.controller.set_player_call_back(self.push_player_state) self.socketIO = SocketIO('volumio.local', 3000) self.socketIO.connect() self.socketIO.on('pushState', self.__on_push_state) def start(self): self.socketIO.wait() def push_player_state(self, state): self.socketIO.emit(state) def __on_push_state(self, status_info: dict, **args): logging.info(f"Volumio state change to {status_info['status']}") if status_info['status'] == 'play': self.controller.turn_on_receiver() is_first_time = False i = 1 while not controller.is_audio_on(): time.sleep(1) logging.info(f"Waiting audio to be [ON]...{i}s") is_first_time = True i += 1 if i == 41: logging.info("Failed start audio") return if is_first_time: self.controller.init_audio_to_hdmi_1() return if status_info['status'] == 'pause' or status_info['status'] == 'stop': if not self.controller.is_tv_on(): self.controller.turn_off_receiver() return
def socketThread(): """ Reads the socketQueue and fill the geo location info(lat, long, city, country) then send new updated data to server. After sending to server put the updated feed object to databaseQueue """ global socketQueue, databaseQueue, IS_RUNNING, socketIOHost, socketIOPort def __toJSON(newFeed): return '{ "url":"%s", "saddr":"%s", "sport":"%s", "sha512":"%s", "md5":"%s", ' \ '"country":"%s", "city":"%s", "x": "%f", "y": "%f"}' \ % (newFeed.url, newFeed.saddr, newFeed.sport, newFeed.sha512, newFeed.md5, newFeed.country, newFeed.city, newFeed.longitude, newFeed.latitude) def _sendNewFeed(chatSocket, newFeed): info = freegeoip.getCityInfoByIp(newFeed.saddr) if info: newFeed.longitude = info['longitude'] newFeed.latitude = info['latitude'] newFeed.country = info['country_code3'] city = info['city'] if city: try: city = city.decode('utf-8', 'ignore') except: city = '' newFeed.city = city # TODO: Add other options except for daddr #coordinate = "{ \"country\":\"%s\", \"city\":\"%s\", \"x\": \"%f\", \"y\": \"%f\"}" % (newFeed.country, newFeed.city, info['longitude'], info['latitude']) coordinate = __toJSON(newFeed) chatSocket.emit('update', coordinate) databaseQueue.put(newFeed) try: socketIO = SocketIO(socketIOHost, socketIOPort) chatSocket = socketIO.connect('/new-event') print 'socketThread started, IS_RUNNING:', IS_RUNNING while IS_RUNNING: try: newFeed = socketQueue.get(True, 1) _sendNewFeed(chatSocket, newFeed) socketQueue.task_done() except Empty: pass except: traceback.print_exc() stopExecution() #IS_RUNNING = False print 'socketThread finished...'
class WaptSocketIOClient(threading.Thread): def __init__(self,config_filename = 'c:/wapt/wapt-get.ini',task_manager=None): threading.Thread.__init__(self) self.name = 'SocketIOClient' self.config_filename = config_filename self.task_manager = task_manager self.config = WaptServiceConfig(config_filename) self.socketio_client = None self.wapt_remote_calls = None self.server_authorization_token = None def run(self): self.config.reload_if_updated() with Wapt(config_filename = self.config.config_filename) as tmp_wapt: logger.info('Starting socketio on "%s://%s:%s" ...' % (self.config.websockets_proto,self.config.websockets_host,self.config.websockets_port)) logger.debug('Certificate checking : %s' % self.config.websockets_verify_cert) def get_connect_params(wapt): connect_params = {'uuid': wapt.host_uuid} if not self.server_authorization_token: try: self.server_authorization_token = wapt.get_auth_token('websocket') logger.info('Websocket token: %s' % self.server_authorization_token) connect_params['token'] = self.server_authorization_token except Exception as e: logger.warning('Websocket connect params: %s' % e) self.server_authorization_token = None return {'params':connect_params, 'cert' :(wapt.get_host_certificate_filename(),wapt.get_host_key_filename())} while True: try: connect_params = get_connect_params(tmp_wapt) if not self.socketio_client and self.config.websockets_host: logger.debug('Creating socketio client') logger.debug('Proxies : %s'%self.config.waptserver.proxies) # bug in socketio... ? we must not pass proxies at all (even None) if we don"t want to switch to polling mode... kwargs = {} if self.config.waptserver.proxies and self.config.waptserver.proxies.get(self.config.websockets_proto,None) is not None: kwargs['proxies'] = self.config.waptserver.proxies kwargs.update(connect_params) self.socketio_client = SocketIO( host="%s://%s" % (self.config.websockets_proto,self.config.websockets_host), port=self.config.websockets_port, Namespace = WaptSocketIORemoteCalls, resource=self.config.websockets_root, verify=self.config.websockets_verify_cert, wait_for_connection = False, transport = ['websocket'], ping_interval = self.config.websockets_ping, hurry_interval_in_seconds = self.config.websockets_hurry_interval, **kwargs) self.socketio_client.get_namespace().wapt = tmp_wapt self.socketio_client.get_namespace().task_manager = self.task_manager if self.socketio_client and self.config.websockets_host: if not self.socketio_client.connected: self.socketio_client._http_session.update(connect_params) self.socketio_client.define(WaptSocketIORemoteCalls) self.socketio_client.get_namespace().wapt = tmp_wapt self.socketio_client.get_namespace().task_manager = self.task_manager self.socketio_client.connect('') else: # be sure server DB is aware of the current connection. # could be avoided self.socketio_client.emit('wapt_pong') if self.socketio_client.connected: logger.info('Socket IO listening for %ss' % self.config.websockets_check_config_interval ) startwait = time.time() self.socketio_client.wait(self.config.websockets_check_config_interval) # QAD workaround for cases where server disconnect but client is between 2 states. # In this case; wait() immediately returns, leading to an indefinite loop eating 1 core. if time.time() - startwait < self.config.websockets_check_config_interval-2: raise Exception('Websocket client seems disconnected. Force Websocket connection to be recreated') elif not self.config.websockets_host: self.socketio_client = None time.sleep(self.config.websockets_retry_delay) else: time.sleep(self.config.websockets_retry_delay) if self.config.reload_if_updated(): tmp_wapt.reload_config_if_updated() if self.socketio_client: self.socketio_client.disconnect() raise EWaptException('Configuration changed, force Websocket connection to be recreated') except Exception as e: try: # reset token self.server_authorization_token = None self.config.reload_if_updated() if self.socketio_client: self.socketio_client = None finally: logger.debug(u'Exception %s, Socket IO Stopped, waiting %ss before retrying' % (repr(e),self.config.websockets_retry_delay)) time.sleep(self.config.websockets_retry_delay)
class P300Client(object): def __init__(self): self.socket_client = None self.marker_outlet = None self.train_mode = True # True for training mode, False for prediction mode # will stay in training mode until first prediction self.train_results = [] self.pred_results = [] self.streams = {} self.register_results = None self.login_results = None self.logout_results = None self.time_diff = 0 # difference between unix and muse time self.sio = socketio.AsyncServer(async_mode='sanic') self.app = Sanic() self.sio.attach(self.app) def connect(self, ip, port): self.socket_client = SocketIO(ip, port) self.socket_client.connect() def disconnect(self): self.socket_client.disconnect() def create_streams(self): self.streams['eeg'] = self._create_eeg_stream() self.streams['marker'] = self._create_marker_stream() # TODO: some kind of switching between training and prediction modes data = { 'event_time': 0.4, # or 0.2? 'train_epochs': 120 } # 120 for 2 min, 240 for 4 min self.streams['ml'] = self._create_ml_stream(data) def start_streams(self): for stream in ['eeg', 'marker', 'ml']: self._start_stream(stream) while len(self.streams['eeg'].data) == 0: time.sleep(0.1) self.time_diff = time.time() - self.streams['eeg'].data[-1][-1] def change_mode(self, train_mode=False): """ train_mode=True for training mode train_mode=False for prediction mode """ if self.streams['ml'] is None: raise Exception(f"ml stream does is not running") curr_mode = self.streams['ml'].get_mode() if curr_mode is not train_mode: self.train_mode = train_mode self.streams['ml'].set_mode(train_mode) async def start_event_loop(self): """Continuously pulls data from ml_stream and sends to server based on whether we are training or predicting""" if self.streams.get('ml') is None: raise Exception(f"ml stream does not exist") data = None while data is None: # send training jobs to server if self.train_mode: data = self.streams['ml'].get_training_data() if data is not None: uuid = data['uuid'] train_data = data['train_data'] train_targets = data['train_targets'] self.train(uuid, train_data, train_targets) return # send prediction jobs to server else: data = self.streams['ml'].get_prediction_data() if data is not None: uuid = data['uuid'] eeg_data = data['eeg_data'] self.predict(uuid, eeg_data) return time.sleep(0.1) # # Callback funcs # def on_retrieve_prediction_results(self, *args): results = args[1] self.pred_results.append(results) def on_train_results(self, *args): results = args[1] self.train_results.append(results) def on_register_results(self, *args): self.register_results = args def on_login_results(self, *args): self.login_results = args def on_logout_results(self, *args): self.logout_results = args # # Server-side communication # def predict(self, uuid, eeg_data): data = (uuid, eeg_data) self.socket_client.emit("retrieve_prediction_results", data, self.on_retrieve_prediction_results) self.socket_client.wait_for_callbacks(seconds=1) def train(self, uuid, eeg_data, p300): data = (uuid, eeg_data, p300) self.socket_client.emit("train_classifier", data, self.on_train_results) self.socket_client.wait_for_callbacks(seconds=1) def register(self, username, password, email): data = (username, password, email) self.socket_client.emit("register", data, self.on_register_results) self.socket_client.wait_for_callbacks(seconds=1) while not self.register_results: time.sleep(.1) return self.register_results def login(self, username, password): data = (username, password) self.socket_client.emit("login", data, self.on_login_results) self.socket_client.wait_for_callbacks(seconds=1) while not self.login_results: time.sleep(.1) return self.login_results def logout(self): self.socket_client.emit("logout", None, self.on_logout_results) self.socket_client.wait_for_callbacks(seconds=1) while not self.logout_results: time.sleep(.1) return self.logout_results # # Private methods for creating and starting streams # @staticmethod def _create_eeg_stream(): return EEGStream(thread_name='EEG_data', event_channel_name='P300') def _create_marker_stream(self): info = pylsl.StreamInfo('Markers', 'Markers', 4, 0, 'string', 'mywid32') self.marker_outlet = pylsl.StreamOutlet(info) return MarkerStream(thread_name='Marker_stream') def _create_ml_stream(self, data): if self.streams.get('eeg') is None: raise Exception(f"EEG stream does not exist") if self.streams.get('marker') is None: raise Exception(f"Marker stream does not exist") return MLStream(m_stream=self.streams['marker'], eeg_stream=self.streams['eeg'], event_time=data['event_time'], train_epochs=data['train_epochs']) def _start_stream(self, stream): if self.streams.get(stream) is None: raise RuntimeError( "Cannot start {0} stream, stream does not exist".format( stream)) elif stream == 'ml': self.streams[stream].start(self.train_mode) else: self.streams[stream].lsl_connect() # # Handlers for communication with front end # def initialize_handlers(self): self.sio.on("train", self.train_handler) self.sio.on("predict", self.predict_handler) self.sio.on("register", self.register_handler) self.sio.on("login", self.login_handler) self.sio.on("logout", self.logout_handler) async def register_handler(self, sid, args): args = json.loads(args) username = args['username'] password = args['password'] email = args['email'] return self.register(username, password, email) async def login_handler(self, sid, args): args = json.loads(args) username = args['username'] password = args['password'] return self.login(username, password) async def logout_handler(self, sid): return self.logout() async def train_handler(self, sid, args): if not self.train_mode: self.change_mode(train_mode=True) time.sleep(.2) args = json.loads(args) uuid = args['uuid'] timestamp = args['timestamp'] p300 = args['p300'] timestamp -= self.time_diff package = [ str(timestamp), str(p300), # target str(1), # 1 event total str(uuid) # take uuid for epoch id ] self.marker_outlet.push_sample(package) await self.start_event_loop() while len(self.train_results) == 0: time.sleep(.1) score = self.train_results.pop(0) return sid, score async def predict_handler(self, sid, args): if self.train_mode: self.change_mode(train_mode=False) time.sleep(.2) args = json.loads(args) uuid = args['uuid'] timestamp = args['timestamp'] timestamp -= self.time_diff package = [ str(timestamp), str(0), # target str(1), # 1 event total str(uuid) # take uuid for epoch id ] self.marker_outlet.push_sample(package) await self.start_event_loop() while len(self.pred_results) == 0: time.sleep(.1) pred = self.pred_results.pop(0) uuid, p300, score = pred results = {'uuid': uuid, 'p300': p300, 'score': score} return sid, results
class Streaming: def __init__(self, config: ConfigDTO = None, wait_for_connection=True): super().__init__() self.__config = copy.deepcopy(config) self.wait_for_connection = wait_for_connection self.q = queue.Queue(maxsize=1000) self.condition = Condition(RLock()) self.started = False self.waiting = False self.socketIO = None def __build(self): #while True: data_auth = { 'username': self.__config.streaming.username, 'password': self.__config.streaming.password } self.socketIO = SocketIO(host=self.__config.streaming.host, port=self.__config.streaming.port, Namespace=Namespace, wait_for_connection=self.wait_for_connection, params=data_auth) self.socketIO.wait(seconds=1) def __check_socket(self): if self.socketIO and self.socketIO.connected == False: self.socketIO.connect() def initialize(self): try: self.__build() self.__check_socket() except Exception as e: print(e) def __on_bbb_response(self, *args): print('on_bbb_response', args) def __process(self, item: StreamDTO = None) -> None: try: if item is None: return jpeg = item.image.tobytes() jpeg = base64.b64encode(jpeg).decode('utf-8') image = "data:image/jpeg;base64,{}".format(jpeg) item = { 'image': True, 'source': item.source, 'buff': image, 'username': self.__config.streaming.username } self.__check_socket() if self.socketIO: self.socketIO.emit('handle_frame', item, callback=self.__on_bbb_response) except Exception as e: print(e) def __worker(self): while self.started == True: if self.q.empty() == True: with self.condition: self.waiting = True self.condition.wait() self.waiting = False else: item = self.q.get() self.__process(item) self.q.task_done() def put_nowait(self, item: StreamDTO = None) -> None: global start_broadcasting if start_broadcasting > 1: self.q.put_nowait(item) self.run() if self.waiting == True: with self.condition: self.condition.notify_all() def put(self, item: StreamDTO = None, block=True, timeout=None) -> None: global start_broadcasting if start_broadcasting > 1: self.q.put(item, block, timeout) self.run() if self.waiting == True: with self.condition: self.condition.notify_all() def run(self) -> None: if self.started == True: return self.started = True self.thr = Thread(target=self.__worker, daemon=True) self.thr.start() def join(self) -> None: self.q.join() def __unsuscriber(self): if self.socketIO: #self.socketIO.emit('on_unsubscriber', callback=self.__on_bbb_response) self.socketIO.emit('unsubscriber', callback=self.__on_bbb_response) self.socketIO.wait_for_callbacks(seconds=1) self.socketIO.disconnect() def stop(self): self.started = False self.__unsuscriber() def __del__(self): self.__config = None self.q = None self.started = None self.socketIO = None self.condition = None self.waiting = None self.wait_for_connection = None
class WaptTestHost(object): def __init__(self,config_filename = 'c:/wapt/wapt-get.ini'): self.config_filename = config_filename self.config = WaptServiceConfig(config_filename) self.socketio_client = None self.wapt_remote_calls = None def run(self): self.config.reload_if_updated() with Wapt(config_filename = self.config.config_filename) as tmp_wapt: logger.info('Starting socketio on "%s://%s:%s" ...' % (self.config.websockets_proto,self.config.websockets_host,self.config.websockets_port)) logger.debug('Certificate checking : %s' % self.config.websockets_verify_cert) while True: try: if not self.socketio_client and self.config.websockets_host: logger.debug('Creating socketio client') logger.debug('Proxies : %s'%self.config.waptserver.proxies) # bug in socketio... ? we must not pass proxies at all (even None) if we don"t want to switch to polling mode... kwargs = {} if self.config.waptserver.proxies and self.config.waptserver.proxies.get(self.config.websockets_proto,None) is not None: kwargs['proxies'] = self.config.waptserver.proxies if not self.socketio_client: self.socketio_client = SocketIO( host="%s://%s" % (self.config.websockets_proto,self.config.websockets_host), port=self.config.websockets_port, Namespace = WaptSocketIORemoteCalls, verify=self.config.websockets_verify_cert, wait_for_connection = False, transport = ['websocket'], ping_interval = self.config.websockets_ping, hurry_interval_in_seconds = self.config.websockets_hurry_interval, params = {'uuid': tmp_wapt.host_uuid,'login':self.config.websockets_auth}, **kwargs) #self.socketio_client.get_namespace().wapt = tmp_wapt if self.socketio_client and self.config.websockets_host: if not self.socketio_client.connected: self.socketio_client._http_session.params.update({'uuid': tmp_wapt.host_uuid,'login':self.config.websockets_auth}) self.socketio_client.define(WaptSocketIORemoteCalls) #self.socketio_client.get_namespace().wapt = tmp_wapt self.socketio_client.connect('') if self.socketio_client.connected: logger.info('Socket IO listening for %ss' % self.config.websockets_check_config_interval ) self.socketio_client.wait(self.config.websockets_check_config_interval) self.config.reload_if_updated() except Exception as e: print('Error in socket io connection %s' % repr(e)) self.config.reload_if_updated() if self.socketio_client: print('stop sio client') self.socketio_client._close() del self.socketio_client self.socketio_client = None if self.socketio_client and self.config.websockets_host: self.socketio_client._http_session.params.update({'uuid': tmp_wapt.host_uuid,'login':self.config.websockets_auth}) logger.info('Socket IO Stopped, waiting %ss before retrying' % self.config.websockets_retry_delay) time.sleep(self.config.websockets_retry_delay)
class WaptSocketIOClient(threading.Thread): def __init__(self,config_filename = 'c:/wapt/wapt-get.ini',task_manager=None): threading.Thread.__init__(self) self.name = 'SocketIOClient' self.config_filename = config_filename self.task_manager = task_manager self.config = WaptServiceConfig(config_filename) self.socketio_client = None self.wapt_remote_calls = None def run(self): self.config.reload_if_updated() with Wapt(config_filename = self.config.config_filename) as tmp_wapt: logger.info('Starting socketio on "%s://%s:%s" ...' % (self.config.websockets_proto,self.config.websockets_host,self.config.websockets_port)) logger.debug('Certificate checking : %s' % self.config.websockets_verify_cert) while True: try: connect_params = dict( uuid = tmp_wapt.host_uuid, ) host_key = tmp_wapt.get_host_key() host_cert = tmp_wapt.get_host_certificate() if not self.socketio_client and self.config.websockets_host: logger.debug('Creating socketio client') logger.debug('Proxies : %s'%self.config.waptserver.proxies) # bug in socketio... ? we must not pass proxies at all (even None) if we don"t want to switch to polling mode... kwargs = {} if self.config.waptserver.proxies and self.config.waptserver.proxies.get(self.config.websockets_proto,None) is not None: kwargs['proxies'] = self.config.waptserver.proxies signed_connect_params = host_key.sign_claim(connect_params,signer_certificate_chain = host_cert) self.socketio_client = SocketIO( host="%s://%s" % (self.config.websockets_proto,self.config.websockets_host), port=self.config.websockets_port, Namespace = WaptSocketIORemoteCalls, resource=self.config.websockets_root, verify=self.config.websockets_verify_cert, wait_for_connection = False, transport = ['websocket'], ping_interval = self.config.websockets_ping, hurry_interval_in_seconds = self.config.websockets_hurry_interval, params = {'uuid': tmp_wapt.host_uuid, 'login':jsondump(signed_connect_params)}, **kwargs) self.socketio_client.get_namespace().wapt = tmp_wapt self.socketio_client.get_namespace().task_manager = self.task_manager if self.socketio_client and self.config.websockets_host: if not self.socketio_client.connected: signed_connect_params = host_key.sign_claim(connect_params,signer_certificate_chain = host_cert) self.socketio_client._http_session.params.update({'uuid': tmp_wapt.host_uuid,'login':jsondump(signed_connect_params)}) self.socketio_client.define(WaptSocketIORemoteCalls) self.socketio_client.get_namespace().wapt = tmp_wapt self.socketio_client.get_namespace().task_manager = self.task_manager self.socketio_client.connect('') else: self.socketio_client.emit('wapt_pong') if self.socketio_client.connected: logger.info('Socket IO listening for %ss' % self.config.websockets_check_config_interval ) startwait = time.time() self.socketio_client.wait(self.config.websockets_check_config_interval) # QAD workaround for cases where server disconnect but client is between 2 states. # In this case; wait() immediately returns, leading to an indefinite loop eating 1 core. if time.time() - startwait < self.config.websockets_check_config_interval-2: raise Exception('Websocket client seems disconnected. Force Websocket connection to be recreated') elif not self.config.websockets_host: self.socketio_client = None time.sleep(self.config.websockets_retry_delay) else: time.sleep(self.config.websockets_retry_delay) if self.config.reload_if_updated(): if self.socketio_client: self.socketio_client.disconnect() raise EWaptException('Configuration changed, force Websocket connection to be recreated') except Exception as e: try: logger.info('Error in socket io connection %s' % repr(e)) self.config.reload_if_updated() if self.socketio_client: logger.debug('stop sio client') self.socketio_client = None finally: logger.debug('Socket IO Stopped, waiting %ss before retrying' % self.config.websockets_retry_delay) time.sleep(self.config.websockets_retry_delay)
#!/usr/bin/env python import os import sys import time if __name__ == '__main__': sPath=os.path.dirname(os.path.realpath(__file__))+'/' sys.path.append(sPath+'../../../lib/python2.7/site-packages/') from socketIO_client import SocketIO info = {"id": "26.9604492_38.2381801" ,"country": "TUR", "city" : "Izmir", "longitude" : 26.9604492, "latitude": 38.2381801} coordinate = "{ \"id\":\"%s\", \"country\":\"%s\", \"city\":\"%s\", \"x\": %f, \"y\": %f}"\ % (info['id'], info['country'], info['city'], info['longitude'], info['latitude']) socketIO = SocketIO('127.0.0.1', 80) chatSocket = socketIO.connect('/new-event') for x in range(0, 100) : chatSocket.emit('update', coordinate) time.sleep(0.2) print coordinate
# info_hijack = { # "key": <hijack_key>, # "prefix": <prefix> # } try: info_hijack = json.loads(args.info_hijack) log.info("Preparing to mitigate via deaggregation hijack {}".format( info_hijack)) hijacked_prefix = str2ip(info_hijack["prefix"]) hijacked_prefix_len = hijacked_prefix.prefixlen deagg_len_threshold = 24 if hijacked_prefix.version == 6: deagg_len_threshold = 64 if hijacked_prefix_len < deagg_len_threshold: subnets = list(map(str, list(hijacked_prefix.subnets()))) log.info("Subnets to announce: {}".format(subnets)) for subnet in subnets: exa_command = "announce route {} next-hop self".format(subnet) sio = SocketIO("http://" + EXA_ROUTE_COMMAND_HOST, namespace=BaseNamespace) sio.connect() sio.emit("route_command", {"command": exa_command}) sio.disconnect() else: log.info("Cannot deaggregate a prefix more specific than /{}".format( deagg_len_threshold - 1)) except Exception as e: log.error("Exception occurred while deaggregating") log.error(e)
class User(): def __init__(self, user_id): self.current_hand = [] self.user_id = user_id self.socketio = SocketIO("localhost", 5000) self.socketio.emit("join_game", self.user_id) self.socketio.on("deal", self.deal) self.socketio.on("action", self.action) self.socketio.on("broadcast_move", self.receive_move) self.socketio.on("result", self.result) self.socketio.connect() self.socketio.wait() # call join game def deal(self, hand): # accept cards and put into hand self.current_hand = [Card(card['number'], card['suit']) for card in hand] def action(self, data): pass def receive_move(self, move_json, my_move): pass def result(self, data): pass def make_move(self, card, board, locations): move = Move() move.played = card if card.number == 11: move.taken = [c for c in board.cards if c.number < 12] move.taken.append(card) elif not locations: # placed card on board move.taken = [] else: #not jack, not empty move.taken = [card] move.taken.extend([board.cards[loc] for loc in locations]) return move def is_valid_turn(self, card, board, locations): # card is type Card # board is type Board # locations is a list if locations == []: # Jack if card.number == 11: return True # Q, K elif card.number > 11: # return fasle if that same card number is on the board return not card.number in [board_card.number for board_card in board.cards] # Numbered Card else: compliment = 11 - card.number number_list = [board_card.number for board_card in board.cards if board_card.number < 11] return not self.checkSum(number_list, compliment, len(number_list)) else: for loc in locations: if loc >= len(board.cards): return False # J if card.number == 11: return False # Q, K elif card.number > 11: if len(locations) > 1: return False else: return card.number == board.cards[locations[0]].number # Numbered Card else: return 11 == card.number + sum(board.cards[loc].number for loc in locations) #subset sum problem def checkSum(self, number_list, sum, n): if sum == 0: # base case where we have reached sum return True elif n == 0: # base case where we did not reach sum return False elif number_list[n-1] > sum: # number is larger than sum return self.checkSum(number_list, sum, n-1) else: return self.checkSum(number_list, sum, n-1) or self.checkSum(number_list, sum - number_list[n-1], n-1)
filename=options.log_name, level=level) reset_connection_timer = time.time() while True: try: # infinite loop socketIO.wait(seconds=0.1) if time.time() - reset_connection_timer > 3600: # reset connection to avoid buildup of broadcast # messages (unlikely but could happen for very long # experiments with slow dpu code/computer) logger.info('resetting connection to eVOLVER to avoid ' 'potential buildup of broadcast messages') socketIO.disconnect() socketIO.connect() reset_connection_timer = time.time() except KeyboardInterrupt: try: print('Ctrl-C detected, pausing experiment') logger.warning('interrupt received, pausing experiment') EVOLVER_NS.stop_exp() # stop receiving broadcasts socketIO.disconnect() while True: key = input( 'Experiment paused. Press enter key to restart ' ' or hit Ctrl-C again to terminate experiment') logger.warning('resuming experiment') # no need to have something like "restart_chemo" here # with the new server logic
return on_type_stream_started() class P300Client(object): def __init__(self): results = [] if __name__ == '__main__': socket_client = SocketIO("localhost", 8001) socket_client.on("eeg_stream_created", on_stream_created) socket_client.on("marker_stream_created", on_stream_created) socket_client.on("ml_stream_created", on_stream_created) socket_client.on("eeg_stream_started", on_stream_created) socket_client.on("marker_stream_started", on_stream_created) socket_client.on("ml_stream_started", on_stream_created) socket_client.connect() socket_client.emit("create_eeg_stream") socket_client.emit("create_marker_stream") socket_client.emit( "create_ml_stream", { 'classifier_path': 'classifer.pkl', 'test_path': 'test_set.pkl', 'analysis_time': 1, 'event_time': 0.2, 'train': True, 'train_epochs': 120, 'get_test': True, }) socket_client.disconnect()
class Streaming(Q): stop_transmission = True def __init__(self, config: ConfigDTO = None, wait_for_connection = True): super().__init__(thread_status = True) self.__config = copy.deepcopy(config) self.wait_for_connection = wait_for_connection self.socketIO = None self.data_auth = {'username': self.__config.streaming.username, 'password': self.__config.streaming.password} def __connect(self, force = False): try: if self.socketIO is None: self.socketIO = SocketIO(host=self.__config.streaming.host, port=self.__config.streaming.port, Namespace=Namespace, wait_for_connection=self.wait_for_connection, params=self.data_auth) self.socketIO.wait(seconds=1) self.__subscribe() elif self.socketIO and self.socketIO.connected == False: self.socketIO.connect() self.socketIO.wait(seconds=1) self.__subscribe() if force == True: self.__subscribe() except Exception as e: raise e def __build_data(self, item: StreamDTO = None): try: jpeg = item.image.tobytes() jpeg = base64.b64encode(jpeg).decode('utf-8') image = "data:image/jpeg;base64,{}".format(jpeg) item = {'image': True, 'source': item.source, 'buff': image} return item except Exception as e: raise e def __on_response(self, *args): pass def __subscribe(self): if self.socketIO: self.socketIO.emit('subscriber', callback=self.__on_response) self.socketIO.wait_for_callbacks(seconds=1) def __unsuscriber(self): if self.socketIO: self.socketIO.emit('unsubscriber', callback=self.__on_response) self.socketIO.wait_for_callbacks(seconds=1) self.socketIO.disconnect() def process_item(self, item: StreamDTO = None) -> None: try: if Streaming.stop_transmission == True: return if item is None: return item = self.__build_data(item) self.__connect(force=False) self.socketIO.emit('cv-data', item, callback=self.__on_response) except Exception as e: print("Streaming__process_item", e) def empty_queue_for_lock(self)-> None: if self.__config.streaming.delay > 0: time.sleep(self.__config.streaming.delay) else: self.apply_lock() def process_status(self)-> None: try: self.__connect(force=True) if self.__config.streaming.delay_status > 0: time.sleep(self.__config.streaming.delay_status) except Exception as e: print("Streaming__process_status", e) def initialize(self): self.__connect(force=False) self.run_queue() def stop(self) -> None: self.stop_queue() self.__unsuscriber() Streaming.stop_transmission = True
class Namespace(BaseNamespace): def on_connect(self, socketIO): print '[Connected]' self.socketIO.emit('subscribe', {'my': 'mynick'}) def on_disconnect(self): print '[Disconnected]' def on_error(self, name, message): print '[Error] %s: %s' % (name, message) def on_message(self, id, message): print '[Message] %s: %s' % (id, message) def on_welcome(self, id, message): print '[Welcome] %s: %s' % (id, message) def on_subscribe(self, id, message): print '[Welcome] %s: %s' % (id, message) def on_test(self, message): print '[Test] message: %s' % (message) socketIO = SocketIO('127.0.0.1', 8000) chatSocket = socketIO.connect('/chat', Namespace) #socketIO.emit('aaa', {'bbb': 'ccc'}) socketIO.wait()
class Muse(Device): def __init__(self, device_id=None): super().__init__(device_id) self.streams = {} self.pred_results = [] self.train_results = [] self.time_diff = 0 # difference between unix and muse time self.train_mode = True # True for training, False for prediction # socket for communicating with whatever wants to pull prediction # results from Muse self.sio = socketio.AsyncServer(async_mode='sanic') self.app = Sanic() self.sio.attach(self.app) @staticmethod def available_devices(): pass # # Callback functions # def on_retrieve_prediction_results(self, *args): """Callback function for saving prediction results""" results = args[0] self.pred_results.append(results) def on_train_results(self, *args): """Callback function for saving training results""" results = args[0] self.train_results.append(results) def print_results(self, *args): """Test callback function that simply prints out the results""" for arg in args: print(arg) # # Private device methods for handling data streams # def _create_eeg_stream(self): """Creates a stream that streams EEG data""" return EEGStream(thread_name='EEG_data', event_channel_name='P300') def _create_marker_stream(self): """Create a stream that streams marker data""" info = pylsl.StreamInfo('Markers', 'Markers', 4, 0, 'string', 'mywid32') self.marker_outlet = pylsl.StreamOutlet(info) return MarkerStream(thread_name='Marker_stream') def _create_ml_stream(self, data): """Creates a stream that combines the EEG and marker streams, and forms epochs based on timestamp""" if self.streams.get('eeg') is None: raise Exception(f"EEG stream does not exist") if self.streams.get('marker') is None: raise Exception(f"Marker stream does not exist") return MLStream(m_stream=self.streams['marker'], eeg_stream=self.streams['eeg'], event_time=data['event_time'], train_epochs=data['train_epochs']) def _start_stream(self, stream): """Starts stream given stream name (one of 'eeg', 'marker', or 'ml')""" if self.streams.get(stream) is None: raise RuntimeError( "Cannot start {0} stream, stream does not exist".format( stream)) elif stream == 'ml': self.streams[stream].start(self.train_mode) else: self.streams[stream].lsl_connect() def _stop_stream(self, stream): """Stops stream given stream name (one of 'eeg', 'marker', or 'ml')""" if self.streams.get(stream) is None: raise RuntimeError( "Cannot stop {0} stream, stream does not exist".format(stream)) else: self.streams[stream].stop() # # Methods for handling server communication # def neurostack_connect(self, ip='35.222.93.233', port=8001): """ Connects to neurostack server at ip:port and starts marker and ML streams. If no arguments for ip and port are given, then connects to the default hardcoded address for a server on the cloud. """ self.socket_client = SocketIO(ip, port) self.socket_client.connect() # assumes EEG stream has already been started for stream in ['marker', 'ml']: self._start_stream(stream) while len(self.streams['eeg'].data) == 0: time.sleep(0.1) self.time_diff = time.time() - self.streams['eeg'].data[-1][-1] def neurostack_disconnect(self): """Disconnects from neurostack server and stops marker and ML streams""" for stream in ['marker', 'ml']: self._stop_stream(stream) self.socket_client.disconnect() def send_train_data(self, uuid, eeg_data, p300): """ Sends training data to neurostack server :param uuid: client's UUID :param eeg_data: one sample of EEG data to be used for training :param p300: True if this data represents a p300 signal, else False :returns: None """ args = {'uuid': uuid, 'data': eeg_data, 'p300': p300} self.socket_client.emit("train_classifier", args, self.on_train_results) self.socket_client.wait_for_callbacks(seconds=1) def send_predict_data(self, uuid, eeg_data): """ Sneds prediction data to neurostack server :param uuid: client's UUID :param eeg_data: one sample of EEG data that we want to predict for :returns: None """ args = {'uuid': uuid, 'data': eeg_data} self.socket_client.emit("retrieve_prediction_results", args, self.on_retrieve_prediction_results) self.socket_client.wait_for_callbacks(seconds=1) def change_mode(self, train_mode=False): """ self.train_mode=True for training mode self.train_mode=False for prediction mode """ if self.streams['ml'] is None: raise Exception(f"ml stream does is not running") curr_mode = self.streams['ml'].get_mode() if curr_mode is not train_mode: self.train_mode = train_mode self.streams['ml'].set_mode(train_mode) def send_predict_data_test(self, uuid, eeg_data): """ Tests endpoint for sending prediction data to neurostack server :param uuid: client's UUID :param eeg_data: one sample of EEG data that we want to predict for :returns: None """ args = {'uuid': uuid, 'data': eeg_data} self.socket_client.emit("retrieve_prediction_results_test", args, self.print_results) self.socket_client.wait_for_callbacks(seconds=1) def send_train_data_test(self, uuid, eeg_data, p300): """ Tests endpoint for sending training data to neurostack server :param uuid: client's UUID :param eeg_data: one sample of EEG data to be used for training :param p300: True if this data represents a p300 signal, else False :returns: None """ args = {'uuid': uuid, 'data': eeg_data, 'p300': p300} self.socket_client.emit("train_classifier_test", args, self.print_results) self.socket_client.wait_for_callbacks(seconds=1) # # Methods for handling client-side communication # def initialize_handlers(self): """Initialize handlers for client-side communication""" self.sio.on("train", self.train_handler) self.sio.on("predict", self.predict_handler) self.sio.on("generate_uuid", self.generate_uuid_handler) async def train_handler(self, sid, args): """Handler for passing training data to Neurostack""" if not self.train_mode: self.change_mode(train_mode=True) time.sleep(.2) args = json.loads(args) uuid = args['uuid'] timestamp = args['timestamp'] p300 = args['p300'] timestamp -= self.time_diff package = [ str(timestamp), str(p300), # target str(1), # 1 event total str(uuid) # epoch ID ] self.marker_outlet.push_sample(package) await self.start_event_loop() while len(self.train_results) == 0: time.sleep(.1) return self.train_results.pop(0) async def predict_handler(self, sid, args): """Handler for passing prediction data to Neurostack""" if self.train_mode: self.change_mode(train_mode=False) time.sleep(.2) args = json.loads(args) uuid = args['uuid'] timestamp = args['timestamp'] timestamp -= self.time_diff package = [ str(timestamp), str(0), # target str(1), # 1 event total str(uuid) # epoch ID ] self.marker_outlet.push_sample(package) await self.start_event_loop() while len(self.pred_results) == 0: time.sleep(.1) return self.pred_results.pop(0) async def generate_uuid_handler(self, sid, args): """Handler for sending a request to the server to generate a UUID""" return generate_uuid() async def start_event_loop(self): """ Continuously pulls data from ml_stream and sends to server based on whether we are training or predicting """ if self.streams.get('ml') is None: raise Exception(f"ml stream does not exist") data = None while data is None: # send training jobs to server if self.train_mode: data = self.streams['ml'].get_training_data() if data is not None: uuid = data['uuid'] train_data = data['train_data'] train_targets = data['train_targets'] self.send_train_data(uuid, train_data, train_targets) return # send prediction jobs to server else: data = self.streams['ml'].get_prediction_data() if data is not None: uuid = data['uuid'] eeg_data = data['eeg_data'] self.send_predict_data(uuid, eeg_data) return time.sleep(0.1) # # Public device metods # def connect(self, device_id=None): """ Creates data streams if there are none and connects to EEG stream (since that is the one that is immediately needed for use) """ if self.streams.get('eeg') is None: self.streams['eeg'] = self._create_eeg_stream() if self.streams.get('marker') is None: self.streams['marker'] = self._create_marker_stream() if self.streams.get('ml') is None: data = { 'event_time': 0.4, 'train_epochs': 120 } # 120 for 2 min, 240 for 4 min self.streams['ml'] = self._create_ml_stream(data) self.streams['eeg'].lsl_connect() def start(self): """Start streaming EEG data""" self.streams['eeg'].start() while len(self.streams['eeg'].data) == 0: time.sleep(0.1) self.time_diff = time.time() - self.streams['eeg'].data[-1][-1] def stop(self): """Stop streaming EEG data""" self.streams['eeg'].stop() def shutdown(self): """Disconnect EEG stream (and stop streaming data)""" for stream_name in ['eeg', 'marker', 'ml']: self.streams[stream_name] = None def get_info(self): pass
class WaptSocketIOClient(threading.Thread): def __init__(self,config_filename = 'c:/wapt/wapt-get.ini',task_manager=None,request_timeout=None): threading.Thread.__init__(self) self.name = 'SocketIOClient' self.config_filename = config_filename self.task_manager = task_manager self.config = WaptServiceConfig(config_filename) self.socketio_client = None self.wapt_remote_calls = None self.server_authorization_token = None if request_timeout is None: request_timeout = self.config.websockets_request_timeout self.request_timeout = request_timeout def run(self): self.config.reload_if_updated() with Wapt(config_filename = self.config.config_filename) as tmp_wapt: logger.info('Starting socketio on "%s://%s:%s" ...' % (self.config.websockets_proto,self.config.websockets_host,self.config.websockets_port)) logger.debug('Certificate checking : %s' % self.config.websockets_verify_cert) def get_connect_params(wapt): connect_params = {'uuid': wapt.host_uuid} if not self.server_authorization_token: try: self.server_authorization_token = wapt.get_auth_token('websocket') logger.info('Websocket token: %s' % self.server_authorization_token) connect_params['token'] = self.server_authorization_token except Exception as e: logger.warning('Websocket connect params: %s' % e) self.server_authorization_token = None return {'params':connect_params, 'cert' :(wapt.get_host_certificate_filename(),wapt.get_host_key_filename())} while True: try: connect_params = get_connect_params(tmp_wapt) if not self.socketio_client and self.config.websockets_host: logger.debug('Creating socketio client') logger.debug('Proxies : %s'%self.config.waptserver.proxies) # bug in socketio... ? we must not pass proxies at all (even None) if we don"t want to switch to polling mode... kwargs = {} if self.config.waptserver.proxies and self.config.waptserver.proxies.get(self.config.websockets_proto,None) is not None: kwargs['proxies'] = self.config.waptserver.proxies kwargs.update(connect_params) self.socketio_client = SocketIO( host="%s://%s" % (self.config.websockets_proto,self.config.websockets_host), port=self.config.websockets_port, Namespace = WaptSocketIORemoteCalls, resource=self.config.websockets_root, verify=self.config.websockets_verify_cert, wait_for_connection = False, transport = ['websocket'], ping_interval = self.config.websockets_ping, hurry_interval_in_seconds = self.config.websockets_hurry_interval, request_timeout = self.request_timeout, **kwargs) self.socketio_client.get_namespace().wapt = tmp_wapt self.socketio_client.get_namespace().task_manager = self.task_manager if self.socketio_client and self.config.websockets_host: if not self.socketio_client.connected: self.socketio_client._http_session.update(connect_params) self.socketio_client.define(WaptSocketIORemoteCalls) self.socketio_client.get_namespace().wapt = tmp_wapt self.socketio_client.get_namespace().task_manager = self.task_manager self.socketio_client.connect('') else: # be sure server DB is aware of the current connection. # could be avoided self.socketio_client.emit('wapt_pong') if self.socketio_client.connected: logger.info('Socket IO listening for %ss' % self.config.websockets_check_config_interval ) startwait = time.time() self.socketio_client.wait(self.config.websockets_check_config_interval) # QAD workaround for cases where server disconnect but client is between 2 states. # In this case; wait() immediately returns, leading to an indefinite loop eating 1 core. if time.time() - startwait < self.config.websockets_check_config_interval-2: raise Exception('Websocket client seems disconnected. Force Websocket connection to be recreated') elif not self.config.websockets_host: self.socketio_client = None time.sleep(self.config.websockets_retry_delay) else: time.sleep(self.config.websockets_retry_delay) if self.config.reload_if_updated(): tmp_wapt.reload_config_if_updated() if self.socketio_client: self.socketio_client.disconnect() raise EWaptException('Configuration changed, force Websocket connection to be recreated') except Exception as e: try: # reset token self.server_authorization_token = None self.config.reload_if_updated() if self.socketio_client: self.socketio_client = None finally: logger.info(u'Exception %s, Socket IO Stopped, waiting %ss before retrying' % (repr(e),self.config.websockets_retry_delay)) time.sleep(self.config.websockets_retry_delay)
from socketIO_client import SocketIO, BaseNamespace class Namespace(BaseNamespace): def on_connect(self, socketIO): print '[Connected]' self.socketIO.emit('subscribe' , {'my': 'mynick'}); def on_disconnect(self): print '[Disconnected]' def on_error(self, name, message): print '[Error] %s: %s' % (name, message) def on_message(self, id, message): print '[Message] %s: %s' % (id, message) def on_welcome(self, id, message): print '[Welcome] %s: %s' % (id, message) def on_subscribe(self, id, message): print '[Welcome] %s: %s' % (id, message) def on_test(self, message): print '[Test] message: %s' % (message) socketIO = SocketIO('127.0.0.1', 8000) chatSocket = socketIO.connect('/chat', Namespace) #socketIO.emit('aaa', {'bbb': 'ccc'}) socketIO.wait()
class Neurostack: def __init__(self, devices=None): """ Initialize a connection with an EEG device, and sets up an asynchronous connection with subscribers passed in. :param device: [Devices] """ self.devices = devices # sanic server connects to app self.sio_app = socketio.AsyncServer(async_mode='sanic', cors_allowed_origins='*') self.sio_app_server = Sanic() self.sio_app.attach(self.sio_app_server) # socketIO client connects to neurostack server self.sio_neurostack = None self.train_results = {} self.predict_results = {} self.stream_raw_data = {} # # Methods for handling devices # def start(self, list_of_devices=None): """ Start streaming EEG from device, and publish data to subscribers. :param list_of_devices: [Device] List of devices to start streaming. If none, all devices will start streaming. :return: None """ if list_of_devices is None: devices_to_start = self.devices else: devices_to_start = list_of_devices for device in devices_to_start: device.start() def stop(self, list_of_devices=None): """ Stop streaming EEG data from device, and stop publishing data to subscribers. Connection to device remains intact, and device is not turned off. :param list_of_devices: [Device] List of devices to stop streaming. If none, all devices will stop streaming. :return: None """ if list_of_devices is None: devices_to_start = self.devices else: devices_to_start = list_of_devices for device in devices_to_start: device.stop() def shutdown(self, list_of_devices=None): """ Close connection to device, WebSocket connections to publishers, and tag sources. :return: None """ pass # # Methods for handling server-side communication # def neurostack_connect(self, ip='neurostack.neurotechuoft.com', port=8001): """ Connects to neurostack server at ip:port. If no arguments for ip and port are given, then connects to the default hardcoded address for a server on the cloud. """ self.sio_neurostack = SocketIO(ip, port) self.sio_neurostack.connect() def neurostack_disconnect(self): """Disconnects from neurostack server""" self.sio_neurostack.disconnect() def send_train_data(self, server_endpoint, uuid, eeg_data, label): """ Sends training data to neurostack server :param server_endpoint: server API's endpoint :param uuid: client's UUID :param eeg_data: one sample of EEG data to be used for training :param label: this data's label :returns: None """ args = {'uuid': uuid, 'data': eeg_data, 'label': label} self.sio_neurostack.emit(server_endpoint, args, self.on_train_results) self.sio_neurostack.wait_for_callbacks(seconds=1) def send_predict_data(self, server_endpoint, uuid, eeg_data): """ Sneds prediction data to neurostack server :param server_endpoint: server API's endpoint :param uuid: client's UUID :param eeg_data: one sample of EEG data that we want to predict for :returns: None """ args = {'uuid': uuid, 'data': eeg_data} self.sio_neurostack.emit(server_endpoint, args, self.on_predict_results) self.sio_neurostack.wait_for_callbacks(seconds=1) def send_train_data_test(self, uuid, eeg_data, label): """ Tests endpoint for sending training data to neurostack server :param uuid: client's UUID :param eeg_data: one sample of EEG data to be used for training :param label: this data's label :returns: None """ args = {'uuid': uuid, 'data': eeg_data, 'label': label} self.sio_neurostack.emit("test_train", args, self.print_results) self.sio_neurostack.wait_for_callbacks(seconds=1) def send_predict_data_test(self, uuid, eeg_data): """ Tests endpoint for sending prediction data to neurostack server :param uuid: client's UUID :param eeg_data: one sample of EEG data that we want to predict for :returns: None """ args = {'uuid': uuid, 'data': eeg_data} self.sio_neurostack.emit("test_predict", args, self.print_results) self.sio_neurostack.wait_for_callbacks(seconds=1) # # Methods for handling client-side communication # def initialize_handlers(self): """Initialize handlers for client-side communication""" # streaming raw data self.sio_app.on("start_streaming_raw_data", self.start_streaming_raw_data_handler) self.sio_app.on("stop_streaming_raw_data", self.stop_streaming_raw_data_handler) # training Neurostack model self.sio_app.on("p300_train", self.p300_train_handler) self.sio_app.on("p300_predict", self.p300_predict_handler) self.sio_app.on("left_right_train", self.left_right_train_handler) self.sio_app.on("left_right_predict", self.left_right_predict_handler) # misc self.sio_app.on("generate_uuid", self.generate_uuid_handler) def run(self, host='localhost', port=8002): """ Runs Neurostack on host:port. This is used as an endpoint for client-side communication. :param host: local address to Neurostack on :param port: port to run Neurostack on :return: None """ self.sio_app_server.run(host=host, port=port) async def start_streaming_raw_data_handler(self, sid, args): """ Handler for streaming raw data :param sid: session ID (not important) :param args: arguments passed to this function. This should include: uuid: universally unique ID of user who wants to stop streaming """ args = json.loads(args) uuid = args['uuid'] self.stream_raw_data[uuid] = True # keep track of data from previous while loop iteration, so that the # same data is not sent twice. prev_data = None while self.stream_raw_data[uuid]: # TODO: devices[0] is the Muse that we set at the bottom, but we # want to support multiple or different devices data_stream = self.devices[0].data_stream eeg_channel_names = data_stream.get_eeg_channels() raw_data = data_stream.get_latest_data(eeg_channel_names) # TODO: raw data can be either a list or a dict right now, should we # just stick with dict? # in case while loop is running faster than device streaming rate if raw_data != prev_data: prev_data = raw_data await self.sio_app.emit('raw_data', raw_data) async def stop_streaming_raw_data_handler(self, sid, args): """ Handler to tell neurostack to stop streaming raw data :param sid: session ID (not important) :param args: arguments passed to this function. This should include: uuid: universally unique ID of user who wants to stop streaming """ args = json.loads(args) uuid = args['uuid'] self.stream_raw_data[uuid] = False await self.sio_app.emit('raw_data', "streaming has stopped") async def p300_train_handler(self, sid, args): """P300 training handler""" args = json.loads(args) await self.train_handler(server_endpoint="p300_train", uuid=args['uuid'], timestamp=args['timestamp'], label=args['p300']) async def p300_predict_handler(self, sid, args): """P300 prediction handler""" args = json.loads(args) await self.predict_handler(server_endpoint="p300_predict", uuid=args['uuid'], timestamp=args['timestamp']) async def left_right_train_handler(self, sid, args): """Left-right training handler""" args = json.loads(args) await self.train_handler(server_endpoint="left_right_train", uuid=args['uuid'], timestamp=args['timestamp'], label=args['left']) async def left_right_predict_handler(self, sid, args): """Left-right prediction handler""" args = json.loads(args) await self.predict_handler(server_endpoint="left_right_predict", uuid=args['uuid'], timestamp=args['timestamp']) async def train_handler(self, server_endpoint, uuid, timestamp, label, window=0.75): """ Handler for passing training data to Neurostack TODO: something for sample rate :param server_endpoint: Neurostack server API endpoint :param uuid: client UUID :param timestamp: timestamp of data we are interested in, in unix time :param label: label for data :param window: window of data we are interested in, in seconds :return: None """ # create list for uuid if not done already self.train_results[uuid] = self.train_results.get(uuid, []) # TODO: change API to specify device device = self.devices[0] # Wait until the device has enough data (ie. the time slice is complete) # then take 100ms - 750ms window for training while time.time() < timestamp + window: time.sleep(.01) # TODO: num_samples = window * sample rate timestamp -= self.devices[0].get_time_diff() data_dict = device.data_stream.get_eeg_data(start_time=timestamp + .1, num_samples=128) data = list(data_dict.values()) self.send_train_data(server_endpoint=server_endpoint, uuid=uuid, eeg_data=data, label=label) # wait for results while len(self.train_results[uuid]) == 0: time.sleep(.01) result = self.train_results[uuid].pop(0) await self.sio_app.emit("train", result) async def predict_handler(self, server_endpoint, uuid, timestamp, window=0.75): """ Handler for passing prediction data to Neurostack TODO: something for sample rate :param server_endpoint: Neurostack server API endpoint :param uuid: client UUID :param timestamp: timestamp of data we are interested in, in unix time :param window: window of data we are interested in, in seconds :return: None """ # create list for uuid if not done already self.predict_results[uuid] = self.predict_results.get(uuid, []) # TODO: change API to specify device device = self.devices[0] # Wait until the device has enough data (ie. the time slice is complete) # then take 100ms - 750ms window for training. The window should # contain 0.65s * 256Hz = 166 samples. while time.time() < timestamp + window: time.sleep(.01) timestamp -= self.devices[0].get_time_diff() data_dict = device.data_stream.get_eeg_data(start_time=timestamp + .1, num_samples=128) data = list(data_dict.values()) self.send_predict_data(server_endpoint=server_endpoint, uuid=uuid, eeg_data=data) # wait for results while len(self.predict_results[uuid]) == 0: time.sleep(.01) result = self.predict_results[uuid].pop(0) await self.sio_app.emit("predict", result) async def generate_uuid_handler(self, sid, args): """Handler for sending a request to the server to generate a UUID""" uuid = generate_uuid() await self.sio_app.emit('generate_uuid', uuid) # # Callback functions # def on_train_results(self, *args): """Callback function for saving training results""" results = args[0] uuid = results['uuid'] self.train_results[uuid].append(results) def on_predict_results(self, *args): """Callback function for saving prediction results""" results = args[0] uuid = results['uuid'] self.predict_results[uuid].append(results) def print_results(self, *args): """Prints out results""" print(args) # # Other methods # def get_info(self, list_of_devices=None) -> []: """ Return list of string representations of device info for specified devices (by calling get_info of each device). By default lists info of all devices under Neurostack. :return: """ if list_of_devices is None: devices_to_start = self.devices else: devices_to_start = list_of_devices info = [device.get_info() for device in devices_to_start] return info