phyling 7.0.2__tar.gz → 7.0.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. {phyling-7.0.2 → phyling-7.0.4}/.github/workflows/python-lint.yml +3 -0
  2. {phyling-7.0.2 → phyling-7.0.4}/.gitignore +2 -0
  3. {phyling-7.0.2 → phyling-7.0.4}/.pre-commit-config.yaml +1 -1
  4. phyling-7.0.4/CLAUDE.md +37 -0
  5. {phyling-7.0.2 → phyling-7.0.4}/PKG-INFO +14 -3
  6. {phyling-7.0.2 → phyling-7.0.4}/README.md +13 -2
  7. {phyling-7.0.2 → phyling-7.0.4}/examples/Analyse/decoder.ipynb +78 -48
  8. {phyling-7.0.2/examples/Nano-Phyling → phyling-7.0.4/examples/NanoPhyling-MiniPhyling}/lab_examples/pendulum.ipynb +0 -2
  9. phyling-7.0.4/examples/NanoPhyling-MiniPhyling/multi_devices.ipynb +210 -0
  10. phyling-7.0.4/examples/NanoPhyling-MiniPhyling/single_device.ipynb +203 -0
  11. phyling-7.0.4/examples/Phyling API/Phyling python lib/api.ipynb +560 -0
  12. {phyling-7.0.2 → phyling-7.0.4}/examples/Phyling API/RAW API examples/minimal_oauth.py +1 -0
  13. {phyling-7.0.2 → phyling-7.0.4}/phyling/api/api.py +186 -0
  14. phyling-7.0.4/phyling/ble/__init__.py +4 -0
  15. phyling-7.0.4/phyling/ble/base_device.py +464 -0
  16. phyling-7.0.4/phyling/ble/miniphyling.py +97 -0
  17. phyling-7.0.4/phyling/ble/nanophyling.py +52 -0
  18. phyling-7.0.4/phyling/ble/phyling_devices.py +212 -0
  19. phyling-7.0.4/phyling/decoder/calib_texisense.py +165 -0
  20. {phyling-7.0.2 → phyling-7.0.4}/phyling/decoder/calibration_use.py +31 -8
  21. phyling-7.0.4/phyling/decoder/decoder.py +450 -0
  22. {phyling-7.0.2 → phyling-7.0.4}/phyling/decoder/decoder_utils.c +11723 -8533
  23. {phyling-7.0.2 → phyling-7.0.4}/phyling/decoder/decoder_utils.pyx +275 -66
  24. phyling-7.0.4/phyling/phyling_utils.py +29 -0
  25. {phyling-7.0.2 → phyling-7.0.4}/phyling.egg-info/PKG-INFO +14 -3
  26. {phyling-7.0.2 → phyling-7.0.4}/phyling.egg-info/SOURCES.txt +12 -5
  27. {phyling-7.0.2 → phyling-7.0.4}/setup.py +7 -1
  28. phyling-7.0.2/examples/Nano-Phyling/nanophyling.ipynb +0 -117
  29. phyling-7.0.2/examples/Phyling API/Phyling python lib/api.ipynb +0 -304
  30. phyling-7.0.2/phyling/ble/nanophyling.py +0 -309
  31. phyling-7.0.2/phyling/decoder/decoder.py +0 -52
  32. phyling-7.0.2/phyling/phyling_utils.py +0 -113
  33. {phyling-7.0.2 → phyling-7.0.4}/.flake8 +0 -0
  34. {phyling-7.0.2 → phyling-7.0.4}/.github/workflows/python-publish.yml +0 -0
  35. {phyling-7.0.2 → phyling-7.0.4}/LICENSE.txt +0 -0
  36. {phyling-7.0.2 → phyling-7.0.4}/MANIFEST.in +0 -0
  37. {phyling-7.0.2 → phyling-7.0.4}/examples/Analyse/example_data.txt +0 -0
  38. {phyling-7.0.2/examples/Nano-Phyling → phyling-7.0.4/examples/NanoPhyling-MiniPhyling}/lab_examples/data/pendulum_example.csv +0 -0
  39. {phyling-7.0.2/examples/Nano-Phyling → phyling-7.0.4/examples/NanoPhyling-MiniPhyling}/lab_examples/data/pendulum_picture.jpg +0 -0
  40. {phyling-7.0.2/examples/Nano-Phyling → phyling-7.0.4/examples/NanoPhyling-MiniPhyling}/lab_examples/data/pendulum_video.mp4 +0 -0
  41. {phyling-7.0.2 → phyling-7.0.4}/examples/Phyling API/Phyling python lib/realtime.ipynb +0 -0
  42. {phyling-7.0.2 → phyling-7.0.4}/examples/Phyling API/RAW API examples/minimal_apikey.html +0 -0
  43. {phyling-7.0.2 → phyling-7.0.4}/examples/Phyling API/RAW API examples/realtime.html +0 -0
  44. {phyling-7.0.2 → phyling-7.0.4}/examples/Phyling API/RAW API examples/requirement.txt +0 -0
  45. {phyling-7.0.2 → phyling-7.0.4}/examples/Phyling API/RAW API examples/single-device.html +0 -0
  46. {phyling-7.0.2 → phyling-7.0.4}/phyling/__init__.py +0 -0
  47. {phyling-7.0.2 → phyling-7.0.4}/phyling/api/__init__.py +0 -0
  48. {phyling-7.0.2 → phyling-7.0.4}/phyling/api/phylingSocket.py +0 -0
  49. {phyling-7.0.2 → phyling-7.0.4}/phyling/api/realtime.py +0 -0
  50. {phyling-7.0.2 → phyling-7.0.4}/phyling/api/record.py +0 -0
  51. {phyling-7.0.2 → phyling-7.0.4}/phyling/api/user.py +0 -0
  52. {phyling-7.0.2 → phyling-7.0.4}/phyling/api/utils.py +0 -0
  53. {phyling-7.0.2 → phyling-7.0.4}/phyling/decoder/__init__.py +0 -0
  54. {phyling-7.0.2 → phyling-7.0.4}/phyling.egg-info/dependency_links.txt +0 -0
  55. {phyling-7.0.2 → phyling-7.0.4}/phyling.egg-info/requires.txt +0 -0
  56. {phyling-7.0.2 → phyling-7.0.4}/phyling.egg-info/top_level.txt +0 -0
  57. {phyling-7.0.2 → phyling-7.0.4}/pyproject.toml +0 -0
  58. {phyling-7.0.2 → phyling-7.0.4}/requirements.txt +0 -0
  59. {phyling-7.0.2 → phyling-7.0.4}/setup.cfg +0 -0
  60. {phyling-7.0.2 → phyling-7.0.4}/tests/__init__.py +0 -0
  61. {phyling-7.0.2 → phyling-7.0.4}/tests/test_base.py +0 -0
