# System architecture

In the defined architecture, users communicate with a central server, named Main_Server, through web pages.

This Main_Server server contains the database with the results of the experiments already carried out and the experimental executions and experimental time schedules requested by users through the web interface. The Main_Server server is also responsible for mediating real-time communication between users and experiences, exchanging configuration requests, status requests and responses and generated data between users actively connected to the apparatus and apparatus.

Architecture of the new system. It is possible to observe the different layers of software that separate the users, on the left side of the image, from the experimental apparatus, on the right side of the image.

Along with the experimental apparatus, a computer, named RPI_Server, acts as an interface between the controller of the experimental apparatus and the Main_Server server. Each RPI_Server is turned on and represents one, and only one, experimental apparatus. It is important to note that this component was named RPI_Server because it is, in principle, implemented through the use of a Raspberry Pi, a computer that has communication modules necessary to communicate natively with the microcontrollers usually used to control the devices. However, this component can be implemented in other ways and it is only strictly necessary that it communicates according to the protocol - e.g. a virtual experience with data generated through a numerical model can implement this component with a normal computer without specialized interfaces. The communication between all components is done over the internet, with the exception of the communication between the RPi_Server and the experimental apparatus, where communications are made through the protocol that the controller of the apparatus implements.

# Communication protocol

To start the connection between the RPi_Server and the Main_Server, when the RPi_Server is turned on, it tries to connect to the Main_Server server. If not successful, it should wait 10 seconds and try again until it manages to make the connection.

• Label
• Label

When the connection is successfully established, the server RPi_Server sends to Main_Servero its ID and Secret. These two variables are then checked on the Main_Server server side as a simple way to authenticate that the connection is coming from an authorized machine. In case of successful verification, the Main_Server responds to the RPi_Server with a message encoded in JSON format that describes the experience to be served by the RPi_Server. This configuration message allows the same RPi_Server program to be adaptable to different experiences with, for example, different numbers of actuators and sensors without changes to the source code. Based on the information contained in this message, the name of the config_file, the RPi_Server looks for the experiment at the indicated address and tries to establish communication with the controller of the experimental apparatus. In order to decouple the RPi_Server from the different communication protocols that each experimental controller may implement, the RPi_Server must communicate with the devices calling a set of standard methods whose implementation must be adapted to suit the target controller.

(TODO)

After this initial configuration, the connection of the RPi_Serverao Main_Serverand the RPi_Serverto the controller of the experiment, the system is ready for the exchange of messages between the components. The messages exchanged between components were defined following an everything is a string philosophy. Thus, the messages exchanged are JSON-formatted strings in which the JSON fields encode the message to be transmitted. The type of each message is identified by the msg_id field of the message JSON, and for the message sent, the reply, if any, must have reply_id with the same value. In order to be adaptable to various types of experimental apparatus, the system does not store apparatus status information so it is possible to send any of the defined messages at any time. The correct sequencing of messages for the successful operation of the apparatus is the responsibility of other user-controlled software layers.

## Sent messages (Main_Server → RPi_Server)

### Message 1

Message sent to transmit the experimental apparatus configuration parameters to the RPi_Server. Parameters must be sent in the config_file field formatted as JSON. The configuration JSON must be adapted to each type of apparatus and to the source code of the interface used.

{
"msg_id": "1",
"config_file":config_json
}


In response, Main_Serverde will see one of the following messages, indicating the initialization state of the apparatus. In case of successful initialization, the response should be as following:

{
"status": "Experiment initialized OK"
}


In case of error, the response is:

{
"status": "Experiment initialized NOT OK",
"error": error_description
}


In this case, the error field can be used to describe in detail the error that occurred on startup, e.g. the experience on the configured serial port could not be found.

### Message 2

Message sent to transmit the configuration parameters of an experimental run defined by a user. The parameters of the experimental run must be sent in the config_params field encoded in JSON format. The JSON encoding the configuration parameters must be adapted to each type of apparatus and to the interface source code used.

{
"msg_id": "2",
"config_params": run_config
}


In response, Main_Server should receive one of the following messages, indicating the configuration and execution status of the apparatus. In case of successful configuration and execution, the response should be formatted as follows:

{
"status": "Experiment Running"
}


In case of error, the response should be as follows:

{
"status": status_description,
"error": error_description
}


The status and error fields should be used to report what state the experimental apparatus was in after the error and specify in detail which error was detected, respectively.

### Message 3

Message sent to stop the on going experimental run. The behavior when sent to an already stopped experimental apparatus is not specified.

{
"msg_id": "3"
}


