diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 00000000..fe58ba21
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,6 @@
+{
+ "idf.openOcdConfigs": [
+ "board/esp32s3-builtin.cfg"
+ ],
+ "idf.portWin": "COM3"
+}
\ No newline at end of file
diff --git a/border-router/deploy.sh b/border-router/deploy.sh
new file mode 100644
index 00000000..8f0ac48a
--- /dev/null
+++ b/border-router/deploy.sh
@@ -0,0 +1 @@
+docker run --name=otbr --detach --network=host --cap-add=NET_ADMIN --device=/dev/ttyACM0 --device=/dev/net/tun --volume=/var/lib/otbr:/data --env-file=otbr-env.list --restart=always openthread/border-router
\ No newline at end of file
diff --git a/border-router/install.txt b/border-router/install.txt
new file mode 100644
index 00000000..d5147570
--- /dev/null
+++ b/border-router/install.txt
@@ -0,0 +1 @@
+docker pull openthread/border-router:latest
\ No newline at end of file
diff --git a/border-router/otbr-env.list b/border-router/otbr-env.list
new file mode 100644
index 00000000..7b9d42fe
--- /dev/null
+++ b/border-router/otbr-env.list
@@ -0,0 +1,4 @@
+OT_RCP_DEVICE=spinel+hdlc+uart:///dev/ttyACM0?uart-baudrate=1000000
+OT_INFRA_IF=wlan0
+OT_THREAD_IF=wpan0
+OT_LOG_LEVEL=7
\ No newline at end of file
diff --git a/esp32-lora/.idea/.gitignore b/esp32-lora/.idea/.gitignore
new file mode 100644
index 00000000..ab1f4164
--- /dev/null
+++ b/esp32-lora/.idea/.gitignore
@@ -0,0 +1,10 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Ignored default folder with query files
+/queries/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
+# Editor-based HTTP Client requests
+/httpRequests/
diff --git a/esp32-lora/.idea/esp32-lora.iml b/esp32-lora/.idea/esp32-lora.iml
new file mode 100644
index 00000000..b0746fbc
--- /dev/null
+++ b/esp32-lora/.idea/esp32-lora.iml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/esp32-lora/.idea/inspectionProfiles/profiles_settings.xml b/esp32-lora/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 00000000..105ce2da
--- /dev/null
+++ b/esp32-lora/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/esp32-lora/.idea/misc.xml b/esp32-lora/.idea/misc.xml
new file mode 100644
index 00000000..ce1f3a9d
--- /dev/null
+++ b/esp32-lora/.idea/misc.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/esp32-lora/.idea/modules.xml b/esp32-lora/.idea/modules.xml
new file mode 100644
index 00000000..25d0803c
--- /dev/null
+++ b/esp32-lora/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/esp32-lora/.idea/vcs.xml b/esp32-lora/.idea/vcs.xml
new file mode 100644
index 00000000..6c0b8635
--- /dev/null
+++ b/esp32-lora/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/esp32-thread/open-thread-client/dependencies.lock b/esp32-thread/open-thread-client/dependencies.lock
index 9bb43cae..bf803597 100644
--- a/esp32-thread/open-thread-client/dependencies.lock
+++ b/esp32-thread/open-thread-client/dependencies.lock
@@ -33,6 +33,16 @@ dependencies:
registry_url: https://components.espressif.com/
type: service
version: 2.5.5
+ espressif/mqtt:
+ component_hash: ffdad5659706b4dc14bc63f8eb73ef765efa015bf7e9adf71c813d52a2dc9342
+ dependencies:
+ - name: idf
+ require: private
+ version: '>=5.3'
+ source:
+ registry_url: https://components.espressif.com/
+ type: service
+ version: 1.0.0
idf:
source:
type: idf
@@ -47,8 +57,9 @@ dependencies:
version: '*'
direct_dependencies:
- espressif/esp_ot_cli_extension
+- espressif/mqtt
- idf
- ot_led
-manifest_hash: 963824e0a62a27ce0c2b82c605b67acbe18d1e3adb4ad12c98b0302b37ad6174
+manifest_hash: 133dc153f57b0466d9170ed20188e209c7ee22bbe2cc755c0f48394b1735e808
target: esp32h2
version: 2.0.0
diff --git a/esp32-thread/open-thread-client/main/CMakeLists.txt b/esp32-thread/open-thread-client/main/CMakeLists.txt
index 4190ec33..5fc72678 100644
--- a/esp32-thread/open-thread-client/main/CMakeLists.txt
+++ b/esp32-thread/open-thread-client/main/CMakeLists.txt
@@ -1,5 +1,5 @@
idf_component_register(
SRCS "esp_ot_cli.c"
INCLUDE_DIRS "."
- REQUIRES esp_http_client openthread esp_netif freertos nvs_flash
+ REQUIRES mqtt esp_http_client openthread esp_netif freertos nvs_flash
)
diff --git a/esp32-thread/open-thread-client/main/esp_ot_cli.c b/esp32-thread/open-thread-client/main/esp_ot_cli.c
index c6ef5914..82c308ce 100644
--- a/esp32-thread/open-thread-client/main/esp_ot_cli.c
+++ b/esp32-thread/open-thread-client/main/esp_ot_cli.c
@@ -39,6 +39,7 @@
#include "openthread/logging.h"
#include "openthread/tasklet.h"
#include "esp_http_client.h"
+#include "mqtt_client.h"
#if CONFIG_OPENTHREAD_STATE_INDICATOR_ENABLE
#include "ot_led_strip.h"
@@ -151,11 +152,78 @@ static void ot_task_worker(void *aContext)
vTaskDelete(NULL);
}
+static bool mqtt_connected = false;
+
+static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) {
+ esp_mqtt_event_handle_t event = event_data;
+ switch (event->event_id) {
+ case MQTT_EVENT_CONNECTED:
+ ESP_LOGI(TAG, "MQTT Connected");
+ mqtt_connected = true;
+ break;
+ case MQTT_EVENT_DISCONNECTED:
+ ESP_LOGI(TAG, "MQTT Disconnected");
+ mqtt_connected = false;
+ break;
+ case MQTT_EVENT_PUBLISHED:
+ ESP_LOGI(TAG, "Message published, msg_id=%d", event->msg_id);
+ break;
+ case MQTT_EVENT_ERROR:
+ ESP_LOGE(TAG, "MQTT Error");
+ mqtt_connected = false;
+ break;
+ default:
+ break;
+ }
+}
+
+static esp_mqtt_client_handle_t client = NULL;
+void mqtt_init(void)
+{
+ esp_mqtt_client_config_t mqtt_cfg = {
+ .broker.address.uri = "mqtt://192.168.15.119:1883",
+ .credentials = {
+ .username = NULL,
+ .client_id = NULL,
+ .set_null_client_id = true
+ },
+ .session.keepalive = 30,
+ .session.disable_clean_session = false,
+ };
+
+ client = esp_mqtt_client_init(&mqtt_cfg);
+ if (!client) {
+ ESP_LOGE(TAG, "Failed to init MQTT client");
+ return;
+ }
+
+ esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
+
+ ESP_LOGI(TAG, "Starting MQTT client...");
+ esp_mqtt_client_start(client);
+}
+
+void send_gps_data(const char *topic, const char *json)
+{
+ if (!client || !json) return;
+
+ if (!mqtt_connected) {
+ ESP_LOGW(TAG, "MQTT not connected, skipping GPS publish");
+ return;
+ }
+
+ int msg_id = esp_mqtt_client_publish(client, topic, json, 0, 1, 0);
+ if (msg_id < 0) {
+ ESP_LOGE(TAG, "Failed to publish GPS");
+ } else {
+ ESP_LOGI(TAG, "Published GPS: msg_id=%d", msg_id);
+ }
+}
+
#define GPS_UART_NUM UART_NUM_1
#define GPS_TX_PIN 4
#define GPS_RX_PIN 5
#define BUF_SIZE 1024
-
static uint8_t gps_buffer[BUF_SIZE];
void init_gps() {
const uart_config_t uart_config = {
@@ -206,14 +274,12 @@ char* gps_to_json(char* gps_data) {
}
}
- // Créer le JSON avec des valeurs valides même si GPS pas fixé
snprintf(json, sizeof(json), "{\"data\":{\"latitude\":%.6f,\"longitude\":%.6f}}",
latitude, longitude);
return json;
}
-
char* read_gps() {
int len = uart_read_bytes(GPS_UART_NUM, gps_buffer, BUF_SIZE - 1, 100 / portTICK_PERIOD_MS);
if (len > 0) {
@@ -223,32 +289,16 @@ char* read_gps() {
return NULL;
}
-void send_gps_data(const char* server_url, const char* json)
-{
- if (!json) return;
-
- ESP_LOGI(TAG, "Sending JSON: %s", json);
-
- esp_http_client_config_t config = { .url = server_url };
- esp_http_client_handle_t client = esp_http_client_init(&config);
- esp_http_client_set_method(client, HTTP_METHOD_POST);
- esp_http_client_set_post_field(client, json, strlen(json));
- esp_http_client_set_header(client, "Content-Type", "application/json");
-
- esp_http_client_perform(client);
- esp_http_client_cleanup(client);
-}
-
void send_position_task(void *pvParameters)
{
- const char* position_endpoint = "http://192.168.15.117:5000/devices/notify-position";
+ const char* gps_topic = "/board-mate/gps/notify";
while (1) {
char* json;
char* raw_data = read_gps();
if (raw_data) {
char* json = gps_to_json(raw_data);
- send_gps_data(position_endpoint, json);
+ send_gps_data(gps_topic, json);
} else {
ESP_LOGI(TAG, "NO GPS DATA");
}
@@ -271,7 +321,8 @@ void app_main(void)
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_vfs_eventfd_register(&eventfd_config));
-
+
+ mqtt_init();
init_gps();
xTaskCreate(ot_task_worker, "ot_cli_main", 10240, xTaskGetCurrentTaskHandle(), 5, NULL);
diff --git a/esp32-thread/open-thread-client/main/idf_component.yml b/esp32-thread/open-thread-client/main/idf_component.yml
index 06b75f0c..71b0f0bc 100644
--- a/esp32-thread/open-thread-client/main/idf_component.yml
+++ b/esp32-thread/open-thread-client/main/idf_component.yml
@@ -1,8 +1,9 @@
## IDF Component Manager Manifest File
dependencies:
espressif/esp_ot_cli_extension:
- version: "~1.2.0"
+ version: ~1.2.0
idf:
- version: ">=4.1.0"
+ version: '>=4.1.0'
ot_led:
path: ${IDF_PATH}/examples/openthread/ot_common_components/ot_led
+ espressif/mqtt: '*'
diff --git a/rpi/.idea/.gitignore b/rpi/.idea/.gitignore
new file mode 100644
index 00000000..ab1f4164
--- /dev/null
+++ b/rpi/.idea/.gitignore
@@ -0,0 +1,10 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Ignored default folder with query files
+/queries/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
+# Editor-based HTTP Client requests
+/httpRequests/
diff --git a/rpi/.idea/inspectionProfiles/profiles_settings.xml b/rpi/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 00000000..105ce2da
--- /dev/null
+++ b/rpi/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/rpi/.idea/misc.xml b/rpi/.idea/misc.xml
new file mode 100644
index 00000000..8eb0f646
--- /dev/null
+++ b/rpi/.idea/misc.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/rpi/.idea/modules.xml b/rpi/.idea/modules.xml
new file mode 100644
index 00000000..165a6e7b
--- /dev/null
+++ b/rpi/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/rpi/.idea/rpi.iml b/rpi/.idea/rpi.iml
new file mode 100644
index 00000000..6bb7029b
--- /dev/null
+++ b/rpi/.idea/rpi.iml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/rpi/.idea/swagger-settings.xml b/rpi/.idea/swagger-settings.xml
new file mode 100644
index 00000000..2d089b8b
--- /dev/null
+++ b/rpi/.idea/swagger-settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/rpi/.idea/vcs.xml b/rpi/.idea/vcs.xml
new file mode 100644
index 00000000..6c0b8635
--- /dev/null
+++ b/rpi/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/rpi/api-resources/board_mate_client/.github/workflows/python.yml b/rpi/api-resources/board_mate_client/.github/workflows/python.yml
new file mode 100644
index 00000000..7371db49
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/.github/workflows/python.yml
@@ -0,0 +1,38 @@
+# NOTE: This file is auto generated by OpenAPI Generator.
+# URL: https://openapi-generator.tech
+#
+# ref: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
+
+name: board_mate_client Python package
+
+on: [push, pull_request]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
+
+ steps:
+ - uses: actions/checkout@v3
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v4
+ with:
+ python-version: ${{ matrix.python-version }}
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install flake8 pytest
+ if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
+ if [ -f test-requirements.txt ]; then pip install -r test-requirements.txt; fi
+ - name: Lint with flake8
+ run: |
+ # stop the build if there are Python syntax errors or undefined names
+ flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
+ # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
+ flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
+ - name: Test with pytest
+ run: |
+ pytest
diff --git a/rpi/api-resources/board_mate_client/.gitignore b/rpi/api-resources/board_mate_client/.gitignore
new file mode 100644
index 00000000..84a2af1e
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/.gitignore
@@ -0,0 +1,66 @@
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+env/
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+*.egg-info/
+.installed.cfg
+*.egg
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit chesscog-bck / coverage reports
+htmlcov/
+.tox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*,cover
+.hypothesis/
+venv/
+.venv/
+.python-version
+.pytest_cache
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+target/
+
+#Ipython Notebook
+.ipynb_checkpoints
diff --git a/rpi/api-resources/board_mate_client/.gitlab-ci.yml b/rpi/api-resources/board_mate_client/.gitlab-ci.yml
new file mode 100644
index 00000000..f4644875
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/.gitlab-ci.yml
@@ -0,0 +1,31 @@
+# NOTE: This file is auto generated by OpenAPI Generator.
+# URL: https://openapi-generator.tech
+#
+# ref: https://docs.gitlab.com/ee/ci/README.html
+# ref: https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Python.gitlab-ci.yml
+
+stages:
+ - chesscog-bck
+
+.pytest:
+ stage: chesscog-bck
+ script:
+ - pip install -r requirements.txt
+ - pip install -r chesscog-bck-requirements.txt
+ - pytest --cov=board_mate_client
+
+pytest-3.7:
+ extends: .pytest
+ image: python:3.7-alpine
+pytest-3.8:
+ extends: .pytest
+ image: python:3.8-alpine
+pytest-3.9:
+ extends: .pytest
+ image: python:3.9-alpine
+pytest-3.10:
+ extends: .pytest
+ image: python:3.10-alpine
+pytest-3.11:
+ extends: .pytest
+ image: python:3.11-alpine
diff --git a/rpi/api-resources/board_mate_client/.openapi-generator-ignore b/rpi/api-resources/board_mate_client/.openapi-generator-ignore
new file mode 100644
index 00000000..7484ee59
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/.openapi-generator-ignore
@@ -0,0 +1,23 @@
+# OpenAPI Generator Ignore
+# Generated by openapi-generator https://github.com/openapitools/openapi-generator
+
+# Use this file to prevent files from being overwritten by the generator.
+# The patterns follow closely to .gitignore or .dockerignore.
+
+# As an example, the C# client generator defines ApiClient.cs.
+# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
+#ApiClient.cs
+
+# You can match any string of characters against a directory, file or extension with a single asterisk (*):
+#foo/*/qux
+# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
+
+# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
+#foo/**/qux
+# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
+
+# You can also negate patterns with an exclamation (!).
+# For example, you can ignore all files in a docs folder with the file extension .md:
+#docs/*.md
+# Then explicitly reverse the ignore rule for a single file:
+#!docs/README.md
diff --git a/rpi/api-resources/board_mate_client/.openapi-generator/FILES b/rpi/api-resources/board_mate_client/.openapi-generator/FILES
new file mode 100644
index 00000000..fcde4e44
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/.openapi-generator/FILES
@@ -0,0 +1,38 @@
+.github/workflows/python.yml
+.gitignore
+.gitlab-ci.yml
+.openapi-generator-ignore
+.travis.yml
+README.md
+docs/DefaultApi.md
+docs/GameDto.md
+docs/MoveDto.md
+docs/ResponseBodyGameDto.md
+docs/ResponseBodyString.md
+git_push.sh
+openapi_client/__init__.py
+openapi_client/api/__init__.py
+openapi_client/api/default_api.py
+openapi_client/api_client.py
+openapi_client/api_response.py
+openapi_client/configuration.py
+openapi_client/exceptions.py
+openapi_client/models/__init__.py
+openapi_client/models/game_dto.py
+openapi_client/models/move_dto.py
+openapi_client/models/response_body_game_dto.py
+openapi_client/models/response_body_string.py
+openapi_client/py.typed
+openapi_client/rest.py
+pyproject.toml
+requirements.txt
+setup.cfg
+setup.py
+test-requirements.txt
+test/__init__.py
+test/test_default_api.py
+test/test_game_dto.py
+test/test_move_dto.py
+test/test_response_body_game_dto.py
+test/test_response_body_string.py
+tox.ini
diff --git a/rpi/api-resources/board_mate_client/.openapi-generator/VERSION b/rpi/api-resources/board_mate_client/.openapi-generator/VERSION
new file mode 100644
index 00000000..18bb4182
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/.openapi-generator/VERSION
@@ -0,0 +1 @@
+7.5.0
diff --git a/rpi/api-resources/board_mate_client/.travis.yml b/rpi/api-resources/board_mate_client/.travis.yml
new file mode 100644
index 00000000..92d4534e
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/.travis.yml
@@ -0,0 +1,17 @@
+# ref: https://docs.travis-ci.com/user/languages/python
+language: python
+python:
+ - "3.7"
+ - "3.8"
+ - "3.9"
+ - "3.10"
+ - "3.11"
+ # uncomment the following if needed
+ #- "3.11-dev" # 3.11 development branch
+ #- "nightly" # nightly build
+# command to install dependencies
+install:
+ - "pip install -r requirements.txt"
+ - "pip install -r chesscog-bck-requirements.txt"
+# command to run tests
+script: pytest --cov=board_mate_client
diff --git a/rpi/api-resources/board_mate_client/README.md b/rpi/api-resources/board_mate_client/README.md
new file mode 100644
index 00000000..85e98cb9
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/README.md
@@ -0,0 +1,112 @@
+# openapi-client
+boardmate_api API
+
+This Python package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
+
+- API version: 1.0.0
+- Package version: 1.0.0
+- Generator version: 7.5.0
+- Build package: org.openapitools.codegen.languages.PythonClientCodegen
+
+## Requirements.
+
+Python 3.7+
+
+## Installation & Usage
+### pip install
+
+If the python package is hosted on a repository, you can install directly using:
+
+```sh
+pip install git+https://github.com/GIT_USER_ID/GIT_REPO_ID.git
+```
+(you may need to run `pip` with root permission: `sudo pip install git+https://github.com/GIT_USER_ID/GIT_REPO_ID.git`)
+
+Then import the package:
+
+```python
+import board_mate_client
+```
+
+### Setuptools
+
+Install via [Setuptools](http://pypi.python.org/pypi/setuptools).
+
+```sh
+python setup.py install --user
+```
+(or `sudo python setup.py install` to install the package for all users)
+
+Then import the package:
+
+```python
+import board_mate_client
+```
+
+### Tests
+
+Execute `pytest` to run the tests.
+
+## Getting Started
+
+Please follow the [installation procedure](#installation--usage) and then run the following:
+
+```python
+
+import board_mate_client
+from board_mate_client.rest import ApiException
+from pprint import pprint
+
+# Defining the host is optional and defaults to https://boardmate_api
+# See configuration.py for a list of all supported configuration parameters.
+configuration = board_mate_client.Configuration(
+ host="https://boardmate_api"
+)
+
+# Enter a context with an instance of the API client
+with board_mate_client.ApiClient(configuration) as api_client:
+ # Create an instance of the API class
+ api_instance = board_mate_client.DefaultApi(api_client)
+ game_id = 'game_id_example' # str |
+ move_dto = board_mate_client.MoveDto() # MoveDto |
+
+ try:
+ # POST moves/add/{gameId}
+ api_response = api_instance.add_move(game_id, move_dto)
+ print("The response of DefaultApi->add_move:\n")
+ pprint(api_response)
+ except ApiException as e:
+ print("Exception when calling DefaultApi->add_move: %s\n" % e)
+
+```
+
+## Documentation for API Endpoints
+
+All URIs are relative to *https://boardmate_api*
+
+Class | Method | HTTP request | Description
+------------ | ------------- | ------------- | -------------
+*DefaultApi* | [**add_move**](docs/DefaultApi.md#add_move) | **POST** /moves/add/{gameId} | POST moves/add/{gameId}
+*DefaultApi* | [**create_party**](docs/DefaultApi.md#create_party) | **POST** /create | POST create
+*DefaultApi* | [**retrieve_games**](docs/DefaultApi.md#retrieve_games) | **GET** /games/{id} | GET games/{id}
+
+
+## Documentation For Models
+
+ - [GameDto](docs/GameDto.md)
+ - [MoveDto](docs/MoveDto.md)
+ - [ResponseBodyGameDto](docs/ResponseBodyGameDto.md)
+ - [ResponseBodyString](docs/ResponseBodyString.md)
+
+
+
+## Documentation For Authorization
+
+Endpoints do not require authorization.
+
+
+## Author
+
+
+
+
diff --git a/rpi/api-resources/board_mate_client/docs/DefaultApi.md b/rpi/api-resources/board_mate_client/docs/DefaultApi.md
new file mode 100644
index 00000000..6f99dec1
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/docs/DefaultApi.md
@@ -0,0 +1,207 @@
+# openapi_client.DefaultApi
+
+All URIs are relative to *https://boardmate_api*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**add_move**](DefaultApi.md#add_move) | **POST** /moves/add/{gameId} | POST moves/add/{gameId}
+[**create_party**](DefaultApi.md#create_party) | **POST** /create | POST create
+[**retrieve_games**](DefaultApi.md#retrieve_games) | **GET** /games/{id} | GET games/{id}
+
+
+# **add_move**
+> ResponseBodyString add_move(game_id, move_dto)
+
+POST moves/add/{gameId}
+
+### Example
+
+```python
+import board_mate_client
+from board_mate_client.models.move_dto import MoveDto
+from board_mate_client.models.response_body_string import ResponseBodyString
+from board_mate_client.rest import ApiException
+from pprint import pprint
+
+# Defining the host is optional and defaults to https://boardmate_api
+# See configuration.py for a list of all supported configuration parameters.
+configuration = board_mate_client.Configuration(
+ host="https://boardmate_api"
+)
+
+# Enter a context with an instance of the API client
+with board_mate_client.ApiClient(configuration) as api_client:
+ # Create an instance of the API class
+ api_instance = board_mate_client.DefaultApi(api_client)
+ game_id = 'game_id_example' # str |
+ move_dto = board_mate_client.MoveDto() # MoveDto |
+
+ try:
+ # POST moves/add/{gameId}
+ api_response = api_instance.add_move(game_id, move_dto)
+ print("The response of DefaultApi->add_move:\n")
+ pprint(api_response)
+ except Exception as e:
+ print("Exception when calling DefaultApi->add_move: %s\n" % e)
+```
+
+
+
+### Parameters
+
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **game_id** | **str**| |
+ **move_dto** | [**MoveDto**](MoveDto.md)| |
+
+### Return type
+
+[**ResponseBodyString**](ResponseBodyString.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: */*
+
+### HTTP response details
+
+| Status code | Description | Response headers |
+|-------------|-------------|------------------|
+**200** | OK | - |
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **create_party**
+> ResponseBodyString create_party(game_dto)
+
+POST create
+
+### Example
+
+```python
+import board_mate_client
+from board_mate_client.models.game_dto import GameDto
+from board_mate_client.models.response_body_string import ResponseBodyString
+from board_mate_client.rest import ApiException
+from pprint import pprint
+
+# Defining the host is optional and defaults to https://boardmate_api
+# See configuration.py for a list of all supported configuration parameters.
+configuration = board_mate_client.Configuration(
+ host="https://boardmate_api"
+)
+
+# Enter a context with an instance of the API client
+with board_mate_client.ApiClient(configuration) as api_client:
+ # Create an instance of the API class
+ api_instance = board_mate_client.DefaultApi(api_client)
+ game_dto = board_mate_client.GameDto() # GameDto |
+
+ try:
+ # POST create
+ api_response = api_instance.create_party(game_dto)
+ print("The response of DefaultApi->create_party:\n")
+ pprint(api_response)
+ except Exception as e:
+ print("Exception when calling DefaultApi->create_party: %s\n" % e)
+```
+
+
+
+### Parameters
+
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **game_dto** | [**GameDto**](GameDto.md)| |
+
+### Return type
+
+[**ResponseBodyString**](ResponseBodyString.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: */*
+
+### HTTP response details
+
+| Status code | Description | Response headers |
+|-------------|-------------|------------------|
+**200** | OK | - |
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **retrieve_games**
+> ResponseBodyGameDto retrieve_games(id)
+
+GET games/{id}
+
+### Example
+
+```python
+import board_mate_client
+from board_mate_client.models.response_body_game_dto import ResponseBodyGameDto
+from board_mate_client.rest import ApiException
+from pprint import pprint
+
+# Defining the host is optional and defaults to https://boardmate_api
+# See configuration.py for a list of all supported configuration parameters.
+configuration = board_mate_client.Configuration(
+ host="https://boardmate_api"
+)
+
+# Enter a context with an instance of the API client
+with board_mate_client.ApiClient(configuration) as api_client:
+ # Create an instance of the API class
+ api_instance = board_mate_client.DefaultApi(api_client)
+ id = 'id_example' # str |
+
+ try:
+ # GET games/{id}
+ api_response = api_instance.retrieve_games(id)
+ print("The response of DefaultApi->retrieve_games:\n")
+ pprint(api_response)
+ except Exception as e:
+ print("Exception when calling DefaultApi->retrieve_games: %s\n" % e)
+```
+
+
+
+### Parameters
+
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **id** | **str**| |
+
+### Return type
+
+[**ResponseBodyGameDto**](ResponseBodyGameDto.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: */*
+
+### HTTP response details
+
+| Status code | Description | Response headers |
+|-------------|-------------|------------------|
+**200** | OK | - |
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/rpi/api-resources/board_mate_client/docs/GameDto.md b/rpi/api-resources/board_mate_client/docs/GameDto.md
new file mode 100644
index 00000000..53665def
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/docs/GameDto.md
@@ -0,0 +1,32 @@
+# GameDto
+
+
+## Properties
+
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**white_name** | **str** | | [optional]
+**black_name** | **str** | | [optional]
+**time_value** | **int** | | [optional]
+**increment** | **int** | | [optional]
+
+## Example
+
+```python
+from board_mate_client.models.game_dto import GameDto
+
+# TODO update the JSON string below
+json = "{}"
+# create an instance of GameDto from a JSON string
+game_dto_instance = GameDto.from_json(json)
+# print the JSON string representation of the object
+print(GameDto.to_json())
+
+# convert the object into a dict
+game_dto_dict = game_dto_instance.to_dict()
+# create an instance of GameDto from a dict
+game_dto_from_dict = GameDto.from_dict(game_dto_dict)
+```
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/rpi/api-resources/board_mate_client/docs/MoveDto.md b/rpi/api-resources/board_mate_client/docs/MoveDto.md
new file mode 100644
index 00000000..dca2c84f
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/docs/MoveDto.md
@@ -0,0 +1,29 @@
+# MoveDto
+
+
+## Properties
+
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**notation** | **str** | | [optional]
+
+## Example
+
+```python
+from board_mate_client.models.move_dto import MoveDto
+
+# TODO update the JSON string below
+json = "{}"
+# create an instance of MoveDto from a JSON string
+move_dto_instance = MoveDto.from_json(json)
+# print the JSON string representation of the object
+print(MoveDto.to_json())
+
+# convert the object into a dict
+move_dto_dict = move_dto_instance.to_dict()
+# create an instance of MoveDto from a dict
+move_dto_from_dict = MoveDto.from_dict(move_dto_dict)
+```
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/rpi/api-resources/board_mate_client/docs/ResponseBodyGameDto.md b/rpi/api-resources/board_mate_client/docs/ResponseBodyGameDto.md
new file mode 100644
index 00000000..74fa5964
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/docs/ResponseBodyGameDto.md
@@ -0,0 +1,31 @@
+# ResponseBodyGameDto
+
+
+## Properties
+
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**data** | **object** | | [optional]
+**message** | **str** | | [optional]
+**success** | **bool** | | [optional]
+
+## Example
+
+```python
+from board_mate_client.models.response_body_game_dto import ResponseBodyGameDto
+
+# TODO update the JSON string below
+json = "{}"
+# create an instance of ResponseBodyGameDto from a JSON string
+response_body_game_dto_instance = ResponseBodyGameDto.from_json(json)
+# print the JSON string representation of the object
+print(ResponseBodyGameDto.to_json())
+
+# convert the object into a dict
+response_body_game_dto_dict = response_body_game_dto_instance.to_dict()
+# create an instance of ResponseBodyGameDto from a dict
+response_body_game_dto_from_dict = ResponseBodyGameDto.from_dict(response_body_game_dto_dict)
+```
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/rpi/api-resources/board_mate_client/docs/ResponseBodyString.md b/rpi/api-resources/board_mate_client/docs/ResponseBodyString.md
new file mode 100644
index 00000000..e795f3df
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/docs/ResponseBodyString.md
@@ -0,0 +1,31 @@
+# ResponseBodyString
+
+
+## Properties
+
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**data** | **str** | | [optional]
+**message** | **str** | | [optional]
+**success** | **bool** | | [optional]
+
+## Example
+
+```python
+from board_mate_client.models.response_body_string import ResponseBodyString
+
+# TODO update the JSON string below
+json = "{}"
+# create an instance of ResponseBodyString from a JSON string
+response_body_string_instance = ResponseBodyString.from_json(json)
+# print the JSON string representation of the object
+print(ResponseBodyString.to_json())
+
+# convert the object into a dict
+response_body_string_dict = response_body_string_instance.to_dict()
+# create an instance of ResponseBodyString from a dict
+response_body_string_from_dict = ResponseBodyString.from_dict(response_body_string_dict)
+```
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/rpi/api-resources/board_mate_client/git_push.sh b/rpi/api-resources/board_mate_client/git_push.sh
new file mode 100644
index 00000000..f53a75d4
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/git_push.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
+#
+# Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl "minor update" "gitlab.com"
+
+git_user_id=$1
+git_repo_id=$2
+release_note=$3
+git_host=$4
+
+if [ "$git_host" = "" ]; then
+ git_host="github.com"
+ echo "[INFO] No command line input provided. Set \$git_host to $git_host"
+fi
+
+if [ "$git_user_id" = "" ]; then
+ git_user_id="GIT_USER_ID"
+ echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id"
+fi
+
+if [ "$git_repo_id" = "" ]; then
+ git_repo_id="GIT_REPO_ID"
+ echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id"
+fi
+
+if [ "$release_note" = "" ]; then
+ release_note="Minor update"
+ echo "[INFO] No command line input provided. Set \$release_note to $release_note"
+fi
+
+# Initialize the local directory as a Git repository
+git init
+
+# Adds the files in the local repository and stages them for commit.
+git add .
+
+# Commits the tracked changes and prepares them to be pushed to a remote repository.
+git commit -m "$release_note"
+
+# Sets the new remote
+git_remote=$(git remote)
+if [ "$git_remote" = "" ]; then # git remote not defined
+
+ if [ "$GIT_TOKEN" = "" ]; then
+ echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment."
+ git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git
+ else
+ git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@${git_host}/${git_user_id}/${git_repo_id}.git
+ fi
+
+fi
+
+git pull origin master
+
+# Pushes (Forces) the changes in the local repository up to the remote repository
+echo "Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git"
+git push origin master 2>&1 | grep -v 'To https'
diff --git a/rpi/api-resources/board_mate_client/openapi_client/__init__.py b/rpi/api-resources/board_mate_client/openapi_client/__init__.py
new file mode 100644
index 00000000..734bcbdd
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/openapi_client/__init__.py
@@ -0,0 +1,37 @@
+# coding: utf-8
+
+# flake8: noqa
+
+"""
+ boardmate_api API
+
+ boardmate_api API
+
+ The version of the OpenAPI document: 1.0.0
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
+
+ Do not edit the class manually.
+""" # noqa: E501
+
+
+__version__ = "1.0.0"
+
+# import apis into sdk package
+from board_mate_client.api.default_api import DefaultApi
+
+# import ApiClient
+from board_mate_client.api_response import ApiResponse
+from board_mate_client.api_client import ApiClient
+from board_mate_client.configuration import Configuration
+from board_mate_client.exceptions import OpenApiException
+from board_mate_client.exceptions import ApiTypeError
+from board_mate_client.exceptions import ApiValueError
+from board_mate_client.exceptions import ApiKeyError
+from board_mate_client.exceptions import ApiAttributeError
+from board_mate_client.exceptions import ApiException
+
+# import models into sdk package
+from board_mate_client.models.game_dto import GameDto
+from board_mate_client.models.move_dto import MoveDto
+from board_mate_client.models.response_body_game_dto import ResponseBodyGameDto
+from board_mate_client.models.response_body_string import ResponseBodyString
diff --git a/rpi/api-resources/board_mate_client/openapi_client/api/__init__.py b/rpi/api-resources/board_mate_client/openapi_client/api/__init__.py
new file mode 100644
index 00000000..8b0861dd
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/openapi_client/api/__init__.py
@@ -0,0 +1,5 @@
+# flake8: noqa
+
+# import apis into api package
+from board_mate_client.api.default_api import DefaultApi
+
diff --git a/rpi/api-resources/board_mate_client/openapi_client/api/default_api.py b/rpi/api-resources/board_mate_client/openapi_client/api/default_api.py
new file mode 100644
index 00000000..7676ad69
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/openapi_client/api/default_api.py
@@ -0,0 +1,843 @@
+# coding: utf-8
+
+"""
+ boardmate_api API
+
+ boardmate_api API
+
+ The version of the OpenAPI document: 1.0.0
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
+
+ Do not edit the class manually.
+""" # noqa: E501
+
+import warnings
+from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt
+from typing import Any, Dict, List, Optional, Tuple, Union
+from typing_extensions import Annotated
+
+from pydantic import StrictStr
+from board_mate_client.models.game_dto import GameDto
+from board_mate_client.models.move_dto import MoveDto
+from board_mate_client.models.response_body_game_dto import ResponseBodyGameDto
+from board_mate_client.models.response_body_string import ResponseBodyString
+
+from board_mate_client.api_client import ApiClient, RequestSerialized
+from board_mate_client.api_response import ApiResponse
+from board_mate_client.rest import RESTResponseType
+
+
+class DefaultApi:
+ """NOTE: This class is auto generated by OpenAPI Generator
+ Ref: https://openapi-generator.tech
+
+ Do not edit the class manually.
+ """
+
+ def __init__(self, api_client=None) -> None:
+ if api_client is None:
+ api_client = ApiClient.get_default()
+ self.api_client = api_client
+
+
+ @validate_call
+ def add_move(
+ self,
+ game_id: StrictStr,
+ move_dto: MoveDto,
+ _request_timeout: Union[
+ None,
+ Annotated[StrictFloat, Field(gt=0)],
+ Tuple[
+ Annotated[StrictFloat, Field(gt=0)],
+ Annotated[StrictFloat, Field(gt=0)]
+ ]
+ ] = None,
+ _request_auth: Optional[Dict[StrictStr, Any]] = None,
+ _content_type: Optional[StrictStr] = None,
+ _headers: Optional[Dict[StrictStr, Any]] = None,
+ _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
+ ) -> ResponseBodyString:
+ """POST moves/add/{gameId}
+
+
+ :param game_id: (required)
+ :type game_id: str
+ :param move_dto: (required)
+ :type move_dto: MoveDto
+ :param _request_timeout: timeout setting for this request. If one
+ number provided, it will be total request
+ timeout. It can also be a pair (tuple) of
+ (connection, read) timeouts.
+ :type _request_timeout: int, tuple(int, int), optional
+ :param _request_auth: set to override the auth_settings for an a single
+ request; this effectively ignores the
+ authentication in the spec for a single request.
+ :type _request_auth: dict, optional
+ :param _content_type: force content-type for the request.
+ :type _content_type: str, Optional
+ :param _headers: set to override the headers for a single
+ request; this effectively ignores the headers
+ in the spec for a single request.
+ :type _headers: dict, optional
+ :param _host_index: set to override the host_index for a single
+ request; this effectively ignores the host_index
+ in the spec for a single request.
+ :type _host_index: int, optional
+ :return: Returns the result object.
+ """ # noqa: E501
+
+ _param = self._add_move_serialize(
+ game_id=game_id,
+ move_dto=move_dto,
+ _request_auth=_request_auth,
+ _content_type=_content_type,
+ _headers=_headers,
+ _host_index=_host_index
+ )
+
+ _response_types_map: Dict[str, Optional[str]] = {
+ '200': "ResponseBodyString",
+ }
+ response_data = self.api_client.call_api(
+ *_param,
+ _request_timeout=_request_timeout
+ )
+ response_data.read()
+ return self.api_client.response_deserialize(
+ response_data=response_data,
+ response_types_map=_response_types_map,
+ ).data
+
+
+ @validate_call
+ def add_move_with_http_info(
+ self,
+ game_id: StrictStr,
+ move_dto: MoveDto,
+ _request_timeout: Union[
+ None,
+ Annotated[StrictFloat, Field(gt=0)],
+ Tuple[
+ Annotated[StrictFloat, Field(gt=0)],
+ Annotated[StrictFloat, Field(gt=0)]
+ ]
+ ] = None,
+ _request_auth: Optional[Dict[StrictStr, Any]] = None,
+ _content_type: Optional[StrictStr] = None,
+ _headers: Optional[Dict[StrictStr, Any]] = None,
+ _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
+ ) -> ApiResponse[ResponseBodyString]:
+ """POST moves/add/{gameId}
+
+
+ :param game_id: (required)
+ :type game_id: str
+ :param move_dto: (required)
+ :type move_dto: MoveDto
+ :param _request_timeout: timeout setting for this request. If one
+ number provided, it will be total request
+ timeout. It can also be a pair (tuple) of
+ (connection, read) timeouts.
+ :type _request_timeout: int, tuple(int, int), optional
+ :param _request_auth: set to override the auth_settings for an a single
+ request; this effectively ignores the
+ authentication in the spec for a single request.
+ :type _request_auth: dict, optional
+ :param _content_type: force content-type for the request.
+ :type _content_type: str, Optional
+ :param _headers: set to override the headers for a single
+ request; this effectively ignores the headers
+ in the spec for a single request.
+ :type _headers: dict, optional
+ :param _host_index: set to override the host_index for a single
+ request; this effectively ignores the host_index
+ in the spec for a single request.
+ :type _host_index: int, optional
+ :return: Returns the result object.
+ """ # noqa: E501
+
+ _param = self._add_move_serialize(
+ game_id=game_id,
+ move_dto=move_dto,
+ _request_auth=_request_auth,
+ _content_type=_content_type,
+ _headers=_headers,
+ _host_index=_host_index
+ )
+
+ _response_types_map: Dict[str, Optional[str]] = {
+ '200': "ResponseBodyString",
+ }
+ response_data = self.api_client.call_api(
+ *_param,
+ _request_timeout=_request_timeout
+ )
+ response_data.read()
+ return self.api_client.response_deserialize(
+ response_data=response_data,
+ response_types_map=_response_types_map,
+ )
+
+
+ @validate_call
+ def add_move_without_preload_content(
+ self,
+ game_id: StrictStr,
+ move_dto: MoveDto,
+ _request_timeout: Union[
+ None,
+ Annotated[StrictFloat, Field(gt=0)],
+ Tuple[
+ Annotated[StrictFloat, Field(gt=0)],
+ Annotated[StrictFloat, Field(gt=0)]
+ ]
+ ] = None,
+ _request_auth: Optional[Dict[StrictStr, Any]] = None,
+ _content_type: Optional[StrictStr] = None,
+ _headers: Optional[Dict[StrictStr, Any]] = None,
+ _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
+ ) -> RESTResponseType:
+ """POST moves/add/{gameId}
+
+
+ :param game_id: (required)
+ :type game_id: str
+ :param move_dto: (required)
+ :type move_dto: MoveDto
+ :param _request_timeout: timeout setting for this request. If one
+ number provided, it will be total request
+ timeout. It can also be a pair (tuple) of
+ (connection, read) timeouts.
+ :type _request_timeout: int, tuple(int, int), optional
+ :param _request_auth: set to override the auth_settings for an a single
+ request; this effectively ignores the
+ authentication in the spec for a single request.
+ :type _request_auth: dict, optional
+ :param _content_type: force content-type for the request.
+ :type _content_type: str, Optional
+ :param _headers: set to override the headers for a single
+ request; this effectively ignores the headers
+ in the spec for a single request.
+ :type _headers: dict, optional
+ :param _host_index: set to override the host_index for a single
+ request; this effectively ignores the host_index
+ in the spec for a single request.
+ :type _host_index: int, optional
+ :return: Returns the result object.
+ """ # noqa: E501
+
+ _param = self._add_move_serialize(
+ game_id=game_id,
+ move_dto=move_dto,
+ _request_auth=_request_auth,
+ _content_type=_content_type,
+ _headers=_headers,
+ _host_index=_host_index
+ )
+
+ _response_types_map: Dict[str, Optional[str]] = {
+ '200': "ResponseBodyString",
+ }
+ response_data = self.api_client.call_api(
+ *_param,
+ _request_timeout=_request_timeout
+ )
+ return response_data.response
+
+
+ def _add_move_serialize(
+ self,
+ game_id,
+ move_dto,
+ _request_auth,
+ _content_type,
+ _headers,
+ _host_index,
+ ) -> RequestSerialized:
+
+ _host = None
+
+ _collection_formats: Dict[str, str] = {
+ }
+
+ _path_params: Dict[str, str] = {}
+ _query_params: List[Tuple[str, str]] = []
+ _header_params: Dict[str, Optional[str]] = _headers or {}
+ _form_params: List[Tuple[str, str]] = []
+ _files: Dict[str, Union[str, bytes]] = {}
+ _body_params: Optional[bytes] = None
+
+ # process the path parameters
+ if game_id is not None:
+ _path_params['gameId'] = game_id
+ # process the query parameters
+ # process the header parameters
+ # process the form parameters
+ # process the body parameter
+ if move_dto is not None:
+ _body_params = move_dto
+
+
+ # set the HTTP header `Accept`
+ _header_params['Accept'] = self.api_client.select_header_accept(
+ [
+ '*/*'
+ ]
+ )
+
+ # set the HTTP header `Content-Type`
+ if _content_type:
+ _header_params['Content-Type'] = _content_type
+ else:
+ _default_content_type = (
+ self.api_client.select_header_content_type(
+ [
+ 'application/json'
+ ]
+ )
+ )
+ if _default_content_type is not None:
+ _header_params['Content-Type'] = _default_content_type
+
+ # authentication setting
+ _auth_settings: List[str] = [
+ ]
+
+ return self.api_client.param_serialize(
+ method='POST',
+ resource_path='/moves/add/{gameId}',
+ path_params=_path_params,
+ query_params=_query_params,
+ header_params=_header_params,
+ body=_body_params,
+ post_params=_form_params,
+ files=_files,
+ auth_settings=_auth_settings,
+ collection_formats=_collection_formats,
+ _host=_host,
+ _request_auth=_request_auth
+ )
+
+
+
+
+ @validate_call
+ def create_party(
+ self,
+ game_dto: GameDto,
+ _request_timeout: Union[
+ None,
+ Annotated[StrictFloat, Field(gt=0)],
+ Tuple[
+ Annotated[StrictFloat, Field(gt=0)],
+ Annotated[StrictFloat, Field(gt=0)]
+ ]
+ ] = None,
+ _request_auth: Optional[Dict[StrictStr, Any]] = None,
+ _content_type: Optional[StrictStr] = None,
+ _headers: Optional[Dict[StrictStr, Any]] = None,
+ _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
+ ) -> ResponseBodyString:
+ """POST create
+
+
+ :param game_dto: (required)
+ :type game_dto: GameDto
+ :param _request_timeout: timeout setting for this request. If one
+ number provided, it will be total request
+ timeout. It can also be a pair (tuple) of
+ (connection, read) timeouts.
+ :type _request_timeout: int, tuple(int, int), optional
+ :param _request_auth: set to override the auth_settings for an a single
+ request; this effectively ignores the
+ authentication in the spec for a single request.
+ :type _request_auth: dict, optional
+ :param _content_type: force content-type for the request.
+ :type _content_type: str, Optional
+ :param _headers: set to override the headers for a single
+ request; this effectively ignores the headers
+ in the spec for a single request.
+ :type _headers: dict, optional
+ :param _host_index: set to override the host_index for a single
+ request; this effectively ignores the host_index
+ in the spec for a single request.
+ :type _host_index: int, optional
+ :return: Returns the result object.
+ """ # noqa: E501
+
+ _param = self._create_party_serialize(
+ game_dto=game_dto,
+ _request_auth=_request_auth,
+ _content_type=_content_type,
+ _headers=_headers,
+ _host_index=_host_index
+ )
+
+ _response_types_map: Dict[str, Optional[str]] = {
+ '200': "ResponseBodyString",
+ }
+ response_data = self.api_client.call_api(
+ *_param,
+ _request_timeout=_request_timeout
+ )
+ response_data.read()
+ return self.api_client.response_deserialize(
+ response_data=response_data,
+ response_types_map=_response_types_map,
+ ).data
+
+
+ @validate_call
+ def create_party_with_http_info(
+ self,
+ game_dto: GameDto,
+ _request_timeout: Union[
+ None,
+ Annotated[StrictFloat, Field(gt=0)],
+ Tuple[
+ Annotated[StrictFloat, Field(gt=0)],
+ Annotated[StrictFloat, Field(gt=0)]
+ ]
+ ] = None,
+ _request_auth: Optional[Dict[StrictStr, Any]] = None,
+ _content_type: Optional[StrictStr] = None,
+ _headers: Optional[Dict[StrictStr, Any]] = None,
+ _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
+ ) -> ApiResponse[ResponseBodyString]:
+ """POST create
+
+
+ :param game_dto: (required)
+ :type game_dto: GameDto
+ :param _request_timeout: timeout setting for this request. If one
+ number provided, it will be total request
+ timeout. It can also be a pair (tuple) of
+ (connection, read) timeouts.
+ :type _request_timeout: int, tuple(int, int), optional
+ :param _request_auth: set to override the auth_settings for an a single
+ request; this effectively ignores the
+ authentication in the spec for a single request.
+ :type _request_auth: dict, optional
+ :param _content_type: force content-type for the request.
+ :type _content_type: str, Optional
+ :param _headers: set to override the headers for a single
+ request; this effectively ignores the headers
+ in the spec for a single request.
+ :type _headers: dict, optional
+ :param _host_index: set to override the host_index for a single
+ request; this effectively ignores the host_index
+ in the spec for a single request.
+ :type _host_index: int, optional
+ :return: Returns the result object.
+ """ # noqa: E501
+
+ _param = self._create_party_serialize(
+ game_dto=game_dto,
+ _request_auth=_request_auth,
+ _content_type=_content_type,
+ _headers=_headers,
+ _host_index=_host_index
+ )
+
+ _response_types_map: Dict[str, Optional[str]] = {
+ '200': "ResponseBodyString",
+ }
+ response_data = self.api_client.call_api(
+ *_param,
+ _request_timeout=_request_timeout
+ )
+ response_data.read()
+ return self.api_client.response_deserialize(
+ response_data=response_data,
+ response_types_map=_response_types_map,
+ )
+
+
+ @validate_call
+ def create_party_without_preload_content(
+ self,
+ game_dto: GameDto,
+ _request_timeout: Union[
+ None,
+ Annotated[StrictFloat, Field(gt=0)],
+ Tuple[
+ Annotated[StrictFloat, Field(gt=0)],
+ Annotated[StrictFloat, Field(gt=0)]
+ ]
+ ] = None,
+ _request_auth: Optional[Dict[StrictStr, Any]] = None,
+ _content_type: Optional[StrictStr] = None,
+ _headers: Optional[Dict[StrictStr, Any]] = None,
+ _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
+ ) -> RESTResponseType:
+ """POST create
+
+
+ :param game_dto: (required)
+ :type game_dto: GameDto
+ :param _request_timeout: timeout setting for this request. If one
+ number provided, it will be total request
+ timeout. It can also be a pair (tuple) of
+ (connection, read) timeouts.
+ :type _request_timeout: int, tuple(int, int), optional
+ :param _request_auth: set to override the auth_settings for an a single
+ request; this effectively ignores the
+ authentication in the spec for a single request.
+ :type _request_auth: dict, optional
+ :param _content_type: force content-type for the request.
+ :type _content_type: str, Optional
+ :param _headers: set to override the headers for a single
+ request; this effectively ignores the headers
+ in the spec for a single request.
+ :type _headers: dict, optional
+ :param _host_index: set to override the host_index for a single
+ request; this effectively ignores the host_index
+ in the spec for a single request.
+ :type _host_index: int, optional
+ :return: Returns the result object.
+ """ # noqa: E501
+
+ _param = self._create_party_serialize(
+ game_dto=game_dto,
+ _request_auth=_request_auth,
+ _content_type=_content_type,
+ _headers=_headers,
+ _host_index=_host_index
+ )
+
+ _response_types_map: Dict[str, Optional[str]] = {
+ '200': "ResponseBodyString",
+ }
+ response_data = self.api_client.call_api(
+ *_param,
+ _request_timeout=_request_timeout
+ )
+ return response_data.response
+
+
+ def _create_party_serialize(
+ self,
+ game_dto,
+ _request_auth,
+ _content_type,
+ _headers,
+ _host_index,
+ ) -> RequestSerialized:
+
+ _host = None
+
+ _collection_formats: Dict[str, str] = {
+ }
+
+ _path_params: Dict[str, str] = {}
+ _query_params: List[Tuple[str, str]] = []
+ _header_params: Dict[str, Optional[str]] = _headers or {}
+ _form_params: List[Tuple[str, str]] = []
+ _files: Dict[str, Union[str, bytes]] = {}
+ _body_params: Optional[bytes] = None
+
+ # process the path parameters
+ # process the query parameters
+ # process the header parameters
+ # process the form parameters
+ # process the body parameter
+ if game_dto is not None:
+ _body_params = game_dto
+
+
+ # set the HTTP header `Accept`
+ _header_params['Accept'] = self.api_client.select_header_accept(
+ [
+ '*/*'
+ ]
+ )
+
+ # set the HTTP header `Content-Type`
+ if _content_type:
+ _header_params['Content-Type'] = _content_type
+ else:
+ _default_content_type = (
+ self.api_client.select_header_content_type(
+ [
+ 'application/json'
+ ]
+ )
+ )
+ if _default_content_type is not None:
+ _header_params['Content-Type'] = _default_content_type
+
+ # authentication setting
+ _auth_settings: List[str] = [
+ ]
+
+ return self.api_client.param_serialize(
+ method='POST',
+ resource_path='/create',
+ path_params=_path_params,
+ query_params=_query_params,
+ header_params=_header_params,
+ body=_body_params,
+ post_params=_form_params,
+ files=_files,
+ auth_settings=_auth_settings,
+ collection_formats=_collection_formats,
+ _host=_host,
+ _request_auth=_request_auth
+ )
+
+
+
+
+ @validate_call
+ def retrieve_games(
+ self,
+ id: StrictStr,
+ _request_timeout: Union[
+ None,
+ Annotated[StrictFloat, Field(gt=0)],
+ Tuple[
+ Annotated[StrictFloat, Field(gt=0)],
+ Annotated[StrictFloat, Field(gt=0)]
+ ]
+ ] = None,
+ _request_auth: Optional[Dict[StrictStr, Any]] = None,
+ _content_type: Optional[StrictStr] = None,
+ _headers: Optional[Dict[StrictStr, Any]] = None,
+ _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
+ ) -> ResponseBodyGameDto:
+ """GET games/{id}
+
+
+ :param id: (required)
+ :type id: str
+ :param _request_timeout: timeout setting for this request. If one
+ number provided, it will be total request
+ timeout. It can also be a pair (tuple) of
+ (connection, read) timeouts.
+ :type _request_timeout: int, tuple(int, int), optional
+ :param _request_auth: set to override the auth_settings for an a single
+ request; this effectively ignores the
+ authentication in the spec for a single request.
+ :type _request_auth: dict, optional
+ :param _content_type: force content-type for the request.
+ :type _content_type: str, Optional
+ :param _headers: set to override the headers for a single
+ request; this effectively ignores the headers
+ in the spec for a single request.
+ :type _headers: dict, optional
+ :param _host_index: set to override the host_index for a single
+ request; this effectively ignores the host_index
+ in the spec for a single request.
+ :type _host_index: int, optional
+ :return: Returns the result object.
+ """ # noqa: E501
+
+ _param = self._retrieve_games_serialize(
+ id=id,
+ _request_auth=_request_auth,
+ _content_type=_content_type,
+ _headers=_headers,
+ _host_index=_host_index
+ )
+
+ _response_types_map: Dict[str, Optional[str]] = {
+ '200': "ResponseBodyGameDto",
+ }
+ response_data = self.api_client.call_api(
+ *_param,
+ _request_timeout=_request_timeout
+ )
+ response_data.read()
+ return self.api_client.response_deserialize(
+ response_data=response_data,
+ response_types_map=_response_types_map,
+ ).data
+
+
+ @validate_call
+ def retrieve_games_with_http_info(
+ self,
+ id: StrictStr,
+ _request_timeout: Union[
+ None,
+ Annotated[StrictFloat, Field(gt=0)],
+ Tuple[
+ Annotated[StrictFloat, Field(gt=0)],
+ Annotated[StrictFloat, Field(gt=0)]
+ ]
+ ] = None,
+ _request_auth: Optional[Dict[StrictStr, Any]] = None,
+ _content_type: Optional[StrictStr] = None,
+ _headers: Optional[Dict[StrictStr, Any]] = None,
+ _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
+ ) -> ApiResponse[ResponseBodyGameDto]:
+ """GET games/{id}
+
+
+ :param id: (required)
+ :type id: str
+ :param _request_timeout: timeout setting for this request. If one
+ number provided, it will be total request
+ timeout. It can also be a pair (tuple) of
+ (connection, read) timeouts.
+ :type _request_timeout: int, tuple(int, int), optional
+ :param _request_auth: set to override the auth_settings for an a single
+ request; this effectively ignores the
+ authentication in the spec for a single request.
+ :type _request_auth: dict, optional
+ :param _content_type: force content-type for the request.
+ :type _content_type: str, Optional
+ :param _headers: set to override the headers for a single
+ request; this effectively ignores the headers
+ in the spec for a single request.
+ :type _headers: dict, optional
+ :param _host_index: set to override the host_index for a single
+ request; this effectively ignores the host_index
+ in the spec for a single request.
+ :type _host_index: int, optional
+ :return: Returns the result object.
+ """ # noqa: E501
+
+ _param = self._retrieve_games_serialize(
+ id=id,
+ _request_auth=_request_auth,
+ _content_type=_content_type,
+ _headers=_headers,
+ _host_index=_host_index
+ )
+
+ _response_types_map: Dict[str, Optional[str]] = {
+ '200': "ResponseBodyGameDto",
+ }
+ response_data = self.api_client.call_api(
+ *_param,
+ _request_timeout=_request_timeout
+ )
+ response_data.read()
+ return self.api_client.response_deserialize(
+ response_data=response_data,
+ response_types_map=_response_types_map,
+ )
+
+
+ @validate_call
+ def retrieve_games_without_preload_content(
+ self,
+ id: StrictStr,
+ _request_timeout: Union[
+ None,
+ Annotated[StrictFloat, Field(gt=0)],
+ Tuple[
+ Annotated[StrictFloat, Field(gt=0)],
+ Annotated[StrictFloat, Field(gt=0)]
+ ]
+ ] = None,
+ _request_auth: Optional[Dict[StrictStr, Any]] = None,
+ _content_type: Optional[StrictStr] = None,
+ _headers: Optional[Dict[StrictStr, Any]] = None,
+ _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
+ ) -> RESTResponseType:
+ """GET games/{id}
+
+
+ :param id: (required)
+ :type id: str
+ :param _request_timeout: timeout setting for this request. If one
+ number provided, it will be total request
+ timeout. It can also be a pair (tuple) of
+ (connection, read) timeouts.
+ :type _request_timeout: int, tuple(int, int), optional
+ :param _request_auth: set to override the auth_settings for an a single
+ request; this effectively ignores the
+ authentication in the spec for a single request.
+ :type _request_auth: dict, optional
+ :param _content_type: force content-type for the request.
+ :type _content_type: str, Optional
+ :param _headers: set to override the headers for a single
+ request; this effectively ignores the headers
+ in the spec for a single request.
+ :type _headers: dict, optional
+ :param _host_index: set to override the host_index for a single
+ request; this effectively ignores the host_index
+ in the spec for a single request.
+ :type _host_index: int, optional
+ :return: Returns the result object.
+ """ # noqa: E501
+
+ _param = self._retrieve_games_serialize(
+ id=id,
+ _request_auth=_request_auth,
+ _content_type=_content_type,
+ _headers=_headers,
+ _host_index=_host_index
+ )
+
+ _response_types_map: Dict[str, Optional[str]] = {
+ '200': "ResponseBodyGameDto",
+ }
+ response_data = self.api_client.call_api(
+ *_param,
+ _request_timeout=_request_timeout
+ )
+ return response_data.response
+
+
+ def _retrieve_games_serialize(
+ self,
+ id,
+ _request_auth,
+ _content_type,
+ _headers,
+ _host_index,
+ ) -> RequestSerialized:
+
+ _host = None
+
+ _collection_formats: Dict[str, str] = {
+ }
+
+ _path_params: Dict[str, str] = {}
+ _query_params: List[Tuple[str, str]] = []
+ _header_params: Dict[str, Optional[str]] = _headers or {}
+ _form_params: List[Tuple[str, str]] = []
+ _files: Dict[str, Union[str, bytes]] = {}
+ _body_params: Optional[bytes] = None
+
+ # process the path parameters
+ if id is not None:
+ _path_params['id'] = id
+ # process the query parameters
+ # process the header parameters
+ # process the form parameters
+ # process the body parameter
+
+
+ # set the HTTP header `Accept`
+ _header_params['Accept'] = self.api_client.select_header_accept(
+ [
+ '*/*'
+ ]
+ )
+
+
+ # authentication setting
+ _auth_settings: List[str] = [
+ ]
+
+ return self.api_client.param_serialize(
+ method='GET',
+ resource_path='/games/{id}',
+ path_params=_path_params,
+ query_params=_query_params,
+ header_params=_header_params,
+ body=_body_params,
+ post_params=_form_params,
+ files=_files,
+ auth_settings=_auth_settings,
+ collection_formats=_collection_formats,
+ _host=_host,
+ _request_auth=_request_auth
+ )
+
+
diff --git a/rpi/api-resources/board_mate_client/openapi_client/api_client.py b/rpi/api-resources/board_mate_client/openapi_client/api_client.py
new file mode 100644
index 00000000..59eaa005
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/openapi_client/api_client.py
@@ -0,0 +1,770 @@
+# coding: utf-8
+
+"""
+ boardmate_api API
+
+ boardmate_api API
+
+ The version of the OpenAPI document: 1.0.0
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
+
+ Do not edit the class manually.
+""" # noqa: E501
+
+
+import datetime
+from dateutil.parser import parse
+from enum import Enum
+import json
+import mimetypes
+import os
+import re
+import tempfile
+
+from urllib.parse import quote
+from typing import Tuple, Optional, List, Dict, Union
+from pydantic import SecretStr
+
+from board_mate_client.configuration import Configuration
+from board_mate_client.api_response import ApiResponse, T as ApiResponseT
+import board_mate_client.models
+from board_mate_client import rest
+from board_mate_client.exceptions import (
+ ApiValueError,
+ ApiException,
+ BadRequestException,
+ UnauthorizedException,
+ ForbiddenException,
+ NotFoundException,
+ ServiceException
+)
+
+RequestSerialized = Tuple[str, str, Dict[str, str], Optional[str], List[str]]
+
+class ApiClient:
+ """Generic API client for OpenAPI client library builds.
+
+ OpenAPI generic API client. This client handles the client-
+ server communication, and is invariant across implementations. Specifics of
+ the methods and models for each application are generated from the OpenAPI
+ templates.
+
+ :param configuration: .Configuration object for this client
+ :param header_name: a header to pass when making calls to the API.
+ :param header_value: a header value to pass when making calls to
+ the API.
+ :param cookie: a cookie to include in the header when making calls
+ to the API
+ """
+
+ PRIMITIVE_TYPES = (float, bool, bytes, str, int)
+ NATIVE_TYPES_MAPPING = {
+ 'int': int,
+ 'long': int, # TODO remove as only py3 is supported?
+ 'float': float,
+ 'str': str,
+ 'bool': bool,
+ 'date': datetime.date,
+ 'datetime': datetime.datetime,
+ 'object': object,
+ }
+ _pool = None
+
+ def __init__(
+ self,
+ configuration=None,
+ header_name=None,
+ header_value=None,
+ cookie=None
+ ) -> None:
+ # use default configuration if none is provided
+ if configuration is None:
+ configuration = Configuration.get_default()
+ self.configuration = configuration
+
+ self.rest_client = rest.RESTClientObject(configuration)
+ self.default_headers = {}
+ if header_name is not None:
+ self.default_headers[header_name] = header_value
+ self.cookie = cookie
+ # Set default User-Agent.
+ self.user_agent = 'OpenAPI-Generator/1.0.0/python'
+ self.client_side_validation = configuration.client_side_validation
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ pass
+
+ @property
+ def user_agent(self):
+ """User agent for this API client"""
+ return self.default_headers['User-Agent']
+
+ @user_agent.setter
+ def user_agent(self, value):
+ self.default_headers['User-Agent'] = value
+
+ def set_default_header(self, header_name, header_value):
+ self.default_headers[header_name] = header_value
+
+
+ _default = None
+
+ @classmethod
+ def get_default(cls):
+ """Return new instance of ApiClient.
+
+ This method returns newly created, based on default constructor,
+ object of ApiClient class or returns a copy of default
+ ApiClient.
+
+ :return: The ApiClient object.
+ """
+ if cls._default is None:
+ cls._default = ApiClient()
+ return cls._default
+
+ @classmethod
+ def set_default(cls, default):
+ """Set default instance of ApiClient.
+
+ It stores default ApiClient.
+
+ :param default: object of ApiClient.
+ """
+ cls._default = default
+
+ def param_serialize(
+ self,
+ method,
+ resource_path,
+ path_params=None,
+ query_params=None,
+ header_params=None,
+ body=None,
+ post_params=None,
+ files=None, auth_settings=None,
+ collection_formats=None,
+ _host=None,
+ _request_auth=None
+ ) -> RequestSerialized:
+
+ """Builds the HTTP request params needed by the request.
+ :param method: Method to call.
+ :param resource_path: Path to method endpoint.
+ :param path_params: Path parameters in the url.
+ :param query_params: Query parameters in the url.
+ :param header_params: Header parameters to be
+ placed in the request header.
+ :param body: Request body.
+ :param post_params dict: Request post form parameters,
+ for `application/x-www-form-urlencoded`, `multipart/form-data`.
+ :param auth_settings list: Auth Settings names for the request.
+ :param files dict: key -> filename, value -> filepath,
+ for `multipart/form-data`.
+ :param collection_formats: dict of collection formats for path, query,
+ header, and post parameters.
+ :param _request_auth: set to override the auth_settings for an a single
+ request; this effectively ignores the authentication
+ in the spec for a single request.
+ :return: tuple of form (path, http_method, query_params, header_params,
+ body, post_params, files)
+ """
+
+ config = self.configuration
+
+ # header parameters
+ header_params = header_params or {}
+ header_params.update(self.default_headers)
+ if self.cookie:
+ header_params['Cookie'] = self.cookie
+ if header_params:
+ header_params = self.sanitize_for_serialization(header_params)
+ header_params = dict(
+ self.parameters_to_tuples(header_params,collection_formats)
+ )
+
+ # path parameters
+ if path_params:
+ path_params = self.sanitize_for_serialization(path_params)
+ path_params = self.parameters_to_tuples(
+ path_params,
+ collection_formats
+ )
+ for k, v in path_params:
+ # specified safe chars, encode everything
+ resource_path = resource_path.replace(
+ '{%s}' % k,
+ quote(str(v), safe=config.safe_chars_for_path_param)
+ )
+
+ # post parameters
+ if post_params or files:
+ post_params = post_params if post_params else []
+ post_params = self.sanitize_for_serialization(post_params)
+ post_params = self.parameters_to_tuples(
+ post_params,
+ collection_formats
+ )
+ if files:
+ post_params.extend(self.files_parameters(files))
+
+ # auth setting
+ self.update_params_for_auth(
+ header_params,
+ query_params,
+ auth_settings,
+ resource_path,
+ method,
+ body,
+ request_auth=_request_auth
+ )
+
+ # body
+ if body:
+ body = self.sanitize_for_serialization(body)
+
+ # request url
+ if _host is None:
+ url = self.configuration.host + resource_path
+ else:
+ # use server/host defined in path or operation instead
+ url = _host + resource_path
+
+ # query parameters
+ if query_params:
+ query_params = self.sanitize_for_serialization(query_params)
+ url_query = self.parameters_to_url_query(
+ query_params,
+ collection_formats
+ )
+ url += "?" + url_query
+
+ return method, url, header_params, body, post_params
+
+
+ def call_api(
+ self,
+ method,
+ url,
+ header_params=None,
+ body=None,
+ post_params=None,
+ _request_timeout=None
+ ) -> rest.RESTResponse:
+ """Makes the HTTP request (synchronous)
+ :param method: Method to call.
+ :param url: Path to method endpoint.
+ :param header_params: Header parameters to be
+ placed in the request header.
+ :param body: Request body.
+ :param post_params dict: Request post form parameters,
+ for `application/x-www-form-urlencoded`, `multipart/form-data`.
+ :param _request_timeout: timeout setting for this request.
+ :return: RESTResponse
+ """
+
+ try:
+ # perform request and return response
+ response_data = self.rest_client.request(
+ method, url,
+ headers=header_params,
+ body=body, post_params=post_params,
+ _request_timeout=_request_timeout
+ )
+
+ except ApiException as e:
+ raise e
+
+ return response_data
+
+ def response_deserialize(
+ self,
+ response_data: rest.RESTResponse,
+ response_types_map: Optional[Dict[str, ApiResponseT]]=None
+ ) -> ApiResponse[ApiResponseT]:
+ """Deserializes response into an object.
+ :param response_data: RESTResponse object to be deserialized.
+ :param response_types_map: dict of response types.
+ :return: ApiResponse
+ """
+
+ msg = "RESTResponse.read() must be called before passing it to response_deserialize()"
+ assert response_data.data is not None, msg
+
+ response_type = response_types_map.get(str(response_data.status), None)
+ if not response_type and isinstance(response_data.status, int) and 100 <= response_data.status <= 599:
+ # if not found, look for '1XX', '2XX', etc.
+ response_type = response_types_map.get(str(response_data.status)[0] + "XX", None)
+
+ # deserialize response data
+ response_text = None
+ return_data = None
+ try:
+ if response_type == "bytearray":
+ return_data = response_data.data
+ elif response_type == "file":
+ return_data = self.__deserialize_file(response_data)
+ elif response_type is not None:
+ match = None
+ content_type = response_data.getheader('content-type')
+ if content_type is not None:
+ match = re.search(r"charset=([a-zA-Z\-\d]+)[\s;]?", content_type)
+ encoding = match.group(1) if match else "utf-8"
+ response_text = response_data.data.decode(encoding)
+ if response_type in ["bytearray", "str"]:
+ return_data = self.__deserialize_primitive(response_text, response_type)
+ else:
+ return_data = self.deserialize(response_text, response_type)
+ finally:
+ if not 200 <= response_data.status <= 299:
+ raise ApiException.from_response(
+ http_resp=response_data,
+ body=response_text,
+ data=return_data,
+ )
+
+ return ApiResponse(
+ status_code = response_data.status,
+ data = return_data,
+ headers = response_data.getheaders(),
+ raw_data = response_data.data
+ )
+
+ def sanitize_for_serialization(self, obj):
+ """Builds a JSON POST object.
+
+ If obj is None, return None.
+ If obj is SecretStr, return obj.get_secret_value()
+ If obj is str, int, long, float, bool, return directly.
+ If obj is datetime.datetime, datetime.date
+ convert to string in iso8601 format.
+ If obj is list, sanitize each element in the list.
+ If obj is dict, return the dict.
+ If obj is OpenAPI model, return the properties dict.
+
+ :param obj: The data to serialize.
+ :return: The serialized form of data.
+ """
+ if obj is None:
+ return None
+ elif isinstance(obj, Enum):
+ return obj.value
+ elif isinstance(obj, SecretStr):
+ return obj.get_secret_value()
+ elif isinstance(obj, self.PRIMITIVE_TYPES):
+ return obj
+ elif isinstance(obj, list):
+ return [
+ self.sanitize_for_serialization(sub_obj) for sub_obj in obj
+ ]
+ elif isinstance(obj, tuple):
+ return tuple(
+ self.sanitize_for_serialization(sub_obj) for sub_obj in obj
+ )
+ elif isinstance(obj, (datetime.datetime, datetime.date)):
+ return obj.isoformat()
+
+ elif isinstance(obj, dict):
+ obj_dict = obj
+ else:
+ # Convert model obj to dict except
+ # attributes `openapi_types`, `attribute_map`
+ # and attributes which value is not None.
+ # Convert attribute name to json key in
+ # model definition for request.
+ if hasattr(obj, 'to_dict') and callable(getattr(obj, 'to_dict')):
+ obj_dict = obj.to_dict()
+ else:
+ obj_dict = obj.__dict__
+
+ return {
+ key: self.sanitize_for_serialization(val)
+ for key, val in obj_dict.items()
+ }
+
+ def deserialize(self, response_text, response_type):
+ """Deserializes response into an object.
+
+ :param response: RESTResponse object to be deserialized.
+ :param response_type: class literal for
+ deserialized object, or string of class name.
+
+ :return: deserialized object.
+ """
+
+ # fetch data from response object
+ try:
+ data = json.loads(response_text)
+ except ValueError:
+ data = response_text
+
+ return self.__deserialize(data, response_type)
+
+ def __deserialize(self, data, klass):
+ """Deserializes dict, list, str into an object.
+
+ :param data: dict, list or str.
+ :param klass: class literal, or string of class name.
+
+ :return: object.
+ """
+ if data is None:
+ return None
+
+ if isinstance(klass, str):
+ if klass.startswith('List['):
+ m = re.match(r'List\[(.*)]', klass)
+ assert m is not None, "Malformed List type definition"
+ sub_kls = m.group(1)
+ return [self.__deserialize(sub_data, sub_kls)
+ for sub_data in data]
+
+ if klass.startswith('Dict['):
+ m = re.match(r'Dict\[([^,]*), (.*)]', klass)
+ assert m is not None, "Malformed Dict type definition"
+ sub_kls = m.group(2)
+ return {k: self.__deserialize(v, sub_kls)
+ for k, v in data.items()}
+
+ # convert str to class
+ if klass in self.NATIVE_TYPES_MAPPING:
+ klass = self.NATIVE_TYPES_MAPPING[klass]
+ else:
+ klass = getattr(board_mate_client.models, klass)
+
+ if klass in self.PRIMITIVE_TYPES:
+ return self.__deserialize_primitive(data, klass)
+ elif klass == object:
+ return self.__deserialize_object(data)
+ elif klass == datetime.date:
+ return self.__deserialize_date(data)
+ elif klass == datetime.datetime:
+ return self.__deserialize_datetime(data)
+ elif issubclass(klass, Enum):
+ return self.__deserialize_enum(data, klass)
+ else:
+ return self.__deserialize_model(data, klass)
+
+ def parameters_to_tuples(self, params, collection_formats):
+ """Get parameters as list of tuples, formatting collections.
+
+ :param params: Parameters as dict or list of two-tuples
+ :param dict collection_formats: Parameter collection formats
+ :return: Parameters as list of tuples, collections formatted
+ """
+ new_params: List[Tuple[str, str]] = []
+ if collection_formats is None:
+ collection_formats = {}
+ for k, v in params.items() if isinstance(params, dict) else params:
+ if k in collection_formats:
+ collection_format = collection_formats[k]
+ if collection_format == 'multi':
+ new_params.extend((k, value) for value in v)
+ else:
+ if collection_format == 'ssv':
+ delimiter = ' '
+ elif collection_format == 'tsv':
+ delimiter = '\t'
+ elif collection_format == 'pipes':
+ delimiter = '|'
+ else: # csv is the default
+ delimiter = ','
+ new_params.append(
+ (k, delimiter.join(str(value) for value in v)))
+ else:
+ new_params.append((k, v))
+ return new_params
+
+ def parameters_to_url_query(self, params, collection_formats):
+ """Get parameters as list of tuples, formatting collections.
+
+ :param params: Parameters as dict or list of two-tuples
+ :param dict collection_formats: Parameter collection formats
+ :return: URL query string (e.g. a=Hello%20World&b=123)
+ """
+ new_params: List[Tuple[str, str]] = []
+ if collection_formats is None:
+ collection_formats = {}
+ for k, v in params.items() if isinstance(params, dict) else params:
+ if isinstance(v, bool):
+ v = str(v).lower()
+ if isinstance(v, (int, float)):
+ v = str(v)
+ if isinstance(v, dict):
+ v = json.dumps(v)
+
+ if k in collection_formats:
+ collection_format = collection_formats[k]
+ if collection_format == 'multi':
+ new_params.extend((k, str(value)) for value in v)
+ else:
+ if collection_format == 'ssv':
+ delimiter = ' '
+ elif collection_format == 'tsv':
+ delimiter = '\t'
+ elif collection_format == 'pipes':
+ delimiter = '|'
+ else: # csv is the default
+ delimiter = ','
+ new_params.append(
+ (k, delimiter.join(quote(str(value)) for value in v))
+ )
+ else:
+ new_params.append((k, quote(str(v))))
+
+ return "&".join(["=".join(map(str, item)) for item in new_params])
+
+ def files_parameters(self, files: Dict[str, Union[str, bytes]]):
+ """Builds form parameters.
+
+ :param files: File parameters.
+ :return: Form parameters with files.
+ """
+ params = []
+ for k, v in files.items():
+ if isinstance(v, str):
+ with open(v, 'rb') as f:
+ filename = os.path.basename(f.name)
+ filedata = f.read()
+ elif isinstance(v, bytes):
+ filename = k
+ filedata = v
+ else:
+ raise ValueError("Unsupported file value")
+ mimetype = (
+ mimetypes.guess_type(filename)[0]
+ or 'application/octet-stream'
+ )
+ params.append(
+ tuple([k, tuple([filename, filedata, mimetype])])
+ )
+ return params
+
+ def select_header_accept(self, accepts: List[str]) -> Optional[str]:
+ """Returns `Accept` based on an array of accepts provided.
+
+ :param accepts: List of headers.
+ :return: Accept (e.g. application/json).
+ """
+ if not accepts:
+ return None
+
+ for accept in accepts:
+ if re.search('json', accept, re.IGNORECASE):
+ return accept
+
+ return accepts[0]
+
+ def select_header_content_type(self, content_types):
+ """Returns `Content-Type` based on an array of content_types provided.
+
+ :param content_types: List of content-types.
+ :return: Content-Type (e.g. application/json).
+ """
+ if not content_types:
+ return None
+
+ for content_type in content_types:
+ if re.search('json', content_type, re.IGNORECASE):
+ return content_type
+
+ return content_types[0]
+
+ def update_params_for_auth(
+ self,
+ headers,
+ queries,
+ auth_settings,
+ resource_path,
+ method,
+ body,
+ request_auth=None
+ ) -> None:
+ """Updates header and query params based on authentication setting.
+
+ :param headers: Header parameters dict to be updated.
+ :param queries: Query parameters tuple list to be updated.
+ :param auth_settings: Authentication setting identifiers list.
+ :resource_path: A string representation of the HTTP request resource path.
+ :method: A string representation of the HTTP request method.
+ :body: A object representing the body of the HTTP request.
+ The object type is the return value of sanitize_for_serialization().
+ :param request_auth: if set, the provided settings will
+ override the token in the configuration.
+ """
+ if not auth_settings:
+ return
+
+ if request_auth:
+ self._apply_auth_params(
+ headers,
+ queries,
+ resource_path,
+ method,
+ body,
+ request_auth
+ )
+ else:
+ for auth in auth_settings:
+ auth_setting = self.configuration.auth_settings().get(auth)
+ if auth_setting:
+ self._apply_auth_params(
+ headers,
+ queries,
+ resource_path,
+ method,
+ body,
+ auth_setting
+ )
+
+ def _apply_auth_params(
+ self,
+ headers,
+ queries,
+ resource_path,
+ method,
+ body,
+ auth_setting
+ ) -> None:
+ """Updates the request parameters based on a single auth_setting
+
+ :param headers: Header parameters dict to be updated.
+ :param queries: Query parameters tuple list to be updated.
+ :resource_path: A string representation of the HTTP request resource path.
+ :method: A string representation of the HTTP request method.
+ :body: A object representing the body of the HTTP request.
+ The object type is the return value of sanitize_for_serialization().
+ :param auth_setting: auth settings for the endpoint
+ """
+ if auth_setting['in'] == 'cookie':
+ headers['Cookie'] = auth_setting['value']
+ elif auth_setting['in'] == 'header':
+ if auth_setting['type'] != 'http-signature':
+ headers[auth_setting['key']] = auth_setting['value']
+ elif auth_setting['in'] == 'query':
+ queries.append((auth_setting['key'], auth_setting['value']))
+ else:
+ raise ApiValueError(
+ 'Authentication token must be in `query` or `header`'
+ )
+
+ def __deserialize_file(self, response):
+ """Deserializes body to file
+
+ Saves response body into a file in a temporary folder,
+ using the filename from the `Content-Disposition` header if provided.
+
+ handle file downloading
+ save response body into a tmp file and return the instance
+
+ :param response: RESTResponse.
+ :return: file path.
+ """
+ fd, path = tempfile.mkstemp(dir=self.configuration.temp_folder_path)
+ os.close(fd)
+ os.remove(path)
+
+ content_disposition = response.getheader("Content-Disposition")
+ if content_disposition:
+ m = re.search(
+ r'filename=[\'"]?([^\'"\s]+)[\'"]?',
+ content_disposition
+ )
+ assert m is not None, "Unexpected 'content-disposition' header value"
+ filename = m.group(1)
+ path = os.path.join(os.path.dirname(path), filename)
+
+ with open(path, "wb") as f:
+ f.write(response.data)
+
+ return path
+
+ def __deserialize_primitive(self, data, klass):
+ """Deserializes string to primitive type.
+
+ :param data: str.
+ :param klass: class literal.
+
+ :return: int, long, float, str, bool.
+ """
+ try:
+ return klass(data)
+ except UnicodeEncodeError:
+ return str(data)
+ except TypeError:
+ return data
+
+ def __deserialize_object(self, value):
+ """Return an original value.
+
+ :return: object.
+ """
+ return value
+
+ def __deserialize_date(self, string):
+ """Deserializes string to date.
+
+ :param string: str.
+ :return: date.
+ """
+ try:
+ return parse(string).date()
+ except ImportError:
+ return string
+ except ValueError:
+ raise rest.ApiException(
+ status=0,
+ reason="Failed to parse `{0}` as date object".format(string)
+ )
+
+ def __deserialize_datetime(self, string):
+ """Deserializes string to datetime.
+
+ The string should be in iso8601 datetime format.
+
+ :param string: str.
+ :return: datetime.
+ """
+ try:
+ return parse(string)
+ except ImportError:
+ return string
+ except ValueError:
+ raise rest.ApiException(
+ status=0,
+ reason=(
+ "Failed to parse `{0}` as datetime object"
+ .format(string)
+ )
+ )
+
+ def __deserialize_enum(self, data, klass):
+ """Deserializes primitive type to enum.
+
+ :param data: primitive type.
+ :param klass: class literal.
+ :return: enum value.
+ """
+ try:
+ return klass(data)
+ except ValueError:
+ raise rest.ApiException(
+ status=0,
+ reason=(
+ "Failed to parse `{0}` as `{1}`"
+ .format(data, klass)
+ )
+ )
+
+ def __deserialize_model(self, data, klass):
+ """Deserializes list or dict to model.
+
+ :param data: dict, list.
+ :param klass: class literal.
+ :return: model object.
+ """
+
+ return klass.from_dict(data)
diff --git a/rpi/api-resources/board_mate_client/openapi_client/api_response.py b/rpi/api-resources/board_mate_client/openapi_client/api_response.py
new file mode 100644
index 00000000..9bc7c11f
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/openapi_client/api_response.py
@@ -0,0 +1,21 @@
+"""API response object."""
+
+from __future__ import annotations
+from typing import Optional, Generic, Mapping, TypeVar
+from pydantic import Field, StrictInt, StrictBytes, BaseModel
+
+T = TypeVar("T")
+
+class ApiResponse(BaseModel, Generic[T]):
+ """
+ API response object
+ """
+
+ status_code: StrictInt = Field(description="HTTP status code")
+ headers: Optional[Mapping[str, str]] = Field(None, description="HTTP headers")
+ data: T = Field(description="Deserialized data given the data type")
+ raw_data: StrictBytes = Field(description="Raw data (HTTP response body)")
+
+ model_config = {
+ "arbitrary_types_allowed": True
+ }
diff --git a/rpi/api-resources/board_mate_client/openapi_client/configuration.py b/rpi/api-resources/board_mate_client/openapi_client/configuration.py
new file mode 100644
index 00000000..0bb11dc9
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/openapi_client/configuration.py
@@ -0,0 +1,436 @@
+# coding: utf-8
+
+"""
+ boardmate_api API
+
+ boardmate_api API
+
+ The version of the OpenAPI document: 1.0.0
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
+
+ Do not edit the class manually.
+""" # noqa: E501
+
+
+import copy
+import logging
+from logging import FileHandler
+import multiprocessing
+import sys
+from typing import Optional
+import urllib3
+
+import http.client as httplib
+
+JSON_SCHEMA_VALIDATION_KEYWORDS = {
+ 'multipleOf', 'maximum', 'exclusiveMaximum',
+ 'minimum', 'exclusiveMinimum', 'maxLength',
+ 'minLength', 'pattern', 'maxItems', 'minItems'
+}
+
+class Configuration:
+ """This class contains various settings of the API client.
+
+ :param host: Base url.
+ :param api_key: Dict to store API key(s).
+ Each entry in the dict specifies an API key.
+ The dict key is the name of the security scheme in the OAS specification.
+ The dict value is the API key secret.
+ :param api_key_prefix: Dict to store API prefix (e.g. Bearer).
+ The dict key is the name of the security scheme in the OAS specification.
+ The dict value is an API key prefix when generating the auth data.
+ :param username: Username for HTTP basic authentication.
+ :param password: Password for HTTP basic authentication.
+ :param access_token: Access token.
+ :param server_index: Index to servers configuration.
+ :param server_variables: Mapping with string values to replace variables in
+ templated server configuration. The validation of enums is performed for
+ variables with defined enum values before.
+ :param server_operation_index: Mapping from operation ID to an index to server
+ configuration.
+ :param server_operation_variables: Mapping from operation ID to a mapping with
+ string values to replace variables in templated server configuration.
+ The validation of enums is performed for variables with defined enum
+ values before.
+ :param ssl_ca_cert: str - the path to a file of concatenated CA certificates
+ in PEM format.
+
+ """
+
+ _default = None
+
+ def __init__(self, host=None,
+ api_key=None, api_key_prefix=None,
+ username=None, password=None,
+ access_token=None,
+ server_index=None, server_variables=None,
+ server_operation_index=None, server_operation_variables=None,
+ ssl_ca_cert=None,
+ ) -> None:
+ """Constructor
+ """
+ self._base_path = "https://boardmate_api" if host is None else host
+ """Default Base url
+ """
+ self.server_index = 0 if server_index is None and host is None else server_index
+ self.server_operation_index = server_operation_index or {}
+ """Default server index
+ """
+ self.server_variables = server_variables or {}
+ self.server_operation_variables = server_operation_variables or {}
+ """Default server variables
+ """
+ self.temp_folder_path = None
+ """Temp file folder for downloading files
+ """
+ # Authentication Settings
+ self.api_key = {}
+ if api_key:
+ self.api_key = api_key
+ """dict to store API key(s)
+ """
+ self.api_key_prefix = {}
+ if api_key_prefix:
+ self.api_key_prefix = api_key_prefix
+ """dict to store API prefix (e.g. Bearer)
+ """
+ self.refresh_api_key_hook = None
+ """function hook to refresh API key if expired
+ """
+ self.username = username
+ """Username for HTTP basic authentication
+ """
+ self.password = password
+ """Password for HTTP basic authentication
+ """
+ self.access_token = access_token
+ """Access token
+ """
+ self.logger = {}
+ """Logging Settings
+ """
+ self.logger["package_logger"] = logging.getLogger("board_mate_client")
+ self.logger["urllib3_logger"] = logging.getLogger("urllib3")
+ self.logger_format = '%(asctime)s %(levelname)s %(message)s'
+ """Log format
+ """
+ self.logger_stream_handler = None
+ """Log stream handler
+ """
+ self.logger_file_handler: Optional[FileHandler] = None
+ """Log file handler
+ """
+ self.logger_file = None
+ """Debug file location
+ """
+ self.debug = False
+ """Debug switch
+ """
+
+ self.verify_ssl = True
+ """SSL/TLS verification
+ Set this to false to skip verifying SSL certificate when calling API
+ from https server.
+ """
+ self.ssl_ca_cert = ssl_ca_cert
+ """Set this to customize the certificate file to verify the peer.
+ """
+ self.cert_file = None
+ """client certificate file
+ """
+ self.key_file = None
+ """client key file
+ """
+ self.assert_hostname = None
+ """Set this to True/False to enable/disable SSL hostname verification.
+ """
+ self.tls_server_name = None
+ """SSL/TLS Server Name Indication (SNI)
+ Set this to the SNI value expected by the server.
+ """
+
+ self.connection_pool_maxsize = multiprocessing.cpu_count() * 5
+ """urllib3 connection pool's maximum number of connections saved
+ per pool. urllib3 uses 1 connection as default value, but this is
+ not the best value when you are making a lot of possibly parallel
+ requests to the same host, which is often the case here.
+ cpu_count * 5 is used as default value to increase performance.
+ """
+
+ self.proxy: Optional[str] = None
+ """Proxy URL
+ """
+ self.proxy_headers = None
+ """Proxy headers
+ """
+ self.safe_chars_for_path_param = ''
+ """Safe chars for path_param
+ """
+ self.retries = None
+ """Adding retries to override urllib3 default value 3
+ """
+ # Enable client side validation
+ self.client_side_validation = True
+
+ self.socket_options = None
+ """Options to pass down to the underlying urllib3 socket
+ """
+
+ self.datetime_format = "%Y-%m-%dT%H:%M:%S.%f%z"
+ """datetime format
+ """
+
+ self.date_format = "%Y-%m-%d"
+ """date format
+ """
+
+ def __deepcopy__(self, memo):
+ cls = self.__class__
+ result = cls.__new__(cls)
+ memo[id(self)] = result
+ for k, v in self.__dict__.items():
+ if k not in ('logger', 'logger_file_handler'):
+ setattr(result, k, copy.deepcopy(v, memo))
+ # shallow copy of loggers
+ result.logger = copy.copy(self.logger)
+ # use setters to configure loggers
+ result.logger_file = self.logger_file
+ result.debug = self.debug
+ return result
+
+ def __setattr__(self, name, value):
+ object.__setattr__(self, name, value)
+
+ @classmethod
+ def set_default(cls, default):
+ """Set default instance of configuration.
+
+ It stores default configuration, which can be
+ returned by get_default_copy method.
+
+ :param default: object of Configuration
+ """
+ cls._default = default
+
+ @classmethod
+ def get_default_copy(cls):
+ """Deprecated. Please use `get_default` instead.
+
+ Deprecated. Please use `get_default` instead.
+
+ :return: The configuration object.
+ """
+ return cls.get_default()
+
+ @classmethod
+ def get_default(cls):
+ """Return the default configuration.
+
+ This method returns newly created, based on default constructor,
+ object of Configuration class or returns a copy of default
+ configuration.
+
+ :return: The configuration object.
+ """
+ if cls._default is None:
+ cls._default = Configuration()
+ return cls._default
+
+ @property
+ def logger_file(self):
+ """The logger file.
+
+ If the logger_file is None, then add stream handler and remove file
+ handler. Otherwise, add file handler and remove stream handler.
+
+ :param value: The logger_file path.
+ :type: str
+ """
+ return self.__logger_file
+
+ @logger_file.setter
+ def logger_file(self, value):
+ """The logger file.
+
+ If the logger_file is None, then add stream handler and remove file
+ handler. Otherwise, add file handler and remove stream handler.
+
+ :param value: The logger_file path.
+ :type: str
+ """
+ self.__logger_file = value
+ if self.__logger_file:
+ # If set logging file,
+ # then add file handler and remove stream handler.
+ self.logger_file_handler = logging.FileHandler(self.__logger_file)
+ self.logger_file_handler.setFormatter(self.logger_formatter)
+ for _, logger in self.logger.items():
+ logger.addHandler(self.logger_file_handler)
+
+ @property
+ def debug(self):
+ """Debug status
+
+ :param value: The debug status, True or False.
+ :type: bool
+ """
+ return self.__debug
+
+ @debug.setter
+ def debug(self, value):
+ """Debug status
+
+ :param value: The debug status, True or False.
+ :type: bool
+ """
+ self.__debug = value
+ if self.__debug:
+ # if debug status is True, turn on debug logging
+ for _, logger in self.logger.items():
+ logger.setLevel(logging.DEBUG)
+ # turn on httplib debug
+ httplib.HTTPConnection.debuglevel = 1
+ else:
+ # if debug status is False, turn off debug logging,
+ # setting log level to default `logging.WARNING`
+ for _, logger in self.logger.items():
+ logger.setLevel(logging.WARNING)
+ # turn off httplib debug
+ httplib.HTTPConnection.debuglevel = 0
+
+ @property
+ def logger_format(self):
+ """The logger format.
+
+ The logger_formatter will be updated when sets logger_format.
+
+ :param value: The format string.
+ :type: str
+ """
+ return self.__logger_format
+
+ @logger_format.setter
+ def logger_format(self, value):
+ """The logger format.
+
+ The logger_formatter will be updated when sets logger_format.
+
+ :param value: The format string.
+ :type: str
+ """
+ self.__logger_format = value
+ self.logger_formatter = logging.Formatter(self.__logger_format)
+
+ def get_api_key_with_prefix(self, identifier, alias=None):
+ """Gets API key (with prefix if set).
+
+ :param identifier: The identifier of apiKey.
+ :param alias: The alternative identifier of apiKey.
+ :return: The token for api key authentication.
+ """
+ if self.refresh_api_key_hook is not None:
+ self.refresh_api_key_hook(self)
+ key = self.api_key.get(identifier, self.api_key.get(alias) if alias is not None else None)
+ if key:
+ prefix = self.api_key_prefix.get(identifier)
+ if prefix:
+ return "%s %s" % (prefix, key)
+ else:
+ return key
+
+ def get_basic_auth_token(self):
+ """Gets HTTP basic authentication header (string).
+
+ :return: The token for basic HTTP authentication.
+ """
+ username = ""
+ if self.username is not None:
+ username = self.username
+ password = ""
+ if self.password is not None:
+ password = self.password
+ return urllib3.util.make_headers(
+ basic_auth=username + ':' + password
+ ).get('authorization')
+
+ def auth_settings(self):
+ """Gets Auth Settings dict for api client.
+
+ :return: The Auth Settings information dict.
+ """
+ auth = {}
+ return auth
+
+ def to_debug_report(self):
+ """Gets the essential information for debugging.
+
+ :return: The report for debugging.
+ """
+ return "Python SDK Debug Report:\n"\
+ "OS: {env}\n"\
+ "Python Version: {pyversion}\n"\
+ "Version of the API: 1.0.0\n"\
+ "SDK Package Version: 1.0.0".\
+ format(env=sys.platform, pyversion=sys.version)
+
+ def get_host_settings(self):
+ """Gets an array of host settings
+
+ :return: An array of host settings
+ """
+ return [
+ {
+ 'url': "https://boardmate_api",
+ 'description': "No description provided",
+ }
+ ]
+
+ def get_host_from_settings(self, index, variables=None, servers=None):
+ """Gets host URL based on the index and variables
+ :param index: array index of the host settings
+ :param variables: hash of variable and the corresponding value
+ :param servers: an array of host settings or None
+ :return: URL based on host settings
+ """
+ if index is None:
+ return self._base_path
+
+ variables = {} if variables is None else variables
+ servers = self.get_host_settings() if servers is None else servers
+
+ try:
+ server = servers[index]
+ except IndexError:
+ raise ValueError(
+ "Invalid index {0} when selecting the host settings. "
+ "Must be less than {1}".format(index, len(servers)))
+
+ url = server['url']
+
+ # go through variables and replace placeholders
+ for variable_name, variable in server.get('variables', {}).items():
+ used_value = variables.get(
+ variable_name, variable['default_value'])
+
+ if 'enum_values' in variable \
+ and used_value not in variable['enum_values']:
+ raise ValueError(
+ "The variable `{0}` in the host URL has invalid value "
+ "{1}. Must be {2}.".format(
+ variable_name, variables[variable_name],
+ variable['enum_values']))
+
+ url = url.replace("{" + variable_name + "}", used_value)
+
+ return url
+
+ @property
+ def host(self):
+ """Return generated host."""
+ return self.get_host_from_settings(self.server_index, variables=self.server_variables)
+
+ @host.setter
+ def host(self, value):
+ """Fix base path."""
+ self._base_path = value
+ self.server_index = None
diff --git a/rpi/api-resources/board_mate_client/openapi_client/exceptions.py b/rpi/api-resources/board_mate_client/openapi_client/exceptions.py
new file mode 100644
index 00000000..e5faa6c5
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/openapi_client/exceptions.py
@@ -0,0 +1,199 @@
+# coding: utf-8
+
+"""
+ boardmate_api API
+
+ boardmate_api API
+
+ The version of the OpenAPI document: 1.0.0
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
+
+ Do not edit the class manually.
+""" # noqa: E501
+
+from typing import Any, Optional
+from typing_extensions import Self
+
+class OpenApiException(Exception):
+ """The base exception class for all OpenAPIExceptions"""
+
+
+class ApiTypeError(OpenApiException, TypeError):
+ def __init__(self, msg, path_to_item=None, valid_classes=None,
+ key_type=None) -> None:
+ """ Raises an exception for TypeErrors
+
+ Args:
+ msg (str): the exception message
+
+ Keyword Args:
+ path_to_item (list): a list of keys an indices to get to the
+ current_item
+ None if unset
+ valid_classes (tuple): the primitive classes that current item
+ should be an instance of
+ None if unset
+ key_type (bool): False if our value is a value in a dict
+ True if it is a key in a dict
+ False if our item is an item in a list
+ None if unset
+ """
+ self.path_to_item = path_to_item
+ self.valid_classes = valid_classes
+ self.key_type = key_type
+ full_msg = msg
+ if path_to_item:
+ full_msg = "{0} at {1}".format(msg, render_path(path_to_item))
+ super(ApiTypeError, self).__init__(full_msg)
+
+
+class ApiValueError(OpenApiException, ValueError):
+ def __init__(self, msg, path_to_item=None) -> None:
+ """
+ Args:
+ msg (str): the exception message
+
+ Keyword Args:
+ path_to_item (list) the path to the exception in the
+ received_data dict. None if unset
+ """
+
+ self.path_to_item = path_to_item
+ full_msg = msg
+ if path_to_item:
+ full_msg = "{0} at {1}".format(msg, render_path(path_to_item))
+ super(ApiValueError, self).__init__(full_msg)
+
+
+class ApiAttributeError(OpenApiException, AttributeError):
+ def __init__(self, msg, path_to_item=None) -> None:
+ """
+ Raised when an attribute reference or assignment fails.
+
+ Args:
+ msg (str): the exception message
+
+ Keyword Args:
+ path_to_item (None/list) the path to the exception in the
+ received_data dict
+ """
+ self.path_to_item = path_to_item
+ full_msg = msg
+ if path_to_item:
+ full_msg = "{0} at {1}".format(msg, render_path(path_to_item))
+ super(ApiAttributeError, self).__init__(full_msg)
+
+
+class ApiKeyError(OpenApiException, KeyError):
+ def __init__(self, msg, path_to_item=None) -> None:
+ """
+ Args:
+ msg (str): the exception message
+
+ Keyword Args:
+ path_to_item (None/list) the path to the exception in the
+ received_data dict
+ """
+ self.path_to_item = path_to_item
+ full_msg = msg
+ if path_to_item:
+ full_msg = "{0} at {1}".format(msg, render_path(path_to_item))
+ super(ApiKeyError, self).__init__(full_msg)
+
+
+class ApiException(OpenApiException):
+
+ def __init__(
+ self,
+ status=None,
+ reason=None,
+ http_resp=None,
+ *,
+ body: Optional[str] = None,
+ data: Optional[Any] = None,
+ ) -> None:
+ self.status = status
+ self.reason = reason
+ self.body = body
+ self.data = data
+ self.headers = None
+
+ if http_resp:
+ if self.status is None:
+ self.status = http_resp.status
+ if self.reason is None:
+ self.reason = http_resp.reason
+ if self.body is None:
+ try:
+ self.body = http_resp.data.decode('utf-8')
+ except Exception:
+ pass
+ self.headers = http_resp.getheaders()
+
+ @classmethod
+ def from_response(
+ cls,
+ *,
+ http_resp,
+ body: Optional[str],
+ data: Optional[Any],
+ ) -> Self:
+ if http_resp.status == 400:
+ raise BadRequestException(http_resp=http_resp, body=body, data=data)
+
+ if http_resp.status == 401:
+ raise UnauthorizedException(http_resp=http_resp, body=body, data=data)
+
+ if http_resp.status == 403:
+ raise ForbiddenException(http_resp=http_resp, body=body, data=data)
+
+ if http_resp.status == 404:
+ raise NotFoundException(http_resp=http_resp, body=body, data=data)
+
+ if 500 <= http_resp.status <= 599:
+ raise ServiceException(http_resp=http_resp, body=body, data=data)
+ raise ApiException(http_resp=http_resp, body=body, data=data)
+
+ def __str__(self):
+ """Custom error messages for exception"""
+ error_message = "({0})\n"\
+ "Reason: {1}\n".format(self.status, self.reason)
+ if self.headers:
+ error_message += "HTTP response headers: {0}\n".format(
+ self.headers)
+
+ if self.data or self.body:
+ error_message += "HTTP response body: {0}\n".format(self.data or self.body)
+
+ return error_message
+
+
+class BadRequestException(ApiException):
+ pass
+
+
+class NotFoundException(ApiException):
+ pass
+
+
+class UnauthorizedException(ApiException):
+ pass
+
+
+class ForbiddenException(ApiException):
+ pass
+
+
+class ServiceException(ApiException):
+ pass
+
+
+def render_path(path_to_item):
+ """Returns a string representation of a path"""
+ result = ""
+ for pth in path_to_item:
+ if isinstance(pth, int):
+ result += "[{0}]".format(pth)
+ else:
+ result += "['{0}']".format(pth)
+ return result
diff --git a/rpi/api-resources/board_mate_client/openapi_client/models/__init__.py b/rpi/api-resources/board_mate_client/openapi_client/models/__init__.py
new file mode 100644
index 00000000..84ce4f7f
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/openapi_client/models/__init__.py
@@ -0,0 +1,20 @@
+# coding: utf-8
+
+# flake8: noqa
+"""
+ boardmate_api API
+
+ boardmate_api API
+
+ The version of the OpenAPI document: 1.0.0
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
+
+ Do not edit the class manually.
+""" # noqa: E501
+
+
+# import models into model package
+from board_mate_client.models.game_dto import GameDto
+from board_mate_client.models.move_dto import MoveDto
+from board_mate_client.models.response_body_game_dto import ResponseBodyGameDto
+from board_mate_client.models.response_body_string import ResponseBodyString
diff --git a/rpi/api-resources/board_mate_client/openapi_client/models/game_dto.py b/rpi/api-resources/board_mate_client/openapi_client/models/game_dto.py
new file mode 100644
index 00000000..04d1de84
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/openapi_client/models/game_dto.py
@@ -0,0 +1,93 @@
+# coding: utf-8
+
+"""
+ boardmate_api API
+
+ boardmate_api API
+
+ The version of the OpenAPI document: 1.0.0
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
+
+ Do not edit the class manually.
+""" # noqa: E501
+
+
+from __future__ import annotations
+import pprint
+import re # noqa: F401
+import json
+
+from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr
+from typing import Any, ClassVar, Dict, List, Optional
+from typing import Optional, Set
+from typing_extensions import Self
+
+class GameDto(BaseModel):
+ """
+ GameDto
+ """ # noqa: E501
+ white_name: Optional[StrictStr] = Field(default=None, alias="whiteName")
+ black_name: Optional[StrictStr] = Field(default=None, alias="blackName")
+ time_value: Optional[StrictInt] = Field(default=None, alias="timeValue")
+ increment: Optional[StrictInt] = None
+ __properties: ClassVar[List[str]] = ["whiteName", "blackName", "timeValue", "increment"]
+
+ model_config = ConfigDict(
+ populate_by_name=True,
+ validate_assignment=True,
+ protected_namespaces=(),
+ )
+
+
+ def to_str(self) -> str:
+ """Returns the string representation of the model using alias"""
+ return pprint.pformat(self.model_dump(by_alias=True))
+
+ def to_json(self) -> str:
+ """Returns the JSON representation of the model using alias"""
+ # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
+ return json.dumps(self.to_dict())
+
+ @classmethod
+ def from_json(cls, json_str: str) -> Optional[Self]:
+ """Create an instance of GameDto from a JSON string"""
+ return cls.from_dict(json.loads(json_str))
+
+ def to_dict(self) -> Dict[str, Any]:
+ """Return the dictionary representation of the model using alias.
+
+ This has the following differences from calling pydantic's
+ `self.model_dump(by_alias=True)`:
+
+ * `None` is only added to the output dict for nullable fields that
+ were set at model initialization. Other fields with value `None`
+ are ignored.
+ """
+ excluded_fields: Set[str] = set([
+ ])
+
+ _dict = self.model_dump(
+ by_alias=True,
+ exclude=excluded_fields,
+ exclude_none=True,
+ )
+ return _dict
+
+ @classmethod
+ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
+ """Create an instance of GameDto from a dict"""
+ if obj is None:
+ return None
+
+ if not isinstance(obj, dict):
+ return cls.model_validate(obj)
+
+ _obj = cls.model_validate({
+ "whiteName": obj.get("whiteName"),
+ "blackName": obj.get("blackName"),
+ "timeValue": obj.get("timeValue"),
+ "increment": obj.get("increment")
+ })
+ return _obj
+
+
diff --git a/rpi/api-resources/board_mate_client/openapi_client/models/move_dto.py b/rpi/api-resources/board_mate_client/openapi_client/models/move_dto.py
new file mode 100644
index 00000000..78af33ea
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/openapi_client/models/move_dto.py
@@ -0,0 +1,86 @@
+# coding: utf-8
+
+"""
+ boardmate_api API
+
+ boardmate_api API
+
+ The version of the OpenAPI document: 1.0.0
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
+
+ Do not edit the class manually.
+""" # noqa: E501
+
+
+from __future__ import annotations
+import pprint
+import re # noqa: F401
+import json
+
+from pydantic import BaseModel, ConfigDict, StrictStr
+from typing import Any, ClassVar, Dict, List, Optional
+from typing import Optional, Set
+from typing_extensions import Self
+
+class MoveDto(BaseModel):
+ """
+ MoveDto
+ """ # noqa: E501
+ notation: Optional[StrictStr] = None
+ __properties: ClassVar[List[str]] = ["notation"]
+
+ model_config = ConfigDict(
+ populate_by_name=True,
+ validate_assignment=True,
+ protected_namespaces=(),
+ )
+
+ def to_str(self) -> str:
+ """Returns the string representation of the model using alias"""
+ return pprint.pformat(self.model_dump(by_alias=True))
+
+ def to_json(self) -> str:
+ """Returns the JSON representation of the model using alias"""
+ # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
+ return json.dumps(self.to_dict())
+
+ @classmethod
+ def from_json(cls, json_str: str) -> Optional[Self]:
+ """Create an instance of MoveDto from a JSON string"""
+ return cls.from_dict(json.loads(json_str))
+
+ def to_dict(self) -> Dict[str, Any]:
+ """Return the dictionary representation of the model using alias.
+
+ This has the following differences from calling pydantic's
+ `self.model_dump(by_alias=True)`:
+
+ * `None` is only added to the output dict for nullable fields that
+ were set at model initialization. Other fields with value `None`
+ are ignored.
+ """
+ excluded_fields: Set[str] = set([
+ ])
+
+ _dict = self.model_dump(
+ by_alias=True,
+ exclude=excluded_fields,
+ exclude_none=True,
+ )
+ return _dict
+
+ @classmethod
+ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
+ """Create an instance of MoveDto from a dict"""
+ if obj is None:
+ return None
+
+ if not isinstance(obj, dict):
+ return cls.model_validate(obj)
+
+ _obj = cls.model_validate({
+ "notation": obj.get("notation")
+ })
+ return _obj
+
+
diff --git a/rpi/api-resources/board_mate_client/openapi_client/models/response_body_game_dto.py b/rpi/api-resources/board_mate_client/openapi_client/models/response_body_game_dto.py
new file mode 100644
index 00000000..963cb622
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/openapi_client/models/response_body_game_dto.py
@@ -0,0 +1,91 @@
+# coding: utf-8
+
+"""
+ boardmate_api API
+
+ boardmate_api API
+
+ The version of the OpenAPI document: 1.0.0
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
+
+ Do not edit the class manually.
+""" # noqa: E501
+
+
+from __future__ import annotations
+import pprint
+import re # noqa: F401
+import json
+
+from pydantic import BaseModel, ConfigDict, StrictBool, StrictStr
+from typing import Any, ClassVar, Dict, List, Optional
+from typing import Optional, Set
+from typing_extensions import Self
+
+class ResponseBodyGameDto(BaseModel):
+ """
+ ResponseBodyGameDto
+ """ # noqa: E501
+ data: Optional[Dict[str, Any]] = None
+ message: Optional[StrictStr] = None
+ success: Optional[StrictBool] = None
+ __properties: ClassVar[List[str]] = ["data", "message", "success"]
+
+ model_config = ConfigDict(
+ populate_by_name=True,
+ validate_assignment=True,
+ protected_namespaces=(),
+ )
+
+
+ def to_str(self) -> str:
+ """Returns the string representation of the model using alias"""
+ return pprint.pformat(self.model_dump(by_alias=True))
+
+ def to_json(self) -> str:
+ """Returns the JSON representation of the model using alias"""
+ # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
+ return json.dumps(self.to_dict())
+
+ @classmethod
+ def from_json(cls, json_str: str) -> Optional[Self]:
+ """Create an instance of ResponseBodyGameDto from a JSON string"""
+ return cls.from_dict(json.loads(json_str))
+
+ def to_dict(self) -> Dict[str, Any]:
+ """Return the dictionary representation of the model using alias.
+
+ This has the following differences from calling pydantic's
+ `self.model_dump(by_alias=True)`:
+
+ * `None` is only added to the output dict for nullable fields that
+ were set at model initialization. Other fields with value `None`
+ are ignored.
+ """
+ excluded_fields: Set[str] = set([
+ ])
+
+ _dict = self.model_dump(
+ by_alias=True,
+ exclude=excluded_fields,
+ exclude_none=True,
+ )
+ return _dict
+
+ @classmethod
+ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
+ """Create an instance of ResponseBodyGameDto from a dict"""
+ if obj is None:
+ return None
+
+ if not isinstance(obj, dict):
+ return cls.model_validate(obj)
+
+ _obj = cls.model_validate({
+ "data": obj.get("data"),
+ "message": obj.get("message"),
+ "success": obj.get("success")
+ })
+ return _obj
+
+
diff --git a/rpi/api-resources/board_mate_client/openapi_client/models/response_body_string.py b/rpi/api-resources/board_mate_client/openapi_client/models/response_body_string.py
new file mode 100644
index 00000000..1d467e16
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/openapi_client/models/response_body_string.py
@@ -0,0 +1,91 @@
+# coding: utf-8
+
+"""
+ boardmate_api API
+
+ boardmate_api API
+
+ The version of the OpenAPI document: 1.0.0
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
+
+ Do not edit the class manually.
+""" # noqa: E501
+
+
+from __future__ import annotations
+import pprint
+import re # noqa: F401
+import json
+
+from pydantic import BaseModel, ConfigDict, StrictBool, StrictStr
+from typing import Any, ClassVar, Dict, List, Optional
+from typing import Optional, Set
+from typing_extensions import Self
+
+class ResponseBodyString(BaseModel):
+ """
+ ResponseBodyString
+ """ # noqa: E501
+ data: Optional[StrictStr] = None
+ message: Optional[StrictStr] = None
+ success: Optional[StrictBool] = None
+ __properties: ClassVar[List[str]] = ["data", "message", "success"]
+
+ model_config = ConfigDict(
+ populate_by_name=True,
+ validate_assignment=True,
+ protected_namespaces=(),
+ )
+
+
+ def to_str(self) -> str:
+ """Returns the string representation of the model using alias"""
+ return pprint.pformat(self.model_dump(by_alias=True))
+
+ def to_json(self) -> str:
+ """Returns the JSON representation of the model using alias"""
+ # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
+ return json.dumps(self.to_dict())
+
+ @classmethod
+ def from_json(cls, json_str: str) -> Optional[Self]:
+ """Create an instance of ResponseBodyString from a JSON string"""
+ return cls.from_dict(json.loads(json_str))
+
+ def to_dict(self) -> Dict[str, Any]:
+ """Return the dictionary representation of the model using alias.
+
+ This has the following differences from calling pydantic's
+ `self.model_dump(by_alias=True)`:
+
+ * `None` is only added to the output dict for nullable fields that
+ were set at model initialization. Other fields with value `None`
+ are ignored.
+ """
+ excluded_fields: Set[str] = set([
+ ])
+
+ _dict = self.model_dump(
+ by_alias=True,
+ exclude=excluded_fields,
+ exclude_none=True,
+ )
+ return _dict
+
+ @classmethod
+ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
+ """Create an instance of ResponseBodyString from a dict"""
+ if obj is None:
+ return None
+
+ if not isinstance(obj, dict):
+ return cls.model_validate(obj)
+
+ _obj = cls.model_validate({
+ "data": obj.get("data"),
+ "message": obj.get("message"),
+ "success": obj.get("success")
+ })
+ return _obj
+
+
diff --git a/rpi/api-resources/board_mate_client/openapi_client/py.typed b/rpi/api-resources/board_mate_client/openapi_client/py.typed
new file mode 100644
index 00000000..e69de29b
diff --git a/rpi/api-resources/board_mate_client/openapi_client/rest.py b/rpi/api-resources/board_mate_client/openapi_client/rest.py
new file mode 100644
index 00000000..cab3b012
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/openapi_client/rest.py
@@ -0,0 +1,257 @@
+# coding: utf-8
+
+"""
+ boardmate_api API
+
+ boardmate_api API
+
+ The version of the OpenAPI document: 1.0.0
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
+
+ Do not edit the class manually.
+""" # noqa: E501
+
+
+import io
+import json
+import re
+import ssl
+
+import urllib3
+
+from board_mate_client.exceptions import ApiException, ApiValueError
+
+SUPPORTED_SOCKS_PROXIES = {"socks5", "socks5h", "socks4", "socks4a"}
+RESTResponseType = urllib3.HTTPResponse
+
+
+def is_socks_proxy_url(url):
+ if url is None:
+ return False
+ split_section = url.split("://")
+ if len(split_section) < 2:
+ return False
+ else:
+ return split_section[0].lower() in SUPPORTED_SOCKS_PROXIES
+
+
+class RESTResponse(io.IOBase):
+
+ def __init__(self, resp) -> None:
+ self.response = resp
+ self.status = resp.status
+ self.reason = resp.reason
+ self.data = None
+
+ def read(self):
+ if self.data is None:
+ self.data = self.response.data
+ return self.data
+
+ def getheaders(self):
+ """Returns a dictionary of the response headers."""
+ return self.response.headers
+
+ def getheader(self, name, default=None):
+ """Returns a given response header."""
+ return self.response.headers.get(name, default)
+
+
+class RESTClientObject:
+
+ def __init__(self, configuration) -> None:
+ # urllib3.PoolManager will pass all kw parameters to connectionpool
+ # https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/poolmanager.py#L75 # noqa: E501
+ # https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/connectionpool.py#L680 # noqa: E501
+ # Custom SSL certificates and client certificates: http://urllib3.readthedocs.io/en/latest/advanced-usage.html # noqa: E501
+
+ # cert_reqs
+ if configuration.verify_ssl:
+ cert_reqs = ssl.CERT_REQUIRED
+ else:
+ cert_reqs = ssl.CERT_NONE
+
+ pool_args = {
+ "cert_reqs": cert_reqs,
+ "ca_certs": configuration.ssl_ca_cert,
+ "cert_file": configuration.cert_file,
+ "key_file": configuration.key_file,
+ }
+ if configuration.assert_hostname is not None:
+ pool_args['assert_hostname'] = (
+ configuration.assert_hostname
+ )
+
+ if configuration.retries is not None:
+ pool_args['retries'] = configuration.retries
+
+ if configuration.tls_server_name:
+ pool_args['server_hostname'] = configuration.tls_server_name
+
+
+ if configuration.socket_options is not None:
+ pool_args['socket_options'] = configuration.socket_options
+
+ if configuration.connection_pool_maxsize is not None:
+ pool_args['maxsize'] = configuration.connection_pool_maxsize
+
+ # https pool manager
+ self.pool_manager: urllib3.PoolManager
+
+ if configuration.proxy:
+ if is_socks_proxy_url(configuration.proxy):
+ from urllib3.contrib.socks import SOCKSProxyManager
+ pool_args["proxy_url"] = configuration.proxy
+ pool_args["headers"] = configuration.proxy_headers
+ self.pool_manager = SOCKSProxyManager(**pool_args)
+ else:
+ pool_args["proxy_url"] = configuration.proxy
+ pool_args["proxy_headers"] = configuration.proxy_headers
+ self.pool_manager = urllib3.ProxyManager(**pool_args)
+ else:
+ self.pool_manager = urllib3.PoolManager(**pool_args)
+
+ def request(
+ self,
+ method,
+ url,
+ headers=None,
+ body=None,
+ post_params=None,
+ _request_timeout=None
+ ):
+ """Perform requests.
+
+ :param method: http request method
+ :param url: http request url
+ :param headers: http request headers
+ :param body: request json body, for `application/json`
+ :param post_params: request post parameters,
+ `application/x-www-form-urlencoded`
+ and `multipart/form-data`
+ :param _request_timeout: timeout setting for this request. If one
+ number provided, it will be total request
+ timeout. It can also be a pair (tuple) of
+ (connection, read) timeouts.
+ """
+ method = method.upper()
+ assert method in [
+ 'GET',
+ 'HEAD',
+ 'DELETE',
+ 'POST',
+ 'PUT',
+ 'PATCH',
+ 'OPTIONS'
+ ]
+
+ if post_params and body:
+ raise ApiValueError(
+ "body parameter cannot be used with post_params parameter."
+ )
+
+ post_params = post_params or {}
+ headers = headers or {}
+
+ timeout = None
+ if _request_timeout:
+ if isinstance(_request_timeout, (int, float)):
+ timeout = urllib3.Timeout(total=_request_timeout)
+ elif (
+ isinstance(_request_timeout, tuple)
+ and len(_request_timeout) == 2
+ ):
+ timeout = urllib3.Timeout(
+ connect=_request_timeout[0],
+ read=_request_timeout[1]
+ )
+
+ try:
+ # For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE`
+ if method in ['POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE']:
+
+ # no content type provided or payload is json
+ content_type = headers.get('Content-Type')
+ if (
+ not content_type
+ or re.search('json', content_type, re.IGNORECASE)
+ ):
+ request_body = None
+ if body is not None:
+ request_body = json.dumps(body)
+ r = self.pool_manager.request(
+ method,
+ url,
+ body=request_body,
+ timeout=timeout,
+ headers=headers,
+ preload_content=False
+ )
+ elif content_type == 'application/x-www-form-urlencoded':
+ r = self.pool_manager.request(
+ method,
+ url,
+ fields=post_params,
+ encode_multipart=False,
+ timeout=timeout,
+ headers=headers,
+ preload_content=False
+ )
+ elif content_type == 'multipart/form-data':
+ # must del headers['Content-Type'], or the correct
+ # Content-Type which generated by urllib3 will be
+ # overwritten.
+ del headers['Content-Type']
+ # Ensures that dict objects are serialized
+ post_params = [(a, json.dumps(b)) if isinstance(b, dict) else (a,b) for a, b in post_params]
+ r = self.pool_manager.request(
+ method,
+ url,
+ fields=post_params,
+ encode_multipart=True,
+ timeout=timeout,
+ headers=headers,
+ preload_content=False
+ )
+ # Pass a `string` parameter directly in the body to support
+ # other content types than JSON when `body` argument is
+ # provided in serialized form.
+ elif isinstance(body, str) or isinstance(body, bytes):
+ r = self.pool_manager.request(
+ method,
+ url,
+ body=body,
+ timeout=timeout,
+ headers=headers,
+ preload_content=False
+ )
+ elif headers['Content-Type'] == 'text/plain' and isinstance(body, bool):
+ request_body = "true" if body else "false"
+ r = self.pool_manager.request(
+ method,
+ url,
+ body=request_body,
+ preload_content=False,
+ timeout=timeout,
+ headers=headers)
+ else:
+ # Cannot generate the request from given parameters
+ msg = """Cannot prepare a request message for provided
+ arguments. Please check that your arguments match
+ declared content type."""
+ raise ApiException(status=0, reason=msg)
+ # For `GET`, `HEAD`
+ else:
+ r = self.pool_manager.request(
+ method,
+ url,
+ fields={},
+ timeout=timeout,
+ headers=headers,
+ preload_content=False
+ )
+ except urllib3.exceptions.SSLError as e:
+ msg = "\n".join([type(e).__name__, str(e)])
+ raise ApiException(status=0, reason=msg)
+
+ return RESTResponse(r)
diff --git a/rpi/api-resources/board_mate_client/pyproject.toml b/rpi/api-resources/board_mate_client/pyproject.toml
new file mode 100644
index 00000000..a4966d89
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/pyproject.toml
@@ -0,0 +1,71 @@
+[tool.poetry]
+name = "openapi_client"
+version = "1.0.0"
+description = "boardmate_api API"
+authors = ["OpenAPI Generator Community "]
+license = "NoLicense"
+readme = "README.md"
+repository = "https://github.com/GIT_USER_ID/GIT_REPO_ID"
+keywords = ["OpenAPI", "OpenAPI-Generator", "boardmate_api API"]
+include = ["openapi_client/py.typed"]
+
+[tool.poetry.dependencies]
+python = "^3.7"
+
+urllib3 = ">= 1.25.3"
+python-dateutil = ">=2.8.2"
+pydantic = ">=2"
+typing-extensions = ">=4.7.1"
+
+[tool.poetry.dev-dependencies]
+pytest = ">=7.2.1"
+tox = ">=3.9.0"
+flake8 = ">=4.0.0"
+types-python-dateutil = ">=2.8.19.14"
+mypy = "1.4.1"
+
+
+[build-system]
+requires = ["setuptools"]
+build-backend = "setuptools.build_meta"
+
+[tool.pylint.'MESSAGES CONTROL']
+extension-pkg-whitelist = "pydantic"
+
+[tool.mypy]
+files = [
+ "openapi_client",
+ #"chesscog-bck", # auto-generated tests
+ "tests", # hand-written tests
+]
+# TODO: enable "strict" once all these individual checks are passing
+# strict = true
+
+# List from: https://mypy.readthedocs.io/en/stable/existing_code.html#introduce-stricter-options
+warn_unused_configs = true
+warn_redundant_casts = true
+warn_unused_ignores = true
+
+## Getting these passing should be easy
+strict_equality = true
+strict_concatenate = true
+
+## Strongly recommend enabling this one as soon as you can
+check_untyped_defs = true
+
+## These shouldn't be too much additional work, but may be tricky to
+## get passing if you use a lot of untyped libraries
+disallow_subclassing_any = true
+disallow_untyped_decorators = true
+disallow_any_generics = true
+
+### These next few are various gradations of forcing use of type annotations
+#disallow_untyped_calls = true
+#disallow_incomplete_defs = true
+#disallow_untyped_defs = true
+#
+### This one isn't too hard to get passing, but return on investment is lower
+#no_implicit_reexport = true
+#
+### This one can be tricky to get passing if you use a lot of untyped libraries
+#warn_return_any = true
diff --git a/rpi/api-resources/board_mate_client/requirements.txt b/rpi/api-resources/board_mate_client/requirements.txt
new file mode 100644
index 00000000..cc85509e
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/requirements.txt
@@ -0,0 +1,5 @@
+python_dateutil >= 2.5.3
+setuptools >= 21.0.0
+urllib3 >= 1.25.3, < 2.1.0
+pydantic >= 2
+typing-extensions >= 4.7.1
diff --git a/rpi/api-resources/board_mate_client/setup.cfg b/rpi/api-resources/board_mate_client/setup.cfg
new file mode 100644
index 00000000..11433ee8
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/setup.cfg
@@ -0,0 +1,2 @@
+[flake8]
+max-line-length=99
diff --git a/rpi/api-resources/board_mate_client/setup.py b/rpi/api-resources/board_mate_client/setup.py
new file mode 100644
index 00000000..9f7b6a08
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/setup.py
@@ -0,0 +1,49 @@
+# coding: utf-8
+
+"""
+ boardmate_api API
+
+ boardmate_api API
+
+ The version of the OpenAPI document: 1.0.0
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
+
+ Do not edit the class manually.
+""" # noqa: E501
+
+
+from setuptools import setup, find_packages # noqa: H301
+
+# To install the library, run the following
+#
+# python setup.py install
+#
+# prerequisite: setuptools
+# http://pypi.python.org/pypi/setuptools
+NAME = "openapi-client"
+VERSION = "1.0.0"
+PYTHON_REQUIRES = ">=3.7"
+REQUIRES = [
+ "urllib3 >= 1.25.3, < 2.1.0",
+ "python-dateutil",
+ "pydantic >= 2",
+ "typing-extensions >= 4.7.1",
+]
+
+setup(
+ name=NAME,
+ version=VERSION,
+ description="boardmate_api API",
+ author="OpenAPI Generator community",
+ author_email="team@openapitools.org",
+ url="",
+ keywords=["OpenAPI", "OpenAPI-Generator", "boardmate_api API"],
+ install_requires=REQUIRES,
+ packages=find_packages(exclude=["chesscog-bck", "tests"]),
+ include_package_data=True,
+ long_description_content_type='text/markdown',
+ long_description="""\
+ boardmate_api API
+ """, # noqa: E501
+ package_data={"board_mate_client": ["py.typed"]},
+)
diff --git a/rpi/api-resources/board_mate_client/test-requirements.txt b/rpi/api-resources/board_mate_client/test-requirements.txt
new file mode 100644
index 00000000..8e6d8cb1
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/test-requirements.txt
@@ -0,0 +1,5 @@
+pytest~=7.1.3
+pytest-cov>=2.8.1
+pytest-randomly>=3.12.0
+mypy>=1.4.1
+types-python-dateutil>=2.8.19
diff --git a/rpi/api-resources/board_mate_client/test/__init__.py b/rpi/api-resources/board_mate_client/test/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/rpi/api-resources/board_mate_client/test/test_default_api.py b/rpi/api-resources/board_mate_client/test/test_default_api.py
new file mode 100644
index 00000000..dfa78530
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/test/test_default_api.py
@@ -0,0 +1,52 @@
+# coding: utf-8
+
+"""
+ boardmate_api API
+
+ boardmate_api API
+
+ The version of the OpenAPI document: 1.0.0
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
+
+ Do not edit the class manually.
+""" # noqa: E501
+
+
+import unittest
+
+from board_mate_client.api.default_api import DefaultApi
+
+
+class TestDefaultApi(unittest.TestCase):
+ """DefaultApi unit chesscog-bck stubs"""
+
+ def setUp(self) -> None:
+ self.api = DefaultApi()
+
+ def tearDown(self) -> None:
+ pass
+
+ def test_add_move(self) -> None:
+ """Test case for add_move
+
+ POST moves/add/{gameId}
+ """
+ pass
+
+ def test_create_party(self) -> None:
+ """Test case for create_party
+
+ POST create
+ """
+ pass
+
+ def test_retrieve_games(self) -> None:
+ """Test case for retrieve_games
+
+ GET games/{id}
+ """
+ pass
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/rpi/api-resources/board_mate_client/test/test_game_dto.py b/rpi/api-resources/board_mate_client/test/test_game_dto.py
new file mode 100644
index 00000000..27a2a06a
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/test/test_game_dto.py
@@ -0,0 +1,54 @@
+# coding: utf-8
+
+"""
+ boardmate_api API
+
+ boardmate_api API
+
+ The version of the OpenAPI document: 1.0.0
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
+
+ Do not edit the class manually.
+""" # noqa: E501
+
+
+import unittest
+
+from board_mate_client.models.game_dto import GameDto
+
+class TestGameDto(unittest.TestCase):
+ """GameDto unit chesscog-bck stubs"""
+
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def make_instance(self, include_optional) -> GameDto:
+ """Test GameDto
+ include_option is a boolean, when False only required
+ params are included, when True both required and
+ optional params are included """
+ # uncomment below to create an instance of `GameDto`
+ """
+ model = GameDto()
+ if include_optional:
+ return GameDto(
+ white_name = '',
+ black_name = '',
+ time_value = 56,
+ increment = 56
+ )
+ else:
+ return GameDto(
+ )
+ """
+
+ def testGameDto(self):
+ """Test GameDto"""
+ # inst_req_only = self.make_instance(include_optional=False)
+ # inst_req_and_optional = self.make_instance(include_optional=True)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/rpi/api-resources/board_mate_client/test/test_move_dto.py b/rpi/api-resources/board_mate_client/test/test_move_dto.py
new file mode 100644
index 00000000..b687c3a8
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/test/test_move_dto.py
@@ -0,0 +1,51 @@
+# coding: utf-8
+
+"""
+ boardmate_api API
+
+ boardmate_api API
+
+ The version of the OpenAPI document: 1.0.0
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
+
+ Do not edit the class manually.
+""" # noqa: E501
+
+
+import unittest
+
+from board_mate_client.models.move_dto import MoveDto
+
+class TestMoveDto(unittest.TestCase):
+ """MoveDto unit chesscog-bck stubs"""
+
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def make_instance(self, include_optional) -> MoveDto:
+ """Test MoveDto
+ include_option is a boolean, when False only required
+ params are included, when True both required and
+ optional params are included """
+ # uncomment below to create an instance of `MoveDto`
+ """
+ model = MoveDto()
+ if include_optional:
+ return MoveDto(
+ notation = ''
+ )
+ else:
+ return MoveDto(
+ )
+ """
+
+ def testMoveDto(self):
+ """Test MoveDto"""
+ # inst_req_only = self.make_instance(include_optional=False)
+ # inst_req_and_optional = self.make_instance(include_optional=True)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/rpi/api-resources/board_mate_client/test/test_response_body_game_dto.py b/rpi/api-resources/board_mate_client/test/test_response_body_game_dto.py
new file mode 100644
index 00000000..e6c699b4
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/test/test_response_body_game_dto.py
@@ -0,0 +1,53 @@
+# coding: utf-8
+
+"""
+ boardmate_api API
+
+ boardmate_api API
+
+ The version of the OpenAPI document: 1.0.0
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
+
+ Do not edit the class manually.
+""" # noqa: E501
+
+
+import unittest
+
+from board_mate_client.models.response_body_game_dto import ResponseBodyGameDto
+
+class TestResponseBodyGameDto(unittest.TestCase):
+ """ResponseBodyGameDto unit chesscog-bck stubs"""
+
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def make_instance(self, include_optional) -> ResponseBodyGameDto:
+ """Test ResponseBodyGameDto
+ include_option is a boolean, when False only required
+ params are included, when True both required and
+ optional params are included """
+ # uncomment below to create an instance of `ResponseBodyGameDto`
+ """
+ model = ResponseBodyGameDto()
+ if include_optional:
+ return ResponseBodyGameDto(
+ data = None,
+ message = '',
+ success = True
+ )
+ else:
+ return ResponseBodyGameDto(
+ )
+ """
+
+ def testResponseBodyGameDto(self):
+ """Test ResponseBodyGameDto"""
+ # inst_req_only = self.make_instance(include_optional=False)
+ # inst_req_and_optional = self.make_instance(include_optional=True)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/rpi/api-resources/board_mate_client/test/test_response_body_string.py b/rpi/api-resources/board_mate_client/test/test_response_body_string.py
new file mode 100644
index 00000000..9bfcb54c
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/test/test_response_body_string.py
@@ -0,0 +1,53 @@
+# coding: utf-8
+
+"""
+ boardmate_api API
+
+ boardmate_api API
+
+ The version of the OpenAPI document: 1.0.0
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
+
+ Do not edit the class manually.
+""" # noqa: E501
+
+
+import unittest
+
+from board_mate_client.models.response_body_string import ResponseBodyString
+
+class TestResponseBodyString(unittest.TestCase):
+ """ResponseBodyString unit chesscog-bck stubs"""
+
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def make_instance(self, include_optional) -> ResponseBodyString:
+ """Test ResponseBodyString
+ include_option is a boolean, when False only required
+ params are included, when True both required and
+ optional params are included """
+ # uncomment below to create an instance of `ResponseBodyString`
+ """
+ model = ResponseBodyString()
+ if include_optional:
+ return ResponseBodyString(
+ data = '',
+ message = '',
+ success = True
+ )
+ else:
+ return ResponseBodyString(
+ )
+ """
+
+ def testResponseBodyString(self):
+ """Test ResponseBodyString"""
+ # inst_req_only = self.make_instance(include_optional=False)
+ # inst_req_and_optional = self.make_instance(include_optional=True)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/rpi/api-resources/board_mate_client/tox.ini b/rpi/api-resources/board_mate_client/tox.ini
new file mode 100644
index 00000000..1a9028b7
--- /dev/null
+++ b/rpi/api-resources/board_mate_client/tox.ini
@@ -0,0 +1,9 @@
+[tox]
+envlist = py3
+
+[testenv]
+deps=-r{toxinidir}/requirements.txt
+ -r{toxinidir}/test-requirements.txt
+
+commands=
+ pytest --cov=openapi_client
diff --git a/rpi/board_mate_client/__pycache__/__init__.cpython-314.pyc b/rpi/board_mate_client/__pycache__/__init__.cpython-314.pyc
new file mode 100644
index 00000000..3c7acd94
Binary files /dev/null and b/rpi/board_mate_client/__pycache__/__init__.cpython-314.pyc differ
diff --git a/rpi/board_mate_client/__pycache__/api_client.cpython-314.pyc b/rpi/board_mate_client/__pycache__/api_client.cpython-314.pyc
new file mode 100644
index 00000000..8ca13492
Binary files /dev/null and b/rpi/board_mate_client/__pycache__/api_client.cpython-314.pyc differ
diff --git a/rpi/board_mate_client/__pycache__/api_response.cpython-314.pyc b/rpi/board_mate_client/__pycache__/api_response.cpython-314.pyc
new file mode 100644
index 00000000..06451975
Binary files /dev/null and b/rpi/board_mate_client/__pycache__/api_response.cpython-314.pyc differ
diff --git a/rpi/board_mate_client/__pycache__/configuration.cpython-314.pyc b/rpi/board_mate_client/__pycache__/configuration.cpython-314.pyc
new file mode 100644
index 00000000..7db1382d
Binary files /dev/null and b/rpi/board_mate_client/__pycache__/configuration.cpython-314.pyc differ
diff --git a/rpi/board_mate_client/__pycache__/exceptions.cpython-314.pyc b/rpi/board_mate_client/__pycache__/exceptions.cpython-314.pyc
new file mode 100644
index 00000000..76576ae5
Binary files /dev/null and b/rpi/board_mate_client/__pycache__/exceptions.cpython-314.pyc differ
diff --git a/rpi/board_mate_client/__pycache__/rest.cpython-314.pyc b/rpi/board_mate_client/__pycache__/rest.cpython-314.pyc
new file mode 100644
index 00000000..9a72fcfb
Binary files /dev/null and b/rpi/board_mate_client/__pycache__/rest.cpython-314.pyc differ
diff --git a/rpi/board_mate_client/api/__pycache__/__init__.cpython-314.pyc b/rpi/board_mate_client/api/__pycache__/__init__.cpython-314.pyc
new file mode 100644
index 00000000..9c011a0c
Binary files /dev/null and b/rpi/board_mate_client/api/__pycache__/__init__.cpython-314.pyc differ
diff --git a/rpi/board_mate_client/api/__pycache__/default_api.cpython-314.pyc b/rpi/board_mate_client/api/__pycache__/default_api.cpython-314.pyc
new file mode 100644
index 00000000..e71d3759
Binary files /dev/null and b/rpi/board_mate_client/api/__pycache__/default_api.cpython-314.pyc differ
diff --git a/rpi/board_mate_client/models/__pycache__/__init__.cpython-314.pyc b/rpi/board_mate_client/models/__pycache__/__init__.cpython-314.pyc
new file mode 100644
index 00000000..ebb7cd74
Binary files /dev/null and b/rpi/board_mate_client/models/__pycache__/__init__.cpython-314.pyc differ
diff --git a/rpi/board_mate_client/models/__pycache__/game_dto.cpython-314.pyc b/rpi/board_mate_client/models/__pycache__/game_dto.cpython-314.pyc
new file mode 100644
index 00000000..24b79bfe
Binary files /dev/null and b/rpi/board_mate_client/models/__pycache__/game_dto.cpython-314.pyc differ
diff --git a/rpi/board_mate_client/models/__pycache__/move_dto.cpython-314.pyc b/rpi/board_mate_client/models/__pycache__/move_dto.cpython-314.pyc
new file mode 100644
index 00000000..795e5a66
Binary files /dev/null and b/rpi/board_mate_client/models/__pycache__/move_dto.cpython-314.pyc differ
diff --git a/rpi/board_mate_client/models/__pycache__/response_body_game_dto.cpython-314.pyc b/rpi/board_mate_client/models/__pycache__/response_body_game_dto.cpython-314.pyc
new file mode 100644
index 00000000..bd32d200
Binary files /dev/null and b/rpi/board_mate_client/models/__pycache__/response_body_game_dto.cpython-314.pyc differ
diff --git a/rpi/board_mate_client/models/__pycache__/response_body_string.cpython-314.pyc b/rpi/board_mate_client/models/__pycache__/response_body_string.cpython-314.pyc
new file mode 100644
index 00000000..0acfd3bb
Binary files /dev/null and b/rpi/board_mate_client/models/__pycache__/response_body_string.cpython-314.pyc differ
diff --git a/rpi/controllers/__pycache__/__init__.cpython-311.pyc b/rpi/controllers/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 00000000..9a3cb4e8
Binary files /dev/null and b/rpi/controllers/__pycache__/__init__.cpython-311.pyc differ
diff --git a/rpi/controllers/__pycache__/__init__.cpython-314.pyc b/rpi/controllers/__pycache__/__init__.cpython-314.pyc
new file mode 100644
index 00000000..09263da4
Binary files /dev/null and b/rpi/controllers/__pycache__/__init__.cpython-314.pyc differ
diff --git a/rpi/controllers/__pycache__/board_mate_controller.cpython-314.pyc b/rpi/controllers/__pycache__/board_mate_controller.cpython-314.pyc
new file mode 100644
index 00000000..db225a38
Binary files /dev/null and b/rpi/controllers/__pycache__/board_mate_controller.cpython-314.pyc differ
diff --git a/rpi/controllers/__pycache__/device_controller.cpython-311.pyc b/rpi/controllers/__pycache__/device_controller.cpython-311.pyc
new file mode 100644
index 00000000..ce226061
Binary files /dev/null and b/rpi/controllers/__pycache__/device_controller.cpython-311.pyc differ
diff --git a/rpi/models/__pycache__/__init__.cpython-311.pyc b/rpi/models/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 00000000..ab845a25
Binary files /dev/null and b/rpi/models/__pycache__/__init__.cpython-311.pyc differ
diff --git a/rpi/models/detection/__pycache__/__init__.cpython-311.pyc b/rpi/models/detection/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 00000000..1c639813
Binary files /dev/null and b/rpi/models/detection/__pycache__/__init__.cpython-311.pyc differ
diff --git a/rpi/models/detection/__pycache__/board_manager.cpython-311.pyc b/rpi/models/detection/__pycache__/board_manager.cpython-311.pyc
new file mode 100644
index 00000000..146ed6bc
Binary files /dev/null and b/rpi/models/detection/__pycache__/board_manager.cpython-311.pyc differ
diff --git a/rpi/models/detection/__pycache__/detector.cpython-311.pyc b/rpi/models/detection/__pycache__/detector.cpython-311.pyc
new file mode 100644
index 00000000..5e7f5315
Binary files /dev/null and b/rpi/models/detection/__pycache__/detector.cpython-311.pyc differ
diff --git a/rpi/models/detection/__pycache__/pieces_manager.cpython-311.pyc b/rpi/models/detection/__pycache__/pieces_manager.cpython-311.pyc
new file mode 100644
index 00000000..b8cf2390
Binary files /dev/null and b/rpi/models/detection/__pycache__/pieces_manager.cpython-311.pyc differ
diff --git a/rpi/training/models/corner.pt b/rpi/training/models/corner.pt
new file mode 100644
index 00000000..0e2d02e4
Binary files /dev/null and b/rpi/training/models/corner.pt differ
diff --git a/rpi/training/models/unified-nano.pt b/rpi/training/models/unified-nano.pt
new file mode 100644
index 00000000..05dda92c
Binary files /dev/null and b/rpi/training/models/unified-nano.pt differ
diff --git a/rpi/training/models/yolo11n-pose.pt b/rpi/training/models/yolo11n-pose.pt
new file mode 100644
index 00000000..f8e73705
Binary files /dev/null and b/rpi/training/models/yolo11n-pose.pt differ
diff --git a/rpi/training/models/yolo11n-seg.pt b/rpi/training/models/yolo11n-seg.pt
new file mode 100644
index 00000000..628f5177
Binary files /dev/null and b/rpi/training/models/yolo11n-seg.pt differ
diff --git a/rpi/training/models/yolo11n.pt b/rpi/training/models/yolo11n.pt
new file mode 100644
index 00000000..45b273b4
Binary files /dev/null and b/rpi/training/models/yolo11n.pt differ
diff --git a/rpi/training/models/yolo11s.pt b/rpi/training/models/yolo11s.pt
new file mode 100644
index 00000000..d4bcb83c
Binary files /dev/null and b/rpi/training/models/yolo11s.pt differ
diff --git a/rpi/training/models/yolov8n.pt b/rpi/training/models/yolov8n.pt
new file mode 100644
index 00000000..0db4ca4b
Binary files /dev/null and b/rpi/training/models/yolov8n.pt differ
diff --git a/rpi/training/result/corners-training/BoxF1_curve.png b/rpi/training/result/corners-training/BoxF1_curve.png
new file mode 100644
index 00000000..fb80e7fd
Binary files /dev/null and b/rpi/training/result/corners-training/BoxF1_curve.png differ
diff --git a/rpi/training/result/corners-training/BoxPR_curve.png b/rpi/training/result/corners-training/BoxPR_curve.png
new file mode 100644
index 00000000..9a7c2d69
Binary files /dev/null and b/rpi/training/result/corners-training/BoxPR_curve.png differ
diff --git a/rpi/training/result/corners-training/BoxP_curve.png b/rpi/training/result/corners-training/BoxP_curve.png
new file mode 100644
index 00000000..3c995641
Binary files /dev/null and b/rpi/training/result/corners-training/BoxP_curve.png differ
diff --git a/rpi/training/result/corners-training/BoxR_curve.png b/rpi/training/result/corners-training/BoxR_curve.png
new file mode 100644
index 00000000..37fe3c53
Binary files /dev/null and b/rpi/training/result/corners-training/BoxR_curve.png differ
diff --git a/rpi/training/result/corners-training/PoseF1_curve.png b/rpi/training/result/corners-training/PoseF1_curve.png
new file mode 100644
index 00000000..cd077107
Binary files /dev/null and b/rpi/training/result/corners-training/PoseF1_curve.png differ
diff --git a/rpi/training/result/corners-training/PosePR_curve.png b/rpi/training/result/corners-training/PosePR_curve.png
new file mode 100644
index 00000000..eca87542
Binary files /dev/null and b/rpi/training/result/corners-training/PosePR_curve.png differ
diff --git a/rpi/training/result/corners-training/PoseP_curve.png b/rpi/training/result/corners-training/PoseP_curve.png
new file mode 100644
index 00000000..ddc67066
Binary files /dev/null and b/rpi/training/result/corners-training/PoseP_curve.png differ
diff --git a/rpi/training/result/corners-training/PoseR_curve.png b/rpi/training/result/corners-training/PoseR_curve.png
new file mode 100644
index 00000000..ac513c85
Binary files /dev/null and b/rpi/training/result/corners-training/PoseR_curve.png differ
diff --git a/rpi/training/result/corners-training/args.yaml b/rpi/training/result/corners-training/args.yaml
new file mode 100644
index 00000000..cac6e821
--- /dev/null
+++ b/rpi/training/result/corners-training/args.yaml
@@ -0,0 +1,106 @@
+task: pose
+mode: train
+model: models/yolo11n-pose.pt
+data: ./datasets/corners/data.yaml
+epochs: 150
+time: null
+patience: 20
+batch: 12
+imgsz: 640
+save: true
+save_period: 25
+cache: false
+device: '0'
+workers: 8
+project: result
+name: corners-training
+exist_ok: true
+pretrained: true
+optimizer: auto
+verbose: true
+seed: 0
+deterministic: true
+single_cls: false
+rect: false
+cos_lr: false
+close_mosaic: 10
+resume: false
+amp: true
+fraction: 1.0
+profile: false
+freeze: null
+multi_scale: false
+compile: false
+overlap_mask: true
+mask_ratio: 4
+dropout: 0.0
+val: true
+split: val
+save_json: false
+conf: null
+iou: 0.7
+max_det: 300
+half: false
+dnn: false
+plots: true
+source: null
+vid_stride: 1
+stream_buffer: false
+visualize: false
+augment: false
+agnostic_nms: false
+classes: null
+retina_masks: false
+embed: null
+show: false
+save_frames: false
+save_txt: false
+save_conf: false
+save_crop: false
+show_labels: true
+show_conf: true
+show_boxes: true
+line_width: null
+format: torchscript
+keras: false
+optimize: false
+int8: false
+dynamic: false
+simplify: true
+opset: null
+workspace: null
+nms: false
+lr0: 0.01
+lrf: 0.01
+momentum: 0.937
+weight_decay: 0.0005
+warmup_epochs: 3.0
+warmup_momentum: 0.8
+warmup_bias_lr: 0.1
+box: 7.5
+cls: 0.5
+dfl: 1.5
+pose: 12.0
+kobj: 1.0
+nbs: 64
+hsv_h: 0.015
+hsv_s: 0.7
+hsv_v: 0.4
+degrees: 0.0
+translate: 0.1
+scale: 0.5
+shear: 0.0
+perspective: 0.0
+flipud: 0.0
+fliplr: 0.5
+bgr: 0.0
+mosaic: 1.0
+mixup: 0.0
+cutmix: 0.0
+copy_paste: 0.0
+copy_paste_mode: flip
+auto_augment: randaugment
+erasing: 0.4
+cfg: null
+tracker: botsort.yaml
+save_dir: C:\Users\Laurent\Desktop\board-mate\rpi\training\result\corners-training
diff --git a/rpi/training/result/corners-training/confusion_matrix.png b/rpi/training/result/corners-training/confusion_matrix.png
new file mode 100644
index 00000000..8dd173f2
Binary files /dev/null and b/rpi/training/result/corners-training/confusion_matrix.png differ
diff --git a/rpi/training/result/corners-training/confusion_matrix_normalized.png b/rpi/training/result/corners-training/confusion_matrix_normalized.png
new file mode 100644
index 00000000..f1e68346
Binary files /dev/null and b/rpi/training/result/corners-training/confusion_matrix_normalized.png differ
diff --git a/rpi/training/result/corners-training/labels.jpg b/rpi/training/result/corners-training/labels.jpg
new file mode 100644
index 00000000..4b198b47
Binary files /dev/null and b/rpi/training/result/corners-training/labels.jpg differ
diff --git a/rpi/training/result/corners-training/results.csv b/rpi/training/result/corners-training/results.csv
new file mode 100644
index 00000000..1827b01d
--- /dev/null
+++ b/rpi/training/result/corners-training/results.csv
@@ -0,0 +1,123 @@
+epoch,time,train/box_loss,train/pose_loss,train/kobj_loss,train/cls_loss,train/dfl_loss,metrics/precision(B),metrics/recall(B),metrics/mAP50(B),metrics/mAP50-95(B),metrics/precision(P),metrics/recall(P),metrics/mAP50(P),metrics/mAP50-95(P),val/box_loss,val/pose_loss,val/kobj_loss,val/cls_loss,val/dfl_loss,lr/pg0,lr/pg1,lr/pg2
+1,41.8658,0.69307,3.77413,0.72815,0.64039,1.28117,0.96175,0.95725,0.98898,0.79175,0.79281,0.72839,0.65072,0.42698,0.75712,2.98661,0.75215,0.57127,1.28227,0.000664706,0.000664706,0.000664706
+2,80.8441,0.51914,2.12866,0.61949,0.38303,1.1348,0.96292,0.98731,0.98494,0.78,0.71747,0.72081,0.62925,0.51147,0.74913,2.41618,0.49852,0.4718,1.31998,0.00132259,0.00132259,0.00132259
+3,118.851,0.49814,1.85884,0.54851,0.37348,1.11293,0.95161,0.94825,0.95944,0.70246,0.771,0.68363,0.67966,0.45502,0.90578,2.80879,0.51889,0.8674,1.37102,0.00197167,0.00197167,0.00197167
+4,157.404,0.47059,1.66767,0.5049,0.34591,1.09446,0.99483,1,0.995,0.89386,0.8726,0.86924,0.86226,0.61132,0.49584,1.71543,0.24321,0.28147,0.97073,0.0019604,0.0019604,0.0019604
+5,200.334,0.44772,1.5232,0.48165,0.33325,1.07828,0.98863,0.99746,0.99457,0.87423,0.90156,0.88335,0.89545,0.67039,0.52482,1.67239,0.12556,0.27693,0.95892,0.0019472,0.0019472,0.0019472
+6,242.53,0.42402,1.32438,0.45056,0.31881,1.06058,0.99746,0.99728,0.995,0.9226,0.83111,0.80711,0.74127,0.48832,0.45583,1.88245,0.13891,0.31602,0.95715,0.001934,0.001934,0.001934
+7,280.951,0.40111,1.24069,0.43256,0.30494,1.04187,0.99992,0.99746,0.995,0.89269,0.90086,0.90355,0.9029,0.61367,0.50832,2.04948,0.13409,0.25962,0.94944,0.0019208,0.0019208,0.0019208
+8,318.789,0.3796,1.11959,0.39854,0.28586,1.03313,0.99367,0.99746,0.995,0.9392,0.86676,0.82487,0.84936,0.61981,0.42305,2.15732,0.13981,0.28876,0.9135,0.0019076,0.0019076,0.0019076
+9,356.462,0.37124,1.05743,0.38984,0.27503,1.02622,0.99982,1,0.995,0.95836,0.98959,0.73604,0.86569,0.80695,0.40299,1.45832,0.07292,0.24985,0.87883,0.0018944,0.0018944,0.0018944
+10,393.255,0.35552,1.01663,0.37543,0.27191,1.00972,0.99946,1,0.995,0.93964,0.85774,0.85787,0.86324,0.77142,0.41781,1.55795,0.05914,0.31105,0.91333,0.0018812,0.0018812,0.0018812
+11,430.457,0.35149,0.96948,0.37342,0.26409,1.01139,0.99981,1,0.995,0.93536,0.87028,0.87056,0.89826,0.72914,0.42494,1.68496,0.11233,0.23818,0.82714,0.001868,0.001868,0.001868
+12,467.26,0.33424,0.96809,0.35249,0.25545,1.00431,0.99947,1,0.995,0.97069,0.90561,0.90609,0.91291,0.49866,0.29453,2.32507,0.1175,0.22286,0.71953,0.0018548,0.0018548,0.0018548
+13,504.36,0.3344,0.94598,0.3399,0.25304,1.00019,0.99632,0.99746,0.995,0.95053,0.90954,0.76562,0.85441,0.71192,0.46083,1.92584,0.13254,0.26008,0.89397,0.0018416,0.0018416,0.0018416
+14,543.383,0.32972,0.92725,0.33625,0.24951,1.0016,1,0.99981,0.995,0.97263,0.85659,0.85533,0.87102,0.76749,0.31991,1.56867,0.11587,0.27602,0.78464,0.0018284,0.0018284,0.0018284
+15,582.997,0.32126,0.88673,0.32864,0.24507,0.99218,0.99796,1,0.995,0.95207,0.83305,0.80711,0.87646,0.75095,0.40368,1.55667,0.06468,0.21577,0.81679,0.0018152,0.0018152,0.0018152
+16,620.991,0.31566,0.87335,0.31561,0.24426,0.99104,0.99965,1,0.995,0.957,0.86337,0.77411,0.81892,0.75989,0.39342,1.56436,0.06818,0.39843,0.84569,0.001802,0.001802,0.001802
+17,658.811,0.30597,0.85827,0.30731,0.23968,0.98902,0.99983,1,0.995,0.96816,0.86637,0.75888,0.87673,0.8227,0.34624,1.56627,0.06645,0.23781,0.7908,0.0017888,0.0017888,0.0017888
+18,696.068,0.30208,0.81425,0.29495,0.22725,0.97742,0.9991,1,0.995,0.904,0.88491,0.88579,0.88404,0.62028,0.44549,1.8752,0.09522,0.44605,0.8804,0.0017756,0.0017756,0.0017756
+19,733.392,0.29831,0.78058,0.2869,0.23091,0.97986,0.99963,1,0.995,0.9597,0.9044,0.90355,0.93166,0.70766,0.36051,1.62024,0.14267,0.22122,0.80243,0.0017624,0.0017624,0.0017624
+20,771.296,0.29695,0.76096,0.28061,0.22734,0.97716,0.99963,1,0.995,0.95951,0.89305,0.8934,0.86533,0.53941,0.28948,1.57599,0.05685,0.20087,0.7097,0.0017492,0.0017492,0.0017492
+21,826.556,0.29791,0.76895,0.27933,0.22934,0.97495,0.99978,1,0.995,0.96711,0.92375,0.92386,0.95084,0.69793,0.32625,1.27303,0.12668,0.18997,0.74181,0.001736,0.001736,0.001736
+22,890.215,0.28593,0.71649,0.26951,0.22073,0.97144,0.99736,1,0.995,0.95264,0.91376,0.91624,0.91481,0.83206,0.33567,1.14861,0.06273,0.20222,0.78067,0.0017228,0.0017228,0.0017228
+23,953.322,0.28703,0.7198,0.26899,0.21899,0.97015,0.99703,1,0.995,0.9584,0.89138,0.88579,0.89882,0.77509,0.31369,1.59085,0.17639,0.24751,0.73889,0.0017096,0.0017096,0.0017096
+24,1002.22,0.28576,0.69198,0.25922,0.22184,0.97505,0.99979,1,0.995,0.96712,0.9465,0.9467,0.95094,0.85392,0.39743,1.07425,0.05928,0.2521,0.83125,0.0016964,0.0016964,0.0016964
+25,1038.67,0.28313,0.62082,0.2471,0.21496,0.97352,0.99985,1,0.995,0.95423,0.93894,0.93909,0.95908,0.85361,0.38329,0.94256,0.04887,0.23358,0.86399,0.0016832,0.0016832,0.0016832
+26,1075.24,0.28052,0.60793,0.25178,0.21419,0.96934,0.9997,1,0.995,0.97003,0.92358,0.92386,0.94426,0.89564,0.36543,0.87032,0.05428,0.23958,0.82694,0.00167,0.00167,0.00167
+27,1111.68,0.27994,0.5941,0.24751,0.21598,0.97132,0.99965,1,0.995,0.97209,0.97427,0.97462,0.98093,0.76219,0.27744,1.08364,0.0685,0.16464,0.70475,0.0016568,0.0016568,0.0016568
+28,1148.44,0.27895,0.58447,0.23733,0.2172,0.9677,0.99984,1,0.995,0.96578,0.95938,0.95939,0.95958,0.87034,0.33851,0.85532,0.06884,0.24491,0.79852,0.0016436,0.0016436,0.0016436
+29,1185.3,0.26658,0.557,0.22924,0.20513,0.96139,0.99984,1,0.995,0.97653,0.94662,0.9467,0.96267,0.93081,0.31553,0.65388,0.04317,0.18593,0.77426,0.0016304,0.0016304,0.0016304
+30,1222.29,0.26477,0.51292,0.21651,0.20264,0.96425,1,0.99983,0.995,0.96328,0.95726,0.95431,0.96143,0.83551,0.34112,0.91659,0.10449,0.22019,0.7806,0.0016172,0.0016172,0.0016172
+31,1259.93,0.26796,0.51762,0.20983,0.20697,0.96354,0.99969,1,0.995,0.94867,0.96416,0.96447,0.97433,0.82392,0.38355,0.96983,0.06258,0.19046,0.84624,0.001604,0.001604,0.001604
+32,1296.88,0.26934,0.49529,0.20868,0.20734,0.9661,0.99979,1,0.995,0.95502,0.95167,0.95178,0.95085,0.89775,0.37629,0.74517,0.05738,0.18957,0.82154,0.0015908,0.0015908,0.0015908
+33,1333.09,0.26369,0.45548,0.19971,0.20748,0.9625,0.99474,0.99746,0.9949,0.96513,0.9593,0.96193,0.97472,0.52948,0.3929,1.97617,0.0817,0.21653,0.79713,0.0015776,0.0015776,0.0015776
+34,1369.3,0.27149,0.45399,0.19625,0.21297,0.96413,0.99992,1,0.995,0.97354,0.96438,0.96447,0.97564,0.92317,0.25638,0.73132,0.0626,0.15593,0.68058,0.0015644,0.0015644,0.0015644
+35,1405.8,0.2666,0.44038,0.18882,0.19958,0.96435,0.99981,1,0.995,0.9722,0.94652,0.9467,0.94965,0.78254,0.27424,1.14871,0.08366,0.17643,0.71587,0.0015512,0.0015512,0.0015512
+36,1444.12,0.26001,0.41753,0.18053,0.19944,0.96203,0.99979,1,0.995,0.97126,0.95515,0.95431,0.96911,0.94105,0.32598,0.53702,0.05907,0.1853,0.76014,0.001538,0.001538,0.001538
+37,1480.32,0.25838,0.41353,0.17386,0.19782,0.96008,0.99967,1,0.995,0.96558,0.96683,0.96701,0.96566,0.87858,0.27835,0.82348,0.0548,0.18958,0.71508,0.0015248,0.0015248,0.0015248
+38,1516.59,0.26064,0.38703,0.16722,0.19878,0.96442,0.99859,1,0.995,0.97447,0.95781,0.95178,0.96992,0.88664,0.25487,0.81123,0.0456,0.15648,0.68062,0.0015116,0.0015116,0.0015116
+39,1553.25,0.24811,0.40134,0.15999,0.19272,0.95348,1,0.99982,0.995,0.96885,0.89805,0.89594,0.88223,0.81577,0.33967,0.98544,0.07561,0.19696,0.74205,0.0014984,0.0014984,0.0014984
+40,1589.29,0.25209,0.39657,0.15808,0.19776,0.95718,0.99983,1,0.995,0.97593,0.9643,0.96447,0.97216,0.93621,0.23164,0.54743,0.05507,0.15628,0.66362,0.0014852,0.0014852,0.0014852
+41,1628.9,0.25354,0.3777,0.15138,0.19667,0.96049,0.99934,1,0.995,0.96965,0.9689,0.96954,0.97076,0.947,0.30746,0.47588,0.05501,0.22409,0.74888,0.001472,0.001472,0.001472
+42,1665.68,0.24466,0.35839,0.13647,0.19282,0.95365,0.99983,1,0.995,0.96907,0.95669,0.95685,0.96969,0.93875,0.32129,0.52932,0.06228,0.18452,0.74446,0.0014588,0.0014588,0.0014588
+43,1702.27,0.24527,0.3491,0.13757,0.19238,0.95308,0.99982,1,0.995,0.96759,0.94906,0.94924,0.96437,0.89086,0.34469,0.61009,0.07387,0.18267,0.77154,0.0014456,0.0014456,0.0014456
+44,1738.51,0.24462,0.3412,0.13426,0.18944,0.95347,0.9998,1,0.995,0.97091,0.97442,0.97462,0.98198,0.89922,0.28994,0.82945,0.06073,0.1874,0.71154,0.0014324,0.0014324,0.0014324
+45,1774.81,0.24343,0.34856,0.1267,0.18817,0.94882,0.99973,1,0.995,0.97358,0.94869,0.9467,0.95493,0.90639,0.33497,0.67311,0.1771,0.18214,0.76598,0.0014192,0.0014192,0.0014192
+46,1810.98,0.24607,0.3128,0.12697,0.19242,0.95653,0.99985,1,0.995,0.97492,0.95678,0.95685,0.97235,0.93275,0.32419,0.60639,0.07634,0.17342,0.76716,0.001406,0.001406,0.001406
+47,1847.36,0.2482,0.32888,0.127,0.22637,0.96001,0.99985,1,0.995,0.97087,0.93388,0.93401,0.92631,0.87381,0.27904,0.78575,0.08141,0.17671,0.71643,0.0013928,0.0013928,0.0013928
+48,1883.96,0.24328,0.31338,0.12048,0.19025,0.94999,0.99983,1,0.995,0.97431,0.97699,0.97716,0.98361,0.93479,0.26735,0.40829,0.04812,0.14566,0.68872,0.0013796,0.0013796,0.0013796
+49,1920.36,0.23871,0.32326,0.12284,0.18374,0.9494,0.99985,1,0.995,0.96977,0.96432,0.96447,0.97387,0.79972,0.27748,0.79306,0.19351,0.17076,0.70923,0.0013664,0.0013664,0.0013664
+50,1956.45,0.24304,0.31749,0.12285,0.18452,0.95087,0.99983,1,0.995,0.97325,0.96941,0.96954,0.97677,0.8745,0.29011,0.55133,0.11191,0.1434,0.69653,0.0013532,0.0013532,0.0013532
+51,1993.55,0.23827,0.29298,0.11593,0.1822,0.94408,0.99938,1,0.995,0.97526,0.96387,0.96447,0.97424,0.93482,0.31133,0.4847,0.0533,0.15991,0.72714,0.00134,0.00134,0.00134
+52,2030.55,0.23563,0.28018,0.11237,0.18133,0.94868,0.99983,1,0.995,0.97096,0.97699,0.97716,0.98402,0.96395,0.31517,0.44986,0.07793,0.20216,0.74575,0.0013268,0.0013268,0.0013268
+53,2066.75,0.23384,0.29695,0.11892,0.1789,0.94541,0.99984,1,0.995,0.97256,0.95927,0.95939,0.97009,0.79479,0.26033,1.10111,0.12698,0.1648,0.69885,0.0013136,0.0013136,0.0013136
+54,2102.91,0.23152,0.2776,0.11114,0.18141,0.94411,0.99982,1,0.995,0.97631,0.97198,0.97208,0.97655,0.95527,0.3197,0.43438,0.03767,0.3008,0.73837,0.0013004,0.0013004,0.0013004
+55,2138.82,0.23046,0.26741,0.10828,0.17577,0.94546,0.99985,1,0.995,0.98041,0.98209,0.98223,0.98877,0.96507,0.2604,0.35929,0.04404,0.16826,0.69072,0.0012872,0.0012872,0.0012872
+56,2174.67,0.22749,0.26357,0.10458,0.17443,0.94552,0.99975,1,0.995,0.97582,0.97692,0.97716,0.98358,0.94576,0.27214,0.35448,0.29325,0.15032,0.69325,0.001274,0.001274,0.001274
+57,2210.82,0.22765,0.24893,0.10514,0.17317,0.94568,0.99984,1,0.995,0.97058,0.97701,0.97716,0.98411,0.95634,0.2492,0.34523,0.04154,0.14017,0.65436,0.0012608,0.0012608,0.0012608
+58,2247.23,0.22911,0.25326,0.09969,0.17453,0.94687,0.99984,1,0.995,0.96941,0.94401,0.94416,0.93237,0.80447,0.29883,0.53882,0.09426,0.15442,0.70813,0.0012476,0.0012476,0.0012476
+59,2283.26,0.22888,0.26267,0.09782,0.17675,0.94686,0.99978,1,0.995,0.96272,0.99475,0.99492,0.99497,0.93516,0.26397,0.43593,0.04185,0.16742,0.68021,0.0012344,0.0012344,0.0012344
+60,2318.97,0.23292,0.25173,0.09804,0.17627,0.94668,0.99981,1,0.995,0.97242,0.97951,0.9797,0.98016,0.94961,0.27568,0.35899,0.0853,0.1925,0.70429,0.0012212,0.0012212,0.0012212
+61,2356.26,0.22807,0.24696,0.10027,0.17422,0.94721,0.99983,1,0.995,0.9662,0.97953,0.9797,0.97445,0.93525,0.23848,0.40063,0.07996,0.16476,0.66578,0.001208,0.001208,0.001208
+62,2392.87,0.22747,0.2581,0.10249,0.17503,0.95321,0.9996,1,0.995,0.97074,0.9793,0.9797,0.97513,0.94557,0.26975,0.39598,0.05737,0.15921,0.68649,0.0011948,0.0011948,0.0011948
+63,2428.91,0.22766,0.24132,0.09611,0.17477,0.94303,0.99971,1,0.995,0.96235,0.97941,0.9797,0.97348,0.93612,0.2428,0.35819,0.039,0.15311,0.66118,0.0011816,0.0011816,0.0011816
+64,2465.95,0.22517,0.21765,0.09105,0.17103,0.94599,0.9998,1,0.995,0.96668,0.98457,0.98477,0.9841,0.94901,0.2771,0.36874,0.06648,0.15681,0.67964,0.0011684,0.0011684,0.0011684
+65,2503.83,0.22064,0.21802,0.09219,0.1702,0.9411,0.99979,1,0.995,0.97612,0.96442,0.96447,0.96162,0.91155,0.24653,0.68639,0.14368,0.18795,0.66392,0.0011552,0.0011552,0.0011552
+66,2541.56,0.22615,0.23008,0.09458,0.17335,0.94477,0.99964,1,0.995,0.9735,0.98188,0.98223,0.98454,0.91693,0.29998,0.56021,0.03456,0.16208,0.7394,0.001142,0.001142,0.001142
+67,2579.34,0.21895,0.22134,0.09177,0.17007,0.9393,0.9998,1,0.995,0.96791,0.98965,0.98985,0.98513,0.95475,0.29002,0.41934,0.04548,0.19376,0.70637,0.0011288,0.0011288,0.0011288
+68,2615.21,0.21973,0.1919,0.08678,0.1709,0.93963,0.99978,1,0.995,0.96724,0.98202,0.98223,0.98349,0.90306,0.26922,0.61318,0.10111,0.20667,0.69965,0.0011156,0.0011156,0.0011156
+69,2650.96,0.2166,0.22402,0.0907,0.16562,0.93782,0.99982,1,0.995,0.97324,0.97191,0.97208,0.98134,0.94279,0.28298,0.46992,0.04373,0.21881,0.71916,0.0011024,0.0011024,0.0011024
+70,2686.79,0.21906,0.20668,0.08299,0.16491,0.93901,0.99965,1,0.995,0.96212,0.98442,0.98477,0.98336,0.96374,0.26579,0.35204,0.08746,0.16889,0.68702,0.0010892,0.0010892,0.0010892
+71,2724.45,0.21016,0.19774,0.08291,0.1634,0.93385,0.9997,1,0.995,0.96475,0.98198,0.98223,0.98332,0.94531,0.27078,0.51252,0.04689,0.18894,0.70118,0.001076,0.001076,0.001076
+72,2760.19,0.2149,0.20865,0.08638,0.16158,0.9367,0.99985,1,0.995,0.97249,0.98722,0.98731,0.99049,0.97898,0.28486,0.2826,0.03408,0.18064,0.71769,0.0010628,0.0010628,0.0010628
+73,2795.77,0.21372,0.18585,0.07757,0.16098,0.93502,0.99985,1,0.995,0.96926,0.98463,0.98477,0.98439,0.96686,0.23842,0.32887,0.03542,0.16675,0.67708,0.0010496,0.0010496,0.0010496
+74,2832.16,0.21219,0.19808,0.08108,0.16174,0.93811,0.99981,1,0.995,0.97396,0.98204,0.98223,0.98686,0.96267,0.25053,0.38738,0.04021,0.16226,0.66394,0.0010364,0.0010364,0.0010364
+75,2884.25,0.21154,0.17501,0.07794,0.16458,0.93535,0.99984,1,0.995,0.96454,0.98212,0.98223,0.98262,0.94393,0.26803,0.44257,0.0566,0.1929,0.70009,0.0010232,0.0010232,0.0010232
+76,2944.97,0.21228,0.19711,0.08138,0.16737,0.93377,0.99983,1,0.995,0.96646,0.98715,0.98731,0.98447,0.92461,0.24225,0.41607,0.0348,0.16097,0.67341,0.00101,0.00101,0.00101
+77,3008.25,0.2151,0.1833,0.07709,0.16469,0.9407,0.99973,1,0.995,0.96418,0.98196,0.98223,0.98366,0.93001,0.2628,0.46921,0.09878,0.17788,0.70491,0.0009968,0.0009968,0.0009968
+78,3049.31,0.21425,0.18755,0.07687,0.1605,0.93539,0.99822,1,0.995,0.96739,0.98056,0.98223,0.98358,0.90628,0.26047,0.53634,0.05729,0.17455,0.68519,0.0009836,0.0009836,0.0009836
+79,3087.06,0.20793,0.1773,0.0746,0.16126,0.9352,0.99975,1,0.995,0.96655,0.98199,0.98223,0.98287,0.91938,0.29016,0.47211,0.05869,0.18346,0.7069,0.0009704,0.0009704,0.0009704
+80,3124.02,0.20848,0.17801,0.0768,0.16115,0.93479,0.99979,1,0.995,0.96672,0.9715,0.96701,0.97093,0.96037,0.28392,0.54634,0.09783,0.17891,0.71633,0.0009572,0.0009572,0.0009572
+81,3160.53,0.2073,0.16688,0.07229,0.15915,0.93552,0.99956,1,0.995,0.96926,0.97164,0.97208,0.97233,0.91555,0.26665,0.54827,0.0452,0.18538,0.69744,0.000944,0.000944,0.000944
+82,3197.02,0.2093,0.16428,0.06873,0.15987,0.93266,0.99981,1,0.995,0.97185,0.98458,0.98477,0.98373,0.95155,0.24957,0.33346,0.0599,0.14366,0.66852,0.0009308,0.0009308,0.0009308
+83,3233.19,0.20772,0.15941,0.07021,0.16025,0.93347,0.99975,1,0.995,0.96732,0.96675,0.96701,0.96219,0.9355,0.27792,0.42357,0.03927,0.16484,0.70684,0.0009176,0.0009176,0.0009176
+84,3269.31,0.20127,0.16847,0.06499,0.15542,0.93088,0.99971,1,0.995,0.96479,0.97434,0.97462,0.9718,0.951,0.25128,0.35881,0.03472,0.16965,0.67475,0.0009044,0.0009044,0.0009044
+85,3305.8,0.20216,0.15587,0.06895,0.15625,0.9334,0.99963,1,0.995,0.96885,0.97172,0.97208,0.97419,0.95291,0.26132,0.37446,0.03852,0.15243,0.69368,0.0008912,0.0008912,0.0008912
+86,3344.2,0.20354,0.16737,0.07149,0.15566,0.9329,0.99929,1,0.995,0.96572,0.97644,0.97716,0.9739,0.94227,0.2245,0.34752,0.03232,0.1351,0.65493,0.000878,0.000878,0.000878
+87,3389.15,0.20533,0.1604,0.06719,0.15668,0.9326,0.99941,1,0.995,0.9638,0.97929,0.9797,0.97424,0.93558,0.22373,0.34606,0.03417,0.13217,0.64715,0.0008648,0.0008648,0.0008648
+88,3438.25,0.20257,0.15615,0.06746,0.15741,0.93127,0.99979,1,0.995,0.96633,0.98203,0.98223,0.98305,0.93607,0.25572,0.38356,0.03464,0.17148,0.69273,0.0008516,0.0008516,0.0008516
+89,3499.91,0.20039,0.13643,0.06695,0.15308,0.93165,0.99985,1,0.995,0.96586,0.97447,0.97462,0.97358,0.85146,0.23551,0.44653,0.03699,0.13512,0.66228,0.0008384,0.0008384,0.0008384
+90,3561.09,0.20274,0.15695,0.06701,0.15267,0.93225,0.99983,1,0.995,0.96748,0.97446,0.97462,0.97583,0.89462,0.2269,0.41481,0.03757,0.16208,0.67632,0.0008252,0.0008252,0.0008252
+91,3618.14,0.19302,0.14341,0.06578,0.14975,0.92917,0.99985,1,0.995,0.97232,0.97448,0.97462,0.9762,0.97089,0.23752,0.2991,0.03227,0.16581,0.72065,0.000812,0.000812,0.000812
+92,3654.23,0.20038,0.15799,0.0652,0.15218,0.9318,0.99984,1,0.995,0.97259,0.98207,0.98223,0.98726,0.98131,0.21235,0.2616,0.04773,0.12781,0.64291,0.0007988,0.0007988,0.0007988
+93,3689.65,0.19023,0.13662,0.06122,0.14574,0.92551,0.99981,1,0.995,0.97527,0.97951,0.9797,0.98493,0.97308,0.2032,0.29249,0.03368,0.14232,0.63621,0.0007856,0.0007856,0.0007856
+94,3724.7,0.19616,0.13415,0.05921,0.14865,0.93075,0.99984,1,0.995,0.97642,0.98208,0.98223,0.987,0.97595,0.21629,0.30119,0.03241,0.14311,0.64116,0.0007724,0.0007724,0.0007724
+95,3759.63,0.20054,0.13043,0.06445,0.15849,0.93305,0.99982,1,0.995,0.97745,0.97699,0.97716,0.98311,0.94879,0.23807,0.39694,0.03499,0.17089,0.65597,0.0007592,0.0007592,0.0007592
+96,3797.99,0.20053,0.14308,0.06001,0.15525,0.92858,0.99964,1,0.995,0.9757,0.97681,0.97716,0.98337,0.94553,0.20586,0.39662,0.03853,0.11513,0.63758,0.000746,0.000746,0.000746
+97,3834.19,0.19415,0.13198,0.06327,0.15219,0.9291,0.99978,1,0.995,0.97892,0.98202,0.98223,0.98701,0.92947,0.21512,0.38049,0.03895,0.12492,0.64288,0.0007328,0.0007328,0.0007328
+98,3869.36,0.19769,0.13726,0.05792,0.1582,0.93047,0.99983,1,0.995,0.97584,0.97954,0.9797,0.98502,0.96447,0.29181,0.43827,0.04533,0.25325,0.69339,0.0007196,0.0007196,0.0007196
+99,3905.48,0.1931,0.14005,0.05879,0.14691,0.92704,0.9998,1,0.995,0.97531,0.9795,0.9797,0.98592,0.97457,0.25615,0.35473,0.05087,0.19319,0.67247,0.0007064,0.0007064,0.0007064
+100,3941.48,0.19669,0.13246,0.05929,0.15339,0.92856,0.99981,1,0.995,0.96973,0.97951,0.9797,0.97536,0.9677,0.29806,0.33783,0.0409,0.17006,0.71805,0.0006932,0.0006932,0.0006932
+101,3977.45,0.19787,0.12413,0.05634,0.14962,0.92788,0.99972,1,0.995,0.97416,0.9845,0.98477,0.98513,0.97464,0.27688,0.29723,0.03804,0.1582,0.69637,0.00068,0.00068,0.00068
+102,4013.43,0.19365,0.12164,0.05403,0.14708,0.92507,0.99973,1,0.995,0.97829,0.98704,0.98731,0.98973,0.98363,0.22145,0.23119,0.03078,0.11484,0.63888,0.0006668,0.0006668,0.0006668
+103,4049.86,0.18922,0.12249,0.0541,0.14511,0.92592,0.9996,1,0.995,0.97635,0.98184,0.98223,0.98645,0.98314,0.22662,0.25381,0.03791,0.12071,0.64712,0.0006536,0.0006536,0.0006536
+104,4085.9,0.19198,0.12236,0.05401,0.14777,0.9304,0.9998,1,0.995,0.97503,0.9795,0.9797,0.98496,0.98162,0.27936,0.26264,0.05589,0.1843,0.72599,0.0006404,0.0006404,0.0006404
+105,4121.83,0.18681,0.11665,0.05452,0.14126,0.92572,0.99984,1,0.995,0.97532,0.98461,0.98477,0.98821,0.98357,0.23599,0.21897,0.03495,0.12562,0.65805,0.0006272,0.0006272,0.0006272
+106,4159.34,0.18931,0.12302,0.05285,0.14246,0.92584,0.99982,1,0.995,0.97722,0.98205,0.98223,0.98684,0.97835,0.25876,0.29638,0.03407,0.16049,0.6784,0.000614,0.000614,0.000614
+107,4195.74,0.18796,0.11484,0.05041,0.14362,0.9265,0.99979,1,0.995,0.96935,0.97949,0.9797,0.97924,0.95248,0.24025,0.2878,0.02369,0.13361,0.65578,0.0006008,0.0006008,0.0006008
+108,4231.54,0.18757,0.11764,0.05198,0.14475,0.92646,0.9998,1,0.995,0.96933,0.98204,0.98223,0.98245,0.93037,0.27001,0.40162,0.03723,0.17234,0.70029,0.0005876,0.0005876,0.0005876
+109,4267.56,0.19175,0.11254,0.05275,0.145,0.9276,0.99983,1,0.995,0.97396,0.98207,0.98223,0.98434,0.93374,0.25562,0.4719,0.02845,0.15375,0.68166,0.0005744,0.0005744,0.0005744
+110,4303.6,0.18424,0.11282,0.05199,0.14493,0.92974,0.99984,1,0.995,0.97399,0.98461,0.98477,0.98563,0.92607,0.24741,0.53219,0.03147,0.15061,0.67807,0.0005612,0.0005612,0.0005612
+111,4339.91,0.18773,0.10936,0.05228,0.14673,0.92905,0.99983,1,0.995,0.97165,0.9846,0.98477,0.98355,0.91287,0.24123,0.47352,0.0301,0.15751,0.67074,0.000548,0.000548,0.000548
+112,4376.47,0.18008,0.10368,0.05034,0.13864,0.92094,0.99979,1,0.995,0.97363,0.98202,0.98223,0.98648,0.95041,0.25188,0.48111,0.02839,0.14908,0.67927,0.0005348,0.0005348,0.0005348
+113,4413.13,0.18541,0.122,0.0518,0.14829,0.9254,0.99976,1,0.995,0.96913,0.982,0.98223,0.98294,0.95892,0.246,0.32916,0.02569,0.15708,0.67047,0.0005216,0.0005216,0.0005216
+114,4449.44,0.17684,0.10055,0.04513,0.13459,0.9226,0.99979,1,0.995,0.97342,0.98203,0.98223,0.98619,0.9794,0.2232,0.25121,0.02916,0.12833,0.64652,0.0005084,0.0005084,0.0005084
+115,4485.77,0.17897,0.09904,0.04583,0.13773,0.92376,0.9998,1,0.995,0.9742,0.98458,0.98477,0.98789,0.97447,0.26093,0.31745,0.03068,0.19056,0.67449,0.0004952,0.0004952,0.0004952
+116,4522.97,0.17672,0.10152,0.04676,0.13291,0.91946,0.99982,1,0.995,0.97666,0.98713,0.98731,0.98997,0.97642,0.23816,0.29252,0.0356,0.14726,0.65811,0.000482,0.000482,0.000482
+117,4559.69,0.17613,0.10321,0.04537,0.13302,0.92168,0.99984,1,0.995,0.97696,0.98715,0.98731,0.98983,0.97863,0.24862,0.28556,0.03062,0.15368,0.67233,0.0004688,0.0004688,0.0004688
+118,4596.34,0.17646,0.10323,0.04861,0.13363,0.91883,0.99985,1,0.995,0.9785,0.98716,0.98731,0.98994,0.97648,0.23669,0.2839,0.02463,0.14847,0.66231,0.0004556,0.0004556,0.0004556
+119,4632.45,0.17602,0.10081,0.04742,0.13517,0.91892,0.99976,1,0.995,0.9778,0.98708,0.98731,0.98987,0.96218,0.241,0.30527,0.02843,0.14518,0.66692,0.0004424,0.0004424,0.0004424
+120,4668.66,0.17735,0.10765,0.05064,0.13768,0.92402,0.9997,1,0.995,0.97626,0.98448,0.98477,0.98786,0.95995,0.22648,0.33094,0.02432,0.13178,0.64916,0.0004292,0.0004292,0.0004292
+121,4704.27,0.1743,0.09213,0.04368,0.13562,0.92291,0.99978,1,0.995,0.97755,0.98456,0.98477,0.98787,0.94648,0.23997,0.34039,0.02239,0.1435,0.66791,0.000416,0.000416,0.000416
+122,4757.92,0.17425,0.09085,0.04699,0.13466,0.91992,0.99965,1,0.995,0.97818,0.98443,0.98477,0.98801,0.94732,0.25639,0.34739,0.0231,0.14642,0.68408,0.0004028,0.0004028,0.0004028
diff --git a/rpi/training/result/corners-training/results.png b/rpi/training/result/corners-training/results.png
new file mode 100644
index 00000000..0878f5de
Binary files /dev/null and b/rpi/training/result/corners-training/results.png differ
diff --git a/rpi/training/result/corners-training/train_batch0.jpg b/rpi/training/result/corners-training/train_batch0.jpg
new file mode 100644
index 00000000..15e7b5e8
Binary files /dev/null and b/rpi/training/result/corners-training/train_batch0.jpg differ
diff --git a/rpi/training/result/corners-training/train_batch1.jpg b/rpi/training/result/corners-training/train_batch1.jpg
new file mode 100644
index 00000000..0ec040e7
Binary files /dev/null and b/rpi/training/result/corners-training/train_batch1.jpg differ
diff --git a/rpi/training/result/corners-training/train_batch2.jpg b/rpi/training/result/corners-training/train_batch2.jpg
new file mode 100644
index 00000000..e8132142
Binary files /dev/null and b/rpi/training/result/corners-training/train_batch2.jpg differ
diff --git a/rpi/training/result/corners-training/val_batch0_labels.jpg b/rpi/training/result/corners-training/val_batch0_labels.jpg
new file mode 100644
index 00000000..73aab30d
Binary files /dev/null and b/rpi/training/result/corners-training/val_batch0_labels.jpg differ
diff --git a/rpi/training/result/corners-training/val_batch0_pred.jpg b/rpi/training/result/corners-training/val_batch0_pred.jpg
new file mode 100644
index 00000000..d99a7b60
Binary files /dev/null and b/rpi/training/result/corners-training/val_batch0_pred.jpg differ
diff --git a/rpi/training/result/corners-training/val_batch1_labels.jpg b/rpi/training/result/corners-training/val_batch1_labels.jpg
new file mode 100644
index 00000000..5215fdee
Binary files /dev/null and b/rpi/training/result/corners-training/val_batch1_labels.jpg differ
diff --git a/rpi/training/result/corners-training/val_batch1_pred.jpg b/rpi/training/result/corners-training/val_batch1_pred.jpg
new file mode 100644
index 00000000..12964dc5
Binary files /dev/null and b/rpi/training/result/corners-training/val_batch1_pred.jpg differ
diff --git a/rpi/training/result/corners-training/val_batch2_labels.jpg b/rpi/training/result/corners-training/val_batch2_labels.jpg
new file mode 100644
index 00000000..a7f4e6fa
Binary files /dev/null and b/rpi/training/result/corners-training/val_batch2_labels.jpg differ
diff --git a/rpi/training/result/corners-training/val_batch2_pred.jpg b/rpi/training/result/corners-training/val_batch2_pred.jpg
new file mode 100644
index 00000000..5d84e353
Binary files /dev/null and b/rpi/training/result/corners-training/val_batch2_pred.jpg differ
diff --git a/rpi/training/result/corners-training/weights/best.pt b/rpi/training/result/corners-training/weights/best.pt
new file mode 100644
index 00000000..ad4f266d
Binary files /dev/null and b/rpi/training/result/corners-training/weights/best.pt differ
diff --git a/rpi/training/result/corners-training/weights/epoch0.pt b/rpi/training/result/corners-training/weights/epoch0.pt
new file mode 100644
index 00000000..9b09c9a6
Binary files /dev/null and b/rpi/training/result/corners-training/weights/epoch0.pt differ
diff --git a/rpi/training/result/corners-training/weights/epoch100.pt b/rpi/training/result/corners-training/weights/epoch100.pt
new file mode 100644
index 00000000..045a6298
Binary files /dev/null and b/rpi/training/result/corners-training/weights/epoch100.pt differ
diff --git a/rpi/training/result/corners-training/weights/epoch25.pt b/rpi/training/result/corners-training/weights/epoch25.pt
new file mode 100644
index 00000000..6663362a
Binary files /dev/null and b/rpi/training/result/corners-training/weights/epoch25.pt differ
diff --git a/rpi/training/result/corners-training/weights/epoch50.pt b/rpi/training/result/corners-training/weights/epoch50.pt
new file mode 100644
index 00000000..fac748c5
Binary files /dev/null and b/rpi/training/result/corners-training/weights/epoch50.pt differ
diff --git a/rpi/training/result/corners-training/weights/epoch75.pt b/rpi/training/result/corners-training/weights/epoch75.pt
new file mode 100644
index 00000000..c415a0f0
Binary files /dev/null and b/rpi/training/result/corners-training/weights/epoch75.pt differ
diff --git a/rpi/training/result/corners-training/weights/last.pt b/rpi/training/result/corners-training/weights/last.pt
new file mode 100644
index 00000000..0d611736
Binary files /dev/null and b/rpi/training/result/corners-training/weights/last.pt differ
diff --git a/rpi/training/result/edges-nano/BoxF1_curve.png b/rpi/training/result/edges-nano/BoxF1_curve.png
new file mode 100644
index 00000000..8e83dad3
Binary files /dev/null and b/rpi/training/result/edges-nano/BoxF1_curve.png differ
diff --git a/rpi/training/result/edges-nano/BoxPR_curve.png b/rpi/training/result/edges-nano/BoxPR_curve.png
new file mode 100644
index 00000000..7d5e8510
Binary files /dev/null and b/rpi/training/result/edges-nano/BoxPR_curve.png differ
diff --git a/rpi/training/result/edges-nano/BoxP_curve.png b/rpi/training/result/edges-nano/BoxP_curve.png
new file mode 100644
index 00000000..046cdb05
Binary files /dev/null and b/rpi/training/result/edges-nano/BoxP_curve.png differ
diff --git a/rpi/training/result/edges-nano/BoxR_curve.png b/rpi/training/result/edges-nano/BoxR_curve.png
new file mode 100644
index 00000000..36520098
Binary files /dev/null and b/rpi/training/result/edges-nano/BoxR_curve.png differ
diff --git a/rpi/training/result/edges-nano/MaskF1_curve.png b/rpi/training/result/edges-nano/MaskF1_curve.png
new file mode 100644
index 00000000..10cd5b53
Binary files /dev/null and b/rpi/training/result/edges-nano/MaskF1_curve.png differ
diff --git a/rpi/training/result/edges-nano/MaskPR_curve.png b/rpi/training/result/edges-nano/MaskPR_curve.png
new file mode 100644
index 00000000..d4169991
Binary files /dev/null and b/rpi/training/result/edges-nano/MaskPR_curve.png differ
diff --git a/rpi/training/result/edges-nano/MaskP_curve.png b/rpi/training/result/edges-nano/MaskP_curve.png
new file mode 100644
index 00000000..dd560158
Binary files /dev/null and b/rpi/training/result/edges-nano/MaskP_curve.png differ
diff --git a/rpi/training/result/edges-nano/MaskR_curve.png b/rpi/training/result/edges-nano/MaskR_curve.png
new file mode 100644
index 00000000..73a78654
Binary files /dev/null and b/rpi/training/result/edges-nano/MaskR_curve.png differ
diff --git a/rpi/training/result/edges-nano/args.yaml b/rpi/training/result/edges-nano/args.yaml
new file mode 100644
index 00000000..12fc7ad2
--- /dev/null
+++ b/rpi/training/result/edges-nano/args.yaml
@@ -0,0 +1,106 @@
+task: segment
+mode: train
+model: models/yolo11n-seg.pt
+data: ./datasets/edges/data.yaml
+epochs: 150
+time: null
+patience: 20
+batch: 12
+imgsz: 640
+save: true
+save_period: 10
+cache: false
+device: '0'
+workers: 8
+project: result
+name: edges-nano
+exist_ok: false
+pretrained: true
+optimizer: auto
+verbose: true
+seed: 0
+deterministic: true
+single_cls: false
+rect: false
+cos_lr: false
+close_mosaic: 10
+resume: false
+amp: true
+fraction: 1.0
+profile: false
+freeze: null
+multi_scale: false
+compile: false
+overlap_mask: true
+mask_ratio: 4
+dropout: 0.0
+val: true
+split: val
+save_json: false
+conf: null
+iou: 0.7
+max_det: 300
+half: false
+dnn: false
+plots: true
+source: null
+vid_stride: 1
+stream_buffer: false
+visualize: false
+augment: false
+agnostic_nms: false
+classes: null
+retina_masks: false
+embed: null
+show: false
+save_frames: false
+save_txt: false
+save_conf: false
+save_crop: false
+show_labels: true
+show_conf: true
+show_boxes: true
+line_width: null
+format: torchscript
+keras: false
+optimize: false
+int8: false
+dynamic: false
+simplify: true
+opset: null
+workspace: null
+nms: false
+lr0: 0.01
+lrf: 0.01
+momentum: 0.937
+weight_decay: 0.0005
+warmup_epochs: 3.0
+warmup_momentum: 0.8
+warmup_bias_lr: 0.1
+box: 7.5
+cls: 0.5
+dfl: 1.5
+pose: 12.0
+kobj: 1.0
+nbs: 64
+hsv_h: 0.015
+hsv_s: 0.7
+hsv_v: 0.4
+degrees: 0.0
+translate: 0.1
+scale: 0.5
+shear: 0.0
+perspective: 0.0
+flipud: 0.0
+fliplr: 0.5
+bgr: 0.0
+mosaic: 1.0
+mixup: 0.0
+cutmix: 0.0
+copy_paste: 0.0
+copy_paste_mode: flip
+auto_augment: randaugment
+erasing: 0.4
+cfg: null
+tracker: botsort.yaml
+save_dir: C:\Users\Laurent\Desktop\board-mate\rpi\training\result\edges-nano
diff --git a/rpi/training/result/edges-nano/confusion_matrix.png b/rpi/training/result/edges-nano/confusion_matrix.png
new file mode 100644
index 00000000..5eff0efa
Binary files /dev/null and b/rpi/training/result/edges-nano/confusion_matrix.png differ
diff --git a/rpi/training/result/edges-nano/confusion_matrix_normalized.png b/rpi/training/result/edges-nano/confusion_matrix_normalized.png
new file mode 100644
index 00000000..83afe957
Binary files /dev/null and b/rpi/training/result/edges-nano/confusion_matrix_normalized.png differ
diff --git a/rpi/training/result/edges-nano/labels.jpg b/rpi/training/result/edges-nano/labels.jpg
new file mode 100644
index 00000000..c1d7d212
Binary files /dev/null and b/rpi/training/result/edges-nano/labels.jpg differ
diff --git a/rpi/training/result/edges-nano/results.csv b/rpi/training/result/edges-nano/results.csv
new file mode 100644
index 00000000..f72a05b8
--- /dev/null
+++ b/rpi/training/result/edges-nano/results.csv
@@ -0,0 +1,117 @@
+epoch,time,train/box_loss,train/seg_loss,train/cls_loss,train/dfl_loss,metrics/precision(B),metrics/recall(B),metrics/mAP50(B),metrics/mAP50-95(B),metrics/precision(M),metrics/recall(M),metrics/mAP50(M),metrics/mAP50-95(M),val/box_loss,val/seg_loss,val/cls_loss,val/dfl_loss,lr/pg0,lr/pg1,lr/pg2
+1,107.847,0.52721,0.86298,1.14096,1.02452,0.95706,0.96913,0.98188,0.88943,0.95461,0.96783,0.97848,0.92424,0.43132,0.42199,0.72877,1.04563,0.0033287,0.0033287,0.0033287
+2,211.841,0.44686,0.4797,0.53649,0.95043,0.97437,0.95304,0.98593,0.917,0.9726,0.9513,0.97861,0.92974,0.36926,0.50062,0.43777,0.96565,0.00661807,0.00661807,0.00661807
+3,308,0.51156,0.51316,0.48149,0.97834,0.9446,0.95913,0.97742,0.88401,0.94374,0.95826,0.97528,0.91235,0.44433,0.50938,0.41321,1.03414,0.00986343,0.00986343,0.00986343
+4,405.057,0.5207,0.54139,0.444,0.98303,0.94353,0.97338,0.97167,0.8953,0.941,0.97077,0.96878,0.91011,0.38921,0.50847,0.37159,0.98678,0.009802,0.009802,0.009802
+5,503.769,0.48829,0.50109,0.39484,0.9659,0.96479,0.95739,0.9814,0.91605,0.96391,0.95652,0.98075,0.94035,0.37348,0.40976,0.34067,0.98688,0.009736,0.009736,0.009736
+6,603.199,0.44573,0.46749,0.35913,0.94838,0.95772,0.98498,0.98425,0.93875,0.95603,0.98324,0.98323,0.95328,0.30719,0.33623,0.30263,0.92314,0.00967,0.00967,0.00967
+7,701.51,0.42676,0.44513,0.34182,0.94303,0.96426,0.98531,0.99037,0.95563,0.96256,0.98375,0.98949,0.96634,0.29032,0.31303,0.25712,0.89738,0.009604,0.009604,0.009604
+8,800.417,0.40862,0.4292,0.32337,0.93522,0.9692,0.99043,0.99207,0.95962,0.96835,0.98957,0.99176,0.97232,0.27948,0.30555,0.24238,0.89432,0.009538,0.009538,0.009538
+9,899.854,0.39211,0.41682,0.30726,0.92751,0.97541,0.98522,0.99297,0.96516,0.97369,0.98348,0.99245,0.97488,0.27858,0.30034,0.23503,0.89253,0.009472,0.009472,0.009472
+10,998.52,0.37684,0.39683,0.29676,0.92015,0.96844,0.98725,0.99224,0.96648,0.96767,0.98892,0.99137,0.97177,0.2589,0.30764,0.22978,0.87593,0.009406,0.009406,0.009406
+11,1099.57,0.36701,0.3901,0.29155,0.91807,0.97418,0.98261,0.99171,0.96789,0.97245,0.98087,0.99115,0.97332,0.26057,0.28331,0.23488,0.87961,0.00934,0.00934,0.00934
+12,1198.78,0.35667,0.37464,0.28446,0.91647,0.9783,0.98001,0.99237,0.96782,0.97656,0.97827,0.99185,0.97345,0.25721,0.27423,0.21859,0.87886,0.009274,0.009274,0.009274
+13,1298.74,0.34492,0.36335,0.27292,0.91135,0.96843,0.98698,0.9909,0.9572,0.96672,0.98524,0.98923,0.96333,0.25834,0.28256,0.2392,0.88907,0.009208,0.009208,0.009208
+14,1395.12,0.34504,0.363,0.27146,0.9142,0.9668,0.98768,0.98881,0.96683,0.96595,0.98681,0.98818,0.9743,0.24674,0.27189,0.21869,0.87302,0.009142,0.009142,0.009142
+15,1490.44,0.33934,0.35701,0.26753,0.91182,0.97507,0.98629,0.99286,0.97156,0.97421,0.98542,0.99266,0.97694,0.24772,0.27236,0.20878,0.86691,0.009076,0.009076,0.009076
+16,1589.01,0.32836,0.34028,0.2593,0.90553,0.97563,0.99217,0.99296,0.97335,0.97478,0.9913,0.99273,0.98075,0.22147,0.2518,0.20329,0.84851,0.00901,0.00901,0.00901
+17,1688.77,0.32741,0.34381,0.25711,0.90524,0.97663,0.98609,0.99208,0.97429,0.97577,0.98522,0.99138,0.97726,0.21371,0.24954,0.19601,0.84607,0.008944,0.008944,0.008944
+18,1787.51,0.3245,0.33391,0.25284,0.90678,0.97665,0.98348,0.99259,0.97682,0.97578,0.98261,0.99222,0.98053,0.21078,0.24404,0.18937,0.84082,0.008878,0.008878,0.008878
+19,1886.49,0.31572,0.33354,0.24965,0.89871,0.97977,0.98261,0.9924,0.97865,0.97817,0.98087,0.99144,0.9801,0.20476,0.24179,0.19052,0.83205,0.008812,0.008812,0.008812
+20,1984.11,0.31172,0.33331,0.24687,0.90068,0.9827,0.98816,0.99354,0.98233,0.98184,0.98729,0.99312,0.98418,0.20096,0.25097,0.17218,0.82988,0.008746,0.008746,0.008746
+21,2081.73,0.31086,0.32866,0.24377,0.89988,0.98765,0.98174,0.99339,0.97762,0.98677,0.98087,0.99293,0.98155,0.21773,0.23336,0.18595,0.84376,0.00868,0.00868,0.00868
+22,2176.5,0.30628,0.32043,0.23928,0.90007,0.986,0.98022,0.99243,0.97854,0.98513,0.97935,0.99179,0.97967,0.1986,0.23492,0.18422,0.83212,0.008614,0.008614,0.008614
+23,2273.73,0.29791,0.31342,0.23157,0.89284,0.98023,0.99182,0.99259,0.98277,0.97937,0.99095,0.99239,0.98313,0.1893,0.22676,0.17066,0.8275,0.008548,0.008548,0.008548
+24,2373.58,0.29793,0.3141,0.23308,0.89246,0.98319,0.99304,0.99291,0.98368,0.98233,0.99217,0.99259,0.9827,0.18488,0.23068,0.16163,0.82214,0.008482,0.008482,0.008482
+25,2471.68,0.29756,0.31658,0.23125,0.89431,0.98024,0.99191,0.993,0.98238,0.97938,0.99107,0.99249,0.98302,0.1895,0.22699,0.17048,0.82978,0.008416,0.008416,0.008416
+26,2569.79,0.29619,0.30354,0.23038,0.89486,0.98768,0.98522,0.99336,0.98248,0.98506,0.98261,0.99276,0.98343,0.19131,0.22987,0.16194,0.82622,0.00835,0.00835,0.00835
+27,2668.19,0.29071,0.31135,0.22767,0.89316,0.97596,0.9884,0.99275,0.982,0.9751,0.98753,0.99256,0.98184,0.18551,0.2253,0.16818,0.81831,0.008284,0.008284,0.008284
+28,2767.34,0.28938,0.31037,0.22534,0.89248,0.97924,0.98418,0.99194,0.98112,0.9775,0.98244,0.99144,0.98149,0.18282,0.21719,0.17099,0.82046,0.008218,0.008218,0.008218
+29,2863.38,0.28634,0.30647,0.2266,0.89076,0.9852,0.98375,0.99333,0.98135,0.98345,0.98201,0.99205,0.98352,0.18189,0.21539,0.16538,0.81536,0.008152,0.008152,0.008152
+30,2961.53,0.28431,0.30689,0.22148,0.88882,0.9832,0.98348,0.99303,0.98327,0.98233,0.98261,0.99238,0.98341,0.1805,0.21713,0.16704,0.81625,0.008086,0.008086,0.008086
+31,3060.95,0.28019,0.30226,0.21823,0.88867,0.97834,0.9913,0.99307,0.98274,0.97748,0.99043,0.99235,0.98211,0.17961,0.22615,0.16259,0.81651,0.00802,0.00802,0.00802
+32,3159.09,0.28009,0.29671,0.21843,0.88636,0.98622,0.98696,0.99274,0.98474,0.98535,0.98609,0.99159,0.98474,0.1755,0.22404,0.15472,0.81,0.007954,0.007954,0.007954
+33,3283.17,0.27592,0.29208,0.21545,0.88575,0.98512,0.98696,0.99307,0.98394,0.98425,0.98609,0.99264,0.98547,0.17483,0.21325,0.15813,0.81005,0.007888,0.007888,0.007888
+34,3428.45,0.27591,0.29288,0.21188,0.89014,0.98611,0.98806,0.99342,0.98452,0.98525,0.98719,0.993,0.98523,0.17652,0.20526,0.15379,0.81851,0.007822,0.007822,0.007822
+35,3550.9,0.27433,0.2968,0.21354,0.88813,0.97851,0.98972,0.99297,0.98386,0.97765,0.98885,0.99262,0.98422,0.17037,0.21182,0.14861,0.80926,0.007756,0.007756,0.007756
+36,3657.09,0.27319,0.287,0.2105,0.88652,0.97939,0.99164,0.99332,0.98437,0.97853,0.99085,0.99242,0.98552,0.16931,0.21514,0.15294,0.8092,0.00769,0.00769,0.00769
+37,3782.23,0.26943,0.28317,0.21014,0.88438,0.98784,0.98876,0.99285,0.98559,0.98697,0.98789,0.99202,0.9857,0.16731,0.21337,0.15326,0.80781,0.007624,0.007624,0.007624
+38,3940.62,0.27105,0.28908,0.21144,0.88662,0.99213,0.98699,0.99338,0.98617,0.9891,0.98783,0.9926,0.98656,0.15869,0.2083,0.13522,0.8036,0.007558,0.007558,0.007558
+39,4072.86,0.26492,0.27526,0.20484,0.88591,0.98964,0.98696,0.99281,0.98695,0.98877,0.98609,0.99181,0.98614,0.16551,0.2036,0.14647,0.80637,0.007492,0.007492,0.007492
+40,4172.63,0.26602,0.28533,0.20697,0.88646,0.98528,0.98921,0.9936,0.98422,0.98441,0.98834,0.99293,0.98513,0.16638,0.20797,0.1441,0.8097,0.007426,0.007426,0.007426
+41,4279.16,0.26753,0.27984,0.20912,0.88635,0.98823,0.9887,0.9937,0.98625,0.9865,0.98696,0.99293,0.98627,0.15909,0.20736,0.14165,0.80237,0.00736,0.00736,0.00736
+42,4379.6,0.26213,0.27729,0.202,0.88377,0.98898,0.98783,0.99328,0.98681,0.98811,0.98696,0.99268,0.98722,0.16117,0.20903,0.14508,0.8047,0.007294,0.007294,0.007294
+43,4482.65,0.26356,0.27833,0.20689,0.8846,0.98664,0.99043,0.99348,0.98706,0.98491,0.9887,0.99285,0.98634,0.15905,0.21222,0.14651,0.80541,0.007228,0.007228,0.007228
+44,4587.38,0.26245,0.2721,0.20489,0.88247,0.9794,0.99242,0.99279,0.98484,0.97855,0.99155,0.99227,0.98563,0.15991,0.20451,0.1494,0.8079,0.007162,0.007162,0.007162
+45,4720.87,0.26093,0.27546,0.20192,0.88395,0.98712,0.98435,0.99327,0.9859,0.98538,0.98261,0.99286,0.98608,0.15651,0.20262,0.14215,0.80211,0.007096,0.007096,0.007096
+46,4836.26,0.25691,0.27387,0.19994,0.8795,0.97768,0.99038,0.99316,0.98708,0.97682,0.98951,0.9927,0.98675,0.14856,0.20668,0.13947,0.79501,0.00703,0.00703,0.00703
+47,4937.59,0.26141,0.27651,0.20042,0.8849,0.98872,0.99067,0.99365,0.98785,0.98785,0.9898,0.99308,0.98787,0.15137,0.20431,0.13473,0.80331,0.006964,0.006964,0.006964
+48,5076.53,0.25335,0.26878,0.19769,0.8797,0.98691,0.98957,0.99366,0.98749,0.98604,0.9887,0.99322,0.98674,0.1512,0.20275,0.13833,0.7981,0.006898,0.006898,0.006898
+49,5221.15,0.25461,0.26933,0.19551,0.8829,0.99032,0.97891,0.99312,0.9857,0.98944,0.97804,0.99217,0.98494,0.15005,0.20016,0.13982,0.79806,0.006832,0.006832,0.006832
+50,5347.85,0.25388,0.26372,0.20132,0.88001,0.98603,0.98609,0.99279,0.98544,0.98436,0.98529,0.99222,0.98599,0.16602,0.19515,0.16115,0.81139,0.006766,0.006766,0.006766
+51,5446.41,0.25017,0.26252,0.19767,0.88037,0.98386,0.98957,0.9935,0.98808,0.98299,0.9887,0.99301,0.98793,0.14872,0.19888,0.14064,0.79716,0.0067,0.0067,0.0067
+52,5546.74,0.24902,0.26676,0.19416,0.88038,0.98597,0.98696,0.99361,0.98833,0.9851,0.98609,0.99294,0.98854,0.1473,0.19526,0.13054,0.79453,0.006634,0.006634,0.006634
+53,5648.25,0.25061,0.26463,0.19772,0.87817,0.98249,0.98957,0.99353,0.98846,0.98163,0.9887,0.9931,0.98846,0.14946,0.1953,0.13429,0.79606,0.006568,0.006568,0.006568
+54,5748.43,0.24758,0.26677,0.19111,0.87727,0.98957,0.99015,0.99375,0.98856,0.9887,0.98928,0.99343,0.98851,0.14773,0.19844,0.13145,0.79443,0.006502,0.006502,0.006502
+55,5847.71,0.24924,0.26486,0.19337,0.87963,0.99035,0.98696,0.99349,0.98674,0.98948,0.98609,0.99286,0.98746,0.14658,0.19858,0.13049,0.79657,0.006436,0.006436,0.006436
+56,5948.91,0.24522,0.2614,0.18804,0.8765,0.98634,0.98783,0.99357,0.98774,0.98547,0.98696,0.99312,0.98804,0.14555,0.19767,0.12854,0.79345,0.00637,0.00637,0.00637
+57,6046.81,0.24461,0.25488,0.1877,0.87849,0.99018,0.98522,0.99339,0.98798,0.98931,0.98435,0.99276,0.98708,0.14312,0.19874,0.12753,0.79348,0.006304,0.006304,0.006304
+58,6146.2,0.24441,0.26141,0.18825,0.8783,0.98528,0.98965,0.99346,0.98791,0.98442,0.98878,0.99271,0.98708,0.14057,0.19596,0.12326,0.79345,0.006238,0.006238,0.006238
+59,6246.06,0.23959,0.2483,0.18563,0.87405,0.9876,0.9913,0.99345,0.98837,0.98673,0.99043,0.99292,0.98837,0.13775,0.19224,0.12165,0.79272,0.006172,0.006172,0.006172
+60,6346.47,0.23885,0.25093,0.18315,0.8762,0.99046,0.98783,0.99346,0.98739,0.98959,0.98696,0.99309,0.98757,0.13777,0.19455,0.12347,0.79413,0.006106,0.006106,0.006106
+61,6445.7,0.24102,0.25811,0.18485,0.87531,0.98787,0.99043,0.99375,0.98854,0.987,0.98957,0.99333,0.98913,0.13641,0.19321,0.11934,0.79002,0.00604,0.00604,0.00604
+62,6546.68,0.23896,0.25377,0.1834,0.87567,0.99111,0.9913,0.99379,0.98876,0.99024,0.99043,0.99335,0.98931,0.13539,0.19097,0.11847,0.79166,0.005974,0.005974,0.005974
+63,6646.1,0.23742,0.24918,0.18155,0.87494,0.98927,0.9913,0.99385,0.9888,0.9884,0.99043,0.99369,0.98909,0.13428,0.19132,0.11804,0.79076,0.005908,0.005908,0.005908
+64,6746.41,0.23531,0.24925,0.18051,0.87635,0.99061,0.9887,0.99377,0.98918,0.98974,0.98783,0.99358,0.98915,0.1357,0.19201,0.11777,0.79173,0.005842,0.005842,0.005842
+65,6845.24,0.23575,0.25051,0.17938,0.87435,0.99169,0.98783,0.99377,0.99001,0.99081,0.98696,0.99322,0.98949,0.13505,0.19327,0.11525,0.79065,0.005776,0.005776,0.005776
+66,6945.39,0.23063,0.24356,0.17718,0.87477,0.99355,0.98696,0.99359,0.99022,0.99268,0.98609,0.9932,0.98921,0.13243,0.19537,0.11622,0.7896,0.00571,0.00571,0.00571
+67,7045.89,0.23135,0.24419,0.17955,0.87322,0.99226,0.98522,0.99366,0.99024,0.99138,0.98435,0.9931,0.9895,0.13099,0.19336,0.11721,0.78831,0.005644,0.005644,0.005644
+68,7145.09,0.23057,0.24131,0.17753,0.87449,0.9912,0.9913,0.99393,0.98994,0.99033,0.99043,0.99333,0.98966,0.13016,0.19263,0.11315,0.78685,0.005578,0.005578,0.005578
+69,7241.54,0.23138,0.24037,0.1771,0.87235,0.99295,0.98783,0.99399,0.99037,0.99208,0.98696,0.99352,0.98936,0.12992,0.19553,0.11402,0.78607,0.005512,0.005512,0.005512
+70,7339.34,0.23042,0.24063,0.17737,0.87156,0.99043,0.99001,0.99402,0.99001,0.98956,0.98919,0.99359,0.9897,0.12757,0.195,0.11428,0.78472,0.005446,0.005446,0.005446
+71,7440.52,0.22789,0.24112,0.17268,0.87278,0.99126,0.98668,0.99386,0.98904,0.99039,0.98606,0.99343,0.98935,0.12873,0.19415,0.1132,0.78489,0.00538,0.00538,0.00538
+72,7541.18,0.23064,0.24128,0.17866,0.8756,0.99126,0.98623,0.99373,0.99002,0.99039,0.98587,0.99324,0.98932,0.12882,0.18836,0.11673,0.78488,0.005314,0.005314,0.005314
+73,7642.52,0.22769,0.24242,0.17408,0.87305,0.99304,0.98522,0.99384,0.98968,0.99129,0.98348,0.99337,0.98942,0.12898,0.18826,0.11708,0.78523,0.005248,0.005248,0.005248
+74,7744.03,0.22611,0.24119,0.17246,0.86984,0.99041,0.98782,0.99373,0.9901,0.98752,0.98609,0.99321,0.98912,0.1296,0.18957,0.12095,0.78648,0.005182,0.005182,0.005182
+75,7847.33,0.22393,0.23545,0.17213,0.87062,0.99353,0.98522,0.99384,0.99031,0.98444,0.99,0.9934,0.98962,0.12963,0.18741,0.12031,0.78659,0.005116,0.005116,0.005116
+76,7948.12,0.22531,0.23716,0.17236,0.87239,0.99137,0.98522,0.99372,0.99016,0.98951,0.98387,0.99303,0.98935,0.12738,0.18816,0.11963,0.78498,0.00505,0.00505,0.00505
+77,8048.73,0.22722,0.24195,0.17362,0.87179,0.98965,0.98522,0.99368,0.98937,0.9879,0.98348,0.99303,0.98896,0.12702,0.18462,0.11948,0.7845,0.004984,0.004984,0.004984
+78,8149.22,0.22423,0.23931,0.16946,0.87213,0.98988,0.98522,0.99386,0.98951,0.98813,0.98348,0.99328,0.98925,0.12623,0.18385,0.11818,0.78371,0.004918,0.004918,0.004918
+79,8248.95,0.22342,0.2358,0.17204,0.87211,0.99022,0.98522,0.99378,0.98962,0.98847,0.98348,0.99322,0.98908,0.12468,0.18246,0.1195,0.78236,0.004852,0.004852,0.004852
+80,8349.88,0.22232,0.22808,0.16801,0.87284,0.98959,0.9887,0.99368,0.99002,0.98785,0.98696,0.99308,0.98892,0.1247,0.18315,0.11735,0.78294,0.004786,0.004786,0.004786
+81,8449.66,0.22067,0.23243,0.16748,0.87033,0.99126,0.98631,0.99359,0.9903,0.99039,0.98544,0.99324,0.9894,0.12434,0.17951,0.11361,0.78327,0.00472,0.00472,0.00472
+82,8551.93,0.22243,0.22983,0.16944,0.87181,0.98729,0.9913,0.99381,0.99031,0.98642,0.99043,0.99352,0.98972,0.12484,0.17985,0.11328,0.78381,0.004654,0.004654,0.004654
+83,8648.59,0.22028,0.23233,0.16666,0.8705,0.98923,0.99043,0.99379,0.99063,0.98738,0.98957,0.99348,0.98982,0.12503,0.17971,0.11253,0.7841,0.004588,0.004588,0.004588
+84,8748.67,0.21639,0.22697,0.16399,0.87016,0.98957,0.98962,0.99378,0.99036,0.9887,0.98878,0.9934,0.98954,0.12442,0.18161,0.11082,0.78324,0.004522,0.004522,0.004522
+85,8850.99,0.21939,0.22881,0.16786,0.87219,0.99043,0.99043,0.99379,0.99043,0.98956,0.98957,0.99338,0.98981,0.12324,0.18243,0.11056,0.7824,0.004456,0.004456,0.004456
+86,8950.73,0.21613,0.22691,0.16661,0.8692,0.98833,0.9913,0.99371,0.99018,0.98746,0.99043,0.99327,0.98942,0.12193,0.18335,0.11169,0.78142,0.00439,0.00439,0.00439
+87,9051.13,0.21453,0.2228,0.16246,0.86885,0.98872,0.99096,0.99371,0.99013,0.98785,0.99009,0.99323,0.9893,0.12044,0.18404,0.11258,0.78011,0.004324,0.004324,0.004324
+88,9152.48,0.21682,0.22344,0.16186,0.87082,0.98926,0.98957,0.99365,0.99007,0.98752,0.98783,0.99305,0.9892,0.11985,0.18472,0.11146,0.77982,0.004258,0.004258,0.004258
+89,9255.58,0.21336,0.22346,0.16062,0.86966,0.98867,0.98957,0.99345,0.98968,0.98693,0.98783,0.99281,0.98888,0.12109,0.1848,0.11003,0.78052,0.004192,0.004192,0.004192
+90,9357.27,0.21107,0.22494,0.1601,0.86871,0.98813,0.98957,0.99364,0.99027,0.98639,0.98783,0.99296,0.98896,0.12081,0.18615,0.10934,0.77999,0.004126,0.004126,0.004126
+91,9459.27,0.21223,0.22007,0.16388,0.86684,0.98856,0.99043,0.99386,0.99049,0.98682,0.9887,0.9933,0.98997,0.1189,0.18616,0.10993,0.77835,0.00406,0.00406,0.00406
+92,9561.02,0.21092,0.2237,0.16179,0.8681,0.9897,0.9887,0.99389,0.9904,0.98712,0.9887,0.9934,0.98989,0.11821,0.18479,0.10797,0.77804,0.003994,0.003994,0.003994
+93,9660.85,0.21216,0.22736,0.16144,0.8675,0.99013,0.99043,0.99394,0.99103,0.98835,0.9887,0.99337,0.99023,0.11807,0.18461,0.10653,0.77787,0.003928,0.003928,0.003928
+94,9759.24,0.20852,0.21977,0.15714,0.86504,0.99099,0.99043,0.99397,0.99106,0.99012,0.98957,0.9935,0.99032,0.11778,0.18495,0.10632,0.7777,0.003862,0.003862,0.003862
+95,9857.62,0.20808,0.22114,0.15844,0.8692,0.99099,0.99043,0.9939,0.99046,0.98902,0.9887,0.99332,0.99022,0.11763,0.18441,0.10582,0.77763,0.003796,0.003796,0.003796
+96,9957.91,0.20941,0.22203,0.15866,0.86763,0.99129,0.98975,0.9939,0.99146,0.99042,0.98888,0.99342,0.99029,0.11712,0.18465,0.10474,0.77737,0.00373,0.00373,0.00373
+97,10056.3,0.20591,0.21762,0.15666,0.86606,0.99214,0.98843,0.99391,0.99114,0.99127,0.98756,0.99351,0.99036,0.11673,0.18515,0.1042,0.77721,0.003664,0.003664,0.003664
+98,10155.7,0.20691,0.21885,0.15554,0.86666,0.99128,0.98834,0.99386,0.99055,0.99041,0.98747,0.99348,0.99029,0.1163,0.1856,0.10369,0.77695,0.003598,0.003598,0.003598
+99,10256.9,0.20577,0.22249,0.15425,0.86595,0.99127,0.98765,0.99364,0.99068,0.9904,0.98678,0.99324,0.98948,0.11618,0.18499,0.10421,0.77715,0.003532,0.003532,0.003532
+100,10355.6,0.20311,0.22198,0.15325,0.86532,0.98871,0.98991,0.99384,0.99049,0.98784,0.98904,0.99351,0.9897,0.11577,0.18463,0.10425,0.77677,0.003466,0.003466,0.003466
+101,10454.2,0.20147,0.21825,0.15342,0.86525,0.99128,0.98889,0.99385,0.99052,0.99041,0.98802,0.99349,0.98977,0.11572,0.18382,0.10408,0.77696,0.0034,0.0034,0.0034
+102,10553.8,0.20307,0.21295,0.15367,0.86584,0.99128,0.98868,0.99387,0.99046,0.99041,0.98782,0.99352,0.99026,0.11598,0.18367,0.10393,0.77721,0.003334,0.003334,0.003334
+103,10654.4,0.19875,0.21258,0.15119,0.86495,0.99128,0.98906,0.99389,0.99087,0.99041,0.98819,0.99356,0.98972,0.11595,0.18309,0.1052,0.77713,0.003268,0.003268,0.003268
+104,10754.4,0.20044,0.21075,0.15066,0.86607,0.99088,0.9887,0.99385,0.99076,0.98869,0.98806,0.99337,0.98953,0.11607,0.18257,0.10604,0.77726,0.003202,0.003202,0.003202
+105,10853.6,0.19926,0.21057,0.15057,0.86453,0.99006,0.9887,0.99386,0.99079,0.98918,0.98783,0.99335,0.98946,0.1159,0.18214,0.1055,0.77734,0.003136,0.003136,0.003136
+106,10953.1,0.19816,0.20993,0.14868,0.86661,0.99073,0.9887,0.99382,0.99091,0.98943,0.98783,0.99335,0.98965,0.11551,0.18218,0.10496,0.7771,0.00307,0.00307,0.00307
+107,11054,0.19633,0.20936,0.14867,0.86245,0.99096,0.9887,0.99382,0.99105,0.99009,0.98783,0.99349,0.98964,0.11532,0.18185,0.10473,0.77706,0.003004,0.003004,0.003004
+108,11155.2,0.19543,0.2036,0.14753,0.86271,0.99089,0.9887,0.9938,0.99108,0.99002,0.98783,0.99349,0.98983,0.11502,0.18157,0.10491,0.77704,0.002938,0.002938,0.002938
+109,11254.4,0.19574,0.20854,0.14731,0.86331,0.99117,0.9887,0.9938,0.99111,0.9903,0.98783,0.99349,0.99033,0.11477,0.18158,0.10344,0.77694,0.002872,0.002872,0.002872
+110,11353.2,0.19467,0.20632,0.14752,0.86375,0.99123,0.9887,0.99371,0.99117,0.99035,0.98783,0.99344,0.9904,0.11454,0.18164,0.10356,0.77685,0.002806,0.002806,0.002806
+111,11451.9,0.19519,0.20673,0.14668,0.86527,0.99126,0.9887,0.99373,0.99114,0.99039,0.98783,0.99342,0.99039,0.11439,0.1819,0.10273,0.77671,0.00274,0.00274,0.00274
+112,11551.9,0.19518,0.20664,0.14639,0.86516,0.99138,0.9887,0.99369,0.99116,0.99051,0.98783,0.9934,0.99026,0.11426,0.18205,0.10282,0.77664,0.002674,0.002674,0.002674
+113,11650.2,0.19237,0.20567,0.14408,0.86097,0.9919,0.9887,0.99375,0.99126,0.99102,0.98783,0.99348,0.99029,0.11428,0.1821,0.1023,0.77659,0.002608,0.002608,0.002608
+114,11751.6,0.19364,0.20859,0.14529,0.86164,0.99063,0.9887,0.99379,0.99078,0.98976,0.98783,0.99351,0.99022,0.11414,0.18241,0.10206,0.77656,0.002542,0.002542,0.002542
+115,11851.6,0.19133,0.20368,0.14179,0.86322,0.99041,0.9887,0.9938,0.99073,0.98954,0.98783,0.99353,0.98979,0.11408,0.18219,0.10188,0.77652,0.002476,0.002476,0.002476
+116,11951.7,0.18858,0.20079,0.14123,0.8617,0.99053,0.98783,0.99382,0.99079,0.98966,0.98696,0.99352,0.9898,0.11395,0.18198,0.10164,0.77645,0.00241,0.00241,0.00241
diff --git a/rpi/training/result/edges-nano/results.png b/rpi/training/result/edges-nano/results.png
new file mode 100644
index 00000000..a661705c
Binary files /dev/null and b/rpi/training/result/edges-nano/results.png differ
diff --git a/rpi/training/result/edges-nano/train_batch0.jpg b/rpi/training/result/edges-nano/train_batch0.jpg
new file mode 100644
index 00000000..5ac06efe
Binary files /dev/null and b/rpi/training/result/edges-nano/train_batch0.jpg differ
diff --git a/rpi/training/result/edges-nano/train_batch1.jpg b/rpi/training/result/edges-nano/train_batch1.jpg
new file mode 100644
index 00000000..6e968565
Binary files /dev/null and b/rpi/training/result/edges-nano/train_batch1.jpg differ
diff --git a/rpi/training/result/edges-nano/train_batch2.jpg b/rpi/training/result/edges-nano/train_batch2.jpg
new file mode 100644
index 00000000..982d1945
Binary files /dev/null and b/rpi/training/result/edges-nano/train_batch2.jpg differ
diff --git a/rpi/training/result/edges-nano/val_batch0_labels.jpg b/rpi/training/result/edges-nano/val_batch0_labels.jpg
new file mode 100644
index 00000000..75699ce7
Binary files /dev/null and b/rpi/training/result/edges-nano/val_batch0_labels.jpg differ
diff --git a/rpi/training/result/edges-nano/val_batch0_pred.jpg b/rpi/training/result/edges-nano/val_batch0_pred.jpg
new file mode 100644
index 00000000..6058b1ab
Binary files /dev/null and b/rpi/training/result/edges-nano/val_batch0_pred.jpg differ
diff --git a/rpi/training/result/edges-nano/val_batch1_labels.jpg b/rpi/training/result/edges-nano/val_batch1_labels.jpg
new file mode 100644
index 00000000..b7985d29
Binary files /dev/null and b/rpi/training/result/edges-nano/val_batch1_labels.jpg differ
diff --git a/rpi/training/result/edges-nano/val_batch1_pred.jpg b/rpi/training/result/edges-nano/val_batch1_pred.jpg
new file mode 100644
index 00000000..d6ee6ef4
Binary files /dev/null and b/rpi/training/result/edges-nano/val_batch1_pred.jpg differ
diff --git a/rpi/training/result/edges-nano/val_batch2_labels.jpg b/rpi/training/result/edges-nano/val_batch2_labels.jpg
new file mode 100644
index 00000000..c3abf64a
Binary files /dev/null and b/rpi/training/result/edges-nano/val_batch2_labels.jpg differ
diff --git a/rpi/training/result/edges-nano/val_batch2_pred.jpg b/rpi/training/result/edges-nano/val_batch2_pred.jpg
new file mode 100644
index 00000000..bb289b99
Binary files /dev/null and b/rpi/training/result/edges-nano/val_batch2_pred.jpg differ
diff --git a/rpi/training/result/edges-nano/weights/best.pt b/rpi/training/result/edges-nano/weights/best.pt
new file mode 100644
index 00000000..3a2f0d89
Binary files /dev/null and b/rpi/training/result/edges-nano/weights/best.pt differ
diff --git a/rpi/training/result/edges-nano/weights/epoch0.pt b/rpi/training/result/edges-nano/weights/epoch0.pt
new file mode 100644
index 00000000..62e8f7ac
Binary files /dev/null and b/rpi/training/result/edges-nano/weights/epoch0.pt differ
diff --git a/rpi/training/result/edges-nano/weights/epoch10.pt b/rpi/training/result/edges-nano/weights/epoch10.pt
new file mode 100644
index 00000000..ef3c9b84
Binary files /dev/null and b/rpi/training/result/edges-nano/weights/epoch10.pt differ
diff --git a/rpi/training/result/edges-nano/weights/epoch100.pt b/rpi/training/result/edges-nano/weights/epoch100.pt
new file mode 100644
index 00000000..3a933383
Binary files /dev/null and b/rpi/training/result/edges-nano/weights/epoch100.pt differ
diff --git a/rpi/training/result/edges-nano/weights/epoch110.pt b/rpi/training/result/edges-nano/weights/epoch110.pt
new file mode 100644
index 00000000..90635e20
Binary files /dev/null and b/rpi/training/result/edges-nano/weights/epoch110.pt differ
diff --git a/rpi/training/result/edges-nano/weights/epoch20.pt b/rpi/training/result/edges-nano/weights/epoch20.pt
new file mode 100644
index 00000000..5112e657
Binary files /dev/null and b/rpi/training/result/edges-nano/weights/epoch20.pt differ
diff --git a/rpi/training/result/edges-nano/weights/epoch30.pt b/rpi/training/result/edges-nano/weights/epoch30.pt
new file mode 100644
index 00000000..561d310b
Binary files /dev/null and b/rpi/training/result/edges-nano/weights/epoch30.pt differ
diff --git a/rpi/training/result/edges-nano/weights/epoch40.pt b/rpi/training/result/edges-nano/weights/epoch40.pt
new file mode 100644
index 00000000..f8757bd7
Binary files /dev/null and b/rpi/training/result/edges-nano/weights/epoch40.pt differ
diff --git a/rpi/training/result/edges-nano/weights/epoch50.pt b/rpi/training/result/edges-nano/weights/epoch50.pt
new file mode 100644
index 00000000..a6d865e0
Binary files /dev/null and b/rpi/training/result/edges-nano/weights/epoch50.pt differ
diff --git a/rpi/training/result/edges-nano/weights/epoch60.pt b/rpi/training/result/edges-nano/weights/epoch60.pt
new file mode 100644
index 00000000..255a9db8
Binary files /dev/null and b/rpi/training/result/edges-nano/weights/epoch60.pt differ
diff --git a/rpi/training/result/edges-nano/weights/epoch70.pt b/rpi/training/result/edges-nano/weights/epoch70.pt
new file mode 100644
index 00000000..603668bc
Binary files /dev/null and b/rpi/training/result/edges-nano/weights/epoch70.pt differ
diff --git a/rpi/training/result/edges-nano/weights/epoch80.pt b/rpi/training/result/edges-nano/weights/epoch80.pt
new file mode 100644
index 00000000..6e7b04b4
Binary files /dev/null and b/rpi/training/result/edges-nano/weights/epoch80.pt differ
diff --git a/rpi/training/result/edges-nano/weights/epoch90.pt b/rpi/training/result/edges-nano/weights/epoch90.pt
new file mode 100644
index 00000000..f4ce57e7
Binary files /dev/null and b/rpi/training/result/edges-nano/weights/epoch90.pt differ
diff --git a/rpi/training/result/edges-nano/weights/last.pt b/rpi/training/result/edges-nano/weights/last.pt
new file mode 100644
index 00000000..a23ae547
Binary files /dev/null and b/rpi/training/result/edges-nano/weights/last.pt differ
diff --git a/rpi/training/result/unified-nano-refined/BoxF1_curve.png b/rpi/training/result/unified-nano-refined/BoxF1_curve.png
new file mode 100644
index 00000000..12fe4795
Binary files /dev/null and b/rpi/training/result/unified-nano-refined/BoxF1_curve.png differ
diff --git a/rpi/training/result/unified-nano-refined/BoxPR_curve.png b/rpi/training/result/unified-nano-refined/BoxPR_curve.png
new file mode 100644
index 00000000..7ee2654a
Binary files /dev/null and b/rpi/training/result/unified-nano-refined/BoxPR_curve.png differ
diff --git a/rpi/training/result/unified-nano-refined/BoxP_curve.png b/rpi/training/result/unified-nano-refined/BoxP_curve.png
new file mode 100644
index 00000000..09c998e9
Binary files /dev/null and b/rpi/training/result/unified-nano-refined/BoxP_curve.png differ
diff --git a/rpi/training/result/unified-nano-refined/BoxR_curve.png b/rpi/training/result/unified-nano-refined/BoxR_curve.png
new file mode 100644
index 00000000..a34391bd
Binary files /dev/null and b/rpi/training/result/unified-nano-refined/BoxR_curve.png differ
diff --git a/rpi/training/result/unified-nano-refined/confusion_matrix.png b/rpi/training/result/unified-nano-refined/confusion_matrix.png
new file mode 100644
index 00000000..93ddcc58
Binary files /dev/null and b/rpi/training/result/unified-nano-refined/confusion_matrix.png differ
diff --git a/rpi/training/result/unified-nano-refined/confusion_matrix_normalized.png b/rpi/training/result/unified-nano-refined/confusion_matrix_normalized.png
new file mode 100644
index 00000000..d625ba49
Binary files /dev/null and b/rpi/training/result/unified-nano-refined/confusion_matrix_normalized.png differ
diff --git a/rpi/training/result/unified-nano-refined/results.png b/rpi/training/result/unified-nano-refined/results.png
new file mode 100644
index 00000000..94721029
Binary files /dev/null and b/rpi/training/result/unified-nano-refined/results.png differ
diff --git a/rpi/training/result/unified-nano-refined/train_batch474600.jpg b/rpi/training/result/unified-nano-refined/train_batch474600.jpg
new file mode 100644
index 00000000..c10adc90
Binary files /dev/null and b/rpi/training/result/unified-nano-refined/train_batch474600.jpg differ
diff --git a/rpi/training/result/unified-nano-refined/train_batch474601.jpg b/rpi/training/result/unified-nano-refined/train_batch474601.jpg
new file mode 100644
index 00000000..ad574747
Binary files /dev/null and b/rpi/training/result/unified-nano-refined/train_batch474601.jpg differ
diff --git a/rpi/training/result/unified-nano-refined/train_batch474602.jpg b/rpi/training/result/unified-nano-refined/train_batch474602.jpg
new file mode 100644
index 00000000..0a038b3d
Binary files /dev/null and b/rpi/training/result/unified-nano-refined/train_batch474602.jpg differ
diff --git a/rpi/training/result/unified-nano-refined/val_batch0_labels.jpg b/rpi/training/result/unified-nano-refined/val_batch0_labels.jpg
new file mode 100644
index 00000000..6189e6c6
Binary files /dev/null and b/rpi/training/result/unified-nano-refined/val_batch0_labels.jpg differ
diff --git a/rpi/training/result/unified-nano-refined/val_batch0_pred.jpg b/rpi/training/result/unified-nano-refined/val_batch0_pred.jpg
new file mode 100644
index 00000000..c19b5822
Binary files /dev/null and b/rpi/training/result/unified-nano-refined/val_batch0_pred.jpg differ
diff --git a/rpi/training/result/unified-nano-refined/val_batch1_labels.jpg b/rpi/training/result/unified-nano-refined/val_batch1_labels.jpg
new file mode 100644
index 00000000..47bc30c8
Binary files /dev/null and b/rpi/training/result/unified-nano-refined/val_batch1_labels.jpg differ
diff --git a/rpi/training/result/unified-nano-refined/val_batch1_pred.jpg b/rpi/training/result/unified-nano-refined/val_batch1_pred.jpg
new file mode 100644
index 00000000..a20bd20d
Binary files /dev/null and b/rpi/training/result/unified-nano-refined/val_batch1_pred.jpg differ
diff --git a/rpi/training/result/unified-nano-refined/val_batch2_labels.jpg b/rpi/training/result/unified-nano-refined/val_batch2_labels.jpg
new file mode 100644
index 00000000..85e566fa
Binary files /dev/null and b/rpi/training/result/unified-nano-refined/val_batch2_labels.jpg differ
diff --git a/rpi/training/result/unified-nano-refined/val_batch2_pred.jpg b/rpi/training/result/unified-nano-refined/val_batch2_pred.jpg
new file mode 100644
index 00000000..c1217007
Binary files /dev/null and b/rpi/training/result/unified-nano-refined/val_batch2_pred.jpg differ
diff --git a/rpi/training/result/unified-nano-refined/weights/best.pt b/rpi/training/result/unified-nano-refined/weights/best.pt
new file mode 100644
index 00000000..6fe4bfa0
Binary files /dev/null and b/rpi/training/result/unified-nano-refined/weights/best.pt differ
diff --git a/rpi/training/result/unified-nano-refined/weights/epoch100.pt b/rpi/training/result/unified-nano-refined/weights/epoch100.pt
new file mode 100644
index 00000000..6b9d0960
Binary files /dev/null and b/rpi/training/result/unified-nano-refined/weights/epoch100.pt differ
diff --git a/rpi/training/result/unified-nano-refined/weights/epoch110.pt b/rpi/training/result/unified-nano-refined/weights/epoch110.pt
new file mode 100644
index 00000000..7ba28ff3
Binary files /dev/null and b/rpi/training/result/unified-nano-refined/weights/epoch110.pt differ
diff --git a/rpi/training/result/unified-nano-refined/weights/epoch120.pt b/rpi/training/result/unified-nano-refined/weights/epoch120.pt
new file mode 100644
index 00000000..4437731b
Binary files /dev/null and b/rpi/training/result/unified-nano-refined/weights/epoch120.pt differ
diff --git a/rpi/training/result/unified-nano-refined/weights/epoch130.pt b/rpi/training/result/unified-nano-refined/weights/epoch130.pt
new file mode 100644
index 00000000..e311df96
Binary files /dev/null and b/rpi/training/result/unified-nano-refined/weights/epoch130.pt differ
diff --git a/rpi/training/result/unified-nano-refined/weights/epoch140.pt b/rpi/training/result/unified-nano-refined/weights/epoch140.pt
new file mode 100644
index 00000000..b30f0183
Binary files /dev/null and b/rpi/training/result/unified-nano-refined/weights/epoch140.pt differ
diff --git a/rpi/training/result/unified-nano-refined/weights/last.pt b/rpi/training/result/unified-nano-refined/weights/last.pt
new file mode 100644
index 00000000..cd9a78e2
Binary files /dev/null and b/rpi/training/result/unified-nano-refined/weights/last.pt differ
diff --git a/rpi/training/result/unified-nano/BoxF1_curve.png b/rpi/training/result/unified-nano/BoxF1_curve.png
new file mode 100644
index 00000000..0237d529
Binary files /dev/null and b/rpi/training/result/unified-nano/BoxF1_curve.png differ
diff --git a/rpi/training/result/unified-nano/BoxPR_curve.png b/rpi/training/result/unified-nano/BoxPR_curve.png
new file mode 100644
index 00000000..c19ae1d7
Binary files /dev/null and b/rpi/training/result/unified-nano/BoxPR_curve.png differ
diff --git a/rpi/training/result/unified-nano/BoxP_curve.png b/rpi/training/result/unified-nano/BoxP_curve.png
new file mode 100644
index 00000000..6e2136f0
Binary files /dev/null and b/rpi/training/result/unified-nano/BoxP_curve.png differ
diff --git a/rpi/training/result/unified-nano/BoxR_curve.png b/rpi/training/result/unified-nano/BoxR_curve.png
new file mode 100644
index 00000000..0efc0227
Binary files /dev/null and b/rpi/training/result/unified-nano/BoxR_curve.png differ
diff --git a/rpi/training/result/unified-nano/args.yaml b/rpi/training/result/unified-nano/args.yaml
new file mode 100644
index 00000000..f6249711
--- /dev/null
+++ b/rpi/training/result/unified-nano/args.yaml
@@ -0,0 +1,106 @@
+task: detect
+mode: train
+model: models/yolo11n.pt
+data: ./datasets/unified/data.yaml
+epochs: 200
+time: null
+patience: 30
+batch: 12
+imgsz: 640
+save: true
+save_period: -1
+cache: false
+device: '0'
+workers: 8
+project: result
+name: unified-training
+exist_ok: true
+pretrained: true
+optimizer: auto
+verbose: true
+seed: 0
+deterministic: true
+single_cls: false
+rect: false
+cos_lr: false
+close_mosaic: 10
+resume: false
+amp: true
+fraction: 1.0
+profile: false
+freeze: null
+multi_scale: false
+compile: false
+overlap_mask: true
+mask_ratio: 4
+dropout: 0.0
+val: true
+split: val
+save_json: false
+conf: null
+iou: 0.7
+max_det: 300
+half: false
+dnn: false
+plots: true
+source: null
+vid_stride: 1
+stream_buffer: false
+visualize: false
+augment: false
+agnostic_nms: false
+classes: null
+retina_masks: false
+embed: null
+show: false
+save_frames: false
+save_txt: false
+save_conf: false
+save_crop: false
+show_labels: true
+show_conf: true
+show_boxes: true
+line_width: null
+format: torchscript
+keras: false
+optimize: false
+int8: false
+dynamic: false
+simplify: true
+opset: null
+workspace: null
+nms: false
+lr0: 0.01
+lrf: 0.01
+momentum: 0.937
+weight_decay: 0.0005
+warmup_epochs: 3.0
+warmup_momentum: 0.8
+warmup_bias_lr: 0.1
+box: 7.5
+cls: 0.5
+dfl: 1.5
+pose: 12.0
+kobj: 1.0
+nbs: 64
+hsv_h: 0.015
+hsv_s: 0.7
+hsv_v: 0.4
+degrees: 0.0
+translate: 0.1
+scale: 0.5
+shear: 0.0
+perspective: 0.0
+flipud: 0.0
+fliplr: 0.5
+bgr: 0.0
+mosaic: 1.0
+mixup: 0.0
+cutmix: 0.0
+copy_paste: 0.0
+copy_paste_mode: flip
+auto_augment: randaugment
+erasing: 0.4
+cfg: null
+tracker: botsort.yaml
+save_dir: C:\Users\Laurent\Desktop\board-mate\rpi\training\result\unified-training
diff --git a/rpi/training/result/unified-nano/confusion_matrix.png b/rpi/training/result/unified-nano/confusion_matrix.png
new file mode 100644
index 00000000..f053a749
Binary files /dev/null and b/rpi/training/result/unified-nano/confusion_matrix.png differ
diff --git a/rpi/training/result/unified-nano/confusion_matrix_normalized.png b/rpi/training/result/unified-nano/confusion_matrix_normalized.png
new file mode 100644
index 00000000..67847709
Binary files /dev/null and b/rpi/training/result/unified-nano/confusion_matrix_normalized.png differ
diff --git a/rpi/training/result/unified-nano/labels.jpg b/rpi/training/result/unified-nano/labels.jpg
new file mode 100644
index 00000000..5c87db46
Binary files /dev/null and b/rpi/training/result/unified-nano/labels.jpg differ
diff --git a/rpi/training/result/unified-nano/results.csv b/rpi/training/result/unified-nano/results.csv
new file mode 100644
index 00000000..45f825c4
--- /dev/null
+++ b/rpi/training/result/unified-nano/results.csv
@@ -0,0 +1,201 @@
+epoch,time,train/box_loss,train/cls_loss,train/dfl_loss,metrics/precision(B),metrics/recall(B),metrics/mAP50(B),metrics/mAP50-95(B),val/box_loss,val/cls_loss,val/dfl_loss,lr/pg0,lr/pg1,lr/pg2
+1,387.074,1.54135,2.249,1.22945,0.56834,0.67345,0.59013,0.36616,1.33114,1.37185,1.26692,0.00333233,0.00333233,0.00333233
+2,784.042,1.39816,1.48273,1.16556,0.69801,0.7264,0.73772,0.47791,1.27288,1.11363,1.22931,0.00663267,0.00663267,0.00663267
+3,1165.34,1.37564,1.35535,1.1369,0.74141,0.73593,0.7686,0.5011,1.26132,1.04966,1.20057,0.00990001,0.00990001,0.00990001
+4,1547.23,1.34984,1.26506,1.11352,0.79277,0.77083,0.81105,0.54335,1.22806,0.90764,1.15669,0.0098515,0.0098515,0.0098515
+5,1933.74,1.30709,1.16458,1.08535,0.83504,0.78384,0.84333,0.57119,1.20297,0.81422,1.13262,0.009802,0.009802,0.009802
+6,2314.5,1.2783,1.09528,1.06905,0.84057,0.80746,0.85442,0.58529,1.17929,0.76579,1.12204,0.0097525,0.0097525,0.0097525
+7,2701.44,1.25912,1.05677,1.0595,0.85394,0.81041,0.86402,0.594,1.16945,0.73629,1.11388,0.009703,0.009703,0.009703
+8,3088.63,1.24198,1.02315,1.0497,0.87621,0.8176,0.87362,0.60549,1.15063,0.70447,1.10297,0.0096535,0.0096535,0.0096535
+9,3470.46,1.22953,1.00064,1.04537,0.87753,0.82792,0.87625,0.61221,1.13665,0.67866,1.09384,0.009604,0.009604,0.009604
+10,3851.1,1.21881,0.97735,1.03972,0.88893,0.82854,0.88463,0.61992,1.12885,0.66714,1.08698,0.0095545,0.0095545,0.0095545
+11,4233.49,1.21282,0.96904,1.03596,0.89095,0.83323,0.88558,0.6247,1.11411,0.65207,1.07961,0.009505,0.009505,0.009505
+12,4616.67,1.20187,0.95111,1.03052,0.88547,0.84135,0.88672,0.63328,1.08935,0.63966,1.06848,0.0094555,0.0094555,0.0094555
+13,5000.29,1.19383,0.94615,1.02721,0.89592,0.84269,0.89072,0.63885,1.08179,0.62822,1.06381,0.009406,0.009406,0.009406
+14,5377.32,1.18517,0.93859,1.02283,0.89876,0.84111,0.89159,0.6402,1.07666,0.62622,1.06023,0.0093565,0.0093565,0.0093565
+15,5750.2,1.17877,0.92156,1.01921,0.90101,0.84185,0.89203,0.64277,1.07085,0.61489,1.05477,0.009307,0.009307,0.009307
+16,6127.21,1.17622,0.91773,1.01664,0.90304,0.84476,0.89433,0.64575,1.06439,0.60887,1.05182,0.0092575,0.0092575,0.0092575
+17,6504.99,1.16711,0.90912,1.01357,0.9012,0.84905,0.89537,0.64806,1.05778,0.60524,1.04919,0.009208,0.009208,0.009208
+18,6900.64,1.16465,0.90184,1.01353,0.90181,0.85085,0.89579,0.64951,1.053,0.59944,1.04613,0.0091585,0.0091585,0.0091585
+19,7301.08,1.15978,0.8963,1.01033,0.90537,0.85051,0.89671,0.65143,1.04909,0.59652,1.04367,0.009109,0.009109,0.009109
+20,7708.07,1.1554,0.8919,1.00774,0.90847,0.84966,0.89751,0.65208,1.0471,0.59352,1.04185,0.0090595,0.0090595,0.0090595
+21,8115.23,1.15368,0.88704,1.00851,0.90991,0.84988,0.89801,0.65341,1.04493,0.59069,1.04107,0.00901,0.00901,0.00901
+22,8525.53,1.14982,0.88713,1.00604,0.91219,0.84936,0.89859,0.65432,1.04312,0.58909,1.04013,0.0089605,0.0089605,0.0089605
+23,8936.32,1.14372,0.87668,1.0034,0.91337,0.84911,0.89921,0.6554,1.04104,0.58682,1.03915,0.008911,0.008911,0.008911
+24,9342.14,1.14249,0.87387,1.00257,0.91423,0.84981,0.89973,0.65613,1.03913,0.58478,1.03817,0.0088615,0.0088615,0.0088615
+25,9746.49,1.13734,0.87047,1.00072,0.91366,0.85107,0.90009,0.65671,1.03762,0.58281,1.03719,0.008812,0.008812,0.008812
+26,10137.1,1.13697,0.8669,1.00021,0.91379,0.85191,0.90036,0.65729,1.03598,0.58113,1.03629,0.0087625,0.0087625,0.0087625
+27,10619.2,1.13603,0.86501,0.99951,0.91506,0.85187,0.90063,0.65806,1.03462,0.57935,1.03555,0.008713,0.008713,0.008713
+28,11165.9,1.1351,0.86129,0.9988,0.915,0.85292,0.90094,0.65866,1.03352,0.57796,1.03481,0.0086635,0.0086635,0.0086635
+29,11663.5,1.12921,0.85704,0.99725,0.91483,0.85357,0.90123,0.65923,1.03238,0.57688,1.03423,0.008614,0.008614,0.008614
+30,12034.2,1.12876,0.85636,0.99732,0.91792,0.85217,0.90147,0.65976,1.03119,0.57544,1.03344,0.0085645,0.0085645,0.0085645
+31,12401.5,1.12578,0.85306,0.99566,0.91902,0.85182,0.90179,0.66029,1.03,0.57439,1.03272,0.008515,0.008515,0.008515
+32,12770.2,1.12534,0.84938,0.99476,0.91993,0.85148,0.90216,0.66108,1.02879,0.57293,1.03195,0.0084655,0.0084655,0.0084655
+33,13148.2,1.12078,0.84847,0.99323,0.92082,0.85197,0.90252,0.66174,1.02762,0.57172,1.03132,0.008416,0.008416,0.008416
+34,13531,1.12241,0.84556,0.99309,0.9202,0.85336,0.90267,0.66231,1.02651,0.57023,1.03066,0.0083665,0.0083665,0.0083665
+35,13900.1,1.11806,0.8405,0.9924,0.92225,0.85241,0.90286,0.6628,1.02579,0.56958,1.03022,0.008317,0.008317,0.008317
+36,14268.1,1.11719,0.84149,0.99192,0.92165,0.85306,0.90311,0.66329,1.02455,0.56832,1.02958,0.0082675,0.0082675,0.0082675
+37,14649.3,1.11641,0.84061,0.99077,0.92157,0.85379,0.90341,0.66373,1.02339,0.56689,1.02896,0.008218,0.008218,0.008218
+38,15022.9,1.11421,0.83634,0.99017,0.92124,0.85473,0.90352,0.6642,1.02211,0.56533,1.02831,0.0081685,0.0081685,0.0081685
+39,15403.7,1.11692,0.83423,0.99093,0.92288,0.85375,0.90376,0.66459,1.02113,0.56424,1.02762,0.008119,0.008119,0.008119
+40,15784.3,1.11144,0.83242,0.98912,0.92354,0.85361,0.90384,0.66512,1.02015,0.56286,1.02695,0.0080695,0.0080695,0.0080695
+41,16167.1,1.1094,0.83134,0.98814,0.92376,0.85416,0.90401,0.66557,1.01906,0.5619,1.0262,0.00802,0.00802,0.00802
+42,16551.5,1.11004,0.82936,0.98819,0.92484,0.85449,0.90407,0.66588,1.01816,0.5608,1.02553,0.0079705,0.0079705,0.0079705
+43,16919,1.10806,0.82789,0.98839,0.92504,0.8547,0.90426,0.66648,1.01706,0.56019,1.02472,0.007921,0.007921,0.007921
+44,17278.5,1.10426,0.82016,0.986,0.92566,0.85479,0.9045,0.667,1.0161,0.55929,1.02399,0.0078715,0.0078715,0.0078715
+45,17654.3,1.1051,0.82223,0.98627,0.92601,0.85531,0.90462,0.66742,1.01534,0.55826,1.02342,0.007822,0.007822,0.007822
+46,18048.6,1.10531,0.82358,0.98665,0.92804,0.85436,0.90478,0.66786,1.01463,0.5573,1.02289,0.0077725,0.0077725,0.0077725
+47,18413.5,1.10193,0.81829,0.98553,0.9289,0.85387,0.90495,0.66833,1.01396,0.55655,1.02217,0.007723,0.007723,0.007723
+48,18852.5,1.10089,0.81843,0.98506,0.92946,0.85439,0.90515,0.66882,1.01297,0.5554,1.02152,0.0076735,0.0076735,0.0076735
+49,19243.8,1.09929,0.81562,0.98555,0.92996,0.85446,0.90529,0.66914,1.01223,0.55424,1.02099,0.007624,0.007624,0.007624
+50,19634.3,1.10232,0.81414,0.98493,0.93078,0.85468,0.90547,0.66968,1.01157,0.55366,1.02026,0.0075745,0.0075745,0.0075745
+51,20024.6,1.09908,0.81642,0.98522,0.93252,0.85413,0.90549,0.66988,1.01088,0.55252,1.01964,0.007525,0.007525,0.007525
+52,20413.3,1.09525,0.81007,0.98347,0.93383,0.85417,0.90575,0.67019,1.00985,0.5513,1.01883,0.0074755,0.0074755,0.0074755
+53,20891.1,1.09673,0.80907,0.98288,0.93345,0.85467,0.90579,0.67057,1.0089,0.55045,1.01806,0.007426,0.007426,0.007426
+54,21376.7,1.09572,0.80743,0.9829,0.93392,0.85486,0.90591,0.671,1.00825,0.54973,1.0174,0.0073765,0.0073765,0.0073765
+55,21769.9,1.09209,0.80945,0.98239,0.93451,0.85532,0.906,0.67148,1.00755,0.54884,1.01663,0.007327,0.007327,0.007327
+56,22159.7,1.09288,0.80433,0.98168,0.93495,0.8558,0.90618,0.67198,1.00648,0.54699,1.01585,0.0072775,0.0072775,0.0072775
+57,22556,1.09303,0.80478,0.98257,0.93485,0.85637,0.90623,0.67231,1.00585,0.54553,1.01528,0.007228,0.007228,0.007228
+58,22943.6,1.09143,0.80066,0.98133,0.93582,0.85645,0.90633,0.67271,1.00496,0.54469,1.01477,0.0071785,0.0071785,0.0071785
+59,23329.9,1.09125,0.80418,0.98185,0.93659,0.85655,0.90654,0.67294,1.00413,0.54303,1.01407,0.007129,0.007129,0.007129
+60,23719.3,1.08502,0.79668,0.97872,0.93713,0.85638,0.90674,0.67338,1.00347,0.5421,1.01351,0.0070795,0.0070795,0.0070795
+61,24122.6,1.08508,0.79801,0.97758,0.93795,0.85629,0.90687,0.67378,1.00281,0.54097,1.01284,0.00703,0.00703,0.00703
+62,24523.5,1.08701,0.79921,0.97986,0.93791,0.85639,0.90698,0.67408,1.00206,0.54003,1.0122,0.0069805,0.0069805,0.0069805
+63,24919.2,1.08329,0.79662,0.97884,0.93876,0.85636,0.90704,0.67445,1.00115,0.53914,1.01165,0.006931,0.006931,0.006931
+64,25320.7,1.08157,0.79609,0.97877,0.93913,0.85664,0.9073,0.67481,1.00034,0.53834,1.01089,0.0068815,0.0068815,0.0068815
+65,25715.8,1.08358,0.79559,0.97847,0.93969,0.85685,0.90752,0.67526,0.99967,0.53721,1.01014,0.006832,0.006832,0.006832
+66,26151.5,1.08562,0.79828,0.97917,0.94055,0.85687,0.90764,0.67539,0.99894,0.53619,1.00964,0.0067825,0.0067825,0.0067825
+67,26530.7,1.08082,0.79387,0.97911,0.94115,0.8566,0.90777,0.67588,0.99831,0.53515,1.0092,0.006733,0.006733,0.006733
+68,26954.8,1.07998,0.79368,0.9787,0.94073,0.85735,0.90779,0.67618,0.99785,0.53446,1.00887,0.0066835,0.0066835,0.0066835
+69,27474,1.07717,0.78887,0.97679,0.94061,0.8583,0.90793,0.67661,0.99721,0.53361,1.00811,0.006634,0.006634,0.006634
+70,27843.9,1.07878,0.78739,0.97595,0.94142,0.8582,0.90799,0.67696,0.99638,0.53268,1.0075,0.0065845,0.0065845,0.0065845
+71,28208.7,1.08077,0.78718,0.97676,0.94091,0.85907,0.90808,0.67734,0.99552,0.53173,1.00691,0.006535,0.006535,0.006535
+72,28573.4,1.0796,0.78524,0.97743,0.9414,0.85971,0.90808,0.6776,0.99477,0.53098,1.00623,0.0064855,0.0064855,0.0064855
+73,28937.5,1.07668,0.78862,0.97504,0.94228,0.85976,0.90818,0.67798,0.99401,0.52984,1.00547,0.006436,0.006436,0.006436
+74,29294.9,1.07441,0.78503,0.97549,0.94273,0.86024,0.90831,0.67848,0.99319,0.52887,1.00482,0.0063865,0.0063865,0.0063865
+75,29656.4,1.07226,0.78286,0.97437,0.94292,0.86033,0.9084,0.67868,0.99265,0.52796,1.00417,0.006337,0.006337,0.006337
+76,30088.2,1.07542,0.78448,0.97552,0.94334,0.86042,0.9085,0.67913,0.99208,0.527,1.00367,0.0062875,0.0062875,0.0062875
+77,30504.6,1.07317,0.78009,0.97482,0.94321,0.86082,0.9086,0.67933,0.99155,0.52625,1.00324,0.006238,0.006238,0.006238
+78,30864.9,1.07024,0.78015,0.97357,0.94341,0.86119,0.90873,0.67984,0.99104,0.5257,1.00269,0.0061885,0.0061885,0.0061885
+79,31231.8,1.07257,0.77927,0.97414,0.94309,0.86146,0.90883,0.68026,0.99048,0.52506,1.00188,0.006139,0.006139,0.006139
+80,31595.9,1.07031,0.77456,0.97213,0.9434,0.86169,0.9089,0.6805,0.99009,0.52431,1.00134,0.0060895,0.0060895,0.0060895
+81,31960.3,1.06834,0.77738,0.97308,0.94321,0.86217,0.90899,0.68088,0.98943,0.52383,1.00083,0.00604,0.00604,0.00604
+82,32335.4,1.07021,0.77843,0.97348,0.94329,0.86268,0.90921,0.68117,0.98885,0.52311,1.00019,0.0059905,0.0059905,0.0059905
+83,32731.2,1.06682,0.77537,0.97269,0.94293,0.86304,0.90928,0.68147,0.9883,0.5225,0.99974,0.005941,0.005941,0.005941
+84,33117.1,1.06572,0.77023,0.97148,0.94272,0.86383,0.90934,0.68166,0.98781,0.52186,0.9991,0.0058915,0.0058915,0.0058915
+85,33498.3,1.06636,0.77628,0.97252,0.94263,0.86448,0.90955,0.68199,0.98746,0.52114,0.99875,0.005842,0.005842,0.005842
+86,33880.3,1.06399,0.76926,0.97116,0.94255,0.86434,0.90963,0.6822,0.98685,0.52028,0.9982,0.0057925,0.0057925,0.0057925
+87,34264.4,1.06566,0.77226,0.97192,0.94267,0.8648,0.90979,0.68247,0.98667,0.51953,0.99802,0.005743,0.005743,0.005743
+88,34648.2,1.06342,0.7702,0.96955,0.94222,0.86544,0.90979,0.68275,0.98641,0.51925,0.9976,0.0056935,0.0056935,0.0056935
+89,35030.9,1.06352,0.76647,0.971,0.9428,0.86513,0.90974,0.68293,0.98604,0.51854,0.9972,0.005644,0.005644,0.005644
+90,35412,1.06335,0.76641,0.97104,0.94242,0.86585,0.90975,0.68328,0.98562,0.51821,0.99682,0.0055945,0.0055945,0.0055945
+91,35793.8,1.06078,0.76719,0.97053,0.94205,0.8663,0.90985,0.68362,0.98475,0.51743,0.99608,0.005545,0.005545,0.005545
+92,36175.3,1.06008,0.76809,0.96953,0.94225,0.86649,0.90998,0.68389,0.98441,0.51652,0.99566,0.0054955,0.0054955,0.0054955
+93,36556.7,1.06228,0.76678,0.97099,0.94318,0.86605,0.9101,0.68408,0.98418,0.51615,0.99534,0.005446,0.005446,0.005446
+94,36941.6,1.0563,0.75804,0.96813,0.94374,0.86549,0.9102,0.68447,0.9834,0.51529,0.9949,0.0053965,0.0053965,0.0053965
+95,37323.8,1.05683,0.76068,0.96909,0.94376,0.86554,0.91031,0.6847,0.9829,0.5148,0.99438,0.005347,0.005347,0.005347
+96,37708.4,1.05559,0.75825,0.96841,0.9438,0.86586,0.91029,0.68484,0.98253,0.51415,0.99403,0.0052975,0.0052975,0.0052975
+97,38093.9,1.0567,0.76148,0.96849,0.94411,0.86609,0.9104,0.68506,0.98223,0.51394,0.99379,0.005248,0.005248,0.005248
+98,38480.1,1.05594,0.75677,0.96858,0.94438,0.86618,0.91048,0.68525,0.98192,0.51366,0.99341,0.0051985,0.0051985,0.0051985
+99,38863.5,1.05323,0.75696,0.96789,0.94451,0.86613,0.91056,0.6855,0.98144,0.51322,0.99288,0.005149,0.005149,0.005149
+100,39419.8,1.05298,0.75681,0.96702,0.94499,0.86593,0.91062,0.68567,0.98111,0.51323,0.99242,0.0050995,0.0050995,0.0050995
+101,39803.4,1.05262,0.75809,0.96782,0.94514,0.8658,0.9108,0.68577,0.98069,0.51288,0.99207,0.00505,0.00505,0.00505
+102,40186.8,1.05373,0.7568,0.96737,0.94441,0.86664,0.91082,0.68602,0.98024,0.51211,0.99166,0.0050005,0.0050005,0.0050005
+103,40573.2,1.05226,0.75694,0.9674,0.94422,0.86714,0.91089,0.68621,0.97982,0.51155,0.99124,0.004951,0.004951,0.004951
+104,40993.3,1.0533,0.75373,0.96739,0.94435,0.86718,0.911,0.68647,0.97952,0.51093,0.99093,0.0049015,0.0049015,0.0049015
+105,41570.4,1.04765,0.7531,0.96593,0.9458,0.86623,0.91096,0.68664,0.97898,0.5105,0.99062,0.004852,0.004852,0.004852
+106,42092.9,1.0505,0.75415,0.96654,0.9456,0.86673,0.9111,0.68687,0.97853,0.51009,0.99033,0.0048025,0.0048025,0.0048025
+107,42482,1.04624,0.7511,0.96535,0.94511,0.86702,0.9111,0.68694,0.97837,0.50984,0.98997,0.004753,0.004753,0.004753
+108,42871.3,1.04777,0.75029,0.96513,0.94542,0.8668,0.91109,0.68711,0.97816,0.50961,0.98965,0.0047035,0.0047035,0.0047035
+109,43264.7,1.04749,0.7482,0.96464,0.94601,0.86616,0.91108,0.68738,0.97797,0.50946,0.98922,0.004654,0.004654,0.004654
+110,43641.7,1.04497,0.74572,0.96514,0.94553,0.86644,0.91116,0.68756,0.97736,0.50915,0.98876,0.0046045,0.0046045,0.0046045
+111,44023.5,1.04476,0.74684,0.96389,0.94559,0.86664,0.91127,0.6877,0.9769,0.50889,0.98841,0.004555,0.004555,0.004555
+112,44410.8,1.04327,0.74367,0.9634,0.94582,0.86679,0.91128,0.68774,0.97653,0.5085,0.98797,0.0045055,0.0045055,0.0045055
+113,44796.8,1.04223,0.74269,0.9638,0.94565,0.86721,0.91136,0.68793,0.97644,0.50813,0.98765,0.004456,0.004456,0.004456
+114,45182.7,1.03992,0.74263,0.96327,0.94551,0.86738,0.9115,0.68827,0.97612,0.50767,0.98733,0.0044065,0.0044065,0.0044065
+115,45572.1,1.04063,0.73976,0.9636,0.94584,0.86761,0.91159,0.68842,0.97542,0.5073,0.98702,0.004357,0.004357,0.004357
+116,45961.3,1.04146,0.74198,0.96347,0.94648,0.86786,0.91173,0.68857,0.97506,0.50679,0.98677,0.0043075,0.0043075,0.0043075
+117,46367.8,1.03854,0.7381,0.96205,0.94662,0.86767,0.91179,0.68875,0.97476,0.50645,0.98652,0.004258,0.004258,0.004258
+118,46755.2,1.04016,0.73999,0.96308,0.94677,0.86765,0.9118,0.68879,0.97438,0.50631,0.98627,0.0042085,0.0042085,0.0042085
+119,47144.5,1.03722,0.7363,0.96312,0.94639,0.86757,0.91165,0.68889,0.97408,0.50604,0.98607,0.004159,0.004159,0.004159
+120,47532.7,1.03819,0.73661,0.9629,0.94581,0.86792,0.91172,0.68909,0.97389,0.50577,0.986,0.0041095,0.0041095,0.0041095
+121,47919.7,1.03418,0.73689,0.96115,0.94734,0.8671,0.91187,0.68934,0.97353,0.50564,0.9857,0.00406,0.00406,0.00406
+122,48304.1,1.03435,0.7325,0.96066,0.94655,0.86779,0.91201,0.68955,0.97332,0.50536,0.9854,0.0040105,0.0040105,0.0040105
+123,48672.2,1.0339,0.73304,0.96,0.94747,0.86731,0.91212,0.68974,0.97296,0.50501,0.98512,0.003961,0.003961,0.003961
+124,49040.4,1.03223,0.72921,0.95974,0.9468,0.86772,0.91217,0.69004,0.97274,0.50459,0.98486,0.0039115,0.0039115,0.0039115
+125,49408.2,1.0341,0.73242,0.96,0.9467,0.86837,0.9122,0.69015,0.97266,0.50416,0.9847,0.003862,0.003862,0.003862
+126,49784.7,1.03182,0.73039,0.95989,0.94707,0.86807,0.91226,0.69035,0.97233,0.50381,0.98441,0.0038125,0.0038125,0.0038125
+127,50234.1,1.03057,0.72791,0.95967,0.94691,0.86849,0.91234,0.69054,0.9719,0.50329,0.98418,0.003763,0.003763,0.003763
+128,50649.4,1.02891,0.72826,0.95874,0.94592,0.86925,0.91235,0.69088,0.97141,0.50282,0.98396,0.0037135,0.0037135,0.0037135
+129,51027.9,1.03088,0.72985,0.95897,0.94654,0.86912,0.91243,0.69099,0.97113,0.5026,0.98374,0.003664,0.003664,0.003664
+130,51397.8,1.02951,0.72674,0.95881,0.94675,0.86896,0.91243,0.69106,0.9709,0.50257,0.98345,0.0036145,0.0036145,0.0036145
+131,51769.2,1.0275,0.72663,0.95826,0.94683,0.8689,0.91238,0.69127,0.9702,0.50223,0.98286,0.003565,0.003565,0.003565
+132,52159.1,1.02612,0.72065,0.9574,0.94698,0.86869,0.91245,0.69148,0.96971,0.50191,0.98259,0.0035155,0.0035155,0.0035155
+133,52566.8,1.02638,0.72293,0.958,0.94738,0.86866,0.91246,0.69164,0.9694,0.50132,0.98231,0.003466,0.003466,0.003466
+134,52940,1.02518,0.72275,0.95777,0.94724,0.86887,0.91255,0.69174,0.96918,0.5011,0.9821,0.0034165,0.0034165,0.0034165
+135,53309,1.02277,0.71909,0.95747,0.9477,0.86876,0.91259,0.69183,0.96874,0.50094,0.98173,0.003367,0.003367,0.003367
+136,53677.7,1.0265,0.726,0.95847,0.94733,0.86951,0.91258,0.69191,0.96849,0.50084,0.9816,0.0033175,0.0033175,0.0033175
+137,54048.3,1.01992,0.71742,0.95651,0.94658,0.87051,0.91263,0.69207,0.9682,0.50056,0.98136,0.003268,0.003268,0.003268
+138,54417.7,1.01813,0.71421,0.9561,0.94651,0.87054,0.91252,0.69234,0.96757,0.50004,0.98097,0.0032185,0.0032185,0.0032185
+139,54789.1,1.01993,0.71707,0.9554,0.94577,0.87117,0.91258,0.69249,0.96709,0.49981,0.98057,0.003169,0.003169,0.003169
+140,55157.4,1.01611,0.71153,0.95583,0.94538,0.87172,0.91253,0.69264,0.96689,0.49925,0.98048,0.0031195,0.0031195,0.0031195
+141,55527.2,1.01735,0.71457,0.95532,0.94599,0.87157,0.91266,0.69278,0.9665,0.499,0.98025,0.00307,0.00307,0.00307
+142,55900.5,1.01572,0.71535,0.95457,0.94618,0.87157,0.9127,0.69271,0.96639,0.49914,0.98015,0.0030205,0.0030205,0.0030205
+143,56271.1,1.01253,0.71174,0.95415,0.94691,0.87101,0.91276,0.69297,0.96605,0.49918,0.9799,0.002971,0.002971,0.002971
+144,56673.8,1.01214,0.70952,0.95423,0.94712,0.871,0.91287,0.69322,0.96569,0.49904,0.97963,0.0029215,0.0029215,0.0029215
+145,57036.1,1.01236,0.70785,0.95411,0.94682,0.87088,0.91297,0.69342,0.96511,0.49852,0.97947,0.002872,0.002872,0.002872
+146,57393.7,1.0129,0.70737,0.95355,0.94652,0.87079,0.91305,0.6935,0.9646,0.49829,0.97914,0.0028225,0.0028225,0.0028225
+147,57752.4,1.01156,0.70568,0.95257,0.94687,0.87082,0.9132,0.69355,0.96434,0.49794,0.97893,0.002773,0.002773,0.002773
+148,58116.3,1.01122,0.70574,0.95359,0.94601,0.8714,0.91316,0.69351,0.96416,0.49761,0.97861,0.0027235,0.0027235,0.0027235
+149,58477.4,1.00715,0.70317,0.9519,0.94599,0.87152,0.91314,0.69386,0.96371,0.49725,0.97837,0.002674,0.002674,0.002674
+150,58851.4,1.00911,0.70364,0.95277,0.94624,0.87107,0.91326,0.69405,0.96342,0.49696,0.97833,0.0026245,0.0026245,0.0026245
+151,59233.5,1.00966,0.7035,0.95239,0.94734,0.87024,0.91323,0.69426,0.9632,0.49677,0.97811,0.002575,0.002575,0.002575
+152,59617.7,1.00583,0.7016,0.95094,0.94707,0.8706,0.91333,0.6944,0.96302,0.49613,0.978,0.0025255,0.0025255,0.0025255
+153,60001.7,1.0066,0.70014,0.95076,0.94793,0.87018,0.91344,0.69468,0.96262,0.49585,0.97785,0.002476,0.002476,0.002476
+154,60383.8,1.00302,0.69818,0.95088,0.94894,0.86952,0.91347,0.69495,0.96221,0.49542,0.97775,0.0024265,0.0024265,0.0024265
+155,60768.1,1.00319,0.69821,0.95181,0.94955,0.86941,0.91353,0.69524,0.96166,0.49512,0.97757,0.002377,0.002377,0.002377
+156,61151.6,1.00393,0.69416,0.95128,0.94965,0.86944,0.91362,0.69542,0.96132,0.49494,0.97744,0.0023275,0.0023275,0.0023275
+157,61534.3,1.00205,0.69411,0.95015,0.94931,0.86957,0.91369,0.6956,0.96113,0.49461,0.97723,0.002278,0.002278,0.002278
+158,61917.3,1.00122,0.69456,0.94907,0.94935,0.86974,0.91391,0.69583,0.96098,0.49417,0.97696,0.0022285,0.0022285,0.0022285
+159,62300,0.99761,0.68917,0.94806,0.94863,0.87064,0.91388,0.69614,0.96087,0.49421,0.97677,0.002179,0.002179,0.002179
+160,62682.6,0.9975,0.69104,0.94908,0.9486,0.87101,0.91401,0.69647,0.9605,0.49382,0.97646,0.0021295,0.0021295,0.0021295
+161,63066.3,0.99514,0.68634,0.94828,0.94991,0.87017,0.91421,0.69675,0.96021,0.49363,0.97609,0.00208,0.00208,0.00208
+162,63449,0.99532,0.68594,0.94801,0.95085,0.86976,0.91428,0.69705,0.95992,0.49321,0.97593,0.0020305,0.0020305,0.0020305
+163,63832.1,0.9932,0.68492,0.94767,0.95003,0.87022,0.91427,0.69725,0.95974,0.4933,0.97587,0.001981,0.001981,0.001981
+164,64215.9,0.99204,0.68295,0.94682,0.95026,0.87019,0.91432,0.69749,0.95946,0.493,0.97565,0.0019315,0.0019315,0.0019315
+165,64599.3,0.99298,0.68411,0.94683,0.95042,0.87036,0.91441,0.69751,0.95941,0.49299,0.97566,0.001882,0.001882,0.001882
+166,64983,0.99121,0.68264,0.94703,0.95021,0.87066,0.91449,0.69766,0.95931,0.49266,0.9756,0.0018325,0.0018325,0.0018325
+167,65366.6,0.98831,0.67835,0.94581,0.95039,0.87043,0.91439,0.69787,0.95912,0.49235,0.97551,0.001783,0.001783,0.001783
+168,65749.9,0.98778,0.6779,0.94405,0.95019,0.87102,0.91456,0.69826,0.95861,0.49215,0.9752,0.0017335,0.0017335,0.0017335
+169,66133.7,0.98531,0.67835,0.94452,0.94997,0.87149,0.91468,0.69853,0.95818,0.49189,0.97504,0.001684,0.001684,0.001684
+170,66516.4,0.98374,0.67366,0.9438,0.94993,0.87118,0.91461,0.69862,0.95775,0.49172,0.97486,0.0016345,0.0016345,0.0016345
+171,66899.7,0.98467,0.67251,0.94443,0.95069,0.87118,0.91469,0.69884,0.95726,0.4913,0.97452,0.001585,0.001585,0.001585
+172,67283.3,0.98189,0.67053,0.94353,0.95017,0.8716,0.91477,0.699,0.9568,0.49099,0.97421,0.0015355,0.0015355,0.0015355
+173,67665.9,0.98138,0.67013,0.94359,0.95033,0.87144,0.91482,0.69907,0.95633,0.49076,0.97395,0.001486,0.001486,0.001486
+174,68048.4,0.97824,0.66907,0.94297,0.95179,0.87027,0.91497,0.69933,0.95608,0.49047,0.97373,0.0014365,0.0014365,0.0014365
+175,68430.2,0.9795,0.66876,0.94197,0.95165,0.87007,0.91501,0.69942,0.95582,0.49015,0.9735,0.001387,0.001387,0.001387
+176,68813.6,0.9791,0.66849,0.94268,0.95115,0.87066,0.91506,0.69957,0.95556,0.48963,0.97319,0.0013375,0.0013375,0.0013375
+177,69198.8,0.97586,0.66709,0.94169,0.95203,0.86986,0.91512,0.69982,0.95525,0.48935,0.97291,0.001288,0.001288,0.001288
+178,69581.9,0.97729,0.66396,0.94241,0.9529,0.86954,0.91514,0.69988,0.95481,0.48891,0.97263,0.0012385,0.0012385,0.0012385
+179,69965.8,0.97436,0.66223,0.94111,0.95211,0.87052,0.91517,0.70014,0.95441,0.48864,0.9724,0.001189,0.001189,0.001189
+180,70348.4,0.96962,0.65873,0.93972,0.9514,0.87101,0.91513,0.70028,0.95419,0.48846,0.97225,0.0011395,0.0011395,0.0011395
+181,70731.5,0.96976,0.6588,0.93919,0.9512,0.87119,0.91511,0.70045,0.95417,0.48838,0.97214,0.00109,0.00109,0.00109
+182,71111.7,0.97061,0.65657,0.93963,0.95023,0.8722,0.91511,0.70065,0.95408,0.48825,0.97199,0.0010405,0.0010405,0.0010405
+183,71494.7,0.96786,0.65543,0.93881,0.94983,0.8725,0.91519,0.70085,0.95378,0.48819,0.97176,0.000991,0.000991,0.000991
+184,71875.9,0.96796,0.65486,0.93848,0.94876,0.87336,0.9152,0.70106,0.95329,0.48771,0.9714,0.0009415,0.0009415,0.0009415
+185,72258.8,0.96234,0.6496,0.93799,0.94852,0.87366,0.91532,0.70131,0.95286,0.48769,0.97125,0.000892,0.000892,0.000892
+186,72641.7,0.96355,0.65094,0.93773,0.94882,0.8736,0.9154,0.70145,0.95239,0.48736,0.97107,0.0008425,0.0008425,0.0008425
+187,73026.1,0.96211,0.649,0.93795,0.94783,0.87434,0.91535,0.70163,0.9519,0.48708,0.97087,0.000793,0.000793,0.000793
+188,73410.8,0.95788,0.64545,0.93539,0.94728,0.87489,0.91556,0.70194,0.95165,0.48676,0.97062,0.0007435,0.0007435,0.0007435
+189,73793.8,0.95877,0.64364,0.93566,0.94848,0.87409,0.9156,0.70218,0.95121,0.48634,0.97037,0.000694,0.000694,0.000694
+190,74176.3,0.9566,0.64378,0.93535,0.94796,0.87436,0.91559,0.70226,0.95103,0.48615,0.97016,0.0006445,0.0006445,0.0006445
+191,74567.9,0.93471,0.57105,0.94238,0.94826,0.87429,0.9157,0.70241,0.95054,0.48575,0.97006,0.000595,0.000595,0.000595
+192,74931.5,0.92816,0.56319,0.94049,0.94775,0.87494,0.91563,0.70251,0.95002,0.48541,0.96982,0.0005455,0.0005455,0.0005455
+193,75296.4,0.92645,0.56294,0.9394,0.94844,0.87434,0.91559,0.70271,0.9495,0.48516,0.96951,0.000496,0.000496,0.000496
+194,75660,0.92161,0.55914,0.93869,0.94778,0.8751,0.91556,0.70278,0.94891,0.48478,0.96933,0.0004465,0.0004465,0.0004465
+195,76025.3,0.91896,0.55666,0.93753,0.94826,0.87491,0.91554,0.70294,0.94845,0.48437,0.96904,0.000397,0.000397,0.000397
+196,76390.9,0.91657,0.55375,0.93573,0.94803,0.87506,0.91552,0.70318,0.94795,0.48442,0.96898,0.0003475,0.0003475,0.0003475
+197,76755.6,0.91365,0.54916,0.935,0.94771,0.87532,0.91542,0.70333,0.94716,0.48416,0.96863,0.000298,0.000298,0.000298
+198,77120,0.91124,0.54938,0.93358,0.94776,0.87553,0.91532,0.70364,0.9465,0.48394,0.96837,0.0002485,0.0002485,0.0002485
+199,77484.6,0.9098,0.54725,0.93255,0.94777,0.87521,0.9152,0.7037,0.94576,0.48354,0.96799,0.000199,0.000199,0.000199
+200,77848.7,0.9061,0.5449,0.93212,0.94734,0.8757,0.91516,0.70377,0.94538,0.48369,0.96777,0.0001495,0.0001495,0.0001495
diff --git a/rpi/training/result/unified-nano/results.png b/rpi/training/result/unified-nano/results.png
new file mode 100644
index 00000000..e8c55469
Binary files /dev/null and b/rpi/training/result/unified-nano/results.png differ
diff --git a/rpi/training/result/unified-nano/train_batch0.jpg b/rpi/training/result/unified-nano/train_batch0.jpg
new file mode 100644
index 00000000..107e91f2
Binary files /dev/null and b/rpi/training/result/unified-nano/train_batch0.jpg differ
diff --git a/rpi/training/result/unified-nano/train_batch1.jpg b/rpi/training/result/unified-nano/train_batch1.jpg
new file mode 100644
index 00000000..4bc19c54
Binary files /dev/null and b/rpi/training/result/unified-nano/train_batch1.jpg differ
diff --git a/rpi/training/result/unified-nano/train_batch2.jpg b/rpi/training/result/unified-nano/train_batch2.jpg
new file mode 100644
index 00000000..16a6f9d2
Binary files /dev/null and b/rpi/training/result/unified-nano/train_batch2.jpg differ
diff --git a/rpi/training/result/unified-nano/train_batch630990.jpg b/rpi/training/result/unified-nano/train_batch630990.jpg
new file mode 100644
index 00000000..361349b8
Binary files /dev/null and b/rpi/training/result/unified-nano/train_batch630990.jpg differ
diff --git a/rpi/training/result/unified-nano/train_batch630991.jpg b/rpi/training/result/unified-nano/train_batch630991.jpg
new file mode 100644
index 00000000..5e675072
Binary files /dev/null and b/rpi/training/result/unified-nano/train_batch630991.jpg differ
diff --git a/rpi/training/result/unified-nano/train_batch630992.jpg b/rpi/training/result/unified-nano/train_batch630992.jpg
new file mode 100644
index 00000000..4a143bfc
Binary files /dev/null and b/rpi/training/result/unified-nano/train_batch630992.jpg differ
diff --git a/rpi/training/result/unified-nano/val_batch0_labels.jpg b/rpi/training/result/unified-nano/val_batch0_labels.jpg
new file mode 100644
index 00000000..d551557a
Binary files /dev/null and b/rpi/training/result/unified-nano/val_batch0_labels.jpg differ
diff --git a/rpi/training/result/unified-nano/val_batch0_pred.jpg b/rpi/training/result/unified-nano/val_batch0_pred.jpg
new file mode 100644
index 00000000..de269d30
Binary files /dev/null and b/rpi/training/result/unified-nano/val_batch0_pred.jpg differ
diff --git a/rpi/training/result/unified-nano/val_batch1_labels.jpg b/rpi/training/result/unified-nano/val_batch1_labels.jpg
new file mode 100644
index 00000000..8be07a8a
Binary files /dev/null and b/rpi/training/result/unified-nano/val_batch1_labels.jpg differ
diff --git a/rpi/training/result/unified-nano/val_batch1_pred.jpg b/rpi/training/result/unified-nano/val_batch1_pred.jpg
new file mode 100644
index 00000000..7d40ce64
Binary files /dev/null and b/rpi/training/result/unified-nano/val_batch1_pred.jpg differ
diff --git a/rpi/training/result/unified-nano/val_batch2_labels.jpg b/rpi/training/result/unified-nano/val_batch2_labels.jpg
new file mode 100644
index 00000000..540a24a1
Binary files /dev/null and b/rpi/training/result/unified-nano/val_batch2_labels.jpg differ
diff --git a/rpi/training/result/unified-nano/val_batch2_pred.jpg b/rpi/training/result/unified-nano/val_batch2_pred.jpg
new file mode 100644
index 00000000..72aafefa
Binary files /dev/null and b/rpi/training/result/unified-nano/val_batch2_pred.jpg differ
diff --git a/rpi/training/result/unified-nano/weights/best.pt b/rpi/training/result/unified-nano/weights/best.pt
new file mode 100644
index 00000000..05dda92c
Binary files /dev/null and b/rpi/training/result/unified-nano/weights/best.pt differ
diff --git a/rpi/training/result/unified-nano/weights/last.pt b/rpi/training/result/unified-nano/weights/last.pt
new file mode 100644
index 00000000..24217c3a
Binary files /dev/null and b/rpi/training/result/unified-nano/weights/last.pt differ
diff --git a/rpi/training/result/unified-small/args.yaml b/rpi/training/result/unified-small/args.yaml
new file mode 100644
index 00000000..b230e8a8
--- /dev/null
+++ b/rpi/training/result/unified-small/args.yaml
@@ -0,0 +1,106 @@
+task: detect
+mode: train
+model: models/yolo11s.pt
+data: ./datasets/pieces/unified/data.yaml
+epochs: 150
+time: null
+patience: 20
+batch: 12
+imgsz: 640
+save: true
+save_period: 10
+cache: false
+device: '0'
+workers: 8
+project: result
+name: unified-small
+exist_ok: true
+pretrained: true
+optimizer: auto
+verbose: true
+seed: 0
+deterministic: true
+single_cls: false
+rect: false
+cos_lr: false
+close_mosaic: 10
+resume: false
+amp: true
+fraction: 1.0
+profile: false
+freeze: null
+multi_scale: false
+compile: false
+overlap_mask: true
+mask_ratio: 4
+dropout: 0.0
+val: true
+split: val
+save_json: false
+conf: null
+iou: 0.7
+max_det: 300
+half: false
+dnn: false
+plots: true
+source: null
+vid_stride: 1
+stream_buffer: false
+visualize: false
+augment: true
+agnostic_nms: false
+classes: null
+retina_masks: false
+embed: null
+show: false
+save_frames: false
+save_txt: false
+save_conf: false
+save_crop: false
+show_labels: true
+show_conf: true
+show_boxes: true
+line_width: null
+format: torchscript
+keras: false
+optimize: false
+int8: false
+dynamic: false
+simplify: true
+opset: null
+workspace: null
+nms: false
+lr0: 0.01
+lrf: 0.01
+momentum: 0.937
+weight_decay: 0.0005
+warmup_epochs: 3.0
+warmup_momentum: 0.8
+warmup_bias_lr: 0.1
+box: 7.5
+cls: 0.5
+dfl: 1.5
+pose: 12.0
+kobj: 1.0
+nbs: 64
+hsv_h: 0.015
+hsv_s: 0.7
+hsv_v: 0.4
+degrees: 10.0
+translate: 0.1
+scale: 0.1
+shear: 2.0
+perspective: 0.0
+flipud: 0.5
+fliplr: 0.5
+bgr: 0.0
+mosaic: 1.0
+mixup: 0.5
+cutmix: 0.0
+copy_paste: 0.0
+copy_paste_mode: flip
+auto_augment: randaugment
+erasing: 0.4
+cfg: null
+tracker: botsort.yaml
+save_dir: C:\Users\Laurent\Desktop\board-mate\rpi\training\result\unified-small
diff --git a/rpi/training/result/unified-small/labels.jpg b/rpi/training/result/unified-small/labels.jpg
new file mode 100644
index 00000000..eb8ceca3
Binary files /dev/null and b/rpi/training/result/unified-small/labels.jpg differ
diff --git a/rpi/training/result/unified-small/results.csv b/rpi/training/result/unified-small/results.csv
new file mode 100644
index 00000000..ae8d112d
--- /dev/null
+++ b/rpi/training/result/unified-small/results.csv
@@ -0,0 +1,36 @@
+epoch,time,train/box_loss,train/cls_loss,train/dfl_loss,metrics/precision(B),metrics/recall(B),metrics/mAP50(B),metrics/mAP50-95(B),val/box_loss,val/cls_loss,val/dfl_loss,lr/pg0,lr/pg1,lr/pg2
+1,469.68,1.4588,1.56499,1.26743,0.7138,0.73829,0.74489,0.46721,1.35429,1.03222,1.18238,0.00333203,0.00333203,0.00333203
+2,930.805,1.30938,1.03071,1.14974,0.81306,0.77515,0.8223,0.53213,1.29176,0.88476,1.13658,0.00662137,0.00662137,0.00662137
+3,1385.97,1.29451,0.98114,1.13067,0.80681,0.76005,0.79528,0.51047,1.32415,0.92207,1.13726,0.00986671,0.00986671,0.00986671
+4,1840.26,1.27626,0.94776,1.12616,0.84026,0.79785,0.84704,0.55468,1.29204,0.80333,1.1131,0.009802,0.009802,0.009802
+5,2297.42,1.23767,0.88241,1.11547,0.8632,0.81914,0.86715,0.58435,1.22597,0.74588,1.10086,0.009736,0.009736,0.009736
+6,2743.86,1.19804,0.82718,1.1022,0.87384,0.82354,0.87485,0.59487,1.21194,0.7117,1.09833,0.00967,0.00967,0.00967
+7,3191.47,1.17186,0.7881,1.09341,0.88492,0.83586,0.88091,0.60785,1.19203,0.67321,1.08615,0.009604,0.009604,0.009604
+8,3646.71,1.15818,0.76657,1.08976,0.89588,0.83731,0.88662,0.61578,1.16675,0.64156,1.08197,0.009538,0.009538,0.009538
+9,4095.04,1.14433,0.75176,1.08606,0.89159,0.84849,0.88986,0.62397,1.1532,0.62466,1.07152,0.009472,0.009472,0.009472
+10,4538.72,1.13229,0.73705,1.08097,0.90648,0.84697,0.89383,0.62912,1.14891,0.61086,1.07327,0.009406,0.009406,0.009406
+11,5015.76,1.12043,0.72166,1.07782,0.90611,0.85248,0.89618,0.63746,1.12122,0.60398,1.06267,0.00934,0.00934,0.00934
+12,5462.81,1.10717,0.70858,1.07164,0.91728,0.85037,0.89778,0.64081,1.11665,0.58918,1.06547,0.009274,0.009274,0.009274
+13,5909.61,1.10204,0.69402,1.06979,0.92239,0.85081,0.90075,0.64708,1.0994,0.58013,1.05117,0.009208,0.009208,0.009208
+14,6357.31,1.09757,0.69004,1.07018,0.92048,0.85302,0.90269,0.65066,1.0898,0.56696,1.04949,0.009142,0.009142,0.009142
+15,6805.4,1.08261,0.67813,1.06249,0.9216,0.8554,0.90299,0.65352,1.08556,0.56459,1.04844,0.009076,0.009076,0.009076
+16,7253.22,1.07969,0.67316,1.06249,0.93867,0.8532,0.90423,0.65793,1.07202,0.55066,1.04528,0.00901,0.00901,0.00901
+17,7706.49,1.07302,0.66449,1.06065,0.9331,0.85267,0.90549,0.66131,1.06352,0.55008,1.04059,0.008944,0.008944,0.008944
+18,8163.63,1.06878,0.65776,1.05646,0.94238,0.85321,0.90743,0.66427,1.05899,0.54161,1.03931,0.008878,0.008878,0.008878
+19,8617.65,1.06094,0.65266,1.05424,0.94308,0.85336,0.90918,0.66715,1.05338,0.53867,1.03518,0.008812,0.008812,0.008812
+20,9061.88,1.05899,0.64725,1.0533,0.94212,0.85584,0.90942,0.6693,1.04804,0.53296,1.0322,0.008746,0.008746,0.008746
+21,9543.8,1.05373,0.64631,1.05307,0.94717,0.8561,0.9104,0.67015,1.044,0.52713,1.02972,0.00868,0.00868,0.00868
+22,10025.7,1.04616,0.64231,1.04737,0.94793,0.85431,0.91076,0.67223,1.03728,0.52253,1.02813,0.008614,0.008614,0.008614
+23,10534.3,1.04453,0.63509,1.0464,0.94859,0.8569,0.91168,0.67283,1.0362,0.5199,1.02708,0.008548,0.008548,0.008548
+24,11013.9,1.0391,0.63,1.04558,0.9513,0.85641,0.91153,0.67441,1.03221,0.51731,1.02609,0.008482,0.008482,0.008482
+25,11561.8,1.03281,0.63061,1.04392,0.95266,0.85681,0.91163,0.67555,1.02975,0.51647,1.02502,0.008416,0.008416,0.008416
+26,12130,1.03067,0.62298,1.04136,0.95371,0.85685,0.91221,0.67638,1.02919,0.51482,1.02454,0.00835,0.00835,0.00835
+27,12758.5,1.02674,0.62246,1.0395,0.95377,0.85823,0.91264,0.67718,1.02754,0.5124,1.02333,0.008284,0.008284,0.008284
+28,13398.8,1.02412,0.62003,1.03772,0.95376,0.85867,0.9129,0.67802,1.02588,0.50997,1.02215,0.008218,0.008218,0.008218
+29,13867.7,1.01843,0.61479,1.03603,0.95459,0.85898,0.91306,0.67849,1.0247,0.50866,1.02127,0.008152,0.008152,0.008152
+30,14367.8,1.0158,0.60871,1.03531,0.95562,0.85835,0.9132,0.67911,1.02295,0.50646,1.02054,0.008086,0.008086,0.008086
+31,14837.8,1.01703,0.61018,1.0366,0.95504,0.85963,0.91351,0.67944,1.02291,0.50515,1.02042,0.00802,0.00802,0.00802
+32,15313.3,1.0105,0.60394,1.03358,0.95705,0.85842,0.91359,0.68019,1.02151,0.50401,1.01983,0.007954,0.007954,0.007954
+33,15778.3,1.00972,0.59947,1.03269,0.95611,0.85983,0.91378,0.68088,1.02043,0.50302,1.0194,0.007888,0.007888,0.007888
+34,16240.9,1.00426,0.59879,1.03068,0.95674,0.85982,0.91412,0.68173,1.01907,0.50182,1.01877,0.007822,0.007822,0.007822
+35,16717.7,1.00091,0.59585,1.02954,0.95583,0.86062,0.9143,0.68221,1.01817,0.50083,1.01836,0.007756,0.007756,0.007756
diff --git a/rpi/training/result/unified-small/train_batch0.jpg b/rpi/training/result/unified-small/train_batch0.jpg
new file mode 100644
index 00000000..2da9c1a5
Binary files /dev/null and b/rpi/training/result/unified-small/train_batch0.jpg differ
diff --git a/rpi/training/result/unified-small/train_batch1.jpg b/rpi/training/result/unified-small/train_batch1.jpg
new file mode 100644
index 00000000..44f67c57
Binary files /dev/null and b/rpi/training/result/unified-small/train_batch1.jpg differ
diff --git a/rpi/training/result/unified-small/train_batch2.jpg b/rpi/training/result/unified-small/train_batch2.jpg
new file mode 100644
index 00000000..0992496c
Binary files /dev/null and b/rpi/training/result/unified-small/train_batch2.jpg differ
diff --git a/rpi/training/result/unified-small/weights/best.pt b/rpi/training/result/unified-small/weights/best.pt
new file mode 100644
index 00000000..7f0e6114
Binary files /dev/null and b/rpi/training/result/unified-small/weights/best.pt differ
diff --git a/rpi/training/result/unified-small/weights/epoch0.pt b/rpi/training/result/unified-small/weights/epoch0.pt
new file mode 100644
index 00000000..04c28ba7
Binary files /dev/null and b/rpi/training/result/unified-small/weights/epoch0.pt differ
diff --git a/rpi/training/result/unified-small/weights/epoch10.pt b/rpi/training/result/unified-small/weights/epoch10.pt
new file mode 100644
index 00000000..6f8c301b
Binary files /dev/null and b/rpi/training/result/unified-small/weights/epoch10.pt differ
diff --git a/rpi/training/result/unified-small/weights/epoch20.pt b/rpi/training/result/unified-small/weights/epoch20.pt
new file mode 100644
index 00000000..27597522
Binary files /dev/null and b/rpi/training/result/unified-small/weights/epoch20.pt differ
diff --git a/rpi/training/result/unified-small/weights/epoch30.pt b/rpi/training/result/unified-small/weights/epoch30.pt
new file mode 100644
index 00000000..16e820c4
Binary files /dev/null and b/rpi/training/result/unified-small/weights/epoch30.pt differ
diff --git a/rpi/training/result/unified-small/weights/last.pt b/rpi/training/result/unified-small/weights/last.pt
new file mode 100644
index 00000000..7f0e6114
Binary files /dev/null and b/rpi/training/result/unified-small/weights/last.pt differ
diff --git a/rpi/training/yolo11n.pt b/rpi/training/yolo11n.pt
new file mode 100644
index 00000000..45b273b4
Binary files /dev/null and b/rpi/training/yolo11n.pt differ