@@ -3,6 +3,9 @@ name: python-lint
3
3
  on:
4
4
  pull_request:
5
5
  branches: [ "**" ]
6
+ push:
7
+ branches: [ "main" ]
8
+ workflow_dispatch:
6
9
 
7
10
  jobs:
8
11
  python-lint:
@@ -137,3 +137,5 @@ venv
137
137
  .pypirc
138
138
  test.json
139
139
  example_data.json
140
+ example_data.csv
141
+ example_data.old.txt
@@ -48,7 +48,7 @@ repos:
48
48
  rev: 0.6.1
49
49
  hooks:
50
50
  - id: nbstripout
51
- exclude: ^examples/Nano-Phyling/lab_examples/.*\.ipynb$
51
+ exclude: ^examples/NanoPhyling-MiniPhyling/lab_examples/.*\.ipynb$
52
52
  - repo: https://github.com/compilerla/conventional-pre-commit
53
53
  rev: v4.2.0
54
54
  hooks:
@@ -0,0 +1,37 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this directory.
4
+
5
+ ## Présentation
6
+
7
+ `phyling` est le package core Python de la plateforme Phyling. Il contient le code Cython pour la communication BLE avec les devices et les algorithmes d'analyse de base.
8
+
9
+ ## Stack
10
+
11
+ - **Langage :** Python 3.10 + Cython
12
+ - **Build :** setuptools avec extensions Cython (`pyproject.toml`)
13
+ - **Dépendances :** numpy, bleak, ujson, urllib3, aiohttp, python-socketio
14
+ - **Installation :** mode éditable `pip install -e .`
15
+
16
+ ## Build
17
+
18
+ ```bash
19
+ cd PhylingApp/phyling
20
+
21
+ # Compiler les extensions Cython
22
+ pip install -e .
23
+
24
+ # Restart via Docker après recompilation
25
+ just --justfile ../infra/justfile docker-restart cloud-simu-dev latest "celery managers realtime-manager"
26
+ ```
27
+
28
+ > ⚠️ Toute modification de fichiers `.pyx` nécessite une recompilation.
29
+
30
+ ## Conventions
31
+
32
+ - **Python 3.10**, 4 espaces, limite 120 caractères
33
+ - **Linting :** Flake8
34
+ - **Formatage :** Black
35
+ - **Cython :** fichiers `.pyx` compilés en `.c` puis `.so`
36
+
37
+ Voir `PhylingApp/CLAUDE.md` pour les conventions communes (imports, logs, docstrings).
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: phyling
3
- Version: 7.0.2
3
+ Version: 7.0.4
4
4
  Summary: Phyling public package
