Hi,
I reported this bug some time ago (AttributeError: 'ioHubDevices' object has no attribute 'pstbox'). It has recently become more pressing to resolve the problem as a security scare about Python earlier this year has meant that the University no longer allows us to install old versions of PsychoPy that predate the bug. So I have found time to look into the source code myself and have identified the cause of the problem. I hope this will mean that a fix will be possible. I’ve decided to create a new thread instead of posting again on the old one as I’m guessing this is more likely to bring it to the attention of somebody who is in a position to implement a fix. Also, the title of that post was misleading, as the ‘ioHub devices object has no attribute pstbox’ error is actually peculiar to Builder and is only tangentially related to the core issue (as explained below). The key error message is in fact:
ERROR: DEVICE CONFIG ERRORS FOUND! IOHUB NOT LOADING DEVICE: psychopy.iohub.devices.serial
errors count 1:
('monitor_event_types', ['PstboxButtonEvent'])
I am using PsychoPy v2024.1.5, which is the version that the University currently gives us access to. The nature of the problem and the error messaging has not changed since I last reported it using v2023.2.3. I will start by focusing on Coder as there is an additional problem in Builder that I will explain separately.
In Coder, ‘Device config validation’ fails for the Pstbox device because the ‘getSupportedConfigSettings’ function in ‘psychopy\iohub\util_init_.py’ returns the wrong value for ‘validation_file_path’. It returns ‘psychopy\iohub\devices\serial\supported_config_settings.yaml’ instead of ‘psychopy\iohub\devices\serial\supported_config_settings_pstbox.yaml’. The main difference between these files is in the permitted values for ‘monitor_event_types’, and this is what triggers the fatal ‘device config’ error. If I rename the ‘supported_config_settings_pstbox.yaml’ file as ‘supported_config_settings.yaml’ (thereby overwriting the existing ‘supported_config_settings.yaml’ file), my Coder program is able to communicate with the Pstbox device without any errors.
The underlying issue is that the ‘psychopy\iohub\devices\serial’ module contains the code to create two kinds of device: Serial and Pstbox, where Pstbox is a child of Serial. The ‘validateDeviceConfiguration’ function in ‘psychopy\iohub\devices\deviceConfigValidation.py’ correctly identifies the ‘validation_module’ for the Pstbox as ‘psychopy.iohub.devices.serial’, but then the ‘getSupportedConfigSettings’ function to which it sends this value of ‘validation_module’ assumes that the ‘yaml’ file that is located in ‘psychopy\iohub\devices\serial’ will be named ‘supported_config_settings.yaml’. Whereas in fact, there are two ‘yaml’ files in this location and the one that is needed for the Pstbox has a different name.
Clearly, my fix that consists in renaming the ‘supported_config_settings_pstbox.yaml’ file as ‘supported_config_settings.yaml’ is just a hack, and the fix that is required would most likely involve sending the ‘getSupportedConfigSettings’ function the ‘device_class_name’ variable, which for the Pstbox has a value of ‘Pstbox’, and using this variable to select the correct ‘yaml’ file.
In Builder, the same fix is required, but it is not sufficient for error-free communication with the Pstbox device, at least when the Builder program includes a Keyboard component.
Before explaining this, it is worth mentioning that the code for setting up the Pstbox device no longer works (as it used to) when placed in the ‘Begin Experiment’ section of a code component. It now has to be placed in the ‘Before Experiment’ section, or else the program throws a ‘ioHub devices object has no attribute pstbox’ error even when my ‘hack’ fix is in place.
When the code for setting up the Pstbox device is placed in the ‘Before Experiment’ section and my hack is in place, the Builder program is able to communicate with the Pstbox, but if the program includes a Keyboard component it fails to respond to key presses. The reason for this is that Builder is now (I don’t think it used to be) creating the Keyboard component as an iohub device. This means that the code instantiates iohub twice: first to set up the Pstbox with the code I have placed in the ‘Before Experiment’ section of a code component; and then to set up the Keyboard with some automatically generated code located in the ‘setupDevices’ function of the PsychoPy program. The second instantiation appears to silently fail, or at any rate the Keyboard device is not functional.
The way I’ve managed to fix this (another hack) is by compiling the Builder program and editing the compiled code. I removed my Pstbox setup code from the ‘Before Experiment’ section and integrated it into the automatically generated code that is in the ‘setupDevices’ function, so as to instantiate iohub only once, for both the Pstbox and the Keyboard.
The automatically generated code in the ‘setupDevices’ function, before I modified it, looked like this:
# --- Setup input devices ---
ioConfig = {}
# Setup iohub keyboard
ioConfig['Keyboard'] = dict(use_keymap='psychopy')
ioSession = '1'
if 'session' in expInfo:
ioSession = str(expInfo['session'])
ioServer = io.launchHubServer(window=win, **ioConfig)
After integrating my code into it, it looks like this:
# Settings for serial port (PST response box) communication.
SERIAL_PORT = 'COM4'
BAUDRATE = 19200
# ioHub configuration.
ioConfig = {
'serial.Pstbox': dict(name='pstbox', port=SERIAL_PORT, baud=BAUDRATE),
'Keyboard': dict(use_keymap='psychopy')
}
# Start the iohub server and set up devices.
ioSession = '1'
if 'session' in expInfo:
ioSession = str(expInfo['session'])
ioServer = io.launchHubServer(window=win, **ioConfig)
global pstbox
pstbox = ioServer.devices.pstbox
It’s obviously not ideal to be editing the compiled code, as this means that the program cannot be viewed and edited again in Builder. But I don’t know if a better fix is feasible, as it might mean rolling back the use of iohub for the Keyboard component. I would be grateful if the main issue that is common to Coder and Builder could be fixed at least. I can create my own hacks by editing the PsychoPy source code at home, but I can’t do this at work because most of our computers are remote client terminals without a local PsychoPy installation.
Thanks, Richard.