{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "916b1413-030a-4cdd-9b4e-79eb33949e7a",
   "metadata": {},
   "source": [
    "# Illustrative example\n",
    "\n",
    "In this example we will create an [acquisition server](https://openbci-stream.readthedocs.io/en/latest/notebooks/A3-server-based_acquisition.html) on a Raspberry Pi and stream EEG data in real-time from them through [Kafka](https://openbci-stream.readthedocs.io/en/latest/notebooks/02-kafka_configuration.html) using the [OpenBCI-Stream library](https://openbci-stream.readthedocs.io/en/latest/index.html).\n",
    "\n",
    "<center>\n",
    "<img src='images/illustrative.svg'></img>\n",
    "</center>\n",
    "\n",
    "Devices used:  \n",
    "\n",
    "  * Raspberry Pi 4 Model B 4GB RAM  \n",
    "  * Cyton Biosensing Board (8-channels)  \n",
    "  * OpenBCI WiFi Shield  \n",
    "  * Computer (with WiFi)  \n",
    "  \n",
    "Conventions used:  \n",
    "\n",
    "  * The **red window frames** indicate that this window is \"owned\" by Raspberry through remote connection using SSH.  \n",
    "  * The **IP** for the **Raspberry** is **192.168.1.1**  \n",
    "  * The **IP** for the **OpenBCI WiFi Shield** is **192.168.1.113**  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "375e82c6-1444-4afc-8044-9fdb8cdc3983",
   "metadata": {},
   "source": [
    "## Acquisition server\n",
    "\n",
    "The [guide to create an acquisition server](https://openbci-stream.readthedocs.io/en/latest/notebooks/A3-server-based_acquisition.html) explain the process to set up the server over a Raspberry Pi, after finish and reboot the system the Raspberry will be an **Acces Point**, we must connect the **OpenBCI WiFi Shield** to this network as well as the main computer (where BCI Framework will be executed).\n",
    "\n",
    "We must verify that the respective daemons are running correctly on Raspberry:\n",
    "\n",
    "    $ sudo systemctl status kafka zookeeper@kafka\n",
    "<center>\n",
    "<img src='images/illustrative/daemon1.gif'></img>\n",
    "</center>\n",
    "\n",
    "    $ sudo systemctl status stream_eeg stream_rpyc\n",
    "<center>\n",
    "<img src='images/illustrative/daemon2.gif'></img>\n",
    "</center>\n",
    "\n",
    "The system uses the NTP to synchronize clocks, so the Rasberry **must have a wired connection** to the internet to synchronize their own clock, to ensure this we can verify the connection and restart the daemon: \n",
    "\n",
    "    $ sudo systemctl restart ntpd\n",
    "$ nptq -pn\n",
    "<center>\n",
    "<img src='images/illustrative/ntp1.gif'></img>\n",
    "</center>\n",
    "\n",
    "After a while, the clock will be synchronized (notice the * in the server **186.30.58.181**)\n",
    "<center>\n",
    "<img src='images/illustrative/ntp2.gif'></img>\n",
    "</center>\n",
    "\n",
    "We can verify the status of the **WiFi Shield** with the command:\n",
    "\n",
    "    $ curl -s http:/192.168.1.113/board | jq\n",
    "<center>\n",
    "<img src='images/illustrative/shield.gif'></img>\n",
    "</center>\n",
    "\n",
    "\n",
    "The above commands being executed through a SSH connection, also can be done by connecting a monitor and a keyboard to the Raspberry."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "007124d5-f306-48e3-a435-2d0dc68e9a70",
   "metadata": {},
   "source": [
    "## Configure montage\n",
    "\n",
    "A simple montage 8 channels:\n",
    "\n",
    "<center>\n",
    "<img src='images/illustrative/montage.gif'></img>\n",
    "</center>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "202c6204-4859-404c-b35c-051eb6bc2177",
   "metadata": {},
   "source": [
    "## Configuration and connection with OpenBCI and then start the stream \n",
    "\n",
    "Connect with the Raspberry that is running under the IP **192.168.1.1** and the **WiFi Shield** on **192.168.1.113**. The sample frequency of **1000 samples per second** with a transmission of packages of **100 samples**.\n",
    "\n",
    "<center>\n",
    "<img src='images/illustrative/connection.gif'></img>\n",
    "</center>\n",
    "\n",
    "## Impedances\n",
    "\n",
    "Once the streamming is started the impedances can be displayed from the **Montages tab**\n",
    "\n",
    "<center>\n",
    "<img src='images/illustrative/impedances.gif'></img>\n",
    "</center>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ea0d3f69-aeb6-4442-94fc-16be8682a887",
   "metadata": {},
   "source": [
    "## Raw EEG and topoplot\n",
    "\n",
    "<center>\n",
    "<img src='images/illustrative/raw.gif'></img>\n",
    "</center>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bed43715-079c-4367-8fdb-216c802fbbdc",
   "metadata": {},
   "source": [
    "## P300 speller\n",
    "\n",
    "<center>\n",
    "<img src='images/illustrative/p300.gif'></img>\n",
    "</center>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "05f01cf8-83b2-4401-b28c-1aa0f11aa53a",
   "metadata": {},
   "source": [
    "## EEG records reading "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "0629522d-82d1-447e-adc6-425b06fe07d1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "==================================================\n",
      "record-04_20_21-13_58_25.h5\n",
      "2021-04-20 13:58:25.717151\n",
      "==================================================\n",
      "MARKERS: ['NO-TARGET', 'TARGET']\n",
      "SAMPLE_RATE: 1000\n",
      "STREAMING_SAMPLE_RATE: 100\n",
      "DATETIME: 1618945105.717151\n",
      "MONTAGE: standard_1020\n",
      "CHANNELS: {1: 'Fp1', 2: 'Fp2', 3: 'T3', 4: 'C3', 5: 'C4', 6: 'T4', 7: 'O1', 8: 'O2'}\n",
      "START-OFFSET: 346.3931083679199\n",
      "SHAPE: [8, 68900]\n",
      "END-OFFSET: 377.5792121887207\n",
      "==================================================\n"
     ]
    }
   ],
   "source": [
    "from openbci_stream.utils.hdf5 import HDF5Reader\n",
    "\n",
    "filename = \"record-04_20_21-13_58_25.h5\"\n",
    "file = HDF5Reader(filename)\n",
    "print(file)\n",
    "file.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "a9db8540-fb8e-4536-a1d8-010905d70b46",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((65, 8, 125), (65,))"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "with HDF5Reader(filename) as file:\n",
    "    data, classes = file.get_data(tmin=0, duration=0.125)\n",
    "\n",
    "data.shape, classes.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a8f79dab-badb-4196-8390-c957dcc9b225",
   "metadata": {},
   "source": [
    "## Online classifier"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "af5a3909-724d-41ae-8712-1c37d15fd016",
   "metadata": {},
   "source": [
    "## P300 speller + Feedback"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
