=========================
PyCollect - Live protocol
=========================
After :ref:`Install` and :ref:`Run` `UBT Launcher` in any of the available
:ref:`Modes`, the system are ready to handle clients connections (*take note
about the selected port*).
Data structure
==============
Requests
--------
* Each request sent to the WebSocket must be done in ``JSON`` format through a ``stringify`` command.
* Each request must include at least one common argument: ``command``.
Response
--------
Each system response must include an ``debug`` object with the argumments: ``command``, ``type`` and ``origin``:
* ``command``: With the same request command that trigger the response.
* ``type``: One of ``DISP``, ``WAVE``, ``CHANNELS``, ``LOG``, ``ERROR``, ``RESP``.
* ``origin``: One of ``PYCOLLECT``, ``PYMASIMO``.
* ``buffersize``: The size of internal buffer.
* ``recording``: Boolean that indicate if system are recording data.
* ``transmitting``: Boolean that indicate if system are transmitting data, in
this case, will send extra information about the data transmitted.
Types
-----
* ``DISP``: Indicate the presense os subrecords.
* ``WAVE``: Indicate the presense os waveforms.
* ``CHANNELS``: Indicate the presense of subrecords and waveforms.
* ``LOG``: When a command not need a response, this type is include a ``message`` argument.
* ``RESP``: Contain the response of a request.
* ``ERROR``: Contain an error message, this type is include a ``message`` argument.
Datetimes
---------
All datetimes data are in `Unix Timestamp` format, for example:
* ``Sun Aug 25 20:57:08 1991`` is equivalent to ``683171828``
* ``Fri Jul 6 11:23:20 2018`` is equivalent to ``1530894200``
Special values
--------------
* ``DATA_INVALID_LIMIT``: -32001
* ``DATA_INVALID``: -32767
* ``DATA_NOT_UPDATED``: -32766
* ``DATA_DISCONT``: -32765
* ``DATA_UNDER_RANGE``: -32764
* ``DATA_OVER_RANGE``: -32763
* ``DATA_NOT_CALIBRATED``: -32762
Commands
========
This list a commands are available, some of them need extra arguments.
.. include:: ../pycollect_commands.rst
Connection with WebSocket
=========================
A standard connection is enough, the default port is ``8890``, the complete ip
could looks like: ``ws://localhost:8890/ws``, note the ``/ws`` that complete the
address.
.. brython::
:hide-input:
from browser import window, html
from mdcframework.mdc import MDCButton, MDCFormField, MDCForm
from pycollect_ws import PyCollectWS
ff = MDCFormField()
form = MDCForm(formfield=ff)
input_port = form.mdc.TextField('IP', box=True, value='ws://localhost:8890/ws', style={'width': '30vw'})
container <= form
button_open = MDCButton('Open WS', id='open_socket', raised=True, style={'margin-top': '30px', 'margin-bottom': '30px', 'margin-right': '30px'})
container <= button_open
button_close = MDCButton('Close WS', id='close_socket', disabled=True, raised=True, style={'margin-top': '30px', 'margin-bottom': '30px', 'margin-right': '30px'})
container <= button_close
def connect(event):
ip = input_port.mdc.value
window.pycollect = PyCollectWS(ip)
button_close.bind('click', window.pycollect.close_connection)
button_open.bind('click', connect)
out = html.PRE(id='connect-status', style={'margin': '-15px'})
container <= out
Quick test
==========
This request will ask for ``available_channels``, start a default ``request_channels``,
wait for 5 seconds, ``start_recording``, wait for 10 seconds ``stop_transfer``
and ``get_edf``, ``get_csv``, and ``get_raw``.
The result can be checked with the browser `developer tools`.
.. brython::
:hide-input:
:merge-output:
from browser import window, html, timer
from mdcframework.mdc import MDCButton
def start_rec():
print('\n'*5)
print("start_recording")
print('\n'*5)
window.pycollect.send({'command': 'start_recording'})
set_item('start_recording', True)
timer.set_timeout(stop_rec, 10000)
def stop_rec():
print('\n'*5)
print("stop_transfer")
print('\n'*5)
window.pycollect.send({'command': 'stop_transfer'})
set_item('stop_transfer', True)
print('\n'*5)
print("get_files")
print('\n'*5)
window.pycollect.send({'command': 'get_edf'})
set_item('get_edf', True)
window.pycollect.send({'command': 'get_csv'})
set_item('get_csv', True)
window.pycollect.send({'command': 'get_raw'})
set_item('get_raw', True)
setattr(button_q, 'disabled', False)
def quick_test():
setattr(button_q, 'disabled', True)
set_item('available_channels', False)
set_item('request_channels', False)
set_item('start_recording', False)
set_item('stop_transfer', False)
set_item('get_edf', False)
set_item('get_csv', False)
set_item('get_raw', False)
print('\n'*5)
print("available_channels")
print('\n'*5)
window.pycollect.send({'command': 'available_channels'})
set_item('available_channels', True)
print('\n'*5)
print("request_channels")
print('\n'*5)
window.pycollect.send({'command': 'request_channels', 'channels':[]})
set_item('request_channels', True)
timer.set_timeout(start_rec, 5000)
button_q = MDCButton('Quick test', disabled=True, raised=True, style={'margin-bottom': '20px', 'margin-right': '30px'})
button_q.bind('click', quick_test)
container <= button_q
container <= html.BR()
items = {}
def add_item(name, description):
global items
parent = html.DIV()
icon = html.SPAN('hourglass_empty', style={'position': 'relative', 'bottom': '-4px'})
desc = html.SPAN(description, style={'margin-left': '5px'})
parent <= icon + desc
items[name] = icon
container <= parent
container <= html.BR()
def set_item(name, done):
global items
if done:
items[name].select('i')[0].style = {'color': 'rgb(91, 224, 42)'}
items[name].select('i')[0].text = 'done'
else:
items[name].select('i')[0].style = {'color': 'rgb(0, 0, 0)'}
items[name].select('i')[0].text = 'hourglass_empty'
add_item('available_channels', 'Available channels')
add_item('request_channels', 'Request channels')
add_item('start_recording', 'Start recording')
add_item('stop_transfer', 'Stop transfer')
add_item('get_edf', 'Get EDF+')
add_item('get_csv', 'Get CSV')
add_item('get_raw', 'Get RAW')
Available subrecords
====================
Request
-------
This command will stop a possible `Subrecord` transfer.
.. raw:: html
request
.. code::
{
"command": "available_subrecords"
}
Response
--------
.. raw:: html
response
.. code::
{
"command": "available_subrecords",
"origin": "PYCOLLECT",
"type": "RESP",
"subrecords": [], //A list of available subrecords labels.
}
Live example
------------
.. raw:: html
request
.. brython::
:hide-output:
request = {
"command": "available_subrecords",
}
#!ignore_bellow
from browser import window
window.request_available_subrecords = request
.. brython::
:hide-input:
:merge-output:
from browser import window, html
from mdcframework.mdc import MDCButton
button_av_subrecords = MDCButton('Request available subrecords', disabled=True, raised=True, style={'margin-bottom': '30px', 'margin-right': '30px'})
container <= button_av_subrecords
button_av_subrecords.bind('click', lambda event:window.pycollect.send(window.request_available_subrecords))
out = html.PRE(id='available_subrecords', Class='ubtlauncher-response')
container <= out
Request subrecords
==================
Request
-------
The value of `subrecords must be a sublist from the list with available subrecords.
If the list of `subrecords` is empty the response will contain all available measures.
.. raw:: html
request
.. code::
{
"command": "request_subrecords",
"subrecords": [], //List of subrecords labels.
}
Response
--------
.. raw:: html
response
.. code::
{
"type": "DISP",
"origin": "PYCOLLECT",
"command": "request_subrecords"
"datetime": 1530894200,
"data": {}, //A dictionary with the subrecords label and their respective measure.
}
Live example
------------
.. brython::
:hide-input:
from browser import window
from mdcframework.mdc import MDCButton, MDCForm
window.list_subrecords = MDCForm()
container <= window.list_subrecords
.. brython::
:hide-input:
:merge-output:
from browser import window, html
from mdcframework.mdc import MDCButton
out = html.PRE(id='available_subrecords_selected', Class='ubtlauncher-request')
container <= out
button_subrecords = MDCButton('Request subrecords', disabled=True, raised=True, style={'margin-bottom': '30px','margin-top': '30px', 'margin-right': '30px'})
container <= button_subrecords
button_subrecords.bind('click', lambda event:window.pycollect.send(window.request_subrecords))
out = html.PRE(id='request_subrecords', Class='ubtlauncher-response')
container <= out
Request possible waveforms
==========================
There is no way to list the `waveforms` that the device can send, this request
return all possible `waveforms`
Request
-------
.. raw:: html
request
.. code::
{
"command": "possible_waveforms",
}
Response
--------
The response is always the same.
.. raw:: html
response
.. code::
{
"type": "RESP",
"origin": "PYCOLLECT",
"command": "possible_waveforms",
"waveforms": [], //A list of all waveforms.
}
Live example
------------
.. raw:: html
request
.. brython::
:hide-output:
request = {
"command": "possible_waveforms"
}
#!ignore_bellow
from browser import window
window.request_available_waveforms = request
.. brython::
:hide-input:
:merge-output:
from browser import window, html
from mdcframework.mdc import MDCButton
button_av_waveforms = MDCButton('Request possible waveforms', disabled=True, raised=True, style={'margin-bottom': '30px', 'margin-right': '30px'})
container <= button_av_waveforms
button_av_waveforms.bind('click', lambda event:window.pycollect.send(window.request_available_waveforms))
out = html.PRE(id='possible_waveforms', Class='ubtlauncher-response')
container <= out
Request waveforms
=================
Request
-------
The value of `waveforms` must be a sublist from the list with all waveforms.
If the list of `wafeforms` is empty the request will be ignored.
.. raw:: html
request
.. code::
{
"command": "request_waveforms",
"waveforms": [], //A list with the desired waveforms labels.
}
Response
--------
The monitor only will send the available `waveforms` and not necessarily all
that was requested.
.. raw:: html
response
.. code::
{
"type": "WAVE",
"origin": "PYCOLLECT",
"command": "request_waveforms"
"channels": [ //list of channels, each channel is a dictionary
{ //channel dictionary
"label": "FLOW",
"datetime": 1530894182,
"physicalDimension": "l/min",
"samplefrequency": 25,
"samples": 100,
"physicalMaximum": null,
"physicalMinimum": null,
"digitalMaximum": 32768,
"digitalMinimum": -32768,
"prefilter": "",
"transducer": "",
"data": [...], //list of integers or floats
},
...
]
}
Live example
------------
.. brython::
:hide-input:
from browser import window
from mdcframework.mdc import MDCButton, MDCForm
window.list_waveforms = MDCForm()
container <= window.list_waveforms
.. brython::
:hide-input:
:merge-output:
from browser import window, html
from mdcframework.mdc import MDCButton
out = html.PRE(id='available_waveforms_selected', Class='ubtlauncher-request')
container <= out
button_waveforms = MDCButton('Request waveforms', disabled=True, raised=True, style={'margin-bottom': '30px','margin-top': '30px', 'margin-right': '30px'})
container <= button_waveforms
button_waveforms.bind('click', lambda event:window.pycollect.send(window.request_waveforms))
out = html.PRE(id='request_waveforms', Class='ubtlauncher-response')
out.style = {
'max-height': '300px',
'overflow': 'scroll',
}
button_waveforms.bind('click', lambda event:setattr(out, 'text', ''))
container <= out
Available channels
==================
Request
-------
This command will stop a possible `Subrecord` and `Waveforms` transfer.
.. raw:: html
request
.. code::
{
"command": "available_channels"
}
Response
--------
.. raw:: html
response
.. code::
{
"command": "available_channels",
"origin": "PYCOLLECT",
"type": "RESP",
"labels": [], //A list of available subrecords and waveforms labels.
}
Live example
------------
.. raw:: html
request
.. brython::
:hide-output:
request = {
"command": "available_channels",
}
#!ignore_bellow
from browser import window
window.request_available_labels = request
.. brython::
:hide-input:
:merge-output:
from browser import window, html
from mdcframework.mdc import MDCButton
button_av_labels = MDCButton('Request available channels', disabled=True, raised=True, style={'margin-bottom': '30px', 'margin-right': '30px'})
container <= button_av_labels
button_av_labels.bind('click', lambda event:window.pycollect.send(window.request_available_labels))
out = html.PRE(id='available_channels', Class='ubtlauncher-response')
container <= out
Request channels
================
Request
-------
The value of `channels` must be a sublist from the list with all waveforms and subrecords.
If the list of `labels` is empty, then will reques the default dataset.
.. raw:: html
request
.. code::
{
"command": "request_channels",
"channels": [], //A list with the desired waveforms and subrecords labels.
}
Response
--------
The monitor only will send the available `waveforms` and not necessarily all
that was requested.
.. raw:: html
response
.. code::
{
"channels": [ //list of channels, each channel is a dictionary
{ //channel dictionary
"label": "FLOW",
"datetime": 1530894182,
"physicalDimension": "l/min",
"samplefrequency": 25,
"samples": 100,
"physicalMaximum": null,
"physicalMinimum": null,
"digitalMaximum": 32768,
"digitalMinimum": -32768,
"prefilter": "",
"transducer": "",
"data": [...], //list of integers, floats, strings or Nones
},
...
]
}
Live example
------------
.. brython::
:hide-input:
from browser import window
from mdcframework.mdc import MDCButton, MDCForm
window.list_labels = MDCForm()
container <= window.list_labels
.. brython::
:hide-input:
:merge-output:
from browser import window, html
from mdcframework.mdc import MDCButton
out = html.PRE(id='available_labels_selected', Class='ubtlauncher-request')
container <= out
button_waveforms = MDCButton('Request channels', disabled=True, raised=True, style={'margin-bottom': '30px','margin-top': '30px', 'margin-right': '30px'})
container <= button_waveforms
button_waveforms.bind('click', lambda event:window.pycollect.send(window.request_labels))
out = html.PRE(id='request_channels', Class='ubtlauncher-response')
out.style = {
'max-height': '300px',
'overflow': 'scroll',
}
button_waveforms.bind('click', lambda event:setattr(out, 'text', ''))
container <= out
Stop transfer
=============
This command will send a request to the monitor for stop the data transmitting.
.. raw:: html
request
.. brython::
:hide-output:
request = {
"command": "stop_transfer"
}
#!ignore_bellow
from browser import window
window.request_stop_transfer = request
.. brython::
:hide-input:
:merge-output:
from browser import window, html
from mdcframework.mdc import MDCButton
button_stop_subrecords = MDCButton('Stop transfer', disabled=True, raised=True, style={'margin-bottom': '30px', 'margin-right': '30px'})
container <= button_stop_subrecords
button_stop_subrecords.bind('click', lambda event:window.pycollect.send(window.request_stop_transfer))
out = html.PRE(id='stop_transfer', Class='ubtlauncher-response')
container <= out
Close stream
============
This command will send a request to the monitor for stop the data transmitting
and will save possible data recording, the serial port will be closed too.
.. raw:: html
request
.. brython::
:hide-output:
request = {
"command": "close_stream"
}
#!ignore_bellow
from browser import window
window.request_close_stream = request
.. brython::
:hide-input:
:merge-output:
from browser import window, html
from mdcframework.mdc import MDCButton
button_stop_subrecords = MDCButton('Close stream', disabled=True, raised=True, style={'margin-bottom': '30px', 'margin-right': '30px'})
container <= button_stop_subrecords
button_stop_subrecords.bind('click', lambda event:window.pycollect.send(window.request_close_stream))
out = html.PRE(id='close_stream', Class='ubtlauncher-response')
container <= out
Reconnect with device
=====================
This command will send a request for connect with the monitor, this method is
called internally with the first connect, will return a ``debug`` response.
.. raw:: html
request
.. brython::
:hide-output:
request = {
"command": "reconnect_device"
}
#!ignore_bellow
from browser import window
window.request_reconnect_device = request
.. brython::
:hide-input:
:merge-output:
from browser import window, html
from mdcframework.mdc import MDCButton
button_stop_subrecords = MDCButton('Connect with device', disabled=True, raised=True, style={'margin-bottom': '30px', 'margin-right': '30px'})
container <= button_stop_subrecords
button_stop_subrecords.bind('click', lambda event:window.pycollect.send(window.request_reconnect_device))
out = html.PRE(id='reconnect_device', Class='ubtlauncher-response')
container <= out
Start recording
===============
This command will clear the data buffer.
.. raw:: html
request
.. brython::
:hide-output:
request = {
"command": "start_recording"
}
#!ignore_bellow
from browser import window
window.request_start_recording = request
.. brython::
:hide-input:
:merge-output:
from browser import window, html
from mdcframework.mdc import MDCButton
button_stop_subrecords = MDCButton('Start recording', disabled=True, raised=True, style={'margin-bottom': '30px', 'margin-right': '30px'})
container <= button_stop_subrecords
button_stop_subrecords.bind('click', lambda event:window.pycollect.send(window.request_start_recording))
out = html.PRE(id='start_recording', Class='ubtlauncher-response')
container <= out
Clear data
==========
This command will clear the data buffer and stop the data transmitting from monitor too.
.. raw:: html
request
.. brython::
:hide-output:
request = {
"command": "clear_data"
}
#!ignore_bellow
from browser import window
window.request_clear_data = request
.. brython::
:hide-input:
:merge-output:
from browser import window, html
from mdcframework.mdc import MDCButton
button_stop_subrecords = MDCButton('Clear data', disabled=True, raised=True, style={'margin-bottom': '30px', 'margin-right': '30px'})
container <= button_stop_subrecords
button_stop_subrecords.bind('click', lambda event:window.pycollect.send(window.request_clear_data))
out = html.PRE(id='clear_data', Class='ubtlauncher-response')
container <= out
Get debug information
=====================
Request
-------
This request will return useful information about connection and transmission.
.. raw:: html
request
.. code::
{
"command": "debug",
}
Response
--------
A complete response, with transmission in process contains the next data.
.. raw:: html
response
.. code::
{
"device": "gehealthcare", //Name of device connected
"port": null, //Serial port name
"ip_port": "8890", //IP port
"debug_mode": true, //Debug mode is enable
"user_dir": "/home/user/ubtdriver",
"download": "http://localhost:8890/download/",
"debug": {
"buffersize": 14976,
"recording": true,
"transmitting": true,
"origin": "PYCOLLECT",
"command": "debug",
"type": "RESP",
"subrecords": {
"startdatetime": 1532624765, //Timestamp for the first data
"enddatetime": 1532624805, //Timestamp for the last data
"totalseconds": 40, //Total of seconds processed
"labels": [] //List of subrecords labels
},
"waveforms": {
"startdatetime": 1532624798, //Timestamp for the first data
"enddatetime": 1532624804, //Timestamp for the last data
"totalseconds": 6, //Total of seconds processed
"labels": [] //List of waveforms labels
},
}
}
Live example
------------
.. raw:: html
request
.. brython::
:hide-output:
request = {
"command": "debug"
}
#!ignore_bellow
from browser import window
window.request_status = request
.. brython::
:hide-input:
:merge-output:
from browser import window, html
from mdcframework.mdc import MDCButton
button_status = MDCButton('Get debug', disabled=True, raised=True, style={'margin-bottom': '30px', 'margin-right': '30px'})
container <= button_status
button_status.bind('click', lambda event:window.pycollect.send(window.request_status))
out = html.PRE(id='debug', Class='ubtlauncher-response')
container <= out
List all measures
=================
Request
-------
This request return information about all measures for all modules (availables or not).
.. raw:: html
request
.. code::
{
"command": "list_all_measures",
}
Response
--------
Each measure contain: label, description, unit and other information for internal usage.
.. raw:: html
response
.. code::
{
"ECG HR": { //Label as dictionary key
"label": "ECG HR", //Label
"desc": "Heart rate", //Description
"key": "ecg:hr", //For internal usage
"unit": "1/min", //The physical unit
"subclass": "basic" //For unternal usage
},
...
}
Live example
------------
.. raw:: html
request
.. brython::
:hide-output:
request = {
"command": "list_all_measures"
}
#!ignore_bellow
from browser import window
window.request_measures = request
.. brython::
:hide-input:
:merge-output:
from browser import window, html
from mdcframework.mdc import MDCButton
button_status = MDCButton('List all measures', disabled=True, raised=True, style={'margin-bottom': '30px', 'margin-right': '30px'})
container <= button_status
button_status.bind('click', lambda event:window.pycollect.send(window.request_measures))
out = html.PRE(id='list_all_measures', Class='ubtlauncher-response')
out.style = {
'max-height': '600px',
'overflow': 'scroll',
}
container <= out
List all waveforms
==================
Request
-------
This request return information about all waveforms.
.. raw:: html
request
.. code::
{
"command": "list_all_waveforms",
}
Response
--------
Each waveform contain: label, unit, samples per second and other information for internal usage.
.. raw:: html
response
.. code::
{
"ECG1": { //Label as dictionary key
"label": "ECG1", //Label
"unit": "uV", //The physical unit
"shift": 0.000001, //For internal usage
"samps": 300, //Samples per second
"transducer": "", //Transductor used, used for generate the EDF+ file
"prefilter": "", //Prefilter, used for generate the EDF+ file
"physical_min": null, //Physical minimum, used for generate the EDF+ file
"physical_max": null, //Physical maximum, used for generate the EDF+ file
},
...
}
Live example
------------
.. raw:: html
request
.. brython::
:hide-output:
request = {
"command": "list_all_waveforms"
}
#!ignore_bellow
from browser import window
window.request_list_waveforms = request
.. brython::
:hide-input:
:merge-output:
from browser import window, html
from mdcframework.mdc import MDCButton
button_list_waveforms = MDCButton('List all waveforms', disabled=True, raised=True, style={'margin-bottom': '30px', 'margin-right': '30px'})
container <= button_list_waveforms
button_list_waveforms.bind('click', lambda event:window.pycollect.send(window.request_list_waveforms))
out = html.PRE(id='list_all_waveforms', Class='ubtlauncher-response')
out.style = {
'max-height': '600px',
'overflow': 'scroll',
}
container <= out
Save as RAW
===========
In this implementation download event will kill the websocket.
.. raw:: html
request
.. brython::
:hide-output:
request = {
"command": "get_raw"
}
#!ignore_bellow
from browser import window
window.request_get_raw = request
.. brython::
:hide-input:
:merge-output:
from browser import window, html
from mdcframework.mdc import MDCButton
button_gen_raw = MDCButton('Generate RAW', disabled=True, id='button_gen_raw', raised=True, style={'margin-bottom': '30px', 'margin-right': '30px'})
container <= button_gen_raw
placeholder = html.DIV(id='raw_download_placeholder')
container <= placeholder
button_gen_raw.bind('click', lambda event:window.pycollect.send(window.request_get_raw))
out = html.PRE(id='get_raw', Class='ubtlauncher-response')
container <= out
Save as CSV
===========
In this implementation download event will kill the websocket.
.. raw:: html
request
.. brython::
:hide-output:
request = {
"command": "get_csv"
}
#!ignore_bellow
from browser import window
window.request_get_csv = request
.. brython::
:hide-input:
:merge-output:
from browser import window, html
from mdcframework.mdc import MDCButton
button_gen_csv = MDCButton('Generate CSV', disabled=True, id='button_gen_csv', raised=True, style={'margin-bottom': '30px', 'margin-right': '30px'})
container <= button_gen_csv
placeholder = html.DIV(id='csv_download_placeholder')
container <= placeholder
button_gen_csv.bind('click', lambda event:window.pycollect.send(window.request_get_csv))
out = html.PRE(id='get_csv', Class='ubtlauncher-response')
container <= out
Save as EDF+
============
In this implementation download event will kill the websocket.
.. brython::
:hide-input:
from browser import window, html
from mdcframework.mdc import MDCButton, MDCFormField, MDCForm
from pycollect_ws import EDFHeader
ff = MDCFormField()
#ff.style = {'width': '100%',
# 'min-height': '40px',
# 'display': 'flow-root'}
form = MDCForm(formfield=ff)
form.mdc.TextField('Admin code', id='edf_admincode', box=True, value='', style={'width': '100%'}).bind('input', EDFHeader.update_edf_header)
form.mdc.TextField('Birthdate', id='edf_birthdate', box=True, type='number', value='', style={'width': '100%'}).bind('input', EDFHeader.update_edf_header)
form.mdc.TextField('Equipment', id='edf_equipment', box=True, value='', style={'width': '100%'}).bind('input', EDFHeader.update_edf_header)
form.mdc.Select('Gender', id='edf_gender', options=[('Male', '0'), ('Female', '1')], selected='0', box=True, value='', style={'width': '100%'}).bind('input', EDFHeader.update_edf_header)
form.mdc.TextField('Patient code', id='edf_patientcode', box=True, value='', style={'width': '100%'}).bind('input', EDFHeader.update_edf_header)
form.mdc.TextField('Patient name', id='edf_patientname', box=True, value='', style={'width': '100%'}).bind('input', EDFHeader.update_edf_header)
form.mdc.TextField('Patient additional', id='edf_patientaditional', box=True, value='', style={'width': '100%'}).bind('input', EDFHeader.update_edf_header)
form.mdc.TextField('Recording additional', id='edf_recordingaditional', box=True, value='', style={'width': '100%'}).bind('input', EDFHeader.update_edf_header)
form.mdc.TextField('Technician', id='edf_technician', box=True, value='', style={'width': '100%'}).bind('input', EDFHeader.update_edf_header)
container <= form
out = html.PRE(id='request_edf_header', Class='ubtlauncher-request', style={'margin-top': '15px'})
container <= out
.. brython::
:hide-input:
:merge-output:
from browser import window, html
from mdcframework.mdc import MDCButton
button_gen_csv = MDCButton('Generate EDF', disabled=True, id='button_gen_csv', raised=True, style={'margin-bottom': '30px', 'margin-top': '15px', 'margin-right': '30px'})
container <= button_gen_csv
placeholder = html.DIV(id='edf_download_placeholder')
container <= placeholder
button_gen_csv.bind('click', lambda event:window.pycollect.send(window.request_get_edf))
out = html.PRE(id='get_edf', Class='ubtlauncher-response')
container <= out
Bad request
===========
When a request is not understood.
.. raw:: html
request
.. brython::
:hide-output:
request = {
"command": "this_request_not_exist"
}
#!ignore_bellow
from browser import window
window.request_bad = request
.. brython::
:hide-input:
:merge-output:
from browser import window, html
from mdcframework.mdc import MDCButton
button_gen_raw = MDCButton('Bad request', disabled=True, id='button_gen_raw', raised=True, style={'margin-bottom': '30px', 'margin-right': '30px'})
container <= button_gen_raw
button_gen_raw.bind('click', lambda event:window.pycollect.send(window.request_bad))
out = html.PRE(id='this_request_not_exist', Class='ubtlauncher-response')
container <= out