"""
Demo using a custom serial rx parser to generate ioHub Serial Device events.

The _parseserial.py file is also required for this demo, as it contains the
custom parser function that the ioHub Serial device uses during runtime.

** This demo assumes that whatever is written to the device serial port 
   is simply returned back (echoed) on the device serial port.**

"""
import time
from psychopy import core, visual
from psychopy.iohub import launchHubServer

# Settings for serial port communication.
SERIAL_PORT = 'COM46'
BAUDRATE = 19200

# event_parser_info dict:
#
# parser_function key value can be a str giving the module.function path,
# or it can be the actual function object to be run by the iohub process.
#
# *Important:* The function provided should be in a file that can be imported
# as a module without causing unwanted behavior on the iohub process.
# Some options:
#     1) Put the function in a file that contains only the function,
#        as is done in this example.
#     2) Ensure any script logic that will be run when the file is called by
#        a user ( i.e. python.exe filewithfunc.py ) is inside a:
#            if __name__ == '__main__':
#        condition so it is not run when the file is only imported.

event_parser_info = dict(parser_function="_parseserial.checkForSerialEvents",
                         parser_kwargs=dict(var1='not used', var2=1234))
# configure iohub
exp_code = 'serial_demo'
sess_code = 'S_{0}'.format(int(time.mktime(time.localtime())))
iohubkwargs = {'experiment_code': exp_code,
               'session_code': sess_code,
               'serial.Serial': dict(name='serial',
                                     port=SERIAL_PORT,
                                     baud=BAUDRATE,
                                     parity='NONE',
                                     bytesize=8,
                                     event_parser=event_parser_info)}

# start the iohub server and set up display and PST box devices
io = launchHubServer(**iohubkwargs)
serial_device = io.devices.serial
keyboard = io.devices.keyboard

# Start collecting data from the PST box in the background.
serial_device.enableEventReporting(True)

# Create a window.
win = visual.Window((1024, 768), units='pix')

# Instruction text.
instruction = visual.TextStim(win, text='Monitoring for serial input events....\n\nPress any key to exit.')
# Display instruction.
instruction.draw()
win.flip()
io.clearEvents('all')

# Check for keyboard and serial events.
# Exit on keyboard press event.
# Print any serial events.
#
while not keyboard.getPresses():
    serial_device.write('aaa')
    io.wait(0.05)
    serial_device.write('bbb')
    io.wait(0.05)
    serial_device.write('ccc')
    io.wait(.500)
    for serevt in serial_device.getEvents():
        print(serevt)

# Stop recording serial events.
serial_device.enableEventReporting(False)

# Close the window and quit the program.
core.quit()
