diff --git a/doc/source/V2_00.rst b/doc/source/V2_00.rst index 3d2640bc643166709e4fa1baf1e8c535a36e5c4c..ac8ecc08b289c267d88d534ea1d57fdf17ed518b 100644 --- a/doc/source/V2_00.rst +++ b/doc/source/V2_00.rst @@ -186,7 +186,7 @@ Interface to communicate with the Pi designed for the Internet of Things (IoT). { "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": { "config": { "nb_meas": 2, @@ -231,8 +231,8 @@ Interface to communicate with the Pi designed for the Internet of Things (IoT). "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/>`_. diff --git a/ohmpi.py b/ohmpi.py index a2e23f595be9cb382470d9cce2d6cbfa97dd9df0..6db7b4c10c3a24703605ad83cf0c6c5bf5ade426 100644 --- a/ohmpi.py +++ b/ohmpi.py @@ -204,7 +204,7 @@ class OhmPi(object): ' Use python/ipython to interact with OhmPi object...') @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. Parameters @@ -429,7 +429,7 @@ class OhmPi(object): self.exec_logger.debug(f'Setting gain to {gain}') return gain - def interrupt(self): + def interrupt(self, cmd_id=None): """Interrupts the acquisition. """ self.status = 'stopping' if self.thread is not None: @@ -439,7 +439,7 @@ class OhmPi(object): self.exec_logger.debug('No sequence measurement thread to interrupt.') 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. Parameters @@ -485,11 +485,11 @@ class OhmPi(object): self.sequence = sequence - def measure(self, *args, **kwargs): + def measure(self, **kwargs): 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) Parameters @@ -505,17 +505,16 @@ class OhmPi(object): self.exec_logger.debug(f'Decoded message {decoded_message}') cmd_id = decoded_message.pop('cmd_id', None) cmd = decoded_message.pop('cmd', None) - args = None # args = decoded_message.pop('args', None) # if args is not None: - # if len(args) != 0: - # if args[0] != '[': - # args = f'["{args}"]' - # self.exec_logger.debug(f'args to decode: {args}') - # args = json.loads(args) if args != '[]' else None - # self.exec_logger.debug(f'Decoded args {args}') - # else: - # args = None + # if len(args) != 0: + # if args[0] != '[': + # args = f'["{args}"]' + # self.exec_logger.debug(f'args to decode: {args}') + # args = json.loads(args) if args != '[]' else None + # self.exec_logger.debug(f'Decoded args {args}') + # else: + # args = None kwargs = decoded_message.pop('kwargs', None) # if kwargs is not None: # if len(kwargs) != 0: @@ -526,27 +525,29 @@ class OhmPi(object): # self.exec_logger.debug(f'Decoded kwargs {kwargs}') # else: # kwargs = None - self.exec_logger.debug(f"Calling method {cmd}(" - f"{str(kwargs) if kwargs is not None else ''})") + self.exec_logger.debug(f"Calling method {cmd}({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: self.exec_logger.warning('You should use a unique identifier for cmd_id') if cmd is not None: try: - if args is None: - if kwargs is None: - output = getattr(self, cmd)() - else: - output = getattr(self, cmd)(**kwargs) + # if args is None: + # if kwargs is None: + # output = getattr(self, cmd)() + # else: + # output = getattr(self, cmd)(**kwargs) + # else: + if kwargs is None: + output = getattr(self, cmd)() else: - if kwargs is None: - output = getattr(self, cmd)(*args) - else: - output = getattr(self, cmd)(*args, **kwargs) + output = getattr(self, cmd)(**kwargs) status = True except Exception as e: self.exec_logger.error( - f"Unable to execute {cmd}("#{str(args) + ', ' if args is not None else ''}" - f"{str(kwargs) if kwargs is not None else ''}): {e}") + f"Unable to execute {cmd}({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 except Exception as e: self.exec_logger.warning(f'Unable to decode command {message}: {e}') @@ -557,7 +558,7 @@ class OhmPi(object): self.exec_logger.debug(f'Execution report: {reply}') @staticmethod - def quit(self): + def quit(self, cmd_id=None): """Quits OhmPi""" exit() @@ -578,11 +579,11 @@ class OhmPi(object): self.board_version = OHMPI_CONFIG['board_version'] 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) - self.load_sequence(filename) + self.load_sequence(**kwargs) - def restart(self): + def restart(self, cmd_id=None): self.exec_logger.info('Restarting pi...') os.system('reboot') @@ -1101,7 +1102,7 @@ class OhmPi(object): self.thread.start() self.status = 'idle' - def rs_check(self, tx_volt=12): + def rs_check(self, tx_volt=12, cmd_id=None): """Checks contact resistances""" # create custom sequence where MN == AB # we only check the electrodes which are in the sequence (not all might be connected) @@ -1259,7 +1260,7 @@ class OhmPi(object): for i in range(0, 4): if quadrupole[i] > 0: self._switch_mux(quadrupole[i], 'off', roles[i]) - def set_sequence(self, sequence=None): + def set_sequence(self, sequence=None, cmd_id=None): try: self.sequence = np.array(sequence).astype(int) # self.sequence = np.loadtxt(StringIO(sequence)).astype('uint32') @@ -1268,7 +1269,7 @@ class OhmPi(object): self.exec_logger.warning(f'Unable to set sequence: {e}') status = False - def stop(self): + def stop(self, cmd_id=None): warnings.warn('This function is deprecated. Use interrupt instead.', DeprecationWarning) self.interrupt() @@ -1316,7 +1317,7 @@ class OhmPi(object): else: 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. Parameters @@ -1333,7 +1334,7 @@ class OhmPi(object): else: 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. Parameters @@ -1405,7 +1406,7 @@ class OhmPi(object): assert isinstance(self._sequence, np.ndarray) return self._sequence - def reset_mux(self): + def reset_mux(self, cmd_id=None): """Switches off all multiplexer relays.""" if self.on_pi and self.use_mux: roles = ['A', 'B', 'M', 'N'] @@ -1423,7 +1424,7 @@ class OhmPi(object): warnings.warn('This function is deprecated, use update_settings() instead.', DeprecationWarning) 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. Parameters can be: - nb_electrodes (number of electrode used, if 4, no MUX needed)