5
5
  License: MIT License
6
6
 
@@ -49,6 +49,16 @@ Installez depuis les sources :
49
49
  pip install -e .
50
50
  ```
51
51
 
52
+ ### Prérequis Windows
53
+
54
+ Le package contient une extension Cython qui nécessite un compilateur C++. Sur Windows, deux outils sont requis avant d'installer :
55
+
56
+ 1. **Git pour Windows** : https://git-scm.com/download/win
57
+ 2. **Microsoft C++ Build Tools** : https://visualstudio.microsoft.com/visual-cpp-build-tools/
58
+ - Dans l'installateur, cocher **"Développement Desktop en C++"**
59
+
60
+ Relancer ensuite `pip install -e .` dans un nouveau terminal après l'installation.
61
+
52
62
  ## Exemples
53
63
 
54
64
  Cette partie regroupe plusieurs exemples :
@@ -59,8 +69,9 @@ Cette partie regroupe plusieurs exemples :
59
69
  ### Décoder un fichier brut Phyling
60
70
  - `phyling/examples/Analyse/decoder.ipynb` : notebook qui charge un enregistrement `.txt` brut, décrit les trames disponibles et les convertit en tableaux/pandas exploitables pour vos analyses.
61
71
 
62
- ### Récupérer les données d'un NanoPhyling
63
- - `examples/Nano-Phyling/nanophyling.ipynb` : notebook qui se connecte à un Nano-Phyling, fait une acquisition de X secondes puis affiche les données
72
+ ### Récupérer les données d'un MiniPhyling ou d'un NanoPhyling
73
+ - `examples/NanoPhyling-MiniPhyling/single_device.ipynb` : notebook qui se connecte à un seul Mini-Phyling ou Nano-Phyling, fait une acquisition puis affiche les données
74
+ - `examples/NanoPhyling-MiniPhyling/multi_devices.ipynb` : notebook qui se connecte à plusieurs devices en parallèle et fusionne les acquisitions
64
75
 
65
76
  ### Se connecter à l'API Phyling
66
77
  La documentation de l'API Phyling est disponible ici : [docs.phyling.fr/api](https://docs.phyling.fr/api/)
@@ -12,6 +12,16 @@ Installez depuis les sources :
12
12
  pip install -e .
13
13
  ```
