Commit a2f6c879 authored by Clement Remi's avatar Clement Remi
Browse files

Merge branch 'docs_V2023' into 'master'

Docs v2023

See merge request reversaal/OhmPi!15
Showing with 3151 additions and 100 deletions
+3151 -100
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
sudo apt-get install -y libatlas-base-dev sudo apt-get install -y libatlas-base-dev
# Create the virtual environment # Create the virtual environment
python3 -m venv ohmpi python3 -m venv ohmpy
# Activate it # Activate it
source ohmpy/bin/activate || exit 1 # NOTE: Added || exit to avoid installing requirements in system python if the virtual environment can't be loaded source ohmpy/bin/activate || exit 1 # NOTE: Added || exit to avoid installing requirements in system python if the virtual environment can't be loaded
......
...@@ -16,7 +16,7 @@ OhmPi project ...@@ -16,7 +16,7 @@ OhmPi project
| Rémi CLEMENT, Vivien DUBOIS, Nicolas Forquet, INRAE, REVERSAAL, Villeurbanne, France | Rémi CLEMENT, Vivien DUBOIS, Nicolas Forquet, INRAE, REVERSAAL, Villeurbanne, France
| Yannick FARGIER, GERS-RRO, Univ Gustave Eiffel, IFSTTAR, Lyon, France | Yannick FARGIER, GERS-RRO, Univ Gustave Eiffel, IFSTTAR, Lyon, France
| Hélène GUYARD, IGE Grenoble, Université Grenoble Alpes, Grenoble, France | Hélène GUYARD, IGE Grenoble, Université Grenoble Alpes, Grenoble, France
| Olivier KAUFMANN, Arnaud WATELET, Université de Mons, Mons, Belgium | Olivier KAUFMANN, Arnaud WATLET, Université de Mons, Mons, Belgium
| Guillaume BLANCHY, ILVO, Merelbeke, Belgium| | Guillaume BLANCHY, ILVO, Merelbeke, Belgium|
......
...@@ -159,7 +159,7 @@ which allows to realize precise current measurement around a shunt resistor. The ...@@ -159,7 +159,7 @@ which allows to realize precise current measurement around a shunt resistor. The
.. warning:: .. warning::
In this version, We used a shunt resistor of 2 ohms, which limits the current measurement to 48 mA. If the current is higher than this value, you just have to decrease the value of the shunt resistor.Change the shunt value in the code. In this version, we used a shunt resistor of 2 ohms, which limits the current measurement to 48 mA. If the current is higher than this value, you just have to decrease the value of the shunt resistor. Don't forget to change the shunt value in the config.py file (value associated to key 'R_shunt' in the OHMPI_CONFIG dict).
......
...@@ -101,11 +101,11 @@ Loggers ...@@ -101,11 +101,11 @@ Loggers
------- -------
Loggers have been introduced in this release. They use the excellent logging python package. Loggers have been introduced in this release. They use the excellent logging python package.
Specific handlers have been implemented for running with ohmpi.py (one for logging to an mqtt broker (see `MQTT interface`_ for more details) and one for creating zipped rotated logs on disk. Specific handlers have been implemented for running with ohmpi.py (one for logging to an mqtt broker (see `MQTT interface`_ for more details) and one for creating zipped rotated logs on disk).
Two loggers have been defined. The first one is dedicated to log operations execution. It is named exec_logger. The second one is dedicated to acquisition data. A third one is planned to log state of health data (SOH) in a future version. Two loggers have been defined. The first one is dedicated to log operations execution. It is named exec_logger. The second one, named data_logger, is dedicated to log data. A third one is planned to log the state of health (SOH) of the system in a future version.
In the default version, logs are written to the console (print-like), stored locally in files (a zip is created after some time i.e. every day and/or when the size of the log exceeds a maximum size) and sent to an MQTT broker. Different logging levels may be defined for the different logs and handlers in the `Configuration file`_. By default, logs are written to the console (print-like), stored locally in files (a zip is created after some time i.e. every day and/or when the size of the log exceeds a maximum size) and sent to an MQTT broker. Different logging levels may be defined for the different logs and handlers in the `Configuration file`_.
Advanced users may write new handlers and edit the `setup_loggers.py` file to customize the logging mechanisms to their needs. Advanced users may write new handlers and edit the `setup_loggers.py` file to customize the logging mechanisms to their needs.
...@@ -138,9 +138,9 @@ Web interface ...@@ -138,9 +138,9 @@ Web interface
This is a user friendly graphical interface for new users as well as running quick and easy acquisitions. This is a user friendly graphical interface for new users as well as running quick and easy acquisitions.
The raspberrypi of the OhmPi is used as a Wifi Access Point (AP) and runs The Raspberry Pi of the OhmPi is used as a Wi-Fi Access Point (AP) and runs
a small webserver to serve the 'index.html' interface. Using a laptop or a small webserver to serve the 'index.html' interface. Using a laptop or
a mobile phone connected to the wifi of the Raspberry Pi, one can see this a mobile phone connected to the Wi-Fi of the Raspberry Pi, one can see this
interface, upload sequences, change parameters, run a sequence and download data. interface, upload sequences, change parameters, run a sequence and download data.
To configure the Raspberry Pi to act as an access point and run To configure the Raspberry Pi to act as an access point and run
...@@ -246,7 +246,7 @@ An example of MQTT broker that can be used is `Mosquitto <https://mosquitto.org/ ...@@ -246,7 +246,7 @@ An example of MQTT broker that can be used is `Mosquitto <https://mosquitto.org/
MQTT messages include logging messages from the OhmPi and commands sent to the OhmPi. These messages can be examined easily using a third party software such as `MQTT Explorer <http://mqtt-explorer.com/>`_. MQTT messages include logging messages from the OhmPi and commands sent to the OhmPi. These messages can be examined easily using a third party software such as `MQTT Explorer <http://mqtt-explorer.com/>`_.
Commands send on the broker are received by the ohmpi.py script that runs on the OhmPi (make sure ohmpi.py starts on reboot) and further processed. Commands sent on the broker are received by the ohmpi.py script that runs on the OhmPi (make sure ohmpi.py starts on reboot) and further processed.
MQTT commands are sent in JSON format following the Python API with kwargs as illustrated below: MQTT commands are sent in JSON format following the Python API with kwargs as illustrated below:
.. code-block:: json .. code-block:: json
...@@ -302,10 +302,25 @@ MQTT commands are sent in JSON format following the Python API with kwargs as il ...@@ -302,10 +302,25 @@ MQTT commands are sent in JSON format following the Python API with kwargs as il
Custom processing of messages and tailor-made dashboards for monitoring experiments may be designed using a browser-based flow editor such as `Node-red <http://mqtt-explorer.com/>`_. Custom processing of messages and tailor-made dashboards for monitoring experiments may be designed using a browser-based flow editor such as `Node-red <http://mqtt-explorer.com/>`_.
This may help designing complex IoT experiments and monitoring systems in which OhmPi is a component. This may help designing complex IoT experiments and monitoring systems in which OhmPi is a component.
An example of a simple flow incorporating execution commands and data outputs from OhmPi can be found in the OhmPi examples. Examples incorporating execution commands and data outputs from OhmPi can be found in the OhmPi examples. Once Node-RED is installed on the OhmPi, these examples can be accessed separately by running a command in the console such as :
.. figure:: img/node-red-flow.png .. code-block:: console
node-red basic_ohmpi_flows_node-red.json
These examples may require installing some additional node packages in order to work properly. This can be done in the `Palette Manager <https://nodered.org/docs/user-guide/editor/palette/manager> within Node-RED.
.. figure:: img/node-red_flow.png
Example flow in node-red to interact with an OhmPi. Example flow in node-red to interact with an OhmPi.
.. figure:: img/node-red_interface_control.png
Example of a dashboard UI created with node-red to interact with an OhmPi - control tab.
.. figure:: img/node-red_interface_data.png
Example of a dashboard UI created with node-red to interact with an OhmPi - data visualization tab.
For more documentation dedicated to node-red, please refer to the Node-red `cookbooks <https://cookbook.nodered.org/>`_. For more documentation dedicated to node-red, please refer to the Node-red `cookbooks <https://cookbook.nodered.org/>`_.
doc/source/img/architecture.png

148 KB | W: | H:

doc/source/img/architecture.png

78.3 KB | W: | H:

doc/source/img/architecture.png
doc/source/img/architecture.png
doc/source/img/architecture.png
doc/source/img/architecture.png
  • 2-up
  • Swipe
  • Onion skin
doc/source/img/node-red_flow.png

158 KB

doc/source/img/node-red_interface_control.png

198 KB

doc/source/img/node-red_interface_data.png

188 KB

...@@ -6,6 +6,280 @@ ...@@ -6,6 +6,280 @@
"disabled": false, "disabled": false,
"info": "" "info": ""
}, },
{
"id": "6ae7e77e.04c64",
"type": "mqtt-broker",
"name": "ohmpi_local_broker",
"broker": "127.0.0.1",
"port": "1883",
"clientid": "",
"autoConnect": true,
"usetls": false,
"compatmode": false,
"protocolVersion": "4",
"keepalive": "60",
"cleansession": true,
"birthTopic": "",
"birthQos": "0",
"birthPayload": "",
"birthMsg": {},
"closeTopic": "",
"closeQos": "0",
"closePayload": "",
"closeMsg": {},
"willTopic": "",
"willQos": "0",
"willPayload": "",
"willMsg": {},
"userProps": "",
"sessionExpiry": ""
},
{
"id": "142ad6ae.d55e29",
"type": "ui_group",
"name": "Buttons",
"tab": "5d888f29.07334",
"order": 1,
"disp": true,
"width": "6",
"collapse": false
},
{
"id": "b0990b3c5ff3c09a",
"type": "ui_group",
"name": "Messages",
"tab": "5d888f29.07334",
"order": 2,
"disp": true,
"width": "16",
"collapse": true
},
{
"id": "7792ecc419ecbb59",
"type": "ui_group",
"name": "Messages",
"tab": "5d888f29.07334",
"order": 3,
"disp": true,
"width": "16",
"collapse": true,
"className": ""
},
{
"id": "5d888f29.07334",
"type": "ui_tab",
"name": "Home",
"icon": "dashboard",
"disabled": false,
"hidden": false
},
{
"id": "f8ac98bca72a3bae",
"type": "ui_base",
"theme": {
"name": "theme-light",
"lightTheme": {
"default": "#0094CE",
"baseColor": "#0094CE",
"baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif",
"edited": true,
"reset": false
},
"darkTheme": {
"default": "#097479",
"baseColor": "#097479",
"baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif",
"edited": false
},
"customTheme": {
"name": "Untitled Theme 1",
"default": "#4B7930",
"baseColor": "#4B7930",
"baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif"
},
"themeState": {
"base-color": {
"default": "#0094CE",
"value": "#0094CE",
"edited": false
},
"page-titlebar-backgroundColor": {
"value": "#0094CE",
"edited": false
},
"page-backgroundColor": {
"value": "#fafafa",
"edited": false
},
"page-sidebar-backgroundColor": {
"value": "#ffffff",
"edited": false
},
"group-textColor": {
"value": "#1bbfff",
"edited": false
},
"group-borderColor": {
"value": "#ffffff",
"edited": false
},
"group-backgroundColor": {
"value": "#ffffff",
"edited": false
},
"widget-textColor": {
"value": "#111111",
"edited": false
},
"widget-backgroundColor": {
"value": "#0094ce",
"edited": false
},
"widget-borderColor": {
"value": "#ffffff",
"edited": false
},
"base-font": {
"value": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif"
}
},
"angularTheme": {
"primary": "indigo",
"accents": "blue",
"warn": "red",
"background": "grey",
"palette": "light"
}
},
"site": {
"name": "Node-RED Dashboard",
"hideToolbar": "false",
"allowSwipe": "false",
"lockMenu": "false",
"allowTempTheme": "true",
"dateFormat": "DD/MM/YYYY",
"sizes": {
"sx": 48,
"sy": 48,
"gx": 6,
"gy": 6,
"cx": 6,
"cy": 6,
"px": 0,
"py": 0
}
}
},
{
"id": "0ee92068968f05f1",
"type": "ui_spacer",
"z": "b19c51e9d4d25a33",
"name": "spacer",
"group": "7792ecc419ecbb59",
"order": 2,
"width": 5,
"height": 1
},
{
"id": "1b78d7bfae14207e",
"type": "ui_spacer",
"z": "b19c51e9d4d25a33",
"name": "spacer",
"group": "7792ecc419ecbb59",
"order": 3,
"width": 5,
"height": 1
},
{
"id": "0f72806163574caf",
"type": "ui_spacer",
"z": "b19c51e9d4d25a33",
"name": "spacer",
"group": "7792ecc419ecbb59",
"order": 4,
"width": 5,
"height": 1
},
{
"id": "4258f679adeaa5f6",
"type": "ui_spacer",
"z": "b19c51e9d4d25a33",
"name": "spacer",
"group": "7792ecc419ecbb59",
"order": 5,
"width": 5,
"height": 1
},
{
"id": "7f92e186430dc718",
"type": "ui_spacer",
"z": "b19c51e9d4d25a33",
"name": "spacer",
"group": "7792ecc419ecbb59",
"order": 6,
"width": 5,
"height": 1
},
{
"id": "41d806cf3e920625",
"type": "ui_spacer",
"z": "b19c51e9d4d25a33",
"name": "spacer",
"group": "7792ecc419ecbb59",
"order": 7,
"width": 5,
"height": 1
},
{
"id": "3430fccc9184a3a6",
"type": "ui_spacer",
"z": "b19c51e9d4d25a33",
"name": "spacer",
"group": "7792ecc419ecbb59",
"order": 8,
"width": 5,
"height": 1
},
{
"id": "88b1f28698ec539f",
"type": "ui_spacer",
"z": "b19c51e9d4d25a33",
"name": "spacer",
"group": "142ad6ae.d55e29",
"order": 3,
"width": 4,
"height": 1
},
{
"id": "d35dbad3536d9071",
"type": "ui_spacer",
"z": "b19c51e9d4d25a33",
"name": "spacer",
"group": "142ad6ae.d55e29",
"order": 7,
"width": 4,
"height": 1
},
{
"id": "d6098d03085c5fdd",
"type": "ui_spacer",
"z": "b19c51e9d4d25a33",
"name": "spacer",
"group": "142ad6ae.d55e29",
"order": 8,
"width": 4,
"height": 1
},
{
"id": "ae2e4e8d768a549e",
"type": "ui_spacer",
"z": "b19c51e9d4d25a33",
"name": "spacer",
"group": "142ad6ae.d55e29",
"order": 9,
"width": 4,
"height": 1
},
{ {
"id": "0f23781293c4b819", "id": "0f23781293c4b819",
"type": "mqtt in", "type": "mqtt in",
...@@ -93,8 +367,8 @@ ...@@ -93,8 +367,8 @@
"name": "Run sequence", "name": "Run sequence",
"group": "142ad6ae.d55e29", "group": "142ad6ae.d55e29",
"order": 1, "order": 1,
"width": "1", "width": 1,
"height": "1", "height": 1,
"passthru": false, "passthru": false,
"label": "&#9210;", "label": "&#9210;",
"tooltip": "run sequence", "tooltip": "run sequence",
...@@ -121,8 +395,8 @@ ...@@ -121,8 +395,8 @@
"name": "Interrupt", "name": "Interrupt",
"group": "142ad6ae.d55e29", "group": "142ad6ae.d55e29",
"order": 2, "order": 2,
"width": "1", "width": 1,
"height": "1", "height": 1,
"passthru": false, "passthru": false,
"label": " &#9726;", "label": " &#9726;",
"tooltip": "interrupt sequence", "tooltip": "interrupt sequence",
...@@ -148,8 +422,8 @@ ...@@ -148,8 +422,8 @@
"z": "b19c51e9d4d25a33", "z": "b19c51e9d4d25a33",
"group": "b0990b3c5ff3c09a", "group": "b0990b3c5ff3c09a",
"order": 2, "order": 2,
"width": "16", "width": 16,
"height": "3", "height": 3,
"name": "MQTT exec", "name": "MQTT exec",
"label": "Execution", "label": "Execution",
"format": "{{msg.payload}}", "format": "{{msg.payload}}",
...@@ -165,8 +439,8 @@ ...@@ -165,8 +439,8 @@
"z": "b19c51e9d4d25a33", "z": "b19c51e9d4d25a33",
"group": "b0990b3c5ff3c09a", "group": "b0990b3c5ff3c09a",
"order": 3, "order": 3,
"width": "16", "width": 16,
"height": "3", "height": 3,
"name": "MQTT Data", "name": "MQTT Data",
"label": "Data", "label": "Data",
"format": "{{msg.payload}}", "format": "{{msg.payload}}",
...@@ -232,7 +506,7 @@ ...@@ -232,7 +506,7 @@
"tooltip": "", "tooltip": "",
"place": "Select option", "place": "Select option",
"group": "142ad6ae.d55e29", "group": "142ad6ae.d55e29",
"order": 5, "order": 4,
"width": 0, "width": 0,
"height": 0, "height": 0,
"passthru": true, "passthru": true,
...@@ -365,8 +639,8 @@ ...@@ -365,8 +639,8 @@
"z": "b19c51e9d4d25a33", "z": "b19c51e9d4d25a33",
"group": "142ad6ae.d55e29", "group": "142ad6ae.d55e29",
"order": 6, "order": 6,
"width": "2", "width": 2,
"height": "3", "height": 3,
"name": "", "name": "",
"label": "Command to send", "label": "Command to send",
"format": "{{msg.payload}}", "format": "{{msg.payload}}",
...@@ -399,7 +673,7 @@ ...@@ -399,7 +673,7 @@
"z": "b19c51e9d4d25a33", "z": "b19c51e9d4d25a33",
"name": "", "name": "",
"group": "142ad6ae.d55e29", "group": "142ad6ae.d55e29",
"order": 7, "order": 10,
"width": 0, "width": 0,
"height": 0, "height": 0,
"passthru": false, "passthru": false,
...@@ -537,9 +811,9 @@ ...@@ -537,9 +811,9 @@
"z": "b19c51e9d4d25a33", "z": "b19c51e9d4d25a33",
"name": "", "name": "",
"group": "7792ecc419ecbb59", "group": "7792ecc419ecbb59",
"order": 3, "order": 1,
"width": "11", "width": 11,
"height": "7", "height": 7,
"label": "chart", "label": "chart",
"chartType": "line", "chartType": "line",
"legend": "true", "legend": "true",
...@@ -617,7 +891,7 @@ ...@@ -617,7 +891,7 @@
"z": "b19c51e9d4d25a33", "z": "b19c51e9d4d25a33",
"name": "", "name": "",
"group": "7792ecc419ecbb59", "group": "7792ecc419ecbb59",
"order": 4, "order": 9,
"width": 0, "width": 0,
"height": 0, "height": 0,
"gtype": "gage", "gtype": "gage",
...@@ -711,72 +985,5 @@ ...@@ -711,72 +985,5 @@
"91523713d9d4918e" "91523713d9d4918e"
] ]
] ]
},
{
"id": "6ae7e77e.04c64",
"type": "mqtt-broker",
"name": "ohmpi_local_broker",
"broker": "127.0.0.1",
"port": "1883",
"clientid": "",
"autoConnect": true,
"usetls": false,
"compatmode": false,
"protocolVersion": "4",
"keepalive": "60",
"cleansession": true,
"birthTopic": "",
"birthQos": "0",
"birthPayload": "",
"birthMsg": {},
"closeTopic": "",
"closeQos": "0",
"closePayload": "",
"closeMsg": {},
"willTopic": "",
"willQos": "0",
"willPayload": "",
"willMsg": {},
"userProps": "",
"sessionExpiry": ""
},
{
"id": "142ad6ae.d55e29",
"type": "ui_group",
"name": "Buttons",
"tab": "5d888f29.07334",
"order": 3,
"disp": true,
"width": "6",
"collapse": false
},
{
"id": "b0990b3c5ff3c09a",
"type": "ui_group",
"name": "Messages",
"tab": "5d888f29.07334",
"order": 2,
"disp": true,
"width": "16",
"collapse": true
},
{
"id": "7792ecc419ecbb59",
"type": "ui_group",
"name": "Messages",
"tab": "5d888f29.07334",
"order": 2,
"disp": true,
"width": "16",
"collapse": true,
"className": ""
},
{
"id": "5d888f29.07334",
"type": "ui_tab",
"name": "Home",
"icon": "dashboard",
"disabled": false,
"hidden": false
} }
] ]
\ No newline at end of file
This diff is collapsed.
...@@ -6,7 +6,7 @@ Hardware: Licensed under CERN-OHL-S v2 or any later version ...@@ -6,7 +6,7 @@ Hardware: Licensed under CERN-OHL-S v2 or any later version
Software: Licensed under the GNU General Public License v3.0 Software: Licensed under the GNU General Public License v3.0
Ohmpi.py is a program to control a low-cost and open hardware resistivity meter OhmPi that has been developed by Ohmpi.py is a program to control a low-cost and open hardware resistivity meter OhmPi that has been developed by
Rémi CLEMENT (INRAE), Vivien DUBOIS (INRAE), Hélène GUYARD (IGE), Nicolas FORQUET (INRAE), Yannick FARGIER (IFSTTAR) Rémi CLEMENT (INRAE), Vivien DUBOIS (INRAE), Hélène GUYARD (IGE), Nicolas FORQUET (INRAE), Yannick FARGIER (IFSTTAR)
Olivier KAUFMANN (UMONS), Arnaud WATELET (UMONS) and Guillaume BLANCHY (FNRS/ULiege). Olivier KAUFMANN (UMONS), Arnaud WATLET (UMONS) and Guillaume BLANCHY (FNRS/ULiege).
""" """
import os import os
...@@ -47,8 +47,6 @@ except ImportError as error: ...@@ -47,8 +47,6 @@ except ImportError as error:
except Exception as error: except Exception as error:
print(colored(f'Unexpected error: {error}', 'red')) print(colored(f'Unexpected error: {error}', 'red'))
arm64_imports = None arm64_imports = None
exit()
class OhmPi(object): class OhmPi(object):
""" OhmPi class. """ OhmPi class.
...@@ -1068,10 +1066,26 @@ class OhmPi(object): ...@@ -1068,10 +1066,26 @@ class OhmPi(object):
if self.on_pi: if self.on_pi:
acquired_data = self.run_measurement(quad, **kwargs) acquired_data = self.run_measurement(quad, **kwargs)
else: # for testing, generate random data else: # for testing, generate random data
sum_vmn = np.random.rand(1)[0] * 1000.
sum_i = np.random.rand(1)[0] * 100.
cmd_id = np.random.randint(1000)
acquired_data = { acquired_data = {
'A': [quad[0]], 'B': [quad[1]], 'M': [quad[2]], 'N': [quad[3]], "time": datetime.now().isoformat(),
'R [ohm]': np.abs(np.random.randn(1)) "A": quad[0],
"B": quad[1],
"M": quad[2],
"N": quad[3],
"inj time [ms]": self.settings['injection_duration'] * 1000.,
"Vmn [mV]": sum_vmn,
"I [mA]": sum_i,
"R [ohm]": sum_vmn / sum_i,
"Ps [mV]": np.random.randn(1)[0] * 100.,
"nbStack": self.settings['nb_stack'],
"Tx [V]": np.random.randn(1)[0] * 5.,
"CPU temp [degC]": np.random.randn(1)[0] * 50.,
"Nb samples [-]": self.nb_samples,
} }
self.data_logger.info(acquired_data)
# switch mux off # switch mux off
self.switch_mux_off(quad) self.switch_mux_off(quad)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment