diff --git a/configs/config_mb_2023.py b/configs/config_mb_2023.py index 3b6b704a195a7930eab97492e552242aa08e4ad6..8bd970d8096ec3515ced1a1c9d11ea5e2aeabbc7 100644 --- a/configs/config_mb_2023.py +++ b/configs/config_mb_2023.py @@ -19,7 +19,7 @@ OHMPI_CONFIG = { HARDWARE_CONFIG = { 'ctl': {'model': 'raspberry_pi'}, - 'pwr': {'model': 'pwr_batt', 'voltage': 12.}, + 'pwr': {'model': 'pwr_batt', 'voltage': 12., 'interface_name': 'none'}, 'tx': {'model': 'mb_2023_0_X', 'voltage_max': 12., # Maximum voltage supported by the TX board [V] 'adc_voltage_max': 4800., # Maximum voltage read by the current ADC on the TX board [mA] diff --git a/ohmpi/__init__.py b/ohmpi/__init__.py index 09c495ea868bac310c7f76790aca8a1b691d6de6..d1c1cf1ce4567059e2106febb97432bcdad4cfa1 100644 --- a/ohmpi/__init__.py +++ b/ohmpi/__init__.py @@ -1 +1,2 @@ # from .ohmpi import OhmPi +#from ohmpi.ohmpi import OhmPi diff --git a/ohmpi/config.py b/ohmpi/config.py index 0763f48ca2240311e01b281a1eea9571c324defd..8bd970d8096ec3515ced1a1c9d11ea5e2aeabbc7 100644 --- a/ohmpi/config.py +++ b/ohmpi/config.py @@ -1,7 +1,7 @@ import logging from ohmpi.utils import get_platform -from paho.mqtt.client import MQTTv31 +from paho.mqtt.client import MQTTv31 # noqa _, on_pi = get_platform() # DEFINE THE ID OF YOUR OhmPi @@ -18,25 +18,34 @@ OHMPI_CONFIG = { } HARDWARE_CONFIG = { - 'ctl': {'model' : 'dummy_ctl' - }, - 'tx' : {'model' : 'dummy_tx', - 'current_max': 4800 / 50 / 2, # Maximum current mA - 'r_shunt': 2, # Shunt resistance in Ohms - 'low_battery': 12. # Volts + 'ctl': {'model': 'raspberry_pi'}, + 'pwr': {'model': 'pwr_batt', 'voltage': 12., 'interface_name': 'none'}, + 'tx': {'model': 'mb_2023_0_X', + 'voltage_max': 12., # Maximum voltage supported by the TX board [V] + 'adc_voltage_max': 4800., # Maximum voltage read by the current ADC on the TX board [mA] + 'r_shunt': 2., # Shunt resistance in Ohms + 'interface_name': 'i2c', }, - 'rx' : {'model': 'dummy_rx', + 'rx': {'model': 'mb_2023_0_X', + 'coef_p2': 2.50, # slope for conversion for ADS, measurement in V/V + 'sampling_rate': 50., # number of samples per second + 'interface_name': 'i2c', }, - 'mux': {'model' : 'dummy_mux', - 'max_elec': 64, - 'voltage_max' : 100, - 'current_max' : 3 - } + 'mux': # default properties given in config are system properties that will be + # overwritten by properties defined in each the board dict below. + # if defined in board specs, values out of specs will be bounded to remain in specs + # omitted properties in config will be set to board specs default values if they exist + {'boards': {}, + 'default': {'interface_name': 'i2c', + 'voltage_max': 100., + 'current_max': 3.} + } } + # SET THE LOGGING LEVELS, MQTT BROKERS AND MQTT OPTIONS ACCORDING TO YOUR NEEDS # Execution logging configuration EXEC_LOGGING_CONFIG = { - 'logging_level': logging.INFO, + 'logging_level': logging.DEBUG, # TODO: set logging level back to INFO 'log_file_logging_level': logging.DEBUG, 'logging_to_console': True, 'file_name': f'exec{logging_suffix}.log', @@ -60,8 +69,8 @@ DATA_LOGGING_CONFIG = { # State of Health logging configuration (For a future release) SOH_LOGGING_CONFIG = { 'logging_level': logging.INFO, - 'log_file_logging_level': logging.DEBUG, 'logging_to_console': True, + 'log_file_logging_level': logging.DEBUG, 'file_name': f'soh{logging_suffix}.log', 'max_bytes': 16777216, 'backup_count': 1024, diff --git a/ohmpi/hardware_components/pwr_batt.py b/ohmpi/hardware_components/pwr_batt.py index 650b5dcde3e86f10d7866aa53049032051ce0ee7..dc67c8b88a742df803691446e0474d5f9c557e83 100644 --- a/ohmpi/hardware_components/pwr_batt.py +++ b/ohmpi/hardware_components/pwr_batt.py @@ -8,7 +8,8 @@ from ohmpi.utils import enforce_specs SPECS = {'model': {'default': os.path.basename(__file__).rstrip('.py')}, 'voltage': {'default': 12., 'max': 12., 'min': 12.}, 'current_adjustable': {'default': False}, - 'voltage_adjustable': {'default': False} + 'voltage_adjustable': {'default': False}, + 'interface': {'default': 'none'}, } diff --git a/ohmpi/hardware_components/raspberry_pi.py b/ohmpi/hardware_components/raspberry_pi.py index f2a59642824a9869d1cb4e7b23f437e278e2a86a..d45ad095c3cf7f7ef977d8a67677378f9d38521b 100644 --- a/ohmpi/hardware_components/raspberry_pi.py +++ b/ohmpi/hardware_components/raspberry_pi.py @@ -34,6 +34,9 @@ class Ctl(CtlAbstract): super().__init__(**kwargs) self.interfaces = dict() + # None interface for battery + self.interfaces['none'] = None + # warnings.filterwarnings("error") # to filter out adafruit warning about setting I2C frequency # I2C try: diff --git a/ohmpi/hardware_system.py b/ohmpi/hardware_system.py index 7112c0469018be44f4de6088cdb57f44e90445e4..8b698406576473dac523e3b0e9dd80e5ead33d08 100644 --- a/ohmpi/hardware_system.py +++ b/ohmpi/hardware_system.py @@ -104,11 +104,11 @@ class OhmPiHardware: if isinstance(ctl_mod, str): ctl_mod = importlib.import_module(f'ohmpi.hardware_components.{ctl_mod}') HARDWARE_CONFIG['pwr']['ctl'] = ctl_mod.Ctl(**HARDWARE_CONFIG['pwr']['ctl']) - HARDWARE_CONFIG['pwr'].update({'connection': - HARDWARE_CONFIG['pwr'].pop('connection', - HARDWARE_CONFIG['pwr']['ctl'].interfaces[ - HARDWARE_CONFIG['pwr'].pop( - 'interface_name', None)])}) + #if 'interface_name' in HARDWARE_CONFIG['pwr']: + HARDWARE_CONFIG['pwr'].update({ + 'connection': HARDWARE_CONFIG['pwr'].pop( + 'connection', HARDWARE_CONFIG['pwr']['ctl'].interfaces[ + HARDWARE_CONFIG['pwr'].pop('interface_name', None)])}) HARDWARE_CONFIG['pwr'].update({'exec_logger': self.exec_logger, 'data_logger': self.data_logger, 'soh_logger': self.soh_logger}) diff --git a/ohmpi/ohmpi.py b/ohmpi/ohmpi.py index ea0b3e2b8d2c31987c7f05c34276049dea4cc5b6..82653c02065ae1d957a5f5148eca3c201439e656 100644 --- a/ohmpi/ohmpi.py +++ b/ohmpi/ohmpi.py @@ -904,6 +904,62 @@ class OhmPi(object): return status + def run_inversion(self, survey_name, elec_spacing=1, **kwargs): + """Invert a specific survey on the Pi using ResIPy. + + Parameters + ---------- + survey_name : str + Filename of the survey to be inverted with its extension. + To get all filenames availables, see get_data(). + elec_spacing : float, optional + Electrode spacing in meters. + **kwargs : dict, optional + Additional keyword arguments are passed to resipy.Project.invert() function. + + Returns + ------- + xzv : dict + Dictionnary with keys: X and Z for centroid of the elements of the mesh + and key 'resistivity' for their resistivity. + """ + # check if resipy is installed + try: + import sys + sys.path.append('../resipy/src/') + from resipy import Project + except Exception as e: + self.exec_logger.error('Could not import ResIPy. Make sure it is installed. Error ' + str(e)) + return + + # create project instance and run inversion + k = Project(typ='R2') + if 'reg_mode' in kwargs: + if kwargs['reg_mode'] != 0: + fname0 = '../data/' + sorted(os.listdir('../data'))[0] + k.createTimeLapseSurvey([fname0, '../data/' + survey_name]) + else: + k.createSurvey('../data/' + survey_name) + else: + k.createSurvey('../data/' + survey_name) + elec = np.zeros((k.surveys[0].df[['a', 'b', 'm', 'n']].max(), 3)) + elec[:, 0] = np.arange(0, elec.shape[0]*elec_spacing, elec_spacing) + k.setElec(elec) + k.createMesh() + k.invert(**kwargs) + k.getResults() + + # extract centroids of elements and values + df = k.meshResults[0].df + xzv = { + 'x': df['X'].values, + 'z': df['Z'].values, + 'resistivity': df['Resistivity(ohm.m)'].values + } + + self.data_logger.info(json.dumps(xzv)) + return xzv + # Properties @property def sequence(self):