In response, Main_Server should receive one of the following messages, indicating the state of the apparatus. In case of successful stop, the response should be formatted as follows:

{
"status": "Experiment Stopped"
}


In case of error, the response should be as follows:

{
"status": "Experiment didn't stop",
"error": error_description
}


The error field should be used to specify in detail what error was detected.

### Message 4

Message sent to command the apparatus reset.

{
"msg_id": "4"
}


In response, Main_Server should receive one of the following messages, indicating whether it was possible to successfully reset the apparatus. In case of successful reset, the response should be formatted as follows:

{
"status": "Experiment Reseted"
}


In case of error, the response should be as follows:

{
"status": "Experiment didn't Reset",
"error": error_description}


The error field should be used to specify in detail what error was detected.

### Message 5

Message sent to request the status of the apparatus.

{
"msg_id": "5"
}


In response, Main_Server should receive one of the following messages, indicating whether it was possible to successfully determine the state of the apparatus. In case of successful status determination, the response should be formatted as follows:

{
"status": exp_status
}


In case of error, the response should be as follows:

{
"status": "Couldn't get status",
"error": error_description
}


The error field should be used to specify in detail what error was detected.

## Sent messages (RPi_Server → Main_Server)

### Message 6

Message sent to request registration of RPi_Server in Main_Server. The id_RP and segredo fields should be used to encode the id and secret associated with the RPi_Server requesting registration.

{
"msg_id":"6",
"id_RP":id,
"segredo":secret
}


In case of successful registration, the answer should be as follows:

{
"status":"Connected"
}


In case of error, the answer should be as follows:

{
"status":"Connection failed",
"error":error_description
}


The field error should be used to specify in detail what error was detected, e.g. the id sent does not exist in the database of authorized experiments.

### Message 7

Message sent to transmit the complete results of the requested trial run. Camporesults should be used to encode, in JSON format, the complete experimental results. The JSON format depends on the type of data generated by the apparatus.

{
"msg_id":"7",
"results":run_results
}


### Message 8

Message sent to signal an error in an experimental run that has already started. The status and error fields should be used to encode the state of the apparatus after the error and which error was detected, respectively.

{
"msg_id":"8",
"status":status,
"error":error_id
}


### Message 9

Message sent to transmit, asynchronously, the state of the apparatus to the Main_Server. The fields timestamp, status and current_config should be used to encode the time when the message was generated, the current state of the apparatus and the configuration of the apparatus, respectively.

{
"msg_id":"9",
"timestamp":timestamp,
"status":status,
"current_config":current_config
}


### Message 10

Message sent to asynchronously transmit an experimental point which cannot be efficiently encoded as text, e.g. an image, and which for that reason is stored in a location accessible by the Main_Server in binary format. The fields timestamp and id_dados_bin must be used to encode the time at which the message was generated and the address where the client will be able to obtain the data sent by the RPi_Server, respectively.

{
"msg_id":"10",
"timestamp":timestamp,
}


### Message 11

Message sent to asynchronously transmit an experimental point encoded as text. The timestamp and date fields should be used to encode the time the message was generated and the experimental data to be transmitted, formatted in JSON, respectively. The formatting of experimental data depends on the type of data generated by the apparatus and should be appropriate to it.

{
"msg_id":"11",
"timestamp":timestamp,
"data":data_point
}


# How to install

## Pre-requisites

### Build environment

• Git (2.30.2+)
• Python (3.7.0+)

## Raspberry PI Server (RPI_Server)

Setup python3 environment variable pointing to run the version installed (in this exemple is for python3.7) by:

   $sudo nano ~/.bashrc  edit it adding to the end: $ alias python3="python3.7"


First checkout the project from github:

   $git clone https://github.com/e-lab-FREE/RPi_Server-PG  then edit the "main.py" file and change the following global variables:  SERVER = "main_server_IP" MY_IP = "RPi_IP" SEGREDO = "password" PORT = Port_to_comunication BINARY_DATA_PORT = Port_to_transfer_Binary_data  After this changes the RPi_Server is ready to run by typing: $ pyhton3 main.py


This will try to connect to the IP defined as SERVER every 10 sec.

## Main Server (Main_Server)

This software is the dispatcher of the information. By allowing the communications form the frontend and each RPi_Server responsable for a experience. To install this you need to install at least Python 3.7 and the lib Flask (https://pypi.org/project/Flask/).

Then go to the project from github:



# Video Streaming

Intro

## Video capture and stream

On the raspberry it is running ....

## Accessing the stream

The experiment stream can be access by a html ....

or by using VLC, allowing to grab the video