14
14
 
15
+ ### Prérequis Windows
16
+
17
+ Le package contient une extension Cython qui nécessite un compilateur C++. Sur Windows, deux outils sont requis avant d'installer :
18
+
19
+ 1. **Git pour Windows** : https://git-scm.com/download/win
20
+ 2. **Microsoft C++ Build Tools** : https://visualstudio.microsoft.com/visual-cpp-build-tools/
21
+ - Dans l'installateur, cocher **"Développement Desktop en C++"**
22
+
23
+ Relancer ensuite `pip install -e .` dans un nouveau terminal après l'installation.
24
+
15
25
  ## Exemples
16
26
 
17
27
  Cette partie regroupe plusieurs exemples :
@@ -22,8 +32,9 @@ Cette partie regroupe plusieurs exemples :
22
32
  ### Décoder un fichier brut Phyling
23
33
  - `phyling/examples/Analyse/decoder.ipynb` : notebook qui charge un enregistrement `.txt` brut, décrit les trames disponibles et les convertit en tableaux/pandas exploitables pour vos analyses.
24
34
 
25
- ### Récupérer les données d'un NanoPhyling
26
- - `examples/Nano-Phyling/nanophyling.ipynb` : notebook qui se connecte à un Nano-Phyling, fait une acquisition de X secondes puis affiche les données
35
+ ### Récupérer les données d'un MiniPhyling ou d'un NanoPhyling
36
+ - `examples/NanoPhyling-MiniPhyling/single_device.ipynb` : notebook qui se connecte à un seul Mini-Phyling ou Nano-Phyling, fait une acquisition puis affiche les données
37
+ - `examples/NanoPhyling-MiniPhyling/multi_devices.ipynb` : notebook qui se connecte à plusieurs devices en parallèle et fusionne les acquisitions
27
38
 
28
39
  ### Se connecter à l'API Phyling
29
40
  La documentation de l'API Phyling est disponible ici : [docs.phyling.fr/api](https://docs.phyling.fr/api/)
@@ -7,10 +7,27 @@
7
7
  "source": [
8
8
  "# Example notebook\n",
9
9
  "\n",
10
- "The purpose of this notebook is to provide examples on how to:\n",
11
- "- decode a file with raw data (txt format)\n",
12
- "- save the decoded file into json format\n",
13
- "- process and visualise the decoded data\n"
10
+ "Ce notebook illustre comment :\n",
11
+ "1. Décoder un fichier brut (format `.txt`) et obtenir les données en mémoire (JSON)\n",
12
+ "2. Processer le fichier brut en JSON et le sauvegarder sur disque\n",
13
+ "3. Générer un DataFrame depuis les données et le sauvegarder sur disque\n"
14
+ ]
15
+ },
16
+ {
17
+ "cell_type": "code",
18
+ "execution_count": null,
19
+ "id": "9fc37f87",
20
+ "metadata": {},
21
+ "outputs": [],
22
+ "source": [
23
+ "%matplotlib widget\n",
24
+ "import matplotlib.pyplot as plt\n",
25
+ "\n",
26
+ "from phyling.decoder import decoder\n",
27
+ "from phyling import phyling_utils\n",
28
+ "\n",
29
+ "path = \"./\"\n",
30
+ "raw_file = \"example_data.txt\""
14
31
  ]
15
32
  },
16
33
  {
@@ -18,21 +35,42 @@
18
35
  "id": "ba52e96f-8bd9-401a-b4d6-8f6b0993a7c5",
19
36
  "metadata": {},
20
37
  "source": [
21
- "## 1. Decode file"
38
+ "## 1. Décoder le fichier → JSON en mémoire"
39
+ ]
40
+ },
41
+ {
42
+ "cell_type": "markdown",
43
+ "id": "719011ea",
44
+ "metadata": {},
45
+ "source": [
46
+ "### 1.1 (optionnel) Changer ou réinitialiser la calibration du fichier\n",
47
+ "Cette étape va modifier le fichier brut mais en sauvegarder une copie"
22
48
  ]
23
49
  },
