psychopy-neuroplaypro-neurolab 0.1.0__py3-none-any.whl → 0.1.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- psychopy_neuroplaypro_neurolab/__init__.py +7 -1
- psychopy_neuroplaypro_neurolab/neuroplay.py +46 -0
- psychopy_neuroplaypro_neurolab/neuroplay_record/__init__.py +100 -0
- psychopy_neuroplaypro_neurolab/neuroplay_record/classic/neuroplay_record.png +0 -0
- psychopy_neuroplaypro_neurolab/neuroplay_record/classic/neuroplay_record@2x.png +0 -0
- psychopy_neuroplaypro_neurolab/neuroplay_record/dark/neuroplay_record.png +0 -0
- psychopy_neuroplaypro_neurolab/neuroplay_record/dark/neuroplay_record@2x.png +0 -0
- psychopy_neuroplaypro_neurolab/neuroplay_record/light/neuroplay_record.png +0 -0
- psychopy_neuroplaypro_neurolab/neuroplay_record/light/neuroplay_record@2x.png +0 -0
- psychopy_neuroplaypro_neurolab-0.1.2.dist-info/METADATA +18 -0
- psychopy_neuroplaypro_neurolab-0.1.2.dist-info/RECORD +15 -0
- {psychopy_neuroplaypro_neurolab-0.1.0.dist-info → psychopy_neuroplaypro_neurolab-0.1.2.dist-info}/WHEEL +1 -1
- psychopy_neuroplaypro_neurolab-0.1.2.dist-info/entry_points.txt +2 -0
- psychopy_neuroplaypro_neurolab/plugin.py +0 -8
- psychopy_neuroplaypro_neurolab-0.1.0.dist-info/METADATA +0 -9
- psychopy_neuroplaypro_neurolab-0.1.0.dist-info/RECORD +0 -8
- psychopy_neuroplaypro_neurolab-0.1.0.dist-info/entry_points.txt +0 -5
- {psychopy_neuroplaypro_neurolab-0.1.0.dist-info → psychopy_neuroplaypro_neurolab-0.1.2.dist-info}/licenses/LICENSE +0 -0
- {psychopy_neuroplaypro_neurolab-0.1.0.dist-info → psychopy_neuroplaypro_neurolab-0.1.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
# neuroplay.py (в корне плагина)
|
2
|
+
|
3
|
+
__all__ = ['NeuroPlayProClient']
|
4
|
+
|
5
|
+
import websocket
|
6
|
+
import threading
|
7
|
+
import json
|
8
|
+
import time
|
9
|
+
|
10
|
+
|
11
|
+
class NeuroPlayProClient:
|
12
|
+
def __init__(self, url="ws://localhost:11234"):
|
13
|
+
self.url = url
|
14
|
+
self.ws = None
|
15
|
+
self.running = False
|
16
|
+
self.listen_thread = None
|
17
|
+
self.messages = []
|
18
|
+
|
19
|
+
def connect(self):
|
20
|
+
self.ws = websocket.create_connection(self.url)
|
21
|
+
|
22
|
+
def send_marker(self, label="TRIGGER"):
|
23
|
+
self.ws.send(json.dumps({"marker": label}))
|
24
|
+
|
25
|
+
def close(self):
|
26
|
+
if self.ws:
|
27
|
+
self.ws.close()
|
28
|
+
|
29
|
+
def listen(self):
|
30
|
+
self.running = True
|
31
|
+
|
32
|
+
def loop():
|
33
|
+
while self.running:
|
34
|
+
try:
|
35
|
+
msg = self.ws.recv()
|
36
|
+
self.messages.append(msg)
|
37
|
+
except:
|
38
|
+
self.running = False
|
39
|
+
|
40
|
+
self.listen_thread = threading.Thread(target=loop)
|
41
|
+
self.listen_thread.start()
|
42
|
+
|
43
|
+
def stop(self):
|
44
|
+
self.running = False
|
45
|
+
if self.listen_thread:
|
46
|
+
self.listen_thread.join()
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
"""
|
3
|
+
NeuroplayRecordingComponent
|
4
|
+
Инициализация и управление записью NeuroPlayPro через WebSocket из PsychoPy Builder
|
5
|
+
"""
|
6
|
+
|
7
|
+
__all__ = ['NeuroplayRecordingComponent']
|
8
|
+
|
9
|
+
from pathlib import Path
|
10
|
+
from psychopy.experiment.components import BaseComponent, Param, getInitVals
|
11
|
+
|
12
|
+
WS_OBJ = 'ws_neuro'
|
13
|
+
|
14
|
+
class NeuroplayRecordingComponent(BaseComponent):
|
15
|
+
categories = ['EEG']
|
16
|
+
targets = ['PsychoPy']
|
17
|
+
iconFile = Path(__file__).parent / 'neuroplay_record.png'
|
18
|
+
tooltip = 'Start/Stop EEG recording via NeuroPlayPro'
|
19
|
+
plugin = "psychopy-neuroplaypro-neurolab"
|
20
|
+
|
21
|
+
def __init__(self, exp, parentName, name='neuroplay_rec'):
|
22
|
+
super().__init__(
|
23
|
+
exp, parentName, name=name,
|
24
|
+
startType='time (s)', startVal=0,
|
25
|
+
stopType='duration (s)', stopVal=1.0,
|
26
|
+
startEstim='', durationEstim='',
|
27
|
+
saveStartStop=False
|
28
|
+
)
|
29
|
+
|
30
|
+
self.type = 'NeuroplayRecording'
|
31
|
+
self.exp.requireImport(importName='websocket')
|
32
|
+
self.exp.requireImport(importName='json')
|
33
|
+
|
34
|
+
self.params['wsURL'] = Param("ws://localhost:1336", valType='str', inputType='editable',
|
35
|
+
hint="WebSocket адрес NeuroPlayPro")
|
36
|
+
|
37
|
+
def writeInitCode(self, buff):
|
38
|
+
inits = getInitVals(self.params, 'PsychoPy')
|
39
|
+
code = (f'{inits["name"]} = visual.BaseVisualStim(' +
|
40
|
+
'win=win, name="{}")\n'.format(inits['name']))
|
41
|
+
buff.writeIndentedLines(code)
|
42
|
+
|
43
|
+
ws_url = inits['wsURL'].val
|
44
|
+
code = f"{WS_OBJ} = websocket.create_connection(\"{ws_url}\")"
|
45
|
+
buff.writeIndentedLines(code)
|
46
|
+
|
47
|
+
def writeRoutineStartCode(self, buff):
|
48
|
+
inits = getInitVals(self.params, 'PsychoPy')
|
49
|
+
buff.writeIndentedLines("# === Start EEG Recording ===")
|
50
|
+
buff.writeIndentedLines("try:")
|
51
|
+
buff.setIndentLevel(1, relative=True)
|
52
|
+
|
53
|
+
buff.writeIndentedLines('start_record_cmd = json.dumps({"command": "startRecord"})')
|
54
|
+
buff.writeIndentedLines(f"{WS_OBJ}.send(start_record_cmd)")
|
55
|
+
buff.writeIndentedLines(f"response = {WS_OBJ}.recv()")
|
56
|
+
buff.writeIndentedLines("print(f'Response from NeuroPlay: {response}')")
|
57
|
+
|
58
|
+
buff.setIndentLevel(-1, relative=True)
|
59
|
+
buff.writeIndentedLines("except Exception as e:")
|
60
|
+
buff.setIndentLevel(1, relative=True)
|
61
|
+
buff.writeIndentedLines('print(f"Ошибка при старте записи NeuroPlay: {e}")')
|
62
|
+
buff.setIndentLevel(-1, relative=True)
|
63
|
+
|
64
|
+
def writeRoutineEndCode(self, buff):
|
65
|
+
buff.writeIndentedLines("# === Stop EEG Recording ===")
|
66
|
+
buff.writeIndentedLines('print("Stopping NeuroPlay...")')
|
67
|
+
buff.writeIndentedLines("try:")
|
68
|
+
buff.setIndentLevel(1, relative=True)
|
69
|
+
buff.writeIndentedLines('stop_record_cmd = json.dumps({"command": "stopRecord"})')
|
70
|
+
buff.writeIndentedLines(f"{WS_OBJ}.send(stop_record_cmd)")
|
71
|
+
buff.writeIndentedLines(f"response = {WS_OBJ}.recv()")
|
72
|
+
buff.writeIndentedLines("print(f'Response from NeuroPlay: {response}')")
|
73
|
+
buff.setIndentLevel(-1, relative=True)
|
74
|
+
buff.writeIndentedLines("except Exception as e:")
|
75
|
+
buff.setIndentLevel(1, relative=True)
|
76
|
+
buff.writeIndentedLines('print(f"Ошибка при остановке записи NeuroPlay: {e}")')
|
77
|
+
buff.setIndentLevel(-1, relative=True)
|
78
|
+
|
79
|
+
def writeExperimentEndCode(self, buff):
|
80
|
+
buff.writeIndentedLines("# === Close WebSocket connection ===")
|
81
|
+
buff.writeIndentedLines("try:")
|
82
|
+
buff.setIndentLevel(1, relative=True)
|
83
|
+
buff.writeIndentedLines(f"{WS_OBJ}.close()")
|
84
|
+
buff.setIndentLevel(-1, relative=True)
|
85
|
+
buff.writeIndentedLines("except Exception as e:")
|
86
|
+
buff.setIndentLevel(1, relative=True)
|
87
|
+
buff.writeIndentedLines("print(f'Ошибка при закрытии WebSocket: {e}')")
|
88
|
+
buff.setIndentLevel(-1, relative=True)
|
89
|
+
|
90
|
+
def writeFrameCode(self, buff):
|
91
|
+
pass
|
92
|
+
|
93
|
+
def writeFrameCodeJS(self, buff):
|
94
|
+
pass
|
95
|
+
|
96
|
+
def writeExperimentEndCodeJS(self, buff):
|
97
|
+
pass
|
98
|
+
|
99
|
+
def writeInitCodeJS(self, buff):
|
100
|
+
pass
|
@@ -0,0 +1,18 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: psychopy-neuroplaypro-neurolab
|
3
|
+
Version: 0.1.2
|
4
|
+
Summary: PsychoPy plugin to support NeuroPlayPro EEG triggers.
|
5
|
+
Author-email: Enicast <enicaster@gmail.com>
|
6
|
+
Requires-Python: >=3.8
|
7
|
+
Description-Content-Type: text/markdown
|
8
|
+
License-File: LICENSE
|
9
|
+
Requires-Dist: websocket-client
|
10
|
+
Dynamic: license-file
|
11
|
+
|
12
|
+
# PsychoPy NeuroPlay Plugin
|
13
|
+
|
14
|
+
Component for controlling NeuroPlayPro EEG recording from PsychoPy Builder experiments.
|
15
|
+
- Start recording when the component starts
|
16
|
+
- Stop recording when the component ends
|
17
|
+
- Choose folder and filename prefix
|
18
|
+
- Auto-add timestamp if needed
|
@@ -0,0 +1,15 @@
|
|
1
|
+
psychopy_neuroplaypro_neurolab/__init__.py,sha256=y5JhTBeswmpSsJIh_qUlL96qqxsp8Pq4AEnQbte75t8,205
|
2
|
+
psychopy_neuroplaypro_neurolab/neuroplay.py,sha256=nEAE8PtCwWNU_0Uf7ADCfIEE7iTWE_UlLhHhs9V5A7A,1093
|
3
|
+
psychopy_neuroplaypro_neurolab/neuroplay_record/__init__.py,sha256=DWfe0Rrjx5JhjdKHy7KSAw3P57imfjlaFinC1MupRPA,4145
|
4
|
+
psychopy_neuroplaypro_neurolab/neuroplay_record/classic/neuroplay_record.png,sha256=yNpZBfil-_BuELl8Qs873-ywIn8mqe7TLzGNuUcC8cQ,5247
|
5
|
+
psychopy_neuroplaypro_neurolab/neuroplay_record/classic/neuroplay_record@2x.png,sha256=SllL2cBmRscQ3GG2d-oIhf3tcJNloLIJ2br5hUk32QE,8826
|
6
|
+
psychopy_neuroplaypro_neurolab/neuroplay_record/dark/neuroplay_record.png,sha256=yNpZBfil-_BuELl8Qs873-ywIn8mqe7TLzGNuUcC8cQ,5247
|
7
|
+
psychopy_neuroplaypro_neurolab/neuroplay_record/dark/neuroplay_record@2x.png,sha256=SllL2cBmRscQ3GG2d-oIhf3tcJNloLIJ2br5hUk32QE,8826
|
8
|
+
psychopy_neuroplaypro_neurolab/neuroplay_record/light/neuroplay_record.png,sha256=yNpZBfil-_BuELl8Qs873-ywIn8mqe7TLzGNuUcC8cQ,5247
|
9
|
+
psychopy_neuroplaypro_neurolab/neuroplay_record/light/neuroplay_record@2x.png,sha256=SllL2cBmRscQ3GG2d-oIhf3tcJNloLIJ2br5hUk32QE,8826
|
10
|
+
psychopy_neuroplaypro_neurolab-0.1.2.dist-info/licenses/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
11
|
+
psychopy_neuroplaypro_neurolab-0.1.2.dist-info/METADATA,sha256=V5uLSin4wi_eKyPclz3_3ctvrKzlfT7PQ8-eqKLlj3c,590
|
12
|
+
psychopy_neuroplaypro_neurolab-0.1.2.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
|
13
|
+
psychopy_neuroplaypro_neurolab-0.1.2.dist-info/entry_points.txt,sha256=yGls5zvDZfmLCDLrSkNMIZgCINfFcqyAioWrlAEuof4,122
|
14
|
+
psychopy_neuroplaypro_neurolab-0.1.2.dist-info/top_level.txt,sha256=mbHktuA5YpOE3G2X-JWuUqqCKZtXNJ5CY4aPqRxJMRI,31
|
15
|
+
psychopy_neuroplaypro_neurolab-0.1.2.dist-info/RECORD,,
|
@@ -1,8 +0,0 @@
|
|
1
|
-
from psychopy.plugins import Plugin
|
2
|
-
from psychopy.experiment.components import registerComponent
|
3
|
-
from psychopy_neuroplaypro_neurolab.components.neuroplay.neuroplay import NeuroPlayComponent
|
4
|
-
|
5
|
-
class NeuroPlayPlugin(Plugin):
|
6
|
-
def onLoad(self):
|
7
|
-
registerComponent("neuroplay", NeuroPlayComponent)
|
8
|
-
print("NeuroPlay plugin loaded")
|
@@ -1,9 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.4
|
2
|
-
Name: psychopy-neuroplaypro-neurolab
|
3
|
-
Version: 0.1.0
|
4
|
-
Summary: Plugin for integrating NeuroPlayPro EEG recording in PsychoPy Builder.
|
5
|
-
Author-email: Enicast <enicaster@gmail.com>
|
6
|
-
Requires-Python: >=3.8
|
7
|
-
License-File: LICENSE
|
8
|
-
Requires-Dist: psychopy
|
9
|
-
Dynamic: license-file
|
@@ -1,8 +0,0 @@
|
|
1
|
-
psychopy_neuroplaypro_neurolab/__init__.py,sha256=fd3Mi-jIseuqbdbmJqsB86t7nxhkg2fq0l3P4OiboA0,87
|
2
|
-
psychopy_neuroplaypro_neurolab/plugin.py,sha256=eAhiWFukVgq1XRN3f0NGR3M74yesw0YakTnw351KqO4,344
|
3
|
-
psychopy_neuroplaypro_neurolab-0.1.0.dist-info/licenses/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
|
-
psychopy_neuroplaypro_neurolab-0.1.0.dist-info/METADATA,sha256=AhiUEjJpbLdNbg1bw-snsQAcOSXLIRHgcmwjlsxQIro,289
|
5
|
-
psychopy_neuroplaypro_neurolab-0.1.0.dist-info/WHEEL,sha256=wXxTzcEDnjrTwFYjLPcsW_7_XihufBwmpiBeiXNBGEA,91
|
6
|
-
psychopy_neuroplaypro_neurolab-0.1.0.dist-info/entry_points.txt,sha256=7YPHFYA-HZjQ-gizsCcvi704WKx3GrvbojxmQmpq7uo,212
|
7
|
-
psychopy_neuroplaypro_neurolab-0.1.0.dist-info/top_level.txt,sha256=mbHktuA5YpOE3G2X-JWuUqqCKZtXNJ5CY4aPqRxJMRI,31
|
8
|
-
psychopy_neuroplaypro_neurolab-0.1.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|