Commit 3e663b80 authored by Guillaume Blanchy's avatar Guillaume Blanchy
Browse files

Merge branch 'mqtt' of https://gitlab.irstea.fr/reversaal/OhmPi into mqtt

Showing with 43 additions and 42 deletions
+43 -42
...@@ -186,7 +186,7 @@ Interface to communicate with the Pi designed for the Internet of Things (IoT). ...@@ -186,7 +186,7 @@ Interface to communicate with the Pi designed for the Internet of Things (IoT).
{ {
"cmd_id": "3fzxv121UITwGjWYgcz4xw", "cmd_id": "3fzxv121UITwGjWYgcz4xw",
"cmd": "update_settings", "cmd": "update_settings",Depending on the experiment needs, MQTT brokers can be set up locally on the Raspberry Pi, on a master Raspberry Pi or on a local or remote server.
"kwargs": { "kwargs": {
"config": { "config": {
"nb_meas": 2, "nb_meas": 2,
...@@ -231,8 +231,8 @@ Interface to communicate with the Pi designed for the Internet of Things (IoT). ...@@ -231,8 +231,8 @@ Interface to communicate with the Pi designed for the Internet of Things (IoT).
"cmd": "interrupt", "cmd": "interrupt",
} }
A local Mosquitto broker can be set up and enabled to run as a service on the OhmPi using the bash script install_local_mqtt_broker.sh.
The mqtt messages can be interfaced easily using the third party software `MQTT Explorer <http://mqtt-explorer.com/>`_. They can also form part of a browser-based flow editor such as `Node-red <http://mqtt-explorer.com/>`_ which can help desinging more 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. For more documentation dedicated to node-red, please refer to the Node-red `cookbooks <https://cookbook.nodered.org/>`_.
......
...@@ -204,7 +204,7 @@ class OhmPi(object): ...@@ -204,7 +204,7 @@ class OhmPi(object):
' Use python/ipython to interact with OhmPi object...') ' Use python/ipython to interact with OhmPi object...')
@staticmethod @staticmethod
def append_and_save(filename, last_measurement): def append_and_save(filename: str, last_measurement: dict, cmd_id=None):
"""Appends and saves the last measurement dict. """Appends and saves the last measurement dict.
Parameters Parameters
...@@ -429,7 +429,7 @@ class OhmPi(object): ...@@ -429,7 +429,7 @@ class OhmPi(object):
self.exec_logger.debug(f'Setting gain to {gain}') self.exec_logger.debug(f'Setting gain to {gain}')
return gain return gain
def interrupt(self): def interrupt(self, cmd_id=None):
"""Interrupts the acquisition. """ """Interrupts the acquisition. """
self.status = 'stopping' self.status = 'stopping'
if self.thread is not None: if self.thread is not None:
...@@ -439,7 +439,7 @@ class OhmPi(object): ...@@ -439,7 +439,7 @@ class OhmPi(object):
self.exec_logger.debug('No sequence measurement thread to interrupt.') self.exec_logger.debug('No sequence measurement thread to interrupt.')
self.exec_logger.debug(f'Status: {self.status}') self.exec_logger.debug(f'Status: {self.status}')
def load_sequence(self, filename: str): def load_sequence(self, filename: str, cmd_id=None):
"""Reads quadrupole sequence from file. """Reads quadrupole sequence from file.
Parameters Parameters
...@@ -485,11 +485,11 @@ class OhmPi(object): ...@@ -485,11 +485,11 @@ class OhmPi(object):
self.sequence = sequence self.sequence = sequence
def measure(self, *args, **kwargs): def measure(self, **kwargs):
warnings.warn('This function is deprecated. Use run_multiple_sequences() instead.', DeprecationWarning) warnings.warn('This function is deprecated. Use run_multiple_sequences() instead.', DeprecationWarning)
self.run_multiple_sequences(self, *args, **kwargs) self.run_multiple_sequences(self, **kwargs)
def _process_commands(self, message): def _process_commands(self, message: str):
"""Processes commands received from the controller(s) """Processes commands received from the controller(s)
Parameters Parameters
...@@ -505,17 +505,16 @@ class OhmPi(object): ...@@ -505,17 +505,16 @@ class OhmPi(object):
self.exec_logger.debug(f'Decoded message {decoded_message}') self.exec_logger.debug(f'Decoded message {decoded_message}')
cmd_id = decoded_message.pop('cmd_id', None) cmd_id = decoded_message.pop('cmd_id', None)
cmd = decoded_message.pop('cmd', None) cmd = decoded_message.pop('cmd', None)
args = None
# args = decoded_message.pop('args', None) # args = decoded_message.pop('args', None)
# if args is not None: # if args is not None:
# if len(args) != 0: # if len(args) != 0:
# if args[0] != '[': # if args[0] != '[':
# args = f'["{args}"]' # args = f'["{args}"]'
# self.exec_logger.debug(f'args to decode: {args}') # self.exec_logger.debug(f'args to decode: {args}')
# args = json.loads(args) if args != '[]' else None # args = json.loads(args) if args != '[]' else None
# self.exec_logger.debug(f'Decoded args {args}') # self.exec_logger.debug(f'Decoded args {args}')
# else: # else:
# args = None # args = None
kwargs = decoded_message.pop('kwargs', None) kwargs = decoded_message.pop('kwargs', None)
# if kwargs is not None: # if kwargs is not None:
# if len(kwargs) != 0: # if len(kwargs) != 0:
...@@ -526,27 +525,29 @@ class OhmPi(object): ...@@ -526,27 +525,29 @@ class OhmPi(object):
# self.exec_logger.debug(f'Decoded kwargs {kwargs}') # self.exec_logger.debug(f'Decoded kwargs {kwargs}')
# else: # else:
# kwargs = None # kwargs = None
self.exec_logger.debug(f"Calling method {cmd}(" self.exec_logger.debug(f"Calling method {cmd}({str(kwargs) if kwargs is not None else ''})")
f"{str(kwargs) if kwargs is not None else ''})") # self.exec_logger.debug(f"Calling method {cmd}({str(args) + ', ' if args is not None else ''}"
# f"{str(kwargs) if kwargs is not None else ''})")
if cmd_id is None: if cmd_id is None:
self.exec_logger.warning('You should use a unique identifier for cmd_id') self.exec_logger.warning('You should use a unique identifier for cmd_id')
if cmd is not None: if cmd is not None:
try: try:
if args is None: # if args is None:
if kwargs is None: # if kwargs is None:
output = getattr(self, cmd)() # output = getattr(self, cmd)()
else: # else:
output = getattr(self, cmd)(**kwargs) # output = getattr(self, cmd)(**kwargs)
# else:
if kwargs is None:
output = getattr(self, cmd)()
else: else:
if kwargs is None: output = getattr(self, cmd)(**kwargs)
output = getattr(self, cmd)(*args)
else:
output = getattr(self, cmd)(*args, **kwargs)
status = True status = True
except Exception as e: except Exception as e:
self.exec_logger.error( self.exec_logger.error(
f"Unable to execute {cmd}("#{str(args) + ', ' if args is not None else ''}" f"Unable to execute {cmd}({str(kwargs) if kwargs is not None else ''}): {e}")
f"{str(kwargs) if kwargs is not None else ''}): {e}") # f"Unable to execute {cmd}({str(args) + ', ' if args is not None else ''}"
# f"{str(kwargs) if kwargs is not None else ''}): {e}")
status = False status = False
except Exception as e: except Exception as e:
self.exec_logger.warning(f'Unable to decode command {message}: {e}') self.exec_logger.warning(f'Unable to decode command {message}: {e}')
...@@ -557,7 +558,7 @@ class OhmPi(object): ...@@ -557,7 +558,7 @@ class OhmPi(object):
self.exec_logger.debug(f'Execution report: {reply}') self.exec_logger.debug(f'Execution report: {reply}')
@staticmethod @staticmethod
def quit(self): def quit(self, cmd_id=None):
"""Quits OhmPi""" """Quits OhmPi"""
exit() exit()
...@@ -578,11 +579,11 @@ class OhmPi(object): ...@@ -578,11 +579,11 @@ class OhmPi(object):
self.board_version = OHMPI_CONFIG['board_version'] self.board_version = OHMPI_CONFIG['board_version']
self.exec_logger.debug(f'OHMPI_CONFIG = {str(OHMPI_CONFIG)}') self.exec_logger.debug(f'OHMPI_CONFIG = {str(OHMPI_CONFIG)}')
def read_quad(self, filename): def read_quad(self, **kwargs):
warnings.warn('This function is deprecated. Use load_sequence instead.', DeprecationWarning) warnings.warn('This function is deprecated. Use load_sequence instead.', DeprecationWarning)
self.load_sequence(filename) self.load_sequence(**kwargs)
def restart(self): def restart(self, cmd_id=None):
self.exec_logger.info('Restarting pi...') self.exec_logger.info('Restarting pi...')
os.system('reboot') os.system('reboot')
...@@ -1101,7 +1102,7 @@ class OhmPi(object): ...@@ -1101,7 +1102,7 @@ class OhmPi(object):
self.thread.start() self.thread.start()
self.status = 'idle' self.status = 'idle'
def rs_check(self, tx_volt=12): def rs_check(self, tx_volt=12, cmd_id=None):
"""Checks contact resistances""" """Checks contact resistances"""
# create custom sequence where MN == AB # create custom sequence where MN == AB
# we only check the electrodes which are in the sequence (not all might be connected) # we only check the electrodes which are in the sequence (not all might be connected)
...@@ -1259,7 +1260,7 @@ class OhmPi(object): ...@@ -1259,7 +1260,7 @@ class OhmPi(object):
for i in range(0, 4): for i in range(0, 4):
if quadrupole[i] > 0: if quadrupole[i] > 0:
self._switch_mux(quadrupole[i], 'off', roles[i]) self._switch_mux(quadrupole[i], 'off', roles[i])
def set_sequence(self, sequence=None): def set_sequence(self, sequence=None, cmd_id=None):
try: try:
self.sequence = np.array(sequence).astype(int) self.sequence = np.array(sequence).astype(int)
# self.sequence = np.loadtxt(StringIO(sequence)).astype('uint32') # self.sequence = np.loadtxt(StringIO(sequence)).astype('uint32')
...@@ -1268,7 +1269,7 @@ class OhmPi(object): ...@@ -1268,7 +1269,7 @@ class OhmPi(object):
self.exec_logger.warning(f'Unable to set sequence: {e}') self.exec_logger.warning(f'Unable to set sequence: {e}')
status = False status = False
def stop(self): def stop(self, cmd_id=None):
warnings.warn('This function is deprecated. Use interrupt instead.', DeprecationWarning) warnings.warn('This function is deprecated. Use interrupt instead.', DeprecationWarning)
self.interrupt() self.interrupt()
...@@ -1316,7 +1317,7 @@ class OhmPi(object): ...@@ -1316,7 +1317,7 @@ class OhmPi(object):
else: else:
self.exec_logger.warning(f'Unable to address electrode nr {electrode_nr}') self.exec_logger.warning(f'Unable to address electrode nr {electrode_nr}')
def switch_mux_on(self, quadrupole): def switch_mux_on(self, quadrupole, cmd_id=None):
"""Switches on multiplexer relays for given quadrupole. """Switches on multiplexer relays for given quadrupole.
Parameters Parameters
...@@ -1333,7 +1334,7 @@ class OhmPi(object): ...@@ -1333,7 +1334,7 @@ class OhmPi(object):
else: else:
self.exec_logger.error('Not switching MUX : A == B -> short circuit risk detected!') self.exec_logger.error('Not switching MUX : A == B -> short circuit risk detected!')
def switch_mux_off(self, quadrupole): def switch_mux_off(self, quadrupole, cmd_id=None):
"""Switches off multiplexer relays for given quadrupole. """Switches off multiplexer relays for given quadrupole.
Parameters Parameters
...@@ -1405,7 +1406,7 @@ class OhmPi(object): ...@@ -1405,7 +1406,7 @@ class OhmPi(object):
assert isinstance(self._sequence, np.ndarray) assert isinstance(self._sequence, np.ndarray)
return self._sequence return self._sequence
def reset_mux(self): def reset_mux(self, cmd_id=None):
"""Switches off all multiplexer relays.""" """Switches off all multiplexer relays."""
if self.on_pi and self.use_mux: if self.on_pi and self.use_mux:
roles = ['A', 'B', 'M', 'N'] roles = ['A', 'B', 'M', 'N']
...@@ -1423,7 +1424,7 @@ class OhmPi(object): ...@@ -1423,7 +1424,7 @@ class OhmPi(object):
warnings.warn('This function is deprecated, use update_settings() instead.', DeprecationWarning) warnings.warn('This function is deprecated, use update_settings() instead.', DeprecationWarning)
self.update_settings(config) self.update_settings(config)
def update_settings(self, config): def update_settings(self, config:str, cmd_id=None):
"""Updates acquisition settings from a json file or dictionary. """Updates acquisition settings from a json file or dictionary.
Parameters can be: Parameters can be:
- nb_electrodes (number of electrode used, if 4, no MUX needed) - nb_electrodes (number of electrode used, if 4, no MUX needed)
......
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