24
50
  {
25
51
  "cell_type": "code",
26
52
  "execution_count": null,
27
- "id": "9fc37f87",
53
+ "id": "252c84b2",
28
54
  "metadata": {},
29
55
  "outputs": [],
30
56
  "source": [
31
- "%matplotlib widget\n",
32
- "import matplotlib.pyplot as plt\n",
33
- "\n",
34
- "from phyling.decoder import decoder\n",
35
- "from phyling import phyling_utils"
57
+ "oldFilename = raw_file[:-3] + \"old.\" + raw_file[-3:]\n",
58
+ "newCalibration = {}\n",
59
+ "print(f\"Rename {raw_file} to {oldFilename} and update the calibration of {raw_file} with {newCalibration}\")\n",
60
+ "decoder.updateCalibration(\n",
61
+ " filename=path + raw_file,\n",
62
+ " oldFilename=path + oldFilename,\n",
63
+ " calibration=newCalibration,\n",
64
+ " use_s3=False,\n",
65
+ ")"
66
+ ]
67
+ },
68
+ {
69
+ "cell_type": "markdown",
70
+ "id": "0993bffc",
71
+ "metadata": {},
72
+ "source": [
73
+ "### 1.2 Décoder le fichier"
36
74
  ]
37
75
  },
38
76
  {
@@ -42,8 +80,6 @@
42
80
  "metadata": {},
43
81
  "outputs": [],
44
82
  "source": [
45
- "path = \"./\"\n",
46
- "raw_file = \"example_data.txt\"\n",
47
83
  "data = decoder.decode(path + raw_file, verbose=True, use_s3=False)"
48
84
  ]
49
85
  },
@@ -52,7 +88,7 @@
52
88
  "id": "9b7f69f8",
53
89
  "metadata": {},
54
90
  "source": [
55
- "## 2. Decode file and save data in json format"
91
+ "## 2. Processer le fichier brut en JSON (et sauvegarder)"
56
92
  ]
57
93
  },
58
94
  {
@@ -62,7 +98,7 @@
62
98
  "metadata": {},
63
99
  "outputs": [],
64
100
  "source": [
65
- "# Decode one file\n",
101
+ "# Décoder et sauvegarder un fichier\n",
66
102
  "decoder.decodeSave(path + raw_file, overwrite=False, verbose=True)"
67
103
  ]
68
104
  },
@@ -73,83 +109,77 @@
73
109
  "metadata": {},
74
110
  "outputs": [],
75
111
  "source": [
76
- "# Decode all files in a folder\n",
112
+ "# Décoder et sauvegarder tous les fichiers d'un dossier\n",
77
113
  "processed_files = decoder.decodeSaveFolder(path, overwrite=False, verbose=True)\n",
78
114
  "print(processed_files)"
79
115
  ]
80
116
  },
117
+ {
118
+ "cell_type": "code",
119
+ "execution_count": null,
120
+ "id": "c60d6783",
121
+ "metadata": {},
122
+ "outputs": [],
123
+ "source": [
124
+ "# Charger le fichier JSON sauvegardé\n",
125
+ "json_file = raw_file.replace(\".txt\", \".json\")\n",
126
+ "data = phyling_utils.load_json(path + json_file)"
127
+ ]
128
+ },
81
129
  {
82
130
  "cell_type": "markdown",
83
131
  "id": "c1f234ae",
84
132
  "metadata": {},
85
133
  "source": [
86
- "## 3. Process and plot data"
134
+ "## 3. Générer un DataFrame (et sauvegarder)"
87
135
  ]
88
136
  },
89
137
  {
90
138
  "cell_type": "code",
91
139
  "execution_count": null,
92
- "id": "c60d6783",
140
+ "id": "f367e153",
93
141
  "metadata": {},
94
142
  "outputs": [],
95
143
  "source": [
96
- "# Load json file\n",
97
- "json_file = raw_file.replace(\".txt\", \".json\")\n",
98
- "data = phyling_utils.load_json(path + json_file)"
144
+ "# Générer le DataFrame depuis les données\n",
145
+ "df = decoder.json2csv(data)"
99
146
  ]
100
147
  },
101
148
  {
102
149
  "cell_type": "code",
103
150
  "execution_count": null,
104
- "id": "d1766acd",
151
+ "id": "7ed8ef70",
105
152
  "metadata": {},
106
153
  "outputs": [],
107
154
  "source": [
108
- "# Directly from data object\n",
109
- "\n",
110
- "modName = \"imu\"\n",
111
- "mod = data[\"modules\"][modName][\"data\"]\n",
112
- "\n",
113
- "plt.figure()\n",
114
- "plt.plot(mod[\"T\"], mod[\"acc_x\"])\n",
115
- "plt.xlabel(\"Temps (s)\")\n",
116
- "plt.ylabel(\"Acc. (m/s$^2$)\")"
155
+ "df.head()"
117
156
  ]
118
157
  },
119
158
  {
120
159
  "cell_type": "code",
121
160
  "execution_count": null,
122
- "id": "48e504ff",
161
+ "id": "a1b2c3d4",
123
162
  "metadata": {},
124
163
  "outputs": [],
125
164
  "source": [
126
- "# Convert data object to Dataframes\n",
127
- "\n",
128
- "df = phyling_utils.data2df(data, \"all\")\n",
129
- "print(list(df))\n",
130
- "df[\"imu\"].head()"
165
+ "# Sauvegarder le DataFrame en CSV\n",
166
+ "csv_file = raw_file.replace(\".txt\", \".csv\")\n",
167
+ "df.to_csv(path + csv_file, index=False)"
131
168
  ]
132
169
  },
133
170
  {
134
171
  "cell_type": "code",
135
172
  "execution_count": null,
136
- "id": "8aac8a16",
173
+ "id": "f3116bf5",
137
174
  "metadata": {},
138
175
  "outputs": [],
139
176
  "source": [
177
+ "# Visualisation\n",
140
178
  "plt.figure()\n",
141
- "plt.plot(df[\"imu\"][\"T\"], df[\"imu\"][\"acc_x\"])\n",
179
+ "plt.plot(df[\"T\"], df[\"imu.acc_x\"])\n",
142
180
  "plt.xlabel(\"Temps (s)\")\n",
143
181
  "plt.ylabel(\"Acc. (m/s$^2$)\")"
144
182
  ]
145
- },
146
- {
147
- "cell_type": "code",
148
- "execution_count": null,
149
- "id": "aa491911",
150
- "metadata": {},
151
- "outputs": [],
152
- "source": []
153
183
  }
154
184
  ],
155
185
  "metadata": {
@@ -168,7 +198,7 @@
168
198
  "name": "python",
169
199
  "nbconvert_exporter": "python",
170
200
  "pygments_lexer": "ipython3",
171
- "version": "3.10.19"
201
+ "version": "3.10.20"
172
202
  }
173
203
  },
174
204
  "nbformat": 4,
@@ -22,9 +22,7 @@
22
22
  "from scipy.optimize import curve_fit\n",
23
23
  "from scipy.integrate import cumulative_trapezoid\n",
24
24
  "from scipy.interpolate import interp1d\n",
25
- "from scipy.signal import butter, filtfilt\n",
26
25
  "from phyling.ble.nanophyling import NanoPhyling\n",
27
- "from tabulate import tabulate\n",
28
26
  "from IPython.display import Video, display\n",
29
27
  "import matplotlib.image as mpimg\n",
30
28
  "\n",
@@ -0,0 +1,210 @@
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": null,
6
+ "metadata": {},
7
+ "outputs": [],
8
+ "source": [
9
+ "%matplotlib widget\n",
10
+ "import matplotlib.pyplot as plt\n",
11
+ "import nest_asyncio\n",
12
+ "\n",
13
+ "nest_asyncio.apply() # used in notebook\n",
14
+ "\n",
15
+ "from phyling.ble import NanoPhyling, MiniPhyling, PhylingDevices"
16
+ ]
17
+ },
18
+ {
19
+ "cell_type": "code",
20
+ "execution_count": null,
21
+ "metadata": {},
22
+ "outputs": [],
23
+ "source": [
24
+ "devices = PhylingDevices(\n",
25
+ " [\n",
26
+ " MiniPhyling(\n",
27
+ " module_name=\"gauche\", # Optionnel, par défaut on utilise le nom Bluetooth\n",
28
+ " ble_name=\"MiniPhyling_42\"\n",
29
+ " ),\n",
30
+ " NanoPhyling(\n",
31
+ " module_name=\"droite\", # Optionnel, par défaut on utilise le nom Bluetooth\n",
32
+ " ble_name=\"NanoPhyling_42\",\n",
33
+ " config={\"rate\": 200, \"data\": [\"acc_x\", \"acc_y\", \"acc_z\", \"gyro_x\", \"gyro_y\", \"gyro_z\", \"mag_x\", \"mag_y\", \"mag_z\"]},\n",
34
+ " ),\n",
35
+ " ],\n",
36
+ " output_fs=200,\n",
37
+ ")"
38
+ ]
39
+ },
40
+ {
41
+ "cell_type": "markdown",
42
+ "metadata": {},
43
+ "source": [
44
+ "## Calibration\n",
45
+ "\n",
46
+ "`tare()` enregistre 5s de données immobiles par device (en parallèle) et calcule un offset par colonne. \n",
47
+ "La calibration s'applique automatiquement dans `get_df()` : `coef * (val + offset)`. \n",
48
+ "Le df existant de chaque device est **préservé**."
49
+ ]
50
+ },
51
+ {
52
+ "cell_type": "code",
53
+ "execution_count": null,
54
+ "metadata": {},
55
+ "outputs": [],
56
+ "source": [
57
+ "# Tare sur plusieurs devices en parallèle\n",
58
+ "devices.tare({\n",
59
+ " \"droite\": [\"gyro_x\", \"gyro_y\", \"gyro_z\"],\n",
60
+ " \"gauche\": [\"gyro_x\", \"gyro_y\", \"gyro_z\"],\n",
61
+ "})"
62
+ ]
63
+ },
64
+ {
65
+ "cell_type": "code",
66
+ "execution_count": null,
67
+ "metadata": {},
68
+ "outputs": [],
69
+ "source": [
70
+ "# Voir la calibration de tous les devices\n",
71
+ "devices.get_calib()"
72
+ ]
73
+ },
74
+ {
75
+ "cell_type": "code",
76
+ "execution_count": null,
77
+ "metadata": {},
78
+ "outputs": [],
79
+ "source": [
80
+ "# Reset la calibration (vide le dict, pas de calibration)\n",
81
+ "devices.reset_calib()"
82
+ ]
83
+ },
84
+ {
85
+ "cell_type": "code",
86
+ "execution_count": null,
87
+ "metadata": {},
88
+ "outputs": [],
89
+ "source": [
90
+ "# Remplacer la calibration d'un device\n",
91
+ "devices.set_calib({\n",
92
+ " \"droite\": {\n",
93
+ " \"mag_z\": {\"coef\": 1, \"offset\": 0},\n",
94
+ " },\n",
95
+ "})"
96
+ ]
97
+ },
98
+ {
99
+ "cell_type": "code",
100
+ "execution_count": null,
101
+ "metadata": {},
102
+ "outputs": [],
103
+ "source": [
104
+ "# Merger une calibration partielle\n",
105
+ "devices.update_calib({\n",
106
+ " \"droite\": {\n",
107
+ " \"acc_z\": {\"coef\": 1.02, \"offset\": 0},\n",
108
+ " },\n",
109
+ "})"
110
+ ]
111
+ },
112
+ {
113
+ "cell_type": "code",
114
+ "execution_count": null,
115
+ "metadata": {},
116
+ "outputs": [],
117
+ "source": [
118
+ "# On peut aussi calibrer un device directement\n",
119
+ "droite = devices.get_device(\"droite\")\n",
120
+ "droite.tare([\"gyro_z\"])\n",
121
+ "droite.get_calib()"
122
+ ]
123
+ },
124
+ {
125
+ "cell_type": "markdown",
126
+ "metadata": {},
127
+ "source": [
128
+ "## Acquisition"
129
+ ]
130
+ },
131
+ {
132
+ "cell_type": "code",
133
+ "execution_count": null,
134
+ "metadata": {},
135
+ "outputs": [],
136
+ "source": [
137
+ "# Vous pouvez kill la cell pendant l'exécution pour arrêter l'enregistrement\n",
138
+ "devices.run(duration=30)"
139
+ ]
140
+ },
141
+ {
142
+ "cell_type": "code",
143
+ "execution_count": null,
144
+ "metadata": {},
145
+ "outputs": [],
146
+ "source": [
147
+ "# La calibration est appliquée ici pour chaque device\n",
148
+ "df = devices.get_df(drop_nan=False)\n",
149
+ "df.head()"
150
+ ]
151
+ },
152
+ {
153
+ "cell_type": "code",
154
+ "execution_count": null,
155
+ "metadata": {},
156
+ "outputs": [],
157
+ "source": [
158
+ "cols = [\"acc_x\", \"acc_y\", \"acc_z\"]\n",
159
+ "\n",
160
+ "fig, axes = plt.subplots(len(cols), 1, sharex=True, figsize=(8, 6))\n",
161
+ "\n",
162
+ "for i, col in enumerate(cols):\n",
163
+ " ax = axes[i]\n",
164
+ "\n",
165
+ " for device in devices.devices:\n",
166
+ " colname = f\"{device.get_name()}.{col}\"\n",
167
+ " if colname in df.columns:\n",
168
+ " ax.plot(df[\"T\"], df[colname], label=colname)\n",
169
+ "\n",
170
+ " ax.set_title(col)\n",
171
+ " ax.grid()\n",
172
+ " ax.legend()\n",
173
+ "\n",
174
+ "axes[-1].set_xlabel(\"Time (s)\")\n",
175
+ "plt.tight_layout()"
176
+ ]
177
+ },
178
+ {
179
+ "cell_type": "code",
180
+ "execution_count": null,
181
+ "metadata": {},
182
+ "outputs": [],
183
+ "source": [
184
+ "# Enregistrer les données dans un CSV\n",
185
+ "# df.to_csv(\"example_data.csv\", index=False)"
186
+ ]
187
+ }
188
+ ],
189
+ "metadata": {
190
+ "kernelspec": {
191
+ "display_name": "venv",
192
+ "language": "python",
193
+ "name": "python3"
194
+ },
195
+ "language_info": {
196
+ "codemirror_mode": {
197
+ "name": "ipython",
198
+ "version": 3
199
+ },
200
+ "file_extension": ".py",
201
+ "mimetype": "text/x-python",
202
+ "name": "python",
203
+ "nbconvert_exporter": "python",
204
+ "pygments_lexer": "ipython3",
205
+ "version": "3.10.19"
206
+ }
207
+ },
208
+ "nbformat": 4,
209
+ "nbformat_minor": 4
210
+ }